diff-cover 9.2.1__tar.gz → 9.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. {diff_cover-9.2.1 → diff_cover-9.2.2}/PKG-INFO +1 -1
  2. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/violationsreporters/violations_reporter.py +2 -0
  3. {diff_cover-9.2.1 → diff_cover-9.2.2}/pyproject.toml +3 -3
  4. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_violations_reporter.py +197 -0
  5. {diff_cover-9.2.1 → diff_cover-9.2.2}/LICENSE +0 -0
  6. {diff_cover-9.2.1 → diff_cover-9.2.2}/README.rst +0 -0
  7. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/__init__.py +0 -0
  8. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/command_runner.py +0 -0
  9. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/config_parser.py +0 -0
  10. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/diff_cover_tool.py +0 -0
  11. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/diff_quality_tool.py +0 -0
  12. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/diff_reporter.py +0 -0
  13. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/git_diff.py +0 -0
  14. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/git_path.py +0 -0
  15. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/hook.py +0 -0
  16. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/hookspecs.py +0 -0
  17. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/report_generator.py +0 -0
  18. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/snippets.py +0 -0
  19. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/console_coverage_report.txt +0 -0
  20. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/console_quality_report.txt +0 -0
  21. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/external_style.css +0 -0
  22. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/html_coverage_report.html +0 -0
  23. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/html_quality_report.html +0 -0
  24. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/markdown_coverage_report.md +0 -0
  25. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/markdown_quality_report.md +0 -0
  26. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/snippet_content.html +0 -0
  27. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/snippet_content.md +0 -0
  28. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/snippet_content.txt +0 -0
  29. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/templates/snippet_style.html +0 -0
  30. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/util.py +0 -0
  31. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/violationsreporters/__init__.py +0 -0
  32. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/violationsreporters/base.py +0 -0
  33. {diff_cover-9.2.1 → diff_cover-9.2.2}/diff_cover/violationsreporters/java_violations_reporter.py +0 -0
  34. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/__init__.py +0 -0
  35. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/add_console_report.txt +0 -0
  36. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/add_html_report.html +0 -0
  37. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/changed_console_report.txt +0 -0
  38. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/changed_html_report.html +0 -0
  39. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/coverage.xml +0 -0
  40. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/coverage1.xml +0 -0
  41. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/coverage2.xml +0 -0
  42. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/coverage_missing_lines.xml +0 -0
  43. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/delete_console_report.txt +0 -0
  44. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/delete_html_report.html +0 -0
  45. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/dotnet_coverage.xml +0 -0
  46. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/dotnet_coverage_console_report.txt +0 -0
  47. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/empty.txt +0 -0
  48. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/empty_pycodestyle_violations.txt +0 -0
  49. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/expand_console_report.txt +0 -0
  50. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/external_css_html_report.html +0 -0
  51. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/external_style.css +0 -0
  52. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_add.txt +0 -0
  53. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_changed.txt +0 -0
  54. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_code_dupe.txt +0 -0
  55. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_delete.txt +0 -0
  56. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_dotnet.txt +0 -0
  57. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_external_css.txt +0 -0
  58. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_lua.txt +0 -0
  59. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_moved.txt +0 -0
  60. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_mult.txt +0 -0
  61. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_subdir.txt +0 -0
  62. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_unicode.txt +0 -0
  63. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_violations.txt +0 -0
  64. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/git_diff_violations_two_files.txt +0 -0
  65. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/hello.py +0 -0
  66. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/hi.py +0 -0
  67. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/html_report.html +0 -0
  68. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/html_report_empty.html +0 -0
  69. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/html_report_one_snippet.html +0 -0
  70. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/html_report_two_snippets.html +0 -0
  71. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/lcov.info +0 -0
  72. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/lua_console_report.txt +0 -0
  73. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/luacoverage.xml +0 -0
  74. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/markdown_report_one_snippet.md +0 -0
  75. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/markdown_report_two_snippets.md +0 -0
  76. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/moved_console_report.txt +0 -0
  77. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/moved_coverage.xml +0 -0
  78. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/moved_html_report.html +0 -0
  79. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/mult_inputs_console_report.txt +0 -0
  80. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/mult_inputs_html_report.html +0 -0
  81. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pycodestyle_report.txt +0 -0
  82. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pycodestyle_violations_report.html +0 -0
  83. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pycodestyle_violations_report.txt +0 -0
  84. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pycodestyle_violations_report_external_css.html +0 -0
  85. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pyflakes_two_files.txt +0 -0
  86. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pyflakes_violations_report.html +0 -0
  87. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pyflakes_violations_report.txt +0 -0
  88. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pylint_dupe.txt +0 -0
  89. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pylint_dupe_violations_report.txt +0 -0
  90. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pylint_report.txt +0 -0
  91. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pylint_violations_console_report.txt +0 -0
  92. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pylint_violations_report.html +0 -0
  93. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pylint_violations_report.txt +0 -0
  94. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/pylintrc +0 -0
  95. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/show_uncovered_lines_console.txt +0 -0
  96. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet.css +0 -0
  97. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_8859.py +0 -0
  98. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_arabic_output.html +0 -0
  99. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_default.html +0 -0
  100. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_invalid_violations.html +0 -0
  101. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_list.html +0 -0
  102. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_list.md +0 -0
  103. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_list2.md +0 -0
  104. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_list3.md +0 -0
  105. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_no_filename_ext.html +0 -0
  106. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_src.py +0 -0
  107. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_src2.cpp +0 -0
  108. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_src3.cpp +0 -0
  109. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_unicode.html +0 -0
  110. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_unicode.py +0 -0
  111. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/snippet_unicode_html_output.html +0 -0
  112. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/subdir_coverage_console_report.txt +0 -0
  113. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/subdir_coverage_html_report.html +0 -0
  114. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/test_src.txt +0 -0
  115. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/unicode_console_report.txt +0 -0
  116. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/unicode_coverage.xml +0 -0
  117. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/unicode_html_report.html +0 -0
  118. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/unicode_test_src.txt +0 -0
  119. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/fixtures/violations_test_file.py +0 -0
  120. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/helpers.py +0 -0
  121. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/snippet_list_unicode.html +0 -0
  122. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_clover_violations_reporter/test.xml +0 -0
  123. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_clover_violations_reporter.py +0 -0
  124. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_config_parser.py +0 -0
  125. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_diff_cover_main.py +0 -0
  126. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_diff_cover_tool.py +0 -0
  127. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_diff_quality_main.py +0 -0
  128. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_diff_reporter.py +0 -0
  129. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_git_diff.py +0 -0
  130. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_git_diff_file.py +0 -0
  131. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_git_path.py +0 -0
  132. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_integration.py +0 -0
  133. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_java_violations_reporter.py +0 -0
  134. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_report_generator.py +0 -0
  135. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_snippets.py +0 -0
  136. {diff_cover-9.2.1 → diff_cover-9.2.2}/tests/test_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diff_cover
3
- Version: 9.2.1
3
+ Version: 9.2.2
4
4
  Summary: Run coverage and linting reports on diffs
5
5
  Home-page: https://github.com/Bachmann1234/diff-cover
6
6
  License: Apache-2.0
@@ -392,6 +392,8 @@ class LcovCoverageReporter(BaseViolationReporter):
392
392
  src_search_path = src_abs_path
393
393
  if src_search_path not in lcov_document:
394
394
  src_search_path = src_rel_path
395
+ if src_search_path not in lcov_document:
396
+ continue
395
397
 
396
398
  # First case, need to define violations initially
397
399
  if violations is None:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "diff_cover"
3
- version = "9.2.1"
3
+ version = "9.2.2"
4
4
  description = "Run coverage and linting reports on diffs"
5
5
  authors = ["See Contributors"]
6
6
  homepage = "https://github.com/Bachmann1234/diff-cover"
@@ -49,13 +49,13 @@ tomli = {version = ">=1.2.1", optional = true}
49
49
  setuptools = { version = ">=17.0.0", python = "<3.8" }
50
50
 
51
51
  [tool.poetry.dev-dependencies]
52
- pytest-cov = "^5.0.0"
52
+ pytest-cov = "^6.0.0"
53
53
  pytest-datadir = "^1.5.0"
54
54
  pytest-mock = "^3.14.0"
55
55
  pycodestyle = ">=2.9.1"
56
56
  flake8 = "^5.0.4"
57
57
  pyflakes = "^2.5.0"
58
- pylint = "^3.2.7"
58
+ pylint = "^3.3.3"
59
59
  pylint-pytest = "^1.1.8"
60
60
  pydocstyle = "^6.1.1"
61
61
  black = "^24.8.0"
@@ -5,6 +5,7 @@
5
5
 
6
6
  import os
7
7
  import subprocess
8
+ import tempfile
8
9
  import xml.etree.ElementTree as etree
9
10
  from io import BytesIO, StringIO
10
11
  from subprocess import Popen
@@ -18,6 +19,7 @@ from diff_cover.violationsreporters.base import QualityReporter
18
19
  from diff_cover.violationsreporters.violations_reporter import (
19
20
  CppcheckDriver,
20
21
  EslintDriver,
22
+ LcovCoverageReporter,
21
23
  PylintDriver,
22
24
  Violation,
23
25
  XmlCoverageReporter,
@@ -794,6 +796,201 @@ class TestJacocoXmlCoverageReporterTest:
794
796
  return root
795
797
 
796
798
 
799
+ class TestLcovCoverageReporterTest:
800
+ MANY_VIOLATIONS = {
801
+ Violation(3, None),
802
+ Violation(7, None),
803
+ Violation(11, None),
804
+ Violation(13, None),
805
+ }
806
+ FEW_MEASURED = {2, 3, 5, 7, 11, 13}
807
+
808
+ FEW_VIOLATIONS = {Violation(3, None), Violation(11, None)}
809
+ MANY_MEASURED = {2, 3, 5, 7, 11, 13, 17}
810
+
811
+ ONE_VIOLATION = {Violation(11, None)}
812
+ VERY_MANY_MEASURED = {2, 3, 5, 7, 11, 13, 17, 23, 24, 25, 26, 26, 27}
813
+
814
+ @pytest.fixture(autouse=True)
815
+ def patch_git_patch(self, mocker):
816
+ # Paths generated by git_path are always the given argument
817
+ _git_path_mock = mocker.patch(
818
+ "diff_cover.violationsreporters.violations_reporter.GitPathTool"
819
+ )
820
+ _git_path_mock.relative_path = lambda path: path
821
+ _git_path_mock.absolute_path = lambda path: path
822
+
823
+ def test_violations(self):
824
+ # Construct the LCOV report
825
+ file_paths = ["file1.java", "subdir/file2.java"]
826
+ violations = self.MANY_VIOLATIONS
827
+ measured = self.FEW_MEASURED
828
+ lcov = self._coverage_lcov(file_paths, violations, measured)
829
+
830
+ # Parse the report
831
+ coverage = LcovCoverageReporter([lcov])
832
+
833
+ # Expect that the name is set
834
+ assert coverage.name() == "LCOV"
835
+
836
+ # By construction, each file has the same set
837
+ # of covered/uncovered lines
838
+ assert violations == coverage.violations("file1.java")
839
+ assert measured == coverage.measured_lines("file1.java")
840
+
841
+ # Try getting a smaller range
842
+ result = coverage.violations("subdir/file2.java")
843
+ assert result == violations
844
+
845
+ # Once more on the first file (for caching)
846
+ result = coverage.violations("file1.java")
847
+ assert result == violations
848
+
849
+ def test_two_inputs_first_violate(self):
850
+ # Construct the LCOV report
851
+ file_paths = ["file1.java"]
852
+
853
+ violations1 = self.MANY_VIOLATIONS
854
+ violations2 = self.FEW_VIOLATIONS
855
+
856
+ measured1 = self.FEW_MEASURED
857
+ measured2 = self.MANY_MEASURED
858
+
859
+ lcov = self._coverage_lcov(file_paths, violations1, measured1)
860
+ lcov2 = self._coverage_lcov(file_paths, violations2, measured2)
861
+
862
+ # Parse the report
863
+ coverage = LcovCoverageReporter([lcov, lcov2])
864
+
865
+ # By construction, each file has the same set
866
+ # of covered/uncovered lines
867
+ assert violations1 & violations2 == coverage.violations("file1.java")
868
+
869
+ assert measured1 | measured2 == coverage.measured_lines("file1.java")
870
+
871
+ def test_two_inputs_second_violate(self):
872
+ # Construct the LCOV report
873
+ file_paths = ["file1.java"]
874
+
875
+ violations1 = self.MANY_VIOLATIONS
876
+ violations2 = self.FEW_VIOLATIONS
877
+
878
+ measured1 = self.FEW_MEASURED
879
+ measured2 = self.MANY_MEASURED
880
+
881
+ lcov = self._coverage_lcov(file_paths, violations1, measured1)
882
+ lcov2 = self._coverage_lcov(file_paths, violations2, measured2)
883
+
884
+ # Parse the report
885
+ coverage = LcovCoverageReporter([lcov2, lcov])
886
+
887
+ # By construction, each file has the same set
888
+ # of covered/uncovered lines
889
+ assert violations1 & violations2 == coverage.violations("file1.java")
890
+
891
+ assert measured1 | measured2 == coverage.measured_lines("file1.java")
892
+
893
+ def test_three_inputs(self):
894
+ # Construct the LCOV report
895
+ file_paths = ["file1.java"]
896
+
897
+ violations1 = self.MANY_VIOLATIONS
898
+ violations2 = self.FEW_VIOLATIONS
899
+ violations3 = self.ONE_VIOLATION
900
+
901
+ measured1 = self.FEW_MEASURED
902
+ measured2 = self.MANY_MEASURED
903
+ measured3 = self.VERY_MANY_MEASURED
904
+
905
+ lcov = self._coverage_lcov(file_paths, violations1, measured1)
906
+ lcov2 = self._coverage_lcov(file_paths, violations2, measured2)
907
+ lcov3 = self._coverage_lcov(file_paths, violations3, measured3)
908
+
909
+ # Parse the report
910
+ coverage = LcovCoverageReporter([lcov2, lcov, lcov3])
911
+
912
+ # By construction, each file has the same set
913
+ # of covered/uncovered lines
914
+ assert violations1 & violations2 & violations3 == coverage.violations(
915
+ "file1.java"
916
+ )
917
+
918
+ assert measured1 | measured2 | measured3 == coverage.measured_lines(
919
+ "file1.java"
920
+ )
921
+
922
+ def test_different_files_in_inputs(self):
923
+ # Construct the LCOV report
924
+ lcov_repots = [
925
+ self._coverage_lcov(["file.java"], self.MANY_VIOLATIONS, self.FEW_MEASURED),
926
+ self._coverage_lcov(
927
+ ["other_file.java"], self.FEW_VIOLATIONS, self.MANY_MEASURED
928
+ ),
929
+ ]
930
+
931
+ # Parse the report
932
+ coverage = LcovCoverageReporter(lcov_repots)
933
+
934
+ assert self.MANY_VIOLATIONS == coverage.violations("file.java")
935
+ assert self.FEW_VIOLATIONS == coverage.violations("other_file.java")
936
+
937
+ def test_empty_violations(self):
938
+ """
939
+ Test that an empty violations report is handled properly
940
+ """
941
+ # Construct the LCOV report
942
+ file_paths = ["file1.java"]
943
+
944
+ violations1 = self.MANY_VIOLATIONS
945
+ violations2 = set()
946
+
947
+ measured1 = self.FEW_MEASURED
948
+ measured2 = self.MANY_MEASURED
949
+
950
+ lcov = self._coverage_lcov(file_paths, violations1, measured1)
951
+ lcov2 = self._coverage_lcov(file_paths, violations2, measured2)
952
+
953
+ # Parse the report
954
+ coverage = LcovCoverageReporter([lcov2, lcov])
955
+
956
+ # By construction, each file has the same set
957
+ # of covered/uncovered lines
958
+ assert violations1 & violations2 == coverage.violations("file1.java")
959
+
960
+ assert measured1 | measured2 == coverage.measured_lines("file1.java")
961
+
962
+ def test_no_such_file(self):
963
+ # Construct the LCOV report with no source files
964
+ lcov = self._coverage_lcov([], [], [])
965
+
966
+ # Parse the report
967
+ coverage = LcovCoverageReporter(lcov)
968
+
969
+ # Expect that we get no results
970
+ result = coverage.violations("file.java")
971
+ assert result == set()
972
+
973
+ def _coverage_lcov(self, file_paths, violations, measured):
974
+ """
975
+ Build an LCOV document based on the provided arguments.
976
+ """
977
+
978
+ violation_lines = {violation.line for violation in violations}
979
+
980
+ with tempfile.NamedTemporaryFile("w", delete=False) as f:
981
+ for file_path in file_paths:
982
+ f.write(f"SF:{file_path}\n")
983
+ for line_num in measured:
984
+ f.write(
985
+ f"DA:{line_num},{0 if line_num in violation_lines else 1}\n"
986
+ )
987
+ f.write("end_of_record\n")
988
+ try:
989
+ return LcovCoverageReporter.parse(f.name)
990
+ finally:
991
+ os.unlink(f.name)
992
+
993
+
797
994
  class TestPycodestyleQualityReporterTest:
798
995
  def test_quality(self, mocker, process_patcher):
799
996
  # Patch the output of `pycodestyle`
File without changes
File without changes
File without changes
File without changes