diff options
-rw-r--r-- | CHANGES.txt | 4 | ||||
-rw-r--r-- | TODO.txt | 4 | ||||
-rw-r--r-- | coverage/cmdline.py | 9 | ||||
-rw-r--r-- | tests/test_cmdline.py | 31 | ||||
-rw-r--r-- | tests/test_process.py | 14 |
5 files changed, 50 insertions, 12 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 94ac7dd..d1e4a43 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,10 @@ Change history for Coverage.py Latest ------ +- 4.0b1 broke --append creating new data files. This is now fixed, closing + `issue 392`_. + +.. _issue 392: https://bitbucket.org/ned/coveragepy/issues/392/run-append-doesnt-create-coverage-file Version 4.0b1 --- 2 August 2015 @@ -42,6 +42,10 @@ Key: - test helpers + cov.config["run:branch"] api (well, coverage.get_option etc) - "added in 4.0" + - tweaks to theme? +- build process + - don't publish to nedbat.com any more + - all doc links should point to rtfd + Remove code only run on <2.6 + Change data file to json + Create data api diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 0a84aa1..b2ffdf7 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -5,6 +5,7 @@ import glob import optparse +import os.path import sys import traceback @@ -344,7 +345,7 @@ class CoverageScript(object): """The command-line interface to coverage.py.""" def __init__(self, _covpkg=None, _run_python_file=None, - _run_python_module=None, _help_fn=None): + _run_python_module=None, _help_fn=None, _path_exists=None): # _covpkg is for dependency injection, so we can test this code. if _covpkg: self.covpkg = _covpkg @@ -356,6 +357,7 @@ class CoverageScript(object): self.run_python_file = _run_python_file or run_python_file self.run_python_module = _run_python_module or run_python_module self.help_fn = _help_fn or self.help + self.path_exists = _path_exists or os.path.exists self.global_option = False self.coverage = None @@ -575,8 +577,9 @@ class CoverageScript(object): self.coverage.stop() if code_ran: if options.append: - data_paths = [self.coverage.get_option("run:data_file")] - self.coverage.combine(data_paths=data_paths) + data_file = self.coverage.get_option("run:data_file") + if self.path_exists(data_file): + self.coverage.combine(data_paths=[data_file]) self.coverage.save() return OK diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 3baa262..4c54088 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -63,30 +63,33 @@ class BaseCmdLineTest(CoverageTest): return mk - def mock_command_line(self, args): + def mock_command_line(self, args, path_exists=None): """Run `args` through the command line, with a Mock. Returns the Mock it used and the status code returned. """ m = self.model_object() + m.path_exists.return_value = path_exists + ret = coverage.cmdline.CoverageScript( _covpkg=m, _run_python_file=m.run_python_file, - _run_python_module=m.run_python_module, _help_fn=m.help_fn + _run_python_module=m.run_python_module, _help_fn=m.help_fn, + _path_exists=m.path_exists, ).command_line(shlex.split(args)) + return m, ret - def cmd_executes(self, args, code, ret=OK): + def cmd_executes(self, args, code, ret=OK, path_exists=None): """Assert that the `args` end up executing the sequence in `code`.""" - m1, r1 = self.mock_command_line(args) - self.assertEqual( - r1, ret, "Wrong status: got %s, wanted %s" % (r1, ret) - ) + m1, r1 = self.mock_command_line(args, path_exists=path_exists) + self.assertEqual(r1, ret, "Wrong status: got %r, wanted %r" % (r1, ret)) # Remove all indentation, and change ".foo()" to "m2.foo()". code = re.sub(r"(?m)^\s+", "", code) code = re.sub(r"(?m)^\.", "m2.", code) m2 = self.model_object() + m2.path_exists.return_value = path_exists code_obj = compile(code, "<code>", "exec") eval(code_obj, globals(), { 'm2': m2 }) # pylint: disable=eval-used @@ -351,15 +354,25 @@ class CmdLineTest(BaseCmdLineTest): .stop() .save() """) - # run -a calls coverage.load first without erasing. + # run -a combines with an existing data file before saving. self.cmd_executes("run -a foo.py", """\ .coverage() .start() .run_python_file('foo.py', ['foo.py']) .stop() + .path_exists('.coverage') .combine(data_paths=['.coverage']) .save() - """) + """, path_exists=True) + # run -a doesn't combine anything if the data file doesn't exist. + self.cmd_executes("run -a foo.py", """\ + .coverage() + .start() + .run_python_file('foo.py', ['foo.py']) + .stop() + .path_exists('.coverage') + .save() + """, path_exists=False) # --timid sets a flag, and program arguments get passed through. self.cmd_executes("run --timid foo.py abc 123", """\ .coverage(timid=True) diff --git a/tests/test_process.py b/tests/test_process.py index fcd8882..9bd7211 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -168,6 +168,20 @@ class ProcessTest(CoverageTest): data.read_file(".mycovdata") self.assertEqual(data.line_counts()['b_or_c.py'], 7) + def test_append_can_create_a_data_file(self): + self.make_b_or_c_py() + + out = self.run_command("coverage run --append b_or_c.py b") + self.assertEqual(out, 'done\n') + self.assert_exists(".coverage") + self.assertEqual(self.number_of_data_files(), 1) + + # Read the coverage file and see that b_or_c.py has only 6 lines + # executed. + data = coverage.CoverageData() + data.read_file(".coverage") + self.assertEqual(data.line_counts()['b_or_c.py'], 6) + def test_combine_with_rc(self): self.make_b_or_c_py() |