Merge pull request #5069 from blueyed/cleanup-summary-to-terminal
cleanup: move terminal summary code to terminal plugin
This commit is contained in:
		
						commit
						f5d2b199e2
					
				| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					The code for the short test summary in the terminal was moved to the terminal plugin.
 | 
				
			||||||
| 
						 | 
					@ -183,128 +183,3 @@ def pytest_report_teststatus(report):
 | 
				
			||||||
            return "xfailed", "x", "XFAIL"
 | 
					            return "xfailed", "x", "XFAIL"
 | 
				
			||||||
        elif report.passed:
 | 
					        elif report.passed:
 | 
				
			||||||
            return "xpassed", "X", "XPASS"
 | 
					            return "xpassed", "X", "XPASS"
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# called by the terminalreporter instance/plugin
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def pytest_terminal_summary(terminalreporter):
 | 
					 | 
				
			||||||
    tr = terminalreporter
 | 
					 | 
				
			||||||
    if not tr.reportchars:
 | 
					 | 
				
			||||||
        return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    lines = []
 | 
					 | 
				
			||||||
    for char in tr.reportchars:
 | 
					 | 
				
			||||||
        action = REPORTCHAR_ACTIONS.get(char, lambda tr, lines: None)
 | 
					 | 
				
			||||||
        action(terminalreporter, lines)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if lines:
 | 
					 | 
				
			||||||
        tr._tw.sep("=", "short test summary info")
 | 
					 | 
				
			||||||
        for line in lines:
 | 
					 | 
				
			||||||
            tr._tw.line(line)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def show_simple(terminalreporter, lines, stat):
 | 
					 | 
				
			||||||
    failed = terminalreporter.stats.get(stat)
 | 
					 | 
				
			||||||
    if failed:
 | 
					 | 
				
			||||||
        config = terminalreporter.config
 | 
					 | 
				
			||||||
        for rep in failed:
 | 
					 | 
				
			||||||
            verbose_word = _get_report_str(config, rep)
 | 
					 | 
				
			||||||
            pos = _get_pos(config, rep)
 | 
					 | 
				
			||||||
            lines.append("%s %s" % (verbose_word, pos))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def show_xfailed(terminalreporter, lines):
 | 
					 | 
				
			||||||
    xfailed = terminalreporter.stats.get("xfailed")
 | 
					 | 
				
			||||||
    if xfailed:
 | 
					 | 
				
			||||||
        config = terminalreporter.config
 | 
					 | 
				
			||||||
        for rep in xfailed:
 | 
					 | 
				
			||||||
            verbose_word = _get_report_str(config, rep)
 | 
					 | 
				
			||||||
            pos = _get_pos(config, rep)
 | 
					 | 
				
			||||||
            lines.append("%s %s" % (verbose_word, pos))
 | 
					 | 
				
			||||||
            reason = rep.wasxfail
 | 
					 | 
				
			||||||
            if reason:
 | 
					 | 
				
			||||||
                lines.append("  " + str(reason))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def show_xpassed(terminalreporter, lines):
 | 
					 | 
				
			||||||
    xpassed = terminalreporter.stats.get("xpassed")
 | 
					 | 
				
			||||||
    if xpassed:
 | 
					 | 
				
			||||||
        config = terminalreporter.config
 | 
					 | 
				
			||||||
        for rep in xpassed:
 | 
					 | 
				
			||||||
            verbose_word = _get_report_str(config, rep)
 | 
					 | 
				
			||||||
            pos = _get_pos(config, rep)
 | 
					 | 
				
			||||||
            reason = rep.wasxfail
 | 
					 | 
				
			||||||
            lines.append("%s %s %s" % (verbose_word, pos, reason))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def folded_skips(skipped):
 | 
					 | 
				
			||||||
    d = {}
 | 
					 | 
				
			||||||
    for event in skipped:
 | 
					 | 
				
			||||||
        key = event.longrepr
 | 
					 | 
				
			||||||
        assert len(key) == 3, (event, key)
 | 
					 | 
				
			||||||
        keywords = getattr(event, "keywords", {})
 | 
					 | 
				
			||||||
        # folding reports with global pytestmark variable
 | 
					 | 
				
			||||||
        # this is workaround, because for now we cannot identify the scope of a skip marker
 | 
					 | 
				
			||||||
        # TODO: revisit after marks scope would be fixed
 | 
					 | 
				
			||||||
        if (
 | 
					 | 
				
			||||||
            event.when == "setup"
 | 
					 | 
				
			||||||
            and "skip" in keywords
 | 
					 | 
				
			||||||
            and "pytestmark" not in keywords
 | 
					 | 
				
			||||||
        ):
 | 
					 | 
				
			||||||
            key = (key[0], None, key[2])
 | 
					 | 
				
			||||||
        d.setdefault(key, []).append(event)
 | 
					 | 
				
			||||||
    values = []
 | 
					 | 
				
			||||||
    for key, events in d.items():
 | 
					 | 
				
			||||||
        values.append((len(events),) + key)
 | 
					 | 
				
			||||||
    return values
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def show_skipped(terminalreporter, lines):
 | 
					 | 
				
			||||||
    tr = terminalreporter
 | 
					 | 
				
			||||||
    skipped = tr.stats.get("skipped", [])
 | 
					 | 
				
			||||||
    if skipped:
 | 
					 | 
				
			||||||
        fskips = folded_skips(skipped)
 | 
					 | 
				
			||||||
        if fskips:
 | 
					 | 
				
			||||||
            verbose_word = _get_report_str(terminalreporter.config, report=skipped[0])
 | 
					 | 
				
			||||||
            for num, fspath, lineno, reason in fskips:
 | 
					 | 
				
			||||||
                if reason.startswith("Skipped: "):
 | 
					 | 
				
			||||||
                    reason = reason[9:]
 | 
					 | 
				
			||||||
                if lineno is not None:
 | 
					 | 
				
			||||||
                    lines.append(
 | 
					 | 
				
			||||||
                        "%s [%d] %s:%d: %s"
 | 
					 | 
				
			||||||
                        % (verbose_word, num, fspath, lineno + 1, reason)
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    lines.append("%s [%d] %s: %s" % (verbose_word, num, fspath, reason))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def shower(stat):
 | 
					 | 
				
			||||||
    def show_(terminalreporter, lines):
 | 
					 | 
				
			||||||
        return show_simple(terminalreporter, lines, stat)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return show_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _get_report_str(config, report):
 | 
					 | 
				
			||||||
    _category, _short, verbose = config.hook.pytest_report_teststatus(
 | 
					 | 
				
			||||||
        report=report, config=config
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    return verbose
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _get_pos(config, rep):
 | 
					 | 
				
			||||||
    nodeid = config.cwd_relative_nodeid(rep.nodeid)
 | 
					 | 
				
			||||||
    return nodeid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
REPORTCHAR_ACTIONS = {
 | 
					 | 
				
			||||||
    "x": show_xfailed,
 | 
					 | 
				
			||||||
    "X": show_xpassed,
 | 
					 | 
				
			||||||
    "f": shower("failed"),
 | 
					 | 
				
			||||||
    "F": shower("failed"),
 | 
					 | 
				
			||||||
    "s": show_skipped,
 | 
					 | 
				
			||||||
    "S": show_skipped,
 | 
					 | 
				
			||||||
    "p": shower("passed"),
 | 
					 | 
				
			||||||
    "E": shower("error"),
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ import collections
 | 
				
			||||||
import platform
 | 
					import platform
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
 | 
					from functools import partial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import attr
 | 
					import attr
 | 
				
			||||||
import pluggy
 | 
					import pluggy
 | 
				
			||||||
| 
						 | 
					@ -681,6 +682,7 @@ class TerminalReporter(object):
 | 
				
			||||||
        self.summary_failures()
 | 
					        self.summary_failures()
 | 
				
			||||||
        self.summary_warnings()
 | 
					        self.summary_warnings()
 | 
				
			||||||
        yield
 | 
					        yield
 | 
				
			||||||
 | 
					        self.short_test_summary()
 | 
				
			||||||
        self.summary_passes()
 | 
					        self.summary_passes()
 | 
				
			||||||
        # Display any extra warnings from teardown here (if any).
 | 
					        # Display any extra warnings from teardown here (if any).
 | 
				
			||||||
        self.summary_warnings()
 | 
					        self.summary_warnings()
 | 
				
			||||||
| 
						 | 
					@ -876,6 +878,106 @@ class TerminalReporter(object):
 | 
				
			||||||
        if self.verbosity == -1:
 | 
					        if self.verbosity == -1:
 | 
				
			||||||
            self.write_line(msg, **markup)
 | 
					            self.write_line(msg, **markup)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def short_test_summary(self):
 | 
				
			||||||
 | 
					        if not self.reportchars:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def show_simple(stat, lines):
 | 
				
			||||||
 | 
					            failed = self.stats.get(stat, [])
 | 
				
			||||||
 | 
					            for rep in failed:
 | 
				
			||||||
 | 
					                verbose_word = _get_report_str(self.config, rep)
 | 
				
			||||||
 | 
					                pos = _get_pos(self.config, rep)
 | 
				
			||||||
 | 
					                lines.append("%s %s" % (verbose_word, pos))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def show_xfailed(lines):
 | 
				
			||||||
 | 
					            xfailed = self.stats.get("xfailed", [])
 | 
				
			||||||
 | 
					            for rep in xfailed:
 | 
				
			||||||
 | 
					                verbose_word = _get_report_str(self.config, rep)
 | 
				
			||||||
 | 
					                pos = _get_pos(self.config, rep)
 | 
				
			||||||
 | 
					                lines.append("%s %s" % (verbose_word, pos))
 | 
				
			||||||
 | 
					                reason = rep.wasxfail
 | 
				
			||||||
 | 
					                if reason:
 | 
				
			||||||
 | 
					                    lines.append("  " + str(reason))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def show_xpassed(lines):
 | 
				
			||||||
 | 
					            xpassed = self.stats.get("xpassed", [])
 | 
				
			||||||
 | 
					            for rep in xpassed:
 | 
				
			||||||
 | 
					                verbose_word = _get_report_str(self.config, rep)
 | 
				
			||||||
 | 
					                pos = _get_pos(self.config, rep)
 | 
				
			||||||
 | 
					                reason = rep.wasxfail
 | 
				
			||||||
 | 
					                lines.append("%s %s %s" % (verbose_word, pos, reason))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def show_skipped(lines):
 | 
				
			||||||
 | 
					            skipped = self.stats.get("skipped", [])
 | 
				
			||||||
 | 
					            fskips = _folded_skips(skipped) if skipped else []
 | 
				
			||||||
 | 
					            if not fskips:
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            verbose_word = _get_report_str(self.config, report=skipped[0])
 | 
				
			||||||
 | 
					            for num, fspath, lineno, reason in fskips:
 | 
				
			||||||
 | 
					                if reason.startswith("Skipped: "):
 | 
				
			||||||
 | 
					                    reason = reason[9:]
 | 
				
			||||||
 | 
					                if lineno is not None:
 | 
				
			||||||
 | 
					                    lines.append(
 | 
				
			||||||
 | 
					                        "%s [%d] %s:%d: %s"
 | 
				
			||||||
 | 
					                        % (verbose_word, num, fspath, lineno + 1, reason)
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    lines.append("%s [%d] %s: %s" % (verbose_word, num, fspath, reason))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def _get_report_str(config, report):
 | 
				
			||||||
 | 
					            _category, _short, verbose = config.hook.pytest_report_teststatus(
 | 
				
			||||||
 | 
					                report=report, config=config
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return verbose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def _get_pos(config, rep):
 | 
				
			||||||
 | 
					            nodeid = config.cwd_relative_nodeid(rep.nodeid)
 | 
				
			||||||
 | 
					            return nodeid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        REPORTCHAR_ACTIONS = {
 | 
				
			||||||
 | 
					            "x": show_xfailed,
 | 
				
			||||||
 | 
					            "X": show_xpassed,
 | 
				
			||||||
 | 
					            "f": partial(show_simple, "failed"),
 | 
				
			||||||
 | 
					            "F": partial(show_simple, "failed"),
 | 
				
			||||||
 | 
					            "s": show_skipped,
 | 
				
			||||||
 | 
					            "S": show_skipped,
 | 
				
			||||||
 | 
					            "p": partial(show_simple, "passed"),
 | 
				
			||||||
 | 
					            "E": partial(show_simple, "error"),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        lines = []
 | 
				
			||||||
 | 
					        for char in self.reportchars:
 | 
				
			||||||
 | 
					            action = REPORTCHAR_ACTIONS.get(char)
 | 
				
			||||||
 | 
					            if action:  # skipping e.g. "P" (passed with output) here.
 | 
				
			||||||
 | 
					                action(lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if lines:
 | 
				
			||||||
 | 
					            self.write_sep("=", "short test summary info")
 | 
				
			||||||
 | 
					            for line in lines:
 | 
				
			||||||
 | 
					                self.write_line(line)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _folded_skips(skipped):
 | 
				
			||||||
 | 
					    d = {}
 | 
				
			||||||
 | 
					    for event in skipped:
 | 
				
			||||||
 | 
					        key = event.longrepr
 | 
				
			||||||
 | 
					        assert len(key) == 3, (event, key)
 | 
				
			||||||
 | 
					        keywords = getattr(event, "keywords", {})
 | 
				
			||||||
 | 
					        # folding reports with global pytestmark variable
 | 
				
			||||||
 | 
					        # this is workaround, because for now we cannot identify the scope of a skip marker
 | 
				
			||||||
 | 
					        # TODO: revisit after marks scope would be fixed
 | 
				
			||||||
 | 
					        if (
 | 
				
			||||||
 | 
					            event.when == "setup"
 | 
				
			||||||
 | 
					            and "skip" in keywords
 | 
				
			||||||
 | 
					            and "pytestmark" not in keywords
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
 | 
					            key = (key[0], None, key[2])
 | 
				
			||||||
 | 
					        d.setdefault(key, []).append(event)
 | 
				
			||||||
 | 
					    values = []
 | 
				
			||||||
 | 
					    for key, events in d.items():
 | 
				
			||||||
 | 
					        values.append((len(events),) + key)
 | 
				
			||||||
 | 
					    return values
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def build_summary_stats_line(stats):
 | 
					def build_summary_stats_line(stats):
 | 
				
			||||||
    known_types = (
 | 
					    known_types = (
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@ import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
from _pytest.runner import runtestprotocol
 | 
					from _pytest.runner import runtestprotocol
 | 
				
			||||||
from _pytest.skipping import folded_skips
 | 
					 | 
				
			||||||
from _pytest.skipping import MarkEvaluator
 | 
					from _pytest.skipping import MarkEvaluator
 | 
				
			||||||
from _pytest.skipping import pytest_runtest_setup
 | 
					from _pytest.skipping import pytest_runtest_setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -749,40 +748,6 @@ def test_skipif_class(testdir):
 | 
				
			||||||
    result.stdout.fnmatch_lines(["*2 skipped*"])
 | 
					    result.stdout.fnmatch_lines(["*2 skipped*"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_skip_reasons_folding():
 | 
					 | 
				
			||||||
    path = "xyz"
 | 
					 | 
				
			||||||
    lineno = 3
 | 
					 | 
				
			||||||
    message = "justso"
 | 
					 | 
				
			||||||
    longrepr = (path, lineno, message)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class X(object):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ev1 = X()
 | 
					 | 
				
			||||||
    ev1.when = "execute"
 | 
					 | 
				
			||||||
    ev1.skipped = True
 | 
					 | 
				
			||||||
    ev1.longrepr = longrepr
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ev2 = X()
 | 
					 | 
				
			||||||
    ev2.when = "execute"
 | 
					 | 
				
			||||||
    ev2.longrepr = longrepr
 | 
					 | 
				
			||||||
    ev2.skipped = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # ev3 might be a collection report
 | 
					 | 
				
			||||||
    ev3 = X()
 | 
					 | 
				
			||||||
    ev3.when = "collect"
 | 
					 | 
				
			||||||
    ev3.longrepr = longrepr
 | 
					 | 
				
			||||||
    ev3.skipped = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    values = folded_skips([ev1, ev2, ev3])
 | 
					 | 
				
			||||||
    assert len(values) == 1
 | 
					 | 
				
			||||||
    num, fspath, lineno, reason = values[0]
 | 
					 | 
				
			||||||
    assert num == 3
 | 
					 | 
				
			||||||
    assert fspath == path
 | 
					 | 
				
			||||||
    assert lineno == lineno
 | 
					 | 
				
			||||||
    assert reason == message
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_skipped_reasons_functional(testdir):
 | 
					def test_skipped_reasons_functional(testdir):
 | 
				
			||||||
    testdir.makepyfile(
 | 
					    testdir.makepyfile(
 | 
				
			||||||
        test_one="""
 | 
					        test_one="""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@ import py
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
from _pytest.main import EXIT_NOTESTSCOLLECTED
 | 
					from _pytest.main import EXIT_NOTESTSCOLLECTED
 | 
				
			||||||
from _pytest.reports import BaseReport
 | 
					from _pytest.reports import BaseReport
 | 
				
			||||||
 | 
					from _pytest.terminal import _folded_skips
 | 
				
			||||||
from _pytest.terminal import _plugin_nameversions
 | 
					from _pytest.terminal import _plugin_nameversions
 | 
				
			||||||
from _pytest.terminal import build_summary_stats_line
 | 
					from _pytest.terminal import build_summary_stats_line
 | 
				
			||||||
from _pytest.terminal import getreportopt
 | 
					from _pytest.terminal import getreportopt
 | 
				
			||||||
| 
						 | 
					@ -1524,3 +1525,37 @@ class TestProgressWithTeardown(object):
 | 
				
			||||||
        monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
 | 
					        monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
 | 
				
			||||||
        output = testdir.runpytest("-n2")
 | 
					        output = testdir.runpytest("-n2")
 | 
				
			||||||
        output.stdout.re_match_lines([r"[\.E]{40} \s+ \[100%\]"])
 | 
					        output.stdout.re_match_lines([r"[\.E]{40} \s+ \[100%\]"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_skip_reasons_folding():
 | 
				
			||||||
 | 
					    path = "xyz"
 | 
				
			||||||
 | 
					    lineno = 3
 | 
				
			||||||
 | 
					    message = "justso"
 | 
				
			||||||
 | 
					    longrepr = (path, lineno, message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class X(object):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ev1 = X()
 | 
				
			||||||
 | 
					    ev1.when = "execute"
 | 
				
			||||||
 | 
					    ev1.skipped = True
 | 
				
			||||||
 | 
					    ev1.longrepr = longrepr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ev2 = X()
 | 
				
			||||||
 | 
					    ev2.when = "execute"
 | 
				
			||||||
 | 
					    ev2.longrepr = longrepr
 | 
				
			||||||
 | 
					    ev2.skipped = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # ev3 might be a collection report
 | 
				
			||||||
 | 
					    ev3 = X()
 | 
				
			||||||
 | 
					    ev3.when = "collect"
 | 
				
			||||||
 | 
					    ev3.longrepr = longrepr
 | 
				
			||||||
 | 
					    ev3.skipped = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    values = _folded_skips([ev1, ev2, ev3])
 | 
				
			||||||
 | 
					    assert len(values) == 1
 | 
				
			||||||
 | 
					    num, fspath, lineno, reason = values[0]
 | 
				
			||||||
 | 
					    assert num == 3
 | 
				
			||||||
 | 
					    assert fspath == path
 | 
				
			||||||
 | 
					    assert lineno == lineno
 | 
				
			||||||
 | 
					    assert reason == message
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue