1package stdlib
2
3import (
4	"fmt"
5	"testing"
6
7	"github.com/zclconf/go-cty/cty"
8)
9
10func TestConcat(t *testing.T) {
11	tests := []struct {
12		Input []cty.Value
13		Want  cty.Value
14	}{
15		{
16			[]cty.Value{
17				cty.ListValEmpty(cty.Number),
18			},
19			cty.ListValEmpty(cty.Number),
20		},
21		{
22			[]cty.Value{
23				cty.ListVal([]cty.Value{
24					cty.NumberIntVal(1),
25					cty.NumberIntVal(2),
26					cty.NumberIntVal(3),
27				}),
28			},
29			cty.ListVal([]cty.Value{
30				cty.NumberIntVal(1),
31				cty.NumberIntVal(2),
32				cty.NumberIntVal(3),
33			}),
34		},
35		{
36			[]cty.Value{
37				cty.ListVal([]cty.Value{
38					cty.NumberIntVal(1),
39				}),
40				cty.ListVal([]cty.Value{
41					cty.NumberIntVal(2),
42					cty.NumberIntVal(3),
43				}),
44			},
45			cty.ListVal([]cty.Value{
46				cty.NumberIntVal(1),
47				cty.NumberIntVal(2),
48				cty.NumberIntVal(3),
49			}),
50		},
51		{
52			[]cty.Value{
53				cty.ListVal([]cty.Value{
54					cty.NumberIntVal(1),
55				}),
56				cty.ListVal([]cty.Value{
57					cty.StringVal("foo"),
58				}),
59				cty.ListVal([]cty.Value{
60					cty.True,
61				}),
62			},
63			cty.ListVal([]cty.Value{
64				cty.StringVal("1"),
65				cty.StringVal("foo"),
66				cty.StringVal("true"),
67			}),
68		},
69		{
70			[]cty.Value{
71				cty.ListVal([]cty.Value{
72					cty.NumberIntVal(1),
73				}),
74				cty.ListVal([]cty.Value{
75					cty.StringVal("foo"),
76					cty.StringVal("bar"),
77				}),
78			},
79			cty.ListVal([]cty.Value{
80				cty.StringVal("1"),
81				cty.StringVal("foo"),
82				cty.StringVal("bar"),
83			}),
84		},
85		{
86			[]cty.Value{
87				cty.EmptyTupleVal,
88			},
89			cty.EmptyTupleVal,
90		},
91		{
92			[]cty.Value{
93				cty.TupleVal([]cty.Value{
94					cty.NumberIntVal(1),
95					cty.True,
96					cty.NumberIntVal(3),
97				}),
98			},
99			cty.TupleVal([]cty.Value{
100				cty.NumberIntVal(1),
101				cty.True,
102				cty.NumberIntVal(3),
103			}),
104		},
105		{
106			[]cty.Value{
107				cty.TupleVal([]cty.Value{
108					cty.NumberIntVal(1),
109				}),
110				cty.TupleVal([]cty.Value{
111					cty.True,
112					cty.NumberIntVal(3),
113				}),
114			},
115			cty.TupleVal([]cty.Value{
116				cty.NumberIntVal(1),
117				cty.True,
118				cty.NumberIntVal(3),
119			}),
120		},
121		{
122			[]cty.Value{
123				cty.ListVal([]cty.Value{
124					cty.NumberIntVal(1),
125				}),
126				cty.TupleVal([]cty.Value{
127					cty.True,
128					cty.NumberIntVal(3),
129				}),
130			},
131			cty.TupleVal([]cty.Value{
132				cty.NumberIntVal(1),
133				cty.True,
134				cty.NumberIntVal(3),
135			}),
136		},
137		{
138			[]cty.Value{
139				cty.TupleVal([]cty.Value{
140					cty.NumberIntVal(1),
141					cty.True,
142				}),
143				cty.ListVal([]cty.Value{
144					cty.NumberIntVal(3),
145				}),
146			},
147			cty.TupleVal([]cty.Value{
148				cty.NumberIntVal(1),
149				cty.True,
150				cty.NumberIntVal(3),
151			}),
152		},
153		{
154			// Two lists with unconvertable element types become a tuple.
155			[]cty.Value{
156				cty.ListVal([]cty.Value{
157					cty.NumberIntVal(1),
158				}),
159				cty.ListVal([]cty.Value{
160					cty.ListValEmpty(cty.Bool),
161				}),
162			},
163			cty.TupleVal([]cty.Value{
164				cty.NumberIntVal(1),
165				cty.ListValEmpty(cty.Bool),
166			}),
167		},
168	}
169
170	for _, test := range tests {
171		t.Run(fmt.Sprintf("Concat(%#v...)", test.Input), func(t *testing.T) {
172			got, err := Concat(test.Input...)
173
174			if err != nil {
175				t.Fatalf("unexpected error: %s", err)
176			}
177
178			if !got.RawEquals(test.Want) {
179				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
180			}
181		})
182	}
183}
184
185func TestRange(t *testing.T) {
186	tests := []struct {
187		Args []cty.Value
188		Want cty.Value
189	}{
190		// One argument
191		{
192			[]cty.Value{
193				cty.NumberIntVal(5),
194			},
195			cty.ListVal([]cty.Value{
196				cty.NumberIntVal(0),
197				cty.NumberIntVal(1),
198				cty.NumberIntVal(2),
199				cty.NumberIntVal(3),
200				cty.NumberIntVal(4),
201			}),
202		},
203		{
204			[]cty.Value{
205				cty.NumberIntVal(-5),
206			},
207			cty.ListVal([]cty.Value{
208				cty.NumberIntVal(0),
209				cty.NumberIntVal(-1),
210				cty.NumberIntVal(-2),
211				cty.NumberIntVal(-3),
212				cty.NumberIntVal(-4),
213			}),
214		},
215		{
216			[]cty.Value{
217				cty.NumberIntVal(1),
218			},
219			cty.ListVal([]cty.Value{
220				cty.NumberIntVal(0),
221			}),
222		},
223		{
224			[]cty.Value{
225				cty.NumberIntVal(0),
226			},
227			cty.ListValEmpty(cty.Number),
228		},
229		{
230			[]cty.Value{
231				cty.MustParseNumberVal("5.5"),
232			},
233			cty.ListVal([]cty.Value{
234				cty.NumberIntVal(0),
235				cty.NumberIntVal(1),
236				cty.NumberIntVal(2),
237				cty.NumberIntVal(3),
238				cty.NumberIntVal(4),
239				cty.NumberIntVal(5), // because 5 < 5.5
240			}),
241		},
242
243		// Two arguments
244		{
245			[]cty.Value{
246				cty.NumberIntVal(1),
247				cty.NumberIntVal(5),
248			},
249			cty.ListVal([]cty.Value{
250				cty.NumberIntVal(1),
251				cty.NumberIntVal(2),
252				cty.NumberIntVal(3),
253				cty.NumberIntVal(4),
254			}),
255		},
256		{
257			[]cty.Value{
258				cty.NumberIntVal(5),
259				cty.NumberIntVal(1),
260			},
261			cty.ListVal([]cty.Value{
262				cty.NumberIntVal(5),
263				cty.NumberIntVal(4),
264				cty.NumberIntVal(3),
265				cty.NumberIntVal(2),
266			}),
267		},
268		{
269			[]cty.Value{
270				cty.NumberFloatVal(1.5),
271				cty.NumberIntVal(5),
272			},
273			cty.ListVal([]cty.Value{
274				cty.NumberFloatVal(1.5),
275				cty.NumberFloatVal(2.5),
276				cty.NumberFloatVal(3.5),
277				cty.NumberFloatVal(4.5),
278			}),
279		},
280		{
281			[]cty.Value{
282				cty.NumberIntVal(1),
283				cty.NumberIntVal(2),
284			},
285			cty.ListVal([]cty.Value{
286				cty.NumberIntVal(1),
287			}),
288		},
289		{
290			[]cty.Value{
291				cty.NumberIntVal(1),
292				cty.NumberIntVal(1),
293			},
294			cty.ListValEmpty(cty.Number),
295		},
296
297		// Three arguments
298		{
299			[]cty.Value{
300				cty.NumberIntVal(0),
301				cty.NumberIntVal(5),
302				cty.NumberIntVal(2),
303			},
304			cty.ListVal([]cty.Value{
305				cty.NumberIntVal(0),
306				cty.NumberIntVal(2),
307				cty.NumberIntVal(4),
308			}),
309		},
310		{
311			[]cty.Value{
312				cty.NumberIntVal(0),
313				cty.NumberIntVal(5),
314				cty.NumberIntVal(1),
315			},
316			cty.ListVal([]cty.Value{
317				cty.NumberIntVal(0),
318				cty.NumberIntVal(1),
319				cty.NumberIntVal(2),
320				cty.NumberIntVal(3),
321				cty.NumberIntVal(4),
322			}),
323		},
324		{
325			[]cty.Value{
326				cty.NumberIntVal(0),
327				cty.NumberIntVal(1),
328				cty.NumberIntVal(1),
329			},
330			cty.ListVal([]cty.Value{
331				cty.NumberIntVal(0),
332			}),
333		},
334		{
335			[]cty.Value{
336				cty.NumberIntVal(0),
337				cty.NumberIntVal(0),
338				cty.NumberIntVal(1),
339			},
340			cty.ListValEmpty(cty.Number),
341		},
342		{
343			[]cty.Value{
344				cty.NumberIntVal(5),
345				cty.NumberIntVal(0),
346				cty.NumberIntVal(-1),
347			},
348			cty.ListVal([]cty.Value{
349				cty.NumberIntVal(5),
350				cty.NumberIntVal(4),
351				cty.NumberIntVal(3),
352				cty.NumberIntVal(2),
353				cty.NumberIntVal(1),
354			}),
355		},
356		{
357			[]cty.Value{
358				cty.NumberIntVal(0),
359				cty.NumberIntVal(5),
360				cty.NumberFloatVal(0.5),
361			},
362			cty.ListVal([]cty.Value{
363				cty.NumberIntVal(0),
364				cty.NumberFloatVal(0.5),
365				cty.NumberIntVal(1),
366				cty.NumberFloatVal(1.5),
367				cty.NumberIntVal(2),
368				cty.NumberFloatVal(2.5),
369				cty.NumberIntVal(3),
370				cty.NumberFloatVal(3.5),
371				cty.NumberIntVal(4),
372				cty.NumberFloatVal(4.5),
373			}),
374		},
375	}
376
377	for _, test := range tests {
378		t.Run(fmt.Sprintf("Range(%#v)", test.Args), func(t *testing.T) {
379			got, err := Range(test.Args...)
380
381			if err != nil {
382				t.Fatalf("unexpected error: %s", err)
383			}
384
385			if !got.RawEquals(test.Want) {
386				t.Errorf(
387					"wrong result\nargs: %#v\ngot:  %#v\nwant: %#v",
388					test.Args, got, test.Want,
389				)
390			}
391		})
392	}
393}
394