blob: b56219be2446f77ced79b61a316cf93b163067b4 [file] [log] [blame]
Guido van Rossumd6cf3af2002-08-19 16:19:15 +00001#!/usr/bin/env python
2
3import unittest, operator, copy
4from sets import Set, ImmutableSet
5from test import test_support
6
7empty_set = Set()
8
9#==============================================================================
10
11class TestBasicOps(unittest.TestCase):
12
13 def test_repr(self):
14 if self.repr is not None:
15 assert `self.set` == self.repr, "Wrong representation for " + self.case
16
17 def test_length(self):
18 assert len(self.set) == self.length, "Wrong length for " + self.case
19
20 def test_self_equality(self):
21 assert self.set == self.set, "Self-equality failed for " + self.case
22
23 def test_equivalent_equality(self):
24 assert self.set == self.dup, "Equivalent equality failed for " + self.case
25
26 def test_copy(self):
27 assert self.set.copy() == self.dup, "Copy and comparison failed for " + self.case
28
29 def test_self_union(self):
30 result = self.set | self.set
31 assert result == self.dup, "Self-union failed for " + self.case
32
33 def test_empty_union(self):
34 result = self.set | empty_set
35 assert result == self.dup, "Union with empty failed for " + self.case
36
37 def test_union_empty(self):
38 result = empty_set | self.set
39 assert result == self.dup, "Union with empty failed for " + self.case
40
41 def test_self_intersection(self):
42 result = self.set & self.set
43 assert result == self.dup, "Self-intersection failed for " + self.case
44
45 def test_empty_intersection(self):
46 result = self.set & empty_set
47 assert result == empty_set, "Intersection with empty failed for " + self.case
48
49 def test_intersection_empty(self):
50 result = empty_set & self.set
51 assert result == empty_set, "Intersection with empty failed for " + self.case
52
53 def test_self_symmetric_difference(self):
54 result = self.set ^ self.set
55 assert result == empty_set, "Self-symdiff failed for " + self.case
56
57 def checkempty_symmetric_difference(self):
58 result = self.set ^ empty_set
59 assert result == self.set, "Symdiff with empty failed for " + self.case
60
61 def test_self_difference(self):
62 result = self.set - self.set
63 assert result == empty_set, "Self-difference failed for " + self.case
64
65 def test_empty_difference(self):
66 result = self.set - empty_set
67 assert result == self.dup, "Difference with empty failed for " + self.case
68
69 def test_empty_difference_rev(self):
70 result = empty_set - self.set
71 assert result == empty_set, "Difference from empty failed for " + self.case
72
73 def test_iteration(self):
74 for v in self.set:
75 assert v in self.values, "Missing item in iteration for " + self.case
76
77#------------------------------------------------------------------------------
78
79class TestBasicOpsEmpty(TestBasicOps):
80 def setUp(self):
81 self.case = "empty set"
82 self.values = []
83 self.set = Set(self.values)
84 self.dup = Set(self.values)
85 self.length = 0
86 self.repr = "Set([])"
87
88#------------------------------------------------------------------------------
89
90class TestBasicOpsSingleton(TestBasicOps):
91 def setUp(self):
92 self.case = "unit set (number)"
93 self.values = [3]
94 self.set = Set(self.values)
95 self.dup = Set(self.values)
96 self.length = 1
97 self.repr = "Set([3])"
98
99 def test_in(self):
100 assert 3 in self.set, "Valueship for unit set"
101
102 def test_not_in(self):
103 assert 2 not in self.set, "Non-valueship for unit set"
104
105#------------------------------------------------------------------------------
106
107class TestBasicOpsTuple(TestBasicOps):
108 def setUp(self):
109 self.case = "unit set (tuple)"
110 self.values = [(0, "zero")]
111 self.set = Set(self.values)
112 self.dup = Set(self.values)
113 self.length = 1
114 self.repr = "Set([(0, 'zero')])"
115
116 def test_in(self):
117 assert (0, "zero") in self.set, "Valueship for tuple set"
118
119 def test_not_in(self):
120 assert 9 not in self.set, "Non-valueship for tuple set"
121
122#------------------------------------------------------------------------------
123
124class TestBasicOpsTriple(TestBasicOps):
125 def setUp(self):
126 self.case = "triple set"
127 self.values = [0, "zero", operator.add]
128 self.set = Set(self.values)
129 self.dup = Set(self.values)
130 self.length = 3
131 self.repr = None
132
133#==============================================================================
134
Raymond Hettingerc3e61e52002-08-21 06:38:44 +0000135class TestSetOfSets(unittest.TestCase):
136 def test_constructor(self):
137 inner = Set([1])
138 outer = Set([inner])
139 element = outer.pop()
140 assert type(element) == ImmutableSet, "Construct set of sets"
Raymond Hettinger045e51a2002-08-24 02:56:01 +0000141 outer.add(inner) # Rebuild set of sets with .add method
142 outer.remove(inner)
143 assert outer == Set() # Verify that remove worked
144 outer.discard(inner) # Absence of KeyError indicates working fine
Raymond Hettingerc3e61e52002-08-21 06:38:44 +0000145
146#==============================================================================
147
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000148class TestBinaryOps(unittest.TestCase):
149 def setUp(self):
150 self.set = Set((2, 4, 6))
151
152 def test_union_subset(self):
153 result = self.set | Set([2])
154 assert result == Set((2, 4, 6)), "Subset union"
155
156 def test_union_superset(self):
157 result = self.set | Set([2, 4, 6, 8])
158 assert result == Set([2, 4, 6, 8]), "Superset union"
159
160 def test_union_overlap(self):
161 result = self.set | Set([3, 4, 5])
162 assert result == Set([2, 3, 4, 5, 6]), "Overlapping union"
163
164 def test_union_non_overlap(self):
165 result = self.set | Set([8])
166 assert result == Set([2, 4, 6, 8]), "Non-overlapping union"
167
168 def test_intersection_subset(self):
169 result = self.set & Set((2, 4))
170 assert result == Set((2, 4)), "Subset intersection"
171
172 def test_intersection_superset(self):
173 result = self.set & Set([2, 4, 6, 8])
174 assert result == Set([2, 4, 6]), "Superset intersection"
175
176 def test_intersection_overlap(self):
177 result = self.set & Set([3, 4, 5])
178 assert result == Set([4]), "Overlapping intersection"
179
180 def test_intersection_non_overlap(self):
181 result = self.set & Set([8])
182 assert result == empty_set, "Non-overlapping intersection"
183
184 def test_sym_difference_subset(self):
185 result = self.set ^ Set((2, 4))
186 assert result == Set([6]), "Subset symmetric difference"
187
188 def test_sym_difference_superset(self):
189 result = self.set ^ Set((2, 4, 6, 8))
190 assert result == Set([8]), "Superset symmetric difference"
191
192 def test_sym_difference_overlap(self):
193 result = self.set ^ Set((3, 4, 5))
194 assert result == Set([2, 3, 5, 6]), "Overlapping symmetric difference"
195
196 def test_sym_difference_non_overlap(self):
197 result = self.set ^ Set([8])
198 assert result == Set([2, 4, 6, 8]), "Non-overlapping symmetric difference"
199
200#==============================================================================
201
202class TestUpdateOps(unittest.TestCase):
203 def setUp(self):
204 self.set = Set((2, 4, 6))
205
206 def test_union_subset(self):
207 self.set |= Set([2])
208 assert self.set == Set((2, 4, 6)), "Subset union"
209
210 def test_union_superset(self):
211 self.set |= Set([2, 4, 6, 8])
212 assert self.set == Set([2, 4, 6, 8]), "Superset union"
213
214 def test_union_overlap(self):
215 self.set |= Set([3, 4, 5])
216 assert self.set == Set([2, 3, 4, 5, 6]), "Overlapping union"
217
218 def test_union_non_overlap(self):
219 self.set |= Set([8])
220 assert self.set == Set([2, 4, 6, 8]), "Non-overlapping union"
221
222 def test_intersection_subset(self):
223 self.set &= Set((2, 4))
224 assert self.set == Set((2, 4)), "Subset intersection"
225
226 def test_intersection_superset(self):
227 self.set &= Set([2, 4, 6, 8])
228 assert self.set == Set([2, 4, 6]), "Superset intersection"
229
230 def test_intersection_overlap(self):
231 self.set &= Set([3, 4, 5])
232 assert self.set == Set([4]), "Overlapping intersection"
233
234 def test_intersection_non_overlap(self):
235 self.set &= Set([8])
236 assert self.set == empty_set, "Non-overlapping intersection"
237
238 def test_sym_difference_subset(self):
239 self.set ^= Set((2, 4))
240 assert self.set == Set([6]), "Subset symmetric difference"
241
242 def test_sym_difference_superset(self):
243 self.set ^= Set((2, 4, 6, 8))
244 assert self.set == Set([8]), "Superset symmetric difference"
245
246 def test_sym_difference_overlap(self):
247 self.set ^= Set((3, 4, 5))
248 assert self.set == Set([2, 3, 5, 6]), "Overlapping symmetric difference"
249
250 def test_sym_difference_non_overlap(self):
251 self.set ^= Set([8])
252 assert self.set == Set([2, 4, 6, 8]), "Non-overlapping symmetric difference"
253
254#==============================================================================
255
256class TestMutate(unittest.TestCase):
257 def setUp(self):
258 self.values = ["a", "b", "c"]
259 self.set = Set(self.values)
260
261 def test_add_present(self):
262 self.set.add("c")
263 assert self.set == Set(("a", "b", "c")), "Adding present element"
264
265 def test_add_absent(self):
266 self.set.add("d")
267 assert self.set == Set(("a", "b", "c", "d")), "Adding missing element"
268
269 def test_add_until_full(self):
270 tmp = Set()
271 expected_len = 0
272 for v in self.values:
273 tmp.add(v)
274 expected_len += 1
275 assert len(tmp) == expected_len, "Adding values one by one to temporary"
276 assert tmp == self.set, "Adding values one by one"
277
278 def test_remove_present(self):
279 self.set.remove("b")
280 assert self.set == Set(("a", "c")), "Removing present element"
281
282 def test_remove_absent(self):
283 try:
284 self.set.remove("d")
285 assert 0, "Removing missing element"
286 except LookupError:
287 pass
288
289 def test_remove_until_empty(self):
290 expected_len = len(self.set)
291 for v in self.values:
292 self.set.remove(v)
293 expected_len -= 1
294 assert len(self.set) == expected_len, "Removing values one by one"
295
296 def test_discard_present(self):
297 self.set.discard("c")
298 assert self.set == Set(("a", "b")), "Discarding present element"
299
300 def test_discard_absent(self):
301 self.set.discard("d")
302 assert self.set == Set(("a", "b", "c")), "Discarding missing element"
303
304 def test_clear(self):
305 self.set.clear()
306 assert len(self.set) == 0, "Clearing set"
307
Guido van Rossumc9196bc2002-08-20 21:51:59 +0000308 def test_pop(self):
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000309 popped = {}
310 while self.set:
Guido van Rossumc9196bc2002-08-20 21:51:59 +0000311 popped[self.set.pop()] = None
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000312 assert len(popped) == len(self.values), "Popping items"
313 for v in self.values:
314 assert v in popped, "Popping items"
315
316 def test_update_empty_tuple(self):
317 self.set.update(())
318 assert self.set == Set(self.values), "Updating with empty tuple"
319
320 def test_update_unit_tuple_overlap(self):
321 self.set.update(("a",))
322 assert self.set == Set(self.values), "Updating with overlapping unit tuple"
323
324 def test_update_unit_tuple_non_overlap(self):
325 self.set.update(("a", "z"))
326 assert self.set == Set(self.values + ["z"]), "Updating with non-overlapping unit tuple"
327
328#==============================================================================
329
330class TestSubsets(unittest.TestCase):
331
332 def test_issubset(self):
333 result = self.left.issubset(self.right)
334 if "<" in self.cases:
335 assert result, "subset: " + self.name
336 else:
337 assert not result, "non-subset: " + self.name
338
339#------------------------------------------------------------------------------
340
341class TestSubsetEqualEmpty(TestSubsets):
342 def setUp(self):
343 self.left = Set()
344 self.right = Set()
345 self.name = "both empty"
346 self.cases = "<>"
347
348#------------------------------------------------------------------------------
349
350class TestSubsetEqualNonEmpty(TestSubsets):
351 def setUp(self):
352 self.left = Set([1, 2])
353 self.right = Set([1, 2])
354 self.name = "equal pair"
355 self.cases = "<>"
356
357#------------------------------------------------------------------------------
358
359class TestSubsetEmptyNonEmpty(TestSubsets):
360 def setUp(self):
361 self.left = Set()
362 self.right = Set([1, 2])
363 self.name = "one empty, one non-empty"
364 self.cases = "<"
365
366#------------------------------------------------------------------------------
367
368class TestSubsetPartial(TestSubsets):
369 def setUp(self):
370 self.left = Set([1])
371 self.right = Set([1, 2])
372 self.name = "one a non-empty subset of other"
373 self.cases = "<"
374
375#------------------------------------------------------------------------------
376
377class TestSubsetNonOverlap(TestSubsets):
378 def setUp(self):
379 self.left = Set([1])
380 self.right = Set([2])
381 self.name = "neither empty, neither contains"
382 self.cases = ""
383
384#==============================================================================
385
386class TestOnlySetsInBinaryOps(unittest.TestCase):
387
388 def test_cmp(self):
389 try:
390 self.other < self.set
391 assert 0, "Comparison with non-set on left"
392 except TypeError:
393 pass
394 try:
395 self.set >= self.other
396 assert 0, "Comparison with non-set on right"
397 except TypeError:
398 pass
399
400 def test_union_update(self):
401 try:
402 self.set |= self.other
403 assert 0, "Union update with non-set"
404 except TypeError:
405 pass
406
407 def test_union(self):
408 try:
409 self.other | self.set
410 assert 0, "Union with non-set on left"
411 except TypeError:
412 pass
413 try:
414 self.set | self.other
415 assert 0, "Union with non-set on right"
416 except TypeError:
417 pass
418
419 def test_intersection_update(self):
420 try:
421 self.set &= self.other
422 assert 0, "Intersection update with non-set"
423 except TypeError:
424 pass
425
426 def test_intersection(self):
427 try:
428 self.other & self.set
429 assert 0, "Intersection with non-set on left"
430 except TypeError:
431 pass
432 try:
433 self.set & self.other
434 assert 0, "Intersection with non-set on right"
435 except TypeError:
436 pass
437
438 def test_sym_difference_update(self):
439 try:
440 self.set ^= self.other
441 assert 0, "Symmetric difference update with non-set"
442 except TypeError:
443 pass
444
445 def test_sym_difference(self):
446 try:
447 self.other ^ self.set
448 assert 0, "Symmetric difference with non-set on left"
449 except TypeError:
450 pass
451 try:
452 self.set ^ self.other
453 assert 0, "Symmetric difference with non-set on right"
454 except TypeError:
455 pass
456
457 def test_difference_update(self):
458 try:
459 self.set -= self.other
460 assert 0, "Symmetric difference update with non-set"
461 except TypeError:
462 pass
463
464 def test_difference(self):
465 try:
466 self.other - self.set
467 assert 0, "Symmetric difference with non-set on left"
468 except TypeError:
469 pass
470 try:
471 self.set - self.other
472 assert 0, "Symmetric difference with non-set on right"
473 except TypeError:
474 pass
475
476#------------------------------------------------------------------------------
477
478class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
479 def setUp(self):
480 self.set = Set((1, 2, 3))
481 self.other = 19
482
483#------------------------------------------------------------------------------
484
485class TestOnlySetsDict(TestOnlySetsInBinaryOps):
486 def setUp(self):
487 self.set = Set((1, 2, 3))
488 self.other = {1:2, 3:4}
489
490#------------------------------------------------------------------------------
491
492class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
493 def setUp(self):
494 self.set = Set((1, 2, 3))
495 self.other = operator.add
496
497#==============================================================================
498
499class TestCopying(unittest.TestCase):
500
501 def test_copy(self):
502 dup = self.set.copy()
503 dup_list = list(dup); dup_list.sort()
504 set_list = list(self.set); set_list.sort()
505 assert len(dup_list) == len(set_list), "Unequal lengths after copy"
506 for i in range(len(dup_list)):
507 assert dup_list[i] is set_list[i], "Non-identical items after copy"
508
509 def test_deep_copy(self):
510 dup = copy.deepcopy(self.set)
511 ##print type(dup), `dup`
512 dup_list = list(dup); dup_list.sort()
513 set_list = list(self.set); set_list.sort()
514 assert len(dup_list) == len(set_list), "Unequal lengths after deep copy"
515 for i in range(len(dup_list)):
516 assert dup_list[i] == set_list[i], "Unequal items after deep copy"
517
518#------------------------------------------------------------------------------
519
520class TestCopyingEmpty(TestCopying):
521 def setUp(self):
522 self.set = Set()
523
524#------------------------------------------------------------------------------
525
526class TestCopyingSingleton(TestCopying):
527 def setUp(self):
528 self.set = Set(["hello"])
529
530#------------------------------------------------------------------------------
531
532class TestCopyingTriple(TestCopying):
533 def setUp(self):
534 self.set = Set(["zero", 0, None])
535
536#------------------------------------------------------------------------------
537
538class TestCopyingTuple(TestCopying):
539 def setUp(self):
540 self.set = Set([(1, 2)])
541
542#------------------------------------------------------------------------------
543
544class TestCopyingNested(TestCopying):
545 def setUp(self):
546 self.set = Set([((1, 2), (3, 4))])
547
548#==============================================================================
549
550def makeAllTests():
551 suite = unittest.TestSuite()
Raymond Hettingerc3e61e52002-08-21 06:38:44 +0000552 suite.addTest(unittest.makeSuite(TestSetOfSets))
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000553 suite.addTest(unittest.makeSuite(TestBasicOpsEmpty))
554 suite.addTest(unittest.makeSuite(TestBasicOpsSingleton))
555 suite.addTest(unittest.makeSuite(TestBasicOpsTuple))
556 suite.addTest(unittest.makeSuite(TestBasicOpsTriple))
557 suite.addTest(unittest.makeSuite(TestBinaryOps))
558 suite.addTest(unittest.makeSuite(TestUpdateOps))
559 suite.addTest(unittest.makeSuite(TestMutate))
560 suite.addTest(unittest.makeSuite(TestSubsetEqualEmpty))
561 suite.addTest(unittest.makeSuite(TestSubsetEqualNonEmpty))
562 suite.addTest(unittest.makeSuite(TestSubsetEmptyNonEmpty))
563 suite.addTest(unittest.makeSuite(TestSubsetPartial))
564 suite.addTest(unittest.makeSuite(TestSubsetNonOverlap))
565 suite.addTest(unittest.makeSuite(TestOnlySetsNumeric))
566 suite.addTest(unittest.makeSuite(TestOnlySetsDict))
567 suite.addTest(unittest.makeSuite(TestOnlySetsOperator))
568 suite.addTest(unittest.makeSuite(TestCopyingEmpty))
569 suite.addTest(unittest.makeSuite(TestCopyingSingleton))
570 suite.addTest(unittest.makeSuite(TestCopyingTriple))
571 suite.addTest(unittest.makeSuite(TestCopyingTuple))
572 suite.addTest(unittest.makeSuite(TestCopyingNested))
573 return suite
574
575#------------------------------------------------------------------------------
576
577def test_main():
578 suite = makeAllTests()
579 test_support.run_suite(suite)
580
581if __name__ == "__main__":
582 test_main()