diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2018-11-10 14:11:47 -0500 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2018-11-11 16:45:33 -0500 |
commit | c376209f35331b358e59c79ed3537a2ed920d677 (patch) | |
tree | 5dddd7715de562ffa851be89738af3f4e9644b3c /coverage/xmlreport.py | |
parent | 19c093580d9ad80fd45dd6ea333c24c059c891bf (diff) | |
download | python-coveragepy-git-c376209f35331b358e59c79ed3537a2ed920d677.tar.gz |
Canonicalize the XML output
https://bugs.python.org/issue34160 added retaining the user's attribute
order to the XML output, which removed the sorting that used to happen.
This broke our XML tests, which compare against saved gold files. This
adds in a rough-and-ready canonicalization to avoid the problem.
Maybe the core devs will eventually support a sort_attributes option,
and I can get rid of this.
Diffstat (limited to 'coverage/xmlreport.py')
-rw-r--r-- | coverage/xmlreport.py | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/coverage/xmlreport.py b/coverage/xmlreport.py index 5148b54a..6c07337a 100644 --- a/coverage/xmlreport.py +++ b/coverage/xmlreport.py @@ -1,3 +1,4 @@ +# coding: utf-8 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt @@ -5,6 +6,7 @@ import os import os.path +import re import sys import time import xml.dom.minidom @@ -124,11 +126,8 @@ class XmlReporter(Reporter): xcoverage.setAttribute("branch-rate", "0") xcoverage.setAttribute("complexity", "0") - # Use the DOM to write the output file. - out = self.xml_out.toprettyxml() - if env.PY2: - out = out.encode("utf8") - outfile.write(out) + # Write the output file. + outfile.write(serialize_xml(self.xml_out)) # Return the total percentage. denom = lnum_tot + bnum_tot @@ -219,3 +218,23 @@ class XmlReporter(Reporter): package[2] += class_lines package[3] += class_br_hits package[4] += class_branches + + +def serialize_xml(dom): + """Serialize a minidom node to XML.""" + out = dom.toprettyxml() + if env.PY2: + out = out.encode("utf8") + # In Python 3.8, minidom lost the sorting of attributes: https://bugs.python.org/issue34160 + # For the limited kinds of XML we produce, this re-sorts them. + if env.PYVERSION >= (3, 8): + rx_attr = r' [\w-]+="[^"]*"' + rx_attrs = r'(' + rx_attr + ')+' + fixed_lines = [] + for line in out.splitlines(True): + hollow_line = re.sub(rx_attrs, u"☺", line) + attrs = sorted(re.findall(rx_attr, line)) + new_line = hollow_line.replace(u"☺", "".join(attrs)) + fixed_lines.append(new_line) + out = "".join(fixed_lines) + return out |