Skip to content

Commit d1bc260

Browse files
authored
pytester: align prefixes (#6026)
pytester: align prefixes
2 parents 73a77c9 + 8ef4287 commit d1bc260

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
@@ -1347,14 +1347,14 @@ def _match_lines(self, lines2, match_func, match_nickname):
13471347
pattern
13481348
:param str match_nickname: the nickname for the match function that
13491349
will be logged to stdout when a match occurs
1350-
13511350
"""
13521351
assert isinstance(lines2, Sequence)
13531352
lines2 = self._getlines(lines2)
13541353
lines1 = self.lines[:]
13551354
nextline = None
13561355
extralines = []
13571356
__tracebackhide__ = True
1357+
wnick = len(match_nickname) + 1
13581358
for line in lines2:
13591359
nomatchprinted = False
13601360
while lines1:
@@ -1364,17 +1364,21 @@ def _match_lines(self, lines2, match_func, match_nickname):
13641364
break
13651365
elif match_func(nextline, line):
13661366
self._log("%s:" % match_nickname, repr(line))
1367-
self._log(" with:", repr(nextline))
1367+
self._log(
1368+
"{:>{width}}".format("with:", width=wnick), repr(nextline)
1369+
)
13681370
break
13691371
else:
13701372
if not nomatchprinted:
1371-
self._log("nomatch:", repr(line))
1373+
self._log(
1374+
"{:>{width}}".format("nomatch:", width=wnick), repr(line)
1375+
)
13721376
nomatchprinted = True
1373-
self._log(" and:", repr(nextline))
1377+
self._log("{:>{width}}".format("and:", width=wnick), repr(nextline))
13741378
extralines.append(nextline)
13751379
else:
13761380
self._log("remains unmatched: {!r}".format(line))
1377-
pytest.fail(self._log_text)
1381+
pytest.fail(self._log_text.lstrip())
13781382

13791383
def no_fnmatch_line(self, pat):
13801384
"""Ensure captured lines do not match the given pattern, using ``fnmatch.fnmatch``.
@@ -1399,16 +1403,19 @@ def _no_match_line(self, pat, match_func, match_nickname):
13991403
"""
14001404
__tracebackhide__ = True
14011405
nomatch_printed = False
1406+
wnick = len(match_nickname) + 1
14021407
try:
14031408
for line in self.lines:
14041409
if match_func(line, pat):
14051410
self._log("%s:" % match_nickname, repr(pat))
1406-
self._log(" with:", repr(line))
1407-
pytest.fail(self._log_text)
1411+
self._log("{:>{width}}".format("with:", width=wnick), repr(line))
1412+
pytest.fail(self._log_text.lstrip())
14081413
else:
14091414
if not nomatch_printed:
1410-
self._log("nomatch:", repr(pat))
1415+
self._log(
1416+
"{:>{width}}".format("nomatch:", width=wnick), repr(pat)
1417+
)
14111418
nomatch_printed = True
1412-
self._log(" and:", repr(line))
1419+
self._log("{:>{width}}".format("and:", width=wnick), repr(line))
14131420
finally:
14141421
self._log_output = []

testing/test_pytester.py

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

448448

449+
def test_linematcher_match_failure():
450+
lm = LineMatcher(["foo", "foo", "bar"])
451+
with pytest.raises(pytest.fail.Exception) as e:
452+
lm.fnmatch_lines(["foo", "f*", "baz"])
453+
assert e.value.msg.splitlines() == [
454+
"exact match: 'foo'",
455+
"fnmatch: 'f*'",
456+
" with: 'foo'",
457+
"nomatch: 'baz'",
458+
" and: 'bar'",
459+
"remains unmatched: 'baz'",
460+
]
461+
462+
lm = LineMatcher(["foo", "foo", "bar"])
463+
with pytest.raises(pytest.fail.Exception) as e:
464+
lm.re_match_lines(["foo", "^f.*", "baz"])
465+
assert e.value.msg.splitlines() == [
466+
"exact match: 'foo'",
467+
"re.match: '^f.*'",
468+
" with: 'foo'",
469+
" nomatch: 'baz'",
470+
" and: 'bar'",
471+
"remains unmatched: 'baz'",
472+
]
473+
474+
449475
@pytest.mark.parametrize("function", ["no_fnmatch_line", "no_re_match_line"])
450476
def test_no_matching(function):
451-
""""""
452477
if function == "no_fnmatch_line":
453-
match_func_name = "fnmatch"
454478
good_pattern = "*.py OK*"
455479
bad_pattern = "*X.py OK*"
456480
else:
457481
assert function == "no_re_match_line"
458-
match_func_name = "re.match"
459482
good_pattern = r".*py OK"
460483
bad_pattern = r".*Xpy OK"
461484

@@ -469,24 +492,30 @@ def test_no_matching(function):
469492
]
470493
)
471494

472-
def check_failure_lines(lines):
473-
expected = [
474-
"nomatch: '{}'".format(good_pattern),
475-
" and: 'cachedir: .pytest_cache'",
476-
" and: 'collecting ... collected 1 item'",
477-
" and: ''",
478-
"{}: '{}'".format(match_func_name, good_pattern),
479-
" with: 'show_fixtures_per_test.py OK'",
480-
]
481-
assert lines == expected
482-
483495
# check the function twice to ensure we don't accumulate the internal buffer
484496
for i in range(2):
485497
with pytest.raises(pytest.fail.Exception) as e:
486498
func = getattr(lm, function)
487499
func(good_pattern)
488500
obtained = str(e.value).splitlines()
489-
check_failure_lines(obtained)
501+
if function == "no_fnmatch_line":
502+
assert obtained == [
503+
"nomatch: '{}'".format(good_pattern),
504+
" and: 'cachedir: .pytest_cache'",
505+
" and: 'collecting ... collected 1 item'",
506+
" and: ''",
507+
"fnmatch: '{}'".format(good_pattern),
508+
" with: 'show_fixtures_per_test.py OK'",
509+
]
510+
else:
511+
assert obtained == [
512+
"nomatch: '{}'".format(good_pattern),
513+
" and: 'cachedir: .pytest_cache'",
514+
" and: 'collecting ... collected 1 item'",
515+
" and: ''",
516+
"re.match: '{}'".format(good_pattern),
517+
" with: 'show_fixtures_per_test.py OK'",
518+
]
490519

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

0 commit comments

Comments
 (0)