Files
govoplan/tests/test_documentation_structure.py
T
zemion c66e1b768d
Dependency Audit / dependency-audit (push) Successful in 1m46s
Deployment Installer / deployment-installer (push) Successful in 9s
Security Audit / security-audit (push) Successful in 11m48s
docs: organize cross-product documentation
2026-08-17 16:52:51 +02:00

62 lines
2.2 KiB
Python

from __future__ import annotations
import re
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
DOCS = ROOT / "docs"
MARKDOWN_LINK = re.compile(
r"!?\[[^\n]*?\]\((?P<destination><[^>]+>|[^)\s]+)"
)
class DocumentationStructureTests(unittest.TestCase):
def test_documentation_root_has_one_human_entry_point(self) -> None:
self.assertEqual(
[path.name for path in sorted(DOCS.glob("*.md"))],
["README.md"],
)
def test_documentation_front_doors_exist(self) -> None:
expected = (
DOCS / "strategy" / "PLATFORM_CORE_IDEAS.md",
DOCS / "strategy" / "ROADMAP.md",
DOCS / "strategy" / "STRATEGY_STATUS.md",
DOCS / "strategy" / "REFERENCE_JOURNEY_PROGRAM.md",
)
self.assertFalse([path for path in expected if not path.is_file()])
def test_local_markdown_links_resolve(self) -> None:
broken: list[str] = []
sources = [ROOT / "README.md", *sorted(DOCS.rglob("*.md"))]
for source in sources:
for line_number, line in enumerate(
source.read_text(encoding="utf-8").splitlines(),
start=1,
):
for match in MARKDOWN_LINK.finditer(line):
destination = match.group("destination")
if destination.startswith("<") and destination.endswith(">"):
destination = destination[1:-1]
path_text = destination.split("#", 1)[0]
if (
not path_text
or path_text.startswith(("/", "mailto:", "data:"))
or "://" in path_text
):
continue
target = (source.parent / path_text).resolve()
if not target.is_relative_to(ROOT):
continue
if not target.exists():
broken.append(
f"{source.relative_to(ROOT)}:{line_number}: {destination}"
)
self.assertEqual(broken, [])
if __name__ == "__main__":
unittest.main()