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:
parent
821f493378
commit
8631c1f57a
|
@ -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)
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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("""
|
||||||
|
|
Loading…
Reference in New Issue