assertSortedEqual: fixed sort of nested lists, switch default of nestedOnly to False (comparison of unsorted lists is rarely needed)

pull/2814/head
sebres 2020-05-25 13:36:09 +02:00
parent 54b2208690
commit fa1ff4c5d8
2 changed files with 19 additions and 4 deletions

View File

@ -390,7 +390,15 @@ class TestsUtilsTest(LogCaptureTestCase):
self.assertSortedEqual(['Z', {'A': ['B', 'C'], 'B': ['E', 'F']}], [{'B': ['F', 'E'], 'A': ['C', 'B']}, 'Z'], self.assertSortedEqual(['Z', {'A': ['B', 'C'], 'B': ['E', 'F']}], [{'B': ['F', 'E'], 'A': ['C', 'B']}, 'Z'],
level=-1) level=-1)
self.assertRaises(AssertionError, lambda: self.assertSortedEqual( self.assertRaises(AssertionError, lambda: self.assertSortedEqual(
['Z', {'A': ['B', 'C'], 'B': ['E', 'F']}], [{'B': ['F', 'E'], 'A': ['C', 'B']}, 'Z'])) ['Z', {'A': ['B', 'C'], 'B': ['E', 'F']}], [{'B': ['F', 'E'], 'A': ['C', 'B']}, 'Z'],
nestedOnly=True))
self.assertSortedEqual(
(0, [['A1'], ['A2', 'A1'], []]),
(0, [['A1'], ['A1', 'A2'], []]),
)
self.assertSortedEqual(list('ABC'), list('CBA'))
self.assertRaises(AssertionError, self.assertSortedEqual, ['ABC'], ['CBA'])
self.assertRaises(AssertionError, self.assertSortedEqual, [['ABC']], [['CBA']])
self._testAssertionErrorRE(r"\['A'\] != \['C', 'B'\]", self._testAssertionErrorRE(r"\['A'\] != \['C', 'B'\]",
self.assertSortedEqual, ['A'], ['C', 'B']) self.assertSortedEqual, ['A'], ['C', 'B'])
self._testAssertionErrorRE(r"\['A', 'B'\] != \['B', 'C'\]", self._testAssertionErrorRE(r"\['A', 'B'\] != \['B', 'C'\]",

View File

@ -556,7 +556,7 @@ if not hasattr(unittest.TestCase, 'assertDictEqual'):
self.fail(msg) self.fail(msg)
unittest.TestCase.assertDictEqual = assertDictEqual unittest.TestCase.assertDictEqual = assertDictEqual
def assertSortedEqual(self, a, b, level=1, nestedOnly=True, key=repr, msg=None): def assertSortedEqual(self, a, b, level=1, nestedOnly=False, key=repr, msg=None):
"""Compare complex elements (like dict, list or tuple) in sorted order until """Compare complex elements (like dict, list or tuple) in sorted order until
level 0 not reached (initial level = -1 meant all levels), level 0 not reached (initial level = -1 meant all levels),
or if nestedOnly set to True and some of the objects still contains nested lists or dicts. or if nestedOnly set to True and some of the objects still contains nested lists or dicts.
@ -566,6 +566,13 @@ def assertSortedEqual(self, a, b, level=1, nestedOnly=True, key=repr, msg=None):
if isinstance(v, dict): if isinstance(v, dict):
return any(isinstance(v, (dict, list, tuple)) for v in v.itervalues()) return any(isinstance(v, (dict, list, tuple)) for v in v.itervalues())
return any(isinstance(v, (dict, list, tuple)) for v in v) return any(isinstance(v, (dict, list, tuple)) for v in v)
if nestedOnly:
_nest_sorted = sorted
else:
def _nest_sorted(v, key=key):
if isinstance(v, (set, list, tuple)):
return sorted(list(_nest_sorted(v, key) for v in v), key=key)
return v
# level comparison routine: # level comparison routine:
def _assertSortedEqual(a, b, level, nestedOnly, key): def _assertSortedEqual(a, b, level, nestedOnly, key):
# first the lengths: # first the lengths:
@ -584,8 +591,8 @@ def assertSortedEqual(self, a, b, level=1, nestedOnly=True, key=repr, msg=None):
elif v1 != v2: elif v1 != v2:
raise ValueError('%r != %r' % (a, b)) raise ValueError('%r != %r' % (a, b))
else: # list, tuple, something iterable: else: # list, tuple, something iterable:
a = sorted(a, key=key) a = _nest_sorted(a, key=key)
b = sorted(b, key=key) b = _nest_sorted(b, key=key)
for v1, v2 in zip(a, b): for v1, v2 in zip(a, b):
if isinstance(v1, (dict, list, tuple)) and isinstance(v2, (dict, list, tuple)): if isinstance(v1, (dict, list, tuple)) and isinstance(v2, (dict, list, tuple)):
_assertSortedEqual(v1, v2, level-1 if level != 0 else 0, nestedOnly, key) _assertSortedEqual(v1, v2, level-1 if level != 0 else 0, nestedOnly, key)