W14: C23 adapter-dom render-output tests (test-only) — section C complete
The DOM adapter's only test file asserts membership predicates ("if is a
render form") — zero tests inspect what render-to-dom actually builds
(hosts.md C23), and the file is excluded from the runner as browser-only.
Discovery: the browser-only assumption is false for render output —
(import (web adapter-dom)) disk-resolves in the OCaml runner and
render-to-dom works against its mock DOM. Add
web/tests/test-adapter-dom-render.sx (8 tests) pinning the adapter's real
output contract (probed first): text renders as a nodeType-3 child text
node; when/map wrap output in a FRAGMENT child; if inlines the chosen
branch; attrs/class/id land on the element; voids have no children.
Auto-included in default runs — first render-output coverage of the
1512-line adapter in the standard gate. Remaining depth (boolean attrs,
on-*/bind/ref/key, reactive attrs, hydration cursor) tracked on the
checklist. 254/0 standalone.
Test-only: no semantics edits, no push.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
93
web/tests/test-adapter-dom-render.sx
Normal file
93
web/tests/test-adapter-dom-render.sx
Normal file
@@ -0,0 +1,93 @@
|
||||
;; ==========================================================================
|
||||
;; test-adapter-dom-render.sx — C23 (W14): actual render-OUTPUT tests for
|
||||
;; the DOM adapter. The pre-existing test-adapter-dom.sx asserts membership
|
||||
;; predicates only ("if is a render form") — zero tests inspected what
|
||||
;; render-to-dom actually builds, leaving the 1512-line adapter the
|
||||
;; thinnest-tested relative to size (hosts.md C23).
|
||||
;;
|
||||
;; Runs against the OCaml runner's mock DOM (host-* primitives) through the
|
||||
;; real (web adapter-dom) library, disk-resolved by import.
|
||||
;;
|
||||
;; Adapter output contract (probed 2026-07-04):
|
||||
;; - text renders as a CHILD TEXT NODE (nodeType 3, textContent set);
|
||||
;; the parent's own textContent prop stays "" in the mock
|
||||
;; - control-flow forms (when/map/...) wrap their output in a FRAGMENT
|
||||
;; child; `if` inlines the chosen branch directly
|
||||
;; ==========================================================================
|
||||
(import (web adapter-dom))
|
||||
|
||||
(defsuite
|
||||
"adapter-dom-render-output"
|
||||
(deftest
|
||||
"simple element: tag, text child node"
|
||||
(let
|
||||
((el (render-to-dom (quote (div "hello")) (make-env))))
|
||||
(assert= (dom-node-name el) "DIV")
|
||||
(let
|
||||
((kids (dom-get-prop el "children")))
|
||||
(assert= (len kids) 1)
|
||||
(assert= (dom-get-prop (first kids) "nodeType") 3)
|
||||
(assert= (dom-text-content (first kids)) "hello"))))
|
||||
(deftest
|
||||
"class and id land on the element"
|
||||
(let
|
||||
((el (render-to-dom (quote (div :class "card" :id "main" "x")) (make-env))))
|
||||
(assert= (dom-get-prop el "className") "card")
|
||||
(assert
|
||||
(or
|
||||
(= (dom-get-prop el "id") "main")
|
||||
(= (get (dom-get-prop el "attributes") "id") "main"))
|
||||
"id not set as prop or attribute")))
|
||||
(deftest
|
||||
"nested children are appended in order"
|
||||
(let
|
||||
((el (render-to-dom (quote (ul (li "a") (li "b") (li "c"))) (make-env))))
|
||||
(let
|
||||
((kids (dom-get-prop el "children")))
|
||||
(assert= (len kids) 3)
|
||||
(assert= (dom-node-name (first kids)) "LI")
|
||||
(assert=
|
||||
(dom-text-content
|
||||
(first (dom-get-prop (nth kids 2) "children")))
|
||||
"c"))))
|
||||
(deftest
|
||||
"void element renders with no children"
|
||||
(let
|
||||
((el (render-to-dom (quote (input :type "text")) (make-env))))
|
||||
(assert= (dom-node-name el) "INPUT")
|
||||
(assert= (len (dom-get-prop el "children")) 0)))
|
||||
(deftest
|
||||
"when false yields an empty fragment"
|
||||
(let
|
||||
((el (render-to-dom (quote (div (when false (span "hidden")))) (make-env))))
|
||||
(let
|
||||
((kids (dom-get-prop el "children")))
|
||||
(assert= (len kids) 1)
|
||||
(assert= (dom-node-name (first kids)) "FRAGMENT")
|
||||
(assert= (len (dom-get-prop (first kids) "children")) 0))))
|
||||
(deftest
|
||||
"when true renders the branch inside its fragment"
|
||||
(let
|
||||
((el (render-to-dom (quote (div (when true (span "shown")))) (make-env))))
|
||||
(let
|
||||
((frag (first (dom-get-prop el "children"))))
|
||||
(assert= (dom-node-name frag) "FRAGMENT")
|
||||
(assert=
|
||||
(dom-node-name (first (dom-get-prop frag "children")))
|
||||
"SPAN"))))
|
||||
(deftest
|
||||
"map render form produces one child per element inside its fragment"
|
||||
(let
|
||||
((el (render-to-dom (quote (ul (map (fn (x) (li x)) (list "1" "2" "3")))) (make-env))))
|
||||
(let
|
||||
((frag (first (dom-get-prop el "children"))))
|
||||
(assert= (dom-node-name frag) "FRAGMENT")
|
||||
(let
|
||||
((items (dom-get-prop frag "children")))
|
||||
(assert= (len items) 3)
|
||||
(assert= (dom-node-name (first items)) "LI")))))
|
||||
(deftest
|
||||
"if render form inlines the chosen branch directly"
|
||||
(let
|
||||
((el (render-to-dom (quote (div (if true (b "yes") (i "no")))) (make-env))))
|
||||
(assert= (dom-node-name (first (dom-get-prop el "children"))) "B"))))
|
||||
Reference in New Issue
Block a user