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