summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2015-11-22 10:58:58 -0500
committerNed Batchelder <ned@nedbatchelder.com>2015-11-22 10:58:58 -0500
commit7889f390058da471c253390a20bde71d88ba0956 (patch)
treefb0dd2d6d2d46a7bff599b1b0796384b99b655df
parent5a38a3e5ff72fcd6fdb2e8b62345974eb96097da (diff)
downloadpython-coveragepy-7889f390058da471c253390a20bde71d88ba0956.tar.gz
XML <source> element properly reflects --source= option. #439
-rw-r--r--AUTHORS.txt1
-rw-r--r--CHANGES.rst5
-rw-r--r--coverage/xmlreport.py12
-rw-r--r--tests/test_xml.py41
4 files changed, 56 insertions, 3 deletions
diff --git a/AUTHORS.txt b/AUTHORS.txt
index 7f6bbf9..de3d650 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -7,6 +7,7 @@ Adi Roiban
Alex Gaynor
Alexander Todorov
Anthony Sottile
+Arcadiy Ivanov
Ben Finney
Bill Hart
Brandon Rhodes
diff --git a/CHANGES.rst b/CHANGES.rst
index 417bf92..bd14278 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -13,6 +13,10 @@ Version 4.0.3, in progress
hanging the process (`issue 420`_), sometimes making database connections
fail (`issue 445`_).
+- The XML report now has correct ``<source>`` elements when using a
+ ``--source=`` option somewhere besides the current directory. This fixes
+ `issue 439`_. Thanks, Arcady Ivanov.
+
- Fixed an unusual edge case of detecting source encodings, described in
`issue 443`_.
@@ -22,6 +26,7 @@ Version 4.0.3, in progress
.. _issue 420: https://bitbucket.org/ned/coveragepy/issues/420/coverage-40-hangs-indefinitely-on-python27
.. _issue 438: https://bitbucket.org/ned/coveragepy/issues/438/parameterise-coverage-command-name
+.. _issue 439: https://bitbucket.org/ned/coveragepy/issues/439/incorrect-cobertura-file-sources-generated
.. _issue 443: https://bitbucket.org/ned/coveragepy/issues/443/coverage-gets-confused-when-encoding
.. _issue 445: https://bitbucket.org/ned/coveragepy/issues/445/django-app-cannot-connect-to-cassandra
diff --git a/coverage/xmlreport.py b/coverage/xmlreport.py
index d7c2f44..3023f4b 100644
--- a/coverage/xmlreport.py
+++ b/coverage/xmlreport.py
@@ -4,6 +4,7 @@
"""XML reporting for coverage.py"""
import os
+import os.path
import sys
import time
import xml.dom.minidom
@@ -38,6 +39,10 @@ class XmlReporter(Reporter):
super(XmlReporter, self).__init__(coverage, config)
self.source_paths = set()
+ if config.source:
+ for src in config.source:
+ if os.path.exists(src):
+ self.source_paths.add(files.canonical_filename(src))
self.packages = {}
self.xml_out = None
self.has_arcs = coverage.data.has_arcs()
@@ -141,9 +146,10 @@ class XmlReporter(Reporter):
parts = dirname.split("/")
dirname = "/".join(parts[:self.config.xml_package_depth])
package_name = dirname.replace("/", ".")
- className = fr.relative_filename()
+ rel_name = fr.relative_filename()
- self.source_paths.add(files.relative_directory().rstrip('/'))
+ if rel_name != fr.filename:
+ self.source_paths.add(fr.filename[:-len(rel_name)].rstrip('/'))
package = self.packages.setdefault(package_name, [{}, 0, 0, 0, 0])
xclass = self.xml_out.createElement("class")
@@ -201,7 +207,7 @@ class XmlReporter(Reporter):
branch_rate = "0"
xclass.setAttribute("branch-rate", branch_rate)
- package[0][className] = xclass
+ package[0][rel_name] = xclass
package[1] += class_hits
package[2] += class_lines
package[3] += class_br_hits
diff --git a/tests/test_xml.py b/tests/test_xml.py
index 5a6437e..b2d3021 100644
--- a/tests/test_xml.py
+++ b/tests/test_xml.py
@@ -4,6 +4,7 @@
"""Tests for XML reports from coverage.py."""
import os
+import os.path
import re
import coverage
@@ -141,6 +142,46 @@ class XmlReportTest(XmlTestHelpers, CoverageTest):
init_line = re_line(xml, 'filename="sub/__init__.py"')
self.assertIn('line-rate="1"', init_line)
+ def assert_source(self, xml, src):
+ """Assert that the XML has a <source> element with `src`."""
+ self.assertRegex(xml, r'<source>\s*{0}\s*</source>'.format(re.escape(src)))
+
+ def test_curdir_source(self):
+ # With no source= option, the XML report should explain that the source
+ # is in the current directory.
+ cov = self.run_doit()
+ cov.xml_report(outfile="-")
+ xml = self.stdout()
+ self.assert_source(xml, os.path.abspath("."))
+ self.assertEqual(xml.count('<source>'), 1)
+
+ def test_deep_source(self):
+ # When using source=, the XML report needs to mention those directories
+ # in the <source> elements.
+ # https://bitbucket.org/ned/coveragepy/issues/439/incorrect-cobertura-file-sources-generated
+ self.make_file("src/main/foo.py", "a = 1")
+ self.make_file("also/over/there/bar.py", "b = 2")
+ cov = coverage.Coverage(source=["src/main", "also/over/there", "not/really"])
+ cov.start()
+ mod_foo = self.import_local_file("foo", "src/main/foo.py")
+ mod_bar = self.import_local_file("bar", "also/over/there/bar.py")
+ cov.stop()
+ cov.xml_report([mod_foo, mod_bar], outfile="-")
+ xml = self.stdout()
+
+ self.assert_source(xml, os.path.abspath("src/main"))
+ self.assert_source(xml, os.path.abspath("also/over/there"))
+ self.assertEqual(xml.count('<source>'), 2)
+
+ self.assertIn(
+ '<class branch-rate="0" complexity="0" filename="foo.py" line-rate="1" name="foo.py">',
+ xml
+ )
+ self.assertIn(
+ '<class branch-rate="0" complexity="0" filename="bar.py" line-rate="1" name="bar.py">',
+ xml
+ )
+
class XmlPackageStructureTest(XmlTestHelpers, CoverageTest):
"""Tests about the package structure reported in the coverage.xml file."""