Parser: skip unit suffix when next ident is a comparison keyword (starts, ends, contains, matches, is, does, in, precedes, follows). Fixes "123 starts with '12'" returning "123starts" instead of true. eval-hs: use hs-compile directly instead of hs-to-sx-from-source with "return " prefix, which was causing the parser to consume the comparison as a string suffix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
110 lines
7.2 KiB
Plaintext
110 lines
7.2 KiB
Plaintext
;; ---------------------------------------------------------------------------
|
|
;; Runners page
|
|
;; ---------------------------------------------------------------------------
|
|
(defcomp ()
|
|
(~docs/page :title "Test Runners"
|
|
(div (~tw :tokens "space-y-8")
|
|
|
|
(div (~tw :tokens "space-y-4")
|
|
(p (~tw :tokens "text-lg text-stone-600")
|
|
"Three runners execute the same test specs on different hosts. Each injects the five platform functions and any per-spec extensions, then evaluates the SX source directly.")
|
|
(p (~tw :tokens "text-stone-600")
|
|
"All runners produce "
|
|
(a :href "https://testanything.org/" (~tw :tokens "text-violet-700 underline") "TAP")
|
|
" output and accept module names as arguments."))
|
|
|
|
;; Node.js runner
|
|
(div (~tw :tokens "space-y-3")
|
|
(h2 (~tw :tokens "text-2xl font-semibold text-stone-800") "Node.js: run.js")
|
|
(div (~tw :tokens "rounded-lg border border-stone-200 bg-white p-5 space-y-3")
|
|
(h3 (~tw :tokens "text-sm font-medium text-stone-500 uppercase tracking-wide") "Usage")
|
|
(~docs/code :src
|
|
(highlight "# Run all specs\nnode shared/sx/tests/run.js\n\n# Run specific specs\nnode shared/sx/tests/run.js eval parser\n\n# Legacy mode (monolithic test.sx)\nnode shared/sx/tests/run.js --legacy" "bash")))
|
|
(p (~tw :tokens "text-stone-600 text-sm")
|
|
"Uses "
|
|
(code (~tw :tokens "text-violet-700 text-sm") "sx-browser.js")
|
|
" as the evaluator. Router tests use bootstrapped functions from "
|
|
(code (~tw :tokens "text-violet-700 text-sm") "Sx.splitPathSegments")
|
|
" etc. Render tests use "
|
|
(code (~tw :tokens "text-violet-700 text-sm") "Sx.renderToHtml")
|
|
"."))
|
|
|
|
;; Python runner
|
|
(div (~tw :tokens "space-y-3")
|
|
(h2 (~tw :tokens "text-2xl font-semibold text-stone-800") "Python: run.py")
|
|
(div (~tw :tokens "rounded-lg border border-stone-200 bg-white p-5 space-y-3")
|
|
(h3 (~tw :tokens "text-sm font-medium text-stone-500 uppercase tracking-wide") "Usage")
|
|
(~docs/code :src
|
|
(highlight "# Run all specs\npython shared/sx/tests/run.py\n\n# Run specific specs\npython shared/sx/tests/run.py eval parser\n\n# Legacy mode (monolithic test.sx)\npython shared/sx/tests/run.py --legacy" "bash")))
|
|
(p (~tw :tokens "text-stone-600 text-sm")
|
|
"Uses the hand-written Python evaluator ("
|
|
(code (~tw :tokens "text-violet-700 text-sm") "evaluator.py")
|
|
"). Router tests import bootstrapped functions from "
|
|
(code (~tw :tokens "text-violet-700 text-sm") "sx_ref.py")
|
|
" because the hand-written evaluator's "
|
|
(code (~tw :tokens "text-violet-700 text-sm") "set!")
|
|
" doesn't propagate across lambda closure copies."))
|
|
|
|
;; Browser runner
|
|
(div (~tw :tokens "space-y-3")
|
|
(h2 (~tw :tokens "text-2xl font-semibold text-stone-800") "Browser: sx-test-runner.js")
|
|
(p (~tw :tokens "text-stone-600")
|
|
"Runs in the browser on each test page. The spec source is embedded in a hidden textarea; the runner parses and evaluates it using the same "
|
|
(code (~tw :tokens "text-violet-700 text-sm") "sx-browser.js")
|
|
" that renders the page itself.")
|
|
(p (~tw :tokens "text-stone-600")
|
|
"This is the strongest proof of cross-host parity — the browser evaluator that users depend on is the same one running the tests."))
|
|
|
|
;; Platform functions table
|
|
(div (~tw :tokens "space-y-3")
|
|
(h2 (~tw :tokens "text-2xl font-semibold text-stone-800") "Platform functions")
|
|
(div (~tw :tokens "overflow-x-auto rounded border border-stone-200")
|
|
(table (~tw :tokens "w-full text-left text-sm")
|
|
(thead (tr (~tw :tokens "border-b border-stone-200 bg-stone-100")
|
|
(th (~tw :tokens "px-3 py-2 font-medium text-stone-600") "Function")
|
|
(th (~tw :tokens "px-3 py-2 font-medium text-stone-600") "Scope")
|
|
(th (~tw :tokens "px-3 py-2 font-medium text-stone-600") "Purpose")))
|
|
(tbody
|
|
(tr (~tw :tokens "border-b border-stone-100")
|
|
(td (~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700") "try-call")
|
|
(td (~tw :tokens "px-3 py-2") "All specs")
|
|
(td (~tw :tokens "px-3 py-2 text-stone-700") "Call a thunk, catch errors, return result dict"))
|
|
(tr (~tw :tokens "border-b border-stone-100")
|
|
(td (~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700") "report-pass")
|
|
(td (~tw :tokens "px-3 py-2") "All specs")
|
|
(td (~tw :tokens "px-3 py-2 text-stone-700") "Report a passing test"))
|
|
(tr (~tw :tokens "border-b border-stone-100")
|
|
(td (~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700") "report-fail")
|
|
(td (~tw :tokens "px-3 py-2") "All specs")
|
|
(td (~tw :tokens "px-3 py-2 text-stone-700") "Report a failing test with error message"))
|
|
(tr (~tw :tokens "border-b border-stone-100")
|
|
(td (~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700") "push-suite")
|
|
(td (~tw :tokens "px-3 py-2") "All specs")
|
|
(td (~tw :tokens "px-3 py-2 text-stone-700") "Push suite name onto context stack"))
|
|
(tr (~tw :tokens "border-b border-stone-100")
|
|
(td (~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700") "pop-suite")
|
|
(td (~tw :tokens "px-3 py-2") "All specs")
|
|
(td (~tw :tokens "px-3 py-2 text-stone-700") "Pop suite name from context stack"))
|
|
(tr (~tw :tokens "border-b border-stone-100")
|
|
(td (~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700") "sx-parse")
|
|
(td (~tw :tokens "px-3 py-2") "Parser")
|
|
(td (~tw :tokens "px-3 py-2 text-stone-700") "Parse SX source to AST"))
|
|
(tr (~tw :tokens "border-b border-stone-100")
|
|
(td (~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700") "sx-serialize")
|
|
(td (~tw :tokens "px-3 py-2") "Parser")
|
|
(td (~tw :tokens "px-3 py-2 text-stone-700") "Serialize AST back to SX source text"))
|
|
(tr (~tw :tokens "border-b border-stone-100")
|
|
(td (~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700") "render-html")
|
|
(td (~tw :tokens "px-3 py-2") "Renderer")
|
|
(td (~tw :tokens "px-3 py-2 text-stone-700") "Parse SX source and render to HTML string"))))))
|
|
|
|
;; Adding a new host
|
|
(div (~tw :tokens "rounded-lg border border-blue-200 bg-blue-50 p-5 space-y-3")
|
|
(h2 (~tw :tokens "text-lg font-semibold text-blue-900") "Adding a new host")
|
|
(ol (~tw :tokens "list-decimal list-inside text-blue-800 space-y-2 text-sm")
|
|
(li "Implement the 5 platform functions in your target language")
|
|
(li "Load " (code (~tw :tokens "text-sm") "test-framework.sx") " — it defines deftest/defsuite macros")
|
|
(li "Load the spec file(s) — the evaluator runs the tests automatically")
|
|
(li "Add per-spec platform functions if testing parser or renderer")
|
|
(li "Compare TAP output across hosts — divergences reveal platform-specific semantics"))))))
|