diff --git a/pycobertura/cobertura.py b/pycobertura/cobertura.py index d328fce..ca3815b 100644 --- a/pycobertura/cobertura.py +++ b/pycobertura/cobertura.py @@ -363,7 +363,7 @@ def has_all_changes_covered(self): return False # line not covered return True - def _diff_attr(self, attr_name, filename): + def _diff_attr(self, attr_name, filename, ignore_regex=None): """ Return the difference between `self.cobertura2.(filename)` and @@ -375,7 +375,7 @@ def _diff_attr(self, attr_name, filename): The returned count may be a float. """ - files = [filename] if filename else self.files() + files = [filename] if filename else self.files(ignore_regex) total_count = 0.0 for filename in files: @@ -390,19 +390,21 @@ def _diff_attr(self, attr_name, filename): return total_count - def diff_total_statements(self, filename=None): - return int(self._diff_attr("total_statements", filename)) + def diff_total_statements(self, filename=None, ignore_regex=None): + return int(self._diff_attr("total_statements", filename, ignore_regex)) - def diff_total_misses(self, filename=None): - return int(self._diff_attr("total_misses", filename)) + def diff_total_misses(self, filename=None, ignore_regex=None): + return int(self._diff_attr("total_misses", filename, ignore_regex)) - def diff_total_hits(self, filename=None): - return int(self._diff_attr("total_hits", filename)) + def diff_total_hits(self, filename=None, ignore_regex=None): + return int(self._diff_attr("total_hits", filename, ignore_regex)) - def diff_line_rate(self, filename=None): + def diff_line_rate(self, filename=None, ignore_regex=None): if filename is not None: return self._diff_attr("line_rate", filename) - return self.cobertura2.line_rate() - self.cobertura1.line_rate() + return self.cobertura2.line_rate( + ignore_regex=ignore_regex + ) - self.cobertura1.line_rate(ignore_regex=ignore_regex) def diff_missed_lines( self, filename: str diff --git a/pycobertura/reporters.py b/pycobertura/reporters.py index 29a8c05..549c9b4 100644 --- a/pycobertura/reporters.py +++ b/pycobertura/reporters.py @@ -336,13 +336,19 @@ def get_summary_lines(self): summary_lines["Filename"].append("TOTAL") summary_lines["Stmts"].append( - self.format_total_statements(self.differ.diff_total_statements()) + self.format_total_statements( + self.differ.diff_total_statements(ignore_regex=self.ignore_regex) + ) ) summary_lines["Miss"].append( - self.format_total_misses(self.differ.diff_total_misses()) + self.format_total_misses( + self.differ.diff_total_misses(ignore_regex=self.ignore_regex) + ) ) summary_lines["Cover"].append( - self.format_line_rate(self.differ.diff_line_rate()) + self.format_line_rate( + self.differ.diff_line_rate(ignore_regex=self.ignore_regex) + ) ) if self.show_source: diff --git a/tests/test_cli.py b/tests/test_cli.py index e699e82..3eca9a0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1255,3 +1255,26 @@ def test_diff__format_yaml__with_ignore_regex(): # Verify total is present assert 'Filename: TOTAL' in result.output + + +def test_diff__ignore_regex_applies_to_total(): + """--ignore-regex must exclude the ignored files from the TOTAL row too.""" + from pycobertura.cli import diff + + runner = CliRunner() + result = runner.invoke( + diff, + [ + "tests/dummy.source1/coverage.xml", + "tests/dummy.source2/coverage.xml", + "--no-source", + "--format", "json", + "--no-color", + "--ignore-regex", ".*", + ], + catch_exceptions=False, + ) + payload = json.loads(result.output) + assert payload["files"] == [] + assert payload["total"]["Stmts"] == "0" + assert payload["total"]["Miss"] == "0" diff --git a/tests/test_reporters.py b/tests/test_reporters.py index 355bbca..e78e68b 100644 --- a/tests/test_reporters.py +++ b/tests/test_reporters.py @@ -987,3 +987,41 @@ def test_delta_reporter__single_file_coverage_changed(): "Cover": "+16.67%" } } + + +def test_text_report_delta__ignore_regex_applies_to_total(): + from pycobertura.reporters import TextReporterDelta + + cobertura1 = make_cobertura("tests/dummy.source1/coverage.xml") + cobertura2 = make_cobertura("tests/dummy.source2/coverage.xml") + + # every file is ignored, so the TOTAL row must not report any change + report_delta = TextReporterDelta( + cobertura1, cobertura2, ignore_regex=".*", show_source=False + ) + + assert report_delta.generate() == """\ +Filename Stmts Miss Cover +---------- ------- ------ -------- +TOTAL 0 0 +100.00%""" + + +def test_text_report_delta__ignore_regex_excludes_file_from_total(): + from pycobertura.reporters import TextReporterDelta + + cobertura1 = make_cobertura("tests/dummy.source1/coverage.xml") + cobertura2 = make_cobertura("tests/dummy.source2/coverage.xml") + + unfiltered = TextReporterDelta(cobertura1, cobertura2, show_source=False) + filtered = TextReporterDelta( + cobertura1, cobertura2, ignore_regex="^dummy/dummy3.*", show_source=False + ) + + # dummy/dummy3.py adds 2 statements, 2 of them missed; ignoring the file + # has to remove its contribution from the TOTAL row as well + unfiltered_total = unfiltered.get_summary_lines() + filtered_total = filtered.get_summary_lines() + + assert unfiltered_total["Stmts"][-1] == "-1" + assert filtered_total["Stmts"][-1] == "-3" + assert filtered_total["Miss"][-1] != unfiltered_total["Miss"][-1]