From 7a333686d7003071b3211ce8ded7e9ce4f76fcc9 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 6 Jan 2020 16:49:36 +0100 Subject: [PATCH] use setter for stats, handling main color --- src/_pytest/terminal.py | 28 ++++++++++++++++++++-------- testing/test_terminal.py | 3 +++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 4031c01a923..ec313c8f59c 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -248,6 +248,8 @@ def __init__(self, config: Config, file=None) -> None: self._showfspath = None self.stats = {} # type: Dict[str, List[Any]] + self._main_color = None # type: Optional[str] + self._known_types = None # type: Optional[List] self.startdir = config.invocation_dir if file is None: file = sys.stdout @@ -366,6 +368,13 @@ def section(self, title, sep="=", **kw): def line(self, msg, **kw): self._tw.line(msg, **kw) + def _add_stats(self, category: str, items: List) -> None: + if category not in self.stats: + self.stats[category] = items + self._set_main_color() + else: + self.stats[category].extend(items) + def pytest_internalerror(self, excrepr): for line in str(excrepr).split("\n"): self.write_line("INTERNALERROR> " + line) @@ -375,7 +384,6 @@ def pytest_warning_captured(self, warning_message, item): # from _pytest.nodes import get_fslocation_from_item from _pytest.warnings import warning_record_to_str - warnings = self.stats.setdefault("warnings", []) fslocation = warning_message.filename, warning_message.lineno message = warning_record_to_str(warning_message) @@ -383,7 +391,7 @@ def pytest_warning_captured(self, warning_message, item): warning_report = WarningReport( fslocation=fslocation, message=message, nodeid=nodeid ) - warnings.append(warning_report) + self._add_stats("warnings", [warning_report]) def pytest_plugin_registered(self, plugin): if self.config.option.traceconfig: @@ -394,7 +402,7 @@ def pytest_plugin_registered(self, plugin): self.write_line(msg) def pytest_deselected(self, items): - self.stats.setdefault("deselected", []).extend(items) + self._add_stats("deselected", items) def pytest_runtest_logstart(self, nodeid, location): # ensure that the path is printed before the @@ -415,7 +423,7 @@ def pytest_runtest_logreport(self, report: TestReport) -> None: word, markup = word else: markup = None - self.stats.setdefault(category, []).append(rep) + self._add_stats(category, [rep]) if not letter and not word: # probably passed setup/teardown return @@ -529,9 +537,9 @@ def pytest_collection(self): def pytest_collectreport(self, report: CollectReport) -> None: if report.failed: - self.stats.setdefault("error", []).append(report) + self._add_stats("error", [report]) elif report.skipped: - self.stats.setdefault("skipped", []).append(report) + self._add_stats("skipped", [report]) items = [x for x in report.result if isinstance(x, pytest.Item)] self._numcollected += len(items) if self.isatty: @@ -1011,6 +1019,11 @@ def show_skipped(lines: List[str]) -> None: self.write_line(line) def _get_main_color(self) -> Tuple[str, List[str]]: + if self._main_color is None or self._known_types is None: + self._main_color, self._known_types = self._set_main_color() + return self._main_color, self._known_types + + def _set_main_color(self) -> Tuple[str, List[str]]: stats = self.stats known_types = ( "failed passed skipped deselected xfailed xpassed warnings error".split() @@ -1031,10 +1044,9 @@ def _get_main_color(self) -> Tuple[str, List[str]]: main_color = "green" else: main_color = "yellow" - return main_color, known_types - def build_summary_stats_line(self): + def build_summary_stats_line(self) -> Tuple[List[Tuple[str, Dict[str, bool]]], str]: main_color, known_types = self._get_main_color() parts = [] diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 9351888d20a..712f1ced9f0 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -1441,6 +1441,9 @@ def test_summary_stats(tr, exp_line, exp_color, stats_arg): tr._testscollected = 0 assert tr._is_last_item + # Reset cache. + tr._main_color = None + print("Based on stats: %s" % stats_arg) print('Expect summary: "{}"; with color "{}"'.format(exp_line, exp_color)) (line, color) = tr.build_summary_stats_line()