Files
zk-data-agent/tests/test_docs_site.py
T

91 lines
2.9 KiB
Python

from __future__ import annotations
import json
from html.parser import HTMLParser
from pathlib import Path
from urllib.parse import urlparse
SITE_ROOT = Path(__file__).parents[1] / "docs" / "site"
ALLOWED_STATUSES = {"baseline", "validated", "backlog"}
class SiteParser(HTMLParser):
def __init__(self) -> None:
super().__init__()
self.ids: set[str] = set()
self.references: list[str] = []
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
values = dict(attrs)
if values.get("id"):
self.ids.add(values["id"])
attribute = "href" if tag in {"a", "link"} else "src" if tag in {"script", "img"} else None
if attribute and values.get(attribute):
self.references.append(values[attribute])
def _parser() -> SiteParser:
parser = SiteParser()
parser.feed((SITE_ROOT / "index.html").read_text())
return parser
def test_docs_site_required_files_are_present() -> None:
for relative_path in ("index.html", "styles.css", "app.js", "experiments.json", "og.png"):
path = SITE_ROOT / relative_path
assert path.is_file(), relative_path
assert path.stat().st_size > 0, relative_path
assert (SITE_ROOT / "og.png").read_bytes().startswith(b"\x89PNG\r\n\x1a\n")
def test_docs_site_local_links_and_anchors_resolve() -> None:
parser = _parser()
for reference in parser.references:
if reference.startswith("#"):
assert reference[1:] in parser.ids, reference
continue
parsed = urlparse(reference)
if parsed.scheme or parsed.netloc or reference.startswith("/"):
continue
if reference == "../static/favicon.svg":
continue
local_path = (SITE_ROOT / parsed.path).resolve()
assert local_path.is_relative_to(SITE_ROOT.resolve()), reference
assert local_path.is_file(), reference
def test_docs_site_navigation_targets_every_top_level_section() -> None:
parser = _parser()
html = (SITE_ROOT / "index.html").read_text()
expected_sections = {
"overview",
"architecture",
"agent-loop",
"workspace",
"models",
"experiments",
"operations",
"timeline",
"repository",
}
assert expected_sections <= parser.ids
for section_id in expected_sections:
assert f'href="#{section_id}"' in html
def test_experiment_ledger_has_unique_stable_records() -> None:
experiments = json.loads((SITE_ROOT / "experiments.json").read_text())
assert len(experiments) >= 5
ids = [item["id"] for item in experiments]
assert len(ids) == len(set(ids))
for item in experiments:
assert item["status"] in ALLOWED_STATUSES
assert item["title"].strip()
assert item["summary"].strip()
assert item["area"].strip()
assert item["version"].strip()
assert isinstance(item["metrics"], list)