Skip to content

Commit 7595d8f

Browse files
committed
test: assert hljs dark-theme URL+hash stay aligned across html and js
Per review feedback on PR #20 — vs2015.min.css URL and SRI hash live in both static/index.html (initial load) and static/js/app.js (HLJS_THEME_SHEETS.dark, runtime swap). On a highlight.js version bump both must update together; the cross-referenced comments warn about it but couldn't enforce it. This test extracts the href + integrity from each file and asserts both pairs match, turning the drift hazard into a checked invariant.
1 parent 1f3cc09 commit 7595d8f

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""Regression test for highlight.js theme URL+hash drift between
2+
static/index.html (initial load) and static/js/app.js (runtime swap).
3+
4+
Both files carry the dark-theme stylesheet URL and its SRI hash. On a
5+
highlight.js version bump both must update together — if they drift, either
6+
the initial load breaks (HTML stale, mismatched hash) or the runtime theme
7+
swap breaks (JS stale). This test fails fast when they diverge so the
8+
"MUST also swap the integrity attribute" comments in both files become a
9+
checked invariant rather than a hope.
10+
"""
11+
12+
from __future__ import annotations
13+
14+
import re
15+
from pathlib import Path
16+
17+
REPO_ROOT = Path(__file__).resolve().parent.parent
18+
INDEX_HTML = REPO_ROOT / "static" / "index.html"
19+
APP_JS = REPO_ROOT / "static" / "js" / "app.js"
20+
21+
22+
def _link_attr(html: str, link_id: str, attr: str) -> str:
23+
"""Return the value of `attr` on the <link> tag with id=`link_id`."""
24+
tag_re = re.compile(
25+
r'<link\b[^>]*\bid\s*=\s*"' + re.escape(link_id) + r'"[^>]*>',
26+
re.DOTALL,
27+
)
28+
m = tag_re.search(html)
29+
assert m, f'No <link id="{link_id}"> found in index.html'
30+
attr_m = re.search(re.escape(attr) + r'\s*=\s*"([^"]*)"', m.group(0))
31+
assert attr_m, f'<link id="{link_id}"> has no {attr!r} attribute'
32+
return attr_m.group(1)
33+
34+
35+
def _js_theme_entry(js: str, theme: str) -> dict:
36+
"""Return {'href': ..., 'integrity': ...} from HLJS_THEME_SHEETS.<theme>."""
37+
block = re.search(re.escape(theme) + r"\s*:\s*\{([^}]*)\}", js, re.DOTALL)
38+
assert block, f"HLJS_THEME_SHEETS.{theme} entry not found in app.js"
39+
body = block.group(1)
40+
out = {}
41+
for key in ("href", "integrity"):
42+
m = re.search(key + r"\s*:\s*['\"]([^'\"]+)['\"]", body)
43+
assert m, f"HLJS_THEME_SHEETS.{theme} has no {key!r} key"
44+
out[key] = m.group(1)
45+
return out
46+
47+
48+
def test_dark_theme_url_and_hash_match_between_html_and_js():
49+
html = INDEX_HTML.read_text(encoding="utf-8")
50+
js = APP_JS.read_text(encoding="utf-8")
51+
52+
html_href = _link_attr(html, "hljs-theme", "href")
53+
html_integrity = _link_attr(html, "hljs-theme", "integrity")
54+
js_dark = _js_theme_entry(js, "dark")
55+
56+
assert html_href == js_dark["href"], (
57+
"highlight.js theme URL drifted between index.html and app.js — "
58+
f"html={html_href!r}, app.js HLJS_THEME_SHEETS.dark={js_dark['href']!r}. "
59+
"On a version bump both must update together (issue #19)."
60+
)
61+
assert html_integrity == js_dark["integrity"], (
62+
"highlight.js theme SRI hash drifted between index.html and app.js — "
63+
f"html={html_integrity!r}, "
64+
f"app.js HLJS_THEME_SHEETS.dark={js_dark['integrity']!r}."
65+
)

0 commit comments

Comments
 (0)