Add "not in" to detailed explanations

This simply uses difflib to compare the text without the offending
string to the full text.

Also ensures the summary line uses all space available.  But the
terminal width is still hardcoded.
This commit is contained in:
Floris Bruynooghe 2010-12-10 01:03:26 +00:00
parent 821f493378
commit 8631c1f57a
3 changed files with 35 additions and 2 deletions

View File

@ -50,8 +50,9 @@ except NameError:
def pytest_assertrepr_compare(op, left, right): def pytest_assertrepr_compare(op, left, right):
"""return specialised explanations for some operators/operands""" """return specialised explanations for some operators/operands"""
left_repr = py.io.saferepr(left, maxsize=30) width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op
right_repr = py.io.saferepr(right, maxsize=30) left_repr = py.io.saferepr(left, maxsize=width/2)
right_repr = py.io.saferepr(right, maxsize=width-len(left_repr))
summary = '%s %s %s' % (left_repr, op, right_repr) summary = '%s %s %s' % (left_repr, op, right_repr)
issequence = lambda x: isinstance(x, (list, tuple)) issequence = lambda x: isinstance(x, (list, tuple))
@ -71,6 +72,9 @@ def pytest_assertrepr_compare(op, left, right):
elif isdict(left) and isdict(right): elif isdict(left) and isdict(right):
explanation = _diff_text(py.std.pprint.pformat(left), explanation = _diff_text(py.std.pprint.pformat(left),
py.std.pprint.pformat(right)) py.std.pprint.pformat(right))
elif op == 'not in':
if istext(left) and istext(right):
explanation = _notin_text(left, right)
except py.builtin._sysex: except py.builtin._sysex:
raise raise
except: except:
@ -154,3 +158,11 @@ def _compare_eq_set(left, right):
for item in diff_right: for item in diff_right:
explanation.append(py.io.saferepr(item)) explanation.append(py.io.saferepr(item))
return explanation return explanation
def _notin_text(term, text):
index = text.find(term)
head = text[:index]
tail = text[index+len(term):]
correct_text = head + tail
return _diff_text(correct_text, text)

View File

@ -77,6 +77,22 @@ class TestSpecialisedExplanations(object):
def test_in_list(self): def test_in_list(self):
assert 1 in [0, 2, 3, 4, 5] assert 1 in [0, 2, 3, 4, 5]
def test_not_in_text_multiline(self):
text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail'
assert 'foo' not in text
def test_not_in_text_single(self):
text = 'single foo line'
assert 'foo' not in text
def test_not_in_text_single_long(self):
text = 'head ' * 50 + 'foo ' + 'tail ' * 20
assert 'foo' not in text
def test_not_in_text_single_long_term(self):
text = 'head ' * 50 + 'f'*70 + 'tail ' * 20
assert 'f'*70 not in text
def test_attribute(): def test_attribute():
class Foo(object): class Foo(object):

View File

@ -114,6 +114,11 @@ class TestAssert_reprcompare:
expl = callequal(A(), '') expl = callequal(A(), '')
assert not expl assert not expl
def test_reprcompare_notin():
detail = plugin.pytest_assertrepr_compare('not in', 'foo', 'aaafoobbb')[1:]
assert '- aaabbb' in detail
assert '+ aaafoobbb' in detail
@needsnewassert @needsnewassert
def test_pytest_assertrepr_compare_integration(testdir): def test_pytest_assertrepr_compare_integration(testdir):
testdir.makepyfile(""" testdir.makepyfile("""