Skip to content

Commit a8acbcf

Browse files
authored
Merge branch 'master' into sigterm-bug
2 parents 77c62d9 + acd1e03 commit a8acbcf

File tree

7 files changed

+131
-77
lines changed

7 files changed

+131
-77
lines changed

.git-blame-ignore-revs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ bf6c12f5da54db7c5c0cc47cbf22c70f686e8236
99
# 2023-03-22 style: use double-quotes
1010
16abd82b6e87753184e8308c4b2606ff3979f8d3
1111
b7be64538aa480fce641349d3053e9a84862d571
12+
13+
# 2023-04-01 style: use double-quotes in JavaScript
14+
b03ab92bae24c54f1d5a98baa3af6b9a18de4d36

coverage/html.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77

88
import collections
99
import datetime
10+
import functools
1011
import json
1112
import os
1213
import re
1314
import shutil
15+
import string # pylint: disable=deprecated-module
1416

1517
from dataclasses import dataclass
1618
from typing import Any, Dict, Iterable, List, Optional, Tuple, TYPE_CHECKING, cast
@@ -187,6 +189,21 @@ def __init__(self, fr: FileReporter, analysis: Analysis) -> None:
187189
self.html_filename = self.rootname + ".html"
188190

189191

192+
HTML_SAFE = string.ascii_letters + string.digits + "!#$%'()*+,-./:;=?@[]^_`{|}~"
193+
194+
@functools.lru_cache(maxsize=None)
195+
def encode_int(n: int) -> str:
196+
"""Create a short HTML-safe string from an integer, using HTML_SAFE."""
197+
if n == 0:
198+
return HTML_SAFE[0]
199+
200+
r = []
201+
while n:
202+
n, t = divmod(n, len(HTML_SAFE))
203+
r.append(HTML_SAFE[t])
204+
return "".join(r)
205+
206+
190207
class HtmlReporter:
191208
"""HTML reporting."""
192209

@@ -373,7 +390,10 @@ def write_html_file(self, ftr: FileToReport, prev_html: str, next_html: str) ->
373390
contexts = collections.Counter(c for cline in file_data.lines for c in cline.contexts)
374391
context_codes = {y: i for (i, y) in enumerate(x[0] for x in contexts.most_common())}
375392
if context_codes:
376-
contexts_json = json.dumps({v: k for (k, v) in context_codes.items()}, indent=2)
393+
contexts_json = json.dumps(
394+
{encode_int(v): k for (k, v) in context_codes.items()},
395+
indent=2,
396+
)
377397
else:
378398
contexts_json = None
379399

@@ -387,9 +407,17 @@ def write_html_file(self, ftr: FileToReport, prev_html: str, next_html: str) ->
387407
tok_html = escape(tok_text) or " "
388408
html_parts.append(f'<span class="{tok_type}">{tok_html}</span>')
389409
ldata.html = "".join(html_parts)
390-
ldata.context_str = ",".join(
391-
str(context_codes[c_context]) for c_context in ldata.context_list
392-
)
410+
if ldata.context_list:
411+
encoded_contexts = [
412+
encode_int(context_codes[c_context]) for c_context in ldata.context_list
413+
]
414+
code_width = max(len(ec) for ec in encoded_contexts)
415+
ldata.context_str = (
416+
str(code_width)
417+
+ "".join(ec.ljust(code_width) for ec in encoded_contexts)
418+
)
419+
else:
420+
ldata.context_str = ""
393421

394422
if ldata.short_annotations:
395423
# 202F is NARROW NO-BREAK SPACE.

coverage/htmlfiles/coverage_html.js

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,9 @@ 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-
220215
// If we're directed to a particular line number, highlight the line.
221216
var frag = location.hash;
222-
if (frag.length > 2 && frag[1] === 't') {
217+
if (frag.length > 2 && frag[1] === "t") {
223218
document.querySelector(frag).closest(".n").classList.add("highlight");
224219
coverage.set_sel(parseInt(frag.substr(2), 10));
225220
} else {
@@ -262,6 +257,10 @@ coverage.pyfile_ready = function () {
262257
coverage.init_scroll_markers();
263258
coverage.wire_up_sticky_header();
264259

260+
document.querySelectorAll("[id^=ctxs]").forEach(
261+
cbox => cbox.addEventListener("click", coverage.expand_contexts)
262+
);
263+
265264
// Rebuild scroll markers when the window height changes.
266265
window.addEventListener("resize", coverage.build_scroll_markers);
267266
};
@@ -533,14 +532,14 @@ coverage.scroll_window = function (to_pos) {
533532

534533
coverage.init_scroll_markers = function () {
535534
// Init some variables
536-
coverage.lines_len = document.querySelectorAll('#source > p').length;
535+
coverage.lines_len = document.querySelectorAll("#source > p").length;
537536

538537
// Build html
539538
coverage.build_scroll_markers();
540539
};
541540

542541
coverage.build_scroll_markers = function () {
543-
const temp_scroll_marker = document.getElementById('scroll_marker')
542+
const temp_scroll_marker = document.getElementById("scroll_marker")
544543
if (temp_scroll_marker) temp_scroll_marker.remove();
545544
// Don't build markers if the window has no scroll bar.
546545
if (document.body.scrollHeight <= window.innerHeight) {
@@ -554,8 +553,8 @@ coverage.build_scroll_markers = function () {
554553

555554
const scroll_marker = document.createElement("div");
556555
scroll_marker.id = "scroll_marker";
557-
document.getElementById('source').querySelectorAll(
558-
'p.show_run, p.show_mis, p.show_exc, p.show_exc, p.show_par'
556+
document.getElementById("source").querySelectorAll(
557+
"p.show_run, p.show_mis, p.show_exc, p.show_exc, p.show_par"
559558
).forEach(element => {
560559
const line_top = Math.floor(element.offsetTop * marker_scale);
561560
const line_number = parseInt(element.querySelector(".n a").id.substr(1));
@@ -582,35 +581,37 @@ coverage.build_scroll_markers = function () {
582581
};
583582

584583
coverage.wire_up_sticky_header = function () {
585-
const header = document.querySelector('header');
584+
const header = document.querySelector("header");
586585
const header_bottom = (
587-
header.querySelector('.content h2').getBoundingClientRect().top -
586+
header.querySelector(".content h2").getBoundingClientRect().top -
588587
header.getBoundingClientRect().top
589588
);
590589

591590
function updateHeader() {
592591
if (window.scrollY > header_bottom) {
593-
header.classList.add('sticky');
592+
header.classList.add("sticky");
594593
} else {
595-
header.classList.remove('sticky');
594+
header.classList.remove("sticky");
596595
}
597596
}
598597

599-
window.addEventListener('scroll', updateHeader);
598+
window.addEventListener("scroll", updateHeader);
600599
updateHeader();
601600
};
602601

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-
span.textContent = "";
609-
span_text.split(",").forEach(function(s) {
610-
ctx = contexts[s];
611-
span.appendChild(document.createTextNode(ctx));
612-
span.appendChild(document.createElement("br"));
613-
})
602+
coverage.expand_contexts = function (e) {
603+
var ctxs = e.target.parentNode.querySelector(".ctxs");
604+
605+
if (!ctxs.classList.contains("expanded")) {
606+
var ctxs_text = ctxs.textContent;
607+
var width = Number(ctxs_text[0]);
608+
ctxs.textContent = "";
609+
for (var i = 1; i < ctxs_text.length; i += width) {
610+
key = ctxs_text.substring(i, i + width).trim();
611+
ctxs.appendChild(document.createTextNode(contexts[key]));
612+
ctxs.appendChild(document.createElement("br"));
613+
}
614+
ctxs.classList.add("expanded");
614615
}
615616
};
616617

@@ -620,5 +621,4 @@ document.addEventListener("DOMContentLoaded", () => {
620621
} else {
621622
coverage.pyfile_ready();
622623
}
623-
624624
});

tests/gold/README.rst

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,22 @@ current output of the tests into the gold files. When a test fails, the actual
1212
output is in the tests/actual directory. Those files are ignored by git.
1313

1414
There's a Makefile in the html directory for working with gold files and their
15-
associated support files. If actual outputs have changed so that comparisons
16-
are failing, but the new output is correct, you can use "make update-gold" to
17-
copy the actual output as the new gold files.
15+
associated support files.
16+
17+
To view the tests/actual files, you need to tentatively copy them to the gold
18+
directories, and then add the supporting files so they can be viewed as
19+
complete output. For example::
20+
21+
cp tests/actual/html/contexts/* tests/gold/html/contexts
22+
cd tests/actual/html
23+
make complete
24+
25+
If the new actual output is correct, you can use "make update-gold" to copy the
26+
actual output as the new gold files.
27+
28+
If you have changed some of the supporting files (.css or .js), then "make
29+
update-support" will copy the updated files to the tests/gold/html/support
30+
directory for checking test output.
1831

1932
If you have added a gold test, you'll need to manually copy the tests/actual
2033
files to tests/gold.
@@ -27,8 +40,9 @@ again, you can run just the failed tests again with::
2740
The saved HTML files in the html directories can't be viewed properly without
2841
the supporting CSS and Javascript files. But we don't want to save copies of
2942
those files in every subdirectory. The make target "make complete" in
30-
tests/gold/html will copy the support file so you can open the HTML files to
31-
see how they look.
43+
tests/gold/html will copy the support files so you can open the HTML files to
44+
see how they look. When you are done checking the output, you can use "make
45+
clean" to remove the support files from the gold directories.
3246

3347
If the output files are correct, you can update the gold files with "make
3448
update-gold". If there are version-specific gold files (for example,

tests/gold/html/contexts/two_tests_py.html

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
<link rel="stylesheet" href="style.css" type="text/css">
88
<script type="text/javascript">
99
contexts = {
10-
"0": "(empty)",
11-
"1": "two_tests.test_two",
12-
"2": "two_tests.test_one"
10+
"a": "(empty)",
11+
"b": "two_tests.test_two",
12+
"c": "two_tests.test_one"
1313
}
1414
</script>
1515
<script type="text/javascript" src="coverage_html.js" defer></script>
@@ -72,7 +72,7 @@ <h2>
7272
<a id="nextFileLink" class="nav" href="index.html">&#xbb; next</a>
7373
&nbsp; &nbsp; &nbsp;
7474
<a class="nav" href="https://coverage.readthedocs.io/en/7.2.3a0.dev1">coverage.py v7.2.3a0.dev1</a>,
75-
created at 2023-03-22 13:16 -0400
75+
created at 2023-04-01 08:30 -0400
7676
</p>
7777
<aside class="hidden">
7878
<button type="button" class="button_next_chunk" data-shortcut="j"/>
@@ -88,20 +88,20 @@ <h2>
8888
</header>
8989
<main id="source">
9090
<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>
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>
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">1acb</span></p>
9292
<p class="pln"><span class="n"><a id="t3" href="#t3">3</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
9393
<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>
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>
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">1c</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">1c</span></p>
9696
<p class="pln"><span class="n"><a id="t7" href="#t7">7</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
9797
<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>
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>
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">1b</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">1b</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">1b</span></p>
101101
<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>
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>
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">1b</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">1b</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">1b</span></p>
105105
<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>
106106
<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>
107107
<p class="pln"><span class="n"><a id="t18" href="#t18">18</a></span><span class="t">&nbsp;</span><span class="r"></span></p>
@@ -118,7 +118,7 @@ <h2>
118118
<a id="nextFileLink" class="nav" href="index.html">&#xbb; next</a>
119119
&nbsp; &nbsp; &nbsp;
120120
<a class="nav" href="https://coverage.readthedocs.io/en/7.2.3a0.dev1">coverage.py v7.2.3a0.dev1</a>,
121-
created at 2023-03-22 13:16 -0400
121+
created at 2023-04-01 08:30 -0400
122122
</p>
123123
</div>
124124
</footer>

0 commit comments

Comments
 (0)