diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-18 20:28:09 +0200 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-18 20:28:09 +0200 |
| commit | 2071e2beda763137416ac386d4bb953711ec995d (patch) | |
| tree | bdcf840cb457f8286c1d967410f98972eb99b50a /tools/tests/test_check_docs.py | |
| parent | a9b1dc8bd9354973eabd72f56d82b2eab6f48d56 (diff) | |
test(tools): add test-log judge, docs and policy checks with tests
- ciq_test_report.py: decides pass/fail from Run No Evil output instead
of monkeydo's unreliable exit code; writes JUnit XML.
- check_docs.py: offline check of relative links and GitHub anchors.
- lint_project.py: project rules (headers, no logging outside Diag,
no secret-like literals, no network APIs or permissions).
- check_budgets.py with budgets.json: perf and memory gates.
- make_icon.py: reproducible launcher icon.
- 31 pytest tests, including Hypothesis fuzzing of the log parser and
integration checks against the real docs and sources; ruff and mypy
(strict) clean.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tools/tests/test_check_docs.py')
| -rw-r--r-- | tools/tests/test_check_docs.py | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/tools/tests/test_check_docs.py b/tools/tests/test_check_docs.py new file mode 100644 index 0000000..67404c9 --- /dev/null +++ b/tools/tests/test_check_docs.py @@ -0,0 +1,68 @@ +"""Tests for tools/check_docs.py, the offline Markdown link checker.""" + +from __future__ import annotations + +import re +from pathlib import Path + +import check_docs as cd +import pytest +from conftest import PROJECT_ROOT +from hypothesis import given +from hypothesis import strategies as st + + +@pytest.mark.parametrize( + ("heading", "anchor"), + [ + ("12.4 How each symbology is proven scannable", "124-how-each-symbology-is-proven-scannable"), + ("3e. Writing values back: unknown", "3e-writing-values-back-unknown"), + ("1. Scope", "1-scope"), + ("`make sim` and noVNC", "make-sim-and-novnc"), + ("A — B", "a--b"), + ("[Link](x.md) text", "link-text"), + ], +) +def test_slugify_matches_github(heading: str, anchor: str) -> None: + assert cd.slugify(heading) == anchor + + +@given(st.text()) +def test_slugify_output_is_anchor_safe(heading: str) -> None: + assert re.fullmatch(r"[\w\-]*", cd.slugify(heading)) + + +def write(tmp_path: Path, name: str, text: str) -> Path: + path = tmp_path / name + path.write_text(text, encoding="utf-8") + return path + + +def test_repeated_headings_get_numbered_anchors(tmp_path: Path) -> None: + doc = write(tmp_path, "a.md", "# Notes\n\n## Notes\n\n```\n# not a heading\n```\n") + assert cd.anchors_of(doc) == {"notes", "notes-1"} + + +def test_broken_links_are_reported(tmp_path: Path) -> None: + write(tmp_path, "other.md", "# Present\n") + doc = write( + tmp_path, + "a.md", + "# Top\n" + "[ok](#top) [ok2](other.md#present) [web](https://example.com/x)\n" + "[missing file](nope.md)\n" + "[missing anchor](other.md#absent)\n" + "`[inline code](ignored.md)`\n" + "```\n[fenced](ignored.md)\n```\n", + ) + problems = cd.check_file(doc, tmp_path, {}) + assert [(p.line, p.message) for p in problems] == [ + (3, "missing file 'nope.md'"), + (4, "no heading for anchor '#absent' in other.md"), + ] + + +def test_project_docs_have_no_broken_links() -> None: + cache: dict[Path, set[str]] = {} + problems = [p for f in cd.markdown_files(PROJECT_ROOT) for p in cd.check_file(f, PROJECT_ROOT, cache)] + assert problems == [], "\n".join(map(str, problems)) |
