Skip to content

fix: raise a Coverage-handlable exception if a file can't be read. #78 #83

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

Merged
merged 1 commit into from
Nov 10, 2021
Merged
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
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ To run the tests::
History
~~~~~~~

Unreleased
----------

If a non-UTF8 file was found when looking for templates, it would fail when
reading during the reporting phase, ending execution. This failure is now
raised in a way that can be ignored with a .coveragerc setting of ``[report]
ignore_errors=True`` (`issue 78`_).

.. _issue 78: https://github.com/nedbat/django_coverage_plugin/issues/78


v2.0.1 --- 2021-10-06
---------------------

Expand Down
10 changes: 9 additions & 1 deletion django_coverage_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
import os.path
import re

try:
from coverage.exceptions import NoSource
except ImportError:
# for coverage 5.x
from coverage.misc import NoSource
import coverage.plugin
import django
import django.template
Expand Down Expand Up @@ -303,7 +308,10 @@ def __init__(self, filename):

def source(self):
if self._source is None:
self._source = read_template_source(self.filename)
try:
self._source = read_template_source(self.filename)
except (IOError, UnicodeError) as exc:
raise NoSource("Couldn't read {}: {}".format(self.filename, exc))
return self._source

def lines(self):
Expand Down
70 changes: 70 additions & 0 deletions tests/test_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

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

import os

try:
from coverage.exceptions import NoSource
except ImportError:
# for coverage 5.x
from coverage.misc import NoSource

from .plugin_test import DjangoPluginTestCase


Expand Down Expand Up @@ -64,3 +72,65 @@ def test_customized_extensions(self):
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")

def test_non_utf8_error(self):
# A non-UTF8 text file will raise an error.
self.make_file(".coveragerc", """\
[run]
plugins = django_coverage_plugin
source = .
""")
# This is a template that is rendered.
self.make_template(name="main.html", text="Hello")
# Extra file containing a word encoded in CP-1252
self.make_file(self._path("static/changelog.txt"), bytes=b"sh\xf6n")

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

self.assert_measured_files("main.html", "static{}changelog.txt".format(os.sep))
self.assert_analysis([1], name="main.html")
with self.assertRaisesRegexp(NoSource, r"changelog.txt.*invalid start byte"):
self.cov.html_report()

def test_non_utf8_omitted(self):
# If we omit the directory with the non-UTF8 file, all is well.
self.make_file(".coveragerc", """\
[run]
plugins = django_coverage_plugin
source = .
[report]
omit = */static/*
""")
# This is a template that is rendered.
self.make_template(name="main.html", text="Hello")
# Extra file containing a word encoded in CP-1252
self.make_file(self._path("static/changelog.txt"), bytes=b"sh\xf6n")

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

self.assert_measured_files("main.html", "static{}changelog.txt".format(os.sep))
self.assert_analysis([1], name="main.html")
self.cov.html_report()

def test_non_utf8_ignored(self):
# If we ignore reporting errors, a non-UTF8 text file is fine.
self.make_file(".coveragerc", """\
[run]
plugins = django_coverage_plugin
source = .
[report]
ignore_errors = True
""")
# This is a template that is rendered.
self.make_template(name="main.html", text="Hello")
# Extra file containing a word encoded in CP-1252
self.make_file(self._path("static/changelog.txt"), bytes=b"sh\xf6n")

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

self.assert_measured_files("main.html", "static{}changelog.txt".format(os.sep))
self.assert_analysis([1], name="main.html")
self.cov.html_report()