diff --git a/testing/test_skipping.py b/testing/test_skipping.py index 4782e7065..fb0822f8f 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -1177,75 +1177,3 @@ def test_summary_list_after_errors(testdir): "FAILED test_summary_list_after_errors.py::test_fail - assert 0", ] ) - - -def test_line_with_reprcrash(monkeypatch): - import _pytest.skipping - from _pytest.skipping import _get_line_with_reprcrash_message - from wcwidth import wcswidth - - mocked_verbose_word = "FAILED" - - def mock_get_report_str(*args): - return mocked_verbose_word - - monkeypatch.setattr(_pytest.skipping, "_get_report_str", mock_get_report_str) - - mocked_pos = "some::nodeid" - - def mock_get_pos(*args): - return mocked_pos - - monkeypatch.setattr(_pytest.skipping, "_get_pos", mock_get_pos) - - class config: - pass - - class rep: - class longrepr: - class reprcrash: - pass - - def check(msg, width, expected): - __tracebackhide__ = True - if msg: - rep.longrepr.reprcrash.message = msg - actual = _get_line_with_reprcrash_message(config, rep, width) - - assert actual == expected - if actual != "%s %s" % (mocked_verbose_word, mocked_pos): - assert len(actual) <= width - assert wcswidth(actual) <= width - - # AttributeError with message - check(None, 80, "FAILED some::nodeid") - - check("msg", 80, "FAILED some::nodeid - msg") - check("msg", 3, "FAILED some::nodeid") - - check("msg", 24, "FAILED some::nodeid") - check("msg", 25, "FAILED some::nodeid - msg") - - check("some longer msg", 24, "FAILED some::nodeid") - check("some longer msg", 25, "FAILED some::nodeid - ...") - check("some longer msg", 26, "FAILED some::nodeid - s...") - - check("some\nmessage", 25, "FAILED some::nodeid - ...") - check("some\nmessage", 26, "FAILED some::nodeid - some") - check("some\nmessage", 80, "FAILED some::nodeid - some") - - # Test unicode safety. - check(u"😄😄😄😄😄\n2nd line", 25, u"FAILED some::nodeid - ...") - check(u"😄😄😄😄😄\n2nd line", 26, u"FAILED some::nodeid - ...") - check(u"😄😄😄😄😄\n2nd line", 27, u"FAILED some::nodeid - 😄...") - check(u"😄😄😄😄😄\n2nd line", 28, u"FAILED some::nodeid - 😄...") - check(u"😄😄😄😄😄\n2nd line", 29, u"FAILED some::nodeid - 😄😄...") - - # NOTE: constructed, not sure if this is supported. - # It would fail if not using u"" in Python 2 for mocked_pos. - mocked_pos = u"nodeid::😄::withunicode" - check(u"😄😄😄😄😄\n2nd line", 29, u"FAILED nodeid::😄::withunicode") - check(u"😄😄😄😄😄\n2nd line", 40, u"FAILED nodeid::😄::withunicode - 😄😄...") - check(u"😄😄😄😄😄\n2nd line", 41, u"FAILED nodeid::😄::withunicode - 😄😄...") - check(u"😄😄😄😄😄\n2nd line", 42, u"FAILED nodeid::😄::withunicode - 😄😄😄...") - check(u"😄😄😄😄😄\n2nd line", 80, u"FAILED nodeid::😄::withunicode - 😄😄😄😄😄") diff --git a/testing/test_terminal.py b/testing/test_terminal.py index ee546a4a1..cf0faf5c3 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -17,6 +17,7 @@ import pytest from _pytest.main import EXIT_NOTESTSCOLLECTED from _pytest.reports import BaseReport from _pytest.terminal import _folded_skips +from _pytest.terminal import _get_line_with_reprcrash_message from _pytest.terminal import _plugin_nameversions from _pytest.terminal import build_summary_stats_line from _pytest.terminal import getreportopt @@ -1582,3 +1583,72 @@ def test_skip_reasons_folding(): assert fspath == path assert lineno == lineno assert reason == message + + +def test_line_with_reprcrash(monkeypatch): + import _pytest.terminal + from wcwidth import wcswidth + + mocked_verbose_word = "FAILED" + + mocked_pos = "some::nodeid" + + def mock_get_pos(*args): + return mocked_pos + + monkeypatch.setattr(_pytest.terminal, "_get_pos", mock_get_pos) + + class config: + pass + + class rep: + def _get_verbose_word(self, *args): + return mocked_verbose_word + + class longrepr: + class reprcrash: + pass + + def check(msg, width, expected): + __tracebackhide__ = True + if msg: + rep.longrepr.reprcrash.message = msg + actual = _get_line_with_reprcrash_message(config, rep, width) + + assert actual == expected + if actual != "%s %s" % (mocked_verbose_word, mocked_pos): + assert len(actual) <= width + assert wcswidth(actual) <= width + + # AttributeError with message + check(None, 80, "FAILED some::nodeid") + + check("msg", 80, "FAILED some::nodeid - msg") + check("msg", 3, "FAILED some::nodeid") + + check("msg", 24, "FAILED some::nodeid") + check("msg", 25, "FAILED some::nodeid - msg") + + check("some longer msg", 24, "FAILED some::nodeid") + check("some longer msg", 25, "FAILED some::nodeid - ...") + check("some longer msg", 26, "FAILED some::nodeid - s...") + + check("some\nmessage", 25, "FAILED some::nodeid - ...") + check("some\nmessage", 26, "FAILED some::nodeid - some") + check("some\nmessage", 80, "FAILED some::nodeid - some") + + # Test unicode safety. + check(u"😄😄😄😄😄\n2nd line", 25, u"FAILED some::nodeid - ...") + check(u"😄😄😄😄😄\n2nd line", 26, u"FAILED some::nodeid - ...") + check(u"😄😄😄😄😄\n2nd line", 27, u"FAILED some::nodeid - 😄...") + check(u"😄😄😄😄😄\n2nd line", 28, u"FAILED some::nodeid - 😄...") + check(u"😄😄😄😄😄\n2nd line", 29, u"FAILED some::nodeid - 😄😄...") + + # NOTE: constructed, not sure if this is supported. + # It would fail if not using u"" in Python 2 for mocked_pos. + mocked_pos = u"nodeid::😄::withunicode" + check(u"😄😄😄😄😄\n2nd line", 29, u"FAILED nodeid::😄::withunicode") + check(u"😄😄😄😄😄\n2nd line", 40, u"FAILED nodeid::😄::withunicode - 😄😄...") + check(u"😄😄😄😄😄\n2nd line", 41, u"FAILED nodeid::😄::withunicode - 😄😄...") + check(u"😄😄😄😄😄\n2nd line", 42, u"FAILED nodeid::😄::withunicode - 😄😄😄...") + check(u"😄😄😄😄😄\n2nd line", 80, u"FAILED nodeid::😄::withunicode - 😄😄😄😄😄")