Skip to content

Commit 8ef4287

Browse files
committed
pytester: align prefixes
This is important for using another match_nickname, e.g. "re.match". TODO: - [ ] changelog - [ ] test
1 parent 978c7ae commit 8ef4287

File tree

3 files changed

+61
-24
lines changed

3 files changed

+61
-24
lines changed

changelog/6026.improvement.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Align prefixes in output of pytester's ``LineMatcher``.

src/_pytest/pytester.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,14 +1344,14 @@ def _match_lines(self, lines2, match_func, match_nickname):
13441344
pattern
13451345
:param str match_nickname: the nickname for the match function that
13461346
will be logged to stdout when a match occurs
1347-
13481347
"""
13491348
assert isinstance(lines2, Sequence)
13501349
lines2 = self._getlines(lines2)
13511350
lines1 = self.lines[:]
13521351
nextline = None
13531352
extralines = []
13541353
__tracebackhide__ = True
1354+
wnick = len(match_nickname) + 1
13551355
for line in lines2:
13561356
nomatchprinted = False
13571357
while lines1:
@@ -1361,17 +1361,21 @@ def _match_lines(self, lines2, match_func, match_nickname):
13611361
break
13621362
elif match_func(nextline, line):
13631363
self._log("%s:" % match_nickname, repr(line))
1364-
self._log(" with:", repr(nextline))
1364+
self._log(
1365+
"{:>{width}}".format("with:", width=wnick), repr(nextline)
1366+
)
13651367
break
13661368
else:
13671369
if not nomatchprinted:
1368-
self._log("nomatch:", repr(line))
1370+
self._log(
1371+
"{:>{width}}".format("nomatch:", width=wnick), repr(line)
1372+
)
13691373
nomatchprinted = True
1370-
self._log(" and:", repr(nextline))
1374+
self._log("{:>{width}}".format("and:", width=wnick), repr(nextline))
13711375
extralines.append(nextline)
13721376
else:
13731377
self._log("remains unmatched: {!r}".format(line))
1374-
pytest.fail(self._log_text)
1378+
pytest.fail(self._log_text.lstrip())
13751379

13761380
def no_fnmatch_line(self, pat):
13771381
"""Ensure captured lines do not match the given pattern, using ``fnmatch.fnmatch``.
@@ -1396,16 +1400,19 @@ def _no_match_line(self, pat, match_func, match_nickname):
13961400
"""
13971401
__tracebackhide__ = True
13981402
nomatch_printed = False
1403+
wnick = len(match_nickname) + 1
13991404
try:
14001405
for line in self.lines:
14011406
if match_func(line, pat):
14021407
self._log("%s:" % match_nickname, repr(pat))
1403-
self._log(" with:", repr(line))
1404-
pytest.fail(self._log_text)
1408+
self._log("{:>{width}}".format("with:", width=wnick), repr(line))
1409+
pytest.fail(self._log_text.lstrip())
14051410
else:
14061411
if not nomatch_printed:
1407-
self._log("nomatch:", repr(pat))
1412+
self._log(
1413+
"{:>{width}}".format("nomatch:", width=wnick), repr(pat)
1414+
)
14081415
nomatch_printed = True
1409-
self._log(" and:", repr(line))
1416+
self._log("{:>{width}}".format("and:", width=wnick), repr(line))
14101417
finally:
14111418
self._log_output = []

testing/test_pytester.py

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -457,16 +457,39 @@ def test_linematcher_with_nonlist():
457457
assert lm._getlines(set()) == set()
458458

459459

460+
def test_linematcher_match_failure():
461+
lm = LineMatcher(["foo", "foo", "bar"])
462+
with pytest.raises(pytest.fail.Exception) as e:
463+
lm.fnmatch_lines(["foo", "f*", "baz"])
464+
assert e.value.msg.splitlines() == [
465+
"exact match: 'foo'",
466+
"fnmatch: 'f*'",
467+
" with: 'foo'",
468+
"nomatch: 'baz'",
469+
" and: 'bar'",
470+
"remains unmatched: 'baz'",
471+
]
472+
473+
lm = LineMatcher(["foo", "foo", "bar"])
474+
with pytest.raises(pytest.fail.Exception) as e:
475+
lm.re_match_lines(["foo", "^f.*", "baz"])
476+
assert e.value.msg.splitlines() == [
477+
"exact match: 'foo'",
478+
"re.match: '^f.*'",
479+
" with: 'foo'",
480+
" nomatch: 'baz'",
481+
" and: 'bar'",
482+
"remains unmatched: 'baz'",
483+
]
484+
485+
460486
@pytest.mark.parametrize("function", ["no_fnmatch_line", "no_re_match_line"])
461487
def test_no_matching(function):
462-
""""""
463488
if function == "no_fnmatch_line":
464-
match_func_name = "fnmatch"
465489
good_pattern = "*.py OK*"
466490
bad_pattern = "*X.py OK*"
467491
else:
468492
assert function == "no_re_match_line"
469-
match_func_name = "re.match"
470493
good_pattern = r".*py OK"
471494
bad_pattern = r".*Xpy OK"
472495

@@ -480,24 +503,30 @@ def test_no_matching(function):
480503
]
481504
)
482505

483-
def check_failure_lines(lines):
484-
expected = [
485-
"nomatch: '{}'".format(good_pattern),
486-
" and: 'cachedir: .pytest_cache'",
487-
" and: 'collecting ... collected 1 item'",
488-
" and: ''",
489-
"{}: '{}'".format(match_func_name, good_pattern),
490-
" with: 'show_fixtures_per_test.py OK'",
491-
]
492-
assert lines == expected
493-
494506
# check the function twice to ensure we don't accumulate the internal buffer
495507
for i in range(2):
496508
with pytest.raises(pytest.fail.Exception) as e:
497509
func = getattr(lm, function)
498510
func(good_pattern)
499511
obtained = str(e.value).splitlines()
500-
check_failure_lines(obtained)
512+
if function == "no_fnmatch_line":
513+
assert obtained == [
514+
"nomatch: '{}'".format(good_pattern),
515+
" and: 'cachedir: .pytest_cache'",
516+
" and: 'collecting ... collected 1 item'",
517+
" and: ''",
518+
"fnmatch: '{}'".format(good_pattern),
519+
" with: 'show_fixtures_per_test.py OK'",
520+
]
521+
else:
522+
assert obtained == [
523+
"nomatch: '{}'".format(good_pattern),
524+
" and: 'cachedir: .pytest_cache'",
525+
" and: 'collecting ... collected 1 item'",
526+
" and: ''",
527+
"re.match: '{}'".format(good_pattern),
528+
" with: 'show_fixtures_per_test.py OK'",
529+
]
501530

502531
func = getattr(lm, function)
503532
func(bad_pattern) # bad pattern does not match any line: passes

0 commit comments

Comments
 (0)