Files
Wallenc/Report/scripts/gen_test_tables.py

119 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Generate a single Typst unit-test table for chapter 5."""
from __future__ import annotations
import re
from pathlib import Path
try:
import yaml
except ImportError:
yaml = None # type: ignore
def typst_escape(s: str) -> str:
return s.replace("\\", "\\\\").replace("`", "\\`")
def load_overrides(script_dir: Path) -> dict[str, str]:
path = script_dir / "test_descriptions.yaml"
if not path.is_file() or yaml is None:
return {}
data = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
return {str(k): str(v) for k, v in data.items()}
def _split_camel(name: str) -> list[str]:
parts: list[str] = []
buf: list[str] = []
for ch in name:
if ch.isupper() and buf and buf[-1].islower():
parts.append("".join(buf))
buf = [ch]
else:
buf.append(ch)
if buf:
parts.append("".join(buf))
return parts
def describe_method(name: str, overrides: dict[str, str]) -> str:
if name in overrides:
return overrides[name]
low = name.lower()
if "encryption" in low and "wrong" in low:
return "дешифрование с неверным ключом завершается ошибкой"
if "encryption" in low and "same" in low:
return "симметрия шифрования и дешифрования при верном ключе"
if "correct key" in low:
return "верный ключ проходит проверку checkKey"
if "incorrect key" in low:
return "неверный ключ не проходит проверку checkKey"
if name.startswith("maps"):
return "исключение преобразуется в типизированную ошибку Wallenc"
if name.startswith("syncGroup"):
rest = _split_camel(name[9:])
return "синхронизация группы: " + " ".join(w.lower() for w in rest)
if name.startswith("sync"):
return "сценарий синхронизации: " + " ".join(w.lower() for w in _split_camel(name[4:]))
if "Totp" in name or "totp" in name or "Otp" in name or "otp" in name:
return "корректность TOTP/OTP: " + " ".join(w.lower() for w in _split_camel(name))
if name.endswith("Works") or "Crud" in name:
return "CRUD-операции и сохранение данных"
if "parses" in low or "rejects" in low:
return "разбор и валидация входных данных"
if "Route" in name or "Intent" in name or "mapsTo" in name:
return "маршрутизация, deep link или подписи UI"
if "enqueue" in low or "cancel" in low or "fail" in low or "progress" in low:
return "жизненный цикл фоновой задачи"
words = _split_camel(name)
return " ".join(w.lower() for w in words)
def main() -> None:
root = Path(__file__).resolve().parents[2]
script_dir = Path(__file__).resolve().parent
out = Path(__file__).resolve().parents[1] / "includes" / "ch05-tests-generated.typ"
overrides = load_overrides(script_dir)
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")
mod = p.parts[p.parts.index("src") - 1]
for m in re.finditer(r"@Test[\s\S]*?fun\s+(?:`([^`]+)`|(\w+))\s*\(", text):
name = m.group(1) or m.group(2)
desc = describe_method(name, overrides)
rows.append((mod, name, desc))
rows.sort(key=lambda r: (r[0], r[1]))
lines = [
"// AUTO-GENERATED by gen_test_tables.py — include from ch05.typ\n",
'#import "common.typ": pz-test-table\n\n',
]
data_rows = []
for i, (mod, name, desc) in enumerate(rows, start=1):
data_rows.append([str(i), mod, name, desc])
lines.append("#pz-test-table(\n")
lines.append(" [Реестр модульных unit-тестов],\n")
lines.append(" 4,\n")
lines.append(" table.header(\n")
for h in ["", "Модуль", "Метод", "Проверяемое поведение"]:
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(") <tbl-unit-all>\n\n")
out.write_text("".join(lines), encoding="utf-8")
print(f"Wrote {out} ({len(rows)} tests)", flush=True)
if __name__ == "__main__":
main()