220 lines
6.1 KiB
Python
220 lines
6.1 KiB
Python
import sys
|
|
|
|
import py, pytest
|
|
import _pytest.assertion as plugin
|
|
|
|
needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)")
|
|
|
|
def interpret(expr):
|
|
return py.code._reinterpret(expr, py.code.Frame(sys._getframe(1)))
|
|
|
|
class TestBinReprIntegration:
|
|
pytestmark = needsnewassert
|
|
|
|
def pytest_funcarg__hook(self, request):
|
|
class MockHook(object):
|
|
def __init__(self):
|
|
self.called = False
|
|
self.args = tuple()
|
|
self.kwargs = dict()
|
|
|
|
def __call__(self, op, left, right):
|
|
self.called = True
|
|
self.op = op
|
|
self.left = left
|
|
self.right = right
|
|
mockhook = MockHook()
|
|
monkeypatch = request.getfuncargvalue("monkeypatch")
|
|
monkeypatch.setattr(py.code, '_reprcompare', mockhook)
|
|
return mockhook
|
|
|
|
def test_pytest_assertrepr_compare_called(self, hook):
|
|
interpret('assert 0 == 1')
|
|
assert hook.called
|
|
|
|
|
|
def test_pytest_assertrepr_compare_args(self, hook):
|
|
interpret('assert [0, 1] == [0, 2]')
|
|
assert hook.op == '=='
|
|
assert hook.left == [0, 1]
|
|
assert hook.right == [0, 2]
|
|
|
|
def test_configure_unconfigure(self, testdir, hook):
|
|
assert hook == py.code._reprcompare
|
|
config = testdir.parseconfig()
|
|
plugin.pytest_configure(config)
|
|
assert hook != py.code._reprcompare
|
|
plugin.pytest_unconfigure(config)
|
|
assert hook == py.code._reprcompare
|
|
|
|
def callequal(left, right):
|
|
return plugin.pytest_assertrepr_compare('==', left, right)
|
|
|
|
class TestAssert_reprcompare:
|
|
def test_different_types(self):
|
|
assert callequal([0, 1], 'foo') is None
|
|
|
|
def test_summary(self):
|
|
summary = callequal([0, 1], [0, 2])[0]
|
|
assert len(summary) < 65
|
|
|
|
def test_text_diff(self):
|
|
diff = callequal('spam', 'eggs')[1:]
|
|
assert '- spam' in diff
|
|
assert '+ eggs' in diff
|
|
|
|
def test_multiline_text_diff(self):
|
|
left = 'foo\nspam\nbar'
|
|
right = 'foo\neggs\nbar'
|
|
diff = callequal(left, right)
|
|
assert '- spam' in diff
|
|
assert '+ eggs' in diff
|
|
|
|
def test_list(self):
|
|
expl = callequal([0, 1], [0, 2])
|
|
assert len(expl) > 1
|
|
|
|
def test_list_different_lenghts(self):
|
|
expl = callequal([0, 1], [0, 1, 2])
|
|
assert len(expl) > 1
|
|
expl = callequal([0, 1, 2], [0, 1])
|
|
assert len(expl) > 1
|
|
|
|
def test_dict(self):
|
|
expl = callequal({'a': 0}, {'a': 1})
|
|
assert len(expl) > 1
|
|
|
|
def test_set(self):
|
|
expl = callequal(set([0, 1]), set([0, 2]))
|
|
assert len(expl) > 1
|
|
|
|
def test_list_tuples(self):
|
|
expl = callequal([], [(1,2)])
|
|
assert len(expl) > 1
|
|
expl = callequal([(1,2)], [])
|
|
assert len(expl) > 1
|
|
|
|
def test_list_bad_repr(self):
|
|
class A:
|
|
def __repr__(self):
|
|
raise ValueError(42)
|
|
expl = callequal([], [A()])
|
|
assert 'ValueError' in "".join(expl)
|
|
expl = callequal({}, {'1': A()})
|
|
assert 'faulty' in "".join(expl)
|
|
|
|
def test_one_repr_empty(self):
|
|
"""
|
|
the faulty empty string repr did trigger
|
|
a unbound local error in _diff_text
|
|
"""
|
|
class A(str):
|
|
def __repr__(self):
|
|
return ''
|
|
expl = callequal(A(), '')
|
|
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
|
|
def test_pytest_assertrepr_compare_integration(testdir):
|
|
testdir.makepyfile("""
|
|
def test_hello():
|
|
x = set(range(100))
|
|
y = x.copy()
|
|
y.remove(50)
|
|
assert x == y
|
|
""")
|
|
result = testdir.runpytest()
|
|
result.stdout.fnmatch_lines([
|
|
"*def test_hello():*",
|
|
"*assert x == y*",
|
|
"*E*Extra items*left*",
|
|
"*E*50*",
|
|
])
|
|
|
|
@needsnewassert
|
|
def test_sequence_comparison_uses_repr(testdir):
|
|
testdir.makepyfile("""
|
|
def test_hello():
|
|
x = set("hello x")
|
|
y = set("hello y")
|
|
assert x == y
|
|
""")
|
|
result = testdir.runpytest()
|
|
result.stdout.fnmatch_lines([
|
|
"*def test_hello():*",
|
|
"*assert x == y*",
|
|
"*E*Extra items*left*",
|
|
"*E*'x'*",
|
|
"*E*Extra items*right*",
|
|
"*E*'y'*",
|
|
])
|
|
|
|
|
|
def test_functional(testdir):
|
|
testdir.makepyfile("""
|
|
def test_hello():
|
|
x = 3
|
|
assert x == 4
|
|
""")
|
|
result = testdir.runpytest()
|
|
assert "3 == 4" in result.stdout.str()
|
|
result = testdir.runpytest("--no-assert")
|
|
assert "3 == 4" not in result.stdout.str()
|
|
|
|
def test_triple_quoted_string_issue113(testdir):
|
|
testdir.makepyfile("""
|
|
def test_hello():
|
|
assert "" == '''
|
|
'''""")
|
|
result = testdir.runpytest("--fulltrace")
|
|
result.stdout.fnmatch_lines([
|
|
"*1 failed*",
|
|
])
|
|
assert 'SyntaxError' not in result.stdout.str()
|
|
|
|
def test_traceback_failure(testdir):
|
|
p1 = testdir.makepyfile("""
|
|
def g():
|
|
return 2
|
|
def f(x):
|
|
assert x == g()
|
|
def test_onefails():
|
|
f(3)
|
|
""")
|
|
result = testdir.runpytest(p1)
|
|
result.stdout.fnmatch_lines([
|
|
"*test_traceback_failure.py F",
|
|
"====* FAILURES *====",
|
|
"____*____",
|
|
"",
|
|
" def test_onefails():",
|
|
"> f(3)",
|
|
"",
|
|
"*test_*.py:6: ",
|
|
"_ _ _ *",
|
|
#"",
|
|
" def f(x):",
|
|
"> assert x == g()",
|
|
"E assert 3 == 2",
|
|
"E + where 2 = g()",
|
|
"",
|
|
"*test_traceback_failure.py:4: AssertionError"
|
|
])
|
|
|
|
@pytest.mark.skipif("sys.version_info < (2,5) or '__pypy__' in sys.builtin_module_names")
|
|
def test_warn_missing(testdir):
|
|
p1 = testdir.makepyfile("")
|
|
result = testdir.run(sys.executable, "-OO", "-m", "pytest", "-h")
|
|
result.stderr.fnmatch_lines([
|
|
"*WARNING*assertion*",
|
|
])
|
|
result = testdir.run(sys.executable, "-OO", "-m", "pytest", "--no-assert")
|
|
result.stderr.fnmatch_lines([
|
|
"*WARNING*assertion*",
|
|
])
|