"""Tests for bin/check_docs.py — documentation CI rules.""" from __future__ import annotations import sys from pathlib import Path import pytest SCRIPTS = Path(__file__).resolve().parents[2] / "bin" sys.path.insert(0, str(SCRIPTS)) from check_docs import ( # noqa: E402 collect_anchors, run_checks, slug_heading, split_link_target, ) ROOT = Path(__file__).resolve().parents[2] GLOSSARY = ROOT / "docs/00-glossary.md" def test_slug_heading_matches_glossary_anchors() -> None: assert slug_heading("T0 — hot") == "t0--hot" assert slug_heading("T3 — warehouse") == "t3--warehouse" assert slug_heading("Source of truth") == "source-of-truth" assert slug_heading("Data & storage") == "data--storage" def test_glossary_term_anchors_exist() -> None: anchors = collect_anchors(GLOSSARY) for term in ( "t0--hot", "t1--warm", "t2--shared", "t3--warehouse", "t4--dev", "source-of-truth", "bulk-sync", "offload", ): assert term in anchors, f"missing glossary anchor #{term}" def test_split_link_target() -> None: assert split_link_target("foo.md#bar") == ("foo.md", "bar") assert split_link_target("foo.md") == ("foo.md", None) def test_repo_docs_pass() -> None: assert run_checks() == 0 def test_broken_link_detected(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: docs = tmp_path / "docs" docs.mkdir() (docs / "00-glossary.md").write_text("# Glossary\n\n## Data & storage\n") (docs / "bad.md").write_text("See [missing](missing.md).\n") rules = tmp_path / "bin" rules.mkdir() (rules / "docs_rules.yaml").write_text( "markdown_paths:\n - docs/**/*.md\n" "glossary:\n file: docs/00-glossary.md\n" "banned_link_targets: []\n" "glossary_section_anchors: []\n" "preferred_term_anchors: []\n" "readability:\n forbid_bare_see_refs: false\n" ) checker = SCRIPTS / "check_docs.py" monkeypatch.setattr("check_docs.ROOT", tmp_path) monkeypatch.setattr("check_docs.RULES_PATH", rules / "docs_rules.yaml") assert run_checks() == 1