summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_unittest.py45
-rw-r--r--Lib/unittest/case.py38
2 files changed, 81 insertions, 2 deletions
diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py
index 453c48d..cf734f7 100644
--- a/Lib/test/test_unittest.py
+++ b/Lib/test/test_unittest.py
@@ -2775,6 +2775,47 @@ class Test_TestCase(TestCase, TestEquality, TestHashing):
self.assertRaises(self.failureException, self.assertSameElements,
[{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 2}])
+
+ def testAssertItemsEqual(self):
+ a = object()
+ self.assertItemsEqual([1, 2, 3], [3, 2, 1])
+ self.assertItemsEqual(['foo', 'bar', 'baz'], ['bar', 'baz', 'foo'])
+ self.assertItemsEqual([a, a, 2, 2, 3], (a, 2, 3, a, 2))
+ self.assertItemsEqual([1, "2", "a", "a"], ["a", "2", True, "a"])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [1, 2] + [3] * 100, [1] * 100 + [2, 3])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [1, "2", "a", "a"], ["a", "2", True, 1])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [10], [10, 11])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [10, 11], [10])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [10, 11, 10], [10, 11])
+
+ # Test that sequences of unhashable objects can be tested for sameness:
+ self.assertItemsEqual([[1, 2], [3, 4], 0], [False, [3, 4], [1, 2]])
+
+ # hashable types, but not orderable
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [], [divmod, 'x', 1, 5j, 2j, frozenset()])
+ # comparing dicts raises a py3k warning
+ self.assertItemsEqual([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}])
+ # comparing heterogenous non-hashable sequences raises a py3k warning
+ self.assertItemsEqual([1, 'x', divmod, []], [divmod, [], 'x', 1])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [], [divmod, [], 'x', 1, 5j, 2j, set()])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [[1]], [[2]])
+
+ # Same elements, but not same sequence length
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [1, 1, 2], [2, 1])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [1, 1, "2", "a", "a"], ["2", "2", True, "a"])
+ self.assertRaises(self.failureException, self.assertItemsEqual,
+ [1, {'b': 2}, None, True], [{'b': 2}, True, None])
+
def testAssertSetEqual(self):
set1 = set()
set2 = set()
@@ -3338,8 +3379,8 @@ class TestLongMessage(TestCase):
"^Missing: 'key'$",
"^Missing: 'key' : oops$"])
- def testAssertSameElements(self):
- self.assertMessages('assertSameElements', ([], [None]),
+ def testAssertItemsEqual(self):
+ self.assertMessages('assertItemsEqual', ([], [None]),
[r"\[None\]$", "^oops$",
r"\[None\]$",
r"\[None\] : oops$"])
diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py
index 8900915..d9f35fe 100644
--- a/Lib/unittest/case.py
+++ b/Lib/unittest/case.py
@@ -838,6 +838,44 @@ class TestCase(object):
standardMsg = '\n'.join(errors)
self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
+ """An unordered sequence / set specific comparison. It asserts that
+ expected_seq and actual_seq contain the same elements. It is
+ the equivalent of::
+
+ self.assertEqual(sorted(expected_seq), sorted(actual_seq))
+
+ Raises with an error message listing which elements of expected_seq
+ are missing from actual_seq and vice versa if any.
+
+ Asserts that each element has the same count in both sequences.
+ Example:
+ - [0, 1, 1] and [1, 0, 1] compare equal.
+ - [0, 0, 1] and [0, 1] compare unequal.
+ """
+ try:
+ expected = sorted(expected_seq)
+ actual = sorted(actual_seq)
+ except TypeError:
+ # Unsortable items (example: set(), complex(), ...)
+ expected = list(expected_seq)
+ actual = list(actual_seq)
+ missing, unexpected = unorderable_list_difference(expected, actual)
+ else:
+ return self.assertSequenceEqual(expected, actual, msg=msg)
+
+ errors = []
+ if missing:
+ errors.append('Expected, but missing:\n %s' %
+ safe_repr(missing))
+ if unexpected:
+ errors.append('Unexpected, but present:\n %s' %
+ safe_repr(unexpected))
+ if errors:
+ standardMsg = '\n'.join(errors)
+ self.fail(self._formatMessage(msg, standardMsg))
+
def assertMultiLineEqual(self, first, second, msg=None):
"""Assert that two multi-line strings are equal."""
self.assert_(isinstance(first, str), (