docs: publish architecture and experiment portal
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user