diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/coveragetest.py | 6 | ||||
-rw-r--r-- | tests/helpers.py | 10 | ||||
-rw-r--r-- | tests/test_coverage.py | 170 | ||||
-rw-r--r-- | tests/test_data.py | 181 |
4 files changed, 193 insertions, 174 deletions
diff --git a/tests/coveragetest.py b/tests/coveragetest.py index c55fffd5..5025602b 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -18,7 +18,7 @@ import sys from types import ModuleType from typing import ( Any, Collection, Dict, Generator, Iterable, List, Mapping, Optional, - Tuple, Union, + Sequence, Tuple, Union, ) import coverage @@ -135,8 +135,8 @@ class CoverageTest( def check_coverage( self, text: str, - lines: Optional[Union[List[TLineNo], List[List[TLineNo]]]]=None, - missing: Union[str, List[str]]="", + lines: Optional[Union[Sequence[TLineNo], Sequence[List[TLineNo]]]]=None, + missing: Union[str, Sequence[str]]="", report: str="", excludes: Optional[Iterable[str]]=None, partials: Iterable[str]=(), diff --git a/tests/helpers.py b/tests/helpers.py index bffd800c..6f427fc3 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -17,7 +17,7 @@ import warnings from typing import ( cast, - Any, Callable, Generator, Iterable, List, Optional, Set, Tuple, Type, Union, + Any, Callable, Generator, Iterable, List, Optional, Set, Tuple, Type, TypeVar, Union, ) import pytest @@ -281,14 +281,20 @@ def change_dir(new_dir: str) -> Generator[None, None, None]: finally: os.chdir(old_dir) +T = TypeVar("T") -def assert_count_equal(a: Iterable[Union[int, str]], b: Iterable[Union[int, str]]) -> None: +def assert_count_equal( + a: Optional[Iterable[T]], + b: Optional[Iterable[T]], +) -> None: """ A pytest-friendly implementation of assertCountEqual. Assert that `a` and `b` have the same elements, but maybe in different order. This only works for hashable elements. """ + assert a is not None + assert b is not None assert collections.Counter(list(a)) == collections.Counter(list(b)) diff --git a/tests/test_coverage.py b/tests/test_coverage.py index 17da4f5e..ee82123d 100644 --- a/tests/test_coverage.py +++ b/tests/test_coverage.py @@ -15,7 +15,7 @@ from tests.coveragetest import CoverageTest class TestCoverageTest(CoverageTest): """Make sure our complex self.check_coverage method works.""" - def test_successful_coverage(self): + def test_successful_coverage(self) -> None: # The simplest run possible. self.check_coverage("""\ a = 1 @@ -49,7 +49,7 @@ class TestCoverageTest(CoverageTest): missing=("47-49", "3", "100,102") ) - def test_failed_coverage(self): + def test_failed_coverage(self) -> None: # If the lines are wrong, the message shows right and wrong. with pytest.raises(AssertionError, match=r"\[1, 2] != \[1]"): self.check_coverage("""\ @@ -89,7 +89,7 @@ class TestCoverageTest(CoverageTest): missing=("37", "4-10"), ) - def test_exceptions_really_fail(self): + def test_exceptions_really_fail(self) -> None: # An assert in the checked code will really raise up to us. with pytest.raises(AssertionError, match="This is bad"): self.check_coverage("""\ @@ -110,7 +110,7 @@ class TestCoverageTest(CoverageTest): class BasicCoverageTest(CoverageTest): """The simplest tests, for quick smoke testing of fundamental changes.""" - def test_simple(self): + def test_simple(self) -> None: self.check_coverage("""\ a = 1 b = 2 @@ -121,7 +121,7 @@ class BasicCoverageTest(CoverageTest): """, [1,2,4,6], report="4 0 0 0 100%") - def test_indentation_wackiness(self): + def test_indentation_wackiness(self) -> None: # Partial final lines are OK. self.check_coverage("""\ import sys @@ -130,7 +130,7 @@ class BasicCoverageTest(CoverageTest): """, # indented last line [1,2,3], "3") - def test_multiline_initializer(self): + def test_multiline_initializer(self) -> None: self.check_coverage("""\ d = { 'foo': 1+2, @@ -142,7 +142,7 @@ class BasicCoverageTest(CoverageTest): """, [1,7], "") - def test_list_comprehension(self): + def test_list_comprehension(self) -> None: self.check_coverage("""\ l = [ 2*i for i in range(10) @@ -156,7 +156,7 @@ class BasicCoverageTest(CoverageTest): class SimpleStatementTest(CoverageTest): """Testing simple single-line statements.""" - def test_expression(self): + def test_expression(self) -> None: # Bare expressions as statements are tricky: some implementations # optimize some of them away. All implementations seem to count # the implicit return at the end as executable. @@ -185,7 +185,7 @@ class SimpleStatementTest(CoverageTest): """, ([1,2,4], [4]), "") - def test_assert(self): + def test_assert(self) -> None: self.check_coverage("""\ assert (1 + 2) assert (1 + @@ -197,7 +197,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,4,5], "") - def test_assignment(self): + def test_assignment(self) -> None: # Simple variable assignment self.check_coverage("""\ a = (1 + 2) @@ -208,7 +208,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,4], "") - def test_assign_tuple(self): + def test_assign_tuple(self) -> None: self.check_coverage("""\ a = 1 a,b,c = 7,8,9 @@ -216,7 +216,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3], "") - def test_more_assignments(self): + def test_more_assignments(self) -> None: self.check_coverage("""\ x = [] d = {} @@ -231,7 +231,7 @@ class SimpleStatementTest(CoverageTest): """, [1, 2, 3], "") - def test_attribute_assignment(self): + def test_attribute_assignment(self) -> None: # Attribute assignment self.check_coverage("""\ class obj: pass @@ -244,7 +244,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3,4,6], "") - def test_list_of_attribute_assignment(self): + def test_list_of_attribute_assignment(self) -> None: self.check_coverage("""\ class obj: pass o = obj() @@ -258,7 +258,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3,4,7], "") - def test_augmented_assignment(self): + def test_augmented_assignment(self) -> None: self.check_coverage("""\ a = 1 a += 1 @@ -269,7 +269,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3,5], "") - def test_triple_string_stuff(self): + def test_triple_string_stuff(self) -> None: self.check_coverage("""\ a = ''' a multiline @@ -291,7 +291,7 @@ class SimpleStatementTest(CoverageTest): """, [1,5,11], "") - def test_pass(self): + def test_pass(self) -> None: # pass is tricky: if it's the only statement in a block, then it is # "executed". But if it is not the only statement, then it is not. self.check_coverage("""\ @@ -328,7 +328,7 @@ class SimpleStatementTest(CoverageTest): """, ([1,2,4,5], [1,2,5]), "") - def test_del(self): + def test_del(self) -> None: self.check_coverage("""\ d = { 'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1 } del d['a'] @@ -342,7 +342,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3,6,9], "") - def test_raise(self): + def test_raise(self) -> None: self.check_coverage("""\ try: raise Exception( @@ -353,7 +353,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,5,6], "") - def test_raise_followed_by_statement(self): + def test_raise_followed_by_statement(self) -> None: if env.PYBEHAVIOR.omit_after_jump: lines = [1,2,4,5] missing = "" @@ -369,7 +369,7 @@ class SimpleStatementTest(CoverageTest): """, lines=lines, missing=missing) - def test_return(self): + def test_return(self) -> None: self.check_coverage("""\ def fn(): a = 1 @@ -402,7 +402,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3,7,8], "") - def test_return_followed_by_statement(self): + def test_return_followed_by_statement(self) -> None: if env.PYBEHAVIOR.omit_after_return: lines = [1,2,3,6,7] missing = "" @@ -421,7 +421,7 @@ class SimpleStatementTest(CoverageTest): lines=lines, missing=missing, ) - def test_yield(self): + def test_yield(self) -> None: self.check_coverage("""\ def gen(): yield 1 @@ -435,7 +435,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3,6,8,9], "") - def test_break(self): + def test_break(self) -> None: if env.PYBEHAVIOR.omit_after_jump: lines = [1,2,3,5] missing = "" @@ -452,7 +452,7 @@ class SimpleStatementTest(CoverageTest): """, lines=lines, missing=missing) - def test_continue(self): + def test_continue(self) -> None: if env.PYBEHAVIOR.omit_after_jump: lines = [1,2,3,5] missing = "" @@ -469,7 +469,7 @@ class SimpleStatementTest(CoverageTest): """, lines=lines, missing=missing) - def test_strange_unexecuted_continue(self): + def test_strange_unexecuted_continue(self) -> None: # Peephole optimization of jumps to jumps can mean that some statements # never hit the line tracer. The behavior is different in different # versions of Python, so be careful when running this test. @@ -500,7 +500,7 @@ class SimpleStatementTest(CoverageTest): missing=["", "6"], ) - def test_import(self): + def test_import(self) -> None: self.check_coverage("""\ import string from sys import path @@ -547,7 +547,7 @@ class SimpleStatementTest(CoverageTest): """, [1,3], "") - def test_global(self): + def test_global(self) -> None: self.check_coverage("""\ g = h = i = 1 def fn(): @@ -568,7 +568,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3,4,5], "") - def test_exec(self): + def test_exec(self) -> None: self.check_coverage("""\ a = b = c = 1 exec("a = 2") @@ -598,7 +598,7 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3,4,7], "") - def test_extra_doc_string(self): + def test_extra_doc_string(self) -> None: self.check_coverage("""\ a = 1 "An extra docstring, should be a comment." @@ -621,7 +621,7 @@ class SimpleStatementTest(CoverageTest): "", ) - def test_nonascii(self): + def test_nonascii(self) -> None: self.check_coverage("""\ # coding: utf-8 a = 2 @@ -630,7 +630,7 @@ class SimpleStatementTest(CoverageTest): [2, 3] ) - def test_module_docstring(self): + def test_module_docstring(self) -> None: self.check_coverage("""\ '''I am a module docstring.''' a = 2 @@ -652,7 +652,7 @@ class SimpleStatementTest(CoverageTest): class CompoundStatementTest(CoverageTest): """Testing coverage of multi-line compound statements.""" - def test_statement_list(self): + def test_statement_list(self) -> None: self.check_coverage("""\ a = 1; b = 2; c = 3 @@ -662,7 +662,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,3,5], "") - def test_if(self): + def test_if(self) -> None: self.check_coverage("""\ a = 1 if a == 1: @@ -705,7 +705,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,3,4,6,8,9], "6-8") - def test_elif(self): + def test_elif(self) -> None: self.check_coverage("""\ a = 1; b = 2; c = 3; if a == 1: @@ -743,7 +743,7 @@ class CompoundStatementTest(CoverageTest): [1,2,3,4,5,7,8], "3, 5", report="7 2 4 2 64% 3, 5", ) - def test_elif_no_else(self): + def test_elif_no_else(self) -> None: self.check_coverage("""\ a = 1; b = 2; c = 3; if a == 1: @@ -765,7 +765,7 @@ class CompoundStatementTest(CoverageTest): [1,2,3,4,5,6], "3", report="6 1 4 2 70% 3, 4->6", ) - def test_elif_bizarre(self): + def test_elif_bizarre(self) -> None: self.check_coverage("""\ def f(self): if self==1: @@ -783,7 +783,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,3,4,5,6,7,8,9,10,11,13], "2-13") - def test_split_if(self): + def test_split_if(self) -> None: self.check_coverage("""\ a = 1; b = 2; c = 3; if \\ @@ -824,7 +824,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,4,5,7,9,10], "4, 7") - def test_pathological_split_if(self): + def test_pathological_split_if(self) -> None: self.check_coverage("""\ a = 1; b = 2; c = 3; if ( @@ -871,7 +871,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,5,6,9,11,12], "5, 9") - def test_absurd_split_if(self): + def test_absurd_split_if(self) -> None: self.check_coverage("""\ a = 1; b = 2; c = 3; if a == 1 \\ @@ -912,7 +912,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,4,5,7,9,10], "4, 7") - def test_constant_if(self): + def test_constant_if(self) -> None: if env.PYBEHAVIOR.keep_constant_test: lines = [1, 2, 3] else: @@ -926,7 +926,7 @@ class CompoundStatementTest(CoverageTest): "", ) - def test_while(self): + def test_while(self) -> None: self.check_coverage("""\ a = 3; b = 0 while a: @@ -944,7 +944,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,3,4,5], "") - def test_while_else(self): + def test_while_else(self) -> None: # Take the else branch. self.check_coverage("""\ a = 3; b = 0 @@ -969,7 +969,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,3,4,5,7,8], "7") - def test_split_while(self): + def test_split_while(self) -> None: self.check_coverage("""\ a = 3; b = 0 while \\ @@ -990,7 +990,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,5,6,7], "") - def test_for(self): + def test_for(self) -> None: self.check_coverage("""\ a = 0 for i in [1,2,3,4,5]: @@ -1016,7 +1016,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,3,4,5], "") - def test_for_else(self): + def test_for_else(self) -> None: self.check_coverage("""\ a = 0 for i in range(5): @@ -1037,7 +1037,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,3,4,6,7], "6") - def test_split_for(self): + def test_split_for(self) -> None: self.check_coverage("""\ a = 0 for \\ @@ -1057,7 +1057,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,6,7], "") - def test_try_except(self): + def test_try_except(self) -> None: self.check_coverage("""\ a = 0 try: @@ -1118,7 +1118,7 @@ class CompoundStatementTest(CoverageTest): arcz_missing="45 58", ) - def test_try_except_stranded_else(self): + def test_try_except_stranded_else(self) -> None: if env.PYBEHAVIOR.omit_after_jump: # The else can't be reached because the try ends with a raise. lines = [1,2,3,4,5,6,9] @@ -1147,7 +1147,7 @@ class CompoundStatementTest(CoverageTest): arcz_missing=arcz_missing, ) - def test_try_finally(self): + def test_try_finally(self) -> None: self.check_coverage("""\ a = 0 try: @@ -1171,7 +1171,7 @@ class CompoundStatementTest(CoverageTest): """, [1,2,3,4,5,7,8,9,10], "") - def test_function_def(self): + def test_function_def(self) -> None: self.check_coverage("""\ a = 99 def foo(): @@ -1213,7 +1213,7 @@ class CompoundStatementTest(CoverageTest): """, [1,10,12,13], "") - def test_class_def(self): + def test_class_def(self) -> None: arcz="-22 2D DE E-2 23 36 6A A-2 -68 8-6 -AB B-A" self.check_coverage("""\ # A comment. @@ -1239,7 +1239,7 @@ class CompoundStatementTest(CoverageTest): class ExcludeTest(CoverageTest): """Tests of the exclusion feature to mark lines as not covered.""" - def test_default(self): + def test_default(self) -> None: # A number of forms of pragma comment are accepted. self.check_coverage("""\ a = 1 @@ -1253,7 +1253,7 @@ class ExcludeTest(CoverageTest): [1,3,5,7] ) - def test_simple(self): + def test_simple(self) -> None: self.check_coverage("""\ a = 1; b = 2 @@ -1262,7 +1262,7 @@ class ExcludeTest(CoverageTest): """, [1,3], "", excludes=['-cc']) - def test_two_excludes(self): + def test_two_excludes(self) -> None: self.check_coverage("""\ a = 1; b = 2 @@ -1274,7 +1274,7 @@ class ExcludeTest(CoverageTest): """, [1,3,5,7], "5", excludes=['-cc', '-xx']) - def test_excluding_if_suite(self): + def test_excluding_if_suite(self) -> None: self.check_coverage("""\ a = 1; b = 2 @@ -1286,7 +1286,7 @@ class ExcludeTest(CoverageTest): """, [1,7], "", excludes=['not-here']) - def test_excluding_if_but_not_else_suite(self): + def test_excluding_if_but_not_else_suite(self) -> None: self.check_coverage("""\ a = 1; b = 2 @@ -1301,7 +1301,7 @@ class ExcludeTest(CoverageTest): """, [1,8,9,10], "", excludes=['not-here']) - def test_excluding_else_suite(self): + def test_excluding_else_suite(self) -> None: self.check_coverage("""\ a = 1; b = 2 @@ -1336,7 +1336,7 @@ class ExcludeTest(CoverageTest): """, [1,3,4,5,6,17], "", excludes=['#pragma: NO COVER']) - def test_excluding_elif_suites(self): + def test_excluding_elif_suites(self) -> None: self.check_coverage("""\ a = 1; b = 2 @@ -1354,7 +1354,7 @@ class ExcludeTest(CoverageTest): """, [1,3,4,5,6,11,12,13], "11-12", excludes=['#pragma: NO COVER']) - def test_excluding_oneline_if(self): + def test_excluding_oneline_if(self) -> None: self.check_coverage("""\ def foo(): a = 2 @@ -1365,7 +1365,7 @@ class ExcludeTest(CoverageTest): """, [1,2,4,6], "", excludes=["no cover"]) - def test_excluding_a_colon_not_a_suite(self): + def test_excluding_a_colon_not_a_suite(self) -> None: self.check_coverage("""\ def foo(): l = list(range(10)) @@ -1376,7 +1376,7 @@ class ExcludeTest(CoverageTest): """, [1,2,4,6], "", excludes=["no cover"]) - def test_excluding_for_suite(self): + def test_excluding_for_suite(self) -> None: self.check_coverage("""\ a = 0 for i in [1,2,3,4,5]: #pragma: NO COVER @@ -1404,7 +1404,7 @@ class ExcludeTest(CoverageTest): """, [1,7], "", excludes=['#pragma: NO COVER']) - def test_excluding_for_else(self): + def test_excluding_for_else(self) -> None: self.check_coverage("""\ a = 0 for i in range(5): @@ -1416,7 +1416,7 @@ class ExcludeTest(CoverageTest): """, [1,2,3,4,7], "", excludes=['#pragma: NO COVER']) - def test_excluding_while(self): + def test_excluding_while(self) -> None: self.check_coverage("""\ a = 3; b = 0 while a*b: #pragma: NO COVER @@ -1436,7 +1436,7 @@ class ExcludeTest(CoverageTest): """, [1,7], "", excludes=['#pragma: NO COVER']) - def test_excluding_while_else(self): + def test_excluding_while_else(self) -> None: self.check_coverage("""\ a = 3; b = 0 while a: @@ -1448,7 +1448,7 @@ class ExcludeTest(CoverageTest): """, [1,2,3,4,7], "", excludes=['#pragma: NO COVER']) - def test_excluding_try_except(self): + def test_excluding_try_except(self) -> None: self.check_coverage("""\ a = 0 try: @@ -1495,7 +1495,7 @@ class ExcludeTest(CoverageTest): arcz_missing="58", ) - def test_excluding_try_except_stranded_else(self): + def test_excluding_try_except_stranded_else(self) -> None: if env.PYBEHAVIOR.omit_after_jump: # The else can't be reached because the try ends with a raise. arcz = ".1 12 23 34 45 56 69 9." @@ -1519,7 +1519,7 @@ class ExcludeTest(CoverageTest): arcz_missing=arcz_missing, ) - def test_excluding_if_pass(self): + def test_excluding_if_pass(self) -> None: # From a comment on the coverage.py page by Michael McNeil Forbes: self.check_coverage("""\ def f(): @@ -1532,7 +1532,7 @@ class ExcludeTest(CoverageTest): """, [1,7], "", excludes=["no cover"]) - def test_excluding_function(self): + def test_excluding_function(self) -> None: self.check_coverage("""\ def fn(foo): #pragma: NO COVER a = 1 @@ -1544,7 +1544,7 @@ class ExcludeTest(CoverageTest): """, [6,7], "", excludes=['#pragma: NO COVER']) - def test_excluding_method(self): + def test_excluding_method(self) -> None: self.check_coverage("""\ class Fooey: def __init__(self): @@ -1558,7 +1558,7 @@ class ExcludeTest(CoverageTest): """, [1,2,3,8,9], "", excludes=['#pragma: NO COVER']) - def test_excluding_class(self): + def test_excluding_class(self) -> None: self.check_coverage("""\ class Fooey: #pragma: NO COVER def __init__(self): @@ -1572,7 +1572,7 @@ class ExcludeTest(CoverageTest): """, [8,9], "", excludes=['#pragma: NO COVER']) - def test_excludes_non_ascii(self): + def test_excludes_non_ascii(self) -> None: self.check_coverage("""\ # coding: utf-8 a = 1; b = 2 @@ -1583,7 +1583,7 @@ class ExcludeTest(CoverageTest): [2, 4], "", excludes=['✘cover'] ) - def test_formfeed(self): + def test_formfeed(self) -> None: # https://github.com/nedbat/coveragepy/issues/461 self.check_coverage("""\ x = 1 @@ -1599,7 +1599,7 @@ class ExcludeTest(CoverageTest): [1, 6], "", excludes=['assert'], ) - def test_excluded_comprehension_branches(self): + def test_excluded_comprehension_branches(self) -> None: # https://github.com/nedbat/coveragepy/issues/1271 self.check_coverage("""\ x, y = [0], [1] @@ -1617,7 +1617,7 @@ class ExcludeTest(CoverageTest): class Py24Test(CoverageTest): """Tests of new syntax in Python 2.4.""" - def test_function_decorators(self): + def test_function_decorators(self) -> None: lines = [1, 2, 3, 4, 6, 8, 10, 12] if env.PYBEHAVIOR.trace_decorated_def: lines = sorted(lines + [9]) @@ -1637,7 +1637,7 @@ class Py24Test(CoverageTest): """, lines, "") - def test_function_decorators_with_args(self): + def test_function_decorators_with_args(self) -> None: lines = [1, 2, 3, 4, 5, 6, 8, 10, 12] if env.PYBEHAVIOR.trace_decorated_def: lines = sorted(lines + [9]) @@ -1657,7 +1657,7 @@ class Py24Test(CoverageTest): """, lines, "") - def test_double_function_decorators(self): + def test_double_function_decorators(self) -> None: lines = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 14, 15, 17, 19, 21, 22, 24, 26] if env.PYBEHAVIOR.trace_decorated_def: lines = sorted(lines + [16, 23]) @@ -1695,7 +1695,7 @@ class Py24Test(CoverageTest): class Py25Test(CoverageTest): """Tests of new syntax in Python 2.5.""" - def test_with_statement(self): + def test_with_statement(self) -> None: self.check_coverage("""\ class Managed: def __enter__(self): @@ -1718,7 +1718,7 @@ class Py25Test(CoverageTest): """, [1,2,3,5,6,8,9,10,11,13,14,15,16,17,18], "") - def test_try_except_finally(self): + def test_try_except_finally(self) -> None: self.check_coverage("""\ a = 0; b = 0 try: @@ -1798,7 +1798,7 @@ class Py25Test(CoverageTest): arcz_missing="45 59", ) - def test_try_except_finally_stranded_else(self): + def test_try_except_finally_stranded_else(self) -> None: if env.PYBEHAVIOR.omit_after_jump: # The else can't be reached because the try ends with a raise. lines = [1,2,3,4,5,6,10,11] @@ -1835,33 +1835,33 @@ class ModuleTest(CoverageTest): run_in_temp_dir = False - def test_not_singleton(self): + def test_not_singleton(self) -> None: # You *can* create another coverage object. coverage.Coverage() coverage.Coverage() - def test_old_name_and_new_name(self): + def test_old_name_and_new_name(self) -> None: assert coverage.coverage is coverage.Coverage class ReportingTest(CoverageTest): """Tests of some reporting behavior.""" - def test_no_data_to_report_on_annotate(self): + def test_no_data_to_report_on_annotate(self) -> None: # Reporting with no data produces a nice message and no output # directory. with pytest.raises(NoDataError, match="No data to report."): self.command_line("annotate -d ann") self.assert_doesnt_exist("ann") - def test_no_data_to_report_on_html(self): + def test_no_data_to_report_on_html(self) -> None: # Reporting with no data produces a nice message and no output # directory. with pytest.raises(NoDataError, match="No data to report."): self.command_line("html -d htmlcov") self.assert_doesnt_exist("htmlcov") - def test_no_data_to_report_on_xml(self): + def test_no_data_to_report_on_xml(self) -> None: # Reporting with no data produces a nice message. with pytest.raises(NoDataError, match="No data to report."): self.command_line("xml") diff --git a/tests/test_data.py b/tests/test_data.py index 6a6228d8..56ef6dfc 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -10,7 +10,11 @@ import re import sqlite3 import threading +from typing import ( + Any, Callable, Collection, Dict, Iterable, Mapping, Set, TypeVar, Union +) from unittest import mock + import pytest from coverage.data import CoverageData, combine_parallel_data @@ -18,6 +22,7 @@ from coverage.data import add_data_to_hash, line_counts from coverage.debug import DebugControlString from coverage.exceptions import DataError, NoDataError from coverage.files import PathAliases, canonical_filename +from coverage.types import TArc, TLineNo from tests.coveragetest import CoverageTest from tests.helpers import assert_count_equal @@ -58,7 +63,7 @@ SUMMARY_3_4 = {'x.py': 4, 'y.py': 2, 'z.py': 1} MEASURED_FILES_3_4 = ['x.py', 'y.py', 'z.py'] -def DebugCoverageData(*args, **kwargs): +def DebugCoverageData(*args: Any, **kwargs: Any) -> CoverageData: """Factory for CovergeData instances with debugging turned on. This lets us exercise the debugging lines in sqldata.py. We don't make @@ -73,25 +78,31 @@ def DebugCoverageData(*args, **kwargs): # This is a way to get a mix of debug options across the tests. options.extend(["sqldata"]) debug = DebugControlString(options=options) - return CoverageData(*args, debug=debug, **kwargs) + return CoverageData(*args, debug=debug, **kwargs) # type: ignore[misc] + +TCoverageData = Callable[..., CoverageData] -def assert_line_counts(covdata, counts, fullpath=False): +def assert_line_counts( + covdata: CoverageData, + counts: Mapping[str, int], + fullpath: bool=False, +) -> None: """Check that the line_counts of `covdata` is `counts`.""" assert line_counts(covdata, fullpath) == counts -def assert_measured_files(covdata, measured): +def assert_measured_files(covdata: CoverageData, measured: Iterable[str]) -> None: """Check that `covdata`'s measured files are `measured`.""" assert_count_equal(covdata.measured_files(), measured) -def assert_lines1_data(covdata): +def assert_lines1_data(covdata: CoverageData) -> None: """Check that `covdata` has the data from LINES1.""" assert_line_counts(covdata, SUMMARY_1) assert_measured_files(covdata, MEASURED_FILES_1) assert_count_equal(covdata.lines("a.py"), A_PY_LINES_1) assert not covdata.has_arcs() -def assert_arcs3_data(covdata): +def assert_arcs3_data(covdata: CoverageData) -> None: """Check that `covdata` has the data from ARCS3.""" assert_line_counts(covdata, SUMMARY_3) assert_measured_files(covdata, MEASURED_FILES_3) @@ -102,7 +113,9 @@ def assert_arcs3_data(covdata): assert covdata.has_arcs() -def dicts_from_sets(file_data): +TData = TypeVar("TData", bound=Union[TLineNo, TArc]) + +def dicts_from_sets(file_data: Dict[str, Set[TData]]) -> Dict[str, Dict[TData, None]]: """Convert a dict of sets into a dict of dicts. Before 6.0, file data was a dict with None as the values. In 6.0, file @@ -115,57 +128,57 @@ def dicts_from_sets(file_data): class CoverageDataTest(CoverageTest): """Test cases for CoverageData.""" - def test_empty_data_is_false(self): + def test_empty_data_is_false(self) -> None: covdata = DebugCoverageData() assert not covdata self.assert_doesnt_exist(".coverage") - def test_empty_data_is_false_when_read(self): + def test_empty_data_is_false_when_read(self) -> None: covdata = DebugCoverageData() covdata.read() assert not covdata self.assert_doesnt_exist(".coverage") - def test_line_data_is_true(self): + def test_line_data_is_true(self) -> None: covdata = DebugCoverageData() covdata.add_lines(LINES_1) assert covdata - def test_arc_data_is_true(self): + def test_arc_data_is_true(self) -> None: covdata = DebugCoverageData() covdata.add_arcs(ARCS_3) assert covdata - def test_empty_line_data_is_false(self): + def test_empty_line_data_is_false(self) -> None: covdata = DebugCoverageData() covdata.add_lines({}) assert not covdata - def test_empty_arc_data_is_false(self): + def test_empty_arc_data_is_false(self) -> None: covdata = DebugCoverageData() covdata.add_arcs({}) assert not covdata @pytest.mark.parametrize("lines", [LINES_1, dicts_from_sets(LINES_1)]) - def test_adding_lines(self, lines): + def test_adding_lines(self, lines: Mapping[str, Collection[TLineNo]]) -> None: covdata = DebugCoverageData() covdata.add_lines(lines) assert_lines1_data(covdata) @pytest.mark.parametrize("arcs", [ARCS_3, dicts_from_sets(ARCS_3)]) - def test_adding_arcs(self, arcs): + def test_adding_arcs(self, arcs: Mapping[str, Collection[TArc]]) -> None: covdata = DebugCoverageData() covdata.add_arcs(arcs) assert_arcs3_data(covdata) - def test_ok_to_add_lines_twice(self): + def test_ok_to_add_lines_twice(self) -> None: covdata = DebugCoverageData() covdata.add_lines(LINES_1) covdata.add_lines(LINES_2) assert_line_counts(covdata, SUMMARY_1_2) assert_measured_files(covdata, MEASURED_FILES_1_2) - def test_ok_to_add_arcs_twice(self): + def test_ok_to_add_arcs_twice(self) -> None: covdata = DebugCoverageData() covdata.add_arcs(ARCS_3) covdata.add_arcs(ARCS_4) @@ -173,7 +186,7 @@ class CoverageDataTest(CoverageTest): assert_measured_files(covdata, MEASURED_FILES_3_4) @pytest.mark.parametrize("klass", [CoverageData, DebugCoverageData]) - def test_cant_add_arcs_with_lines(self, klass): + def test_cant_add_arcs_with_lines(self, klass: TCoverageData) -> None: covdata = klass() covdata.add_lines(LINES_1) msg = "Can't add branch measurements to existing line data" @@ -181,26 +194,26 @@ class CoverageDataTest(CoverageTest): covdata.add_arcs(ARCS_3) @pytest.mark.parametrize("klass", [CoverageData, DebugCoverageData]) - def test_cant_add_lines_with_arcs(self, klass): + def test_cant_add_lines_with_arcs(self, klass: TCoverageData) -> None: covdata = klass() covdata.add_arcs(ARCS_3) msg = "Can't add line measurements to existing branch data" with pytest.raises(DataError, match=msg): covdata.add_lines(LINES_1) - def test_touch_file_with_lines(self): + def test_touch_file_with_lines(self) -> None: covdata = DebugCoverageData() covdata.add_lines(LINES_1) covdata.touch_file('zzz.py') assert_measured_files(covdata, MEASURED_FILES_1 + ['zzz.py']) - def test_touch_file_with_arcs(self): + def test_touch_file_with_arcs(self) -> None: covdata = DebugCoverageData() covdata.add_arcs(ARCS_3) covdata.touch_file('zzz.py') assert_measured_files(covdata, MEASURED_FILES_3 + ['zzz.py']) - def test_set_query_contexts(self): + def test_set_query_contexts(self) -> None: covdata = DebugCoverageData() covdata.set_context('test_a') covdata.add_lines(LINES_1) @@ -209,14 +222,14 @@ class CoverageDataTest(CoverageTest): covdata.set_query_contexts(['other']) assert covdata.lines('a.py') == [] - def test_no_lines_vs_unmeasured_file(self): + def test_no_lines_vs_unmeasured_file(self) -> None: covdata = DebugCoverageData() covdata.add_lines(LINES_1) covdata.touch_file('zzz.py') assert covdata.lines('zzz.py') == [] assert covdata.lines('no_such_file.py') is None - def test_lines_with_contexts(self): + def test_lines_with_contexts(self) -> None: covdata = DebugCoverageData() covdata.set_context('test_a') covdata.add_lines(LINES_1) @@ -226,7 +239,7 @@ class CoverageDataTest(CoverageTest): covdata.set_query_contexts(['other']) assert covdata.lines('a.py') == [] - def test_contexts_by_lineno_with_lines(self): + def test_contexts_by_lineno_with_lines(self) -> None: covdata = DebugCoverageData() covdata.set_context('test_a') covdata.add_lines(LINES_1) @@ -234,7 +247,7 @@ class CoverageDataTest(CoverageTest): assert covdata.contexts_by_lineno('a.py') == expected @pytest.mark.parametrize("lines", [LINES_1, dicts_from_sets(LINES_1)]) - def test_no_duplicate_lines(self, lines): + def test_no_duplicate_lines(self, lines: Mapping[str, Collection[TLineNo]]) -> None: covdata = DebugCoverageData() covdata.set_context("context1") covdata.add_lines(lines) @@ -243,7 +256,7 @@ class CoverageDataTest(CoverageTest): assert covdata.lines('a.py') == A_PY_LINES_1 @pytest.mark.parametrize("arcs", [ARCS_3, dicts_from_sets(ARCS_3)]) - def test_no_duplicate_arcs(self, arcs): + def test_no_duplicate_arcs(self, arcs: Mapping[str, Collection[TArc]]) -> None: covdata = DebugCoverageData() covdata.set_context("context1") covdata.add_arcs(arcs) @@ -251,7 +264,7 @@ class CoverageDataTest(CoverageTest): covdata.add_arcs(arcs) assert covdata.arcs('x.py') == X_PY_ARCS_3 - def test_no_arcs_vs_unmeasured_file(self): + def test_no_arcs_vs_unmeasured_file(self) -> None: covdata = DebugCoverageData() covdata.add_arcs(ARCS_3) covdata.touch_file('zzz.py') @@ -260,7 +273,7 @@ class CoverageDataTest(CoverageTest): assert covdata.arcs('zzz.py') == [] assert covdata.arcs('no_such_file.py') is None - def test_arcs_with_contexts(self): + def test_arcs_with_contexts(self) -> None: covdata = DebugCoverageData() covdata.set_context('test_x') covdata.add_arcs(ARCS_3) @@ -270,20 +283,20 @@ class CoverageDataTest(CoverageTest): covdata.set_query_contexts(['other']) assert covdata.arcs('x.py') == [] - def test_contexts_by_lineno_with_arcs(self): + def test_contexts_by_lineno_with_arcs(self) -> None: covdata = DebugCoverageData() covdata.set_context('test_x') covdata.add_arcs(ARCS_3) expected = {1: ['test_x'], 2: ['test_x'], 3: ['test_x']} assert covdata.contexts_by_lineno('x.py') == expected - def test_contexts_by_lineno_with_unknown_file(self): + def test_contexts_by_lineno_with_unknown_file(self) -> None: covdata = DebugCoverageData() covdata.set_context('test_x') covdata.add_arcs(ARCS_3) assert covdata.contexts_by_lineno('xyz.py') == {} - def test_context_by_lineno_with_query_contexts_with_lines(self): + def test_context_by_lineno_with_query_contexts_with_lines(self) -> None: covdata = DebugCoverageData() covdata.set_context("test_1") covdata.add_lines(LINES_1) @@ -292,7 +305,7 @@ class CoverageDataTest(CoverageTest): covdata.set_query_context("test_1") assert covdata.contexts_by_lineno("a.py") == dict.fromkeys([1,2], ["test_1"]) - def test_context_by_lineno_with_query_contexts_with_arcs(self): + def test_context_by_lineno_with_query_contexts_with_arcs(self) -> None: covdata = DebugCoverageData() covdata.set_context("test_1") covdata.add_arcs(ARCS_3) @@ -301,7 +314,7 @@ class CoverageDataTest(CoverageTest): covdata.set_query_context("test_1") assert covdata.contexts_by_lineno("x.py") == dict.fromkeys([1,2,3], ["test_1"]) - def test_file_tracer_name(self): + def test_file_tracer_name(self) -> None: covdata = DebugCoverageData() covdata.add_lines({ "p1.foo": [1, 2, 3], @@ -314,7 +327,7 @@ class CoverageDataTest(CoverageTest): assert covdata.file_tracer("main.py") == "" assert covdata.file_tracer("p3.not_here") is None - def test_ok_to_repeat_file_tracer(self): + def test_ok_to_repeat_file_tracer(self) -> None: covdata = DebugCoverageData() covdata.add_lines({ "p1.foo": [1, 2, 3], @@ -324,7 +337,7 @@ class CoverageDataTest(CoverageTest): covdata.add_file_tracers({"p1.foo": "p1.plugin"}) assert covdata.file_tracer("p1.foo") == "p1.plugin" - def test_ok_to_set_empty_file_tracer(self): + def test_ok_to_set_empty_file_tracer(self) -> None: covdata = DebugCoverageData() covdata.add_lines({ "p1.foo": [1, 2, 3], @@ -335,7 +348,7 @@ class CoverageDataTest(CoverageTest): assert covdata.file_tracer("p1.foo") == "p1.plugin" assert covdata.file_tracer("main.py") == "" - def test_cant_file_tracer_unmeasured_files(self): + def test_cant_file_tracer_unmeasured_files(self) -> None: covdata = DebugCoverageData() msg = "Can't add file tracer data for unmeasured file 'p1.foo'" with pytest.raises(DataError, match=msg): @@ -345,7 +358,7 @@ class CoverageDataTest(CoverageTest): with pytest.raises(DataError, match=msg): covdata.add_file_tracers({"p1.foo": "p1.plugin"}) - def test_cant_change_file_tracer_name(self): + def test_cant_change_file_tracer_name(self) -> None: covdata = DebugCoverageData() covdata.add_lines({"p1.foo": [1, 2, 3]}) covdata.add_file_tracers({"p1.foo": "p1.plugin"}) @@ -354,7 +367,7 @@ class CoverageDataTest(CoverageTest): with pytest.raises(DataError, match=msg): covdata.add_file_tracers({"p1.foo": "p1.plugin.foo"}) - def test_update_lines(self): + def test_update_lines(self) -> None: covdata1 = DebugCoverageData(suffix='1') covdata1.add_lines(LINES_1) @@ -368,7 +381,7 @@ class CoverageDataTest(CoverageTest): assert_line_counts(covdata3, SUMMARY_1_2) assert_measured_files(covdata3, MEASURED_FILES_1_2) - def test_update_arcs(self): + def test_update_arcs(self) -> None: covdata1 = DebugCoverageData(suffix='1') covdata1.add_arcs(ARCS_3) @@ -382,7 +395,7 @@ class CoverageDataTest(CoverageTest): assert_line_counts(covdata3, SUMMARY_3_4) assert_measured_files(covdata3, MEASURED_FILES_3_4) - def test_update_cant_mix_lines_and_arcs(self): + def test_update_cant_mix_lines_and_arcs(self) -> None: covdata1 = DebugCoverageData(suffix='1') covdata1.add_lines(LINES_1) @@ -395,7 +408,7 @@ class CoverageDataTest(CoverageTest): with pytest.raises(DataError, match="Can't combine line data with arc data"): covdata2.update(covdata1) - def test_update_file_tracers(self): + def test_update_file_tracers(self) -> None: covdata1 = DebugCoverageData(suffix='1') covdata1.add_lines({ "p1.html": [1, 2, 3, 4], @@ -428,7 +441,7 @@ class CoverageDataTest(CoverageTest): assert covdata3.file_tracer("p3.foo") == "foo_plugin" assert covdata3.file_tracer("main.py") == "" - def test_update_conflicting_file_tracers(self): + def test_update_conflicting_file_tracers(self) -> None: covdata1 = DebugCoverageData(suffix='1') covdata1.add_lines({"p1.html": [1, 2, 3]}) covdata1.add_file_tracers({"p1.html": "html.plugin"}) @@ -445,7 +458,7 @@ class CoverageDataTest(CoverageTest): with pytest.raises(DataError, match=msg): covdata2.update(covdata1) - def test_update_file_tracer_vs_no_file_tracer(self): + def test_update_file_tracer_vs_no_file_tracer(self) -> None: covdata1 = DebugCoverageData(suffix="1") covdata1.add_lines({"p1.html": [1, 2, 3]}) covdata1.add_file_tracers({"p1.html": "html.plugin"}) @@ -461,7 +474,7 @@ class CoverageDataTest(CoverageTest): with pytest.raises(DataError, match=msg): covdata2.update(covdata1) - def test_update_lines_empty(self): + def test_update_lines_empty(self) -> None: covdata1 = DebugCoverageData(suffix='1') covdata1.add_lines(LINES_1) @@ -469,7 +482,7 @@ class CoverageDataTest(CoverageTest): covdata1.update(covdata2) assert_line_counts(covdata1, SUMMARY_1) - def test_update_arcs_empty(self): + def test_update_arcs_empty(self) -> None: covdata1 = DebugCoverageData(suffix='1') covdata1.add_arcs(ARCS_3) @@ -477,14 +490,14 @@ class CoverageDataTest(CoverageTest): covdata1.update(covdata2) assert_line_counts(covdata1, SUMMARY_3) - def test_asking_isnt_measuring(self): + def test_asking_isnt_measuring(self) -> None: # Asking about an unmeasured file shouldn't make it seem measured. covdata = DebugCoverageData() assert_measured_files(covdata, []) assert covdata.arcs("missing.py") is None assert_measured_files(covdata, []) - def test_add_to_hash_with_lines(self): + def test_add_to_hash_with_lines(self) -> None: covdata = DebugCoverageData() covdata.add_lines(LINES_1) hasher = mock.Mock() @@ -494,7 +507,7 @@ class CoverageDataTest(CoverageTest): mock.call.update(""), # file_tracer name ] - def test_add_to_hash_with_arcs(self): + def test_add_to_hash_with_arcs(self) -> None: covdata = DebugCoverageData() covdata.add_arcs(ARCS_3) covdata.add_file_tracers({"y.py": "hologram_plugin"}) @@ -505,7 +518,7 @@ class CoverageDataTest(CoverageTest): mock.call.update("hologram_plugin"), # file_tracer name ] - def test_add_to_lines_hash_with_missing_file(self): + def test_add_to_lines_hash_with_missing_file(self) -> None: # https://github.com/nedbat/coveragepy/issues/403 covdata = DebugCoverageData() covdata.add_lines(LINES_1) @@ -516,7 +529,7 @@ class CoverageDataTest(CoverageTest): mock.call.update(None), ] - def test_add_to_arcs_hash_with_missing_file(self): + def test_add_to_arcs_hash_with_missing_file(self) -> None: # https://github.com/nedbat/coveragepy/issues/403 covdata = DebugCoverageData() covdata.add_arcs(ARCS_3) @@ -528,25 +541,25 @@ class CoverageDataTest(CoverageTest): mock.call.update(None), ] - def test_empty_lines_are_still_lines(self): + def test_empty_lines_are_still_lines(self) -> None: covdata = DebugCoverageData() covdata.add_lines({}) covdata.touch_file("abc.py") assert not covdata.has_arcs() - def test_empty_arcs_are_still_arcs(self): + def test_empty_arcs_are_still_arcs(self) -> None: covdata = DebugCoverageData() covdata.add_arcs({}) covdata.touch_file("abc.py") assert covdata.has_arcs() - def test_cant_touch_in_empty_data(self): + def test_cant_touch_in_empty_data(self) -> None: covdata = DebugCoverageData() msg = "Can't touch files in an empty CoverageData" with pytest.raises(DataError, match=msg): covdata.touch_file("abc.py") - def test_read_and_write_are_opposites(self): + def test_read_and_write_are_opposites(self) -> None: covdata1 = DebugCoverageData() covdata1.add_arcs(ARCS_3) covdata1.write() @@ -555,11 +568,11 @@ class CoverageDataTest(CoverageTest): covdata2.read() assert_arcs3_data(covdata2) - def test_thread_stress(self): + def test_thread_stress(self) -> None: covdata = DebugCoverageData() exceptions = [] - def thread_main(): + def thread_main() -> None: """Every thread will try to add the same data.""" try: covdata.add_lines(LINES_1) @@ -579,7 +592,7 @@ class CoverageDataTest(CoverageTest): class CoverageDataInTempDirTest(CoverageTest): """Tests of CoverageData that need a temporary directory to make files.""" - def test_read_write_lines(self): + def test_read_write_lines(self) -> None: covdata1 = DebugCoverageData("lines.dat") covdata1.add_lines(LINES_1) covdata1.write() @@ -588,7 +601,7 @@ class CoverageDataInTempDirTest(CoverageTest): covdata2.read() assert_lines1_data(covdata2) - def test_read_write_arcs(self): + def test_read_write_arcs(self) -> None: covdata1 = DebugCoverageData("arcs.dat") covdata1.add_arcs(ARCS_3) covdata1.write() @@ -597,14 +610,14 @@ class CoverageDataInTempDirTest(CoverageTest): covdata2.read() assert_arcs3_data(covdata2) - def test_read_errors(self): + def test_read_errors(self) -> None: self.make_file("xyzzy.dat", "xyzzy") with pytest.raises(DataError, match=r"Couldn't .* '.*[/\\]xyzzy.dat': \S+"): covdata = DebugCoverageData("xyzzy.dat") covdata.read() assert not covdata - def test_hard_read_error(self): + def test_hard_read_error(self) -> None: self.make_file("noperms.dat", "go away") os.chmod("noperms.dat", 0) with pytest.raises(DataError, match=r"Couldn't .* '.*[/\\]noperms.dat': \S+"): @@ -612,17 +625,17 @@ class CoverageDataInTempDirTest(CoverageTest): covdata.read() @pytest.mark.parametrize("klass", [CoverageData, DebugCoverageData]) - def test_error_when_closing(self, klass): + def test_error_when_closing(self, klass: TCoverageData) -> None: msg = r"Couldn't .* '.*[/\\]flaked.dat': \S+" with pytest.raises(DataError, match=msg): covdata = klass("flaked.dat") covdata.add_lines(LINES_1) # I don't know how to make a real error, so let's fake one. sqldb = list(covdata._dbs.values())[0] - sqldb.close = lambda: 1/0 + sqldb.close = lambda: 1/0 # type: ignore[assignment] covdata.add_lines(LINES_1) - def test_wrong_schema_version(self): + def test_wrong_schema_version(self) -> None: with sqlite3.connect("wrong_schema.db") as con: con.execute("create table coverage_schema (version integer)") con.execute("insert into coverage_schema (version) values (99)") @@ -632,7 +645,7 @@ class CoverageDataInTempDirTest(CoverageTest): covdata.read() assert not covdata - def test_wrong_schema_schema(self): + def test_wrong_schema_schema(self) -> None: with sqlite3.connect("wrong_schema_schema.db") as con: con.execute("create table coverage_schema (xyzzy integer)") con.execute("insert into coverage_schema (xyzzy) values (99)") @@ -646,13 +659,13 @@ class CoverageDataInTempDirTest(CoverageTest): class CoverageDataFilesTest(CoverageTest): """Tests of CoverageData file handling.""" - def test_reading_missing(self): + def test_reading_missing(self) -> None: self.assert_doesnt_exist(".coverage") covdata = DebugCoverageData() covdata.read() assert_line_counts(covdata, {}) - def test_writing_and_reading(self): + def test_writing_and_reading(self) -> None: covdata1 = DebugCoverageData() covdata1.add_lines(LINES_1) covdata1.write() @@ -661,7 +674,7 @@ class CoverageDataFilesTest(CoverageTest): covdata2.read() assert_line_counts(covdata2, SUMMARY_1) - def test_debug_output_with_debug_option(self): + def test_debug_output_with_debug_option(self) -> None: # With debug option dataio, we get debug output about reading and # writing files. debug = DebugControlString(options=["dataio"]) @@ -681,7 +694,7 @@ class CoverageDataFilesTest(CoverageTest): debug.get_output() ) - def test_debug_output_without_debug_option(self): + def test_debug_output_without_debug_option(self) -> None: # With a debug object, but not the dataio option, we don't get debug # output. debug = DebugControlString(options=[]) @@ -695,7 +708,7 @@ class CoverageDataFilesTest(CoverageTest): assert debug.get_output() == "" - def test_explicit_suffix(self): + def test_explicit_suffix(self) -> None: self.assert_doesnt_exist(".coverage.SUFFIX") covdata = DebugCoverageData(suffix='SUFFIX') covdata.add_lines(LINES_1) @@ -703,7 +716,7 @@ class CoverageDataFilesTest(CoverageTest): self.assert_exists(".coverage.SUFFIX") self.assert_doesnt_exist(".coverage") - def test_true_suffix(self): + def test_true_suffix(self) -> None: self.assert_file_count(".coverage.*", 0) # suffix=True will make a randomly named data file. @@ -725,7 +738,7 @@ class CoverageDataFilesTest(CoverageTest): # In addition to being different, the suffixes have the pid in them. assert all(str(os.getpid()) in fn for fn in data_files2) - def test_combining(self): + def test_combining(self) -> None: self.assert_file_count(".coverage.*", 0) covdata1 = DebugCoverageData(suffix='1') @@ -746,7 +759,7 @@ class CoverageDataFilesTest(CoverageTest): assert_measured_files(covdata3, MEASURED_FILES_1_2) self.assert_file_count(".coverage.*", 0) - def test_erasing(self): + def test_erasing(self) -> None: covdata1 = DebugCoverageData() covdata1.add_lines(LINES_1) covdata1.write() @@ -758,7 +771,7 @@ class CoverageDataFilesTest(CoverageTest): covdata2.read() assert_line_counts(covdata2, {}) - def test_erasing_parallel(self): + def test_erasing_parallel(self) -> None: self.make_file("datafile.1") self.make_file("datafile.2") self.make_file(".coverage") @@ -767,7 +780,7 @@ class CoverageDataFilesTest(CoverageTest): self.assert_file_count("datafile.*", 0) self.assert_exists(".coverage") - def test_combining_with_aliases(self): + def test_combining_with_aliases(self) -> None: covdata1 = DebugCoverageData(suffix='1') covdata1.add_lines({ '/home/ned/proj/src/a.py': {1, 2}, @@ -807,7 +820,7 @@ class CoverageDataFilesTest(CoverageTest): assert_measured_files(covdata3, [apy, sub_bpy, template_html]) assert covdata3.file_tracer(template_html) == 'html.plugin' - def test_combining_from_different_directories(self): + def test_combining_from_different_directories(self) -> None: os.makedirs('cov1') covdata1 = DebugCoverageData('cov1/.coverage.1') covdata1.add_lines(LINES_1) @@ -832,7 +845,7 @@ class CoverageDataFilesTest(CoverageTest): self.assert_doesnt_exist("cov2/.coverage.2") self.assert_exists(".coverage.xxx") - def test_combining_from_files(self): + def test_combining_from_files(self) -> None: os.makedirs('cov1') covdata1 = DebugCoverageData('cov1/.coverage.1') covdata1.add_lines(LINES_1) @@ -862,13 +875,13 @@ class CoverageDataFilesTest(CoverageTest): self.assert_exists(".coverage.xxx") self.assert_exists("cov2/.coverage.xxx") - def test_combining_from_nonexistent_directories(self): + def test_combining_from_nonexistent_directories(self) -> None: covdata = DebugCoverageData() msg = "Couldn't combine from non-existent path 'xyzzy'" with pytest.raises(NoDataError, match=msg): combine_parallel_data(covdata, data_paths=['xyzzy']) - def test_interleaved_erasing_bug716(self): + def test_interleaved_erasing_bug716(self) -> None: # pytest-cov could produce this scenario. #716 covdata1 = DebugCoverageData() covdata2 = DebugCoverageData() @@ -888,7 +901,7 @@ class CoverageDataFilesTest(CoverageTest): ("[3-1]", "[b-a]"), ], ) - def test_combining_with_crazy_filename(self, dpart, fpart): + def test_combining_with_crazy_filename(self, dpart: str, fpart: str) -> None: dirname = f"py{dpart}" basename = f"{dirname}/.coverage{fpart}" os.makedirs(dirname) @@ -907,7 +920,7 @@ class CoverageDataFilesTest(CoverageTest): assert_measured_files(covdata3, MEASURED_FILES_1_2) self.assert_file_count(glob.escape(basename) + ".*", 0) - def test_meta_data(self): + def test_meta_data(self) -> None: # The metadata written to the data file shouldn't interfere with # hashing to remove duplicates, except for debug=process, which # writes debugging info as metadata. @@ -934,7 +947,7 @@ class DumpsLoadsTest(CoverageTest): run_in_temp_dir = False @pytest.mark.parametrize("klass", [CoverageData, DebugCoverageData]) - def test_serialization(self, klass): + def test_serialization(self, klass: TCoverageData) -> None: covdata1 = klass(no_disk=True) covdata1.add_lines(LINES_1) covdata1.add_lines(LINES_2) @@ -945,7 +958,7 @@ class DumpsLoadsTest(CoverageTest): assert_line_counts(covdata2, SUMMARY_1_2) assert_measured_files(covdata2, MEASURED_FILES_1_2) - def test_misfed_serialization(self): + def test_misfed_serialization(self) -> None: covdata = CoverageData(no_disk=True) bad_data = b'Hello, world!\x07 ' + b'z' * 100 msg = r"Unrecognized serialization: {} \(head of {} bytes\)".format( @@ -961,7 +974,7 @@ class NoDiskTest(CoverageTest): run_in_temp_dir = False - def test_updating(self): + def test_updating(self) -> None: # https://github.com/nedbat/coveragepy/issues/1323 a = CoverageData(no_disk=True) a.add_lines({'foo.py': [10, 20, 30]}) |