Rename pytest_assert_compare to pytest_assert_binrepr

Holger prefers to only have one hook and it also turns out that "in"
is actually a ast.Compare node as well too.

This also modifies the pytest_assert_binrepr hook slightly so that
it's more accomodating to other operators then just compare (i.e.
don't bail out as soon as the types of the operands differ).

--HG--
branch : trunk
This commit is contained in:
Floris Bruynooghe 2010-09-22 00:56:39 +01:00
parent b86207a6c1
commit ca84a5e8e0
4 changed files with 29 additions and 28 deletions

View File

@ -184,7 +184,7 @@ class DebugInterpreter(ast.NodeVisitor):
break break
left_explanation, left_result = next_explanation, next_result left_explanation, left_result = next_explanation, next_result
if self._pytesthook: if self._pytesthook:
hook_result = self._pytesthook.pytest_assert_compare( hook_result = self._pytesthook.pytest_assert_binrepr(
op=op_symbol, left=left_result, right=next_result) op=op_symbol, left=left_result, right=next_result)
if hook_result: if hook_result:
for new_expl in hook_result: for new_expl in hook_result:

View File

@ -127,13 +127,14 @@ def pytest_sessionfinish(session, exitstatus):
# hooks for customising the assert methods # hooks for customising the assert methods
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
def pytest_assert_compare(op, left, right): def pytest_assert_binrepr(op, left, right):
"""Customise compare assertion """Customise explanation for binary operators
Return None or an empty list for no custom compare, otherwise Return None or an empty list for no custom explanation, otherwise
return a list of strings. The strings will be joined by newlines return a list of strings. The strings will be joined by newlines
but any newlines *in* as string will be escaped. Note that all but any newlines *in* a string will be escaped. Note that all but
but the first line will be indented sligthly. the first line will be indented sligthly, the intention is for the
first line to be a summary.
""" """
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------

View File

@ -33,32 +33,32 @@ def warn_about_missing_assertion():
" (are you using python -O?)") " (are you using python -O?)")
def pytest_assert_compare(op, left, right): def pytest_assert_binrepr(op, left, right):
"""Make a specialised explanation for comapare equal""" """Make specialised explanations for some operators/operands"""
if type(left) != type(right):
return None
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)
summary = '%s %s %s' % (left_repr, op, right_repr) summary = '%s %s %s' % (left_repr, op, right_repr)
issquence = lambda x: isinstance(x, (list, tuple)) issequence = 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)
isset = lambda: isinstance(left, set) isset = lambda x: isinstance(x, set)
explanation = None explanation = None
if op == '==': if op == '==':
if istext(left): if istext(left) and istext(right):
explanation = [line.strip('\n') for line in explanation = [line.strip('\n') for line in
py.std.difflib.ndiff(left.splitlines(), py.std.difflib.ndiff(left.splitlines(),
right.splitlines())] right.splitlines())]
elif issquence(left): elif issequence(left) and issequence(right):
explanation = _compare_eq_sequence(left, right) explanation = _compare_eq_sequence(left, right)
elif isset(): elif isset(left) and isset(right):
explanation = _compare_eq_set(left, right) explanation = _compare_eq_set(left, right)
elif isdict(left): elif isdict(left) and isdict(right):
explanation = _pprint_diff(left, right) explanation = _pprint_diff(left, right)
elif op == 'in':
# XXX
pass
if not explanation: if not explanation:
return None return None

View File

@ -77,17 +77,17 @@ def test_traceback_failure(testdir):
]) ])
def test_pytest_assert_compare_called(monkeypatch, hook): def test_pytest_assert_binrepr_called(monkeypatch, hook):
monkeypatch.setattr(py._plugin.pytest_assertion, monkeypatch.setattr(py._plugin.pytest_assertion,
'pytest_assert_compare', hook) 'pytest_assert_binrepr', hook)
interpret('assert 0 == 1', getframe()) interpret('assert 0 == 1', getframe())
assert hook.called assert hook.called
def test_pytest_assert_compare_args(monkeypatch, hook): def test_pytest_assert_binrepr_args(monkeypatch, hook):
print hook.called print hook.called
monkeypatch.setattr(py._plugin.pytest_assertion, monkeypatch.setattr(py._plugin.pytest_assertion,
'pytest_assert_compare', hook) 'pytest_assert_binrepr', hook)
interpret('assert [0, 1] == [0, 2]', getframe()) interpret('assert [0, 1] == [0, 2]', getframe())
print hook.called print hook.called
print hook.left print hook.left
@ -99,32 +99,32 @@ def test_pytest_assert_compare_args(monkeypatch, hook):
class TestAssertCompare: class TestAssertCompare:
def test_different_types(self): def test_different_types(self):
assert plugin.pytest_assert_compare('==', [0, 1], 'foo') is None assert plugin.pytest_assert_binrepr('==', [0, 1], 'foo') is None
def test_summary(self): def test_summary(self):
summary = plugin.pytest_assert_compare('==', [0, 1], [0, 2])[0] summary = plugin.pytest_assert_binrepr('==', [0, 1], [0, 2])[0]
assert len(summary) < 65 assert len(summary) < 65
def test_text_diff(self): def test_text_diff(self):
diff = plugin.pytest_assert_compare('==', 'spam', 'eggs')[1:] diff = plugin.pytest_assert_binrepr('==', 'spam', 'eggs')[1:]
assert '- spam' in diff assert '- spam' in diff
assert '+ eggs' in diff assert '+ eggs' in diff
def test_multiline_text_diff(self): def test_multiline_text_diff(self):
left = 'foo\nspam\nbar' left = 'foo\nspam\nbar'
right = 'foo\neggs\nbar' right = 'foo\neggs\nbar'
diff = plugin.pytest_assert_compare('==', left, right) diff = plugin.pytest_assert_binrepr('==', left, right)
assert '- spam' in diff assert '- spam' in diff
assert '+ eggs' in diff assert '+ eggs' in diff
def test_list(self): def test_list(self):
expl = plugin.pytest_assert_compare('==', [0, 1], [0, 2]) expl = plugin.pytest_assert_binrepr('==', [0, 1], [0, 2])
assert len(expl) > 1 assert len(expl) > 1
def test_dict(self): def test_dict(self):
expl = plugin.pytest_assert_compare('==', {'a': 0}, {'a': 1}) expl = plugin.pytest_assert_binrepr('==', {'a': 0}, {'a': 1})
assert len(expl) > 1 assert len(expl) > 1
def test_set(self): def test_set(self):
expl = plugin.pytest_assert_compare('==', set([0, 1]), set([0, 2])) expl = plugin.pytest_assert_binrepr('==', set([0, 1]), set([0, 2]))
assert len(expl) > 1 assert len(expl) > 1