|
| 1 | +import pytest |
| 2 | +import sys |
| 3 | +import re |
| 4 | +from pathlib import Path |
| 5 | + |
| 6 | +_CURRENT_DIR = ( |
| 7 | + Path(sys.argv[0] if __name__ == "__main__" else __file__).resolve().parent |
| 8 | +) |
| 9 | +_REPO_DIR = _CURRENT_DIR.parent.parent.parent |
| 10 | +_DOCS_DIR = _REPO_DIR / "docs" |
| 11 | + |
| 12 | +assert _DOCS_DIR.exists |
| 13 | + |
| 14 | +_MD_LINK_PATTERN = re.compile(r"\[(.*?)\]\((.*?)\)") |
| 15 | + |
| 16 | + |
| 17 | +def _collect_links(): |
| 18 | + def _extract_file_links(markdown_file: Path) -> tuple[Path, str, str]: |
| 19 | + content = markdown_file.read_text() |
| 20 | + # Find all markdown links (e.g., [text](path/to/file)) |
| 21 | + links = _MD_LINK_PATTERN.findall(content) |
| 22 | + return [(markdown_file, text, file_link) for text, file_link in links] |
| 23 | + |
| 24 | + links = [] |
| 25 | + for md_file in _DOCS_DIR.rglob("*.md"): |
| 26 | + links.extend(_extract_file_links(md_file)) |
| 27 | + return links |
| 28 | + |
| 29 | + |
| 30 | +@pytest.mark.parametrize("md_file, link_text, file_link", _collect_links()) |
| 31 | +def test_markdown_links(md_file: Path, link_text: str, file_link: str): |
| 32 | + if file_link.startswith("http"): |
| 33 | + pytest.skip(f"External link skipped: {file_link}") |
| 34 | + |
| 35 | + # NOTE: that current doc only support relative to repo! |
| 36 | + relative_to_repo = (_REPO_DIR / file_link).resolve() |
| 37 | + |
| 38 | + assert ( |
| 39 | + relative_to_repo.exists() |
| 40 | + ), f"Broken link found: [{link_text}]({file_link}) in {md_file}" |
0 commit comments