Files
rose-ash/sx/sx/reactive-islands/runner-placeholder.sx
giles 84a48f0de3 Fix navigation: deep URL routing, back button, render timeout
- request-handler.sx: replace all dots (not just `.(`) and auto-quote
  undefined symbols as strings so 3-level URLs like
  /sx/(geography.(reactive.(examples.counter))) resolve correctly
- sx-platform.js: register popstate handler (was missing from manual
  boot sequence) and fetch full HTML for back/forward navigation
- sx_ref.ml: add CEK step limit (10M steps) checked every 4096 steps
  so runaway renders return 500 instead of blocking the worker forever
- Rename test-runner.sx → runner-placeholder.sx to avoid `test-` skip
- Playwright config: pin testDir, single worker, ignore worktrees

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 17:54:33 +00:00

4 lines
2.5 KiB
Plaintext

(defcomp ~reactive-islands/test-runner-placeholder () (div :class "rounded border border-stone-200 bg-stone-50 p-4" :data-sx-island "reactive-islands/test-runner" (p :class "text-stone-400 text-sm italic" "Loading tests...")))
(defisland ~reactive-islands/test-runner () (let ((results (signal nil)) (running (signal false))) (letrec ((run-tests (fn () (reset! running true) (let ((script-el (dom-query "script[data-for]")) (test-results (list))) (when script-el (let ((test-src (host-get script-el "textContent")) (parsed (let ((raw (host-get script-el "textContent")) (decoded (host-call raw "replaceAll" "&quot;" "\""))) (sx-parse (host-call decoded "replaceAll" "&amp;" "&"))))) (for-each (fn (expr) (when (and (list? expr) (not (empty? expr)) (= (type-of (first expr)) "symbol")) (let ((head (symbol-name (first expr)))) (cond (= head "defsuite") (for-each (fn (child) (when (and (list? child) (not (empty? child)) (= (type-of (first child)) "symbol") (= (symbol-name (first child)) "deftest")) (append! test-results (try-test (nth child 1) (last child))))) (slice expr 2)) (= head "deftest") (append! test-results (try-test (nth expr 1) (last expr))))))) parsed))) (reset! results test-results) (reset! running false)))) (try-test (fn (name body) (let ((result (cek-try (fn () (eval-expr body (global-env)) true) (fn (err) err)))) (if (= result true) {:pass true :error nil :name name} {:pass false :error (str result) :name name}))))) (run-tests) (div :class "rounded border border-stone-200 bg-stone-50 p-4" (div :class "flex items-center justify-between mb-3" (h4 :class "text-sm font-semibold text-stone-700" "Tests") (button :class "px-2 py-1 text-xs rounded bg-stone-200 hover:bg-stone-300 transition" :on-click (fn (e) (run-tests)) "Re-run")) (if (deref running) (p :class "text-stone-400 text-sm italic" "Running...") (if (nil? (deref results)) (p :class "text-stone-400 text-sm italic" "No test source found") (let ((r (deref results)) (pass-count (len (filter (fn (t) (get t "pass")) r))) (fail-count (len (filter (fn (t) (not (get t "pass"))) r)))) (div :class "space-y-2" (div :class "text-sm font-mono" (span :class (if (= fail-count 0) "text-emerald-600 font-semibold" "text-red-600 font-semibold") (str pass-count "/" (len r) " passed"))) (map (fn (t) (div :class "flex items-start gap-2 text-xs font-mono py-0.5" (span :class (if (get t "pass") "text-emerald-500" "text-red-500") (if (get t "pass") "✓" "✗")) (span :class "text-stone-600" (get t "name")) (when (get t "error") (span :class "text-red-400 ml-2" (get t "error"))))) r)))))))))