Skip to content

Commit ffc701a

Browse files
committed
mypy: test_xml.py
1 parent 5580cf8 commit ffc701a

File tree

2 files changed

+50
-43
lines changed

2 files changed

+50
-43
lines changed

tests/test_xml.py

+49-42
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
import os
77
import os.path
88
import re
9+
10+
from typing import Any, Dict, Iterator, Tuple, Union
911
from xml.etree import ElementTree
1012

1113
import pytest
1214

1315
import coverage
16+
from coverage import Coverage
1417
from coverage.exceptions import NoDataError
1518
from coverage.files import abs_file
1619
from coverage.misc import import_local_file
@@ -23,7 +26,7 @@
2326
class XmlTestHelpers(CoverageTest):
2427
"""Methods to use from XML tests."""
2528

26-
def run_doit(self):
29+
def run_doit(self) -> Coverage:
2730
"""Construct a simple sub-package."""
2831
self.make_file("sub/__init__.py")
2932
self.make_file("sub/doit.py", "print('doit!')")
@@ -32,7 +35,7 @@ def run_doit(self):
3235
self.start_import_stop(cov, "main")
3336
return cov
3437

35-
def make_tree(self, width, depth, curdir="."):
38+
def make_tree(self, width: int, depth: int, curdir: str=".") -> None:
3639
"""Make a tree of packages.
3740
3841
Makes `width` directories, named d0 .. d{width-1}. Each directory has
@@ -44,7 +47,7 @@ def make_tree(self, width, depth, curdir="."):
4447
if depth == 0:
4548
return
4649

47-
def here(p):
50+
def here(p: str) -> str:
4851
"""A path for `p` in our currently interesting directory."""
4952
return os.path.join(curdir, p)
5053

@@ -57,7 +60,11 @@ def here(p):
5760
filename = here(f"f{i}.py")
5861
self.make_file(filename, f"# {filename}\n")
5962

60-
def assert_source(self, xmldom, src):
63+
def assert_source(
64+
self,
65+
xmldom: Union[ElementTree.Element, ElementTree.ElementTree],
66+
src: str,
67+
) -> None:
6168
"""Assert that the XML has a <source> element with `src`."""
6269
src = abs_file(src)
6370
elts = xmldom.findall(".//sources/source")
@@ -69,7 +76,7 @@ class XmlTestHelpersTest(XmlTestHelpers, CoverageTest):
6976

7077
run_in_temp_dir = False
7178

72-
def test_assert_source(self):
79+
def test_assert_source(self) -> None:
7380
dom = ElementTree.fromstring("""\
7481
<doc>
7582
<src>foo</src>
@@ -94,24 +101,24 @@ def test_assert_source(self):
94101
class XmlReportTest(XmlTestHelpers, CoverageTest):
95102
"""Tests of the XML reports from coverage.py."""
96103

97-
def make_mycode_data(self):
104+
def make_mycode_data(self) -> None:
98105
"""Pretend that we ran mycode.py, so we can report on it."""
99106
self.make_file("mycode.py", "print('hello')\n")
100107
self.make_data_file(lines={abs_file("mycode.py"): [1]})
101108

102-
def run_xml_report(self, **kwargs):
109+
def run_xml_report(self, **kwargs: Any) -> None:
103110
"""Run xml_report()"""
104111
cov = coverage.Coverage()
105112
cov.load()
106113
cov.xml_report(**kwargs)
107114

108-
def test_default_file_placement(self):
115+
def test_default_file_placement(self) -> None:
109116
self.make_mycode_data()
110117
self.run_xml_report()
111118
self.assert_exists("coverage.xml")
112119
assert self.stdout() == ""
113120

114-
def test_argument_affects_xml_placement(self):
121+
def test_argument_affects_xml_placement(self) -> None:
115122
self.make_mycode_data()
116123
cov = coverage.Coverage(messages=True)
117124
cov.load()
@@ -120,28 +127,28 @@ def test_argument_affects_xml_placement(self):
120127
self.assert_doesnt_exist("coverage.xml")
121128
self.assert_exists("put_it_there.xml")
122129

123-
def test_output_directory_does_not_exist(self):
130+
def test_output_directory_does_not_exist(self) -> None:
124131
self.make_mycode_data()
125132
self.run_xml_report(outfile="nonexistent/put_it_there.xml")
126133
self.assert_doesnt_exist("coverage.xml")
127134
self.assert_doesnt_exist("put_it_there.xml")
128135
self.assert_exists("nonexistent/put_it_there.xml")
129136

130-
def test_config_affects_xml_placement(self):
137+
def test_config_affects_xml_placement(self) -> None:
131138
self.make_mycode_data()
132139
self.make_file(".coveragerc", "[xml]\noutput = xml.out\n")
133140
self.run_xml_report()
134141
self.assert_doesnt_exist("coverage.xml")
135142
self.assert_exists("xml.out")
136143

137-
def test_no_data(self):
144+
def test_no_data(self) -> None:
138145
# https://github.com/nedbat/coveragepy/issues/210
139146
with pytest.raises(NoDataError, match="No data to report."):
140147
self.run_xml_report()
141148
self.assert_doesnt_exist("coverage.xml")
142149
self.assert_doesnt_exist(".coverage")
143150

144-
def test_no_source(self):
151+
def test_no_source(self) -> None:
145152
# Written while investigating a bug, might as well keep it.
146153
# https://github.com/nedbat/coveragepy/issues/208
147154
self.make_file("innocuous.py", "a = 4")
@@ -156,23 +163,23 @@ def test_no_source(self):
156163
)
157164
self.assert_exists("coverage.xml")
158165

159-
def test_filename_format_showing_everything(self):
166+
def test_filename_format_showing_everything(self) -> None:
160167
cov = self.run_doit()
161168
cov.xml_report()
162169
dom = ElementTree.parse("coverage.xml")
163170
elts = dom.findall(".//class[@name='doit.py']")
164171
assert len(elts) == 1
165172
assert elts[0].get('filename') == "sub/doit.py"
166173

167-
def test_filename_format_including_filename(self):
174+
def test_filename_format_including_filename(self) -> None:
168175
cov = self.run_doit()
169176
cov.xml_report(["sub/doit.py"])
170177
dom = ElementTree.parse("coverage.xml")
171178
elts = dom.findall(".//class[@name='doit.py']")
172179
assert len(elts) == 1
173180
assert elts[0].get('filename') == "sub/doit.py"
174181

175-
def test_filename_format_including_module(self):
182+
def test_filename_format_including_module(self) -> None:
176183
cov = self.run_doit()
177184
import sub.doit # pylint: disable=import-error
178185
cov.xml_report([sub.doit])
@@ -181,7 +188,7 @@ def test_filename_format_including_module(self):
181188
assert len(elts) == 1
182189
assert elts[0].get('filename') == "sub/doit.py"
183190

184-
def test_reporting_on_nothing(self):
191+
def test_reporting_on_nothing(self) -> None:
185192
# Used to raise a zero division error:
186193
# https://github.com/nedbat/coveragepy/issues/250
187194
self.make_file("empty.py", "")
@@ -194,7 +201,7 @@ def test_reporting_on_nothing(self):
194201
assert elts[0].get('filename') == "empty.py"
195202
assert elts[0].get('line-rate') == '1'
196203

197-
def test_empty_file_is_100_not_0(self):
204+
def test_empty_file_is_100_not_0(self) -> None:
198205
# https://github.com/nedbat/coveragepy/issues/345
199206
cov = self.run_doit()
200207
cov.xml_report()
@@ -203,14 +210,14 @@ def test_empty_file_is_100_not_0(self):
203210
assert len(elts) == 1
204211
assert elts[0].get('line-rate') == '1'
205212

206-
def test_empty_file_is_skipped(self):
213+
def test_empty_file_is_skipped(self) -> None:
207214
cov = self.run_doit()
208215
cov.xml_report(skip_empty=True)
209216
dom = ElementTree.parse("coverage.xml")
210217
elts = dom.findall(".//class[@name='__init__.py']")
211218
assert len(elts) == 0
212219

213-
def test_curdir_source(self):
220+
def test_curdir_source(self) -> None:
214221
# With no source= option, the XML report should explain that the source
215222
# is in the current directory.
216223
cov = self.run_doit()
@@ -220,7 +227,7 @@ def test_curdir_source(self):
220227
sources = dom.findall(".//source")
221228
assert len(sources) == 1
222229

223-
def test_deep_source(self):
230+
def test_deep_source(self) -> None:
224231
# When using source=, the XML report needs to mention those directories
225232
# in the <source> elements.
226233
# https://github.com/nedbat/coveragepy/issues/439
@@ -264,15 +271,15 @@ def test_deep_source(self):
264271
'name': 'bar.py',
265272
}
266273

267-
def test_nonascii_directory(self):
274+
def test_nonascii_directory(self) -> None:
268275
# https://github.com/nedbat/coveragepy/issues/573
269276
self.make_file("테스트/program.py", "a = 1")
270277
with change_dir("테스트"):
271278
cov = coverage.Coverage()
272279
self.start_import_stop(cov, "program")
273280
cov.xml_report()
274281

275-
def test_accented_dot_py(self):
282+
def test_accented_dot_py(self) -> None:
276283
# Make a file with a non-ascii character in the filename.
277284
self.make_file("h\xe2t.py", "print('accented')")
278285
self.make_data_file(lines={abs_file("h\xe2t.py"): [1]})
@@ -285,7 +292,7 @@ def test_accented_dot_py(self):
285292
assert ' filename="h\xe2t.py"'.encode() in xml
286293
assert ' name="h\xe2t.py"'.encode() in xml
287294

288-
def test_accented_directory(self):
295+
def test_accented_directory(self) -> None:
289296
# Make a file with a non-ascii character in the directory name.
290297
self.make_file("\xe2/accented.py", "print('accented')")
291298
self.make_data_file(lines={abs_file("\xe2/accented.py"): [1]})
@@ -310,7 +317,7 @@ def test_accented_directory(self):
310317
}
311318

312319

313-
def unbackslash(v):
320+
def unbackslash(v: Any) -> Any:
314321
"""Find strings in `v`, and replace backslashes with slashes throughout."""
315322
if isinstance(v, (tuple, list)):
316323
return [unbackslash(vv) for vv in v]
@@ -324,24 +331,24 @@ def unbackslash(v):
324331
class XmlPackageStructureTest(XmlTestHelpers, CoverageTest):
325332
"""Tests about the package structure reported in the coverage.xml file."""
326333

327-
def package_and_class_tags(self, cov):
334+
def package_and_class_tags(self, cov: Coverage) -> Iterator[Tuple[str, Dict[str, Any]]]:
328335
"""Run an XML report on `cov`, and get the package and class tags."""
329336
cov.xml_report()
330337
dom = ElementTree.parse("coverage.xml")
331338
for node in dom.iter():
332339
if node.tag in ('package', 'class'):
333340
yield (node.tag, {a:v for a,v in node.items() if a in ('name', 'filename')})
334341

335-
def assert_package_and_class_tags(self, cov, result):
342+
def assert_package_and_class_tags(self, cov: Coverage, result: Any) -> None:
336343
"""Check the XML package and class tags from `cov` match `result`."""
337344
assert unbackslash(list(self.package_and_class_tags(cov))) == unbackslash(result)
338345

339-
def test_package_names(self):
346+
def test_package_names(self) -> None:
340347
self.make_tree(width=1, depth=3)
341348
self.make_file("main.py", """\
342349
from d0.d0 import f0
343350
""")
344-
cov = coverage.Coverage(source=".")
351+
cov = coverage.Coverage(source=["."])
345352
self.start_import_stop(cov, "main")
346353
self.assert_package_and_class_tags(cov, [
347354
('package', {'name': "."}),
@@ -354,12 +361,12 @@ def test_package_names(self):
354361
('class', {'filename': "d0/d0/f0.py", 'name': "f0.py"}),
355362
])
356363

357-
def test_package_depth_1(self):
364+
def test_package_depth_1(self) -> None:
358365
self.make_tree(width=1, depth=4)
359366
self.make_file("main.py", """\
360367
from d0.d0 import f0
361368
""")
362-
cov = coverage.Coverage(source=".")
369+
cov = coverage.Coverage(source=["."])
363370
self.start_import_stop(cov, "main")
364371

365372
cov.set_option("xml:package_depth", 1)
@@ -375,12 +382,12 @@ def test_package_depth_1(self):
375382
('class', {'filename': "d0/f0.py", 'name': "f0.py"}),
376383
])
377384

378-
def test_package_depth_2(self):
385+
def test_package_depth_2(self) -> None:
379386
self.make_tree(width=1, depth=4)
380387
self.make_file("main.py", """\
381388
from d0.d0 import f0
382389
""")
383-
cov = coverage.Coverage(source=".")
390+
cov = coverage.Coverage(source=["."])
384391
self.start_import_stop(cov, "main")
385392

386393
cov.set_option("xml:package_depth", 2)
@@ -397,12 +404,12 @@ def test_package_depth_2(self):
397404
('class', {'filename': "d0/d0/f0.py", 'name': "f0.py"}),
398405
])
399406

400-
def test_package_depth_3(self):
407+
def test_package_depth_3(self) -> None:
401408
self.make_tree(width=1, depth=4)
402409
self.make_file("main.py", """\
403410
from d0.d0 import f0
404411
""")
405-
cov = coverage.Coverage(source=".")
412+
cov = coverage.Coverage(source=["."])
406413
self.start_import_stop(cov, "main")
407414

408415
cov.set_option("xml:package_depth", 3)
@@ -420,7 +427,7 @@ def test_package_depth_3(self):
420427
('class', {'filename': "d0/d0/d0/f0.py", 'name': "f0.py"}),
421428
])
422429

423-
def test_source_prefix(self):
430+
def test_source_prefix(self) -> None:
424431
# https://github.com/nedbat/coveragepy/issues/465
425432
# https://github.com/nedbat/coveragepy/issues/526
426433
self.make_file("src/mod.py", "print(17)")
@@ -434,7 +441,7 @@ def test_source_prefix(self):
434441
dom = ElementTree.parse("coverage.xml")
435442
self.assert_source(dom, "src")
436443

437-
def test_relative_source(self):
444+
def test_relative_source(self) -> None:
438445
self.make_file("src/mod.py", "print(17)")
439446
cov = coverage.Coverage(source=["src"])
440447
cov.set_option("run:relative_files", True)
@@ -448,7 +455,7 @@ def test_relative_source(self):
448455
assert [elt.text for elt in elts] == ["src"]
449456

450457

451-
def compare_xml(expected, actual, **kwargs):
458+
def compare_xml(expected: str, actual: str, actual_extra: bool=False) -> None:
452459
"""Specialized compare function for our XML files."""
453460
source_path = coverage.files.relative_directory().rstrip(r"\/")
454461

@@ -458,13 +465,13 @@ def compare_xml(expected, actual, **kwargs):
458465
(r'<source>\s*.*?\s*</source>', '<source>%s</source>' % re.escape(source_path)),
459466
(r'/coverage.readthedocs.io/?[-.\w/]*', '/coverage.readthedocs.io/VER'),
460467
]
461-
compare(expected, actual, scrubs=scrubs, **kwargs)
468+
compare(expected, actual, scrubs=scrubs, actual_extra=actual_extra)
462469

463470

464471
class XmlGoldTest(CoverageTest):
465472
"""Tests of XML reporting that use gold files."""
466473

467-
def test_a_xml_1(self):
474+
def test_a_xml_1(self) -> None:
468475
self.make_file("a.py", """\
469476
if 1 < 2:
470477
# Needed a < to look at HTML entities.
@@ -478,7 +485,7 @@ def test_a_xml_1(self):
478485
cov.xml_report(a, outfile="coverage.xml")
479486
compare_xml(gold_path("xml/x_xml"), ".", actual_extra=True)
480487

481-
def test_a_xml_2(self):
488+
def test_a_xml_2(self) -> None:
482489
self.make_file("a.py", """\
483490
if 1 < 2:
484491
# Needed a < to look at HTML entities.
@@ -498,7 +505,7 @@ def test_a_xml_2(self):
498505
cov.xml_report(a)
499506
compare_xml(gold_path("xml/x_xml"), "xml_2")
500507

501-
def test_y_xml_branch(self):
508+
def test_y_xml_branch(self) -> None:
502509
self.make_file("y.py", """\
503510
def choice(x):
504511
if x < 2:

tox.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ setenv =
101101
C_FN=coverage/files.py coverage/inorout.py coverage/jsonreport.py coverage/lcovreport.py coverage/multiproc.py coverage/numbits.py
102102
C_OP=coverage/parser.py coverage/phystokens.py coverage/plugin.py coverage/plugin_support.py coverage/python.py
103103
C_QZ=coverage/report.py coverage/results.py coverage/sqldata.py coverage/tomlconfig.py coverage/types.py coverage/version.py coverage/xmlreport.py
104-
T_AN=tests/test_api.py tests/test_cmdline.py tests/goldtest.py tests/helpers.py tests/test_html.py
104+
T_AN=tests/test_api.py tests/test_cmdline.py tests/goldtest.py tests/helpers.py tests/test_html.py tests/test_xml.py
105105
TYPEABLE={env:C__B} {env:C_CC} {env:C_DE} {env:C_FN} {env:C_OP} {env:C_QZ} {env:T_AN}
106106

107107
commands =

0 commit comments

Comments
 (0)