"""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))