Coverage for tests / test_cmdline.py: 100.000%
417 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"""Test cmdline.py for coverage.py."""
6from __future__ import annotations 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
8import ast 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
9import os 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
10import pprint 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
11import re 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
12import sys 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
13import textwrap 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
15from unittest import mock 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
16from typing import Any 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
17from collections.abc import Mapping 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
19import pytest 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
21import coverage 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
22import coverage.cmdline 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
23from coverage import env 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
24from coverage.control import DEFAULT_DATAFILE 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
25from coverage.config import CoverageConfig 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
26from coverage.exceptions import _ExceptionDuringRun 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
27from coverage.types import TConfigValueIn, TConfigValueOut 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
28from coverage.version import __url__ 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
30from tests import testenv 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
31from tests.coveragetest import CoverageTest, OK, ERR, command_line 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
32from tests.helpers import os_sep, re_line, re_lines 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
35class BaseCmdLineTest(CoverageTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
36 """Tests of execution paths through the command line interpreter."""
38 run_in_temp_dir = False 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
40 # Make a dict mapping function names to the default values that cmdline.py
41 # uses when calling the function.
42 _defaults = mock.Mock() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
43 _defaults.Coverage().annotate( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
44 directory=None,
45 ignore_errors=None,
46 include=None,
47 omit=None,
48 morfs=[],
49 contexts=None,
50 )
51 _defaults.Coverage().html_report( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
52 directory=None,
53 ignore_errors=None,
54 include=None,
55 omit=None,
56 morfs=[],
57 skip_covered=None,
58 show_contexts=None,
59 title=None,
60 contexts=None,
61 skip_empty=None,
62 precision=None,
63 )
64 _defaults.Coverage().report( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
65 ignore_errors=None,
66 include=None,
67 omit=None,
68 morfs=[],
69 show_missing=None,
70 skip_covered=None,
71 contexts=None,
72 skip_empty=None,
73 precision=None,
74 sort=None,
75 output_format=None,
76 )
77 _defaults.Coverage().xml_report( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
78 ignore_errors=None,
79 include=None,
80 omit=None,
81 morfs=[],
82 outfile=None,
83 contexts=None,
84 skip_empty=None,
85 )
86 _defaults.Coverage().json_report( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
87 ignore_errors=None,
88 include=None,
89 omit=None,
90 morfs=[],
91 outfile=None,
92 contexts=None,
93 pretty_print=None,
94 show_contexts=None,
95 )
96 _defaults.Coverage().lcov_report( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
97 ignore_errors=None,
98 include=None,
99 omit=None,
100 morfs=[],
101 outfile=None,
102 contexts=None,
103 )
104 _defaults.Coverage( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
105 data_file=DEFAULT_DATAFILE,
106 cover_pylib=None,
107 data_suffix=None,
108 timid=None,
109 branch=None,
110 config_file=True,
111 source=None,
112 include=None,
113 omit=None,
114 debug=None,
115 concurrency=None,
116 check_preimported=True,
117 context=None,
118 messages=True,
119 )
121 DEFAULT_KWARGS = {name: kw for name, _, kw in _defaults.mock_calls} 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
123 def model_object(self) -> mock.Mock: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
124 """Return a Mock suitable for use in CoverageScript."""
125 mk = mock.Mock() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
127 cov = mk.Coverage.return_value 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
129 # The mock needs options.
130 mk.config = CoverageConfig() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
131 cov.get_option = mk.config.get_option 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
132 cov.set_option = mk.config.set_option 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
134 # Get the type right for the result of reporting.
135 cov.report.return_value = 50.0 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
136 cov.html_report.return_value = 50.0 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
137 cov.xml_report.return_value = 50.0 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
138 cov.json_report.return_value = 50.0 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
139 cov.lcov_report.return_value = 50.0 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
141 return mk 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
143 # Global names in cmdline.py that will be mocked during the tests.
144 MOCK_GLOBALS = ["Coverage", "PyRunner", "show_help"] 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
146 def mock_command_line( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv
147 self,
148 args: str,
149 options: Mapping[str, TConfigValueIn] | None = None,
150 ) -> tuple[mock.Mock, int]:
151 """Run `args` through the command line, with a Mock.
153 `options` is a dict of names and values to pass to `set_option`.
155 Returns the Mock it used and the status code returned.
157 """
158 mk = self.model_object() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
160 if options is not None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
161 for name, value in options.items(): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
162 mk.config.set_option(name, value) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
164 patchers = [ 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
165 mock.patch("coverage.cmdline." + name, getattr(mk, name)) for name in self.MOCK_GLOBALS
166 ]
167 for patcher in patchers: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
168 patcher.start() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
169 try: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
170 ret = command_line(args) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
171 finally:
172 for patcher in patchers: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
173 patcher.stop() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
175 return mk, ret 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
177 def cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
178 self,
179 args: str,
180 code: str,
181 ret: int = OK,
182 options: Mapping[str, TConfigValueIn] | None = None,
183 ) -> None:
184 """Assert that the `args` end up executing the sequence in `code`."""
185 called, status = self.mock_command_line(args, options=options) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
186 assert status == ret, f"Wrong status: got {status!r}, wanted {ret!r}" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
188 # Remove all indentation, and execute with mock globals
189 code = textwrap.dedent(code) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
190 expected = self.model_object() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
191 globs = {n: getattr(expected, n) for n in self.MOCK_GLOBALS} 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
192 code_obj = compile(code, "<code>", "exec", dont_inherit=True) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
193 eval(code_obj, globs, {}) # pylint: disable=eval-used 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
195 # Many of our functions take a lot of arguments, and cmdline.py
196 # calls them with many. But most of them are just the defaults, which
197 # we don't want to have to repeat in all tests. For each call, apply
198 # the defaults. This lets the tests just mention the interesting ones.
199 for name, _, kwargs in expected.mock_calls: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
200 for k, v in self.DEFAULT_KWARGS.get(name, {}).items(): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
201 kwargs.setdefault(k, v) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
203 self.assert_same_mock_calls(expected, called) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
205 def cmd_executes_same(self, args1: str, args2: str) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
206 """Assert that the `args1` executes the same as `args2`."""
207 m1, r1 = self.mock_command_line(args1) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
208 m2, r2 = self.mock_command_line(args2) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
209 assert r1 == r2 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
210 self.assert_same_mock_calls(m1, m2) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
212 def assert_same_mock_calls(self, m1: mock.Mock, m2: mock.Mock) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
213 """Assert that `m1.mock_calls` and `m2.mock_calls` are the same."""
214 # Use a real equality comparison, but if it fails, use a nicer assert
215 # so we can tell what's going on. We have to use the real == first due
216 # to CmdOptionParser.__eq__
217 if m1.mock_calls != m2.mock_calls: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
218 pp1 = pprint.pformat(m1.mock_calls) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
219 pp2 = pprint.pformat(m2.mock_calls) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
220 assert pp1 + "\n" == pp2 + "\n" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
222 def cmd_help( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
223 self,
224 args: str,
225 help_msg: str | None = None,
226 topic: str | None = None,
227 ret: int = ERR,
228 ) -> None:
229 """Run a command line, and check that it prints the right help.
231 Only the last function call in the mock is checked, which should be the
232 help message that we want to see.
234 """
235 mk, status = self.mock_command_line(args) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
236 assert status == ret, f"Wrong status: got {status}, wanted {ret}" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
237 if help_msg: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
238 assert mk.mock_calls[-1] == ("show_help", (help_msg,), {}) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
239 else:
240 assert mk.mock_calls[-1] == ("show_help", (), {"topic": topic}) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
243class BaseCmdLineTestTest(BaseCmdLineTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
244 """Tests that our BaseCmdLineTest helpers work."""
246 def test_cmd_executes_same(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
247 # All the other tests here use self.cmd_executes_same in successful
248 # ways, so here we just check that it fails.
249 with pytest.raises(AssertionError): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
250 self.cmd_executes_same("run", "debug") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
253class CmdLineTest(BaseCmdLineTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
254 """Tests of the coverage.py command line."""
256 def test_annotate(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
257 # coverage annotate [-d DIR] [-i] [--omit DIR,...] [FILE1 FILE2 ...]
258 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
259 "annotate",
260 """\
261 cov = Coverage()
262 cov.load()
263 cov.annotate()
264 """,
265 )
266 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
267 "annotate -d dir1",
268 """\
269 cov = Coverage()
270 cov.load()
271 cov.annotate(directory="dir1")
272 """,
273 )
274 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
275 "annotate -i",
276 """\
277 cov = Coverage()
278 cov.load()
279 cov.annotate(ignore_errors=True)
280 """,
281 )
282 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
283 "annotate --omit fooey",
284 """\
285 cov = Coverage(omit=["fooey"])
286 cov.load()
287 cov.annotate(omit=["fooey"])
288 """,
289 )
290 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
291 "annotate --omit fooey,booey",
292 """\
293 cov = Coverage(omit=["fooey", "booey"])
294 cov.load()
295 cov.annotate(omit=["fooey", "booey"])
296 """,
297 )
298 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
299 "annotate mod1",
300 """\
301 cov = Coverage()
302 cov.load()
303 cov.annotate(morfs=["mod1"])
304 """,
305 )
306 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
307 "annotate mod1 mod2 mod3",
308 """\
309 cov = Coverage()
310 cov.load()
311 cov.annotate(morfs=["mod1", "mod2", "mod3"])
312 """,
313 )
315 def test_combine(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
316 # coverage combine with args
317 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
318 "combine datadir1",
319 """\
320 cov = Coverage()
321 cov.combine(["datadir1"], strict=True, keep=False)
322 cov.save()
323 """,
324 )
325 # coverage combine, appending
326 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
327 "combine --append datadir1",
328 """\
329 cov = Coverage()
330 cov.load()
331 cov.combine(["datadir1"], strict=True, keep=False)
332 cov.save()
333 """,
334 )
335 # coverage combine without args
336 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
337 "combine",
338 """\
339 cov = Coverage()
340 cov.combine(None, strict=True, keep=False)
341 cov.save()
342 """,
343 )
344 # coverage combine quietly
345 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
346 "combine -q",
347 """\
348 cov = Coverage(messages=False)
349 cov.combine(None, strict=True, keep=False)
350 cov.save()
351 """,
352 )
353 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
354 "combine --quiet",
355 """\
356 cov = Coverage(messages=False)
357 cov.combine(None, strict=True, keep=False)
358 cov.save()
359 """,
360 )
361 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
362 "combine --data-file=foo.cov",
363 """\
364 cov = Coverage(data_file="foo.cov")
365 cov.combine(None, strict=True, keep=False)
366 cov.save()
367 """,
368 )
370 def test_combine_doesnt_confuse_options_with_args(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
371 # https://github.com/coveragepy/coveragepy/issues/385
372 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
373 "combine --rcfile cov.ini",
374 """\
375 cov = Coverage(config_file='cov.ini')
376 cov.combine(None, strict=True, keep=False)
377 cov.save()
378 """,
379 )
380 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
381 "combine --rcfile cov.ini data1 data2/more",
382 """\
383 cov = Coverage(config_file='cov.ini')
384 cov.combine(["data1", "data2/more"], strict=True, keep=False)
385 cov.save()
386 """,
387 )
389 @pytest.mark.parametrize( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
390 "cmd, output",
391 [
392 (
393 "debug",
394 "What information would you like: config, data, sys, premain, pybehave, sqlite?",
395 ),
396 ("debug foo", "Don't know what you mean by 'foo'"),
397 ("debug sys config", "Only one topic at a time, please"),
398 ],
399 )
400 def test_debug(self, cmd: str, output: str) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
401 self.cmd_help(cmd, output) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
403 def test_debug_sys(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
404 self.command_line("debug sys") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
405 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
406 assert "version:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
407 assert "data_file:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
409 def test_debug_config(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
410 self.command_line("debug config") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
411 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
412 assert "cover_pylib:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
413 assert "skip_covered:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
414 assert "skip_empty:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
416 def test_debug_pybehave(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
417 self.command_line("debug pybehave") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
418 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
419 assert " CPYTHON:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
420 assert " PYVERSION:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
421 assert " deferred_annotations:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
423 # Some things that shouldn't appear..
424 assert "typing." not in out # import from typing 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
425 assert ": <" not in out # objects without a good repr 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
427 # It should report PYVERSION correctly.
428 pyversion = re_line(r" PYVERSION:", out) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
429 vtuple = ast.literal_eval(pyversion.partition(":")[-1].strip()) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
430 assert vtuple[:5] == sys.version_info 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
432 def test_debug_premain(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
433 self.command_line("debug premain") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
434 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
435 # -- premain ---------------------------------------------------
436 # ... many lines ...
437 # _multicall : /Users/ned/cov/trunk/.tox/py39/site-packages/pluggy/_callers.py:77
438 # pytest_pyfunc_call : /Users/ned/cov/trunk/.tox/py39/site-packages/_pytest/python.py:183
439 # test_debug_premain : /Users/ned/cov/trunk/tests/test_cmdline.py:284
440 # command_line : /Users/ned/cov/trunk/tests/coveragetest.py:309
441 # command_line : /Users/ned/cov/trunk/tests/coveragetest.py:472
442 # command_line : /Users/ned/cov/trunk/coverage/cmdline.py:592
443 # do_debug : /Users/ned/cov/trunk/coverage/cmdline.py:804
444 lines = out.splitlines() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
445 s = re.escape(os.sep) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
446 assert lines[0].startswith("-- premain ----") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
447 assert len(lines) > 25 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
448 assert re.search(rf"{s}site-packages{s}_pytest{s}", out) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
449 assert re.search(rf"{s}site-packages{s}pluggy{s}", out) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
450 assert re.search(rf"(?m)^\s+test_debug_premain : .*{s}tests{s}test_cmdline.py:\d+$", out) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
451 assert re.search(rf"(?m)^\s+command_line : .*{s}coverage{s}cmdline.py:\d+$", out) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
452 assert re.search(rf"(?m)^\s+do_debug : .*{s}coverage{s}cmdline.py:\d+$", out) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
453 assert "do_debug : " in lines[-1] 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
455 def test_debug_sqlite(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
456 self.command_line("debug sqlite") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
457 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
458 assert "sqlite3_sqlite_version:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
459 assert "sqlite3_compile_options:" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
460 assert len(out.splitlines()) > 15 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
461 # Lots of lines of indented SQLite compile-time options.
462 assert len(re_lines(r"^ {20,35}[A-Z]{3}", out)) > 12 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
464 def test_erase(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
465 # coverage erase
466 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
467 "erase",
468 """\
469 cov = Coverage()
470 cov.erase()
471 """,
472 )
473 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
474 "erase --data-file=foo.cov",
475 """\
476 cov = Coverage(data_file="foo.cov")
477 cov.erase()
478 """,
479 )
481 def test_version(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
482 # coverage --version
483 self.cmd_help("--version", topic="version", ret=OK) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
485 def test_help_option(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
486 # coverage -h
487 self.cmd_help("-h", topic="help", ret=OK) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
488 self.cmd_help("--help", topic="help", ret=OK) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
490 def test_help_command(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
491 self.cmd_executes("help", "show_help(topic='help')") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
493 def test_cmd_help(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
494 self.cmd_executes("run --help", "show_help(parser='<CmdOptionParser:run>')") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
495 self.cmd_executes_same("help run", "run --help") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
497 def test_html(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
498 # coverage html -d DIR [-i] [--omit DIR,...] [FILE1 FILE2 ...]
499 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
500 "html",
501 """\
502 cov = Coverage()
503 cov.load()
504 cov.html_report()
505 """,
506 )
507 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
508 "html -d dir1",
509 """\
510 cov = Coverage()
511 cov.load()
512 cov.html_report(directory="dir1")
513 """,
514 )
515 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
516 "html -i",
517 """\
518 cov = Coverage()
519 cov.load()
520 cov.html_report(ignore_errors=True)
521 """,
522 )
523 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
524 "html --omit fooey",
525 """\
526 cov = Coverage(omit=["fooey"])
527 cov.load()
528 cov.html_report(omit=["fooey"])
529 """,
530 )
531 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
532 "html --omit fooey,booey",
533 """\
534 cov = Coverage(omit=["fooey", "booey"])
535 cov.load()
536 cov.html_report(omit=["fooey", "booey"])
537 """,
538 )
539 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
540 "html mod1",
541 """\
542 cov = Coverage()
543 cov.load()
544 cov.html_report(morfs=["mod1"])
545 """,
546 )
547 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
548 "html mod1 mod2 mod3",
549 """\
550 cov = Coverage()
551 cov.load()
552 cov.html_report(morfs=["mod1", "mod2", "mod3"])
553 """,
554 )
555 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
556 "html --precision=3",
557 """\
558 cov = Coverage()
559 cov.load()
560 cov.html_report(precision=3)
561 """,
562 )
563 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
564 "html --title=Hello_there",
565 """\
566 cov = Coverage()
567 cov.load()
568 cov.html_report(title='Hello_there')
569 """,
570 )
571 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
572 "html -q",
573 """\
574 cov = Coverage(messages=False)
575 cov.load()
576 cov.html_report()
577 """,
578 )
579 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
580 "html --quiet",
581 """\
582 cov = Coverage(messages=False)
583 cov.load()
584 cov.html_report()
585 """,
586 )
588 def test_json(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
589 # coverage json [-i] [--omit DIR,...] [FILE1 FILE2 ...]
590 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
591 "json",
592 """\
593 cov = Coverage()
594 cov.load()
595 cov.json_report()
596 """,
597 )
598 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
599 "json --pretty-print",
600 """\
601 cov = Coverage()
602 cov.load()
603 cov.json_report(pretty_print=True)
604 """,
605 )
606 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
607 "json --pretty-print --show-contexts",
608 """\
609 cov = Coverage()
610 cov.load()
611 cov.json_report(pretty_print=True, show_contexts=True)
612 """,
613 )
614 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
615 "json -i",
616 """\
617 cov = Coverage()
618 cov.load()
619 cov.json_report(ignore_errors=True)
620 """,
621 )
622 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
623 "json -o myjson.foo",
624 """\
625 cov = Coverage()
626 cov.load()
627 cov.json_report(outfile="myjson.foo")
628 """,
629 )
630 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
631 "json -o -",
632 """\
633 cov = Coverage()
634 cov.load()
635 cov.json_report(outfile="-")
636 """,
637 )
638 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
639 "json --omit fooey",
640 """\
641 cov = Coverage(omit=["fooey"])
642 cov.load()
643 cov.json_report(omit=["fooey"])
644 """,
645 )
646 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
647 "json --omit fooey,booey",
648 """\
649 cov = Coverage(omit=["fooey", "booey"])
650 cov.load()
651 cov.json_report(omit=["fooey", "booey"])
652 """,
653 )
654 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
655 "json mod1",
656 """\
657 cov = Coverage()
658 cov.load()
659 cov.json_report(morfs=["mod1"])
660 """,
661 )
662 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
663 "json mod1 mod2 mod3",
664 """\
665 cov = Coverage()
666 cov.load()
667 cov.json_report(morfs=["mod1", "mod2", "mod3"])
668 """,
669 )
670 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
671 "json -q",
672 """\
673 cov = Coverage(messages=False)
674 cov.load()
675 cov.json_report()
676 """,
677 )
678 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
679 "json --quiet",
680 """\
681 cov = Coverage(messages=False)
682 cov.load()
683 cov.json_report()
684 """,
685 )
687 def test_lcov(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
688 # coverage lcov [-i] [--omit DIR,...] [FILE1 FILE2 ...]
689 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
690 "lcov",
691 """\
692 cov = Coverage()
693 cov.load()
694 cov.lcov_report()
695 """,
696 )
697 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
698 "lcov -i",
699 """\
700 cov = Coverage()
701 cov.load()
702 cov.lcov_report(ignore_errors=True)
703 """,
704 )
705 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
706 "lcov -o mylcov.foo",
707 """\
708 cov = Coverage()
709 cov.load()
710 cov.lcov_report(outfile="mylcov.foo")
711 """,
712 )
713 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
714 "lcov -o -",
715 """\
716 cov = Coverage()
717 cov.load()
718 cov.lcov_report(outfile="-")
719 """,
720 )
721 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
722 "lcov --omit fooey",
723 """\
724 cov = Coverage(omit=["fooey"])
725 cov.load()
726 cov.lcov_report(omit=["fooey"])
727 """,
728 )
729 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
730 "lcov --omit fooey,booey",
731 """\
732 cov = Coverage(omit=["fooey", "booey"])
733 cov.load()
734 cov.lcov_report(omit=["fooey", "booey"])
735 """,
736 )
737 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
738 "lcov -q",
739 """\
740 cov = Coverage(messages=False)
741 cov.load()
742 cov.lcov_report()
743 """,
744 )
745 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
746 "lcov --quiet",
747 """\
748 cov = Coverage(messages=False)
749 cov.load()
750 cov.lcov_report()
751 """,
752 )
754 def test_report(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
755 # coverage report [-m] [-i] [-o DIR,...] [FILE1 FILE2 ...]
756 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
757 "report",
758 """\
759 cov = Coverage()
760 cov.load()
761 cov.report(show_missing=None)
762 """,
763 )
764 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
765 "report -i",
766 """\
767 cov = Coverage()
768 cov.load()
769 cov.report(ignore_errors=True)
770 """,
771 )
772 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
773 "report -m",
774 """\
775 cov = Coverage()
776 cov.load()
777 cov.report(show_missing=True)
778 """,
779 )
780 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
781 "report --omit fooey",
782 """\
783 cov = Coverage(omit=["fooey"])
784 cov.load()
785 cov.report(omit=["fooey"])
786 """,
787 )
788 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
789 "report --omit fooey,booey",
790 """\
791 cov = Coverage(omit=["fooey", "booey"])
792 cov.load()
793 cov.report(omit=["fooey", "booey"])
794 """,
795 )
796 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
797 "report mod1",
798 """\
799 cov = Coverage()
800 cov.load()
801 cov.report(morfs=["mod1"])
802 """,
803 )
804 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
805 "report mod1 mod2 mod3",
806 """\
807 cov = Coverage()
808 cov.load()
809 cov.report(morfs=["mod1", "mod2", "mod3"])
810 """,
811 )
812 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
813 "report --precision=7",
814 """\
815 cov = Coverage()
816 cov.load()
817 cov.report(precision=7)
818 """,
819 )
820 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
821 "report --skip-covered",
822 """\
823 cov = Coverage()
824 cov.load()
825 cov.report(skip_covered=True)
826 """,
827 )
828 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
829 "report --skip-covered --no-skip-covered",
830 """\
831 cov = Coverage()
832 cov.load()
833 cov.report(skip_covered=False)
834 """,
835 )
836 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
837 "report --no-skip-covered",
838 """\
839 cov = Coverage()
840 cov.load()
841 cov.report(skip_covered=False)
842 """,
843 )
844 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
845 "report --skip-empty",
846 """\
847 cov = Coverage()
848 cov.load()
849 cov.report(skip_empty=True)
850 """,
851 )
852 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
853 "report --contexts=foo,bar",
854 """\
855 cov = Coverage()
856 cov.load()
857 cov.report(contexts=["foo", "bar"])
858 """,
859 )
860 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
861 "report --sort=-foo",
862 """\
863 cov = Coverage()
864 cov.load()
865 cov.report(sort='-foo')
866 """,
867 )
868 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
869 "report --data-file=foo.cov.2",
870 """\
871 cov = Coverage(data_file="foo.cov.2")
872 cov.load()
873 cov.report(show_missing=None)
874 """,
875 )
876 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
877 "report --format=markdown",
878 """\
879 cov = Coverage()
880 cov.load()
881 cov.report(output_format="markdown")
882 """,
883 )
885 def test_run(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
886 # coverage run [-p] [-L] [--timid] MODULE.py [ARG1 ARG2 ...]
888 # run calls coverage.erase first.
889 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
890 "run foo.py",
891 """\
892 cov = Coverage()
893 runner = PyRunner(['foo.py'], as_module=False)
894 runner.prepare()
895 cov.start()
896 runner.run()
897 cov.stop()
898 cov.save()
899 """,
900 )
901 # run -a combines with an existing data file before saving.
902 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
903 "run -a foo.py",
904 """\
905 cov = Coverage()
906 runner = PyRunner(['foo.py'], as_module=False)
907 runner.prepare()
908 cov.load()
909 cov.start()
910 runner.run()
911 cov.stop()
912 cov.save()
913 """,
914 )
915 # --timid sets a flag, and program arguments get passed through.
916 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
917 "run --timid foo.py abc 123",
918 """\
919 cov = Coverage(timid=True)
920 runner = PyRunner(['foo.py', 'abc', '123'], as_module=False)
921 runner.prepare()
922 cov.start()
923 runner.run()
924 cov.stop()
925 cov.save()
926 """,
927 )
928 # -L sets a flag, and flags for the program don't confuse us.
929 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
930 "run -p -L foo.py -a -b",
931 """\
932 cov = Coverage(cover_pylib=True, data_suffix=True)
933 runner = PyRunner(['foo.py', '-a', '-b'], as_module=False)
934 runner.prepare()
935 cov.start()
936 runner.run()
937 cov.stop()
938 cov.save()
939 """,
940 )
941 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
942 "run --branch foo.py",
943 """\
944 cov = Coverage(branch=True)
945 runner = PyRunner(['foo.py'], as_module=False)
946 runner.prepare()
947 cov.start()
948 runner.run()
949 cov.stop()
950 cov.save()
951 """,
952 )
953 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
954 "run --rcfile=myrc.rc foo.py",
955 """\
956 cov = Coverage(config_file="myrc.rc")
957 runner = PyRunner(['foo.py'], as_module=False)
958 runner.prepare()
959 cov.start()
960 runner.run()
961 cov.stop()
962 cov.save()
963 """,
964 )
965 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
966 "run --include=pre1,pre2 foo.py",
967 """\
968 cov = Coverage(include=["pre1", "pre2"])
969 runner = PyRunner(['foo.py'], as_module=False)
970 runner.prepare()
971 cov.start()
972 runner.run()
973 cov.stop()
974 cov.save()
975 """,
976 )
977 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
978 "run --omit=opre1,opre2 foo.py",
979 """\
980 cov = Coverage(omit=["opre1", "opre2"])
981 runner = PyRunner(['foo.py'], as_module=False)
982 runner.prepare()
983 cov.start()
984 runner.run()
985 cov.stop()
986 cov.save()
987 """,
988 )
989 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
990 "run --include=pre1,pre2 --omit=opre1,opre2 foo.py",
991 """\
992 cov = Coverage(include=["pre1", "pre2"], omit=["opre1", "opre2"])
993 runner = PyRunner(['foo.py'], as_module=False)
994 runner.prepare()
995 cov.start()
996 runner.run()
997 cov.stop()
998 cov.save()
999 """,
1000 )
1001 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1002 "run --source=quux,hi.there,/home/bar foo.py",
1003 """\
1004 cov = Coverage(source=["quux", "hi.there", "/home/bar"])
1005 runner = PyRunner(['foo.py'], as_module=False)
1006 runner.prepare()
1007 cov.start()
1008 runner.run()
1009 cov.stop()
1010 cov.save()
1011 """,
1012 )
1013 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1014 "run --concurrency=gevent foo.py",
1015 """\
1016 cov = Coverage(concurrency=['gevent'])
1017 runner = PyRunner(['foo.py'], as_module=False)
1018 runner.prepare()
1019 cov.start()
1020 runner.run()
1021 cov.stop()
1022 cov.save()
1023 """,
1024 )
1025 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1026 "run --concurrency=multiprocessing foo.py",
1027 """\
1028 cov = Coverage(concurrency=['multiprocessing'])
1029 runner = PyRunner(['foo.py'], as_module=False)
1030 runner.prepare()
1031 cov.start()
1032 runner.run()
1033 cov.stop()
1034 cov.save()
1035 """,
1036 )
1037 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1038 "run --concurrency=gevent,thread foo.py",
1039 """\
1040 cov = Coverage(concurrency=['gevent', 'thread'])
1041 runner = PyRunner(['foo.py'], as_module=False)
1042 runner.prepare()
1043 cov.start()
1044 runner.run()
1045 cov.stop()
1046 cov.save()
1047 """,
1048 )
1049 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1050 "run --data-file=output.coverage foo.py",
1051 """\
1052 cov = Coverage(data_file="output.coverage")
1053 runner = PyRunner(['foo.py'], as_module=False)
1054 runner.prepare()
1055 cov.start()
1056 runner.run()
1057 cov.stop()
1058 cov.save()
1059 """,
1060 )
1062 def test_multiprocessing_needs_config_file(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1063 # You can't use command-line args to add options to multiprocessing
1064 # runs, since they won't make it to the subprocesses. You need to use a
1065 # config file.
1066 self.command_line("run --concurrency=multiprocessing --branch foo.py", ret=ERR) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1067 msg = "Options affecting multiprocessing must only be specified in a configuration file." 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1068 _, err = self.stdouterr() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1069 assert msg in err 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1070 assert "Remove --branch from the command line." in err 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1072 def test_run_debug(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1073 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1074 "run --debug=opt1 foo.py",
1075 """\
1076 cov = Coverage(debug=["opt1"])
1077 runner = PyRunner(['foo.py'], as_module=False)
1078 runner.prepare()
1079 cov.start()
1080 runner.run()
1081 cov.stop()
1082 cov.save()
1083 """,
1084 )
1085 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1086 "run --debug=opt1,opt2 foo.py",
1087 """\
1088 cov = Coverage(debug=["opt1","opt2"])
1089 runner = PyRunner(['foo.py'], as_module=False)
1090 runner.prepare()
1091 cov.start()
1092 runner.run()
1093 cov.stop()
1094 cov.save()
1095 """,
1096 )
1098 def test_run_module(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1099 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1100 "run -m mymodule",
1101 """\
1102 cov = Coverage()
1103 runner = PyRunner(['mymodule'], as_module=True)
1104 runner.prepare()
1105 cov.start()
1106 runner.run()
1107 cov.stop()
1108 cov.save()
1109 """,
1110 )
1111 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1112 "run -m mymodule -qq arg1 arg2",
1113 """\
1114 cov = Coverage()
1115 runner = PyRunner(['mymodule', '-qq', 'arg1', 'arg2'], as_module=True)
1116 runner.prepare()
1117 cov.start()
1118 runner.run()
1119 cov.stop()
1120 cov.save()
1121 """,
1122 )
1123 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1124 "run --branch -m mymodule",
1125 """\
1126 cov = Coverage(branch=True)
1127 runner = PyRunner(['mymodule'], as_module=True)
1128 runner.prepare()
1129 cov.start()
1130 runner.run()
1131 cov.stop()
1132 cov.save()
1133 """,
1134 )
1135 self.cmd_executes_same("run -m mymodule", "run --module mymodule") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1137 def test_run_nothing(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1138 self.command_line("run", ret=ERR) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1139 assert "Nothing to do" in self.stderr() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1141 def test_run_from_config(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1142 options = {"run:command_line": "myprog.py a 123 'a quoted thing' xyz"} 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1143 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1144 "run",
1145 """\
1146 cov = Coverage()
1147 runner = PyRunner(['myprog.py', 'a', '123', 'a quoted thing', 'xyz'], as_module=False)
1148 runner.prepare()
1149 cov.start()
1150 runner.run()
1151 cov.stop()
1152 cov.save()
1153 """,
1154 options=options,
1155 )
1157 def test_run_module_from_config(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1158 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1159 "run",
1160 """\
1161 cov = Coverage()
1162 runner = PyRunner(['mymodule', 'thing1', 'thing2'], as_module=True)
1163 runner.prepare()
1164 cov.start()
1165 runner.run()
1166 cov.stop()
1167 cov.save()
1168 """,
1169 options={"run:command_line": "-m mymodule thing1 thing2"},
1170 )
1172 def test_run_from_config_but_empty(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1173 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1174 "run",
1175 """\
1176 cov = Coverage()
1177 show_help('Nothing to do.')
1178 """,
1179 ret=ERR,
1180 options={"run:command_line": ""},
1181 )
1183 def test_run_dashm_only(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1184 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1185 "run -m",
1186 """\
1187 cov = Coverage()
1188 show_help('No module specified for -m')
1189 """,
1190 ret=ERR,
1191 )
1192 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1193 "run -m",
1194 """\
1195 cov = Coverage()
1196 show_help('No module specified for -m')
1197 """,
1198 ret=ERR,
1199 options={"run:command_line": "myprog.py"},
1200 )
1202 def test_cant_append_parallel(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1203 self.command_line("run --append --parallel-mode foo.py", ret=ERR) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1204 assert "Can't append to data files in parallel mode." in self.stderr() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1206 def test_xml(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1207 # coverage xml [-i] [--omit DIR,...] [FILE1 FILE2 ...]
1208 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1209 "xml",
1210 """\
1211 cov = Coverage()
1212 cov.load()
1213 cov.xml_report()
1214 """,
1215 )
1216 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1217 "xml -i",
1218 """\
1219 cov = Coverage()
1220 cov.load()
1221 cov.xml_report(ignore_errors=True)
1222 """,
1223 )
1224 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1225 "xml -o myxml.foo",
1226 """\
1227 cov = Coverage()
1228 cov.load()
1229 cov.xml_report(outfile="myxml.foo")
1230 """,
1231 )
1232 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1233 "xml -o -",
1234 """\
1235 cov = Coverage()
1236 cov.load()
1237 cov.xml_report(outfile="-")
1238 """,
1239 )
1240 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1241 "xml --omit fooey",
1242 """\
1243 cov = Coverage(omit=["fooey"])
1244 cov.load()
1245 cov.xml_report(omit=["fooey"])
1246 """,
1247 )
1248 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1249 "xml --omit fooey,booey",
1250 """\
1251 cov = Coverage(omit=["fooey", "booey"])
1252 cov.load()
1253 cov.xml_report(omit=["fooey", "booey"])
1254 """,
1255 )
1256 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1257 "xml mod1",
1258 """\
1259 cov = Coverage()
1260 cov.load()
1261 cov.xml_report(morfs=["mod1"])
1262 """,
1263 )
1264 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1265 "xml mod1 mod2 mod3",
1266 """\
1267 cov = Coverage()
1268 cov.load()
1269 cov.xml_report(morfs=["mod1", "mod2", "mod3"])
1270 """,
1271 )
1272 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1273 "xml -q",
1274 """\
1275 cov = Coverage(messages=False)
1276 cov.load()
1277 cov.xml_report()
1278 """,
1279 )
1280 self.cmd_executes( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1281 "xml --quiet",
1282 """\
1283 cov = Coverage(messages=False)
1284 cov.load()
1285 cov.xml_report()
1286 """,
1287 )
1289 def test_no_arguments_at_all(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1290 self.cmd_help("", topic="minimum_help", ret=OK) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1292 def test_bad_command(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1293 self.cmd_help("xyzzy", "Unknown command: 'xyzzy'") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1295 def test_save_signal_wrong(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1296 self.cmd_help( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1297 "run --save-signal=XYZ nothing.py",
1298 "option --save-signal: invalid choice: 'XYZ' (choose from 'USR1', 'USR2')",
1299 )
1301 @pytest.mark.skipif(not env.WINDOWS, reason="this is a windows-only error") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1302 def test_save_signal_windows(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1303 self.cmd_help( 1abcdefghijklmnopqrstuv'
1304 "run --save-signal=USR1 nothing.py",
1305 "--save-signal is not supported on Windows.",
1306 )
1309class CmdLineWithFilesTest(BaseCmdLineTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1310 """Test the command line in ways that need temp files."""
1312 run_in_temp_dir = True 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1314 def test_debug_data(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1315 data = self.make_data_file( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1316 lines={
1317 "file1.py": range(1, 18),
1318 "file2.py": range(1, 24),
1319 },
1320 file_tracers={"file1.py": "a_plugin"},
1321 )
1323 self.command_line("debug data") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1324 assert self.stdout() == textwrap.dedent(f"""\ 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1325 -- data ------------------------------------------------------
1326 path: {data.data_filename()}
1327 has_arcs: False
1328 2 files:
1329 file1.py: 17 lines [a_plugin]
1330 file2.py: 23 lines
1331 """)
1333 def test_debug_data_with_no_data_file(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1334 data = self.make_data_file() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1335 self.command_line("debug data") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1336 assert self.stdout() == textwrap.dedent(f"""\ 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1337 -- data ------------------------------------------------------
1338 path: {data.data_filename()}
1339 No data collected: file doesn't exist
1340 """)
1342 def test_debug_combinable_data(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1343 data1 = self.make_data_file(lines={"file1.py": range(1, 18), "file2.py": [1]}) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1344 data2 = self.make_data_file(suffix="123", lines={"file2.py": range(1, 10)}) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1346 self.command_line("debug data") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1347 assert self.stdout() == textwrap.dedent(f"""\ 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1348 -- data ------------------------------------------------------
1349 path: {data1.data_filename()}
1350 has_arcs: False
1351 2 files:
1352 file1.py: 17 lines
1353 file2.py: 1 line
1354 -----
1355 path: {data2.data_filename()}
1356 has_arcs: False
1357 1 file:
1358 file2.py: 9 lines
1359 """)
1362class CmdLineStdoutTest(BaseCmdLineTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1363 """Test the command line with real stdout output."""
1365 def test_minimum_help(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1366 self.command_line("") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1367 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1368 assert "Code coverage for Python" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1369 assert out.count("\n") < 4 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1371 def test_version(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1372 self.command_line("--version") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1373 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1374 assert "ersion " in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1375 if testenv.C_TRACER: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1376 assert "with C extension" in out 1wyaACcEGeIKgMOiQTkWZn25q8#t
1377 else:
1378 assert "without C extension" in out 1xzbBDdFHfJLhNPjRSUVlmXY01op3467rs9!$%uv()'
1379 assert out.count("\n") < 4 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1381 def test_help_contains_command_name(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1382 # Command name should be present in help output.
1383 fake_command_path = os_sep("lorem/ipsum/dolor") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1384 expected_command_name = "dolor" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1385 fake_argv = [fake_command_path, "sit", "amet"] 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1386 with mock.patch.object(sys, "argv", new=fake_argv): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1387 self.command_line("help") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1388 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1389 assert expected_command_name in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1391 def test_help_contains_command_name_from_package(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1392 # Command package name should be present in help output.
1393 #
1394 # When the main module is actually a package's `__main__` module, the resulting command line
1395 # has the `__main__.py` file's patch as the command name. Instead, the command name should
1396 # be derived from the package name.
1398 fake_command_path = os_sep("lorem/ipsum/dolor/__main__.py") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1399 expected_command_name = "dolor" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1400 fake_argv = [fake_command_path, "sit", "amet"] 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1401 with mock.patch.object(sys, "argv", new=fake_argv): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1402 self.command_line("help") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1403 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1404 assert expected_command_name in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1406 def test_help(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1407 self.command_line("help") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1408 lines = self.stdout().splitlines() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1409 assert len(lines) > 10 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1410 assert lines[-1] == f"Full documentation is at {__url__}" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1412 def test_cmd_help(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1413 self.command_line("help run") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1414 out = self.stdout() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1415 lines = out.splitlines() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1416 assert "<pyfile>" in lines[0] 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1417 assert "--timid" in out 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1418 assert len(lines) > 20 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1419 assert lines[-1] == f"Full documentation is at {__url__}" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1421 def test_unknown_topic(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1422 # Should probably be an ERR return, but meh.
1423 self.command_line("help foobar") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1424 lines = self.stdout().splitlines() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1425 assert lines[0] == "Don't know topic 'foobar'" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1426 assert lines[-1] == f"Full documentation is at {__url__}" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1428 def test_error(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1429 self.command_line("fooey kablooey", ret=ERR) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1430 err = self.stderr() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1431 assert "fooey" in err 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1432 assert "help" in err 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1434 def test_option_error(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1435 self.command_line("run --fooey", ret=ERR) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1436 err = self.stderr() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1437 assert "fooey" in err 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1438 assert "help" in err 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1440 def test_doc_url(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1441 assert __url__.startswith("https://coverage.readthedocs.io") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1444class CmdMainTest(CoverageTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1445 """Tests of coverage.cmdline.main(), using mocking for isolation."""
1447 run_in_temp_dir = False 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1449 class CoverageScriptStub: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1450 """A stub for coverage.cmdline.CoverageScript, used by CmdMainTest."""
1452 def command_line(self, argv: list[str]) -> int: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1453 """Stub for command_line, the arg determines what it will do."""
1454 if argv[0] == "hello": 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1455 print("Hello, world!") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1456 elif argv[0] == "raise": 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1457 try: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1458 raise RuntimeError("oh noes!") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1459 except: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1460 raise _ExceptionDuringRun(*sys.exc_info()) from None 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1461 elif argv[0] == "internalraise": 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1462 raise ValueError("coverage is broken") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1463 elif argv[0] == "exit": 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1464 sys.exit(23) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1465 else:
1466 raise AssertionError(f"Bad CoverageScriptStub: {argv!r}")
1467 return 0 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1469 def setUp(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1470 super().setUp() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1471 old_CoverageScript = coverage.cmdline.CoverageScript 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1472 coverage.cmdline.CoverageScript = self.CoverageScriptStub # type: ignore 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1473 self.addCleanup(setattr, coverage.cmdline, "CoverageScript", old_CoverageScript) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1475 def test_normal(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1476 ret = coverage.cmdline.main(["hello"]) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1477 assert ret == 0 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1478 assert self.stdout() == "Hello, world!\n" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1480 def test_raise(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1481 ret = coverage.cmdline.main(["raise"]) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1482 assert ret == 1 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1483 out, err = self.stdouterr() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1484 assert out == "" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1485 print(err) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1486 err_parts = err.splitlines(keepends=True) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1487 assert err_parts[0] == "Traceback (most recent call last):\n" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1488 assert ' raise RuntimeError("oh noes!")\n' in err_parts 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1489 assert err_parts[-1] == "RuntimeError: oh noes!\n" 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1491 def test_internalraise(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1492 with pytest.raises(ValueError, match="coverage is broken"): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1493 coverage.cmdline.main(["internalraise"]) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1495 def test_exit(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1496 ret = coverage.cmdline.main(["exit"]) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1497 assert ret == 23 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1500class CoverageReportingFake: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1501 """A fake Coverage.coverage test double for FailUnderTest methods."""
1503 # pylint: disable=missing-function-docstring
1504 def __init__( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv
1505 self,
1506 report_result: float,
1507 html_result: float = 0,
1508 xml_result: float = 0,
1509 json_report: float = 0,
1510 lcov_result: float = 0,
1511 ) -> None:
1512 self.config = CoverageConfig() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1513 self.report_result = report_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1514 self.html_result = html_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1515 self.xml_result = xml_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1516 self.json_result = json_report 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1517 self.lcov_result = lcov_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1519 def set_option(self, optname: str, optvalue: TConfigValueIn) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1520 self.config.set_option(optname, optvalue) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1522 def get_option(self, optname: str) -> TConfigValueOut: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1523 return self.config.get_option(optname) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1525 def load(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1526 pass 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1528 def report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1529 return self.report_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1531 def html_report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1532 return self.html_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1534 def xml_report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1535 return self.xml_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1537 def json_report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1538 return self.json_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1540 def lcov_report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1541 return self.lcov_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1544class FailUnderTest(CoverageTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1545 """Tests of the --fail-under handling in cmdline.py."""
1547 @pytest.mark.parametrize( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1548 "results, fail_under, cmd, ret",
1549 [
1550 # Command-line switch properly checks the result of reporting functions.
1551 ((20, 30, 40, 50, 60), None, "report --fail-under=19", 0),
1552 ((20, 30, 40, 50, 60), None, "report --fail-under=21", 2),
1553 ((20, 30, 40, 50, 60), None, "html --fail-under=29", 0),
1554 ((20, 30, 40, 50, 60), None, "html --fail-under=31", 2),
1555 ((20, 30, 40, 50, 60), None, "xml --fail-under=39", 0),
1556 ((20, 30, 40, 50, 60), None, "xml --fail-under=41", 2),
1557 ((20, 30, 40, 50, 60), None, "json --fail-under=49", 0),
1558 ((20, 30, 40, 50, 60), None, "json --fail-under=51", 2),
1559 ((20, 30, 40, 50, 60), None, "lcov --fail-under=59", 0),
1560 ((20, 30, 40, 50, 60), None, "lcov --fail-under=61", 2),
1561 # Configuration file setting properly checks the result of reporting.
1562 ((20, 30, 40, 50, 60), 19, "report", 0),
1563 ((20, 30, 40, 50, 60), 21, "report", 2),
1564 ((20, 30, 40, 50, 60), 29, "html", 0),
1565 ((20, 30, 40, 50, 60), 31, "html", 2),
1566 ((20, 30, 40, 50, 60), 39, "xml", 0),
1567 ((20, 30, 40, 50, 60), 41, "xml", 2),
1568 ((20, 30, 40, 50, 60), 49, "json", 0),
1569 ((20, 30, 40, 50, 60), 51, "json", 2),
1570 ((20, 30, 40, 50, 60), 59, "lcov", 0),
1571 ((20, 30, 40, 50, 60), 61, "lcov", 2),
1572 # Command-line overrides configuration.
1573 ((20, 30, 40, 50, 60), 19, "report --fail-under=21", 2),
1574 ],
1575 )
1576 def test_fail_under( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1577 self,
1578 results: tuple[float, float, float, float, float],
1579 fail_under: float | None,
1580 cmd: str,
1581 ret: int,
1582 ) -> None:
1583 cov = CoverageReportingFake(*results) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1584 if fail_under is not None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1585 cov.set_option("report:fail_under", fail_under) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1586 with mock.patch("coverage.cmdline.Coverage", lambda *a, **kw: cov): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1587 self.command_line(cmd, ret) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1589 @pytest.mark.parametrize( 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1590 "result, cmd, ret, msg",
1591 [
1592 (20.5, "report --fail-under=20.4 --precision=1", 0, ""),
1593 (
1594 20.5,
1595 "report --fail-under=20.6 --precision=1",
1596 2,
1597 "Coverage failure: total of 20.5 is less than fail-under=20.6\n",
1598 ),
1599 (
1600 20.12345,
1601 "report --fail-under=20.1235 --precision=5",
1602 2,
1603 "Coverage failure: total of 20.12345 is less than fail-under=20.12350\n",
1604 ),
1605 (20.12339, "report --fail-under=20.1234 --precision=4", 0, ""),
1606 ],
1607 )
1608 def test_fail_under_with_precision(self, result: float, cmd: str, ret: int, msg: str) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1609 cov = CoverageReportingFake(report_result=result) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1610 with mock.patch("coverage.cmdline.Coverage", lambda *a, **kw: cov): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1611 self.command_line(cmd, ret) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'
1612 assert self.stdout() == msg 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'