Files
rose-ash/spec/tests/test-hyperscript-behavioral.sx
giles 1461919857 eval-hs helper + generator fixes — 304/941 (32%)
Added eval-hs: compile and evaluate HS expressions/commands, used by
conformance-dev tests. Smart wrapping: adds 'return' prefix for
expressions, leaves commands (set/put/get/then/return) as-is.

Fixed generator ref() to use context-aware variable mapping.

304/941 with the user's conformance-dev.sx tests included (110 new).
Failure breakdown: 111 stubs, 74 "bar" (eval errors), 51 assertion
failures, 30 eval-only stubs, 24 undefined "live", 18 parser errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:09:03 +00:00

7746 lines
329 KiB
Plaintext

;; Hyperscript behavioral tests — auto-generated from upstream _hyperscript test suite
;; Source: spec/tests/hyperscript-upstream-tests.json (831 tests, v0.9.14 + dev)
;; DO NOT EDIT — regenerate with: python3 tests/playwright/generate-sx-tests.py
;; ── Test helpers ──────────────────────────────────────────────────
(define hs-test-el
(fn (tag hs-src)
(let ((el (dom-create-element tag)))
(dom-set-attr el "_" hs-src)
(dom-append (dom-body) el)
(hs-activate! el)
el)))
(define hs-cleanup!
(fn ()
(dom-set-inner-html (dom-body) "")))
;; ── add (19 tests) ──
(defsuite "hs-upstream-add"
(deftest "can add class ref on a single div"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
))
(deftest "can add class ref w/ double dash on a single div"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo--bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo--bar"))
))
(deftest "can add class ref on a single form"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-set-attr _el-form "_" "on click add .foo")
(dom-append (dom-body) _el-form)
(hs-activate! _el-form)
(dom-dispatch _el-form "click" nil)
(assert (dom-has-class? _el-form "foo"))
))
(deftest "can target another div for class ref"
(hs-cleanup!)
(let ((_el-bar (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-bar "id" "bar")
(dom-append (dom-body) _el-bar)
(dom-set-attr _el-div "_" "on click add .foo to #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-bar "foo"))
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can add to query in me"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo to <p/> in me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can add to children"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo to my children")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can add non-class attributes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add [@foo=\"bar\"]")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-attr? _el-div "foo")))
(assert= "bar" (dom-get-attr _el-div "foo"))
))
(deftest "can add css properties"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add {color: red; font-family: monospace}")
(dom-set-attr _el-div "style" "color: blue")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "monospace" (dom-get-style _el-div "fontFamily"))
))
(deftest "can add templated css properties"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add {color: ${\"red\"};}")
(dom-set-attr _el-div "style" "color: blue")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can add multiple class refs"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (dom-has-class? _el-div "bar"))
))
(deftest "can add class refs w/ colons and dashes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo:bar-doh")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo:bar-doh"))
))
(deftest "can filter class addition via the when clause"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .rey to .bar when it matches .doh")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-add-class _el-div1 "bar")
(dom-append (dom-body) _el-div1)
(dom-add-class _el-div2 "bar")
(dom-add-class _el-div2 "doh")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert (not (dom-has-class? _el-div2 "rey")))
(assert (dom-has-class? _el-div2 "rey"))
))
(deftest "can filter property addition via the when clause"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add @rey to .bar when it matches .doh")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-add-class _el-div1 "bar")
(dom-append (dom-body) _el-div1)
(dom-add-class _el-div2 "bar")
(dom-add-class _el-div2 "doh")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert (not (dom-has-attr? _el-div2 "rey")))
(assert (dom-has-attr? _el-div2 "rey"))
))
(deftest "can add to an HTMLCollection"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo to the children of #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-append (dom-body) _el-bar)
(dom-dispatch _el-bar "click" nil)
;; SKIP check: skip byId("c1").classList.contains("foo").should.equal(false)
;; SKIP check: skip byId("c2").classList.contains("foo").should.equal(false)
;; SKIP check: skip byId("c1").classList.contains("foo").should.equal(true)
;; SKIP check: skip byId("c2").classList.contains("foo").should.equal(true)
))
(deftest "supports async expressions in when clause"
(hs-cleanup!)
(let ((_el-trigger (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-trigger "id" "trigger")
(dom-set-attr _el-trigger "_" "on click add .foo to #d2 when asyncCheck()")
(dom-append (dom-body) _el-trigger)
(hs-activate! _el-trigger)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch (dom-query-by-id "trigger") "click" nil)
(assert (dom-has-class? (dom-query-by-id "d2") "foo"))
))
(deftest "when clause sets result to matched elements"
(hs-cleanup!)
(let ((_el-trigger (dom-create-element "div")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-none (dom-create-element "div")))
(dom-set-attr _el-trigger "id" "trigger")
(dom-set-attr _el-trigger "_" "on click add .foo to .item when it matches .yes then if the result is empty show #none else hide #none")
(dom-append (dom-body) _el-trigger)
(hs-activate! _el-trigger)
(dom-set-attr _el-d1 "id" "d1")
(dom-add-class _el-d1 "item")
(dom-add-class _el-d1 "yes")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-add-class _el-d2 "item")
(dom-append (dom-body) _el-d2)
(dom-set-attr _el-none "id" "none")
(dom-set-attr _el-none "style" "display:none")
(dom-append (dom-body) _el-none)
(dom-dispatch (dom-query-by-id "trigger") "click" nil)
(assert (not (dom-visible? (dom-query-by-id "none"))))
))
(deftest "when clause result is empty when nothing matches"
(hs-cleanup!)
(let ((_el-trigger (dom-create-element "div")) (_el-d1 (dom-create-element "div")) (_el-none (dom-create-element "div")))
(dom-set-attr _el-trigger "id" "trigger")
(dom-set-attr _el-trigger "_" "on click add .foo to .item when it matches .nope then if the result is empty remove @hidden from #none")
(dom-append (dom-body) _el-trigger)
(hs-activate! _el-trigger)
(dom-set-attr _el-d1 "id" "d1")
(dom-add-class _el-d1 "item")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-none "id" "none")
(dom-append (dom-body) _el-none)
(dom-dispatch (dom-query-by-id "trigger") "click" nil)
(assert (not (dom-has-attr? (dom-query-by-id "none") "hidden")))
))
(deftest "can add a value to an array"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :arr to [1,2,3] add 4 to :arr put :arr as String into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1,2,3,4" (dom-text-content _el-div))
))
(deftest "can add a value to a set"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :s to [] as Set add 'a' to :s add 'b' to :s add 'a' to :s put :s.size into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "2" (dom-text-content _el-div))
))
)
;; ── remove (14 tests) ──
(defsuite "hs-upstream-remove"
(deftest "can remove class ref on a single div"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "foo")
(dom-set-attr _el-div "_" "on click remove .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can remove class ref on a single form"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-add-class _el-form "foo")
(dom-set-attr _el-form "_" "on click remove .foo")
(dom-append (dom-body) _el-form)
(hs-activate! _el-form)
(dom-dispatch _el-form "click" nil)
(assert (not (dom-has-class? _el-form "foo")))
))
(deftest "can target another div for class ref"
(hs-cleanup!)
(let ((_el-bar (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-bar "id" "bar")
(dom-add-class _el-bar "foo")
(dom-append (dom-body) _el-bar)
(dom-set-attr _el-div "_" "on click remove .foo from #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-bar "foo")))
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can remove non-class attributes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click remove [@foo]")
(dom-set-attr _el-div "foo" "bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "bar" (dom-get-attr _el-div "foo"))
(assert (not (dom-has-attr? _el-div "foo")))
))
(deftest "can remove elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click remove me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (not (nil? (dom-parent _el-div))))
(assert (nil? (dom-parent _el-div)))
))
(deftest "can remove other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-that (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click remove #that")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-that "id" "that")
(dom-append (dom-body) _el-that)
(dom-dispatch _el-that "click" nil)
(assert (not (nil? (dom-parent _el-that))))
(assert (nil? (dom-parent _el-that)))
))
(deftest "can remove parent element"
(hs-cleanup!)
(let ((_el-p1 (dom-create-element "div")))
(dom-set-attr _el-p1 "id" "p1")
(dom-append (dom-body) _el-p1)
(dom-dispatch _el-p1 "click" nil)
(assert (not (nil? (dom-parent _el-p1))))
(assert (nil? (dom-parent _el-p1)))
))
(deftest "can remove multiple class refs"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "foo")
(dom-add-class _el-div "bar")
(dom-add-class _el-div "doh")
(dom-set-attr _el-div "_" "on click remove .foo .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-div "foo")))
(assert (not (dom-has-class? _el-div "bar")))
(assert (dom-has-class? _el-div "doh"))
))
(deftest "can remove query refs from specific things"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip div.innerHTML.includes("foo").should.equal(true)
;; SKIP check: skip div.innerHTML.includes("bar").should.equal(true)
;; SKIP check: skip div.innerHTML.includes("doh").should.equal(true)
;; SKIP check: skip div.innerHTML.includes("foo").should.equal(false)
))
(deftest "can filter class removal via the when clause"
(hs-cleanup!)
(let ((_el-trigger (dom-create-element "div")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-trigger "id" "trigger")
(dom-set-attr _el-trigger "_" "on click remove .highlight from .item when it matches .old")
(dom-append (dom-body) _el-trigger)
(hs-activate! _el-trigger)
(dom-set-attr _el-d1 "id" "d1")
(dom-add-class _el-d1 "item")
(dom-add-class _el-d1 "old")
(dom-add-class _el-d1 "highlight")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-add-class _el-d2 "item")
(dom-add-class _el-d2 "highlight")
(dom-append (dom-body) _el-d2)
(dom-dispatch (dom-query-by-id "trigger") "click" nil)
(assert (not (dom-has-class? (dom-query-by-id "d1") "highlight")))
(assert (dom-has-class? (dom-query-by-id "d2") "highlight"))
))
(deftest "can remove CSS properties"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click remove {color} from me")
(dom-set-attr _el-div "style" "color: red; font-weight: bold;")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
))
(deftest "can remove multiple CSS properties"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click remove {color; font-weight} from me")
(dom-set-attr _el-div "style" "color: red; font-weight: bold; opacity: 0.5;")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
))
(deftest "can remove a value from an array"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :arr to [1,2,3,4] remove 3 from :arr put :arr as String into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1,2,4" (dom-text-content _el-div))
))
(deftest "can remove a value from a set"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :s to ['a','b','c'] as Set remove 'b' from :s put :s.size into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "2" (dom-text-content _el-div))
))
)
;; ── toggle (30 tests) ──
(defsuite "hs-upstream-toggle"
(deftest "can toggle class ref on a single div"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can toggle class ref on a single form"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-set-attr _el-form "_" "on click toggle .foo")
(dom-append (dom-body) _el-form)
(hs-activate! _el-form)
(dom-dispatch _el-form "click" nil)
(dom-dispatch _el-form "click" nil)
(assert (not (dom-has-class? _el-form "foo")))
))
(deftest "can target another div for class ref toggle"
(hs-cleanup!)
(let ((_el-bar (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-bar "id" "bar")
(dom-append (dom-body) _el-bar)
(dom-set-attr _el-div "_" "on click toggle .foo on #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-bar "foo")))
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can toggle non-class attributes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle [@foo=\"bar\"]")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-attr? _el-div "foo")))
(assert= "bar" (dom-get-attr _el-div "foo"))
))
(deftest "can toggle non-class attributes on selects"
(hs-cleanup!)
(let ((_el-select (dom-create-element "select")))
(dom-set-attr _el-select "_" "on click toggle [@foo=\"bar\"]")
(dom-append (dom-body) _el-select)
(hs-activate! _el-select)
(dom-dispatch _el-select "click" nil)
(dom-dispatch _el-select "click" nil)
(assert (not (dom-has-attr? _el-select "foo")))
(assert= "bar" (dom-get-attr _el-select "foo"))
))
(deftest "can toggle for a fixed amount of time"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle .foo for 10ms")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can toggle until an event on another element"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-div "_" "on click toggle .foo until foo from #d1")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-d1 "foo" nil)
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can toggle between two classes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "foo")
(dom-set-attr _el-div "_" "on click toggle between .foo and .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (not (dom-has-class? _el-div "bar")))
))
(deftest "can toggle multiple class refs"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "bar")
(dom-set-attr _el-div "_" "on click toggle .foo .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-div "foo")))
(assert (dom-has-class? _el-div "bar"))
))
(deftest "can toggle display"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle *display")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.display
))
(deftest "can toggle opacity"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle *opacity")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.opacity
))
(deftest "can toggle opacity"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle *visibility")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.visibility
))
(deftest "can toggle display w/ my"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle my *display")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.display
))
(deftest "can toggle display w/ my"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle my *opacity")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.opacity
))
(deftest "can toggle display w/ my"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle my *visibility")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.visibility
))
(deftest "can toggle display on other elt"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle the *display of #d2")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(dom-dispatch _el-d2 "click" nil)
;; SKIP computed style: div2.display
))
(deftest "can toggle display on other elt"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle the *opacity of #d2")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(dom-dispatch _el-d2 "click" nil)
;; SKIP computed style: div2.opacity
))
(deftest "can toggle display on other elt"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle the *visibility of #d2")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(dom-dispatch _el-d2 "click" nil)
;; SKIP computed style: div2.visibility
))
(deftest "can toggle crazy tailwinds class ref on a single form"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-set-attr _el-form "_" "on click toggle .group-[:nth-of-type(3)_&]:block")
(dom-append (dom-body) _el-form)
(hs-activate! _el-form)
(dom-dispatch _el-form "click" nil)
(dom-dispatch _el-form "click" nil)
(assert (not (dom-has-class? _el-form "group-[:nth-of-type(3)_&]:block")))
))
(deftest "can toggle between two attribute values"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "inactive" (dom-get-attr _el-div "data-state"))
(dom-dispatch _el-div "click" nil)
(assert= "active" (dom-get-attr _el-div "data-state"))
))
(deftest "can toggle between different attributes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "true" (dom-get-attr _el-div "disabled"))
(dom-dispatch _el-div "click" nil)
(assert= "true" (dom-get-attr _el-div "enabled"))
))
(deftest "can toggle visibility"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle *visibility")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "hidden" (dom-get-style _el-div "visibility"))
(dom-dispatch _el-div "click" nil)
(assert= "visible" (dom-get-style _el-div "visibility"))
))
(deftest "can toggle opacity w/ my"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle my *opacity")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "0" (dom-get-style _el-div "opacity"))
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-get-style _el-div "opacity"))
))
(deftest "can toggle visibility w/ my"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle my *visibility")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "hidden" (dom-get-style _el-div "visibility"))
(dom-dispatch _el-div "click" nil)
(assert= "visible" (dom-get-style _el-div "visibility"))
))
(deftest "can toggle opacity on other elt"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle the *opacity of #d2")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
))
(deftest "can toggle visibility on other elt"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click toggle the *visibility of #d2")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
))
(deftest "can toggle *display between two values"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "flex" (dom-get-style _el-div "display"))
(dom-dispatch _el-div "click" nil)
(assert= "none" (dom-get-style _el-div "display"))
))
(deftest "can toggle *opacity between three values"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "0.5" (dom-get-style _el-div "opacity"))
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-get-style _el-div "opacity"))
(dom-dispatch _el-div "click" nil)
(assert= "0" (dom-get-style _el-div "opacity"))
))
(deftest "can toggle a global variable between two values"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
))
(deftest "can toggle a global variable between three values"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
))
)
;; ── set (25 tests) ──
(defsuite "hs-upstream-set"
(deftest "can set properties"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can set indirect properties"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can set complex indirect properties lhs"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "can set complex indirect properties rhs"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "can set chained indirect properties"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "can set styles"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can set javascript globals"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip window["temp"].should.equal("red")
))
(deftest "can set local variables"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click set newVar to \"foo\" then put newVar into #d1.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can set into id ref"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can set into class ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")))
(dom-add-class _el-div "divs")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "divs")
(dom-append (dom-body) _el-div1)
(dom-dispatch _el-div1 "click" nil)
(assert= "foo" (dom-inner-html _el-div1))
(assert= "foo" (dom-inner-html _el-div1))
))
(deftest "can set into attribute ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "divs")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-get-attr _el-div "bar"))
))
(deftest "can set into indirect attribute ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click set #div2's @bar to 'foo'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "foo" (dom-get-attr _el-div2 "bar"))
))
(deftest "can set into indirect attribute ref 2"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click set #div2's @bar to 'foo'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "foo" (dom-get-attr _el-div2 "bar"))
))
(deftest "can set into indirect attribute ref 3"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click set @bar of #div2 to 'foo'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "foo" (dom-get-attr _el-div2 "bar"))
))
(deftest "can set into style ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "divs")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip d1.style["color"].should.equal("red")
))
(deftest "can set into indirect style ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click set #div2's *color to 'red'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
;; SKIP check: skip d2.style["color"].should.equal("red")
))
(deftest "can set into indirect style ref 2"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click set #div2's *color to 'red'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
;; SKIP check: skip d2.style["color"].should.equal("red")
))
(deftest "can set into indirect style ref 3"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click set *color of #div2 to 'red'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
;; SKIP check: skip d2.style["color"].should.equal("red")
))
(deftest "set waits on promises"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click set #d1.innerHTML to promiseAString()")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can set many properties at once with object literal"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set {bar: 2, baz: 3} on obj")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
;; SKIP check: skip obj.should.deep.equal({ foo: 1, bar: 2, baz: 3 })
))
(deftest "can set props w/ array access syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can set props w/ array access syntax and var"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can set arrays w/ array access syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set arr to [1, 2, 3] set arr[0] to \"red\" set my *color to arr[0]")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can set arrays w/ array access syntax and var"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set arr to [1, 2, 3] set idx to 0 set arr[idx] to \"red\" set my *color to arr[0]")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "handles set url regression properly"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set trackingcode to `foo` set pdfurl to `https://yyy.xxxxxx.com/path/out/${trackingcode}.pdf` put pdfurl into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip d1.innerText.should.equal("https://yyy.xxxxxx.com/path/out/f
))
)
;; ── put (38 tests) ──
(defsuite "hs-upstream-put"
(deftest "can set properties"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"foo\" into #d1.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can put directly into nodes"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"foo\" into #d1")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-text-content _el-d1))
))
(deftest "can put nodes into nodes"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "_" "on click put #d1 into #d2")
(dom-append (dom-body) _el-d2)
(hs-activate! _el-d2)
(dom-dispatch _el-d2 "click" nil)
;; SKIP check: skip d2.firstChild.should.equal(d1)
))
(deftest "can put directly into symbols"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"foo\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "me symbol doesn't get stomped on direct write"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"foo\" into me then put \"bar\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "bar" (dom-inner-html _el-div))
))
(deftest "can set styles"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"red\" into my.style.color")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can set javascript globals"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"red\" into window.temp")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip window["temp"].should.equal("red")
))
(deftest "can set into class ref w/ flatmapped property"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"foo\" into .divs.parentElement.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert= "foo" (dom-text-content _el-d1))
(assert= "foo" (dom-text-content _el-d2))
))
(deftest "can set into class ref w/ flatmapped property using of"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"foo\" into innerHTML of parentElement of .divs")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert= "foo" (dom-text-content _el-d1))
(assert= "foo" (dom-text-content _el-d2))
))
(deftest "can set local variables"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"foo\" into newVar then put newVar into #d1.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can set into id ref"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"foo\" into #d1.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can insert before"
(hs-cleanup!)
(let ((_el-d2 (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "_" "on click put #d1 before #d2")
(dom-append (dom-body) _el-d2)
(hs-activate! _el-d2)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d2 "click" nil)
;; SKIP check: skip d2.previousSibling.textContent.should.equal("foo")
))
(deftest "can insert after"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "_" "on click put #d1 after #d2")
(dom-append (dom-body) _el-d2)
(hs-activate! _el-d2)
(dom-dispatch _el-d2 "click" nil)
;; SKIP check: skip d2.nextSibling.textContent.should.equal("foo")
))
(deftest "can insert after beginning"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"foo\" at start of #d1")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo*" (dom-text-content _el-d1))
))
(deftest "can insert before end"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"foo\" at end of #d1")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "*foo" (dom-text-content _el-d1))
))
(deftest "can set into attribute ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put \"foo\" into @bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-get-attr _el-div "bar"))
))
(deftest "can set into indirect attribute ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put \"foo\" into my @bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-get-attr _el-div "bar"))
))
(deftest "can set into indirect attribute ref 2"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put 'foo' into #div2's @bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "foo" (dom-get-attr _el-div2 "bar"))
))
(deftest "can set into indirect attribute ref 3"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put 'foo' into @bar of #div2")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "foo" (dom-get-attr _el-div2 "bar"))
))
(deftest "can set into style ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put \"red\" into *color")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip d1.style["color"].should.equal("red")
))
(deftest "can set into indirect style ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put \"red\" into my *color")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip d1.style["color"].should.equal("red")
))
(deftest "can set into indirect style ref 2"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put 'red' into #div2's *color")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
;; SKIP check: skip d2.style["color"].should.equal("red")
))
(deftest "can set into indirect style ref 3"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put 'red' into the *color of #div2")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "id" "div2")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
;; SKIP check: skip d2.style["color"].should.equal("red")
))
(deftest "waits on promises"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put promiseAString() into #d1.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "foo" (dom-inner-html _el-d1))
))
(deftest "can put properties w/ array access syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"red\" into my style[\"color\"]")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can put properties w/ array access syntax and var"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set foo to \"color\" then put \"red\" into my style[foo]")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can put array vals w/ array access syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set arr to [1, 2, 3] put \"red\" into arr[0] put arr[0] into my *color")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "can put array vals w/ array access syntax and var"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set arr to [1, 2, 3] set idx to 0 put \"red\" into arr[idx] put arr[0] into my *color")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "red" (dom-get-style _el-div "color"))
))
(deftest "properly processes hyperscript in new content in a symbol write"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"<button id=\"b1\" _=\"on click put 42 into me\">40</button>\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "42" (dom-inner-html _el-div))
))
(deftest "properly processes hyperscript in new content in a element target"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"<button id=\"b1\" _=\"on click put 42 into me\">40</button>\" into <div#d1/>")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(dom-dispatch _el-d1 "click" nil)
(assert= "42" (dom-inner-html _el-d1))
))
(deftest "properly processes hyperscript in before"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"<button id=\"b1\" _=\"on click put 42 into me\">40</button>\" before me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(dom-dispatch _el-d1 "click" nil)
(assert= "42" (dom-inner-html _el-d1))
))
(deftest "properly processes hyperscript at start of"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"<button id=\"b1\" _=\"on click put 42 into me\">40</button>\" at the start of me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(dom-dispatch _el-d1 "click" nil)
(assert= "42" (dom-inner-html _el-d1))
))
(deftest "properly processes hyperscript at end of"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"<button id=\"b1\" _=\"on click put 42 into me\">40</button>\" at the end of me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(dom-dispatch _el-d1 "click" nil)
(assert= "42" (dom-inner-html _el-d1))
))
(deftest "properly processes hyperscript after"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put \"<button id=\"b1\" _=\"on click put 42 into me\">40</button>\" after me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(dom-dispatch _el-d1 "click" nil)
(assert= "42" (dom-inner-html _el-d1))
))
(deftest "is null tolerant"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "divs")
(dom-set-attr _el-div "_" "on click put \"red\" into #a-bad-id-that-does-not-exist")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
))
(deftest "put null into attribute removes it"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put null into @foo")
(dom-set-attr _el-d1 "foo" "bar")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert (not (dom-has-attr? (dom-query-by-id "d1") "foo")))
))
(deftest "can put at start of an array"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :arr to [2,3] put 1 at start of :arr put :arr as String into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1,2,3" (dom-text-content _el-div))
))
(deftest "can put at end of an array"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :arr to [1,2] put 3 at end of :arr put :arr as String into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1,2,3" (dom-text-content _el-div))
))
)
;; ── hide (14 tests) ──
(defsuite "hs-upstream-hide"
(deftest "can hide element with no target"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.display
))
(deftest "hide element then show element retains original display"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click 1 hide on click 2 show")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "" (dom-get-style _el-div "display"))
;; SKIP computed style: div.display
))
(deftest "can hide element with no target followed by command"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.display
(assert (dom-has-class? _el-div "foo"))
))
(deftest "can hide element with no target followed by then"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide then add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.display
(assert (dom-has-class? _el-div "foo"))
))
(deftest "can hide element with no target with a with"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide with display then add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.display
(assert (dom-has-class? _el-div "foo"))
))
(deftest "can hide element, with display:none by default"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.display
))
(deftest "can hide element with display:none explicitly"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide me with display")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.display
))
(deftest "can hide element with opacity:0"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide me with opacity")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.opacity
))
(deftest "can hide element with opacity style literal"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide me with *opacity")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.opacity
))
(deftest "can hide element, with visibility:hidden"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide me with visibility")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP computed style: div.visibility
))
(deftest "can hide other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")))
(dom-add-class _el-div "hideme")
(dom-append (dom-body) _el-div)
(dom-set-attr _el-div1 "_" "on click hide .hideme")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-dispatch _el-div1 "click" nil)
;; SKIP computed style: hideme.display
))
(deftest "can hide with custom strategy"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide with myHide")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
;; SKIP action: classList.remove__foo__
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
))
(deftest "can set default to custom strategy"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click hide")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
;; SKIP action: classList.remove__foo__
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
))
(deftest "can filter hide via the when clause"
(hs-cleanup!)
(let ((_el-trigger (dom-create-element "div")))
(dom-set-attr _el-trigger "id" "trigger")
(dom-set-attr _el-trigger "_" "on click hide <div/> in me when it matches .hideable")
(dom-append (dom-body) _el-trigger)
(hs-activate! _el-trigger)
(dom-dispatch (dom-query-by-id "trigger") "click" nil)
(assert= "none" (dom-get-style (dom-query-by-id "d1") "display"))
(assert= "block" (dom-get-style (dom-query-by-id "d2") "display"))
))
)
;; ── if (19 tests) ──
(defsuite "hs-upstream-if"
(deftest "basic true branch works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if true put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic true branch works with multiple commands"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if true log me then put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic true branch works with end"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if true put \"foo\" into me.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic true branch works with naked else"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if true put \"foo\" into me.innerHTML else")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic true branch works with naked else end"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if true put \"foo\" into me.innerHTML else end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic else branch works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false else put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic else branch works with end"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false else put \"foo\" into me.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic else if branch works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false else if true put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic else if branch works with end"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false else if true put \"foo\" into me.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "otherwise alias works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false otherwise put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "triple else if branch works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false else if false else put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "triple else if branch works with end"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false else if false else put \"foo\" into me.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "basic else branch works with multiple commands"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false put \"bar\" into me.innerHTML else log me then put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "true branch with a wait works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if true wait 10 ms then put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "false branch with a wait works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false else wait 10 ms then put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "if properly passes execution along if child is not executed"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click if false end put \"foo\" into me.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "if properly supports nested if statements and end block"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click n if window.tmp thenn put \"foo\" into men else if not window.tmp thenn // do nothingn endn catch en // just here for the parsing...n")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "foo" (dom-inner-html _el-div))
))
(deftest "if on new line does not join w/ else"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click n if window.tmp thenn elsen if window.tmp then endn put \"foo\" into men endn")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "" (dom-inner-html _el-div))
))
(deftest "passes the sieve test"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── repeat (30 tests) ──
(defsuite "hs-upstream-repeat"
(deftest "basic for loop works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat for x in [1, 2, 3] put x at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "123" (dom-inner-html _el-div))
))
(deftest "basic for loop with null works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat for x in null put x at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "" (dom-inner-html _el-div))
))
(deftest "waiting in for loop works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat for x in [1, 2, 3]n log me put x at end of men wait 1msn end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "123" (dom-inner-html _el-div))
))
(deftest "basic raw for loop works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click for x in [1, 2, 3] put x at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "123" (dom-inner-html _el-div))
))
(deftest "basic raw for loop works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click for x in null put x at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "" (dom-inner-html _el-div))
))
(deftest "waiting in raw for loop works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click for x in [1, 2, 3]n put x at end of men wait 1msn end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "123" (dom-inner-html _el-div))
))
(deftest "repeat forever works"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put repeatForeverWithReturn() into my.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "5" (dom-inner-html _el-d1))
))
(deftest "repeat forever works w/o keyword"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put repeatForeverWithReturn() into my.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "5" (dom-inner-html _el-d1))
))
(deftest "basic in loop works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat in [1, 2, 3] put it at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "123" (dom-inner-html _el-div))
))
(deftest "index syntax works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat for x in [\"a\", \"ab\", \"abc\"] index i put x + i at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "a0ab1abc2" (dom-inner-html _el-div))
))
(deftest "indexed by syntax works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat for x in [\"a\", \"ab\", \"abc\"] indexed by i put x + i at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "a0ab1abc2" (dom-inner-html _el-div))
))
(deftest "while keyword works"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put repeatWhileTest() into my.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "5" (dom-inner-html _el-d1))
))
(deftest "until keyword works"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click put repeatUntilTest() into my.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "5" (dom-inner-html _el-d1))
))
(deftest "until event keyword works"
(hs-cleanup!)
(let ((_el-untilTest (dom-create-element "div")) (_el-script (dom-create-element "script")))
(dom-set-attr _el-untilTest "id" "untilTest")
(dom-append (dom-body) _el-untilTest)
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-dispatch _el-untilTest "click" nil)
;; SKIP check: skip value.should.equal(42)
))
(deftest "only executes the init expression once"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click for x in getArray() put x into my.innerHTML end")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "3" (dom-inner-html _el-d1))
;; SKIP check: skip window.called.should.equal(1)
))
(deftest "can nest loops"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click call sprayInto(me)")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "123246369" (dom-inner-html _el-d1))
))
(deftest "basic times loop works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat 3 times put \"a\" at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "aaa" (dom-inner-html _el-div))
))
(deftest "times loop with expression works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat 3 + 3 times put \"a\" at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "aaaaaa" (dom-inner-html _el-div))
))
(deftest "loop continue works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat 2 times for x in ['A', 'B', 'C', 'D'] if (x != 'D') then put 'success ' + x + '. ' at end of me continue put 'FAIL!!. ' at end of me end put 'expected D. ' at end of me end end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "success A. success B. success C. expected D. success A. success B. success C. expected D. " (dom-inner-html _el-div))
))
(deftest "loop break works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat 2 times for x in ['A', 'B', 'C', 'D'] if x is 'C' break end put x at end of me end end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "ABAB" (dom-inner-html _el-div))
))
(deftest "basic raw for loop with null works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click for x in null put x at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "" (dom-text-content _el-div))
))
(deftest "basic property for loop works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to {foo:1, bar:2, baz:3} for prop in x put x[prop] at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "123" (dom-text-content _el-div))
))
(deftest "bottom-tested repeat until"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to 0 repeat set x to until x is 3 end put x into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "3" (dom-text-content _el-div))
))
(deftest "bottom-tested repeat while"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to 0 repeat set x to while x < 3 end put x into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "3" (dom-text-content _el-div))
))
(deftest "bottom-tested loop always runs at least once"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to 0 repeat set x to until true end put x into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-text-content _el-div))
))
(deftest "break exits a simple repeat loop"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to 0 repeat 10 times set x to x + 1 if x is 3 break end end put x into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "3" (dom-text-content _el-div))
))
(deftest "continue skips rest of iteration in simple repeat loop"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat for x in [1, 2, 3, 4, 5] if x is 3 continue end put x at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1245" (dom-text-content _el-div))
))
(deftest "break exits a for-in loop"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat for x in [1, 2, 3, 4, 5] if x is 4 break end put x at end of me end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "123" (dom-text-content _el-div))
))
(deftest "break exits a while loop"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to 0 repeat while x < 100 set x to x + 1 if x is 5 break end end put x into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "5" (dom-text-content _el-div))
))
(deftest "for loop over undefined skips without error"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click repeat for x in doesNotExist put x at end of me end then put \"done\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "done" (dom-text-content _el-div))
))
)
;; ── wait (7 tests) ──
(defsuite "hs-upstream-wait"
(deftest "can wait on time"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo then wait 20ms then add .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (dom-has-class? _el-div "bar"))
))
(deftest "can wait on event"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo then wait for foo then add .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (dom-has-class? _el-div "bar"))
))
(deftest "waiting on an event sets 'it' to the event"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click wait for foo then put its.detail into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
(assert= "hyperscript is hyper cool" (dom-inner-html _el-div))
))
(deftest "can destructure properties in a wait"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click wait for foo(bar) then put bar into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
(assert= "bar" (dom-inner-html _el-div))
))
(deftest "can wait on event on another element"
(hs-cleanup!)
(let ((_el-d2 (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-set-attr _el-div "_" "on click add .foo then wait for foo from #d2 then add .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (dom-has-class? _el-div "bar"))
))
(deftest "can wait on event or timeout 1"
(hs-cleanup!)
(let ((_el-d2 (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-set-attr _el-div "_" "on click add .foo then wait for foo or 0ms then add .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (dom-has-class? _el-div "bar"))
))
(deftest "can wait on event or timeout 2"
(hs-cleanup!)
(let ((_el-d2 (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-set-attr _el-div "_" "on click add .foo then wait for foo or 0ms then add .bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (dom-has-class? _el-div "bar"))
))
)
;; ── send (8 tests) ──
(defsuite "hs-upstream-send"
(deftest "can send events"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send foo to #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-set-attr _el-bar "_" "on foo add .foo-sent")
(dom-append (dom-body) _el-bar)
(hs-activate! _el-bar)
(dom-dispatch _el-bar "click" nil)
(assert (dom-has-class? _el-bar "foo-sent"))
))
(deftest "can reference sender in events"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click log 0 send foo to #bar log 3")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-set-attr _el-bar "_" "on foo add .foo-sent to sender log 1, me, sender")
(dom-append (dom-body) _el-bar)
(hs-activate! _el-bar)
(dom-dispatch _el-bar "click" nil)
(assert (dom-has-class? _el-bar "foo-sent"))
))
(deftest "can send events with args"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send foo(x:42) to #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-set-attr _el-bar "_" "on foo put event.detail.x into my.innerHTML")
(dom-append (dom-body) _el-bar)
(hs-activate! _el-bar)
(dom-dispatch _el-bar "click" nil)
(assert (not (dom-has-class? _el-bar "foo-sent")))
(assert= "42" (dom-inner-html _el-bar))
))
(deftest "can send events with dots"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send foo.bar to #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-set-attr _el-bar "_" "on foo.bar add .foo-sent")
(dom-append (dom-body) _el-bar)
(hs-activate! _el-bar)
(dom-dispatch _el-bar "click" nil)
(assert (dom-has-class? _el-bar "foo-sent"))
))
(deftest "can send events with dots with args"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send foo.bar(x:42) to #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-set-attr _el-bar "_" "on foo.bar put event.detail.x into my.innerHTML")
(dom-append (dom-body) _el-bar)
(hs-activate! _el-bar)
(dom-dispatch _el-bar "click" nil)
(assert (not (dom-has-class? _el-bar "foo-sent")))
(assert= "42" (dom-inner-html _el-bar))
))
(deftest "can send events with colons"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send foo:bar to #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-set-attr _el-bar "_" "on foo:bar add .foo-sent")
(dom-append (dom-body) _el-bar)
(hs-activate! _el-bar)
(dom-dispatch _el-bar "click" nil)
(assert (dom-has-class? _el-bar "foo-sent"))
))
(deftest "can send events with colons with args"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send foo:bar(x:42) to #bar")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-set-attr _el-bar "_" "on foo:bar put event.detail.x into my.innerHTML")
(dom-append (dom-body) _el-bar)
(hs-activate! _el-bar)
(dom-dispatch _el-bar "click" nil)
(assert (not (dom-has-class? _el-bar "foo-sent")))
(assert= "42" (dom-inner-html _el-bar))
))
(deftest "can send events to any expression"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-bar (dom-create-element "div")))
(dom-set-attr _el-div "_" "def bar return #bar on click send foo to bar()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-bar "id" "bar")
(dom-set-attr _el-bar "_" "on foo add .foo-sent")
(dom-append (dom-body) _el-bar)
(hs-activate! _el-bar)
(dom-dispatch _el-bar "click" nil)
(assert (dom-has-class? _el-bar "foo-sent"))
))
)
;; ── take (12 tests) ──
(defsuite "hs-upstream-take"
(deftest "can take a class from other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "div")
(dom-add-class _el-div "foo")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take .foo from .div")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-add-class _el-div2 "div")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert (not (dom-has-class? _el-div2 "foo")))
(assert (dom-has-class? _el-div2 "foo"))
(assert (not (dom-has-class? _el-div2 "foo")))
))
(deftest "can take a class from other forms"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")) (_el-form1 (dom-create-element "form")) (_el-form2 (dom-create-element "form")))
(dom-add-class _el-form "div")
(dom-add-class _el-form "foo")
(dom-append (dom-body) _el-form)
(dom-add-class _el-form1 "div")
(dom-set-attr _el-form1 "_" "on click take .foo from .div")
(dom-append (dom-body) _el-form1)
(hs-activate! _el-form1)
(dom-add-class _el-form2 "div")
(dom-append (dom-body) _el-form2)
(dom-dispatch _el-form2 "click" nil)
(assert (not (dom-has-class? _el-form2 "foo")))
(assert (dom-has-class? _el-form2 "foo"))
(assert (not (dom-has-class? _el-form2 "foo")))
))
(deftest "can take a class for other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-d3 (dom-create-element "div")))
(dom-add-class _el-div "div")
(dom-add-class _el-div "foo")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take .foo from .div for #d3")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-set-attr _el-d3 "id" "d3")
(dom-add-class _el-d3 "div")
(dom-append (dom-body) _el-d3)
(dom-dispatch _el-d3 "click" nil)
(assert (not (dom-has-class? _el-d3 "foo")))
(assert (not (dom-has-class? _el-d3 "foo")))
(assert (dom-has-class? _el-d3 "foo"))
))
(deftest "a parent can take a class for other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click take .foo from .div for event.target")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-div "foo")))
(assert (dom-has-class? _el-div "foo"))
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "can take an attribute from other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "div")
(dom-set-attr _el-div "data-foo" "bar")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take @data-foo from .div")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-add-class _el-div2 "div")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "bar" (dom-get-attr _el-div2 "data-foo"))
(assert= "" (dom-get-attr _el-div2 "data-foo"))
;; SKIP check: skip assert.isNull(d2.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d3.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d1.getAttribute("data-foo")
))
(deftest "can take an attribute with specific value from other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "div")
(dom-set-attr _el-div "data-foo" "bar")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take @data-foo=baz from .div")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-add-class _el-div2 "div")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "bar" (dom-get-attr _el-div2 "data-foo"))
(assert= "baz" (dom-get-attr _el-div2 "data-foo"))
;; SKIP check: skip assert.isNull(d2.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d3.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d1.getAttribute("data-foo")
))
(deftest "can take an attribute value from other elements and set specific values instead"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "div")
(dom-set-attr _el-div "data-foo" "bar")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take @data-foo=baz with \"qux\" from .div")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-add-class _el-div2 "div")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "qux" (dom-get-attr _el-div2 "data-foo"))
(assert= "baz" (dom-get-attr _el-div2 "data-foo"))
(assert= "qux" (dom-get-attr _el-div2 "data-foo"))
;; SKIP check: skip assert.isNull(d2.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d3.getAttribute("data-foo")
))
(deftest "can take an attribute value from other elements and set value from an expression instead"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "div")
(dom-set-attr _el-div "data-foo" "bar")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take @data-foo=baz with my @data-foo from .div")
(dom-set-attr _el-div1 "data-foo" "qux")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-add-class _el-div2 "div")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert= "qux" (dom-get-attr _el-div2 "data-foo"))
(assert= "baz" (dom-get-attr _el-div2 "data-foo"))
(assert= "qux" (dom-get-attr _el-div2 "data-foo"))
;; SKIP check: skip assert.isNull(d3.getAttribute("data-foo")
))
(deftest "can take an attribute for other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-d3 (dom-create-element "div")))
(dom-add-class _el-div "div")
(dom-set-attr _el-div "data-foo" "bar")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take @data-foo from .div for #d3")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-set-attr _el-d3 "id" "d3")
(dom-add-class _el-d3 "div")
(dom-append (dom-body) _el-d3)
(dom-dispatch _el-d3 "click" nil)
(assert= "bar" (dom-get-attr _el-d3 "data-foo"))
(assert= "" (dom-get-attr _el-d3 "data-foo"))
;; SKIP check: skip assert.isNull(d2.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d3.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d1.getAttribute("data-foo")
))
(deftest "a parent can take an attribute for other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click take @data-foo from .div for event.target")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "bar" (dom-get-attr _el-div "data-foo"))
(assert= "" (dom-get-attr _el-div "data-foo"))
;; SKIP check: skip assert.isNull(d2.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d3.getAttribute("data-foo")
;; SKIP check: skip assert.isNull(d1.getAttribute("data-foo")
))
(deftest "can take multiple classes from other elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "div")
(dom-add-class _el-div "foo")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take .foo .bar")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-add-class _el-div2 "div")
(dom-add-class _el-div2 "bar")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert (not (dom-has-class? _el-div2 "foo")))
(assert (dom-has-class? _el-div2 "foo"))
(assert (not (dom-has-class? _el-div2 "foo")))
(assert (not (dom-has-class? _el-div2 "bar")))
(assert (dom-has-class? _el-div2 "bar"))
(assert (not (dom-has-class? _el-div2 "bar")))
))
(deftest "can take multiple classes from specific element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "div1")
(dom-add-class _el-div "foo")
(dom-add-class _el-div "bar")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "div")
(dom-set-attr _el-div1 "_" "on click take .foo .bar from .div1")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-add-class _el-div2 "div")
(dom-add-class _el-div2 "bar")
(dom-append (dom-body) _el-div2)
(dom-dispatch _el-div2 "click" nil)
(assert (not (dom-has-class? _el-div2 "foo")))
(assert (dom-has-class? _el-div2 "foo"))
(assert (not (dom-has-class? _el-div2 "foo")))
(assert (not (dom-has-class? _el-div2 "bar")))
(assert (dom-has-class? _el-div2 "bar"))
(assert (dom-has-class? _el-div2 "bar"))
))
)
;; ── transition (23 tests) ──
(defsuite "hs-upstream-transition"
(deftest "can transition a single property on current element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "100px" (dom-get-style _el-div "width"))
))
(deftest "can transition with parameterized values"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set startWidth to 0 set endWidth to 100 transition width from (startWidth)px to (endWidth)px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "100px" (dom-get-style _el-div "width"))
))
(deftest "can transition a single property on form"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-set-attr _el-form "_" "on click transition width from 0px to 100px")
(dom-append (dom-body) _el-form)
(hs-activate! _el-form)
(dom-dispatch _el-form "click" nil)
(assert= "100px" (dom-get-style _el-form "width"))
))
(deftest "can transition a single property on current element with the my prefix"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition my width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "100px" (dom-get-style _el-div "width"))
))
(deftest "can transition two properties on current element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition width from 0px to 100px height from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "100px" (dom-get-style _el-div "height"))
))
(deftest "can transition on another element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition element #foo width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
(dom-dispatch _el-foo "click" nil)
(assert= "100px" (dom-get-style _el-foo "width"))
))
(deftest "can transition on another element no element prefix"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition #foo width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
(dom-dispatch _el-foo "click" nil)
(assert= "100px" (dom-get-style _el-foo "width"))
))
(deftest "can transition on another element no element prefix + possessive"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition #foo's width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
(dom-dispatch _el-foo "click" nil)
(assert= "100px" (dom-get-style _el-foo "width"))
))
(deftest "can transition on another element no element prefix with it"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click get #foo then transition its width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
(dom-dispatch _el-foo "click" nil)
(assert= "100px" (dom-get-style _el-foo "width"))
))
(deftest "can transition with a custom transition time"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
(dom-dispatch _el-foo "click" nil)
(assert= "100px" (dom-get-style _el-foo "width"))
))
(deftest "can transition with a custom transition time via the over syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition element #foo width from 0px to 100px over 2s")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
(dom-dispatch _el-foo "click" nil)
(assert= "100px" (dom-get-style _el-foo "width"))
))
(deftest "can transition a single property on current element using style ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition *width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "100px" (dom-get-style _el-div "width"))
))
(deftest "can transition a single property on form using style ref"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-set-attr _el-form "_" "on click transition *width from 0px to 100px")
(dom-append (dom-body) _el-form)
(hs-activate! _el-form)
(dom-dispatch _el-form "click" nil)
(assert= "100px" (dom-get-style _el-form "width"))
))
(deftest "can transition a single property on current element with the my prefix using style ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition my *width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "100px" (dom-get-style _el-div "width"))
))
(deftest "can use initial to transition to original value"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click 1 transition my *width to 100px on click 2 transition my *width to initial")
(dom-set-attr _el-div "style" "width: 10px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "10px" (dom-get-style _el-div "width"))
))
(deftest "can transition on another element with of syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition *width of #foo from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
))
(deftest "can transition on another element with possessive"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition #foo's *width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
))
(deftest "can transition on another element with it"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click get #foo then transition its *width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
))
(deftest "can transition with a custom transition string"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-set-attr _el-foo "id" "foo")
(dom-append (dom-body) _el-foo)
))
(deftest "can transition a single property on form using style ref"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-set-attr _el-form "_" "on click transition *width from 0px to 100px")
(dom-append (dom-body) _el-form)
(hs-activate! _el-form)
))
(deftest "can transition a single property on current element with the my prefix using style ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click transition my *width from 0px to 100px")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "can transition on query ref with possessive"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can transition on query ref with of syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-span (dom-create-element "span")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-append (dom-body) _el-span)
(dom-dispatch _el-div "click" nil)
(assert= "100px" (dom-get-style _el-span "width"))
))
)
;; ── log (4 tests) ──
(defsuite "hs-upstream-log"
(deftest "can log single item"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click log me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
))
(deftest "can log multiple items"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click log me, my")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
))
(deftest "can log multiple items with debug"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click log me, my with console.debug")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
))
(deftest "can log multiple items with error"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click log me, my with console.error")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
))
)
;; ── call (6 tests) ──
(defsuite "hs-upstream-call"
(deftest "can call javascript instance functions"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click call document.getElementById(\"d1\") then put it into window.results")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
;; SKIP check: skip value.should.equal(d1)
))
(deftest "can call global javascript functions"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click call globalFunction(\"foo\")")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip "foo".should.equal(calledWith)
))
(deftest "can call no argument functions"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click call globalFunction()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip called.should.equal(true)
))
(deftest "can call functions w/ underscores"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click call global_function()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip called.should.equal(true)
))
(deftest "can call functions w/ dollar signs"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click call $()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip called.should.equal(true)
))
(deftest "call functions that return promises are waited on"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click call promiseAnInt() then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip div.innerText.should.equal("")
;; SKIP check: skip div.innerText.should.equal("42")
))
)
;; ── fetch (23 tests) ──
(defsuite "hs-upstream-fetch"
(deftest "can do a simple fetch"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch \"/test\" then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "can do a simple fetch w/ a naked URL"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "can do a simple fetch w/ html"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as html then log it then put it into my.innerHTML put its childElementCount into my @data-count")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "[object DocumentFragment]" (dom-inner-html _el-div))
;; SKIP check: skip div.dataset.count.should.equal("1")
))
(deftest "can do a simple fetch w/ json"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as json then get result as JSON then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "'{\"foo\":1}'" (dom-inner-html _el-div))
))
(deftest "can do a simple fetch w/ json using Object syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as Object then get result as JSON then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "'{\"foo\":1}'" (dom-inner-html _el-div))
))
(deftest "can do a simple fetch w/ json using Object syntax and an 'an' prefix"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as an Object then get result as JSON then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "'{\"foo\":1}'" (dom-inner-html _el-div))
))
(deftest "can do a simple fetch with a response object"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as response then if its.ok put \"yep\" into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yep" (dom-inner-html _el-div))
))
(deftest "can do a simple fetch w/ a custom conversion"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as Number then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1.2" (dom-inner-html _el-div))
))
(deftest "can do a simple post"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test {method:\"POST\"} then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "can do a simple post alt syntax without curlies"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test with method:\"POST\" then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "can do a simple post alt syntax w/ curlies"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test with {method:\"POST\"} then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "can put response conversion after with"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test with {method:\"POST\"} as text then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "can put response conversion before with"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as text with {method:\"POST\"} then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "triggers an event just before fetching"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch \"/test\" then put it into my.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo-set"))
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "submits the fetch parameters to the event handler"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch \"/test\" {headers: {\"X-CustomHeader\": \"foo\"}} then put it into my.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip event.detail.headers.should.have.property('X-CustomHeader',
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "allows the event handler to change the fetch parameters"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch \"/test\" then put it into my.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip arguments[1].should.have.property('headers')
;; SKIP check: skip arguments[1].headers.should.have.property('X-CustomHeader',
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "can catch an error that occurs when using fetch"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test catch e log e put \"yay\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yay" (dom-inner-html _el-div))
))
(deftest "can do a simple fetch w/ json using JSON syntax"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as JSON then get result as JSONString then put it into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "{\"foo\":1}" (dom-text-content _el-div))
))
(deftest "throws on non-2xx response by default"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test catch e put \"caught\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "caught" (dom-text-content _el-div))
))
(deftest "do not throw passes through 404 response"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test do not throw then put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "the body" (dom-text-content _el-div))
))
(deftest "don't throw passes through 404 response"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test don't throw then put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "the body" (dom-text-content _el-div))
))
(deftest "as response does not throw on 404"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click fetch /test as response then put it.status into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "404" (dom-text-content _el-div))
))
(deftest "Response can be converted to JSON via as JSON"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "Joe" (dom-text-content _el-div))
))
)
;; ── increment (20 tests) ──
(defsuite "hs-upstream-increment"
(deftest "can increment an empty variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click increment value then put value into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-inner-html _el-div))
))
(deftest "can increment a variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set value to 20 then increment value by 2 then put value into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "22" (dom-inner-html _el-div))
))
(deftest "can increment refer to result"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click increment value by 2 then put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "2" (dom-inner-html _el-div))
))
(deftest "can increment an attribute"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click increment @value then put @value into me")
(dom-set-attr _el-div "value" "5")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "8" (dom-inner-html _el-div))
))
(deftest "can increment an floating point numbers"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set value to 5.2 then increment value by 6.1 then put value into me")
(dom-set-attr _el-div "value" "5")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "11.3" (dom-inner-html _el-div))
))
(deftest "can increment a property"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click increment my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "6" (dom-inner-html _el-div))
))
(deftest "can increment by zero"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set value to 20 then increment value by 0 then put value into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "20" (dom-inner-html _el-div))
))
(deftest "can increment a value multiple times"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click increment my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "5" (dom-inner-html _el-div))
))
(deftest "can decrement an empty variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click decrement value then put value into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "-1" (dom-inner-html _el-div))
))
(deftest "can decrement a variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set value to 20 then decrement value by 2 then put value into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "18" (dom-inner-html _el-div))
))
(deftest "can decrement an attribute"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click decrement @value then put @value into me")
(dom-set-attr _el-div "value" "5")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "2" (dom-inner-html _el-div))
))
(deftest "can decrement an floating point numbers"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set value to 6.1 then decrement value by 5.1 then put value into me")
(dom-set-attr _el-div "value" "5")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-inner-html _el-div))
))
(deftest "can decrement a property"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click decrement my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "0" (dom-inner-html _el-div))
))
(deftest "can decrement a value multiple times"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click decrement my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "-5" (dom-inner-html _el-div))
))
(deftest "can decrement by zero"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set value to 20 then decrement value by 0 then put value into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "20" (dom-inner-html _el-div))
))
(deftest "can increment an array element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set arr to [10, 20, 30] then increment arr[1] then put arr[1] into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "21" (dom-text-content _el-div))
))
(deftest "can decrement an array element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set arr to [10, 20, 30] then decrement arr[1] then put arr[1] into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "19" (dom-text-content _el-div))
))
(deftest "can increment a possessive property"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click increment #d1's innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "6" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "can increment a property of expression"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click increment innerHTML of #d1")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "6" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "can increment a style ref"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set my *opacity to 0.5 then increment *opacity by 0.25 then put *opacity into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "0.75" (dom-text-content _el-div))
))
)
;; ── append (13 tests) ──
(defsuite "hs-upstream-append"
(deftest "can append a string to another string"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set value to 'Hello there.' then append ' General Kenobi.' to value then set my.innerHTML to value")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "Hello there. General Kenobi." (dom-inner-html _el-div))
))
(deftest "can append a value into an array"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set value to [1,2,3] append 4 to value set my.innerHTML to value as String")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1,2,3,4" (dom-inner-html _el-div))
))
(deftest "can append a value to 'it'"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set result to [1,2,3] append 4 put it as String into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1,2,3,4" (dom-inner-html _el-div))
))
(deftest "can append a value to a DOM node"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click append '<span>This is my inner HTML</span>' to me append '<b>With Tags</b>' to me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "<span>This is my inner HTML</span><b>With Tags</b>" (dom-inner-html _el-div))
))
(deftest "can append a value to a DOM element"
(hs-cleanup!)
(let ((_el-content (dom-create-element "div")))
(dom-set-attr _el-content "id" "content")
(dom-set-attr _el-content "_" "on click append 'Content' to #content")
(dom-append (dom-body) _el-content)
(hs-activate! _el-content)
(dom-dispatch _el-content "click" nil)
(assert= "Content" (dom-inner-html _el-content))
))
(deftest "can append a value to I"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click append 'Content' to I")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "Content" (dom-inner-html _el-div))
))
(deftest "can append a value to an object property"
(hs-cleanup!)
(let ((_el-id (dom-create-element "div")))
(dom-set-attr _el-id "id" "id")
(dom-set-attr _el-id "_" "on click append '_new' to my id")
(dom-append (dom-body) _el-id)
(hs-activate! _el-id)
(dom-dispatch _el-id "click" nil)
;; SKIP check: skip div.id.should.equal("id_new")
))
(deftest "multiple appends work"
(hs-cleanup!)
(let ((_el-id (dom-create-element "div")))
(dom-set-attr _el-id "id" "id")
(dom-set-attr _el-id "_" "on click get 'foo' then append 'bar' then append 'doh' then append it to me")
(dom-append (dom-body) _el-id)
(hs-activate! _el-id)
(dom-dispatch _el-id "click" nil)
(assert= "foobardoh" (dom-inner-html _el-id))
))
(deftest "append to undefined ignores the undefined"
(hs-cleanup!)
(let ((_el-id (dom-create-element "div")))
(dom-set-attr _el-id "id" "id")
(dom-set-attr _el-id "_" "on click append 'bar' then append it to me")
(dom-append (dom-body) _el-id)
(hs-activate! _el-id)
(dom-dispatch _el-id "click" nil)
(assert= "bar" (dom-inner-html _el-id))
))
(deftest "append preserves existing content rather than overwriting it"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click append '<a>New Content</a>' to me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip clicks.should.equal(1)
;; SKIP check: skip div.innerHTML.should.contain("New Content")
;; SKIP check: skip btn.parentNode.should.equal(div)
))
(deftest "new content added by append will be live"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click append `<button id='b1' _='on click increment window.temp'>Test</button>` to me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip window.temp.should.equal(1)
))
(deftest "new DOM content added by append will be live"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click make a <span.topping/> then append it to me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "topping"))
))
(deftest "can append a value to a set"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :s to [1,2] as Set append 3 to :s append 1 to :s put :s.size into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "3" (dom-text-content _el-div))
))
)
;; ── tell (10 tests) ──
(defsuite "hs-upstream-tell"
(deftest "establishes a proper beingTold symbol"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click add .foo tell #d2 add .bar")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert (not (dom-has-class? _el-d2 "bar")))
(assert (dom-has-class? _el-d2 "foo"))
(assert (dom-has-class? _el-d2 "bar"))
(assert (not (dom-has-class? _el-d2 "foo")))
))
(deftest "does not overwrite the me symbol"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click add .foo tell #d2 add .bar to me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert (dom-has-class? _el-d2 "bar"))
(assert (dom-has-class? _el-d2 "foo"))
(assert (not (dom-has-class? _el-d2 "bar")))
(assert (not (dom-has-class? _el-d2 "foo")))
))
(deftest "works with an array"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click add .foo tell <p/> in me add .bar")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert (not (dom-has-class? _el-d1 "bar")))
(assert (dom-has-class? _el-d1 "foo"))
(assert (not (dom-has-class? _el-d1 "bar")))
(assert (not (dom-has-class? _el-d1 "foo")))
(assert (dom-has-class? _el-d1 "bar"))
(assert (not (dom-has-class? _el-d1 "foo")))
(assert (dom-has-class? _el-d1 "bar"))
(assert (not (dom-has-class? _el-d1 "foo")))
))
(deftest "restores a proper implicit me symbol"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click tell #d2 add .bar end add .foo")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert (not (dom-has-class? _el-d2 "bar")))
(assert (dom-has-class? _el-d2 "foo"))
(assert (dom-has-class? _el-d2 "bar"))
(assert (not (dom-has-class? _el-d2 "foo")))
))
(deftest "ignores null"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click tell null add .bar end add .foo")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert (not (dom-has-class? _el-d2 "bar")))
(assert (dom-has-class? _el-d2 "foo"))
(assert (not (dom-has-class? _el-d2 "bar")))
(assert (not (dom-has-class? _el-d2 "foo")))
))
(deftest "you symbol represents the thing being told"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click tell #d2 add .bar to you")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert (not (dom-has-class? _el-d2 "bar")))
(assert (dom-has-class? _el-d2 "bar"))
))
(deftest "your symbol represents the thing being told"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click tell #d2 put your innerText into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
;; SKIP check: skip div1.innerText.should.equal("")
;; SKIP check: skip div2.innerText.should.equal("foo")
;; SKIP check: skip div1.innerText.should.equal("foo")
))
(deftest "attributes refer to the thing being told"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click tell #d2 put @foo into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "foo" "bar")
(dom-append (dom-body) _el-d2)
(dom-dispatch _el-d2 "click" nil)
;; SKIP check: skip div1.innerText.should.equal("")
;; SKIP check: skip div2.innerText.should.equal("")
;; SKIP check: skip div1.innerText.should.equal("bar")
))
(deftest "yourself attribute also works"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click tell #d2 remove yourself")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "" (dom-inner-html _el-d1))
))
(deftest "tell terminates with a feature"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click tell #d2 remove yourself on click tell #d3 remove yourself")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "" (dom-inner-html _el-d1))
))
)
;; ── on (63 tests) ──
(defsuite "hs-upstream-on"
(deftest "can respond to events with dots in names"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send example.event to #d1")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on example.event add .called")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert (dom-has-class? _el-d1 "called"))
))
(deftest "can respond to events with colons in names"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send example:event to #d1")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on example:event add .called")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert (dom-has-class? _el-d1 "called"))
))
(deftest "can respond to events with minus in names"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click send \"a-b\" to #d1")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on \"a-b\" add .called")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert (dom-has-class? _el-d1 "called"))
))
(deftest "can respond to events on other elements"
(hs-cleanup!)
(let ((_el-bar (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-bar "id" "bar")
(dom-append (dom-body) _el-bar)
(dom-set-attr _el-div "_" "on click from #bar add .clicked")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-bar "click" nil)
(assert (dom-has-class? _el-div "clicked"))
))
(deftest "listeners on other elements are removed when the registering element is removed"
(hs-cleanup!)
(let ((_el-bar (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-bar "id" "bar")
(dom-append (dom-body) _el-bar)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-dispatch _el-bar "click" nil)
(dom-dispatch _el-bar "click" nil)
(assert= "a" (dom-inner-html _el-bar))
))
(deftest "listeners on self are not removed when the element is removed"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on someCustomEvent put 1 into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
;; SKIP action: div.remove__
;; SKIP action: div.dispatchEvent_new Event__someCustomE
(assert= "1" (dom-inner-html _el-div))
))
(deftest "supports "elsewhere" modifier"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click elsewhere add .clicked")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "clicked"))
))
(deftest "supports "from elsewhere" modifier"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click from elsewhere add .clicked")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "clicked"))
))
(deftest "can pick detail fields out by name"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click send custom(foo:\"fromBar\") to #d2")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "_" "on custom(foo) call me.classList.add(foo)")
(dom-append (dom-body) _el-d2)
(hs-activate! _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert (dom-has-class? _el-d2 "fromBar"))
))
(deftest "can pick event properties out by name"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click send fromBar to #d2")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "_" "on fromBar(type) call me.classList.add(type)")
(dom-append (dom-body) _el-d2)
(hs-activate! _el-d2)
(dom-dispatch _el-d2 "click" nil)
(assert (dom-has-class? _el-d2 "fromBar"))
))
(deftest "can fire an event on load"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on load put \"Loaded\" into my.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
;; SKIP check: skip div.innerText.should.equal("Loaded")
))
(deftest "can be in a top level script tag"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-loadedDemo (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-loadedDemo "id" "loadedDemo")
(dom-append (dom-body) _el-loadedDemo)
;; SKIP check: skip byId("loadedDemo").innerText.should.equal("Loaded")
))
(deftest "can have a simple event filter"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click[false] log event then put \"Clicked\" into my.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch _el-d1 "click" nil)
;; SKIP check: skip byId("d1").innerText.should.equal("")
))
(deftest "can refer to event properties directly in filter"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click[buttons==0] log event then put \"Clicked\" into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div1 "_" "on click[buttons==1] log event then put \"Clicked\" into my.innerHTML")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-set-attr _el-div2 "_" "on click[buttons==1 and buttons==0] log event then put \"Clicked\" into my.innerHTML")
(dom-append (dom-body) _el-div2)
(hs-activate! _el-div2)
(dom-dispatch _el-div2 "click" nil)
(dom-dispatch _el-div2 "click" nil)
(dom-dispatch _el-div2 "click" nil)
;; SKIP check: skip div.innerText.should.equal("Clicked")
;; SKIP check: skip div.innerText.should.equal("")
))
(deftest "can refer to event detail properties directly in filter"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on example[foo] increment @count then put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
;; SKIP action: div.dispatchEvent_event_
;; SKIP action: div.dispatchEvent_event_
;; SKIP action: div.dispatchEvent_event_
;; SKIP check: skip div.innerText.should.equal("1")
;; SKIP check: skip div.innerText.should.equal("2")
))
(deftest "can click after a positive event filter"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on foo(bar)[bar] put \"triggered\" into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
;; SKIP check: skip div.innerText.should.equal("")
;; SKIP check: skip div.innerText.should.equal("triggered")
))
(deftest "multiple event handlers at a time are allowed to execute with the every keyword"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on every click put increment() into my.innerHTML then wait for a customEvent")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip div.innerText.should.equal("1")
;; SKIP check: skip div.innerText.should.equal("2")
;; SKIP check: skip div.innerText.should.equal("3")
))
(deftest "can have multiple event handlers"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on foo put increment() into my.innerHTML end on bar put increment() into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "foo" nil)
;; SKIP check: skip div.innerText.should.equal("1")
;; SKIP check: skip div.innerText.should.equal("2")
;; SKIP check: skip div.innerText.should.equal("3")
))
(deftest "can have multiple event handlers, no end"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on foo put increment() into my.innerHTML on bar put increment() into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "foo" nil)
;; SKIP check: skip div.innerText.should.equal("1")
;; SKIP check: skip div.innerText.should.equal("2")
;; SKIP check: skip div.innerText.should.equal("3")
))
(deftest "can queue events"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on foo wait for bar then call increment()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "bar" nil)
;; SKIP check: skip i.should.equal(0)
;; SKIP check: skip i.should.equal(1)
;; SKIP check: skip i.should.equal(2)
))
(deftest "can queue first event"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on foo queue first wait for bar then call increment()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "bar" nil)
;; SKIP check: skip i.should.equal(0)
;; SKIP check: skip i.should.equal(1)
;; SKIP check: skip i.should.equal(2)
))
(deftest "can queue last event"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on foo queue last wait for bar then call increment()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "bar" nil)
;; SKIP check: skip i.should.equal(0)
;; SKIP check: skip i.should.equal(1)
;; SKIP check: skip i.should.equal(2)
))
(deftest "can queue all events"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on foo queue all wait for bar then call increment()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "foo" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "bar" nil)
(dom-dispatch _el-div "bar" nil)
;; SKIP check: skip i.should.equal(0)
;; SKIP check: skip i.should.equal(1)
;; SKIP check: skip i.should.equal(2)
;; SKIP check: skip i.should.equal(3)
))
(deftest "queue none does not allow future queued events"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click queue none put increment() into my.innerHTML then wait for a customEvent")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "customEvent" nil)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip div.innerText.should.equal("1")
;; SKIP check: skip div.innerText.should.equal("2")
))
(deftest "can invoke on multiple events"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click or foo call increment()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
;; SKIP check: skip i.should.equal(1)
;; SKIP check: skip i.should.equal(2)
))
(deftest "can listen for events in another element (lazy)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click in #d1 put it into window.tmp")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
;; SKIP check: skip div1.should.equal(window.tmp)
))
(deftest "can filter events based on count"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click 1 put 1 + my.innerHTML as Int into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-inner-html _el-div))
))
(deftest "can filter events based on count range"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click 1 to 2 put 1 + my.innerHTML as Int into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "2" (dom-inner-html _el-div))
))
(deftest "can filter events based on unbounded count range"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click 2 and on put 1 + my.innerHTML as Int into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "2" (dom-inner-html _el-div))
))
(deftest "can mix ranges"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click 1 put \"one\" into my.innerHTML on click 3 put \"three\" into my.innerHTML on click 2 put \"two\" into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "click" nil)
(assert= "three" (dom-inner-html _el-div))
))
(deftest "can listen for general mutations"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation put \"Mutated\" into me then wait for hyperscript:mutation")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "foo" "bar")
(assert= "Mutated" (dom-inner-html _el-div))
))
(deftest "can listen for attribute mutations"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation of attributes put \"Mutated\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "foo" "bar")
(assert= "Mutated" (dom-inner-html _el-div))
))
(deftest "can listen for specific attribute mutations"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation of @foo put \"Mutated\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "foo" "bar")
(assert= "Mutated" (dom-inner-html _el-div))
))
(deftest "can listen for specific attribute mutations and filter out other attribute mutations"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation of @bar put \"Mutated\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "foo" "bar")
(assert= "" (dom-inner-html _el-div))
))
(deftest "can listen for childList mutations"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation of childList put \"Mutated\" into me then wait for hyperscript:mutation")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-append _el-div (dom-create-element "P"))
(assert= "Mutated" (dom-inner-html _el-div))
))
(deftest "can listen for childList mutation filter out other mutations"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation of childList put \"Mutated\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "foo" "bar")
(assert= "" (dom-inner-html _el-div))
))
(deftest "can listen for characterData mutation filter out other mutations"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation of characterData put \"Mutated\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "foo" "bar")
(assert= "" (dom-inner-html _el-div))
))
(deftest "can listen for multiple mutations"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation of @foo or @bar put \"Mutated\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "foo" "bar")
(assert= "Mutated" (dom-inner-html _el-div))
))
(deftest "can listen for multiple mutations 2"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on mutation of @foo or @bar put \"Mutated\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "bar" "bar")
(assert= "Mutated" (dom-inner-html _el-div))
))
(deftest "can listen for attribute mutations on other elements"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-div "_" "on mutation of attributes from #d1 put \"Mutated\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div "foo" "bar")
(assert= "Mutated" (dom-inner-html _el-div))
))
(deftest "each behavior installation has its own event queue"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-div (dom-create-element "div")) (_el-div2 (dom-create-element "div")) (_el-div3 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-div "_" "install DemoBehavior")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-div2 "_" "install DemoBehavior")
(dom-append (dom-body) _el-div2)
(hs-activate! _el-div2)
(dom-set-attr _el-div3 "_" "install DemoBehavior")
(dom-append (dom-body) _el-div3)
(hs-activate! _el-div3)
(dom-dispatch _el-div3 "foo" nil)
(dom-dispatch _el-div3 "foo" nil)
(dom-dispatch _el-div3 "foo" nil)
(assert= "behavior" (dom-inner-html _el-div3))
(assert= "behavior" (dom-inner-html _el-div3))
(assert= "behavior" (dom-inner-html _el-div3))
))
(deftest "can catch exceptions thrown in js functions"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click throwBar() catch e put e into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "can catch exceptions thrown in hyperscript functions"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-button "_" "on click throwBar() catch e put e into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "can catch top-level exceptions"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click throw \"bar\" catch e put e into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "can catch async top-level exceptions"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click wait 1ms then throw \"bar\" catch e put e into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "async exceptions don't kill the event queue"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click increment :x if :x is 1 wait 1ms then throw \"bar\" otherwise put \"success\" into me end catch e put e into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(dom-dispatch _el-button "click" nil)
(assert= "success" (dom-inner-html _el-button))
))
(deftest "exceptions in catch block don't kill the event queue"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click increment :x if :x is 1 throw \"bar\" otherwise put \"success\" into me end catch e put e into me then throw e")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(dom-dispatch _el-button "click" nil)
(assert= "success" (dom-inner-html _el-button))
))
(deftest "uncaught exceptions trigger 'exception' event"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click put \"foo\" into me then throw \"bar\" on exception(error) put error into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "caught exceptions do not trigger 'exception' event"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click put \"foo\" into me then throw \"bar\" catch e log e on exception(error) put error into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "foo" (dom-inner-html _el-button))
))
(deftest "rethrown exceptions trigger 'exception' event"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click put \"foo\" into me then throw \"bar\" catch e throw e on exception(error) put error into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "basic finally blocks work"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click throw \"bar\" finally put \"bar\" into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "finally blocks work when exception thrown in catch"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click throw \"bar\" catch e throw e finally put \"bar\" into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "async basic finally blocks work"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click wait a tick then throw \"bar\" finally put \"bar\" into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-inner-html _el-button))
))
(deftest "async finally blocks work when exception thrown in catch"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click wait a tick then throw \"bar\" catch e set :foo to \"foo\" then throw e finally put :foo + \"bar\" into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "foobar" (dom-inner-html _el-button))
))
(deftest "async exceptions in finally block don't kill the event queue"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click increment :x finally if :x is 1 wait 1ms then throw \"bar\" otherwise put \"success\" into me end")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(dom-dispatch _el-button "click" nil)
(assert= "success" (dom-inner-html _el-button))
))
(deftest "exceptions in finally block don't kill the event queue"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click increment :x finally if :x is 1 throw \"bar\" otherwise put \"success\" into me end")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(dom-dispatch _el-button "click" nil)
(assert= "success" (dom-inner-html _el-button))
))
(deftest "can ignore when target doesn't exist"
(hs-cleanup!)
(let ((_el-#d1 (dom-create-element "div")))
(dom-set-attr _el-#d1 "id" "#d1")
(dom-set-attr _el-#d1 "_" "on click from #doesntExist throw \"bar\" on click put \"clicked\" into me")
(dom-append (dom-body) _el-#d1)
(hs-activate! _el-#d1)
(dom-dispatch _el-#d1 "click" nil)
(assert= "clicked" (dom-inner-html _el-#d1))
))
(deftest "can handle an or after a from clause"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-set-attr _el-div "_" "on click from #d1 or click from #d2 increment @count then put @count into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-d1 "click" nil)
(dom-dispatch _el-d2 "click" nil)
(assert= "2" (dom-inner-html _el-div))
))
(deftest "handles custom events with null detail"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on myEvent(foo) if foo put foo into me else put \"no-detail\" into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
))
(deftest "on first click fires only once"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on first click put 1 + my.innerHTML as Int into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-text-content _el-div))
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-text-content _el-div))
))
(deftest "caught exceptions do not trigger 'exception' event"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click put \"foo\" into me then throw \"bar\" catch e log e on exception(error) put error into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "foo" (dom-text-content _el-button))
))
(deftest "rethrown exceptions trigger 'exception' event"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")))
(dom-set-attr _el-button "_" "on click put \"foo\" into me then throw \"bar\" catch e throw e on exception(error) put error into me")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "bar" (dom-text-content _el-button))
))
(deftest "can ignore when target doesn\'t exist"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click from #doesntExist throw \"bar\" on click put \"clicked\" into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "clicked" (dom-text-content _el-div))
))
)
;; ── init (3 tests) ──
(defsuite "hs-upstream-init"
(deftest "can define an init block inline"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set my.foo to 42 end on click put my.foo into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "42" (dom-inner-html _el-div))
))
(deftest "can define an init block in a script"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.foo.should.equal(42)
))
(deftest "can initialize immediately"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.foo.should.equal(10)
))
)
;; ── def (27 tests) ──
(defsuite "hs-upstream-def"
(deftest "can define a basic no arg function"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-div "_" "on click call foo()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert (dom-has-class? _el-d1 "called"))
))
(deftest "can define a basic one arg function"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-div "_" "on click call foo(\"called\")")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert= "called" (dom-inner-html _el-d1))
))
(deftest "functions can be namespaced"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-div "_" "on click call utils.foo()")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert (dom-has-class? _el-d1 "called"))
))
(deftest "is called synchronously"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-div "_" "on click call foo() then add .called to #d1")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert (dom-has-class? _el-d1 "called"))
))
(deftest "can call asynchronously"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-div "_" "on click call foo() then add .called to #d1")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
(assert (dom-has-class? _el-d1 "called"))
))
(deftest "can return a value synchronously"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-div "_" "on click call foo() then put it into #d1.innerText")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
;; SKIP check: skip div.innerText.should.equal("")
;; SKIP check: skip div.innerText.should.equal("foo")
))
(deftest "can exit"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
))
(deftest "can return a value asynchronously"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")) (_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
(dom-set-attr _el-div "_" "on click call foo() then put it into #d1.innerText")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-dispatch _el-d1 "click" nil)
;; SKIP check: skip div.innerText.should.equal("")
;; SKIP check: skip div.innerText.should.equal("foo")
))
(deftest "can interop with javascript"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip foo().should.equal("foo")
))
(deftest "can interop with javascript asynchronously"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip val.should.equal("foo")
))
(deftest "can catch exceptions"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.bar.should.equal("bar")
))
(deftest "can rethrow in catch blocks"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip true.should.equal(false)
;; SKIP check: skip e.should.equal("bar")
))
(deftest "can return in catch blocks"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip foo().should.equal(42)
))
(deftest "can catch async exceptions"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.bar.should.equal("bar")
))
(deftest "can catch nested async exceptions"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.bar.should.equal("bar")
))
(deftest "can rethrow in async catch blocks"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip reason.should.equal("bar")
))
(deftest "can return in async catch blocks"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip val.should.equal(42)
))
(deftest "can install a function on an element and use in children w/ no leak"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "def func() put 42 into #d3")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
;; SKIP check: skip byId("d3").innerText.should.equal("42")
))
(deftest "can install a function on an element and use in children w/ return value"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "def func() return 42")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
;; SKIP check: skip byId("d1").innerText.should.equal("42")
))
(deftest "can install a function on an element and use me symbol correctly"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "def func() put 42 into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
;; SKIP check: skip div.innerText.should.equal("42")
))
(deftest "finally blocks run normally"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.bar.should.equal(20)
))
(deftest "finally blocks run when an exception occurs"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.bar.should.equal(20)
))
(deftest "finally blocks run when an exception expr occurs"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.bar.should.equal(20)
))
(deftest "async finally blocks run normally"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.bar.should.equal(20)
))
(deftest "async finally blocks run when an exception occurs"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
;; SKIP check: skip window.bar.should.equal(20)
))
(deftest "exit stops execution mid-function"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
))
(deftest "can return without a value"
(hs-cleanup!)
(let ((_el-script (dom-create-element "script")))
(dom-set-attr _el-script "type" "text/hyperscript")
(dom-append (dom-body) _el-script)
))
)
;; ── askAnswer (5 tests) ──
(defsuite "hs-upstream-askAnswer"
(deftest "prompts and puts result in it"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-button "_" "on click ask \"What is your name?\" then put it into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "Alice" (dom-text-content (dom-query-by-id "out")))
))
(deftest "returns null on cancel"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-button "_" "on click ask \"Name?\" then put it into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "null" (dom-text-content (dom-query-by-id "out")))
))
(deftest "shows an alert"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-button "_" "on click answer \"Hello!\" then put \"done\" into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "done" (dom-text-content (dom-query-by-id "out")))
))
(deftest "confirm returns first choice on OK"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-button "_" "on click answer \"Save?\" with \"Yes\" or \"No\" then put it into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "Yes" (dom-text-content (dom-query-by-id "out")))
))
(deftest "confirm returns second choice on cancel"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-button "_" "on click answer \"Save?\" with \"Yes\" or \"No\" then put it into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "No" (dom-text-content (dom-query-by-id "out")))
))
)
;; ── dialog (10 tests) ──
(defsuite "hs-upstream-dialog"
(deftest "show opens a dialog as modal"
(hs-cleanup!)
(let ((_el-d (dom-create-element "dialog")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-d "id" "d")
(dom-append (dom-body) _el-d)
(dom-set-attr _el-button "_" "on click show #d")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert (dom-has-attr? (dom-query-by-id "d") "open"))
))
(deftest "hide closes a dialog"
(hs-cleanup!)
(let ((_el-d (dom-create-element "dialog")))
(dom-set-attr _el-d "id" "d")
(dom-append (dom-body) _el-d)
(dom-dispatch (dom-query-by-id "close") "click" nil)
(assert (not (dom-has-attr? (dom-query-by-id "d") "open")))
))
(deftest "show on already-open dialog is a no-op"
(hs-cleanup!)
(let ((_el-d (dom-create-element "dialog")))
(dom-set-attr _el-d "id" "d")
(dom-append (dom-body) _el-d)
(dom-dispatch (dom-query "button") "click" nil)
(assert (dom-has-attr? (dom-query-by-id "d") "open"))
))
(deftest "open opens a dialog"
(hs-cleanup!)
(let ((_el-d (dom-create-element "dialog")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-d "id" "d")
(dom-append (dom-body) _el-d)
(dom-set-attr _el-button "_" "on click open #d")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert (dom-has-attr? (dom-query-by-id "d") "open"))
))
(deftest "close closes a dialog"
(hs-cleanup!)
(let ((_el-d (dom-create-element "dialog")))
(dom-set-attr _el-d "id" "d")
(dom-append (dom-body) _el-d)
(dom-dispatch (dom-query-by-id "close") "click" nil)
(assert (not (dom-has-attr? (dom-query-by-id "d") "open")))
))
(deftest "open opens a details element"
(hs-cleanup!)
(let ((_el-d (dom-create-element "details")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-d "id" "d")
(dom-append (dom-body) _el-d)
(dom-set-attr _el-button "_" "on click open #d")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert (dom-has-attr? (dom-query-by-id "d") "open"))
))
(deftest "close closes a details element"
(hs-cleanup!)
(let ((_el-d (dom-create-element "details")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-d "id" "d")
(dom-append (dom-body) _el-d)
(dom-set-attr _el-button "_" "on click close #d")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert (not (dom-has-attr? (dom-query-by-id "d") "open")))
))
(deftest "open shows a popover"
(hs-cleanup!)
(let ((_el-p (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-p "id" "p")
(dom-append (dom-body) _el-p)
(dom-set-attr _el-button "_" "on click open #p")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "close hides a popover"
(hs-cleanup!)
(let ((_el-p (dom-create-element "div")))
(dom-set-attr _el-p "id" "p")
(dom-append (dom-body) _el-p)
(dom-dispatch (dom-query-by-id "close") "click" nil)
))
(deftest "open on implicit me"
(hs-cleanup!)
(let ((_el-d (dom-create-element "dialog")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-d "id" "d")
(dom-set-attr _el-d "_" "on myOpen open")
(dom-append (dom-body) _el-d)
(hs-activate! _el-d)
(dom-set-attr _el-button "_" "on click send myOpen to #d")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert (dom-has-attr? (dom-query-by-id "d") "open"))
))
)
;; ── empty (13 tests) ──
(defsuite "hs-upstream-empty"
(deftest "can empty an element"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-button "_" "on click empty #d1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "empty with no target empties me"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click empty")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "" (dom-text-content _el-div))
))
(deftest "can empty multiple elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-add-class _el-div "clearme")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "clearme")
(dom-append (dom-body) _el-div1)
(dom-set-attr _el-button "_" "on click empty .clearme")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "can empty an array"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :arr to [1,2,3] empty :arr put :arr.length into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "0" (dom-text-content _el-div))
))
(deftest "can empty a set"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :s to [1,2,3] as Set empty :s put :s.size into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "0" (dom-text-content _el-div))
))
(deftest "can empty a map"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set :m to {a:1, b:2} as Map empty :m put :m.size into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "0" (dom-text-content _el-div))
))
(deftest "can empty a text input"
(hs-cleanup!)
(let ((_el-t1 (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-t1 "id" "t1")
(dom-set-attr _el-t1 "type" "text")
(dom-set-attr _el-t1 "value" "hello")
(dom-append (dom-body) _el-t1)
(dom-set-attr _el-button "_" "on click empty #t1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "" (dom-get-prop (dom-query-by-id "t1") "value"))
))
(deftest "can empty a textarea"
(hs-cleanup!)
(let ((_el-ta1 (dom-create-element "textarea")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-ta1 "id" "ta1")
(dom-append (dom-body) _el-ta1)
(dom-set-attr _el-button "_" "on click empty #ta1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "" (dom-get-prop (dom-query-by-id "ta1") "value"))
))
(deftest "can empty a checkbox"
(hs-cleanup!)
(let ((_el-cb1 (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-cb1 "id" "cb1")
(dom-set-attr _el-cb1 "type" "checkbox")
(dom-append (dom-body) _el-cb1)
(dom-set-attr _el-button "_" "on click empty #cb1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert (not (dom-get-prop (dom-query-by-id "cb1") "checked")))
))
(deftest "can empty a select"
(hs-cleanup!)
(let ((_el-sel1 (dom-create-element "select")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-sel1 "id" "sel1")
(dom-append (dom-body) _el-sel1)
(dom-set-attr _el-button "_" "on click empty #sel1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "can empty a form (clears all inputs)"
(hs-cleanup!)
(let ((_el-f1 (dom-create-element "form")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-f1 "id" "f1")
(dom-append (dom-body) _el-f1)
(dom-set-attr _el-button "_" "on click empty #f1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "" (dom-get-prop (dom-query-by-id "t2") "value"))
(assert= "" (dom-get-prop (dom-query-by-id "ta2") "value"))
(assert (not (dom-get-prop (dom-query-by-id "cb2") "checked")))
))
(deftest "clear is an alias for empty"
(hs-cleanup!)
(let ((_el-t3 (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-t3 "id" "t3")
(dom-set-attr _el-t3 "type" "text")
(dom-set-attr _el-t3 "value" "hello")
(dom-append (dom-body) _el-t3)
(dom-set-attr _el-button "_" "on click clear #t3")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "" (dom-get-prop (dom-query-by-id "t3") "value"))
))
(deftest "clear works on elements"
(hs-cleanup!)
(let ((_el-d2 (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
(dom-set-attr _el-button "_" "on click clear #d2")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "" (dom-text-content (dom-query-by-id "d2")))
))
)
;; ── focus (3 tests) ──
(defsuite "hs-upstream-focus"
(deftest "can focus an element"
(hs-cleanup!)
(let ((_el-i1 (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-i1 "id" "i1")
(dom-append (dom-body) _el-i1)
(dom-set-attr _el-button "_" "on click focus #i1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "focus with no target focuses me"
(hs-cleanup!)
(let ((_el-i1 (dom-create-element "input")))
(dom-set-attr _el-i1 "id" "i1")
(dom-set-attr _el-i1 "_" "on click focus")
(dom-append (dom-body) _el-i1)
(hs-activate! _el-i1)
(dom-dispatch (dom-query-by-id "i1") "click" nil)
))
(deftest "can blur an element"
(hs-cleanup!)
(let ((_el-i1 (dom-create-element "input")))
(dom-set-attr _el-i1 "id" "i1")
(dom-set-attr _el-i1 "_" "on focus wait 10ms then blur me")
(dom-append (dom-body) _el-i1)
(hs-activate! _el-i1)
))
)
;; ── go (5 tests) ──
(defsuite "hs-upstream-go"
(deftest "can parse go to with string URL"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
))
(deftest "deprecated url keyword still parses"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click go to url /test")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "go to naked URL starting with / parses"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click go to /test/path")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "go to element scrolls"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-target (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-set-attr _el-div "style" "height: 2000px")
(dom-append (dom-body) _el-div)
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-div2 "_" "on click go to #target")
(dom-append (dom-body) _el-div2)
(hs-activate! _el-div2)
(dom-dispatch (dom-query "div:nth-of-type(3)") "click" nil)
))
(deftest "deprecated scroll form still works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-target (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-set-attr _el-div "style" "height: 2000px")
(dom-append (dom-body) _el-div)
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-div2 "_" "on click go to the top of #target")
(dom-append (dom-body) _el-div2)
(hs-activate! _el-div2)
(dom-dispatch (dom-query "div:nth-of-type(3)") "click" nil)
))
)
;; ── halt (7 tests) ──
(defsuite "hs-upstream-halt"
(deftest "halts event propagation and default"
(hs-cleanup!)
(let ((_el-outer (dom-create-element "div")))
(dom-set-attr _el-outer "id" "outer")
(dom-set-attr _el-outer "_" "on click add .outer-clicked")
(dom-append (dom-body) _el-outer)
(hs-activate! _el-outer)
(dom-dispatch (dom-query-by-id "inner") "click" nil)
(assert (not (dom-has-class? (dom-query-by-id "outer") "outer-clicked")))
))
(deftest "halt stops execution after the halt"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click halt then add .should-not-happen")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (not (dom-has-class? _el-div "should-not-happen")))
))
(deftest "halt the event stops propagation but continues execution"
(hs-cleanup!)
(let ((_el-outer (dom-create-element "div")))
(dom-set-attr _el-outer "id" "outer")
(dom-set-attr _el-outer "_" "on click add .outer-clicked")
(dom-append (dom-body) _el-outer)
(hs-activate! _el-outer)
(dom-dispatch (dom-query-by-id "inner") "click" nil)
(assert (not (dom-has-class? (dom-query-by-id "outer") "outer-clicked")))
(assert (dom-has-class? (dom-query-by-id "inner") "continued"))
))
(deftest "halt the event's stops propagation but continues execution"
(hs-cleanup!)
(let ((_el-outer (dom-create-element "div")))
(dom-set-attr _el-outer "id" "outer")
(dom-set-attr _el-outer "_" "on click add .outer-clicked")
(dom-append (dom-body) _el-outer)
(hs-activate! _el-outer)
(dom-dispatch (dom-query-by-id "inner") "click" nil)
(assert (not (dom-has-class? (dom-query-by-id "outer") "outer-clicked")))
(assert (dom-has-class? (dom-query-by-id "inner") "continued"))
))
(deftest "halt bubbling only stops propagation, not default"
(hs-cleanup!)
(let ((_el-outer (dom-create-element "div")))
(dom-set-attr _el-outer "id" "outer")
(dom-set-attr _el-outer "_" "on click add .outer-clicked")
(dom-append (dom-body) _el-outer)
(hs-activate! _el-outer)
(dom-dispatch (dom-query-by-id "inner") "click" nil)
(assert (not (dom-has-class? (dom-query-by-id "outer") "outer-clicked")))
(assert (not (dom-has-class? (dom-query-by-id "inner") "continued")))
))
(deftest "halt works outside of event context"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "halt default only prevents default, not propagation"
(hs-cleanup!)
(let ((_el-outer (dom-create-element "div")))
(dom-set-attr _el-outer "id" "outer")
(dom-set-attr _el-outer "_" "on click add .outer-clicked")
(dom-append (dom-body) _el-outer)
(hs-activate! _el-outer)
(dom-dispatch (dom-query-by-id "inner") "click" nil)
(assert (dom-has-class? (dom-query-by-id "outer") "outer-clicked"))
))
)
;; ── morph (10 tests) ──
(defsuite "hs-upstream-morph"
(deftest "basic morph updates content"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "new" (dom-text-content (dom-query-by-id "target")))
))
(deftest "morph preserves element identity"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-go (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-go "id" "go")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-go)
(dom-dispatch (dom-query-by-id "go") "click" nil)
(assert= "new" (dom-text-content (dom-query-by-id "target")))
))
(deftest "morph updates attributes"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-add-class _el-target "old")
(dom-append (dom-body) _el-target)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-dispatch _el-button "click" nil)
(assert (dom-has-class? (dom-query-by-id "target") "new"))
))
(deftest "morph adds new children"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-target1 (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-target1 "id" "target")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-target1)
(dom-dispatch (dom-query-by-id "go") "click" nil)
))
(deftest "morph removes old children"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-target1 (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-target1 "id" "target")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-target1)
(dom-dispatch (dom-query-by-id "go") "click" nil)
))
(deftest "morph initializes hyperscript on new elements"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-target1 (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-target1 "id" "target")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-target1)
(dom-dispatch (dom-query-by-id "go") "click" nil)
(assert= "new" (dom-text-content (dom-query-by-id "inner")))
(dom-dispatch (dom-query-by-id "inner") "click" nil)
(assert= "clicked" (dom-text-content (dom-query-by-id "inner")))
))
(deftest "morph cleans up removed hyperscript elements"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "morph reorders children by id"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "morph preserves matched child identity"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-go (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-go "id" "go")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-go)
(dom-dispatch (dom-query-by-id "go") "click" nil)
))
(deftest "morph with variable content"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-go (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-go "id" "go")
(dom-set-attr _el-go "_" "on click set content to \"<div id=target>morphed</div>\" then morph #target to content")
(dom-append (dom-body) _el-go)
(hs-activate! _el-go)
(dom-dispatch (dom-query-by-id "go") "click" nil)
(assert= "morphed" (dom-text-content (dom-query-by-id "target")))
))
)
;; ── reset (8 tests) ──
(defsuite "hs-upstream-reset"
(deftest "can reset a form"
(hs-cleanup!)
(let ((_el-f1 (dom-create-element "form")))
(dom-set-attr _el-f1 "id" "f1")
(dom-append (dom-body) _el-f1)
(dom-dispatch (dom-query-by-id "rst") "click" nil)
(assert= "original" (dom-get-prop (dom-query-by-id "t1") "value"))
))
(deftest "reset with no target resets me (form)"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-set-attr _el-form "_" "on custom reset")
(dom-append (dom-body) _el-form)
(hs-activate! _el-form)
(dom-dispatch _el-form "custom" nil)
(assert= "default" (dom-get-prop (dom-query-by-id "t2") "value"))
))
(deftest "can reset a text input to defaultValue"
(hs-cleanup!)
(let ((_el-t3 (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-t3 "id" "t3")
(dom-set-attr _el-t3 "type" "text")
(dom-set-attr _el-t3 "value" "hello")
(dom-append (dom-body) _el-t3)
(dom-set-attr _el-button "_" "on click reset #t3")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "hello" (dom-get-prop (dom-query-by-id "t3") "value"))
))
(deftest "can reset a checkbox"
(hs-cleanup!)
(let ((_el-cb1 (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-cb1 "id" "cb1")
(dom-set-attr _el-cb1 "type" "checkbox")
(dom-append (dom-body) _el-cb1)
(dom-set-attr _el-button "_" "on click reset #cb1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert (dom-get-prop (dom-query-by-id "cb1") "checked"))
))
(deftest "can reset an unchecked checkbox"
(hs-cleanup!)
(let ((_el-cb2 (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-cb2 "id" "cb2")
(dom-set-attr _el-cb2 "type" "checkbox")
(dom-append (dom-body) _el-cb2)
(dom-set-attr _el-button "_" "on click reset #cb2")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert (not (dom-get-prop (dom-query-by-id "cb2") "checked")))
))
(deftest "can reset a textarea"
(hs-cleanup!)
(let ((_el-ta1 (dom-create-element "textarea")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-ta1 "id" "ta1")
(dom-append (dom-body) _el-ta1)
(dom-set-attr _el-button "_" "on click reset #ta1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "original text" (dom-get-prop (dom-query-by-id "ta1") "value"))
))
(deftest "can reset a select"
(hs-cleanup!)
(let ((_el-sel1 (dom-create-element "select")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-sel1 "id" "sel1")
(dom-append (dom-body) _el-sel1)
(dom-set-attr _el-button "_" "on click reset #sel1")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "b" (dom-get-prop (dom-query-by-id "sel1") "value"))
))
(deftest "can reset multiple inputs"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-input1 (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-add-class _el-input "resettable")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "one")
(dom-append (dom-body) _el-input)
(dom-add-class _el-input1 "resettable")
(dom-set-attr _el-input1 "type" "text")
(dom-set-attr _el-input1 "value" "two")
(dom-append (dom-body) _el-input1)
(dom-set-attr _el-button "_" "on click reset .resettable")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
)
;; ── scroll (8 tests) ──
(defsuite "hs-upstream-scroll"
(deftest "can scroll to an element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-target (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-set-attr _el-div "style" "height: 2000px")
(dom-append (dom-body) _el-div)
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-div2 "_" "on click scroll to #target")
(dom-append (dom-body) _el-div2)
(hs-activate! _el-div2)
(dom-dispatch (dom-query "div:nth-of-type(3)") "click" nil)
))
(deftest "can scroll to top of element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-target (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-set-attr _el-div "style" "height: 2000px")
(dom-append (dom-body) _el-div)
(dom-set-attr _el-target "id" "target")
(dom-set-attr _el-target "style" "height: 200px")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-div2 "_" "on click scroll to the top of #target")
(dom-append (dom-body) _el-div2)
(hs-activate! _el-div2)
(dom-dispatch (dom-query "div:nth-of-type(3)") "click" nil)
))
(deftest "can scroll down by amount"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")))
(dom-set-attr _el-div "style" "height: 5000px")
(dom-append (dom-body) _el-div)
(dom-set-attr _el-div1 "_" "on click scroll down by 300px")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil)
))
(deftest "can scroll up by amount"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")))
(dom-set-attr _el-div "style" "height: 5000px")
(dom-append (dom-body) _el-div)
(dom-set-attr _el-div1 "_" "on click scroll up by 100px")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil)
))
(deftest "can scroll by without direction (defaults to down)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")))
(dom-set-attr _el-div "style" "height: 5000px")
(dom-append (dom-body) _el-div)
(dom-set-attr _el-div1 "_" "on click scroll by 200px")
(dom-append (dom-body) _el-div1)
(hs-activate! _el-div1)
(dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil)
))
(deftest "can scroll container by amount"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-go (dom-create-element "button")))
(dom-set-attr _el-box "id" "box")
(dom-set-attr _el-box "style" "height: 100px; overflow: auto")
(dom-append (dom-body) _el-box)
(dom-set-attr _el-go "id" "go")
(dom-set-attr _el-go "_" "on click scroll #box down by 200px")
(dom-append (dom-body) _el-go)
(hs-activate! _el-go)
(dom-dispatch (dom-query-by-id "go") "click" nil)
))
(deftest "can scroll to element in container"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-go (dom-create-element "button")))
(dom-set-attr _el-box "id" "box")
(dom-set-attr _el-box "style" "height: 100px; overflow: auto")
(dom-append (dom-body) _el-box)
(dom-set-attr _el-go "id" "go")
(dom-set-attr _el-go "_" "on click scroll to #item in #box")
(dom-append (dom-body) _el-go)
(hs-activate! _el-go)
(dom-dispatch (dom-query-by-id "go") "click" nil)
))
(deftest "can scroll left by amount"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-go (dom-create-element "button")))
(dom-set-attr _el-box "id" "box")
(dom-set-attr _el-box "style" "width: 100px; overflow: auto; white-space: nowrap")
(dom-append (dom-body) _el-box)
(dom-set-attr _el-go "id" "go")
(dom-set-attr _el-go "_" "on click scroll #box right by 300px")
(dom-append (dom-body) _el-go)
(hs-activate! _el-go)
(dom-dispatch (dom-query-by-id "go") "click" nil)
))
)
;; ── select (4 tests) ──
(defsuite "hs-upstream-select"
(deftest "selects text in an input"
(hs-cleanup!)
(let ((_el-inp (dom-create-element "input")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-inp "id" "inp")
(dom-set-attr _el-inp "value" "hello world")
(dom-append (dom-body) _el-inp)
(dom-set-attr _el-button "_" "on click select #inp")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "selects text in a textarea"
(hs-cleanup!)
(let ((_el-ta (dom-create-element "textarea")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-ta "id" "ta")
(dom-append (dom-body) _el-ta)
(dom-set-attr _el-button "_" "on click select #ta")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "selects implicit me"
(hs-cleanup!)
(let ((_el-inp (dom-create-element "input")))
(dom-set-attr _el-inp "id" "inp")
(dom-set-attr _el-inp "_" "on click select")
(dom-set-attr _el-inp "value" "test")
(dom-append (dom-body) _el-inp)
(hs-activate! _el-inp)
(dom-dispatch (dom-query-by-id "inp") "click" nil)
))
(deftest "returns selected text"
(hs-cleanup!)
(let ((_el-text (dom-create-element "p")) (_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-text "id" "text")
(dom-append (dom-body) _el-text)
(dom-set-attr _el-button "_" "on click put the selection into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "Hello" (dom-text-content (dom-query-by-id "out")))
))
)
;; ── swap (4 tests) ──
(defsuite "hs-upstream-swap"
(deftest "can swap two variables"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click set x to \"a\" then set y to \"b\" then swap x with y then put x + y into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "ba" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "can swap two properties"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-a (dom-create-element "span")) (_el-b (dom-create-element "span")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click set #a.textContent to \"hello\" then set #b.textContent to \"world\" then swap #a.textContent with #b.textContent")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-a "id" "a")
(dom-append (dom-body) _el-a)
(dom-set-attr _el-b "id" "b")
(dom-append (dom-body) _el-b)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "world" (dom-text-content (dom-query-by-id "a")))
(assert= "hello" (dom-text-content (dom-query-by-id "b")))
))
(deftest "can swap array elements"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click set arr to [1,2,3] then swap arr[0] with arr[2] then put arr as String into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "3,2,1" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "can swap a variable with a property"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-target (dom-create-element "span")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click set x to \"old\" then set #target.dataset.val to \"new\" then swap x with #target.dataset.val then put x into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-target "id" "target")
(dom-set-attr _el-target "data-val" "x")
(dom-append (dom-body) _el-target)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "new" (dom-text-content (dom-query-by-id "d1")))
(assert= "old" (dom-get-attr (dom-query-by-id "target") "data-val"))
))
)
;; ── bind (44 tests) ──
(defsuite "hs-upstream-bind"
(deftest "syncs variable and input value in both directions"
(hs-cleanup!)
(let ((_el-name-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-name-input "id" "name-input")
(dom-set-attr _el-name-input "type" "text")
(dom-set-attr _el-name-input "value" "Alice")
(dom-append (dom-body) _el-name-input)
(dom-set-attr _el-span "_" "bind $name and #name-input.value end when $name changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "syncs variable and attribute in both directions"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind $theme and @data-theme")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "dedup prevents infinite loop in two-way bind"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind $color and @data-color")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest ""with" is a synonym for "and""
(hs-cleanup!)
(let ((_el-city-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-city-input "id" "city-input")
(dom-set-attr _el-city-input "type" "text")
(dom-set-attr _el-city-input "value" "Paris")
(dom-append (dom-body) _el-city-input)
(dom-set-attr _el-span "_" "bind $city to #city-input.value end when $city changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "shorthand on text input binds to value"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-input "_" "bind $greeting to me end when $greeting changes put it into next <span/>")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "hello")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-append (dom-body) _el-span)
))
(deftest "shorthand on checkbox binds to checked"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-input "_" "bind $isDarkMode to me")
(dom-set-attr _el-input "type" "checkbox")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-set-attr _el-span "_" "when $isDarkMode changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "shorthand on textarea binds to value"
(hs-cleanup!)
(let ((_el-textarea (dom-create-element "textarea")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-textarea "_" "bind $bio to me")
(dom-append (dom-body) _el-textarea)
(hs-activate! _el-textarea)
(dom-set-attr _el-span "_" "when $bio changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "shorthand on select binds to value"
(hs-cleanup!)
(let ((_el-select (dom-create-element "select")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-select "_" "bind $country to me")
(dom-append (dom-body) _el-select)
(hs-activate! _el-select)
(dom-set-attr _el-span "_" "when $country changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "unsupported element: bind to plain div errors"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "shorthand on type=number preserves number type"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-input "_" "bind $price to me")
(dom-set-attr _el-input "type" "number")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-set-attr _el-span "_" "when $price changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "boolean bind to attribute uses presence/absence"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind $isEnabled and @data-active")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "boolean bind to aria-* attribute uses "true"/"false" strings"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind $isHidden and @aria-hidden")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "style bind is one-way: variable drives style, not vice versa"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind $opacity and *opacity")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "same value does not re-set input (prevents cursor jump)"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind $message to me")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "hello")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
))
(deftest "external JS property write does not sync (known limitation)"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-input "_" "bind $searchTerm to me")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "original")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-set-attr _el-span "_" "when $searchTerm changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "form.reset() syncs variable back to default value"
(hs-cleanup!)
(let ((_el-test-form (dom-create-element "form")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-test-form "id" "test-form")
(dom-append (dom-body) _el-test-form)
(dom-set-attr _el-span "_" "when $formField changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "clicking a radio sets the variable to its value"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-input1 (dom-create-element "input")) (_el-input2 (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-input "_" "bind $color to me")
(dom-set-attr _el-input "type" "radio")
(dom-set-attr _el-input "name" "color")
(dom-set-attr _el-input "value" "red")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-set-attr _el-input1 "_" "bind $color to me")
(dom-set-attr _el-input1 "type" "radio")
(dom-set-attr _el-input1 "name" "color")
(dom-set-attr _el-input1 "value" "blue")
(dom-append (dom-body) _el-input1)
(hs-activate! _el-input1)
(dom-set-attr _el-input2 "_" "bind $color to me")
(dom-set-attr _el-input2 "type" "radio")
(dom-set-attr _el-input2 "name" "color")
(dom-set-attr _el-input2 "value" "green")
(dom-append (dom-body) _el-input2)
(hs-activate! _el-input2)
(dom-set-attr _el-span "_" "when $color changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
(dom-dispatch (dom-query "input[value="blue"]") "click" nil)
(dom-dispatch (dom-query "input[value="green"]") "click" nil)
))
(deftest "setting variable programmatically checks the matching radio"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-input1 (dom-create-element "input")) (_el-input2 (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind $size to me")
(dom-set-attr _el-input "type" "radio")
(dom-set-attr _el-input "name" "size")
(dom-set-attr _el-input "value" "small")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-set-attr _el-input1 "_" "bind $size to me")
(dom-set-attr _el-input1 "type" "radio")
(dom-set-attr _el-input1 "name" "size")
(dom-set-attr _el-input1 "value" "medium")
(dom-append (dom-body) _el-input1)
(hs-activate! _el-input1)
(dom-set-attr _el-input2 "_" "bind $size to me")
(dom-set-attr _el-input2 "type" "radio")
(dom-set-attr _el-input2 "name" "size")
(dom-set-attr _el-input2 "value" "large")
(dom-append (dom-body) _el-input2)
(hs-activate! _el-input2)
))
(deftest "initial value checks the correct radio on load"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-input1 (dom-create-element "input")) (_el-input2 (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind $fruit to me")
(dom-set-attr _el-input "type" "radio")
(dom-set-attr _el-input "name" "fruit")
(dom-set-attr _el-input "value" "apple")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-set-attr _el-input1 "_" "bind $fruit to me")
(dom-set-attr _el-input1 "type" "radio")
(dom-set-attr _el-input1 "name" "fruit")
(dom-set-attr _el-input1 "value" "banana")
(dom-append (dom-body) _el-input1)
(hs-activate! _el-input1)
(dom-set-attr _el-input2 "_" "bind $fruit to me")
(dom-set-attr _el-input2 "type" "radio")
(dom-set-attr _el-input2 "name" "fruit")
(dom-set-attr _el-input2 "value" "cherry")
(dom-append (dom-body) _el-input2)
(hs-activate! _el-input2)
))
(deftest "variable drives class: setting variable adds/removes class"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind .dark and $darkMode")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "external class change syncs back to variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind .dark and $darkMode")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "right side wins on class init"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind .highlight to $highlighted")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "init: right side wins — input value (Y) overwrites variable (X)"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind $name to my value")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "Bob")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
))
(deftest "init: right side wins — variable (Y) overwrites input value (X)"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind my value to $name")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "Bob")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
))
(deftest "init: right side wins — attribute (Y) initializes variable (X)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind $color to @data-color")
(dom-set-attr _el-div "data-color" "red")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "init: right side wins — variable (Y) initializes attribute (X)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind @data-theme to $theme")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "init: right side wins — variable (Y) drives class (X)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind .dark to $isDark")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "init: right side wins — class (Y) drives variable (X)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "dark")
(dom-set-attr _el-div "_" "bind $isDark to .dark")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "possessive property: bind $var to my value"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind $myVal to my value")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "hello")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
))
(deftest "possessive attribute: bind $var and my @data-label"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind $label and my @data-label")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "of-expression: bind $var to value of #input"
(hs-cleanup!)
(let ((_el-of-input (dom-create-element "input")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-of-input "id" "of-input")
(dom-set-attr _el-of-input "type" "text")
(dom-set-attr _el-of-input "value" "initial")
(dom-append (dom-body) _el-of-input)
(dom-set-attr _el-div "_" "bind $search to value of #of-input")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "class bound to another element checkbox"
(hs-cleanup!)
(let ((_el-dark-toggle (dom-create-element "input")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-dark-toggle "id" "dark-toggle")
(dom-set-attr _el-dark-toggle "type" "checkbox")
(dom-append (dom-body) _el-dark-toggle)
(dom-set-attr _el-div "_" "bind .dark and #dark-toggle's checked")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "attribute bound to another element input value"
(hs-cleanup!)
(let ((_el-title-input (dom-create-element "input")) (_el-h1 (dom-create-element "h1")))
(dom-set-attr _el-title-input "id" "title-input")
(dom-set-attr _el-title-input "type" "text")
(dom-set-attr _el-title-input "value" "Hello")
(dom-append (dom-body) _el-title-input)
(dom-set-attr _el-h1 "_" "bind @data-title and #title-input's value")
(dom-append (dom-body) _el-h1)
(hs-activate! _el-h1)
))
(deftest "two inputs synced via bind"
(hs-cleanup!)
(let ((_el-slider (dom-create-element "input")) (_el-input (dom-create-element "input")))
(dom-set-attr _el-slider "id" "slider")
(dom-set-attr _el-slider "type" "range")
(dom-set-attr _el-slider "value" "50")
(dom-append (dom-body) _el-slider)
(dom-set-attr _el-input "_" "bind my value and #slider's value")
(dom-set-attr _el-input "type" "number")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
))
(deftest "bind variable to element by id auto-detects value"
(hs-cleanup!)
(let ((_el-name-field (dom-create-element "input")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-name-field "id" "name-field")
(dom-set-attr _el-name-field "type" "text")
(dom-set-attr _el-name-field "value" "")
(dom-append (dom-body) _el-name-field)
(dom-set-attr _el-div "_" "bind $name to #name-field")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "bind variable to checkbox by id auto-detects checked"
(hs-cleanup!)
(let ((_el-agree-cb (dom-create-element "input")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-agree-cb "id" "agree-cb")
(dom-set-attr _el-agree-cb "type" "checkbox")
(dom-append (dom-body) _el-agree-cb)
(dom-set-attr _el-div "_" "bind $agreed to #agree-cb")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "bind variable to number input by id auto-detects valueAsNumber"
(hs-cleanup!)
(let ((_el-qty-input (dom-create-element "input")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-qty-input "id" "qty-input")
(dom-set-attr _el-qty-input "type" "number")
(dom-append (dom-body) _el-qty-input)
(dom-set-attr _el-div "_" "bind $qty to #qty-input")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "bind element to element: both sides auto-detect"
(hs-cleanup!)
(let ((_el-range-slider (dom-create-element "input")) (_el-input (dom-create-element "input")))
(dom-set-attr _el-range-slider "id" "range-slider")
(dom-set-attr _el-range-slider "type" "range")
(dom-set-attr _el-range-slider "value" "50")
(dom-append (dom-body) _el-range-slider)
(dom-set-attr _el-input "_" "bind me to #range-slider")
(dom-set-attr _el-input "type" "number")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
))
(deftest "right side wins on init: variable (Y) initializes input (X)"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind me to $name")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "Bob")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
))
(deftest "right side wins on init: input (Y) initializes variable (X)"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind $name to me")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "Bob")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
))
(deftest "bind to contenteditable element auto-detects textContent"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "bind $text to me")
(dom-set-attr _el-div "contenteditable" "true")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "bind to custom element with value property auto-detects value"
(hs-cleanup!)
(let ((_el-test-input (dom-create-element "test-input")))
(dom-set-attr _el-test-input "_" "bind $custom to me")
(dom-append (dom-body) _el-test-input)
(hs-activate! _el-test-input)
))
(deftest "radio change listener is removed on cleanup"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-input1 (dom-create-element "input")))
(dom-set-attr _el-input "_" "bind $color to me")
(dom-set-attr _el-input "type" "radio")
(dom-set-attr _el-input "name" "color")
(dom-set-attr _el-input "value" "red")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-set-attr _el-input1 "_" "bind $color to me")
(dom-set-attr _el-input1 "type" "radio")
(dom-set-attr _el-input1 "name" "color")
(dom-set-attr _el-input1 "value" "blue")
(dom-append (dom-body) _el-input1)
(hs-activate! _el-input1)
))
(deftest "form reset listener is removed on cleanup"
(hs-cleanup!)
(let ((_el-form (dom-create-element "form")))
(dom-append (dom-body) _el-form)
))
)
;; ── live (23 tests) ──
(defsuite "hs-upstream-live"
(deftest "derives a variable from a computed expression"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live set $total to ($price * $qty) end when $total changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "updates DOM text reactively with put"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live put 'hello ' + $greeting into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "sets an attribute reactively"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live set my @data-theme to $theme")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "sets a style reactively"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live set *opacity to $opacity")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "puts a computed dollar amount into the DOM"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live put '$' + ($price * $qty) into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "block form re-runs all commands when any dependency changes"
(hs-cleanup!)
(let ((_el-w (dom-create-element "span")) (_el-h (dom-create-element "span")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-w "id" "w")
(dom-set-attr _el-w "_" "when $doubleWidth changes put it into me")
(dom-append (dom-body) _el-w)
(hs-activate! _el-w)
(dom-set-attr _el-h "id" "h")
(dom-set-attr _el-h "_" "when $doubleHeight changes put it into me")
(dom-append (dom-body) _el-h)
(hs-activate! _el-h)
(dom-set-attr _el-div "_" "live set $doubleWidth to ($width * 2) set $doubleHeight to ($height * 2) end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "separate live statements create independent effects"
(hs-cleanup!)
(let ((_el-w (dom-create-element "span")) (_el-h (dom-create-element "span")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-w "id" "w")
(dom-set-attr _el-w "_" "when $doubleWidth changes put it into me")
(dom-append (dom-body) _el-w)
(hs-activate! _el-w)
(dom-set-attr _el-h "id" "h")
(dom-set-attr _el-h "_" "when $doubleHeight changes put it into me")
(dom-append (dom-body) _el-h)
(hs-activate! _el-h)
(dom-set-attr _el-div "_" "live set $doubleWidth to ($width * 2) end live set $doubleHeight to ($height * 2)")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "block form cascades inter-dependent commands"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live set $subtotal to ($price * $qty) set $total to ($subtotal + $tax) end when $total changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "toggles a class based on a boolean variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live if $isActive add .active to me else remove .active from me end end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "toggles display style based on a boolean variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live if $isVisible set *display to 'block' else set *display to 'none' end end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "effects stop when element is removed from DOM"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live put $message into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "conditional branch only tracks the active dependency"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live if $showFirst put $firstName into me else put $lastName into me end end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "multiple live on same element work independently"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live set my @data-name to $firstName end live set my @data-age to $age")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "live and when on same element do not interfere"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live set my @data-status to $status end when $status changes put 'Status: ' + it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "bind and live on same element do not interfere"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-input "_" "bind $username to me end live set my @data-mirror to $username")
(dom-set-attr _el-input "type" "text")
(dom-set-attr _el-input "value" "alice")
(dom-append (dom-body) _el-input)
(hs-activate! _el-input)
(dom-set-attr _el-span "_" "when $username changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "reactive effects are stopped on cleanup"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "live put $count into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
))
(deftest "append triggers live block"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live put $items.join(', ') into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "push via pseudo-command triggers live block"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live put $items.join(', ') into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "push via call triggers live block"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live put $items.join(', ') into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "array + still works with live"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live put $items.join(', ') into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "set property still works with live"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "live put $obj.name into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "property change on object in array triggers live re-render"
(hs-cleanup!)
(let ((_el-people-tmpl (dom-create-element "template")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-people-tmpl "id" "people-tmpl")
(dom-append (dom-body) _el-people-tmpl)
(dom-set-attr _el-div "_" "live render #people-tmpl with people: $people then put it into my.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "push object then modify its property both trigger live"
(hs-cleanup!)
(let ((_el-items-tmpl (dom-create-element "template")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-items-tmpl "id" "items-tmpl")
(dom-append (dom-body) _el-items-tmpl)
(dom-set-attr _el-div "_" "live render #items-tmpl with items: $items then put it into my.innerHTML end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
)
;; ── reactive-properties (4 tests) ──
(defsuite "hs-upstream-reactive-properties"
(deftest "setting a property on a plain object triggers reactivity"
(hs-cleanup!)
(let ((_el-output (dom-create-element "output")))
(dom-set-attr _el-output "_" "when ($obj's x + $obj's y) changes put it into me")
(dom-append (dom-body) _el-output)
(hs-activate! _el-output)
))
(deftest "nested property chain triggers on intermediate reassignment"
(hs-cleanup!)
(let ((_el-output (dom-create-element "output")))
(dom-set-attr _el-output "_" "when $data's inner's val changes put it into me")
(dom-append (dom-body) _el-output)
(hs-activate! _el-output)
))
(deftest "property change on DOM element triggers reactivity via setProperty"
(hs-cleanup!)
(let ((_el-prop-input (dom-create-element "input")) (_el-output (dom-create-element "output")))
(dom-set-attr _el-prop-input "id" "prop-input")
(dom-set-attr _el-prop-input "type" "text")
(dom-set-attr _el-prop-input "value" "start")
(dom-append (dom-body) _el-prop-input)
(dom-set-attr _el-output "_" "when #prop-input's value changes put it into me")
(dom-append (dom-body) _el-output)
(hs-activate! _el-output)
))
(deftest "live block tracks property reads on plain objects"
(hs-cleanup!)
(let ((_el-output (dom-create-element "output")))
(dom-set-attr _el-output "_" "live put $config's label into me")
(dom-append (dom-body) _el-output)
(hs-activate! _el-output)
))
)
;; ── resize (3 tests) ──
(defsuite "hs-upstream-resize"
(deftest "fires when element is resized"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-box "id" "box")
(dom-set-attr _el-box "_" "on resize put detail.width into #out")
(dom-set-attr _el-box "style" "width:100px; height:100px")
(dom-append (dom-body) _el-box)
(hs-activate! _el-box)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
))
(deftest "provides height in detail"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-box "id" "box")
(dom-set-attr _el-box "_" "on resize put detail.height into #out")
(dom-set-attr _el-box "style" "width:100px; height:100px")
(dom-append (dom-body) _el-box)
(hs-activate! _el-box)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
))
(deftest "works with from clause"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-box "id" "box")
(dom-set-attr _el-box "style" "width:100px; height:100px")
(dom-append (dom-body) _el-box)
(dom-set-attr _el-out "id" "out")
(dom-set-attr _el-out "_" "on resize from #box put detail.width into me")
(dom-append (dom-body) _el-out)
(hs-activate! _el-out)
))
)
;; ── when (41 tests) ──
(defsuite "hs-upstream-when"
(deftest "provides access to `it` and syncs initial value"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $global changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "detects changes from $global variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $global changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "detects changes from :element variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set :count to 0 end when :count changes put it into me end on click increment :count")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "1" (dom-text-content _el-div))
(dom-dispatch _el-div "click" nil)
(assert= "2" (dom-text-content _el-div))
))
(deftest "triggers multiple elements watching same variable"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "when $shared changes put 'first' into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "_" "when $shared changes put 'second' into me")
(dom-append (dom-body) _el-d2)
(hs-activate! _el-d2)
))
(deftest "executes multiple commands"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $multi changes put 'first' into me then add .executed to me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "does not execute when variable is undefined initially"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $neverSet changes put 'synced' into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "only triggers when variable actually changes value"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $dedup changes increment :callCount then put :callCount into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "auto-tracks compound expressions"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when ($a + $b) changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "detects attribute changes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when @data-title changes put it into me")
(dom-set-attr _el-div "data-title" "original")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "detects form input value changes via user interaction"
(hs-cleanup!)
(let ((_el-reactive-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-reactive-input "id" "reactive-input")
(dom-set-attr _el-reactive-input "type" "text")
(dom-set-attr _el-reactive-input "value" "start")
(dom-append (dom-body) _el-reactive-input)
(dom-set-attr _el-span "_" "when #reactive-input.value changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "detects property change via hyperscript set"
(hs-cleanup!)
(let ((_el-prog-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-prog-input "id" "prog-input")
(dom-set-attr _el-prog-input "type" "text")
(dom-set-attr _el-prog-input "value" "initial")
(dom-append (dom-body) _el-prog-input)
(dom-set-attr _el-span "_" "when #prog-input.value changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "disposes effect when element is removed from DOM"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $dispose changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "batches multiple synchronous writes into one effect run"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when ($batchA + $batchB) changes increment :runCount then put :runCount into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "handles chained reactivity across elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-output (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $source changes set $derived to (it * 2)")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-set-attr _el-output "id" "output")
(dom-set-attr _el-output "_" "when $derived changes put it into me")
(dom-append (dom-body) _el-output)
(hs-activate! _el-output)
))
(deftest "supports multiple when features on the same element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $left changes put it into my @data-left end when $right changes put it into my @data-right")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "works with on handlers that modify the watched variable"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set :label to 'initial' end when :label changes put it into me end on click set :label to 'clicked'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "clicked" (dom-text-content _el-div))
))
(deftest "does not cross-trigger on unrelated variable writes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $trigger changes increment :count put :count into me set $other to 'side-effect'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "handles rapid successive changes correctly"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $rapid changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "isolates element-scoped variables between elements"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "init set :value to 'A' end when :value changes put it into me end on click set :value to 'A-clicked'")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "_" "init set :value to 'B' end when :value changes put it into me end on click set :value to 'B-clicked'")
(dom-append (dom-body) _el-d2)
(hs-activate! _el-d2)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "A-clicked" (dom-text-content (dom-query-by-id "d1")))
(assert= "B" (dom-text-content (dom-query-by-id "d2")))
(dom-dispatch (dom-query-by-id "d2") "click" nil)
(assert= "B-clicked" (dom-text-content (dom-query-by-id "d2")))
(assert= "A-clicked" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "handles NaN without infinite re-firing"
(hs-cleanup!)
(let ((_el-nan-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-nan-input "id" "nan-input")
(dom-set-attr _el-nan-input "type" "text")
(dom-set-attr _el-nan-input "value" "not a number")
(dom-append (dom-body) _el-nan-input)
(dom-set-attr _el-span "_" "when (#nan-input.value * 1) changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "fires when either expression changes using or"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $x or $y changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "supports three or more expressions with or"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $r or $g or $b changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "#element.checked is tracked"
(hs-cleanup!)
(let ((_el-cb-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-cb-input "id" "cb-input")
(dom-set-attr _el-cb-input "type" "checkbox")
(dom-append (dom-body) _el-cb-input)
(dom-set-attr _el-span "_" "when #cb-input.checked changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "my @attr is tracked"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when my @data-x changes put it into me")
(dom-set-attr _el-div "data-x" "one")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "value of #element is tracked"
(hs-cleanup!)
(let ((_el-of-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-of-input "id" "of-input")
(dom-set-attr _el-of-input "type" "text")
(dom-set-attr _el-of-input "value" "init")
(dom-append (dom-body) _el-of-input)
(dom-set-attr _el-span "_" "when (value of #of-input) changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "math on tracked symbols works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when ($mA * $mB) changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "comparison on tracked symbol works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when ($cmpVal > 5) changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "string template with tracked symbol works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when `hello ${$tplName}` changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "function call on tracked value works (Math.round)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when (Math.round($rawNum)) changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "inline style change via JS is NOT detected"
(hs-cleanup!)
(let ((_el-style-target (dom-create-element "div")))
(dom-set-attr _el-style-target "id" "style-target")
(dom-set-attr _el-style-target "_" "when (*opacity) changes put it into me")
(dom-set-attr _el-style-target "style" "opacity: 1")
(dom-append (dom-body) _el-style-target)
(hs-activate! _el-style-target)
))
(deftest "reassigning whole array IS detected"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $arrWhole changes put it.join(',') into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "mutating array element in place is NOT detected"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when $arrMut[0] changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "local variable in when expression produces a parse error"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "attribute observers are persistent (not recreated on re-run)"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "boolean short-circuit does not track unread branch"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "when ($x and $y) changes put it into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "diamond: cascaded derived values produce correct final value"
(hs-cleanup!)
(let ((_el-d-b (dom-create-element "span")) (_el-d-c (dom-create-element "span")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-d-b "id" "d-b")
(dom-set-attr _el-d-b "_" "when $a changes set $b to (it * 2)")
(dom-append (dom-body) _el-d-b)
(hs-activate! _el-d-b)
(dom-set-attr _el-d-c "id" "d-c")
(dom-set-attr _el-d-c "_" "when $a changes set $c to (it * 3)")
(dom-append (dom-body) _el-d-c)
(hs-activate! _el-d-c)
(dom-set-attr _el-div "_" "live increment :runs then put ($ (runs:)' into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "error in one effect does not break other effects in the same batch"
(hs-cleanup!)
(let ((_el-err-a (dom-create-element "span")))
(dom-set-attr _el-err-a "id" "err-a")
(dom-set-attr _el-err-a "_" "when $trigger changes put null.boom into me")
(dom-append (dom-body) _el-err-a)
(hs-activate! _el-err-a)
))
(deftest "circular guard resets after cascade settles"
(hs-cleanup!)
(let ((_el-span (dom-create-element "span")))
(dom-set-attr _el-span "_" "when $ping changes set $ping to (i<div _=")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "cross-microtask ping-pong is caught by circular guard"
(hs-cleanup!)
(let ((_el-span (dom-create-element "span")))
(dom-set-attr _el-span "_" "when $ping changes put it into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
))
(deftest "element moved in DOM retains reactivity"
(hs-cleanup!)
(let ((_el-container-a (dom-create-element "div")) (_el-container-b (dom-create-element "div")))
(dom-set-attr _el-container-a "id" "container-a")
(dom-append (dom-body) _el-container-a)
(dom-set-attr _el-container-b "id" "container-b")
(dom-append (dom-body) _el-container-b)
))
(deftest "rapid detach/reattach in same sync block does not kill effect"
(hs-cleanup!)
(let ((_el-thrash-parent (dom-create-element "div")))
(dom-set-attr _el-thrash-parent "id" "thrash-parent")
(dom-append (dom-body) _el-thrash-parent)
))
)
;; ── asyncError (2 tests) ──
(defsuite "hs-upstream-asyncError"
(deftest "rejected promise stops execution"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-button "_" "on click call failAsync() put 'should not reach' into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "original" (dom-text-content (dom-query-by-id "out")))
))
(deftest "rejected promise triggers catch block"
(hs-cleanup!)
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-button "_" "on click call failAsync() put 'unreachable' into #out catch e put e.message into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "boom" (dom-text-content (dom-query-by-id "out")))
))
)
;; ── dom-scope (25 tests) ──
(defsuite "hs-upstream-dom-scope"
(deftest "isolated stops ^var resolution"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^color to 'red'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "closest jumps to matching ancestor"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "outer")
(dom-set-attr _el-div "_" "init set ^val to 'from-outer'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "closest with no match stops resolution"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^val to 'found'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "parent of jumps past matching ancestor to its parent"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "outer")
(dom-set-attr _el-div "_" "init set ^val to 'from-outer'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "isolated allows setting ^var on the isolated element itself"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^outer to 'leaked'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "child reads ^var set by parent"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^count to 42")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "42" (dom-text-content (dom-query "span")))
))
(deftest "child writes ^var and parent sees it"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^count to 0")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "button") "click" nil)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "99" (dom-text-content (dom-query "span")))
))
(deftest "deeply nested child reads ^var from grandparent"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^name to 'alice'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "alice" (dom-text-content (dom-query "span")))
))
(deftest "closest ancestor wins (shadowing)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^color to 'red'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "blue" (dom-text-content (dom-query "span")))
))
(deftest "sibling subtrees have independent ^vars"
(hs-cleanup!)
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")))
(dom-set-attr _el-a "id" "a")
(dom-set-attr _el-a "_" "init set ^val to 'A'")
(dom-append (dom-body) _el-a)
(hs-activate! _el-a)
(dom-set-attr _el-b "id" "b")
(dom-set-attr _el-b "_" "init set ^val to 'B'")
(dom-append (dom-body) _el-b)
(hs-activate! _el-b)
(dom-dispatch (dom-query "#a span") "click" nil)
(assert= "A" (dom-text-content (dom-query "#a span")))
(dom-dispatch (dom-query "#b span") "click" nil)
(assert= "B" (dom-text-content (dom-query "#b span")))
))
(deftest "write to ^var not found anywhere creates on current element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-append (dom-body) _el-div)
(dom-dispatch (dom-query "button") "click" nil)
(assert= "created" (dom-text-content (dom-query "span")))
))
(deftest "child write updates the ancestor, not a local copy"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^shared to 0")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "button") "click" nil)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "10" (dom-text-content (dom-query "span")))
))
(deftest "increment works on inherited var"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^count to 0")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "button") "click" nil)
(dom-dispatch (dom-query "button") "click" nil)
(dom-dispatch (dom-query "button") "click" nil)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "3" (dom-text-content (dom-query "span")))
))
(deftest "dom keyword works as scope modifier"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set dom count to 42")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "42" (dom-text-content (dom-query "span")))
))
(deftest "set ^var on explicit element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "store")
(dom-append (dom-body) _el-div)
(dom-dispatch (dom-query "button") "click" nil)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "hello" (dom-text-content (dom-query "span")))
))
(deftest "on clause targets a specific ancestor"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "outer")
(dom-set-attr _el-div "_" "init set ^outerVal to 'outer'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "span") "click" nil)
(assert= "outer" (dom-text-content (dom-query "span")))
))
(deftest "on clause with id reference"
(hs-cleanup!)
(let ((_el-state-holder (dom-create-element "div")) (_el-button (dom-create-element "button")) (_el-span (dom-create-element "span")))
(dom-set-attr _el-state-holder "id" "state-holder")
(dom-append (dom-body) _el-state-holder)
(dom-set-attr _el-button "_" "on click set ^count on #state-holder to 99")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-span "_" "on click put ^count on #state-holder into me")
(dom-append (dom-body) _el-span)
(hs-activate! _el-span)
(dom-dispatch _el-button "click" nil)
(dom-dispatch _el-span "click" nil)
(assert= "99" (dom-text-content _el-span))
))
(deftest "when reacts to ^var changes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^count to 0")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "button") "click" nil)
(assert= "1" (dom-text-content (dom-query "output")))
(dom-dispatch (dom-query "button") "click" nil)
(assert= "2" (dom-text-content (dom-query "output")))
))
(deftest "always reacts to ^var changes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^name to 'alice'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "button") "click" nil)
))
(deftest "multiple children react to same ^var"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^color to 'red'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "button") "click" nil)
(assert= "blue" (dom-text-content (dom-query-by-id "a")))
(assert= "blue" (dom-text-content (dom-query-by-id "b")))
))
(deftest "sibling subtrees react independently with ^var"
(hs-cleanup!)
(let ((_el-a (dom-create-element "div")))
(dom-set-attr _el-a "id" "a")
(dom-set-attr _el-a "_" "init set ^val to 0")
(dom-append (dom-body) _el-a)
(hs-activate! _el-a)
(dom-dispatch (dom-query "#a button") "click" nil)
(dom-dispatch (dom-query "#a button") "click" nil)
(assert= "2" (dom-text-content (dom-query "#a output")))
(assert= "0" (dom-text-content (dom-query "#b output")))
(dom-dispatch (dom-query "#b button") "click" nil)
(assert= "1" (dom-text-content (dom-query "#b output")))
(assert= "2" (dom-text-content (dom-query "#a output")))
))
(deftest "bind works with ^var"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^search to ''")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "derived ^var chains reactively"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^price to 10 then set ^qty to 2 then set ^total to 20")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query-by-id "price-btn") "click" nil)
(dom-dispatch (dom-query-by-id "qty-btn") "click" nil)
))
(deftest "effect stops when element is removed"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^msg to 'hello'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "button") "click" nil)
))
(deftest "dedup prevents re-fire on same ^var value"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^val to 'same'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "button:text("same")") "click" nil)
(assert= "1" (dom-text-content (dom-query "output")))
(dom-dispatch (dom-query-by-id "diff") "click" nil)
(assert= "2" (dom-text-content (dom-query "output")))
))
)
;; ── evalStatically (8 tests) ──
(defsuite "hs-upstream-evalStatically"
(deftest "works on number literals"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "works on boolean literals"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "works on null literal"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "works on plain string literals"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "works on time expressions"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "throws on template strings"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "throws on symbol references"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "throws on math expressions"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── liveTemplate (10 tests) ──
(defsuite "hs-upstream-liveTemplate"
(deftest "renders static content after the template"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-append (dom-body) _el-template)
))
(deftest "renders template expressions"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-append (dom-body) _el-template)
))
(deftest "applies init script from _ attribute"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-set-attr _el-template "_" "init set ^msg to 'initialized'")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
))
(deftest "reactively updates when dependencies change"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-set-attr _el-template "_" "init set ^count to 0")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-dispatch (dom-query "[data-live-template] button") "click" nil)
))
(deftest "processes hyperscript on inner elements"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-set-attr _el-template "_" "init set ^val to 0")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-dispatch (dom-query "[data-live-template] button") "click" nil)
))
(deftest "supports #for loops"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-set-attr _el-template "_" "init set ^items to ['a', 'b', 'c']")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
))
(deftest "supports #if conditionals"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-set-attr _el-template "_" "init set ^show to true")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
))
(deftest "reacts to global state without init script"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-append (dom-body) _el-template)
))
(deftest "wrapper has display:contents"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")))
(dom-append (dom-body) _el-template)
))
(deftest "multiple live templates are independent"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-template1 (dom-create-element "template")))
(dom-set-attr _el-template "_" "init set ^x to 'first'")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-set-attr _el-template1 "_" "init set ^x to 'second'")
(dom-append (dom-body) _el-template1)
(hs-activate! _el-template1)
))
)
;; ── assignableElements (8 tests) ──
(defsuite "hs-upstream-assignableElements"
(deftest "set #id replaces element with HTML string"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "new" (dom-text-content (dom-query-by-id "target")))
))
(deftest "set #id replaces element with another element"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-button "_" "on click make a <span.replaced/> then put \"moved\" into it then set #target to it")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "set .class replaces all matching elements"
(hs-cleanup!)
(let ((_el-list (dom-create-element "ul")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-list "id" "list")
(dom-append (dom-body) _el-list)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "set <query/> replaces all matching elements"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-box "id" "box")
(dom-append (dom-body) _el-box)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "set closest replaces ancestor"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-add-class _el-div "wrapper")
(dom-append (dom-body) _el-div)
(dom-dispatch (dom-query "button") "click" nil)
(assert= "replaced" (dom-text-content (dom-query ".wrapper")))
))
(deftest "hyperscript in replacement content is initialized"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-target1 (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-target1 "id" "target")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-target1)
(dom-dispatch (dom-query-by-id "go") "click" nil)
(assert= "new" (dom-text-content (dom-query-by-id "target")))
(dom-dispatch (dom-query-by-id "target") "click" nil)
(assert= "clicked" (dom-text-content (dom-query-by-id "target")))
))
(deftest "swap #a with #b swaps DOM positions"
(hs-cleanup!)
(let ((_el-container (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-container "id" "container")
(dom-append (dom-body) _el-container)
(dom-set-attr _el-button "_" "on click swap #a with #b")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "put into still works as innerHTML"
(hs-cleanup!)
(let ((_el-target (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-target "id" "target")
(dom-append (dom-body) _el-target)
(dom-set-attr _el-button "_" "on click put \"new\" into #target")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "new" (dom-text-content (dom-query-by-id "target")))
))
)
;; ── collectionExpressions (22 tests) ──
(defsuite "hs-upstream-collectionExpressions"
(deftest "filters an array by condition"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "filters with comparison"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "works with DOM elements"
(hs-cleanup!)
(let ((_el-list (dom-create-element "ul")) (_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-list "id" "list")
(dom-append (dom-body) _el-list)
(dom-set-attr _el-button "_" "on click set items to <li/> in #list then set matches to items where it matches .yes then put matches mapped to its textContent into #out")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "AC" (dom-text-content (dom-query-by-id "out")))
))
(deftest "sorts by a property"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "sorts descending"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "sorts numbers by a computed key"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "maps to a property"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "maps with an expression"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "where then mapped to"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "sorted by then mapped to"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "where then sorted by then mapped to"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "the result inside where refers to previous command result, not current element"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "where binds after in without parens"
(hs-cleanup!)
(let ((_el-container (dom-create-element "div")))
(dom-set-attr _el-container "id" "container")
(dom-append (dom-body) _el-container)
))
(deftest "sorted by binds after in without parens"
(hs-cleanup!)
(let ((_el-list (dom-create-element "ul")))
(dom-set-attr _el-list "id" "list")
(dom-append (dom-body) _el-list)
))
(deftest "where binds after property access"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "where after in with mapped to"
(hs-cleanup!)
(let ((_el-items (dom-create-element "ul")))
(dom-set-attr _el-items "id" "items")
(dom-append (dom-body) _el-items)
))
(deftest "where binds after in on closest"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-button (dom-create-element "button")) (_el-b2 (dom-create-element "button")))
(dom-set-attr _el-box "id" "box")
(dom-append (dom-body) _el-box)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-set-attr _el-b2 "id" "b2")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-b2)
(dom-dispatch (dom-query-by-id "b2") "click" nil)
(assert= "2" (dom-text-content (dom-query-by-id "b2")))
))
(deftest "where in init followed by on feature"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-box "id" "box")
(dom-append (dom-body) _el-box)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-dispatch _el-button "click" nil)
(assert= "1" (dom-text-content _el-button))
))
(deftest "where in component init followed by on feature"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-template (dom-create-element "template")) (_el-test-where-comp (dom-create-element "test-where-comp")))
(dom-set-attr _el-box "id" "box")
(dom-append (dom-body) _el-box)
(dom-set-attr _el-template "_" "set :items to <span/> in #box where it matches .a on click put :items.length into me")
(dom-set-attr _el-template "component" "test-where-comp")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-append (dom-body) _el-test-where-comp)
(dom-dispatch _el-test-where-comp "click" nil)
(assert= "1" (dom-text-content _el-test-where-comp))
))
(deftest "where with is not me in component template"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")))
(dom-set-attr _el-box "id" "box")
(dom-append (dom-body) _el-box)
(dom-dispatch (dom-query "test-where-me input") "click" nil)
))
(deftest "where with is not me followed by on feature"
(hs-cleanup!)
(let ((_el-table (dom-create-element "table")))
(dom-append (dom-body) _el-table)
(dom-dispatch (dom-query-by-id "master") "click" nil)
))
(deftest "full select-all pattern with multiple on features"
(hs-cleanup!)
(let ((_el-table (dom-create-element "table")))
(dom-append (dom-body) _el-table)
(dom-dispatch (dom-query-by-id "master") "click" nil)
))
)
;; ── splitJoin (7 tests) ──
(defsuite "hs-upstream-splitJoin"
(deftest "splits a string by delimiter"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "splits by whitespace"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "joins an array with delimiter"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "joins with empty string"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "split then where then joined"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "split then sorted then joined"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "split then mapped then joined"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── component (19 tests) ──
(defsuite "hs-upstream-component"
(deftest "registers a custom element from a template"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-hello (dom-create-element "test-hello")))
(dom-set-attr _el-template "component" "test-hello")
(dom-append (dom-body) _el-template)
(dom-append (dom-body) _el-test-hello)
))
(deftest "renders template expressions"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-greet (dom-create-element "test-greet")))
(dom-set-attr _el-template "component" "test-greet")
(dom-append (dom-body) _el-template)
(dom-append (dom-body) _el-test-greet)
))
(deftest "applies _ hyperscript to component instance"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-init (dom-create-element "test-init")))
(dom-set-attr _el-template "_" "init set ^msg to 'initialized'")
(dom-set-attr _el-template "component" "test-init")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-append (dom-body) _el-test-init)
))
(deftest "processes _ on inner elements"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-inner (dom-create-element "test-inner")))
(dom-set-attr _el-template "_" "init set ^count to 0")
(dom-set-attr _el-template "component" "test-inner")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-append (dom-body) _el-test-inner)
(dom-dispatch (dom-query "test-inner button") "click" nil)
))
(deftest "reactively updates template expressions"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-reactive (dom-create-element "test-reactive")))
(dom-set-attr _el-template "_" "init set ^count to 0")
(dom-set-attr _el-template "component" "test-reactive")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-append (dom-body) _el-test-reactive)
(dom-dispatch (dom-query "test-reactive button") "click" nil)
))
(deftest "supports multiple independent instances"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-a (dom-create-element "test-multi")) (_el-b (dom-create-element "test-multi")))
(dom-set-attr _el-template "_" "init set ^count to 0")
(dom-set-attr _el-template "component" "test-multi")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-set-attr _el-a "id" "a")
(dom-append (dom-body) _el-a)
(dom-set-attr _el-b "id" "b")
(dom-append (dom-body) _el-b)
(dom-dispatch (dom-query "#a button") "click" nil)
))
(deftest "reads attributes via @"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-attrs (dom-create-element "test-attrs")))
(dom-set-attr _el-template "_" "init set ^val to @data-start as Int")
(dom-set-attr _el-template "component" "test-attrs")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-set-attr _el-test-attrs "data-start" "42")
(dom-append (dom-body) _el-test-attrs)
))
(deftest "supports #for loops in template"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-loop (dom-create-element "test-loop")))
(dom-set-attr _el-template "_" "init set ^items to ['a', 'b', 'c']")
(dom-set-attr _el-template "component" "test-loop")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-append (dom-body) _el-test-loop)
))
(deftest "supports #if conditionals in template"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-cond (dom-create-element "test-cond")))
(dom-set-attr _el-template "_" "init set ^show to true")
(dom-set-attr _el-template "component" "test-cond")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-append (dom-body) _el-test-cond)
))
(deftest "substitutes slot content into template"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-card (dom-create-element "test-card")))
(dom-set-attr _el-template "component" "test-card")
(dom-append (dom-body) _el-template)
(dom-append (dom-body) _el-test-card)
))
(deftest "blocks processing of inner hyperscript until render"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-block (dom-create-element "test-block")))
(dom-set-attr _el-template "_" "init set ^msg to 'ready'")
(dom-set-attr _el-template "component" "test-block")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-append (dom-body) _el-test-block)
(dom-dispatch (dom-query "test-block span") "click" nil)
))
(deftest "supports named slots"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-named-slot (dom-create-element "test-named-slot")))
(dom-set-attr _el-template "component" "test-named-slot")
(dom-append (dom-body) _el-template)
(dom-append (dom-body) _el-test-named-slot)
))
(deftest "does not process slotted _ attributes prematurely"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^x to 42")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "test-slot-hs span") "click" nil)
))
(deftest "slotted content resolves ^var from outer scope, not component scope"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^outer to 'from-outside'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "component isolation prevents ^var leaking inward"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "init set ^leaked to 'should-not-see'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "bind keeps ^var in sync with attribute changes"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-bind-attr (dom-create-element "test-bind-attr")))
(dom-set-attr _el-template "_" "bind ^count to @data-count")
(dom-set-attr _el-template "component" "test-bind-attr")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-set-attr _el-test-bind-attr "data-count" "5")
(dom-append (dom-body) _el-test-bind-attr)
))
(deftest "attrs evaluates attribute as hyperscript in parent scope"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-args (dom-create-element "test-args")))
(dom-set-attr _el-template "_" "init set ^list to attrs.items")
(dom-set-attr _el-template "component" "test-args")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-set-attr _el-test-args "items" "$stuff")
(dom-append (dom-body) _el-test-args)
))
(deftest "attrs works with bind for reactive pass-through"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-args-bind (dom-create-element "test-args-bind")) (_el-button (dom-create-element "button")))
(dom-set-attr _el-template "_" "bind ^val to attrs.count")
(dom-set-attr _el-template "component" "test-args-bind")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-set-attr _el-test-args-bind "count" "$count")
(dom-append (dom-body) _el-test-args-bind)
(dom-set-attr _el-button "_" "on click increment $count")
(dom-append (dom-body) _el-button)
(hs-activate! _el-button)
(dom-dispatch _el-button "click" nil)
))
(deftest "attrs bind is bidirectional — inner changes flow outward"
(hs-cleanup!)
(let ((_el-template (dom-create-element "template")) (_el-test-args-bidir (dom-create-element "test-args-bidir")) (_el-p (dom-create-element "p")))
(dom-set-attr _el-template "_" "bind ^count to attrs.count")
(dom-set-attr _el-template "component" "test-args-bidir")
(dom-append (dom-body) _el-template)
(hs-activate! _el-template)
(dom-set-attr _el-test-args-bidir "count" "$count")
(dom-append (dom-body) _el-test-args-bidir)
(dom-set-attr _el-p "_" "live put $count into me")
(dom-append (dom-body) _el-p)
(hs-activate! _el-p)
(dom-dispatch (dom-query "test-args-bidir button") "click" nil)
))
)
;; ── default (9 tests) ──
(defsuite "hs-upstream-default"
(deftest "can default possessive properties"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "bar" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "can default of-expression properties"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "bar" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "can default array elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set arr to [null, null] then default arr[0] to 'yes' then put arr[0] into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "yes" (dom-text-content _el-div))
))
(deftest "default array element respects existing value"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set arr to ['existing', null] then default arr[0] to 'new' then put arr[0] into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "existing" (dom-text-content _el-div))
))
(deftest "default preserves zero"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to 0 then default x to 10 then put x into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "0" (dom-text-content _el-div))
))
(deftest "default overwrites empty string"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to \"\" then default x to \"fallback\" then put x into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "fallback" (dom-text-content _el-div))
))
(deftest "default preserves false"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click set x to false then default x to true then put x into me")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "false" (dom-text-content _el-div))
))
(deftest "can default style ref when unset"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click default *background-color to 'red'")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "" (dom-get-style _el-div "background-color"))
))
(deftest "default style ref preserves existing value"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click default *color to 'red'")
(dom-set-attr _el-div "style" "color: blue")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "" (dom-get-style _el-div "color"))
))
)
;; ── js (1 tests) ──
(defsuite "hs-upstream-js"
(deftest "handles rejected promises without hanging"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click js return Promise.reject(\"boom\") end catch e put e into my.innerHTML")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "boom" (dom-text-content _el-div))
))
)
;; ── measure (2 tests) ──
(defsuite "hs-upstream-measure"
(deftest "can measure with possessive syntax"
(hs-cleanup!)
(let ((_el-other (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-other "id" "other")
(dom-set-attr _el-other "style" "all: initial; position: fixed; top: 89px")
(dom-append (dom-body) _el-other)
(dom-set-attr _el-div "_" "on click measure #other's top then set window.measurement to {top: top}")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil)
))
(deftest "can measure with of syntax"
(hs-cleanup!)
(let ((_el-other (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-other "id" "other")
(dom-set-attr _el-other "style" "all: initial; position: fixed; top: 89px")
(dom-append (dom-body) _el-other)
(dom-set-attr _el-div "_" "on click measure top of #other then set window.measurement to {top: top}")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil)
))
)
;; ── pick (7 tests) ──
(defsuite "hs-upstream-pick"
(deftest "does not hang on zero-length regex matches"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can pick first n items"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can pick last n items"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can pick random item"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can pick random n items"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can pick items using 'of' syntax"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can pick match using 'of' syntax"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── settle (1 tests) ──
(defsuite "hs-upstream-settle"
(deftest "can settle a collection of elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-trigger (dom-create-element "div")))
(dom-add-class _el-div "item")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "item")
(dom-append (dom-body) _el-div1)
(dom-set-attr _el-trigger "id" "trigger")
(dom-set-attr _el-trigger "_" "on click settle <.item/> then add .done to <.item/>")
(dom-append (dom-body) _el-trigger)
(hs-activate! _el-trigger)
(dom-dispatch (dom-query-by-id "trigger") "click" nil)
))
)
;; ── show (2 tests) ──
(defsuite "hs-upstream-show"
(deftest "the result in a when clause refers to previous command result, not element being tested"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-s1 (dom-create-element "span")) (_el-s2 (dom-create-element "span")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-set-attr _el-s1 "id" "s1")
(dom-set-attr _el-s1 "style" "display:none")
(dom-append (dom-body) _el-s1)
(dom-set-attr _el-s2 "id" "s2")
(dom-set-attr _el-s2 "style" "display:none")
(dom-append (dom-body) _el-s2)
(dom-dispatch _el-div "click" nil)
(assert (dom-visible? (dom-query-by-id "s1")))
(assert (dom-visible? (dom-query-by-id "s2")))
))
(deftest "the result after show...when is the matched elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-p (dom-create-element "p")) (_el-p2 (dom-create-element "p")) (_el-out (dom-create-element "span")))
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-div)
(dom-set-attr _el-p "style" "display:none")
(dom-append (dom-body) _el-p)
(dom-set-attr _el-p2 "style" "display:none")
(dom-append (dom-body) _el-p2)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-div "click" nil)
(assert= "some" (dom-text-content (dom-query-by-id "out")))
))
)
;; ── socket (4 tests) ──
(defsuite "hs-upstream-socket"
(deftest "parses socket with absolute ws:// URL"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts relative URL to wss:// on https pages"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts relative URL to ws:// on http pages"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "namespaced sockets work"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── bootstrap (14 tests) ──
(defsuite "hs-upstream-bootstrap"
(deftest "hyperscript can have more than one action"
(hs-cleanup!)
(let ((_el-bar (dom-create-element "div")) (_el-div (dom-create-element "div")))
(dom-set-attr _el-bar "id" "bar")
(dom-append (dom-body) _el-bar)
(dom-set-attr _el-div "_" "on click add .foo to #bar then add .blah")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil)
(assert (dom-has-class? (dom-query-by-id "bar") "foo"))
(assert (not (dom-has-class? (dom-query-by-id "bar") "blah")))
(assert (not (dom-has-class? (dom-query "div:nth-of-type(2)") "foo")))
(assert (dom-has-class? (dom-query "div:nth-of-type(2)") "blah"))
))
(deftest "stores state on elt._hyperscript"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "skips reinitialization if script unchanged"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "reinitializes if script attribute changes"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "bar"))
))
(deftest "cleanup removes event listeners on the element"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (not (dom-has-class? _el-div "foo")))
))
(deftest "cleanup removes cross-element event listeners"
(hs-cleanup!)
(let ((_el-source (dom-create-element "div")) (_el-target (dom-create-element "div")))
(dom-set-attr _el-source "id" "source")
(dom-append (dom-body) _el-source)
(dom-set-attr _el-target "id" "target")
(dom-set-attr _el-target "_" "on click from #source add .foo")
(dom-append (dom-body) _el-target)
(hs-activate! _el-target)
(dom-dispatch (dom-query-by-id "source") "click" nil)
(assert (dom-has-class? (dom-query-by-id "target") "foo"))
))
(deftest "cleanup tracks listeners in elt._hyperscript"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "cleanup clears elt._hyperscript"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "sets data-hyperscript-powered on initialized elements"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "cleanup removes data-hyperscript-powered"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "fires hyperscript:before:init and hyperscript:after:init"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "hyperscript:before:init can cancel initialization"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "fires hyperscript:before:cleanup and hyperscript:after:cleanup"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click add .foo")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
))
(deftest "logAll config logs events to console"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── parser (7 tests) ──
(defsuite "hs-upstream-parser"
(deftest "can have comments in attributes (triple dash)"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-set-attr _el-div "_" "on click put \"clicked\" into my.innerHTML ---put some content into the div...")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(assert= "clicked" (dom-text-content _el-div))
))
(deftest "recovers across feature boundaries and reports all errors"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click blargh end on mouseenter put \"hovered\" into my.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
))
(deftest "recovers across multiple feature errors"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click blargh end on mouseenter also_bad end on focus put \"focused\" into my.innerHTML")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
))
(deftest "fires hyperscript:parse-error event with all errors"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "element-level isolation still works with error recovery"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")))
(dom-append (dom-body) _el-div)
(dom-dispatch (dom-query-by-id "d2") "click" nil)
(assert= "clicked" (dom-text-content (dom-query-by-id "d2")))
))
(deftest "_hyperscript() evaluate API still throws on first error"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "parse error at EOF on trailing newline does not crash"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── scoping (1 tests) ──
(defsuite "hs-upstream-scoping"
(deftest "element scoped variables span features w/short syntax"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click 1 set :x to 10 on click 2 set @out to :x")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "10" (dom-get-attr (dom-query-by-id "d1") "out"))
))
)
;; ── asExpression (17 tests) ──
(defsuite "hs-upstream-asExpression"
(deftest "converts value as Boolean"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can use the a modifier if you like"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "parses string as JSON to object"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts value as JSONString"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "pipe operator chains conversions"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "can use the an modifier if you'd like"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "collects duplicate text inputs into an array"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts multiple selects with programmatically changed selections"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts a form element into Values | JSONString"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts a form element into Values | FormEncoded"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts array as Set"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts object as Map"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts object as Keys"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts object as Entries"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts array as Reversed"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts array as Unique"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "converts nested array as Flat"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── attributeRef (1 tests) ──
(defsuite "hs-upstream-attributeRef"
(deftest "attributeRef can be set through possessive w/ short syntax"
(hs-cleanup!)
(let ((_el-arDiv (dom-create-element "div")))
(dom-set-attr _el-arDiv "id" "arDiv")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-arDiv)
(dom-dispatch (dom-query-by-id "arDiv") "click" nil)
))
)
;; ── closest (3 tests) ──
(defsuite "hs-upstream-closest"
(deftest "attributes can be set via the closest expression 2"
(hs-cleanup!)
(let ((_el-outerDiv2 (dom-create-element "div")))
(dom-set-attr _el-outerDiv2 "id" "outerDiv2")
(dom-set-attr _el-outerDiv2 "foo" "bar")
(dom-append (dom-body) _el-outerDiv2)
(dom-dispatch (dom-query-by-id "d1b") "click" nil)
))
(deftest "closest does not consume a following where clause"
(hs-cleanup!)
(let ((_el-table (dom-create-element "table")))
(dom-append (dom-body) _el-table)
(dom-dispatch (dom-query-by-id "master") "click" nil)
(assert= "2" (dom-text-content (dom-query-by-id "out")))
))
(deftest "closest with to modifier still works after parse change"
(hs-cleanup!)
(let ((_el-outer (dom-create-element "div")))
(dom-set-attr _el-outer "id" "outer")
(dom-append (dom-body) _el-outer)
))
)
;; ── comparisonOperator (40 tests) ──
(defsuite "hs-upstream-comparisonOperator"
(deftest "is a works with instanceof fallback"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click if I am a Element put \"yes\" into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "yes" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "is a Node works via instanceof"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click if I am a Node put \"yes\" into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "yes" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "is not a works with instanceof fallback"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-set-attr _el-d1 "_" "on click if \"hello\" is not a Element put \"yes\" into me")
(dom-append (dom-body) _el-d1)
(hs-activate! _el-d1)
(dom-dispatch (dom-query-by-id "d1") "click" nil)
(assert= "yes" (dom-text-content (dom-query-by-id "d1")))
))
(deftest "is ignoring case works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is not ignoring case works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "contains ignoring case works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "matches ignoring case works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "starts with works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "ends with works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "does not start with works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "does not end with works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "starts with null is false"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "ends with null is false"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "starts with ignoring case works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "ends with ignoring case works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "starts with coerces to string"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "ends with coerces to string"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is between works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is not between works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "between works with strings"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "I am between works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "I am not between works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "precedes works"
(hs-cleanup!)
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")) (_el-c (dom-create-element "div")))
(dom-set-attr _el-a "id" "a")
(dom-append (dom-body) _el-a)
(dom-set-attr _el-b "id" "b")
(dom-append (dom-body) _el-b)
(dom-set-attr _el-c "id" "c")
(dom-append (dom-body) _el-c)
))
(deftest "follows works"
(hs-cleanup!)
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")) (_el-c (dom-create-element "div")))
(dom-set-attr _el-a "id" "a")
(dom-append (dom-body) _el-a)
(dom-set-attr _el-b "id" "b")
(dom-append (dom-body) _el-b)
(dom-set-attr _el-c "id" "c")
(dom-append (dom-body) _el-c)
))
(deftest "does not precede works"
(hs-cleanup!)
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")))
(dom-set-attr _el-a "id" "a")
(dom-append (dom-body) _el-a)
(dom-set-attr _el-b "id" "b")
(dom-append (dom-body) _el-b)
))
(deftest "does not follow works"
(hs-cleanup!)
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")))
(dom-set-attr _el-a "id" "a")
(dom-append (dom-body) _el-a)
(dom-set-attr _el-b "id" "b")
(dom-append (dom-body) _el-b)
))
(deftest "precedes with null is false"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "I precede works"
(hs-cleanup!)
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")))
(dom-set-attr _el-a "id" "a")
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-a)
(dom-set-attr _el-b "id" "b")
(dom-append (dom-body) _el-b)
(dom-dispatch (dom-query-by-id "a") "click" nil)
(assert= "yes" (dom-text-content (dom-query-by-id "a")))
))
(deftest "is really works without equal to"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is not really works without equal to"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is equal works without to"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is not equal works without to"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "am works as alias for is"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is not undefined still works as equality"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is not null still works as equality"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is falls back to boolean property when rhs is undefined"
(hs-cleanup!)
(let ((_el-c1 (dom-create-element "input")) (_el-c2 (dom-create-element "input")))
(dom-set-attr _el-c1 "id" "c1")
(dom-set-attr _el-c1 "type" "checkbox")
(dom-set-attr _el-c1 "checked" "checked")
(dom-append (dom-body) _el-c1)
(dom-set-attr _el-c2 "id" "c2")
(dom-set-attr _el-c2 "type" "checkbox")
(dom-append (dom-body) _el-c2)
))
(deftest "is not falls back to boolean property when rhs is undefined"
(hs-cleanup!)
(let ((_el-c1 (dom-create-element "input")) (_el-c2 (dom-create-element "input")))
(dom-set-attr _el-c1 "id" "c1")
(dom-set-attr _el-c1 "type" "checkbox")
(dom-set-attr _el-c1 "checked" "checked")
(dom-append (dom-body) _el-c1)
(dom-set-attr _el-c2 "id" "c2")
(dom-set-attr _el-c2 "type" "checkbox")
(dom-append (dom-body) _el-c2)
))
(deftest "is boolean property works with disabled"
(hs-cleanup!)
(let ((_el-b1 (dom-create-element "button")) (_el-b2 (dom-create-element "button")))
(dom-set-attr _el-b1 "id" "b1")
(dom-append (dom-body) _el-b1)
(dom-set-attr _el-b2 "id" "b2")
(dom-append (dom-body) _el-b2)
))
(deftest "is still does equality when rhs variable exists"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "is boolean property works in where clause"
(hs-cleanup!)
(let ((_el-input (dom-create-element "input")) (_el-input1 (dom-create-element "input")) (_el-input2 (dom-create-element "input")))
(dom-add-class _el-input "cb")
(dom-set-attr _el-input "type" "checkbox")
(dom-set-attr _el-input "checked" "checked")
(dom-append (dom-body) _el-input)
(dom-add-class _el-input1 "cb")
(dom-set-attr _el-input1 "type" "checkbox")
(dom-append (dom-body) _el-input1)
(dom-add-class _el-input2 "cb")
(dom-set-attr _el-input2 "type" "checkbox")
(dom-set-attr _el-input2 "checked" "checked")
(dom-append (dom-body) _el-input2)
))
)
;; ── cookies (1 tests) ──
(defsuite "hs-upstream-cookies"
(deftest "length is 0 when no cookies are set"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── in (1 tests) ──
(defsuite "hs-upstream-in"
(deftest "null value in array returns empty"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── logicalOperator (3 tests) ──
(defsuite "hs-upstream-logicalOperator"
(deftest "and short-circuits when lhs promise resolves to false"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "or short-circuits when lhs promise resolves to true"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "or evaluates rhs when lhs promise resolves to false"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── mathOperator (5 tests) ──
(defsuite "hs-upstream-mathOperator"
(deftest "array + array concats"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "array + single value appends"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "array + array does not mutate original"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "array concat chains"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "empty array + array works"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── no (5 tests) ──
(defsuite "hs-upstream-no"
(deftest "no returns false for non-empty array"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "no with where filters then checks emptiness"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "no with where returns false when matches exist"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "no with where and is not"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
(deftest "no with where on DOM elements"
(hs-cleanup!)
(let ((_el-box (dom-create-element "div")) (_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
(dom-set-attr _el-box "id" "box")
(dom-append (dom-body) _el-box)
;; HS source has bare quotes — HTML parse artifact
(dom-append (dom-body) _el-button)
(dom-set-attr _el-out "id" "out")
(dom-append (dom-body) _el-out)
(dom-dispatch _el-button "click" nil)
(assert= "none" (dom-text-content (dom-query-by-id "out")))
))
)
;; ── objectLiteral (1 tests) ──
(defsuite "hs-upstream-objectLiteral"
(deftest "allows trailing commas"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)
;; ── queryRef (1 tests) ──
(defsuite "hs-upstream-queryRef"
(deftest "queryRef w/ $ works"
(hs-cleanup!)
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
(dom-add-class _el-div "c1")
(dom-append (dom-body) _el-div)
(dom-add-class _el-div1 "c2")
(dom-set-attr _el-div1 "foo" "bar")
(dom-append (dom-body) _el-div1)
(dom-add-class _el-div2 "c3")
(dom-append (dom-body) _el-div2)
))
)
;; ── relativePositionalExpression (4 tests) ──
(defsuite "hs-upstream-relativePositionalExpression"
(deftest "can access property of next element with possessive"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
))
(deftest "can access property of previous element with possessive"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-append (dom-body) _el-d2)
))
(deftest "can access style of next element with possessive"
(hs-cleanup!)
(let ((_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")))
(dom-set-attr _el-d1 "id" "d1")
(dom-append (dom-body) _el-d1)
(dom-set-attr _el-d2 "id" "d2")
(dom-set-attr _el-d2 "style" "color: red")
(dom-append (dom-body) _el-d2)
))
(deftest "can write to next element with put command"
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
)