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

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 

3 

4"""Test cmdline.py for coverage.py.""" 

5 

6from __future__ import annotations 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

7 

8import ast 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

9import os 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

10import pprint 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

11import re 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

12import sys 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

13import textwrap 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

14 

15from unittest import mock 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

16from typing import Any 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

17from collections.abc import Mapping 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

18 

19import pytest 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

20 

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()'

29 

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()'

33 

34 

35class BaseCmdLineTest(CoverageTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

36 """Tests of execution paths through the command line interpreter.""" 

37 

38 run_in_temp_dir = False 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

39 

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 ) 

120 

121 DEFAULT_KWARGS = {name: kw for name, _, kw in _defaults.mock_calls} 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

122 

123 def model_object(self) -> mock.Mock: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

124 """Return a Mock suitable for use in CoverageScript.""" 

125 mk = mock.Mock() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

126 

127 cov = mk.Coverage.return_value 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

128 

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()'

133 

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()'

140 

141 return mk 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

142 

143 # Global names in cmdline.py that will be mocked during the tests. 

144 MOCK_GLOBALS = ["Coverage", "PyRunner", "show_help"] 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

145 

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. 

152 

153 `options` is a dict of names and values to pass to `set_option`. 

154 

155 Returns the Mock it used and the status code returned. 

156 

157 """ 

158 mk = self.model_object() 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

159 

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()'

163 

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()'

174 

175 return mk, ret 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

176 

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()'

187 

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()'

194 

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()'

202 

203 self.assert_same_mock_calls(expected, called) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

204 

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()'

211 

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()'

221 

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. 

230 

231 Only the last function call in the mock is checked, which should be the 

232 help message that we want to see. 

233 

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()'

241 

242 

243class BaseCmdLineTestTest(BaseCmdLineTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

244 """Tests that our BaseCmdLineTest helpers work.""" 

245 

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()'

251 

252 

253class CmdLineTest(BaseCmdLineTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

254 """Tests of the coverage.py command line.""" 

255 

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 ) 

314 

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 ) 

369 

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 ) 

388 

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()'

402 

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()'

408 

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()'

415 

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()'

422 

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()'

426 

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()'

431 

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()'

454 

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()'

463 

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 ) 

480 

481 def test_version(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

482 # coverage --version 

483 self.cmd_help("--version", topic="version", ret=OK) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

484 

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()'

489 

490 def test_help_command(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

491 self.cmd_executes("help", "show_help(topic='help')") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

492 

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()'

496 

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 ) 

587 

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 ) 

686 

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 ) 

753 

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 ) 

884 

885 def test_run(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

886 # coverage run [-p] [-L] [--timid] MODULE.py [ARG1 ARG2 ...] 

887 

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 ) 

1061 

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()'

1071 

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 ) 

1097 

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()'

1136 

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()'

1140 

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 ) 

1156 

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 ) 

1171 

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 ) 

1182 

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 ) 

1201 

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()'

1205 

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 ) 

1288 

1289 def test_no_arguments_at_all(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1290 self.cmd_help("", topic="minimum_help", ret=OK) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1291 

1292 def test_bad_command(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1293 self.cmd_help("xyzzy", "Unknown command: 'xyzzy'") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1294 

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 ) 

1300 

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 ) 

1307 

1308 

1309class CmdLineWithFilesTest(BaseCmdLineTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1310 """Test the command line in ways that need temp files.""" 

1311 

1312 run_in_temp_dir = True 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1313 

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 ) 

1322 

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 """) 

1332 

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 """) 

1341 

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()'

1345 

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 """) 

1360 

1361 

1362class CmdLineStdoutTest(BaseCmdLineTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1363 """Test the command line with real stdout output.""" 

1364 

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()'

1370 

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()'

1380 

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()'

1390 

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. 

1397 

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()'

1405 

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()'

1411 

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()'

1420 

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()'

1427 

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()'

1433 

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()'

1439 

1440 def test_doc_url(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1441 assert __url__.startswith("https://coverage.readthedocs.io") 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1442 

1443 

1444class CmdMainTest(CoverageTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1445 """Tests of coverage.cmdline.main(), using mocking for isolation.""" 

1446 

1447 run_in_temp_dir = False 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1448 

1449 class CoverageScriptStub: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1450 """A stub for coverage.cmdline.CoverageScript, used by CmdMainTest.""" 

1451 

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()'

1468 

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()'

1474 

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()'

1479 

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()'

1490 

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()'

1494 

1495 def test_exit(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1496 ret = coverage.cmdline.main(["exit"]) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1497 assert ret == 23 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1498 

1499 

1500class CoverageReportingFake: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1501 """A fake Coverage.coverage test double for FailUnderTest methods.""" 

1502 

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()'

1518 

1519 def set_option(self, optname: str, optvalue: TConfigValueIn) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1520 self.config.set_option(optname, optvalue) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1521 

1522 def get_option(self, optname: str) -> TConfigValueOut: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1523 return self.config.get_option(optname) 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1524 

1525 def load(self) -> None: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1526 pass 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1527 

1528 def report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1529 return self.report_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1530 

1531 def html_report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1532 return self.html_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1533 

1534 def xml_report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1535 return self.xml_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1536 

1537 def json_report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1538 return self.json_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1539 

1540 def lcov_report(self, *args_unused: Any, **kwargs_unused: Any) -> float: 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1541 return self.lcov_result 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1542 

1543 

1544class FailUnderTest(CoverageTest): 1wxyzabABCDcdEFGHefIJKLghMNOPijQRSTUVklmWXYZ01nop234567qrs89!#$%tuv()'

1545 """Tests of the --fail-under handling in cmdline.py.""" 

1546 

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()'

1588 

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()'