import unittest
, operator
, copy
, pickle
, random
from sets
import Set
, ImmutableSet
from test
import test_support
#==============================================================================
class TestBasicOps(unittest
.TestCase
):
if self
.repr is not None:
self
.assertEqual(repr(self
.set), self
.repr)
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
)
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
):
self
.assert_(v
in self
.values
)
p
= pickle
.dumps(self
.set)
self
.assertEqual(self
.set, copy
,
"%s != %s" % (self
.set, copy
))
#------------------------------------------------------------------------------
class TestBasicOpsEmpty(TestBasicOps
):
self
.set = Set(self
.values
)
self
.dup
= Set(self
.values
)
#------------------------------------------------------------------------------
class TestBasicOpsSingleton(TestBasicOps
):
self
.case
= "unit set (number)"
self
.set = Set(self
.values
)
self
.dup
= Set(self
.values
)
self
.failUnless(3 in self
.set)
self
.failUnless(2 not in self
.set)
#------------------------------------------------------------------------------
class TestBasicOpsTuple(TestBasicOps
):
self
.case
= "unit set (tuple)"
self
.values
= [(0, "zero")]
self
.set = Set(self
.values
)
self
.dup
= Set(self
.values
)
self
.repr = "Set([(0, 'zero')])"
self
.failUnless((0, "zero") in self
.set)
self
.failUnless(9 not in self
.set)
#------------------------------------------------------------------------------
class TestBasicOpsTriple(TestBasicOps
):
self
.values
= [0, "zero", operator
.add
]
self
.set = Set(self
.values
)
self
.dup
= Set(self
.values
)
#==============================================================================
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({'one':1, 'two':2, 'three':3})
#==============================================================================
class TestSetOfSets(unittest
.TestCase
):
def test_constructor(self
):
self
.assertEqual(type(element
), ImmutableSet
)
outer
.add(inner
) # Rebuild set of sets with .add method
self
.assertEqual(outer
, Set()) # Verify that remove worked
outer
.discard(inner
) # Absence of KeyError indicates working fine
#==============================================================================
class TestBinaryOps(unittest
.TestCase
):
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]))
a
, b
= Set('a'), Set('b')
self
.assertRaises(TypeError, cmp, a
, b
)
# You can view this as a buglet: cmp(a, a) does not raise TypeError,
# because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
# which Python thinks is good enough to synthesize a cmp() result
# without calling __cmp__.
self
.assertEqual(cmp(a
, a
), 0)
self
.assertRaises(TypeError, cmp, a
, 12)
self
.assertRaises(TypeError, cmp, "abc", a
)
def test_inplace_on_self(self
):
self
.assertEqual(t
, self
.set)
self
.assertEqual(t
, self
.set)
self
.assertEqual(len(t
), 0)
self
.assertEqual(len(t
), 0)
#==============================================================================
class TestUpdateOps(unittest
.TestCase
):
self
.set = Set((2, 4, 6))
def test_union_subset(self
):
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
.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
.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
.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
.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
.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
.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
.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
):
self
.values
= ["a", "b", "c"]
self
.set = Set(self
.values
)
def test_add_present(self
):
self
.assertEqual(self
.set, Set("abc"))
def test_add_absent(self
):
self
.assertEqual(self
.set, Set("abcd"))
def test_add_until_full(self
):
self
.assertEqual(len(tmp
), expected_len
)
self
.assertEqual(tmp
, self
.set)
def test_remove_present(self
):
self
.assertEqual(self
.set, Set("ac"))
def test_remove_absent(self
):
self
.fail("Removing missing element should have raised LookupError")
def test_remove_until_empty(self
):
expected_len
= len(self
.set)
self
.assertEqual(len(self
.set), expected_len
)
def test_discard_present(self
):
self
.assertEqual(self
.set, Set("ab"))
def test_discard_absent(self
):
self
.assertEqual(self
.set, Set("abc"))
self
.assertEqual(len(self
.set), 0)
popped
[self
.set.pop()] = None
self
.assertEqual(len(popped
), len(self
.values
))
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",
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
])
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
])
self
.assertEqual(result
, expected
)
#------------------------------------------------------------------------------
class TestSubsetEqualEmpty(TestSubsets
):
#------------------------------------------------------------------------------
class TestSubsetEqualNonEmpty(TestSubsets
):
#------------------------------------------------------------------------------
class TestSubsetEmptyNonEmpty(TestSubsets
):
name
= "one empty, one non-empty"
#------------------------------------------------------------------------------
class TestSubsetPartial(TestSubsets
):
name
= "one a non-empty proper subset of other"
#------------------------------------------------------------------------------
class TestSubsetNonOverlap(TestSubsets
):
name
= "neither empty, neither contains"
#==============================================================================
class TestOnlySetsInBinaryOps(unittest
.TestCase
):
# 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)
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
)
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
):
self
.fail("expected TypeError")
def test_union_update(self
):
self
.set.union_update(self
.other
)
self
.assertRaises(TypeError, self
.set.union_update
, self
.other
)
self
.assertRaises(TypeError, lambda: self
.set | self
.other
)
self
.assertRaises(TypeError, lambda: self
.other | self
.set)
self
.set.union(self
.other
)
self
.assertRaises(TypeError, self
.set.union
, self
.other
)
def test_intersection_update_operator(self
):
self
.fail("expected TypeError")
def test_intersection_update(self
):
self
.set.intersection_update(self
.other
)
self
.assertRaises(TypeError,
self
.set.intersection_update
,
def test_intersection(self
):
self
.assertRaises(TypeError, lambda: self
.set & self
.other
)
self
.assertRaises(TypeError, lambda: self
.other
& self
.set)
self
.set.intersection(self
.other
)
self
.assertRaises(TypeError, self
.set.intersection
, self
.other
)
def test_sym_difference_update_operator(self
):
self
.fail("expected TypeError")
def test_sym_difference_update(self
):
self
.set.symmetric_difference_update(self
.other
)
self
.assertRaises(TypeError,
self
.set.symmetric_difference_update
,
def test_sym_difference(self
):
self
.assertRaises(TypeError, lambda: self
.set ^ self
.other
)
self
.assertRaises(TypeError, lambda: self
.other ^ self
.set)
self
.set.symmetric_difference(self
.other
)
self
.assertRaises(TypeError, self
.set.symmetric_difference
, self
.other
)
def test_difference_update_operator(self
):
self
.fail("expected TypeError")
def test_difference_update(self
):
self
.set.difference_update(self
.other
)
self
.assertRaises(TypeError,
self
.set.difference_update
,
def test_difference(self
):
self
.assertRaises(TypeError, lambda: self
.set - self
.other
)
self
.assertRaises(TypeError, lambda: self
.other
- self
.set)
self
.set.difference(self
.other
)
self
.assertRaises(TypeError, self
.set.difference
, self
.other
)
#------------------------------------------------------------------------------
class TestOnlySetsNumeric(TestOnlySetsInBinaryOps
):
self
.set = Set((1, 2, 3))
self
.otherIsIterable
= False
#------------------------------------------------------------------------------
class TestOnlySetsDict(TestOnlySetsInBinaryOps
):
self
.set = Set((1, 2, 3))
self
.otherIsIterable
= True
#------------------------------------------------------------------------------
class TestOnlySetsOperator(TestOnlySetsInBinaryOps
):
self
.set = Set((1, 2, 3))
self
.other
= operator
.add
self
.otherIsIterable
= False
#------------------------------------------------------------------------------
class TestOnlySetsTuple(TestOnlySetsInBinaryOps
):
self
.set = Set((1, 2, 3))
self
.otherIsIterable
= True
#------------------------------------------------------------------------------
class TestOnlySetsString(TestOnlySetsInBinaryOps
):
self
.set = Set((1, 2, 3))
self
.otherIsIterable
= True
#------------------------------------------------------------------------------
class TestOnlySetsGenerator(TestOnlySetsInBinaryOps
):
for i
in xrange(0, 10, 2):
self
.set = Set((1, 2, 3))
self
.otherIsIterable
= True
#------------------------------------------------------------------------------
class TestOnlySetsofSets(TestOnlySetsInBinaryOps
):
self
.set = Set((1, 2, 3))
self
.other
= [Set('ab'), ImmutableSet('cd')]
self
.otherIsIterable
= True
#==============================================================================
class TestCopying(unittest
.TestCase
):
dup_list
= list(dup
); dup_list
.sort()
set_list
= list(self
.set); set_list
.sort()
self
.assertEqual(len(dup_list
), len(set_list
))
for i
in range(len(dup_list
)):
self
.failUnless(dup_list
[i
] is set_list
[i
])
def test_deep_copy(self
):
dup
= copy
.deepcopy(self
.set)
##print type(dup), repr(dup)
dup_list
= list(dup
); dup_list
.sort()
set_list
= list(self
.set); set_list
.sort()
self
.assertEqual(len(dup_list
), len(set_list
))
for i
in range(len(dup_list
)):
self
.assertEqual(dup_list
[i
], set_list
[i
])
#------------------------------------------------------------------------------
class TestCopyingEmpty(TestCopying
):
#------------------------------------------------------------------------------
class TestCopyingSingleton(TestCopying
):
self
.set = Set(["hello"])
#------------------------------------------------------------------------------
class TestCopyingTriple(TestCopying
):
self
.set = Set(["zero", 0, None])
#------------------------------------------------------------------------------
class TestCopyingTuple(TestCopying
):
#------------------------------------------------------------------------------
class TestCopyingNested(TestCopying
):
self
.set = Set([((1, 2), (3, 4))])
#==============================================================================
class TestIdentities(unittest
.TestCase
):
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
):
self
.assert_(a ^ b
<= a | b
)
def test_commutativity(self
):
self
.assertEqual(a
&b
, b
&a
)
self
.assertEqual(a|b
, b|a
)
self
.assertEqual(a^b
, b^a
)
self
.assertNotEqual(a
-b
, b
-a
)
def test_reflexsive_relations(self
):
self
.assertEqual(a ^ a
, zero
)
self
.assertEqual(a
- a
, zero
)
self
.assertEqual(a | a
, a
)
self
.assertEqual(a
& a
, a
)
def test_summations(self
):
# check that sums of parts equal the whole
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
):
# 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
)
def test_cardinality_relations(self
):
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
))
self
.assertEqual(len(a^b
) + len(a
&b
), len(a|b
))
#==============================================================================
Example from the Library Reference: Doc/lib/libsets.tex
>>> from sets import Set as Base # override _repr to get sorted output
... return Base._repr(self, sorted=True)
>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
>>> 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')
Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
>>> employees.issuperset(engineers) # superset test
>>> employees.union_update(engineers) # update from another set
>>> employees.issuperset(engineers)
>>> for group in [engineers, programmers, managers, employees]:
... group.discard('Susan') # unconditionally remove element
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 test_sets
, doctest
test_support
.run_unittest(
TestExceptionPropagation
,
doctest
.DocTestSuite(test_sets
),
if __name__
== "__main__":