Skip to content

Commit d6cb1cd

Browse files
authored
fix: put contexts dict in <script> and reveal them using JavaScript (#1587)
* Put contexts dict in <script> and reveal them using JavaScript Fixes #1584 * Address review comments * coverage/htmlfiles/style.css: Align the contexts to the right * coverage/htmlfiles/style.scss: Match style.css * coverage/html.py: Fix linting and mypy errors * two_tests_py.html: make update-gold
1 parent 551522e commit d6cb1cd

File tree

7 files changed

+65
-17
lines changed

7 files changed

+65
-17
lines changed

coverage/html.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import os
1111
import re
1212
import shutil
13+
from collections import Counter
1314

1415
from dataclasses import dataclass
1516
from typing import Any, Dict, Iterable, List, Optional, Tuple, TYPE_CHECKING, cast
@@ -84,6 +85,7 @@ class LineData:
8485
short_annotations: List[str]
8586
long_annotations: List[str]
8687
html: str = ""
88+
context_str: Optional[str] = None
8789
annotate: Optional[str] = None
8890
annotate_long: Optional[str] = None
8991
css_class: str = ""
@@ -367,6 +369,11 @@ def write_html_file(self, ftr: FileToReport, prev_html: str, next_html: str) ->
367369

368370
# Write the HTML page for this file.
369371
file_data = self.datagen.data_for_file(ftr.fr, ftr.analysis)
372+
373+
contexts = Counter(c for cline in file_data.lines for c in cline.contexts)
374+
context_codes = {y: i for (i, y) in enumerate(x[0] for x in contexts.most_common())}
375+
contexts_json = json.dumps({v: k for (k, v) in context_codes.items()}, indent=2)
376+
370377
for ldata in file_data.lines:
371378
# Build the HTML for the line.
372379
html_parts = []
@@ -380,6 +387,9 @@ def write_html_file(self, ftr: FileToReport, prev_html: str, next_html: str) ->
380387
)
381388
ldata.html = ''.join(html_parts)
382389

390+
ldata.context_str = ",".join(
391+
str(context_codes[c_context]) for c_context in ldata.context_list)
392+
383393
if ldata.short_annotations:
384394
# 202F is NARROW NO-BREAK SPACE.
385395
# 219B is RIGHTWARDS ARROW WITH STROKE.
@@ -412,6 +422,10 @@ def write_html_file(self, ftr: FileToReport, prev_html: str, next_html: str) ->
412422
)
413423
ldata.css_class = ' '.join(css_classes) or "pln"
414424

425+
if context_codes:
426+
file_data.__dict__["contexts_json"] = contexts_json
427+
else:
428+
file_data.__dict__["contexts_json"] = None
415429
html_path = os.path.join(self.directory, ftr.html_filename)
416430
html = self.source_tmpl.render({
417431
**file_data.__dict__,

coverage/htmlfiles/coverage_html.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ coverage.index_ready = function () {
212212
coverage.LINE_FILTERS_STORAGE = "COVERAGE_LINE_FILTERS";
213213

214214
coverage.pyfile_ready = function () {
215+
cboxes = document.querySelectorAll('[id^=ctxs]')
216+
cboxes.forEach(function(cbox) {
217+
cbox.addEventListener("click", coverage.showContexts)
218+
});
219+
215220
// If we're directed to a particular line number, highlight the line.
216221
var frag = location.hash;
217222
if (frag.length > 2 && frag[1] === 't') {
@@ -595,10 +600,26 @@ coverage.wire_up_sticky_header = function () {
595600
updateHeader();
596601
};
597602

603+
coverage.showContexts = function (e) {
604+
span = e.target.nextElementSibling.nextElementSibling;
605+
span_text = span.textContent;
606+
607+
if (/^[0-9,]+$/.test(span_text))
608+
{
609+
span.textContent = "";
610+
span_text.split(",").forEach(function(s) {
611+
ctx = contexts[s];
612+
span.appendChild(document.createTextNode(ctx));
613+
span.appendChild(document.createElement("br"));
614+
})
615+
}
616+
};
617+
598618
document.addEventListener("DOMContentLoaded", () => {
599619
if (document.body.classList.contains("indexfile")) {
600620
coverage.index_ready();
601621
} else {
602622
coverage.pyfile_ready();
603623
}
624+
604625
});

coverage/htmlfiles/pyfile.html

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111
{% if extra_css %}
1212
<link rel="stylesheet" href="{{ extra_css }}" type="text/css">
1313
{% endif %}
14+
15+
{% if contexts_json %}
16+
<script type="text/javascript">
17+
contexts = {{ contexts_json }}
18+
</script>
19+
{% endif %}
20+
1421
<script type="text/javascript" src="coverage_html.js" defer></script>
1522
</head>
1623
<body class="pyfile">
@@ -117,11 +124,9 @@ <h2>
117124
{% endif %}
118125
</span>
119126
{# Things that should appear below the line. #}
120-
{% if line.context_list %}
127+
{% if line.context_str %}
121128
<span class="ctxs">
122-
{% for context in line.context_list %}
123-
<span>{{context}}</span>
124-
{% endfor %}
129+
{{ line.context_str }}
125130
</span>
126131
{% endif %}
127132
</p>

coverage/htmlfiles/style.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
258258

259259
@media (prefers-color-scheme: dark) { #source p label.ctx { color: #777; } }
260260

261-
#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #d0e8ff; border-radius: .25em; margin-right: 1.75em; }
261+
#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #d0e8ff; border-radius: .25em; margin-right: 1.75em; text-align: right; }
262262

263263
@media (prefers-color-scheme: dark) { #source p .ctxs { background: #056; } }
264264

coverage/htmlfiles/style.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ $border-indicator-width: .2em;
622622
@include background-dark($dark-context-bg-color);
623623
border-radius: .25em;
624624
margin-right: 1.75em;
625+
text-align: right;
625626
span {
626627
display: block;
627628
text-align: right;

tests/gold/html/contexts/two_tests_py.html

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
<title>Coverage for two_tests.py: 94%</title>
66
<link rel="icon" sizes="32x32" href="favicon_32.png">
77
<link rel="stylesheet" href="style.css" type="text/css">
8+
<script type="text/javascript">
9+
contexts = {
10+
"0": "(empty)",
11+
"1": "two_tests.test_two",
12+
"2": "two_tests.test_one"
13+
}
14+
</script>
815
<script type="text/javascript" src="coverage_html.js" defer></script>
916
</head>
1017
<body class="pyfile">
@@ -65,7 +72,7 @@ <h2>
6572
<a id="nextFileLink" class="nav" href="index.html">&#xbb; next</a>
6673
&nbsp; &nbsp; &nbsp;
6774
<a class="nav" href="https://coverage.readthedocs.io/en/7.2.3a0.dev1">coverage.py v7.2.3a0.dev1</a>,
68-
created at 2023-03-21 08:44 -0400
75+
created at 2023-03-22 16:13 +0100
6976
</p>
7077
<aside class="hidden">
7178
<button type="button" class="button_next_chunk" data-shortcut="j"/>
@@ -81,20 +88,20 @@ <h2>
8188
</header>
8289
<main id="source">
8390
<p class="run"><span class="n"><a id="t1" href="#t1">1</a></span><span class="t"><span class="key">def</span> <span class="nam">helper</span><span class="op">(</span><span class="nam">lineno</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"><label for="ctxs1" class="ctx">(empty)</label></span></p>
84-
<p class="run"><span class="n"><a id="t2" href="#t2">2</a></span><span class="t"> <span class="nam">x</span> <span class="op">=</span> <span class="num">2</span>&nbsp;</span><input type="checkbox" id="ctxs2" /><span class="r"><label for="ctxs2" class="ctx">3 ctx</label></span><span class="ctxs"><span>(empty)</span><span>two_tests.test_one</span><span>two_tests.test_two</span></span></p>
91+
<p class="run"><span class="n"><a id="t2" href="#t2">2</a></span><span class="t"> <span class="nam">x</span> <span class="op">=</span> <span class="num">2</span>&nbsp;</span><input type="checkbox" id="ctxs2" /><span class="r"><label for="ctxs2" class="ctx">3 ctx</label></span><span class="ctxs">0,2,1</span></p>
8592
<p class="pln"><span class="n"><a id="t3" href="#t3">3</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
8693
<p class="run"><span class="n"><a id="t4" href="#t4">4</a></span><span class="t"><span class="key">def</span> <span class="nam">test_one</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"><label for="ctxs4" class="ctx">(empty)</label></span></p>
87-
<p class="run"><span class="n"><a id="t5" href="#t5">5</a></span><span class="t"> <span class="nam">a</span> <span class="op">=</span> <span class="num">5</span>&nbsp;</span><input type="checkbox" id="ctxs5" /><span class="r"><label for="ctxs5" class="ctx">1 ctx</label></span><span class="ctxs"><span>two_tests.test_one</span></span></p>
88-
<p class="run"><span class="n"><a id="t6" href="#t6">6</a></span><span class="t"> <span class="nam">helper</span><span class="op">(</span><span class="num">6</span><span class="op">)</span>&nbsp;</span><input type="checkbox" id="ctxs6" /><span class="r"><label for="ctxs6" class="ctx">1 ctx</label></span><span class="ctxs"><span>two_tests.test_one</span></span></p>
94+
<p class="run"><span class="n"><a id="t5" href="#t5">5</a></span><span class="t"> <span class="nam">a</span> <span class="op">=</span> <span class="num">5</span>&nbsp;</span><input type="checkbox" id="ctxs5" /><span class="r"><label for="ctxs5" class="ctx">1 ctx</label></span><span class="ctxs">2</span></p>
95+
<p class="run"><span class="n"><a id="t6" href="#t6">6</a></span><span class="t"> <span class="nam">helper</span><span class="op">(</span><span class="num">6</span><span class="op">)</span>&nbsp;</span><input type="checkbox" id="ctxs6" /><span class="r"><label for="ctxs6" class="ctx">1 ctx</label></span><span class="ctxs">2</span></p>
8996
<p class="pln"><span class="n"><a id="t7" href="#t7">7</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
9097
<p class="run"><span class="n"><a id="t8" href="#t8">8</a></span><span class="t"><span class="key">def</span> <span class="nam">test_two</span><span class="op">(</span><span class="op">)</span><span class="op">:</span>&nbsp;</span><span class="r"><label for="ctxs8" class="ctx">(empty)</label></span></p>
91-
<p class="run"><span class="n"><a id="t9" href="#t9">9</a></span><span class="t"> <span class="nam">a</span> <span class="op">=</span> <span class="num">9</span>&nbsp;</span><input type="checkbox" id="ctxs9" /><span class="r"><label for="ctxs9" class="ctx">1 ctx</label></span><span class="ctxs"><span>two_tests.test_two</span></span></p>
92-
<p class="run"><span class="n"><a id="t10" href="#t10">10</a></span><span class="t"> <span class="nam">b</span> <span class="op">=</span> <span class="num">10</span>&nbsp;</span><input type="checkbox" id="ctxs10" /><span class="r"><label for="ctxs10" class="ctx">1 ctx</label></span><span class="ctxs"><span>two_tests.test_two</span></span></p>
93-
<p class="run"><span class="n"><a id="t11" href="#t11">11</a></span><span class="t"> <span class="key">if</span> <span class="nam">a</span> <span class="op">></span> <span class="num">11</span><span class="op">:</span>&nbsp;</span><input type="checkbox" id="ctxs11" /><span class="r"><label for="ctxs11" class="ctx">1 ctx</label></span><span class="ctxs"><span>two_tests.test_two</span></span></p>
98+
<p class="run"><span class="n"><a id="t9" href="#t9">9</a></span><span class="t"> <span class="nam">a</span> <span class="op">=</span> <span class="num">9</span>&nbsp;</span><input type="checkbox" id="ctxs9" /><span class="r"><label for="ctxs9" class="ctx">1 ctx</label></span><span class="ctxs">1</span></p>
99+
<p class="run"><span class="n"><a id="t10" href="#t10">10</a></span><span class="t"> <span class="nam">b</span> <span class="op">=</span> <span class="num">10</span>&nbsp;</span><input type="checkbox" id="ctxs10" /><span class="r"><label for="ctxs10" class="ctx">1 ctx</label></span><span class="ctxs">1</span></p>
100+
<p class="run"><span class="n"><a id="t11" href="#t11">11</a></span><span class="t"> <span class="key">if</span> <span class="nam">a</span> <span class="op">></span> <span class="num">11</span><span class="op">:</span>&nbsp;</span><input type="checkbox" id="ctxs11" /><span class="r"><label for="ctxs11" class="ctx">1 ctx</label></span><span class="ctxs">1</span></p>
94101
<p class="mis show_mis"><span class="n"><a id="t12" href="#t12">12</a></span><span class="t"> <span class="nam">b</span> <span class="op">=</span> <span class="num">12</span>&nbsp;</span><span class="r"></span></p>
95-
<p class="run"><span class="n"><a id="t13" href="#t13">13</a></span><span class="t"> <span class="key">assert</span> <span class="nam">a</span> <span class="op">==</span> <span class="op">(</span><span class="num">13</span><span class="op">-</span><span class="num">4</span><span class="op">)</span>&nbsp;</span><input type="checkbox" id="ctxs13" /><span class="r"><label for="ctxs13" class="ctx">1 ctx</label></span><span class="ctxs"><span>two_tests.test_two</span></span></p>
96-
<p class="run"><span class="n"><a id="t14" href="#t14">14</a></span><span class="t"> <span class="key">assert</span> <span class="nam">b</span> <span class="op">==</span> <span class="op">(</span><span class="num">14</span><span class="op">-</span><span class="num">4</span><span class="op">)</span>&nbsp;</span><input type="checkbox" id="ctxs14" /><span class="r"><label for="ctxs14" class="ctx">1 ctx</label></span><span class="ctxs"><span>two_tests.test_two</span></span></p>
97-
<p class="run"><span class="n"><a id="t15" href="#t15">15</a></span><span class="t"> <span class="nam">helper</span><span class="op">(</span>&nbsp;</span><input type="checkbox" id="ctxs15" /><span class="r"><label for="ctxs15" class="ctx">1 ctx</label></span><span class="ctxs"><span>two_tests.test_two</span></span></p>
102+
<p class="run"><span class="n"><a id="t13" href="#t13">13</a></span><span class="t"> <span class="key">assert</span> <span class="nam">a</span> <span class="op">==</span> <span class="op">(</span><span class="num">13</span><span class="op">-</span><span class="num">4</span><span class="op">)</span>&nbsp;</span><input type="checkbox" id="ctxs13" /><span class="r"><label for="ctxs13" class="ctx">1 ctx</label></span><span class="ctxs">1</span></p>
103+
<p class="run"><span class="n"><a id="t14" href="#t14">14</a></span><span class="t"> <span class="key">assert</span> <span class="nam">b</span> <span class="op">==</span> <span class="op">(</span><span class="num">14</span><span class="op">-</span><span class="num">4</span><span class="op">)</span>&nbsp;</span><input type="checkbox" id="ctxs14" /><span class="r"><label for="ctxs14" class="ctx">1 ctx</label></span><span class="ctxs">1</span></p>
104+
<p class="run"><span class="n"><a id="t15" href="#t15">15</a></span><span class="t"> <span class="nam">helper</span><span class="op">(</span>&nbsp;</span><input type="checkbox" id="ctxs15" /><span class="r"><label for="ctxs15" class="ctx">1 ctx</label></span><span class="ctxs">1</span></p>
98105
<p class="pln"><span class="n"><a id="t16" href="#t16">16</a></span><span class="t"> <span class="num">16</span>&nbsp;</span><span class="r"></span></p>
99106
<p class="pln"><span class="n"><a id="t17" href="#t17">17</a></span><span class="t"> <span class="op">)</span>&nbsp;</span><span class="r"></span></p>
100107
<p class="pln"><span class="n"><a id="t18" href="#t18">18</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
@@ -111,7 +118,7 @@ <h2>
111118
<a id="nextFileLink" class="nav" href="index.html">&#xbb; next</a>
112119
&nbsp; &nbsp; &nbsp;
113120
<a class="nav" href="https://coverage.readthedocs.io/en/7.2.3a0.dev1">coverage.py v7.2.3a0.dev1</a>,
114-
created at 2023-03-21 08:44 -0400
121+
created at 2023-03-22 16:13 +0100
115122
</p>
116123
</div>
117124
</footer>

tests/gold/html/styled/style.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
258258

259259
@media (prefers-color-scheme: dark) { #source p label.ctx { color: #777; } }
260260

261-
#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #d0e8ff; border-radius: .25em; margin-right: 1.75em; }
261+
#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #d0e8ff; border-radius: .25em; margin-right: 1.75em; text-align: right; }
262262

263263
@media (prefers-color-scheme: dark) { #source p .ctxs { background: #056; } }
264264

0 commit comments

Comments
 (0)