# -*- coding: utf-8 -*- """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 from tests.coveragetest import CoverageTest class HtmlTestHelpers(CoverageTest): """Methods that help with HTML tests.""" def create_initial_files(self): """Create the source files we need to run these tests.""" self.make_file("main_file.py", """\ import helper1, helper2 helper1.func1(12) helper2.func2(12) """) self.make_file("helper1.py", """\ def func1(x): if x % 2: print("odd") """) self.make_file("helper2.py", """\ def func2(x): print("x is %d" % x) """) def run_coverage(self, covargs=None, htmlargs=None): """Run coverage on main_file.py, and create an HTML report.""" self.clean_local_file_imports() cov = coverage.coverage(**(covargs or {})) self.start_import_stop(cov, "main_file") cov.html_report(**(htmlargs or {})) def remove_html_files(self): """Remove the HTML files created as part of the HTML report.""" os.remove("htmlcov/index.html") os.remove("htmlcov/main_file_py.html") os.remove("htmlcov/helper1_py.html") os.remove("htmlcov/helper2_py.html") def get_html_report_content(self, module): """Return the content of the HTML report for `module`.""" filename = module.replace(".", "_").replace("/", "_") + ".html" filename = os.path.join("htmlcov", filename) with open(filename) as f: return f.read() class HtmlDeltaTest(HtmlTestHelpers, CoverageTest): """Tests of the HTML delta speed-ups.""" def setUp(self): super(HtmlDeltaTest, self).setUp() # At least one of our tests monkey-patches the version of coverage, # so grab it here to restore it later. self.real_coverage_version = coverage.__version__ self.addCleanup(self.restore_coverage_version) def restore_coverage_version(self): """A cleanup.""" coverage.__version__ = self.real_coverage_version def test_html_created(self): # Test basic HTML generation: files should be created. self.create_initial_files() self.run_coverage() self.assert_exists("htmlcov/index.html") self.assert_exists("htmlcov/main_file_py.html") self.assert_exists("htmlcov/helper1_py.html") self.assert_exists("htmlcov/helper2_py.html") self.assert_exists("htmlcov/style.css") self.assert_exists("htmlcov/coverage_html.js") def test_html_delta_from_source_change(self): # HTML generation can create only the files that have changed. # 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() self.remove_html_files() # Now change a file and do it again self.make_file("helper1.py", """\ def func1(x): # A nice function if x % 2: print("odd") """) self.run_coverage() # Only the changed files should have been created. self.assert_exists("htmlcov/index.html") 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() self.assertMultiLineEqual(index1, index2) def test_html_delta_from_coverage_change(self): # HTML generation can create only the files that have changed. # In this case, helper1 changes because its coverage is different. self.create_initial_files() self.run_coverage() self.remove_html_files() # Now change a file and do it again self.make_file("main_file.py", """\ import helper1, helper2 helper1.func1(23) helper2.func2(23) """) self.run_coverage() # Only the changed files should have been created. self.assert_exists("htmlcov/index.html") self.assert_exists("htmlcov/helper1_py.html") self.assert_exists("htmlcov/main_file_py.html") self.assert_doesnt_exist("htmlcov/helper2_py.html") 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. self.create_initial_files() self.run_coverage(covargs=dict(omit=[])) with open("htmlcov/index.html") as f: index1 = f.read() self.remove_html_files() self.run_coverage(covargs=dict(omit=['xyzzy*'])) # All the files have been reported again. self.assert_exists("htmlcov/index.html") 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() 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 # changed. self.create_initial_files() self.run_coverage() with open("htmlcov/index.html") as f: index1 = f.read() self.remove_html_files() # "Upgrade" coverage.py! coverage.__version__ = "XYZZY" self.run_coverage() # All the files have been reported again. self.assert_exists("htmlcov/index.html") 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() fixed_index2 = index2.replace("XYZZY", self.real_coverage_version) self.assertMultiLineEqual(index1, fixed_index2) class HtmlTitleTest(HtmlTestHelpers, CoverageTest): """Tests of the HTML title support.""" def test_default_title(self): self.create_initial_files() self.run_coverage() with open("htmlcov/index.html") as f: index = f.read() self.assertIn("
Created on {time_stamp}
".format(time_stamp=time_stamp), index) class HtmlStaticFileTest(CoverageTest): """Tests of the static file copying for the HTML report.""" def setUp(self): super(HtmlStaticFileTest, self).setUp() self.original_path = list(coverage.html.STATIC_PATH) self.addCleanup(self.restore_static_path) def restore_static_path(self): """A cleanup.""" coverage.html.STATIC_PATH = self.original_path def test_copying_static_files_from_system(self): # Make a new place for static files. self.make_file("static_here/jquery.min.js", "Not Really JQuery!") coverage.html.STATIC_PATH.insert(0, "static_here") self.make_file("main.py", "print(17)") cov = coverage.coverage() self.start_import_stop(cov, "main") cov.html_report() with open("htmlcov/jquery.min.js") as f: jquery = f.read() self.assertEqual(jquery, "Not Really JQuery!") def test_copying_static_files_from_system_in_dir(self): # Make a new place for static files. INSTALLED = [ "jquery/jquery.min.js", "jquery-hotkeys/jquery.hotkeys.js", "jquery-isonscreen/jquery.isonscreen.js", "jquery-tablesorter/jquery.tablesorter.min.js", ] for fpath in INSTALLED: self.make_file(os.path.join("static_here", fpath), "Not real.") coverage.html.STATIC_PATH.insert(0, "static_here") self.make_file("main.py", "print(17)") cov = coverage.coverage() self.start_import_stop(cov, "main") cov.html_report() for fpath in INSTALLED: the_file = os.path.basename(fpath) with open(os.path.join("htmlcov", the_file)) as f: contents = f.read() self.assertEqual(contents, "Not real.") def test_cant_find_static_files(self): # Make the path point to useless places. coverage.html.STATIC_PATH = ["/xyzzy"] self.make_file("main.py", "print(17)") cov = coverage.coverage() self.start_import_stop(cov, "main") msg = "Couldn't find static file u?'.*'" with self.assertRaisesRegex(CoverageException, msg): cov.html_report()