blob: a2aa69a45f02aeed53e8bb7703c27d98cf468d95 [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"
141
142#==============================================================================
143
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000144class TestBinaryOps(unittest.TestCase):
145 def setUp(self):
146 self.set = Set((2, 4, 6))
147
148 def test_union_subset(self):
149 result = self.set | Set([2])
150 assert result == Set((2, 4, 6)), "Subset union"
151
152 def test_union_superset(self):
153 result = self.set | Set([2, 4, 6, 8])
154 assert result == Set([2, 4, 6, 8]), "Superset union"
155
156 def test_union_overlap(self):
157 result = self.set | Set([3, 4, 5])
158 assert result == Set([2, 3, 4, 5, 6]), "Overlapping union"
159
160 def test_union_non_overlap(self):
161 result = self.set | Set([8])
162 assert result == Set([2, 4, 6, 8]), "Non-overlapping union"
163
164 def test_intersection_subset(self):
165 result = self.set & Set((2, 4))
166 assert result == Set((2, 4)), "Subset intersection"
167
168 def test_intersection_superset(self):
169 result = self.set & Set([2, 4, 6, 8])
170 assert result == Set([2, 4, 6]), "Superset intersection"
171
172 def test_intersection_overlap(self):
173 result = self.set & Set([3, 4, 5])
174 assert result == Set([4]), "Overlapping intersection"
175
176 def test_intersection_non_overlap(self):
177 result = self.set & Set([8])
178 assert result == empty_set, "Non-overlapping intersection"
179
180 def test_sym_difference_subset(self):
181 result = self.set ^ Set((2, 4))
182 assert result == Set([6]), "Subset symmetric difference"
183
184 def test_sym_difference_superset(self):
185 result = self.set ^ Set((2, 4, 6, 8))
186 assert result == Set([8]), "Superset symmetric difference"
187
188 def test_sym_difference_overlap(self):
189 result = self.set ^ Set((3, 4, 5))
190 assert result == Set([2, 3, 5, 6]), "Overlapping symmetric difference"
191
192 def test_sym_difference_non_overlap(self):
193 result = self.set ^ Set([8])
194 assert result == Set([2, 4, 6, 8]), "Non-overlapping symmetric difference"
195
196#==============================================================================
197
198class TestUpdateOps(unittest.TestCase):
199 def setUp(self):
200 self.set = Set((2, 4, 6))
201
202 def test_union_subset(self):
203 self.set |= Set([2])
204 assert self.set == Set((2, 4, 6)), "Subset union"
205
206 def test_union_superset(self):
207 self.set |= Set([2, 4, 6, 8])
208 assert self.set == Set([2, 4, 6, 8]), "Superset union"
209
210 def test_union_overlap(self):
211 self.set |= Set([3, 4, 5])
212 assert self.set == Set([2, 3, 4, 5, 6]), "Overlapping union"
213
214 def test_union_non_overlap(self):
215 self.set |= Set([8])
216 assert self.set == Set([2, 4, 6, 8]), "Non-overlapping union"
217
218 def test_intersection_subset(self):
219 self.set &= Set((2, 4))
220 assert self.set == Set((2, 4)), "Subset intersection"
221
222 def test_intersection_superset(self):
223 self.set &= Set([2, 4, 6, 8])
224 assert self.set == Set([2, 4, 6]), "Superset intersection"
225
226 def test_intersection_overlap(self):
227 self.set &= Set([3, 4, 5])
228 assert self.set == Set([4]), "Overlapping intersection"
229
230 def test_intersection_non_overlap(self):
231 self.set &= Set([8])
232 assert self.set == empty_set, "Non-overlapping intersection"
233
234 def test_sym_difference_subset(self):
235 self.set ^= Set((2, 4))
236 assert self.set == Set([6]), "Subset symmetric difference"
237
238 def test_sym_difference_superset(self):
239 self.set ^= Set((2, 4, 6, 8))
240 assert self.set == Set([8]), "Superset symmetric difference"
241
242 def test_sym_difference_overlap(self):
243 self.set ^= Set((3, 4, 5))
244 assert self.set == Set([2, 3, 5, 6]), "Overlapping symmetric difference"
245
246 def test_sym_difference_non_overlap(self):
247 self.set ^= Set([8])
248 assert self.set == Set([2, 4, 6, 8]), "Non-overlapping symmetric difference"
249
250#==============================================================================
251
252class TestMutate(unittest.TestCase):
253 def setUp(self):
254 self.values = ["a", "b", "c"]
255 self.set = Set(self.values)
256
257 def test_add_present(self):
258 self.set.add("c")
259 assert self.set == Set(("a", "b", "c")), "Adding present element"
260
261 def test_add_absent(self):
262 self.set.add("d")
263 assert self.set == Set(("a", "b", "c", "d")), "Adding missing element"
264
265 def test_add_until_full(self):
266 tmp = Set()
267 expected_len = 0
268 for v in self.values:
269 tmp.add(v)
270 expected_len += 1
271 assert len(tmp) == expected_len, "Adding values one by one to temporary"
272 assert tmp == self.set, "Adding values one by one"
273
274 def test_remove_present(self):
275 self.set.remove("b")
276 assert self.set == Set(("a", "c")), "Removing present element"
277
278 def test_remove_absent(self):
279 try:
280 self.set.remove("d")
281 assert 0, "Removing missing element"
282 except LookupError:
283 pass
284
285 def test_remove_until_empty(self):
286 expected_len = len(self.set)
287 for v in self.values:
288 self.set.remove(v)
289 expected_len -= 1
290 assert len(self.set) == expected_len, "Removing values one by one"
291
292 def test_discard_present(self):
293 self.set.discard("c")
294 assert self.set == Set(("a", "b")), "Discarding present element"
295
296 def test_discard_absent(self):
297 self.set.discard("d")
298 assert self.set == Set(("a", "b", "c")), "Discarding missing element"
299
300 def test_clear(self):
301 self.set.clear()
302 assert len(self.set) == 0, "Clearing set"
303
Guido van Rossumc9196bc2002-08-20 21:51:59 +0000304 def test_pop(self):
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000305 popped = {}
306 while self.set:
Guido van Rossumc9196bc2002-08-20 21:51:59 +0000307 popped[self.set.pop()] = None
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000308 assert len(popped) == len(self.values), "Popping items"
309 for v in self.values:
310 assert v in popped, "Popping items"
311
312 def test_update_empty_tuple(self):
313 self.set.update(())
314 assert self.set == Set(self.values), "Updating with empty tuple"
315
316 def test_update_unit_tuple_overlap(self):
317 self.set.update(("a",))
318 assert self.set == Set(self.values), "Updating with overlapping unit tuple"
319
320 def test_update_unit_tuple_non_overlap(self):
321 self.set.update(("a", "z"))
322 assert self.set == Set(self.values + ["z"]), "Updating with non-overlapping unit tuple"
323
324#==============================================================================
325
326class TestSubsets(unittest.TestCase):
327
328 def test_issubset(self):
329 result = self.left.issubset(self.right)
330 if "<" in self.cases:
331 assert result, "subset: " + self.name
332 else:
333 assert not result, "non-subset: " + self.name
334
335#------------------------------------------------------------------------------
336
337class TestSubsetEqualEmpty(TestSubsets):
338 def setUp(self):
339 self.left = Set()
340 self.right = Set()
341 self.name = "both empty"
342 self.cases = "<>"
343
344#------------------------------------------------------------------------------
345
346class TestSubsetEqualNonEmpty(TestSubsets):
347 def setUp(self):
348 self.left = Set([1, 2])
349 self.right = Set([1, 2])
350 self.name = "equal pair"
351 self.cases = "<>"
352
353#------------------------------------------------------------------------------
354
355class TestSubsetEmptyNonEmpty(TestSubsets):
356 def setUp(self):
357 self.left = Set()
358 self.right = Set([1, 2])
359 self.name = "one empty, one non-empty"
360 self.cases = "<"
361
362#------------------------------------------------------------------------------
363
364class TestSubsetPartial(TestSubsets):
365 def setUp(self):
366 self.left = Set([1])
367 self.right = Set([1, 2])
368 self.name = "one a non-empty subset of other"
369 self.cases = "<"
370
371#------------------------------------------------------------------------------
372
373class TestSubsetNonOverlap(TestSubsets):
374 def setUp(self):
375 self.left = Set([1])
376 self.right = Set([2])
377 self.name = "neither empty, neither contains"
378 self.cases = ""
379
380#==============================================================================
381
382class TestOnlySetsInBinaryOps(unittest.TestCase):
383
384 def test_cmp(self):
385 try:
386 self.other < self.set
387 assert 0, "Comparison with non-set on left"
388 except TypeError:
389 pass
390 try:
391 self.set >= self.other
392 assert 0, "Comparison with non-set on right"
393 except TypeError:
394 pass
395
396 def test_union_update(self):
397 try:
398 self.set |= self.other
399 assert 0, "Union update with non-set"
400 except TypeError:
401 pass
402
403 def test_union(self):
404 try:
405 self.other | self.set
406 assert 0, "Union with non-set on left"
407 except TypeError:
408 pass
409 try:
410 self.set | self.other
411 assert 0, "Union with non-set on right"
412 except TypeError:
413 pass
414
415 def test_intersection_update(self):
416 try:
417 self.set &= self.other
418 assert 0, "Intersection update with non-set"
419 except TypeError:
420 pass
421
422 def test_intersection(self):
423 try:
424 self.other & self.set
425 assert 0, "Intersection with non-set on left"
426 except TypeError:
427 pass
428 try:
429 self.set & self.other
430 assert 0, "Intersection with non-set on right"
431 except TypeError:
432 pass
433
434 def test_sym_difference_update(self):
435 try:
436 self.set ^= self.other
437 assert 0, "Symmetric difference update with non-set"
438 except TypeError:
439 pass
440
441 def test_sym_difference(self):
442 try:
443 self.other ^ self.set
444 assert 0, "Symmetric difference with non-set on left"
445 except TypeError:
446 pass
447 try:
448 self.set ^ self.other
449 assert 0, "Symmetric difference with non-set on right"
450 except TypeError:
451 pass
452
453 def test_difference_update(self):
454 try:
455 self.set -= self.other
456 assert 0, "Symmetric difference update with non-set"
457 except TypeError:
458 pass
459
460 def test_difference(self):
461 try:
462 self.other - self.set
463 assert 0, "Symmetric difference with non-set on left"
464 except TypeError:
465 pass
466 try:
467 self.set - self.other
468 assert 0, "Symmetric difference with non-set on right"
469 except TypeError:
470 pass
471
472#------------------------------------------------------------------------------
473
474class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
475 def setUp(self):
476 self.set = Set((1, 2, 3))
477 self.other = 19
478
479#------------------------------------------------------------------------------
480
481class TestOnlySetsDict(TestOnlySetsInBinaryOps):
482 def setUp(self):
483 self.set = Set((1, 2, 3))
484 self.other = {1:2, 3:4}
485
486#------------------------------------------------------------------------------
487
488class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
489 def setUp(self):
490 self.set = Set((1, 2, 3))
491 self.other = operator.add
492
493#==============================================================================
494
495class TestCopying(unittest.TestCase):
496
497 def test_copy(self):
498 dup = self.set.copy()
499 dup_list = list(dup); dup_list.sort()
500 set_list = list(self.set); set_list.sort()
501 assert len(dup_list) == len(set_list), "Unequal lengths after copy"
502 for i in range(len(dup_list)):
503 assert dup_list[i] is set_list[i], "Non-identical items after copy"
504
505 def test_deep_copy(self):
506 dup = copy.deepcopy(self.set)
507 ##print type(dup), `dup`
508 dup_list = list(dup); dup_list.sort()
509 set_list = list(self.set); set_list.sort()
510 assert len(dup_list) == len(set_list), "Unequal lengths after deep copy"
511 for i in range(len(dup_list)):
512 assert dup_list[i] == set_list[i], "Unequal items after deep copy"
513
514#------------------------------------------------------------------------------
515
516class TestCopyingEmpty(TestCopying):
517 def setUp(self):
518 self.set = Set()
519
520#------------------------------------------------------------------------------
521
522class TestCopyingSingleton(TestCopying):
523 def setUp(self):
524 self.set = Set(["hello"])
525
526#------------------------------------------------------------------------------
527
528class TestCopyingTriple(TestCopying):
529 def setUp(self):
530 self.set = Set(["zero", 0, None])
531
532#------------------------------------------------------------------------------
533
534class TestCopyingTuple(TestCopying):
535 def setUp(self):
536 self.set = Set([(1, 2)])
537
538#------------------------------------------------------------------------------
539
540class TestCopyingNested(TestCopying):
541 def setUp(self):
542 self.set = Set([((1, 2), (3, 4))])
543
544#==============================================================================
545
546def makeAllTests():
547 suite = unittest.TestSuite()
Raymond Hettingerc3e61e52002-08-21 06:38:44 +0000548 suite.addTest(unittest.makeSuite(TestSetOfSets))
Guido van Rossumd6cf3af2002-08-19 16:19:15 +0000549 suite.addTest(unittest.makeSuite(TestBasicOpsEmpty))
550 suite.addTest(unittest.makeSuite(TestBasicOpsSingleton))
551 suite.addTest(unittest.makeSuite(TestBasicOpsTuple))
552 suite.addTest(unittest.makeSuite(TestBasicOpsTriple))
553 suite.addTest(unittest.makeSuite(TestBinaryOps))
554 suite.addTest(unittest.makeSuite(TestUpdateOps))
555 suite.addTest(unittest.makeSuite(TestMutate))
556 suite.addTest(unittest.makeSuite(TestSubsetEqualEmpty))
557 suite.addTest(unittest.makeSuite(TestSubsetEqualNonEmpty))
558 suite.addTest(unittest.makeSuite(TestSubsetEmptyNonEmpty))
559 suite.addTest(unittest.makeSuite(TestSubsetPartial))
560 suite.addTest(unittest.makeSuite(TestSubsetNonOverlap))
561 suite.addTest(unittest.makeSuite(TestOnlySetsNumeric))
562 suite.addTest(unittest.makeSuite(TestOnlySetsDict))
563 suite.addTest(unittest.makeSuite(TestOnlySetsOperator))
564 suite.addTest(unittest.makeSuite(TestCopyingEmpty))
565 suite.addTest(unittest.makeSuite(TestCopyingSingleton))
566 suite.addTest(unittest.makeSuite(TestCopyingTriple))
567 suite.addTest(unittest.makeSuite(TestCopyingTuple))
568 suite.addTest(unittest.makeSuite(TestCopyingNested))
569 return suite
570
571#------------------------------------------------------------------------------
572
573def test_main():
574 suite = makeAllTests()
575 test_support.run_suite(suite)
576
577if __name__ == "__main__":
578 test_main()