Skip to content

Commit 657c0b2

Browse files
committed
test(html-reader): guard the bold-lead-in list rendering with real pandoc
The reason 640 collapsed lists shipped green is that no test exercised real markdown->HTML rendering — the existing build_html_reader tests stub pandoc with a fake, covering TOC/mermaid plumbing but never the markdown parse. This feeds the exact bold-lead-in pattern through the real pandoc invocation the reader uses and asserts the list survives as <ul>. Proven both ways: passes with the extension, fails when it is removed.
1 parent 7391bf9 commit 657c0b2

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

tests/test_html_list_rendering.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""Regression: the HTML reader must not collapse bold-lead-in lists into a paragraph.
2+
3+
The book style writes a bold label immediately followed by a list, with no blank
4+
line between them:
5+
6+
**触发分离的条件**:
7+
- 输入序列长度 > 某阈值
8+
9+
Strict CommonMark (pandoc's default `-f markdown`) requires a blank line before a
10+
list, so it folds all three bullets into one <p>. build_html_reader.py therefore
11+
must pass `markdown+lists_without_preceding_blankline`. This test feeds that exact
12+
pattern through the *real* pandoc invocation the reader uses and asserts the list
13+
survives — the check that would have caught the 640 collapsed lists that shipped.
14+
"""
15+
16+
import re
17+
import shutil
18+
import subprocess
19+
import unittest
20+
from pathlib import Path
21+
22+
ROOT = Path(__file__).resolve().parents[1]
23+
READER = ROOT / "tools" / "build_html_reader.py"
24+
25+
# The pattern the book uses everywhere: bold lead-in, then a list, no blank line.
26+
SAMPLE = "**触发分离的条件**:\n- 输入序列长度 > 某阈值\n- 输入序列未命中前缀缓存\n"
27+
28+
29+
def _reader_pandoc_format() -> str:
30+
"""Extract the pandoc `-f` value the reader uses, across every fork shape.
31+
32+
Forks differ: an inline "-f", "markdown..." literal, a `reader = "markdown..."`
33+
variable, a `context="markdown..."` kwarg, or a PANDOC_MARKDOWN_READER constant
34+
living in tools/publication_sources.py (possibly as an implicitly-joined
35+
multiline string). Search both files and stitch adjacent string fragments.
36+
"""
37+
texts = [READER.read_text(encoding="utf-8")]
38+
sources = READER.parent / "publication_sources.py"
39+
if sources.is_file():
40+
texts.append(sources.read_text(encoding="utf-8"))
41+
for src in texts:
42+
for pat in (
43+
r'"-f",\s*"(markdown[^"]*)"',
44+
r'reader\s*=\s*"(markdown[^"]*)"',
45+
r'context="(markdown[^"]*)"',
46+
# constant, one or more adjacent "..." fragments (implicit join)
47+
r'PANDOC_MARKDOWN_READER\s*=\s*\(?\s*((?:"[^"]*"\s*)+)\)?',
48+
):
49+
m = re.search(pat, src)
50+
if m:
51+
raw = m.group(1)
52+
# collapse implicit string concatenation into one value
53+
return "".join(re.findall(r'"([^"]*)"', raw)) or raw
54+
raise AssertionError("could not find the reader's pandoc -f markdown format")
55+
56+
57+
class HtmlListRenderingTests(unittest.TestCase):
58+
def test_reader_declares_the_no_blank_line_list_extension(self):
59+
fmt = _reader_pandoc_format()
60+
self.assertIn(
61+
"lists_without_preceding_blankline",
62+
fmt,
63+
"build_html_reader.py must enable lists_without_preceding_blankline; "
64+
f"pandoc format is currently {fmt!r}. Without it, every bold-lead-in "
65+
"list in the book collapses into a paragraph in the shipped HTML.",
66+
)
67+
68+
def test_bold_lead_in_list_renders_as_ul_under_real_pandoc(self):
69+
pandoc = shutil.which("pandoc")
70+
if pandoc is None:
71+
self.skipTest("pandoc not installed; CI installs it and runs this check")
72+
fmt = _reader_pandoc_format()
73+
out = subprocess.run(
74+
[pandoc, "-f", fmt, "-t", "html5"],
75+
input=SAMPLE,
76+
capture_output=True,
77+
text=True,
78+
check=True,
79+
).stdout
80+
self.assertIn("<ul>", out, f"list collapsed; pandoc -f {fmt} produced:\n{out}")
81+
self.assertEqual(out.count("<li>"), 2, f"expected 2 <li>; got:\n{out}")
82+
83+
84+
if __name__ == "__main__":
85+
unittest.main()

0 commit comments

Comments
 (0)