summaryrefslogtreecommitdiff
path: root/coverage/xmlreport.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2009-09-25 07:52:21 -0400
committerNed Batchelder <ned@nedbatchelder.com>2009-09-25 07:52:21 -0400
commit97bdac70cc42ca7cb87cfbb3edf2f5ea1b9fa767 (patch)
treed4cf8a9c74931ec0e5eaa05ef17e5ee2fdb86070 /coverage/xmlreport.py
parent98f9e829485eeba4fbe51d98cebf6c7050ade482 (diff)
downloadpython-coveragepy-97bdac70cc42ca7cb87cfbb3edf2f5ea1b9fa767.tar.gz
Clean up the XML code, use common reporting infrastructure, add a Generator comment, don't output packages that don't really exist.
Diffstat (limited to 'coverage/xmlreport.py')
-rw-r--r--coverage/xmlreport.py145
1 files changed, 74 insertions, 71 deletions
diff --git a/coverage/xmlreport.py b/coverage/xmlreport.py
index 8d5e4dd..dbec7e9 100644
--- a/coverage/xmlreport.py
+++ b/coverage/xmlreport.py
@@ -3,7 +3,8 @@
import os, sys
import xml.dom.minidom
-from coverage.backward import sorted
+from coverage import __version__
+from coverage.backward import sorted # pylint: disable-msg=W0622
from coverage.report import Reporter
@@ -12,6 +13,9 @@ class XmlReporter(Reporter):
def __init__(self, coverage, ignore_errors=False):
super(XmlReporter, self).__init__(coverage, ignore_errors)
+
+ self.packages = None
+ self.xml_out = None
def report(self, morfs, omit_prefixes=None, outfile=None):
"""Generate a Cobertura-compatible XML report for `morfs`.
@@ -28,88 +32,87 @@ class XmlReporter(Reporter):
impl = xml.dom.minidom.getDOMImplementation()
docType = impl.createDocumentType(
"coverage", None,
- "http://cobertura.sourceforge.net/xml/coverage-03.dtd" )
- doc = impl.createDocument(None, "coverage", docType)
- root = doc.documentElement
+ "http://cobertura.sourceforge.net/xml/coverage-03.dtd"
+ )
+ self.xml_out = impl.createDocument(None, "coverage", docType)
+ root = self.xml_out.documentElement
- packageXml = doc.createElement("packages")
+ root.appendChild(self.xml_out.createComment(
+ " Generated by coverage.py %s: "
+ "http://nedbatchelder.com/code/coverage " % __version__
+ ))
+ packageXml = self.xml_out.createElement("packages")
root.appendChild(packageXml)
- packages = {}
+ self.packages = {}
errors = False
- for cu in self.code_units:
- # Create the 'lines' and 'package' XML elements, which
- # are populated later. Note that a package == a directory.
- dirname, fname = os.path.split(cu.name)
- dirname = dirname or '.'
- package = packages.setdefault(
- dirname, [ doc.createElement("package"), {}, 0, 0, 0, 0 ] )
- c = doc.createElement("class")
- lines = doc.createElement("lines")
- c.appendChild(lines)
- className = fname.replace('.', '_')
- c.setAttribute("name", className)
- c.setAttribute("filename", cu.filename)
- c.setAttribute("complexity", "0.0")
-
- try:
- statements, _, missing, _ = self.coverage._analyze(cu)
-
- # For each statement, create an XML 'line' element.
- for line in statements:
- l = doc.createElement("line")
- l.setAttribute("number", str(line))
-
- # Q: can we get info about the number of times
- # a statement is executed? If so, that should be
- # recorded here.
- l.setAttribute("hits", str(int(not line in missing)))
-
- # Q: can we get info about whether this statement
- # is a branch? If so, that data should be
- # used here.
- l.setAttribute("branch", "false")
- lines.appendChild(l)
- class_lines = 1.0 * len(statements)
- class_hits = class_lines - len(missing)
- class_branches = 0.0
- class_branch_hits = 0.0
-
- # Finalize the statistics that are collected in the XML DOM.
- line_rate = class_hits / (class_lines or 1.0)
- branch_rate = class_branch_hits / (class_branches or 1.0)
- c.setAttribute("line-rate", str(line_rate))
- c.setAttribute("branch-rate", str(branch_rate))
- package[1][className] = c
- package[2] += class_hits
- package[3] += class_lines
- package[4] += class_branch_hits
- package[5] += class_branches
- except KeyboardInterrupt: #pragma: no cover
- raise
- except:
- if not self.ignore_errors:
- typ, msg = sys.exc_info()[:2]
- fmt_err = "%s %s: %s\n"
- outfile.write(fmt_err % (cu.name, typ.__name__, msg))
- errors = True
-
+
+ self.report_files(self.xml_file, morfs, omit_prefixes=omit_prefixes)
+
# Don't write the XML data if we've encountered errors.
if errors:
return
# Populate the XML DOM with the package info.
- for packageName, packageData in packages.items():
- package = packageData[0]
+ for packageName, packageData in self.packages.items():
+ package = self.xml_out.createElement("package")
packageXml.appendChild(package)
- classes = doc.createElement("classes")
+ classes = self.xml_out.createElement("classes")
package.appendChild(classes)
- for className in sorted(packageData[1].keys()):
- classes.appendChild(packageData[1][className])
+ for className in sorted(packageData[0].keys()):
+ classes.appendChild(packageData[0][className])
package.setAttribute("name", packageName.replace(os.sep, '.'))
- package.setAttribute("line-rate", str(packageData[2]/(packageData[3] or 1.0)))
- package.setAttribute("branch-rate", str(packageData[4] / (packageData[5] or 1.0) ))
+ package.setAttribute("line-rate", str(packageData[1]/(packageData[2] or 1.0)))
+ package.setAttribute("branch-rate", str(packageData[3]/(packageData[4] or 1.0)))
package.setAttribute("complexity", "0.0")
# Use the DOM to write the output file.
- outfile.write(doc.toprettyxml())
+ outfile.write(self.xml_out.toprettyxml())
+
+ def xml_file(self, cu, statements, excluded, missing):
+ """Add to the XML report for a single file."""
+
+ # Create the 'lines' and 'package' XML elements, which
+ # are populated later. Note that a package == a directory.
+ dirname, fname = os.path.split(cu.name)
+ dirname = dirname or '.'
+ package = self.packages.setdefault(dirname, [ {}, 0, 0, 0, 0 ])
+ c = self.xml_out.createElement("class")
+ lines = self.xml_out.createElement("lines")
+ c.appendChild(lines)
+ className = fname.replace('.', '_')
+ c.setAttribute("name", className)
+ c.setAttribute("filename", cu.filename)
+ c.setAttribute("complexity", "0.0")
+
+ # For each statement, create an XML 'line' element.
+ for line in statements:
+ l = self.xml_out.createElement("line")
+ l.setAttribute("number", str(line))
+
+ # Q: can we get info about the number of times
+ # a statement is executed? If so, that should be
+ # recorded here.
+ l.setAttribute("hits", str(int(not line in missing)))
+
+ # Q: can we get info about whether this statement
+ # is a branch? If so, that data should be
+ # used here.
+ l.setAttribute("branch", "false")
+ lines.appendChild(l)
+
+ class_lines = 1.0 * len(statements)
+ class_hits = class_lines - len(missing)
+ class_branches = 0.0
+ class_branch_hits = 0.0
+
+ # Finalize the statistics that are collected in the XML DOM.
+ line_rate = class_hits / (class_lines or 1.0)
+ branch_rate = class_branch_hits / (class_branches or 1.0)
+ c.setAttribute("line-rate", str(line_rate))
+ c.setAttribute("branch-rate", str(branch_rate))
+ package[0][className] = c
+ package[1] += class_hits
+ package[2] += class_lines
+ package[3] += class_branch_hits
+ package[4] += class_branches