Index: tools/telemetry/third_party/coverage/tests/test_html.py |
diff --git a/tools/telemetry/third_party/coverage/tests/test_html.py b/tools/telemetry/third_party/coverage/tests/test_html.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..11f0979aa66e78770bd2118bfae22833cc65a5cd |
--- /dev/null |
+++ b/tools/telemetry/third_party/coverage/tests/test_html.py |
@@ -0,0 +1,769 @@ |
+# -*- 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 glob |
+import os |
+import os.path |
+import re |
+import sys |
+ |
+import coverage |
+import coverage.files |
+import coverage.html |
+from coverage.misc import CoverageException, NotPython, NoSource |
+ |
+from tests.coveragetest import CoverageTest |
+from tests.goldtest import CoverageGoldTest |
+from tests.goldtest import change_dir, compare, contains, doesnt_contain, contains_any |
+ |
+ |
+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.py 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() |
+ |
+ 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 |
+ |
+ 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 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.py, |
+ # so grab it here to restore it later. |
+ self.real_coverage_version = coverage.__version__ |
+ self.addCleanup(self.cleanup_coverage_version) |
+ |
+ def cleanup_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() |
+ index1 = self.get_html_index_content() |
+ 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") |
+ index2 = self.get_html_index_content() |
+ 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.py settings |
+ # have changed. |
+ self.create_initial_files() |
+ self.run_coverage(covargs=dict(omit=[])) |
+ index1 = self.get_html_index_content() |
+ 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") |
+ 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.py version has |
+ # changed. |
+ self.create_initial_files() |
+ self.run_coverage() |
+ index1 = self.get_html_index_content() |
+ 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") |
+ index2 = self.get_html_index_content() |
+ 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() |
+ index = self.get_html_index_content() |
+ self.assertIn("<title>Coverage report</title>", index) |
+ self.assertIn("<h1>Coverage report:", index) |
+ |
+ def test_title_set_in_config_file(self): |
+ self.create_initial_files() |
+ self.make_file(".coveragerc", "[html]\ntitle = Metrics & stuff!\n") |
+ self.run_coverage() |
+ index = self.get_html_index_content() |
+ self.assertIn("<title>Metrics & stuff!</title>", index) |
+ self.assertIn("<h1>Metrics & stuff!:", index) |
+ |
+ def test_non_ascii_title_set_in_config_file(self): |
+ self.create_initial_files() |
+ self.make_file(".coveragerc", "[html]\ntitle = «ταБЬℓσ» numbers") |
+ self.run_coverage() |
+ index = self.get_html_index_content() |
+ self.assertIn( |
+ "<title>«ταБЬℓσ»" |
+ " numbers", index |
+ ) |
+ self.assertIn( |
+ "<h1>«ταБЬℓσ»" |
+ " numbers", index |
+ ) |
+ |
+ def test_title_set_in_args(self): |
+ self.create_initial_files() |
+ self.make_file(".coveragerc", "[html]\ntitle = Good title\n") |
+ self.run_coverage(htmlargs=dict(title="«ταБЬℓσ» & stüff!")) |
+ index = self.get_html_index_content() |
+ self.assertIn( |
+ "<title>«ταБЬℓσ»" |
+ " & stüff!</title>", index |
+ ) |
+ self.assertIn( |
+ "<h1>«ταБЬℓσ»" |
+ " & stüff!:", index |
+ ) |
+ |
+ |
+class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest): |
+ """Test the behavior when measuring unparsable files.""" |
+ |
+ def test_dotpy_not_python(self): |
+ self.make_file("innocuous.py", "a = 1") |
+ 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" |
+ with self.assertRaisesRegex(NotPython, msg): |
+ cov.html_report() |
+ |
+ def test_dotpy_not_python_ignored(self): |
+ self.make_file("innocuous.py", "a = 2") |
+ 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) |
+ self.assert_exists("htmlcov/index.html") |
+ # This would be better as a glob, if the HTML layout changes: |
+ self.assert_doesnt_exist("htmlcov/innocuous.html") |
+ |
+ def test_dothtml_not_python(self): |
+ # We run a .html file, and when reporting, we can't parse it as |
+ # Python. Since it wasn't .py, no error is reported. |
+ |
+ # Run an "HTML" file |
+ self.make_file("innocuous.html", "a = 3") |
+ self.run_command("coverage run innocuous.html") |
+ # Before reporting, change it to be an HTML file. |
+ self.make_file("innocuous.html", "<h1>This isn't python at all!</h1>") |
+ output = self.run_command("coverage html") |
+ self.assertEqual(output.strip(), "No data to report.") |
+ |
+ def test_execed_liar_ignored(self): |
+ # Jinja2 sets __file__ to be a non-Python file, and then execs code. |
+ # If that file contains non-Python code, a TokenError shouldn't |
+ # have been raised when writing the HTML report. |
+ 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() |
+ self.start_import_stop(cov, "liar") |
+ cov.html_report() |
+ self.assert_exists("htmlcov/index.html") |
+ |
+ def test_execed_liar_ignored_indentation_error(self): |
+ # Jinja2 sets __file__ to be a non-Python file, and then execs code. |
+ # If that file contains untokenizable code, we shouldn't get an |
+ # exception. |
+ source = "exec(compile('','','exec'), {'__file__': 'liar.html'})" |
+ 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() |
+ self.start_import_stop(cov, "liar") |
+ cov.html_report() |
+ self.assert_exists("htmlcov/index.html") |
+ |
+ 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. |
+ self.make_file("main.py", "import sub.not_ascii") |
+ self.make_file("sub/__init__.py") |
+ self.make_file("sub/not_ascii.py", """\ |
+ # coding: utf8 |
+ a = 1 # Isn't this great?! |
+ """) |
+ cov = coverage.Coverage() |
+ self.start_import_stop(cov, "main") |
+ |
+ # Create the undecodable version of the file. make_file is too helpful, |
+ # so get down and dirty with bytes. |
+ with open("sub/not_ascii.py", "wb") as f: |
+ f.write(b"# coding: utf8\na = 1 # Isn't this great?\xcb!\n") |
+ |
+ with open("sub/not_ascii.py", "rb") as f: |
+ undecodable = f.read() |
+ self.assertIn(b"?\xcb!", undecodable) |
+ |
+ cov.html_report() |
+ |
+ html_report = self.get_html_report_content("sub/not_ascii.py") |
+ 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() |
+ self.start_import_stop(cov, "formfeed") |
+ cov.html_report() |
+ |
+ formfeed_html = self.get_html_report_content("formfeed.py") |
+ self.assertIn("line_two", formfeed_html) |
+ |
+ |
+class HtmlTest(HtmlTestHelpers, CoverageTest): |
+ """Moar HTML tests.""" |
+ |
+ def test_missing_source_file_incorrect_message(self): |
+ # https://bitbucket.org/ned/coveragepy/issue/60 |
+ 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() |
+ self.start_import_stop(cov, 'thefile') |
+ os.remove("sub/another.py") |
+ |
+ missing_file = os.path.join(self.temp_dir, "sub", "another.py") |
+ missing_file = os.path.realpath(missing_file) |
+ msg = "(?i)No source for code: '%s'" % re.escape(missing_file) |
+ with self.assertRaisesRegex(NoSource, msg): |
+ cov.html_report() |
+ |
+ def test_extensionless_file_collides_with_extension(self): |
+ # 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("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/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 test_reporting_on_unmeasured_file(self): |
+ # It should be ok to ask for an HTML report on a file that wasn't even |
+ # measured at all. https://bitbucket.org/ned/coveragepy/issues/403 |
+ self.create_initial_files() |
+ self.make_file("other.py", "a = 1\n") |
+ self.run_coverage(htmlargs=dict(morfs=['other.py'])) |
+ self.assert_exists("htmlcov/index.html") |
+ self.assert_exists("htmlcov/other_py.html") |
+ |
+ def test_shining_panda_fix(self): |
+ # The ShiningPanda plugin looks for "status.dat" to find HTML reports. |
+ # Accomodate them, but only if we are running under Jenkins. |
+ self.set_environ("JENKINS_URL", "Something or other") |
+ self.create_initial_files() |
+ self.run_coverage() |
+ self.assert_exists("htmlcov/status.dat") |
+ |
+ |
+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.cleanup_static_path) |
+ |
+ def cleanup_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() |
+ |
+ |
+class HtmlGoldTests(CoverageGoldTest): |
+ """Tests of HTML reporting that use gold files.""" |
+ |
+ root_dir = 'tests/farm/html' |
+ |
+ def test_a(self): |
+ self.output_dir("out/a") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error |
+ cov = coverage.Coverage() |
+ cov.start() |
+ import a # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(a, directory='../out/a') |
+ |
+ compare("gold_a", "out/a", size_within=10, file_pattern="*.html") |
+ contains( |
+ "out/a/a_py.html", |
+ ('<span class="key">if</span> <span class="num">1</span> ' |
+ '<span class="op"><</span> <span class="num">2</span>'), |
+ (' <span class="nam">a</span> ' |
+ '<span class="op">=</span> <span class="num">3</span>'), |
+ '<span class="pc_cov">67%</span>', |
+ ) |
+ contains( |
+ "out/a/index.html", |
+ '<a href="a_py.html">a.py</a>', |
+ '<span class="pc_cov">67%</span>', |
+ '<td class="right" data-ratio="2 3">67%</td>', |
+ ) |
+ |
+ def test_b_branch(self): |
+ self.output_dir("out/b_branch") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error |
+ cov = coverage.Coverage(branch=True) |
+ cov.start() |
+ import b # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(b, directory="../out/b_branch") |
+ |
+ compare("gold_b_branch", "out/b_branch", size_within=10, file_pattern="*.html") |
+ contains( |
+ "out/b_branch/b_py.html", |
+ ('<span class="key">if</span> <span class="nam">x</span> ' |
+ '<span class="op"><</span> <span class="num">2</span>'), |
+ (' <span class="nam">a</span> <span class="op">=</span> ' |
+ '<span class="num">3</span>'), |
+ '<span class="pc_cov">70%</span>', |
+ ('<span class="annotate" title="Line 8 was executed, but never jumped to line 11">' |
+ '8 ↛ 11 [?]</span>'), |
+ ('<span class="annotate" title="Line 17 was executed, but never jumped ' |
+ 'to the function exit">17 ↛ exit [?]</span>'), |
+ ('<span class="annotate" title="Line 25 was executed, but never jumped ' |
+ 'to line 26 or line 28">25 ↛ 26, ' |
+ '25 ↛ 28 [?]</span>'), |
+ ) |
+ contains( |
+ "out/b_branch/index.html", |
+ '<a href="b_py.html">b.py</a>', |
+ '<span class="pc_cov">70%</span>', |
+ '<td class="right" data-ratio="16 23">70%</td>', |
+ ) |
+ |
+ def test_bom(self): |
+ self.output_dir("out/bom") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error |
+ cov = coverage.Coverage() |
+ cov.start() |
+ import bom # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(bom, directory="../out/bom") |
+ |
+ compare("gold_bom", "out/bom", size_within=10, file_pattern="*.html") |
+ contains( |
+ "out/bom/bom_py.html", |
+ '<span class="str">"3×4 = 12, ÷2 = 6±0"</span>', |
+ ) |
+ |
+ def test_isolatin1(self): |
+ self.output_dir("out/isolatin1") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error |
+ cov = coverage.Coverage() |
+ cov.start() |
+ import isolatin1 # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(isolatin1, directory="../out/isolatin1") |
+ |
+ compare("gold_isolatin1", "out/isolatin1", size_within=10, file_pattern="*.html") |
+ contains( |
+ "out/isolatin1/isolatin1_py.html", |
+ '<span class="str">"3×4 = 12, ÷2 = 6±0"</span>', |
+ ) |
+ |
+ def test_omit_1(self): |
+ self.output_dir("out/omit_1") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error, unused-variable |
+ cov = coverage.Coverage(include=["./*"]) |
+ cov.start() |
+ import main # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(directory="../out/omit_1") |
+ |
+ compare("gold_omit_1", "out/omit_1", size_within=10, file_pattern="*.html") |
+ |
+ def test_omit_2(self): |
+ self.output_dir("out/omit_2") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error, unused-variable |
+ cov = coverage.Coverage(include=["./*"]) |
+ cov.start() |
+ import main # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(directory="../out/omit_2", omit=["m1.py"]) |
+ |
+ compare("gold_omit_2", "out/omit_2", size_within=10, file_pattern="*.html") |
+ |
+ def test_omit_3(self): |
+ self.output_dir("out/omit_3") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error, unused-variable |
+ cov = coverage.Coverage(include=["./*"]) |
+ cov.start() |
+ import main # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(directory="../out/omit_3", omit=["m1.py", "m2.py"]) |
+ |
+ compare("gold_omit_3", "out/omit_3", size_within=10, file_pattern="*.html") |
+ |
+ def test_omit_4(self): |
+ self.output_dir("out/omit_4") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error, unused-variable |
+ cov = coverage.Coverage(config_file="omit4.ini", include=["./*"]) |
+ cov.start() |
+ import main # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(directory="../out/omit_4") |
+ |
+ compare("gold_omit_4", "out/omit_4", size_within=10, file_pattern="*.html") |
+ |
+ def test_omit_5(self): |
+ self.output_dir("out/omit_5") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error, unused-variable |
+ cov = coverage.Coverage(config_file="omit5.ini", include=["./*"]) |
+ cov.start() |
+ import main # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report() |
+ |
+ compare("gold_omit_5", "out/omit_5", size_within=10, file_pattern="*.html") |
+ |
+ def test_other(self): |
+ self.output_dir("out/other") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error, unused-variable |
+ sys.path.insert(0, "../othersrc") |
+ cov = coverage.Coverage(include=["./*", "../othersrc/*"]) |
+ cov.start() |
+ import here # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(directory="../out/other") |
+ |
+ # Different platforms will name the "other" file differently. Rename it |
+ for p in glob.glob("out/other/*_other_py.html"): |
+ os.rename(p, "out/other/blah_blah_other_py.html") |
+ |
+ compare("gold_other", "out/other", size_within=10, file_pattern="*.html") |
+ contains( |
+ "out/other/index.html", |
+ '<a href="here_py.html">here.py</a>', |
+ 'other_py.html">', 'other.py</a>', |
+ ) |
+ |
+ def test_partial(self): |
+ self.output_dir("out/partial") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error |
+ cov = coverage.Coverage(branch=True) |
+ cov.start() |
+ import partial # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(partial, directory="../out/partial") |
+ |
+ compare("gold_partial", "out/partial", size_within=10, file_pattern="*.html") |
+ contains( |
+ "out/partial/partial_py.html", |
+ '<p id="t8" class="stm run hide_run">', |
+ '<p id="t11" class="stm run hide_run">', |
+ '<p id="t14" class="stm run hide_run">', |
+ # The "if 0" and "if 1" statements are optimized away. |
+ '<p id="t17" class="pln">', |
+ ) |
+ contains( |
+ "out/partial/index.html", |
+ '<a href="partial_py.html">partial.py</a>', |
+ ) |
+ contains( |
+ "out/partial/index.html", |
+ '<span class="pc_cov">100%</span>' |
+ ) |
+ |
+ def test_styled(self): |
+ self.output_dir("out/styled") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error |
+ cov = coverage.Coverage() |
+ cov.start() |
+ import a # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(a, directory="../out/styled", extra_css="extra.css") |
+ |
+ compare("gold_styled", "out/styled", size_within=10, file_pattern="*.html") |
+ compare("gold_styled", "out/styled", size_within=10, file_pattern="*.css") |
+ contains( |
+ "out/styled/a_py.html", |
+ '<link rel="stylesheet" href="extra.css" type="text/css">', |
+ ('<span class="key">if</span> <span class="num">1</span> ' |
+ '<span class="op"><</span> <span class="num">2</span>'), |
+ (' <span class="nam">a</span> <span class="op">=</span> ' |
+ '<span class="num">3</span>'), |
+ '<span class="pc_cov">67%</span>' |
+ ) |
+ contains( |
+ "out/styled/index.html", |
+ '<link rel="stylesheet" href="extra.css" type="text/css">', |
+ '<a href="a_py.html">a.py</a>', |
+ '<span class="pc_cov">67%</span>' |
+ ) |
+ |
+ def test_tabbed(self): |
+ self.output_dir("out/tabbed") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error |
+ cov = coverage.Coverage() |
+ cov.start() |
+ import tabbed # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(tabbed, directory="../out/tabbed") |
+ |
+ # Editors like to change things, make sure our source file still has tabs. |
+ contains("src/tabbed.py", "\tif x:\t\t\t\t\t# look nice") |
+ |
+ contains( |
+ "out/tabbed/tabbed_py.html", |
+ '> <span class="key">if</span> ' |
+ '<span class="nam">x</span><span class="op">:</span>' |
+ ' ' |
+ ' ' |
+ '<span class="com"># look nice</span>' |
+ ) |
+ |
+ doesnt_contain("out/tabbed/tabbed_py.html", "\t") |
+ |
+ def test_unicode(self): |
+ self.output_dir("out/unicode") |
+ |
+ with change_dir("src"): |
+ # pylint: disable=import-error, redefined-builtin |
+ cov = coverage.Coverage() |
+ cov.start() |
+ import unicode # pragma: nested |
+ cov.stop() # pragma: nested |
+ cov.html_report(unicode, directory="../out/unicode") |
+ |
+ compare("gold_unicode", "out/unicode", size_within=10, file_pattern="*.html") |
+ contains( |
+ "out/unicode/unicode_py.html", |
+ ('<span class="str">"ʎd˙ǝbɐɹǝʌoɔ"' |
+ '</span>'), |
+ ) |
+ |
+ contains_any( |
+ "out/unicode/unicode_py.html", |
+ '<span class="str">"db40,dd00: x��"</span>', |
+ '<span class="str">"db40,dd00: x󠄀"</span>', |
+ ) |