blob: 9ff98a6503c11008a4720b2a14b37575fd92f2af [file] [log] [blame]
Guido van Rossumd6cf3af2002-08-19 16:19:15 +00001#!/usr/bin/env python
2
3import unittest, operator, copy
4from sets import Set, ImmutableSet
5from test import test_support
6
7empty_set = Set()
8
9#==============================================================================
10
11class TestBasicOps(unittest.TestCase):
12
13 def test_repr(self):
14 if self.repr is not None:
15 assert `self.set` == self.repr, "Wrong representation for " + self.case
16
17 def test_length(self):
18 assert len(self.set) == self.length, "Wrong length for " + self.case
19
20 def test_self_equality(self):
21 assert self.set == self.set, "Self-equality failed for " + self.case
22
23 def test_equivalent_equality(self):
24 assert self.set == self.dup, "Equivalent equality failed for " + self.case
25
26 def test_copy(self):
27 assert self.set.copy() == self.dup, "Copy and comparison failed for " + self.case
28
29 def test_self_union(self):
30 result = self.set | self.set
31 assert result == self.dup, "Self-union failed for " + self.case
32
33 def test_empty_union(self):
34 result = self.set | empty_set
35 assert result == self.dup, "Union with empty failed for " + self.case
36
37 def test_union_empty(self):
38 result = empty_set | self.set
39 assert result == self.dup, "Union with empty failed for " + self.case
40
41 def test_self_intersection(self):
42 result = self.set & self.set
43 assert result == self.dup, "Self-intersection failed for " + self.case
44
45 def test_empty_intersection(self):
46 result = self.set & empty_set
47 assert result == empty_set, "Intersection with empty failed for " + self.case
48
49 def test_intersection_empty(self):
50 result = empty_set & self.set
51 assert result == empty_set, "Intersection with empty failed for " + self.case
52
53 def test_self_symmetric_difference(self):
54 result = self.set ^ self.set
55 assert result == empty_set, "Self-symdiff failed for " + self.case
56
57 def checkempty_symmetric_difference(self):
58 result = self.set ^ empty_set
59 assert result == self.set, "Symdiff with empty failed for " + self.case
60
61 def test_self_difference(self):
62 result = self.set - self.set
63 assert result == empty_set, "Self-difference failed for " + self.case
64
65 def test_empty_difference(self):
66 result = self.set - empty_set
67 assert result == self.dup, "Difference with empty failed for " + self.case
68
69 def test_empty_difference_rev(self):
70 result = empty_set - self.set
71 assert result == empty_set, "Difference from empty failed for " + self.case
72
73 def test_iteration(self):
74 for v in self.set:
75 assert v in self.values, "Missing item in iteration for " + self.case
76
77#------------------------------------------------------------------------------
78
79class TestBasicOpsEmpty(TestBasicOps):
80 def setUp(self):
81 self.case = "empty set"
82 self.values = []
83 self.set = Set(self.values)
84 self.dup = Set(self.values)
85 self.length = 0
86 self.repr = "Set([])"
87
88#------------------------------------------------------------------------------
89
90class TestBasicOpsSingleton(TestBasicOps):
91 def setUp(self):
92 self.case = "unit set (number)"
93 self.values = [3]
94 self.set = Set(self.values)
95 self.dup = Set(self.values)
96 self.length = 1
97 self.repr = "Set([3])"
98
99 def test_in(self):
100 assert 3 in self.set, "Valueship for unit set"
101
102 def test_not_in(self):
103 assert 2 not in self.set, "Non-valueship for unit set"
104
105#------------------------------------------------------------------------------
106
107class TestBasicOpsTuple(TestBasicOps):
108 def setUp(self):
109 self.case = "unit set (tuple)"
110 self.values = [(0, "zero")]
111 self.set = Set(self.values)
112 self.dup = Set(self.values)
113 self.length = 1
114 self.repr = "Set([(0, 'zero')])"
115
116 def test_in(self):
117 assert (0, "zero") in self.set, "Valueship for tuple set"
118
119 def test_not_in(self):
120 assert 9 not in self.set, "Non-valueship for tuple set"
121
122#------------------------------------------------------------------------------
123
124class TestBasicOpsTriple(TestBasicOps):
125 def setUp(self):
126 self.case = "triple set"
127 self.values = [0, "zero", operator.add]
128 self.set = Set(self.values)
129 self.dup = Set(self.values)
130 self.length = 3
131 self.repr = None
132
133#==============================================================================
134
Raymond Hettingerc3e61e52002-08-21 06:38:44 +0000135class TestSetOfSets(unittest.TestCase):
136 def test_constructor(self):
137 inner = Set([1])
138 outer = Set([inner])
139 element = outer.pop()
140 assert type(element) == ImmutableSet, "Construct set of sets"
Raymond Hettinger045e51a2002-08-24 02:56:01 +0000141 outer.add(inner) # Rebuild set of sets with .add method
142 outer.remove(inner)
143 assert outer == Set() # Verify that remove worked
144 outer.discard(inner) # Absence of KeyError indicates working fine
Raymond Hettingerc3e61e52002-08-21 06:38:44 +0000145
146#==============================================================================
147
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000148class TestBinaryOps(unittest.TestCase):
149 def setUp(self):
150 self.set = Set((2, 4, 6))
151
152 def test_union_subset(self):
153 result = self.set | Set([2])
154 assert result == Set((2, 4, 6)), "Subset union"
155
156 def test_union_superset(self):
157 result = self.set | Set([2, 4, 6, 8])
158 assert result == Set([2, 4, 6, 8]), "Superset union"
159
160 def test_union_overlap(self):
161 result = self.set | Set([3, 4, 5])
162 assert result == Set([2, 3, 4, 5, 6]), "Overlapping union"
163
164 def test_union_non_overlap(self):
165 result = self.set | Set([8])
166 assert result == Set([2, 4, 6, 8]), "Non-overlapping union"
167
168 def test_intersection_subset(self):
169 result = self.set & Set((2, 4))
170 assert result == Set((2, 4)), "Subset intersection"
171
172 def test_intersection_superset(self):
173 result = self.set & Set([2, 4, 6, 8])
174 assert result == Set([2, 4, 6]), "Superset intersection"
175
176 def test_intersection_overlap(self):
177 result = self.set & Set([3, 4, 5])
178 assert result == Set([4]), "Overlapping intersection"
179
180 def test_intersection_non_overlap(self):
181 result = self.set & Set([8])
182 assert result == empty_set, "Non-overlapping intersection"
183
184 def test_sym_difference_subset(self):
185 result = self.set ^ Set((2, 4))
186 assert result == Set([6]), "Subset symmetric difference"
187
188 def test_sym_difference_superset(self):
189 result = self.set ^ Set((2, 4, 6, 8))
190 assert result == Set([8]), "Superset symmetric difference"
191
192 def test_sym_difference_overlap(self):
193 result = self.set ^ Set((3, 4, 5))
194 assert result == Set([2, 3, 5, 6]), "Overlapping symmetric difference"
195
196 def test_sym_difference_non_overlap(self):
197 result = self.set ^ Set([8])
198 assert result == Set([2, 4, 6, 8]), "Non-overlapping symmetric difference"
199
200#==============================================================================
201
202class TestUpdateOps(unittest.TestCase):
203 def setUp(self):
204 self.set = Set((2, 4, 6))
205
206 def test_union_subset(self):
207 self.set |= Set([2])
208 assert self.set == Set((2, 4, 6)), "Subset union"
209
210 def test_union_superset(self):
211 self.set |= Set([2, 4, 6, 8])
212 assert self.set == Set([2, 4, 6, 8]), "Superset union"
213
214 def test_union_overlap(self):
215 self.set |= Set([3, 4, 5])
216 assert self.set == Set([2, 3, 4, 5, 6]), "Overlapping union"
217
218 def test_union_non_overlap(self):
219 self.set |= Set([8])
220 assert self.set == Set([2, 4, 6, 8]), "Non-overlapping union"
221
Raymond Hettinger1b9f5d42002-08-24 06:19:02 +0000222 def test_union_method_call(self):
223 self.set.union_update(Set([3, 4, 5]))
224 assert self.set == Set([2, 3, 4, 5, 6]), "Union method call"
225
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000226 def test_intersection_subset(self):
227 self.set &= Set((2, 4))
228 assert self.set == Set((2, 4)), "Subset intersection"
229
230 def test_intersection_superset(self):
231 self.set &= Set([2, 4, 6, 8])
232 assert self.set == Set([2, 4, 6]), "Superset intersection"
233
234 def test_intersection_overlap(self):
235 self.set &= Set([3, 4, 5])
236 assert self.set == Set([4]), "Overlapping intersection"
237
238 def test_intersection_non_overlap(self):
239 self.set &= Set([8])
240 assert self.set == empty_set, "Non-overlapping intersection"
241
Raymond Hettinger1b9f5d42002-08-24 06:19:02 +0000242 def test_intersection_method_call(self):
243 self.set.intersection_update(Set([3, 4, 5]))
244 assert self.set == Set([4]), "Intersection method call"
245
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000246 def test_sym_difference_subset(self):
247 self.set ^= Set((2, 4))
248 assert self.set == Set([6]), "Subset symmetric difference"
249
250 def test_sym_difference_superset(self):
251 self.set ^= Set((2, 4, 6, 8))
252 assert self.set == Set([8]), "Superset symmetric difference"
253
254 def test_sym_difference_overlap(self):
255 self.set ^= Set((3, 4, 5))
256 assert self.set == Set([2, 3, 5, 6]), "Overlapping symmetric difference"
257
258 def test_sym_difference_non_overlap(self):
259 self.set ^= Set([8])
260 assert self.set == Set([2, 4, 6, 8]), "Non-overlapping symmetric difference"
261
Raymond Hettinger1b9f5d42002-08-24 06:19:02 +0000262 def test_sym_difference_method_call(self):
263 self.set.symmetric_difference_update(Set([3, 4, 5]))
264 assert self.set == Set([2, 3, 5, 6]), "Symmetric difference method call"
265
266 def test_difference_subset(self):
267 self.set -= Set((2, 4))
268 assert self.set == Set([6]), "Subset difference"
269
270 def test_difference_superset(self):
271 self.set -= Set((2, 4, 6, 8))
272 assert self.set == Set([]), "Superset difference"
273
274 def test_difference_overlap(self):
275 self.set -= Set((3, 4, 5))
276 assert self.set == Set([2, 6]), "Overlapping difference"
277
278 def test_difference_non_overlap(self):
279 self.set -= Set([8])
280 assert self.set == Set([2, 4, 6]), "Non-overlapping difference"
281
282 def test_difference_method_call(self):
283 self.set.difference_update(Set([3, 4, 5]))
284 assert self.set == Set([2, 6]), "Difference method call"
285
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000286#==============================================================================
287
288class TestMutate(unittest.TestCase):
289 def setUp(self):
290 self.values = ["a", "b", "c"]
291 self.set = Set(self.values)
292
293 def test_add_present(self):
294 self.set.add("c")
295 assert self.set == Set(("a", "b", "c")), "Adding present element"
296
297 def test_add_absent(self):
298 self.set.add("d")
299 assert self.set == Set(("a", "b", "c", "d")), "Adding missing element"
300
301 def test_add_until_full(self):
302 tmp = Set()
303 expected_len = 0
304 for v in self.values:
305 tmp.add(v)
306 expected_len += 1
307 assert len(tmp) == expected_len, "Adding values one by one to temporary"
308 assert tmp == self.set, "Adding values one by one"
309
310 def test_remove_present(self):
311 self.set.remove("b")
312 assert self.set == Set(("a", "c")), "Removing present element"
313
314 def test_remove_absent(self):
315 try:
316 self.set.remove("d")
317 assert 0, "Removing missing element"
318 except LookupError:
319 pass
320
321 def test_remove_until_empty(self):
322 expected_len = len(self.set)
323 for v in self.values:
324 self.set.remove(v)
325 expected_len -= 1
326 assert len(self.set) == expected_len, "Removing values one by one"
327
328 def test_discard_present(self):
329 self.set.discard("c")
330 assert self.set == Set(("a", "b")), "Discarding present element"
331
332 def test_discard_absent(self):
333 self.set.discard("d")
334 assert self.set == Set(("a", "b", "c")), "Discarding missing element"
335
336 def test_clear(self):
337 self.set.clear()
338 assert len(self.set) == 0, "Clearing set"
339
Guido van Rossumc9196bc2002-08-20 21:51:59 +0000340 def test_pop(self):
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000341 popped = {}
342 while self.set:
Guido van Rossumc9196bc2002-08-20 21:51:59 +0000343 popped[self.set.pop()] = None
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000344 assert len(popped) == len(self.values), "Popping items"
345 for v in self.values:
346 assert v in popped, "Popping items"
347
348 def test_update_empty_tuple(self):
349 self.set.update(())
350 assert self.set == Set(self.values), "Updating with empty tuple"
351
352 def test_update_unit_tuple_overlap(self):
353 self.set.update(("a",))
354 assert self.set == Set(self.values), "Updating with overlapping unit tuple"
355
356 def test_update_unit_tuple_non_overlap(self):
357 self.set.update(("a", "z"))
358 assert self.set == Set(self.values + ["z"]), "Updating with non-overlapping unit tuple"
359
360#==============================================================================
361
362class TestSubsets(unittest.TestCase):
363
364 def test_issubset(self):
365 result = self.left.issubset(self.right)
366 if "<" in self.cases:
367 assert result, "subset: " + self.name
368 else:
369 assert not result, "non-subset: " + self.name
370
371#------------------------------------------------------------------------------
372
373class TestSubsetEqualEmpty(TestSubsets):
374 def setUp(self):
375 self.left = Set()
376 self.right = Set()
377 self.name = "both empty"
378 self.cases = "<>"
379
380#------------------------------------------------------------------------------
381
382class TestSubsetEqualNonEmpty(TestSubsets):
383 def setUp(self):
384 self.left = Set([1, 2])
385 self.right = Set([1, 2])
386 self.name = "equal pair"
387 self.cases = "<>"
388
389#------------------------------------------------------------------------------
390
391class TestSubsetEmptyNonEmpty(TestSubsets):
392 def setUp(self):
393 self.left = Set()
394 self.right = Set([1, 2])
395 self.name = "one empty, one non-empty"
396 self.cases = "<"
397
398#------------------------------------------------------------------------------
399
400class TestSubsetPartial(TestSubsets):
401 def setUp(self):
402 self.left = Set([1])
403 self.right = Set([1, 2])
404 self.name = "one a non-empty subset of other"
405 self.cases = "<"
406
407#------------------------------------------------------------------------------
408
409class TestSubsetNonOverlap(TestSubsets):
410 def setUp(self):
411 self.left = Set([1])
412 self.right = Set([2])
413 self.name = "neither empty, neither contains"
414 self.cases = ""
415
416#==============================================================================
417
418class TestOnlySetsInBinaryOps(unittest.TestCase):
419
420 def test_cmp(self):
421 try:
422 self.other < self.set
423 assert 0, "Comparison with non-set on left"
424 except TypeError:
425 pass
426 try:
427 self.set >= self.other
428 assert 0, "Comparison with non-set on right"
429 except TypeError:
430 pass
431
432 def test_union_update(self):
433 try:
434 self.set |= self.other
435 assert 0, "Union update with non-set"
436 except TypeError:
437 pass
438
439 def test_union(self):
440 try:
441 self.other | self.set
442 assert 0, "Union with non-set on left"
443 except TypeError:
444 pass
445 try:
446 self.set | self.other
447 assert 0, "Union with non-set on right"
448 except TypeError:
449 pass
450
451 def test_intersection_update(self):
452 try:
453 self.set &= self.other
454 assert 0, "Intersection update with non-set"
455 except TypeError:
456 pass
457
458 def test_intersection(self):
459 try:
460 self.other & self.set
461 assert 0, "Intersection with non-set on left"
462 except TypeError:
463 pass
464 try:
465 self.set & self.other
466 assert 0, "Intersection with non-set on right"
467 except TypeError:
468 pass
469
470 def test_sym_difference_update(self):
471 try:
472 self.set ^= self.other
473 assert 0, "Symmetric difference update with non-set"
474 except TypeError:
475 pass
476
477 def test_sym_difference(self):
478 try:
479 self.other ^ self.set
480 assert 0, "Symmetric difference with non-set on left"
481 except TypeError:
482 pass
483 try:
484 self.set ^ self.other
485 assert 0, "Symmetric difference with non-set on right"
486 except TypeError:
487 pass
488
489 def test_difference_update(self):
490 try:
491 self.set -= self.other
492 assert 0, "Symmetric difference update with non-set"
493 except TypeError:
494 pass
495
496 def test_difference(self):
497 try:
498 self.other - self.set
499 assert 0, "Symmetric difference with non-set on left"
500 except TypeError:
501 pass
502 try:
503 self.set - self.other
504 assert 0, "Symmetric difference with non-set on right"
505 except TypeError:
506 pass
507
508#------------------------------------------------------------------------------
509
510class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
511 def setUp(self):
512 self.set = Set((1, 2, 3))
513 self.other = 19
514
515#------------------------------------------------------------------------------
516
517class TestOnlySetsDict(TestOnlySetsInBinaryOps):
518 def setUp(self):
519 self.set = Set((1, 2, 3))
520 self.other = {1:2, 3:4}
521
522#------------------------------------------------------------------------------
523
524class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
525 def setUp(self):
526 self.set = Set((1, 2, 3))
527 self.other = operator.add
528
529#==============================================================================
530
531class TestCopying(unittest.TestCase):
532
533 def test_copy(self):
534 dup = self.set.copy()
535 dup_list = list(dup); dup_list.sort()
536 set_list = list(self.set); set_list.sort()
537 assert len(dup_list) == len(set_list), "Unequal lengths after copy"
538 for i in range(len(dup_list)):
539 assert dup_list[i] is set_list[i], "Non-identical items after copy"
540
541 def test_deep_copy(self):
542 dup = copy.deepcopy(self.set)
543 ##print type(dup), `dup`
544 dup_list = list(dup); dup_list.sort()
545 set_list = list(self.set); set_list.sort()
546 assert len(dup_list) == len(set_list), "Unequal lengths after deep copy"
547 for i in range(len(dup_list)):
548 assert dup_list[i] == set_list[i], "Unequal items after deep copy"
549
550#------------------------------------------------------------------------------
551
552class TestCopyingEmpty(TestCopying):
553 def setUp(self):
554 self.set = Set()
555
556#------------------------------------------------------------------------------
557
558class TestCopyingSingleton(TestCopying):
559 def setUp(self):
560 self.set = Set(["hello"])
561
562#------------------------------------------------------------------------------
563
564class TestCopyingTriple(TestCopying):
565 def setUp(self):
566 self.set = Set(["zero", 0, None])
567
568#------------------------------------------------------------------------------
569
570class TestCopyingTuple(TestCopying):
571 def setUp(self):
572 self.set = Set([(1, 2)])
573
574#------------------------------------------------------------------------------
575
576class TestCopyingNested(TestCopying):
577 def setUp(self):
578 self.set = Set([((1, 2), (3, 4))])
579
580#==============================================================================
581
582def makeAllTests():
583 suite = unittest.TestSuite()
Raymond Hettingerc3e61e52002-08-21 06:38:44 +0000584 suite.addTest(unittest.makeSuite(TestSetOfSets))
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000585 suite.addTest(unittest.makeSuite(TestBasicOpsEmpty))
586 suite.addTest(unittest.makeSuite(TestBasicOpsSingleton))
587 suite.addTest(unittest.makeSuite(TestBasicOpsTuple))
588 suite.addTest(unittest.makeSuite(TestBasicOpsTriple))
589 suite.addTest(unittest.makeSuite(TestBinaryOps))
590 suite.addTest(unittest.makeSuite(TestUpdateOps))
591 suite.addTest(unittest.makeSuite(TestMutate))
592 suite.addTest(unittest.makeSuite(TestSubsetEqualEmpty))
593 suite.addTest(unittest.makeSuite(TestSubsetEqualNonEmpty))
594 suite.addTest(unittest.makeSuite(TestSubsetEmptyNonEmpty))
595 suite.addTest(unittest.makeSuite(TestSubsetPartial))
596 suite.addTest(unittest.makeSuite(TestSubsetNonOverlap))
597 suite.addTest(unittest.makeSuite(TestOnlySetsNumeric))
598 suite.addTest(unittest.makeSuite(TestOnlySetsDict))
599 suite.addTest(unittest.makeSuite(TestOnlySetsOperator))
600 suite.addTest(unittest.makeSuite(TestCopyingEmpty))
601 suite.addTest(unittest.makeSuite(TestCopyingSingleton))
602 suite.addTest(unittest.makeSuite(TestCopyingTriple))
603 suite.addTest(unittest.makeSuite(TestCopyingTuple))
604 suite.addTest(unittest.makeSuite(TestCopyingNested))
605 return suite
606
607#------------------------------------------------------------------------------
608
609def test_main():
610 suite = makeAllTests()
611 test_support.run_suite(suite)
612
613if __name__ == "__main__":
614 test_main()