Skip to content

Commit

Permalink
feat: template file extensions are configurable. #60
Browse files Browse the repository at this point in the history
  • Loading branch information
nedbat committed Jun 8, 2021
1 parent 3eee25d commit 07970d9
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 6 deletions.
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ Unreleased

Drop support for Python 3.4 and 3.5.

A setting is available: ``template_extensions`` lets you set the file
extensions that will be considered when looking for unused templates
(requested in `issue 60`_).

Fix an issue on Windows where file names were being compared
case-sensitively, causing templates to be missed (`issue 46`_).

Fix an issue (`issue 63`_) where tag libraries can't be found if imported
during test collection. Thanks to Daniel Izquierdo for the fix.

.. _issue 46: https://github.com/nedbat/django_coverage_plugin/issues/46
.. _issue 60: https://github.com/nedbat/django_coverage_plugin/issues/60
.. _issue 63: https://github.com/nedbat/django_coverage_plugin/issues/63

v1.8.0 --- 2020-01-23
Expand Down
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ The Django template plugin uses some existing settings from your
.coveragerc file. The ``source=``, ``include=``, and ``omit=`` options
control what template files are included in the report.

The plugin can find unused template and include them in your results. By
default, it will look for files in your templates directory with an extension
of .html, .htm, or .txt. You can configure it to look for a different set of
extensions if you like::

[run]
plugins = django_coverage_plugin

[django_coverage_plugin]
template_extensions = html, txt, tex, email


Caveats
~~~~~~~
Expand Down
2 changes: 1 addition & 1 deletion django_coverage_plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@


def coverage_init(reg, options):
reg.add_file_tracer(DjangoTemplatePlugin())
reg.add_file_tracer(DjangoTemplatePlugin(options))
15 changes: 10 additions & 5 deletions django_coverage_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,10 @@ class DjangoTemplatePlugin(
coverage.plugin.FileTracer,
):

def __init__(self):
def __init__(self, options):
extensions = options.get("template_extensions", "html,htm,txt")
self.extensions = [e.strip() for e in extensions.split(",")]

self.debug_checked = False

self.django_template_dir = os.path.normcase(os.path.realpath(
Expand Down Expand Up @@ -190,12 +193,14 @@ def file_reporter(self, filename):
return FileReporter(filename)

def find_executable_files(self, src_dir):
# We're only interested in files that look like reasonable HTML
# files: Must end with one of our extensions, and must not have
# funny characters that probably mean they are editor junk.
rx = r"^[^.#~!$@%^&*()+=,]+\.(" + "|".join(self.extensions) + r")$"

for (dirpath, dirnames, filenames) in os.walk(src_dir):
for filename in filenames:
# We're only interested in files that look like reasonable HTML
# files: Must end with .htm or .html, and must not have certain
# funny characters that probably mean they are editor junk.
if re.match(r"^[^.#~!$@%^&*()+=,]+\.html?$", filename):
if re.search(rx, filename):
yield os.path.join(dirpath, filename)

# --- FileTracer methods
Expand Down
66 changes: 66 additions & 0 deletions tests/test_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/django_coverage_plugin/blob/master/NOTICE.txt

"""Tests of template inheritance for django_coverage_plugin."""

from .plugin_test import DjangoPluginTestCase


class FindSourceTest(DjangoPluginTestCase):

def test_finding_source(self):
# This is a template that is rendered.
self.make_template(name="main.html", text="Hello")
# These are templates that aren't rendered, but are considered renderable.
self.make_template(name="unused.html", text="Not used")
self.make_template(name="unused.htm", text="Not used")
self.make_template(name="unused.txt", text="Not used")
# These are things left behind by an editor.
self.make_template(name="~unused.html", text="junk")
self.make_template(name="unused=.html", text="junk")
self.make_template(name="unused.html,", text="junk")
# This is some other file format we don't recognize.
self.make_template(name="phd.tex", text="Too complicated to read")

text = self.run_django_coverage(name="main.html")
self.assertEqual(text, "Hello")

# The rendered file has data, and was measured.
self.assert_analysis([1], name="main.html")
# The unrendered files have data, and were not measured.
self.assert_analysis([1], name="unused.html", missing=[1])
self.assert_analysis([1], name="unused.htm", missing=[1])
self.assert_analysis([1], name="unused.txt", missing=[1])
# The editor leave-behinds are not in the measured files.
self.assert_measured_files("main.html", "unused.html", "unused.htm", "unused.txt")

def test_customized_extensions(self):
self.make_file(".coveragerc", """\
[run]
plugins = django_coverage_plugin
[django_coverage_plugin]
template_extensions = html, tex
""")
# This is a template that is rendered.
self.make_template(name="main.html", text="Hello")
# These are templates that aren't rendered, but are considered renderable.
self.make_template(name="unused.html", text="Not used")
self.make_template(name="phd.tex", text="Too complicated to read")
# These are things left behind by an editor.
self.make_template(name="~unused.html", text="junk")
self.make_template(name="unused=.html", text="junk")
self.make_template(name="unused.html,", text="junk")
# This is some other file format we don't recognize.
self.make_template(name="unused.htm", text="Not used")
self.make_template(name="unused.txt", text="Not used")

text = self.run_django_coverage(name="main.html")
self.assertEqual(text, "Hello")

# The rendered file has data, and was measured.
self.assert_analysis([1], name="main.html")
# The unrendered files have data, and were not measured.
self.assert_analysis([1], name="unused.html", missing=[1])
self.assert_analysis([1], name="phd.tex", missing=[1])
# The editor leave-behinds are not in the measured files.
self.assert_measured_files("main.html", "unused.html", "phd.tex")

0 comments on commit 07970d9

Please sign in to comment.