pytester: align prefixes
This is important for using another match_nickname, e.g. "re.match". TODO: - [ ] changelog - [ ] test
This commit is contained in:
parent
978c7ae1b7
commit
8ef4287bf0
|
@ -0,0 +1 @@
|
||||||
|
Align prefixes in output of pytester's ``LineMatcher``.
|
|
@ -1344,7 +1344,6 @@ class LineMatcher:
|
||||||
pattern
|
pattern
|
||||||
:param str match_nickname: the nickname for the match function that
|
:param str match_nickname: the nickname for the match function that
|
||||||
will be logged to stdout when a match occurs
|
will be logged to stdout when a match occurs
|
||||||
|
|
||||||
"""
|
"""
|
||||||
assert isinstance(lines2, Sequence)
|
assert isinstance(lines2, Sequence)
|
||||||
lines2 = self._getlines(lines2)
|
lines2 = self._getlines(lines2)
|
||||||
|
@ -1352,6 +1351,7 @@ class LineMatcher:
|
||||||
nextline = None
|
nextline = None
|
||||||
extralines = []
|
extralines = []
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
|
wnick = len(match_nickname) + 1
|
||||||
for line in lines2:
|
for line in lines2:
|
||||||
nomatchprinted = False
|
nomatchprinted = False
|
||||||
while lines1:
|
while lines1:
|
||||||
|
@ -1361,17 +1361,21 @@ class LineMatcher:
|
||||||
break
|
break
|
||||||
elif match_func(nextline, line):
|
elif match_func(nextline, line):
|
||||||
self._log("%s:" % match_nickname, repr(line))
|
self._log("%s:" % match_nickname, repr(line))
|
||||||
self._log(" with:", repr(nextline))
|
self._log(
|
||||||
|
"{:>{width}}".format("with:", width=wnick), repr(nextline)
|
||||||
|
)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if not nomatchprinted:
|
if not nomatchprinted:
|
||||||
self._log("nomatch:", repr(line))
|
self._log(
|
||||||
|
"{:>{width}}".format("nomatch:", width=wnick), repr(line)
|
||||||
|
)
|
||||||
nomatchprinted = True
|
nomatchprinted = True
|
||||||
self._log(" and:", repr(nextline))
|
self._log("{:>{width}}".format("and:", width=wnick), repr(nextline))
|
||||||
extralines.append(nextline)
|
extralines.append(nextline)
|
||||||
else:
|
else:
|
||||||
self._log("remains unmatched: {!r}".format(line))
|
self._log("remains unmatched: {!r}".format(line))
|
||||||
pytest.fail(self._log_text)
|
pytest.fail(self._log_text.lstrip())
|
||||||
|
|
||||||
def no_fnmatch_line(self, pat):
|
def no_fnmatch_line(self, pat):
|
||||||
"""Ensure captured lines do not match the given pattern, using ``fnmatch.fnmatch``.
|
"""Ensure captured lines do not match the given pattern, using ``fnmatch.fnmatch``.
|
||||||
|
@ -1396,16 +1400,19 @@ class LineMatcher:
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
nomatch_printed = False
|
nomatch_printed = False
|
||||||
|
wnick = len(match_nickname) + 1
|
||||||
try:
|
try:
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
if match_func(line, pat):
|
if match_func(line, pat):
|
||||||
self._log("%s:" % match_nickname, repr(pat))
|
self._log("%s:" % match_nickname, repr(pat))
|
||||||
self._log(" with:", repr(line))
|
self._log("{:>{width}}".format("with:", width=wnick), repr(line))
|
||||||
pytest.fail(self._log_text)
|
pytest.fail(self._log_text.lstrip())
|
||||||
else:
|
else:
|
||||||
if not nomatch_printed:
|
if not nomatch_printed:
|
||||||
self._log("nomatch:", repr(pat))
|
self._log(
|
||||||
|
"{:>{width}}".format("nomatch:", width=wnick), repr(pat)
|
||||||
|
)
|
||||||
nomatch_printed = True
|
nomatch_printed = True
|
||||||
self._log(" and:", repr(line))
|
self._log("{:>{width}}".format("and:", width=wnick), repr(line))
|
||||||
finally:
|
finally:
|
||||||
self._log_output = []
|
self._log_output = []
|
||||||
|
|
|
@ -457,16 +457,39 @@ def test_linematcher_with_nonlist():
|
||||||
assert lm._getlines(set()) == set()
|
assert lm._getlines(set()) == set()
|
||||||
|
|
||||||
|
|
||||||
|
def test_linematcher_match_failure():
|
||||||
|
lm = LineMatcher(["foo", "foo", "bar"])
|
||||||
|
with pytest.raises(pytest.fail.Exception) as e:
|
||||||
|
lm.fnmatch_lines(["foo", "f*", "baz"])
|
||||||
|
assert e.value.msg.splitlines() == [
|
||||||
|
"exact match: 'foo'",
|
||||||
|
"fnmatch: 'f*'",
|
||||||
|
" with: 'foo'",
|
||||||
|
"nomatch: 'baz'",
|
||||||
|
" and: 'bar'",
|
||||||
|
"remains unmatched: 'baz'",
|
||||||
|
]
|
||||||
|
|
||||||
|
lm = LineMatcher(["foo", "foo", "bar"])
|
||||||
|
with pytest.raises(pytest.fail.Exception) as e:
|
||||||
|
lm.re_match_lines(["foo", "^f.*", "baz"])
|
||||||
|
assert e.value.msg.splitlines() == [
|
||||||
|
"exact match: 'foo'",
|
||||||
|
"re.match: '^f.*'",
|
||||||
|
" with: 'foo'",
|
||||||
|
" nomatch: 'baz'",
|
||||||
|
" and: 'bar'",
|
||||||
|
"remains unmatched: 'baz'",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("function", ["no_fnmatch_line", "no_re_match_line"])
|
@pytest.mark.parametrize("function", ["no_fnmatch_line", "no_re_match_line"])
|
||||||
def test_no_matching(function):
|
def test_no_matching(function):
|
||||||
""""""
|
|
||||||
if function == "no_fnmatch_line":
|
if function == "no_fnmatch_line":
|
||||||
match_func_name = "fnmatch"
|
|
||||||
good_pattern = "*.py OK*"
|
good_pattern = "*.py OK*"
|
||||||
bad_pattern = "*X.py OK*"
|
bad_pattern = "*X.py OK*"
|
||||||
else:
|
else:
|
||||||
assert function == "no_re_match_line"
|
assert function == "no_re_match_line"
|
||||||
match_func_name = "re.match"
|
|
||||||
good_pattern = r".*py OK"
|
good_pattern = r".*py OK"
|
||||||
bad_pattern = r".*Xpy OK"
|
bad_pattern = r".*Xpy OK"
|
||||||
|
|
||||||
|
@ -480,24 +503,30 @@ def test_no_matching(function):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
def check_failure_lines(lines):
|
|
||||||
expected = [
|
|
||||||
"nomatch: '{}'".format(good_pattern),
|
|
||||||
" and: 'cachedir: .pytest_cache'",
|
|
||||||
" and: 'collecting ... collected 1 item'",
|
|
||||||
" and: ''",
|
|
||||||
"{}: '{}'".format(match_func_name, good_pattern),
|
|
||||||
" with: 'show_fixtures_per_test.py OK'",
|
|
||||||
]
|
|
||||||
assert lines == expected
|
|
||||||
|
|
||||||
# check the function twice to ensure we don't accumulate the internal buffer
|
# check the function twice to ensure we don't accumulate the internal buffer
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
with pytest.raises(pytest.fail.Exception) as e:
|
with pytest.raises(pytest.fail.Exception) as e:
|
||||||
func = getattr(lm, function)
|
func = getattr(lm, function)
|
||||||
func(good_pattern)
|
func(good_pattern)
|
||||||
obtained = str(e.value).splitlines()
|
obtained = str(e.value).splitlines()
|
||||||
check_failure_lines(obtained)
|
if function == "no_fnmatch_line":
|
||||||
|
assert obtained == [
|
||||||
|
"nomatch: '{}'".format(good_pattern),
|
||||||
|
" and: 'cachedir: .pytest_cache'",
|
||||||
|
" and: 'collecting ... collected 1 item'",
|
||||||
|
" and: ''",
|
||||||
|
"fnmatch: '{}'".format(good_pattern),
|
||||||
|
" with: 'show_fixtures_per_test.py OK'",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
assert obtained == [
|
||||||
|
"nomatch: '{}'".format(good_pattern),
|
||||||
|
" and: 'cachedir: .pytest_cache'",
|
||||||
|
" and: 'collecting ... collected 1 item'",
|
||||||
|
" and: ''",
|
||||||
|
"re.match: '{}'".format(good_pattern),
|
||||||
|
" with: 'show_fixtures_per_test.py OK'",
|
||||||
|
]
|
||||||
|
|
||||||
func = getattr(lm, function)
|
func = getattr(lm, function)
|
||||||
func(bad_pattern) # bad pattern does not match any line: passes
|
func(bad_pattern) # bad pattern does not match any line: passes
|
||||||
|
|
Loading…
Reference in New Issue