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:
parent
b86207a6c1
commit
ca84a5e8e0
|
@ -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:
|
||||||
|
|
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue