|
8 | 8 | import textwrap
|
9 | 9 |
|
10 | 10 | import coverage
|
| 11 | +from coverage import env |
11 | 12 | from coverage.files import abs_file
|
12 | 13 |
|
13 | 14 | from tests.coveragetest import CoverageTest
|
@@ -156,3 +157,127 @@ def test_map_paths_during_lcov_report(self) -> None:
|
156 | 157 | cov.lcov_report()
|
157 | 158 | contains("coverage.lcov", os_sep("src/program.py"))
|
158 | 159 | doesnt_contain("coverage.lcov", os_sep("ver1/program.py"), os_sep("ver2/program.py"))
|
| 160 | + |
| 161 | + |
| 162 | +class ReportWithJinjaTest(CoverageTest): |
| 163 | + """Tests of Jinja-like behavior. |
| 164 | +
|
| 165 | + Jinja2 compiles a template into Python code, and then runs the Python code |
| 166 | + to render the template. But during rendering, it uses the template name |
| 167 | + (for example, "template.j2") as the file name, not the Python code file |
| 168 | + name. Then during reporting, we will try to parse template.j2 as Python |
| 169 | + code. |
| 170 | +
|
| 171 | + If the file can be parsed, it's included in the report (as a Python file!). |
| 172 | + If it can't be parsed, then it's not included in the report. |
| 173 | +
|
| 174 | + These tests confirm that code doesn't raise an exception (as reported in |
| 175 | + #1553), and that the current (incorrect) behavior remains stable. Ideally, |
| 176 | + good.j2 wouldn't be listed at all, since we can't report on it accurately. |
| 177 | +
|
| 178 | + See https://github.com/nedbat/coveragepy/issues/1553 for more detail, and |
| 179 | + https://github.com/nedbat/coveragepy/issues/1623 for an issue about this |
| 180 | + behavior. |
| 181 | +
|
| 182 | + """ |
| 183 | + |
| 184 | + def make_files(self) -> None: |
| 185 | + """Create test files: two Jinja templates, and data from rendering them.""" |
| 186 | + # A Jinja2 file that is syntactically acceptable Python (though it wont run). |
| 187 | + self.make_file("good.j2", """\ |
| 188 | + {{ data }} |
| 189 | + line2 |
| 190 | + line3 |
| 191 | + """) |
| 192 | + # A Jinja2 file that is a Python syntax error. |
| 193 | + self.make_file("bad.j2", """\ |
| 194 | + This is data: {{ data }}. |
| 195 | + line 2 |
| 196 | + line 3 |
| 197 | + """) |
| 198 | + self.make_data_file( |
| 199 | + lines={ |
| 200 | + abs_file("good.j2"): [1, 3, 5, 7, 9], |
| 201 | + abs_file("bad.j2"): [1, 3, 5, 7, 9], |
| 202 | + } |
| 203 | + ) |
| 204 | + |
| 205 | + def test_report(self) -> None: |
| 206 | + self.make_files() |
| 207 | + cov = coverage.Coverage() |
| 208 | + cov.load() |
| 209 | + cov.report(show_missing=True) |
| 210 | + expected = textwrap.dedent("""\ |
| 211 | + Name Stmts Miss Cover Missing |
| 212 | + --------------------------------------- |
| 213 | + good.j2 3 1 67% 2 |
| 214 | + --------------------------------------- |
| 215 | + TOTAL 3 1 67% |
| 216 | + """) |
| 217 | + assert expected == self.stdout() |
| 218 | + |
| 219 | + def test_html(self) -> None: |
| 220 | + self.make_files() |
| 221 | + cov = coverage.Coverage() |
| 222 | + cov.load() |
| 223 | + cov.html_report() |
| 224 | + contains("htmlcov/index.html", """\ |
| 225 | + <tbody> |
| 226 | + <tr class="file"> |
| 227 | + <td class="name left"><a href="good_j2.html">good.j2</a></td> |
| 228 | + <td>3</td> |
| 229 | + <td>1</td> |
| 230 | + <td>0</td> |
| 231 | + <td class="right" data-ratio="2 3">67%</td> |
| 232 | + </tr> |
| 233 | + </tbody>""" |
| 234 | + ) |
| 235 | + doesnt_contain("htmlcov/index.html", "bad.j2") |
| 236 | + |
| 237 | + def test_xml(self) -> None: |
| 238 | + self.make_files() |
| 239 | + cov = coverage.Coverage() |
| 240 | + cov.load() |
| 241 | + cov.xml_report() |
| 242 | + contains("coverage.xml", 'filename="good.j2"') |
| 243 | + if env.PYVERSION >= (3, 8): # Py3.7 puts attributes in the other order. |
| 244 | + contains("coverage.xml", |
| 245 | + '<line number="1" hits="1"/>', |
| 246 | + '<line number="2" hits="0"/>', |
| 247 | + '<line number="3" hits="1"/>', |
| 248 | + ) |
| 249 | + doesnt_contain("coverage.xml", 'filename="bad.j2"') |
| 250 | + if env.PYVERSION >= (3, 8): # Py3.7 puts attributes in the other order. |
| 251 | + doesnt_contain("coverage.xml", '<line number="4"',) |
| 252 | + |
| 253 | + def test_json(self) -> None: |
| 254 | + self.make_files() |
| 255 | + cov = coverage.Coverage() |
| 256 | + cov.load() |
| 257 | + cov.json_report() |
| 258 | + contains("coverage.json", |
| 259 | + # Notice the .json report claims lines in good.j2 executed that |
| 260 | + # don't even exist in good.j2... |
| 261 | + '"files": {"good.j2": {"executed_lines": [1, 3, 5, 7, 9], ' + |
| 262 | + '"summary": {"covered_lines": 2, "num_statements": 3', |
| 263 | + ) |
| 264 | + doesnt_contain("coverage.json", "bad.j2") |
| 265 | + |
| 266 | + def test_lcov(self) -> None: |
| 267 | + self.make_files() |
| 268 | + cov = coverage.Coverage() |
| 269 | + cov.load() |
| 270 | + cov.lcov_report() |
| 271 | + with open("coverage.lcov") as lcov: |
| 272 | + actual = lcov.read() |
| 273 | + expected = textwrap.dedent("""\ |
| 274 | + TN: |
| 275 | + SF:good.j2 |
| 276 | + DA:1,1,FHs1rDakj9p/NAzMCu3Kgw |
| 277 | + DA:3,1,DGOyp8LEgI+3CcdFYw9uKQ |
| 278 | + DA:2,0,5iUbzxp9w7peeTPjJbvmBQ |
| 279 | + LF:3 |
| 280 | + LH:2 |
| 281 | + end_of_record |
| 282 | + """) |
| 283 | + assert expected == actual |
0 commit comments