Coverage for tests / test_api.py: 100.000%
827 statements
« prev ^ index » next coverage.py v7.12.1a0.dev1, created at 2025-11-30 17:57 +0000
« prev ^ index » next coverage.py v7.12.1a0.dev1, created at 2025-11-30 17:57 +0000
1# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2# For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
4"""Tests for coverage.py's API."""
6from __future__ import annotations 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
8import fnmatch 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
9import glob 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
10import io 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
11import os 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
12import os.path 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
13import re 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
14import shutil 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
15import sys 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
16import textwrap 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
18from typing import cast, Callable 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
19from collections.abc import Iterable 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
21import pytest 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
23import coverage 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
24from coverage import Coverage, env 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
25from coverage.data import line_counts, sorted_lines 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
26from coverage.exceptions import ConfigError, CoverageException, DataError, NoDataError, NoSource 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
27from coverage.files import abs_file, relative_filename 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
28from coverage.misc import import_local_file 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
29from coverage.types import FilePathClasses, FilePathType, TCovKwargs 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
31from tests import testenv 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
32from tests.coveragetest import CoverageTest, TESTS_DIR, UsingModulesMixin 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
33from tests.helpers import ( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
34 assert_count_equal,
35 assert_coverage_warnings,
36 change_dir,
37 get_coverage_warnings,
38 nice_file,
39 os_sep,
40)
42BAD_SQLITE_REGEX = r"file( is encrypted or)? is not a database" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
45class ApiTest(CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
46 """Api-oriented tests for coverage.py."""
48 def clean_files(self, files: list[str], pats: list[str]) -> list[str]: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
49 """Remove names matching `pats` from `files`, a list of file names."""
50 good = [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
51 for f in files: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
52 for pat in pats: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
53 if fnmatch.fnmatch(f, pat): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
54 break 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
55 else:
56 good.append(f) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
57 return good 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
59 def assertFiles(self, files: list[str]) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
60 """Assert that the files here are `files`, ignoring the usual junk."""
61 here = os.listdir(".") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
62 here = self.clean_files(here, ["*.pyc", "__pycache__", "*$py.class"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
63 assert_count_equal(here, files) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
65 def test_unexecuted_file(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
66 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
68 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
69 "mycode.py",
70 """\
71 a = 1
72 b = 2
73 if b == 3:
74 c = 4
75 d = 5
76 """,
77 )
79 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
80 "not_run.py",
81 """\
82 fooey = 17
83 """,
84 )
86 # Import the Python file, executing it.
87 self.start_import_stop(cov, "mycode") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
89 _, statements, missing, _ = cov.analysis("not_run.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
90 assert statements == [1] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
91 assert missing == [1] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
93 def test_filenames(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
94 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
95 "mymain.py",
96 """\
97 import mymod
98 a = 1
99 """,
100 )
102 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
103 "mymod.py",
104 """\
105 fooey = 17
106 """,
107 )
109 # Import the Python file, executing it.
110 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
111 self.start_import_stop(cov, "mymain") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
113 filename, _, _, _ = cov.analysis("mymain.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
114 assert os.path.basename(filename) == "mymain.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
115 filename, _, _, _ = cov.analysis("mymod.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
116 assert os.path.basename(filename) == "mymod.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
118 filename, _, _, _ = cov.analysis(sys.modules["mymain"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
119 assert os.path.basename(filename) == "mymain.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
120 filename, _, _, _ = cov.analysis(sys.modules["mymod"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
121 assert os.path.basename(filename) == "mymod.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
123 # Import the Python file, executing it again, once it's been compiled
124 # already.
125 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
126 self.start_import_stop(cov, "mymain") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
128 filename, _, _, _ = cov.analysis("mymain.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
129 assert os.path.basename(filename) == "mymain.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
130 filename, _, _, _ = cov.analysis("mymod.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
131 assert os.path.basename(filename) == "mymod.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
133 filename, _, _, _ = cov.analysis(sys.modules["mymain"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
134 assert os.path.basename(filename) == "mymain.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
135 filename, _, _, _ = cov.analysis(sys.modules["mymod"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
136 assert os.path.basename(filename) == "mymod.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
138 @pytest.mark.parametrize("cover_pylib", [False, True]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
139 def test_stdlib(self, cover_pylib: bool) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
140 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
141 "mymain.py",
142 """\
143 import colorsys
144 a = 1
145 hls = colorsys.rgb_to_hls(1.0, 0.5, 0.0)
146 """,
147 )
149 # Measure without the stdlib.
150 cov1 = coverage.Coverage(cover_pylib=cover_pylib) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
151 self.start_import_stop(cov1, "mymain") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
153 _, statements, missing, _ = cov1.analysis("mymain.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
154 assert statements == [1, 2, 3] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
155 assert missing == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
156 # but none were in colorsys.py
157 _, statements, missing, _ = cov1.analysis("colorsys.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
158 if cover_pylib: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
159 assert statements != missing 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
160 else:
161 assert statements == missing 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
163 def test_include_can_measure_stdlib(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
164 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
165 "mymain.py",
166 """\
167 import colorsys, random
168 a = 1
169 r, g, b = [random.random() for _ in range(3)]
170 hls = colorsys.rgb_to_hls(r, g, b)
171 """,
172 )
174 # Measure without the stdlib, but include colorsys.
175 cov1 = coverage.Coverage(cover_pylib=False, include=["*/colorsys.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
176 self.start_import_stop(cov1, "mymain") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
178 # some statements were marked executed in colorsys.py
179 _, statements, missing, _ = cov1.analysis("colorsys.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
180 assert statements != missing 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
181 # but none were in random.py
182 _, statements, missing, _ = cov1.analysis("random.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
183 assert statements == missing 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
185 def test_exclude_list(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
186 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
187 cov.clear_exclude() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
188 assert cov.get_exclude_list() == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
189 cov.exclude("foo") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
190 assert cov.get_exclude_list() == ["foo"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
191 cov.exclude("bar") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
192 assert cov.get_exclude_list() == ["foo", "bar"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
193 assert cov._exclude_regex("exclude") == "(?:foo)|(?:bar)" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
194 cov.clear_exclude() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
195 assert cov.get_exclude_list() == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
197 def test_exclude_partial_list(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
198 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
199 cov.clear_exclude(which="partial") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
200 assert cov.get_exclude_list(which="partial") == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
201 cov.exclude("foo", which="partial") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
202 assert cov.get_exclude_list(which="partial") == ["foo"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
203 cov.exclude("bar", which="partial") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
204 assert cov.get_exclude_list(which="partial") == ["foo", "bar"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
205 assert cov._exclude_regex(which="partial") == "(?:foo)|(?:bar)" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
206 cov.clear_exclude(which="partial") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
207 assert cov.get_exclude_list(which="partial") == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
209 def test_exclude_and_partial_are_separate_lists(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
210 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
211 cov.clear_exclude(which="partial") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
212 cov.clear_exclude(which="exclude") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
213 cov.exclude("foo", which="partial") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
214 assert cov.get_exclude_list(which="partial") == ["foo"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
215 assert cov.get_exclude_list(which="exclude") == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
216 cov.exclude("bar", which="exclude") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
217 assert cov.get_exclude_list(which="partial") == ["foo"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
218 assert cov.get_exclude_list(which="exclude") == ["bar"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
219 cov.exclude("p2", which="partial") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
220 cov.exclude("e2", which="exclude") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
221 assert cov.get_exclude_list(which="partial") == ["foo", "p2"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
222 assert cov.get_exclude_list(which="exclude") == ["bar", "e2"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
223 cov.clear_exclude(which="partial") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
224 assert cov.get_exclude_list(which="partial") == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
225 assert cov.get_exclude_list(which="exclude") == ["bar", "e2"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
226 cov.clear_exclude(which="exclude") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
227 assert cov.get_exclude_list(which="partial") == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
228 assert cov.get_exclude_list(which="exclude") == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
230 def test_datafile_default(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
231 # Default data file behavior: it's .coverage
232 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
233 "datatest1.py",
234 """\
235 fooey = 17
236 """,
237 )
239 self.assertFiles(["datatest1.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
240 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
241 self.start_import_stop(cov, "datatest1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
242 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
243 self.assertFiles(["datatest1.py", ".coverage"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
245 @pytest.mark.parametrize("file_class", FilePathClasses) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
246 def test_datafile_specified(self, file_class: FilePathType) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
247 # You can specify the data file name.
248 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
249 "datatest2.py",
250 """\
251 fooey = 17
252 """,
253 )
255 self.assertFiles(["datatest2.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
256 cov = coverage.Coverage(data_file=file_class("cov.data")) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
257 self.start_import_stop(cov, "datatest2") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
258 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
259 self.assertFiles(["datatest2.py", "cov.data"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
261 @pytest.mark.parametrize("file_class", FilePathClasses) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
262 def test_datafile_and_suffix_specified(self, file_class: FilePathType) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
263 # You can specify the data file name and suffix.
264 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
265 "datatest3.py",
266 """\
267 fooey = 17
268 """,
269 )
271 self.assertFiles(["datatest3.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
272 cov = coverage.Coverage(data_file=file_class("cov.data"), data_suffix="14") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
273 self.start_import_stop(cov, "datatest3") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
274 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
275 self.assertFiles(["datatest3.py", "cov.data.14"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
277 def test_datafile_from_rcfile(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
278 # You can specify the data file name in the .coveragerc file
279 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
280 "datatest4.py",
281 """\
282 fooey = 17
283 """,
284 )
285 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
286 ".coveragerc",
287 """\
288 [run]
289 data_file = mydata.dat
290 """,
291 )
293 self.assertFiles(["datatest4.py", ".coveragerc"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
294 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
295 self.start_import_stop(cov, "datatest4") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
296 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
297 self.assertFiles(["datatest4.py", ".coveragerc", "mydata.dat"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
299 def test_deep_datafile(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
300 self.make_file("datatest5.py", "fooey = 17") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
301 self.assertFiles(["datatest5.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
302 cov = coverage.Coverage(data_file="deep/sub/cov.data") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
303 self.start_import_stop(cov, "datatest5") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
304 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
305 self.assertFiles(["datatest5.py", "deep"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
306 self.assert_exists("deep/sub/cov.data") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
308 def test_datafile_none(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
309 cov = coverage.Coverage(data_file=None) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
311 def f1() -> None: # pragma: nested 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
312 a = 1 # pylint: disable=unused-variable
314 one_line_number = f1.__code__.co_firstlineno + 1 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
315 lines = [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
317 def run_one_function(f: Callable[[], None]) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
318 cov.erase() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
319 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
320 f() 1abcdefghijklmnopqrstuvwxyzABCD
322 fs = cov.get_data().measured_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
323 lines.append(cov.get_data().lines(list(fs)[0])) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
325 run_one_function(f1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
326 run_one_function(f1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
327 run_one_function(f1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
328 assert lines == [[one_line_number]] * 3 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
329 self.assert_doesnt_exist(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
330 assert os.listdir(".") == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
332 def test_empty_reporting(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
333 # empty summary reports raise exception, just like the xml report
334 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
335 cov.erase() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
336 with pytest.raises(NoDataError, match="No data to report."): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
337 cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
339 def test_completely_zero_reporting(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
340 # https://github.com/coveragepy/coveragepy/issues/884
341 # If nothing was measured, the file-touching didn't happen properly.
342 self.make_file("foo/bar.py", "print('Never run')") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
343 self.make_file("test.py", "assert True") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
344 with pytest.warns(Warning) as warns: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
345 cov = coverage.Coverage(source=["foo"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
346 self.start_import_stop(cov, "test") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
347 cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
348 assert_coverage_warnings(warns, "No data was collected. (no-data-collected)") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
349 # Name Stmts Miss Cover
350 # --------------------------------
351 # foo/bar.py 1 1 0%
352 # --------------------------------
353 # TOTAL 1 1 0%
355 last = self.last_line_squeezed(self.stdout()) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
356 assert "TOTAL 1 1 0%" == last 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
358 def test_cov4_data_file(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
359 cov4_data = ( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
360 "!coverage.py: This is a private format, don't read it directly!"
361 + '{"lines":{"/somewhere/not/really.py":[1,5,2,3]}}'
362 )
363 self.make_file(".coverage", cov4_data) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
364 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
365 with pytest.raises(DataError, match="Looks like a coverage 4.x data file"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
366 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
367 cov.erase() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
369 def make_code1_code2(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
370 """Create the code1.py and code2.py files."""
371 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
372 "code1.py",
373 """\
374 code1 = 1
375 """,
376 )
377 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
378 "code2.py",
379 """\
380 code2 = 1
381 code2 = 2
382 """,
383 )
385 def check_code1_code2(self, cov: Coverage) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
386 """Check the analysis is correct for code1.py and code2.py."""
387 _, statements, missing, _ = cov.analysis("code1.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
388 assert statements == [1] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
389 assert missing == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
390 _, statements, missing, _ = cov.analysis("code2.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
391 assert statements == [1, 2] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
392 assert missing == [] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
394 def test_start_stop_start_stop(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
395 self.make_code1_code2() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
396 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
397 self.start_import_stop(cov, "code1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
398 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
399 self.start_import_stop(cov, "code2") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
400 self.check_code1_code2(cov) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
402 def test_start_save_stop(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
403 self.make_code1_code2() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
404 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
405 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
406 import_local_file("code1") 1abcdefghijklmnopqrstuvwxyzABCD
407 cov.save() 1abcdefghijklmnopqrstuvwxyzABCD
408 import_local_file("code2") 1abcdefghijklmnopqrstuvwxyzABCD
409 self.check_code1_code2(cov) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
411 def test_start_save_nostop(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
412 self.make_code1_code2() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
413 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
414 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
415 import_local_file("code1") 1abcdefghijklmnopqrstuvwxyzABCD
416 cov.save() 1abcdefghijklmnopqrstuvwxyzABCD
417 import_local_file("code2") 1abcdefghijklmnopqrstuvwxyzABCD
418 self.check_code1_code2(cov) 1abcdefghijklmnopqrstuvwxyzABCD
420 def test_two_getdata_only_warn_once(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
421 self.make_code1_code2() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
422 cov = coverage.Coverage(source=["."], omit=["code1.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
423 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
424 import_local_file("code1") 1abcdefghijklmnopqrstuvwxyzABCD
425 # We didn't collect any data, so we should get a warning.
426 with self.assert_warnings(cov, ["No data was collected"]): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
427 cov.get_data() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
428 # But calling get_data a second time with no intervening activity
429 # won't make another warning.
430 with self.assert_warnings(cov, []): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
431 cov.get_data() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
433 def test_two_getdata_warn_twice(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
434 self.make_code1_code2() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
435 cov = coverage.Coverage(source=["."], omit=["code1.py", "code2.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
436 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
437 import_local_file("code1") 1abcdefghijklmnopqrstuvwxyzABCD
438 # We didn't collect any data, so we should get a warning.
439 with self.assert_warnings(cov, ["No data was collected"]): 1abcdefghijklmnopqrstuvwxyzABCD
440 cov.save() 1abcdefghijklmnopqrstuvwxyzABCD
441 import_local_file("code2") 1abcdefghijklmnopqrstuvwxyzABCD
442 # Calling get_data a second time after tracing some more will warn again.
443 with self.assert_warnings(cov, ["No data was collected"]): 1abcdefghijklmnopqrstuvwxyzABCD
444 cov.get_data() 1abcdefghijklmnopqrstuvwxyzABCD
446 def make_good_data_files(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
447 """Make some good data files."""
448 self.make_code1_code2() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
449 cov = coverage.Coverage(data_suffix=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
450 self.start_import_stop(cov, "code1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
451 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
453 cov = coverage.Coverage(data_suffix=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
454 self.start_import_stop(cov, "code2") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
455 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
456 self.assert_file_count(".coverage.*", 2) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
458 def test_combining_corrupt_data(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
459 # If you combine a corrupt data file, then you will get a warning,
460 # and the file will remain.
461 self.make_good_data_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
462 self.make_file(".coverage.foo", """La la la, this isn't coverage data!""") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
463 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
464 warning_regex = r"Couldn't use data file '.*\.coverage\.foo': " + BAD_SQLITE_REGEX 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
465 with self.assert_warnings(cov, [warning_regex]): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
466 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
468 # We got the results from code1 and code2 properly.
469 self.check_code1_code2(cov) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
471 # The bad file still exists, but it's the only parallel data file left.
472 self.assert_exists(".coverage.foo") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
473 self.assert_file_count(".coverage.*", 1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
475 def test_combining_twice(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
476 self.make_good_data_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
477 cov1 = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
478 cov1.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
479 assert self.stdout() == "" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
480 cov1.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
481 self.check_code1_code2(cov1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
482 self.assert_file_count(".coverage.*", 0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
483 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
485 cov2 = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
486 with pytest.raises(NoDataError, match=r"No data to combine"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
487 cov2.combine(strict=True, keep=False) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
489 cov3 = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
490 cov3.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
491 assert self.stdout() == "" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
492 # Now the data is empty!
493 _, statements, missing, _ = cov3.analysis("code1.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
494 assert statements == [1] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
495 assert missing == [1] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
496 _, statements, missing, _ = cov3.analysis("code2.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
497 assert statements == [1, 2] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
498 assert missing == [1, 2] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
500 def test_combining_with_a_used_coverage(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
501 # Can you use a coverage object to run one shard of a parallel suite,
502 # and then also combine the data?
503 self.make_code1_code2() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
504 cov = coverage.Coverage(data_suffix=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
505 self.start_import_stop(cov, "code1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
506 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
508 cov = coverage.Coverage(data_suffix=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
509 self.start_import_stop(cov, "code2") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
510 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
512 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
513 assert self.stdout() == "" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
514 self.check_code1_code2(cov) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
516 def test_ordered_combine(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
517 # https://github.com/coveragepy/coveragepy/issues/649
518 # The order of the [paths] setting used to matter. Now the
519 # resulting path must exist, so the order doesn't matter.
520 def make_files() -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
521 self.make_file("plugins/p1.py", "") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
522 self.make_file("girder/g1.py", "") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
523 self.make_data_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
524 basename=".coverage.1",
525 lines={
526 abs_file("ci/girder/g1.py"): range(10),
527 abs_file("ci/girder/plugins/p1.py"): range(10),
528 },
529 )
531 def get_combined_filenames() -> set[str]: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
532 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
533 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
534 assert self.stdout() == "" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
535 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
536 data = cov.get_data() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
537 filenames = {relative_filename(f).replace("\\", "/") for f in data.measured_files()} 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
538 return filenames 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
540 # Case 1: get the order right.
541 make_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
542 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
543 ".coveragerc",
544 """\
545 [paths]
546 plugins =
547 plugins/
548 ci/girder/plugins/
549 girder =
550 girder/
551 ci/girder/
552 """,
553 )
554 assert get_combined_filenames() == {"girder/g1.py", "plugins/p1.py"} 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
556 # Case 2: get the order "wrong".
557 make_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
558 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
559 ".coveragerc",
560 """\
561 [paths]
562 girder =
563 girder/
564 ci/girder/
565 plugins =
566 plugins/
567 ci/girder/plugins/
568 """,
569 )
570 assert get_combined_filenames() == {"girder/g1.py", "plugins/p1.py"} 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
572 def test_warnings(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
573 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
574 "hello.py",
575 """\
576 import sys, os
577 print("Hello")
578 """,
579 )
580 with pytest.warns(Warning) as warns: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
581 cov = coverage.Coverage(source=["sys", "xyzzy", "quux"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
582 self.start_import_stop(cov, "hello") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
583 cov.get_data() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
585 assert "Hello\n" == self.stdout() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
586 assert_coverage_warnings( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
587 warns,
588 "Module sys has no Python source. (module-not-python)",
589 "Module xyzzy was never imported. (module-not-imported)",
590 "Module quux was never imported. (module-not-imported)",
591 "No data was collected. (no-data-collected)",
592 )
594 def test_warnings_suppressed(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
595 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
596 "hello.py",
597 """\
598 import sys, os
599 print("Hello")
600 """,
601 )
602 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
603 ".coveragerc",
604 """\
605 [run]
606 disable_warnings = no-data-collected, module-not-imported
607 """,
608 )
609 with pytest.warns(Warning) as warns: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
610 cov = coverage.Coverage(source=["sys", "xyzzy", "quux"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
611 self.start_import_stop(cov, "hello") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
612 cov.get_data() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
614 assert "Hello\n" == self.stdout() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
615 assert_coverage_warnings(warns, "Module sys has no Python source. (module-not-python)") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
616 # No "module-not-imported" in warns
617 # No "no-data-collected" in warns
619 def test_warn_once(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
620 with pytest.warns(Warning) as warns: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
621 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
622 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
623 cov._warn("Warning, warning 1!", slug="bot", once=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
624 cov._warn("Warning, warning 2!", slug="bot", once=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
626 assert_coverage_warnings(warns, "Warning, warning 1! (bot)") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
627 # No "Warning, warning 2!" in warns
628 assert len(get_coverage_warnings(warns)) == 1 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
630 def test_warnings_with_urls(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
631 with pytest.warns(Warning) as warns: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
632 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
633 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
634 cov._warn("Warning Will Robinson", slug="will-rob") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
635 cov._warn("Warning, warning 2!", slug="second-one") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
636 warnings = get_coverage_warnings(warns) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
638 def url(slug: str) -> str: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
639 return ( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
640 f"https://coverage.readthedocs.io/en/{coverage.__version__}"
641 + f"/messages.html#warning-{slug}"
642 )
644 assert warnings == [ 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
645 f"Warning Will Robinson (will-rob); see {url('will-rob')}",
646 f"Warning, warning 2! (second-one); see {url('second-one')}",
647 ]
649 def test_source_and_include_dont_conflict(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
650 # A bad fix made this case fail: https://github.com/coveragepy/coveragepy/issues/541
651 self.make_file("a.py", "import b\na = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
652 self.make_file("b.py", "b = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
653 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
654 ".coveragerc",
655 """\
656 [run]
657 source = .
658 """,
659 )
661 # Just like: coverage run a.py
662 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
663 self.start_import_stop(cov, "a") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
664 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
666 # Run the equivalent of: coverage report --include=b.py
667 cov = coverage.Coverage(include=["b.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
668 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
669 # There should be no exception. At one point, report() threw:
670 # CoverageException: --include and --source are mutually exclusive
671 cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
672 expected = textwrap.dedent("""\ 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
673 Name Stmts Miss Cover
674 ---------------------------
675 b.py 1 0 100%
676 ---------------------------
677 TOTAL 1 0 100%
678 """)
679 assert expected == self.stdout() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
681 def test_config_crash(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
682 # The internal '[run] _crash' setting can be used to artificially raise
683 # exceptions from inside Coverage.
684 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
685 cov.set_option("run:_crash", "test_config_crash") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
686 with pytest.raises(Exception, match="Crashing because called by test_config_crash"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
687 cov.start() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
689 def test_config_crash_no_crash(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
690 # '[run] _crash' really checks the call stack.
691 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
692 cov.set_option("run:_crash", "not_my_caller") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
693 cov.start() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
694 cov.stop() 1abcdefghijklmnopqrstuvwxyzABCD
696 def test_run_debug_sys(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
697 # https://github.com/coveragepy/coveragepy/issues/907
698 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
699 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
700 d = dict(cov.sys_info()) 1abcdefghijklmnopqrstuvwxyzABCD
701 assert cast(str, d["data_file"]).endswith(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
704@pytest.mark.skipif(not testenv.DYN_CONTEXTS, reason="No dynamic contexts with this core.") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
705class SwitchContextTest(CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
706 """Tests of the .switch_context() method."""
708 def make_test_files(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
709 """Create a simple file representing a method with two tests."""
710 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
711 "testsuite.py",
712 """\
713 def timestwo(x):
714 return x*2
716 def test_multiply_zero():
717 assert timestwo(0) == 0
719 def test_multiply_six():
720 assert timestwo(6) == 12
721 """,
722 )
724 def test_switch_context_testrunner(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
725 # This test simulates a coverage-aware test runner,
726 # measuring labeled coverage via public API
727 self.make_test_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
729 # Test runner starts
730 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
731 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
732 # Imports the test suite
733 suite = import_local_file("testsuite") 1abcdefghijklmnopqrstuvwxyzABCD
735 # Measures test case 1
736 cov.switch_context("multiply_zero") 1abcdefghijklmnopqrstuvwxyzABCD
737 suite.test_multiply_zero() 1abcdefghijklmnopqrstuvwxyzABCD
739 # Measures test case 2
740 cov.switch_context("multiply_six") 1abcdefghijklmnopqrstuvwxyzABCD
741 suite.test_multiply_six() 1abcdefghijklmnopqrstuvwxyzABCD
743 # Runner finishes
744 cov.save() 1abcdefghijklmnopqrstuvwxyzABCD
746 # Labeled data is collected
747 data = cov.get_data() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
748 assert ["", "multiply_six", "multiply_zero"] == sorted(data.measured_contexts()) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
750 filenames = self.get_measured_filenames(data) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
751 suite_filename = filenames["testsuite.py"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
753 data.set_query_context("multiply_six") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
754 assert [2, 8] == sorted_lines(data, suite_filename) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
755 data.set_query_context("multiply_zero") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
756 assert [2, 5] == sorted_lines(data, suite_filename) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
758 def test_switch_context_with_static(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
759 # This test simulates a coverage-aware test runner,
760 # measuring labeled coverage via public API,
761 # with static label prefix.
762 self.make_test_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
764 # Test runner starts
765 cov = coverage.Coverage(context="mysuite") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
766 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
767 # Imports the test suite
768 suite = import_local_file("testsuite") 1abcdefghijklmnopqrstuvwxyzABCD
770 # Measures test case 1
771 cov.switch_context("multiply_zero") 1abcdefghijklmnopqrstuvwxyzABCD
772 suite.test_multiply_zero() 1abcdefghijklmnopqrstuvwxyzABCD
774 # Measures test case 2
775 cov.switch_context("multiply_six") 1abcdefghijklmnopqrstuvwxyzABCD
776 suite.test_multiply_six() 1abcdefghijklmnopqrstuvwxyzABCD
778 # Runner finishes
779 cov.save() 1abcdefghijklmnopqrstuvwxyzABCD
781 # Labeled data is collected
782 data = cov.get_data() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
783 expected = ["mysuite", "mysuite|multiply_six", "mysuite|multiply_zero"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
784 assert expected == sorted(data.measured_contexts()) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
786 filenames = self.get_measured_filenames(data) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
787 suite_filename = filenames["testsuite.py"] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
789 data.set_query_context("mysuite|multiply_six") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
790 assert [2, 8] == sorted_lines(data, suite_filename) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
791 data.set_query_context("mysuite|multiply_zero") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
792 assert [2, 5] == sorted_lines(data, suite_filename) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
794 def test_dynamic_context_conflict(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
795 cov = coverage.Coverage(source=["."]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
796 cov.set_option("run:dynamic_context", "test_function") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
797 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
798 with pytest.warns(Warning) as warns: 1abcdefghijklmnopqrstuvwxyzABCD
799 # Switch twice, but only get one warning.
800 cov.switch_context("test1") 1abcdefghijklmnopqrstuvwxyzABCD
801 cov.switch_context("test2") 1abcdefghijklmnopqrstuvwxyzABCD
802 assert_coverage_warnings(warns, "Conflicting dynamic contexts (dynamic-conflict)") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
804 def test_unknown_dynamic_context(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
805 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
806 cov.set_option("run:dynamic_context", "no-idea") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
807 with pytest.raises(Exception, match="Don't understand dynamic_context setting: 'no-idea'"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
808 cov.start() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
810 def test_switch_context_unstarted(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
811 # Coverage must be started to switch context
812 msg = "Cannot switch context, coverage is not started" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
813 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
814 with pytest.raises(CoverageException, match=msg): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
815 cov.switch_context("test1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
817 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
818 cov.switch_context("test2") 1abcdefghijklmnopqrstuvwxyzABCD
820 with pytest.raises(CoverageException, match=msg): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
821 cov.switch_context("test3") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
824class CurrentInstanceTest(CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
825 """Tests of Coverage.current()."""
827 run_in_temp_dir = False 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
829 def assert_current_is_none(self, current: Coverage | None) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
830 """Assert that a current we expect to be None is correct."""
831 # During meta-coverage, the None answers will be wrong because the
832 # overall coverage measurement will still be on the current-stack.
833 # Since we know they will be wrong, and we have non-meta test runs
834 # also, don't assert them.
835 if not env.METACOV: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
836 assert current is None
838 def test_current(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
839 cur0 = coverage.Coverage.current() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
840 self.assert_current_is_none(cur0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
841 # Making an instance doesn't make it current.
842 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
843 cur1 = coverage.Coverage.current() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
844 self.assert_current_is_none(cur1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
845 assert cur0 is cur1 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
846 # Starting the instance makes it current.
847 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
848 cur2 = coverage.Coverage.current() 1abcdefghijklmnopqrstuvwxyzABCD
849 assert cur2 is cov 1abcdefghijklmnopqrstuvwxyzABCD
850 # Stopping the instance makes current None again.
852 cur3 = coverage.Coverage.current() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
853 self.assert_current_is_none(cur3) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
854 assert cur0 is cur3 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
857class NamespaceModuleTest(UsingModulesMixin, CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
858 """Test PEP-420 namespace modules."""
860 def test_explicit_namespace_module(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
861 self.make_file("main.py", "import namespace_420\n") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
863 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
864 self.start_import_stop(cov, "main") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
866 with pytest.raises(CoverageException, match=r"Module .* has no file"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
867 cov.analysis(sys.modules["namespace_420"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
869 def test_bug_572(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
870 self.make_file("main.py", "import namespace_420\n") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
872 # Use source=namespace_420 to trigger the check that used to fail,
873 # and use source=main so that something is measured.
874 cov = coverage.Coverage(source=["namespace_420", "main"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
875 with self.assert_warnings(cov, []): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
876 self.start_import_stop(cov, "main") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
877 cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
880class IncludeOmitTestsMixin(UsingModulesMixin, CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
881 """Test methods for coverage methods taking include and omit."""
883 # An abstract method for subclasses to define, to appease mypy.
884 def coverage_usepkgs(self, **kwargs_unused: TCovKwargs) -> Iterable[str]: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
885 """Run coverage on usepkgs, return a line summary. kwargs are for Coverage(**kwargs)."""
886 raise NotImplementedError() # pragma: not covered
888 def filenames_in(self, summary: Iterable[str], filenames: str) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
889 """Assert the `filenames` are in the `summary`."""
890 for filename in filenames.split(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
891 assert filename in summary 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
893 def filenames_not_in(self, summary: Iterable[str], filenames: str) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
894 """Assert the `filenames` are not in the `summary`."""
895 for filename in filenames.split(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
896 assert filename not in summary 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
898 def test_nothing_specified(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
899 result = self.coverage_usepkgs() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
900 self.filenames_in(result, "p1a p1b p2a p2b othera otherb osa osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
901 self.filenames_not_in(result, "p1c") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
902 # Because there was no source= specified, we don't search for
903 # un-executed files.
905 def test_include(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
906 result = self.coverage_usepkgs(include=["*/p1a.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
907 self.filenames_in(result, "p1a") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
908 self.filenames_not_in(result, "p1b p1c p2a p2b othera otherb osa osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
910 def test_include_2(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
911 result = self.coverage_usepkgs(include=["*a.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
912 self.filenames_in(result, "p1a p2a othera osa") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
913 self.filenames_not_in(result, "p1b p1c p2b otherb osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
915 def test_include_as_string(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
916 result = self.coverage_usepkgs(include="*a.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
917 self.filenames_in(result, "p1a p2a othera osa") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
918 self.filenames_not_in(result, "p1b p1c p2b otherb osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
920 def test_omit(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
921 result = self.coverage_usepkgs(omit=["*/p1a.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
922 self.filenames_in(result, "p1b p2a p2b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
923 self.filenames_not_in(result, "p1a p1c") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
925 def test_omit_2(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
926 result = self.coverage_usepkgs(omit=["*a.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
927 self.filenames_in(result, "p1b p2b otherb osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
928 self.filenames_not_in(result, "p1a p1c p2a othera osa") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
930 def test_omit_as_string(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
931 result = self.coverage_usepkgs(omit="*a.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
932 self.filenames_in(result, "p1b p2b otherb osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
933 self.filenames_not_in(result, "p1a p1c p2a othera osa") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
935 def test_omit_and_include(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
936 result = self.coverage_usepkgs(include=["*/p1*"], omit=["*/p1a.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
937 self.filenames_in(result, "p1b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
938 self.filenames_not_in(result, "p1a p1c p2a p2b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
941class SourceIncludeOmitTest(IncludeOmitTestsMixin, CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
942 """Test using `source`, `include`, and `omit` when measuring code."""
944 def setUp(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
945 super().setUp() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
947 # These tests use the TESTS_DIR/modules files, but they cd into it. To
948 # keep tests from cross-contaminating, we make a copy of the files.
949 # Since we need to import from there, we also add it to the beginning
950 # of sys.path.
952 shutil.copytree( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
953 nice_file(TESTS_DIR, "modules"),
954 "tests_dir_modules",
955 ignore=shutil.ignore_patterns("__pycache__"),
956 )
957 sys.path.insert(0, abs_file("tests_dir_modules")) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
959 def coverage_usepkgs_counts(self, **kwargs: TCovKwargs) -> dict[str, int]: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
960 """Run coverage on usepkgs and return a line summary.
962 Arguments are passed to the `coverage.Coverage` constructor.
964 """
965 cov = coverage.Coverage(**kwargs) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
966 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
967 import usepkgs # pylint: disable=import-error, unused-import 1abcdefghijklmnopqrstuvwxyzABCD
968 with self.assert_warnings(cov, []): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
969 data = cov.get_data() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
970 summary = line_counts(data) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
971 for k, v in list(summary.items()): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
972 assert k.endswith(".py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
973 summary[k[:-3]] = v 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
974 return summary 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
976 def coverage_usepkgs(self, **kwargs: TCovKwargs) -> Iterable[str]: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
977 summary = self.coverage_usepkgs_counts(**kwargs) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
978 return list(summary) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
980 def test_source_include_exclusive(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
981 cov = coverage.Coverage(source=["pkg1"], include=["pkg2"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
982 with self.assert_warnings(cov, ["--include is ignored because --source is set"]): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
983 cov.start() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
984 cov.stop() 1abcdefghijklmnopqrstuvwxyzABCD
986 def test_source_package_as_package(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
987 assert not os.path.isdir("pkg1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
988 lines = self.coverage_usepkgs_counts(source=["pkg1"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
989 self.filenames_in(list(lines), "p1a p1b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
990 self.filenames_not_in(list(lines), "p2a p2b othera otherb osa osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
991 # Because source= was specified, we do search for un-executed files.
992 assert lines["p1c"] == 0 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
994 def test_source_package_as_dir(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
995 os.chdir("tests_dir_modules") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
996 assert os.path.isdir("pkg1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
997 lines = self.coverage_usepkgs_counts(source=["pkg1"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
998 self.filenames_in(list(lines), "p1a p1b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRnoSpTqUrVsWt1uXvYwxZy0zABCD
999 self.filenames_not_in(list(lines), "p2a p2b othera otherb osa osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRnoSpTqUrVsWt1uXvYwxZy0zABCD
1000 # Because source= was specified, we do search for un-executed files.
1001 assert lines["p1c"] == 0 1EaFbGcHdIeJfKgLhMiNjOkPlQmRnoSpTqUrVsWt1uXvYwxZy0zABCD
1003 def test_source_package_dotted_sub(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1004 lines = self.coverage_usepkgs_counts(source=["pkg1.sub"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1005 self.filenames_not_in(list(lines), "p2a p2b othera otherb osa osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWtuXvYw3xZy0z4ABCD
1006 # Because source= was specified, we do search for un-executed files.
1007 assert lines["runmod3"] == 0 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWtuXvYw3xZy0z4ABCD
1009 def test_source_package_dotted_p1b(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1010 lines = self.coverage_usepkgs_counts(source=["pkg1.p1b"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1011 self.filenames_in(list(lines), "p1b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1012 self.filenames_not_in(list(lines), "p1a p1c p2a p2b othera otherb osa osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1014 def test_source_package_part_omitted(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1015 # https://github.com/coveragepy/coveragepy/issues/218
1016 # Used to be if you omitted something executed and inside the source,
1017 # then after it was executed but not recorded, it would be found in
1018 # the search for un-executed files, and given a score of 0%.
1020 # The omit arg is by path, so need to be in the modules directory.
1021 os.chdir("tests_dir_modules") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1022 lines = self.coverage_usepkgs_counts(source=["pkg1"], omit=["pkg1/p1b.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1023 self.filenames_in(list(lines), "p1a") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1024 self.filenames_not_in(list(lines), "p1b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1025 assert lines["p1c"] == 0 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1027 def test_source_package_as_package_part_omitted(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1028 # https://github.com/coveragepy/coveragepy/issues/638
1029 lines = self.coverage_usepkgs_counts(source=["pkg1"], omit=["*/p1b.py"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1030 self.filenames_in(list(lines), "p1a") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1031 self.filenames_not_in(list(lines), "p1b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1032 assert lines["p1c"] == 0 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1034 def test_ambiguous_source_package_as_dir(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1035 # pkg1 is a directory and a pkg, since we cd into tests_dir_modules/ambiguous
1036 os.chdir("tests_dir_modules/ambiguous") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1037 # pkg1 defaults to directory because tests_dir_modules/ambiguous/pkg1 exists
1038 lines = self.coverage_usepkgs_counts(source=["pkg1"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1039 self.filenames_in(list(lines), "ambiguous") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1040 self.filenames_not_in(list(lines), "p1a p1b p1c") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1042 def test_ambiguous_source_package_as_package(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1043 # pkg1 is a directory and a pkg, since we cd into tests_dir_modules/ambiguous
1044 os.chdir("tests_dir_modules/ambiguous") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1045 lines = self.coverage_usepkgs_counts(source_pkgs=["pkg1"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1046 self.filenames_in(list(lines), "p1a p1b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1047 self.filenames_not_in(list(lines), "p2a p2b othera otherb osa osb ambiguous") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1048 # Because source= was specified, we do search for un-executed files.
1049 assert lines["p1c"] == 0 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1051 def test_source_dirs(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1052 os.chdir("tests_dir_modules") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1053 assert os.path.isdir("pkg1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1054 lines = self.coverage_usepkgs_counts(source_dirs=["pkg1"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1055 self.filenames_in(list(lines), "p1a p1b") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1056 self.filenames_not_in(list(lines), "p2a p2b othera otherb osa osb") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1057 # Because source_dirs= was specified, we do search for un-executed files.
1058 assert lines["p1c"] == 0 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1060 def test_non_existent_source_dir(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1061 with pytest.raises( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1062 ConfigError,
1063 match=re.escape("Source dir is not a directory: 'i-do-not-exist'"),
1064 ):
1065 self.coverage_usepkgs_counts(source_dirs=["i-do-not-exist"]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1068class ReportIncludeOmitTest(IncludeOmitTestsMixin, CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1069 """Tests of the report include/omit functionality."""
1071 def coverage_usepkgs(self, **kwargs: TCovKwargs) -> Iterable[str]: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1072 """Try coverage.report()."""
1073 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1074 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1075 import usepkgs # pylint: disable=import-error, unused-import 1abcdefghijklmnopqrstuvwxyzABCD
1076 report = io.StringIO() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1077 cov.report(file=report, **kwargs) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1078 return report.getvalue() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1081class XmlIncludeOmitTest(IncludeOmitTestsMixin, CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1082 """Tests of the XML include/omit functionality.
1084 This also takes care of the HTML and annotate include/omit, by virtue
1085 of the structure of the code.
1087 """
1089 def coverage_usepkgs(self, **kwargs: TCovKwargs) -> Iterable[str]: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1090 """Try coverage.xml_report()."""
1091 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1092 with cov.collect(): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1093 import usepkgs # pylint: disable=import-error, unused-import 1abcdefghijklmnopqrstuvwxyzABCD
1094 cov.xml_report(outfile="-", **kwargs) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1095 return self.stdout() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1098class AnalysisTest(CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1099 """Test the numerical analysis of results."""
1101 def test_many_missing_branches(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1102 cov = coverage.Coverage(branch=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1104 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1105 "missing.py",
1106 """\
1107 def fun1(x):
1108 if x == 1:
1109 print("one")
1110 else:
1111 print("not one")
1112 print("done") # pragma: nocover
1114 def fun2(x):
1115 if x:
1116 print("x")
1117 else:
1118 print("not x")
1120 fun2(3)
1121 """,
1122 )
1124 # Import the Python file, executing it.
1125 self.start_import_stop(cov, "missing") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1127 nums = cov._analyze("missing.py").numbers 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1128 assert nums.n_files == 1 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1129 assert nums.n_statements == 9 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1130 assert nums.n_excluded == 1 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1131 assert nums.n_missing == 4 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1132 assert nums.n_branches == 4 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1133 assert nums.n_partial_branches == 1 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1134 assert nums.n_missing_branches == 3 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1136 filename, statements, excluded, missing, missing_formatted = cov.analysis2("missing.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1137 assert os.path.relpath(filename) == "missing.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1138 assert statements == [1, 2, 3, 5, 8, 9, 10, 12, 14] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1139 assert excluded == [6] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1140 assert missing == [2, 3, 5, 12] 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1141 assert missing_formatted == "2-5, 12" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1143 branch_stats = cov.branch_stats("missing.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1144 assert branch_stats == {2: (2, 0), 9: (2, 1)} 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1147class TestRunnerPluginTest(CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1148 """Test that the API works properly the way various third-party plugins call it.
1150 We don't actually use the plugins, but these tests call the API the same
1151 way they do.
1153 """
1155 def pretend_to_be_nose_with_cover(self, erase: bool = False, cd: bool = False) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1156 """This is what the nose --with-cover plugin does."""
1157 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1158 "no_biggie.py",
1159 """\
1160 a = 1
1161 b = 2
1162 if b == 1:
1163 c = 4
1164 """,
1165 )
1166 self.make_file("sub/hold.txt", "") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1168 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1169 if erase: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1170 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTq5Ur6VsWt71u8XvYw3x9Zy0z!4A#BCD
1171 cov.erase() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTq5Ur6VsWt71u8XvYw3x9Zy0z!4A#BCD
1172 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1173 self.start_import_stop(cov, "no_biggie") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1174 if cd: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1175 os.chdir("sub") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1176 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1177 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1178 cov.report(["no_biggie.py"], show_missing=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1179 assert self.stdout() == textwrap.dedent("""\ 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1180 Name Stmts Miss Cover Missing
1181 --------------------------------------------
1182 no_biggie.py 4 1 75% 4
1183 --------------------------------------------
1184 TOTAL 4 1 75%
1185 """)
1186 if cd: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1187 os.chdir("..") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1189 def test_nose_plugin(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1190 self.pretend_to_be_nose_with_cover() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1192 def test_nose_plugin_with_erase(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1193 self.pretend_to_be_nose_with_cover(erase=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1195 def test_nose_plugin_with_cd(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1196 # https://github.com/coveragepy/coveragepy/issues/916
1197 self.pretend_to_be_nose_with_cover(cd=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1199 def pretend_to_be_pytestcov(self, append: bool) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1200 """Act like pytest-cov."""
1201 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1202 "prog.py",
1203 """\
1204 a = 1
1205 b = 2
1206 if b == 1:
1207 c = 4
1208 """,
1209 )
1210 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1211 ".coveragerc",
1212 """\
1213 [run]
1214 parallel = True
1215 source = .
1216 """,
1217 )
1219 cov = coverage.Coverage(source=None, branch=None, config_file=".coveragerc") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1220 if append: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1221 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTq5Ur6VsWt71u8XvYw$3x9Zy0z!4A#BCD
1222 else:
1223 cov.erase() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1224 self.start_import_stop(cov, "prog") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1225 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1226 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1227 report = io.StringIO() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1228 cov.report( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1229 show_missing=None, ignore_errors=True, file=report, skip_covered=None, skip_empty=None
1230 )
1231 assert report.getvalue() == textwrap.dedent("""\ 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1232 Name Stmts Miss Cover
1233 -----------------------------
1234 prog.py 4 1 75%
1235 -----------------------------
1236 TOTAL 4 1 75%
1237 """)
1238 self.assert_file_count(".coverage", 0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1239 self.assert_file_count(".coverage.*", 1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1241 def test_pytestcov_parallel(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1242 self.pretend_to_be_pytestcov(append=False) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1244 def test_pytestcov_parallel_append(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1245 self.pretend_to_be_pytestcov(append=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1248class ImmutableConfigTest(CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1249 """Check that reporting methods don't permanently change the configuration."""
1251 def test_config_doesnt_change(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1252 self.make_file("simple.py", "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1253 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1254 self.start_import_stop(cov, "simple") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1255 assert cov.get_option("report:show_missing") is False 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1256 cov.report(show_missing=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1257 assert cov.get_option("report:show_missing") is False 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1260class RelativePathTest(CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1261 """Tests of the relative_files setting."""
1263 def test_moving_stuff(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1264 # When using absolute file names, moving the source around results in
1265 # "No source for code" errors while reporting.
1266 self.make_file("foo.py", "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1267 cov = coverage.Coverage(source=["."]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1268 self.start_import_stop(cov, "foo") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1269 res = cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1270 assert res == 100 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1272 expected = re.escape("No source for code: '{}'.".format(abs_file("foo.py"))) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1273 os.remove("foo.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1274 self.make_file("new/foo.py", "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1275 shutil.move(".coverage", "new/.coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1276 with change_dir("new"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1277 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1278 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1279 with pytest.raises(NoSource, match=expected): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1280 cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1282 def test_moving_stuff_with_relative(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1283 # When using relative file names, moving the source around is fine.
1284 self.make_file("foo.py", "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1285 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1286 ".coveragerc",
1287 """\
1288 [run]
1289 relative_files = true
1290 """,
1291 )
1292 cov = coverage.Coverage(source=["."]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1293 self.start_import_stop(cov, "foo") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1294 res = cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1295 assert res == 100 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1297 os.remove("foo.py") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1298 self.make_file("new/foo.py", "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1299 shutil.move(".coverage", "new/.coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1300 shutil.move(".coveragerc", "new/.coveragerc") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1301 with change_dir("new"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1302 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1303 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1304 res = cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1305 assert res == 100 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1307 def test_combine_relative(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1308 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1309 "foo.py",
1310 """\
1311 import mod
1312 a = 1
1313 """,
1314 )
1315 self.make_file("lib/mod/__init__.py", "x = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1316 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1317 ".coveragerc",
1318 """\
1319 [run]
1320 relative_files = true
1321 """,
1322 )
1323 sys.path.append("lib") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1324 cov = coverage.Coverage(source=["."], data_suffix=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1325 self.start_import_stop(cov, "foo") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1326 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1328 self.make_file("dir2/bar.py", "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1329 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1330 "dir2/.coveragerc",
1331 """\
1332 [run]
1333 relative_files = true
1334 """,
1335 )
1336 with change_dir("dir2"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1337 cov = coverage.Coverage(source=["."], data_suffix=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1338 self.start_import_stop(cov, "bar") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1339 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1340 shutil.move(glob.glob(".coverage.*")[0], "..") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1342 self.make_file("foo.py", "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1343 self.make_file("bar.py", "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1344 self.make_file("modsrc/__init__.py", "x = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1346 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1347 ".coveragerc",
1348 """\
1349 [run]
1350 relative_files = true
1351 [paths]
1352 source =
1353 modsrc
1354 */mod
1355 """,
1356 )
1357 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1358 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1359 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1361 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1362 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1363 files = cov.get_data().measured_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1364 assert files == {"foo.py", "bar.py", os_sep("modsrc/__init__.py")} 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1365 res = cov.report() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1366 assert res == 100 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1368 def test_combine_no_suffix_multiprocessing(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1369 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1370 ".coveragerc",
1371 """\
1372 [run]
1373 branch = True
1374 """,
1375 )
1376 cov = coverage.Coverage( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1377 config_file=".coveragerc",
1378 concurrency="multiprocessing",
1379 data_suffix=False,
1380 )
1381 cov.start() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1382 cov.stop() 1abcdefghijklmnopqrstuvwxyzABCD
1383 # The warning isn't the point of this test, but suppress it.
1384 with pytest.warns(Warning) as warns: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1385 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1386 assert_coverage_warnings(warns, "No data was collected. (no-data-collected)") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1387 cov.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1388 self.assert_file_count(".coverage.*", 0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1389 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1391 def test_files_up_one_level(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1392 # https://github.com/coveragepy/coveragepy/issues/1280
1393 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1394 "src/mycode.py",
1395 """\
1396 def foo():
1397 return 17
1398 """,
1399 )
1400 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1401 "test/test_it.py",
1402 """\
1403 from src.mycode import foo
1404 assert foo() == 17
1405 """,
1406 )
1407 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1408 "test/.coveragerc",
1409 """\
1410 [run]
1411 parallel = True
1412 relative_files = True
1414 [paths]
1415 source =
1416 ../src/
1417 */src
1418 """,
1419 )
1420 os.chdir("test") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1421 sys.path.insert(0, "..") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1422 cov1 = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1423 self.start_import_stop(cov1, "test_it") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1424 cov1.save() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1425 cov2 = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1426 cov2.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1427 cov3 = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1428 cov3.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1429 report = self.get_report(cov3) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1430 assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSpTqUrVsWt1uXvYw3xZy0z4ABCD
1433class CombiningTest(CoverageTest): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1434 """More tests of combining data."""
1436 B_LINES = {"b_or_c.py": [1, 2, 3, 4, 8, 9]} 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1437 C_LINES = {"b_or_c.py": [1, 2, 3, 6, 7, 8, 9]} 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1439 def make_b_or_c_py(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1440 """Create b_or_c.py, used in a few of these tests."""
1441 # "b_or_c.py b" will run 6 lines.
1442 # "b_or_c.py c" will run 7 lines.
1443 # Together, they run 8 lines.
1444 self.make_file( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1445 "b_or_c.py",
1446 """\
1447 import sys
1448 a = 2
1449 if sys.argv[1] == 'b':
1450 b = 4
1451 else:
1452 c = 6
1453 c2 = 7
1454 d = 8
1455 print('done')
1456 """,
1457 )
1459 def test_combine_parallel_data(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1460 self.make_b_or_c_py() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1461 self.make_data_file(".coverage.b", lines=self.B_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1462 self.make_data_file(".coverage.c", lines=self.C_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1464 # Combine the parallel coverage data files into .coverage .
1465 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1466 cov.combine(strict=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1467 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1469 # After combining, there should be only the .coverage file.
1470 self.assert_file_count(".coverage.*", 0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1472 # Read the coverage file and see that b_or_c.py has all 8 lines
1473 # executed.
1474 data = coverage.CoverageData() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1475 data.read() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1476 assert line_counts(data)["b_or_c.py"] == 8 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1478 # Running combine again should fail, because there are no parallel data
1479 # files to combine.
1480 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1481 with pytest.raises(NoDataError, match=r"No data to combine"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1482 cov.combine(strict=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1484 # And the originally combined data is still there.
1485 data = coverage.CoverageData() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1486 data.read() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1487 assert line_counts(data)["b_or_c.py"] == 8 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1489 def test_combine_parallel_data_with_a_corrupt_file(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1490 self.make_b_or_c_py() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1491 self.make_data_file(".coverage.b", lines=self.B_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1492 self.make_data_file(".coverage.c", lines=self.C_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1494 # Make a bogus data file.
1495 self.make_file(".coverage.bad", "This isn't a coverage data file.") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1497 # Combine the parallel coverage data files into .coverage .
1498 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1499 with pytest.warns(Warning) as warns: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1500 cov.combine(strict=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1501 assert_coverage_warnings( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1502 warns,
1503 re.compile(
1504 r"Couldn't use data file '.*[/\\]\.coverage\.bad': " + BAD_SQLITE_REGEX,
1505 ),
1506 )
1508 # After combining, those two should be the only data files.
1509 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1510 self.assert_exists(".coverage.bad") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1511 self.assert_file_count(".coverage.*", 1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1513 # Read the coverage file and see that b_or_c.py has all 8 lines
1514 # executed.
1515 data = coverage.CoverageData() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1516 data.read() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1517 assert line_counts(data)["b_or_c.py"] == 8 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1519 def test_combine_no_usable_files(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1520 # https://github.com/coveragepy/coveragepy/issues/629
1521 self.make_b_or_c_py() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1522 self.make_data_file(".coverage", lines=self.B_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1524 # Make bogus data files.
1525 self.make_file(".coverage.bad1", "This isn't a coverage data file.") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1526 self.make_file(".coverage.bad2", "This isn't a coverage data file either.") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1528 # Combine the parallel coverage data files into .coverage, but nothing is readable.
1529 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1530 with pytest.warns(Warning) as warns: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1531 with pytest.raises(NoDataError, match=r"No usable data files"): 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1532 cov.combine(strict=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1534 warn_rx = re.compile( 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1535 r"Couldn't use data file '.*[/\\]\.coverage\.bad[12]': " + BAD_SQLITE_REGEX,
1536 )
1537 assert_coverage_warnings(warns, warn_rx, warn_rx) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1539 # After combining, we should have a main file and two parallel files.
1540 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1541 self.assert_exists(".coverage.bad1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1542 self.assert_exists(".coverage.bad2") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1543 self.assert_file_count(".coverage.*", 2) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1545 # Read the coverage file and see that b_or_c.py has 6 lines
1546 # executed (we only did b, not c).
1547 data = coverage.CoverageData() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1548 data.read() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1549 assert line_counts(data)["b_or_c.py"] == 6 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1551 def test_combine_parallel_data_in_two_steps(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1552 self.make_b_or_c_py() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1553 self.make_data_file(".coverage.b", lines=self.B_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1555 # Combine the (one) parallel coverage data file into .coverage .
1556 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1557 cov.combine(strict=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1559 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1560 self.assert_file_count(".coverage.*", 0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1562 self.make_data_file(".coverage.c", lines=self.C_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1563 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1564 self.assert_file_count(".coverage.*", 1) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1566 # Combine the parallel coverage data files into .coverage .
1567 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1568 cov.load() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1569 cov.combine(strict=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1571 # After combining, there should be only the .coverage file.
1572 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1573 self.assert_file_count(".coverage.*", 0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1575 # Read the coverage file and see that b_or_c.py has all 8 lines
1576 # executed.
1577 data = coverage.CoverageData() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1578 data.read() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1579 assert line_counts(data)["b_or_c.py"] == 8 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1581 def test_combine_parallel_data_no_append(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1582 self.make_b_or_c_py() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1583 self.make_data_file(".coverage.b", lines=self.B_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1585 # Combine the (one) parallel coverage data file into .coverage .
1586 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1587 cov.combine(strict=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1588 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1589 self.assert_file_count(".coverage.*", 0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1591 self.make_data_file(".coverage.c", lines=self.C_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1593 # Combine the parallel coverage data files into .coverage, but don't
1594 # use the data in .coverage already.
1595 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1596 cov.combine(strict=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1598 # After combining, there should be only the .coverage file.
1599 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1600 self.assert_file_count(".coverage.*", 0) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1602 # Read the coverage file and see that b_or_c.py has only 7 lines
1603 # because we didn't keep the data from running b.
1604 data = coverage.CoverageData() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1605 data.read() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1606 assert line_counts(data)["b_or_c.py"] == 7 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1608 def test_combine_parallel_data_keep(self) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1609 self.make_b_or_c_py() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1610 self.make_data_file(".coverage.b", lines=self.B_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1611 self.make_data_file(".coverage.c", lines=self.C_LINES) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1613 # Combine the parallel coverage data files into .coverage with the keep flag.
1614 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1615 cov.combine(strict=True, keep=True) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1617 # After combining, the .coverage file & the original combined file should still be there.
1618 self.assert_exists(".coverage") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1619 self.assert_file_count(".coverage.*", 2) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1621 @pytest.mark.parametrize("abs_order, rel_order", [(1, 2), (2, 1)]) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1622 def test_combine_absolute_then_relative_1752(self, abs_order: int, rel_order: int) -> None: 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1623 # https://github.com/coveragepy/coveragepy/issues/1752
1624 # If we're combining a relative data file and an absolute data file,
1625 # the absolutes were made relative only if the relative file name was
1626 # encountered first. Test combining in both orders and check that the
1627 # absolute file name is properly relative in either order.
1628 FILE = "sub/myprog.py" 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1629 self.make_file(FILE, "a = 1") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1631 self.make_data_file(suffix=f"{abs_order}.abs", lines={abs_file(FILE): [1]}) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1632 self.make_data_file(suffix=f"{rel_order}.rel", lines={FILE: [1]}) 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1634 self.make_file(".coveragerc", "[run]\nrelative_files = True\n") 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1635 cov = coverage.Coverage() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1636 cov.combine() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1637 data = coverage.CoverageData() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1638 data.read() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD
1639 assert {os_sep("sub/myprog.py")} == data.measured_files() 1EaFbGcHdIeJfKgLhMiNjOkPlQmRn2oSp%Tq5Ur6Vs'Wt71u8Xv(Yw$3x9Zy)0z!4A#BCD