diff options
author | loic@dachary.org <loic@dachary.org> | 2017-01-06 15:42:56 +0100 |
---|---|---|
committer | loic@dachary.org <loic@dachary.org> | 2017-01-06 15:42:56 +0100 |
commit | bcc6d71c52207fa4808f14234231af7d399b975f (patch) | |
tree | 6fd982d58f1434c6f438934afba4fae368fb8f67 | |
parent | 6d5ebb6b653b9551c78383e23309860f1f650ba3 (diff) | |
download | python-coveragepy-git-bcc6d71c52207fa4808f14234231af7d399b975f.tar.gz |
make --source module do the same as --source directory #426
The --source argument can either be a module or a directory. The user
expects that it behaves the same in both cases. Make sure the module
is recursively explored so that files that are not run show in the
coverage report.
close #426
--HG--
branch : issue-426
-rw-r--r-- | coverage/control.py | 24 | ||||
-rw-r--r-- | tests/test_process.py | 9 |
2 files changed, 28 insertions, 5 deletions
diff --git a/coverage/control.py b/coverage/control.py index 992ca585..d968b182 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -159,6 +159,7 @@ class Coverage(object): # Other instance attributes, set later. self.omit = self.include = self.source = None + self.source_pkgs_unmatched = None self.source_pkgs = None self.data = self.data_files = self.collector = None self.plugins = None @@ -223,6 +224,7 @@ class Coverage(object): self.source.append(files.canonical_filename(src)) else: self.source_pkgs.append(src) + self.source_pkgs_unmatched = self.source_pkgs[:] self.omit = prep_patterns(self.config.omit) self.include = prep_patterns(self.config.include) @@ -549,8 +551,8 @@ class Coverage(object): # stdlib and coverage.py directories. if self.source_match: if self.source_pkgs_match.match(modulename): - if modulename in self.source_pkgs: - self.source_pkgs.remove(modulename) + if modulename in self.source_pkgs_unmatched: + self.source_pkgs_unmatched.remove(modulename) return None # There's no reason to skip this file. if not self.source_match.match(filename): @@ -815,10 +817,10 @@ class Coverage(object): self.collector.save_data(self.data) - # If there are still entries in the source_pkgs list, then we never + # If there are still entries in the source_pkgs_unmatched list, then we never # encountered those packages. if self._warn_unimported_source: - for pkg in self.source_pkgs: + for pkg in self.source_pkgs_unmatched: if pkg not in sys.modules: self._warn("Module %s was never imported." % pkg) elif not ( @@ -833,8 +835,20 @@ class Coverage(object): if not self.data and self._warn_no_data: self._warn("No data was collected.") + src_directories = self.source[:] + + for pkg in self.source_pkgs: + if (not pkg in sys.modules or + not hasattr(sys.modules[pkg], '__file__') or + not os.path.exists(sys.modules[pkg].__file__)): + continue + pkg_file = sys.modules[pkg].__file__ + if not pkg_file.endswith(('__init__.py', '__init__.pyc', '__init__.pyo')): + continue + src_directories.append(self._canonical_dir(sys.modules[pkg])) + # Find files that were never executed at all. - for src in self.source: + for src in src_directories: for py_file in find_python_files(src): py_file = files.canonical_filename(py_file) diff --git a/tests/test_process.py b/tests/test_process.py index be9bdb76..a9e8d4c6 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -505,6 +505,15 @@ class ProcessTest(CoverageTest): self.assertEqual(st, 0) self.assertEqual(self.line_count(out), 6, out) + def test_coverage_doubledashsource_module(self): + """ pkg1.sub is not a directory, verify the files it contains + and that were not run show in the report """ + out = self.run_command("coverage run --source pkg1.sub -m pkg1.sub arg") + self.assertIn('pkg1.sub.__main__: passed', out) + st, out = self.run_command_status("coverage report") + self.assertEqual(st, 0) + self.assertIn('runmod3.py', out) + def test_coverage_run_script_imports_doubledashsource(self): # This file imports try_execfile, which compiles it to .pyc, so the # first run will have __file__ == "try_execfile.py" and the second will |