diff options
-rw-r--r-- | coverage/config.py | 8 | ||||
-rw-r--r-- | coverage/control.py | 11 | ||||
-rw-r--r-- | coverage/data.py | 2 | ||||
-rw-r--r-- | test/test_config.py | 13 | ||||
-rw-r--r-- | test/test_process.py | 46 |
5 files changed, 77 insertions, 3 deletions
diff --git a/coverage/config.py b/coverage/config.py index 6b441ddc..e72a728b 100644 --- a/coverage/config.py +++ b/coverage/config.py @@ -55,6 +55,9 @@ class CoverageConfig(object): # Defaults for [xml] self.xml_output = "coverage.xml" + # Defaults for [paths] + self.paths = {} + def from_environment(self, env_var): """Read configuration from the `env_var` environment variable.""" # Timidity: for nose users, read an environment variable. This is a @@ -124,6 +127,11 @@ class CoverageConfig(object): if cp.has_option('xml', 'output'): self.xml_output = cp.get('xml', 'output') + # [paths] + if cp.has_section('paths'): + for option in cp.options('paths'): + self.paths[option] = self.get_list(cp, 'paths', option) + def get_list(self, cp, section, option): """Read a list of strings from the ConfigParser `cp`. diff --git a/coverage/control.py b/coverage/control.py index 4ba3a034..a77d805d 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -9,7 +9,7 @@ from coverage.collector import Collector from coverage.config import CoverageConfig from coverage.data import CoverageData from coverage.files import FileLocator, TreeMatcher, FnmatchMatcher -from coverage.files import find_python_files +from coverage.files import PathAliases, find_python_files from coverage.html import HtmlReporter from coverage.misc import CoverageException, bool_or_none, join_regex from coverage.results import Analysis, Numbers @@ -467,7 +467,14 @@ class coverage(object): current measurements. """ - self.data.combine_parallel_data() + aliases = None + if self.config.paths: + aliases = PathAliases() + for paths in self.config.paths.values(): + result = paths[0] + for pattern in paths[1:]: + aliases.add(pattern, result) + self.data.combine_parallel_data(aliases=aliases) def _harvest_data(self): """Get the collected data and reset the collector. diff --git a/coverage/data.py b/coverage/data.py index 1d6799f0..7a8d656f 100644 --- a/coverage/data.py +++ b/coverage/data.py @@ -176,7 +176,7 @@ class CoverageData(object): Treat `self.filename` as a file prefix, and combine the data from all of the data files starting with that prefix plus a dot. - If `aliases` is provided, it's a PathAliases object that is used to + If `aliases` is provided, it's a `PathAliases` object that is used to re-map paths to match the local machine's. """ diff --git a/test/test_config.py b/test/test_config.py index 3c4be9b7..13ec0f3c 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -140,6 +140,13 @@ class ConfigFileTest(CoverageTest): [xml] output=mycov.xml + [paths] + source = + . + /home/ned/src/ + + other = other, /home/ned/other, c:\\Ned\\etc + """) cov = coverage.coverage() @@ -168,3 +175,9 @@ class ConfigFileTest(CoverageTest): self.assertEqual(cov.config.html_dir, r"c:\tricky\dir.somewhere") 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'] + }) + diff --git a/test/test_process.py b/test/test_process.py index 1bdb1400..5b576d1f 100644 --- a/test/test_process.py +++ b/test/test_process.py @@ -129,6 +129,52 @@ 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") + self.assertEqual(data.summary(fullpath=True), {'src/x.py': 6}) + def test_missing_source_file(self): # Check what happens if the source is missing when reporting happens. self.make_file("fleeting.py", """\ |