diff options
Diffstat (limited to 'tests/test_html.py')
-rw-r--r-- | tests/test_html.py | 131 |
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 & stuff!</title>", index) self.assertIn("<h1>Metrics & 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>«ταБЬℓσ»" " 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>«ταБЬℓσ»" " & stü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't this great?�!" - else: - expected = "# Isn't this great?Ë!" + expected = "# Isn't this great?�!" 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): |