Coverage for tests / test_report.py: 100.000%

523 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 text-based summary reporting for coverage.py""" 

5 

6from __future__ import annotations 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

7 

8import glob 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

9import io 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

10import math 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

11import os 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

12import os.path 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

13import py_compile 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

14import re 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

15 

16 

17import pytest 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

18 

19import coverage 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

20from coverage import env 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

21from coverage.control import Coverage 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

22from coverage.data import CoverageData 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

23from coverage.exceptions import ConfigError, NoDataError, NotPython 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

24from coverage.files import abs_file 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

25from coverage.report import SummaryReporter 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

26from coverage.types import TConfigValueIn 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

27 

28from tests.coveragetest import CoverageTest, TESTS_DIR, UsingModulesMixin 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

29from tests.helpers import assert_coverage_warnings 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

30 

31 

32class SummaryTest(UsingModulesMixin, CoverageTest): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

33 """Tests of the text summary reporting for coverage.py.""" 

34 

35 def make_mycode(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

36 """Make the mycode.py file when needed.""" 

37 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

38 "mycode.py", 

39 """\ 

40 import covmod1 

41 import covmodzip1 

42 a = 1 

43 print('done') 

44 """, 

45 ) 

46 

47 def test_report(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

48 self.make_mycode() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

49 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

50 self.start_import_stop(cov, "mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

51 assert self.stdout() == "done\n" 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPv3fQwRxXgSyTzhUAVBYiCDj

52 report = self.get_report(cov) 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPv3fQwRxXgSyTzhUAVBYiCDj

53 

54 # Name Stmts Miss Cover 

55 # ------------------------------------------------------------------ 

56 # c:/ned/coverage/tests/modules/covmod1.py 2 0 100% 

57 # c:/ned/coverage/tests/zipmods.zip/covmodzip1.py 2 0 100% 

58 # mycode.py 4 0 100% 

59 # ------------------------------------------------------------------ 

60 # TOTAL 8 0 100% 

61 

62 assert "/coverage/__init__/" not in report 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPv3fQwRxXgSyTzhUAVBYiCDj

63 assert "/tests/modules/covmod1.py " in report 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPv3fQwRxXgSyTzhUAVBYiCDj

64 assert "/tests/zipmods.zip/covmodzip1.py " in report 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPv3fQwRxXgSyTzhUAVBYiCDj

65 assert "mycode.py " in report 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPv3fQwRxXgSyTzhUAVBYiCDj

66 assert self.last_line_squeezed(report) == "TOTAL 8 0 100%" 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPv3fQwRxXgSyTzhUAVBYiCDj

67 

68 def test_report_just_one(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

69 # Try reporting just one module 

70 self.make_mycode() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

71 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

72 self.start_import_stop(cov, "mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

73 report = self.get_report(cov, morfs=["mycode.py"]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

74 

75 # Name Stmts Miss Cover 

76 # ------------------------------- 

77 # mycode.py 4 0 100% 

78 # ------------------------------- 

79 # TOTAL 4 0 100% 

80 assert self.line_count(report) == 5 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

81 assert "/coverage/" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

82 assert "/tests/modules/covmod1.py " not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

83 assert "/tests/zipmods.zip/covmodzip1.py " not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

84 assert "mycode.py " in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

85 assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

86 

87 def test_report_wildcard(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

88 # Try reporting using wildcards to get the modules. 

89 self.make_mycode() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

90 self.add_test_modules_to_pythonpath() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

91 # Wildcard is handled by shell or cmdline.py, so use real commands 

92 self.run_command("coverage run mycode.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

93 report = self.report_from_command("coverage report my*.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

94 

95 # Name Stmts Miss Cover 

96 # ------------------------------- 

97 # mycode.py 4 0 100% 

98 # ------------------------------- 

99 # TOTAL 4 0 100% 

100 

101 assert self.line_count(report) == 5 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

102 assert "/coverage/" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

103 assert "/tests/modules/covmod1.py " not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

104 assert "/tests/zipmods.zip/covmodzip1.py " not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

105 assert "mycode.py " in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

106 assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

107 

108 def test_report_omitting(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

109 # Try reporting while omitting some modules 

110 self.make_mycode() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

111 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

112 self.start_import_stop(cov, "mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

113 report = self.get_report(cov, omit=[f"{TESTS_DIR}/*", "*/site-packages/*"]) 1EkFlaGmHn0bIoJpcKqLrdMsNteOuPvfQwRxgSyTz4hUAVBiCDj

114 

115 # Name Stmts Miss Cover 

116 # ------------------------------- 

117 # mycode.py 4 0 100% 

118 # ------------------------------- 

119 # TOTAL 4 0 100% 

120 

121 assert self.line_count(report) == 5 1EkFlaGmHn0bIoJpcKqLrdMsNteOuPvfQwRxgSyTz4hUAVBiCDj

122 assert "/coverage/" not in report 1EkFlaGmHn0bIoJpcKqLrdMsNteOuPvfQwRxgSyTz4hUAVBiCDj

123 assert "/tests/modules/covmod1.py " not in report 1EkFlaGmHn0bIoJpcKqLrdMsNteOuPvfQwRxgSyTz4hUAVBiCDj

124 assert "/tests/zipmods.zip/covmodzip1.py " not in report 1EkFlaGmHn0bIoJpcKqLrdMsNteOuPvfQwRxgSyTz4hUAVBiCDj

125 assert "mycode.py " in report 1EkFlaGmHn0bIoJpcKqLrdMsNteOuPvfQwRxgSyTz4hUAVBiCDj

126 assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" 1EkFlaGmHn0bIoJpcKqLrdMsNteOuPvfQwRxgSyTz4hUAVBiCDj

127 

128 def test_report_including(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

129 # Try reporting while including some modules 

130 self.make_mycode() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

131 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

132 self.start_import_stop(cov, "mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

133 report = self.get_report(cov, include=["mycode*"]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

134 

135 # Name Stmts Miss Cover 

136 # ------------------------------- 

137 # mycode.py 4 0 100% 

138 # ------------------------------- 

139 # TOTAL 4 0 100% 

140 

141 assert self.line_count(report) == 5 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

142 assert "/coverage/" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

143 assert "/tests/modules/covmod1.py " not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

144 assert "/tests/zipmods.zip/covmodzip1.py " not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

145 assert "mycode.py " in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

146 assert self.last_line_squeezed(report) == "TOTAL 4 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

147 

148 def test_report_include_relative_files_and_path(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

149 """ 

150 Test that when relative_files is True and a relative path to a module 

151 is included, coverage is reported for the module. 

152 

153 Ref: https://github.com/coveragepy/coveragepy/issues/1604 

154 """ 

155 self.make_mycode() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

156 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

157 ".coveragerc", 

158 """\ 

159 [run] 

160 relative_files = true 

161 """, 

162 ) 

163 self.make_file("submodule/mycode.py", "import mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

164 

165 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

166 self.start_import_stop(cov, "submodule/mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

167 report = self.get_report(cov, include="submodule/mycode.py") 1EkFlaGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

168 

169 # Name Stmts Miss Cover 

170 # --------------------------------------- 

171 # submodule/mycode.py 1 0 100% 

172 # --------------------------------------- 

173 # TOTAL 1 0 100% 

174 

175 assert "submodule/mycode.py " in report 1EkFlaGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

176 assert self.last_line_squeezed(report) == "TOTAL 1 0 100%" 1EkFlaGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

177 

178 def test_report_include_relative_files_and_wildcard_path(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

179 self.make_mycode() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

180 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

181 ".coveragerc", 

182 """\ 

183 [run] 

184 relative_files = true 

185 """, 

186 ) 

187 self.make_file("submodule/mycode.py", "import nested.submodule.mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

188 self.make_file("nested/submodule/mycode.py", "import mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

189 

190 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

191 self.start_import_stop(cov, "submodule/mycode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

192 report = self.get_report(cov, include="*/submodule/mycode.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

193 

194 # Name Stmts Miss Cover 

195 # ------------------------------------------------- 

196 # nested/submodule/mycode.py 1 0 100% 

197 # submodule/mycode.py 1 0 100% 

198 # ------------------------------------------------- 

199 # TOTAL 2 0 100% 

200 

201 reported_files = [line.split()[0] for line in report.splitlines()[2:4]] 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

202 assert reported_files == [ 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

203 "nested/submodule/mycode.py", 

204 "submodule/mycode.py", 

205 ] 

206 

207 def test_omit_files_here(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

208 # https://github.com/coveragepy/coveragepy/issues/1407 

209 self.make_file("foo.py", "") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

210 self.make_file("bar/bar.py", "") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

211 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

212 "tests/test_baz.py", 

213 """\ 

214 def test_foo(): 

215 assert True 

216 test_foo() 

217 """, 

218 ) 

219 self.run_command("coverage run --source=. --omit='./*.py' -m tests.test_baz") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

220 report = self.report_from_command("coverage report") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

221 

222 # Name Stmts Miss Cover 

223 # --------------------------------------- 

224 # tests/test_baz.py 3 0 100% 

225 # --------------------------------------- 

226 # TOTAL 3 0 100% 

227 

228 assert self.line_count(report) == 5 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

229 assert "foo" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

230 assert "bar" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

231 assert "tests/test_baz.py" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

232 assert self.last_line_squeezed(report) == "TOTAL 3 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

233 

234 def test_run_source_vs_report_include(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

235 # https://github.com/coveragepy/coveragepy/issues/621 

236 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

237 ".coveragerc", 

238 """\ 

239 [run] 

240 source = . 

241 

242 [report] 

243 include = mod/*,tests/* 

244 """, 

245 ) 

246 # It should be OK to use that configuration. 

247 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

248 with self.assert_warnings(cov, []): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

249 with cov.collect(): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

250 pass 1klamnbopcqrdsteuvfwxgyzhABiCDj

251 

252 def test_run_omit_vs_report_omit(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

253 # https://github.com/coveragepy/coveragepy/issues/622 

254 # report:omit shouldn't clobber run:omit. 

255 self.make_mycode() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

256 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

257 ".coveragerc", 

258 """\ 

259 [run] 

260 omit = */covmodzip1.py 

261 

262 [report] 

263 omit = */covmod1.py 

264 """, 

265 ) 

266 self.add_test_modules_to_pythonpath() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

267 self.run_command("coverage run mycode.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

268 

269 # Read the data written, to see that the right files have been omitted from running. 

270 covdata = CoverageData() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

271 covdata.read() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

272 files = [os.path.basename(p) for p in covdata.measured_files()] 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

273 assert "covmod1.py" in files 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

274 assert "covmodzip1.py" not in files 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

275 

276 def test_report_branches(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

277 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

278 "mybranch.py", 

279 """\ 

280 def branch(x): 

281 if x: 

282 print("x") 

283 return x 

284 branch(1) 

285 """, 

286 ) 

287 cov = coverage.Coverage(source=["."], branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

288 self.start_import_stop(cov, "mybranch") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

289 assert self.stdout() == "x\n" 1EkFlaGmHnbIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

290 report = self.get_report(cov) 1EkFlaGmHnbIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

291 

292 # Name Stmts Miss Branch BrPart Cover 

293 # ----------------------------------------------- 

294 # mybranch.py 5 0 2 1 86% 

295 # ----------------------------------------------- 

296 # TOTAL 5 0 2 1 86% 

297 assert self.line_count(report) == 5 1EkFlaGmHnbIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

298 assert "mybranch.py " in report 1EkFlaGmHnbIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

299 assert self.last_line_squeezed(report) == "TOTAL 5 0 2 1 86%" 1EkFlaGmHnbIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

300 

301 def test_report_show_missing(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

302 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

303 "mymissing.py", 

304 """\ 

305 def missing(x, y): 

306 if x: 

307 print("x") 

308 return x 

309 if y: 

310 print("y") 

311 try: 

312 print("z") 

313 1/0 

314 print("Never!") 

315 except ZeroDivisionError: 

316 pass 

317 return x 

318 missing(0, 1) 

319 """, 

320 ) 

321 cov = coverage.Coverage(source=["."]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

322 self.start_import_stop(cov, "mymissing") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

323 assert self.stdout() == "y\nz\n" 1EkFl2aGmHnbIoJpWcKqLrdMsNtZeOuPvfQwRxXgSyTz4hUAVBYiCDj

324 report = self.get_report(cov, show_missing=True) 1EkFl2aGmHnbIoJpWcKqLrdMsNtZeOuPvfQwRxXgSyTz4hUAVBYiCDj

325 

326 # Name Stmts Miss Cover Missing 

327 # -------------------------------------------- 

328 # mymissing.py 14 3 79% 3-4, 10 

329 # -------------------------------------------- 

330 # TOTAL 14 3 79% 

331 

332 assert self.line_count(report) == 5 1EkFl2aGmHnbIoJpWcKqLrdMsNtZeOuPvfQwRxXgSyTz4hUAVBYiCDj

333 squeezed = self.squeezed_lines(report) 1EkFl2aGmHnbIoJpWcKqLrdMsNtZeOuPvfQwRxXgSyTz4hUAVBYiCDj

334 assert squeezed[2] == "mymissing.py 14 3 79% 3-4, 10" 1EkFl2aGmHnbIoJpWcKqLrdMsNtZeOuPvfQwRxXgSyTz4hUAVBYiCDj

335 assert squeezed[4] == "TOTAL 14 3 79%" 1EkFl2aGmHnbIoJpWcKqLrdMsNtZeOuPvfQwRxXgSyTz4hUAVBYiCDj

336 

337 def test_report_show_missing_branches(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

338 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

339 "mybranch.py", 

340 """\ 

341 def branch(x, y): 

342 if x: 

343 print("x") 

344 if y: 

345 print("y") 

346 branch(1, 1) 

347 """, 

348 ) 

349 cov = coverage.Coverage(branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

350 self.start_import_stop(cov, "mybranch") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

351 assert self.stdout() == "x\ny\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

352 report = self.get_report(cov, show_missing=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

353 

354 # Name Stmts Miss Branch BrPart Cover Missing 

355 # ---------------------------------------------------------- 

356 # mybranch.py 6 0 4 2 80% 2->4, 4->exit 

357 # ---------------------------------------------------------- 

358 # TOTAL 6 0 4 2 80% 

359 

360 assert self.line_count(report) == 5 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

361 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

362 assert squeezed[2] == "mybranch.py 6 0 4 2 80% 2->4, 4->exit" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

363 assert squeezed[4] == "TOTAL 6 0 4 2 80%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

364 

365 def test_report_show_missing_branches_and_lines(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

366 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

367 "main.py", 

368 """\ 

369 import mybranch 

370 """, 

371 ) 

372 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

373 "mybranch.py", 

374 """\ 

375 def branch(x, y, z): 

376 if x: 

377 print("x") 

378 if y: 

379 print("y") 

380 if z: 

381 if x and y: 

382 print("z") 

383 return x 

384 branch(1, 1, 0) 

385 """, 

386 ) 

387 cov = coverage.Coverage(branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

388 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

389 assert self.stdout() == "x\ny\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

390 report_lines = self.get_report(cov, squeeze=False, show_missing=True).splitlines() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

391 

392 expected = [ 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

393 "Name Stmts Miss Branch BrPart Cover Missing", 

394 "---------------------------------------------------------", 

395 "main.py 1 0 0 0 100%", 

396 "mybranch.py 10 2 8 3 61% 2->4, 4->6, 7-8", 

397 "---------------------------------------------------------", 

398 "TOTAL 11 2 8 3 63%", 

399 ] 

400 assert expected == report_lines 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

401 

402 def test_report_skip_covered_no_branches(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

403 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

404 "main.py", 

405 """\ 

406 import not_covered 

407 

408 def normal(): 

409 print("z") 

410 normal() 

411 """, 

412 ) 

413 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

414 "not_covered.py", 

415 """\ 

416 def not_covered(): 

417 print("n") 

418 """, 

419 ) 

420 # --fail-under is handled by cmdline.py, use real commands. 

421 out = self.run_command("coverage run main.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

422 assert out == "z\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

423 report = self.report_from_command("coverage report --skip-covered --fail-under=70") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

424 

425 # Name Stmts Miss Cover 

426 # ------------------------------------ 

427 # not_covered.py 2 1 50% 

428 # ------------------------------------ 

429 # TOTAL 6 1 83% 

430 # 

431 # 1 file skipped due to complete coverage. 

432 

433 assert self.line_count(report) == 7, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

434 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

435 assert squeezed[2] == "not_covered.py 2 1 50%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

436 assert squeezed[4] == "TOTAL 6 1 83%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

437 assert squeezed[6] == "1 file skipped due to complete coverage." 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

438 assert self.last_command_status == 0 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

439 

440 def test_report_skip_covered_branches(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

441 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

442 "main.py", 

443 """\ 

444 import not_covered, covered 

445 

446 def normal(z): 

447 if z: 

448 print("z") 

449 normal(True) 

450 normal(False) 

451 """, 

452 ) 

453 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

454 "not_covered.py", 

455 """\ 

456 def not_covered(n): 

457 if n: 

458 print("n") 

459 not_covered(True) 

460 """, 

461 ) 

462 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

463 "covered.py", 

464 """\ 

465 def foo(): 

466 pass 

467 foo() 

468 """, 

469 ) 

470 cov = coverage.Coverage(branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

471 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

472 assert self.stdout() == "n\nz\n" 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPvfQwRxXgSyTz4hUAVBYiCDj

473 report = self.get_report(cov, skip_covered=True) 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPvfQwRxXgSyTz4hUAVBYiCDj

474 

475 # Name Stmts Miss Branch BrPart Cover 

476 # -------------------------------------------------- 

477 # not_covered.py 4 0 2 1 83% 

478 # -------------------------------------------------- 

479 # TOTAL 13 0 4 1 94% 

480 # 

481 # 2 files skipped due to complete coverage. 

482 

483 assert self.line_count(report) == 7, report 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPvfQwRxXgSyTz4hUAVBYiCDj

484 squeezed = self.squeezed_lines(report) 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPvfQwRxXgSyTz4hUAVBYiCDj

485 assert squeezed[2] == "not_covered.py 4 0 2 1 83%" 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPvfQwRxXgSyTz4hUAVBYiCDj

486 assert squeezed[4] == "TOTAL 13 0 4 1 94%" 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPvfQwRxXgSyTz4hUAVBYiCDj

487 assert squeezed[6] == "2 files skipped due to complete coverage." 1EkFlaGmHnbIoJpWcKqLrdMsNteOuPvfQwRxXgSyTz4hUAVBYiCDj

488 

489 def test_report_skip_covered_branches_with_totals(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

490 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

491 "main.py", 

492 """\ 

493 import not_covered 

494 import also_not_run 

495 

496 def normal(z): 

497 if z: 

498 print("z") 

499 normal(True) 

500 normal(False) 

501 """, 

502 ) 

503 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

504 "not_covered.py", 

505 """\ 

506 def not_covered(n): 

507 if n: 

508 print("n") 

509 not_covered(True) 

510 """, 

511 ) 

512 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

513 "also_not_run.py", 

514 """\ 

515 def does_not_appear_in_this_film(ni): 

516 print("Ni!") 

517 """, 

518 ) 

519 cov = coverage.Coverage(branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

520 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

521 assert self.stdout() == "n\nz\n" 1EkFl2aGmHn0bIoJpcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

522 report = self.get_report(cov, skip_covered=True) 1EkFl2aGmHn0bIoJpcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

523 

524 # Name Stmts Miss Branch BrPart Cover 

525 # -------------------------------------------------- 

526 # also_not_run.py 2 1 0 0 50% 

527 # not_covered.py 4 0 2 1 83% 

528 # -------------------------------------------------- 

529 # TOTAL 13 1 4 1 88% 

530 # 

531 # 1 file skipped due to complete coverage. 

532 

533 assert self.line_count(report) == 8, report 1EkFl2aGmHn0bIoJpcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

534 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

535 assert squeezed[2] == "also_not_run.py 2 1 0 0 50%" 1EkFl2aGmHn0bIoJpcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

536 assert squeezed[3] == "not_covered.py 4 0 2 1 83%" 1EkFl2aGmHn0bIoJpcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

537 assert squeezed[5] == "TOTAL 13 1 4 1 88%" 1EkFl2aGmHn0bIoJpcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

538 assert squeezed[7] == "1 file skipped due to complete coverage." 1EkFl2aGmHn0bIoJpcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

539 

540 def test_report_skip_covered_all_files_covered(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

541 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

542 "main.py", 

543 """\ 

544 def foo(): 

545 pass 

546 foo() 

547 """, 

548 ) 

549 cov = coverage.Coverage(source=["."], branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

550 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

551 assert self.stdout() == "" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

552 report = self.get_report(cov, skip_covered=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

553 

554 # Name Stmts Miss Branch BrPart Cover 

555 # ----------------------------------------- 

556 # TOTAL 3 0 0 0 100% 

557 # 

558 # 1 file skipped due to complete coverage. 

559 

560 assert self.line_count(report) == 5, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

561 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

562 assert squeezed[4] == "1 file skipped due to complete coverage." 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

563 

564 report = self.get_report(cov, squeeze=False, skip_covered=True, output_format="markdown") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

565 

566 # | Name | Stmts | Miss | Branch | BrPart | Cover | 

567 # |---------- | -------: | -------: | -------: | -------: | -------: | 

568 # | **TOTAL** | **3** | **0** | **0** | **0** | **100%** | 

569 # 

570 # 1 file skipped due to complete coverage. 

571 

572 assert self.line_count(report) == 5, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

573 assert report.split("\n")[0] == ( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

574 "| Name | Stmts | Miss | Branch | BrPart | Cover |" 

575 ) 

576 assert report.split("\n")[1] == ( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

577 "|---------- | -------: | -------: | -------: | -------: | -------: |" 

578 ) 

579 assert report.split("\n")[2] == ( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

580 "| **TOTAL** | **3** | **0** | **0** | **0** | **100%** |" 

581 ) 

582 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

583 assert squeezed[4] == "1 file skipped due to complete coverage." 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

584 

585 total = self.get_report(cov, output_format="total", skip_covered=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

586 assert total == "100\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPvfQwRxXgSyTzhUAVBYiCDj

587 

588 def test_report_skip_covered_longfilename(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

589 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

590 "long_______________filename.py", 

591 """\ 

592 def foo(): 

593 pass 

594 foo() 

595 """, 

596 ) 

597 cov = coverage.Coverage(source=["."], branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

598 self.start_import_stop(cov, "long_______________filename") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

599 assert self.stdout() == "" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

600 report = self.get_report(cov, squeeze=False, skip_covered=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

601 

602 # Name Stmts Miss Branch BrPart Cover 

603 # ----------------------------------------- 

604 # TOTAL 3 0 0 0 100% 

605 # 

606 # 1 file skipped due to complete coverage. 

607 

608 assert self.line_count(report) == 5, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

609 lines = self.report_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

610 assert lines[0] == "Name Stmts Miss Branch BrPart Cover" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

611 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

612 assert squeezed[4] == "1 file skipped due to complete coverage." 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

613 

614 def test_report_skip_covered_no_data(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

615 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

616 cov.load() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

617 with pytest.raises(NoDataError, match="No data to report."): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

618 self.get_report(cov, skip_covered=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

619 self.assert_doesnt_exist(".coverage") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

620 

621 def test_report_skip_empty(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

622 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

623 "main.py", 

624 """\ 

625 import submodule 

626 

627 def normal(): 

628 print("z") 

629 normal() 

630 """, 

631 ) 

632 self.make_file("submodule/__init__.py", "") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

633 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

634 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

635 assert self.stdout() == "z\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

636 report = self.get_report(cov, skip_empty=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

637 

638 # Name Stmts Miss Cover 

639 # ------------------------------------ 

640 # main.py 4 0 100% 

641 # ------------------------------------ 

642 # TOTAL 4 0 100% 

643 # 

644 # 1 empty file skipped. 

645 

646 assert self.line_count(report) == 7, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

647 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

648 assert squeezed[2] == "main.py 4 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

649 assert squeezed[4] == "TOTAL 4 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

650 assert squeezed[6] == "1 empty file skipped." 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTzhUAVBYiCDj

651 

652 def test_report_skip_empty_no_data(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

653 self.make_file("__init__.py", "") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

654 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

655 self.start_import_stop(cov, "__init__") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

656 assert self.stdout() == "" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

657 report = self.get_report(cov, skip_empty=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

658 

659 # Name Stmts Miss Cover 

660 # ------------------------------------ 

661 # TOTAL 0 0 100% 

662 # 

663 # 1 empty file skipped. 

664 

665 assert self.line_count(report) == 5, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

666 assert report.split("\n")[2] == "TOTAL 0 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

667 assert report.split("\n")[4] == "1 empty file skipped." 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxgSyTz4hUAVBYiCDj

668 

669 def test_report_precision(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

670 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

671 ".coveragerc", 

672 """\ 

673 [report] 

674 precision = 3 

675 omit = */site-packages/* 

676 """, 

677 ) 

678 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

679 "main.py", 

680 """\ 

681 import not_covered, covered 

682 

683 def normal(z): 

684 if z: 

685 print("z") 

686 normal(True) 

687 normal(False) 

688 """, 

689 ) 

690 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

691 "not_covered.py", 

692 """\ 

693 def not_covered(n): 

694 if n: 

695 print("n") 

696 not_covered(True) 

697 """, 

698 ) 

699 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

700 "covered.py", 

701 """\ 

702 def foo(): 

703 pass 

704 foo() 

705 """, 

706 ) 

707 cov = coverage.Coverage(branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

708 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

709 assert self.stdout() == "n\nz\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

710 report = self.get_report(cov, squeeze=False) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

711 

712 # Name Stmts Miss Branch BrPart Cover 

713 # ------------------------------------------------------ 

714 # covered.py 3 0 0 0 100.000% 

715 # main.py 6 0 2 0 100.000% 

716 # not_covered.py 4 0 2 1 83.333% 

717 # ------------------------------------------------------ 

718 # TOTAL 13 0 4 1 94.118% 

719 

720 assert self.line_count(report) == 7, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

721 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

722 assert squeezed[2] == "covered.py 3 0 0 0 100.000%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

723 assert squeezed[4] == "not_covered.py 4 0 2 1 83.333%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

724 assert squeezed[6] == "TOTAL 13 0 4 1 94.118%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

725 

726 def test_report_precision_all_zero(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

727 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

728 "not_covered.py", 

729 """\ 

730 def not_covered(n): 

731 if n: 

732 print("n") 

733 """, 

734 ) 

735 self.make_file("empty.py", "") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

736 cov = coverage.Coverage(source=["."]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

737 self.start_import_stop(cov, "empty") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

738 report = self.get_report(cov, precision=6, squeeze=False) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

739 

740 # Name Stmts Miss Cover 

741 # ----------------------------------------- 

742 # empty.py 0 0 100.000000% 

743 # not_covered.py 3 3 0.000000% 

744 # ----------------------------------------- 

745 # TOTAL 3 3 0.000000% 

746 

747 assert self.line_count(report) == 6, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

748 assert "empty.py 0 0 100.000000%" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

749 assert "not_covered.py 3 3 0.000000%" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

750 assert "TOTAL 3 3 0.000000%" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

751 

752 def test_report_module_docstrings(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

753 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

754 "main.py", 

755 """\ 

756 # Line 1 

757 '''Line 2 docstring.''' 

758 import other 

759 a = 4 

760 """, 

761 ) 

762 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

763 "other.py", 

764 """\ 

765 '''Line 1''' 

766 a = 2 

767 """, 

768 ) 

769 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

770 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

771 report = self.get_report(cov) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

772 

773 # Name Stmts Miss Cover 

774 # ------------------------------ 

775 # main.py 2 0 100% 

776 # other.py 1 0 100% 

777 # ------------------------------ 

778 # TOTAL 3 0 100% 

779 

780 assert self.line_count(report) == 6, report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

781 squeezed = self.squeezed_lines(report) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

782 assert squeezed[2] == "main.py 2 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

783 assert squeezed[3] == "other.py 1 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

784 assert squeezed[5] == "TOTAL 3 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

785 

786 def test_dotpy_not_python(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

787 # We run a .py file, and when reporting, we can't parse it as Python. 

788 # We should get an error message in the report. 

789 

790 self.make_data_file(lines={"mycode.py": [1]}) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

791 self.make_file("mycode.py", "This isn't python at all!") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

792 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

793 cov.load() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

794 msg = r"Couldn't parse '.*[/\\]mycode.py' as Python source: '.*' at line 1" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

795 with pytest.raises(NotPython, match=msg): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

796 self.get_report(cov, morfs=["mycode.py"]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

797 

798 def test_accented_directory(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

799 # Make a file with a non-ascii character in the directory name. 

800 self.make_file("\xe2/accented.py", "print('accented')") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

801 self.make_data_file(lines={abs_file("\xe2/accented.py"): [1]}) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

802 report_expected = ( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

803 "Name Stmts Miss Cover\n" 

804 + "-----------------------------------\n" 

805 + "\xe2/accented.py 1 0 100%\n" 

806 + "-----------------------------------\n" 

807 + "TOTAL 1 0 100%\n" 

808 ) 

809 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

810 cov.load() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

811 output = self.get_report(cov, squeeze=False) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

812 assert output == report_expected 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

813 

814 def test_accenteddotpy_not_python(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

815 # We run a .py file with a non-ascii name, and when reporting, we can't 

816 # parse it as Python. We should get an error message in the report. 

817 

818 self.make_data_file(lines={"accented\xe2.py": [1]}) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

819 self.make_file("accented\xe2.py", "This isn't python at all!") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

820 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

821 cov.load() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

822 msg = r"Couldn't parse '.*[/\\]accented\xe2.py' as Python source: '.*' at line 1" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

823 with pytest.raises(NotPython, match=msg): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

824 self.get_report(cov, morfs=["accented\xe2.py"]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

825 

826 @pytest.mark.parametrize("filename", ["mycode.py", "my_script"]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

827 def test_dotpy_not_python_ignored(self, filename: str) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

828 # We run a Python file, and when reporting, we can't parse it as Python, 

829 # but we've said to ignore errors, so there's no error reported, 

830 # though we still get a warning. 

831 self.make_file(filename, "This isn't python at all! I can't cope.") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

832 self.make_data_file(lines={filename: [1]}) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

833 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

834 cov.load() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

835 with pytest.raises(NoDataError, match="No data to report."): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

836 with pytest.warns(Warning) as warns: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

837 self.get_report(cov, morfs=[filename], ignore_errors=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

838 assert_coverage_warnings( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

839 warns, 

840 re.compile(rf"Couldn't parse Python file '.*[/\\]{filename}' \(couldnt-parse\)"), 

841 ) 

842 

843 def test_dothtml_not_python(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

844 # We run a .html file, and when reporting, we can't parse it as 

845 # Python. Since it wasn't .py, no error is reported. 

846 

847 # Pretend to run an html file. 

848 self.make_file("mycode.html", "<h1>This isn't python at all!</h1>") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

849 self.make_data_file(lines={"mycode.html": [1]}) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

850 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

851 cov.load() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

852 with pytest.raises(NoDataError, match="No data to report."): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

853 self.get_report(cov, morfs=["mycode.html"]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

854 

855 def test_report_no_extension(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

856 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

857 "xxx", 

858 """\ 

859 # This is a python file though it doesn't look like it, like a main script. 

860 a = b = c = d = 0 

861 a = 3 

862 b = 4 

863 if not b: 

864 c = 6 

865 d = 7 

866 print(f"xxx: {a} {b} {c} {d}") 

867 """, 

868 ) 

869 self.make_data_file(lines={abs_file("xxx"): [2, 3, 4, 5, 7, 8]}) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

870 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

871 cov.load() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

872 report = self.get_report(cov) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

873 assert self.last_line_squeezed(report) == "TOTAL 7 1 86%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

874 

875 def test_report_with_chdir(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

876 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

877 "chdir.py", 

878 """\ 

879 import os 

880 print("Line One") 

881 os.chdir("subdir") 

882 print("Line Two") 

883 print(open("something", encoding="utf-8").read()) 

884 """, 

885 ) 

886 self.make_file("subdir/something", "hello") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

887 out = self.run_command("coverage run --source=. chdir.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

888 assert out == "Line One\nLine Two\nhello\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

889 report = self.report_from_command("coverage report") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

890 assert self.last_line_squeezed(report) == "TOTAL 5 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

891 report = self.report_from_command("coverage report --format=markdown") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

892 assert self.last_line_squeezed(report) == "| **TOTAL** | **5** | **0** | **100%** |" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

893 

894 def test_bug_156_file_not_run_should_be_zero(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

895 # https://github.com/coveragepy/coveragepy/issues/156 

896 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

897 "mybranch.py", 

898 """\ 

899 def branch(x): 

900 if x: 

901 print("x") 

902 return x 

903 branch(1) 

904 """, 

905 ) 

906 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

907 "main.py", 

908 """\ 

909 print("y") 

910 """, 

911 ) 

912 cov = coverage.Coverage(branch=True, source=["."]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

913 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

914 report = self.get_report(cov).splitlines() 1EkFl2aGmHnbIoJpcKqLr1dMsNteOuPv3fQwRxXgSyTz4hUAVBYiCDj

915 assert "mybranch.py 5 5 2 0 0%" in report 1EkFl2aGmHnbIoJpcKqLr1dMsNteOuPv3fQwRxXgSyTz4hUAVBYiCDj

916 

917 def run_TheCode_and_report_it(self) -> str: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

918 """A helper for the next few tests.""" 

919 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

920 self.start_import_stop(cov, "TheCode") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

921 return self.get_report(cov) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

922 

923 def test_bug_203_mixed_case_listed_twice_with_rc(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

924 self.make_file("TheCode.py", "a = 1\n") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

925 self.make_file(".coveragerc", "[run]\nsource = .\n") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

926 

927 report = self.run_TheCode_and_report_it() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

928 assert "TheCode" in report 1EkFlaGmHn0bIoJpWcKqLrdMsNtZeOuPvfQwRxgSyTz4hUAVBYiCDj

929 assert "thecode" not in report 1EkFlaGmHn0bIoJpWcKqLrdMsNtZeOuPvfQwRxgSyTz4hUAVBYiCDj

930 

931 def test_bug_203_mixed_case_listed_twice(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

932 self.make_file("TheCode.py", "a = 1\n") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

933 

934 report = self.run_TheCode_and_report_it() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

935 

936 assert "TheCode" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

937 assert "thecode" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

938 

939 @pytest.mark.skipif(not env.WINDOWS, reason=".pyw files are only on Windows.") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

940 def test_pyw_files(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

941 # https://github.com/coveragepy/coveragepy/issues/261 

942 self.make_file( 12a0bWc1dZe3f5Xg64h7Yi8j

943 "start.pyw", 

944 """\ 

945 import mod 

946 print("In start.pyw") 

947 """, 

948 ) 

949 self.make_file( 12a0bWc1dZe3f5Xg64h7Yi8j

950 "mod.pyw", 

951 """\ 

952 print("In mod.pyw") 

953 """, 

954 ) 

955 cov = coverage.Coverage() 12a0bWc1dZe3f5Xg64h7Yi8j

956 # start_import_stop can't import the .pyw file, so use the long form. 

957 with cov.collect(): 12a0bWc1dZe3f5Xg64h7Yi8j

958 import start # pylint: disable=import-error, unused-import 1abcdefghij

959 

960 report = self.get_report(cov) 12a0bWc1dZe3fXghYij

961 assert "NoSource" not in report 12a0bWc1dZe3fXghYij

962 report_lines = report.splitlines() 12a0bWc1dZe3fXghYij

963 assert "start.pyw 2 0 100%" in report_lines 12a0bWc1dZe3fXghYij

964 assert "mod.pyw 1 0 100%" in report_lines 12a0bWc1dZe3fXghYij

965 

966 def test_tracing_pyc_file(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

967 # Create two Python files. 

968 self.make_file("mod.py", "a = 1\n") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

969 self.make_file("main.py", "import mod\n") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

970 

971 # Make one into a .pyc. 

972 py_compile.compile("mod.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

973 

974 # Run the program. 

975 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

976 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

977 

978 report_lines = self.get_report(cov).splitlines() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

979 assert "mod.py 1 0 100%" in report_lines 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

980 report = self.get_report(cov, squeeze=False, output_format="markdown") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

981 assert report.split("\n")[3] == "| mod.py | 1 | 0 | 100% |" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

982 assert report.split("\n")[4] == "| **TOTAL** | **2** | **0** | **100%** |" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

983 

984 def test_missing_py_file_during_run(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

985 # Create two Python files. 

986 self.make_file("mod.py", "a = 1\n") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

987 self.make_file("main.py", "import mod\n") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

988 

989 # Make one into a .pyc, and remove the .py. 

990 py_compile.compile("mod.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

991 os.remove("mod.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

992 

993 # Python 3 puts the .pyc files in a __pycache__ directory, and will 

994 # not import from there without source. It will import a .pyc from 

995 # the source location though. 

996 pycs = glob.glob("__pycache__/mod.*.pyc") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

997 assert len(pycs) == 1 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

998 os.rename(pycs[0], "mod.pyc") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

999 

1000 # Run the program. 

1001 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1002 self.start_import_stop(cov, "main") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1003 

1004 # Put back the missing Python file. 

1005 self.make_file("mod.py", "a = 1\n") 1EkFl2aGmHn0bIoJpcKqLr1dMsNteOuPv3fQwRxXgSyTz4hUAVBYiCDj

1006 report = self.get_report(cov).splitlines() 1EkFl2aGmHn0bIoJpcKqLr1dMsNteOuPv3fQwRxXgSyTz4hUAVBYiCDj

1007 assert "mod.py 1 0 100%" in report 1EkFl2aGmHn0bIoJpcKqLr1dMsNteOuPv3fQwRxXgSyTz4hUAVBYiCDj

1008 

1009 def test_empty_files(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1010 # Shows that empty files like __init__.py are listed as having zero 

1011 # statements, not one statement. 

1012 cov = coverage.Coverage(branch=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1013 with cov.collect(): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1014 import usepkgs # pylint: disable=import-error, unused-import 1klamnbopcqrdsteuvfwxgyzhABiCDj

1015 report = self.get_report(cov) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

1016 assert "tests/modules/pkg1/__init__.py 1 0 0 0 100%" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

1017 assert "tests/modules/pkg2/__init__.py 0 0 0 0 100%" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

1018 report = self.get_report(cov, squeeze=False, output_format="markdown") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

1019 # get_report() escapes backslash so we expect forward slash escaped 

1020 # underscore 

1021 assert "tests/modules/pkg1//_/_init/_/_.py " in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

1022 assert "| 1 | 0 | 0 | 0 | 100% |" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

1023 assert "tests/modules/pkg2//_/_init/_/_.py " in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

1024 assert "| 0 | 0 | 0 | 0 | 100% |" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBiCDj

1025 

1026 def test_markdown_with_missing(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1027 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1028 "mymissing.py", 

1029 """\ 

1030 def missing(x, y): 

1031 if x: 

1032 print("x") 

1033 return x 

1034 if y: 

1035 print("y") 

1036 try: 

1037 print("z") 

1038 1/0 

1039 print("Never!") 

1040 except ZeroDivisionError: 

1041 pass 

1042 return x 

1043 missing(0, 1) 

1044 """, 

1045 ) 

1046 cov = coverage.Coverage(source=["."]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1047 self.start_import_stop(cov, "mymissing") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1048 assert self.stdout() == "y\nz\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1049 report = self.get_report(cov, squeeze=False, output_format="markdown", show_missing=True) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1050 

1051 # | Name | Stmts | Miss | Cover | Missing | 

1052 # |------------- | -------: | -------: | ------: | --------: | 

1053 # | mymissing.py | 14 | 3 | 79% | 3-4, 10 | 

1054 # | **TOTAL** | **14** | **3** | **79%** | | 

1055 assert self.line_count(report) == 4 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1056 report_lines = report.split("\n") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1057 assert report_lines[2] == "| mymissing.py | 14 | 3 | 79% | 3-4, 10 |" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1058 assert report_lines[3] == "| **TOTAL** | **14** | **3** | **79%** | |" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1059 

1060 assert self.get_report(cov, output_format="total") == "79\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1061 assert self.get_report(cov, output_format="total", precision=2) == "78.57\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1062 assert self.get_report(cov, output_format="total", precision=4) == "78.5714\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1063 

1064 def test_bug_1524(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1065 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1066 "bug1524.py", 

1067 """\ 

1068 class Mine: 

1069 @property 

1070 def thing(self) -> int: 

1071 return 17 

1072 

1073 print(Mine().thing) 

1074 """, 

1075 ) 

1076 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1077 self.start_import_stop(cov, "bug1524") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1078 assert self.stdout() == "17\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1079 report = self.get_report(cov) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1080 report_lines = report.splitlines() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1081 assert report_lines[2] == "bug1524.py 5 0 100%" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1082 

1083 

1084class ReportingReturnValueTest(CoverageTest): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1085 """Tests of reporting functions returning values.""" 

1086 

1087 def run_coverage(self) -> Coverage: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1088 """Run coverage on doit.py and return the coverage object.""" 

1089 self.make_file( 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1090 "doit.py", 

1091 """\ 

1092 a = 1 

1093 b = 2 

1094 c = 3 

1095 d = 4 

1096 if a > 10: 

1097 f = 6 

1098 g = 7 

1099 """, 

1100 ) 

1101 

1102 cov = coverage.Coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1103 self.start_import_stop(cov, "doit") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1104 return cov 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1105 

1106 def test_report(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1107 cov = self.run_coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1108 val = cov.report(include="*/doit.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1109 assert math.isclose(val, 6 / 7 * 100) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1110 

1111 def test_html(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1112 cov = self.run_coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1113 val = cov.html_report(include="*/doit.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1114 assert math.isclose(val, 6 / 7 * 100) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1115 

1116 def test_xml(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1117 cov = self.run_coverage() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1118 val = cov.xml_report(include="*/doit.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1119 assert math.isclose(val, 6 / 7 * 100) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1120 

1121 

1122class SummaryReporterConfigurationTest(CoverageTest): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1123 """Tests of SummaryReporter.""" 

1124 

1125 def make_rigged_file(self, filename: str, stmts: int, miss: int) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1126 """Create a file that will have specific results. 

1127 

1128 `stmts` and `miss` are ints, the number of statements, and 

1129 missed statements that should result. 

1130 """ 

1131 run = stmts - miss - 1 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1132 dont_run = miss 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1133 source = "" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1134 source += "a = 1\n" * run 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1135 source += "if a == 99:\n" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1136 source += " a = 2\n" * dont_run 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1137 self.make_file(filename, source) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1138 

1139 def get_summary_text(self, *options: tuple[str, TConfigValueIn]) -> str: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1140 """Get text output from the SummaryReporter. 

1141 

1142 The arguments are tuples: (name, value) for Coverage.set_option. 

1143 """ 

1144 self.make_rigged_file("file1.py", 339, 155) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1145 self.make_rigged_file("file2.py", 13, 3) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1146 self.make_rigged_file("file10.py", 234, 228) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1147 self.make_file("doit.py", "import file1, file2, file10") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1148 

1149 cov = Coverage(source=["."], omit=["doit.py"]) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1150 self.start_import_stop(cov, "doit") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1151 for name, value in options: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1152 cov.set_option(name, value) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1153 printer = SummaryReporter(cov) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1154 destination = io.StringIO() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1155 printer.report([], destination) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1156 return destination.getvalue() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1157 

1158 def test_test_data(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1159 # We use our own test files as test data. Check that our assumptions 

1160 # about them are still valid. We want the three columns of numbers to 

1161 # sort in three different orders. 

1162 report = self.get_summary_text() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1163 # Name Stmts Miss Cover 

1164 # ------------------------------ 

1165 # file1.py 339 155 54% 

1166 # file2.py 13 3 77% 

1167 # file10.py 234 228 3% 

1168 # ------------------------------ 

1169 # TOTAL 586 386 34% 

1170 lines = report.splitlines()[2:-2] 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1171 assert len(lines) == 3 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1172 nums = [list(map(int, l.replace("%", "").split()[1:])) for l in lines] 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1173 # [ 

1174 # [339, 155, 54], 

1175 # [ 13, 3, 77], 

1176 # [234, 228, 3] 

1177 # ] 

1178 assert nums[1][0] < nums[2][0] < nums[0][0] 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1179 assert nums[1][1] < nums[0][1] < nums[2][1] 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1180 assert nums[2][2] < nums[0][2] < nums[1][2] 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1181 

1182 def test_defaults(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1183 """Run the report with no configuration options.""" 

1184 report = self.get_summary_text() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1185 assert "Missing" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1186 assert "Branch" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1187 

1188 def test_print_missing(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1189 """Run the report printing the missing lines.""" 

1190 report = self.get_summary_text(("report:show_missing", True)) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1191 assert "Missing" in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1192 assert "Branch" not in report 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1193 

1194 def assert_ordering(self, text: str, *words: str) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1195 """Assert that the `words` appear in order in `text`.""" 

1196 indexes = list(map(text.find, words)) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1197 assert -1 not in indexes 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1198 msg = f"The words {words!r} don't appear in order in {text!r}" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1199 assert indexes == sorted(indexes), msg 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1200 

1201 def test_default_sort_report(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1202 # Sort the text report by the default (Name) column. 

1203 report = self.get_summary_text() 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1204 self.assert_ordering(report, "file1.py", "file2.py", "file10.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1205 

1206 def test_sort_report_by_name(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1207 # Sort the text report explicitly by the Name column. 

1208 report = self.get_summary_text(("report:sort", "Name")) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1209 self.assert_ordering(report, "file1.py", "file2.py", "file10.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1210 

1211 def test_sort_report_by_stmts(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1212 # Sort the text report by the Stmts column. 

1213 report = self.get_summary_text(("report:sort", "Stmts")) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1214 self.assert_ordering(report, "file2.py", "file10.py", "file1.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1215 

1216 def test_sort_report_by_missing(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1217 # Sort the text report by the Missing column. 

1218 report = self.get_summary_text(("report:sort", "Miss")) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1219 self.assert_ordering(report, "file2.py", "file1.py", "file10.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1220 

1221 def test_sort_report_by_cover(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1222 # Sort the text report by the Cover column. 

1223 report = self.get_summary_text(("report:sort", "Cover")) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1224 self.assert_ordering(report, "file10.py", "file1.py", "file2.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1225 

1226 def test_sort_report_by_cover_plus(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1227 # Sort the text report by the Cover column, including the explicit + sign. 

1228 report = self.get_summary_text(("report:sort", "+Cover")) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1229 self.assert_ordering(report, "file10.py", "file1.py", "file2.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1230 

1231 def test_sort_report_by_cover_reversed(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1232 # Sort the text report by the Cover column reversed. 

1233 report = self.get_summary_text(("report:sort", "-Cover")) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1234 self.assert_ordering(report, "file2.py", "file1.py", "file10.py") 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOuPv3fQwRxXgSyTz4hUAVBYiCDj

1235 

1236 def test_sort_report_by_invalid_option(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1237 # Sort the text report by a nonsense column. 

1238 msg = "Invalid sorting option: 'Xyzzy'" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1239 with pytest.raises(ConfigError, match=msg): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1240 self.get_summary_text(("report:sort", "Xyzzy")) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1241 

1242 def test_report_with_invalid_format(self) -> None: 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1243 # Ask for an invalid format. 

1244 msg = "Unknown report format choice: 'xyzzy'" 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1245 with pytest.raises(ConfigError, match=msg): 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj

1246 self.get_summary_text(("report:format", "xyzzy")) 1EkFl2aGmHn0bIoJpWcKqLr1dMsNtZeOu9Pv!3f5Qw#Rx$Xg6Sy%Tz'4h7UA(VB)Yi8CDj