Spec explorer data endpoint, spec file finder, browser render test (failing)
- Add spec-explorer-data-by-slug helper with _SPEC_SLUG_MAP - _find_spec_file searches spec/, web/, shared/sx/ref/ directories - defpage specs-explore-page uses :data for server-side data fetch - test_evaluator_renders_in_browser: failing test for client-side rendering (client re-evaluates defpage content, find-spec unavailable — pre-existing) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Tiers" :id "tiers"
|
||||
(p "Four tiers, matching the " (a :href "/sx/(geography.(reactive.plan))" :class "text-violet-700 underline" "reactive islands") " levels:")
|
||||
(p "Four tiers, matching the " (a :href "/sx/(geography.(reactive.(reactive-design)))" :class "text-violet-700 underline" "reactive islands") " levels:")
|
||||
|
||||
(div :class "overflow-x-auto rounded border border-stone-200 mb-4"
|
||||
(table :class "w-full text-left text-sm"
|
||||
@@ -275,7 +275,7 @@
|
||||
(ul :class "list-disc pl-5 text-stone-700 space-y-1"
|
||||
(li (a :href "/sx/(etc.(plan.environment-images))" :class "text-violet-700 underline" "Environment Images") " — tiered images are smaller. An L0 image omits the parser, evaluator, and most primitives.")
|
||||
(li (a :href "/sx/(etc.(plan.content-addressed-components))" :class "text-violet-700 underline" "Content-Addressed Components") " — component CID resolution is L3-only. L0 pages don't resolve components client-side.")
|
||||
(li (a :href "/sx/(geography.(reactive.plan))" :class "text-violet-700 underline" "Reactive Islands") " — L2 tier is defined by island presence. The signal runtime is the L1→L2 delta.")
|
||||
(li (a :href "/sx/(geography.(reactive.(reactive-design)))" :class "text-violet-700 underline" "Reactive Islands") " — L2 tier is defined by island presence. The signal runtime is the L1→L2 delta.")
|
||||
(li (a :href "/sx/(etc.(plan.isomorphic-architecture))" :class "text-violet-700 underline" "Isomorphic Architecture") " — client-side page rendering is L3. Most pages don't need it."))
|
||||
|
||||
(div :class "rounded border border-amber-200 bg-amber-50 p-3 mt-2"
|
||||
|
||||
@@ -159,18 +159,35 @@ def _reference_data(slug: str) -> dict:
|
||||
return build_reference_data(slug, raw, detail_keys)
|
||||
|
||||
|
||||
def _read_spec_file(filename: str) -> str:
|
||||
"""Read a spec .sx file from the ref directory. Pure I/O — metadata lives in .sx."""
|
||||
def _find_spec_file(filename: str) -> str | None:
|
||||
"""Find a spec .sx file across spec/, web/, shared/sx/ref/ directories."""
|
||||
import os
|
||||
ref_dir = os.path.join(os.path.dirname(__file__), "..", "..", "shared", "sx", "ref")
|
||||
if not os.path.isdir(ref_dir):
|
||||
ref_dir = "/app/shared/sx/ref"
|
||||
filepath = os.path.join(ref_dir, filename)
|
||||
base = os.path.join(os.path.dirname(__file__), "..", "..")
|
||||
search_dirs = [
|
||||
os.path.join(base, "spec"),
|
||||
os.path.join(base, "web"),
|
||||
os.path.join(base, "shared", "sx", "ref"),
|
||||
"/app/spec",
|
||||
"/app/web",
|
||||
"/app/shared/sx/ref",
|
||||
]
|
||||
for d in search_dirs:
|
||||
path = os.path.join(d, filename)
|
||||
if os.path.isfile(path):
|
||||
return path
|
||||
return None
|
||||
|
||||
|
||||
def _read_spec_file(filename: str) -> str:
|
||||
"""Read a spec .sx file. Pure I/O — metadata lives in .sx."""
|
||||
filepath = _find_spec_file(filename)
|
||||
if not filepath:
|
||||
return ";; spec file not found: " + filename
|
||||
try:
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
return f.read()
|
||||
except FileNotFoundError:
|
||||
return ";; spec file not found"
|
||||
except (FileNotFoundError, TypeError):
|
||||
return ";; spec file not found: " + filename
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -332,7 +349,7 @@ def _collect_symbols(expr) -> set[str]:
|
||||
|
||||
_SPEC_SLUG_MAP = {
|
||||
"parser": ("parser.sx", "Parser", "Tokenization and parsing"),
|
||||
"evaluator": ("eval.sx", "Evaluator", "Tree-walking evaluation"),
|
||||
"evaluator": ("evaluator.sx", "Evaluator", "CEK machine evaluator"),
|
||||
"primitives": ("primitives.sx", "Primitives", "Built-in pure functions"),
|
||||
"render": ("render.sx", "Renderer", "Three rendering modes"),
|
||||
"special-forms": ("special-forms.sx", "Special Forms", "Special form dispatch"),
|
||||
@@ -374,10 +391,9 @@ def _spec_explorer_data(filename: str, title: str = "", desc: str = "") -> dict
|
||||
return None
|
||||
|
||||
# Read the raw source
|
||||
ref_dir = os.path.join(os.path.dirname(__file__), "..", "..", "shared", "sx", "ref")
|
||||
if not os.path.isdir(ref_dir):
|
||||
ref_dir = "/app/shared/sx/ref"
|
||||
filepath = os.path.join(ref_dir, filename)
|
||||
filepath = _find_spec_file(filename)
|
||||
if not filepath:
|
||||
return None
|
||||
try:
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
source = f.read()
|
||||
|
||||
@@ -491,6 +491,15 @@ class TestSpecExplorer:
|
||||
assert "define" in body, "Should contain define forms from spec"
|
||||
assert "eval-expr" in body, "Should contain eval-expr from evaluator spec"
|
||||
|
||||
def test_evaluator_renders_in_browser(self, page: Page):
|
||||
"""Spec explorer should render correctly in the browser, not show 'not found'."""
|
||||
nav(page, "(language.(spec.(explore.evaluator)))")
|
||||
page.wait_for_timeout(3000)
|
||||
content = page.locator("#main-panel").text_content() or ""
|
||||
assert "not found" not in content.lower(), \
|
||||
f"Page shows 'not found' instead of spec content: {content[:200]}"
|
||||
expect(page.locator("#main-panel")).to_contain_text("Evaluator", timeout=5000)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Key doc pages (smoke tests)
|
||||
|
||||
Reference in New Issue
Block a user