diff options
Diffstat (limited to 'test')
101 files changed, 7626 insertions, 2177 deletions
diff --git a/test/backtest.py b/test/backtest.py index e8d8366d..b17aa242 100644 --- a/test/backtest.py +++ b/test/backtest.py @@ -1,6 +1,6 @@ """Add things to old Pythons so I can pretend they are newer, for tests.""" -# pylint: disable-msg=W0622 +# pylint: disable=W0622 # (Redefining built-in blah) # The whole point of this file is to redefine built-ins, so shut up about it. @@ -30,10 +30,10 @@ else: stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) - status = proc.wait() + output, _ = proc.communicate() + status = proc.returncode # pylint: disable=E1101 # Get the output, and canonicalize it to strings with newlines. - output = proc.stdout.read() if not isinstance(output, str): output = output.decode('utf-8') output = output.replace('\r', '') diff --git a/test/backunittest.py b/test/backunittest.py index f606185f..30da78eb 100644 --- a/test/backunittest.py +++ b/test/backunittest.py @@ -2,7 +2,7 @@ import difflib, re, sys, unittest -from coverage.backward import set # pylint: disable-msg=W0622 +from coverage.backward import set # pylint: disable=W0622 def _need(method): @@ -29,6 +29,27 @@ class TestCase(unittest.TestCase): if exp: self.fail(msg) + if _need('assertIn'): + def assertIn(self, member, container, msg=None): + """Assert that `member` is in `container`.""" + if member not in container: + msg = msg or ('%r not found in %r' % (member, container)) + self.fail(msg) + + if _need('assertNotIn'): + def assertNotIn(self, member, container, msg=None): + """Assert that `member` is not in `container`.""" + if member in container: + msg = msg or ('%r found in %r' % (member, container)) + self.fail(msg) + + if _need('assertGreater'): + def assertGreater(self, a, b, msg=None): + """Assert that `a` is greater than `b`.""" + if not a > b: + msg = msg or ('%r not greater than %r' % (a, b)) + self.fail(msg) + if _need('assertRaisesRegexp'): def assertRaisesRegexp(self, excClass, regexp, callobj, *args, **kw): """ Just like unittest.TestCase.assertRaises, @@ -46,7 +67,7 @@ class TestCase(unittest.TestCase): # Message provided, and it didn't match: fail! raise self.failureException( "Right exception, wrong message: " - "'%s' doesn't match '%s'" % (excMsg, regexp) + "%r doesn't match %r" % (excMsg, regexp) ) # No need to catch other exceptions: They'll fail the test all by # themselves! @@ -66,11 +87,12 @@ class TestCase(unittest.TestCase): self.assertEqual(set(s1), set(s2)) if _need('assertRegexpMatches'): - def assertRegexpMatches(self, s, regex): - """Assert that `s` matches `regex`.""" - m = re.search(regex, s) + def assertRegexpMatches(self, text, regex, msg=None): + """Assert that `text` matches `regex`.""" + m = re.search(regex, text) if not m: - raise self.failureException("%r doesn't match %r" % (s, regex)) + msg = msg or ("%r doesn't match %r" % (text, regex)) + raise self.failureException(msg) if _need('assertMultiLineEqual'): def assertMultiLineEqual(self, first, second, msg=None): diff --git a/test/coveragetest.py b/test/coveragetest.py index 53f0ef0b..4ae399cc 100644 --- a/test/coveragetest.py +++ b/test/coveragetest.py @@ -1,9 +1,10 @@ """Base test case class for coverage testing.""" -import imp, os, random, shlex, shutil, sys, tempfile, textwrap +import glob, imp, os, random, shlex, shutil, sys, tempfile, textwrap import coverage -from coverage.backward import sorted, StringIO # pylint: disable-msg=W0622 +from coverage.backward import sorted, StringIO # pylint: disable=W0622 +from coverage.backward import to_bytes from backtest import run_command from backunittest import TestCase @@ -21,6 +22,12 @@ class Tee(object): for f in self._files: f.write(data) + if 0: + # Use this if you need to use a debugger, though it makes some tests + # fail, I'm not sure why... + def __getattr__(self, name): + return getattr(self._files[0], name) + # Status returns for the command line. OK, ERR = 0, 1 @@ -31,6 +38,14 @@ class CoverageTest(TestCase): run_in_temp_dir = True def setUp(self): + super(CoverageTest, self).setUp() + + # Tell newer unittest implementations to print long helpful messages. + self.longMessage = True + + # tearDown will restore the original sys.path + self.old_syspath = sys.path[:] + if self.run_in_temp_dir: # Create a temporary directory. self.noise = str(random.random())[2:] @@ -40,9 +55,7 @@ class CoverageTest(TestCase): self.old_dir = os.getcwd() os.chdir(self.temp_dir) - # Modules should be importable from this temp directory. - self.old_syspath = sys.path[:] sys.path.insert(0, '') # Keep a counter to make every call to check_coverage unique. @@ -66,10 +79,12 @@ class CoverageTest(TestCase): self.old_modules = dict(sys.modules) def tearDown(self): - if self.run_in_temp_dir: - # Restore the original sys.path. - sys.path = self.old_syspath + super(CoverageTest, self).tearDown() + # Restore the original sys.path. + sys.path = self.old_syspath + + if self.run_in_temp_dir: # Get rid of the temporary directory. os.chdir(self.old_dir) shutil.rmtree(self.temp_root) @@ -81,8 +96,14 @@ class CoverageTest(TestCase): sys.stdout = self.old_stdout sys.stderr = self.old_stderr - # Remove any new modules imported during the test run. This lets us - # import the same source files for more than one test. + self.clean_modules() + + def clean_modules(self): + """Remove any new modules imported during the test run. + + This lets us import the same source files for more than one test. + + """ for m in [m for m in sys.modules if m not in self.old_modules]: del sys.modules[m] @@ -123,11 +144,12 @@ class CoverageTest(TestCase): """Return the data written to stderr during the test.""" return self.captured_stderr.getvalue() - def make_file(self, filename, text=""): + def make_file(self, filename, text="", newline=None): """Create a temp file. `filename` is the path to the file, including directories if desired, - and `text` is the content. + and `text` is the content. If `newline` is provided, it is a string + that will be used as the line endings in the created file. Returns the path to the file. @@ -135,6 +157,8 @@ class CoverageTest(TestCase): # Tests that call `make_file` should be run in a temp environment. assert self.run_in_temp_dir text = textwrap.dedent(text) + if newline: + text = text.replace("\n", newline) # Make sure the directories are available. dirs, _ = os.path.split(filename) @@ -142,12 +166,31 @@ class CoverageTest(TestCase): os.makedirs(dirs) # Create the file. - f = open(filename, 'w') - f.write(text) - f.close() + f = open(filename, 'wb') + try: + f.write(to_bytes(text)) + finally: + f.close() return filename + def clean_local_file_imports(self): + """Clean up the results of calls to `import_local_file`. + + Use this if you need to `import_local_file` the same file twice in + one test. + + """ + # So that we can re-import files, clean them out first. + self.clean_modules() + # Also have to clean out the .pyc file, since the timestamp + # resolution is only one second, a changed file might not be + # picked up. + for pyc in glob.glob('*.pyc'): + os.remove(pyc) + if os.path.exists("__pycache__"): + shutil.rmtree("__pycache__") + def import_local_file(self, modname): """Import a local file as a module. @@ -162,7 +205,7 @@ class CoverageTest(TestCase): if suff[0] == '.py': break try: - # pylint: disable-msg=W0631 + # pylint: disable=W0631 # (Using possibly undefined loop variable 'suff') mod = imp.load_module(modname, f, modfile, suff) finally: @@ -224,8 +267,9 @@ class CoverageTest(TestCase): s2 = "\n".join([repr(a) for a in a2]) + "\n" self.assertMultiLineEqual(s1, s2, msg) - def check_coverage(self, text, lines=None, missing="", excludes=None, - report="", arcz=None, arcz_missing="", arcz_unpredicted=""): + def check_coverage(self, text, lines=None, missing="", report="", + excludes=None, partials="", + arcz=None, arcz_missing="", arcz_unpredicted=""): """Check the coverage measurement of `text`. The source `text` is run and measured. `lines` are the line numbers @@ -258,6 +302,8 @@ class CoverageTest(TestCase): cov.erase() for exc in excludes or []: cov.exclude(exc) + for par in partials or []: + cov.exclude(par, which='partial') cov.start() try: # pragma: recursive coverage @@ -333,6 +379,16 @@ class CoverageTest(TestCase): flist2_nice = [self.nice_file(f) for f in flist2] self.assertSameElements(flist1_nice, flist2_nice) + def assert_exists(self, fname): + """Assert that `fname` is a file that exists.""" + msg = "File %r should exist" % fname + self.assert_(os.path.exists(fname), msg) + + def assert_doesnt_exist(self, fname): + """Assert that `fname` is a file that doesn't exist.""" + msg = "File %r shouldn't exist" % fname + self.assert_(not os.path.exists(fname), msg) + def command_line(self, args, ret=OK, _covpkg=None): """Run `args` through the command line. @@ -380,7 +436,7 @@ class CoverageTest(TestCase): here = os.path.dirname(self.nice_file(coverage.__file__, "..")) testmods = self.nice_file(here, 'test/modules') zipfile = self.nice_file(here, 'test/zipmods.zip') - pypath = self.original_environ('PYTHONPATH', "") + pypath = os.getenv('PYTHONPATH', '') if pypath: pypath += os.pathsep pypath += testmods + os.pathsep + zipfile diff --git a/test/farm/html/gold_a/a.html b/test/farm/html/gold_a/a.html index b3a28792..c794525e 100644 --- a/test/farm/html/gold_a/a.html +++ b/test/farm/html/gold_a/a.html @@ -1,69 +1,95 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for a: 67%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>a</b> :
- <span class='pc_cov'>67%</span>
- </h1>
- <h2 class='stats'>
- 3 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>1 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='pln'><a href='#n1'>1</a></p>
-<p id='n2' class='pln'><a href='#n2'>2</a></p>
-<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p>
-<p id='n4' class='pln'><a href='#n4'>4</a></p>
-<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p>
-<p id='n6' class='pln'><a href='#n6'>6</a></p>
-<p id='n7' class='stm mis'><a href='#n7'>7</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='pln'><span class='com'># A test file for HTML reporting by coverage.</span><span class='strut'> </span></p>
-<p id='t2' class='pln'><span class='strut'> </span></p>
-<p id='t3' class='stm run hide_run'><span class='key'>if</span> <span class='num'>1</span> <span class='op'><</span> <span class='num'>2</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t4' class='pln'> <span class='com'># Needed a < to look at HTML entities.</span><span class='strut'> </span></p>
-<p id='t5' class='stm run hide_run'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>3</span><span class='strut'> </span></p>
-<p id='t6' class='pln'><span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t7' class='stm mis'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>4</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for a: 67%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>a</b> : + <span class='pc_cov'>67%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 3 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>1 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='pln'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='pln'><a href='#n6'>6</a></p> +<p id='n7' class='stm mis'><a href='#n7'>7</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># A test file for HTML reporting by coverage.</span><span class='strut'> </span></p> +<p id='t2' class='pln'><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>if</span> <span class='num'>1</span> <span class='op'><</span> <span class='num'>2</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t4' class='pln'> <span class='com'># Needed a < to look at HTML entities.</span><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>3</span><span class='strut'> </span></p> +<p id='t6' class='pln'><span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t7' class='stm mis'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>4</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_a/index.html b/test/farm/html/gold_a/index.html index 35224e6b..a821e9df 100644 --- a/test/farm/html/gold_a/index.html +++ b/test/farm/html/gold_a/index.html @@ -1,72 +1,89 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
- <title>Coverage report</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='jquery.tablesorter.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(index_ready);
- </script>
-</head>
-<body id='indexfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage report:
- <span class='pc_cov'>67%</span>
- </h1>
- </div>
-</div>
-
-<div id='index'>
- <table class='index'>
- <thead>
-
- <tr class='tablehead' title='Click to sort'>
- <th class='name left headerSortDown'>Module</th>
- <th>statements</th>
- <th>missing</th>
- <th>excluded</th>
-
- <th class='right'>coverage</th>
- </tr>
- </thead>
-
- <tfoot>
- <tr class='total'>
- <td class='name left'>Total</td>
- <td>3</td>
- <td>1</td>
- <td>0</td>
-
- <td class='right'>67%</td>
- </tr>
- </tfoot>
- <tbody>
-
- <tr class='file'>
- <td class='name left'><a href='a.html'>a</a></td>
- <td>3</td>
- <td>1</td>
- <td>0</td>
-
- <td class='right'>67%</td>
- </tr>
-
- </tbody>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>67%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>3</td> + <td>1</td> + <td>0</td> + + <td class='right'>67%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='a.html'>a</a></td> + <td>3</td> + <td>1</td> + <td>0</td> + + <td class='right'>67%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_b_branch/b.html b/test/farm/html/gold_b_branch/b.html index ba57e964..0258ad13 100644 --- a/test/farm/html/gold_b_branch/b.html +++ b/test/farm/html/gold_b_branch/b.html @@ -1,113 +1,139 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for b: 76%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>b</b> :
- <span class='pc_cov'>76%</span>
- </h1>
- <h2 class='stats'>
- 16 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>14 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>2 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- <span class='par run hide_run' onclick='toggle_lines(this, "par")'>3 partial</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='pln'><a href='#n1'>1</a></p>
-<p id='n2' class='pln'><a href='#n2'>2</a></p>
-<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p>
-<p id='n4' class='pln'><a href='#n4'>4</a></p>
-<p id='n5' class='stm par run hide_run'><a href='#n5'>5</a></p>
-<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p>
-<p id='n7' class='pln'><a href='#n7'>7</a></p>
-<p id='n8' class='stm mis'><a href='#n8'>8</a></p>
-<p id='n9' class='pln'><a href='#n9'>9</a></p>
-<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p>
-<p id='n11' class='pln'><a href='#n11'>11</a></p>
-<p id='n12' class='stm run hide_run'><a href='#n12'>12</a></p>
-<p id='n13' class='pln'><a href='#n13'>13</a></p>
-<p id='n14' class='stm par run hide_run'><a href='#n14'>14</a></p>
-<p id='n15' class='stm run hide_run'><a href='#n15'>15</a></p>
-<p id='n16' class='pln'><a href='#n16'>16</a></p>
-<p id='n17' class='stm run hide_run'><a href='#n17'>17</a></p>
-<p id='n18' class='pln'><a href='#n18'>18</a></p>
-<p id='n19' class='stm run hide_run'><a href='#n19'>19</a></p>
-<p id='n20' class='pln'><a href='#n20'>20</a></p>
-<p id='n21' class='stm par run hide_run'><a href='#n21'>21</a></p>
-<p id='n22' class='stm run hide_run'><a href='#n22'>22</a></p>
-<p id='n23' class='stm run hide_run'><a href='#n23'>23</a></p>
-<p id='n24' class='pln'><a href='#n24'>24</a></p>
-<p id='n25' class='stm mis'><a href='#n25'>25</a></p>
-<p id='n26' class='stm run hide_run'><a href='#n26'>26</a></p>
-<p id='n27' class='pln'><a href='#n27'>27</a></p>
-<p id='n28' class='stm run hide_run'><a href='#n28'>28</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='pln'><span class='com'># A test file for HTML reporting by coverage.</span><span class='strut'> </span></p>
-<p id='t2' class='pln'><span class='strut'> </span></p>
-<p id='t3' class='stm run hide_run'><span class='key'>def</span> <span class='nam'>one</span><span class='op'>(</span><span class='nam'>x</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t4' class='pln'> <span class='com'># This will be a branch that misses the else.</span><span class='strut'> </span></p>
-<p id='t5' class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>8</span> <span class='key'>if</span> <span class='nam'>x</span> <span class='op'><</span> <span class='num'>2</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t6' class='stm run hide_run'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>3</span><span class='strut'> </span></p>
-<p id='t7' class='pln'> <span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t8' class='stm mis'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>4</span><span class='strut'> </span></p>
-<p id='t9' class='pln'><span class='strut'> </span></p>
-<p id='t10' class='stm run hide_run'><span class='nam'>one</span><span class='op'>(</span><span class='num'>1</span><span class='op'>)</span><span class='strut'> </span></p>
-<p id='t11' class='pln'><span class='strut'> </span></p>
-<p id='t12' class='stm run hide_run'><span class='key'>def</span> <span class='nam'>two</span><span class='op'>(</span><span class='nam'>x</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t13' class='pln'> <span class='com'># A missed else that branches to "exit"</span><span class='strut'> </span></p>
-<p id='t14' class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>exit</span> <span class='key'>if</span> <span class='nam'>x</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t15' class='stm run hide_run'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p>
-<p id='t16' class='pln'><span class='strut'> </span></p>
-<p id='t17' class='stm run hide_run'><span class='nam'>two</span><span class='op'>(</span><span class='num'>1</span><span class='op'>)</span><span class='strut'> </span></p>
-<p id='t18' class='pln'><span class='strut'> </span></p>
-<p id='t19' class='stm run hide_run'><span class='key'>def</span> <span class='nam'>three_way</span><span class='op'>(</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t20' class='pln'> <span class='com'># for-else can be a three-way branch.</span><span class='strut'> </span></p>
-<p id='t21' class='stm par run hide_run'><span class='annotate' title='no jumps to these line numbers'>25 26</span> <span class='key'>for</span> <span class='nam'>i</span> <span class='key'>in</span> <span class='nam'>range</span><span class='op'>(</span><span class='num'>10</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t22' class='stm run hide_run'> <span class='key'>if</span> <span class='nam'>i</span> <span class='op'>==</span> <span class='num'>3</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t23' class='stm run hide_run'> <span class='key'>break</span><span class='strut'> </span></p>
-<p id='t24' class='pln'> <span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t25' class='stm mis'> <span class='key'>return</span> <span class='num'>23</span><span class='strut'> </span></p>
-<p id='t26' class='stm run hide_run'> <span class='key'>return</span> <span class='num'>17</span><span class='strut'> </span></p>
-<p id='t27' class='pln'><span class='strut'> </span></p>
-<p id='t28' class='stm run hide_run'><span class='nam'>three_way</span><span class='op'>(</span><span class='op'>)</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for b: 76%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>b</b> : + <span class='pc_cov'>76%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 16 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>14 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>2 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + <span class='par run hide_run shortkey_p' onclick='coverage.toggle_lines(this, "par")'>3 partial</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='pln'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm par run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='pln'><a href='#n7'>7</a></p> +<p id='n8' class='stm mis'><a href='#n8'>8</a></p> +<p id='n9' class='pln'><a href='#n9'>9</a></p> +<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p> +<p id='n11' class='pln'><a href='#n11'>11</a></p> +<p id='n12' class='stm run hide_run'><a href='#n12'>12</a></p> +<p id='n13' class='pln'><a href='#n13'>13</a></p> +<p id='n14' class='stm par run hide_run'><a href='#n14'>14</a></p> +<p id='n15' class='stm run hide_run'><a href='#n15'>15</a></p> +<p id='n16' class='pln'><a href='#n16'>16</a></p> +<p id='n17' class='stm run hide_run'><a href='#n17'>17</a></p> +<p id='n18' class='pln'><a href='#n18'>18</a></p> +<p id='n19' class='stm run hide_run'><a href='#n19'>19</a></p> +<p id='n20' class='pln'><a href='#n20'>20</a></p> +<p id='n21' class='stm par run hide_run'><a href='#n21'>21</a></p> +<p id='n22' class='stm run hide_run'><a href='#n22'>22</a></p> +<p id='n23' class='stm run hide_run'><a href='#n23'>23</a></p> +<p id='n24' class='pln'><a href='#n24'>24</a></p> +<p id='n25' class='stm mis'><a href='#n25'>25</a></p> +<p id='n26' class='stm run hide_run'><a href='#n26'>26</a></p> +<p id='n27' class='pln'><a href='#n27'>27</a></p> +<p id='n28' class='stm run hide_run'><a href='#n28'>28</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># A test file for HTML reporting by coverage.</span><span class='strut'> </span></p> +<p id='t2' class='pln'><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>def</span> <span class='nam'>one</span><span class='op'>(</span><span class='nam'>x</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t4' class='pln'> <span class='com'># This will be a branch that misses the else.</span><span class='strut'> </span></p> +<p id='t5' class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>8</span> <span class='key'>if</span> <span class='nam'>x</span> <span class='op'><</span> <span class='num'>2</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>3</span><span class='strut'> </span></p> +<p id='t7' class='pln'> <span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t8' class='stm mis'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>4</span><span class='strut'> </span></p> +<p id='t9' class='pln'><span class='strut'> </span></p> +<p id='t10' class='stm run hide_run'><span class='nam'>one</span><span class='op'>(</span><span class='num'>1</span><span class='op'>)</span><span class='strut'> </span></p> +<p id='t11' class='pln'><span class='strut'> </span></p> +<p id='t12' class='stm run hide_run'><span class='key'>def</span> <span class='nam'>two</span><span class='op'>(</span><span class='nam'>x</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t13' class='pln'> <span class='com'># A missed else that branches to "exit"</span><span class='strut'> </span></p> +<p id='t14' class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>exit</span> <span class='key'>if</span> <span class='nam'>x</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t15' class='stm run hide_run'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p> +<p id='t16' class='pln'><span class='strut'> </span></p> +<p id='t17' class='stm run hide_run'><span class='nam'>two</span><span class='op'>(</span><span class='num'>1</span><span class='op'>)</span><span class='strut'> </span></p> +<p id='t18' class='pln'><span class='strut'> </span></p> +<p id='t19' class='stm run hide_run'><span class='key'>def</span> <span class='nam'>three_way</span><span class='op'>(</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t20' class='pln'> <span class='com'># for-else can be a three-way branch.</span><span class='strut'> </span></p> +<p id='t21' class='stm par run hide_run'><span class='annotate' title='no jumps to these line numbers'>25 26</span> <span class='key'>for</span> <span class='nam'>i</span> <span class='key'>in</span> <span class='nam'>range</span><span class='op'>(</span><span class='num'>10</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t22' class='stm run hide_run'> <span class='key'>if</span> <span class='nam'>i</span> <span class='op'>==</span> <span class='num'>3</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t23' class='stm run hide_run'> <span class='key'>break</span><span class='strut'> </span></p> +<p id='t24' class='pln'> <span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t25' class='stm mis'> <span class='key'>return</span> <span class='num'>23</span><span class='strut'> </span></p> +<p id='t26' class='stm run hide_run'> <span class='key'>return</span> <span class='num'>17</span><span class='strut'> </span></p> +<p id='t27' class='pln'><span class='strut'> </span></p> +<p id='t28' class='stm run hide_run'><span class='nam'>three_way</span><span class='op'>(</span><span class='op'>)</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_b_branch/index.html b/test/farm/html/gold_b_branch/index.html index a37f357a..cb6ffa17 100644 --- a/test/farm/html/gold_b_branch/index.html +++ b/test/farm/html/gold_b_branch/index.html @@ -1,81 +1,101 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
- <title>Coverage report</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='jquery.tablesorter.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(index_ready);
- </script>
-</head>
-<body id='indexfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage report:
- <span class='pc_cov'>76%</span>
- </h1>
- </div>
-</div>
-
-<div id='index'>
- <table class='index'>
- <thead>
-
- <tr class='tablehead' title='Click to sort'>
- <th class='name left headerSortDown'>Module</th>
- <th>statements</th>
- <th>missing</th>
- <th>excluded</th>
-
- <th>branches</th>
- <th>partial</th>
-
- <th class='right'>coverage</th>
- </tr>
- </thead>
-
- <tfoot>
- <tr class='total'>
- <td class='name left'>Total</td>
- <td>16</td>
- <td>2</td>
- <td>0</td>
-
- <td>9</td>
- <td>4</td>
-
- <td class='right'>76%</td>
- </tr>
- </tfoot>
- <tbody>
-
- <tr class='file'>
- <td class='name left'><a href='b.html'>b</a></td>
- <td>16</td>
- <td>2</td>
- <td>0</td>
-
- <td>9</td>
- <td>4</td>
-
- <td class='right'>76%</td>
- </tr>
-
- </tbody>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>76%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>b</span> + <span class='key'>p</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='shortkey_b'>branches</th> + <th class='shortkey_p'>partial</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>16</td> + <td>2</td> + <td>0</td> + + <td>9</td> + <td>4</td> + + <td class='right'>76%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='b.html'>b</a></td> + <td>16</td> + <td>2</td> + <td>0</td> + + <td>9</td> + <td>4</td> + + <td class='right'>76%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_bom/bom.html b/test/farm/html/gold_bom/bom.html new file mode 100644 index 00000000..1d61a62c --- /dev/null +++ b/test/farm/html/gold_bom/bom.html @@ -0,0 +1,104 @@ +<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for bom: 71%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>bom</b> : + <span class='pc_cov'>71%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 7 statements + <span class='run hide_run shortkey_r button_toggle_run'>5 run</span> + <span class='mis shortkey_m button_toggle_mis'>2 missing</span> + <span class='exc shortkey_x button_toggle_exc'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> +<p id='n3' class='pln'><a href='#n3'>3</a></p> +<p id='n4' class='stm run hide_run'><a href='#n4'>4</a></p> +<p id='n5' class='pln'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='stm mis'><a href='#n7'>7</a></p> +<p id='n8' class='stm mis'><a href='#n8'>8</a></p> +<p id='n9' class='pln'><a href='#n9'>9</a></p> +<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p> +<p id='n11' class='stm run hide_run'><a href='#n11'>11</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># A python source file in utf-8, with BOM</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>math</span> <span class='op'>=</span> <span class='str'>"3×4 = 12, ÷2 = 6±0"</span><span class='strut'> </span></p> +<p id='t3' class='pln'><span class='strut'> </span></p> +<p id='t4' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>sys</span><span class='strut'> </span></p> +<p id='t5' class='pln'><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'><span class='key'>if</span> <span class='nam'>sys</span><span class='op'>.</span><span class='nam'>version_info</span> <span class='op'>>=</span> <span class='op'>(</span><span class='num'>3</span><span class='op'>,</span> <span class='num'>0</span><span class='op'>)</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t7' class='stm mis'> <span class='key'>assert</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>math</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>18</span><span class='strut'> </span></p> +<p id='t8' class='stm mis'> <span class='key'>assert</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>math</span><span class='op'>.</span><span class='nam'>encode</span><span class='op'>(</span><span class='str'>'utf-8'</span><span class='op'>)</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>21</span><span class='strut'> </span></p> +<p id='t9' class='pln'><span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t10' class='stm run hide_run'> <span class='key'>assert</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>math</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>21</span><span class='strut'> </span></p> +<p id='t11' class='stm run hide_run'> <span class='key'>assert</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>math</span><span class='op'>.</span><span class='nam'>decode</span><span class='op'>(</span><span class='str'>'utf-8'</span><span class='op'>)</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>18</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.5.2</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_bom/index.html b/test/farm/html/gold_bom/index.html new file mode 100644 index 00000000..8653b23e --- /dev/null +++ b/test/farm/html/gold_bom/index.html @@ -0,0 +1,90 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>71%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>7</td> + <td>2</td> + <td>0</td> + + <td class='right'>71%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='bom.html'>bom</a></td> + <td>7</td> + <td>2</td> + <td>0</td> + + <td class='right'>71%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.5.2</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_isolatin1/index.html b/test/farm/html/gold_isolatin1/index.html new file mode 100644 index 00000000..6e9f3ca7 --- /dev/null +++ b/test/farm/html/gold_isolatin1/index.html @@ -0,0 +1,89 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='isolatin1.html'>isolatin1</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5.2b1'>coverage.py v3.5.2b1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_isolatin1/isolatin1.html b/test/farm/html/gold_isolatin1/isolatin1.html new file mode 100644 index 00000000..276a6c25 --- /dev/null +++ b/test/farm/html/gold_isolatin1/isolatin1.html @@ -0,0 +1,91 @@ +<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for isolatin1: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>isolatin1</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='pln'><a href='#n2'>2</a></p> +<p id='n3' class='pln'><a href='#n3'>3</a></p> +<p id='n4' class='stm run hide_run'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># A python source file in another encoding.</span><span class='strut'> </span></p> +<p id='t2' class='pln'><span class='com'># -*- coding: iso8859-1 -*-</span><span class='strut'> </span></p> +<p id='t3' class='pln'><span class='strut'> </span></p> +<p id='t4' class='stm run hide_run'><span class='nam'>math</span> <span class='op'>=</span> <span class='str'>"3×4 = 12, ÷2 = 6±0"</span><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>math</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>18</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5.2b1'>coverage.py v3.5.2b1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_1/index.html b/test/farm/html/gold_omit_1/index.html index 2612a88e..5616d012 100644 --- a/test/farm/html/gold_omit_1/index.html +++ b/test/farm/html/gold_omit_1/index.html @@ -1,99 +1,116 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
- <title>Coverage report</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='jquery.tablesorter.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(index_ready);
- </script>
-</head>
-<body id='indexfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage report:
- <span class='pc_cov'>100%</span>
- </h1>
- </div>
-</div>
-
-<div id='index'>
- <table class='index'>
- <thead>
-
- <tr class='tablehead' title='Click to sort'>
- <th class='name left headerSortDown'>Module</th>
- <th>statements</th>
- <th>missing</th>
- <th>excluded</th>
-
- <th class='right'>coverage</th>
- </tr>
- </thead>
-
- <tfoot>
- <tr class='total'>
- <td class='name left'>Total</td>
- <td>14</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
- </tfoot>
- <tbody>
-
- <tr class='file'>
- <td class='name left'><a href='m1.html'>m1</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='m2.html'>m2</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='m3.html'>m3</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='main.html'>main</a></td>
- <td>8</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- </tbody>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>14</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='m1.html'>m1</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='m2.html'>m2</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='m3.html'>m3</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='main.html'>main</a></td> + <td>8</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_1/m1.html b/test/farm/html/gold_omit_1/m1.html index 20b86df7..62ba1e0a 100644 --- a/test/farm/html/gold_omit_1/m1.html +++ b/test/farm/html/gold_omit_1/m1.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m1: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m1</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m1a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m1b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m1: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m1</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m1a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m1b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_1/m2.html b/test/farm/html/gold_omit_1/m2.html index 6cbf78ed..d75a5ba0 100644 --- a/test/farm/html/gold_omit_1/m2.html +++ b/test/farm/html/gold_omit_1/m2.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m2: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m2</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m2a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m2b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m2: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m2</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m2a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m2b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_1/m3.html b/test/farm/html/gold_omit_1/m3.html index 6e618619..bd99138a 100644 --- a/test/farm/html/gold_omit_1/m3.html +++ b/test/farm/html/gold_omit_1/m3.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m3: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m3</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m3a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m3b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m3: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m3</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m3a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m3b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_1/main.html b/test/farm/html/gold_omit_1/main.html index d7b84c45..03948718 100644 --- a/test/farm/html/gold_omit_1/main.html +++ b/test/farm/html/gold_omit_1/main.html @@ -1,75 +1,101 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for main: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>main</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 8 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>8 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p>
-<p id='n4' class='pln'><a href='#n4'>4</a></p>
-<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p>
-<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p>
-<p id='n7' class='pln'><a href='#n7'>7</a></p>
-<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p>
-<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p>
-<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p>
-<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p>
-<p id='t4' class='pln'><span class='strut'> </span></p>
-<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p>
-<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p>
-<p id='t7' class='pln'><span class='strut'> </span></p>
-<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for main: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>main</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 8 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>8 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='pln'><a href='#n7'>7</a></p> +<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p> +<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p> +<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p> +<p id='t4' class='pln'><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p> +<p id='t7' class='pln'><span class='strut'> </span></p> +<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_2/index.html b/test/farm/html/gold_omit_2/index.html index 6fababf4..3ce5bade 100644 --- a/test/farm/html/gold_omit_2/index.html +++ b/test/farm/html/gold_omit_2/index.html @@ -1,90 +1,107 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
- <title>Coverage report</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='jquery.tablesorter.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(index_ready);
- </script>
-</head>
-<body id='indexfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage report:
- <span class='pc_cov'>100%</span>
- </h1>
- </div>
-</div>
-
-<div id='index'>
- <table class='index'>
- <thead>
-
- <tr class='tablehead' title='Click to sort'>
- <th class='name left headerSortDown'>Module</th>
- <th>statements</th>
- <th>missing</th>
- <th>excluded</th>
-
- <th class='right'>coverage</th>
- </tr>
- </thead>
-
- <tfoot>
- <tr class='total'>
- <td class='name left'>Total</td>
- <td>12</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
- </tfoot>
- <tbody>
-
- <tr class='file'>
- <td class='name left'><a href='m2.html'>m2</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='m3.html'>m3</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='main.html'>main</a></td>
- <td>8</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- </tbody>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>12</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='m2.html'>m2</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='m3.html'>m3</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='main.html'>main</a></td> + <td>8</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_2/m2.html b/test/farm/html/gold_omit_2/m2.html index 6cbf78ed..d75a5ba0 100644 --- a/test/farm/html/gold_omit_2/m2.html +++ b/test/farm/html/gold_omit_2/m2.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m2: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m2</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m2a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m2b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m2: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m2</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m2a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m2b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_2/m3.html b/test/farm/html/gold_omit_2/m3.html index 6e618619..bd99138a 100644 --- a/test/farm/html/gold_omit_2/m3.html +++ b/test/farm/html/gold_omit_2/m3.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m3: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m3</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m3a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m3b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m3: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m3</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m3a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m3b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_2/main.html b/test/farm/html/gold_omit_2/main.html index d7b84c45..03948718 100644 --- a/test/farm/html/gold_omit_2/main.html +++ b/test/farm/html/gold_omit_2/main.html @@ -1,75 +1,101 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for main: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>main</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 8 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>8 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p>
-<p id='n4' class='pln'><a href='#n4'>4</a></p>
-<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p>
-<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p>
-<p id='n7' class='pln'><a href='#n7'>7</a></p>
-<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p>
-<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p>
-<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p>
-<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p>
-<p id='t4' class='pln'><span class='strut'> </span></p>
-<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p>
-<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p>
-<p id='t7' class='pln'><span class='strut'> </span></p>
-<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for main: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>main</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 8 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>8 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='pln'><a href='#n7'>7</a></p> +<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p> +<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p> +<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p> +<p id='t4' class='pln'><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p> +<p id='t7' class='pln'><span class='strut'> </span></p> +<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_3/index.html b/test/farm/html/gold_omit_3/index.html index 919fc965..fb826bf5 100644 --- a/test/farm/html/gold_omit_3/index.html +++ b/test/farm/html/gold_omit_3/index.html @@ -1,81 +1,98 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
- <title>Coverage report</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='jquery.tablesorter.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(index_ready);
- </script>
-</head>
-<body id='indexfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage report:
- <span class='pc_cov'>100%</span>
- </h1>
- </div>
-</div>
-
-<div id='index'>
- <table class='index'>
- <thead>
-
- <tr class='tablehead' title='Click to sort'>
- <th class='name left headerSortDown'>Module</th>
- <th>statements</th>
- <th>missing</th>
- <th>excluded</th>
-
- <th class='right'>coverage</th>
- </tr>
- </thead>
-
- <tfoot>
- <tr class='total'>
- <td class='name left'>Total</td>
- <td>10</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
- </tfoot>
- <tbody>
-
- <tr class='file'>
- <td class='name left'><a href='m3.html'>m3</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='main.html'>main</a></td>
- <td>8</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- </tbody>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>10</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='m3.html'>m3</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='main.html'>main</a></td> + <td>8</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_3/m3.html b/test/farm/html/gold_omit_3/m3.html index 6e618619..bd99138a 100644 --- a/test/farm/html/gold_omit_3/m3.html +++ b/test/farm/html/gold_omit_3/m3.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m3: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m3</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m3a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m3b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m3: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m3</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m3a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m3b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_3/main.html b/test/farm/html/gold_omit_3/main.html index d7b84c45..03948718 100644 --- a/test/farm/html/gold_omit_3/main.html +++ b/test/farm/html/gold_omit_3/main.html @@ -1,75 +1,101 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for main: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>main</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 8 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>8 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p>
-<p id='n4' class='pln'><a href='#n4'>4</a></p>
-<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p>
-<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p>
-<p id='n7' class='pln'><a href='#n7'>7</a></p>
-<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p>
-<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p>
-<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p>
-<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p>
-<p id='t4' class='pln'><span class='strut'> </span></p>
-<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p>
-<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p>
-<p id='t7' class='pln'><span class='strut'> </span></p>
-<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for main: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>main</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 8 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>8 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='pln'><a href='#n7'>7</a></p> +<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p> +<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p> +<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p> +<p id='t4' class='pln'><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p> +<p id='t7' class='pln'><span class='strut'> </span></p> +<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_4/index.html b/test/farm/html/gold_omit_4/index.html index 1d528d39..e437cf10 100644 --- a/test/farm/html/gold_omit_4/index.html +++ b/test/farm/html/gold_omit_4/index.html @@ -1,90 +1,107 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
- <title>Coverage report</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='jquery.tablesorter.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(index_ready);
- </script>
-</head>
-<body id='indexfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage report:
- <span class='pc_cov'>100%</span>
- </h1>
- </div>
-</div>
-
-<div id='index'>
- <table class='index'>
- <thead>
-
- <tr class='tablehead' title='Click to sort'>
- <th class='name left headerSortDown'>Module</th>
- <th>statements</th>
- <th>missing</th>
- <th>excluded</th>
-
- <th class='right'>coverage</th>
- </tr>
- </thead>
-
- <tfoot>
- <tr class='total'>
- <td class='name left'>Total</td>
- <td>12</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
- </tfoot>
- <tbody>
-
- <tr class='file'>
- <td class='name left'><a href='m1.html'>m1</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='m3.html'>m3</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='main.html'>main</a></td>
- <td>8</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- </tbody>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>12</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='m1.html'>m1</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='m3.html'>m3</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='main.html'>main</a></td> + <td>8</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_4/m1.html b/test/farm/html/gold_omit_4/m1.html index 20b86df7..62ba1e0a 100644 --- a/test/farm/html/gold_omit_4/m1.html +++ b/test/farm/html/gold_omit_4/m1.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m1: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m1</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m1a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m1b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m1: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m1</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m1a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m1b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_4/m3.html b/test/farm/html/gold_omit_4/m3.html index 6e618619..bd99138a 100644 --- a/test/farm/html/gold_omit_4/m3.html +++ b/test/farm/html/gold_omit_4/m3.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m3: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m3</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m3a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m3b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m3: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m3</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m3a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m3b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_4/main.html b/test/farm/html/gold_omit_4/main.html index d7b84c45..03948718 100644 --- a/test/farm/html/gold_omit_4/main.html +++ b/test/farm/html/gold_omit_4/main.html @@ -1,75 +1,101 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for main: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>main</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 8 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>8 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p>
-<p id='n4' class='pln'><a href='#n4'>4</a></p>
-<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p>
-<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p>
-<p id='n7' class='pln'><a href='#n7'>7</a></p>
-<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p>
-<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p>
-<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p>
-<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p>
-<p id='t4' class='pln'><span class='strut'> </span></p>
-<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p>
-<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p>
-<p id='t7' class='pln'><span class='strut'> </span></p>
-<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for main: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>main</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 8 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>8 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='pln'><a href='#n7'>7</a></p> +<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p> +<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p> +<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p> +<p id='t4' class='pln'><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p> +<p id='t7' class='pln'><span class='strut'> </span></p> +<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_5/index.html b/test/farm/html/gold_omit_5/index.html index 61eeceb8..4bde6b73 100644 --- a/test/farm/html/gold_omit_5/index.html +++ b/test/farm/html/gold_omit_5/index.html @@ -1,81 +1,98 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
- <title>Coverage report</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='jquery.tablesorter.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(index_ready);
- </script>
-</head>
-<body id='indexfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage report:
- <span class='pc_cov'>100%</span>
- </h1>
- </div>
-</div>
-
-<div id='index'>
- <table class='index'>
- <thead>
-
- <tr class='tablehead' title='Click to sort'>
- <th class='name left headerSortDown'>Module</th>
- <th>statements</th>
- <th>missing</th>
- <th>excluded</th>
-
- <th class='right'>coverage</th>
- </tr>
- </thead>
-
- <tfoot>
- <tr class='total'>
- <td class='name left'>Total</td>
- <td>10</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
- </tfoot>
- <tbody>
-
- <tr class='file'>
- <td class='name left'><a href='m1.html'>m1</a></td>
- <td>2</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='main.html'>main</a></td>
- <td>8</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- </tbody>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>10</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='m1.html'>m1</a></td> + <td>2</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='main.html'>main</a></td> + <td>8</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_5/m1.html b/test/farm/html/gold_omit_5/m1.html index 20b86df7..62ba1e0a 100644 --- a/test/farm/html/gold_omit_5/m1.html +++ b/test/farm/html/gold_omit_5/m1.html @@ -1,59 +1,85 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for m1: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>m1</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 2 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>2 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='nam'>m1a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='nam'>m1b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for m1: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>m1</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 2 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='nam'>m1a</span> <span class='op'>=</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='nam'>m1b</span> <span class='op'>=</span> <span class='num'>2</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_omit_5/main.html b/test/farm/html/gold_omit_5/main.html index d7b84c45..03948718 100644 --- a/test/farm/html/gold_omit_5/main.html +++ b/test/farm/html/gold_omit_5/main.html @@ -1,75 +1,101 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for main: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>main</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 8 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>8 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p>
-<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p>
-<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p>
-<p id='n4' class='pln'><a href='#n4'>4</a></p>
-<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p>
-<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p>
-<p id='n7' class='pln'><a href='#n7'>7</a></p>
-<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p>
-<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p>
-<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p>
-<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p>
-<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p>
-<p id='t4' class='pln'><span class='strut'> </span></p>
-<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p>
-<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p>
-<p id='t7' class='pln'><span class='strut'> </span></p>
-<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for main: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>main</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 8 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>8 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='stm run hide_run'><a href='#n1'>1</a></p> +<p id='n2' class='stm run hide_run'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='pln'><a href='#n7'>7</a></p> +<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p> +<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p> +<p id='n10' class='stm run hide_run'><a href='#n10'>10</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m1</span><span class='strut'> </span></p> +<p id='t2' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m2</span><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>m3</span><span class='strut'> </span></p> +<p id='t4' class='pln'><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>5</span><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'><span class='nam'>b</span> <span class='op'>=</span> <span class='num'>6</span><span class='strut'> </span></p> +<p id='t7' class='pln'><span class='strut'> </span></p> +<p id='t8' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m1</span><span class='op'>.</span><span class='nam'>m1a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t9' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m2</span><span class='op'>.</span><span class='nam'>m2a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> +<p id='t10' class='stm run hide_run'><span class='key'>assert</span> <span class='nam'>m3</span><span class='op'>.</span><span class='nam'>m3a</span> <span class='op'>==</span> <span class='num'>1</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_other/blah_blah_other.html b/test/farm/html/gold_other/blah_blah_other.html index 46e05aaf..ab5ae371 100644 --- a/test/farm/html/gold_other/blah_blah_other.html +++ b/test/farm/html/gold_other/blah_blah_other.html @@ -1,63 +1,89 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for othersrc\other: 100%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>othersrc\other</b> :
- <span class='pc_cov'>100%</span>
- </h1>
- <h2 class='stats'>
- 1 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>1 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>0 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='pln'><a href='#n1'>1</a></p>
-<p id='n2' class='pln'><a href='#n2'>2</a></p>
-<p id='n3' class='pln'><a href='#n3'>3</a></p>
-<p id='n4' class='stm run hide_run'><a href='#n4'>4</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='pln'><span class='com'># A file in another directory. We're checking that it ends up in the</span><span class='strut'> </span></p>
-<p id='t2' class='pln'><span class='com'># HTML report.</span><span class='strut'> </span></p>
-<p id='t3' class='pln'><span class='strut'> </span></p>
-<p id='t4' class='stm run hide_run'><span class='key'>print</span><span class='op'>(</span><span class='str'>"This is the other src!"</span><span class='op'>)</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for /home/ned/coverage/trunk/test/farm/html/othersrc/other: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>/home/ned/coverage/trunk/test/farm/html/othersrc/other</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 1 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>1 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='pln'><a href='#n2'>2</a></p> +<p id='n3' class='pln'><a href='#n3'>3</a></p> +<p id='n4' class='stm run hide_run'><a href='#n4'>4</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># A file in another directory. We're checking that it ends up in the</span><span class='strut'> </span></p> +<p id='t2' class='pln'><span class='com'># HTML report.</span><span class='strut'> </span></p> +<p id='t3' class='pln'><span class='strut'> </span></p> +<p id='t4' class='stm run hide_run'><span class='key'>print</span><span class='op'>(</span><span class='str'>"This is the other src!"</span><span class='op'>)</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_other/here.html b/test/farm/html/gold_other/here.html index 1ae248f5..1da5bcd6 100644 --- a/test/farm/html/gold_other/here.html +++ b/test/farm/html/gold_other/here.html @@ -1,71 +1,97 @@ -<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
-
-
- <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
- <title>Coverage for here: 75%</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(pyfile_ready);
- </script>
-</head>
-<body id='pyfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage for <b>here</b> :
- <span class='pc_cov'>75%</span>
- </h1>
- <h2 class='stats'>
- 4 statements
- <span class='run hide_run' onclick='toggle_lines(this, "run")'>3 run</span>
- <span class='mis' onclick='toggle_lines(this, "mis")'>1 missing</span>
- <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
-
- </h2>
- </div>
-</div>
-
-<div id='source'>
- <table cellspacing='0' cellpadding='0'>
- <tr>
- <td class='linenos' valign='top'>
-<p id='n1' class='pln'><a href='#n1'>1</a></p>
-<p id='n2' class='pln'><a href='#n2'>2</a></p>
-<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p>
-<p id='n4' class='pln'><a href='#n4'>4</a></p>
-<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p>
-<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p>
-<p id='n7' class='pln'><a href='#n7'>7</a></p>
-<p id='n8' class='stm mis'><a href='#n8'>8</a></p>
-
- </td>
- <td class='text' valign='top'>
-<p id='t1' class='pln'><span class='com'># A test file for HTML reporting by coverage.</span><span class='strut'> </span></p>
-<p id='t2' class='pln'><span class='strut'> </span></p>
-<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>other</span><span class='strut'> </span></p>
-<p id='t4' class='pln'><span class='strut'> </span></p>
-<p id='t5' class='stm run hide_run'><span class='key'>if</span> <span class='num'>1</span> <span class='op'><</span> <span class='num'>2</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t6' class='stm run hide_run'> <span class='nam'>h</span> <span class='op'>=</span> <span class='num'>3</span><span class='strut'> </span></p>
-<p id='t7' class='pln'><span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p>
-<p id='t8' class='stm mis'> <span class='nam'>h</span> <span class='op'>=</span> <span class='num'>4</span><span class='strut'> </span></p>
-
- </td>
- </tr>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for here: 75%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>here</b> : + <span class='pc_cov'>75%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 4 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>3 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>1 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='pln'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='pln'><a href='#n7'>7</a></p> +<p id='n8' class='stm mis'><a href='#n8'>8</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># A test file for HTML reporting by coverage.</span><span class='strut'> </span></p> +<p id='t2' class='pln'><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>import</span> <span class='nam'>other</span><span class='strut'> </span></p> +<p id='t4' class='pln'><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='key'>if</span> <span class='num'>1</span> <span class='op'><</span> <span class='num'>2</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'> <span class='nam'>h</span> <span class='op'>=</span> <span class='num'>3</span><span class='strut'> </span></p> +<p id='t7' class='pln'><span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t8' class='stm mis'> <span class='nam'>h</span> <span class='op'>=</span> <span class='num'>4</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_other/index.html b/test/farm/html/gold_other/index.html index 9021036f..7665cfe4 100644 --- a/test/farm/html/gold_other/index.html +++ b/test/farm/html/gold_other/index.html @@ -1,81 +1,98 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
- <title>Coverage report</title>
- <link rel='stylesheet' href='style.css' type='text/css'>
- <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
- <script type='text/javascript' src='jquery.tablesorter.min.js'></script>
- <script type='text/javascript' src='coverage_html.js'></script>
- <script type='text/javascript' charset='utf-8'>
- jQuery(document).ready(index_ready);
- </script>
-</head>
-<body id='indexfile'>
-
-<div id='header'>
- <div class='content'>
- <h1>Coverage report:
- <span class='pc_cov'>80%</span>
- </h1>
- </div>
-</div>
-
-<div id='index'>
- <table class='index'>
- <thead>
-
- <tr class='tablehead' title='Click to sort'>
- <th class='name left headerSortDown'>Module</th>
- <th>statements</th>
- <th>missing</th>
- <th>excluded</th>
-
- <th class='right'>coverage</th>
- </tr>
- </thead>
-
- <tfoot>
- <tr class='total'>
- <td class='name left'>Total</td>
- <td>5</td>
- <td>1</td>
- <td>0</td>
-
- <td class='right'>80%</td>
- </tr>
- </tfoot>
- <tbody>
-
- <tr class='file'>
- <td class='name left'><a href='here.html'>here</a></td>
- <td>4</td>
- <td>1</td>
- <td>0</td>
-
- <td class='right'>75%</td>
- </tr>
-
- <tr class='file'>
- <td class='name left'><a href='othersrc_other.html'>othersrc\other</a></td>
- <td>1</td>
- <td>0</td>
- <td>0</td>
-
- <td class='right'>100%</td>
- </tr>
-
- </tbody>
- </table>
-</div>
-
-<div id='footer'>
- <div class='content'>
- <p>
- <a class='nav' href='http://nedbatchelder.com/code/coverage'>coverage.py v3.3.2a1</a>
- </p>
- </div>
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>80%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>5</td> + <td>1</td> + <td>0</td> + + <td class='right'>80%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='_home_ned_coverage_trunk_test_farm_html_othersrc_other.html'>/home/ned/coverage/trunk/test/farm/html/othersrc/other</a></td> + <td>1</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + <tr class='file'> + <td class='name left'><a href='here.html'>here</a></td> + <td>4</td> + <td>1</td> + <td>0</td> + + <td class='right'>75%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_partial/index.html b/test/farm/html/gold_partial/index.html new file mode 100644 index 00000000..5556150a --- /dev/null +++ b/test/farm/html/gold_partial/index.html @@ -0,0 +1,101 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>b</span> + <span class='key'>p</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='shortkey_b'>branches</th> + <th class='shortkey_p'>partial</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>8</td> + <td>0</td> + <td>0</td> + + <td>6</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='partial.html'>partial</a></td> + <td>8</td> + <td>0</td> + <td>0</td> + + <td>6</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_partial/partial.html b/test/farm/html/gold_partial/partial.html new file mode 100644 index 00000000..b9640ce4 --- /dev/null +++ b/test/farm/html/gold_partial/partial.html @@ -0,0 +1,121 @@ +<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for partial: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>partial</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 8 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>8 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + <span class='par run hide_run shortkey_p' onclick='coverage.toggle_lines(this, "par")'>0 partial</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='pln'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='stm run hide_run'><a href='#n6'>6</a></p> +<p id='n7' class='pln'><a href='#n7'>7</a></p> +<p id='n8' class='stm run hide_run'><a href='#n8'>8</a></p> +<p id='n9' class='stm run hide_run'><a href='#n9'>9</a></p> +<p id='n10' class='pln'><a href='#n10'>10</a></p> +<p id='n11' class='stm run hide_run'><a href='#n11'>11</a></p> +<p id='n12' class='stm run hide_run'><a href='#n12'>12</a></p> +<p id='n13' class='pln'><a href='#n13'>13</a></p> +<p id='n14' class='pln'><a href='#n14'>14</a></p> +<p id='n15' class='pln'><a href='#n15'>15</a></p> +<p id='n16' class='pln'><a href='#n16'>16</a></p> +<p id='n17' class='pln'><a href='#n17'>17</a></p> +<p id='n18' class='stm run hide_run'><a href='#n18'>18</a></p> +<p id='n19' class='pln'><a href='#n19'>19</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># partial branches</span><span class='strut'> </span></p> +<p id='t2' class='pln'><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='nam'>a</span> <span class='op'>=</span> <span class='num'>3</span><span class='strut'> </span></p> +<p id='t4' class='pln'><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='key'>while</span> <span class='nam'>True</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t6' class='stm run hide_run'> <span class='key'>break</span><span class='strut'> </span></p> +<p id='t7' class='pln'><span class='strut'> </span></p> +<p id='t8' class='stm run hide_run'><span class='key'>while</span> <span class='num'>1</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t9' class='stm run hide_run'> <span class='key'>break</span><span class='strut'> </span></p> +<p id='t10' class='pln'><span class='strut'> </span></p> +<p id='t11' class='stm run hide_run'><span class='key'>while</span> <span class='nam'>a</span><span class='op'>:</span> <span class='com'># pragma: no branch</span><span class='strut'> </span></p> +<p id='t12' class='stm run hide_run'> <span class='key'>break</span><span class='strut'> </span></p> +<p id='t13' class='pln'><span class='strut'> </span></p> +<p id='t14' class='pln'><span class='key'>if</span> <span class='num'>0</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t15' class='pln'> <span class='nam'>never_happen</span><span class='op'>(</span><span class='op'>)</span><span class='strut'> </span></p> +<p id='t16' class='pln'><span class='strut'> </span></p> +<p id='t17' class='pln'><span class='key'>if</span> <span class='num'>1</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t18' class='stm run hide_run'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>13</span><span class='strut'> </span></p> +<p id='t19' class='pln'><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_styled/a.html b/test/farm/html/gold_styled/a.html new file mode 100644 index 00000000..c794525e --- /dev/null +++ b/test/farm/html/gold_styled/a.html @@ -0,0 +1,95 @@ +<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for a: 67%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>a</b> : + <span class='pc_cov'>67%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 3 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>2 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>1 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='pln'><a href='#n2'>2</a></p> +<p id='n3' class='stm run hide_run'><a href='#n3'>3</a></p> +<p id='n4' class='pln'><a href='#n4'>4</a></p> +<p id='n5' class='stm run hide_run'><a href='#n5'>5</a></p> +<p id='n6' class='pln'><a href='#n6'>6</a></p> +<p id='n7' class='stm mis'><a href='#n7'>7</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># A test file for HTML reporting by coverage.</span><span class='strut'> </span></p> +<p id='t2' class='pln'><span class='strut'> </span></p> +<p id='t3' class='stm run hide_run'><span class='key'>if</span> <span class='num'>1</span> <span class='op'><</span> <span class='num'>2</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t4' class='pln'> <span class='com'># Needed a < to look at HTML entities.</span><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>3</span><span class='strut'> </span></p> +<p id='t6' class='pln'><span class='key'>else</span><span class='op'>:</span><span class='strut'> </span></p> +<p id='t7' class='stm mis'> <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>4</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_styled/extra.css b/test/farm/html/gold_styled/extra.css new file mode 100644 index 00000000..46c41fcd --- /dev/null +++ b/test/farm/html/gold_styled/extra.css @@ -0,0 +1 @@ +/* Doesn't matter what goes in here, it gets copied. */ diff --git a/test/farm/html/gold_styled/index.html b/test/farm/html/gold_styled/index.html new file mode 100644 index 00000000..a821e9df --- /dev/null +++ b/test/farm/html/gold_styled/index.html @@ -0,0 +1,89 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>67%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>3</td> + <td>1</td> + <td>0</td> + + <td class='right'>67%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='a.html'>a</a></td> + <td>3</td> + <td>1</td> + <td>0</td> + + <td class='right'>67%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5a1'>coverage.py v3.5a1</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_styled/style.css b/test/farm/html/gold_styled/style.css new file mode 100644 index 00000000..c40357b8 --- /dev/null +++ b/test/farm/html/gold_styled/style.css @@ -0,0 +1,275 @@ +/* CSS styles for Coverage. */ +/* Page-wide styles */ +html, body, h1, h2, h3, p, td, th { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; + } + +/* Set baseline grid to 16 pt. */ +body { + font-family: georgia, serif; + font-size: 1em; + } + +html>body { + font-size: 16px; + } + +/* Set base font size to 12/16 */ +p { + font-size: .75em; /* 12/16 */ + line-height: 1.3333em; /* 16/12 */ + } + +table { + border-collapse: collapse; + } + +a.nav { + text-decoration: none; + color: inherit; + } +a.nav:hover { + text-decoration: underline; + color: inherit; + } + +/* Page structure */ +#header { + background: #f8f8f8; + width: 100%; + border-bottom: 1px solid #eee; + } + +#source { + padding: 1em; + font-family: "courier new", monospace; + } + +#indexfile #footer { + margin: 1em 3em; + } + +#pyfile #footer { + margin: 1em 1em; + } + +#footer .content { + padding: 0; + font-size: 85%; + font-family: verdana, sans-serif; + color: #666666; + font-style: italic; + } + +#index { + margin: 1em 0 0 3em; + } + +/* Header styles */ +#header .content { + padding: 1em 3em; + } + +h1 { + font-size: 1.25em; +} + +h2.stats { + margin-top: .5em; + font-size: 1em; +} +.stats span { + border: 1px solid; + padding: .1em .25em; + margin: 0 .1em; + cursor: pointer; + border-color: #999 #ccc #ccc #999; +} +.stats span.hide_run, .stats span.hide_exc, +.stats span.hide_mis, .stats span.hide_par, +.stats span.par.hide_run.hide_par { + border-color: #ccc #999 #999 #ccc; +} +.stats span.par.hide_run { + border-color: #999 #ccc #ccc #999; +} + +/* Help panel */ +#keyboard_icon { + float: right; + cursor: pointer; +} + +.help_panel { + position: absolute; + background: #ffc; + padding: .5em; + border: 1px solid #883; + display: none; +} + +#indexfile .help_panel { + width: 20em; height: 4em; +} + +#pyfile .help_panel { + width: 16em; height: 8em; +} + +.help_panel .legend { + font-style: italic; + margin-bottom: 1em; +} + +#panel_icon { + float: right; + cursor: pointer; +} + +.keyhelp { + margin: .75em; +} + +.keyhelp .key { + border: 1px solid black; + border-color: #888 #333 #333 #888; + padding: .1em .35em; + font-family: monospace; + font-weight: bold; + background: #eee; +} + +/* Source file styles */ +.linenos p { + text-align: right; + margin: 0; + padding: 0 .5em; + color: #999999; + font-family: verdana, sans-serif; + font-size: .625em; /* 10/16 */ + line-height: 1.6em; /* 16/10 */ + } +.linenos p.highlight { + background: #ffdd00; + } +.linenos p a { + text-decoration: none; + color: #999999; + } +.linenos p a:hover { + text-decoration: underline; + color: #999999; + } + +td.text { + width: 100%; + } +.text p { + margin: 0; + padding: 0 0 0 .5em; + border-left: 2px solid #ffffff; + white-space: nowrap; + } + +.text p.mis { + background: #ffdddd; + border-left: 2px solid #ff0000; + } +.text p.run, .text p.run.hide_par { + background: #ddffdd; + border-left: 2px solid #00ff00; + } +.text p.exc { + background: #eeeeee; + border-left: 2px solid #808080; + } +.text p.par, .text p.par.hide_run { + background: #ffffaa; + border-left: 2px solid #eeee99; + } +.text p.hide_run, .text p.hide_exc, .text p.hide_mis, .text p.hide_par, +.text p.hide_run.hide_par { + background: inherit; + } + +.text span.annotate { + font-family: georgia; + font-style: italic; + color: #666; + float: right; + padding-right: .5em; + } +.text p.hide_par span.annotate { + display: none; + } + +/* Syntax coloring */ +.text .com { + color: green; + font-style: italic; + line-height: 1px; + } +.text .key { + font-weight: bold; + line-height: 1px; + } +.text .str { + color: #000080; + } + +/* index styles */ +#index td, #index th { + text-align: right; + width: 5em; + padding: .25em .5em; + border-bottom: 1px solid #eee; + } +#index th { + font-style: italic; + color: #333; + border-bottom: 1px solid #ccc; + cursor: pointer; + } +#index th:hover { + background: #eee; + border-bottom: 1px solid #999; + } +#index td.left, #index th.left { + padding-left: 0; + } +#index td.right, #index th.right { + padding-right: 0; + } +#index th.headerSortDown, #index th.headerSortUp { + border-bottom: 1px solid #000; + } +#index td.name, #index th.name { + text-align: left; + width: auto; + } +#index td.name a { + text-decoration: none; + color: #000; + } +#index td.name a:hover { + text-decoration: underline; + color: #000; + } +#index tr.total { + } +#index tr.total td { + font-weight: bold; + border-top: 1px solid #ccc; + border-bottom: none; + } +#index tr.file:hover { + background: #eeeeee; + } diff --git a/test/farm/html/gold_unicode/index.html b/test/farm/html/gold_unicode/index.html new file mode 100644 index 00000000..9ba1bb39 --- /dev/null +++ b/test/farm/html/gold_unicode/index.html @@ -0,0 +1,89 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Coverage report</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.tablesorter.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.index_ready); + </script> +</head> +<body id='indexfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage report: + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> + <p class='legend'>Hot-keys on this page</p> + <div> + <p class='keyhelp'> + <span class='key'>n</span> + <span class='key'>s</span> + <span class='key'>m</span> + <span class='key'>x</span> + + <span class='key'>c</span> change column sorting + </p> + </div> +</div> + +<div id='index'> + <table class='index'> + <thead> + + <tr class='tablehead' title='Click to sort'> + <th class='name left headerSortDown shortkey_n'>Module</th> + <th class='shortkey_s'>statements</th> + <th class='shortkey_m'>missing</th> + <th class='shortkey_x'>excluded</th> + + <th class='right shortkey_c'>coverage</th> + </tr> + </thead> + + <tfoot> + <tr class='total'> + <td class='name left'>Total</td> + <td>1</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + </tfoot> + <tbody> + + <tr class='file'> + <td class='name left'><a href='unicode.html'>unicode</a></td> + <td>1</td> + <td>0</td> + <td>0</td> + + <td class='right'>100%</td> + </tr> + + </tbody> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5.1a0'>coverage.py v3.5.1a0</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_unicode/unicode.html b/test/farm/html/gold_unicode/unicode.html new file mode 100644 index 00000000..518a59a1 --- /dev/null +++ b/test/farm/html/gold_unicode/unicode.html @@ -0,0 +1,91 @@ +<!doctype html PUBLIC "-//W3C//DTD html 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + + + <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> + <title>Coverage for unicode: 100%</title> + <link rel='stylesheet' href='style.css' type='text/css'> + <script type='text/javascript' src='jquery-1.4.3.min.js'></script> + <script type='text/javascript' src='jquery.hotkeys.js'></script> + <script type='text/javascript' src='jquery.isonscreen.js'></script> + <script type='text/javascript' src='coverage_html.js'></script> + <script type='text/javascript' charset='utf-8'> + jQuery(document).ready(coverage.pyfile_ready); + </script> +</head> +<body id='pyfile'> + +<div id='header'> + <div class='content'> + <h1>Coverage for <b>unicode</b> : + <span class='pc_cov'>100%</span> + </h1> + <img id='keyboard_icon' src='keybd_closed.png'> + <h2 class='stats'> + 1 statements + <span class='run hide_run shortkey_r' onclick='coverage.toggle_lines(this, "run")'>1 run</span> + <span class='mis shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>0 missing</span> + <span class='exc shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>0 excluded</span> + + </h2> + </div> +</div> + +<div class='help_panel'> + <img id='panel_icon' src='keybd_open.png'> +<p class='legend'>Hot-keys on this page</p> + <div> +<p class='keyhelp'> + <span class='key'>r</span> + <span class='key'>m</span> + <span class='key'>x</span> + <span class='key'>p</span> toggle line displays + </p> +<p class='keyhelp'> + <span class='key'>j</span> + <span class='key'>k</span> next/prev highlighted chunk + </p> +<p class='keyhelp'> + <span class='key'>0</span> (zero) top of page + </p> +<p class='keyhelp'> + <span class='key'>1</span> (one) first highlighted chunk + </p> + </div> +</div> + +<div id='source'> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> +<p id='n1' class='pln'><a href='#n1'>1</a></p> +<p id='n2' class='pln'><a href='#n2'>2</a></p> +<p id='n3' class='pln'><a href='#n3'>3</a></p> +<p id='n4' class='stm run hide_run'><a href='#n4'>4</a></p> +<p id='n5' class='pln'><a href='#n5'>5</a></p> + + </td> + <td class='text' valign='top'> +<p id='t1' class='pln'><span class='com'># A python source file with exotic characters</span><span class='strut'> </span></p> +<p id='t2' class='pln'><span class='com'># -*- coding: utf-8 -*-</span><span class='strut'> </span></p> +<p id='t3' class='pln'><span class='strut'> </span></p> +<p id='t4' class='stm run hide_run'><span class='nam'>upside_down</span> <span class='op'>=</span> <span class='str'>"ʎd˙ǝbɐɹǝʌoɔ"</span><span class='strut'> </span></p> +<p id='t5' class='stm run hide_run'><span class='nam'>surrogate</span> <span class='op'>=</span> <span class='str'>"db40,dd00: x�� 󠄀"</span><span class='strut'> </span></p> + + </td> + </tr> + </table> +</div> + +<div id='footer'> + <div class='content'> + <p> + <a class='nav' href='index.html'>« index</a> <a class='nav' href='http://nedbatchelder.com/code/coverage/3.5.1a0'>coverage.py v3.5.1a0</a> + </p> + </div> +</div> + +</body> +</html> diff --git a/test/farm/html/gold_x_xml/coverage.xml b/test/farm/html/gold_x_xml/coverage.xml index d558f5d7..912112f2 100644 --- a/test/farm/html/gold_x_xml/coverage.xml +++ b/test/farm/html/gold_x_xml/coverage.xml @@ -4,7 +4,7 @@ <coverage branch-rate="0" line-rate="0.6667" timestamp="1253972570431" version="3.1b1">
<!-- Generated by coverage.py: http://nedbatchelder.com/code/coverage/VER -->
<packages>
- <package branch-rate="0" complexity="0" line-rate="0.6667" name=".">
+ <package branch-rate="0" complexity="0" line-rate="0.6667" name="">
<classes>
<class branch-rate="0" complexity="0" filename="a.py" line-rate="0.6667" name="a">
<methods/>
diff --git a/test/farm/html/gold_y_xml_branch/coverage.xml b/test/farm/html/gold_y_xml_branch/coverage.xml index f7bf0b89..ecbe0073 100644 --- a/test/farm/html/gold_y_xml_branch/coverage.xml +++ b/test/farm/html/gold_y_xml_branch/coverage.xml @@ -4,7 +4,7 @@ <coverage branch-rate="0.5" line-rate="0.8" timestamp="1259288252325" version="3.2b4">
<!-- Generated by coverage.py: http://nedbatchelder.com/code/coverage/VER -->
<packages>
- <package branch-rate="0.5" complexity="0" line-rate="0.8" name=".">
+ <package branch-rate="0.5" complexity="0" line-rate="0.8" name="">
<classes>
<class branch-rate="0.5" complexity="0" filename="y.py" line-rate="0.8" name="y">
<methods/>
diff --git a/test/farm/html/run_b_branch.py b/test/farm/html/run_b_branch.py index f129e436..761d9662 100644 --- a/test/farm/html/run_b_branch.py +++ b/test/farm/html/run_b_branch.py @@ -1,5 +1,5 @@ def html_it(): - """Run coverage with branches and make an HTML report for a.""" + """Run coverage with branches and make an HTML report for b.""" import coverage cov = coverage.coverage(branch=True) cov.start() @@ -15,14 +15,14 @@ compare("gold_b_branch", "html_b_branch", size_within=10, file_pattern="*.html") contains("html_b_branch/b.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'>76%</span>", + "<span class='pc_cov'>70%</span>", "<span class='annotate' title='no jump to this line number'>8</span>", "<span class='annotate' title='no jump to this line number'>exit</span>", - "<span class='annotate' title='no jumps to these line numbers'>25 26</span>", + "<span class='annotate' title='no jumps to these line numbers'>23 25</span>", ) contains("html_b_branch/index.html", "<a href='b.html'>b</a>", - "<span class='pc_cov'>76%</span>" + "<span class='pc_cov'>70%</span>" ) clean("html_b_branch") diff --git a/test/farm/html/run_bom.py b/test/farm/html/run_bom.py new file mode 100644 index 00000000..918ad784 --- /dev/null +++ b/test/farm/html/run_bom.py @@ -0,0 +1,21 @@ +import sys + +def html_it(): + """Run coverage and make an HTML report for bom.py.""" + import coverage + cov = coverage.coverage() + cov.start() + import bom + cov.stop() + cov.html_report(bom, directory="../html_bom") + +runfunc(html_it, rundir="src") + +# HTML files will change often. Check that the sizes are reasonable, +# and check that certain key strings are in the output. +compare("gold_bom", "html_bom", size_within=10, file_pattern="*.html") +contains("html_bom/bom.html", + "<span class='str'>"3×4 = 12, ÷2 = 6±0"</span>", + ) + +clean("html_bom") diff --git a/test/farm/html/run_isolatin1.py b/test/farm/html/run_isolatin1.py new file mode 100644 index 00000000..9f4b8690 --- /dev/null +++ b/test/farm/html/run_isolatin1.py @@ -0,0 +1,21 @@ +import sys + +def html_it(): + """Run coverage and make an HTML report for isolatin1.py.""" + import coverage + cov = coverage.coverage() + cov.start() + import isolatin1 + cov.stop() + cov.html_report(isolatin1, directory="../html_isolatin1") + +runfunc(html_it, rundir="src") + +# HTML files will change often. Check that the sizes are reasonable, +# and check that certain key strings are in the output. +compare("gold_isolatin1", "html_isolatin1", size_within=10, file_pattern="*.html") +contains("html_isolatin1/isolatin1.html", + "<span class='str'>"3×4 = 12, ÷2 = 6±0"</span>", + ) + +clean("html_isolatin1") diff --git a/test/farm/html/run_partial.py b/test/farm/html/run_partial.py new file mode 100644 index 00000000..0ef8589c --- /dev/null +++ b/test/farm/html/run_partial.py @@ -0,0 +1,32 @@ +import sys + +def html_it(): + """Run coverage and make an HTML report for partial.""" + import coverage + cov = coverage.coverage(branch=True) + cov.start() + import partial + cov.stop() + cov.html_report(partial, directory="../html_partial") + +runfunc(html_it, rundir="src") + +# HTML files will change often. Check that the sizes are reasonable, +# and check that certain key strings are in the output. +compare("gold_partial", "html_partial", size_within=10, file_pattern="*.html") +contains("html_partial/partial.html", + "<p id='t5' class='stm run hide_run'>", + "<p id='t8' class='stm run hide_run'>", + "<p id='t11' class='stm run hide_run'>", + # The "if 0" and "if 1" statements are optimized away. + "<p id='t14' class='pln'>", + ) +contains("html_partial/index.html", + "<a href='partial.html'>partial</a>", + ) +if sys.version_info >= (2, 4): + contains("html_partial/index.html", + "<span class='pc_cov'>100%</span>" + ) + +clean("html_partial") diff --git a/test/farm/html/run_styled.py b/test/farm/html/run_styled.py new file mode 100644 index 00000000..3a212957 --- /dev/null +++ b/test/farm/html/run_styled.py @@ -0,0 +1,28 @@ +def html_it(): + """Run coverage and make an HTML report for a.""" + import coverage + cov = coverage.coverage() + cov.start() + import a + cov.stop() + cov.html_report(a, directory="../html_styled", extra_css="extra.css") + +runfunc(html_it, rundir="src") + +# HTML files will change often. Check that the sizes are reasonable, +# and check that certain key strings are in the output. +compare("gold_styled", "html_styled", size_within=10, file_pattern="*.html") +compare("gold_styled", "html_styled", size_within=10, file_pattern="*.css") +contains("html_styled/a.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("html_styled/index.html", + "<link rel='stylesheet' href='extra.css' type='text/css'>", + "<a href='a.html'>a</a>", + "<span class='pc_cov'>67%</span>" + ) + +clean("html_styled") diff --git a/test/farm/html/run_unicode.py b/test/farm/html/run_unicode.py new file mode 100644 index 00000000..6ed44660 --- /dev/null +++ b/test/farm/html/run_unicode.py @@ -0,0 +1,30 @@ +import sys + +def html_it(): + """Run coverage and make an HTML report for unicode.py.""" + import coverage + cov = coverage.coverage() + cov.start() + import unicode + cov.stop() + cov.html_report(unicode, directory="../html_unicode") + +runfunc(html_it, rundir="src") + +# HTML files will change often. Check that the sizes are reasonable, +# and check that certain key strings are in the output. +compare("gold_unicode", "html_unicode", size_within=10, file_pattern="*.html") +contains("html_unicode/unicode.html", + "<span class='str'>"ʎd˙ǝbɐɹǝʌoɔ"</span>", + ) + +if sys.maxunicode == 65535: + contains("html_unicode/unicode.html", + "<span class='str'>"db40,dd00: x��"</span>", + ) +else: + contains("html_unicode/unicode.html", + "<span class='str'>"db40,dd00: x󠄀"</span>", + ) + +clean("html_unicode") diff --git a/test/farm/html/src/b.py b/test/farm/html/src/b.py index dffdd50f..3bf73a9f 100644 --- a/test/farm/html/src/b.py +++ b/test/farm/html/src/b.py @@ -16,13 +16,14 @@ def two(x): two(1) -def three_way(): - # for-else can be a three-way branch. - for i in range(10): - if i == 3: - break - else: - return 23 - return 17 +def three(): + try: + # This if has two branches, *neither* one taken. + if name_error_this_variable_doesnt_exist: + a = 1 + else: + a = 2 + except: + pass -three_way() +three() diff --git a/test/farm/html/src/bom.py b/test/farm/html/src/bom.py new file mode 100644 index 00000000..2db8b717 --- /dev/null +++ b/test/farm/html/src/bom.py @@ -0,0 +1,11 @@ +# A python source file in utf-8, with BOM
+math = "3×4 = 12, ÷2 = 6±0"
+ +import sys
+
+if sys.version_info >= (3, 0):
+ assert len(math) == 18
+ assert len(math.encode('utf-8')) == 21
+else:
+ assert len(math) == 21
+ assert len(math.decode('utf-8')) == 18
diff --git a/test/farm/html/src/coverage.xml b/test/farm/html/src/coverage.xml index bc517328..128cf750 100644 --- a/test/farm/html/src/coverage.xml +++ b/test/farm/html/src/coverage.xml @@ -4,7 +4,7 @@ <coverage branch-rate="0.0" line-rate="0.666666666667" timestamp="1263087779313" version="3.3a1">
<!-- Generated by coverage.py: http://nedbatchelder.com/code/coverage -->
<packages>
- <package branch-rate="0.0" complexity="0.0" line-rate="0.666666666667" name=".">
+ <package branch-rate="0.0" complexity="0.0" line-rate="0.666666666667" name="">
<classes>
<class branch-rate="0.0" complexity="0.0" filename="a.py" line-rate="0.666666666667" name="a">
<methods/>
diff --git a/test/farm/html/src/extra.css b/test/farm/html/src/extra.css new file mode 100644 index 00000000..46c41fcd --- /dev/null +++ b/test/farm/html/src/extra.css @@ -0,0 +1 @@ +/* Doesn't matter what goes in here, it gets copied. */ diff --git a/test/farm/html/src/isolatin1.py b/test/farm/html/src/isolatin1.py new file mode 100644 index 00000000..057c097b --- /dev/null +++ b/test/farm/html/src/isolatin1.py @@ -0,0 +1,5 @@ +# A python source file in another encoding. +# -*- coding: iso8859-1 -*- + +math = "34 = 12, 2 = 60" +assert len(math) == 18 diff --git a/test/farm/html/src/partial.py b/test/farm/html/src/partial.py new file mode 100644 index 00000000..8d62f5c5 --- /dev/null +++ b/test/farm/html/src/partial.py @@ -0,0 +1,18 @@ +# partial branches + +a = 3 + +while True: + break + +while 1: + break + +while a: # pragma: no branch + break + +if 0: + never_happen() + +if 1: + a = 13 diff --git a/test/farm/html/src/tabbed.py b/test/farm/html/src/tabbed.py index 4c39cafe..2035852f 100644 --- a/test/farm/html/src/tabbed.py +++ b/test/farm/html/src/tabbed.py @@ -5,4 +5,3 @@ if x: if x: # look nice b = "No spaces" # when they c = "Done" # line up. - diff --git a/test/farm/html/src/unicode.py b/test/farm/html/src/unicode.py new file mode 100644 index 00000000..f6a9a052 --- /dev/null +++ b/test/farm/html/src/unicode.py @@ -0,0 +1,5 @@ +# A python source file with exotic characters +# -*- coding: utf-8 -*- + +upside_down = "ʎd˙ǝbɐɹǝʌoɔ" +surrogate = "db40,dd00: x󠄀" diff --git a/test/farm/run/run_timid.py b/test/farm/run/run_timid.py index 3810e6db..b4f5134f 100644 --- a/test/farm/run/run_timid.py +++ b/test/farm/run/run_timid.py @@ -20,9 +20,8 @@ contains("out/showtraceout.txt", "timid PyTracer") if os.environ.get('COVERAGE_TEST_TRACER', 'c') == 'c': # If the C trace function is being tested, then regular running should have - # the C function (shown as None in f_trace since it isn't a Python - # function). - contains("out/showtraceout.txt", "regular None") + # the C function, which registers itself as f_trace. + contains("out/showtraceout.txt", "regular CTracer") else: # If the Python trace function is being tested, then regular running will # also show the Python function. diff --git a/test/farm/run/src/chdir.py b/test/farm/run/src/chdir.py index d8287ed7..6d834924 100644 --- a/test/farm/run/src/chdir.py +++ b/test/farm/run/src/chdir.py @@ -2,4 +2,3 @@ import os print("Line One") os.chdir("subdir") print("Line Two") - diff --git a/test/farm/run/src/showtrace.py b/test/farm/run/src/showtrace.py index c3b4356c..e97412e0 100644 --- a/test/farm/run/src/showtrace.py +++ b/test/farm/run/src/showtrace.py @@ -4,7 +4,7 @@ import sys # Show what the trace function is. If a C-based function is used, then f_trace -# is None. +# may be None. trace_fn = sys._getframe(0).f_trace if trace_fn is None: trace_name = "None" @@ -13,6 +13,11 @@ else: try: trace_name = trace_fn.im_class.__name__ except AttributeError: - trace_name = trace_fn.__self__.__class__.__name__ + try: + trace_name = trace_fn.__self__.__class__.__name__ + except AttributeError: + # A C-based function could also manifest as an f_trace value + # which doesn't have im_class or __self__. + trace_name = trace_fn.__class__.__name__ print("%s %s" % (sys.argv[1], trace_name)) diff --git a/test/js/index.html b/test/js/index.html new file mode 100644 index 00000000..60bdb30a --- /dev/null +++ b/test/js/index.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> +<head> + <title>Coverage.py Javascript Test Suite</title> + <link rel="stylesheet" href="../qunit/qunit.css" type="text/css" media="screen"> + <script type="text/javascript" src="../../coverage/htmlfiles/jquery-1.4.3.min.js"></script> + <script type='text/javascript' src="../../coverage/htmlfiles/jquery.isonscreen.js"></script> + <script type="text/javascript" src="../../coverage/htmlfiles/coverage_html.js"></script> + <script type="text/javascript" src="../qunit/qunit.js"></script> + <script type="text/javascript" src="../qunit/jquery.tmpl.min.js"></script> + + <style> + .r { background-color: red; } + .w { } + .b { background-color: blue; } + </style> + + <!-- Templates for the coverage report output --> + <script id="fixture-template" type="text/x-jquery-tmpl"> + <table cellspacing='0' cellpadding='0'> + <tr> + <td class='linenos' valign='top'> + <!-- #lineno-template goes here --> + </td> + <td class='text' valign='top'> + <!-- #text-template goes here --> + </td> + </tr> + </table> + </script> + + <script id="lineno-template" type="text/x-jquery-tmpl"> + <p id='n${number}' class='${klass}'><a href='#n${number}'>${number}</a></p> + </script> + + <script id="text-template" type="text/x-jquery-tmpl"> + <p id='t${number}' class='${klass}'>Hello, world!</p> + </script> + + <!-- Pull in the tests --> + <script type="text/javascript" src="tests.js"></script> + +</head> +<body> + <h1 id="qunit-header">Coverage.py Javascript Test Suite</h1> + <h2 id="qunit-banner"></h2> + <div id="qunit-testrunner-toolbar"></div> + <h2 id="qunit-userAgent"></h2> + <ol id="qunit-tests"></ol> + <div id="qunit-fixture"></div> +</body> +</html> diff --git a/test/js/tests.js b/test/js/tests.js new file mode 100644 index 00000000..73b4ce2b --- /dev/null +++ b/test/js/tests.js @@ -0,0 +1,204 @@ +// Tests of coverage.py HTML report chunk navigation. +/*global coverage, test, module, equals, jQuery, $ */ + +// Test helpers + +function selection_is(sel) { + raw_selection_is(sel, true); +} + +function raw_selection_is(sel, check_highlight) { + var beg = sel[0], end = sel[1]; + equals(coverage.sel_begin, beg); + equals(coverage.sel_end, end); + if (check_highlight) { + equals(coverage.code_container().find(".highlight").length, end-beg); + } +} + +function build_fixture(spec) { + var i, data; + $("#fixture-template").tmpl().appendTo("#qunit-fixture"); + for (i = 0; i < spec.length; i++) { + data = {number: i+1, klass: spec.substr(i, 1)}; + $("#lineno-template").tmpl(data).appendTo("#qunit-fixture .linenos"); + $("#text-template").tmpl(data).appendTo("#qunit-fixture .text"); + } + coverage.pyfile_ready(jQuery); +} + +// Tests + +// Zero-chunk tests + +module("Zero-chunk navigation", { + setup: function () { + build_fixture("wwww"); + } +}); + +test("set_sel defaults", function () { + coverage.set_sel(2); + equals(coverage.sel_begin, 2); + equals(coverage.sel_end, 3); +}); + +test("No first chunk to select", function () { + coverage.to_first_chunk(); +}); + +// One-chunk tests + +$.each([ + ['rrrrr', [1,6]], + ['r', [1,2]], + ['wwrrrr', [3,7]], + ['wwrrrrww', [3,7]], + ['rrrrww', [1,5]] +], function (i, params) { + + // Each of these tests uses a fixture with one highlighted chunks. + var id = params[0]; + var c1 = params[1]; + + module("One-chunk navigation - " + id, { + setup: function () { + build_fixture(id); + } + }); + + test("First chunk", function () { + coverage.to_first_chunk(); + selection_is(c1); + }); + + test("Next chunk is first chunk", function () { + coverage.to_next_chunk(); + selection_is(c1); + }); + + test("There is no next chunk", function () { + coverage.to_first_chunk(); + coverage.to_next_chunk(); + selection_is(c1); + }); + + test("There is no prev chunk", function () { + coverage.to_first_chunk(); + coverage.to_prev_chunk(); + selection_is(c1); + }); +}); + +// Two-chunk tests + +$.each([ + ['rrwwrrrr', [1,3], [5,9]], + ['rb', [1,2], [2,3]], + ['rbbbbbbbbbb', [1,2], [2,12]], + ['rrrrrrrrrrb', [1,11], [11,12]], + ['wrrwrrrrw', [2,4], [5,9]], + ['rrrbbb', [1,4], [4,7]] +], function (i, params) { + + // Each of these tests uses a fixture with two highlighted chunks. + var id = params[0]; + var c1 = params[1]; + var c2 = params[2]; + + module("Two-chunk navigation - " + id, { + setup: function () { + build_fixture(id); + } + }); + + test("First chunk", function () { + coverage.to_first_chunk(); + selection_is(c1); + }); + + test("Next chunk is first chunk", function () { + coverage.to_next_chunk(); + selection_is(c1); + }); + + test("Move to next chunk", function () { + coverage.to_first_chunk(); + coverage.to_next_chunk(); + selection_is(c2); + }); + + test("Move to first chunk", function () { + coverage.to_first_chunk(); + coverage.to_next_chunk(); + coverage.to_first_chunk(); + selection_is(c1); + }); + + test("Move to previous chunk", function () { + coverage.to_first_chunk(); + coverage.to_next_chunk(); + coverage.to_prev_chunk(); + selection_is(c1); + }); + + test("Next doesn't move after last chunk", function () { + coverage.to_first_chunk(); + coverage.to_next_chunk(); + coverage.to_next_chunk(); + selection_is(c2); + }); + + test("Prev doesn't move before first chunk", function () { + coverage.to_first_chunk(); + coverage.to_next_chunk(); + coverage.to_prev_chunk(); + coverage.to_prev_chunk(); + selection_is(c1); + }); + +}); + +module("Miscellaneous"); + +test("Jump from a line selected", function () { + build_fixture("rrwwrr"); + coverage.set_sel(3); + coverage.to_next_chunk(); + selection_is([5,7]); +}); + +// Tests of select_line_or_chunk. + +$.each([ + // The data for each test: a spec for the fixture to build, and an array + // of the selection that will be selected by select_line_or_chunk for + // each line in the fixture. + ['rrwwrr', [[1,3], [1,3], [3,4], [4,5], [5,7], [5,7]]], + ['rb', [[1,2], [2,3]]], + ['r', [[1,2]]], + ['w', [[1,2]]], + ['www', [[1,2], [2,3], [3,4]]], + ['wwwrrr', [[1,2], [2,3], [3,4], [4,7], [4,7], [4,7]]], + ['rrrwww', [[1,4], [1,4], [1,4], [4,5], [5,6], [6,7]]], + ['rrrbbb', [[1,4], [1,4], [1,4], [4,7], [4,7], [4,7]]] +], function (i, params) { + + // Each of these tests uses a fixture with two highlighted chunks. + var id = params[0]; + var sels = params[1]; + + module("Select line or chunk - " + id, { + setup: function () { + build_fixture(id); + } + }); + + $.each(sels, function (i, sel) { + i++; + test("Select line " + i, function () { + coverage.select_line_or_chunk(i); + raw_selection_is(sel); + }); + }); +}); diff --git a/test/meta_coverage.py b/test/meta_coverage.py index 1c71abf0..ef0292ae 100644 --- a/test/meta_coverage.py +++ b/test/meta_coverage.py @@ -45,7 +45,7 @@ def run_tests_with_coverage(): if hasattr(mod, '__file__') and mod.__file__.startswith(covdir): covmods[name] = mod del sys.modules[name] - import coverage # don't warn about re-import: pylint: disable-msg=W0404 + import coverage # don't warn about re-import: pylint: disable=W0404 #sys.modules.update(covmods) # Run nosetests, with the arguments from our command line. diff --git a/test/modules/pkg1/__main__.py b/test/modules/pkg1/__main__.py new file mode 100644 index 00000000..66ce5956 --- /dev/null +++ b/test/modules/pkg1/__main__.py @@ -0,0 +1,3 @@ +# Used in the tests for run_python_module +import sys +print("pkg1.__main__: passed %s" % sys.argv[1]) diff --git a/test/modules/pkg1/runmod2.py b/test/modules/pkg1/runmod2.py new file mode 100644 index 00000000..b52964cb --- /dev/null +++ b/test/modules/pkg1/runmod2.py @@ -0,0 +1,3 @@ +# Used in the tests for run_python_module +import sys +print("runmod2: passed %s" % sys.argv[1]) diff --git a/test/modules/pkg1/sub/__main__.py b/test/modules/pkg1/sub/__main__.py new file mode 100644 index 00000000..b5be9f1c --- /dev/null +++ b/test/modules/pkg1/sub/__main__.py @@ -0,0 +1,3 @@ +# Used in the tests for run_python_module +import sys +print("pkg1.sub.__main__: passed %s" % sys.argv[1]) diff --git a/test/modules/pkg1/sub/runmod3.py b/test/modules/pkg1/sub/runmod3.py new file mode 100644 index 00000000..3a1ad155 --- /dev/null +++ b/test/modules/pkg1/sub/runmod3.py @@ -0,0 +1,3 @@ +# Used in the tests for run_python_module +import sys +print("runmod3: passed %s" % sys.argv[1]) diff --git a/test/modules/runmod1.py b/test/modules/runmod1.py new file mode 100644 index 00000000..671d81ef --- /dev/null +++ b/test/modules/runmod1.py @@ -0,0 +1,3 @@ +# Used in the tests for run_python_module +import sys +print("runmod1: passed %s" % sys.argv[1]) diff --git a/test/modules/usepkgs.py b/test/modules/usepkgs.py index 208e3f30..93c7d904 100644 --- a/test/modules/usepkgs.py +++ b/test/modules/usepkgs.py @@ -1,2 +1,4 @@ import pkg1.p1a, pkg1.p1b import pkg2.p2a, pkg2.p2b +import othermods.othera, othermods.otherb +import othermods.sub.osa, othermods.sub.osb diff --git a/test/moremodules/othermods/__init__.py b/test/moremodules/othermods/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/moremodules/othermods/__init__.py diff --git a/test/moremodules/othermods/othera.py b/test/moremodules/othermods/othera.py new file mode 100644 index 00000000..78896928 --- /dev/null +++ b/test/moremodules/othermods/othera.py @@ -0,0 +1,2 @@ +o = 1 +p = 2 diff --git a/test/moremodules/othermods/otherb.py b/test/moremodules/othermods/otherb.py new file mode 100644 index 00000000..2bd8a441 --- /dev/null +++ b/test/moremodules/othermods/otherb.py @@ -0,0 +1,2 @@ +q = 3 +r = 4 diff --git a/test/moremodules/othermods/sub/__init__.py b/test/moremodules/othermods/sub/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/moremodules/othermods/sub/__init__.py diff --git a/test/moremodules/othermods/sub/osa.py b/test/moremodules/othermods/sub/osa.py new file mode 100644 index 00000000..0139d28b --- /dev/null +++ b/test/moremodules/othermods/sub/osa.py @@ -0,0 +1,2 @@ +s = 5 +t = 6 diff --git a/test/moremodules/othermods/sub/osb.py b/test/moremodules/othermods/sub/osb.py new file mode 100644 index 00000000..b024b148 --- /dev/null +++ b/test/moremodules/othermods/sub/osb.py @@ -0,0 +1,2 @@ +u = 7 +v = 8 diff --git a/test/osinfo.py b/test/osinfo.py index 04855fe6..25c3a7c6 100644 --- a/test/osinfo.py +++ b/test/osinfo.py @@ -45,8 +45,10 @@ elif sys.platform == 'linux2': try: # get pseudo file /proc/<pid>/status t = open('/proc/%d/status' % os.getpid()) - v = t.read() - t.close() + try: + v = t.read() + finally: + t.close() except IOError: return 0 # non-Linux? # get VmKey line e.g. 'VmRSS: 9999 kB\n ...' diff --git a/test/qunit/jquery.tmpl.min.js b/test/qunit/jquery.tmpl.min.js new file mode 100644 index 00000000..7438b2ca --- /dev/null +++ b/test/qunit/jquery.tmpl.min.js @@ -0,0 +1,10 @@ +/* + * jQuery Templates Plugin 1.0.0pre + * http://github.com/jquery/jquery-tmpl + * Requires jQuery 1.4.2 + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + */ +(function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},i=0,c=0,l=[];function g(g,d,h,e){var c={data:e||(e===0||e===false)?e:d?d.data:{},_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};g&&a.extend(c,g,{nodes:[],parent:d});if(h){c.tmpl=h;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++i;(l.length?f:b)[i]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if(j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for(h=0,m=i.length;h<m;h++){c=h;k=(h>0?this.clone(true):this).get();a(i[h])[d](k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,m,k){if(d[0]&&a.isArray(d[0])){var g=a.makeArray(arguments),h=d[0],j=h.length,i=0,f;while(i<j&&!(f=a.data(h[i++],"tmplItem")));if(f&&c)g[2]=function(b){a.tmpl.afterManip(this,b,k)};r.apply(this,g)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var i,k=!c;if(k){c=p;d=a.template[d]||a.template(null,d);f={}}else if(!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(j(c,null,c.tmpl(a,c)))}if(!d)return[];if(typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);i=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(j(c,null,i)):i},tmplItem:function(b){var c;if(b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if(b){if(typeof b==="string")b=o(b);else if(b instanceof a)b=b[0]||{};if(b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("<").split(">").join(">").split('"').join(""").split("'").join("'")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function j(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:j(a,e,a._ctnt)}):e;if(g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if(c)b=k(c).concat(b);if(d)b=b.concat(k(d))});return b?b:k(c)}function k(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,k,g,b,c,d){var j=a.tmpl.tag[k],i,e,f;if(!j)throw"Unknown template tag: "+k;i=j._default||[];if(c&&!/\w$/.test(b)){b+=c;c=""}if(b){b=h(b);d=d?","+h(d)+")":c?")":"";e=c?b.indexOf(".")>-1?b+h(c):"("+b+").call($item"+d:b;f=c?e:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else f=e=i.$1||"null";g=h(g);return"');"+j[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(f).split("$1").join(e).split("$2").join(g||i.$2||"")+"__.push('"})+"');}return __;")}function n(c,b){c._wrap=j(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function h(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,h;for(e=0,p=o.length;e<p;e++){if((k=o[e]).nodeType!==1)continue;j=k.getElementsByTagName("*");for(h=j.length-1;h>=0;h--)m(j[h]);m(k)}function m(j){var p,h=j,k,e,m;if(m=j.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(p=h.getAttribute(d)));if(p!==m){h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0;if(!(e=b[m])){e=f[m];e=g(e,b[h]||f[h]);e.key=++i;b[i]=e}c&&o(m)}j.removeAttribute(d)}else if(c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;h=a.data(j.parentNode,"tmplItem");h=h?h.key:0}if(e){k=e;while(k&&k.key!=h){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent)}}}function u(a,d,c,b){if(!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery);
\ No newline at end of file diff --git a/test/qunit/qunit.css b/test/qunit/qunit.css new file mode 100644 index 00000000..b3c6db52 --- /dev/null +++ b/test/qunit/qunit.css @@ -0,0 +1,225 @@ +/** + * QUnit - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult { + margin: 0; + padding: 0; +} + + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699a4; + background-color: #0d3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: normal; + + border-radius: 15px 15px 0 0; + -moz-border-radius: 15px 15px 0 0; + -webkit-border-top-right-radius: 15px; + -webkit-border-top-left-radius: 15px; +} + +#qunit-header a { + text-decoration: none; + color: #c2ccd1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #fff; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; +} + +#qunit-userAgent { + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; +} + +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { + display: none; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li a { + padding: 0.5em; + color: #c2ccd1; + text-decoration: none; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests ol { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #fff; + + border-radius: 15px; + -moz-border-radius: 15px; + -webkit-border-radius: 15px; + + box-shadow: inset 0px 2px 13px #999; + -moz-box-shadow: inset 0px 2px 13px #999; + -webkit-box-shadow: inset 0px 2px 13px #999; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: .2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #ffcaca; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: black; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + margin: 0.5em; + padding: 0.4em 0.5em 0.4em 0.5em; + background-color: #fff; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #5E740B; + background-color: #fff; + border-left: 26px solid #C6E746; +} + +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } +#qunit-tests .pass .test-name { color: #366097; } + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #fff; + border-left: 26px solid #EE5757; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 15px 15px; + -moz-border-radius: 0 0 15px 15px; + -webkit-border-bottom-right-radius: 15px; + -webkit-border-bottom-left-radius: 15px; +} + +#qunit-tests .fail { color: #000000; background-color: #EE5757; } +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { color: #000000; } + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: green; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + + +/** Result */ + +#qunit-testresult { + padding: 0.5em 0.5em 0.5em 2.5em; + + color: #2b81af; + background-color: #D2E0E6; + + border-bottom: 1px solid white; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; +} diff --git a/test/qunit/qunit.js b/test/qunit/qunit.js new file mode 100644 index 00000000..e00cca90 --- /dev/null +++ b/test/qunit/qunit.js @@ -0,0 +1,1448 @@ +/** + * QUnit - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +(function(window) { + +var defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + try { + return !!sessionStorage.getItem; + } catch(e){ + return false; + } + })() +}; + +var testId = 0; + +var Test = function(name, testName, expected, testEnvironmentArg, async, callback) { + this.name = name; + this.testName = testName; + this.expected = expected; + this.testEnvironmentArg = testEnvironmentArg; + this.async = async; + this.callback = callback; + this.assertions = []; +}; +Test.prototype = { + init: function() { + var tests = id("qunit-tests"); + if (tests) { + var b = document.createElement("strong"); + b.innerHTML = "Running " + this.name; + var li = document.createElement("li"); + li.appendChild( b ); + li.className = "running"; + li.id = this.id = "test-output" + testId++; + tests.appendChild( li ); + } + }, + setup: function() { + if (this.module != config.previousModule) { + if ( config.previousModule ) { + QUnit.moduleDone( { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + QUnit.moduleStart( { + name: this.module + } ); + } + + config.current = this; + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment); + if (this.testEnvironmentArg) { + extend(this.testEnvironment, this.testEnvironmentArg); + } + + QUnit.testStart( { + name: this.testName + } ); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + try { + if ( !config.pollution ) { + saveGlobal(); + } + + this.testEnvironment.setup.call(this.testEnvironment); + } catch(e) { + QUnit.ok( false, "Setup failed on " + this.testName + ": " + e.message ); + } + }, + run: function() { + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call(this.testEnvironment); + return; + } + try { + this.callback.call(this.testEnvironment); + } catch(e) { + fail("Test " + this.testName + " died, exception and test follows", e, this.callback); + QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + start(); + } + } + }, + teardown: function() { + try { + this.testEnvironment.teardown.call(this.testEnvironment); + checkPollution(); + } catch(e) { + QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message ); + } + }, + finish: function() { + if ( this.expected && this.expected != this.assertions.length ) { + QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); + } + + var good = 0, bad = 0, + tests = id("qunit-tests"); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + var ol = document.createElement("ol"); + + for ( var i = 0; i < this.assertions.length; i++ ) { + var assertion = this.assertions[i]; + + var li = document.createElement("li"); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed"); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if ( QUnit.config.reorder && defined.sessionStorage ) { + if (bad) { + sessionStorage.setItem("qunit-" + this.module + "-" + this.testName, bad); + } else { + sessionStorage.removeItem("qunit-" + this.module + "-" + this.testName); + } + } + + if (bad == 0) { + ol.style.display = "none"; + } + + var b = document.createElement("strong"); + b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; + + var a = document.createElement("a"); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + + addEvent(b, "click", function() { + var next = b.nextSibling.nextSibling, + display = next.style.display; + next.style.display = display === "none" ? "block" : "none"; + }); + + addEvent(b, "dblclick", function(e) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location = QUnit.url({ filter: getText([target]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + } + }); + + var li = id(this.id); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + li.appendChild( b ); + li.appendChild( a ); + li.appendChild( ol ); + + } else { + for ( var i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + try { + QUnit.reset(); + } catch(e) { + fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset); + } + + QUnit.testDone( { + name: this.testName, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length + } ); + }, + + queue: function() { + var test = this; + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + // defer when previous test run passed, if storage is available + var bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.module + "-" + this.testName); + if (bad) { + run(); + } else { + synchronize(run); + }; + } + +}; + +var QUnit = { + + // call on start of module test to prepend name to all tests + module: function(name, testEnvironment) { + config.currentModule = name; + config.currentModuleTestEnviroment = testEnvironment; + }, + + asyncTest: function(testName, expected, callback) { + if ( arguments.length === 2 ) { + callback = expected; + expected = 0; + } + + QUnit.test(testName, expected, callback, true); + }, + + test: function(testName, expected, callback, async) { + var name = '<span class="test-name">' + testName + '</span>', testEnvironmentArg; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + // is 2nd argument a testEnvironment? + if ( expected && typeof expected === 'object') { + testEnvironmentArg = expected; + expected = null; + } + + if ( config.currentModule ) { + name = '<span class="module-name">' + config.currentModule + "</span>: " + name; + } + + if ( !validTest(config.currentModule + ": " + testName) ) { + return; + } + + var test = new Test(name, testName, expected, testEnvironmentArg, async, callback); + test.module = config.currentModule; + test.moduleTestEnvironment = config.currentModuleTestEnviroment; + test.queue(); + }, + + /** + * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + */ + expect: function(asserts) { + config.current.expected = asserts; + }, + + /** + * Asserts true. + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function(a, msg) { + a = !!a; + var details = { + result: a, + message: msg + }; + msg = escapeHtml(msg); + QUnit.log(details); + config.current.assertions.push({ + result: a, + message: msg + }); + }, + + /** + * Checks that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * + * Prefered to ok( actual == expected, message ) + * + * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." ); + * + * @param Object actual + * @param Object expected + * @param String message (optional) + */ + equal: function(actual, expected, message) { + QUnit.push(expected == actual, actual, expected, message); + }, + + notEqual: function(actual, expected, message) { + QUnit.push(expected != actual, actual, expected, message); + }, + + deepEqual: function(actual, expected, message) { + QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); + }, + + notDeepEqual: function(actual, expected, message) { + QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); + }, + + strictEqual: function(actual, expected, message) { + QUnit.push(expected === actual, actual, expected, message); + }, + + notStrictEqual: function(actual, expected, message) { + QUnit.push(expected !== actual, actual, expected, message); + }, + + raises: function(block, expected, message) { + var actual, ok = false; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + if (actual) { + // we don't want to validate thrown error + if (!expected) { + ok = true; + // expected is a regexp + } else if (QUnit.objectType(expected) === "regexp") { + ok = expected.test(actual); + // expected is a constructor + } else if (actual instanceof expected) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if (expected.call({}, actual) === true) { + ok = true; + } + } + + QUnit.ok(ok, message); + }, + + start: function() { + config.semaphore--; + if (config.semaphore > 0) { + // don't start until equal number of stop-calls + return; + } + if (config.semaphore < 0) { + // ignore if start is called more often then stop + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if ( config.timeout ) { + clearTimeout(config.timeout); + } + + config.blocking = false; + process(); + }, 13); + } else { + config.blocking = false; + process(); + } + }, + + stop: function(timeout) { + config.semaphore++; + config.blocking = true; + + if ( timeout && defined.setTimeout ) { + clearTimeout(config.timeout); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + QUnit.start(); + }, timeout); + } + } +}; + +// Backwards compatibility, deprecated +QUnit.equals = QUnit.equal; +QUnit.same = QUnit.deepEqual; + +// Maintain internal state +var config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + noglobals: false, + notrycatch: false +}; + +// Load paramaters +(function() { + var location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( var i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + if ( current[ 0 ] in config ) { + config[ current[ 0 ] ] = current[ 1 ]; + } + } + } + + QUnit.urlParams = urlParams; + config.filter = urlParams.filter; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = !!(location.protocol === 'file:'); +})(); + +// Expose the API as global variables, unless an 'exports' +// object exists, in that case we assume we're in CommonJS +if ( typeof exports === "undefined" || typeof require === "undefined" ) { + extend(window, QUnit); + window.QUnit = QUnit; +} else { + extend(exports, QUnit); + exports.QUnit = QUnit; +} + +// define these after exposing globals to keep them in these QUnit namespace only +extend(QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend(config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date, + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 0 + }); + + var tests = id( "qunit-tests" ), + banner = id( "qunit-banner" ), + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = 'Running...<br/> '; + } + }, + + /** + * Resets the test setup. Useful for tests that modify the DOM. + * + * If jQuery is available, uses jQuery's html(), otherwise just innerHTML. + */ + reset: function() { + if ( window.jQuery ) { + jQuery( "#qunit-fixture" ).html( config.fixture ); + } else { + var main = id( 'qunit-fixture' ); + if ( main ) { + main.innerHTML = config.fixture; + } + } + }, + + /** + * Trigger an event on an element. + * + * @example triggerEvent( document.body, "click" ); + * + * @param DOMElement elem + * @param String type + */ + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent("MouseEvents"); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + elem.dispatchEvent( event ); + + } else if ( elem.fireEvent ) { + elem.fireEvent("on"+type); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if (typeof obj === "undefined") { + return "undefined"; + + // consider: typeof null === object + } + if (obj === null) { + return "null"; + } + + var type = Object.prototype.toString.call( obj ) + .match(/^\[object\s(.*)\]$/)[1] || ''; + + switch (type) { + case 'Number': + if (isNaN(obj)) { + return "nan"; + } else { + return "number"; + } + case 'String': + case 'Boolean': + case 'Array': + case 'Date': + case 'RegExp': + case 'Function': + return type.toLowerCase(); + } + if (typeof obj === "object") { + return "object"; + } + return undefined; + }, + + push: function(result, actual, expected, message) { + var details = { + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeHtml(message) || (result ? "okay" : "failed"); + message = '<span class="test-message">' + message + "</span>"; + expected = escapeHtml(QUnit.jsDump.parse(expected)); + actual = escapeHtml(QUnit.jsDump.parse(actual)); + var output = message + '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>'; + if (actual != expected) { + output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>'; + output += '<tr class="test-diff"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>'; + } + if (!result) { + var source = sourceFromStacktrace(); + if (source) { + details.source = source; + output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeHtml(source) + '</pre></td></tr>'; + } + } + output += "</table>"; + + QUnit.log(details); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var querystring = "?", + key; + for ( key in params ) { + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.pathname + querystring.slice( 0, -1 ); + }, + + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: function() {}, + // done: { failed, passed, total, runtime } + done: function() {}, + // log: { result, actual, expected, message } + log: function() {}, + // testStart: { name } + testStart: function() {}, + // testDone: { name, failed, passed, total } + testDone: function() {}, + // moduleStart: { name } + moduleStart: function() {}, + // moduleDone: { name, failed, passed, total } + moduleDone: function() {} +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +addEvent(window, "load", function() { + QUnit.begin({}); + + // Initialize the config, saving the execution queue + var oldconfig = extend({}, config); + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + var userAgent = id("qunit-userAgent"); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + var banner = id("qunit-header"); + if ( banner ) { + banner.innerHTML = '<a href="' + QUnit.url({ filter: undefined }) + '"> ' + banner.innerHTML + '</a> ' + + '<label><input name="noglobals" type="checkbox"' + ( config.noglobals ? ' checked="checked"' : '' ) + '>noglobals</label>' + + '<label><input name="notrycatch" type="checkbox"' + ( config.notrycatch ? ' checked="checked"' : '' ) + '>notrycatch</label>'; + addEvent( banner, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + } + + var toolbar = id("qunit-testrunner-toolbar"); + if ( toolbar ) { + var filter = document.createElement("input"); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + addEvent( filter, "click", function() { + var ol = document.getElementById("qunit-tests"); + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + var tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace(/ hidepass /, " "); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem("qunit-filter-passed-tests", "true"); + } else { + sessionStorage.removeItem("qunit-filter-passed-tests"); + } + } + }); + if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { + filter.checked = true; + var ol = document.getElementById("qunit-tests"); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + var label = document.createElement("label"); + label.setAttribute("for", "qunit-filter-pass"); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + } + + var main = id('qunit-fixture'); + if ( main ) { + config.fixture = main.innerHTML; + } + + if (config.autostart) { + QUnit.start(); + } +}); + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + QUnit.moduleDone( { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + + var banner = id("qunit-banner"), + tests = id("qunit-tests"), + runtime = +new Date - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + 'Tests completed in ', + runtime, + ' milliseconds.<br/>', + '<span class="passed">', + passed, + '</span> tests of <span class="total">', + config.stats.all, + '</span> passed, <span class="failed">', + config.stats.bad, + '</span> failed.' + ].join(''); + + if ( banner ) { + banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass"); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = (config.stats.bad ? "\u2716" : "\u2714") + " " + document.title; + } + + QUnit.done( { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + } ); +} + +function validTest( name ) { + var filter = config.filter, + run = false; + + if ( !filter ) { + return true; + } + + var not = filter.charAt( 0 ) === "!"; + if ( not ) { + filter = filter.slice( 1 ); + } + + if ( name.indexOf( filter ) !== -1 ) { + return !not; + } + + if ( not ) { + run = true; + } + + return run; +} + +// so far supports only Firefox, Chrome and Opera (buggy) +// could be extended in the future to use something like https://github.com/csnover/TraceKit +function sourceFromStacktrace() { + try { + throw new Error(); + } catch ( e ) { + if (e.stacktrace) { + // Opera + return e.stacktrace.split("\n")[6]; + } else if (e.stack) { + // Firefox, Chrome + return e.stack.split("\n")[4]; + } + } +} + +function escapeHtml(s) { + if (!s) { + return ""; + } + s = s + ""; + return s.replace(/[\&"<>\\]/g, function(s) { + switch(s) { + case "&": return "&"; + case "\\": return "\\\\"; + case '"': return '\"'; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process(); + } +} + +function process() { + var start = (new Date()).getTime(); + + while ( config.queue.length && !config.blocking ) { + if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) { + config.queue.shift()(); + } else { + window.setTimeout( process, 13 ); + break; + } + } + if (!config.blocking && !config.queue.length) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var old = config.pollution; + saveGlobal(); + + var newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + ok( false, "Introduced global variable(s): " + newGlobals.join(", ") ); + } + + var deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var result = a.slice(); + for ( var i = 0; i < result.length; i++ ) { + for ( var j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice(i, 1); + i--; + break; + } + } + } + return result; +} + +function fail(message, exception, callback) { + if ( typeof console !== "undefined" && console.error && console.warn ) { + console.error(message); + console.error(exception); + console.warn(callback.toString()); + + } else if ( window.opera && opera.postError ) { + opera.postError(message, exception, callback.toString); + } +} + +function extend(a, b) { + for ( var prop in b ) { + if ( b[prop] === undefined ) { + delete a[prop]; + } else { + a[prop] = b[prop]; + } + } + + return a; +} + +function addEvent(elem, type, fn) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id(name) { + return !!(typeof document !== "undefined" && document && document.getElementById) && + document.getElementById( name ); +} + +// Test for equality any JavaScript type. +// Discussions and reference: http://philrathe.com/articles/equiv +// Test suites: http://philrathe.com/tests/equiv +// Author: Philippe Rathé <prathe@gmail.com> +QUnit.equiv = function () { + + var innerEquiv; // the real equiv function + var callers = []; // stack to decide between skip/abort functions + var parents = []; // stack to avoiding loops from circular referencing + + // Call the o related callback with the given arguments. + function bindCallbacks(o, callbacks, args) { + var prop = QUnit.objectType(o); + if (prop) { + if (QUnit.objectType(callbacks[prop]) === "function") { + return callbacks[prop].apply(callbacks, args); + } else { + return callbacks[prop]; // or undefined + } + } + } + + var callbacks = function () { + + // for string, boolean, number and null + function useStrictEquality(b, a) { + if (b instanceof a.constructor || a instanceof b.constructor) { + // to catch short annotaion VS 'new' annotation of a declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string": useStrictEquality, + "boolean": useStrictEquality, + "number": useStrictEquality, + "null": useStrictEquality, + "undefined": useStrictEquality, + + "nan": function (b) { + return isNaN(b); + }, + + "date": function (b, a) { + return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp": function (b, a) { + return QUnit.objectType(b) === "regexp" && + a.source === b.source && // the regex itself + a.global === b.global && // and its modifers (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function": function () { + var caller = callers[callers.length - 1]; + return caller !== Object && + typeof caller !== "undefined"; + }, + + "array": function (b, a) { + var i, j, loop; + var len; + + // b could be an object literal here + if ( ! (QUnit.objectType(b) === "array")) { + return false; + } + + len = a.length; + if (len !== b.length) { // safe and faster + return false; + } + + //track reference to avoid circular references + parents.push(a); + for (i = 0; i < len; i++) { + loop = false; + for(j=0;j<parents.length;j++){ + if(parents[j] === a[i]){ + loop = true;//dont rewalk array + } + } + if (!loop && ! innerEquiv(a[i], b[i])) { + parents.pop(); + return false; + } + } + parents.pop(); + return true; + }, + + "object": function (b, a) { + var i, j, loop; + var eq = true; // unless we can proove it + var aProperties = [], bProperties = []; // collection of strings + + // comparing constructors is more strict than using instanceof + if ( a.constructor !== b.constructor) { + return false; + } + + // stack constructor before traversing properties + callers.push(a.constructor); + //track reference to avoid circular references + parents.push(a); + + for (i in a) { // be strict: don't ensures hasOwnProperty and go deep + loop = false; + for(j=0;j<parents.length;j++){ + if(parents[j] === a[i]) + loop = true; //don't go down the same path twice + } + aProperties.push(i); // collect a's properties + + if (!loop && ! innerEquiv(a[i], b[i])) { + eq = false; + break; + } + } + + callers.pop(); // unstack, we are done + parents.pop(); + + for (i in b) { + bProperties.push(i); // collect b's properties + } + + // Ensures identical properties name + return eq && innerEquiv(aProperties.sort(), bProperties.sort()); + } + }; + }(); + + innerEquiv = function () { // can take multiple arguments + var args = Array.prototype.slice.apply(arguments); + if (args.length < 2) { + return true; // end transition + } + + return (function (a, b) { + if (a === b) { + return true; // catch the most you can + } else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || QUnit.objectType(a) !== QUnit.objectType(b)) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [b, a]); + } + + // apply transition with (1..n) arguments + })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1)); + }; + + return innerEquiv; + +}(); + +/** + * jsDump + * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com + * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php) + * Date: 5/15/2008 + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ +QUnit.jsDump = (function() { + function quote( str ) { + return '"' + str.toString().replace(/"/g, '\\"') + '"'; + }; + function literal( o ) { + return o + ''; + }; + function join( pre, arr, post ) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if ( arr.join ) + arr = arr.join( ',' + s + inner ); + if ( !arr ) + return pre + post; + return [ pre, inner + arr, base + post ].join(s); + }; + function array( arr ) { + var i = arr.length, ret = Array(i); + this.up(); + while ( i-- ) + ret[i] = this.parse( arr[i] ); + this.down(); + return join( '[', ret, ']' ); + }; + + var reName = /^function (\w+)/; + + var jsDump = { + parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance + var parser = this.parsers[ type || this.typeOf(obj) ]; + type = typeof parser; + + return type == 'function' ? parser.call( this, obj ) : + type == 'string' ? parser : + this.parsers.error; + }, + typeOf:function( obj ) { + var type; + if ( obj === null ) { + type = "null"; + } else if (typeof obj === "undefined") { + type = "undefined"; + } else if (QUnit.is("RegExp", obj)) { + type = "regexp"; + } else if (QUnit.is("Date", obj)) { + type = "date"; + } else if (QUnit.is("Function", obj)) { + type = "function"; + } else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") { + type = "window"; + } else if (obj.nodeType === 9) { + type = "document"; + } else if (obj.nodeType) { + type = "node"; + } else if (typeof obj === "object" && typeof obj.length === "number" && obj.length >= 0) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator:function() { + return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? ' ' : ' '; + }, + indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) + return ''; + var chr = this.indentChar; + if ( this.HTML ) + chr = chr.replace(/\t/g,' ').replace(/ /g,' '); + return Array( this._depth_ + (extra||0) ).join(chr); + }, + up:function( a ) { + this._depth_ += a || 1; + }, + down:function( a ) { + this._depth_ -= a || 1; + }, + setParser:function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote:quote, + literal:literal, + join:join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers:{ + window: '[Window]', + document: '[Document]', + error:'[ERROR]', //when no parser is found, shouldn't happen + unknown: '[Unknown]', + 'null':'null', + 'undefined':'undefined', + 'function':function( fn ) { + var ret = 'function', + name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE + if ( name ) + ret += ' ' + name; + ret += '('; + + ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); + return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); + }, + array: array, + nodelist: array, + arguments: array, + object:function( map ) { + var ret = [ ]; + QUnit.jsDump.up(); + for ( var key in map ) + ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(map[key]) ); + QUnit.jsDump.down(); + return join( '{', ret, '}' ); + }, + node:function( node ) { + var open = QUnit.jsDump.HTML ? '<' : '<', + close = QUnit.jsDump.HTML ? '>' : '>'; + + var tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( var a in QUnit.jsDump.DOMAttrs ) { + var val = node[QUnit.jsDump.DOMAttrs[a]]; + if ( val ) + ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' ); + } + return ret + close + open + '/' + tag + close; + }, + functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function + var l = fn.length; + if ( !l ) return ''; + + var args = Array(l); + while ( l-- ) + args[l] = String.fromCharCode(97+l);//97 is 'a' + return ' ' + args.join(', ') + ' '; + }, + key:quote, //object calls it internally, the key part of an item in a map + functionCode:'[code]', //function calls it internally, it's the content of the function + attribute:quote, //node calls it internally, it's an html attribute value + string:quote, + date:quote, + regexp:literal, //regex + number:literal, + 'boolean':literal + }, + DOMAttrs:{//attributes to dump from nodes, name=>realName + id:'id', + name:'name', + 'class':'className' + }, + HTML:false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar:' ',//indentation unit + multiline:true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +})(); + +// from Sizzle.js +function getText( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += getText( elem.childNodes ); + } + } + + return ret; +}; + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over" + */ +QUnit.diff = (function() { + function diff(o, n){ + var ns = new Object(); + var os = new Object(); + + for (var i = 0; i < n.length; i++) { + if (ns[n[i]] == null) + ns[n[i]] = { + rows: new Array(), + o: null + }; + ns[n[i]].rows.push(i); + } + + for (var i = 0; i < o.length; i++) { + if (os[o[i]] == null) + os[o[i]] = { + rows: new Array(), + n: null + }; + os[o[i]].rows.push(i); + } + + for (var i in ns) { + if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { + n[ns[i].rows[0]] = { + text: n[ns[i].rows[0]], + row: os[i].rows[0] + }; + o[os[i].rows[0]] = { + text: o[os[i].rows[0]], + row: ns[i].rows[0] + }; + } + } + + for (var i = 0; i < n.length - 1; i++) { + if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && + n[i + 1] == o[n[i].row + 1]) { + n[i + 1] = { + text: n[i + 1], + row: n[i].row + 1 + }; + o[n[i].row + 1] = { + text: o[n[i].row + 1], + row: i + 1 + }; + } + } + + for (var i = n.length - 1; i > 0; i--) { + if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && + n[i - 1] == o[n[i].row - 1]) { + n[i - 1] = { + text: n[i - 1], + row: n[i].row - 1 + }; + o[n[i].row - 1] = { + text: o[n[i].row - 1], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function(o, n){ + o = o.replace(/\s+$/, ''); + n = n.replace(/\s+$/, ''); + var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)); + + var str = ""; + + var oSpace = o.match(/\s+/g); + if (oSpace == null) { + oSpace = [" "]; + } + else { + oSpace.push(" "); + } + var nSpace = n.match(/\s+/g); + if (nSpace == null) { + nSpace = [" "]; + } + else { + nSpace.push(" "); + } + + if (out.n.length == 0) { + for (var i = 0; i < out.o.length; i++) { + str += '<del>' + out.o[i] + oSpace[i] + "</del>"; + } + } + else { + if (out.n[0].text == null) { + for (n = 0; n < out.o.length && out.o[n].text == null; n++) { + str += '<del>' + out.o[n] + oSpace[n] + "</del>"; + } + } + + for (var i = 0; i < out.n.length; i++) { + if (out.n[i].text == null) { + str += '<ins>' + out.n[i] + nSpace[i] + "</ins>"; + } + else { + var pre = ""; + + for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { + pre += '<del>' + out.o[n] + oSpace[n] + "</del>"; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +})(); + +})(this); diff --git a/test/test_api.py b/test/test_api.py index 5952dfe7..c15db5ed 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -84,13 +84,13 @@ class SingletonApiTest(CoverageTest): self.do_report_work("mycode4") coverage.report() rpt = re.sub(r"\s+", " ", self.stdout()) - self.assertTrue("mycode4 7 3 57% 4-6" in rpt) + self.assertIn("mycode4 7 3 57% 4-6", rpt) class ApiTest(CoverageTest): """Api-oriented tests for Coverage.""" - def clean_files(self, files, *pats): + def clean_files(self, files, pats): """Remove names matching `pats` from `files`, a list of filenames.""" good = [] for f in files: @@ -101,10 +101,11 @@ class ApiTest(CoverageTest): good.append(f) return good - def listdir(self, where): - """Like os.listdir, but exclude files we don't care about.""" - files = os.listdir(where) - return self.clean_files(files, "*.pyc", "__pycache__") + def assertFiles(self, files): + """Assert that the files here are `files`, ignoring the usual junk.""" + here = os.listdir(".") + here = self.clean_files(here, ["*.pyc", "__pycache__"]) + self.assertSameElements(here, files) def test_unexecuted_file(self): cov = coverage.coverage() @@ -176,15 +177,11 @@ class ApiTest(CoverageTest): def test_ignore_stdlib(self): self.make_file("mymain.py", """\ - import mymod, colorsys + import colorsys a = 1 hls = colorsys.rgb_to_hls(1.0, 0.5, 0.0) """) - self.make_file("mymod.py", """\ - fooey = 17 - """) - # Measure without the stdlib. cov1 = coverage.coverage() self.assertEqual(cov1.config.cover_pylib, False) @@ -212,6 +209,27 @@ class ApiTest(CoverageTest): _, statements, missing, _ = cov2.analysis("colorsys.py") self.assertNotEqual(statements, missing) + def test_include_can_measure_stdlib(self): + self.make_file("mymain.py", """\ + import colorsys, random + a = 1 + r, g, b = [random.random() for _ in range(3)] + hls = colorsys.rgb_to_hls(r, g, b) + """) + + # Measure without the stdlib, but include colorsys. + cov1 = coverage.coverage(cover_pylib=False, include=["*/colorsys.py"]) + cov1.start() + self.import_local_file("mymain") # pragma: recursive coverage + cov1.stop() # pragma: recursive coverage + + # some statements were marked executed in colorsys.py + _, statements, missing, _ = cov1.analysis("colorsys.py") + self.assertNotEqual(statements, missing) + # but none were in random.py + _, statements, missing, _ = cov1.analysis("random.py") + self.assertEqual(statements, missing) + def test_exclude_list(self): cov = coverage.coverage() cov.clear_exclude() @@ -220,24 +238,56 @@ class ApiTest(CoverageTest): self.assertEqual(cov.get_exclude_list(), ["foo"]) cov.exclude("bar") self.assertEqual(cov.get_exclude_list(), ["foo", "bar"]) - self.assertEqual(cov.exclude_re, "(foo)|(bar)") + self.assertEqual(cov._exclude_regex('exclude'), "(foo)|(bar)") cov.clear_exclude() self.assertEqual(cov.get_exclude_list(), []) + def test_exclude_partial_list(self): + cov = coverage.coverage() + cov.clear_exclude(which='partial') + self.assertEqual(cov.get_exclude_list(which='partial'), []) + cov.exclude("foo", which='partial') + self.assertEqual(cov.get_exclude_list(which='partial'), ["foo"]) + cov.exclude("bar", which='partial') + self.assertEqual(cov.get_exclude_list(which='partial'), ["foo", "bar"]) + self.assertEqual(cov._exclude_regex(which='partial'), "(foo)|(bar)") + cov.clear_exclude(which='partial') + self.assertEqual(cov.get_exclude_list(which='partial'), []) + + def test_exclude_and_partial_are_separate_lists(self): + cov = coverage.coverage() + cov.clear_exclude(which='partial') + cov.clear_exclude(which='exclude') + cov.exclude("foo", which='partial') + self.assertEqual(cov.get_exclude_list(which='partial'), ['foo']) + self.assertEqual(cov.get_exclude_list(which='exclude'), []) + cov.exclude("bar", which='exclude') + self.assertEqual(cov.get_exclude_list(which='partial'), ['foo']) + self.assertEqual(cov.get_exclude_list(which='exclude'), ['bar']) + cov.exclude("p2", which='partial') + cov.exclude("e2", which='exclude') + self.assertEqual(cov.get_exclude_list(which='partial'), ['foo', 'p2']) + self.assertEqual(cov.get_exclude_list(which='exclude'), ['bar', 'e2']) + cov.clear_exclude(which='partial') + self.assertEqual(cov.get_exclude_list(which='partial'), []) + self.assertEqual(cov.get_exclude_list(which='exclude'), ['bar', 'e2']) + cov.clear_exclude(which='exclude') + self.assertEqual(cov.get_exclude_list(which='partial'), []) + self.assertEqual(cov.get_exclude_list(which='exclude'), []) + def test_datafile_default(self): # Default data file behavior: it's .coverage self.make_file("datatest1.py", """\ fooey = 17 """) - self.assertSameElements(self.listdir("."), ["datatest1.py"]) + self.assertFiles(["datatest1.py"]) cov = coverage.coverage() cov.start() self.import_local_file("datatest1") # pragma: recursive coverage cov.stop() # pragma: recursive coverage cov.save() - self.assertSameElements(self.listdir("."), - ["datatest1.py", ".coverage"]) + self.assertFiles(["datatest1.py", ".coverage"]) def test_datafile_specified(self): # You can specify the data file name. @@ -245,14 +295,13 @@ class ApiTest(CoverageTest): fooey = 17 """) - self.assertSameElements(self.listdir("."), ["datatest2.py"]) + self.assertFiles(["datatest2.py"]) cov = coverage.coverage(data_file="cov.data") cov.start() self.import_local_file("datatest2") # pragma: recursive coverage cov.stop() # pragma: recursive coverage cov.save() - self.assertSameElements(self.listdir("."), - ["datatest2.py", "cov.data"]) + self.assertFiles(["datatest2.py", "cov.data"]) def test_datafile_and_suffix_specified(self): # You can specify the data file name and suffix. @@ -260,14 +309,13 @@ class ApiTest(CoverageTest): fooey = 17 """) - self.assertSameElements(self.listdir("."), ["datatest3.py"]) + self.assertFiles(["datatest3.py"]) cov = coverage.coverage(data_file="cov.data", data_suffix="14") cov.start() self.import_local_file("datatest3") # pragma: recursive coverage cov.stop() # pragma: recursive coverage cov.save() - self.assertSameElements(self.listdir("."), - ["datatest3.py", "cov.data.14"]) + self.assertFiles(["datatest3.py", "cov.data.14"]) def test_datafile_from_rcfile(self): # You can specify the data file name in the .coveragerc file @@ -279,15 +327,13 @@ class ApiTest(CoverageTest): data_file = mydata.dat """) - self.assertSameElements(self.listdir("."), - ["datatest4.py", ".coveragerc"]) + self.assertFiles(["datatest4.py", ".coveragerc"]) cov = coverage.coverage() cov.start() self.import_local_file("datatest4") # pragma: recursive coverage cov.stop() # pragma: recursive coverage cov.save() - self.assertSameElements(self.listdir("."), - ["datatest4.py", ".coveragerc", "mydata.dat"]) + self.assertFiles(["datatest4.py", ".coveragerc", "mydata.dat"]) def test_empty_reporting(self): # Used to be you'd get an exception reporting on nothing... @@ -296,17 +342,84 @@ class ApiTest(CoverageTest): cov.report() -class SourceOmitIncludeTest(CoverageTest): - """Test using `source`, `omit` and `include` when measuring code.""" +class UsingModulesMixin(object): + """A mixin for importing modules from test/modules and test/moremodules.""" run_in_temp_dir = False def setUp(self): - super(SourceOmitIncludeTest, self).setUp() + super(UsingModulesMixin, self).setUp() # Parent class saves and restores sys.path, we can just modify it. - sys.path.append(self.nice_file(os.path.dirname(__file__), 'modules')) + self.old_dir = os.getcwd() + os.chdir(self.nice_file(os.path.dirname(__file__), 'modules')) + sys.path.append(".") + sys.path.append("../moremodules") + + def tearDown(self): + os.chdir(self.old_dir) + super(UsingModulesMixin, self).tearDown() + + +class OmitIncludeTestsMixin(UsingModulesMixin): + """Test methods for coverage methods taking include and omit.""" + + def filenames_in(self, summary, filenames): + """Assert the `filenames` are in the keys of `summary`.""" + for filename in filenames.split(): + self.assertIn(filename, summary) + + def filenames_not_in(self, summary, filenames): + """Assert the `filenames` are not in the keys of `summary`.""" + for filename in filenames.split(): + self.assertNotIn(filename, summary) + + def test_nothing_specified(self): + result = self.coverage_usepkgs() + self.filenames_in(result, "p1a p1b p2a p2b othera otherb osa osb") + self.filenames_not_in(result, "p1c") + # Because there was no source= specified, we don't search for + # unexecuted files. + + def test_include(self): + result = self.coverage_usepkgs(include=["*/p1a.py"]) + self.filenames_in(result, "p1a") + self.filenames_not_in(result, "p1b p1c p2a p2b othera otherb osa osb") + + def test_include_2(self): + result = self.coverage_usepkgs(include=["*a.py"]) + self.filenames_in(result, "p1a p2a othera osa") + self.filenames_not_in(result, "p1b p1c p2b otherb osb") + + def test_include_as_string(self): + result = self.coverage_usepkgs(include="*a.py") + self.filenames_in(result, "p1a p2a othera osa") + self.filenames_not_in(result, "p1b p1c p2b otherb osb") + + def test_omit(self): + result = self.coverage_usepkgs(omit=["*/p1a.py"]) + self.filenames_in(result, "p1b p2a p2b") + self.filenames_not_in(result, "p1a p1c") + + def test_omit_2(self): + result = self.coverage_usepkgs(omit=["*a.py"]) + self.filenames_in(result, "p1b p2b otherb osb") + self.filenames_not_in(result, "p1a p1c p2a othera osa") - def coverage_usepkgs_summary(self, **kwargs): + def test_omit_as_string(self): + result = self.coverage_usepkgs(omit="*a.py") + self.filenames_in(result, "p1b p2b otherb osb") + self.filenames_not_in(result, "p1a p1c p2a othera osa") + + def test_omit_and_include(self): + result = self.coverage_usepkgs( include=["*/p1*"], omit=["*/p1a.py"]) + self.filenames_in(result, "p1b") + self.filenames_not_in(result, "p1a p1c p2a p2b") + + +class SourceOmitIncludeTest(OmitIncludeTestsMixin, CoverageTest): + """Test using `source`, `omit` and `include` when measuring code.""" + + def coverage_usepkgs(self, **kwargs): """Run coverage on usepkgs and return the line summary. Arguments are passed to the `coverage.coverage` constructor. @@ -314,56 +427,89 @@ class SourceOmitIncludeTest(CoverageTest): """ cov = coverage.coverage(**kwargs) cov.start() - import usepkgs # pylint: disable-msg=F0401,W0612 + import usepkgs # pylint: disable=F0401,W0612 cov.stop() - return cov.data.summary() - - def test_nothing_specified(self): - lines = self.coverage_usepkgs_summary() - self.assertEqual(lines['p1a.py'], 3) - self.assertEqual(lines['p1b.py'], 3) - self.assertEqual(lines['p2a.py'], 3) - self.assertEqual(lines['p2b.py'], 3) - # Because there was no source= specified, we don't search for - # unexecuted files. - self.assert_('p1c.py' not in lines) + cov._harvest_data() # private! sshhh... + summary = cov.data.summary() + for k, v in list(summary.items()): + assert k.endswith(".py") + summary[k[:-3]] = v + return summary def test_source_package(self): - lines = self.coverage_usepkgs_summary(source=["pkg1"]) - self.assertEqual(lines['p1a.py'], 3) - self.assertEqual(lines['p1b.py'], 3) - self.assert_('p2a.py' not in lines) - self.assert_('p2b.py' not in lines) + lines = self.coverage_usepkgs(source=["pkg1"]) + self.filenames_in(lines, "p1a p1b") + self.filenames_not_in(lines, "p2a p2b othera otherb osa osb") # Because source= was specified, we do search for unexecuted files. - self.assertEqual(lines['p1c.py'], 0) + self.assertEqual(lines['p1c'], 0) def test_source_package_dotted(self): - lines = self.coverage_usepkgs_summary(source=["pkg1.p1b"]) - self.assert_('p1a.py' not in lines) - self.assertEqual(lines['p1b.py'], 3) - self.assert_('p2a.py' not in lines) - self.assert_('p2b.py' not in lines) - self.assert_('p1c.py' not in lines) + lines = self.coverage_usepkgs(source=["pkg1.p1b"]) + self.filenames_in(lines, "p1b") + self.filenames_not_in(lines, "p1a p1c p2a p2b othera otherb osa osb") - def test_include(self): - lines = self.coverage_usepkgs_summary(include=["*/p1a.py"]) - self.assertEqual(lines['p1a.py'], 3) - self.assert_('p1b.py' not in lines) - self.assert_('p2a.py' not in lines) - self.assert_('p2b.py' not in lines) - def test_omit(self): - lines = self.coverage_usepkgs_summary(omit=["*/p1a.py"]) - self.assert_('p1a.py' not in lines) - self.assertEqual(lines['p1b.py'], 3) - self.assertEqual(lines['p2a.py'], 3) - self.assertEqual(lines['p2b.py'], 3) +class ReportIncludeOmitTest(OmitIncludeTestsMixin, CoverageTest): + """Tests of the report include/omit functionality.""" - def test_omit_and_include(self): - lines = self.coverage_usepkgs_summary( - include=["*/p1*"], omit=["*/p1a.py"] - ) - self.assert_('p1a.py' not in lines) - self.assertEqual(lines['p1b.py'], 3) - self.assert_('p2a.py' not in lines) - self.assert_('p2b.py' not in lines) + def coverage_usepkgs(self, **kwargs): + """Try coverage.report().""" + cov = coverage.coverage() + cov.start() + import usepkgs # pylint: disable=F0401,W0612 + cov.stop() + report = StringIO() + cov.report(file=report, **kwargs) + return report.getvalue() + + +class XmlIncludeOmitTest(OmitIncludeTestsMixin, CoverageTest): + """Tests of the xml include/omit functionality. + + This also takes care of the HTML and annotate include/omit, by virtue + of the structure of the code. + + """ + + def coverage_usepkgs(self, **kwargs): + """Try coverage.xml_report().""" + cov = coverage.coverage() + cov.start() + import usepkgs # pylint: disable=F0401,W0612 + cov.stop() + cov.xml_report(outfile="-", **kwargs) + return self.stdout() + + +class AnalysisTest(CoverageTest): + """Test the numerical analysis of results.""" + def test_many_missing_branches(self): + cov = coverage.coverage(branch=True) + + self.make_file("missing.py", """\ + def fun1(x): + if x == 1: + print("one") + else: + print("not one") + print("done") # pragma: nocover + + def fun2(x): + print("x") + + fun2(3) + """) + + # Import the python file, executing it. + cov.start() + self.import_local_file("missing") # pragma: recursive coverage + cov.stop() # pragma: recursive coverage + + nums = cov._analyze("missing.py").numbers + self.assertEqual(nums.n_files, 1) + self.assertEqual(nums.n_statements, 7) + self.assertEqual(nums.n_excluded, 1) + self.assertEqual(nums.n_missing, 3) + self.assertEqual(nums.n_branches, 2) + self.assertEqual(nums.n_partial_branches, 0) + self.assertEqual(nums.n_missing_branches, 2) diff --git a/test/test_arcs.py b/test/test_arcs.py index dafe0fbb..a9f7470b 100644 --- a/test/test_arcs.py +++ b/test/test_arcs.py @@ -143,6 +143,23 @@ class SimpleArcTest(CoverageTest): ) +if sys.version_info >= (2, 6): + class WithTest(CoverageTest): + """Arc-measuring tests involving context managers.""" + + def test_with(self): + self.check_coverage("""\ + def example(): + with open("test", "w") as f: # exit + f.write("") + return 1 + + example() + """, + arcz=".1 .2 23 34 4. 16 6." + ) + + class LoopArcTest(CoverageTest): """Arc-measuring tests involving loops.""" @@ -213,15 +230,14 @@ class LoopArcTest(CoverageTest): i += 1 assert a == 4 and i == 3 """, - arcz=".1 12 23 34 45 36 63 57 27 7.", - arcz_missing="27" # while loop never exits naturally. + arcz=".1 12 23 34 45 36 63 57 7.", ) # With "while True", 2.x thinks it's computation, 3.x thinks it's # constant. if sys.version_info >= (3, 0): - arcz = ".1 12 23 34 45 36 63 57 27 7." + arcz = ".1 12 23 34 45 36 63 57 7." else: - arcz = ".1 12 23 34 45 36 62 57 27 7." + arcz = ".1 12 23 27 34 45 36 62 57 7." self.check_coverage("""\ a, i = 1, 0 while True: @@ -232,7 +248,6 @@ class LoopArcTest(CoverageTest): assert a == 4 and i == 3 """, arcz=arcz, - arcz_missing="27" # while loop never exits naturally. ) def test_for_if_else_for(self): @@ -262,6 +277,21 @@ class LoopArcTest(CoverageTest): arcz_missing="26 6." ) + def test_for_else(self): + self.check_coverage("""\ + def forelse(seq): + for n in seq: + if n > 5: + break + else: + print('None of the values were greater than 5') + print('Done') + forelse([1,2]) + forelse([1,6]) + """, + arcz=".1 .2 23 32 34 47 26 67 7. 18 89 9." + ) + class ExceptionArcTest(CoverageTest): """Arc-measuring tests involving exception handling.""" @@ -420,18 +450,19 @@ class ExceptionArcTest(CoverageTest): arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AB AD BC CD D.", arcz_missing="3D AB BC CD", arcz_unpredicted="") - def xxx_xest_finally_in_loop_2(self): - self.check_coverage("""\ - for i in range(5): - try: - j = 3 - finally: - f = 5 - g = 6 - h = 7 - """, - arcz=".1 12 23 35 56 61 17 7.", - arcz_missing="", arcz_unpredicted="") + if 0: + def test_finally_in_loop_2(self): + self.check_coverage("""\ + for i in range(5): + try: + j = 3 + finally: + f = 5 + g = 6 + h = 7 + """, + arcz=".1 12 23 35 56 61 17 7.", + arcz_missing="", arcz_unpredicted="") if sys.version_info >= (2, 5): # Try-except-finally was new in 2.5 @@ -481,3 +512,33 @@ class MiscArcTest(CoverageTest): assert d """, arcz=".1 19 9.") + + +class ExcludeTest(CoverageTest): + """Tests of exclusions to indicate known partial branches.""" + + def test_default(self): + # A number of forms of pragma comment are accepted. + self.check_coverage("""\ + a = 1 + if a: #pragma: no branch + b = 3 + c = 4 + if c: # pragma NOBRANCH + d = 6 + e = 7 + """, + [1,2,3,4,5,6,7], + arcz=".1 12 23 24 34 45 56 57 67 7.", arcz_missing="") + + def test_custom_pragmas(self): + self.check_coverage("""\ + a = 1 + while a: # [only some] + c = 3 + break + assert c == 5-2 + """, + [1,2,3,4,5], + partials=["only some"], + arcz=".1 12 23 34 45 25 5.", arcz_missing="") diff --git a/test/test_cmdline.py b/test/test_cmdline.py index aa72b340..eb7fe0f5 100644 --- a/test/test_cmdline.py +++ b/test/test_cmdline.py @@ -33,7 +33,8 @@ class CmdLineTest(CoverageTest): """ m = self.model_object() ret = coverage.CoverageScript( - _covpkg=m, _run_python_file=m.run_python_file, _help_fn=m.help_fn + _covpkg=m, _run_python_file=m.run_python_file, + _run_python_module=m.run_python_module, _help_fn=m.help_fn ).command_line(shlex.split(args)) return m, ret @@ -250,35 +251,35 @@ class ClassicCmdLineTest(CmdLineTest): def test_html_report(self): # coverage -b -d DIR [-i] [-o DIR,...] [FILE1 FILE2 ...] self.cmd_executes("-b", self.INIT_LOAD + """\ - .html_report(directory=None, ignore_errors=None, + .html_report(directory=None, ignore_errors=None, title=None, omit=None, include=None, morfs=[]) """) self.cmd_executes("-b -d dir1", self.INIT_LOAD + """\ - .html_report(directory="dir1", ignore_errors=None, + .html_report(directory="dir1", ignore_errors=None, title=None, omit=None, include=None, morfs=[]) """) self.cmd_executes("-b -i", self.INIT_LOAD + """\ - .html_report(directory=None, ignore_errors=True, + .html_report(directory=None, ignore_errors=True, title=None, omit=None, include=None, morfs=[]) """) self.cmd_executes("-b -o fooey", """\ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey"]) .load() - .html_report(directory=None, ignore_errors=None, + .html_report(directory=None, ignore_errors=None, title=None, omit=["fooey"], include=None, morfs=[]) """) self.cmd_executes("-b -o fooey,booey", """\ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey", "booey"]) .load() - .html_report(directory=None, ignore_errors=None, + .html_report(directory=None, ignore_errors=None, title=None, omit=["fooey", "booey"], include=None, morfs=[]) """) self.cmd_executes("-b mod1", self.INIT_LOAD + """\ - .html_report(directory=None, ignore_errors=None, + .html_report(directory=None, ignore_errors=None, title=None, omit=None, include=None, morfs=["mod1"]) """) self.cmd_executes("-b mod1 mod2 mod3", self.INIT_LOAD + """\ - .html_report(directory=None, ignore_errors=None, + .html_report(directory=None, ignore_errors=None, title=None, omit=None, include=None, morfs=["mod1", "mod2", "mod3"]) """) @@ -372,7 +373,7 @@ class FakeCoverageForDebugData(object): """Fake coverage().data.has_arcs()""" return False - def summary(self, fullpath): # pylint: disable-msg=W0613 + def summary(self, fullpath): # pylint: disable=W0613 """Fake coverage().data.summary()""" return self._summary @@ -446,6 +447,14 @@ class NewCmdLineTest(CmdLineTest): self.cmd_executes_same("html --omit f,b", "-b --omit f,b") self.cmd_executes_same("html m1", "-b m1") self.cmd_executes_same("html m1 m2 m3", "-b m1 m2 m3") + self.cmd_executes("html", self.INIT_LOAD + """\ + .html_report(ignore_errors=None, omit=None, include=None, morfs=[], + directory=None, title=None) + """) + self.cmd_executes("html --title=Hello_there", self.INIT_LOAD + """\ + .html_report(ignore_errors=None, omit=None, include=None, morfs=[], + directory=None, title='Hello_there') + """) def test_report(self): self.cmd_executes_same("report", "-r") @@ -521,15 +530,42 @@ class NewCmdLineTest(CmdLineTest): .save() """) + def test_run_module(self): + self.cmd_executes("run -m mymodule", """\ + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None) + .erase() + .start() + .run_python_module('mymodule', ['mymodule']) + .stop() + .save() + """) + self.cmd_executes("run -m mymodule -qq arg1 arg2", """\ + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None) + .erase() + .start() + .run_python_module('mymodule', ['mymodule', '-qq', 'arg1', 'arg2']) + .stop() + .save() + """) + self.cmd_executes("run --branch -m mymodule", """\ + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=True, config_file=True, source=None, include=None, omit=None) + .erase() + .start() + .run_python_module('mymodule', ['mymodule']) + .stop() + .save() + """) + self.cmd_executes_same("run -m mymodule", "run --module mymodule") + def test_xml(self): # coverage xml [-i] [--omit DIR,...] [FILE1 FILE2 ...] self.cmd_executes("xml", self.INIT_LOAD + """\ .xml_report(ignore_errors=None, omit=None, include=None, morfs=[], - outfile="coverage.xml") + outfile=None) """) self.cmd_executes("xml -i", self.INIT_LOAD + """\ .xml_report(ignore_errors=True, omit=None, include=None, morfs=[], - outfile="coverage.xml") + outfile=None) """) self.cmd_executes("xml -o myxml.foo", self.INIT_LOAD + """\ .xml_report(ignore_errors=None, omit=None, include=None, morfs=[], @@ -543,21 +579,21 @@ class NewCmdLineTest(CmdLineTest): .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey"]) .load() .xml_report(ignore_errors=None, omit=["fooey"], include=None, morfs=[], - outfile="coverage.xml") + outfile=None) """) self.cmd_executes("xml --omit fooey,booey", """\ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey", "booey"]) .load() .xml_report(ignore_errors=None, omit=["fooey", "booey"], include=None, - morfs=[], outfile="coverage.xml") + morfs=[], outfile=None) """) self.cmd_executes("xml mod1", self.INIT_LOAD + """\ .xml_report(ignore_errors=None, omit=None, include=None, morfs=["mod1"], - outfile="coverage.xml") + outfile=None) """) self.cmd_executes("xml mod1 mod2 mod3", self.INIT_LOAD + """\ .xml_report(ignore_errors=None, omit=None, include=None, - morfs=["mod1", "mod2", "mod3"], outfile="coverage.xml") + morfs=["mod1", "mod2", "mod3"], outfile=None) """) def test_no_arguments_at_all(self): @@ -576,6 +612,12 @@ class CmdLineStdoutTest(CmdLineTest): assert "Code coverage for Python." in out assert out.count("\n") < 4 + def test_version(self): + self.command_line("--version") + out = self.stdout() + assert "ersion " in out + assert out.count("\n") < 4 + def test_help(self): self.command_line("help") out = self.stdout() diff --git a/test/test_codeunit.py b/test/test_codeunit.py index 7903d153..b543949c 100644 --- a/test/test_codeunit.py +++ b/test/test_codeunit.py @@ -8,7 +8,7 @@ from coverage.files import FileLocator sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest -# pylint: disable-msg=F0401 +# pylint: disable=F0401 # Unable to import 'aa' (No module named aa) class CodeUnitTest(CoverageTest): diff --git a/test/test_config.py b/test/test_config.py index d5290584..19e37ab9 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """Test the config file handling for coverage.py""" import os, sys @@ -127,13 +128,29 @@ class ConfigFileTest(CoverageTest): yet_more precision = 3 + partial_branches = + pragma:?\\s+no branch + partial_branches_always = + if 0: + while True: + + show_missing= TruE + [html] directory = c:\\tricky\\dir.somewhere - + extra_css=something/extra.css + title = Title & nums # nums! [xml] output=mycov.xml + [paths] + source = + . + /home/ned/src/ + + other = other, /home/ned/other, c:\\Ned\\etc + """) cov = coverage.coverage() @@ -144,7 +161,7 @@ class ConfigFileTest(CoverageTest): self.assertTrue(cov.config.parallel) self.assertEqual(cov.get_exclude_list(), - ["if 0:", "pragma:?\s+no cover", "another_tab"] + ["if 0:", r"pragma:?\s+no cover", "another_tab"] ) self.assertTrue(cov.config.ignore_errors) self.assertEqual(cov.config.include, ["a/", "b/"]) @@ -153,6 +170,33 @@ class ConfigFileTest(CoverageTest): ) self.assertEqual(cov.config.precision, 3) + self.assertEqual(cov.config.partial_list, + [r"pragma:?\s+no branch"] + ) + self.assertEqual(cov.config.partial_always_list, + ["if 0:", "while True:"] + ) + self.assertTrue(cov.config.show_missing) self.assertEqual(cov.config.html_dir, r"c:\tricky\dir.somewhere") + self.assertEqual(cov.config.extra_css, "something/extra.css") + self.assertEqual(cov.config.html_title, "Title & nums # nums!") self.assertEqual(cov.config.xml_output, "mycov.xml") + + self.assertEqual(cov.config.paths, { + 'source': ['.', '/home/ned/src/'], + 'other': ['other', '/home/ned/other', 'c:\\Ned\\etc'] + }) + + if sys.version_info[:2] != (3,1): + def test_one(self): + # This sample file tries to use lots of variation of syntax... + self.make_file(".coveragerc", """\ + [html] + title = tabblo & «ταБЬℓσ» # numbers + """) + cov = coverage.coverage() + + self.assertEqual(cov.config.html_title, + "tabblo & «ταБЬℓσ» # numbers" + ) diff --git a/test/test_coverage.py b/test/test_coverage.py index 31f3aa17..5da9cb16 100644 --- a/test/test_coverage.py +++ b/test/test_coverage.py @@ -140,12 +140,33 @@ class SimpleStatementTest(CoverageTest): """Testing simple single-line statements.""" def test_expression(self): + # Bare expressions as statements are tricky: some implementations + # optimize some of them away. All implementations seem to count + # the implicit return at the end as executable. + self.check_coverage("""\ + 12 + 23 + """, + ([1,2],[2]), "") + self.check_coverage("""\ + 12 + 23 + a = 3 + """, + ([1,2,3],[3]), "") self.check_coverage("""\ 1 + 2 1 + \\ 2 """, - [1,2], "") + ([1,2], [2]), "") + self.check_coverage("""\ + 1 + 2 + 1 + \\ + 2 + a = 4 + """, + ([1,2,4], [4]), "") def test_assert(self): self.check_coverage("""\ @@ -560,7 +581,7 @@ class SimpleStatementTest(CoverageTest): c = 6 assert (a,b,c) == (1,3,6) """, - ([1,3,5,6,7], [1,3,4,5,6,7]), "") + ([1,3,6,7], [1,3,5,6,7], [1,3,4,5,6,7]), "") class CompoundStatementTest(CoverageTest): @@ -821,6 +842,16 @@ class CompoundStatementTest(CoverageTest): """, [1,2,4,5,7,9,10], "4, 7") + if sys.version_info >= (2, 4): + # In 2.4 and up, constant if's were compiled away. + def test_constant_if(self): + self.check_coverage("""\ + if 1: + a = 2 + assert a == 2 + """, + [2,3], "") + def test_while(self): self.check_coverage("""\ a = 3; b = 0 @@ -1134,7 +1165,7 @@ class ExcludeTest(CoverageTest): if 0: a = 4 # -cc """, - [1,3], "", ['-cc']) + [1,3], "", excludes=['-cc']) def test_two_excludes(self): self.check_coverage("""\ @@ -1146,7 +1177,7 @@ class ExcludeTest(CoverageTest): c = 6 # -xx assert a == 1 and b == 2 """, - [1,3,5,7], "5", ['-cc', '-xx']) + [1,3,5,7], "5", excludes=['-cc', '-xx']) def test_excluding_if_suite(self): self.check_coverage("""\ @@ -1158,7 +1189,7 @@ class ExcludeTest(CoverageTest): c = 6 assert a == 1 and b == 2 """, - [1,7], "", ['if 0:']) + [1,7], "", excludes=['if 0:']) def test_excluding_if_but_not_else_suite(self): self.check_coverage("""\ @@ -1173,7 +1204,7 @@ class ExcludeTest(CoverageTest): b = 9 assert a == 8 and b == 9 """, - [1,8,9,10], "", ['if 0:']) + [1,8,9,10], "", excludes=['if 0:']) def test_excluding_else_suite(self): self.check_coverage("""\ @@ -1188,7 +1219,7 @@ class ExcludeTest(CoverageTest): b = 9 assert a == 4 and b == 5 and c == 6 """, - [1,3,4,5,6,10], "", ['#pragma: NO COVER']) + [1,3,4,5,6,10], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 1; b = 2 @@ -1208,7 +1239,7 @@ class ExcludeTest(CoverageTest): b = 9 assert a == 4 and b == 5 and c == 6 """, - [1,3,4,5,6,17], "", ['#pragma: NO COVER']) + [1,3,4,5,6,17], "", excludes=['#pragma: NO COVER']) def test_excluding_elif_suites(self): self.check_coverage("""\ @@ -1226,7 +1257,7 @@ class ExcludeTest(CoverageTest): b = 12 assert a == 4 and b == 5 and c == 6 """, - [1,3,4,5,6,11,12,13], "11-12", ['#pragma: NO COVER']) + [1,3,4,5,6,11,12,13], "11-12", excludes=['#pragma: NO COVER']) def test_excluding_oneline_if(self): self.check_coverage("""\ @@ -1237,7 +1268,7 @@ class ExcludeTest(CoverageTest): foo() """, - [1,2,4,6], "", ["no cover"]) + [1,2,4,6], "", excludes=["no cover"]) def test_excluding_a_colon_not_a_suite(self): self.check_coverage("""\ @@ -1248,7 +1279,7 @@ class ExcludeTest(CoverageTest): foo() """, - [1,2,4,6], "", ["no cover"]) + [1,2,4,6], "", excludes=["no cover"]) def test_excluding_for_suite(self): self.check_coverage("""\ @@ -1257,7 +1288,7 @@ class ExcludeTest(CoverageTest): a += i assert a == 15 """, - [1,4], "", ['#pragma: NO COVER']) + [1,4], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 for i in [1, @@ -1266,7 +1297,7 @@ class ExcludeTest(CoverageTest): a += i assert a == 15 """, - [1,6], "", ['#pragma: NO COVER']) + [1,6], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 for i in [1,2,3,4,5 @@ -1276,7 +1307,7 @@ class ExcludeTest(CoverageTest): a = 99 assert a == 1 """, - [1,7], "", ['#pragma: NO COVER']) + [1,7], "", excludes=['#pragma: NO COVER']) def test_excluding_for_else(self): self.check_coverage("""\ @@ -1289,7 +1320,7 @@ class ExcludeTest(CoverageTest): a = 123 assert a == 1 """, - [1,2,3,4,5,8], "5", ['#pragma: NO COVER']) + [1,2,3,4,5,8], "5", excludes=['#pragma: NO COVER']) def test_excluding_while(self): self.check_coverage("""\ @@ -1300,7 +1331,7 @@ class ExcludeTest(CoverageTest): b = 99 assert a == 3 and b == 0 """, - [1,6], "", ['#pragma: NO COVER']) + [1,6], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 3; b = 0 while ( @@ -1311,7 +1342,7 @@ class ExcludeTest(CoverageTest): b = 99 assert a == 3 and b == 0 """, - [1,8], "", ['#pragma: NO COVER']) + [1,8], "", excludes=['#pragma: NO COVER']) def test_excluding_while_else(self): self.check_coverage("""\ @@ -1324,7 +1355,7 @@ class ExcludeTest(CoverageTest): b = 123 assert a == 3 and b == 1 """, - [1,2,3,4,5,8], "5", ['#pragma: NO COVER']) + [1,2,3,4,5,8], "5", excludes=['#pragma: NO COVER']) def test_excluding_try_except(self): self.check_coverage("""\ @@ -1335,7 +1366,7 @@ class ExcludeTest(CoverageTest): a = 99 assert a == 1 """, - [1,2,3,6], "", ['#pragma: NO COVER']) + [1,2,3,6], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: @@ -1345,7 +1376,7 @@ class ExcludeTest(CoverageTest): a = 99 assert a == 99 """, - [1,2,3,4,5,6,7], "", ['#pragma: NO COVER']) + [1,2,3,4,5,6,7], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: @@ -1357,7 +1388,7 @@ class ExcludeTest(CoverageTest): a = 123 assert a == 123 """, - [1,2,3,4,7,8,9], "", ['#pragma: NO COVER']) + [1,2,3,4,7,8,9], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: @@ -1368,7 +1399,7 @@ class ExcludeTest(CoverageTest): a = 123 assert a == 123 """, - [1,2,3,7,8], "", ['#pragma: NO COVER']) + [1,2,3,7,8], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: @@ -1380,7 +1411,7 @@ class ExcludeTest(CoverageTest): a = 123 assert a == 99 """, - [1,2,3,4,5,6,9], "", ['#pragma: NO COVER']) + [1,2,3,4,5,6,9], "", excludes=['#pragma: NO COVER']) def test_excluding_try_except_pass(self): self.check_coverage("""\ @@ -1391,7 +1422,7 @@ class ExcludeTest(CoverageTest): x = 2 assert a == 1 """, - [1,2,3,6], "", ['#pragma: NO COVER']) + [1,2,3,6], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: @@ -1403,7 +1434,7 @@ class ExcludeTest(CoverageTest): a = 123 assert a == 123 """, - [1,2,3,4,7,8,9], "", ['#pragma: NO COVER']) + [1,2,3,4,7,8,9], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: @@ -1414,7 +1445,7 @@ class ExcludeTest(CoverageTest): a = 123 assert a == 123 """, - [1,2,3,7,8], "", ['#pragma: NO COVER']) + [1,2,3,7,8], "", excludes=['#pragma: NO COVER']) self.check_coverage("""\ a = 0 try: @@ -1426,7 +1457,7 @@ class ExcludeTest(CoverageTest): x = 2 assert a == 99 """, - [1,2,3,4,5,6,9], "", ['#pragma: NO COVER']) + [1,2,3,4,5,6,9], "", excludes=['#pragma: NO COVER']) def test_excluding_if_pass(self): # From a comment on the coverage page by Michael McNeil Forbes: @@ -1439,7 +1470,7 @@ class ExcludeTest(CoverageTest): f() """, - [1,7], "", ["no cover"]) + [1,7], "", excludes=["no cover"]) def test_excluding_function(self): self.check_coverage("""\ @@ -1451,7 +1482,7 @@ class ExcludeTest(CoverageTest): x = 1 assert x == 1 """, - [6,7], "", ['#pragma: NO COVER']) + [6,7], "", excludes=['#pragma: NO COVER']) def test_excluding_method(self): self.check_coverage("""\ @@ -1465,7 +1496,7 @@ class ExcludeTest(CoverageTest): x = Fooey() assert x.a == 1 """, - [1,2,3,8,9], "", ['#pragma: NO COVER']) + [1,2,3,8,9], "", excludes=['#pragma: NO COVER']) def test_excluding_class(self): self.check_coverage("""\ @@ -1479,7 +1510,7 @@ class ExcludeTest(CoverageTest): x = 1 assert x == 1 """, - [8,9], "", ['#pragma: NO COVER']) + [8,9], "", excludes=['#pragma: NO COVER']) if sys.version_info >= (2, 4): @@ -1683,7 +1714,7 @@ class ReportingTest(CoverageTest): CoverageException, "No data to report.", self.command_line, "annotate -d ann" ) - self.assertFalse(os.path.exists("ann")) + self.assert_doesnt_exist("ann") def test_no_data_to_report_on_html(self): # Reporting with no data produces a nice message and no output dir. @@ -1691,7 +1722,7 @@ class ReportingTest(CoverageTest): CoverageException, "No data to report.", self.command_line, "html -d htmlcov" ) - self.assertFalse(os.path.exists("htmlcov")) + self.assert_doesnt_exist("htmlcov") def test_no_data_to_report_on_xml(self): # Reporting with no data produces a nice message. diff --git a/test/test_data.py b/test/test_data.py index 298078a2..5ad2f440 100644 --- a/test/test_data.py +++ b/test/test_data.py @@ -4,6 +4,7 @@ import os, sys from coverage.backward import pickle from coverage.data import CoverageData +from coverage.files import PathAliases sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest @@ -23,12 +24,13 @@ ARC_DATA_3 = { 'x.py': {(1,2):None, (2,3):None}, 'y.py': {(17,23):None} } X_PY_ARCS_3 = [(1,2), (2,3)] Y_PY_ARCS_3 = [(17,23)] + class DataTest(CoverageTest): """Test cases for coverage.data.""" - def assert_summary(self, covdata, summary): + def assert_summary(self, covdata, summary, fullpath=False): """Check that the summary of `covdata` is `summary`.""" - self.assertEqual(covdata.summary(), summary) + self.assertEqual(covdata.summary(fullpath), summary) def assert_measured_files(self, covdata, measured): """Check that `covdata`'s measured files are `measured`.""" @@ -120,3 +122,28 @@ class DataTest(CoverageTest): arcs = data['arcs'] self.assertSameElements(arcs['x.py'], X_PY_ARCS_3) self.assertSameElements(arcs['y.py'], Y_PY_ARCS_3) + + def test_combining_with_aliases(self): + covdata1 = CoverageData() + covdata1.add_line_data({ + '/home/ned/proj/src/a.py': {1:None, 2:None}, + '/home/ned/proj/src/sub/b.py': {3:None}, + }) + covdata1.write(suffix='1') + + covdata2 = CoverageData() + covdata2.add_line_data({ + r'c:\ned\test\a.py': {4:None, 5:None}, + r'c:\ned\test\sub\b.py': {6:None}, + }) + covdata2.write(suffix='2') + + covdata3 = CoverageData() + aliases = PathAliases() + aliases.add("/home/ned/proj/src/", "./") + aliases.add(r"c:\ned\test", "./") + covdata3.combine_parallel_data(aliases=aliases) + self.assert_summary( + covdata3, { './a.py':4, './sub/b.py':2 }, fullpath=True + ) + self.assert_measured_files(covdata3, [ './a.py', './sub/b.py' ]) diff --git a/test/test_execfile.py b/test/test_execfile.py index 2f28a069..1c5b8024 100644 --- a/test/test_execfile.py +++ b/test/test_execfile.py @@ -2,7 +2,7 @@ import os, sys -from coverage.execfile import run_python_file +from coverage.execfile import run_python_file, run_python_module from coverage.misc import NoSource sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k @@ -10,7 +10,7 @@ from coveragetest import CoverageTest here = os.path.dirname(__file__) -class RunTest(CoverageTest): +class RunFileTest(CoverageTest): """Test cases for `run_python_file`.""" def test_run_python_file(self): @@ -55,8 +55,10 @@ class RunTest(CoverageTest): pylines = """# try newlines|print('Hello, world!')|""".split('|') for nl in ('\n', '\r\n', '\r'): fpy = open('nl.py', 'wb') - fpy.write(nl.join(pylines).encode('utf-8')) - fpy.close() + try: + fpy.write(nl.join(pylines).encode('utf-8')) + finally: + fpy.close() run_python_file('nl.py', ['nl.py']) self.assertEqual(self.stdout(), "Hello, world!\n"*3) @@ -74,3 +76,42 @@ class RunTest(CoverageTest): def test_no_such_file(self): self.assertRaises(NoSource, run_python_file, "xyzzy.py", []) + + +class RunModuleTest(CoverageTest): + """Test run_python_module.""" + + run_in_temp_dir = False + + def setUp(self): + super(RunModuleTest, self).setUp() + # Parent class saves and restores sys.path, we can just modify it. + sys.path.append(self.nice_file(os.path.dirname(__file__), 'modules')) + + def test_runmod1(self): + run_python_module("runmod1", ["runmod1", "hello"]) + self.assertEqual(self.stdout(), "runmod1: passed hello\n") + + def test_runmod2(self): + run_python_module("pkg1.runmod2", ["runmod2", "hello"]) + self.assertEqual(self.stdout(), "runmod2: passed hello\n") + + def test_runmod3(self): + run_python_module("pkg1.sub.runmod3", ["runmod3", "hello"]) + self.assertEqual(self.stdout(), "runmod3: passed hello\n") + + def test_pkg1_main(self): + run_python_module("pkg1", ["pkg1", "hello"]) + self.assertEqual(self.stdout(), "pkg1.__main__: passed hello\n") + + def test_pkg1_sub_main(self): + run_python_module("pkg1.sub", ["pkg1.sub", "hello"]) + self.assertEqual(self.stdout(), "pkg1.sub.__main__: passed hello\n") + + def test_no_such_module(self): + self.assertRaises(NoSource, run_python_module, "i_dont_exist", []) + self.assertRaises(NoSource, run_python_module, "i.dont_exist", []) + self.assertRaises(NoSource, run_python_module, "i.dont.exist", []) + + def test_no_main(self): + self.assertRaises(NoSource, run_python_module, "pkg2", ["pkg2", "hi"]) diff --git a/test/test_farm.py b/test/test_farm.py index 79b345a6..f06158e4 100644 --- a/test/test_farm.py +++ b/test/test_farm.py @@ -3,7 +3,7 @@ import difflib, filecmp, fnmatch, glob, os, re, shutil, sys sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k -from backtest import run_command, execfile # pylint: disable-msg=W0622 +from backtest import run_command, execfile # pylint: disable=W0622 def test_farm(clean_only=False): @@ -52,7 +52,8 @@ class FarmTestCase(object): def addtopath(self, directory): """Add `directory` to the path, and return the old path.""" oldpath = sys.path[:] - sys.path.insert(0, directory) + if directory is not None: + sys.path.insert(0, directory) return oldpath def restorepath(self, path): @@ -144,6 +145,8 @@ class FarmTestCase(object): """ cwd = self.cd(rundir) + if outfile: + fout = open(outfile, "a+") try: for cmd in cmds.split("\n"): cmd = cmd.strip() @@ -152,10 +155,12 @@ class FarmTestCase(object): retcode, output = run_command(cmd) print(output.rstrip()) if outfile: - open(outfile, "a+").write(output) + fout.write(output) if retcode: raise Exception("command exited abnormally") finally: + if outfile: + fout.close() self.cd(cwd) def runfunc(self, fn, rundir="src", addtopath=None): @@ -321,7 +326,12 @@ def main(): # pragma: no cover clean - Clean all the output for all tests. """ - op = sys.argv[1] + op = 'help' + try: + op = sys.argv[1] + except IndexError: + pass + if op == 'run': # Run the test for real. case = FarmTestCase(sys.argv[2]) @@ -335,7 +345,7 @@ def main(): # pragma: no cover for test in test_farm(clean_only=True): test[0].run_fully() else: - print("Need an operation: run, out, clean") + print(main.__doc__) # So that we can run just one farm run.py at a time. if __name__ == '__main__': diff --git a/test/test_files.py b/test/test_files.py index 4ffc6ca2..5692699c 100644 --- a/test/test_files.py +++ b/test/test_files.py @@ -3,8 +3,9 @@ import os, sys from coverage.files import FileLocator, TreeMatcher, FnmatchMatcher -from coverage.files import find_python_files -from coverage.backward import set # pylint: disable-msg=W0622 +from coverage.files import PathAliases, find_python_files, abs_file +from coverage.backward import set # pylint: disable=W0622 +from coverage.misc import CoverageException sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest @@ -36,6 +37,17 @@ class FileLocatorTest(CoverageTest): self.assertEqual(fl.relative_filename(a1), "file1.py") self.assertEqual(fl.relative_filename(a2), a2) + def test_filepath_contains_absolute_prefix_twice(self): + # https://bitbucket.org/ned/coveragepy/issue/194 + # Build a path that has two pieces matching the absolute path prefix. + # Technically, this test doesn't do that on Windows, but drive + # letters make that impractical to acheive. + fl = FileLocator() + d = abs_file(os.curdir) + trick = os.path.splitdrive(d)[1].lstrip(os.path.sep) + rel = os.path.join('sub', trick, 'file1.py') + self.assertEqual(fl.relative_filename(abs_file(rel)), rel) + class MatcherTest(CoverageTest): """Tests of file matchers.""" @@ -72,20 +84,87 @@ class MatcherTest(CoverageTest): self.assertFalse(fnm.match(fl.canonical_filename(file5))) +class PathAliasesTest(CoverageTest): + """Tests for coverage/files.py:PathAliases""" + + def test_noop(self): + aliases = PathAliases() + self.assertEqual(aliases.map('/ned/home/a.py'), '/ned/home/a.py') + + def test_nomatch(self): + aliases = PathAliases() + aliases.add('/home/*/src', './mysrc') + self.assertEqual(aliases.map('/home/foo/a.py'), '/home/foo/a.py') + + def test_wildcard(self): + aliases = PathAliases() + aliases.add('/ned/home/*/src', './mysrc') + self.assertEqual(aliases.map('/ned/home/foo/src/a.py'), './mysrc/a.py') + aliases = PathAliases() + aliases.add('/ned/home/*/src/', './mysrc') + self.assertEqual(aliases.map('/ned/home/foo/src/a.py'), './mysrc/a.py') + + def test_no_accidental_match(self): + aliases = PathAliases() + aliases.add('/home/*/src', './mysrc') + self.assertEqual(aliases.map('/home/foo/srcetc'), '/home/foo/srcetc') + + def test_multiple_patterns(self): + aliases = PathAliases() + aliases.add('/home/*/src', './mysrc') + aliases.add('/lib/*/libsrc', './mylib') + self.assertEqual(aliases.map('/home/foo/src/a.py'), './mysrc/a.py') + self.assertEqual(aliases.map('/lib/foo/libsrc/a.py'), './mylib/a.py') + + def test_cant_have_wildcard_at_end(self): + aliases = PathAliases() + self.assertRaisesRegexp( + CoverageException, "Pattern must not end with wildcards.", + aliases.add, "/ned/home/*", "fooey" + ) + self.assertRaisesRegexp( + CoverageException, "Pattern must not end with wildcards.", + aliases.add, "/ned/home/*/", "fooey" + ) + self.assertRaisesRegexp( + CoverageException, "Pattern must not end with wildcards.", + aliases.add, "/ned/home/*/*/", "fooey" + ) + + def test_no_accidental_munging(self): + aliases = PathAliases() + aliases.add(r'c:\Zoo\boo', 'src/') + aliases.add('/home/ned$', 'src/') + self.assertEqual(aliases.map(r'c:\Zoo\boo\foo.py'), 'src/foo.py') + self.assertEqual(aliases.map(r'/home/ned$/foo.py'), 'src/foo.py') + + def test_paths_are_os_corrected(self): + aliases = PathAliases() + aliases.add('/home/ned/*/src', './mysrc') + aliases.add(r'c:\ned\src', './mysrc') + mapped = aliases.map(r'C:\Ned\src\sub\a.py') + self.assertEqual(mapped, './mysrc/sub/a.py') + + aliases = PathAliases() + aliases.add('/home/ned/*/src', r'.\mysrc') + aliases.add(r'c:\ned\src', r'.\mysrc') + mapped = aliases.map(r'/home/ned/foo/src/sub/a.py') + self.assertEqual(mapped, r'.\mysrc\sub\a.py') + + class FindPythonFilesTest(CoverageTest): """Tests of `find_python_files`.""" def test_find_python_files(self): self.make_file("sub/a.py") self.make_file("sub/b.py") - self.make_file("sub/__init__.py") self.make_file("sub/x.c") # nope: not .py self.make_file("sub/ssub/__init__.py") self.make_file("sub/ssub/s.py") + self.make_file("sub/ssub/~s.py") # nope: editor effluvia self.make_file("sub/lab/exp.py") # nope: no __init__.py py_files = set(find_python_files("sub")) self.assert_same_files(py_files, [ - "sub/__init__.py", "sub/a.py", "sub/b.py", + "sub/a.py", "sub/b.py", "sub/ssub/__init__.py", "sub/ssub/s.py", ]) - diff --git a/test/test_html.py b/test/test_html.py new file mode 100644 index 00000000..29106562 --- /dev/null +++ b/test/test_html.py @@ -0,0 +1,289 @@ +# -*- coding: utf-8 -*- +"""Tests that HTML generation is awesome.""" + +import os.path, sys +import coverage +from coverage.misc import NotPython + +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k +from 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 {})) + cov.start() + self.import_local_file("main_file") + cov.stop() + 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.html") + os.remove("htmlcov/helper1.html") + os.remove("htmlcov/helper2.html") + + +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.maxDiff = None + + def tearDown(self): + coverage.__version__ = self.real_coverage_version + super(HtmlDeltaTest, self).tearDown() + + 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.html") + self.assert_exists("htmlcov/helper1.html") + self.assert_exists("htmlcov/helper2.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 = open("htmlcov/index.html").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.html") + self.assert_doesnt_exist("htmlcov/main_file.html") + self.assert_doesnt_exist("htmlcov/helper2.html") + index2 = open("htmlcov/index.html").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.html") + self.assert_exists("htmlcov/main_file.html") + self.assert_doesnt_exist("htmlcov/helper2.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(timid=False)) + index1 = open("htmlcov/index.html").read() + self.remove_html_files() + + self.run_coverage(covargs=dict(timid=True)) + + # All the files have been reported again. + self.assert_exists("htmlcov/index.html") + self.assert_exists("htmlcov/helper1.html") + self.assert_exists("htmlcov/main_file.html") + self.assert_exists("htmlcov/helper2.html") + index2 = open("htmlcov/index.html").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() + index1 = open("htmlcov/index.html").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.html") + self.assert_exists("htmlcov/main_file.html") + self.assert_exists("htmlcov/helper2.html") + index2 = open("htmlcov/index.html").read() + fixed_index2 = index2.replace("XYZZY", self.real_coverage_version) + self.assertMultiLineEqual(index1, fixed_index2) + + +class HtmlTitleTests(HtmlTestHelpers, CoverageTest): + """Tests of the HTML title support.""" + + def test_default_title(self): + self.create_initial_files() + self.run_coverage() + index = open("htmlcov/index.html").read() + 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 = open("htmlcov/index.html").read() + self.assertIn("<title>Metrics & stuff!</title>", index) + self.assertIn("<h1>Metrics & stuff!:", index) + + if sys.version_info[:2] != (3,1): + 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 = open("htmlcov/index.html").read() + 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 = open("htmlcov/index.html").read() + self.assertIn( + "<title>«ταБЬℓσ»" + " & stüff!</title>", index + ) + self.assertIn( + "<h1>«ταБЬℓσ»" + " & stüff!:", index + ) + + +class HtmlWithUnparsableFilesTest(CoverageTest): + """Test the behavior when measuring unparsable files.""" + + def test_dotpy_not_python(self): + self.make_file("innocuous.py", "a = 1") + cov = coverage.coverage() + cov.start() + self.import_local_file("innocuous") + cov.stop() + self.make_file("innocuous.py", "<h1>This isn't python!</h1>") + self.assertRaisesRegexp( + NotPython, + "Couldn't parse '.*innocuous.py' as Python source: '.*' at line 1", + cov.html_report + ) + + def test_dotpy_not_python_ignored(self): + self.make_file("innocuous.py", "a = 2") + cov = coverage.coverage() + cov.start() + self.import_local_file("innocuous") + cov.stop() + 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. + if sys.version_info < (3, 0): + source = "exec compile('','','exec') in {'__file__': 'liar.html'}" + else: + 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.start() + self.import_local_file("liar") + cov.stop() + 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. + if sys.version_info < (3, 0): + source = "exec compile('','','exec') in {'__file__': 'liar.html'}" + else: + 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() + cov.start() + self.import_local_file("liar") + cov.stop() + cov.html_report() + self.assert_exists("htmlcov/index.html") diff --git a/test/test_misc.py b/test/test_misc.py new file mode 100644 index 00000000..ac53cddb --- /dev/null +++ b/test/test_misc.py @@ -0,0 +1,76 @@ +"""Tests of miscellaneous stuff.""" + +import os, sys + +from coverage.misc import Hasher, file_be_gone +from coverage import __version__, __url__ +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k +from coveragetest import CoverageTest + +class HasherTest(CoverageTest): + """Test our wrapper of md5 hashing.""" + + def test_string_hashing(self): + h1 = Hasher() + h1.update("Hello, world!") + h2 = Hasher() + h2.update("Goodbye!") + h3 = Hasher() + h3.update("Hello, world!") + self.assertNotEqual(h1.digest(), h2.digest()) + self.assertEqual(h1.digest(), h3.digest()) + + def test_dict_hashing(self): + h1 = Hasher() + h1.update({'a': 17, 'b': 23}) + h2 = Hasher() + h2.update({'b': 23, 'a': 17}) + self.assertEqual(h1.digest(), h2.digest()) + + +class RemoveFileTest(CoverageTest): + """Tests of misc.file_be_gone.""" + + def test_remove_nonexistent_file(self): + # it's ok to try to remove a file that doesn't exist. + file_be_gone("not_here.txt") + + def test_remove_actual_file(self): + # it really does remove a file that does exist. + self.make_file("here.txt", "We are here, we are here, we are here!") + file_be_gone("here.txt") + self.assert_doesnt_exist("here.txt") + + def test_actual_errors(self): + # Errors can still happen. + # ". is a directory" on Unix, or "Access denied" on Windows + self.assertRaises(OSError, file_be_gone, ".") + + +class SetupPyTest(CoverageTest): + """Tests of setup.py""" + + run_in_temp_dir = False + + def test_metadata(self): + status, output = self.run_command_status( + "python setup.py --description --version --url --author" + ) + self.assertEqual(status, 0) + out = output.splitlines() + self.assertIn("measurement", out[0]) + self.assertEqual(out[1], __version__) + self.assertEqual(out[2], __url__) + self.assertIn("Ned Batchelder", out[3]) + + def test_more_metadata(self): + from setup import setup_args + + classifiers = setup_args['classifiers'] + self.assertGreater(len(classifiers), 7) + self.assertTrue(classifiers[-1].startswith("Development Status ::")) + + long_description = setup_args['long_description'].splitlines() + self.assertGreater(len(long_description), 7) + self.assertNotEqual(long_description[0].strip(), "") + self.assertNotEqual(long_description[-1].strip(), "") diff --git a/test/test_oddball.py b/test/test_oddball.py index e94e2bad..a8c243de 100644 --- a/test/test_oddball.py +++ b/test/test_oddball.py @@ -129,7 +129,13 @@ class RecursionTest(CoverageTest): class MemoryLeakTest(CoverageTest): - """Attempt the impossible: test that memory doesn't leak.""" + """Attempt the impossible: test that memory doesn't leak. + + Note: this test is truly unusual, and may fail unexpectedly. + In particular, it is known to fail on PyPy if test_oddball.py is run in + isolation: https://bitbucket.org/ned/coveragepy/issue/186 + + """ def test_for_leaks(self): lines = list(range(301, 315)) @@ -301,6 +307,7 @@ class ExceptionTest(CoverageTest): # Clean the line data and compare to expected results. # The filenames are absolute, so keep just the base. + cov._harvest_data() # private! sshhh... lines = cov.data.line_data() clean_lines = {} for f, llist in lines.items(): @@ -348,3 +355,37 @@ if sys.version_info >= (2, 5): doctest.testmod(sys.modules[__name__]) # we're not __main__ :( ''', [1,11,12,14,16,17], "") + + +if hasattr(sys, 'gettrace'): + class GettraceTest(CoverageTest): + """Tests that we work properly with `sys.gettrace()`.""" + def test_round_trip(self): + self.check_coverage('''\ + import sys + def foo(n): + return 3*n + def bar(n): + return 5*n + a = foo(6) + sys.settrace(sys.gettrace()) + a = bar(8) + ''', + [1,2,3,4,5,6,7,8], "") + + def test_multi_layers(self): + self.check_coverage('''\ + import sys + def level1(): + a = 3 + level2() + b = 5 + def level2(): + c = 7 + sys.settrace(sys.gettrace()) + d = 9 + e = 10 + level1() + f = 12 + ''', + [1,2,3,4,5,6,7,8,9,10,11,12], "") diff --git a/test/test_parser.py b/test/test_parser.py index b398044d..220db17e 100644 --- a/test/test_parser.py +++ b/test/test_parser.py @@ -16,7 +16,7 @@ class ParserTest(CoverageTest): def parse_source(self, text): """Parse `text` as source, and return the `CodeParser` used.""" text = textwrap.dedent(text) - cp = CodeParser(text, exclude="nocover") + cp = CodeParser(text=text, exclude="nocover") cp.parse_source() return cp @@ -94,3 +94,41 @@ class ParserTest(CoverageTest): b = 6 """) self.assertEqual(cp.exit_counts(), { 1:1, 2:1, 3:1, 6:1 }) + + +class ParserFileTest(CoverageTest): + """Tests for Coverage.py's code parsing from files.""" + + def parse_file(self, filename): + """Parse `text` as source, and return the `CodeParser` used.""" + cp = CodeParser(filename=filename, exclude="nocover") + cp.parse_source() + return cp + + def test_line_endings(self): + text = """\ + # check some basic branch counting + class Foo: + def foo(self, a): + if a: + return 5 + else: + return 7 + + class Bar: + pass + """ + counts = { 2:1, 3:1, 4:2, 5:1, 7:1, 9:1, 10:1 } + name_endings = (("unix", "\n"), ("dos", "\r\n"), ("mac", "\r")) + for fname, newline in name_endings: + fname = fname + ".py" + self.make_file(fname, text, newline=newline) + cp = self.parse_file(fname) + self.assertEqual(cp.exit_counts(), counts) + + def test_encoding(self): + self.make_file("encoded.py", """\ + coverage = "\xe7\xf6v\xear\xe3g\xe9" + """) + cp = self.parse_file("encoded.py") + cp.exit_counts() diff --git a/test/test_phystokens.py b/test/test_phystokens.py index 0e778510..d4e417e8 100644 --- a/test/test_phystokens.py +++ b/test/test_phystokens.py @@ -37,8 +37,8 @@ class PhysTokensTest(CoverageTest): # source_token_lines doesn't preserve trailing spaces, so trim all that # before comparing. source = source.replace('\r\n', '\n') - source = re.sub("(?m)[ \t]+$", "", source) - tokenized = re.sub("(?m)[ \t]+$", "", tokenized) + source = re.sub(r"(?m)[ \t]+$", "", source) + tokenized = re.sub(r"(?m)[ \t]+$", "", tokenized) self.assertMultiLineEqual(source, tokenized) def check_file_tokenization(self, fname): diff --git a/test/test_process.py b/test/test_process.py index 89804c16..2d926038 100644 --- a/test/test_process.py +++ b/test/test_process.py @@ -6,6 +6,7 @@ import coverage sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest +here = os.path.dirname(__file__) class ProcessTest(CoverageTest): """Tests of the per-process behavior of coverage.py.""" @@ -24,9 +25,9 @@ class ProcessTest(CoverageTest): w = "world" """) - self.assertFalse(os.path.exists(".coverage")) + self.assert_doesnt_exist(".coverage") self.run_command("coverage -x mycode.py") - self.assertTrue(os.path.exists(".coverage")) + self.assert_exists(".coverage") def test_environment(self): # Checks that we can import modules from the test directory at all! @@ -37,9 +38,9 @@ class ProcessTest(CoverageTest): print ('done') """) - self.assertFalse(os.path.exists(".coverage")) + self.assert_doesnt_exist(".coverage") out = self.run_command("coverage -x mycode.py") - self.assertTrue(os.path.exists(".coverage")) + self.assert_exists(".coverage") self.assertEqual(out, 'done\n') def test_combine_parallel_data(self): @@ -56,18 +57,18 @@ class ProcessTest(CoverageTest): out = self.run_command("coverage -x -p b_or_c.py b") self.assertEqual(out, 'done\n') - self.assertFalse(os.path.exists(".coverage")) + self.assert_doesnt_exist(".coverage") out = self.run_command("coverage -x -p b_or_c.py c") self.assertEqual(out, 'done\n') - self.assertFalse(os.path.exists(".coverage")) + self.assert_doesnt_exist(".coverage") # After two -p runs, there should be two .coverage.machine.123 files. self.assertEqual(self.number_of_data_files(), 2) # Combine the parallel coverage data files into .coverage . self.run_command("coverage -c") - self.assertTrue(os.path.exists(".coverage")) + self.assert_exists(".coverage") # After combining, there should be only the .coverage file. self.assertEqual(self.number_of_data_files(), 1) @@ -97,19 +98,19 @@ class ProcessTest(CoverageTest): out = self.run_command("coverage run b_or_c.py b") self.assertEqual(out, 'done\n') - self.assertFalse(os.path.exists(".coverage")) + self.assert_doesnt_exist(".coverage") out = self.run_command("coverage run b_or_c.py c") self.assertEqual(out, 'done\n') - self.assertFalse(os.path.exists(".coverage")) + self.assert_doesnt_exist(".coverage") # After two runs, there should be two .coverage.machine.123 files. self.assertEqual(self.number_of_data_files(), 2) # Combine the parallel coverage data files into .coverage . self.run_command("coverage combine") - self.assertTrue(os.path.exists(".coverage")) - self.assertTrue(os.path.exists(".coveragerc")) + self.assert_exists(".coverage") + self.assert_exists(".coveragerc") # After combining, there should be only the .coverage file. self.assertEqual(self.number_of_data_files(), 1) @@ -128,6 +129,57 @@ class ProcessTest(CoverageTest): b_or_c 7 0 100% """)) + def test_combine_with_aliases(self): + self.make_file("d1/x.py", """\ + a = 1 + b = 2 + print("%s %s" % (a, b)) + """) + + self.make_file("d2/x.py", """\ + # 1 + # 2 + # 3 + c = 4 + d = 5 + print("%s %s" % (c, d)) + """) + + self.make_file(".coveragerc", """\ + [run] + parallel = True + + [paths] + source = + src + */d1 + */d2 + """) + + out = self.run_command("coverage run " + os.path.normpath("d1/x.py")) + self.assertEqual(out, '1 2\n') + out = self.run_command("coverage run " + os.path.normpath("d2/x.py")) + self.assertEqual(out, '4 5\n') + + self.assertEqual(self.number_of_data_files(), 2) + + self.run_command("coverage combine") + self.assert_exists(".coverage") + + # After combining, there should be only the .coverage file. + self.assertEqual(self.number_of_data_files(), 1) + + # Read the coverage data file and see that the two different x.py + # files have been combined together. + data = coverage.CoverageData() + data.read_file(".coverage") + summary = data.summary(fullpath=True) + self.assertEqual(len(summary), 1) + actual = os.path.normcase(os.path.abspath(list(summary.keys())[0])) + expected = os.path.normcase(os.path.abspath('src/x.py')) + self.assertEqual(actual, expected) + self.assertEqual(list(summary.values())[0], 6) + def test_missing_source_file(self): # Check what happens if the source is missing when reporting happens. self.make_file("fleeting.py", """\ @@ -138,7 +190,7 @@ class ProcessTest(CoverageTest): os.remove("fleeting.py") out = self.run_command("coverage html -d htmlcov") self.assertRegexpMatches(out, "No source for code: '.*fleeting.py'") - self.assertFalse("Traceback" in out) + self.assertNotIn("Traceback", out) # It happens that the code paths are different for *.py and other # files, so try again with no extension. @@ -150,13 +202,13 @@ class ProcessTest(CoverageTest): os.remove("fleeting") status, out = self.run_command_status("coverage html -d htmlcov", 1) self.assertRegexpMatches(out, "No source for code: '.*fleeting'") - self.assertFalse("Traceback" in out) + self.assertNotIn("Traceback", out) self.assertEqual(status, 1) def test_running_missing_file(self): status, out = self.run_command_status("coverage run xyzzy.py", 1) self.assertRegexpMatches(out, "No file to run: .*xyzzy.py") - self.assertFalse("Traceback" in out) + self.assertNotIn("Traceback", out) self.assertEqual(status, 1) def test_code_throws(self): @@ -174,12 +226,16 @@ class ProcessTest(CoverageTest): # same traceback. status, out = self.run_command_status("coverage run throw.py", 1) out2 = self.run_command("python throw.py") + if '__pypy__' in sys.builtin_module_names: + # Pypy has an extra frame in the traceback for some reason + lines2 = out2.splitlines() + out2 = "".join([l+"\n" for l in lines2 if "toplevel" not in l]) self.assertMultiLineEqual(out, out2) # But also make sure that the output is what we expect. - self.assertTrue('File "throw.py", line 5, in f2' in out) - self.assertTrue('raise Exception("hey!")' in out) - self.assertFalse('coverage' in out) + self.assertIn('File "throw.py", line 5, in f2', out) + self.assertIn('raise Exception("hey!")', out) + self.assertNotIn('coverage', out) self.assertEqual(status, 1) def test_code_exits(self): @@ -220,6 +276,28 @@ class ProcessTest(CoverageTest): self.assertEqual(status, status2) self.assertEqual(status, 0) + def test_coverage_run_is_like_python(self): + tryfile = os.path.join(here, "try_execfile.py") + self.make_file("run_me.py", open(tryfile).read()) + out = self.run_command("coverage run run_me.py") + out2 = self.run_command("python run_me.py") + self.assertMultiLineEqual(out, out2) + + if sys.version_info >= (2, 6): # Doesn't work in 2.5, and I don't care! + def test_coverage_run_dashm_is_like_python_dashm(self): + # These -m commands assume the coverage tree is on the path. + out = self.run_command("coverage run -m test.try_execfile") + out2 = self.run_command("python -m test.try_execfile") + self.assertMultiLineEqual(out, out2) + + if 0: + # For https://bitbucket.org/ned/coveragepy/issue/207 + def test_coverage_run_dashm_is_like_python_dashm_with__main__(self): + self.make_file("package/__init__.py") # empty + self.make_file("package/__main__.py", "#\n") # empty + out = self.run_command("coverage run -m package") + out2 = self.run_command("python -m package") + self.assertMultiLineEqual(out, out2) if hasattr(os, 'fork'): def test_fork(self): @@ -242,7 +320,7 @@ class ProcessTest(CoverageTest): out = self.run_command("coverage run -p fork.py") self.assertEqual(out, 'Child!\n') - self.assertFalse(os.path.exists(".coverage")) + self.assert_doesnt_exist(".coverage") # After running the forking program, there should be two # .coverage.machine.123 files. @@ -250,7 +328,7 @@ class ProcessTest(CoverageTest): # Combine the parallel coverage data files into .coverage . self.run_command("coverage -c") - self.assertTrue(os.path.exists(".coverage")) + self.assert_exists(".coverage") # After combining, there should be only the .coverage file. self.assertEqual(self.number_of_data_files(), 1) @@ -268,10 +346,106 @@ class ProcessTest(CoverageTest): """) out = self.run_command("coverage run --source=sys,xyzzy,quux hello.py") - self.assertTrue("Hello\n" in out) - self.assertTrue(textwrap.dedent("""\ - Coverage.py warning: Module sys has no python source. - Coverage.py warning: Source module xyzzy was never encountered. - Coverage.py warning: Source module quux was never encountered. + self.assertIn("Hello\n", out) + self.assertIn(textwrap.dedent("""\ + Coverage.py warning: Module sys has no Python source. + Coverage.py warning: Module xyzzy was never imported. + Coverage.py warning: Module quux was never imported. Coverage.py warning: No data was collected. - """) in out) + """), out) + + def test_warnings_if_never_run(self): + out = self.run_command("coverage run i_dont_exist.py") + self.assertIn("No file to run: 'i_dont_exist.py'", out) + self.assertNotIn("warning", out) + self.assertNotIn("Exception", out) + + out = self.run_command("coverage run -m no_such_module") + self.assertTrue( + ("No module named no_such_module" in out) or + ("No module named 'no_such_module'" in out) + ) + self.assertNotIn("warning", out) + self.assertNotIn("Exception", out) + + if sys.version_info >= (3, 0): # This only works on 3.x for now. + # It only works with the C tracer. + if os.getenv('COVERAGE_TEST_TRACER', 'c') == 'c': + def test_fullcoverage(self): + # fullcoverage is a trick to get stdlib modules measured from + # the very beginning of the process. Here we import os and + # then check how many lines are measured. + self.make_file("getenv.py", """\ + import os + print("FOOEY == %s" % os.getenv("FOOEY")) + """) + + fullcov = os.path.join( + os.path.dirname(coverage.__file__), "fullcoverage" + ) + self.set_environ("FOOEY", "BOO") + self.set_environ("PYTHONPATH", fullcov) + out = self.run_command("python -m coverage run -L getenv.py") + self.assertEqual(out, "FOOEY == BOO\n") + data = coverage.CoverageData() + data.read_file(".coverage") + # The actual number of executed lines in os.py when it's + # imported is 120 or so. Just running os.getenv executes + # about 5. + self.assertGreater(data.summary()['os.py'], 50) + + +class AliasedCommandTests(CoverageTest): + """Tests of the version-specific command aliases.""" + + def test__major_version_works(self): + # "coverage2" works on py2 + cmd = "coverage%d" % sys.version_info[0] + out = self.run_command(cmd) + self.assertIn("Code coverage for Python", out) + + def test_wrong_alias_doesnt_work(self): + # "coverage3" doesn't work on py2 + badcmd = "coverage%d" % (5 - sys.version_info[0]) + out = self.run_command(badcmd) + self.assertNotIn("Code coverage for Python", out) + + def test_specific_alias_works(self): + # "coverage-2.7" works on py2.7 + cmd = "coverage-%d.%d" % sys.version_info[:2] + out = self.run_command(cmd) + self.assertIn("Code coverage for Python", out) + + +class FailUnderTest(CoverageTest): + """Tests of the --fail-under switch.""" + + def setUp(self): + super(FailUnderTest, self).setUp() + self.make_file("fifty.py", """\ + # I have 50% coverage! + a = 1 + if a > 2: + b = 3 + c = 4 + """) + st, _ = self.run_command_status("coverage run fifty.py", 0) + self.assertEqual(st, 0) + + def test_report(self): + st, _ = self.run_command_status("coverage report --fail-under=50", 0) + self.assertEqual(st, 0) + st, _ = self.run_command_status("coverage report --fail-under=51", 2) + self.assertEqual(st, 2) + + def test_html_report(self): + st, _ = self.run_command_status("coverage html --fail-under=50", 0) + self.assertEqual(st, 0) + st, _ = self.run_command_status("coverage html --fail-under=51", 2) + self.assertEqual(st, 2) + + def test_xml_report(self): + st, _ = self.run_command_status("coverage xml --fail-under=50", 0) + self.assertEqual(st, 0) + st, _ = self.run_command_status("coverage xml --fail-under=51", 2) + self.assertEqual(st, 2) diff --git a/test/test_results.py b/test/test_results.py index d6919fa2..3da92e4c 100644 --- a/test/test_results.py +++ b/test/test_results.py @@ -62,4 +62,3 @@ class NumbersTest(CoverageTest): self.assertEqual(n9999.pc_covered_str, "0.1") self.assertEqual(n10000.pc_covered_str, "0.0") Numbers.set_precision(0) - diff --git a/test/test_summary.py b/test/test_summary.py index fcc26125..b460c2dc 100644 --- a/test/test_summary.py +++ b/test/test_summary.py @@ -1,6 +1,6 @@ """Test text-based summary reporting for coverage.py""" -import os, re, sys, textwrap +import os, re, sys import coverage from coverage.backward import StringIO @@ -25,7 +25,7 @@ class SummaryTest(CoverageTest): def report_from_command(self, cmd): """Return the report from the `cmd`, with some convenience added.""" report = self.run_command(cmd).replace('\\', '/') - self.assertFalse("error" in report.lower()) + self.assertNotIn("error", report.lower()) return report def line_count(self, report): @@ -51,10 +51,10 @@ class SummaryTest(CoverageTest): # --------------------------------------------------------------------- # TOTAL 8 0 100% - self.assertFalse("/coverage/__init__/" in report) - self.assertTrue("/test/modules/covmod1 " in report) - self.assertTrue("/test/zipmods.zip/covmodzip1 " in report) - self.assertTrue("mycode " in report) + self.assertNotIn("/coverage/__init__/", report) + self.assertIn("/test/modules/covmod1 ", report) + self.assertIn("/test/zipmods.zip/covmodzip1 ", report) + self.assertIn("mycode ", report) self.assertEqual(self.last_line_squeezed(report), "TOTAL 8 0 100%") def test_report_just_one(self): @@ -67,10 +67,10 @@ class SummaryTest(CoverageTest): # mycode 4 0 100% self.assertEqual(self.line_count(report), 3) - self.assertFalse("/coverage/" in report) - self.assertFalse("/test/modules/covmod1 " in report) - self.assertFalse("/test/zipmods.zip/covmodzip1 " in report) - self.assertTrue("mycode " in report) + self.assertNotIn("/coverage/", report) + self.assertNotIn("/test/modules/covmod1 ", report) + self.assertNotIn("/test/zipmods.zip/covmodzip1 ", report) + self.assertIn("mycode ", report) self.assertEqual(self.last_line_squeezed(report), "mycode 4 0 100%") def test_report_omitting(self): @@ -84,10 +84,10 @@ class SummaryTest(CoverageTest): # mycode 4 0 100% self.assertEqual(self.line_count(report), 3) - self.assertFalse("/coverage/" in report) - self.assertFalse("/test/modules/covmod1 " in report) - self.assertFalse("/test/zipmods.zip/covmodzip1 " in report) - self.assertTrue("mycode " in report) + self.assertNotIn("/coverage/", report) + self.assertNotIn("/test/modules/covmod1 ", report) + self.assertNotIn("/test/zipmods.zip/covmodzip1 ", report) + self.assertIn("mycode ", report) self.assertEqual(self.last_line_squeezed(report), "mycode 4 0 100%") def test_report_including(self): @@ -100,10 +100,10 @@ class SummaryTest(CoverageTest): # mycode 4 0 100% self.assertEqual(self.line_count(report), 3) - self.assertFalse("/coverage/" in report) - self.assertFalse("/test/modules/covmod1 " in report) - self.assertFalse("/test/zipmods.zip/covmodzip1 " in report) - self.assertTrue("mycode " in report) + self.assertNotIn("/coverage/", report) + self.assertNotIn("/test/modules/covmod1 ", report) + self.assertNotIn("/test/zipmods.zip/covmodzip1 ", report) + self.assertIn("mycode ", report) self.assertEqual(self.last_line_squeezed(report), "mycode 4 0 100%") def test_report_branches(self): @@ -118,15 +118,120 @@ class SummaryTest(CoverageTest): self.assertEqual(out, 'x\n') report = self.report_from_command("coverage report") - # Name Stmts Miss Branch BrPart Cover + # Name Stmts Miss Branch BrMiss Cover # -------------------------------------------- # mybranch 5 0 2 1 85% self.assertEqual(self.line_count(report), 3) - self.assertTrue("mybranch " in report) + self.assertIn("mybranch ", report) self.assertEqual(self.last_line_squeezed(report), "mybranch 5 0 2 1 86%") + def test_dotpy_not_python(self): + # We run a .py file, and when reporting, we can't parse it as Python. + # We should get an error message in the report. + + self.run_command("coverage run mycode.py") + self.make_file("mycode.py", "This isn't python at all!") + report = self.report_from_command("coverage -r mycode.py") + + # pylint: disable=C0301 + # Name Stmts Miss Cover + # ---------------------------- + # mycode NotPython: Couldn't parse '/tmp/test_cover/63354509363/mycode.py' as Python source: 'invalid syntax' at line 1 + + last = self.last_line_squeezed(report) + # The actual file name varies run to run. + last = re.sub(r"parse '.*mycode.py", "parse 'mycode.py", last) + # The actual error message varies version to version + last = re.sub(r": '.*' at", ": 'error' at", last) + self.assertEqual(last, + "mycode NotPython: " + "Couldn't parse 'mycode.py' as Python source: " + "'error' at line 1" + ) + + def test_dotpy_not_python_ignored(self): + # We run a .py file, and when reporting, we can't parse it as Python, + # but we've said to ignore errors, so there's no error reported. + self.run_command("coverage run mycode.py") + self.make_file("mycode.py", "This isn't python at all!") + report = self.report_from_command("coverage -r -i mycode.py") + + # Name Stmts Miss Cover + # ---------------------------- + + self.assertEqual(self.line_count(report), 2) + + 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("mycode.html", "a = 1") + self.run_command("coverage run mycode.html") + # Before reporting, change it to be an HTML file. + self.make_file("mycode.html", "<h1>This isn't python at all!</h1>") + report = self.report_from_command("coverage -r mycode.html") + + # Name Stmts Miss Cover + # ---------------------------- + + self.assertEqual(self.line_count(report), 2) + + def get_report(self, cov): + """Get the report from `cov`, and canonicalize it.""" + repout = StringIO() + cov.report(file=repout, show_missing=False) + report = repout.getvalue().replace('\\', '/') + report = re.sub(r" +", " ", report) + return report + + def test_bug_156_file_not_run_should_be_zero(self): + # https://bitbucket.org/ned/coveragepy/issue/156 + self.make_file("mybranch.py", """\ + def branch(x): + if x: + print("x") + return x + branch(1) + """) + self.make_file("main.py", """\ + print("y") + """) + cov = coverage.coverage(branch=True, source=["."]) + cov.start() + import main # pylint: disable=F0401,W0612 + cov.stop() + report = self.get_report(cov).splitlines() + self.assertIn("mybranch 5 5 2 2 0%", report) + + def run_TheCode_and_report_it(self): + """A helper for the next few tests.""" + cov = coverage.coverage() + cov.start() + import TheCode # pylint: disable=F0401,W0612 + cov.stop() + return self.get_report(cov) + + def test_bug_203_mixed_case_listed_twice_with_rc(self): + self.make_file("TheCode.py", "a = 1\n") + self.make_file(".coveragerc", "[run]\nsource = .\n") + + report = self.run_TheCode_and_report_it() + + self.assertIn("TheCode", report) + self.assertNotIn("thecode", report) + + def test_bug_203_mixed_case_listed_twice(self): + self.make_file("TheCode.py", "a = 1\n") + + report = self.run_TheCode_and_report_it() + + self.assertIn("TheCode", report) + self.assertNotIn("thecode", report) + + class SummaryTest2(CoverageTest): """Another bunch of summary tests.""" # This class exists because tests naturally clump into classes based on the @@ -138,28 +243,59 @@ class SummaryTest2(CoverageTest): def setUp(self): super(SummaryTest2, self).setUp() # Parent class saves and restores sys.path, we can just modify it. - sys.path.append(self.nice_file(os.path.dirname(__file__), 'modules')) + this_dir = os.path.dirname(__file__) + sys.path.append(self.nice_file(this_dir, 'modules')) + sys.path.append(self.nice_file(this_dir, 'moremodules')) def test_empty_files(self): + # Shows that empty files like __init__.py are listed as having zero + # statements, not one statement. cov = coverage.coverage() cov.start() - import usepkgs # pylint: disable-msg=F0401,W0612 + import usepkgs # pylint: disable=F0401,W0612 cov.stop() repout = StringIO() cov.report(file=repout, show_missing=False) report = repout.getvalue().replace('\\', '/') - self.assertMultiLineEqual(report, textwrap.dedent("""\ - Name Stmts Miss Cover - ------------------------------------------------ - test/modules/pkg1/__init__ 1 0 100% - test/modules/pkg1/p1a 3 0 100% - test/modules/pkg1/p1b 3 0 100% - test/modules/pkg2/__init__ 0 0 100% - test/modules/pkg2/p2a 3 0 100% - test/modules/pkg2/p2b 3 0 100% - test/modules/usepkgs 2 0 100% - ------------------------------------------------ - TOTAL 15 0 100% - """)) + report = re.sub(r"\s+", " ", report) + self.assertIn("test/modules/pkg1/__init__ 1 0 100%", report) + self.assertIn("test/modules/pkg2/__init__ 0 0 100%", report) + + +class ReportingReturnValue(CoverageTest): + """Tests of reporting functions returning values.""" + + def run_coverage(self): + """Run coverage on doit.py and return the coverage object.""" + self.make_file("doit.py", """\ + a = 1 + b = 2 + c = 3 + d = 4 + if a > 10: + f = 6 + g = 7 + """) + + cov = coverage.coverage() + cov.start() + self.import_local_file("doit") + cov.stop() + return cov + + def test_report(self): + cov = self.run_coverage() + val = cov.report(include="*/doit.py") + self.assertAlmostEqual(val, 85.7, 1) + + def test_html(self): + cov = self.run_coverage() + val = cov.html_report(include="*/doit.py") + self.assertAlmostEqual(val, 85.7, 1) + + def test_xml(self): + cov = self.run_coverage() + val = cov.xml_report(include="*/doit.py") + self.assertAlmostEqual(val, 85.7, 1) diff --git a/test/test_templite.py b/test/test_templite.py index 93e9183d..0435c545 100644 --- a/test/test_templite.py +++ b/test/test_templite.py @@ -3,7 +3,7 @@ from coverage.templite import Templite import unittest -# pylint: disable-msg=W0612,E1101 +# pylint: disable=W0612,E1101 # Disable W0612 (Unused variable) and # E1101 (Instance of 'foo' has no 'bar' member) diff --git a/test/test_testing.py b/test/test_testing.py index 1cae9310..9943b65c 100644 --- a/test/test_testing.py +++ b/test/test_testing.py @@ -1,11 +1,13 @@ +# -*- coding: utf-8 -*- """Tests that our test infrastructure is really working!""" import os, sys sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k +from coverage.backward import to_bytes from backunittest import TestCase from coveragetest import CoverageTest -from coverage.backward import set # pylint: disable-msg=W0622 +from coverage.backward import set # pylint: disable=W0622 class TestingTest(TestCase): """Tests of helper methods on `backunittest.TestCase`.""" @@ -92,10 +94,42 @@ class TestingTest(TestCase): self.assertFalse(False) self.assertRaises(AssertionError, self.assertFalse, True) + def test_assert_in(self): + self.assertIn("abc", "hello abc") + self.assertIn("abc", ["xyz", "abc", "foo"]) + self.assertIn("abc", {'abc': 1, 'xyz': 2}) + self.assertRaises(AssertionError, self.assertIn, "abc", "xyz") + self.assertRaises(AssertionError, self.assertIn, "abc", ["x", "xabc"]) + self.assertRaises(AssertionError, self.assertIn, "abc", {'x':'abc'}) + + def test_assert_not_in(self): + self.assertRaises(AssertionError, self.assertNotIn, "abc", "hello abc") + self.assertRaises(AssertionError, + self.assertNotIn, "abc", ["xyz", "abc", "foo"] + ) + self.assertRaises(AssertionError, + self.assertNotIn, "abc", {'abc': 1, 'xyz': 2} + ) + self.assertNotIn("abc", "xyz") + self.assertNotIn("abc", ["x", "xabc"]) + self.assertNotIn("abc", {'x':'abc'}) + + def test_assert_greater(self): + self.assertGreater(10, 9) + self.assertGreater("xyz", "abc") + self.assertRaises(AssertionError, self.assertGreater, 9, 10) + self.assertRaises(AssertionError, self.assertGreater, 10, 10) + self.assertRaises(AssertionError, self.assertGreater, "abc", "xyz") + self.assertRaises(AssertionError, self.assertGreater, "xyz", "xyz") + class CoverageTestTest(CoverageTest): """Test the methods in `CoverageTest`.""" + def file_text(self, fname): + """Return the text read from a file.""" + return open(fname, "rb").read().decode('ascii') + def test_make_file(self): # A simple file. self.make_file("fooey.boo", "Hello there") @@ -109,3 +143,27 @@ class CoverageTestTest(CoverageTest): # A deeper directory self.make_file("sub/deeper/evenmore/third.txt") self.assertEqual(open("sub/deeper/evenmore/third.txt").read(), "") + + def test_make_file_newline(self): + self.make_file("unix.txt", "Hello\n") + self.assertEqual(self.file_text("unix.txt"), "Hello\n") + self.make_file("dos.txt", "Hello\n", newline="\r\n") + self.assertEqual(self.file_text("dos.txt"), "Hello\r\n") + self.make_file("mac.txt", "Hello\n", newline="\r") + self.assertEqual(self.file_text("mac.txt"), "Hello\r") + + def test_make_file_non_ascii(self): + self.make_file("unicode.txt", "tabblo: «ταБЬℓσ»") + self.assertEqual( + open("unicode.txt", "rb").read(), + to_bytes("tabblo: «ταБЬℓσ»") + ) + + def test_file_exists(self): + self.make_file("whoville.txt", "We are here!") + self.assert_exists("whoville.txt") + self.assert_doesnt_exist("shadow.txt") + self.assertRaises( + AssertionError, self.assert_doesnt_exist, "whoville.txt" + ) + self.assertRaises(AssertionError, self.assert_exists, "shadow.txt") diff --git a/test/test_xml.py b/test/test_xml.py new file mode 100644 index 00000000..dda03e09 --- /dev/null +++ b/test/test_xml.py @@ -0,0 +1,89 @@ +"""Tests for XML reports from coverage.py.""" + +import os, re, sys +import coverage + +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k +from coveragetest import CoverageTest + +class XmlReportTest(CoverageTest): + """Tests of the XML reports from coverage.py.""" + + def run_mycode(self): + """Run mycode.py, so we can report on it.""" + self.make_file("mycode.py", "print('hello')\n") + self.run_command("coverage run mycode.py") + + def test_default_file_placement(self): + self.run_mycode() + self.run_command("coverage xml") + self.assert_exists("coverage.xml") + + def test_argument_affects_xml_placement(self): + self.run_mycode() + self.run_command("coverage xml -o put_it_there.xml") + self.assert_doesnt_exist("coverage.xml") + self.assert_exists("put_it_there.xml") + + def test_config_affects_xml_placement(self): + self.run_mycode() + self.make_file(".coveragerc", "[xml]\noutput = xml.out\n") + self.run_command("coverage xml") + self.assert_doesnt_exist("coverage.xml") + self.assert_exists("xml.out") + + def test_no_data(self): + # https://bitbucket.org/ned/coveragepy/issue/210 + self.run_command("coverage xml") + self.assert_doesnt_exist("coverage.xml") + + def test_no_source(self): + # Written while investigating a bug, might as well keep it. + # https://bitbucket.org/ned/coveragepy/issue/208 + self.make_file("innocuous.py", "a = 4") + cov = coverage.coverage() + cov.start() + self.import_local_file("innocuous") + cov.stop() + os.remove("innocuous.py") + cov.xml_report(ignore_errors=True) + self.assert_exists("coverage.xml") + + def run_doit(self): + """Construct a simple sub-package.""" + self.make_file("sub/__init__.py") + self.make_file("sub/doit.py", "print('doit!')") + self.make_file("main.py", "import sub.doit") + cov = coverage.coverage() + cov.start() + self.import_local_file("main") + cov.stop() + return cov + + def test_filename_format_showing_everything(self): + cov = self.run_doit() + cov.xml_report(outfile="-") + xml = self.stdout() + doit_line = re_line(xml, "class.*doit") + self.assertIn('filename="sub/doit.py"', doit_line) + + def test_filename_format_including_filename(self): + cov = self.run_doit() + cov.xml_report(["sub/doit.py"], outfile="-") + xml = self.stdout() + doit_line = re_line(xml, "class.*doit") + self.assertIn('filename="sub/doit.py"', doit_line) + + def test_filename_format_including_module(self): + cov = self.run_doit() + import sub.doit # pylint: disable=F0401 + cov.xml_report([sub.doit], outfile="-") + xml = self.stdout() + doit_line = re_line(xml, "class.*doit") + self.assertIn('filename="sub/doit.py"', doit_line) + + +def re_line(text, pat): + """Return the one line in `text` that matches regex `pat`.""" + lines = [l for l in text.splitlines() if re.search(pat, l)] + return lines[0] diff --git a/test/try_execfile.py b/test/try_execfile.py index d7ea4398..9bbabd1a 100644 --- a/test/try_execfile.py +++ b/test/try_execfile.py @@ -1,6 +1,6 @@ """Test file for run_python_file.""" -import pprint, sys +import os, pprint, sys DATA = "xyzzy" @@ -12,17 +12,23 @@ def my_function(a): FN_VAL = my_function("fooey") +try: + pkg = __package__ +except NameError: + pkg = "*No __package__*" + globals_to_check = { '__name__': __name__, '__file__': __file__, '__doc__': __doc__, '__builtins__.has_open': hasattr(__builtins__, 'open'), '__builtins__.dir': dir(__builtins__), + '__package__': pkg, 'DATA': DATA, 'FN_VAL': FN_VAL, '__main__.DATA': getattr(__main__, "DATA", "nothing"), 'argv': sys.argv, - 'path0': sys.path[0], + 'path': [os.path.normcase(p) for p in sys.path], } pprint.pprint(globals_to_check) |