summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2023-01-04 21:09:42 -0500
committerNed Batchelder <ned@nedbatchelder.com>2023-01-04 21:09:42 -0500
commit3a02703108831a554ec893b9031dcebe377fdd89 (patch)
treee2b579730daf750c05bfb2e0ee0596e0fa47079b /tests
parent7b487470d0cccaf12d06cc363318c9b5eca6985f (diff)
downloadpython-coveragepy-git-3a02703108831a554ec893b9031dcebe377fdd89.tar.gz
mypy: test_debug.py test_execfile.py test_filereporter.py test_files.py
Diffstat (limited to 'tests')
-rw-r--r--tests/test_cmdline.py10
-rw-r--r--tests/test_debug.py50
-rw-r--r--tests/test_execfile.py56
-rw-r--r--tests/test_filereporter.py12
-rw-r--r--tests/test_files.py121
-rw-r--r--tests/test_summary.py4
6 files changed, 139 insertions, 114 deletions
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
index 96bd3bbf..f20cfe74 100644
--- a/tests/test_cmdline.py
+++ b/tests/test_cmdline.py
@@ -20,7 +20,7 @@ from coverage import env
from coverage.control import DEFAULT_DATAFILE
from coverage.config import CoverageConfig
from coverage.exceptions import _ExceptionDuringRun
-from coverage.types import TConfigValue
+from coverage.types import TConfigValueIn, TConfigValueOut
from coverage.version import __url__
from tests.coveragetest import CoverageTest, OK, ERR, command_line
@@ -96,7 +96,7 @@ class BaseCmdLineTest(CoverageTest):
def mock_command_line(
self,
args: str,
- options: Optional[Mapping[str, TConfigValue]]=None,
+ options: Optional[Mapping[str, TConfigValueIn]]=None,
) -> Tuple[mock.Mock, int]:
"""Run `args` through the command line, with a Mock.
@@ -130,7 +130,7 @@ class BaseCmdLineTest(CoverageTest):
args: str,
code: str,
ret: int=OK,
- options: Optional[Mapping[str, TConfigValue]]=None,
+ options: Optional[Mapping[str, TConfigValueIn]]=None,
) -> None:
"""Assert that the `args` end up executing the sequence in `code`."""
called, status = self.mock_command_line(args, options=options)
@@ -1139,10 +1139,10 @@ class CoverageReportingFake:
self.json_result = json_report
self.lcov_result = lcov_result
- def set_option(self, optname: str, optvalue: TConfigValue) -> None:
+ def set_option(self, optname: str, optvalue: TConfigValueIn) -> None:
self.config.set_option(optname, optvalue)
- def get_option(self, optname: str) -> TConfigValue:
+ def get_option(self, optname: str) -> TConfigValueOut:
return self.config.get_option(optname)
def load(self) -> None:
diff --git a/tests/test_debug.py b/tests/test_debug.py
index b4ce6d92..73217f1a 100644
--- a/tests/test_debug.py
+++ b/tests/test_debug.py
@@ -9,6 +9,8 @@ import os
import re
import sys
+from typing import Any, Callable, Iterable
+
import pytest
import coverage
@@ -25,7 +27,7 @@ class InfoFormatterTest(CoverageTest):
run_in_temp_dir = False
- def test_info_formatter(self):
+ def test_info_formatter(self) -> None:
lines = list(info_formatter([
('x', 'hello there'),
('very long label', ['one element']),
@@ -43,7 +45,7 @@ class InfoFormatterTest(CoverageTest):
]
assert expected == lines
- def test_info_formatter_with_generator(self):
+ def test_info_formatter_with_generator(self) -> None:
lines = list(info_formatter(('info%d' % i, i) for i in range(3)))
expected = [
' info0: 0',
@@ -52,7 +54,7 @@ class InfoFormatterTest(CoverageTest):
]
assert expected == lines
- def test_too_long_label(self):
+ def test_too_long_label(self) -> None:
with pytest.raises(AssertionError):
list(info_formatter([('this label is way too long and will not fit', 23)]))
@@ -61,7 +63,7 @@ class InfoFormatterTest(CoverageTest):
("x", "-- x ---------------------------------------------------------"),
("hello there", "-- hello there -----------------------------------------------"),
])
-def test_info_header(label, header):
+def test_info_header(label: str, header: str) -> None:
assert info_header(label) == header
@@ -71,7 +73,7 @@ def test_info_header(label, header):
(0xA5A55A5A, 0xFFFF),
(0x1234cba956780fed, 0x8008),
])
-def test_short_id(id64, id16):
+def test_short_id(id64: int, id16: int) -> None:
assert short_id(id64) == id16
@@ -79,7 +81,7 @@ def test_short_id(id64, id16):
("hello", 10, "'hello'"),
("0123456789abcdefghijklmnopqrstuvwxyz", 15, "'01234...vwxyz'"),
])
-def test_clipped_repr(text, numchars, result):
+def test_clipped_repr(text: str, numchars: int, result: str) -> None:
assert clipped_repr(text, numchars) == result
@@ -90,14 +92,18 @@ def test_clipped_repr(text, numchars, result):
("hello\nbye\n", [lambda x: "="+x], "=hello\n=bye\n"),
("hello\nbye\n", [lambda x: "="+x, lambda x: x+"\ndone\n"], "=hello\ndone\n=bye\ndone\n"),
])
-def test_filter_text(text, filters, result):
+def test_filter_text(
+ text: str,
+ filters: Iterable[Callable[[str], str]],
+ result: str,
+) -> None:
assert filter_text(text, filters) == result
class DebugTraceTest(CoverageTest):
"""Tests of debug output."""
- def f1_debug_output(self, debug):
+ def f1_debug_output(self, debug: Iterable[str]) -> str:
"""Runs some code with `debug` option, returns the debug output."""
# Make code to run.
self.make_file("f1.py", """\
@@ -116,13 +122,13 @@ class DebugTraceTest(CoverageTest):
return debug_out.getvalue()
- def test_debug_no_trace(self):
+ def test_debug_no_trace(self) -> None:
out_text = self.f1_debug_output([])
# We should have no output at all.
assert not out_text
- def test_debug_trace(self):
+ def test_debug_trace(self) -> None:
out_text = self.f1_debug_output(["trace"])
# We should have a line like "Tracing 'f1.py'", perhaps with an
@@ -132,7 +138,7 @@ class DebugTraceTest(CoverageTest):
# We should have lines like "Not tracing 'collector.py'..."
assert re_lines(r"^Not tracing .*: is part of coverage.py$", out_text)
- def test_debug_trace_pid(self):
+ def test_debug_trace_pid(self) -> None:
out_text = self.f1_debug_output(["trace", "pid"])
# Now our lines are always prefixed with the process id.
@@ -144,7 +150,7 @@ class DebugTraceTest(CoverageTest):
assert re_lines(pid_prefix + "Tracing ", out_text)
assert re_lines(pid_prefix + "Not tracing ", out_text)
- def test_debug_callers(self):
+ def test_debug_callers(self) -> None:
out_text = self.f1_debug_output(["pid", "dataop", "dataio", "callers", "lock"])
# For every real message, there should be a stack trace with a line like
# "f1_debug_output : /Users/ned/coverage/tests/test_debug.py @71"
@@ -161,7 +167,7 @@ class DebugTraceTest(CoverageTest):
assert re_lines(r"^\s*\d+\.\w{4}: Adding file tracers: 0 files", real_messages[-1])
assert re_lines(r"\s+add_file_tracers : .*coverage[/\\]sqldata.py:\d+$", last_line)
- def test_debug_config(self):
+ def test_debug_config(self) -> None:
out_text = self.f1_debug_output(["config"])
labels = """
@@ -176,7 +182,7 @@ class DebugTraceTest(CoverageTest):
msg = f"Incorrect lines for {label!r}"
assert 1 == len(re_lines(label_pat, out_text)), msg
- def test_debug_sys(self):
+ def test_debug_sys(self) -> None:
out_text = self.f1_debug_output(["sys"])
labels = """
@@ -190,7 +196,7 @@ class DebugTraceTest(CoverageTest):
msg = f"Incorrect lines for {label!r}"
assert 1 == len(re_lines(label_pat, out_text)), msg
- def test_debug_sys_ctracer(self):
+ def test_debug_sys_ctracer(self) -> None:
out_text = self.f1_debug_output(["sys"])
tracer_line = re_line(r"CTracer:", out_text).strip()
if env.C_TRACER:
@@ -199,7 +205,7 @@ class DebugTraceTest(CoverageTest):
expected = "CTracer: unavailable"
assert expected == tracer_line
- def test_debug_pybehave(self):
+ def test_debug_pybehave(self) -> None:
out_text = self.f1_debug_output(["pybehave"])
out_lines = out_text.splitlines()
assert 10 < len(out_lines) < 40
@@ -208,15 +214,15 @@ class DebugTraceTest(CoverageTest):
assert vtuple[:5] == sys.version_info
-def f_one(*args, **kwargs):
+def f_one(*args: Any, **kwargs: Any) -> str:
"""First of the chain of functions for testing `short_stack`."""
return f_two(*args, **kwargs)
-def f_two(*args, **kwargs):
+def f_two(*args: Any, **kwargs: Any) -> str:
"""Second of the chain of functions for testing `short_stack`."""
return f_three(*args, **kwargs)
-def f_three(*args, **kwargs):
+def f_three(*args: Any, **kwargs: Any) -> str:
"""Third of the chain of functions for testing `short_stack`."""
return short_stack(*args, **kwargs)
@@ -226,17 +232,17 @@ class ShortStackTest(CoverageTest):
run_in_temp_dir = False
- def test_short_stack(self):
+ def test_short_stack(self) -> None:
stack = f_one().splitlines()
assert len(stack) > 10
assert "f_three" in stack[-1]
assert "f_two" in stack[-2]
assert "f_one" in stack[-3]
- def test_short_stack_limit(self):
+ def test_short_stack_limit(self) -> None:
stack = f_one(limit=5).splitlines()
assert len(stack) == 5
- def test_short_stack_skip(self):
+ def test_short_stack_skip(self) -> None:
stack = f_one(skip=1).splitlines()
assert "f_two" in stack[-1]
diff --git a/tests/test_execfile.py b/tests/test_execfile.py
index e1db7bb5..229d8d95 100644
--- a/tests/test_execfile.py
+++ b/tests/test_execfile.py
@@ -12,6 +12,8 @@ import py_compile
import re
import sys
+from typing import Any, Generator
+
import pytest
from coverage.exceptions import NoCode, NoSource, _ExceptionDuringRun
@@ -27,12 +29,12 @@ class RunFileTest(CoverageTest):
"""Test cases for `run_python_file`."""
@pytest.fixture(autouse=True)
- def clean_up(self):
+ def clean_up(self) -> Generator[None, None, None]:
"""These tests all run in-process. Clean up global changes."""
yield
sys.excepthook = sys.__excepthook__
- def test_run_python_file(self):
+ def test_run_python_file(self) -> None:
run_python_file([TRY_EXECFILE, "arg1", "arg2"])
mod_globs = json.loads(self.stdout())
@@ -58,7 +60,7 @@ class RunFileTest(CoverageTest):
# __builtins__ should have the right values, like open().
assert mod_globs['__builtins__.has_open'] is True
- def test_no_extra_file(self):
+ def test_no_extra_file(self) -> None:
# Make sure that running a file doesn't create an extra compiled file.
self.make_file("xxx", """\
desc = "a non-.py file!"
@@ -68,7 +70,7 @@ class RunFileTest(CoverageTest):
run_python_file(["xxx"])
assert os.listdir(".") == ["xxx"]
- def test_universal_newlines(self):
+ def test_universal_newlines(self) -> None:
# Make sure we can read any sort of line ending.
pylines = """# try newlines|print('Hello, world!')|""".split('|')
for nl in ('\n', '\r\n', '\r'):
@@ -77,7 +79,7 @@ class RunFileTest(CoverageTest):
run_python_file(['nl.py'])
assert self.stdout() == "Hello, world!\n"*3
- def test_missing_final_newline(self):
+ def test_missing_final_newline(self) -> None:
# Make sure we can deal with a Python file with no final newline.
self.make_file("abrupt.py", """\
if 1:
@@ -90,25 +92,25 @@ class RunFileTest(CoverageTest):
run_python_file(["abrupt.py"])
assert self.stdout() == "a is 1\n"
- def test_no_such_file(self):
+ def test_no_such_file(self) -> None:
path = python_reported_file('xyzzy.py')
msg = re.escape(f"No file to run: '{path}'")
with pytest.raises(NoSource, match=msg):
run_python_file(["xyzzy.py"])
- def test_directory_with_main(self):
+ def test_directory_with_main(self) -> None:
self.make_file("with_main/__main__.py", """\
print("I am __main__")
""")
run_python_file(["with_main"])
assert self.stdout() == "I am __main__\n"
- def test_directory_without_main(self):
+ def test_directory_without_main(self) -> None:
self.make_file("without_main/__init__.py", "")
with pytest.raises(NoSource, match="Can't find '__main__' module in 'without_main'"):
run_python_file(["without_main"])
- def test_code_throws(self):
+ def test_code_throws(self) -> None:
self.make_file("throw.py", """\
class MyException(Exception):
pass
@@ -129,7 +131,7 @@ class RunFileTest(CoverageTest):
assert self.stdout() == "about to raise..\n"
assert self.stderr() == ""
- def test_code_exits(self):
+ def test_code_exits(self) -> None:
self.make_file("exit.py", """\
import sys
def f1():
@@ -148,7 +150,7 @@ class RunFileTest(CoverageTest):
assert self.stdout() == "about to exit..\n"
assert self.stderr() == ""
- def test_excepthook_exit(self):
+ def test_excepthook_exit(self) -> None:
self.make_file("excepthook_exit.py", """\
import sys
@@ -165,7 +167,7 @@ class RunFileTest(CoverageTest):
cov_out = self.stdout()
assert cov_out == "in excepthook\n"
- def test_excepthook_throw(self):
+ def test_excepthook_throw(self) -> None:
self.make_file("excepthook_throw.py", """\
import sys
@@ -193,7 +195,7 @@ class RunFileTest(CoverageTest):
class RunPycFileTest(CoverageTest):
"""Test cases for `run_python_file`."""
- def make_pyc(self, **kwargs):
+ def make_pyc(self, **kwargs: Any) -> str:
"""Create a .pyc file, and return the path to it."""
self.make_file("compiled.py", """\
def doit():
@@ -207,12 +209,12 @@ class RunPycFileTest(CoverageTest):
# Find the .pyc file!
return str(next(pathlib.Path(".").rglob("compiled*.pyc")))
- def test_running_pyc(self):
+ def test_running_pyc(self) -> None:
pycfile = self.make_pyc()
run_python_file([pycfile])
assert self.stdout() == "I am here!\n"
- def test_running_pyo(self):
+ def test_running_pyo(self) -> None:
pycfile = self.make_pyc()
pyofile = re.sub(r"[.]pyc$", ".pyo", pycfile)
assert pycfile != pyofile
@@ -220,7 +222,7 @@ class RunPycFileTest(CoverageTest):
run_python_file([pyofile])
assert self.stdout() == "I am here!\n"
- def test_running_pyc_from_wrong_python(self):
+ def test_running_pyc_from_wrong_python(self) -> None:
pycfile = self.make_pyc()
# Jam Python 2.1 magic number into the .pyc file.
@@ -234,18 +236,18 @@ class RunPycFileTest(CoverageTest):
# In some environments, the pycfile persists and pollutes another test.
os.remove(pycfile)
- def test_running_hashed_pyc(self):
+ def test_running_hashed_pyc(self) -> None:
pycfile = self.make_pyc(invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH)
run_python_file([pycfile])
assert self.stdout() == "I am here!\n"
- def test_no_such_pyc_file(self):
+ def test_no_such_pyc_file(self) -> None:
path = python_reported_file('xyzzy.pyc')
msg = re.escape(f"No file to run: '{path}'")
with pytest.raises(NoCode, match=msg):
run_python_file(["xyzzy.pyc"])
- def test_running_py_from_binary(self):
+ def test_running_py_from_binary(self) -> None:
# Use make_file to get the bookkeeping. Ideally, it would
# be able to write binary files.
bf = self.make_file("binary")
@@ -266,43 +268,43 @@ class RunModuleTest(UsingModulesMixin, CoverageTest):
run_in_temp_dir = False
- def test_runmod1(self):
+ def test_runmod1(self) -> None:
run_python_module(["runmod1", "hello"])
out, err = self.stdouterr()
assert out == "runmod1: passed hello\n"
assert err == ""
- def test_runmod2(self):
+ def test_runmod2(self) -> None:
run_python_module(["pkg1.runmod2", "hello"])
out, err = self.stdouterr()
assert out == "pkg1.__init__: pkg1\nrunmod2: passed hello\n"
assert err == ""
- def test_runmod3(self):
+ def test_runmod3(self) -> None:
run_python_module(["pkg1.sub.runmod3", "hello"])
out, err = self.stdouterr()
assert out == "pkg1.__init__: pkg1\nrunmod3: passed hello\n"
assert err == ""
- def test_pkg1_main(self):
+ def test_pkg1_main(self) -> None:
run_python_module(["pkg1", "hello"])
out, err = self.stdouterr()
assert out == "pkg1.__init__: pkg1\npkg1.__main__: passed hello\n"
assert err == ""
- def test_pkg1_sub_main(self):
+ def test_pkg1_sub_main(self) -> None:
run_python_module(["pkg1.sub", "hello"])
out, err = self.stdouterr()
assert out == "pkg1.__init__: pkg1\npkg1.sub.__main__: passed hello\n"
assert err == ""
- def test_pkg1_init(self):
+ def test_pkg1_init(self) -> None:
run_python_module(["pkg1.__init__", "wut?"])
out, err = self.stdouterr()
assert out == "pkg1.__init__: pkg1\npkg1.__init__: __main__\n"
assert err == ""
- def test_no_such_module(self):
+ def test_no_such_module(self) -> None:
with pytest.raises(NoSource, match="No module named '?i_dont_exist'?"):
run_python_module(["i_dont_exist"])
with pytest.raises(NoSource, match="No module named '?i'?"):
@@ -310,6 +312,6 @@ class RunModuleTest(UsingModulesMixin, CoverageTest):
with pytest.raises(NoSource, match="No module named '?i'?"):
run_python_module(["i.dont.exist"])
- def test_no_main(self):
+ def test_no_main(self) -> None:
with pytest.raises(NoSource):
run_python_module(["pkg2", "hi"])
diff --git a/tests/test_filereporter.py b/tests/test_filereporter.py
index 227cc458..59335309 100644
--- a/tests/test_filereporter.py
+++ b/tests/test_filereporter.py
@@ -20,7 +20,7 @@ class FileReporterTest(UsingModulesMixin, CoverageTest):
run_in_temp_dir = False
- def test_filenames(self):
+ def test_filenames(self) -> None:
acu = PythonFileReporter("aa/afile.py")
bcu = PythonFileReporter("aa/bb/bfile.py")
ccu = PythonFileReporter("aa/bb/cc/cfile.py")
@@ -31,7 +31,7 @@ class FileReporterTest(UsingModulesMixin, CoverageTest):
assert bcu.source() == "# bfile.py\n"
assert ccu.source() == "# cfile.py\n"
- def test_odd_filenames(self):
+ def test_odd_filenames(self) -> None:
acu = PythonFileReporter("aa/afile.odd.py")
bcu = PythonFileReporter("aa/bb/bfile.odd.py")
b2cu = PythonFileReporter("aa/bb.odd/bfile.py")
@@ -42,7 +42,7 @@ class FileReporterTest(UsingModulesMixin, CoverageTest):
assert bcu.source() == "# bfile.odd.py\n"
assert b2cu.source() == "# bfile.py\n"
- def test_modules(self):
+ def test_modules(self) -> None:
import aa
import aa.bb
import aa.bb.cc
@@ -57,7 +57,7 @@ class FileReporterTest(UsingModulesMixin, CoverageTest):
assert bcu.source() == "# bb\n"
assert ccu.source() == "" # yes, empty
- def test_module_files(self):
+ def test_module_files(self) -> None:
import aa.afile
import aa.bb.bfile
import aa.bb.cc.cfile
@@ -72,7 +72,7 @@ class FileReporterTest(UsingModulesMixin, CoverageTest):
assert bcu.source() == "# bfile.py\n"
assert ccu.source() == "# cfile.py\n"
- def test_comparison(self):
+ def test_comparison(self) -> None:
acu = FileReporter("aa/afile.py")
acu2 = FileReporter("aa/afile.py")
zcu = FileReporter("aa/zfile.py")
@@ -83,7 +83,7 @@ class FileReporterTest(UsingModulesMixin, CoverageTest):
assert acu < bcu and acu <= bcu and acu != bcu
assert bcu > acu and bcu >= acu and bcu != acu
- def test_zipfile(self):
+ def test_zipfile(self) -> None:
sys.path.append("tests/zip1.zip")
# Test that we can get files out of zipfiles, and read their source files.
diff --git a/tests/test_files.py b/tests/test_files.py
index 2d029a04..ff02e0e9 100644
--- a/tests/test_files.py
+++ b/tests/test_files.py
@@ -7,6 +7,8 @@ import itertools
import os
import os.path
import re
+
+from typing import Any, Generator, Iterable, List
from unittest import mock
import pytest
@@ -17,6 +19,7 @@ from coverage.files import (
GlobMatcher, ModuleMatcher, PathAliases, TreeMatcher, abs_file,
actual_path, find_python_files, flat_rootname, globs_to_regex,
)
+from coverage.types import Protocol
from tests.coveragetest import CoverageTest
from tests.helpers import os_sep
@@ -25,11 +28,11 @@ from tests.helpers import os_sep
class FilesTest(CoverageTest):
"""Tests of coverage.files."""
- def abs_path(self, p):
+ def abs_path(self, p: str) -> str:
"""Return the absolute path for `p`."""
return os.path.join(abs_file(os.getcwd()), os.path.normpath(p))
- def test_simple(self):
+ def test_simple(self) -> None:
self.make_file("hello.py")
files.set_relative_directory()
assert files.relative_filename("hello.py") == "hello.py"
@@ -37,7 +40,7 @@ class FilesTest(CoverageTest):
assert a != "hello.py"
assert files.relative_filename(a) == "hello.py"
- def test_peer_directories(self):
+ def test_peer_directories(self) -> None:
self.make_file("sub/proj1/file1.py")
self.make_file("sub/proj2/file2.py")
a1 = self.abs_path("sub/proj1/file1.py")
@@ -48,7 +51,7 @@ class FilesTest(CoverageTest):
assert files.relative_filename(a1) == "file1.py"
assert files.relative_filename(a2) == a2
- def test_filepath_contains_absolute_prefix_twice(self):
+ def test_filepath_contains_absolute_prefix_twice(self) -> None:
# https://github.com/nedbat/coveragepy/issues/194
# Build a path that has two pieces matching the absolute path prefix.
# Technically, this test doesn't do that on Windows, but drive
@@ -59,7 +62,7 @@ class FilesTest(CoverageTest):
rel = os.path.join('sub', trick, 'file1.py')
assert files.relative_filename(abs_file(rel)) == rel
- def test_canonical_filename_ensure_cache_hit(self):
+ def test_canonical_filename_ensure_cache_hit(self) -> None:
self.make_file("sub/proj1/file1.py")
d = actual_path(self.abs_path("sub/proj1"))
os.chdir(d)
@@ -76,7 +79,7 @@ class FilesTest(CoverageTest):
("X:\\", "\\"),
]
)
- def test_relative_dir_for_root(self, curdir, sep):
+ def test_relative_dir_for_root(self, curdir: str, sep: str) -> None:
with mock.patch.object(files.os, 'curdir', new=curdir):
with mock.patch.object(files.os, 'sep', new=sep):
with mock.patch('coverage.files.os.path.normcase', return_value=curdir):
@@ -95,7 +98,7 @@ class FilesTest(CoverageTest):
("src/files.pex", "src/files.pex/zipfiles/files.zip/foo.py", True),
]
)
- def test_source_exists(self, to_make, to_check, answer):
+ def test_source_exists(self, to_make: str, to_check: str, answer: bool) -> None:
# source_exists won't look inside the zipfile, so it's fine to make
# an empty file with the zipfile name.
self.make_file(to_make, "")
@@ -122,13 +125,17 @@ class FilesTest(CoverageTest):
"d_e597dfacb73a23d5_my_program_py"
),
])
-def test_flat_rootname(original, flat):
+def test_flat_rootname(original: str, flat: str) -> None:
assert flat_rootname(original) == flat
def globs_to_regex_params(
- patterns, case_insensitive=False, partial=False, matches=(), nomatches=(),
-):
+ patterns: Iterable[str],
+ case_insensitive: bool=False,
+ partial: bool=False,
+ matches: Iterable[str]=(),
+ nomatches: Iterable[str]=(),
+) -> Generator[Any, None, None]:
"""Generate parameters for `test_globs_to_regex`.
`patterns`, `case_insensitive`, and `partial` are arguments for
@@ -242,11 +249,14 @@ def globs_to_regex_params(
),
]))
)
-def test_globs_to_regex(patterns, case_insensitive, partial, text, result):
+def test_globs_to_regex(
+ patterns: Iterable[str],
+ case_insensitive: bool,
+ partial: bool,
+ text: str,
+ result: bool,
+) -> None:
regex = globs_to_regex(patterns, case_insensitive=case_insensitive, partial=partial)
- print(patterns)
- print(regex)
- print(text)
assert bool(regex.match(text)) == result
@@ -261,26 +271,33 @@ def test_globs_to_regex(patterns, case_insensitive, partial, text, result):
("x/**a/b.py", "**a"),
("x/**/**/b.py", "**/**"),
])
-def test_invalid_globs(pattern, bad_word):
+def test_invalid_globs(pattern: str, bad_word: str) -> None:
msg = f"File pattern can't include {bad_word!r}"
with pytest.raises(ConfigError, match=re.escape(msg)):
globs_to_regex([pattern])
+class TMatcher(Protocol):
+ """The shape all Matchers have."""
+
+ def match(self, s: str) -> bool:
+ """Does this string match?"""
+
+
class MatcherTest(CoverageTest):
"""Tests of file matchers."""
- def setUp(self):
+ def setUp(self) -> None:
super().setUp()
files.set_relative_directory()
- def assertMatches(self, matcher, filepath, matches):
+ def assertMatches(self, matcher: TMatcher, filepath: str, matches: bool) -> None:
"""The `matcher` should agree with `matches` about `filepath`."""
canonical = files.canonical_filename(filepath)
msg = f"File {filepath} should have matched as {matches}"
assert matches == matcher.match(canonical), msg
- def test_tree_matcher(self):
+ def test_tree_matcher(self) -> None:
case_folding = env.WINDOWS
matches_to_try = [
(self.make_file("sub/file1.py"), True),
@@ -302,7 +319,7 @@ class MatcherTest(CoverageTest):
for filepath, matches in matches_to_try:
self.assertMatches(tm, filepath, matches)
- def test_module_matcher(self):
+ def test_module_matcher(self) -> None:
matches_to_try = [
('test', True),
('trash', False),
@@ -325,7 +342,7 @@ class MatcherTest(CoverageTest):
for modulename, matches in matches_to_try:
assert mm.match(modulename) == matches, modulename
- def test_glob_matcher(self):
+ def test_glob_matcher(self) -> None:
matches_to_try = [
(self.make_file("sub/file1.py"), True),
(self.make_file("sub/file2.c"), False),
@@ -338,7 +355,7 @@ class MatcherTest(CoverageTest):
for filepath, matches in matches_to_try:
self.assertMatches(fnm, filepath, matches)
- def test_glob_matcher_overload(self):
+ def test_glob_matcher_overload(self) -> None:
fnm = GlobMatcher(["*x%03d*.txt" % i for i in range(500)])
self.assertMatches(fnm, "x007foo.txt", True)
self.assertMatches(fnm, "x123foo.txt", True)
@@ -346,7 +363,7 @@ class MatcherTest(CoverageTest):
self.assertMatches(fnm, "x499.txt", True)
self.assertMatches(fnm, "x500.txt", False)
- def test_glob_windows_paths(self):
+ def test_glob_windows_paths(self) -> None:
# We should be able to match Windows paths even if we are running on
# a non-Windows OS.
fnm = GlobMatcher(["*/foo.py"])
@@ -356,9 +373,9 @@ class MatcherTest(CoverageTest):
@pytest.fixture(params=[False, True], name="rel_yn")
-def relative_setting(request):
+def relative_setting(request: pytest.FixtureRequest) -> bool:
"""Parameterized fixture to choose whether PathAliases is relative or not."""
- return request.param
+ return request.param # type: ignore[no-any-return]
class PathAliasesTest(CoverageTest):
@@ -366,7 +383,7 @@ class PathAliasesTest(CoverageTest):
run_in_temp_dir = False
- def assert_mapped(self, aliases, inp, out):
+ def assert_mapped(self, aliases: PathAliases, inp: str, out: str) -> None:
"""Assert that `inp` mapped through `aliases` produces `out`.
If the aliases are not relative, then `out` is canonicalized first,
@@ -380,20 +397,20 @@ class PathAliasesTest(CoverageTest):
expected = files.canonical_filename(out)
assert mapped == expected
- def assert_unchanged(self, aliases, inp, exists=True):
+ def assert_unchanged(self, aliases: PathAliases, inp: str, exists: bool=True) -> None:
"""Assert that `inp` mapped through `aliases` is unchanged."""
assert aliases.map(inp, exists=lambda p: exists) == inp
- def test_noop(self, rel_yn):
+ def test_noop(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
self.assert_unchanged(aliases, '/ned/home/a.py')
- def test_nomatch(self, rel_yn):
+ def test_nomatch(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
aliases.add('/home/*/src', './mysrc')
self.assert_unchanged(aliases, '/home/foo/a.py')
- def test_wildcard(self, rel_yn):
+ def test_wildcard(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
aliases.add('/ned/home/*/src', './mysrc')
self.assert_mapped(aliases, '/ned/home/foo/src/a.py', './mysrc/a.py')
@@ -402,24 +419,24 @@ class PathAliasesTest(CoverageTest):
aliases.add('/ned/home/*/src/', './mysrc')
self.assert_mapped(aliases, '/ned/home/foo/src/a.py', './mysrc/a.py')
- def test_no_accidental_match(self, rel_yn):
+ def test_no_accidental_match(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
aliases.add('/home/*/src', './mysrc')
self.assert_unchanged(aliases, '/home/foo/srcetc')
- def test_no_map_if_not_exist(self, rel_yn):
+ def test_no_map_if_not_exist(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
aliases.add('/ned/home/*/src', './mysrc')
self.assert_unchanged(aliases, '/ned/home/foo/src/a.py', exists=False)
self.assert_unchanged(aliases, 'foo/src/a.py', exists=False)
- def test_no_dotslash(self, rel_yn):
+ def test_no_dotslash(self, rel_yn: bool) -> None:
# The result shouldn't start with "./" if the map result didn't.
aliases = PathAliases(relative=rel_yn)
aliases.add('*/project', '.')
self.assert_mapped(aliases, '/ned/home/project/src/a.py', os_sep('src/a.py'))
- def test_relative_pattern(self):
+ def test_relative_pattern(self) -> None:
aliases = PathAliases(relative=True)
aliases.add(".tox/*/site-packages", "src")
self.assert_mapped(
@@ -428,9 +445,9 @@ class PathAliasesTest(CoverageTest):
os_sep("src/proj/a.py"),
)
- def test_multiple_patterns(self, rel_yn):
+ def test_multiple_patterns(self, rel_yn: bool) -> None:
# also test the debugfn...
- msgs = []
+ msgs: List[str] = []
aliases = PathAliases(debugfn=msgs.append, relative=rel_yn)
aliases.add('/home/*/src', './mysrc')
aliases.add('/lib/*/libsrc', './mylib')
@@ -466,20 +483,20 @@ class PathAliasesTest(CoverageTest):
"/ned/home/*/",
"/ned/home/*/*/",
])
- def test_cant_have_wildcard_at_end(self, badpat):
+ def test_cant_have_wildcard_at_end(self, badpat: str) -> None:
aliases = PathAliases()
msg = "Pattern must not end with wildcards."
with pytest.raises(ConfigError, match=msg):
aliases.add(badpat, "fooey")
- def test_no_accidental_munging(self):
+ def test_no_accidental_munging(self) -> None:
aliases = PathAliases()
aliases.add(r'c:\Zoo\boo', 'src/')
aliases.add('/home/ned$', 'src/')
self.assert_mapped(aliases, r'c:\Zoo\boo\foo.py', 'src/foo.py')
self.assert_mapped(aliases, r'/home/ned$/foo.py', 'src/foo.py')
- def test_paths_are_os_corrected(self, rel_yn):
+ def test_paths_are_os_corrected(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
aliases.add('/home/ned/*/src', './mysrc')
aliases.add(r'c:\ned\src', './mysrc')
@@ -500,7 +517,7 @@ class PathAliasesTest(CoverageTest):
lin_win_paths = [[lin, win], [win, lin]]
@pytest.mark.parametrize("paths", lin_win_paths)
- def test_windows_on_linux(self, paths, rel_yn):
+ def test_windows_on_linux(self, paths: Iterable[str], rel_yn: bool) -> None:
# https://github.com/nedbat/coveragepy/issues/618
aliases = PathAliases(relative=rel_yn)
for path in paths:
@@ -512,7 +529,7 @@ class PathAliasesTest(CoverageTest):
)
@pytest.mark.parametrize("paths", lin_win_paths)
- def test_linux_on_windows(self, paths, rel_yn):
+ def test_linux_on_windows(self, paths: Iterable[str], rel_yn: bool) -> None:
# https://github.com/nedbat/coveragepy/issues/618
aliases = PathAliases(relative=rel_yn)
for path in paths:
@@ -524,7 +541,7 @@ class PathAliasesTest(CoverageTest):
)
@pytest.mark.parametrize("paths", lin_win_paths)
- def test_relative_windows_on_linux(self, paths):
+ def test_relative_windows_on_linux(self, paths: Iterable[str]) -> None:
# https://github.com/nedbat/coveragepy/issues/991
aliases = PathAliases(relative=True)
for path in paths:
@@ -536,7 +553,7 @@ class PathAliasesTest(CoverageTest):
)
@pytest.mark.parametrize("paths", lin_win_paths)
- def test_relative_linux_on_windows(self, paths):
+ def test_relative_linux_on_windows(self, paths: Iterable[str]) -> None:
# https://github.com/nedbat/coveragepy/issues/991
aliases = PathAliases(relative=True)
for path in paths:
@@ -548,7 +565,7 @@ class PathAliasesTest(CoverageTest):
)
@pytest.mark.skipif(env.WINDOWS, reason="This test assumes Unix file system")
- def test_implicit_relative_windows_on_linux(self):
+ def test_implicit_relative_windows_on_linux(self) -> None:
# https://github.com/nedbat/coveragepy/issues/991
aliases = PathAliases(relative=True)
self.assert_mapped(
@@ -558,7 +575,7 @@ class PathAliasesTest(CoverageTest):
)
@pytest.mark.skipif(not env.WINDOWS, reason="This test assumes Windows file system")
- def test_implicit_relative_linux_on_windows(self):
+ def test_implicit_relative_linux_on_windows(self) -> None:
# https://github.com/nedbat/coveragepy/issues/991
aliases = PathAliases(relative=True)
self.assert_mapped(
@@ -567,7 +584,7 @@ class PathAliasesTest(CoverageTest):
r"project\module\tests\file.py",
)
- def test_multiple_wildcard(self, rel_yn):
+ def test_multiple_wildcard(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
aliases.add('/home/jenkins/*/a/*/b/*/django', './django')
self.assert_mapped(
@@ -576,7 +593,7 @@ class PathAliasesTest(CoverageTest):
'./django/foo/bar.py',
)
- def test_windows_root_paths(self, rel_yn):
+ def test_windows_root_paths(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
aliases.add('X:\\', '/tmp/src')
self.assert_mapped(
@@ -590,7 +607,7 @@ class PathAliasesTest(CoverageTest):
"/tmp/src/file.py",
)
- def test_leading_wildcard(self, rel_yn):
+ def test_leading_wildcard(self, rel_yn: bool) -> None:
aliases = PathAliases(relative=rel_yn)
aliases.add('*/d1', './mysrc1')
aliases.add('*/d2', './mysrc2')
@@ -598,7 +615,7 @@ class PathAliasesTest(CoverageTest):
self.assert_mapped(aliases, '/foo/bar/d2/y.py', './mysrc2/y.py')
@pytest.mark.parametrize("dirname", [".", "..", "../other", "/"])
- def test_dot(self, dirname):
+ def test_dot(self, dirname: str) -> None:
if env.WINDOWS and dirname == "/":
# The root test case was added for the manylinux Docker images,
# and I'm not sure how it should work on Windows, so skip it.
@@ -616,7 +633,7 @@ class PathAliasesTest(CoverageTest):
class PathAliasesRealFilesTest(CoverageTest):
"""Tests for coverage/files.py:PathAliases using real files."""
- def test_aliasing_zip_files(self):
+ def test_aliasing_zip_files(self) -> None:
self.make_file("src/zipfiles/code.zip", "fake zip, doesn't matter")
aliases = PathAliases()
aliases.add("*/d1", "./src")
@@ -629,7 +646,7 @@ class PathAliasesRealFilesTest(CoverageTest):
class FindPythonFilesTest(CoverageTest):
"""Tests of `find_python_files`."""
- def test_find_python_files(self):
+ def test_find_python_files(self) -> None:
self.make_file("sub/a.py")
self.make_file("sub/b.py")
self.make_file("sub/x.c") # nope: not .py
@@ -645,7 +662,7 @@ class FindPythonFilesTest(CoverageTest):
"sub/windows.pyw",
])
- def test_find_python_files_include_namespace_packages(self):
+ def test_find_python_files_include_namespace_packages(self) -> None:
self.make_file("sub/a.py")
self.make_file("sub/b.py")
self.make_file("sub/x.c") # nope: not .py
@@ -669,5 +686,5 @@ class WindowsFileTest(CoverageTest):
run_in_temp_dir = False
- def test_actual_path(self):
+ def test_actual_path(self) -> None:
assert actual_path(r'c:\Windows') == actual_path(r'C:\wINDOWS')
diff --git a/tests/test_summary.py b/tests/test_summary.py
index f3c7ed3f..15c75348 100644
--- a/tests/test_summary.py
+++ b/tests/test_summary.py
@@ -22,7 +22,7 @@ from coverage.data import CoverageData
from coverage.exceptions import ConfigError, NoDataError, NotPython
from coverage.files import abs_file
from coverage.summary import SummaryReporter
-from coverage.types import TConfigValue
+from coverage.types import TConfigValueIn
from tests.coveragetest import CoverageTest, TESTS_DIR, UsingModulesMixin
from tests.helpers import assert_coverage_warnings
@@ -900,7 +900,7 @@ class SummaryReporterConfigurationTest(CoverageTest):
source += " a = 2\n" * dont_run
self.make_file(filename, source)
- def get_summary_text(self, *options: Tuple[str, TConfigValue]) -> str:
+ def get_summary_text(self, *options: Tuple[str, TConfigValueIn]) -> str:
"""Get text output from the SummaryReporter.
The arguments are tuples: (name, value) for Coverage.set_option.