summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Richter <stephan.richter@gmail.com>2019-01-24 07:44:59 -0500
committerNed Batchelder <ned@nedbatchelder.com>2019-06-10 17:15:32 -0400
commit0f5c9347aa8c72d853f49761d5580a770c4fd39f (patch)
tree82e0a136a16456d2df85f803a3ed9dc3da66d5ee
parent5c157a28c46b2f5ed9e9051e5b6c8d461b490f1b (diff)
downloadpython-coveragepy-git-0f5c9347aa8c72d853f49761d5580a770c4fd39f.tar.gz
Extend HTML report to to show contexts for every covered line.
-rw-r--r--coverage/cmdline.py7
-rw-r--r--coverage/config.py1
-rw-r--r--coverage/control.py4
-rw-r--r--coverage/html.py5
-rw-r--r--coverage/htmlfiles/pyfile.html17
-rw-r--r--coverage/htmlfiles/style.css47
6 files changed, 79 insertions, 2 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index 76af0213..1c31b1e7 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -93,6 +93,10 @@ class Opts(object):
'--skip-covered', action='store_true',
help="Skip files with 100% coverage.",
)
+ show_contexts = optparse.make_option(
+ '--show-contexts', action='store_true',
+ help="Show contexts for covered lines.",
+ )
omit = optparse.make_option(
'', '--omit', action='store',
metavar="PAT1,PAT2,...",
@@ -190,6 +194,7 @@ class CoverageOptionParser(optparse.OptionParser, object):
rcfile=True,
show_missing=None,
skip_covered=None,
+ show_contexts=None,
source=None,
timid=None,
title=None,
@@ -341,6 +346,7 @@ CMDS = {
Opts.omit,
Opts.title,
Opts.skip_covered,
+ Opts.show_contexts
] + GLOBAL_ARGS,
usage="[options] [modules]",
description=(
@@ -553,6 +559,7 @@ class CoverageScript(object):
directory=options.directory,
title=options.title,
skip_covered=options.skip_covered,
+ show_contexts=options.show_contexts,
**report_args
)
elif options.action == "xml":
diff --git a/coverage/config.py b/coverage/config.py
index 0188a013..f8c91897 100644
--- a/coverage/config.py
+++ b/coverage/config.py
@@ -202,6 +202,7 @@ class CoverageConfig(object):
self.precision = 0
self.show_missing = False
self.skip_covered = False
+ self.show_contexts = False
# Defaults for [html]
self.extra_css = None
diff --git a/coverage/control.py b/coverage/control.py
index 029b439a..552f7bc2 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -787,7 +787,7 @@ class Coverage(object):
def html_report(self, morfs=None, directory=None, ignore_errors=None,
omit=None, include=None, extra_css=None, title=None,
- skip_covered=None, contexts=None):
+ skip_covered=None, show_contexts=None, contexts=None):
"""Generate an HTML report.
The HTML is written to `directory`. The file "index.html" is the
@@ -814,7 +814,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, query_contexts=contexts,
+ skip_covered=skip_covered, show_contexts=show_contexts, query_contexts=contexts,
)
reporter = HtmlReporter(self, self.config)
return reporter.report(morfs)
diff --git a/coverage/html.py b/coverage/html.py
index d5edd5f7..3cd47d5a 100644
--- a/coverage/html.py
+++ b/coverage/html.py
@@ -214,6 +214,9 @@ class HtmlReporter(Reporter):
c_mis = "mis"
c_par = "par " + c_run
+ # Lookup line number contexts.
+ contexts_by_lineno = analysis.data.contexts_by_lineno(fr.filename)
+
lines = []
for lineno, line in enumerate(fr.source_token_lines(), start=1):
@@ -268,6 +271,7 @@ class HtmlReporter(Reporter):
'html': ''.join(html),
'number': lineno,
'class': ' '.join(line_class) or "pln",
+ 'contexts': sorted(filter(None, contexts_by_lineno[lineno])) or None,
'annotate': annotate_html,
'annotate_long': annotate_long,
})
@@ -279,6 +283,7 @@ class HtmlReporter(Reporter):
'c_par': c_par,
'c_run': c_run,
'has_arcs': self.has_arcs,
+ 'show_contexts': self.config.show_contexts,
'extra_css': self.extra_css,
'fr': fr,
'nums': nums,
diff --git a/coverage/htmlfiles/pyfile.html b/coverage/htmlfiles/pyfile.html
index 245ecf41..025ae797 100644
--- a/coverage/htmlfiles/pyfile.html
+++ b/coverage/htmlfiles/pyfile.html
@@ -88,6 +88,23 @@
</p>
{% endfor %}
</td>
+ {% if show_contexts -%}
+ <td class="contexts">
+ {% for line in lines -%}
+ <p>{#-#}
+ {% if line.contexts -%}
+ <span class="context-button">ctx</span>{#-#}
+ <span class="context-list">
+ {% for context in line.contexts -%}
+ <span class="context-line">{{context}}</span>{#-#}
+ {% endfor -%}
+ </span>{#-#}
+ {% endif -%}
+ &nbsp;
+ </p>{#-#}
+ {% endfor %}
+ </td>
+ {% endif -%}
</tr>
</table>
</div>
diff --git a/coverage/htmlfiles/style.css b/coverage/htmlfiles/style.css
index 41bcf2be..c663ed33 100644
--- a/coverage/htmlfiles/style.css
+++ b/coverage/htmlfiles/style.css
@@ -297,6 +297,53 @@ td.text {
color: #000080;
}
+td.contexts p {
+ margin: 0;
+ padding: 0 .5em;
+ color: #999999;
+ font-family: verdana, sans-serif;
+ white-space: nowrap;
+ position: relative;
+ }
+
+td.contexts p:hover {
+ background: #eee;
+ }
+
+td.contexts p span.context-list {
+ display: none;
+ }
+
+td.contexts p:hover span.context-list {
+ display: block;
+ min-width: 30em;
+ //max-width: 50%;
+ white-space: normal;
+ float: right;
+ position: absolute;
+ top: 1.75em;
+ right: 1em;
+ height: auto;
+ color: #333;
+ background: #ffffcc;
+ border: 1px solid #888;
+ padding: .25em .5em;
+ z-index: 999;
+ border-radius: .2em;
+ box-shadow: #cccccc .2em .2em .2em;
+ }
+
+span.context-list span.context-line {
+ display: block;
+}
+
+td.contexts p span.context-button {
+ display: inline-block;
+ cursor: pointer;
+ font-size: .8333em; /* 10/12 */
+ line-height: 1em;
+ }
+
/* index styles */
#index td, #index th {
text-align: right;