3 import unittest
, operator
, copy
, pickle
4 from sets
import Set
, ImmutableSet
5 from test
import test_support
9 #==============================================================================
11 class TestBasicOps(unittest
.TestCase
):
14 if self
.repr is not None:
15 self
.assertEqual(`self
.set`
, self
.repr)
17 def test_length(self
):
18 self
.assertEqual(len(self
.set), self
.length
)
20 def test_self_equality(self
):
21 self
.assertEqual(self
.set, self
.set)
23 def test_equivalent_equality(self
):
24 self
.assertEqual(self
.set, self
.dup
)
27 self
.assertEqual(self
.set.copy(), self
.dup
)
29 def test_self_union(self
):
30 result
= self
.set | self
.set
31 self
.assertEqual(result
, self
.dup
)
33 def test_empty_union(self
):
34 result
= self
.set | empty_set
35 self
.assertEqual(result
, self
.dup
)
37 def test_union_empty(self
):
38 result
= empty_set | self
.set
39 self
.assertEqual(result
, self
.dup
)
41 def test_self_intersection(self
):
42 result
= self
.set & self
.set
43 self
.assertEqual(result
, self
.dup
)
45 def test_empty_intersection(self
):
46 result
= self
.set & empty_set
47 self
.assertEqual(result
, empty_set
)
49 def test_intersection_empty(self
):
50 result
= empty_set
& self
.set
51 self
.assertEqual(result
, empty_set
)
53 def test_self_symmetric_difference(self
):
54 result
= self
.set ^ self
.set
55 self
.assertEqual(result
, empty_set
)
57 def checkempty_symmetric_difference(self
):
58 result
= self
.set ^ empty_set
59 self
.assertEqual(result
, self
.set)
61 def test_self_difference(self
):
62 result
= self
.set - self
.set
63 self
.assertEqual(result
, empty_set
)
65 def test_empty_difference(self
):
66 result
= self
.set - empty_set
67 self
.assertEqual(result
, self
.dup
)
69 def test_empty_difference_rev(self
):
70 result
= empty_set
- self
.set
71 self
.assertEqual(result
, empty_set
)
73 def test_iteration(self
):
75 self
.assert_(v
in self
.values
)
77 def test_pickling(self
):
78 p
= pickle
.dumps(self
.set)
79 copy
= pickle
.loads(p
)
80 self
.assertEqual(self
.set, copy
,
81 "%s != %s" % (self
.set, copy
))
83 #------------------------------------------------------------------------------
85 class TestBasicOpsEmpty(TestBasicOps
):
87 self
.case
= "empty set"
89 self
.set = Set(self
.values
)
90 self
.dup
= Set(self
.values
)
94 #------------------------------------------------------------------------------
96 class TestBasicOpsSingleton(TestBasicOps
):
98 self
.case
= "unit set (number)"
100 self
.set = Set(self
.values
)
101 self
.dup
= Set(self
.values
)
103 self
.repr = "Set([3])"
106 self
.failUnless(3 in self
.set)
108 def test_not_in(self
):
109 self
.failUnless(2 not in self
.set)
111 #------------------------------------------------------------------------------
113 class TestBasicOpsTuple(TestBasicOps
):
115 self
.case
= "unit set (tuple)"
116 self
.values
= [(0, "zero")]
117 self
.set = Set(self
.values
)
118 self
.dup
= Set(self
.values
)
120 self
.repr = "Set([(0, 'zero')])"
123 self
.failUnless((0, "zero") in self
.set)
125 def test_not_in(self
):
126 self
.failUnless(9 not in self
.set)
128 #------------------------------------------------------------------------------
130 class TestBasicOpsTriple(TestBasicOps
):
132 self
.case
= "triple set"
133 self
.values
= [0, "zero", operator
.add
]
134 self
.set = Set(self
.values
)
135 self
.dup
= Set(self
.values
)
139 #==============================================================================
148 class TestExceptionPropagation(unittest
.TestCase
):
149 """SF 628246: Set constructor should not trap iterator TypeErrors"""
151 def test_instanceWithException(self
):
152 self
.assertRaises(TypeError, Set
, baditer())
154 def test_instancesWithoutException(self
):
155 # All of these iterables should load without exception.
158 Set({'one':1, 'two':2, 'three':3})
163 #==============================================================================
165 class TestSetOfSets(unittest
.TestCase
):
166 def test_constructor(self
):
169 element
= outer
.pop()
170 self
.assertEqual(type(element
), ImmutableSet
)
171 outer
.add(inner
) # Rebuild set of sets with .add method
173 self
.assertEqual(outer
, Set()) # Verify that remove worked
174 outer
.discard(inner
) # Absence of KeyError indicates working fine
176 #==============================================================================
178 class TestBinaryOps(unittest
.TestCase
):
180 self
.set = Set((2, 4, 6))
182 def test_eq(self
): # SF bug 643115
183 self
.assertEqual(self
.set, Set({2:1,4:3,6:5}))
185 def test_union_subset(self
):
186 result
= self
.set |
Set([2])
187 self
.assertEqual(result
, Set((2, 4, 6)))
189 def test_union_superset(self
):
190 result
= self
.set |
Set([2, 4, 6, 8])
191 self
.assertEqual(result
, Set([2, 4, 6, 8]))
193 def test_union_overlap(self
):
194 result
= self
.set |
Set([3, 4, 5])
195 self
.assertEqual(result
, Set([2, 3, 4, 5, 6]))
197 def test_union_non_overlap(self
):
198 result
= self
.set |
Set([8])
199 self
.assertEqual(result
, Set([2, 4, 6, 8]))
201 def test_intersection_subset(self
):
202 result
= self
.set & Set((2, 4))
203 self
.assertEqual(result
, Set((2, 4)))
205 def test_intersection_superset(self
):
206 result
= self
.set & Set([2, 4, 6, 8])
207 self
.assertEqual(result
, Set([2, 4, 6]))
209 def test_intersection_overlap(self
):
210 result
= self
.set & Set([3, 4, 5])
211 self
.assertEqual(result
, Set([4]))
213 def test_intersection_non_overlap(self
):
214 result
= self
.set & Set([8])
215 self
.assertEqual(result
, empty_set
)
217 def test_sym_difference_subset(self
):
218 result
= self
.set ^
Set((2, 4))
219 self
.assertEqual(result
, Set([6]))
221 def test_sym_difference_superset(self
):
222 result
= self
.set ^
Set((2, 4, 6, 8))
223 self
.assertEqual(result
, Set([8]))
225 def test_sym_difference_overlap(self
):
226 result
= self
.set ^
Set((3, 4, 5))
227 self
.assertEqual(result
, Set([2, 3, 5, 6]))
229 def test_sym_difference_non_overlap(self
):
230 result
= self
.set ^
Set([8])
231 self
.assertEqual(result
, Set([2, 4, 6, 8]))
234 a
, b
= Set('a'), Set('b')
235 self
.assertRaises(TypeError, cmp, a
, b
)
237 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
238 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
239 # which Python thinks is good enough to synthesize a cmp() result
240 # without calling __cmp__.
241 self
.assertEqual(cmp(a
, a
), 0)
243 self
.assertRaises(TypeError, cmp, a
, 12)
244 self
.assertRaises(TypeError, cmp, "abc", a
)
246 #==============================================================================
248 class TestUpdateOps(unittest
.TestCase
):
250 self
.set = Set((2, 4, 6))
252 def test_union_subset(self
):
254 self
.assertEqual(self
.set, Set((2, 4, 6)))
256 def test_union_superset(self
):
257 self
.set |
= Set([2, 4, 6, 8])
258 self
.assertEqual(self
.set, Set([2, 4, 6, 8]))
260 def test_union_overlap(self
):
261 self
.set |
= Set([3, 4, 5])
262 self
.assertEqual(self
.set, Set([2, 3, 4, 5, 6]))
264 def test_union_non_overlap(self
):
266 self
.assertEqual(self
.set, Set([2, 4, 6, 8]))
268 def test_union_method_call(self
):
269 self
.set.union_update(Set([3, 4, 5]))
270 self
.assertEqual(self
.set, Set([2, 3, 4, 5, 6]))
272 def test_intersection_subset(self
):
273 self
.set &= Set((2, 4))
274 self
.assertEqual(self
.set, Set((2, 4)))
276 def test_intersection_superset(self
):
277 self
.set &= Set([2, 4, 6, 8])
278 self
.assertEqual(self
.set, Set([2, 4, 6]))
280 def test_intersection_overlap(self
):
281 self
.set &= Set([3, 4, 5])
282 self
.assertEqual(self
.set, Set([4]))
284 def test_intersection_non_overlap(self
):
286 self
.assertEqual(self
.set, empty_set
)
288 def test_intersection_method_call(self
):
289 self
.set.intersection_update(Set([3, 4, 5]))
290 self
.assertEqual(self
.set, Set([4]))
292 def test_sym_difference_subset(self
):
293 self
.set ^
= Set((2, 4))
294 self
.assertEqual(self
.set, Set([6]))
296 def test_sym_difference_superset(self
):
297 self
.set ^
= Set((2, 4, 6, 8))
298 self
.assertEqual(self
.set, Set([8]))
300 def test_sym_difference_overlap(self
):
301 self
.set ^
= Set((3, 4, 5))
302 self
.assertEqual(self
.set, Set([2, 3, 5, 6]))
304 def test_sym_difference_non_overlap(self
):
306 self
.assertEqual(self
.set, Set([2, 4, 6, 8]))
308 def test_sym_difference_method_call(self
):
309 self
.set.symmetric_difference_update(Set([3, 4, 5]))
310 self
.assertEqual(self
.set, Set([2, 3, 5, 6]))
312 def test_difference_subset(self
):
313 self
.set -= Set((2, 4))
314 self
.assertEqual(self
.set, Set([6]))
316 def test_difference_superset(self
):
317 self
.set -= Set((2, 4, 6, 8))
318 self
.assertEqual(self
.set, Set([]))
320 def test_difference_overlap(self
):
321 self
.set -= Set((3, 4, 5))
322 self
.assertEqual(self
.set, Set([2, 6]))
324 def test_difference_non_overlap(self
):
326 self
.assertEqual(self
.set, Set([2, 4, 6]))
328 def test_difference_method_call(self
):
329 self
.set.difference_update(Set([3, 4, 5]))
330 self
.assertEqual(self
.set, Set([2, 6]))
332 #==============================================================================
334 class TestMutate(unittest
.TestCase
):
336 self
.values
= ["a", "b", "c"]
337 self
.set = Set(self
.values
)
339 def test_add_present(self
):
341 self
.assertEqual(self
.set, Set("abc"))
343 def test_add_absent(self
):
345 self
.assertEqual(self
.set, Set("abcd"))
347 def test_add_until_full(self
):
350 for v
in self
.values
:
353 self
.assertEqual(len(tmp
), expected_len
)
354 self
.assertEqual(tmp
, self
.set)
356 def test_remove_present(self
):
358 self
.assertEqual(self
.set, Set("ac"))
360 def test_remove_absent(self
):
363 self
.fail("Removing missing element should have raised LookupError")
367 def test_remove_until_empty(self
):
368 expected_len
= len(self
.set)
369 for v
in self
.values
:
372 self
.assertEqual(len(self
.set), expected_len
)
374 def test_discard_present(self
):
375 self
.set.discard("c")
376 self
.assertEqual(self
.set, Set("ab"))
378 def test_discard_absent(self
):
379 self
.set.discard("d")
380 self
.assertEqual(self
.set, Set("abc"))
382 def test_clear(self
):
384 self
.assertEqual(len(self
.set), 0)
389 popped
[self
.set.pop()] = None
390 self
.assertEqual(len(popped
), len(self
.values
))
391 for v
in self
.values
:
392 self
.failUnless(v
in popped
)
394 def test_update_empty_tuple(self
):
395 self
.set.union_update(())
396 self
.assertEqual(self
.set, Set(self
.values
))
398 def test_update_unit_tuple_overlap(self
):
399 self
.set.union_update(("a",))
400 self
.assertEqual(self
.set, Set(self
.values
))
402 def test_update_unit_tuple_non_overlap(self
):
403 self
.set.union_update(("a", "z"))
404 self
.assertEqual(self
.set, Set(self
.values
+ ["z"]))
406 #==============================================================================
408 class TestSubsets(unittest
.TestCase
):
410 case2method
= {"<=": "issubset",
414 reverse
= {"==": "==",
422 def test_issubset(self
):
425 for case
in "!=", "==", "<", "<=", ">", ">=":
426 expected
= case
in self
.cases
427 # Test the binary infix spelling.
428 result
= eval("x" + case
+ "y", locals())
429 self
.assertEqual(result
, expected
)
430 # Test the "friendly" method-name spelling, if one exists.
431 if case
in TestSubsets
.case2method
:
432 method
= getattr(x
, TestSubsets
.case2method
[case
])
434 self
.assertEqual(result
, expected
)
436 # Now do the same for the operands reversed.
437 rcase
= TestSubsets
.reverse
[case
]
438 result
= eval("y" + rcase
+ "x", locals())
439 self
.assertEqual(result
, expected
)
440 if rcase
in TestSubsets
.case2method
:
441 method
= getattr(y
, TestSubsets
.case2method
[rcase
])
443 self
.assertEqual(result
, expected
)
444 #------------------------------------------------------------------------------
446 class TestSubsetEqualEmpty(TestSubsets
):
450 cases
= "==", "<=", ">="
452 #------------------------------------------------------------------------------
454 class TestSubsetEqualNonEmpty(TestSubsets
):
458 cases
= "==", "<=", ">="
460 #------------------------------------------------------------------------------
462 class TestSubsetEmptyNonEmpty(TestSubsets
):
465 name
= "one empty, one non-empty"
466 cases
= "!=", "<", "<="
468 #------------------------------------------------------------------------------
470 class TestSubsetPartial(TestSubsets
):
473 name
= "one a non-empty proper subset of other"
474 cases
= "!=", "<", "<="
476 #------------------------------------------------------------------------------
478 class TestSubsetNonOverlap(TestSubsets
):
481 name
= "neither empty, neither contains"
484 #==============================================================================
486 class TestOnlySetsInBinaryOps(unittest
.TestCase
):
488 def test_eq_ne(self
):
489 # Unlike the others, this is testing that == and != *are* allowed.
490 self
.assertEqual(self
.other
== self
.set, False)
491 self
.assertEqual(self
.set == self
.other
, False)
492 self
.assertEqual(self
.other
!= self
.set, True)
493 self
.assertEqual(self
.set != self
.other
, True)
495 def test_ge_gt_le_lt(self
):
496 self
.assertRaises(TypeError, lambda: self
.set < self
.other
)
497 self
.assertRaises(TypeError, lambda: self
.set <= self
.other
)
498 self
.assertRaises(TypeError, lambda: self
.set > self
.other
)
499 self
.assertRaises(TypeError, lambda: self
.set >= self
.other
)
501 self
.assertRaises(TypeError, lambda: self
.other
< self
.set)
502 self
.assertRaises(TypeError, lambda: self
.other
<= self
.set)
503 self
.assertRaises(TypeError, lambda: self
.other
> self
.set)
504 self
.assertRaises(TypeError, lambda: self
.other
>= self
.set)
506 def test_union_update_operator(self
):
508 self
.set |
= self
.other
512 self
.fail("expected TypeError")
514 def test_union_update(self
):
515 if self
.otherIsIterable
:
516 self
.set.union_update(self
.other
)
518 self
.assertRaises(TypeError, self
.set.union_update
, self
.other
)
520 def test_union(self
):
521 self
.assertRaises(TypeError, lambda: self
.set | self
.other
)
522 self
.assertRaises(TypeError, lambda: self
.other | self
.set)
523 if self
.otherIsIterable
:
524 self
.set.union(self
.other
)
526 self
.assertRaises(TypeError, self
.set.union
, self
.other
)
528 def test_intersection_update_operator(self
):
530 self
.set &= self
.other
534 self
.fail("expected TypeError")
536 def test_intersection_update(self
):
537 if self
.otherIsIterable
:
538 self
.set.intersection_update(self
.other
)
540 self
.assertRaises(TypeError,
541 self
.set.intersection_update
,
544 def test_intersection(self
):
545 self
.assertRaises(TypeError, lambda: self
.set & self
.other
)
546 self
.assertRaises(TypeError, lambda: self
.other
& self
.set)
547 if self
.otherIsIterable
:
548 self
.set.intersection(self
.other
)
550 self
.assertRaises(TypeError, self
.set.intersection
, self
.other
)
552 def test_sym_difference_update_operator(self
):
554 self
.set ^
= self
.other
558 self
.fail("expected TypeError")
560 def test_sym_difference_update(self
):
561 if self
.otherIsIterable
:
562 self
.set.symmetric_difference_update(self
.other
)
564 self
.assertRaises(TypeError,
565 self
.set.symmetric_difference_update
,
568 def test_sym_difference(self
):
569 self
.assertRaises(TypeError, lambda: self
.set ^ self
.other
)
570 self
.assertRaises(TypeError, lambda: self
.other ^ self
.set)
571 if self
.otherIsIterable
:
572 self
.set.symmetric_difference(self
.other
)
574 self
.assertRaises(TypeError, self
.set.symmetric_difference
, self
.other
)
576 def test_difference_update_operator(self
):
578 self
.set -= self
.other
582 self
.fail("expected TypeError")
584 def test_difference_update(self
):
585 if self
.otherIsIterable
:
586 self
.set.difference_update(self
.other
)
588 self
.assertRaises(TypeError,
589 self
.set.difference_update
,
592 def test_difference(self
):
593 self
.assertRaises(TypeError, lambda: self
.set - self
.other
)
594 self
.assertRaises(TypeError, lambda: self
.other
- self
.set)
595 if self
.otherIsIterable
:
596 self
.set.difference(self
.other
)
598 self
.assertRaises(TypeError, self
.set.difference
, self
.other
)
599 #------------------------------------------------------------------------------
601 class TestOnlySetsNumeric(TestOnlySetsInBinaryOps
):
603 self
.set = Set((1, 2, 3))
605 self
.otherIsIterable
= False
607 #------------------------------------------------------------------------------
609 class TestOnlySetsDict(TestOnlySetsInBinaryOps
):
611 self
.set = Set((1, 2, 3))
612 self
.other
= {1:2, 3:4}
613 self
.otherIsIterable
= True
615 #------------------------------------------------------------------------------
617 class TestOnlySetsOperator(TestOnlySetsInBinaryOps
):
619 self
.set = Set((1, 2, 3))
620 self
.other
= operator
.add
621 self
.otherIsIterable
= False
623 #------------------------------------------------------------------------------
625 class TestOnlySetsTuple(TestOnlySetsInBinaryOps
):
627 self
.set = Set((1, 2, 3))
628 self
.other
= (2, 4, 6)
629 self
.otherIsIterable
= True
631 #------------------------------------------------------------------------------
633 class TestOnlySetsString(TestOnlySetsInBinaryOps
):
635 self
.set = Set((1, 2, 3))
637 self
.otherIsIterable
= True
639 #------------------------------------------------------------------------------
641 class TestOnlySetsGenerator(TestOnlySetsInBinaryOps
):
644 for i
in xrange(0, 10, 2):
646 self
.set = Set((1, 2, 3))
648 self
.otherIsIterable
= True
650 #==============================================================================
652 class TestCopying(unittest
.TestCase
):
655 dup
= self
.set.copy()
656 dup_list
= list(dup
); dup_list
.sort()
657 set_list
= list(self
.set); set_list
.sort()
658 self
.assertEqual(len(dup_list
), len(set_list
))
659 for i
in range(len(dup_list
)):
660 self
.failUnless(dup_list
[i
] is set_list
[i
])
662 def test_deep_copy(self
):
663 dup
= copy
.deepcopy(self
.set)
664 ##print type(dup), `dup`
665 dup_list
= list(dup
); dup_list
.sort()
666 set_list
= list(self
.set); set_list
.sort()
667 self
.assertEqual(len(dup_list
), len(set_list
))
668 for i
in range(len(dup_list
)):
669 self
.assertEqual(dup_list
[i
], set_list
[i
])
671 #------------------------------------------------------------------------------
673 class TestCopyingEmpty(TestCopying
):
677 #------------------------------------------------------------------------------
679 class TestCopyingSingleton(TestCopying
):
681 self
.set = Set(["hello"])
683 #------------------------------------------------------------------------------
685 class TestCopyingTriple(TestCopying
):
687 self
.set = Set(["zero", 0, None])
689 #------------------------------------------------------------------------------
691 class TestCopyingTuple(TestCopying
):
693 self
.set = Set([(1, 2)])
695 #------------------------------------------------------------------------------
697 class TestCopyingNested(TestCopying
):
699 self
.set = Set([((1, 2), (3, 4))])
701 #==============================================================================
703 class TestIdentities(unittest
.TestCase
):
705 self
.a
= Set('abracadabra')
706 self
.b
= Set('alacazam')
708 def test_binopsVsSubsets(self
):
709 a
, b
= self
.a
, self
.b
710 self
.assert_(a
- b
< a
)
711 self
.assert_(b
- a
< b
)
712 self
.assert_(a
& b
< a
)
713 self
.assert_(a
& b
< b
)
714 self
.assert_(a | b
> a
)
715 self
.assert_(a | b
> b
)
716 self
.assert_(a ^ b
< a | b
)
718 def test_commutativity(self
):
719 a
, b
= self
.a
, self
.b
720 self
.assertEqual(a
&b
, b
&a
)
721 self
.assertEqual(a|b
, b|a
)
722 self
.assertEqual(a^b
, b^a
)
724 self
.assertNotEqual(a
-b
, b
-a
)
726 def test_summations(self
):
727 # check that sums of parts equal the whole
728 a
, b
= self
.a
, self
.b
729 self
.assertEqual((a
-b
)|
(a
&b
)|
(b
-a
), a|b
)
730 self
.assertEqual((a
&b
)|
(a^b
), a|b
)
731 self
.assertEqual(a|
(b
-a
), a|b
)
732 self
.assertEqual((a
-b
)|b
, a|b
)
733 self
.assertEqual((a
-b
)|
(a
&b
), a
)
734 self
.assertEqual((b
-a
)|
(a
&b
), b
)
735 self
.assertEqual((a
-b
)|
(b
-a
), a^b
)
737 def test_exclusion(self
):
738 # check that inverse operations show non-overlap
739 a
, b
, zero
= self
.a
, self
.b
, Set()
740 self
.assertEqual((a
-b
)&b
, zero
)
741 self
.assertEqual((b
-a
)&a
, zero
)
742 self
.assertEqual((a
&b
)&(a^b
), zero
)
744 #==============================================================================
747 Example from the Library Reference: Doc/lib/libsets.tex
749 >>> from sets import Set as Base # override _repr to get sorted output
752 ... return Base._repr(self, sorted=True)
753 >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
754 >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
755 >>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])
756 >>> employees = engineers | programmers | managers # union
757 >>> engineering_management = engineers & managers # intersection
758 >>> fulltime_management = managers - engineers - programmers # difference
759 >>> engineers.add('Marvin')
761 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
762 >>> employees.issuperset(engineers) # superset test
764 >>> employees.union_update(engineers) # update from another set
765 >>> employees.issuperset(engineers)
767 >>> for group in [engineers, programmers, managers, employees]:
768 ... group.discard('Susan') # unconditionally remove element
771 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
772 Set(['Jack', 'Janice', 'Sam'])
773 Set(['Jack', 'Jane', 'Zack'])
774 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin', 'Sam', 'Zack'])
777 #==============================================================================
779 __test__
= {'libreftest' : libreftest
}
781 def test_main(verbose
=None):
782 from test
import test_sets
783 test_support
.run_unittest(
785 TestExceptionPropagation
,
787 TestBasicOpsSingleton
,
793 TestSubsetEqualEmpty
,
794 TestSubsetEqualNonEmpty
,
795 TestSubsetEmptyNonEmpty
,
797 TestSubsetNonOverlap
,
800 TestOnlySetsOperator
,
803 TestOnlySetsGenerator
,
805 TestCopyingSingleton
,
811 test_support
.run_doctest(test_sets
, verbose
)
813 if __name__
== "__main__":
814 test_main(verbose
=True)