forked from
tangled.org/core
Monorepo for Tangled — https://tangled.org
1package sets
2
3import (
4 "slices"
5 "testing"
6 "testing/quick"
7)
8
9func TestNew(t *testing.T) {
10 s := New[int]()
11 if s.Len() != 0 {
12 t.Errorf("New set should be empty, got length %d", s.Len())
13 }
14 if !s.IsEmpty() {
15 t.Error("New set should be empty")
16 }
17}
18
19func TestFromSlice(t *testing.T) {
20 s := Collect(slices.Values([]int{1, 2, 3, 2, 1}))
21 if s.Len() != 3 {
22 t.Errorf("Expected length 3, got %d", s.Len())
23 }
24 if !s.Contains(1) || !s.Contains(2) || !s.Contains(3) {
25 t.Error("Set should contain all unique elements from slice")
26 }
27}
28
29func TestInsert(t *testing.T) {
30 s := New[string]()
31
32 if !s.Insert("hello") {
33 t.Error("First insert should return true")
34 }
35 if s.Insert("hello") {
36 t.Error("Duplicate insert should return false")
37 }
38 if s.Len() != 1 {
39 t.Errorf("Expected length 1, got %d", s.Len())
40 }
41}
42
43func TestRemove(t *testing.T) {
44 s := Collect(slices.Values([]int{1, 2, 3}))
45
46 if !s.Remove(2) {
47 t.Error("Remove existing element should return true")
48 }
49 if s.Remove(2) {
50 t.Error("Remove non-existing element should return false")
51 }
52 if s.Contains(2) {
53 t.Error("Element should be removed")
54 }
55 if s.Len() != 2 {
56 t.Errorf("Expected length 2, got %d", s.Len())
57 }
58}
59
60func TestContains(t *testing.T) {
61 s := Collect(slices.Values([]int{1, 2, 3}))
62
63 if !s.Contains(1) {
64 t.Error("Should contain 1")
65 }
66 if s.Contains(4) {
67 t.Error("Should not contain 4")
68 }
69}
70
71func TestClear(t *testing.T) {
72 s := Collect(slices.Values([]int{1, 2, 3}))
73 s.Clear()
74
75 if !s.IsEmpty() {
76 t.Error("Set should be empty after clear")
77 }
78 if s.Len() != 0 {
79 t.Errorf("Expected length 0, got %d", s.Len())
80 }
81}
82
83func TestIterator(t *testing.T) {
84 s := Collect(slices.Values([]int{1, 2, 3}))
85 var items []int
86
87 for item := range s.All() {
88 items = append(items, item)
89 }
90
91 slices.Sort(items)
92 expected := []int{1, 2, 3}
93 if !slices.Equal(items, expected) {
94 t.Errorf("Expected %v, got %v", expected, items)
95 }
96}
97
98func TestClone(t *testing.T) {
99 s1 := Collect(slices.Values([]int{1, 2, 3}))
100 s2 := s1.Clone()
101
102 if !s1.Equal(s2) {
103 t.Error("Cloned set should be equal to original")
104 }
105
106 s2.Insert(4)
107 if s1.Contains(4) {
108 t.Error("Modifying clone should not affect original")
109 }
110}
111
112func TestUnion(t *testing.T) {
113 s1 := Collect(slices.Values([]int{1, 2}))
114 s2 := Collect(slices.Values([]int{2, 3}))
115
116 result := Collect(s1.Union(s2))
117 expected := Collect(slices.Values([]int{1, 2, 3}))
118
119 if !result.Equal(expected) {
120 t.Errorf("Expected %v, got %v", expected, result)
121 }
122}
123
124func TestIntersection(t *testing.T) {
125 s1 := Collect(slices.Values([]int{1, 2, 3}))
126 s2 := Collect(slices.Values([]int{2, 3, 4}))
127
128 expected := Collect(slices.Values([]int{2, 3}))
129 result := Collect(s1.Intersection(s2))
130
131 if !result.Equal(expected) {
132 t.Errorf("Expected %v, got %v", expected, result)
133 }
134}
135
136func TestDifference(t *testing.T) {
137 s1 := Collect(slices.Values([]int{1, 2, 3}))
138 s2 := Collect(slices.Values([]int{2, 3, 4}))
139
140 expected := Collect(slices.Values([]int{1}))
141 result := Collect(s1.Difference(s2))
142
143 if !result.Equal(expected) {
144 t.Errorf("Expected %v, got %v", expected, result)
145 }
146}
147
148func TestSymmetricDifference(t *testing.T) {
149 s1 := Collect(slices.Values([]int{1, 2, 3}))
150 s2 := Collect(slices.Values([]int{2, 3, 4}))
151
152 expected := Collect(slices.Values([]int{1, 4}))
153 result := Collect(s1.SymmetricDifference(s2))
154
155 if !result.Equal(expected) {
156 t.Errorf("Expected %v, got %v", expected, result)
157 }
158}
159
160func TestSymmetricDifferenceCommutativeProperty(t *testing.T) {
161 s1 := Collect(slices.Values([]int{1, 2, 3}))
162 s2 := Collect(slices.Values([]int{2, 3, 4}))
163
164 result1 := Collect(s1.SymmetricDifference(s2))
165 result2 := Collect(s2.SymmetricDifference(s1))
166
167 if !result1.Equal(result2) {
168 t.Errorf("Expected %v, got %v", result1, result2)
169 }
170}
171
172func TestIsSubset(t *testing.T) {
173 s1 := Collect(slices.Values([]int{1, 2}))
174 s2 := Collect(slices.Values([]int{1, 2, 3}))
175
176 if !s1.IsSubset(s2) {
177 t.Error("s1 should be subset of s2")
178 }
179 if s2.IsSubset(s1) {
180 t.Error("s2 should not be subset of s1")
181 }
182}
183
184func TestIsSuperset(t *testing.T) {
185 s1 := Collect(slices.Values([]int{1, 2, 3}))
186 s2 := Collect(slices.Values([]int{1, 2}))
187
188 if !s1.IsSuperset(s2) {
189 t.Error("s1 should be superset of s2")
190 }
191 if s2.IsSuperset(s1) {
192 t.Error("s2 should not be superset of s1")
193 }
194}
195
196func TestIsDisjoint(t *testing.T) {
197 s1 := Collect(slices.Values([]int{1, 2}))
198 s2 := Collect(slices.Values([]int{3, 4}))
199 s3 := Collect(slices.Values([]int{2, 3}))
200
201 if !s1.IsDisjoint(s2) {
202 t.Error("s1 and s2 should be disjoint")
203 }
204 if s1.IsDisjoint(s3) {
205 t.Error("s1 and s3 should not be disjoint")
206 }
207}
208
209func TestEqual(t *testing.T) {
210 s1 := Collect(slices.Values([]int{1, 2, 3}))
211 s2 := Collect(slices.Values([]int{3, 2, 1}))
212 s3 := Collect(slices.Values([]int{1, 2}))
213
214 if !s1.Equal(s2) {
215 t.Error("s1 and s2 should be equal")
216 }
217 if s1.Equal(s3) {
218 t.Error("s1 and s3 should not be equal")
219 }
220}
221
222func TestCollect(t *testing.T) {
223 s1 := Collect(slices.Values([]int{1, 2}))
224 s2 := Collect(slices.Values([]int{2, 3}))
225
226 unionSet := Collect(s1.Union(s2))
227 if unionSet.Len() != 3 {
228 t.Errorf("Expected union set length 3, got %d", unionSet.Len())
229 }
230 if !unionSet.Contains(1) || !unionSet.Contains(2) || !unionSet.Contains(3) {
231 t.Error("Union set should contain 1, 2, and 3")
232 }
233
234 diffSet := Collect(s1.Difference(s2))
235 if diffSet.Len() != 1 {
236 t.Errorf("Expected difference set length 1, got %d", diffSet.Len())
237 }
238 if !diffSet.Contains(1) {
239 t.Error("Difference set should contain 1")
240 }
241}
242
243func TestPropertySingleonLen(t *testing.T) {
244 f := func(item int) bool {
245 single := Singleton(item)
246 return single.Len() == 1
247 }
248
249 if err := quick.Check(f, nil); err != nil {
250 t.Error(err)
251 }
252}
253
254func TestPropertyInsertIdempotent(t *testing.T) {
255 f := func(s Set[int], item int) bool {
256 clone := s.Clone()
257
258 clone.Insert(item)
259 firstLen := clone.Len()
260
261 clone.Insert(item)
262 secondLen := clone.Len()
263
264 return firstLen == secondLen
265 }
266
267 if err := quick.Check(f, nil); err != nil {
268 t.Error(err)
269 }
270}
271
272func TestPropertyUnionCommutative(t *testing.T) {
273 f := func(s1 Set[int], s2 Set[int]) bool {
274 union1 := Collect(s1.Union(s2))
275 union2 := Collect(s2.Union(s1))
276 return union1.Equal(union2)
277 }
278
279 if err := quick.Check(f, nil); err != nil {
280 t.Error(err)
281 }
282}
283
284func TestPropertyIntersectionCommutative(t *testing.T) {
285 f := func(s1 Set[int], s2 Set[int]) bool {
286 inter1 := Collect(s1.Intersection(s2))
287 inter2 := Collect(s2.Intersection(s1))
288 return inter1.Equal(inter2)
289 }
290
291 if err := quick.Check(f, nil); err != nil {
292 t.Error(err)
293 }
294}
295
296func TestPropertyCloneEquals(t *testing.T) {
297 f := func(s Set[int]) bool {
298 clone := s.Clone()
299 return s.Equal(clone)
300 }
301
302 if err := quick.Check(f, nil); err != nil {
303 t.Error(err)
304 }
305}
306
307func TestPropertyIntersectionIsSubset(t *testing.T) {
308 f := func(s1 Set[int], s2 Set[int]) bool {
309 inter := Collect(s1.Intersection(s2))
310 return inter.IsSubset(s1) && inter.IsSubset(s2)
311 }
312
313 if err := quick.Check(f, nil); err != nil {
314 t.Error(err)
315 }
316}
317
318func TestPropertyUnionIsSuperset(t *testing.T) {
319 f := func(s1 Set[int], s2 Set[int]) bool {
320 union := Collect(s1.Union(s2))
321 return union.IsSuperset(s1) && union.IsSuperset(s2)
322 }
323
324 if err := quick.Check(f, nil); err != nil {
325 t.Error(err)
326 }
327}
328
329func TestPropertyDifferenceDisjoint(t *testing.T) {
330 f := func(s1 Set[int], s2 Set[int]) bool {
331 diff := Collect(s1.Difference(s2))
332 return diff.IsDisjoint(s2)
333 }
334
335 if err := quick.Check(f, nil); err != nil {
336 t.Error(err)
337 }
338}
339
340func TestPropertySymmetricDifferenceCommutative(t *testing.T) {
341 f := func(s1 Set[int], s2 Set[int]) bool {
342 symDiff1 := Collect(s1.SymmetricDifference(s2))
343 symDiff2 := Collect(s2.SymmetricDifference(s1))
344 return symDiff1.Equal(symDiff2)
345 }
346
347 if err := quick.Check(f, nil); err != nil {
348 t.Error(err)
349 }
350}
351
352func TestPropertyRemoveWorks(t *testing.T) {
353 f := func(s Set[int], item int) bool {
354 clone := s.Clone()
355 clone.Insert(item)
356 clone.Remove(item)
357 return !clone.Contains(item)
358 }
359
360 if err := quick.Check(f, nil); err != nil {
361 t.Error(err)
362 }
363}
364
365func TestPropertyClearEmpty(t *testing.T) {
366 f := func(s Set[int]) bool {
367 s.Clear()
368 return s.IsEmpty() && s.Len() == 0
369 }
370
371 if err := quick.Check(f, nil); err != nil {
372 t.Error(err)
373 }
374}
375
376func TestPropertyIsSubsetReflexive(t *testing.T) {
377 f := func(s Set[int]) bool {
378 return s.IsSubset(s)
379 }
380
381 if err := quick.Check(f, nil); err != nil {
382 t.Error(err)
383 }
384}
385
386func TestPropertyDeMorganUnion(t *testing.T) {
387 f := func(s1 Set[int], s2 Set[int], universe Set[int]) bool {
388 // create a universe that contains both sets
389 u := universe.Clone()
390 for item := range s1.All() {
391 u.Insert(item)
392 }
393 for item := range s2.All() {
394 u.Insert(item)
395 }
396
397 // (A u B)' = A' n B'
398 union := Collect(s1.Union(s2))
399 complementUnion := Collect(u.Difference(union))
400
401 complementS1 := Collect(u.Difference(s1))
402 complementS2 := Collect(u.Difference(s2))
403 intersectionComplements := Collect(complementS1.Intersection(complementS2))
404
405 return complementUnion.Equal(intersectionComplements)
406 }
407
408 if err := quick.Check(f, nil); err != nil {
409 t.Error(err)
410 }
411}