Accumulated changes from WASM browser development sessions: - sx_runtime.ml: signal subscription + notify, env unwrap tolerance - sx_browser.bc.js: rebuilt js_of_ocaml browser kernel - sx_browser.bc.wasm.js + assets: WASM browser kernel build - sx-platform.js browser tests (test_js, test_platform, test_wasm) - Playwright sx-inspect.js: interactive page inspector tool - harness-web.sx: DOM assertion updates - deploy.sh, Dockerfile, dune-project: build config updates - test-stepper.sx: stepper unit tests - reader-macro-demo plan update Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
187 lines
7.0 KiB
Plaintext
187 lines
7.0 KiB
Plaintext
(defsuite
|
|
"stepper-lib"
|
|
(deftest
|
|
"split-tag: string literal becomes leaf step"
|
|
(let
|
|
((result (list)))
|
|
(split-tag "hello" result)
|
|
(assert-equal 1 (len result))
|
|
(assert-equal "leaf" (get (first result) "type"))
|
|
(assert-equal "hello" (get (first result) "expr"))))
|
|
(deftest
|
|
"split-tag: number literal becomes leaf step"
|
|
(let
|
|
((result (list)))
|
|
(split-tag 42 result)
|
|
(assert-equal 1 (len result))
|
|
(assert-equal "leaf" (get (first result) "type"))
|
|
(assert-equal 42 (get (first result) "expr"))))
|
|
(deftest
|
|
"split-tag: empty list produces nothing"
|
|
(let
|
|
((result (list)))
|
|
(split-tag (list) result)
|
|
(assert-equal 0 (len result))))
|
|
(deftest
|
|
"split-tag: simple div becomes open+close"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(div)")))
|
|
(split-tag (first parsed) result)
|
|
(assert-equal 2 (len result))
|
|
(assert-equal "open" (get (first result) "type"))
|
|
(assert-equal "div" (get (first result) "tag"))
|
|
(assert-equal "close" (get (nth result 1) "type"))))
|
|
(deftest
|
|
"split-tag: div with text child becomes open+leaf+close"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(div \"hello\")")))
|
|
(split-tag (first parsed) result)
|
|
(assert-equal 3 (len result))
|
|
(assert-equal "open" (get (first result) "type"))
|
|
(assert-equal "leaf" (get (nth result 1) "type"))
|
|
(assert-equal "hello" (get (nth result 1) "expr"))
|
|
(assert-equal "close" (get (nth result 2) "type"))))
|
|
(deftest
|
|
"split-tag: keyword attrs captured in open step"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(div :class \"foo\" \"text\")")))
|
|
(split-tag (first parsed) result)
|
|
(assert-equal 3 (len result))
|
|
(assert-equal "open" (get (first result) "type"))
|
|
(let
|
|
((attrs (get (first result) "attrs")))
|
|
(assert-equal 2 (len attrs)))))
|
|
(deftest
|
|
"split-tag: nested tags produce nested open/close pairs"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(div (span \"hi\"))")))
|
|
(split-tag (first parsed) result)
|
|
(assert-equal 5 (len result))
|
|
(assert-equal "open" (get (first result) "type"))
|
|
(assert-equal "div" (get (first result) "tag"))
|
|
(assert-equal "open" (get (nth result 1) "type"))
|
|
(assert-equal "span" (get (nth result 1) "tag"))
|
|
(assert-equal "leaf" (get (nth result 2) "type"))
|
|
(assert-equal "close" (get (nth result 3) "type"))
|
|
(assert-equal "close" (get (nth result 4) "type"))))
|
|
(deftest
|
|
"split-tag: component call becomes expr step"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(~my/comp :title \"hi\")")))
|
|
(split-tag (first parsed) result)
|
|
(assert-equal 1 (len result))
|
|
(assert-equal "expr" (get (first result) "type"))))
|
|
(deftest
|
|
"split-tag: component inside div becomes spread"
|
|
(let
|
|
((result (list))
|
|
(parsed (sx-parse "(div (~cssx/tw :tokens \"foo\") \"text\")")))
|
|
(split-tag (first parsed) result)
|
|
(let
|
|
((open-step (first result)))
|
|
(assert-equal "open" (get open-step "type"))
|
|
(assert-equal 1 (len (get open-step "spreads"))))))
|
|
(deftest
|
|
"build-code-tokens: string expr produces quoted token"
|
|
(let
|
|
((tokens (list)) (ref (dict "v" 0)))
|
|
(build-code-tokens "hello" tokens ref 0)
|
|
(assert-equal 1 (len tokens))
|
|
(assert-equal "\"hello\"" (get (first tokens) "text"))
|
|
(assert-equal "text-emerald-700" (get (first tokens) "cls"))
|
|
(assert-equal 0 (get (first tokens) "step"))))
|
|
(deftest
|
|
"build-code-tokens: number expr produces token"
|
|
(let
|
|
((tokens (list)) (ref (dict "v" 0)))
|
|
(build-code-tokens 42 tokens ref 0)
|
|
(assert-equal 1 (len tokens))
|
|
(assert-equal "42" (get (first tokens) "text"))
|
|
(assert-equal "text-amber-700" (get (first tokens) "cls"))))
|
|
(deftest
|
|
"build-code-tokens: symbol produces token with name"
|
|
(let
|
|
((tokens (list)) (ref (dict "v" 0)))
|
|
(build-code-tokens (make-symbol "foo") tokens ref 0)
|
|
(assert-equal 1 (len tokens))
|
|
(assert-equal "foo" (get (first tokens) "text"))
|
|
(assert-equal "text-stone-700" (get (first tokens) "cls"))))
|
|
(deftest
|
|
"build-code-tokens: html tag symbol gets sky color"
|
|
(let
|
|
((tokens (list)) (ref (dict "v" 0)))
|
|
(build-code-tokens (make-symbol "div") tokens ref 0)
|
|
(assert-equal "text-sky-700 font-semibold" (get (first tokens) "cls"))))
|
|
(deftest
|
|
"build-code-tokens: component symbol gets rose color"
|
|
(let
|
|
((tokens (list)) (ref (dict "v" 0)))
|
|
(build-code-tokens (make-symbol "~my/comp") tokens ref 0)
|
|
(assert-equal "text-rose-600 font-semibold" (get (first tokens) "cls"))))
|
|
(deftest
|
|
"build-code-tokens: list produces open-paren + children + close-paren"
|
|
(let
|
|
((tokens (list))
|
|
(ref (dict "v" 0))
|
|
(parsed (sx-parse "(div \"hi\")")))
|
|
(build-code-tokens (first parsed) tokens ref 0)
|
|
(assert-equal "(" (get (first tokens) "text"))
|
|
(assert-equal ")" (get (last tokens) "text"))))
|
|
(deftest
|
|
"build-code-tokens: step counter increments for strings"
|
|
(let
|
|
((tokens (list)) (ref (dict "v" 5)))
|
|
(build-code-tokens "hello" tokens ref 0)
|
|
(assert-equal 5 (get (first tokens) "step"))
|
|
(assert-equal 6 (get ref "v"))))
|
|
(deftest
|
|
"steps-to-preview: empty steps returns nil"
|
|
(assert-equal nil (steps-to-preview (list) 5)))
|
|
(deftest
|
|
"steps-to-preview: target 0 returns nil"
|
|
(let
|
|
((result (list)))
|
|
(split-tag "hello" result)
|
|
(assert-equal nil (steps-to-preview result 0))))
|
|
(deftest
|
|
"steps-to-preview: single leaf step reconstructs value"
|
|
(let
|
|
((result (list)))
|
|
(split-tag "hello" result)
|
|
(assert-equal "hello" (steps-to-preview result 1))))
|
|
(deftest
|
|
"steps-to-preview: open+close reconstructs empty tag"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(div)")))
|
|
(split-tag (first parsed) result)
|
|
(let
|
|
((preview (steps-to-preview result 2)))
|
|
(assert-equal "div" (symbol-name (first preview))))))
|
|
(deftest
|
|
"steps-to-preview: partial steps build partial tree"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(div (span \"a\") (span \"b\"))")))
|
|
(split-tag (first parsed) result)
|
|
(let
|
|
((preview (steps-to-preview result 4)))
|
|
(assert-equal "div" (symbol-name (first preview)))
|
|
(assert-equal true (> (len preview) 1)))))
|
|
(deftest
|
|
"steps-to-preview: full steps build complete tree"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(div \"hello\")")))
|
|
(split-tag (first parsed) result)
|
|
(let
|
|
((preview (steps-to-preview result (len result))))
|
|
(assert-equal "div" (symbol-name (first preview)))
|
|
(assert-equal "hello" (nth preview 1))))))
|
|
|
|
(deftest
|
|
"split-tag result is a render leak (list of dicts)"
|
|
(let
|
|
((result (list)) (parsed (sx-parse "(div \"hello\")")))
|
|
(split-tag (first parsed) result)
|
|
(assert-equal true (is-render-leak? result))
|
|
(assert-equal true (> (len result) 0))
|
|
(assert-equal true (dict? (first result)))))
|