Skip to content

Add a configuration option to allow block tags to be excluded by regex #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
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 @@ -91,15 +91,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
26 changes: 24 additions & 2 deletions django_coverage_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import os.path
import re

from coverage.misc import join_regex

try:
from coverage.exceptions import NoSource
except ImportError:
Expand Down Expand Up @@ -149,6 +151,8 @@ class DjangoTemplatePlugin(
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.debug_checked = False

Expand Down Expand Up @@ -184,7 +188,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 @@ -292,10 +296,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 @@ -351,6 +361,12 @@ def lines(self):
# In an inheriting template, ignore all tags outside of
# 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

if token.contents == "comment":
comment = True
Expand Down Expand Up @@ -389,6 +405,12 @@ 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])