test_whitespace_eater_unicode(): Make this test Python 2.1 compatible.
[python/dscho.git] / Lib / test / test_sets.py
blobd5c886a72801e37cfe944c64a2963a6290fbe965
1 #!/usr/bin/env python
3 import unittest, operator, copy, pickle
4 from sets import Set, ImmutableSet
5 from test import test_support
7 empty_set = Set()
9 #==============================================================================
11 class TestBasicOps(unittest.TestCase):
13 def test_repr(self):
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)
26 def test_copy(self):
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):
74 for v in self.set:
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):
86 def setUp(self):
87 self.case = "empty set"
88 self.values = []
89 self.set = Set(self.values)
90 self.dup = Set(self.values)
91 self.length = 0
92 self.repr = "Set([])"
94 #------------------------------------------------------------------------------
96 class TestBasicOpsSingleton(TestBasicOps):
97 def setUp(self):
98 self.case = "unit set (number)"
99 self.values = [3]
100 self.set = Set(self.values)
101 self.dup = Set(self.values)
102 self.length = 1
103 self.repr = "Set([3])"
105 def test_in(self):
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):
114 def setUp(self):
115 self.case = "unit set (tuple)"
116 self.values = [(0, "zero")]
117 self.set = Set(self.values)
118 self.dup = Set(self.values)
119 self.length = 1
120 self.repr = "Set([(0, 'zero')])"
122 def test_in(self):
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):
131 def setUp(self):
132 self.case = "triple set"
133 self.values = [0, "zero", operator.add]
134 self.set = Set(self.values)
135 self.dup = Set(self.values)
136 self.length = 3
137 self.repr = None
139 #==============================================================================
141 def baditer():
142 raise TypeError
143 yield True
145 def gooditer():
146 yield True
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."""
156 Set([1,2,3])
157 Set((1,2,3))
158 Set({'one':1, 'two':2, 'three':3})
159 Set(xrange(3))
160 Set('abc')
161 Set(gooditer())
163 #==============================================================================
165 class TestSetOfSets(unittest.TestCase):
166 def test_constructor(self):
167 inner = Set([1])
168 outer = Set([inner])
169 element = outer.pop()
170 self.assertEqual(type(element), ImmutableSet)
171 outer.add(inner) # Rebuild set of sets with .add method
172 outer.remove(inner)
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):
179 def setUp(self):
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]))
233 def test_cmp(self):
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):
249 def setUp(self):
250 self.set = Set((2, 4, 6))
252 def test_union_subset(self):
253 self.set |= Set([2])
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):
265 self.set |= Set([8])
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):
285 self.set &= Set([8])
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):
305 self.set ^= Set([8])
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):
325 self.set -= Set([8])
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):
335 def setUp(self):
336 self.values = ["a", "b", "c"]
337 self.set = Set(self.values)
339 def test_add_present(self):
340 self.set.add("c")
341 self.assertEqual(self.set, Set("abc"))
343 def test_add_absent(self):
344 self.set.add("d")
345 self.assertEqual(self.set, Set("abcd"))
347 def test_add_until_full(self):
348 tmp = Set()
349 expected_len = 0
350 for v in self.values:
351 tmp.add(v)
352 expected_len += 1
353 self.assertEqual(len(tmp), expected_len)
354 self.assertEqual(tmp, self.set)
356 def test_remove_present(self):
357 self.set.remove("b")
358 self.assertEqual(self.set, Set("ac"))
360 def test_remove_absent(self):
361 try:
362 self.set.remove("d")
363 self.fail("Removing missing element should have raised LookupError")
364 except LookupError:
365 pass
367 def test_remove_until_empty(self):
368 expected_len = len(self.set)
369 for v in self.values:
370 self.set.remove(v)
371 expected_len -= 1
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):
383 self.set.clear()
384 self.assertEqual(len(self.set), 0)
386 def test_pop(self):
387 popped = {}
388 while self.set:
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.update(())
396 self.assertEqual(self.set, Set(self.values))
398 def test_update_unit_tuple_overlap(self):
399 self.set.update(("a",))
400 self.assertEqual(self.set, Set(self.values))
402 def test_update_unit_tuple_non_overlap(self):
403 self.set.update(("a", "z"))
404 self.assertEqual(self.set, Set(self.values + ["z"]))
406 #==============================================================================
408 class TestSubsets(unittest.TestCase):
410 case2method = {"<=": "issubset",
411 ">=": "issuperset",
414 reverse = {"==": "==",
415 "!=": "!=",
416 "<": ">",
417 ">": "<",
418 "<=": ">=",
419 ">=": "<=",
422 def test_issubset(self):
423 x = self.left
424 y = self.right
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])
433 result = method(y)
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])
442 result = method(x)
443 self.assertEqual(result, expected)
444 #------------------------------------------------------------------------------
446 class TestSubsetEqualEmpty(TestSubsets):
447 left = Set()
448 right = Set()
449 name = "both empty"
450 cases = "==", "<=", ">="
452 #------------------------------------------------------------------------------
454 class TestSubsetEqualNonEmpty(TestSubsets):
455 left = Set([1, 2])
456 right = Set([1, 2])
457 name = "equal pair"
458 cases = "==", "<=", ">="
460 #------------------------------------------------------------------------------
462 class TestSubsetEmptyNonEmpty(TestSubsets):
463 left = Set()
464 right = Set([1, 2])
465 name = "one empty, one non-empty"
466 cases = "!=", "<", "<="
468 #------------------------------------------------------------------------------
470 class TestSubsetPartial(TestSubsets):
471 left = Set([1])
472 right = Set([1, 2])
473 name = "one a non-empty proper subset of other"
474 cases = "!=", "<", "<="
476 #------------------------------------------------------------------------------
478 class TestSubsetNonOverlap(TestSubsets):
479 left = Set([1])
480 right = Set([2])
481 name = "neither empty, neither contains"
482 cases = "!="
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(self):
507 try:
508 self.set |= self.other
509 except TypeError:
510 pass
511 else:
512 self.fail("expected TypeError")
514 def test_union(self):
515 self.assertRaises(TypeError, lambda: self.set | self.other)
516 self.assertRaises(TypeError, lambda: self.other | self.set)
518 def test_intersection_update(self):
519 try:
520 self.set &= self.other
521 except TypeError:
522 pass
523 else:
524 self.fail("expected TypeError")
526 def test_intersection(self):
527 self.assertRaises(TypeError, lambda: self.set & self.other)
528 self.assertRaises(TypeError, lambda: self.other & self.set)
530 def test_sym_difference_update(self):
531 try:
532 self.set ^= self.other
533 except TypeError:
534 pass
535 else:
536 self.fail("expected TypeError")
538 def test_sym_difference(self):
539 self.assertRaises(TypeError, lambda: self.set ^ self.other)
540 self.assertRaises(TypeError, lambda: self.other ^ self.set)
542 def test_difference_update(self):
543 try:
544 self.set -= self.other
545 except TypeError:
546 pass
547 else:
548 self.fail("expected TypeError")
550 def test_difference(self):
551 self.assertRaises(TypeError, lambda: self.set - self.other)
552 self.assertRaises(TypeError, lambda: self.other - self.set)
554 #------------------------------------------------------------------------------
556 class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
557 def setUp(self):
558 self.set = Set((1, 2, 3))
559 self.other = 19
561 #------------------------------------------------------------------------------
563 class TestOnlySetsDict(TestOnlySetsInBinaryOps):
564 def setUp(self):
565 self.set = Set((1, 2, 3))
566 self.other = {1:2, 3:4}
568 #------------------------------------------------------------------------------
570 class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
571 def setUp(self):
572 self.set = Set((1, 2, 3))
573 self.other = operator.add
575 #==============================================================================
577 class TestCopying(unittest.TestCase):
579 def test_copy(self):
580 dup = self.set.copy()
581 dup_list = list(dup); dup_list.sort()
582 set_list = list(self.set); set_list.sort()
583 self.assertEqual(len(dup_list), len(set_list))
584 for i in range(len(dup_list)):
585 self.failUnless(dup_list[i] is set_list[i])
587 def test_deep_copy(self):
588 dup = copy.deepcopy(self.set)
589 ##print type(dup), `dup`
590 dup_list = list(dup); dup_list.sort()
591 set_list = list(self.set); set_list.sort()
592 self.assertEqual(len(dup_list), len(set_list))
593 for i in range(len(dup_list)):
594 self.assertEqual(dup_list[i], set_list[i])
596 #------------------------------------------------------------------------------
598 class TestCopyingEmpty(TestCopying):
599 def setUp(self):
600 self.set = Set()
602 #------------------------------------------------------------------------------
604 class TestCopyingSingleton(TestCopying):
605 def setUp(self):
606 self.set = Set(["hello"])
608 #------------------------------------------------------------------------------
610 class TestCopyingTriple(TestCopying):
611 def setUp(self):
612 self.set = Set(["zero", 0, None])
614 #------------------------------------------------------------------------------
616 class TestCopyingTuple(TestCopying):
617 def setUp(self):
618 self.set = Set([(1, 2)])
620 #------------------------------------------------------------------------------
622 class TestCopyingNested(TestCopying):
623 def setUp(self):
624 self.set = Set([((1, 2), (3, 4))])
626 #==============================================================================
628 libreftest = """
629 Example from the Library Reference: Doc/lib/libsets.tex
631 >>> from sets import Set as Base # override _repr to get sorted output
632 >>> class Set(Base):
633 ... def _repr(self):
634 ... return Base._repr(self, sorted=True)
635 >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
636 >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
637 >>> management = Set(['Jane', 'Jack', 'Susan', 'Zack'])
638 >>> employees = engineers | programmers | management # union
639 >>> engineering_management = engineers & programmers # intersection
640 >>> fulltime_management = management - engineers - programmers # difference
641 >>> engineers.add('Marvin')
642 >>> print engineers
643 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
644 >>> employees.issuperset(engineers) # superset test
645 False
646 >>> employees.update(engineers) # update from another set
647 >>> employees.issuperset(engineers)
648 True
649 >>> for group in [engineers, programmers, management, employees]:
650 ... group.discard('Susan') # unconditionally remove element
651 ... print group
653 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
654 Set(['Jack', 'Janice', 'Sam'])
655 Set(['Jack', 'Jane', 'Zack'])
656 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin', 'Sam', 'Zack'])
659 #==============================================================================
661 def makeAllTests():
662 suite = unittest.TestSuite()
663 for klass in (TestSetOfSets,
664 TestExceptionPropagation,
665 TestBasicOpsEmpty,
666 TestBasicOpsSingleton,
667 TestBasicOpsTuple,
668 TestBasicOpsTriple,
669 TestBinaryOps,
670 TestUpdateOps,
671 TestMutate,
672 TestSubsetEqualEmpty,
673 TestSubsetEqualNonEmpty,
674 TestSubsetEmptyNonEmpty,
675 TestSubsetPartial,
676 TestSubsetNonOverlap,
677 TestOnlySetsNumeric,
678 TestOnlySetsDict,
679 TestOnlySetsOperator,
680 TestCopyingEmpty,
681 TestCopyingSingleton,
682 TestCopyingTriple,
683 TestCopyingTuple,
684 TestCopyingNested,
686 suite.addTest(unittest.makeSuite(klass))
687 return suite
689 #------------------------------------------------------------------------------
691 __test__ = {'libreftest' : libreftest}
693 def test_main(verbose=None):
694 from test import test_sets
695 suite = makeAllTests()
696 test_support.run_suite(suite)
697 test_support.run_doctest(test_sets, verbose)
699 if __name__ == "__main__":
700 test_main(verbose=True)