diff --git a/django_coverage_plugin/plugin.py b/django_coverage_plugin/plugin.py
index 13e9c41..4037558 100644
--- a/django_coverage_plugin/plugin.py
+++ b/django_coverage_plugin/plugin.py
@@ -349,6 +349,13 @@ def lines(self):
if lines[0].isspace():
lineno += 1
num_lines -= 1
+ # When a tag is not at the start of a line, the preceding
+ # TEXT token ends with whitespace and no newline.
+ # That partial line is not executable content.
+ if num_lines > 0 and (
+ lines[-1].isspace() and not lines[-1].endswith(("\n", "\r"))
+ ):
+ num_lines -= 1
source_lines.update(range(lineno, lineno+num_lines))
if SHOW_PARSING:
diff --git a/tests/test_extends.py b/tests/test_extends.py
index 3f7a987..43dd0dc 100644
--- a/tests/test_extends.py
+++ b/tests/test_extends.py
@@ -95,6 +95,74 @@ def test_inheriting_with_unused_blocks(self):
self.assert_analysis([1, 2, 3], name="base.html")
self.assert_analysis([1, 4, 8], [8], name="specific.html")
+ def test_empty_parent_block_on_new_line_when_extended(self):
+ """
+ When a block is empty and extended, endblock should not appear
+ as an uncovered line.
+
+ https://github.com/coveragepy/django_coverage_plugin/issues/74
+ """
+ self.make_template(name="base.html", text="""\
+ Hello
+ {% block content %}
+ {% endblock content %}
+ Goodbye
+ """)
+ self.make_template(name="child.html", text="""\
+ {% extends "base.html" %}
+ {% block content %}
+ Override
+ {% endblock %}
+ """)
+ text = self.run_django_coverage(name="child.html")
+ self.assert_analysis([1, 2, 4], name="base.html")
+ self.assert_analysis([1, 3], name="child.html")
+ self.assertEqual(text.strip(), "Hello\n \n Override\n\nGoodbye")
+
+ def test_non_empty_parent_block_when_extended(self):
+ self.make_template(name="base.html", text="""\
+ Hello
+ {% block content %}
+ This line should be reported as uncovered.
+ {% endblock content %}
+ Goodbye
+ """)
+ self.make_template(name="child.html", text="""\
+ {% extends "base.html" %}
+ {% block content %}
+ Override
+ {% endblock %}
+ """)
+ text = self.run_django_coverage(name="child.html")
+ self.assert_analysis([1, 2, 3, 5], missing=[3], name="base.html")
+ self.assert_analysis([1, 3], name="child.html")
+
+ self.assertEqual(text.strip(), "Hello\n \n Override\n\nGoodbye")
+
+ def test_nested_blocks_outer_endblock_on_its_own_line(self):
+ """
+ When blocks are nested, on their own lines, and extended,
+ then endblock should not appear as uncovered.
+
+ Ref: https://github.com/coveragepy/django_coverage_plugin/issues/74
+ """
+ self.make_template(name="base.html", text="""\
+ {% block outer %}
+ {% block inner %}
+ {% endblock inner %}
+ {% endblock outer %}
+ """)
+ self.make_template(name="child.html", text="""\
+ {% extends "base.html" %}
+ {% block inner %}
+ Override
+ {% endblock %}
+ """)
+ text = self.run_django_coverage(name="child.html")
+ self.assert_analysis([1, 2], missing=[], name="base.html")
+ self.assert_analysis([1, 3], name="child.html")
+ self.assertEqual(text.strip(), "Override")
+
class LoadTest(DjangoPluginTestCase):
def test_load(self):
diff --git a/tests/test_flow.py b/tests/test_flow.py
index db83fa8..0bc7420 100644
--- a/tests/test_flow.py
+++ b/tests/test_flow.py
@@ -25,6 +25,31 @@ def test_if(self):
self.assertEqual(text.strip(), '')
self.assert_analysis([1, 2], [2])
+ def test_endif_not_at_start_of_line(self):
+ self.make_template("""\
+