def test_empty_violations(self):
        """
        Test that an empty violations report is handled properly
        """

        # Construct the XML report
        file_paths = ['file1.py']

        violations1 = self.MANY_VIOLATIONS
        violations2 = set()

        measured1 = self.FEW_MEASURED
        measured2 = self.MANY_MEASURED

        xml = self._coverage_xml(file_paths, violations1, measured1)
        xml2 = self._coverage_xml(file_paths, violations2, measured2)

        # Parse the report
        coverage = XmlCoverageReporter([xml2, xml])

        # By construction, each file has the same set
        # of covered/uncovered lines
        self.assertEqual(
            violations1 & violations2,
            coverage.violations('file1.py')
        )

        self.assertEqual(
            measured1 | measured2,
            coverage.measured_lines('file1.py')
        )
    def test_non_python_violations(self):
        """
        Non python projects often just have a file name specified while
         the full path can be acquired from a sources tag in the XML.

         This test checks that flow by requesting violation info from a path
         that can only be constructed by using the path provided in the sources
         tag
        """
        fancy_path = 'superFancyPath'
        file_paths = ['file1.java']
        source_paths = [fancy_path]
        violations = self.MANY_VIOLATIONS
        measured = self.FEW_MEASURED

        xml = self._coverage_xml(file_paths,
                                 violations,
                                 measured,
                                 source_paths=source_paths)
        coverage = XmlCoverageReporter([xml])

        self.assertEqual(
            violations,
            coverage.violations('{0}/{1}'.format(fancy_path, file_paths[0])))

        self.assertEqual(
            measured,
            coverage.measured_lines('{0}/{1}'.format(fancy_path,
                                                     file_paths[0])))
    def test_three_inputs(self):

        # Construct the XML report
        file_paths = ['file1.py']

        violations1 = self.MANY_VIOLATIONS
        violations2 = self.FEW_VIOLATIONS
        violations3 = self.ONE_VIOLATION

        measured1 = self.FEW_MEASURED
        measured2 = self.MANY_MEASURED
        measured3 = self.VERY_MANY_MEASURED

        xml = self._coverage_xml(file_paths, violations1, measured1)
        xml2 = self._coverage_xml(file_paths, violations2, measured2)
        xml3 = self._coverage_xml(file_paths, violations3, measured3)

        # Parse the report
        coverage = XmlCoverageReporter([xml2, xml, xml3])

        # By construction, each file has the same set
        # of covered/uncovered lines
        self.assertEqual(
            violations1 & violations2 & violations3,
            coverage.violations('file1.py')
        )

        self.assertEqual(
            measured1 | measured2 | measured3,
            coverage.measured_lines('file1.py')
        )
    def test_empty_violations(self):
        """
        Test that an empty violations report is handled properly
        """

        # Construct the XML report
        file_paths = ['file1.py']

        violations1 = self.MANY_VIOLATIONS
        violations2 = set()

        measured1 = self.FEW_MEASURED
        measured2 = self.MANY_MEASURED

        xml = self._coverage_xml(file_paths, violations1, measured1)
        xml2 = self._coverage_xml(file_paths, violations2, measured2)

        # Parse the report
        coverage = XmlCoverageReporter([xml2, xml])

        # By construction, each file has the same set
        # of covered/uncovered lines
        self.assertEqual(violations1 & violations2,
                         coverage.violations('file1.py'))

        self.assertEqual(measured1 | measured2,
                         coverage.measured_lines('file1.py'))
    def test_three_inputs(self):

        # Construct the XML report
        file_paths = ['file1.py']

        violations1 = self.MANY_VIOLATIONS
        violations2 = self.FEW_VIOLATIONS
        violations3 = self.ONE_VIOLATION

        measured1 = self.FEW_MEASURED
        measured2 = self.MANY_MEASURED
        measured3 = self.VERY_MANY_MEASURED

        xml = self._coverage_xml(file_paths, violations1, measured1)
        xml2 = self._coverage_xml(file_paths, violations2, measured2)
        xml3 = self._coverage_xml(file_paths, violations3, measured3)

        # Parse the report
        coverage = XmlCoverageReporter([xml2, xml, xml3])

        # By construction, each file has the same set
        # of covered/uncovered lines
        self.assertEqual(violations1 & violations2 & violations3,
                         coverage.violations('file1.py'))

        self.assertEqual(measured1 | measured2 | measured3,
                         coverage.measured_lines('file1.py'))
    def test_no_such_file(self):

        # Construct the XML report with no source files
        xml = self._coverage_xml([], [], [])

        # Parse the report
        coverage = XmlCoverageReporter(xml)

        # Expect that we get no results
        result = coverage.violations('file.py')
        self.assertEqual(result, set([]))
    def test_no_such_file(self):

        # Construct the XML report with no source files
        xml = self._coverage_xml([], [], [])

        # Parse the report
        coverage = XmlCoverageReporter(xml)

        # Expect that we get no results
        result = coverage.violations('file.py')
        self.assertEqual(result, set([]))
    def test_different_files_in_inputs(self):

        # Construct the XML report
        xml_roots = [
            self._coverage_xml(['file.py'], self.MANY_VIOLATIONS, self.FEW_MEASURED),
            self._coverage_xml(['other_file.py'], self.FEW_VIOLATIONS, self.MANY_MEASURED)
        ]

        # Parse the report
        coverage = XmlCoverageReporter(xml_roots)

        self.assertEqual(self.MANY_VIOLATIONS, coverage.violations('file.py'))
        self.assertEqual(self.FEW_VIOLATIONS, coverage.violations('other_file.py'))
Exemple #9
0
def test_get_src_path_clover():
    GitPathTool._cwd = "/"
    GitPathTool._root = "/"
    clover_report = etree.parse(
        StringIO("""<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1622182664251" clover="3.2.0">
  <project timestamp="1622182664251" name="All files">
    <metrics statements="8" coveredstatements="8" conditionals="6" coveredconditionals="5" methods="2" coveredmethods="2" elements="16" coveredelements="15" complexity="0" loc="8" ncloc="8" packages="2" files="2" classes="2"/>
    <package name="src">
      <metrics statements="6" coveredstatements="6" conditionals="4" coveredconditionals="4" methods="1" coveredmethods="1"/>
      <file name="isLucky.js" path="isLucky.js">
        <metrics statements="6" coveredstatements="6" conditionals="4" coveredconditionals="4" methods="1" coveredmethods="1"/>
        <line num="2" count="3" type="cond" truecount="2" falsecount="0"/>
        <line num="3" count="1" type="stmt"/>
        <line num="5" count="2" type="cond" truecount="2" falsecount="0"/>
        <line num="6" count="1" type="stmt"/>
        <line num="8" count="1" type="stmt"/>
        <line num="12" count="1" type="stmt"/>
      </file>
    </package>
    <package name="src.test">
      <metrics statements="2" coveredstatements="2" conditionals="2" coveredconditionals="1" methods="1" coveredmethods="1"/>
      <file name="isLucky2.js" path="isLucky2.js">
        <metrics statements="2" coveredstatements="2" conditionals="2" coveredconditionals="1" methods="1" coveredmethods="1"/>
        <line num="1" count="1" type="cond" truecount="1" falsecount="1"/>
        <line num="3" count="1" type="stmt"/>
      </file>
    </package>
  </project>
</coverage>"""))
    result = XmlCoverageReporter.get_src_path_line_nodes_clover(
        clover_report, "isLucky.js")
    assert sorted([int(line.attrib["num"])
                   for line in result]) == [2, 3, 5, 6, 8, 12]
Exemple #10
0
def generate_coverage_report(coverage_xml, compare_branch,
                             html_report=None, css_file=None,
                             ignore_staged=False, ignore_unstaged=False,
                             exclude=None, src_roots=None):
    """
    Generate the diff coverage report, using kwargs from `parse_args()`.
    """
    diff = GitDiffReporter(
        compare_branch, git_diff=GitDiffTool(), ignore_staged=ignore_staged,
        ignore_unstaged=ignore_unstaged, exclude=exclude)

    xml_roots = [cElementTree.parse(xml_root) for xml_root in coverage_xml]
    coverage = XmlCoverageReporter(xml_roots, src_roots)

    # Build a report generator
    if html_report is not None:
        css_url = css_file
        if css_url is not None:
            css_url = os.path.relpath(css_file, os.path.dirname(html_report))
        reporter = HtmlReportGenerator(coverage, diff, css_url=css_url)
        with open(html_report, "wb") as output_file:
            reporter.generate_report(output_file)
        if css_file is not None:
            with open(css_file, "wb") as output_file:
                reporter.generate_css(output_file)

    reporter = StringReportGenerator(coverage, diff)
    output_file = sys.stdout if six.PY2 else sys.stdout.buffer

    # Generate the report
    reporter.generate_report(output_file)
    return reporter.total_percent_covered()
def coverage_xml_parse(xml_file_path, src_file_path):
    from diff_cover.violationsreporters.violations_reporter import XmlCoverageReporter
    from diff_cover.git_path import GitPathTool

    try:
        # Needed for Python < 3.3, works up to 3.8
        import xml.etree.cElementTree as etree
    except ImportError:
        # Python 3.9 onwards
        import xml.etree.ElementTree as etree

    GitPathTool.set_cwd(None)
    xml_roots = [etree.parse(xml_root) for xml_root in [xml_file_path]]
    coverage = XmlCoverageReporter(xml_roots, [os.path.dirname(src_file_path)])
    coverage._cache_file(src_file_path)
    return coverage._info_cache[src_file_path]
Exemple #12
0
def generate_coverage_report(coverage_xml,
                             compare_branch,
                             html_report=None,
                             ignore_unstaged=False):
    """
    Generate the diff coverage report, using kwargs from `parse_args()`.
    """
    diff = GitDiffReporter(compare_branch,
                           git_diff=GitDiffTool(),
                           ignore_unstaged=ignore_unstaged)

    xml_roots = [cElementTree.parse(xml_root) for xml_root in coverage_xml]
    coverage = XmlCoverageReporter(xml_roots)

    # Build a report generator
    if html_report is not None:
        reporter = HtmlReportGenerator(coverage, diff)
        with open(html_report, "wb") as output_file:
            reporter.generate_report(output_file)

    reporter = StringReportGenerator(coverage, diff)
    output_file = sys.stdout if six.PY2 else sys.stdout.buffer

    # Generate the report
    reporter.generate_report(output_file)
    return reporter.total_percent_covered()
    def test_different_files_in_inputs(self):

        # Construct the XML report
        xml_roots = [
            self._coverage_xml(['file.py'], self.MANY_VIOLATIONS,
                               self.FEW_MEASURED),
            self._coverage_xml(['other_file.py'], self.FEW_VIOLATIONS,
                               self.MANY_MEASURED)
        ]

        # Parse the report
        coverage = XmlCoverageReporter(xml_roots)

        self.assertEqual(self.MANY_VIOLATIONS, coverage.violations('file.py'))
        self.assertEqual(self.FEW_VIOLATIONS,
                         coverage.violations('other_file.py'))
Exemple #14
0
def generate_coverage_report(
    coverage_xml,
    compare_branch,
    html_report=None,
    css_file=None,
    json_report=None,
    markdown_report=None,
    ignore_staged=False,
    ignore_unstaged=False,
    exclude=None,
    src_roots=None,
    diff_range_notation=None,
    ignore_whitespace=False,
    quiet=False,
    show_uncovered=False,
):
    """
    Generate the diff coverage report, using kwargs from `parse_args()`.
    """
    diff = GitDiffReporter(
        compare_branch,
        git_diff=GitDiffTool(diff_range_notation, ignore_whitespace),
        ignore_staged=ignore_staged,
        ignore_unstaged=ignore_unstaged,
        exclude=exclude,
    )

    xml_roots = [etree.parse(xml_root) for xml_root in coverage_xml]
    coverage = XmlCoverageReporter(xml_roots, src_roots)

    # Build a report generator
    if html_report is not None:
        css_url = css_file
        if css_url is not None:
            css_url = os.path.relpath(css_file, os.path.dirname(html_report))
        reporter = HtmlReportGenerator(coverage, diff, css_url=css_url)
        with open(html_report, "wb") as output_file:
            reporter.generate_report(output_file)
        if css_file is not None:
            with open(css_file, "wb") as output_file:
                reporter.generate_css(output_file)

    elif json_report is not None:
        reporter = JsonReportGenerator(coverage, diff)
        with open(json_report, "wb") as output_file:
            reporter.generate_report(output_file)

    elif markdown_report is not None:
        reporter = MarkdownReportGenerator(coverage, diff)
        with open(markdown_report, "wb") as output_file:
            reporter.generate_report(output_file)

    # Generate the report for stdout
    reporter = StringReportGenerator(coverage, diff, show_uncovered)
    output_file = io.BytesIO() if quiet else sys.stdout.buffer

    # Generate the report
    reporter.generate_report(output_file)
    return reporter.total_percent_covered()
    def test_violations(self):

        # Construct the XML report
        file_paths = ['file1.py', 'subdir/file2.py']
        violations = self.MANY_VIOLATIONS
        measured = self.FEW_MEASURED
        xml = self._coverage_xml(file_paths, violations, measured)

        # Parse the report
        coverage = XmlCoverageReporter(xml)

        # Expect that the name is set
        self.assertEqual(coverage.name(), "XML")

        # By construction, each file has the same set
        # of covered/uncovered lines
        self.assertEqual(violations, coverage.violations('file1.py'))
        self.assertEqual(measured, coverage.measured_lines('file1.py'))

        # Try getting a smaller range
        result = coverage.violations('subdir/file2.py')
        self.assertEqual(result, violations)

        # Once more on the first file (for caching)
        result = coverage.violations('file1.py')
        self.assertEqual(result, violations)
    def test_violations(self):

        # Construct the XML report
        file_paths = ['file1.py', 'subdir/file2.py']
        violations = self.MANY_VIOLATIONS
        measured = self.FEW_MEASURED
        xml = self._coverage_xml(file_paths, violations, measured)

        # Parse the report
        coverage = XmlCoverageReporter(xml)

        # Expect that the name is set
        self.assertEqual(coverage.name(), "XML")

        # By construction, each file has the same set
        # of covered/uncovered lines
        self.assertEqual(violations, coverage.violations('file1.py'))
        self.assertEqual(measured, coverage.measured_lines('file1.py'))

        # Try getting a smaller range
        result = coverage.violations('subdir/file2.py')
        self.assertEqual(result, violations)

        # Once more on the first file (for caching)
        result = coverage.violations('file1.py')
        self.assertEqual(result, violations)
Exemple #17
0
def generate_coverage_report(coverage_xml,
                             compare_branch,
                             html_report=None,
                             css_file=None,
                             ignore_staged=False,
                             ignore_unstaged=False,
                             exclude=None):
    """
    Generate the diff coverage report, using kwargs from `parse_args()`.
    """
    diff = GitDiffReporter(compare_branch,
                           git_diff=GitDiffTool(),
                           ignore_staged=ignore_staged,
                           ignore_unstaged=ignore_unstaged,
                           exclude=exclude)

    xml_roots = [cElementTree.parse(xml_root) for xml_root in coverage_xml]
    clover_xml_roots = [
        clover_xml for clover_xml in xml_roots
        if clover_xml.findall('.[@clover]')
    ]
    cobertura_xml_roots = [
        cobertura_xml for cobertura_xml in xml_roots
        if cobertura_xml.findall('.[@line-rate]')
    ]
    if clover_xml_roots and cobertura_xml_roots:
        raise TypeError("Can't handle mixed coverage reports")
    elif clover_xml_roots:
        coverage = CloverXmlCoverageReporter(clover_xml_roots)
    elif cobertura_xml_roots:
        coverage = XmlCoverageReporter(cobertura_xml_roots)

    # Build a report generator
    if html_report is not None:
        css_url = css_file
        if css_url is not None:
            css_url = os.path.relpath(css_file, os.path.dirname(html_report))
        reporter = HtmlReportGenerator(coverage, diff, css_url=css_url)
        with open(html_report, "wb") as output_file:
            reporter.generate_report(output_file)
        if css_file is not None:
            with open(css_file, "wb") as output_file:
                reporter.generate_css(output_file)

    reporter = StringReportGenerator(coverage, diff)
    output_file = sys.stdout if six.PY2 else sys.stdout.buffer

    # Generate the report
    reporter.generate_report(output_file)
    return reporter.total_percent_covered()
    def test_non_python_violations(self):
        """
        Non python projects often just have a file name specified while
         the full path can be acquired from a sources tag in the XML.

         This test checks that flow by requesting violation info from a path
         that can only be constructed by using the path provided in the sources
         tag
        """
        fancy_path = 'superFancyPath'
        file_paths = ['file1.java']
        source_paths = [fancy_path]
        violations = self.MANY_VIOLATIONS
        measured = self.FEW_MEASURED

        xml = self._coverage_xml(
            file_paths,
            violations,
            measured,
            source_paths=source_paths
        )
        coverage = XmlCoverageReporter([xml])

        self.assertEqual(
            violations,
            coverage.violations(
                '{0}/{1}'.format(fancy_path, file_paths[0])
            )
        )

        self.assertEqual(
            measured,
            coverage.measured_lines(
                '{0}/{1}'.format(fancy_path, file_paths[0])
            )
        )
def generate_coverage_report(coverage_xml, compare_branch,
                             html_report=None, css_file=None,
                             json_report=None,
                             ignore_staged=False, ignore_unstaged=False,
                             exclude=None, src_roots=None, diff_range_notation=None,
                             target_dir=None, diff_json=None):
    """
    Generate the diff coverage report, using kwargs from `parse_args()`.
    """
    if target_dir:
        class FileDiffReporter(GitDiffReporter):
            def __init__(self, *args, **kwargs):
                self.target_dir = kwargs.pop("td")
                super(FileDiffReporter, self).__init__(*args, **kwargs)

            def _git_diff(self):
                def compare(left, right):
                    d = difile.Difile()
                    result = d.compare_dir(left, right)
                    diff_result = dict()

                    for each_file in result:
                        if not each_file:
                            continue
                        key = each_file[0].file_path.as_posix()
                        if key.startswith(str(self.target_dir)):
                            key = key.replace(str(self.target_dir) + "/", "")
                        if key not in diff_result:
                            diff_result[key] = []
                        for each_line in each_file:
                            diff_result[key].append(each_line.line_no)
                    return diff_result
                return compare(src_roots[0], self.target_dir)

        diff = FileDiffReporter(
            compare_branch, git_diff=GitDiffTool(diff_range_notation),
            ignore_staged=ignore_staged, ignore_unstaged=ignore_unstaged,
            exclude=exclude, td=target_dir)
    else:
        diff = GitDiffReporter(
            compare_branch, git_diff=GitDiffTool(diff_range_notation),
            ignore_staged=ignore_staged, ignore_unstaged=ignore_unstaged,
            exclude=exclude)

    xml_roots = [etree.parse(xml_root) for xml_root in coverage_xml]
    coverage = XmlCoverageReporter(xml_roots, src_roots)

    if diff_json:
        diff_dict = diff._git_diff()
        with open(diff_json, "w") as f:
            json.dump(diff_dict, f)

    # Build a report generator
    if html_report is not None:
        css_url = css_file
        if css_url is not None:
            css_url = os.path.relpath(css_file, os.path.dirname(html_report))
        reporter = HtmlReportGenerator(coverage, diff, css_url=css_url)
        with open(html_report, "wb") as output_file:
            reporter.generate_report(output_file)
        if css_file is not None:
            with open(css_file, "wb") as output_file:
                reporter.generate_css(output_file)

    elif json_report is not None:
        reporter = JsonReportGenerator(coverage, diff)
        with open(json_report, "wb") as output_file:
            reporter.generate_report(output_file)

    reporter = StringReportGenerator(coverage, diff)
    output_file = sys.stdout if six.PY2 else sys.stdout.buffer

    # Generate the report
    reporter.generate_report(output_file)
    return reporter.total_percent_covered()