cpython/Lib/test/test_sets.py

854 lines
27 KiB
Python
Raw Normal View History

#!/usr/bin/env python
2003-09-21 05:14:11 -03:00
import unittest, operator, copy, pickle, random
from sets import Set, ImmutableSet
from test import test_support
empty_set = Set()
#==============================================================================
class TestBasicOps(unittest.TestCase):
def test_repr(self):
if self.repr is not None:
self.assertEqual(repr(self.set), self.repr)
def test_length(self):
self.assertEqual(len(self.set), self.length)
def test_self_equality(self):
self.assertEqual(self.set, self.set)
def test_equivalent_equality(self):
self.assertEqual(self.set, self.dup)
def test_copy(self):
self.assertEqual(self.set.copy(), self.dup)
def test_self_union(self):
result = self.set | self.set
self.assertEqual(result, self.dup)
def test_empty_union(self):
result = self.set | empty_set
self.assertEqual(result, self.dup)
def test_union_empty(self):
result = empty_set | self.set
self.assertEqual(result, self.dup)
def test_self_intersection(self):
result = self.set & self.set
self.assertEqual(result, self.dup)
def test_empty_intersection(self):
result = self.set & empty_set
self.assertEqual(result, empty_set)
def test_intersection_empty(self):
result = empty_set & self.set
self.assertEqual(result, empty_set)
def test_self_symmetric_difference(self):
result = self.set ^ self.set
self.assertEqual(result, empty_set)
def checkempty_symmetric_difference(self):
result = self.set ^ empty_set
self.assertEqual(result, self.set)
def test_self_difference(self):
result = self.set - self.set
self.assertEqual(result, empty_set)
def test_empty_difference(self):
result = self.set - empty_set
self.assertEqual(result, self.dup)
def test_empty_difference_rev(self):
result = empty_set - self.set
self.assertEqual(result, empty_set)
def test_iteration(self):
for v in self.set:
2002-08-25 15:02:29 -03:00
self.assert_(v in self.values)
def test_pickling(self):
p = pickle.dumps(self.set)
copy = pickle.loads(p)
self.assertEqual(self.set, copy,
"%s != %s" % (self.set, copy))
#------------------------------------------------------------------------------
class TestBasicOpsEmpty(TestBasicOps):
def setUp(self):
self.case = "empty set"
self.values = []
self.set = Set(self.values)
self.dup = Set(self.values)
self.length = 0
self.repr = "Set([])"
#------------------------------------------------------------------------------
class TestBasicOpsSingleton(TestBasicOps):
def setUp(self):
self.case = "unit set (number)"
self.values = [3]
self.set = Set(self.values)
self.dup = Set(self.values)
self.length = 1
self.repr = "Set([3])"
def test_in(self):
2002-08-25 15:02:29 -03:00
self.failUnless(3 in self.set)
def test_not_in(self):
2002-08-25 15:02:29 -03:00
self.failUnless(2 not in self.set)
#------------------------------------------------------------------------------
class TestBasicOpsTuple(TestBasicOps):
def setUp(self):
self.case = "unit set (tuple)"
self.values = [(0, "zero")]
self.set = Set(self.values)
self.dup = Set(self.values)
self.length = 1
self.repr = "Set([(0, 'zero')])"
def test_in(self):
2002-08-25 15:02:29 -03:00
self.failUnless((0, "zero") in self.set)
def test_not_in(self):
2002-08-25 15:02:29 -03:00
self.failUnless(9 not in self.set)
#------------------------------------------------------------------------------
class TestBasicOpsTriple(TestBasicOps):
def setUp(self):
self.case = "triple set"
self.values = [0, "zero", operator.add]
self.set = Set(self.values)
self.dup = Set(self.values)
self.length = 3
self.repr = None
#==============================================================================
def baditer():
raise TypeError
yield True
def gooditer():
yield True
class TestExceptionPropagation(unittest.TestCase):
"""SF 628246: Set constructor should not trap iterator TypeErrors"""
def test_instanceWithException(self):
self.assertRaises(TypeError, Set, baditer())
def test_instancesWithoutException(self):
# All of these iterables should load without exception.
Set([1,2,3])
Set((1,2,3))
Set({'one':1, 'two':2, 'three':3})
Set(xrange(3))
Set('abc')
Set(gooditer())
#==============================================================================
class TestSetOfSets(unittest.TestCase):
def test_constructor(self):
inner = Set([1])
outer = Set([inner])
element = outer.pop()
2002-08-25 15:02:29 -03:00
self.assertEqual(type(element), ImmutableSet)
2002-08-23 23:56:01 -03:00
outer.add(inner) # Rebuild set of sets with .add method
outer.remove(inner)
2002-08-25 15:02:29 -03:00
self.assertEqual(outer, Set()) # Verify that remove worked
2002-08-23 23:56:01 -03:00
outer.discard(inner) # Absence of KeyError indicates working fine
#==============================================================================
class TestBinaryOps(unittest.TestCase):
def setUp(self):
self.set = Set((2, 4, 6))
def test_eq(self): # SF bug 643115
self.assertEqual(self.set, Set({2:1,4:3,6:5}))
def test_union_subset(self):
result = self.set | Set([2])
self.assertEqual(result, Set((2, 4, 6)))
def test_union_superset(self):
result = self.set | Set([2, 4, 6, 8])
self.assertEqual(result, Set([2, 4, 6, 8]))
def test_union_overlap(self):
result = self.set | Set([3, 4, 5])
self.assertEqual(result, Set([2, 3, 4, 5, 6]))
def test_union_non_overlap(self):
result = self.set | Set([8])
self.assertEqual(result, Set([2, 4, 6, 8]))
def test_intersection_subset(self):
result = self.set & Set((2, 4))
self.assertEqual(result, Set((2, 4)))
def test_intersection_superset(self):
result = self.set & Set([2, 4, 6, 8])
self.assertEqual(result, Set([2, 4, 6]))
def test_intersection_overlap(self):
result = self.set & Set([3, 4, 5])
self.assertEqual(result, Set([4]))
def test_intersection_non_overlap(self):
result = self.set & Set([8])
self.assertEqual(result, empty_set)
def test_sym_difference_subset(self):
result = self.set ^ Set((2, 4))
self.assertEqual(result, Set([6]))
def test_sym_difference_superset(self):
result = self.set ^ Set((2, 4, 6, 8))
self.assertEqual(result, Set([8]))
def test_sym_difference_overlap(self):
result = self.set ^ Set((3, 4, 5))
self.assertEqual(result, Set([2, 3, 5, 6]))
def test_sym_difference_non_overlap(self):
result = self.set ^ Set([8])
self.assertEqual(result, Set([2, 4, 6, 8]))
def test_cmp(self):
a, b = Set('a'), Set('b')
self.assertRaises(TypeError, cmp, a, b)
Restructure comparison dramatically. There is no longer a default *ordering* between objects; there is only a default equality test (defined by an object being equal to itself only). Read the comment in object.c. The current implementation never uses a three-way comparison to compute a rich comparison, but it does use a rich comparison to compute a three-way comparison. I'm not quite done ripping out all the calls to PyObject_Compare/Cmp, or replacing tp_compare implementations with tp_richcompare implementations; but much of that has happened (to make most unit tests pass). The following tests still fail, because I need help deciding or understanding: test_codeop -- depends on comparing code objects test_datetime -- need Tim Peters' opinion test_marshal -- depends on comparing code objects test_mutants -- need help understanding it The problem with test_codeop and test_marshal is this: these tests compare two different code objects and expect them to be equal. Is that still a feature we'd like to support? I've temporarily removed the comparison and hash code from code objects, so they use the default (equality by pointer only) comparison. For the other two tests, run them to see for yourself. (There may be more failing test with "-u all".) A general problem with getting lots of these tests to pass is the reality that for object types that have a natural total ordering, implementing __cmp__ is much more convenient than implementing __eq__, __ne__, __lt__, and so on. Should we go back to allowing __cmp__ to provide a total ordering? Should we provide some other way to implement rich comparison with a single method override? Alex proposed a __key__() method; I've considered a __richcmp__() method. Or perhaps __cmp__() just shouldn't be killed off...
2006-08-23 21:41:19 -03:00
# In py3k, this works!
self.assertRaises(TypeError, cmp, a, a)
self.assertRaises(TypeError, cmp, a, 12)
self.assertRaises(TypeError, cmp, "abc", a)
def test_inplace_on_self(self):
t = self.set.copy()
t |= t
self.assertEqual(t, self.set)
t &= t
self.assertEqual(t, self.set)
t -= t
self.assertEqual(len(t), 0)
t = self.set.copy()
t ^= t
self.assertEqual(len(t), 0)
#==============================================================================
class TestUpdateOps(unittest.TestCase):
def setUp(self):
self.set = Set((2, 4, 6))
def test_union_subset(self):
self.set |= Set([2])
self.assertEqual(self.set, Set((2, 4, 6)))
def test_union_superset(self):
self.set |= Set([2, 4, 6, 8])
self.assertEqual(self.set, Set([2, 4, 6, 8]))
def test_union_overlap(self):
self.set |= Set([3, 4, 5])
self.assertEqual(self.set, Set([2, 3, 4, 5, 6]))
def test_union_non_overlap(self):
self.set |= Set([8])
self.assertEqual(self.set, Set([2, 4, 6, 8]))
def test_union_method_call(self):
self.set.union_update(Set([3, 4, 5]))
self.assertEqual(self.set, Set([2, 3, 4, 5, 6]))
def test_intersection_subset(self):
self.set &= Set((2, 4))
self.assertEqual(self.set, Set((2, 4)))
def test_intersection_superset(self):
self.set &= Set([2, 4, 6, 8])
self.assertEqual(self.set, Set([2, 4, 6]))
def test_intersection_overlap(self):
self.set &= Set([3, 4, 5])
self.assertEqual(self.set, Set([4]))
def test_intersection_non_overlap(self):
self.set &= Set([8])
self.assertEqual(self.set, empty_set)
def test_intersection_method_call(self):
self.set.intersection_update(Set([3, 4, 5]))
self.assertEqual(self.set, Set([4]))
def test_sym_difference_subset(self):
self.set ^= Set((2, 4))
self.assertEqual(self.set, Set([6]))
def test_sym_difference_superset(self):
self.set ^= Set((2, 4, 6, 8))
self.assertEqual(self.set, Set([8]))
def test_sym_difference_overlap(self):
self.set ^= Set((3, 4, 5))
self.assertEqual(self.set, Set([2, 3, 5, 6]))
def test_sym_difference_non_overlap(self):
self.set ^= Set([8])
self.assertEqual(self.set, Set([2, 4, 6, 8]))
def test_sym_difference_method_call(self):
self.set.symmetric_difference_update(Set([3, 4, 5]))
self.assertEqual(self.set, Set([2, 3, 5, 6]))
def test_difference_subset(self):
self.set -= Set((2, 4))
self.assertEqual(self.set, Set([6]))
def test_difference_superset(self):
self.set -= Set((2, 4, 6, 8))
self.assertEqual(self.set, Set([]))
def test_difference_overlap(self):
self.set -= Set((3, 4, 5))
self.assertEqual(self.set, Set([2, 6]))
def test_difference_non_overlap(self):
self.set -= Set([8])
self.assertEqual(self.set, Set([2, 4, 6]))
def test_difference_method_call(self):
self.set.difference_update(Set([3, 4, 5]))
self.assertEqual(self.set, Set([2, 6]))
#==============================================================================
class TestMutate(unittest.TestCase):
def setUp(self):
self.values = ["a", "b", "c"]
self.set = Set(self.values)
def test_add_present(self):
self.set.add("c")
self.assertEqual(self.set, Set("abc"))
def test_add_absent(self):
self.set.add("d")
self.assertEqual(self.set, Set("abcd"))
def test_add_until_full(self):
tmp = Set()
expected_len = 0
for v in self.values:
tmp.add(v)
expected_len += 1
self.assertEqual(len(tmp), expected_len)
self.assertEqual(tmp, self.set)
def test_remove_present(self):
self.set.remove("b")
self.assertEqual(self.set, Set("ac"))
def test_remove_absent(self):
try:
self.set.remove("d")
2002-08-25 15:02:29 -03:00
self.fail("Removing missing element should have raised LookupError")
except LookupError:
pass
def test_remove_until_empty(self):
expected_len = len(self.set)
for v in self.values:
self.set.remove(v)
expected_len -= 1
2002-08-25 15:02:29 -03:00
self.assertEqual(len(self.set), expected_len)
def test_discard_present(self):
self.set.discard("c")
self.assertEqual(self.set, Set("ab"))
def test_discard_absent(self):
self.set.discard("d")
self.assertEqual(self.set, Set("abc"))
def test_clear(self):
self.set.clear()
self.assertEqual(len(self.set), 0)
def test_pop(self):
popped = {}
while self.set:
popped[self.set.pop()] = None
self.assertEqual(len(popped), len(self.values))
for v in self.values:
2002-08-25 15:02:29 -03:00
self.failUnless(v in popped)
def test_update_empty_tuple(self):
self.set.union_update(())
self.assertEqual(self.set, Set(self.values))
def test_update_unit_tuple_overlap(self):
self.set.union_update(("a",))
self.assertEqual(self.set, Set(self.values))
def test_update_unit_tuple_non_overlap(self):
self.set.union_update(("a", "z"))
self.assertEqual(self.set, Set(self.values + ["z"]))
#==============================================================================
class TestSubsets(unittest.TestCase):
case2method = {"<=": "issubset",
">=": "issuperset",
}
reverse = {"==": "==",
"!=": "!=",
"<": ">",
">": "<",
"<=": ">=",
">=": "<=",
}
def test_issubset(self):
x = self.left
y = self.right
for case in "!=", "==", "<", "<=", ">", ">=":
expected = case in self.cases
# Test the binary infix spelling.
result = eval("x" + case + "y", locals())
self.assertEqual(result, expected)
# Test the "friendly" method-name spelling, if one exists.
if case in TestSubsets.case2method:
method = getattr(x, TestSubsets.case2method[case])
result = method(y)
self.assertEqual(result, expected)
# Now do the same for the operands reversed.
rcase = TestSubsets.reverse[case]
result = eval("y" + rcase + "x", locals())
self.assertEqual(result, expected)
if rcase in TestSubsets.case2method:
method = getattr(y, TestSubsets.case2method[rcase])
result = method(x)
self.assertEqual(result, expected)
#------------------------------------------------------------------------------
class TestSubsetEqualEmpty(TestSubsets):
left = Set()
right = Set()
name = "both empty"
cases = "==", "<=", ">="
#------------------------------------------------------------------------------
class TestSubsetEqualNonEmpty(TestSubsets):
left = Set([1, 2])
right = Set([1, 2])
name = "equal pair"
cases = "==", "<=", ">="
#------------------------------------------------------------------------------
class TestSubsetEmptyNonEmpty(TestSubsets):
left = Set()
right = Set([1, 2])
name = "one empty, one non-empty"
cases = "!=", "<", "<="
#------------------------------------------------------------------------------
class TestSubsetPartial(TestSubsets):
2002-11-09 01:26:15 -04:00
left = Set([1])
right = Set([1, 2])
name = "one a non-empty proper subset of other"
cases = "!=", "<", "<="
#------------------------------------------------------------------------------
class TestSubsetNonOverlap(TestSubsets):
left = Set([1])
right = Set([2])
name = "neither empty, neither contains"
cases = "!="
#==============================================================================
class TestOnlySetsInBinaryOps(unittest.TestCase):
def test_eq_ne(self):
# Unlike the others, this is testing that == and != *are* allowed.
self.assertEqual(self.other == self.set, False)
self.assertEqual(self.set == self.other, False)
self.assertEqual(self.other != self.set, True)
self.assertEqual(self.set != self.other, True)
2003-03-01 20:31:23 -04:00
def test_ge_gt_le_lt(self):
self.assertRaises(TypeError, lambda: self.set < self.other)
self.assertRaises(TypeError, lambda: self.set <= self.other)
self.assertRaises(TypeError, lambda: self.set > self.other)
self.assertRaises(TypeError, lambda: self.set >= self.other)
2003-03-01 20:31:23 -04:00
self.assertRaises(TypeError, lambda: self.other < self.set)
self.assertRaises(TypeError, lambda: self.other <= self.set)
self.assertRaises(TypeError, lambda: self.other > self.set)
self.assertRaises(TypeError, lambda: self.other >= self.set)
def test_union_update_operator(self):
try:
self.set |= self.other
except TypeError:
pass
else:
self.fail("expected TypeError")
def test_union_update(self):
if self.otherIsIterable:
self.set.union_update(self.other)
else:
self.assertRaises(TypeError, self.set.union_update, self.other)
def test_union(self):
self.assertRaises(TypeError, lambda: self.set | self.other)
self.assertRaises(TypeError, lambda: self.other | self.set)
if self.otherIsIterable:
self.set.union(self.other)
else:
self.assertRaises(TypeError, self.set.union, self.other)
def test_intersection_update_operator(self):
try:
self.set &= self.other
except TypeError:
pass
else:
self.fail("expected TypeError")
def test_intersection_update(self):
if self.otherIsIterable:
self.set.intersection_update(self.other)
else:
self.assertRaises(TypeError,
self.set.intersection_update,
self.other)
def test_intersection(self):
self.assertRaises(TypeError, lambda: self.set & self.other)
self.assertRaises(TypeError, lambda: self.other & self.set)
if self.otherIsIterable:
self.set.intersection(self.other)
else:
self.assertRaises(TypeError, self.set.intersection, self.other)
def test_sym_difference_update_operator(self):
try:
self.set ^= self.other
except TypeError:
pass
else:
self.fail("expected TypeError")
def test_sym_difference_update(self):
if self.otherIsIterable:
self.set.symmetric_difference_update(self.other)
else:
self.assertRaises(TypeError,
self.set.symmetric_difference_update,
self.other)
def test_sym_difference(self):
self.assertRaises(TypeError, lambda: self.set ^ self.other)
self.assertRaises(TypeError, lambda: self.other ^ self.set)
if self.otherIsIterable:
self.set.symmetric_difference(self.other)
else:
self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
def test_difference_update_operator(self):
try:
self.set -= self.other
except TypeError:
pass
else:
self.fail("expected TypeError")
def test_difference_update(self):
if self.otherIsIterable:
self.set.difference_update(self.other)
else:
self.assertRaises(TypeError,
self.set.difference_update,
self.other)
def test_difference(self):
self.assertRaises(TypeError, lambda: self.set - self.other)
self.assertRaises(TypeError, lambda: self.other - self.set)
if self.otherIsIterable:
self.set.difference(self.other)
else:
self.assertRaises(TypeError, self.set.difference, self.other)
#------------------------------------------------------------------------------
class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
def setUp(self):
self.set = Set((1, 2, 3))
self.other = 19
self.otherIsIterable = False
#------------------------------------------------------------------------------
class TestOnlySetsDict(TestOnlySetsInBinaryOps):
def setUp(self):
self.set = Set((1, 2, 3))
self.other = {1:2, 3:4}
self.otherIsIterable = True
#------------------------------------------------------------------------------
class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
def setUp(self):
self.set = Set((1, 2, 3))
self.other = operator.add
self.otherIsIterable = False
#------------------------------------------------------------------------------
class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
def setUp(self):
self.set = Set((1, 2, 3))
self.other = (2, 4, 6)
self.otherIsIterable = True
#------------------------------------------------------------------------------
class TestOnlySetsString(TestOnlySetsInBinaryOps):
def setUp(self):
self.set = Set((1, 2, 3))
self.other = 'abc'
self.otherIsIterable = True
#------------------------------------------------------------------------------
class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
def setUp(self):
def gen():
for i in xrange(0, 10, 2):
yield i
self.set = Set((1, 2, 3))
self.other = gen()
self.otherIsIterable = True
#------------------------------------------------------------------------------
class TestOnlySetsofSets(TestOnlySetsInBinaryOps):
def setUp(self):
self.set = Set((1, 2, 3))
self.other = [Set('ab'), ImmutableSet('cd')]
self.otherIsIterable = True
#==============================================================================
class TestCopying(unittest.TestCase):
def test_copy(self):
dup = self.set.copy()
Restructure comparison dramatically. There is no longer a default *ordering* between objects; there is only a default equality test (defined by an object being equal to itself only). Read the comment in object.c. The current implementation never uses a three-way comparison to compute a rich comparison, but it does use a rich comparison to compute a three-way comparison. I'm not quite done ripping out all the calls to PyObject_Compare/Cmp, or replacing tp_compare implementations with tp_richcompare implementations; but much of that has happened (to make most unit tests pass). The following tests still fail, because I need help deciding or understanding: test_codeop -- depends on comparing code objects test_datetime -- need Tim Peters' opinion test_marshal -- depends on comparing code objects test_mutants -- need help understanding it The problem with test_codeop and test_marshal is this: these tests compare two different code objects and expect them to be equal. Is that still a feature we'd like to support? I've temporarily removed the comparison and hash code from code objects, so they use the default (equality by pointer only) comparison. For the other two tests, run them to see for yourself. (There may be more failing test with "-u all".) A general problem with getting lots of these tests to pass is the reality that for object types that have a natural total ordering, implementing __cmp__ is much more convenient than implementing __eq__, __ne__, __lt__, and so on. Should we go back to allowing __cmp__ to provide a total ordering? Should we provide some other way to implement rich comparison with a single method override? Alex proposed a __key__() method; I've considered a __richcmp__() method. Or perhaps __cmp__() just shouldn't be killed off...
2006-08-23 21:41:19 -03:00
dup_list = sorted(dup, key=repr)
set_list = sorted(self.set, key=repr)
2002-08-25 15:02:29 -03:00
self.assertEqual(len(dup_list), len(set_list))
for i in range(len(dup_list)):
2002-08-25 15:02:29 -03:00
self.failUnless(dup_list[i] is set_list[i])
def test_deep_copy(self):
dup = copy.deepcopy(self.set)
##print type(dup), repr(dup)
Restructure comparison dramatically. There is no longer a default *ordering* between objects; there is only a default equality test (defined by an object being equal to itself only). Read the comment in object.c. The current implementation never uses a three-way comparison to compute a rich comparison, but it does use a rich comparison to compute a three-way comparison. I'm not quite done ripping out all the calls to PyObject_Compare/Cmp, or replacing tp_compare implementations with tp_richcompare implementations; but much of that has happened (to make most unit tests pass). The following tests still fail, because I need help deciding or understanding: test_codeop -- depends on comparing code objects test_datetime -- need Tim Peters' opinion test_marshal -- depends on comparing code objects test_mutants -- need help understanding it The problem with test_codeop and test_marshal is this: these tests compare two different code objects and expect them to be equal. Is that still a feature we'd like to support? I've temporarily removed the comparison and hash code from code objects, so they use the default (equality by pointer only) comparison. For the other two tests, run them to see for yourself. (There may be more failing test with "-u all".) A general problem with getting lots of these tests to pass is the reality that for object types that have a natural total ordering, implementing __cmp__ is much more convenient than implementing __eq__, __ne__, __lt__, and so on. Should we go back to allowing __cmp__ to provide a total ordering? Should we provide some other way to implement rich comparison with a single method override? Alex proposed a __key__() method; I've considered a __richcmp__() method. Or perhaps __cmp__() just shouldn't be killed off...
2006-08-23 21:41:19 -03:00
dup_list = sorted(dup, key=repr)
set_list = sorted(self.set, key=repr)
2002-08-25 15:02:29 -03:00
self.assertEqual(len(dup_list), len(set_list))
for i in range(len(dup_list)):
2002-08-25 15:02:29 -03:00
self.assertEqual(dup_list[i], set_list[i])
#------------------------------------------------------------------------------
class TestCopyingEmpty(TestCopying):
def setUp(self):
self.set = Set()
#------------------------------------------------------------------------------
class TestCopyingSingleton(TestCopying):
def setUp(self):
self.set = Set(["hello"])
#------------------------------------------------------------------------------
class TestCopyingTriple(TestCopying):
def setUp(self):
self.set = Set(["zero", 0, None])
#------------------------------------------------------------------------------
class TestCopyingTuple(TestCopying):
def setUp(self):
self.set = Set([(1, 2)])
#------------------------------------------------------------------------------
class TestCopyingNested(TestCopying):
def setUp(self):
self.set = Set([((1, 2), (3, 4))])
#==============================================================================
class TestIdentities(unittest.TestCase):
def setUp(self):
2003-09-21 05:14:11 -03:00
self.a = Set([random.randrange(100) for i in xrange(50)])
self.b = Set([random.randrange(100) for i in xrange(50)])
def test_binopsVsSubsets(self):
a, b = self.a, self.b
2003-09-21 05:14:11 -03:00
self.assert_(a - b <= a)
self.assert_(b - a <= b)
self.assert_(a & b <= a)
self.assert_(a & b <= b)
self.assert_(a | b >= a)
self.assert_(a | b >= b)
self.assert_(a ^ b <= a | b)
def test_commutativity(self):
a, b = self.a, self.b
self.assertEqual(a&b, b&a)
self.assertEqual(a|b, b|a)
self.assertEqual(a^b, b^a)
if a != b:
self.assertNotEqual(a-b, b-a)
2003-09-24 00:56:07 -03:00
def test_reflexsive_relations(self):
a, zero = self.a, Set()
self.assertEqual(a ^ a, zero)
self.assertEqual(a - a, zero)
self.assertEqual(a | a, a)
self.assertEqual(a & a, a)
self.assert_(a <= a)
self.assert_(a >= a)
self.assert_(a == a)
def test_summations(self):
# check that sums of parts equal the whole
a, b = self.a, self.b
self.assertEqual((a-b)|(a&b)|(b-a), a|b)
self.assertEqual((a&b)|(a^b), a|b)
self.assertEqual(a|(b-a), a|b)
self.assertEqual((a-b)|b, a|b)
self.assertEqual((a-b)|(a&b), a)
self.assertEqual((b-a)|(a&b), b)
self.assertEqual((a-b)|(b-a), a^b)
def test_exclusion(self):
2003-09-21 05:14:11 -03:00
# check that inverse operations do not overlap
a, b, zero = self.a, self.b, Set()
self.assertEqual((a-b)&b, zero)
self.assertEqual((b-a)&a, zero)
self.assertEqual((a&b)&(a^b), zero)
2003-09-21 05:14:11 -03:00
def test_cardinality_relations(self):
a, b = self.a, self.b
self.assertEqual(len(a), len(a-b) + len(a&b))
self.assertEqual(len(b), len(b-a) + len(a&b))
self.assertEqual(len(a^b), len(a-b) + len(b-a))
self.assertEqual(len(a|b), len(a-b) + len(a&b) + len(b-a))
2003-09-24 00:56:07 -03:00
self.assertEqual(len(a^b) + len(a&b), len(a|b))
2003-09-21 05:14:11 -03:00
#==============================================================================
libreftest = """
Example from the Library Reference: Doc/lib/libsets.tex
>>> from sets import Set as Base # override _repr to get sorted output
>>> class Set(Base):
... def _repr(self):
... return Base._repr(self, sorted=True)
>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
2003-08-15 21:59:59 -03:00
>>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])
>>> employees = engineers | programmers | managers # union
>>> engineering_management = engineers & managers # intersection
>>> fulltime_management = managers - engineers - programmers # difference
>>> engineers.add('Marvin')
>>> print engineers
Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
>>> employees.issuperset(engineers) # superset test
False
>>> employees.union_update(engineers) # update from another set
>>> employees.issuperset(engineers)
True
2003-08-15 21:59:59 -03:00
>>> for group in [engineers, programmers, managers, employees]:
... group.discard('Susan') # unconditionally remove element
... print group
...
Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
Set(['Jack', 'Janice', 'Sam'])
Set(['Jack', 'Jane', 'Zack'])
Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin', 'Sam', 'Zack'])
"""
#==============================================================================
__test__ = {'libreftest' : libreftest}
def test_main(verbose=None):
import doctest
from test import test_sets
test_support.run_unittest(
TestSetOfSets,
TestExceptionPropagation,
TestBasicOpsEmpty,
TestBasicOpsSingleton,
TestBasicOpsTuple,
TestBasicOpsTriple,
TestBinaryOps,
TestUpdateOps,
TestMutate,
TestSubsetEqualEmpty,
TestSubsetEqualNonEmpty,
TestSubsetEmptyNonEmpty,
TestSubsetPartial,
TestSubsetNonOverlap,
TestOnlySetsNumeric,
TestOnlySetsDict,
TestOnlySetsOperator,
TestOnlySetsTuple,
TestOnlySetsString,
TestOnlySetsGenerator,
TestOnlySetsofSets,
TestCopyingEmpty,
TestCopyingSingleton,
TestCopyingTriple,
TestCopyingTuple,
TestCopyingNested,
TestIdentities,
doctest.DocTestSuite(test_sets),
)
if __name__ == "__main__":
test_main(verbose=True)