100 lines
2.9 KiB
Python
100 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate Typst tables of unit tests for chapter 5."""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from collections import defaultdict
|
|
from pathlib import Path
|
|
|
|
|
|
def typst_escape(s: str) -> str:
|
|
return s.replace("\\", "\\\\").replace("`", "\\`")
|
|
|
|
|
|
def emit_table(
|
|
lines: list[str],
|
|
caption: str,
|
|
ncol: int,
|
|
headers: list[str],
|
|
data_rows: list[list[str]],
|
|
label: str,
|
|
) -> None:
|
|
lines.append("#pz-test-table(\n")
|
|
lines.append(f" [{caption}],\n")
|
|
lines.append(f" {ncol},\n")
|
|
lines.append(" table.header(\n")
|
|
for h in headers:
|
|
lines.append(f" [{typst_escape(h)}],\n")
|
|
lines.append(" ),\n")
|
|
for row in data_rows:
|
|
cells = ", ".join(f"[{typst_escape(c)}]" for c in row)
|
|
lines.append(f" {cells},\n")
|
|
lines.append(f") <{label}>\n\n")
|
|
|
|
|
|
def main() -> None:
|
|
root = Path(__file__).resolve().parents[2]
|
|
out = Path(__file__).resolve().parents[1] / "includes" / "ch05-tests-generated.typ"
|
|
rows: list[tuple[str, str, str, str]] = []
|
|
|
|
for p in sorted(root.rglob("*.kt")):
|
|
if "/src/test/" not in p.as_posix():
|
|
continue
|
|
text = p.read_text(encoding="utf-8", errors="replace")
|
|
cls_m = re.search(r"class\s+(\w+)", text)
|
|
if not cls_m:
|
|
continue
|
|
cls = cls_m.group(1)
|
|
mod = p.parts[p.parts.index("src") - 1]
|
|
rel = p.relative_to(root).as_posix()
|
|
for m in re.finditer(r"@Test[\s\S]*?fun\s+(?:`([^`]+)`|(\w+))\s*\(", text):
|
|
name = m.group(1) or m.group(2)
|
|
rows.append((mod, cls, name, rel))
|
|
|
|
by_mod: dict[str, list] = defaultdict(list)
|
|
for mod, cls, name, rel in rows:
|
|
by_mod[mod].append((cls, name, rel))
|
|
|
|
lines = [
|
|
"// AUTO-GENERATED by gen_test_tables.py — include from ch05.typ\n",
|
|
'#import "common.typ": pz-test-table\n\n',
|
|
]
|
|
|
|
summary_rows = []
|
|
for mod in sorted(by_mod):
|
|
for cls, name, rel in by_mod[mod]:
|
|
short = rel.split("/")[-1]
|
|
summary_rows.append([mod, cls, name, short])
|
|
|
|
emit_table(
|
|
lines,
|
|
"Сводка модульных unit-тестов (src/test)",
|
|
4,
|
|
["Модуль", "Класс", "Метод", "Файл"],
|
|
summary_rows,
|
|
"tbl-unit-all",
|
|
)
|
|
|
|
for mod in sorted(by_mod):
|
|
safe = mod.replace("-", "_")
|
|
lines.append(f"=== Реестр тестов модуля :{mod}\n\n")
|
|
mod_rows = [
|
|
[cls, name, rel.split("/")[-1]]
|
|
for cls, name, rel in by_mod[mod]
|
|
]
|
|
emit_table(
|
|
lines,
|
|
f"Unit-тесты модуля :{mod}",
|
|
3,
|
|
["Класс", "Метод", "Файл"],
|
|
mod_rows,
|
|
f"tbl-unit-{safe}",
|
|
)
|
|
|
|
out.write_text("".join(lines), encoding="utf-8")
|
|
print(f"Wrote {out} ({len(rows)} tests)", flush=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|