summaryrefslogtreecommitdiff
path: root/tests/test_html.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_html.py')
-rw-r--r--tests/test_html.py131
1 files changed, 79 insertions, 52 deletions
diff --git a/tests/test_html.py b/tests/test_html.py
index 004ebbfb..d9ecb678 100644
--- a/tests/test_html.py
+++ b/tests/test_html.py
@@ -1,11 +1,14 @@
# -*- coding: utf-8 -*-
+# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
+# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
+
"""Tests that HTML generation is awesome."""
+import datetime
import os.path
import re
import coverage
-from coverage import env
import coverage.html
from coverage.misc import CoverageException, NotPython, NoSource
@@ -33,9 +36,9 @@ class HtmlTestHelpers(CoverageTest):
""")
def run_coverage(self, covargs=None, htmlargs=None):
- """Run coverage on main_file.py, and create an HTML report."""
+ """Run coverage.py on main_file.py, and create an HTML report."""
self.clean_local_file_imports()
- cov = coverage.coverage(**(covargs or {}))
+ cov = coverage.Coverage(**(covargs or {}))
self.start_import_stop(cov, "main_file")
cov.html_report(**(htmlargs or {}))
@@ -53,6 +56,21 @@ class HtmlTestHelpers(CoverageTest):
with open(filename) as f:
return f.read()
+ def get_html_index_content(self):
+ """Return the content of index.html.
+
+ Timestamps are replaced with a placeholder so that clocks don't matter.
+
+ """
+ with open("htmlcov/index.html") as f:
+ index = f.read()
+ index = re.sub(
+ r"created at \d{4}-\d{2}-\d{2} \d{2}:\d{2}",
+ r"created at YYYY-MM-DD HH:MM",
+ index,
+ )
+ return index
+
class HtmlDeltaTest(HtmlTestHelpers, CoverageTest):
"""Tests of the HTML delta speed-ups."""
@@ -60,7 +78,7 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest):
def setUp(self):
super(HtmlDeltaTest, self).setUp()
- # At least one of our tests monkey-patches the version of coverage,
+ # At least one of our tests monkey-patches the version of coverage.py,
# so grab it here to restore it later.
self.real_coverage_version = coverage.__version__
self.addCleanup(self.restore_coverage_version)
@@ -86,8 +104,7 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest):
# In this case, helper1 changes because its source is different.
self.create_initial_files()
self.run_coverage()
- with open("htmlcov/index.html") as f:
- index1 = f.read()
+ index1 = self.get_html_index_content()
self.remove_html_files()
# Now change a file and do it again
@@ -104,8 +121,7 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest):
self.assert_exists("htmlcov/helper1_py.html")
self.assert_doesnt_exist("htmlcov/main_file_py.html")
self.assert_doesnt_exist("htmlcov/helper2_py.html")
- with open("htmlcov/index.html") as f:
- index2 = f.read()
+ index2 = self.get_html_index_content()
self.assertMultiLineEqual(index1, index2)
def test_html_delta_from_coverage_change(self):
@@ -132,12 +148,11 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest):
def test_html_delta_from_settings_change(self):
# HTML generation can create only the files that have changed.
- # In this case, everything changes because the coverage settings have
- # changed.
+ # In this case, everything changes because the coverage.py settings
+ # have changed.
self.create_initial_files()
self.run_coverage(covargs=dict(omit=[]))
- with open("htmlcov/index.html") as f:
- index1 = f.read()
+ index1 = self.get_html_index_content()
self.remove_html_files()
self.run_coverage(covargs=dict(omit=['xyzzy*']))
@@ -147,18 +162,16 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest):
self.assert_exists("htmlcov/helper1_py.html")
self.assert_exists("htmlcov/main_file_py.html")
self.assert_exists("htmlcov/helper2_py.html")
- with open("htmlcov/index.html") as f:
- index2 = f.read()
+ index2 = self.get_html_index_content()
self.assertMultiLineEqual(index1, index2)
def test_html_delta_from_coverage_version_change(self):
# HTML generation can create only the files that have changed.
- # In this case, everything changes because the coverage version has
+ # In this case, everything changes because the coverage.py version has
# changed.
self.create_initial_files()
self.run_coverage()
- with open("htmlcov/index.html") as f:
- index1 = f.read()
+ index1 = self.get_html_index_content()
self.remove_html_files()
# "Upgrade" coverage.py!
@@ -171,8 +184,7 @@ class HtmlDeltaTest(HtmlTestHelpers, CoverageTest):
self.assert_exists("htmlcov/helper1_py.html")
self.assert_exists("htmlcov/main_file_py.html")
self.assert_exists("htmlcov/helper2_py.html")
- with open("htmlcov/index.html") as f:
- index2 = f.read()
+ index2 = self.get_html_index_content()
fixed_index2 = index2.replace("XYZZY", self.real_coverage_version)
self.assertMultiLineEqual(index1, fixed_index2)
@@ -183,8 +195,7 @@ class HtmlTitleTest(HtmlTestHelpers, CoverageTest):
def test_default_title(self):
self.create_initial_files()
self.run_coverage()
- with open("htmlcov/index.html") as f:
- index = f.read()
+ index = self.get_html_index_content()
self.assertIn("<title>Coverage report</title>", index)
self.assertIn("<h1>Coverage report:", index)
@@ -192,8 +203,7 @@ class HtmlTitleTest(HtmlTestHelpers, CoverageTest):
self.create_initial_files()
self.make_file(".coveragerc", "[html]\ntitle = Metrics & stuff!\n")
self.run_coverage()
- with open("htmlcov/index.html") as f:
- index = f.read()
+ index = self.get_html_index_content()
self.assertIn("<title>Metrics &amp; stuff!</title>", index)
self.assertIn("<h1>Metrics &amp; stuff!:", index)
@@ -203,8 +213,7 @@ class HtmlTitleTest(HtmlTestHelpers, CoverageTest):
"[html]\ntitle = «ταБЬℓσ» numbers"
)
self.run_coverage()
- with open("htmlcov/index.html") as f:
- index = f.read()
+ index = self.get_html_index_content()
self.assertIn(
"<title>&#171;&#964;&#945;&#1041;&#1068;&#8467;&#963;&#187;"
" numbers", index
@@ -218,8 +227,7 @@ class HtmlTitleTest(HtmlTestHelpers, CoverageTest):
self.create_initial_files()
self.make_file(".coveragerc", "[html]\ntitle = Good title\n")
self.run_coverage(htmlargs=dict(title="«ταБЬℓσ» & stüff!"))
- with open("htmlcov/index.html") as f:
- index = f.read()
+ index = self.get_html_index_content()
self.assertIn(
"<title>&#171;&#964;&#945;&#1041;&#1068;&#8467;&#963;&#187;"
" &amp; st&#252;ff!</title>", index
@@ -235,7 +243,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest):
def test_dotpy_not_python(self):
self.make_file("innocuous.py", "a = 1")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "innocuous")
self.make_file("innocuous.py", "<h1>This isn't python!</h1>")
msg = "Couldn't parse '.*innocuous.py' as Python source: .* at line 1"
@@ -244,7 +252,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest):
def test_dotpy_not_python_ignored(self):
self.make_file("innocuous.py", "a = 2")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "innocuous")
self.make_file("innocuous.py", "<h1>This isn't python!</h1>")
cov.html_report(ignore_errors=True)
@@ -271,7 +279,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest):
source = "exec(compile('','','exec'), {'__file__': 'liar.html'})"
self.make_file("liar.py", source)
self.make_file("liar.html", "{# Whoops, not python code #}")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "liar")
cov.html_report()
self.assert_exists("htmlcov/index.html")
@@ -284,14 +292,13 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest):
self.make_file("liar.py", source)
# Tokenize will raise an IndentationError if it can't dedent.
self.make_file("liar.html", "0\n 2\n 1\n")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "liar")
cov.html_report()
self.assert_exists("htmlcov/index.html")
- # TODO: enable this test, and then fix this:
- # https://bitbucket.org/ned/coveragepy/issue/351/files-with-incorrect-encoding-are-ignored
- def SKIP_THIS_decode_error(self):
+ def test_decode_error(self):
+ # https://bitbucket.org/ned/coveragepy/issue/351/files-with-incorrect-encoding-are-ignored
# imp.load_module won't load a file with an undecodable character
# in a comment, though Python will run them. So we'll change the
# file after running.
@@ -301,7 +308,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest):
# coding: utf8
a = 1 # Isn't this great?!
""")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "main")
# Create the undecodable version of the file. make_file is too helpful,
@@ -316,16 +323,13 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest):
cov.html_report()
html_report = self.get_html_report_content("sub/not_ascii.py")
- if env.PY2:
- expected = "# Isn&#39;t this great?&#65533;!"
- else:
- expected = "# Isn&#39;t this great?&#203;!"
+ expected = "# Isn&#39;t this great?&#65533;!"
self.assertIn(expected, html_report)
def test_formfeeds(self):
# https://bitbucket.org/ned/coveragepy/issue/360/html-reports-get-confused-by-l-in-the-code
self.make_file("formfeed.py", "line_one = 1\n\f\nline_two = 2\n")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "formfeed")
cov.html_report()
@@ -333,7 +337,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest):
self.assertIn("line_two", formfeed_html)
-class HtmlTest(CoverageTest):
+class HtmlTest(HtmlTestHelpers, CoverageTest):
"""Moar HTML tests."""
def test_missing_source_file_incorrect_message(self):
@@ -341,7 +345,7 @@ class HtmlTest(CoverageTest):
self.make_file("thefile.py", "import sub.another\n")
self.make_file("sub/__init__.py", "")
self.make_file("sub/another.py", "print('another')\n")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, 'thefile')
os.remove("sub/another.py")
@@ -352,16 +356,39 @@ class HtmlTest(CoverageTest):
cov.html_report()
def test_extensionless_file_collides_with_extension(self):
- # It used to be that "afile" and "afile.py" would both be reported to
- # "afile.html". Now they are not.
+ # It used to be that "program" and "program.py" would both be reported
+ # to "program.html". Now they are not.
# https://bitbucket.org/ned/coveragepy/issue/69
- self.make_file("afile", "import afile\n")
- self.make_file("afile.py", "a = 1\n")
- self.run_command("coverage run afile")
+ self.make_file("program", "import program\n")
+ self.make_file("program.py", "a = 1\n")
+ self.run_command("coverage run program")
self.run_command("coverage html")
self.assert_exists("htmlcov/index.html")
- self.assert_exists("htmlcov/afile.html")
- self.assert_exists("htmlcov/afile_py.html")
+ self.assert_exists("htmlcov/program.html")
+ self.assert_exists("htmlcov/program_py.html")
+
+ def test_has_date_stamp_in_files(self):
+ self.create_initial_files()
+ self.run_coverage()
+
+ with open("htmlcov/index.html") as f:
+ self.assert_correct_timestamp(f.read())
+ with open("htmlcov/main_file_py.html") as f:
+ self.assert_correct_timestamp(f.read())
+
+ def assert_correct_timestamp(self, html):
+ """Extract the timestamp from `html`, and assert it is recent."""
+ timestamp_pat = r"created at (\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})"
+ m = re.search(timestamp_pat, html)
+ self.assertTrue(m, "Didn't find a timestamp!")
+ timestamp = datetime.datetime(*map(int, m.groups()))
+ # The timestamp only records the minute, so the delta could be from
+ # 12:00 to 12:01:59, or two minutes.
+ self.assert_recent_datetime(
+ timestamp,
+ seconds=120,
+ msg="Timestamp is wrong: {0}".format(timestamp),
+ )
class HtmlStaticFileTest(CoverageTest):
@@ -382,7 +409,7 @@ class HtmlStaticFileTest(CoverageTest):
coverage.html.STATIC_PATH.insert(0, "static_here")
self.make_file("main.py", "print(17)")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "main")
cov.html_report()
@@ -403,7 +430,7 @@ class HtmlStaticFileTest(CoverageTest):
coverage.html.STATIC_PATH.insert(0, "static_here")
self.make_file("main.py", "print(17)")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "main")
cov.html_report()
@@ -418,7 +445,7 @@ class HtmlStaticFileTest(CoverageTest):
coverage.html.STATIC_PATH = ["/xyzzy"]
self.make_file("main.py", "print(17)")
- cov = coverage.coverage()
+ cov = coverage.Coverage()
self.start_import_stop(cov, "main")
msg = "Couldn't find static file u?'.*'"
with self.assertRaisesRegex(CoverageException, msg):