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