|
1 # coding: utf-8 |
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 |
2 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 |
2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt |
3 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt |
3 |
4 |
4 """XML reporting for coverage.py""" |
5 """XML reporting for coverage.py""" |
5 |
6 |
6 import os |
7 import os |
7 import os.path |
8 import os.path |
|
9 import re |
8 import sys |
10 import sys |
9 import time |
11 import time |
10 import xml.dom.minidom |
12 import xml.dom.minidom |
11 |
13 |
12 from coverage import env |
14 from coverage import env |
121 xcoverage.setAttribute("branches-covered", "0") |
123 xcoverage.setAttribute("branches-covered", "0") |
122 xcoverage.setAttribute("branches-valid", "0") |
124 xcoverage.setAttribute("branches-valid", "0") |
123 xcoverage.setAttribute("branch-rate", "0") |
125 xcoverage.setAttribute("branch-rate", "0") |
124 xcoverage.setAttribute("complexity", "0") |
126 xcoverage.setAttribute("complexity", "0") |
125 |
127 |
126 # Use the DOM to write the output file. |
128 # Write the output file. |
127 out = self.xml_out.toprettyxml() |
129 outfile.write(serialize_xml(self.xml_out)) |
128 if env.PY2: |
|
129 out = out.encode("utf8") |
|
130 outfile.write(out) |
|
131 |
130 |
132 # Return the total percentage. |
131 # Return the total percentage. |
133 denom = lnum_tot + bnum_tot |
132 denom = lnum_tot + bnum_tot |
134 if denom == 0: |
133 if denom == 0: |
135 pct = 0.0 |
134 pct = 0.0 |
216 package[0][rel_name] = xclass |
215 package[0][rel_name] = xclass |
217 package[1] += class_hits |
216 package[1] += class_hits |
218 package[2] += class_lines |
217 package[2] += class_lines |
219 package[3] += class_br_hits |
218 package[3] += class_br_hits |
220 package[4] += class_branches |
219 package[4] += class_branches |
|
220 |
|
221 |
|
222 def serialize_xml(dom): |
|
223 """Serialize a minidom node to XML.""" |
|
224 out = dom.toprettyxml() |
|
225 if env.PY2: |
|
226 out = out.encode("utf8") |
|
227 # In Python 3.8, minidom lost the sorting of attributes: https://bugs.python.org/issue34160 |
|
228 # For the limited kinds of XML we produce, this re-sorts them. |
|
229 if env.PYVERSION >= (3, 8): |
|
230 rx_attr = r' [\w-]+="[^"]*"' |
|
231 rx_attrs = r'(' + rx_attr + ')+' |
|
232 fixed_lines = [] |
|
233 for line in out.splitlines(True): |
|
234 hollow_line = re.sub(rx_attrs, u"☺", line) |
|
235 attrs = sorted(re.findall(rx_attr, line)) |
|
236 new_line = hollow_line.replace(u"☺", "".join(attrs)) |
|
237 fixed_lines.append(new_line) |
|
238 out = "".join(fixed_lines) |
|
239 return out |