Issue 7832: renaming unittest.TestCase.assertSameElements to assertItemsEqual and changing behaviour

This commit is contained in:
Michael Foord 2010-03-20 03:00:34 +00:00
parent 2e6d2622bd
commit 98e7b7644b
6 changed files with 144 additions and 68 deletions

View file

@ -8,8 +8,9 @@ import re
import warnings
from . import result
from .util import strclass, safe_repr, sorted_list_difference
from .util import (
strclass, safe_repr, sorted_list_difference, unorderable_list_difference
)
class SkipTest(Exception):
"""
@ -686,10 +687,9 @@ class TestCase(object):
msg: Optional message to use on failure instead of a list of
differences.
For more general containership equality, assertSameElements will work
with things other than sets. This uses ducktyping to support
different types of sets, and is optimized for sets specifically
(parameters must support a difference method).
assertSetEqual uses ducktyping to support different types of sets, and
is optimized for sets specifically (parameters must support a
difference method).
"""
try:
difference1 = set1.difference(set2)
@ -784,42 +784,48 @@ class TestCase(object):
self.fail(self._formatMessage(msg, standardMsg))
def assertSameElements(self, expected_seq, actual_seq, msg=None):
"""An unordered sequence specific comparison.
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.
Duplicate elements are ignored when comparing *expected_seq* and
*actual_seq*. It is the equivalent of ``assertEqual(set(expected),
set(actual))`` but it works with sequences of unhashable objects as
well.
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.
"""
with warnings.catch_warnings():
if sys.py3kwarning:
# Silence Py3k warning raised during the sorting
for _msg in ["dict inequality comparisons",
"builtin_function_or_method order comparisons",
"comparing unequal types"]:
"builtin_function_or_method order comparisons",
"comparing unequal types"]:
warnings.filterwarnings("ignore", _msg, DeprecationWarning)
try:
expected = set(expected_seq)
actual = set(actual_seq)
missing = sorted(expected.difference(actual))
unexpected = sorted(actual.difference(expected))
except TypeError:
# Fall back to slower list-compare if any of the objects are
# not hashable.
expected = sorted(expected_seq)
actual = sorted(actual_seq)
missing, unexpected = sorted_list_difference(expected, actual)
except TypeError:
# Unsortable items (example: set(), complex(), ...)
expected = list(expected_seq)
actual = list(actual_seq)
missing, unexpected = unorderable_list_difference(
expected, actual, ignore_duplicate=False
)
else:
return self.assertSequenceEqual(expected, actual, msg=msg)
errors = []
if missing:
errors.append('Expected, but missing:\n %s' %
safe_repr(missing))
safe_repr(missing))
if unexpected:
errors.append('Unexpected, but present:\n %s' %
safe_repr(unexpected))
safe_repr(unexpected))
if errors:
standardMsg = '\n'.join(errors)
self.fail(self._formatMessage(msg, standardMsg))