Add set comparison

Also add a (too) simple mechanism too truncate too long explanations.

--HG--
branch : trunk
This commit is contained in:
Floris Bruynooghe 2010-09-16 01:06:07 +01:00
parent 6fb56443a9
commit 58169edc8e
2 changed files with 46 additions and 13 deletions

View File

@ -30,25 +30,39 @@ def warn_about_missing_assertion():
def pytest_assert_compare(op, left, right): def pytest_assert_compare(op, left, right):
"""Make a specialised explanation for comapare equal""" """Make a specialised explanation for comapare equal"""
if op != '==' or type(left) != type(right): if type(left) != type(right):
return None return None
explanation = []
left_repr = py.io.saferepr(left, maxsize=30) left_repr = py.io.saferepr(left, maxsize=30)
right_repr = py.io.saferepr(right, maxsize=30) right_repr = py.io.saferepr(right, maxsize=30)
explanation += ['%s == %s' % (left_repr, right_repr)] summary = '%s %s %s' % (left_repr, op, right_repr)
issquence = lambda x: isinstance(x, (list, tuple)) issquence = lambda x: isinstance(x, (list, tuple))
istext = lambda x: isinstance(x, basestring) istext = lambda x: isinstance(x, basestring)
isdict = lambda x: isinstance(x, dict) isdict = lambda x: isinstance(x, dict)
if istext(left): isset = lambda: isinstance(left, set)
explanation += [line.strip('\n') for line in
py.std.difflib.ndiff(left.splitlines(), right.splitlines())] explanation = None
elif issquence(left): if op == '==':
explanation += _compare_eq_sequence(left, right) if istext(left):
elif isdict(left): explanation = [line.strip('\n') for line in
explanation += _pprint_diff(left, right) py.std.difflib.ndiff(left.splitlines(),
else: right.splitlines())]
return None # No specialised knowledge elif issquence(left):
return explanation explanation = _compare_eq_sequence(left, right)
elif isset():
explanation = _compare_eq_set(left, right)
elif isdict(left):
explanation = _pprint_diff(left, right)
if not explanation:
return None
# Don't include pageloads of data, should be configurable
if len(''.join(explanation)) > 80*8:
explanation = ['Detailed information too verbose, truncated']
return [summary] + explanation
def _compare_eq_sequence(left, right): def _compare_eq_sequence(left, right):
@ -72,3 +86,18 @@ def _pprint_diff(left, right):
return [line.strip('\n') for line in return [line.strip('\n') for line in
py.std.difflib.ndiff(py.std.pprint.pformat(left).splitlines(), py.std.difflib.ndiff(py.std.pprint.pformat(left).splitlines(),
py.std.pprint.pformat(right).splitlines())] py.std.pprint.pformat(right).splitlines())]
def _compare_eq_set(left, right):
explanation = []
diff_left = left - right
diff_right = right - left
if diff_left:
explanation.append('Extra items in the left set:')
for item in diff_left:
explanation.append(py.io.saferepr(item))
if diff_right:
explanation.append('Extra items in the right set:')
for item in diff_right:
explanation.append(py.io.saferepr(item))
return explanation

View File

@ -81,3 +81,7 @@ class Test_pytest_assert_compare:
def test_dict(self): def test_dict(self):
expl = plugin.pytest_assert_compare('==', {'a': 0}, {'a': 1}) expl = plugin.pytest_assert_compare('==', {'a': 0}, {'a': 1})
assert len(expl) > 1 assert len(expl) > 1
def test_set(self):
expl = plugin.pytest_assert_compare('==', set([0, 1]), set([0, 2]))
assert len(expl) > 1