Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | #!/usr/bin/env python |
2 | ||
3 | import unittest, operator, copy, pickle, random | |
4 | from sets import Set, ImmutableSet | |
5 | from test import test_support | |
6 | ||
7 | empty_set = Set() | |
8 | ||
9 | #============================================================================== | |
10 | ||
11 | class TestBasicOps(unittest.TestCase): | |
12 | ||
13 | def test_repr(self): | |
14 | if self.repr is not None: | |
15 | self.assertEqual(repr(self.set), self.repr) | |
16 | ||
17 | def test_length(self): | |
18 | self.assertEqual(len(self.set), self.length) | |
19 | ||
20 | def test_self_equality(self): | |
21 | self.assertEqual(self.set, self.set) | |
22 | ||
23 | def test_equivalent_equality(self): | |
24 | self.assertEqual(self.set, self.dup) | |
25 | ||
26 | def test_copy(self): | |
27 | self.assertEqual(self.set.copy(), self.dup) | |
28 | ||
29 | def test_self_union(self): | |
30 | result = self.set | self.set | |
31 | self.assertEqual(result, self.dup) | |
32 | ||
33 | def test_empty_union(self): | |
34 | result = self.set | empty_set | |
35 | self.assertEqual(result, self.dup) | |
36 | ||
37 | def test_union_empty(self): | |
38 | result = empty_set | self.set | |
39 | self.assertEqual(result, self.dup) | |
40 | ||
41 | def test_self_intersection(self): | |
42 | result = self.set & self.set | |
43 | self.assertEqual(result, self.dup) | |
44 | ||
45 | def test_empty_intersection(self): | |
46 | result = self.set & empty_set | |
47 | self.assertEqual(result, empty_set) | |
48 | ||
49 | def test_intersection_empty(self): | |
50 | result = empty_set & self.set | |
51 | self.assertEqual(result, empty_set) | |
52 | ||
53 | def test_self_symmetric_difference(self): | |
54 | result = self.set ^ self.set | |
55 | self.assertEqual(result, empty_set) | |
56 | ||
57 | def checkempty_symmetric_difference(self): | |
58 | result = self.set ^ empty_set | |
59 | self.assertEqual(result, self.set) | |
60 | ||
61 | def test_self_difference(self): | |
62 | result = self.set - self.set | |
63 | self.assertEqual(result, empty_set) | |
64 | ||
65 | def test_empty_difference(self): | |
66 | result = self.set - empty_set | |
67 | self.assertEqual(result, self.dup) | |
68 | ||
69 | def test_empty_difference_rev(self): | |
70 | result = empty_set - self.set | |
71 | self.assertEqual(result, empty_set) | |
72 | ||
73 | def test_iteration(self): | |
74 | for v in self.set: | |
75 | self.assert_(v in self.values) | |
76 | ||
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)) | |
82 | ||
83 | #------------------------------------------------------------------------------ | |
84 | ||
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([])" | |
93 | ||
94 | #------------------------------------------------------------------------------ | |
95 | ||
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])" | |
104 | ||
105 | def test_in(self): | |
106 | self.failUnless(3 in self.set) | |
107 | ||
108 | def test_not_in(self): | |
109 | self.failUnless(2 not in self.set) | |
110 | ||
111 | #------------------------------------------------------------------------------ | |
112 | ||
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')])" | |
121 | ||
122 | def test_in(self): | |
123 | self.failUnless((0, "zero") in self.set) | |
124 | ||
125 | def test_not_in(self): | |
126 | self.failUnless(9 not in self.set) | |
127 | ||
128 | #------------------------------------------------------------------------------ | |
129 | ||
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 | |
138 | ||
139 | #============================================================================== | |
140 | ||
141 | def baditer(): | |
142 | raise TypeError | |
143 | yield True | |
144 | ||
145 | def gooditer(): | |
146 | yield True | |
147 | ||
148 | class TestExceptionPropagation(unittest.TestCase): | |
149 | """SF 628246: Set constructor should not trap iterator TypeErrors""" | |
150 | ||
151 | def test_instanceWithException(self): | |
152 | self.assertRaises(TypeError, Set, baditer()) | |
153 | ||
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()) | |
162 | ||
163 | #============================================================================== | |
164 | ||
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 | |
175 | ||
176 | #============================================================================== | |
177 | ||
178 | class TestBinaryOps(unittest.TestCase): | |
179 | def setUp(self): | |
180 | self.set = Set((2, 4, 6)) | |
181 | ||
182 | def test_eq(self): # SF bug 643115 | |
183 | self.assertEqual(self.set, Set({2:1,4:3,6:5})) | |
184 | ||
185 | def test_union_subset(self): | |
186 | result = self.set | Set([2]) | |
187 | self.assertEqual(result, Set((2, 4, 6))) | |
188 | ||
189 | def test_union_superset(self): | |
190 | result = self.set | Set([2, 4, 6, 8]) | |
191 | self.assertEqual(result, Set([2, 4, 6, 8])) | |
192 | ||
193 | def test_union_overlap(self): | |
194 | result = self.set | Set([3, 4, 5]) | |
195 | self.assertEqual(result, Set([2, 3, 4, 5, 6])) | |
196 | ||
197 | def test_union_non_overlap(self): | |
198 | result = self.set | Set([8]) | |
199 | self.assertEqual(result, Set([2, 4, 6, 8])) | |
200 | ||
201 | def test_intersection_subset(self): | |
202 | result = self.set & Set((2, 4)) | |
203 | self.assertEqual(result, Set((2, 4))) | |
204 | ||
205 | def test_intersection_superset(self): | |
206 | result = self.set & Set([2, 4, 6, 8]) | |
207 | self.assertEqual(result, Set([2, 4, 6])) | |
208 | ||
209 | def test_intersection_overlap(self): | |
210 | result = self.set & Set([3, 4, 5]) | |
211 | self.assertEqual(result, Set([4])) | |
212 | ||
213 | def test_intersection_non_overlap(self): | |
214 | result = self.set & Set([8]) | |
215 | self.assertEqual(result, empty_set) | |
216 | ||
217 | def test_sym_difference_subset(self): | |
218 | result = self.set ^ Set((2, 4)) | |
219 | self.assertEqual(result, Set([6])) | |
220 | ||
221 | def test_sym_difference_superset(self): | |
222 | result = self.set ^ Set((2, 4, 6, 8)) | |
223 | self.assertEqual(result, Set([8])) | |
224 | ||
225 | def test_sym_difference_overlap(self): | |
226 | result = self.set ^ Set((3, 4, 5)) | |
227 | self.assertEqual(result, Set([2, 3, 5, 6])) | |
228 | ||
229 | def test_sym_difference_non_overlap(self): | |
230 | result = self.set ^ Set([8]) | |
231 | self.assertEqual(result, Set([2, 4, 6, 8])) | |
232 | ||
233 | def test_cmp(self): | |
234 | a, b = Set('a'), Set('b') | |
235 | self.assertRaises(TypeError, cmp, a, b) | |
236 | ||
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) | |
242 | ||
243 | self.assertRaises(TypeError, cmp, a, 12) | |
244 | self.assertRaises(TypeError, cmp, "abc", a) | |
245 | ||
246 | def test_inplace_on_self(self): | |
247 | t = self.set.copy() | |
248 | t |= t | |
249 | self.assertEqual(t, self.set) | |
250 | t &= t | |
251 | self.assertEqual(t, self.set) | |
252 | t -= t | |
253 | self.assertEqual(len(t), 0) | |
254 | t = self.set.copy() | |
255 | t ^= t | |
256 | self.assertEqual(len(t), 0) | |
257 | ||
258 | ||
259 | #============================================================================== | |
260 | ||
261 | class TestUpdateOps(unittest.TestCase): | |
262 | def setUp(self): | |
263 | self.set = Set((2, 4, 6)) | |
264 | ||
265 | def test_union_subset(self): | |
266 | self.set |= Set([2]) | |
267 | self.assertEqual(self.set, Set((2, 4, 6))) | |
268 | ||
269 | def test_union_superset(self): | |
270 | self.set |= Set([2, 4, 6, 8]) | |
271 | self.assertEqual(self.set, Set([2, 4, 6, 8])) | |
272 | ||
273 | def test_union_overlap(self): | |
274 | self.set |= Set([3, 4, 5]) | |
275 | self.assertEqual(self.set, Set([2, 3, 4, 5, 6])) | |
276 | ||
277 | def test_union_non_overlap(self): | |
278 | self.set |= Set([8]) | |
279 | self.assertEqual(self.set, Set([2, 4, 6, 8])) | |
280 | ||
281 | def test_union_method_call(self): | |
282 | self.set.union_update(Set([3, 4, 5])) | |
283 | self.assertEqual(self.set, Set([2, 3, 4, 5, 6])) | |
284 | ||
285 | def test_intersection_subset(self): | |
286 | self.set &= Set((2, 4)) | |
287 | self.assertEqual(self.set, Set((2, 4))) | |
288 | ||
289 | def test_intersection_superset(self): | |
290 | self.set &= Set([2, 4, 6, 8]) | |
291 | self.assertEqual(self.set, Set([2, 4, 6])) | |
292 | ||
293 | def test_intersection_overlap(self): | |
294 | self.set &= Set([3, 4, 5]) | |
295 | self.assertEqual(self.set, Set([4])) | |
296 | ||
297 | def test_intersection_non_overlap(self): | |
298 | self.set &= Set([8]) | |
299 | self.assertEqual(self.set, empty_set) | |
300 | ||
301 | def test_intersection_method_call(self): | |
302 | self.set.intersection_update(Set([3, 4, 5])) | |
303 | self.assertEqual(self.set, Set([4])) | |
304 | ||
305 | def test_sym_difference_subset(self): | |
306 | self.set ^= Set((2, 4)) | |
307 | self.assertEqual(self.set, Set([6])) | |
308 | ||
309 | def test_sym_difference_superset(self): | |
310 | self.set ^= Set((2, 4, 6, 8)) | |
311 | self.assertEqual(self.set, Set([8])) | |
312 | ||
313 | def test_sym_difference_overlap(self): | |
314 | self.set ^= Set((3, 4, 5)) | |
315 | self.assertEqual(self.set, Set([2, 3, 5, 6])) | |
316 | ||
317 | def test_sym_difference_non_overlap(self): | |
318 | self.set ^= Set([8]) | |
319 | self.assertEqual(self.set, Set([2, 4, 6, 8])) | |
320 | ||
321 | def test_sym_difference_method_call(self): | |
322 | self.set.symmetric_difference_update(Set([3, 4, 5])) | |
323 | self.assertEqual(self.set, Set([2, 3, 5, 6])) | |
324 | ||
325 | def test_difference_subset(self): | |
326 | self.set -= Set((2, 4)) | |
327 | self.assertEqual(self.set, Set([6])) | |
328 | ||
329 | def test_difference_superset(self): | |
330 | self.set -= Set((2, 4, 6, 8)) | |
331 | self.assertEqual(self.set, Set([])) | |
332 | ||
333 | def test_difference_overlap(self): | |
334 | self.set -= Set((3, 4, 5)) | |
335 | self.assertEqual(self.set, Set([2, 6])) | |
336 | ||
337 | def test_difference_non_overlap(self): | |
338 | self.set -= Set([8]) | |
339 | self.assertEqual(self.set, Set([2, 4, 6])) | |
340 | ||
341 | def test_difference_method_call(self): | |
342 | self.set.difference_update(Set([3, 4, 5])) | |
343 | self.assertEqual(self.set, Set([2, 6])) | |
344 | ||
345 | #============================================================================== | |
346 | ||
347 | class TestMutate(unittest.TestCase): | |
348 | def setUp(self): | |
349 | self.values = ["a", "b", "c"] | |
350 | self.set = Set(self.values) | |
351 | ||
352 | def test_add_present(self): | |
353 | self.set.add("c") | |
354 | self.assertEqual(self.set, Set("abc")) | |
355 | ||
356 | def test_add_absent(self): | |
357 | self.set.add("d") | |
358 | self.assertEqual(self.set, Set("abcd")) | |
359 | ||
360 | def test_add_until_full(self): | |
361 | tmp = Set() | |
362 | expected_len = 0 | |
363 | for v in self.values: | |
364 | tmp.add(v) | |
365 | expected_len += 1 | |
366 | self.assertEqual(len(tmp), expected_len) | |
367 | self.assertEqual(tmp, self.set) | |
368 | ||
369 | def test_remove_present(self): | |
370 | self.set.remove("b") | |
371 | self.assertEqual(self.set, Set("ac")) | |
372 | ||
373 | def test_remove_absent(self): | |
374 | try: | |
375 | self.set.remove("d") | |
376 | self.fail("Removing missing element should have raised LookupError") | |
377 | except LookupError: | |
378 | pass | |
379 | ||
380 | def test_remove_until_empty(self): | |
381 | expected_len = len(self.set) | |
382 | for v in self.values: | |
383 | self.set.remove(v) | |
384 | expected_len -= 1 | |
385 | self.assertEqual(len(self.set), expected_len) | |
386 | ||
387 | def test_discard_present(self): | |
388 | self.set.discard("c") | |
389 | self.assertEqual(self.set, Set("ab")) | |
390 | ||
391 | def test_discard_absent(self): | |
392 | self.set.discard("d") | |
393 | self.assertEqual(self.set, Set("abc")) | |
394 | ||
395 | def test_clear(self): | |
396 | self.set.clear() | |
397 | self.assertEqual(len(self.set), 0) | |
398 | ||
399 | def test_pop(self): | |
400 | popped = {} | |
401 | while self.set: | |
402 | popped[self.set.pop()] = None | |
403 | self.assertEqual(len(popped), len(self.values)) | |
404 | for v in self.values: | |
405 | self.failUnless(v in popped) | |
406 | ||
407 | def test_update_empty_tuple(self): | |
408 | self.set.union_update(()) | |
409 | self.assertEqual(self.set, Set(self.values)) | |
410 | ||
411 | def test_update_unit_tuple_overlap(self): | |
412 | self.set.union_update(("a",)) | |
413 | self.assertEqual(self.set, Set(self.values)) | |
414 | ||
415 | def test_update_unit_tuple_non_overlap(self): | |
416 | self.set.union_update(("a", "z")) | |
417 | self.assertEqual(self.set, Set(self.values + ["z"])) | |
418 | ||
419 | #============================================================================== | |
420 | ||
421 | class TestSubsets(unittest.TestCase): | |
422 | ||
423 | case2method = {"<=": "issubset", | |
424 | ">=": "issuperset", | |
425 | } | |
426 | ||
427 | reverse = {"==": "==", | |
428 | "!=": "!=", | |
429 | "<": ">", | |
430 | ">": "<", | |
431 | "<=": ">=", | |
432 | ">=": "<=", | |
433 | } | |
434 | ||
435 | def test_issubset(self): | |
436 | x = self.left | |
437 | y = self.right | |
438 | for case in "!=", "==", "<", "<=", ">", ">=": | |
439 | expected = case in self.cases | |
440 | # Test the binary infix spelling. | |
441 | result = eval("x" + case + "y", locals()) | |
442 | self.assertEqual(result, expected) | |
443 | # Test the "friendly" method-name spelling, if one exists. | |
444 | if case in TestSubsets.case2method: | |
445 | method = getattr(x, TestSubsets.case2method[case]) | |
446 | result = method(y) | |
447 | self.assertEqual(result, expected) | |
448 | ||
449 | # Now do the same for the operands reversed. | |
450 | rcase = TestSubsets.reverse[case] | |
451 | result = eval("y" + rcase + "x", locals()) | |
452 | self.assertEqual(result, expected) | |
453 | if rcase in TestSubsets.case2method: | |
454 | method = getattr(y, TestSubsets.case2method[rcase]) | |
455 | result = method(x) | |
456 | self.assertEqual(result, expected) | |
457 | #------------------------------------------------------------------------------ | |
458 | ||
459 | class TestSubsetEqualEmpty(TestSubsets): | |
460 | left = Set() | |
461 | right = Set() | |
462 | name = "both empty" | |
463 | cases = "==", "<=", ">=" | |
464 | ||
465 | #------------------------------------------------------------------------------ | |
466 | ||
467 | class TestSubsetEqualNonEmpty(TestSubsets): | |
468 | left = Set([1, 2]) | |
469 | right = Set([1, 2]) | |
470 | name = "equal pair" | |
471 | cases = "==", "<=", ">=" | |
472 | ||
473 | #------------------------------------------------------------------------------ | |
474 | ||
475 | class TestSubsetEmptyNonEmpty(TestSubsets): | |
476 | left = Set() | |
477 | right = Set([1, 2]) | |
478 | name = "one empty, one non-empty" | |
479 | cases = "!=", "<", "<=" | |
480 | ||
481 | #------------------------------------------------------------------------------ | |
482 | ||
483 | class TestSubsetPartial(TestSubsets): | |
484 | left = Set([1]) | |
485 | right = Set([1, 2]) | |
486 | name = "one a non-empty proper subset of other" | |
487 | cases = "!=", "<", "<=" | |
488 | ||
489 | #------------------------------------------------------------------------------ | |
490 | ||
491 | class TestSubsetNonOverlap(TestSubsets): | |
492 | left = Set([1]) | |
493 | right = Set([2]) | |
494 | name = "neither empty, neither contains" | |
495 | cases = "!=" | |
496 | ||
497 | #============================================================================== | |
498 | ||
499 | class TestOnlySetsInBinaryOps(unittest.TestCase): | |
500 | ||
501 | def test_eq_ne(self): | |
502 | # Unlike the others, this is testing that == and != *are* allowed. | |
503 | self.assertEqual(self.other == self.set, False) | |
504 | self.assertEqual(self.set == self.other, False) | |
505 | self.assertEqual(self.other != self.set, True) | |
506 | self.assertEqual(self.set != self.other, True) | |
507 | ||
508 | def test_ge_gt_le_lt(self): | |
509 | self.assertRaises(TypeError, lambda: self.set < self.other) | |
510 | self.assertRaises(TypeError, lambda: self.set <= self.other) | |
511 | self.assertRaises(TypeError, lambda: self.set > self.other) | |
512 | self.assertRaises(TypeError, lambda: self.set >= self.other) | |
513 | ||
514 | self.assertRaises(TypeError, lambda: self.other < self.set) | |
515 | self.assertRaises(TypeError, lambda: self.other <= self.set) | |
516 | self.assertRaises(TypeError, lambda: self.other > self.set) | |
517 | self.assertRaises(TypeError, lambda: self.other >= self.set) | |
518 | ||
519 | def test_union_update_operator(self): | |
520 | try: | |
521 | self.set |= self.other | |
522 | except TypeError: | |
523 | pass | |
524 | else: | |
525 | self.fail("expected TypeError") | |
526 | ||
527 | def test_union_update(self): | |
528 | if self.otherIsIterable: | |
529 | self.set.union_update(self.other) | |
530 | else: | |
531 | self.assertRaises(TypeError, self.set.union_update, self.other) | |
532 | ||
533 | def test_union(self): | |
534 | self.assertRaises(TypeError, lambda: self.set | self.other) | |
535 | self.assertRaises(TypeError, lambda: self.other | self.set) | |
536 | if self.otherIsIterable: | |
537 | self.set.union(self.other) | |
538 | else: | |
539 | self.assertRaises(TypeError, self.set.union, self.other) | |
540 | ||
541 | def test_intersection_update_operator(self): | |
542 | try: | |
543 | self.set &= self.other | |
544 | except TypeError: | |
545 | pass | |
546 | else: | |
547 | self.fail("expected TypeError") | |
548 | ||
549 | def test_intersection_update(self): | |
550 | if self.otherIsIterable: | |
551 | self.set.intersection_update(self.other) | |
552 | else: | |
553 | self.assertRaises(TypeError, | |
554 | self.set.intersection_update, | |
555 | self.other) | |
556 | ||
557 | def test_intersection(self): | |
558 | self.assertRaises(TypeError, lambda: self.set & self.other) | |
559 | self.assertRaises(TypeError, lambda: self.other & self.set) | |
560 | if self.otherIsIterable: | |
561 | self.set.intersection(self.other) | |
562 | else: | |
563 | self.assertRaises(TypeError, self.set.intersection, self.other) | |
564 | ||
565 | def test_sym_difference_update_operator(self): | |
566 | try: | |
567 | self.set ^= self.other | |
568 | except TypeError: | |
569 | pass | |
570 | else: | |
571 | self.fail("expected TypeError") | |
572 | ||
573 | def test_sym_difference_update(self): | |
574 | if self.otherIsIterable: | |
575 | self.set.symmetric_difference_update(self.other) | |
576 | else: | |
577 | self.assertRaises(TypeError, | |
578 | self.set.symmetric_difference_update, | |
579 | self.other) | |
580 | ||
581 | def test_sym_difference(self): | |
582 | self.assertRaises(TypeError, lambda: self.set ^ self.other) | |
583 | self.assertRaises(TypeError, lambda: self.other ^ self.set) | |
584 | if self.otherIsIterable: | |
585 | self.set.symmetric_difference(self.other) | |
586 | else: | |
587 | self.assertRaises(TypeError, self.set.symmetric_difference, self.other) | |
588 | ||
589 | def test_difference_update_operator(self): | |
590 | try: | |
591 | self.set -= self.other | |
592 | except TypeError: | |
593 | pass | |
594 | else: | |
595 | self.fail("expected TypeError") | |
596 | ||
597 | def test_difference_update(self): | |
598 | if self.otherIsIterable: | |
599 | self.set.difference_update(self.other) | |
600 | else: | |
601 | self.assertRaises(TypeError, | |
602 | self.set.difference_update, | |
603 | self.other) | |
604 | ||
605 | def test_difference(self): | |
606 | self.assertRaises(TypeError, lambda: self.set - self.other) | |
607 | self.assertRaises(TypeError, lambda: self.other - self.set) | |
608 | if self.otherIsIterable: | |
609 | self.set.difference(self.other) | |
610 | else: | |
611 | self.assertRaises(TypeError, self.set.difference, self.other) | |
612 | ||
613 | #------------------------------------------------------------------------------ | |
614 | ||
615 | class TestOnlySetsNumeric(TestOnlySetsInBinaryOps): | |
616 | def setUp(self): | |
617 | self.set = Set((1, 2, 3)) | |
618 | self.other = 19 | |
619 | self.otherIsIterable = False | |
620 | ||
621 | #------------------------------------------------------------------------------ | |
622 | ||
623 | class TestOnlySetsDict(TestOnlySetsInBinaryOps): | |
624 | def setUp(self): | |
625 | self.set = Set((1, 2, 3)) | |
626 | self.other = {1:2, 3:4} | |
627 | self.otherIsIterable = True | |
628 | ||
629 | #------------------------------------------------------------------------------ | |
630 | ||
631 | class TestOnlySetsOperator(TestOnlySetsInBinaryOps): | |
632 | def setUp(self): | |
633 | self.set = Set((1, 2, 3)) | |
634 | self.other = operator.add | |
635 | self.otherIsIterable = False | |
636 | ||
637 | #------------------------------------------------------------------------------ | |
638 | ||
639 | class TestOnlySetsTuple(TestOnlySetsInBinaryOps): | |
640 | def setUp(self): | |
641 | self.set = Set((1, 2, 3)) | |
642 | self.other = (2, 4, 6) | |
643 | self.otherIsIterable = True | |
644 | ||
645 | #------------------------------------------------------------------------------ | |
646 | ||
647 | class TestOnlySetsString(TestOnlySetsInBinaryOps): | |
648 | def setUp(self): | |
649 | self.set = Set((1, 2, 3)) | |
650 | self.other = 'abc' | |
651 | self.otherIsIterable = True | |
652 | ||
653 | #------------------------------------------------------------------------------ | |
654 | ||
655 | class TestOnlySetsGenerator(TestOnlySetsInBinaryOps): | |
656 | def setUp(self): | |
657 | def gen(): | |
658 | for i in xrange(0, 10, 2): | |
659 | yield i | |
660 | self.set = Set((1, 2, 3)) | |
661 | self.other = gen() | |
662 | self.otherIsIterable = True | |
663 | ||
664 | #------------------------------------------------------------------------------ | |
665 | ||
666 | class TestOnlySetsofSets(TestOnlySetsInBinaryOps): | |
667 | def setUp(self): | |
668 | self.set = Set((1, 2, 3)) | |
669 | self.other = [Set('ab'), ImmutableSet('cd')] | |
670 | self.otherIsIterable = True | |
671 | ||
672 | #============================================================================== | |
673 | ||
674 | class TestCopying(unittest.TestCase): | |
675 | ||
676 | def test_copy(self): | |
677 | dup = self.set.copy() | |
678 | dup_list = list(dup); dup_list.sort() | |
679 | set_list = list(self.set); set_list.sort() | |
680 | self.assertEqual(len(dup_list), len(set_list)) | |
681 | for i in range(len(dup_list)): | |
682 | self.failUnless(dup_list[i] is set_list[i]) | |
683 | ||
684 | def test_deep_copy(self): | |
685 | dup = copy.deepcopy(self.set) | |
686 | ##print type(dup), repr(dup) | |
687 | dup_list = list(dup); dup_list.sort() | |
688 | set_list = list(self.set); set_list.sort() | |
689 | self.assertEqual(len(dup_list), len(set_list)) | |
690 | for i in range(len(dup_list)): | |
691 | self.assertEqual(dup_list[i], set_list[i]) | |
692 | ||
693 | #------------------------------------------------------------------------------ | |
694 | ||
695 | class TestCopyingEmpty(TestCopying): | |
696 | def setUp(self): | |
697 | self.set = Set() | |
698 | ||
699 | #------------------------------------------------------------------------------ | |
700 | ||
701 | class TestCopyingSingleton(TestCopying): | |
702 | def setUp(self): | |
703 | self.set = Set(["hello"]) | |
704 | ||
705 | #------------------------------------------------------------------------------ | |
706 | ||
707 | class TestCopyingTriple(TestCopying): | |
708 | def setUp(self): | |
709 | self.set = Set(["zero", 0, None]) | |
710 | ||
711 | #------------------------------------------------------------------------------ | |
712 | ||
713 | class TestCopyingTuple(TestCopying): | |
714 | def setUp(self): | |
715 | self.set = Set([(1, 2)]) | |
716 | ||
717 | #------------------------------------------------------------------------------ | |
718 | ||
719 | class TestCopyingNested(TestCopying): | |
720 | def setUp(self): | |
721 | self.set = Set([((1, 2), (3, 4))]) | |
722 | ||
723 | #============================================================================== | |
724 | ||
725 | class TestIdentities(unittest.TestCase): | |
726 | def setUp(self): | |
727 | self.a = Set([random.randrange(100) for i in xrange(50)]) | |
728 | self.b = Set([random.randrange(100) for i in xrange(50)]) | |
729 | ||
730 | def test_binopsVsSubsets(self): | |
731 | a, b = self.a, self.b | |
732 | self.assert_(a - b <= a) | |
733 | self.assert_(b - a <= b) | |
734 | self.assert_(a & b <= a) | |
735 | self.assert_(a & b <= b) | |
736 | self.assert_(a | b >= a) | |
737 | self.assert_(a | b >= b) | |
738 | self.assert_(a ^ b <= a | b) | |
739 | ||
740 | def test_commutativity(self): | |
741 | a, b = self.a, self.b | |
742 | self.assertEqual(a&b, b&a) | |
743 | self.assertEqual(a|b, b|a) | |
744 | self.assertEqual(a^b, b^a) | |
745 | if a != b: | |
746 | self.assertNotEqual(a-b, b-a) | |
747 | ||
748 | def test_reflexsive_relations(self): | |
749 | a, zero = self.a, Set() | |
750 | self.assertEqual(a ^ a, zero) | |
751 | self.assertEqual(a - a, zero) | |
752 | self.assertEqual(a | a, a) | |
753 | self.assertEqual(a & a, a) | |
754 | self.assert_(a <= a) | |
755 | self.assert_(a >= a) | |
756 | self.assert_(a == a) | |
757 | ||
758 | def test_summations(self): | |
759 | # check that sums of parts equal the whole | |
760 | a, b = self.a, self.b | |
761 | self.assertEqual((a-b)|(a&b)|(b-a), a|b) | |
762 | self.assertEqual((a&b)|(a^b), a|b) | |
763 | self.assertEqual(a|(b-a), a|b) | |
764 | self.assertEqual((a-b)|b, a|b) | |
765 | self.assertEqual((a-b)|(a&b), a) | |
766 | self.assertEqual((b-a)|(a&b), b) | |
767 | self.assertEqual((a-b)|(b-a), a^b) | |
768 | ||
769 | def test_exclusion(self): | |
770 | # check that inverse operations do not overlap | |
771 | a, b, zero = self.a, self.b, Set() | |
772 | self.assertEqual((a-b)&b, zero) | |
773 | self.assertEqual((b-a)&a, zero) | |
774 | self.assertEqual((a&b)&(a^b), zero) | |
775 | ||
776 | def test_cardinality_relations(self): | |
777 | a, b = self.a, self.b | |
778 | self.assertEqual(len(a), len(a-b) + len(a&b)) | |
779 | self.assertEqual(len(b), len(b-a) + len(a&b)) | |
780 | self.assertEqual(len(a^b), len(a-b) + len(b-a)) | |
781 | self.assertEqual(len(a|b), len(a-b) + len(a&b) + len(b-a)) | |
782 | self.assertEqual(len(a^b) + len(a&b), len(a|b)) | |
783 | ||
784 | #============================================================================== | |
785 | ||
786 | libreftest = """ | |
787 | Example from the Library Reference: Doc/lib/libsets.tex | |
788 | ||
789 | >>> from sets import Set as Base # override _repr to get sorted output | |
790 | >>> class Set(Base): | |
791 | ... def _repr(self): | |
792 | ... return Base._repr(self, sorted=True) | |
793 | >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice']) | |
794 | >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice']) | |
795 | >>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack']) | |
796 | >>> employees = engineers | programmers | managers # union | |
797 | >>> engineering_management = engineers & managers # intersection | |
798 | >>> fulltime_management = managers - engineers - programmers # difference | |
799 | >>> engineers.add('Marvin') | |
800 | >>> print engineers | |
801 | Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin']) | |
802 | >>> employees.issuperset(engineers) # superset test | |
803 | False | |
804 | >>> employees.union_update(engineers) # update from another set | |
805 | >>> employees.issuperset(engineers) | |
806 | True | |
807 | >>> for group in [engineers, programmers, managers, employees]: | |
808 | ... group.discard('Susan') # unconditionally remove element | |
809 | ... print group | |
810 | ... | |
811 | Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin']) | |
812 | Set(['Jack', 'Janice', 'Sam']) | |
813 | Set(['Jack', 'Jane', 'Zack']) | |
814 | Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin', 'Sam', 'Zack']) | |
815 | """ | |
816 | ||
817 | #============================================================================== | |
818 | ||
819 | __test__ = {'libreftest' : libreftest} | |
820 | ||
821 | def test_main(verbose=None): | |
822 | import test_sets, doctest | |
823 | test_support.run_unittest( | |
824 | TestSetOfSets, | |
825 | TestExceptionPropagation, | |
826 | TestBasicOpsEmpty, | |
827 | TestBasicOpsSingleton, | |
828 | TestBasicOpsTuple, | |
829 | TestBasicOpsTriple, | |
830 | TestBinaryOps, | |
831 | TestUpdateOps, | |
832 | TestMutate, | |
833 | TestSubsetEqualEmpty, | |
834 | TestSubsetEqualNonEmpty, | |
835 | TestSubsetEmptyNonEmpty, | |
836 | TestSubsetPartial, | |
837 | TestSubsetNonOverlap, | |
838 | TestOnlySetsNumeric, | |
839 | TestOnlySetsDict, | |
840 | TestOnlySetsOperator, | |
841 | TestOnlySetsTuple, | |
842 | TestOnlySetsString, | |
843 | TestOnlySetsGenerator, | |
844 | TestOnlySetsofSets, | |
845 | TestCopyingEmpty, | |
846 | TestCopyingSingleton, | |
847 | TestCopyingTriple, | |
848 | TestCopyingTuple, | |
849 | TestCopyingNested, | |
850 | TestIdentities, | |
851 | doctest.DocTestSuite(test_sets), | |
852 | ) | |
853 | ||
854 | if __name__ == "__main__": | |
855 | test_main(verbose=True) |