Look up the pytest_assertrepr_compare hook for each test item
Before this was only done at the time the assertion plugin was loaded. This lead to counter-intuitive behaviour where two subdirectories with a pytest_assertrepr_compare hook in their conftest.py would not work, only one would ever be used. This defers assiging the _pytest.assertion.util._reprcompare function until the item is loaded (pytest_runtest_setup) so that it can use the hookrelay of the test item to find the appropriate pytest_assertrepr_compare hook for the item. This fixes issue #77.
This commit is contained in:
parent
45b98d6e70
commit
e2201fe3a9
|
@ -43,23 +43,10 @@ def pytest_configure(config):
|
||||||
mode = "reinterp"
|
mode = "reinterp"
|
||||||
if mode != "plain":
|
if mode != "plain":
|
||||||
_load_modules(mode)
|
_load_modules(mode)
|
||||||
def callbinrepr(op, left, right):
|
|
||||||
hook_result = config.hook.pytest_assertrepr_compare(
|
|
||||||
config=config, op=op, left=left, right=right)
|
|
||||||
for new_expl in hook_result:
|
|
||||||
if new_expl:
|
|
||||||
res = '\n~'.join(new_expl)
|
|
||||||
if mode == "rewrite":
|
|
||||||
# The result will be fed back a python % formatting
|
|
||||||
# operation, which will fail if there are extraneous
|
|
||||||
# '%'s in the string. Escape them here.
|
|
||||||
res = res.replace("%", "%%")
|
|
||||||
return res
|
|
||||||
m = monkeypatch()
|
m = monkeypatch()
|
||||||
config._cleanup.append(m.undo)
|
config._cleanup.append(m.undo)
|
||||||
m.setattr(py.builtin.builtins, 'AssertionError',
|
m.setattr(py.builtin.builtins, 'AssertionError',
|
||||||
reinterpret.AssertionError)
|
reinterpret.AssertionError)
|
||||||
m.setattr(util, '_reprcompare', callbinrepr)
|
|
||||||
hook = None
|
hook = None
|
||||||
if mode == "rewrite":
|
if mode == "rewrite":
|
||||||
hook = rewrite.AssertionRewritingHook()
|
hook = rewrite.AssertionRewritingHook()
|
||||||
|
@ -82,6 +69,24 @@ def pytest_collection(session):
|
||||||
if hook is not None:
|
if hook is not None:
|
||||||
hook.set_session(session)
|
hook.set_session(session)
|
||||||
|
|
||||||
|
def pytest_runtest_setup(item):
|
||||||
|
def callbinrepr(op, left, right):
|
||||||
|
hook_result = item.ihook.pytest_assertrepr_compare(
|
||||||
|
config=item.config, op=op, left=left, right=right)
|
||||||
|
for new_expl in hook_result:
|
||||||
|
if new_expl:
|
||||||
|
res = '\n~'.join(new_expl)
|
||||||
|
if item.config.getvalue("assertmode") == "rewrite":
|
||||||
|
# The result will be fed back a python % formatting
|
||||||
|
# operation, which will fail if there are extraneous
|
||||||
|
# '%'s in the string. Escape them here.
|
||||||
|
res = res.replace("%", "%%")
|
||||||
|
return res
|
||||||
|
util._reprcompare = callbinrepr
|
||||||
|
|
||||||
|
def pytest_runtest_teardown(item):
|
||||||
|
util._reprcompare = None
|
||||||
|
|
||||||
def pytest_sessionfinish(session):
|
def pytest_sessionfinish(session):
|
||||||
hook = session.config._assertstate.hook
|
hook = session.config._assertstate.hook
|
||||||
if hook is not None:
|
if hook is not None:
|
||||||
|
|
|
@ -40,15 +40,6 @@ class TestBinReprIntegration:
|
||||||
assert hook.left == [0, 1]
|
assert hook.left == [0, 1]
|
||||||
assert hook.right == [0, 2]
|
assert hook.right == [0, 2]
|
||||||
|
|
||||||
def test_configure_unconfigure(self, testdir, hook):
|
|
||||||
assert hook == util._reprcompare
|
|
||||||
config = testdir.parseconfig()
|
|
||||||
plugin.pytest_configure(config)
|
|
||||||
assert hook != util._reprcompare
|
|
||||||
from _pytest.config import pytest_unconfigure
|
|
||||||
pytest_unconfigure(config)
|
|
||||||
assert hook == util._reprcompare
|
|
||||||
|
|
||||||
def callequal(left, right):
|
def callequal(left, right):
|
||||||
return plugin.pytest_assertrepr_compare('==', left, right)
|
return plugin.pytest_assertrepr_compare('==', left, right)
|
||||||
|
|
||||||
|
@ -167,6 +158,28 @@ def test_sequence_comparison_uses_repr(testdir):
|
||||||
"*E*'y'*",
|
"*E*'y'*",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@needsnewassert
|
||||||
|
def test_assertrepr_loaded_per_dir(testdir):
|
||||||
|
testdir.makepyfile(test_base=['def test_base(): assert 1 == 2'])
|
||||||
|
a = testdir.mkdir('a')
|
||||||
|
a_test = a.join('test_a.py')
|
||||||
|
a_test.write('def test_a(): assert 1 == 2')
|
||||||
|
a_conftest = a.join('conftest.py')
|
||||||
|
a_conftest.write('def pytest_assertrepr_compare(): return ["summary a"]')
|
||||||
|
b = testdir.mkdir('b')
|
||||||
|
b_test = b.join('test_b.py')
|
||||||
|
b_test.write('def test_b(): assert 1 == 2')
|
||||||
|
b_conftest = b.join('conftest.py')
|
||||||
|
b_conftest.write('def pytest_assertrepr_compare(): return ["summary b"]')
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines([
|
||||||
|
'*def test_base():*',
|
||||||
|
'*E*assert 1 == 2*',
|
||||||
|
'*def test_a():*',
|
||||||
|
'*E*assert summary a*',
|
||||||
|
'*def test_b():*',
|
||||||
|
'*E*assert summary b*'])
|
||||||
|
|
||||||
|
|
||||||
def test_assertion_options(testdir):
|
def test_assertion_options(testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
|
|
Loading…
Reference in New Issue