diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2019-07-01 23:14:15 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2019-07-01 23:14:15 -0400 |
commit | 25aff80d444a6b1fa87173ffd8026f69be7ae0d0 (patch) | |
tree | bce9981e83cf7374098fc9e299574b93b089c744 | |
parent | 262c06921db064a85f442b19cbf0980bb3cd786d (diff) | |
download | python-coveragepy-git-25aff80d444a6b1fa87173ffd8026f69be7ae0d0.tar.gz |
Clean up and test filtering contexts for reporting
-rw-r--r-- | coverage/cmdline.py | 2 | ||||
-rw-r--r-- | coverage/config.py | 3 | ||||
-rw-r--r-- | coverage/control.py | 8 | ||||
-rw-r--r-- | coverage/html.py | 5 | ||||
-rw-r--r-- | coverage/sqldata.py | 17 | ||||
-rw-r--r-- | coverage/summary.py | 2 | ||||
-rw-r--r-- | tests/test_html.py | 21 |
7 files changed, 37 insertions, 21 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py index cf97bb01..354ae8c2 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -109,7 +109,7 @@ class Opts(object): '', '--contexts', action='store', metavar="PAT1,PAT2,...", help=( - "Only count the lines covered in given contexts. " + "Only display data from lines covered in the given contexts. " "Accepts shell-style wildcards, which must be quoted." ), ) diff --git a/coverage/config.py b/coverage/config.py index d5d89d1f..4bb60eb3 100644 --- a/coverage/config.py +++ b/coverage/config.py @@ -179,7 +179,6 @@ class CoverageConfig(object): self.command_line = None self.concurrency = None self.context = None - self.query_contexts = None self.cover_pylib = False self.data_file = ".coverage" self.debug = [] @@ -202,6 +201,7 @@ class CoverageConfig(object): self.partial_always_list = DEFAULT_PARTIAL_ALWAYS[:] self.partial_list = DEFAULT_PARTIAL[:] self.precision = 0 + self.report_contexts = None self.show_missing = False self.skip_covered = False @@ -347,6 +347,7 @@ class CoverageConfig(object): ('partial_always_list', 'report:partial_branches_always', 'regexlist'), ('partial_list', 'report:partial_branches', 'regexlist'), ('precision', 'report:precision', 'int'), + ('report_contexts', 'report:contexts', 'list'), ('report_include', 'report:include', 'list'), ('report_omit', 'report:omit', 'list'), ('show_missing', 'report:show_missing', 'boolean'), diff --git a/coverage/control.py b/coverage/control.py index a8e9d15c..a4e21295 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -781,7 +781,7 @@ class Coverage(object): self.config.from_args( ignore_errors=ignore_errors, report_omit=omit, report_include=include, show_missing=show_missing, skip_covered=skip_covered, - query_contexts=contexts, + report_contexts=contexts, ) reporter = SummaryReporter(self) return reporter.report(morfs, outfile=file) @@ -802,7 +802,7 @@ class Coverage(object): """ self.config.from_args( ignore_errors=ignore_errors, report_omit=omit, - report_include=include, query_contexts=contexts, + report_include=include, report_contexts=contexts, ) reporter = AnnotateReporter(self) reporter.report(morfs, directory=directory) @@ -836,7 +836,7 @@ class Coverage(object): self.config.from_args( ignore_errors=ignore_errors, report_omit=omit, report_include=include, html_dir=directory, extra_css=extra_css, html_title=title, - skip_covered=skip_covered, show_contexts=show_contexts, query_contexts=contexts, + skip_covered=skip_covered, show_contexts=show_contexts, report_contexts=contexts, ) reporter = HtmlReporter(self) return reporter.report(morfs) @@ -859,7 +859,7 @@ class Coverage(object): """ self.config.from_args( ignore_errors=ignore_errors, report_omit=omit, report_include=include, - xml_output=outfile, query_contexts=contexts, + xml_output=outfile, report_contexts=contexts, ) file_to_close = None delete_file = False diff --git a/coverage/html.py b/coverage/html.py index cff2419d..fc3bb364 100644 --- a/coverage/html.py +++ b/coverage/html.py @@ -80,7 +80,9 @@ class HtmlDataGeneration(object): def __init__(self, cov): self.coverage = cov self.config = self.coverage.config - self.has_arcs = self.coverage.get_data().has_arcs() + data = self.coverage.get_data() + self.has_arcs = data.has_arcs() + data.set_query_contexts(self.config.report_contexts) def data_for_file(self, fr, analysis): """Produce the data needed for one file's report.""" @@ -218,7 +220,6 @@ class HtmlReporter(object): self.incr.check_global_data(self.config, self.pyfile_html_source) # Process all the files. - self.coverage.get_data().set_query_contexts(self.config.query_contexts) for fr, analysis in get_analysis_to_report(self.coverage, morfs): self.html_file(fr, analysis) diff --git a/coverage/sqldata.py b/coverage/sqldata.py index 1cc64f24..03a352ba 100644 --- a/coverage/sqldata.py +++ b/coverage/sqldata.py @@ -558,10 +558,12 @@ class CoverageSqliteData(SimpleReprMixin): return "" # File was measured, but no tracer associated. - def set_query_contexts(self, contexts=None): + def set_query_contexts(self, contexts): """Set query contexts for future `lines`, `arcs` etc. calls.""" - self._query_context_ids = self._get_query_context_ids(contexts) \ - if contexts is not None else None + if contexts: + self._query_context_ids = self._get_query_context_ids(contexts) + else: + self._query_context_ids = None self._query_contexts = contexts def _get_query_context_ids(self, contexts=None): @@ -570,13 +572,10 @@ class CoverageSqliteData(SimpleReprMixin): return None self._start_using() with self._connect() as con: - # Context entries can be globs, so convert '*' with '%'. - context_selectors = [context.replace('*', '%') for context in contexts] - context_clause = ' or '.join(['context like ?']*len(contexts)) - cur = con.execute( - "select id from context where " + context_clause, context_selectors) + context_clause = ' or '.join(['context glob ?'] * len(contexts)) + cur = con.execute("select id from context where " + context_clause, contexts) return [row[0] for row in cur.fetchall()] - elif self._query_contexts is not None: + elif self._query_contexts: return self._query_context_ids return None diff --git a/coverage/summary.py b/coverage/summary.py index 419051b0..72d21033 100644 --- a/coverage/summary.py +++ b/coverage/summary.py @@ -40,7 +40,7 @@ class SummaryReporter(object): """ self.outfile = outfile or sys.stdout - self.coverage.get_data().set_query_contexts(self.config.query_contexts) + self.coverage.get_data().set_query_contexts(self.config.report_contexts) for fr, analysis in get_analysis_to_report(self.coverage, morfs): self.report_one_file(fr, analysis) diff --git a/tests/test_html.py b/tests/test_html.py index 37862f6d..4509e52f 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -1037,10 +1037,10 @@ assert len(math) == 18 def html_data_from_cov(cov, morf): """Get HTML report data from a `Coverage` object for a morf.""" - reporter = coverage.html.HtmlDataGeneration(cov) + datagen = coverage.html.HtmlDataGeneration(cov) for fr, analysis in get_analysis_to_report(cov, [morf]): # This will only loop once, so it's fine to return inside the loop. - file_data = reporter.data_for_file(fr, analysis) + file_data = datagen.data_for_file(fr, analysis) return file_data @@ -1081,7 +1081,7 @@ class HtmlWithContextsTest(HtmlTestHelpers, CoverageTest): TEST_ONE_LINES = [5, 6, 2] TEST_TWO_LINES = [9, 10, 11, 13, 14, 15, 2] - def test_dynamic_alone(self): + def test_dynamic_contexts(self): self.make_file("two_tests.py", self.SOURCE) cov = coverage.Coverage(source=["."]) cov.set_option("run:dynamic_context", "test_function") @@ -1094,3 +1094,18 @@ class HtmlWithContextsTest(HtmlTestHelpers, CoverageTest): for label, expected in zip(context_labels, expected_lines): actual = [ld.number for ld in d.lines if label in (ld.contexts or ())] assert sorted(expected) == sorted(actual) + + def test_filtered_dynamic_contexts(self): + self.make_file("two_tests.py", self.SOURCE) + cov = coverage.Coverage(source=["."]) + cov.set_option("run:dynamic_context", "test_function") + cov.set_option("html:show_contexts", True) + cov.set_option("report:contexts", ["*test_one*"]) + mod = self.start_import_stop(cov, "two_tests") + d = html_data_from_cov(cov, mod) + + context_labels = ['(empty)', 'two_tests.test_one', 'two_tests.test_two'] + expected_lines = [[], self.TEST_ONE_LINES, []] + for label, expected in zip(context_labels, expected_lines): + actual = [ld.number for ld in d.lines if label in (ld.contexts or ())] + assert sorted(expected) == sorted(actual) |