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