lib/hyperscript/runtime.sx — thin wrappers over web/lib/dom.sx primitives implementing hyperscript-specific semantics: Event handling: hs-on, hs-on-every, hs-init Async/timing: hs-wait (IO suspend), hs-wait-for, hs-settle Classes: hs-toggle-class!, hs-toggle-between!, hs-take! DOM insertion: hs-put! (into/before/after) Navigation: hs-navigate!, hs-next, hs-previous, hs-query-first/last Iteration: hs-repeat-times, hs-repeat-forever Fetch: hs-fetch (json/text/html format dispatch) Type coercion: hs-coerce (Int/Float/String/Boolean/Array) Object creation: hs-make (Object/Array/Set/Map) Behaviors: hs-install Measurement: hs-measure Transitions: hs-transition (CSS property + optional duration) 23 runtime + 7 end-to-end pipeline tests. 3099/3099 full build, zero regressions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
128 lines
4.3 KiB
Plaintext
128 lines
4.3 KiB
Plaintext
;; _hyperscript runtime tests
|
|
;; Pure function tests run directly; DOM-dependent shims tested via Playwright.
|
|
|
|
;; ── Type coercion ─────────────────────────────────────────────
|
|
(defsuite
|
|
"hs-runtime-coerce"
|
|
(deftest "coerce string to Int" (assert= 42 (hs-coerce "42" "Int")))
|
|
(deftest
|
|
"coerce string to Float"
|
|
(assert= 3.14 (hs-coerce "3.14" "Float")))
|
|
(deftest "coerce number to String" (assert= "42" (hs-coerce 42 "String")))
|
|
(deftest "coerce truthy to Boolean" (assert= true (hs-coerce 1 "Boolean")))
|
|
(deftest
|
|
"coerce falsy to Boolean"
|
|
(assert= false (hs-coerce nil "Boolean")))
|
|
(deftest
|
|
"coerce value to Array wraps"
|
|
(let
|
|
((result (hs-coerce 5 "Array")))
|
|
(assert= true (list? result))
|
|
(assert= 5 (first result))))
|
|
(deftest
|
|
"coerce list to Array passes through"
|
|
(let
|
|
((result (hs-coerce (list 1 2) "Array")))
|
|
(assert= 2 (len result))))
|
|
(deftest
|
|
"unknown type passes through"
|
|
(assert= "hello" (hs-coerce "hello" "Foo"))))
|
|
|
|
;; ── Object creation ───────────────────────────────────────────
|
|
(defsuite
|
|
"hs-runtime-make"
|
|
(deftest
|
|
"make Object returns dict"
|
|
(let ((obj (hs-make "Object"))) (assert= true (dict? obj))))
|
|
(deftest
|
|
"make Array returns list"
|
|
(let
|
|
((arr (hs-make "Array")))
|
|
(assert= true (list? arr))
|
|
(assert= 0 (len arr))))
|
|
(deftest
|
|
"make Set returns list"
|
|
(let ((s (hs-make "Set"))) (assert= true (list? s))))
|
|
(deftest
|
|
"make Map returns dict"
|
|
(let ((m (hs-make "Map"))) (assert= true (dict? m)))))
|
|
|
|
;; ── Iteration ─────────────────────────────────────────────────
|
|
(defsuite
|
|
"hs-runtime-repeat"
|
|
(deftest
|
|
"repeat-times calls thunk N times"
|
|
(let
|
|
((count 0))
|
|
(hs-repeat-times 5 (fn () (set! count (+ count 1))))
|
|
(assert= 5 count)))
|
|
(deftest
|
|
"repeat-times zero does nothing"
|
|
(let
|
|
((count 0))
|
|
(hs-repeat-times 0 (fn () (set! count (+ count 1))))
|
|
(assert= 0 count)))
|
|
(deftest
|
|
"repeat-times one"
|
|
(let
|
|
((count 0))
|
|
(hs-repeat-times 1 (fn () (set! count (+ count 1))))
|
|
(assert= 1 count))))
|
|
|
|
;; ── Init ──────────────────────────────────────────────────────
|
|
(defsuite
|
|
"hs-runtime-init"
|
|
(deftest
|
|
"init calls thunk"
|
|
(let
|
|
((called false))
|
|
(hs-init (fn () (set! called true)))
|
|
(assert= true called))))
|
|
|
|
;; ── End-to-end pipeline ───────────────────────────────────────
|
|
(defsuite
|
|
"hs-runtime-e2e"
|
|
(deftest
|
|
"source → SX shape: add class"
|
|
(let
|
|
((sx (hs-to-sx-from-source "add .active to me")))
|
|
(assert= (quote dom-add-class) (first sx))
|
|
(assert= 3 (len sx))))
|
|
(deftest
|
|
"source → SX shape: sequence"
|
|
(let
|
|
((sx (hs-to-sx-from-source "add .a to me then add .b to me")))
|
|
(assert= (quote do) (first sx))
|
|
(assert= 3 (len sx))))
|
|
(deftest
|
|
"source → SX shape: on handler"
|
|
(let
|
|
((sx (hs-to-sx-from-source "on click log 'hi' end")))
|
|
(assert= (quote hs-on) (first sx))
|
|
(assert= (quote me) (nth sx 1))
|
|
(assert= "click" (nth sx 2))))
|
|
(deftest
|
|
"source → SX shape: if-else"
|
|
(let
|
|
((sx (hs-to-sx-from-source "if true log 1 else log 0 end")))
|
|
(assert= (quote if) (first sx))))
|
|
(deftest
|
|
"source → SX shape: set variable"
|
|
(let
|
|
((sx (hs-to-sx-from-source "set x to 42")))
|
|
(assert= (quote set!) (first sx))
|
|
(assert= (quote x) (nth sx 1))
|
|
(assert= 42 (nth sx 2))))
|
|
(deftest
|
|
"source → SX shape: fetch"
|
|
(let
|
|
((sx (hs-to-sx-from-source "fetch '/api'")))
|
|
(assert= (quote hs-fetch) (first sx))
|
|
(assert= "json" (nth sx 2))))
|
|
(deftest
|
|
"source → SX shape: def function"
|
|
(let
|
|
((sx (hs-to-sx-from-source "def add(a, b) return a end")))
|
|
(assert= (quote define) (first sx))
|
|
(assert= (quote add) (nth sx 1))
|
|
(assert= (quote fn) (first (nth sx 2)))))) |