Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ extensions if you like::
[django_coverage_plugin]
template_extensions = html, txt, tex, email

If you use ``pyproject.toml`` for tool configuration use::
Block tags can be excluded using regexes to match the block content;
for example, to exclude a custom template tag ``{% my_tag ... %}``, use::

[tool.coverage.run]
plugins = [
'django_coverage_plugin',
]
[run]
plugins = django_coverage_plugin

[django_coverage_plugin]
exclude_blocks = ["my_tag.+"]

[tool.coverage.django_coverage_plugin]
template_extensions = 'html, txt, tex, email'

Caveats
~~~~~~~
Expand Down
34 changes: 32 additions & 2 deletions django_coverage_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import django
import django.template
from coverage.exceptions import NoSource
from coverage.misc import join_regex
from django.template.base import Lexer, NodeList, Template, TextNode, TokenType
from django.template.defaulttags import VerbatimNode
from django.templatetags.i18n import BlockTranslateNode
Expand Down Expand Up @@ -117,6 +118,10 @@ def __init__(self, options):
extensions = options.get("template_extensions", "html,htm,txt")
self.extensions = [e.strip() for e in extensions.split(",")]

self.exclude_blocks = options.get("exclude_blocks")

self.exclude_blocks = options.get("exclude_blocks")

self.debug_checked = False

self.django_template_dir = os.path.normcase(os.path.realpath(
Expand Down Expand Up @@ -151,7 +156,7 @@ def file_tracer(self, filename):
return None

def file_reporter(self, filename):
return FileReporter(filename)
return FileReporter(filename, self.exclude_blocks)

def find_executable_files(self, src_dir):
# We're only interested in files that look like reasonable HTML
Expand Down Expand Up @@ -259,10 +264,16 @@ def get_line_map(self, filename):


class FileReporter(coverage.plugin.FileReporter):
def __init__(self, filename):
def __init__(self, filename, exclude_blocks):
super().__init__(filename)
# TODO: html filenames are absolute.

if exclude_blocks:
self.exclude_blocks_regex = re.compile(join_regex(exclude_blocks))
else:
self.exclude_blocks_regex = None
self._excluded = set()

self._source = None

def source(self):
Expand Down Expand Up @@ -319,6 +330,18 @@ def lines(self):
# blocks.
continue

# Ignore any block token content that has been explcitly
# excluded in config
if self.exclude_block_token(token):
self._excluded.add(token.lineno)
continue

# Ignore any block token content that has been explcitly
# excluded in config
if self.exclude_block_token(token):
self._excluded.add(token.lineno)
continue

if token.contents == "comment":
comment = True
if token.contents.startswith("end"):
Expand Down Expand Up @@ -356,6 +379,13 @@ def lines(self):

return source_lines

def excluded_lines(self):
return self._excluded

def exclude_block_token(self, token):
if self.exclude_blocks_regex:
return self.exclude_blocks_regex.search(token.contents)


def running_sum(seq):
total = 0
Expand Down
27 changes: 27 additions & 0 deletions tests/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,30 @@ def test_with_branch_enabled(self):
)
self.assertEqual(text, 'Hello\nWorld\n\nGoodbye')
self.assert_analysis([1, 2, 3, 4])


class ExcludeTest(DjangoPluginTestCase):
"""Tests of excluding block tokens by regex."""

def test_exclude_block(self):
self.make_template("""\
First
{% with foo='bar' %}
{{ foo }}
{% endwith %}
Last
""")
text = self.run_django_coverage()
self.assertEqual(text, "First\n\n bar\n\nLast\n")
self.assert_analysis([1, 2, 3, 5])

self.make_file(".coveragerc", """\
[run]
plugins = django_coverage_plugin
[django_coverage_plugin]
exclude_blocks = [".+foo.+"]
""")

text = self.run_django_coverage()
self.assertEqual(text, "First\n\n bar\n\nLast\n")
self.assert_analysis([1, 3, 5])