blob: 1edb2dd999381e08a0c796aca4816d00d0bcd59c [file] [log] [blame]
Raymond Hettingera690a992003-11-16 16:17:49 +00001import unittest
2from test import test_support
3import operator
4import copy
5import pickle
6
7class PassThru(Exception):
8 pass
9
10def check_pass_thru():
11 raise PassThru
12 yield 1
13
14class TestJointOps(unittest.TestCase):
15 # Tests common to both set and frozenset
16
17 def setUp(self):
18 self.word = word = 'simsalabim'
19 self.otherword = 'madagascar'
20 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
21 self.s = self.thetype(word)
22 self.d = dict.fromkeys(word)
23
24 def test_uniquification(self):
25 actual = list.sorted(self.s)
26 expected = list.sorted(self.d)
27 self.assertEqual(actual, expected)
28 self.assertRaises(PassThru, self.thetype, check_pass_thru())
29 self.assertRaises(TypeError, self.thetype, [[]])
30
31 def test_len(self):
32 self.assertEqual(len(self.s), len(self.d))
33
34 def test_contains(self):
35 for c in self.letters:
36 self.assertEqual(c in self.s, c in self.d)
37 self.assertRaises(TypeError, self.s.__contains__, [[]])
38
39 def test_copy(self):
40 dup = self.s.copy()
41 self.assertEqual(self.s, dup)
42 self.assertNotEqual(id(self.s), id(dup))
43
44 def test_union(self):
45 u = self.s.union(self.otherword)
46 for c in self.letters:
47 self.assertEqual(c in u, c in self.d or c in self.otherword)
48 self.assertEqual(type(u), self.thetype)
49 self.assertRaises(PassThru, self.s.union, check_pass_thru())
50 self.assertRaises(TypeError, self.s.union, [[]])
51
52 def test_or(self):
53 i = self.s.union(self.otherword)
54 self.assertEqual(self.s | set(self.otherword), i)
55 self.assertEqual(self.s | frozenset(self.otherword), i)
56 try:
57 self.s | self.otherword
58 except TypeError:
59 pass
60 else:
61 self.fail("s|t did not screen-out general iterables")
62
63 def test_intersection(self):
64 i = self.s.intersection(self.otherword)
65 for c in self.letters:
66 self.assertEqual(c in i, c in self.d and c in self.otherword)
67 self.assertEqual(type(i), self.thetype)
68 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
69
70 def test_and(self):
71 i = self.s.intersection(self.otherword)
72 self.assertEqual(self.s & set(self.otherword), i)
73 self.assertEqual(self.s & frozenset(self.otherword), i)
74 try:
75 self.s & self.otherword
76 except TypeError:
77 pass
78 else:
79 self.fail("s&t did not screen-out general iterables")
80
81 def test_difference(self):
82 i = self.s.difference(self.otherword)
83 for c in self.letters:
84 self.assertEqual(c in i, c in self.d and c not in self.otherword)
85 self.assertEqual(type(i), self.thetype)
86 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
87 self.assertRaises(TypeError, self.s.difference, [[]])
88
89 def test_sub(self):
90 i = self.s.difference(self.otherword)
91 self.assertEqual(self.s - set(self.otherword), i)
92 self.assertEqual(self.s - frozenset(self.otherword), i)
93 try:
94 self.s - self.otherword
95 except TypeError:
96 pass
97 else:
98 self.fail("s-t did not screen-out general iterables")
99
100 def test_symmetric_difference(self):
101 i = self.s.symmetric_difference(self.otherword)
102 for c in self.letters:
103 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
104 self.assertEqual(type(i), self.thetype)
105 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
106 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
107
108 def test_xor(self):
109 i = self.s.symmetric_difference(self.otherword)
110 self.assertEqual(self.s ^ set(self.otherword), i)
111 self.assertEqual(self.s ^ frozenset(self.otherword), i)
112 try:
113 self.s ^ self.otherword
114 except TypeError:
115 pass
116 else:
117 self.fail("s^t did not screen-out general iterables")
118
119 def test_equality(self):
120 self.assertEqual(self.s, set(self.word))
121 self.assertEqual(self.s, frozenset(self.word))
122 self.assertEqual(self.s == self.word, False)
123 self.assertNotEqual(self.s, set(self.otherword))
124 self.assertNotEqual(self.s, frozenset(self.otherword))
125 self.assertEqual(self.s != self.word, True)
126
127 def test_setOfFrozensets(self):
128 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
129 s = self.thetype(t)
130 self.assertEqual(len(s), 3)
131
132 def test_compare(self):
133 self.assertRaises(TypeError, self.s.__cmp__, self.s)
134
135 def test_sub_and_super(self):
136 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
137 self.assert_(p < q)
138 self.assert_(p <= q)
139 self.assert_(q <= q)
140 self.assert_(q > p)
141 self.assert_(q >= p)
142 self.failIf(q < r)
143 self.failIf(q <= r)
144 self.failIf(q > r)
145 self.failIf(q >= r)
146
147 def test_pickling(self):
148 p = pickle.dumps(self.s)
149 dup = pickle.loads(p)
150 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
151
152class TestSet(TestJointOps):
153 thetype = set
154
155 def test_hash(self):
156 self.assertRaises(TypeError, hash, self.s)
157
158 def test_clear(self):
159 self.s.clear()
160 self.assertEqual(self.s, set([]))
161
162 def test_add(self):
163 self.s.add('Q')
164 self.assert_('Q' in self.s)
165 self.assertRaises(TypeError, self.s.add, [])
166
167 def test_remove(self):
168 self.s.remove('a')
169 self.assert_('a' not in self.s)
170 self.assertRaises(KeyError, self.s.remove, 'Q')
171 self.assertRaises(TypeError, self.s.remove, [])
172
173 def test_discard(self):
174 self.s.discard('a')
175 self.assert_('a' not in self.s)
176 self.s.discard('Q')
177 self.assertRaises(TypeError, self.s.discard, [])
178
179 def test_pop(self):
180 for i in xrange(len(self.s)):
181 elem = self.s.pop()
182 self.assert_(elem not in self.s)
183 self.assertRaises(KeyError, self.s.pop)
184
185 def test_union_update(self):
186 retval = self.s.union_update(self.otherword)
187 self.assertEqual(retval, None)
188 for c in (self.word + self.otherword):
189 self.assert_(c in self.s)
190 self.assertRaises(PassThru, self.s.union_update, check_pass_thru())
191 self.assertRaises(TypeError, self.s.union_update, [[]])
192
193 def test_ior(self):
194 self.s |= set(self.otherword)
195 for c in (self.word + self.otherword):
196 self.assert_(c in self.s)
197
198 def test_intersection_update(self):
199 retval = self.s.intersection_update(self.otherword)
200 self.assertEqual(retval, None)
201 for c in (self.word + self.otherword):
202 if c in self.otherword and c in self.word:
203 self.assert_(c in self.s)
204 else:
205 self.assert_(c not in self.s)
206 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
207 self.assertRaises(TypeError, self.s.intersection_update, [[]])
208
209 def test_iand(self):
210 self.s &= set(self.otherword)
211 for c in (self.word + self.otherword):
212 if c in self.otherword and c in self.word:
213 self.assert_(c in self.s)
214 else:
215 self.assert_(c not in self.s)
216
217 def test_difference_update(self):
218 retval = self.s.difference_update(self.otherword)
219 self.assertEqual(retval, None)
220 for c in (self.word + self.otherword):
221 if c in self.word and c not in self.otherword:
222 self.assert_(c in self.s)
223 else:
224 self.assert_(c not in self.s)
225 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
226 self.assertRaises(TypeError, self.s.difference_update, [[]])
227
228 def test_isub(self):
229 self.s -= set(self.otherword)
230 for c in (self.word + self.otherword):
231 if c in self.word and c not in self.otherword:
232 self.assert_(c in self.s)
233 else:
234 self.assert_(c not in self.s)
235
236 def test_symmetric_difference_update(self):
237 retval = self.s.symmetric_difference_update(self.otherword)
238 self.assertEqual(retval, None)
239 for c in (self.word + self.otherword):
240 if (c in self.word) ^ (c in self.otherword):
241 self.assert_(c in self.s)
242 else:
243 self.assert_(c not in self.s)
244 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
245 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
246
247 def test_ixor(self):
248 self.s ^= set(self.otherword)
249 for c in (self.word + self.otherword):
250 if (c in self.word) ^ (c in self.otherword):
251 self.assert_(c in self.s)
252 else:
253 self.assert_(c not in self.s)
254
255
256class TestFrozenSet(TestJointOps):
257 thetype = frozenset
258
259 def test_hash(self):
260 self.assertEqual(hash(frozenset('abcdeb')), hash(frozenset('ebecda')))
261
262 def test_frozen_as_dictkey(self):
263 seq = range(10) + list('abcdefg') + ['apple']
264 key1 = frozenset(seq)
265 key2 = frozenset(reversed(seq))
266 self.assertEqual(key1, key2)
267 self.assertNotEqual(id(key1), id(key2))
268 d = {}
269 d[key1] = 42
270 self.assertEqual(d[key2], 42)
271
272 def test_hash_caching(self):
273 f = frozenset('abcdcda')
274 self.assertEqual(hash(f), hash(f))
275
276# Tests taken from test_sets.py =============================================
277
278empty_set = set()
279
280#==============================================================================
281
282class TestBasicOps(unittest.TestCase):
283
284 def test_repr(self):
285 if self.repr is not None:
286 self.assertEqual(`self.set`, self.repr)
287
288 def test_length(self):
289 self.assertEqual(len(self.set), self.length)
290
291 def test_self_equality(self):
292 self.assertEqual(self.set, self.set)
293
294 def test_equivalent_equality(self):
295 self.assertEqual(self.set, self.dup)
296
297 def test_copy(self):
298 self.assertEqual(self.set.copy(), self.dup)
299
300 def test_self_union(self):
301 result = self.set | self.set
302 self.assertEqual(result, self.dup)
303
304 def test_empty_union(self):
305 result = self.set | empty_set
306 self.assertEqual(result, self.dup)
307
308 def test_union_empty(self):
309 result = empty_set | self.set
310 self.assertEqual(result, self.dup)
311
312 def test_self_intersection(self):
313 result = self.set & self.set
314 self.assertEqual(result, self.dup)
315
316 def test_empty_intersection(self):
317 result = self.set & empty_set
318 self.assertEqual(result, empty_set)
319
320 def test_intersection_empty(self):
321 result = empty_set & self.set
322 self.assertEqual(result, empty_set)
323
324 def test_self_symmetric_difference(self):
325 result = self.set ^ self.set
326 self.assertEqual(result, empty_set)
327
328 def checkempty_symmetric_difference(self):
329 result = self.set ^ empty_set
330 self.assertEqual(result, self.set)
331
332 def test_self_difference(self):
333 result = self.set - self.set
334 self.assertEqual(result, empty_set)
335
336 def test_empty_difference(self):
337 result = self.set - empty_set
338 self.assertEqual(result, self.dup)
339
340 def test_empty_difference_rev(self):
341 result = empty_set - self.set
342 self.assertEqual(result, empty_set)
343
344 def test_iteration(self):
345 for v in self.set:
346 self.assert_(v in self.values)
347
348 def test_pickling(self):
349 p = pickle.dumps(self.set)
350 copy = pickle.loads(p)
351 self.assertEqual(self.set, copy,
352 "%s != %s" % (self.set, copy))
353
354#------------------------------------------------------------------------------
355
356class TestBasicOpsEmpty(TestBasicOps):
357 def setUp(self):
358 self.case = "empty set"
359 self.values = []
360 self.set = set(self.values)
361 self.dup = set(self.values)
362 self.length = 0
363 self.repr = "set([])"
364
365#------------------------------------------------------------------------------
366
367class TestBasicOpsSingleton(TestBasicOps):
368 def setUp(self):
369 self.case = "unit set (number)"
370 self.values = [3]
371 self.set = set(self.values)
372 self.dup = set(self.values)
373 self.length = 1
374 self.repr = "set([3])"
375
376 def test_in(self):
377 self.failUnless(3 in self.set)
378
379 def test_not_in(self):
380 self.failUnless(2 not in self.set)
381
382#------------------------------------------------------------------------------
383
384class TestBasicOpsTuple(TestBasicOps):
385 def setUp(self):
386 self.case = "unit set (tuple)"
387 self.values = [(0, "zero")]
388 self.set = set(self.values)
389 self.dup = set(self.values)
390 self.length = 1
391 self.repr = "set([(0, 'zero')])"
392
393 def test_in(self):
394 self.failUnless((0, "zero") in self.set)
395
396 def test_not_in(self):
397 self.failUnless(9 not in self.set)
398
399#------------------------------------------------------------------------------
400
401class TestBasicOpsTriple(TestBasicOps):
402 def setUp(self):
403 self.case = "triple set"
404 self.values = [0, "zero", operator.add]
405 self.set = set(self.values)
406 self.dup = set(self.values)
407 self.length = 3
408 self.repr = None
409
410#==============================================================================
411
412def baditer():
413 raise TypeError
414 yield True
415
416def gooditer():
417 yield True
418
419class TestExceptionPropagation(unittest.TestCase):
420 """SF 628246: Set constructor should not trap iterator TypeErrors"""
421
422 def test_instanceWithException(self):
423 self.assertRaises(TypeError, set, baditer())
424
425 def test_instancesWithoutException(self):
426 # All of these iterables should load without exception.
427 set([1,2,3])
428 set((1,2,3))
429 set({'one':1, 'two':2, 'three':3})
430 set(xrange(3))
431 set('abc')
432 set(gooditer())
433
434#==============================================================================
435
436class TestSetOfSets(unittest.TestCase):
437 def test_constructor(self):
438 inner = frozenset([1])
439 outer = set([inner])
440 element = outer.pop()
441 self.assertEqual(type(element), frozenset)
442 outer.add(inner) # Rebuild set of sets with .add method
443 outer.remove(inner)
444 self.assertEqual(outer, set()) # Verify that remove worked
445 outer.discard(inner) # Absence of KeyError indicates working fine
446
447#==============================================================================
448
449class TestBinaryOps(unittest.TestCase):
450 def setUp(self):
451 self.set = set((2, 4, 6))
452
453 def test_eq(self): # SF bug 643115
454 self.assertEqual(self.set, set({2:1,4:3,6:5}))
455
456 def test_union_subset(self):
457 result = self.set | set([2])
458 self.assertEqual(result, set((2, 4, 6)))
459
460 def test_union_superset(self):
461 result = self.set | set([2, 4, 6, 8])
462 self.assertEqual(result, set([2, 4, 6, 8]))
463
464 def test_union_overlap(self):
465 result = self.set | set([3, 4, 5])
466 self.assertEqual(result, set([2, 3, 4, 5, 6]))
467
468 def test_union_non_overlap(self):
469 result = self.set | set([8])
470 self.assertEqual(result, set([2, 4, 6, 8]))
471
472 def test_intersection_subset(self):
473 result = self.set & set((2, 4))
474 self.assertEqual(result, set((2, 4)))
475
476 def test_intersection_superset(self):
477 result = self.set & set([2, 4, 6, 8])
478 self.assertEqual(result, set([2, 4, 6]))
479
480 def test_intersection_overlap(self):
481 result = self.set & set([3, 4, 5])
482 self.assertEqual(result, set([4]))
483
484 def test_intersection_non_overlap(self):
485 result = self.set & set([8])
486 self.assertEqual(result, empty_set)
487
488 def test_sym_difference_subset(self):
489 result = self.set ^ set((2, 4))
490 self.assertEqual(result, set([6]))
491
492 def test_sym_difference_superset(self):
493 result = self.set ^ set((2, 4, 6, 8))
494 self.assertEqual(result, set([8]))
495
496 def test_sym_difference_overlap(self):
497 result = self.set ^ set((3, 4, 5))
498 self.assertEqual(result, set([2, 3, 5, 6]))
499
500 def test_sym_difference_non_overlap(self):
501 result = self.set ^ set([8])
502 self.assertEqual(result, set([2, 4, 6, 8]))
503
504 def test_cmp(self):
505 a, b = set('a'), set('b')
506 self.assertRaises(TypeError, cmp, a, b)
507
508 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
509 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
510 # which Python thinks is good enough to synthesize a cmp() result
511 # without calling __cmp__.
512 self.assertEqual(cmp(a, a), 0)
513
514 self.assertRaises(TypeError, cmp, a, 12)
515 self.assertRaises(TypeError, cmp, "abc", a)
516
517#==============================================================================
518
519class TestUpdateOps(unittest.TestCase):
520 def setUp(self):
521 self.set = set((2, 4, 6))
522
523 def test_union_subset(self):
524 self.set |= set([2])
525 self.assertEqual(self.set, set((2, 4, 6)))
526
527 def test_union_superset(self):
528 self.set |= set([2, 4, 6, 8])
529 self.assertEqual(self.set, set([2, 4, 6, 8]))
530
531 def test_union_overlap(self):
532 self.set |= set([3, 4, 5])
533 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
534
535 def test_union_non_overlap(self):
536 self.set |= set([8])
537 self.assertEqual(self.set, set([2, 4, 6, 8]))
538
539 def test_union_method_call(self):
540 self.set.union_update(set([3, 4, 5]))
541 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
542
543 def test_intersection_subset(self):
544 self.set &= set((2, 4))
545 self.assertEqual(self.set, set((2, 4)))
546
547 def test_intersection_superset(self):
548 self.set &= set([2, 4, 6, 8])
549 self.assertEqual(self.set, set([2, 4, 6]))
550
551 def test_intersection_overlap(self):
552 self.set &= set([3, 4, 5])
553 self.assertEqual(self.set, set([4]))
554
555 def test_intersection_non_overlap(self):
556 self.set &= set([8])
557 self.assertEqual(self.set, empty_set)
558
559 def test_intersection_method_call(self):
560 self.set.intersection_update(set([3, 4, 5]))
561 self.assertEqual(self.set, set([4]))
562
563 def test_sym_difference_subset(self):
564 self.set ^= set((2, 4))
565 self.assertEqual(self.set, set([6]))
566
567 def test_sym_difference_superset(self):
568 self.set ^= set((2, 4, 6, 8))
569 self.assertEqual(self.set, set([8]))
570
571 def test_sym_difference_overlap(self):
572 self.set ^= set((3, 4, 5))
573 self.assertEqual(self.set, set([2, 3, 5, 6]))
574
575 def test_sym_difference_non_overlap(self):
576 self.set ^= set([8])
577 self.assertEqual(self.set, set([2, 4, 6, 8]))
578
579 def test_sym_difference_method_call(self):
580 self.set.symmetric_difference_update(set([3, 4, 5]))
581 self.assertEqual(self.set, set([2, 3, 5, 6]))
582
583 def test_difference_subset(self):
584 self.set -= set((2, 4))
585 self.assertEqual(self.set, set([6]))
586
587 def test_difference_superset(self):
588 self.set -= set((2, 4, 6, 8))
589 self.assertEqual(self.set, set([]))
590
591 def test_difference_overlap(self):
592 self.set -= set((3, 4, 5))
593 self.assertEqual(self.set, set([2, 6]))
594
595 def test_difference_non_overlap(self):
596 self.set -= set([8])
597 self.assertEqual(self.set, set([2, 4, 6]))
598
599 def test_difference_method_call(self):
600 self.set.difference_update(set([3, 4, 5]))
601 self.assertEqual(self.set, set([2, 6]))
602
603#==============================================================================
604
605class TestMutate(unittest.TestCase):
606 def setUp(self):
607 self.values = ["a", "b", "c"]
608 self.set = set(self.values)
609
610 def test_add_present(self):
611 self.set.add("c")
612 self.assertEqual(self.set, set("abc"))
613
614 def test_add_absent(self):
615 self.set.add("d")
616 self.assertEqual(self.set, set("abcd"))
617
618 def test_add_until_full(self):
619 tmp = set()
620 expected_len = 0
621 for v in self.values:
622 tmp.add(v)
623 expected_len += 1
624 self.assertEqual(len(tmp), expected_len)
625 self.assertEqual(tmp, self.set)
626
627 def test_remove_present(self):
628 self.set.remove("b")
629 self.assertEqual(self.set, set("ac"))
630
631 def test_remove_absent(self):
632 try:
633 self.set.remove("d")
634 self.fail("Removing missing element should have raised LookupError")
635 except LookupError:
636 pass
637
638 def test_remove_until_empty(self):
639 expected_len = len(self.set)
640 for v in self.values:
641 self.set.remove(v)
642 expected_len -= 1
643 self.assertEqual(len(self.set), expected_len)
644
645 def test_discard_present(self):
646 self.set.discard("c")
647 self.assertEqual(self.set, set("ab"))
648
649 def test_discard_absent(self):
650 self.set.discard("d")
651 self.assertEqual(self.set, set("abc"))
652
653 def test_clear(self):
654 self.set.clear()
655 self.assertEqual(len(self.set), 0)
656
657 def test_pop(self):
658 popped = {}
659 while self.set:
660 popped[self.set.pop()] = None
661 self.assertEqual(len(popped), len(self.values))
662 for v in self.values:
663 self.failUnless(v in popped)
664
665 def test_update_empty_tuple(self):
666 self.set.union_update(())
667 self.assertEqual(self.set, set(self.values))
668
669 def test_update_unit_tuple_overlap(self):
670 self.set.union_update(("a",))
671 self.assertEqual(self.set, set(self.values))
672
673 def test_update_unit_tuple_non_overlap(self):
674 self.set.union_update(("a", "z"))
675 self.assertEqual(self.set, set(self.values + ["z"]))
676
677#==============================================================================
678
679class TestSubsets(unittest.TestCase):
680
681 case2method = {"<=": "issubset",
682 ">=": "issuperset",
683 }
684
685 reverse = {"==": "==",
686 "!=": "!=",
687 "<": ">",
688 ">": "<",
689 "<=": ">=",
690 ">=": "<=",
691 }
692
693 def test_issubset(self):
694 x = self.left
695 y = self.right
696 for case in "!=", "==", "<", "<=", ">", ">=":
697 expected = case in self.cases
698 # Test the binary infix spelling.
699 result = eval("x" + case + "y", locals())
700 self.assertEqual(result, expected)
701 # Test the "friendly" method-name spelling, if one exists.
702 if case in TestSubsets.case2method:
703 method = getattr(x, TestSubsets.case2method[case])
704 result = method(y)
705 self.assertEqual(result, expected)
706
707 # Now do the same for the operands reversed.
708 rcase = TestSubsets.reverse[case]
709 result = eval("y" + rcase + "x", locals())
710 self.assertEqual(result, expected)
711 if rcase in TestSubsets.case2method:
712 method = getattr(y, TestSubsets.case2method[rcase])
713 result = method(x)
714 self.assertEqual(result, expected)
715#------------------------------------------------------------------------------
716
717class TestSubsetEqualEmpty(TestSubsets):
718 left = set()
719 right = set()
720 name = "both empty"
721 cases = "==", "<=", ">="
722
723#------------------------------------------------------------------------------
724
725class TestSubsetEqualNonEmpty(TestSubsets):
726 left = set([1, 2])
727 right = set([1, 2])
728 name = "equal pair"
729 cases = "==", "<=", ">="
730
731#------------------------------------------------------------------------------
732
733class TestSubsetEmptyNonEmpty(TestSubsets):
734 left = set()
735 right = set([1, 2])
736 name = "one empty, one non-empty"
737 cases = "!=", "<", "<="
738
739#------------------------------------------------------------------------------
740
741class TestSubsetPartial(TestSubsets):
742 left = set([1])
743 right = set([1, 2])
744 name = "one a non-empty proper subset of other"
745 cases = "!=", "<", "<="
746
747#------------------------------------------------------------------------------
748
749class TestSubsetNonOverlap(TestSubsets):
750 left = set([1])
751 right = set([2])
752 name = "neither empty, neither contains"
753 cases = "!="
754
755#==============================================================================
756
757class TestOnlySetsInBinaryOps(unittest.TestCase):
758
759 def test_eq_ne(self):
760 # Unlike the others, this is testing that == and != *are* allowed.
761 self.assertEqual(self.other == self.set, False)
762 self.assertEqual(self.set == self.other, False)
763 self.assertEqual(self.other != self.set, True)
764 self.assertEqual(self.set != self.other, True)
765
766 def test_ge_gt_le_lt(self):
767 self.assertRaises(TypeError, lambda: self.set < self.other)
768 self.assertRaises(TypeError, lambda: self.set <= self.other)
769 self.assertRaises(TypeError, lambda: self.set > self.other)
770 self.assertRaises(TypeError, lambda: self.set >= self.other)
771
772 self.assertRaises(TypeError, lambda: self.other < self.set)
773 self.assertRaises(TypeError, lambda: self.other <= self.set)
774 self.assertRaises(TypeError, lambda: self.other > self.set)
775 self.assertRaises(TypeError, lambda: self.other >= self.set)
776
777 def test_union_update_operator(self):
778 try:
779 self.set |= self.other
780 except TypeError:
781 pass
782 else:
783 self.fail("expected TypeError")
784
785 def test_union_update(self):
786 if self.otherIsIterable:
787 self.set.union_update(self.other)
788 else:
789 self.assertRaises(TypeError, self.set.union_update, self.other)
790
791 def test_union(self):
792 self.assertRaises(TypeError, lambda: self.set | self.other)
793 self.assertRaises(TypeError, lambda: self.other | self.set)
794 if self.otherIsIterable:
795 self.set.union(self.other)
796 else:
797 self.assertRaises(TypeError, self.set.union, self.other)
798
799 def test_intersection_update_operator(self):
800 try:
801 self.set &= self.other
802 except TypeError:
803 pass
804 else:
805 self.fail("expected TypeError")
806
807 def test_intersection_update(self):
808 if self.otherIsIterable:
809 self.set.intersection_update(self.other)
810 else:
811 self.assertRaises(TypeError,
812 self.set.intersection_update,
813 self.other)
814
815 def test_intersection(self):
816 self.assertRaises(TypeError, lambda: self.set & self.other)
817 self.assertRaises(TypeError, lambda: self.other & self.set)
818 if self.otherIsIterable:
819 self.set.intersection(self.other)
820 else:
821 self.assertRaises(TypeError, self.set.intersection, self.other)
822
823 def test_sym_difference_update_operator(self):
824 try:
825 self.set ^= self.other
826 except TypeError:
827 pass
828 else:
829 self.fail("expected TypeError")
830
831 def test_sym_difference_update(self):
832 if self.otherIsIterable:
833 self.set.symmetric_difference_update(self.other)
834 else:
835 self.assertRaises(TypeError,
836 self.set.symmetric_difference_update,
837 self.other)
838
839 def test_sym_difference(self):
840 self.assertRaises(TypeError, lambda: self.set ^ self.other)
841 self.assertRaises(TypeError, lambda: self.other ^ self.set)
842 if self.otherIsIterable:
843 self.set.symmetric_difference(self.other)
844 else:
845 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
846
847 def test_difference_update_operator(self):
848 try:
849 self.set -= self.other
850 except TypeError:
851 pass
852 else:
853 self.fail("expected TypeError")
854
855 def test_difference_update(self):
856 if self.otherIsIterable:
857 self.set.difference_update(self.other)
858 else:
859 self.assertRaises(TypeError,
860 self.set.difference_update,
861 self.other)
862
863 def test_difference(self):
864 self.assertRaises(TypeError, lambda: self.set - self.other)
865 self.assertRaises(TypeError, lambda: self.other - self.set)
866 if self.otherIsIterable:
867 self.set.difference(self.other)
868 else:
869 self.assertRaises(TypeError, self.set.difference, self.other)
870
871#------------------------------------------------------------------------------
872
873class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
874 def setUp(self):
875 self.set = set((1, 2, 3))
876 self.other = 19
877 self.otherIsIterable = False
878
879#------------------------------------------------------------------------------
880
881class TestOnlySetsDict(TestOnlySetsInBinaryOps):
882 def setUp(self):
883 self.set = set((1, 2, 3))
884 self.other = {1:2, 3:4}
885 self.otherIsIterable = True
886
887#------------------------------------------------------------------------------
888
889class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
890 def setUp(self):
891 self.set = set((1, 2, 3))
892 self.other = operator.add
893 self.otherIsIterable = False
894
895#------------------------------------------------------------------------------
896
897class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
898 def setUp(self):
899 self.set = set((1, 2, 3))
900 self.other = (2, 4, 6)
901 self.otherIsIterable = True
902
903#------------------------------------------------------------------------------
904
905class TestOnlySetsString(TestOnlySetsInBinaryOps):
906 def setUp(self):
907 self.set = set((1, 2, 3))
908 self.other = 'abc'
909 self.otherIsIterable = True
910
911#------------------------------------------------------------------------------
912
913class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
914 def setUp(self):
915 def gen():
916 for i in xrange(0, 10, 2):
917 yield i
918 self.set = set((1, 2, 3))
919 self.other = gen()
920 self.otherIsIterable = True
921
922#==============================================================================
923
924class TestCopying(unittest.TestCase):
925
926 def test_copy(self):
927 dup = self.set.copy()
928 dup_list = list(dup); dup_list.sort()
929 set_list = list(self.set); set_list.sort()
930 self.assertEqual(len(dup_list), len(set_list))
931 for i in range(len(dup_list)):
932 self.failUnless(dup_list[i] is set_list[i])
933
934 def test_deep_copy(self):
935 dup = copy.deepcopy(self.set)
936 ##print type(dup), `dup`
937 dup_list = list(dup); dup_list.sort()
938 set_list = list(self.set); set_list.sort()
939 self.assertEqual(len(dup_list), len(set_list))
940 for i in range(len(dup_list)):
941 self.assertEqual(dup_list[i], set_list[i])
942
943#------------------------------------------------------------------------------
944
945class TestCopyingEmpty(TestCopying):
946 def setUp(self):
947 self.set = set()
948
949#------------------------------------------------------------------------------
950
951class TestCopyingSingleton(TestCopying):
952 def setUp(self):
953 self.set = set(["hello"])
954
955#------------------------------------------------------------------------------
956
957class TestCopyingTriple(TestCopying):
958 def setUp(self):
959 self.set = set(["zero", 0, None])
960
961#------------------------------------------------------------------------------
962
963class TestCopyingTuple(TestCopying):
964 def setUp(self):
965 self.set = set([(1, 2)])
966
967#------------------------------------------------------------------------------
968
969class TestCopyingNested(TestCopying):
970 def setUp(self):
971 self.set = set([((1, 2), (3, 4))])
972
973#==============================================================================
974
975class TestIdentities(unittest.TestCase):
976 def setUp(self):
977 self.a = set('abracadabra')
978 self.b = set('alacazam')
979
980 def test_binopsVsSubsets(self):
981 a, b = self.a, self.b
982 self.assert_(a - b < a)
983 self.assert_(b - a < b)
984 self.assert_(a & b < a)
985 self.assert_(a & b < b)
986 self.assert_(a | b > a)
987 self.assert_(a | b > b)
988 self.assert_(a ^ b < a | b)
989
990 def test_commutativity(self):
991 a, b = self.a, self.b
992 self.assertEqual(a&b, b&a)
993 self.assertEqual(a|b, b|a)
994 self.assertEqual(a^b, b^a)
995 if a != b:
996 self.assertNotEqual(a-b, b-a)
997
998 def test_summations(self):
999 # check that sums of parts equal the whole
1000 a, b = self.a, self.b
1001 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1002 self.assertEqual((a&b)|(a^b), a|b)
1003 self.assertEqual(a|(b-a), a|b)
1004 self.assertEqual((a-b)|b, a|b)
1005 self.assertEqual((a-b)|(a&b), a)
1006 self.assertEqual((b-a)|(a&b), b)
1007 self.assertEqual((a-b)|(b-a), a^b)
1008
1009 def test_exclusion(self):
1010 # check that inverse operations show non-overlap
1011 a, b, zero = self.a, self.b, set()
1012 self.assertEqual((a-b)&b, zero)
1013 self.assertEqual((b-a)&a, zero)
1014 self.assertEqual((a&b)&(a^b), zero)
1015
1016# Tests derived from test_itertools.py =======================================
1017
1018def R(seqn):
1019 'Regular generator'
1020 for i in seqn:
1021 yield i
1022
1023class G:
1024 'Sequence using __getitem__'
1025 def __init__(self, seqn):
1026 self.seqn = seqn
1027 def __getitem__(self, i):
1028 return self.seqn[i]
1029
1030class I:
1031 'Sequence using iterator protocol'
1032 def __init__(self, seqn):
1033 self.seqn = seqn
1034 self.i = 0
1035 def __iter__(self):
1036 return self
1037 def next(self):
1038 if self.i >= len(self.seqn): raise StopIteration
1039 v = self.seqn[self.i]
1040 self.i += 1
1041 return v
1042
1043class Ig:
1044 'Sequence using iterator protocol defined with a generator'
1045 def __init__(self, seqn):
1046 self.seqn = seqn
1047 self.i = 0
1048 def __iter__(self):
1049 for val in self.seqn:
1050 yield val
1051
1052class X:
1053 'Missing __getitem__ and __iter__'
1054 def __init__(self, seqn):
1055 self.seqn = seqn
1056 self.i = 0
1057 def next(self):
1058 if self.i >= len(self.seqn): raise StopIteration
1059 v = self.seqn[self.i]
1060 self.i += 1
1061 return v
1062
1063class N:
1064 'Iterator missing next()'
1065 def __init__(self, seqn):
1066 self.seqn = seqn
1067 self.i = 0
1068 def __iter__(self):
1069 return self
1070
1071class E:
1072 'Test propagation of exceptions'
1073 def __init__(self, seqn):
1074 self.seqn = seqn
1075 self.i = 0
1076 def __iter__(self):
1077 return self
1078 def next(self):
1079 3/0
1080
1081class S:
1082 'Test immediate stop'
1083 def __init__(self, seqn):
1084 pass
1085 def __iter__(self):
1086 return self
1087 def next(self):
1088 raise StopIteration
1089
1090from itertools import chain, imap
1091def L(seqn):
1092 'Test multiple tiers of iterators'
1093 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1094
1095class TestVariousIteratorArgs(unittest.TestCase):
1096
1097 def test_constructor(self):
1098 for cons in (set, frozenset):
1099 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1100 for g in (G, I, Ig, S, L, R):
1101 self.assertEqual(list.sorted(cons(g(s))), list.sorted(g(s)))
1102 self.assertRaises(TypeError, cons , X(s))
1103 self.assertRaises(TypeError, cons , N(s))
1104 self.assertRaises(ZeroDivisionError, cons , E(s))
1105
1106 def test_inline_methods(self):
1107 s = set('november')
1108 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
1109 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference):
1110 for g in (G, I, Ig, L, R):
1111 expected = meth(data)
1112 actual = meth(G(data))
1113 self.assertEqual(list.sorted(actual), list.sorted(expected))
1114 self.assertRaises(TypeError, meth, X(s))
1115 self.assertRaises(TypeError, meth, N(s))
1116 self.assertRaises(ZeroDivisionError, meth, E(s))
1117
1118 def test_inplace_methods(self):
1119 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
1120 for methname in ('union_update', 'intersection_update',
1121 'difference_update', 'symmetric_difference_update'):
1122 for g in (G, I, Ig, S, L, R):
1123 s = set('january')
1124 t = s.copy()
1125 getattr(s, methname)(list(g(data)))
1126 getattr(t, methname)(g(data))
1127 self.assertEqual(list.sorted(s), list.sorted(t))
1128
1129 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1130 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1131 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1132
1133#==============================================================================
1134
1135def test_main(verbose=None):
1136 import sys
1137 from test import test_sets
1138 test_classes = (
1139 TestSet,
1140 TestFrozenSet,
1141 TestSetOfSets,
1142 TestExceptionPropagation,
1143 TestBasicOpsEmpty,
1144 TestBasicOpsSingleton,
1145 TestBasicOpsTuple,
1146 TestBasicOpsTriple,
1147 TestBinaryOps,
1148 TestUpdateOps,
1149 TestMutate,
1150 TestSubsetEqualEmpty,
1151 TestSubsetEqualNonEmpty,
1152 TestSubsetEmptyNonEmpty,
1153 TestSubsetPartial,
1154 TestSubsetNonOverlap,
1155 TestOnlySetsNumeric,
1156 TestOnlySetsDict,
1157 TestOnlySetsOperator,
1158 TestOnlySetsTuple,
1159 TestOnlySetsString,
1160 TestOnlySetsGenerator,
1161 TestCopyingEmpty,
1162 TestCopyingSingleton,
1163 TestCopyingTriple,
1164 TestCopyingTuple,
1165 TestCopyingNested,
1166 TestIdentities,
1167 TestVariousIteratorArgs,
1168 )
1169
1170 test_support.run_unittest(*test_classes)
1171
1172 # verify reference counting
1173 if verbose and hasattr(sys, "gettotalrefcount"):
1174 import gc
1175 counts = [None] * 5
1176 for i in xrange(len(counts)):
1177 test_support.run_unittest(*test_classes)
1178 gc.collect()
1179 counts[i] = sys.gettotalrefcount()
1180 print counts
1181
1182if __name__ == "__main__":
1183 test_main(verbose=True)