Skip to content

Commit 615f9e1

Browse files
committed
fix: skipped tags falsely reported as uncovered when not at start of line
When a tag ({% endif %}, {% endfor %}, {% else %}, etc.) is not at the start of a line, the preceding TEXT token ends with a whitespace-only fragment with no newline terminator. That partial line is not executable content but was incorrectly added to source_lines. Extends the endblock fix to apply universally — built-in and user-defined end tags are all covered by the same condition.
1 parent b9bc324 commit 615f9e1

3 files changed

Lines changed: 50 additions & 6 deletions

File tree

django_coverage_plugin/plugin.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,10 @@ def lines(self):
349349
if lines[0].isspace():
350350
lineno += 1
351351
num_lines -= 1
352-
# When {% endblock %} is not at the start of a line, the
353-
# preceding TEXT token ends with whitespace and no newline.
352+
# When a tag is not at the start of a line, the preceding
353+
# TEXT token ends with whitespace and no newline.
354354
# That partial line is not executable content.
355-
if inblock and num_lines > 0 and (
355+
if num_lines > 0 and (
356356
lines[-1].isspace() and not lines[-1].endswith(("\n", "\r"))
357357
):
358358
num_lines -= 1

tests/test_flow.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,29 @@ def test_if(self):
2525
self.assertEqual(text.strip(), '')
2626
self.assert_analysis([1, 2], [2])
2727

28+
def test_endif_not_at_start_of_line(self):
29+
self.make_template("""\
30+
{% if foo %}
31+
Hello
32+
{% endif %}
33+
After
34+
""")
35+
text = self.run_django_coverage(context={'foo': False})
36+
self.assertEqual(text.strip(), 'After')
37+
self.assert_analysis([1, 2, 4], missing=[2])
38+
39+
def test_else_not_at_start_of_line(self):
40+
self.make_template("""\
41+
{% if foo %}
42+
Hello
43+
{% else %}
44+
Goodbye
45+
{% endif %}
46+
""")
47+
text = self.run_django_coverage(context={'foo': True})
48+
self.assertEqual(text.strip(), 'Hello')
49+
self.assert_analysis([1, 2, 4], missing=[4])
50+
2851
def test_if_else(self):
2952
self.make_template("""\
3053
{% if foo %}
@@ -84,6 +107,17 @@ def test_loop(self):
84107
self.assertEqual(text, "Before\n\nAfter\n")
85108
self.assert_analysis([1, 2, 3, 5], [3])
86109

110+
def test_endfor_not_at_start_of_line(self):
111+
self.make_template("""\
112+
{% for item in items %}
113+
{{ item }}
114+
{% endfor %}
115+
After
116+
""")
117+
text = self.run_django_coverage(context={'items': []})
118+
self.assertEqual(text.strip(), 'After')
119+
self.assert_analysis([1, 2, 4], missing=[2])
120+
87121
def test_loop_with_empty_clause(self):
88122
self.make_template("""\
89123
Before
@@ -135,7 +169,7 @@ def test_regroup(self):
135169
<ul><li>New York: 20</li><li>Chicago: 7</li></ul></li><li>Japan
136170
<ul><li>Tokyo: 33</li></ul></li></ul>
137171
"""))
138-
self.assert_analysis([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13])
172+
self.assert_analysis([1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 13])
139173

140174

141175
class IfChangedTest(DjangoPluginTestCase):
@@ -154,7 +188,7 @@ def test_ifchanged(self):
154188
'items': [("A", "X"), ("A", "Y"), ("B", "Z"), ("B", "W")],
155189
})
156190
self.assertEqual(squashed(text), 'AXYBZW')
157-
self.assert_analysis([1, 2, 3, 4, 5])
191+
self.assert_analysis([1, 2, 3, 5])
158192

159193
def test_ifchanged_variable(self):
160194
self.make_template("""\
@@ -170,7 +204,7 @@ def test_ifchanged_variable(self):
170204
'items': [("A", "X"), ("A", "Y"), ("B", "Z"), ("B", "W")],
171205
})
172206
self.assertEqual(squashed(text), 'AXYBZW')
173-
self.assert_analysis([1, 2, 3, 4, 5])
207+
self.assert_analysis([1, 2, 3, 5])
174208

175209

176210
@django_stop_before(4, 0)

tests/test_simple.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,16 @@ def test_with(self):
238238
self.assertEqual(text, "\nalpha = 1, beta = 2.\n\n")
239239
self.assert_analysis([1, 2])
240240

241+
def test_endwith_not_at_start_of_line(self):
242+
self.make_template("""\
243+
{% with alpha=1 %}
244+
{{ alpha }}
245+
{% endwith %}
246+
""")
247+
text = self.run_django_coverage()
248+
self.assertEqual(text.strip(), '1')
249+
self.assert_analysis([1, 2])
250+
241251

242252
class StringTemplateTest(DjangoPluginTestCase):
243253

0 commit comments

Comments
 (0)