Greenfield SX-native pivot (NOT a strangler): the host speaks SX/SXTP end to end;
JSON only at the future ActivityPub federation edge.
- OUTPUT: host/json-status -> host/sx-status — every host/ok/host/error response is
text/sx via the serialize primitive (NOT application/json). Flips feed, relations,
blog reads. Tests assert the SX envelope ({:ok true :data ...}).
- DELETE the blog JSON CRUD /posts (POST/PUT/DELETE) + bearer-based host/blog--protect:
a pure old-contract REST mirror. Create/edit go through the HTML editor forms;
programmatic writes speak SXTP. FOLLOW-UP: no browser delete route yet (was JSON-only,
no UI) — add POST /:slug/delete + cascade edge cleanup when the metamodel UI needs it.
- INPUT: host/sx-body (sxtp.sx) parses a text/sx request body to a string-keyed dict
(parse-safe + sxtp/-normalize). feed POST + relations attach/detach read it.
- UNIFIED field reader host/fields / host/field: text/sx body OR urlencoded form by
content-type. The blog form handlers (new/edit/relate/unrelate) + login read through
it — additive, urlencoded still works (no-engine / bootstrap fallback).
Conformance 290/290 (11 suites). Retires the strangler framing in the plan; adds the
'SX all the way out' wire table. The engine half (browser posts text/sx) follows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
76 lines
2.2 KiB
Plaintext
76 lines
2.2 KiB
Plaintext
;; lib/host/tests/router.sx — host app assembly: health endpoint, group mounting,
|
|
;; 404 fallback.
|
|
|
|
(define host-rt-pass 0)
|
|
(define host-rt-fail 0)
|
|
(define host-rt-fails (list))
|
|
|
|
(define
|
|
host-rt-test
|
|
(fn
|
|
(name actual expected)
|
|
(if
|
|
(= actual expected)
|
|
(set! host-rt-pass (+ host-rt-pass 1))
|
|
(begin
|
|
(set! host-rt-fail (+ host-rt-fail 1))
|
|
(append! host-rt-fails {:name name :actual actual :expected expected})))))
|
|
|
|
(define
|
|
host-rt-req
|
|
(fn (method target) (dream-request method target {} "")))
|
|
|
|
;; An app built from one domain group of two routes.
|
|
(define
|
|
host-rt-app
|
|
(host/make-app
|
|
(list
|
|
(list
|
|
(dream-get "/ping" (fn (req) (host/ok "pong")))
|
|
(dream-get "/widgets/:id" (fn (req) (host/ok (dream-param req "id"))))))))
|
|
|
|
;; ── health ─────────────────────────────────────────────────────────
|
|
(host-rt-test
|
|
"health status 200"
|
|
(dream-status (host-rt-app (host-rt-req "GET" "/health")))
|
|
200)
|
|
(host-rt-test
|
|
"health body healthy"
|
|
(contains?
|
|
(dream-resp-body (host-rt-app (host-rt-req "GET" "/health")))
|
|
"healthy")
|
|
true)
|
|
|
|
;; ── group routes mounted ───────────────────────────────────────────
|
|
(host-rt-test
|
|
"group route ping"
|
|
(contains?
|
|
(dream-resp-body (host-rt-app (host-rt-req "GET" "/ping")))
|
|
"pong")
|
|
true)
|
|
(host-rt-test
|
|
"group path param"
|
|
(contains?
|
|
(dream-resp-body (host-rt-app (host-rt-req "GET" "/widgets/42")))
|
|
":data \"42\"")
|
|
true)
|
|
|
|
;; ── fallback ───────────────────────────────────────────────────────
|
|
(host-rt-test
|
|
"unknown path 404"
|
|
(dream-status (host-rt-app (host-rt-req "GET" "/nope")))
|
|
404)
|
|
(host-rt-test
|
|
"wrong method 405"
|
|
(dream-status (host-rt-app (host-rt-req "POST" "/ping")))
|
|
405)
|
|
|
|
(define
|
|
host-rt-tests-run!
|
|
(fn
|
|
()
|
|
{:total (+ host-rt-pass host-rt-fail)
|
|
:passed host-rt-pass
|
|
:failed host-rt-fail
|
|
:fails host-rt-fails}))
|