from __future__ import annotations import importlib.util from pathlib import Path def _load_module(): script_path = Path(__file__).resolve().parents[1] / "scripts" / "validate_docs_sync.py" spec = importlib.util.spec_from_file_location("validate_docs_sync", script_path) assert spec is not None assert spec.loader is not None module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module def test_collect_command_endpoints_parses_markdown_table_rows() -> None: module = _load_module() text = "\n".join( [ "| Endpoint | Description |", "|----------|-------------|", "| `GET /api/status` | status |", "| `POST /api/run` | run |", "| not-a-row | ignored |", ] ) endpoints = module.collect_command_endpoints(text) assert endpoints == ["GET /api/status", "POST /api/run"] def test_validate_links_resolve_detects_absolute_and_broken_links(tmp_path) -> None: module = _load_module() doc = tmp_path / "doc.md" existing = tmp_path / "ok.md" existing.write_text("# ok\n", encoding="utf-8") doc.write_text( "\n".join( [ "[ok](./ok.md)", "[abs](/tmp/nowhere.md)", "[broken](./missing.md)", ] ), encoding="utf-8", ) errors: list[str] = [] module.validate_links_resolve(doc, doc.read_text(encoding="utf-8"), errors) assert any("absolute link is forbidden" in err for err in errors) assert any("broken link" in err for err in errors) def test_validate_summary_docs_reference_core_docs(monkeypatch) -> None: module = _load_module() errors: list[str] = [] fake_docs = { str(module.REQUIRED_FILES["README.md"]): ( "docs/workflow.md docs/commands.md docs/testing.md" ), str(module.REQUIRED_FILES["CLAUDE.md"]): "docs/workflow.md docs/commands.md", } def fake_read(path: Path) -> str: return fake_docs[str(path)] monkeypatch.setattr(module, "_read", fake_read) module.validate_summary_docs_reference_core_docs(errors) assert errors == [] def test_validate_commands_endpoint_duplicates_reports_duplicates(monkeypatch) -> None: module = _load_module() errors: list[str] = [] text = "\n".join( [ "| `GET /api/status` | status |", "| `GET /api/status` | duplicate |", ] ) def fake_read(path: Path) -> str: assert path == module.REQUIRED_FILES["commands"] return text monkeypatch.setattr(module, "_read", fake_read) module.validate_commands_endpoint_duplicates(errors) assert errors assert "duplicated API endpoint row -> GET /api/status" in errors[0] def test_validate_testing_doc_has_dynamic_count_guidance(monkeypatch) -> None: module = _load_module() errors: list[str] = [] def fake_read(path: Path) -> str: assert path == module.REQUIRED_FILES["testing"] return "Use pytest --collect-only -q for dynamic counts." monkeypatch.setattr(module, "_read", fake_read) module.validate_testing_doc_has_dynamic_count_guidance(errors) assert errors == []