92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
"""B-68: CLAUDE.md and README must describe the code as it is now.
|
|||
|
|
|
||
|
|
The audit found both files still asserting things the code had moved past —
|
||
|
|
JWT "no revocation" after token_version implemented exactly that, /report-bug
|
||
|
|
"a placeholder" after it shipped with admin triage, three stale test counts, a
|
||
|
|
code map missing three modules, and README links to a file and an anchor that
|
||
|
|
no longer exist. None of that is catchable by reading the code, so it is
|
||
|
|
pinned here instead.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import re
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
|
||
|
|
_ROOT = Path(__file__).resolve().parents[2]
|
||
|
|
CLAUDE_MD = (_ROOT / "CLAUDE.md").read_text(encoding="utf-8")
|
||
|
|
README = (_ROOT / "README.md").read_text(encoding="utf-8")
|
||
|
|
|
||
|
|
|
||
|
|
def _collected_test_count() -> int:
|
||
|
|
result = subprocess.run(
|
||
|
|
[sys.executable, "-m", "pytest", "--collect-only", "-q"],
|
||
|
|
cwd=_ROOT,
|
||
|
|
capture_output=True,
|
||
|
|
text=True,
|
||
|
|
timeout=300,
|
||
|
|
)
|
||
|
|
match = re.search(r"(\d+) tests? collected", result.stdout)
|
||
|
|
assert match, f"could not parse the collection summary:\n{result.stdout[-2000:]}"
|
||
|
|
return int(match.group(1))
|
||
|
|
|
||
|
|
|
||
|
|
def test_documented_test_counts_match_reality():
|
||
|
|
actual = _collected_test_count()
|
||
|
|
documented = [int(n) for n in re.findall(r"(\d+) tests\b", CLAUDE_MD)]
|
||
|
|
documented += [int(n) for n in re.findall(r"(\d+) unit tests\b", README)]
|
||
|
|
assert documented, "no test count found in CLAUDE.md or README — did the wording change?"
|
||
|
|
for count in documented:
|
||
|
|
assert count == actual, (
|
||
|
|
f"docs claim {count} tests, the suite collects {actual} — "
|
||
|
|
"update the counts in CLAUDE.md (twice) and README.md"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize(
|
||
|
|
"stale",
|
||
|
|
[
|
||
|
|
"no revocation", # token_version implements it (app/auth/dependencies.py)
|
||
|
|
"`/report-bug` are placeholders", # /report-bug shipped, only /guida is a stub
|
||
|
|
],
|
||
|
|
)
|
||
|
|
def test_claude_md_has_no_stale_claims(stale):
|
||
|
|
assert stale not in CLAUDE_MD
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize(
|
||
|
|
"module",
|
||
|
|
["rate_limit.py", "client_ip.py", "bug_reports"],
|
||
|
|
)
|
||
|
|
def test_code_map_covers_every_package_member(module):
|
||
|
|
code_map = CLAUDE_MD.split("## Code map", 1)[1].split("## Background tasks", 1)[0]
|
||
|
|
assert module in code_map
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize(
|
||
|
|
"link",
|
||
|
|
["(flowchart.mmd)", "CLAUDE.md#tech-stack-mvp"],
|
||
|
|
)
|
||
|
|
def test_readme_has_no_dead_links(link):
|
||
|
|
assert link not in README
|
||
|
|
|
||
|
|
|
||
|
|
def test_readme_relative_links_resolve():
|
||
|
|
for target in re.findall(r"\]\(([^)#]+)(?:#[^)]*)?\)", README):
|
||
|
|
if target.startswith(("http://", "https://", "mailto:")):
|
||
|
|
continue
|
||
|
|
assert (_ROOT / target).exists(), f"README links {target}, which does not exist"
|
||
|
|
|
||
|
|
|
||
|
|
def test_claude_md_anchors_into_itself_resolve():
|
||
|
|
headings = {
|
||
|
|
re.sub(r"[^a-z0-9 -]", "", line.lstrip("# ").lower()).replace(" ", "-")
|
||
|
|
for line in CLAUDE_MD.splitlines()
|
||
|
|
if line.startswith("#")
|
||
|
|
}
|
||
|
|
for anchor in re.findall(r"\(CLAUDE\.md#([a-z0-9-]+)\)", README + CLAUDE_MD):
|
||
|
|
assert anchor in headings, f"anchor #{anchor} matches no CLAUDE.md heading"
|