;; 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-set-attr _el-div "_" "on click add .foo to #bar") (dom-append (dom-body) _el-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")) (_el-p1 (dom-create-element "p"))) (dom-set-attr _el-div "_" "on click add .foo to

in me") (dom-set-attr _el-p1 "id" "p1") (dom-append (dom-body) _el-div) (dom-append _el-div _el-p1) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert (dom-has-class? _el-p1 "foo")) (assert (not (dom-has-class? _el-div "foo"))) )) (deftest "can add to children" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-p1 (dom-create-element "p"))) (dom-set-attr _el-div "_" "on click add .foo to my children") (dom-set-attr _el-p1 "id" "p1") (dom-append (dom-body) _el-div) (dom-append _el-div _el-p1) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert (dom-has-class? _el-p1 "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= (dom-get-attr _el-div "foo") "bar") )) (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= (dom-get-style _el-div "color") "red") (assert= (dom-get-style _el-div "fontFamily") "monospace") )) (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= (dom-get-style _el-div "color") "red") )) (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-add-class _el-div1 "bar") (dom-add-class _el-div2 "bar") (dom-add-class _el-div2 "doh") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert (not (dom-has-class? _el-div1 "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-add-class _el-div1 "bar") (dom-add-class _el-div2 "bar") (dom-add-class _el-div2 "doh") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert (not (dom-has-attr? _el-div1 "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")) (_el-c1 (dom-create-element "div")) (_el-c2 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click add .foo to the children of #bar") (dom-set-attr _el-bar "id" "bar") (dom-set-attr _el-c1 "id" "c1") (dom-set-attr _el-c2 "id" "c2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-bar) (dom-append _el-bar _el-c1) (dom-append _el-bar _el-c2) (hs-activate! _el-div) (dom-dispatch _el-div "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-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-trigger) (dom-append (dom-body) _el-d2) (hs-activate! _el-trigger) (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-set-attr _el-d1 "id" "d1") (dom-add-class _el-d1 "item") (dom-add-class _el-d1 "yes") (dom-set-attr _el-d2 "id" "d2") (dom-add-class _el-d2 "item") (dom-set-attr _el-none "id" "none") (dom-set-attr _el-none "style" "display:none") (dom-append (dom-body) _el-trigger) (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (dom-append (dom-body) _el-none) (hs-activate! _el-trigger) (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-set-attr _el-d1 "id" "d1") (dom-add-class _el-d1 "item") (dom-set-attr _el-none "id" "none") (dom-append (dom-body) _el-trigger) (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-none) (hs-activate! _el-trigger) (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] then add 4 to :arr then put :arr as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1,2,3,4") )) (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 then add 'a' to :s then add 'b' to :s then add 'a' to :s then put :s.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "2") )) ) ;; ── 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-set-attr _el-div "_" "on click remove .foo from #bar") (dom-append (dom-body) _el-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 (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 (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-set-attr _el-that "id" "that") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-that) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert (nil? (dom-parent _el-that))) )) (deftest "can remove parent element" (hs-cleanup!) (let ((_el-p1 (dom-create-element "div")) (_el-b1 (dom-create-element "button"))) (dom-set-attr _el-p1 "id" "p1") (dom-set-attr _el-b1 "id" "b1") (dom-set-attr _el-b1 "_" "on click remove my.parentElement") (dom-append (dom-body) _el-p1) (dom-append _el-p1 _el-b1) (hs-activate! _el-b1) (dom-dispatch _el-p1 "click" nil) (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")) (_el-d1 (dom-create-element "div")) (_el-p (dom-create-element "p")) (_el-p3 (dom-create-element "p"))) (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click remove

from me") (dom-set-inner-html _el-p "foo") (dom-set-inner-html _el-p3 "doh") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (dom-append _el-d1 _el-p) (dom-append _el-div _el-p3) (hs-activate! _el-d1) (dom-dispatch _el-d1 "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-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-set-attr _el-d2 "id" "d2") (dom-add-class _el-d2 "item") (dom-add-class _el-d2 "highlight") (dom-append (dom-body) _el-trigger) (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-trigger) (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] then remove 3 from :arr then put :arr as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1,2,4") )) (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 then remove 'b' from :s then put :s.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "2") )) ) ;; ── 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-set-attr _el-div "_" "on click toggle .foo on #bar") (dom-append (dom-body) _el-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"))) )) (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"))) )) (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-set-attr _el-div "_" "on click toggle .foo until foo from #d1") (dom-append (dom-body) _el-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-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (dom-dispatch _el-div "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-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (dom-dispatch _el-div "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-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (dom-dispatch _el-div "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 or embedded HTML (dom-set-attr _el-div "data-state" "active") ;; SKIP attr [@data-state (contains special chars) (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div "data-state") "inactive") (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div "data-state") "active") )) (deftest "can toggle between different attributes" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes or embedded HTML (dom-set-attr _el-div "enabled" "true") ;; SKIP attr [@enabled (contains special chars) ;; SKIP attr [@disabled (contains special chars) (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div "disabled") "true") (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div "enabled") "true") )) (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= (dom-get-style _el-div "visibility") "hidden") (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "visibility") "visible") )) (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= (dom-get-style _el-div "opacity") "0") (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "opacity") "1") )) (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= (dom-get-style _el-div "visibility") "hidden") (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "visibility") "visible") )) (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-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d2) (hs-activate! _el-div) )) (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-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d2) (hs-activate! _el-div) )) (deftest "can toggle *display between two values" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes or embedded HTML (dom-set-attr _el-div "style" "display:none") (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "display") "flex") (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "display") "none") )) (deftest "can toggle *opacity between three values" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes or embedded HTML (dom-set-attr _el-div "style" "opacity:0") (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "opacity") "0.5") (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "opacity") "1") (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "opacity") "0") )) (deftest "can toggle a global variable between two values" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes or embedded HTML (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 or embedded HTML (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") (dom-set-attr _el-d1 "_" "on click set #d1.innerHTML to \"foo\"") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "foo") )) (deftest "can set indirect properties" (hs-cleanup!) (let ((_el-d1 (dom-create-element "div"))) (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click set innerHTML of #d1 to \"foo\"") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "foo") )) (deftest "can set complex indirect properties lhs" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click set parentNode.innerHTML of #d1 to \"foo\"") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (hs-activate! _el-div) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "foo") )) (deftest "can set complex indirect properties rhs" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click set innerHTML of #d1.parentNode to \"foo\"") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (hs-activate! _el-div) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "foo") )) (deftest "can set chained indirect properties" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click set the innerHTML of the parentNode of #d1 to \"foo\"") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (hs-activate! _el-div) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "foo") )) (deftest "can set styles" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click set my.style.color to \"red\"") (dom-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (deftest "can set javascript globals" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click set window.temp to \"red\"") (dom-set-inner-html _el-div "lolwat") (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 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= (dom-inner-html _el-d1) "foo") )) (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 set #d1.innerHTML to \"foo\"") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "foo") )) (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") (dom-set-attr _el-div "_" "on click set .divs.innerHTML to \"foo\"") (dom-add-class _el-div1 "divs") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-inner-html _el-div) "foo") (assert= (dom-inner-html _el-div1) "foo") )) (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 set @bar to \"foo\"") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div "bar") "foo") )) (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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div2 "bar") "foo") )) (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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div2 "bar") "foo") )) (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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div2 "bar") "foo") )) (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 set *color to \"red\"") (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")) (_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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "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= (dom-inner-html _el-d1) "foo") )) (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"))) (dom-set-attr _el-div "_" "on click set my style[\"color\"] to \"red\"") (dom-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (deftest "can set props 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 set my style[foo] to \"red\"") (dom-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (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-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (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-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (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` then set pdfurl to `https://yyy.xxxxxx.com/path/out/${trackingcode}.pdf` then put pdfurl into me") (dom-set-inner-html _el-div "lolwat") (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= (dom-inner-html _el-d1) "foo") )) (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= (dom-text-content _el-d1) "foo") )) (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-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "_" "on click put #d1 into #d2") (dom-append (dom-body) _el-d1) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "bar") )) (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-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (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-set-inner-html _el-div "lolwat") (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-div2 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-div4 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click put \"foo\" into .divs.parentElement.innerHTML") (dom-set-attr _el-d1 "id" "d1") (dom-add-class _el-div2 "divs") (dom-set-attr _el-d2 "id" "d2") (dom-add-class _el-div4 "divs") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (dom-append _el-d1 _el-div2) (dom-append (dom-body) _el-d2) (dom-append _el-d2 _el-div4) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-d1) "foo") (assert= (dom-text-content _el-d2) "foo") )) (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-div2 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-div4 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click put \"foo\" into innerHTML of parentElement of .divs") (dom-set-attr _el-d1 "id" "d1") (dom-add-class _el-div2 "divs") (dom-set-attr _el-d2 "id" "d2") (dom-add-class _el-div4 "divs") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (dom-append _el-d1 _el-div2) (dom-append (dom-body) _el-d2) (dom-append _el-d2 _el-div4) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-d1) "foo") (assert= (dom-text-content _el-d2) "foo") )) (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= (dom-inner-html _el-d1) "foo") )) (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= (dom-inner-html _el-d1) "foo") )) (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-set-attr _el-d1 "id" "d1") (dom-set-inner-html _el-d1 "foo") (dom-append (dom-body) _el-d2) (dom-append (dom-body) _el-d1) (hs-activate! _el-d2) (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-set-inner-html _el-d1 "foo") (dom-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "_" "on click put #d1 after #d2") (dom-append (dom-body) _el-d1) (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-set-inner-html _el-d1 "*") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-text-content _el-d1) "foo*") )) (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-set-inner-html _el-d1 "*") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-text-content _el-d1) "*foo") )) (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= (dom-get-attr _el-div "bar") "foo") )) (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= (dom-get-attr _el-div "bar") "foo") )) (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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div2 "bar") "foo") )) (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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-attr _el-div2 "bar") "foo") )) (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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "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-set-attr _el-div2 "id" "div2") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (dom-dispatch _el-div "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= (dom-inner-html _el-d1) "foo") )) (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-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (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-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (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-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (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-set-inner-html _el-div "lolwat") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-div "color") "red") )) (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 \"\" 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= (dom-inner-html _el-div) "42") )) (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 \"\" into ") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "42") )) (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 \"\" 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= (dom-inner-html _el-d1) "42") )) (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 \"\" 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= (dom-inner-html _el-d1) "42") )) (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 \"\" 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= (dom-inner-html _el-d1) "42") )) (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 \"\" 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= (dom-inner-html _el-d1) "42") )) (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] then put 1 at start of :arr then put :arr as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1,2,3") )) (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] then put 3 at end of :arr then put :arr as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1,2,3") )) ) ;; ── 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) ;; 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-set-attr _el-div1 "_" "on click hide .hideme") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (hs-activate! _el-div1) (dom-dispatch _el-div "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")) (_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 hide

in me when it matches .hideable") (dom-set-attr _el-d1 "id" "d1") (dom-add-class _el-d1 "hideable") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-trigger) (dom-append _el-trigger _el-d1) (dom-append _el-trigger _el-d2) (hs-activate! _el-trigger) (dom-dispatch (dom-query-by-id "trigger") "click" nil) (assert= (dom-get-style (dom-query-by-id "d1") "display") "none") (assert= (dom-get-style (dom-query-by-id "d2") "display") "block") )) ) ;; ── 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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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= (dom-inner-html _el-div) "foo") )) (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 then if window.tmp thenn then 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= (dom-inner-html _el-div) "foo") )) (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 then if window.tmp thenn elsen then if window.tmp then endn then 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= (dom-inner-html _el-div) "123") )) (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 then 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 then log me then put x at end of men then wait 1msn end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-inner-html _el-div) "123") )) (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= (dom-inner-html _el-div) "123") )) (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 then 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 then put x at end of men then wait 1msn end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-inner-html _el-div) "123") )) (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-set-inner-html _el-script "def repeatForeverWithReturn() set retVal to 0 repeat forever set retVal to retVal + 1 if retVal == 5 then return retVal end end end") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click put repeatForeverWithReturn() into my.innerHTML") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "5") )) (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-set-inner-html _el-script "def repeatForeverWithReturn() set retVal to 0 repeat set retVal to retVal + 1 if retVal == 5 then return retVal end end end") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click put repeatForeverWithReturn() into my.innerHTML") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "5") )) (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= (dom-inner-html _el-div) "123") )) (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 then 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= (dom-inner-html _el-div) "a0ab1abc2") )) (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 then 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= (dom-inner-html _el-div) "a0ab1abc2") )) (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-set-inner-html _el-script "def repeatWhileTest() set retVal to 0 repeat while retVal < 5 set retVal to retVal + 1 end return retVal end") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click put repeatWhileTest() into my.innerHTML") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "5") )) (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-set-inner-html _el-script "def repeatUntilTest() set retVal to 0 repeat until retVal == 5 set retVal to retVal + 1 end return retVal end") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click put repeatUntilTest() into my.innerHTML") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "5") )) (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-set-attr _el-script "type" "text/hyperscript") (dom-set-inner-html _el-script "def repeatUntilTest() repeat until event click from #untilTest wait 2ms end return 42 end") (dom-append (dom-body) _el-untilTest) (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-set-inner-html _el-script "def getArray() set window.called to (window.called or 0) + 1 return [1, 2, 3] end") (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-script) (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "3") ;; 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-set-inner-html _el-script "def sprayInto(elt) for x in [1, 2, 3] for y in [1, 2, 3] put x * y at end of elt end end end") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click call sprayInto(me)") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= (dom-inner-html _el-d1) "123246369") )) (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= (dom-inner-html _el-div) "aaa") )) (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= (dom-inner-html _el-div) "aaaaaa") )) (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 then continue then put 'FAIL!!. ' at end of me then end then put 'expected D. ' at end of me then end then end then") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-inner-html _el-div) "success A. success B. success C. expected D. success A. success B. success C. expected D. ") )) (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' then break then end then put x at end of me then end then end then") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-inner-html _el-div) "ABAB") )) (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 then 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} then for prop in x then 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= (dom-text-content _el-div) "123") )) (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 then repeat then set x to until x is 3 end then put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "3") )) (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 then repeat then set x to while x < 3 end then put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "3") )) (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 then repeat then set x to until true end then put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1") )) (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 then repeat 10 times set x to x + 1 then if x is 3 break end then end then put x into me then") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "3") )) (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 then put x at end of me then end then") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1245") )) (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 then put x at end of me then end then") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "123") )) (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 then repeat while x < 100 then set x to x + 1 then if x is 5 break end then end then put x into me then") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "5") )) (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= (dom-text-content _el-div) "done") )) ) ;; ── 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= (dom-inner-html _el-div) "hyperscript is hyper cool") )) (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= (dom-inner-html _el-div) "bar") )) (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-set-attr _el-div "_" "on click add .foo then wait for foo from #d2 then add .bar") (dom-append (dom-body) _el-d2) (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-set-attr _el-div "_" "on click add .foo then wait for foo or 0ms then add .bar") (dom-append (dom-body) _el-d2) (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-set-attr _el-div "_" "on click add .foo then wait for foo or 0ms then add .bar") (dom-append (dom-body) _el-d2) (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-set-attr _el-bar "id" "bar") (dom-set-attr _el-bar "_" "on foo add .foo-sent") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-bar) (hs-activate! _el-div) (hs-activate! _el-bar) (dom-dispatch _el-div "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-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-div) (dom-append (dom-body) _el-bar) (hs-activate! _el-div) (hs-activate! _el-bar) (dom-dispatch _el-div "click" nil) (assert (dom-has-class? _el-div "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-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-div) (dom-append (dom-body) _el-bar) (hs-activate! _el-div) (hs-activate! _el-bar) (dom-dispatch _el-div "click" nil) (assert (not (dom-has-class? _el-bar "foo-sent"))) (assert= (dom-inner-html _el-bar) "42") )) (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-set-attr _el-bar "id" "bar") (dom-set-attr _el-bar "_" "on foo.bar add .foo-sent") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-bar) (hs-activate! _el-div) (hs-activate! _el-bar) (dom-dispatch _el-div "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-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-div) (dom-append (dom-body) _el-bar) (hs-activate! _el-div) (hs-activate! _el-bar) (dom-dispatch _el-div "click" nil) (assert (not (dom-has-class? _el-bar "foo-sent"))) (assert= (dom-inner-html _el-bar) "42") )) (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-set-attr _el-bar "id" "bar") (dom-set-attr _el-bar "_" "on foo:bar add .foo-sent") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-bar) (hs-activate! _el-div) (hs-activate! _el-bar) (dom-dispatch _el-div "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-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-div) (dom-append (dom-body) _el-bar) (hs-activate! _el-div) (hs-activate! _el-bar) (dom-dispatch _el-div "click" nil) (assert (not (dom-has-class? _el-bar "foo-sent"))) (assert= (dom-inner-html _el-bar) "42") )) (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-set-attr _el-bar "id" "bar") (dom-set-attr _el-bar "_" "on foo add .foo-sent") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-bar) (hs-activate! _el-div) (hs-activate! _el-bar) (dom-dispatch _el-div "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-add-class _el-div1 "div") (dom-set-attr _el-div1 "_" "on click take .foo from .div") (dom-add-class _el-div2 "div") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert (not (dom-has-class? _el-div "foo"))) (assert (dom-has-class? _el-div1 "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-add-class _el-form1 "div") (dom-set-attr _el-form1 "_" "on click take .foo from .div") (dom-add-class _el-form2 "div") (dom-append (dom-body) _el-form) (dom-append (dom-body) _el-form1) (dom-append (dom-body) _el-form2) (hs-activate! _el-form1) (dom-dispatch (dom-query-by-id "f2") "click" nil) (assert (not (dom-has-class? (dom-query-by-id "f1") "foo"))) (assert (dom-has-class? (dom-query-by-id "f2") "foo")) (assert (not (dom-has-class? (dom-query-by-id "f3") "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-add-class _el-div1 "div") (dom-set-attr _el-div1 "_" "on click take .foo from .div for #d3") (dom-set-attr _el-d3 "id" "d3") (dom-add-class _el-d3 "div") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-d3) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert (not (dom-has-class? _el-div "foo"))) (assert (not (dom-has-class? _el-div1 "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")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-d3 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click take .foo from .div for event.target") (dom-set-attr _el-d1 "id" "d1") (dom-add-class _el-d1 "div") (dom-add-class _el-d1 "foo") (dom-set-attr _el-d2 "id" "d2") (dom-add-class _el-d2 "div") (dom-set-attr _el-d3 "id" "d3") (dom-add-class _el-d3 "div") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (dom-append _el-div _el-d2) (dom-append _el-div _el-d3) (hs-activate! _el-div) (dom-dispatch _el-d2 "click" nil) (assert (not (dom-has-class? _el-d1 "foo"))) (assert (dom-has-class? _el-d2 "foo")) (assert (not (dom-has-class? _el-d3 "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-add-class _el-div1 "div") (dom-set-attr _el-div1 "_" "on click take @data-foo from .div") (dom-add-class _el-div2 "div") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert= (dom-get-attr _el-div "data-foo") "bar") (assert= (dom-get-attr _el-div1 "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-add-class _el-div1 "div") (dom-set-attr _el-div1 "_" "on click take @data-foo=baz from .div") (dom-add-class _el-div2 "div") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert= (dom-get-attr _el-div "data-foo") "bar") (assert= (dom-get-attr _el-div1 "data-foo") "baz") ;; 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-add-class _el-div1 "div") (dom-set-attr _el-div1 "_" "on click take @data-foo=baz with \"qux\" from .div") (dom-add-class _el-div2 "div") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert= (dom-get-attr _el-div "data-foo") "qux") (assert= (dom-get-attr _el-div1 "data-foo") "baz") (assert= (dom-get-attr _el-div2 "data-foo") "qux") ;; 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-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-add-class _el-div2 "div") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert= (dom-get-attr _el-div "data-foo") "qux") (assert= (dom-get-attr _el-div1 "data-foo") "baz") (assert= (dom-get-attr _el-div2 "data-foo") "qux") ;; 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-add-class _el-div1 "div") (dom-set-attr _el-div1 "_" "on click take @data-foo from .div for #d3") (dom-set-attr _el-d3 "id" "d3") (dom-add-class _el-d3 "div") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-d3) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert= (dom-get-attr _el-div "data-foo") "bar") (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")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-d3 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click take @data-foo from .div for event.target") (dom-set-attr _el-d1 "id" "d1") (dom-add-class _el-d1 "div") (dom-set-attr _el-d1 "data-foo" "bar") (dom-set-attr _el-d2 "id" "d2") (dom-add-class _el-d2 "div") (dom-set-attr _el-d3 "id" "d3") (dom-add-class _el-d3 "div") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (dom-append _el-div _el-d2) (dom-append _el-div _el-d3) (hs-activate! _el-div) (dom-dispatch _el-d2 "click" nil) (assert= (dom-get-attr _el-d1 "data-foo") "bar") (assert= (dom-get-attr _el-d2 "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-add-class _el-div1 "div") (dom-set-attr _el-div1 "_" "on click take .foo .bar") (dom-add-class _el-div2 "div") (dom-add-class _el-div2 "bar") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert (not (dom-has-class? _el-div "foo"))) (assert (dom-has-class? _el-div1 "foo")) (assert (not (dom-has-class? _el-div2 "foo"))) (assert (not (dom-has-class? _el-div "bar"))) (assert (dom-has-class? _el-div1 "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-add-class _el-div1 "div") (dom-set-attr _el-div1 "_" "on click take .foo .bar from .div1") (dom-add-class _el-div2 "div") (dom-add-class _el-div2 "bar") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div1) (dom-dispatch _el-div1 "click" nil) (assert (not (dom-has-class? _el-div "foo"))) (assert (dom-has-class? _el-div1 "foo")) (assert (not (dom-has-class? _el-div2 "foo"))) (assert (not (dom-has-class? _el-div "bar"))) (assert (dom-has-class? _el-div1 "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= (dom-get-style _el-div "width") "100px") )) (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 then 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= (dom-get-style _el-div "width") "100px") )) (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= (dom-get-style _el-form "width") "100px") )) (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= (dom-get-style _el-div "width") "100px") )) (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= (dom-get-style _el-div "width") "100px") (assert= (dom-get-style _el-div "height") "100px") )) (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-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-foo "width") "100px") )) (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-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-foo "width") "100px") )) (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-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-foo "width") "100px") )) (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-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-foo "width") "100px") )) (deftest "can transition with a custom transition time" (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 using \"width 2s ease-in\"") (dom-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-foo "width") "100px") )) (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-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-foo "width") "100px") )) (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= (dom-get-style _el-div "width") "100px") )) (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= (dom-get-style _el-form "width") "100px") )) (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= (dom-get-style _el-div "width") "100px") )) (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= (dom-get-style _el-div "width") "10px") )) (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-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) )) (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-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) )) (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-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) )) (deftest "can transition with a custom transition string" (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 using \"width 2s ease-in\"") (dom-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-foo) (hs-activate! _el-div) )) (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 or embedded HTML (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-span) (dom-dispatch _el-div "click" nil) (assert= (dom-get-style _el-span "width") "100px") )) ) ;; ── 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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "[object DocumentFragment]") ;; 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= (dom-inner-html _el-div) "'{\"foo\":1}'") )) (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= (dom-inner-html _el-div) "'{\"foo\":1}'") )) (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= (dom-inner-html _el-div) "'{\"foo\":1}'") )) (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= (dom-inner-html _el-div) "yep") )) (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= (dom-inner-html _el-div) "1.2") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-inner-html _el-div) "yay") )) (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= (dom-text-content _el-div) "{\"foo\":1}") )) (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= (dom-text-content _el-div) "caught") )) (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= (dom-text-content _el-div) "the body") )) (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= (dom-text-content _el-div) "the body") )) (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= (dom-text-content _el-div) "404") )) (deftest "Response can be converted to JSON via as JSON" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes or embedded HTML (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "Joe") )) ) ;; ── 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= (dom-inner-html _el-div) "1") )) (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= (dom-inner-html _el-div) "22") )) (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= (dom-inner-html _el-div) "2") )) (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= (dom-inner-html _el-div) "8") )) (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= (dom-inner-html _el-div) "11.3") )) (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-set-inner-html _el-div "3") (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= (dom-inner-html _el-div) "6") )) (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= (dom-inner-html _el-div) "20") )) (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= (dom-inner-html _el-div) "5") )) (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= (dom-inner-html _el-div) "-1") )) (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= (dom-inner-html _el-div) "18") )) (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= (dom-inner-html _el-div) "2") )) (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= (dom-inner-html _el-div) "1") )) (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-set-inner-html _el-div "3") (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= (dom-inner-html _el-div) "0") )) (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= (dom-inner-html _el-div) "-5") )) (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= (dom-inner-html _el-div) "20") )) (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= (dom-text-content _el-div) "21") )) (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= (dom-text-content _el-div) "19") )) (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-set-inner-html _el-d1 "5") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch (dom-query-by-id "d1") "click" nil) (assert= (dom-text-content (dom-query-by-id "d1")) "6") )) (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-set-inner-html _el-d1 "5") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) (dom-dispatch (dom-query-by-id "d1") "click" nil) (assert= (dom-text-content (dom-query-by-id "d1")) "6") )) (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= (dom-text-content _el-div) "0.75") )) ) ;; ── 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= (dom-inner-html _el-div) "Hello there. General Kenobi.") )) (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] then append 4 to value then set my.innerHTML to value as String") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-inner-html _el-div) "1,2,3,4") )) (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] then append 4 then put it as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-inner-html _el-div) "1,2,3,4") )) (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 'This is my inner HTML' to me then append 'With Tags' to me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-inner-html _el-div) "This is my inner HTMLWith Tags") )) (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= (dom-inner-html _el-content) "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= (dom-inner-html _el-div) "Content") )) (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= (dom-inner-html _el-id) "foobardoh") )) (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= (dom-inner-html _el-id) "bar") )) (deftest "append preserves existing content rather than overwriting it" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-btn1 (dom-create-element "button"))) (dom-set-attr _el-div "_" "on click append 'New Content' to me") (dom-set-attr _el-btn1 "id" "btn1") (dom-set-inner-html _el-btn1 "Click Me") (dom-append (dom-body) _el-div) (dom-append _el-div _el-btn1) (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 `` 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 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 then append 3 to :s then append 1 to :s then put :s.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "3") )) ) ;; ── 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 then tell #d2 then add .bar") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (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 (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 then tell #d2 then add .bar to me") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert (dom-has-class? _el-d1 "bar")) (assert (dom-has-class? _el-d1 "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")) (_el-p1 (dom-create-element "p")) (_el-p2 (dom-create-element "p")) (_el-d2 (dom-create-element "div"))) (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click add .foo then tell

in me then add .bar") (dom-set-attr _el-p1 "id" "p1") (dom-set-attr _el-p2 "id" "p2") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d1) (dom-append _el-d1 _el-p1) (dom-append _el-d1 _el-p2) (dom-append _el-d1 _el-d2) (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? (dom-query-by-id "div2") "bar"))) (assert (not (dom-has-class? (dom-query-by-id "div2") "foo"))) (assert (dom-has-class? _el-p1 "bar")) (assert (not (dom-has-class? _el-p1 "foo"))) (assert (dom-has-class? _el-p2 "bar")) (assert (not (dom-has-class? _el-p2 "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 then add .bar end then add .foo") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (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 (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 then add .bar end then add .foo") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (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-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 then add .bar to you") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-d1) (dom-dispatch _el-d1 "click" nil) (assert (not (dom-has-class? _el-d1 "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 then put your innerText into me") (dom-set-attr _el-d2 "id" "d2") (dom-set-inner-html _el-d2 "foo") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-d1) (dom-dispatch _el-d1 "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 then put @foo into me") (dom-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "foo" "bar") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-d1) (dom-dispatch _el-d1 "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")) (_el-d2 (dom-create-element "div"))) (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click tell #d2 remove yourself") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d1) (dom-append _el-d1 _el-d2) (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")) (_el-d2 (dom-create-element "div")) (_el-d3 (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-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d3 "id" "d3") (dom-append (dom-body) _el-d1) (dom-append _el-d1 _el-d2) (dom-append _el-d1 _el-d3) (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-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on example.event add .called") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (hs-activate! _el-d1) (dom-dispatch _el-div "click" nil) (assert (dom-has-class? _el-div "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-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on example:event add .called") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (hs-activate! _el-d1) (dom-dispatch _el-div "click" nil) (assert (dom-has-class? _el-div "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-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on \"a-b\" add .called") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (hs-activate! _el-d1) (dom-dispatch _el-div "click" nil) (assert (dom-has-class? _el-div "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-set-attr _el-div "_" "on click from #bar add .clicked") (dom-append (dom-body) _el-bar) (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-set-attr _el-div "_" "on click from #bar set #bar.innerHTML to #bar.innerHTML + \"a\"") (dom-append (dom-body) _el-bar) (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-bar "click" nil) (dom-dispatch _el-bar "click" nil) (assert= (dom-inner-html _el-bar) "a") )) (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= (dom-inner-html _el-div) "1") )) (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-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "_" "on custom(foo) call me.classList.add(foo)") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-d1) (hs-activate! _el-d2) (dom-dispatch _el-d1 "click" nil) (assert (dom-has-class? _el-d1 "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-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "_" "on fromBar(type) call me.classList.add(type)") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-d1) (hs-activate! _el-d2) (dom-dispatch _el-d1 "click" nil) (assert (dom-has-class? _el-d1 "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-set-inner-html _el-script "on load put \"Loaded\" into #loadedDemo.innerHTML") (dom-set-attr _el-loadedDemo "id" "loadedDemo") (dom-append (dom-body) _el-script) (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-set-attr _el-div1 "_" "on click[buttons==1] log event then put \"Clicked\" into my.innerHTML") (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-div) (dom-append (dom-body) _el-div1) (dom-append (dom-body) _el-div2) (hs-activate! _el-div) (hs-activate! _el-div1) (hs-activate! _el-div2) (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("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")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div"))) (dom-set-attr _el-div "_" "on click in #d1 put it into window.tmp") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (dom-append _el-div _el-d2) (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-set-inner-html _el-div "0") (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= (dom-inner-html _el-div) "1") )) (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-set-inner-html _el-div "0") (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= (dom-inner-html _el-div) "2") )) (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-set-inner-html _el-div "0") (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= (dom-inner-html _el-div) "2") )) (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-set-inner-html _el-div "0") (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= (dom-inner-html _el-div) "three") )) (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= (dom-inner-html _el-div) "Mutated") )) (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= (dom-inner-html _el-div) "Mutated") )) (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= (dom-inner-html _el-div) "Mutated") )) (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= (dom-inner-html _el-div) "Mutated") )) (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= (dom-inner-html _el-div) "Mutated") )) (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= (dom-inner-html _el-div) "Mutated") )) (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-set-attr _el-div "_" "on mutation of attributes from #d1 put \"Mutated\" into me") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-set-attr _el-d1 "foo" "bar") (assert= (dom-inner-html _el-div) "Mutated") )) (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-set-inner-html _el-script "behavior DemoBehavior on foo wait 10ms then set my innerHTML to 'behavior'") (dom-set-attr _el-div "_" "install DemoBehavior") (dom-set-attr _el-div2 "_" "install DemoBehavior") (dom-set-attr _el-div3 "_" "install DemoBehavior") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div2) (dom-append (dom-body) _el-div3) (hs-activate! _el-div) (hs-activate! _el-div2) (hs-activate! _el-div3) (dom-dispatch _el-div "foo" nil) (dom-dispatch _el-div2 "foo" nil) (dom-dispatch _el-div3 "foo" nil) (assert= (dom-inner-html _el-div) "behavior") (assert= (dom-inner-html _el-div2) "behavior") (assert= (dom-inner-html _el-div3) "behavior") )) (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= (dom-inner-html _el-button) "bar") )) (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-set-inner-html _el-script "def throwBar() throw 'bar' end") (dom-set-attr _el-button "_" "on click throwBar() catch e put e into me") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-button) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-inner-html _el-button) "bar") )) (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= (dom-inner-html _el-button) "bar") )) (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= (dom-inner-html _el-button) "bar") )) (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 then if :x is 1 then wait 1ms then throw \"bar\" otherwise then put \"success\" into me end catch e then 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= (dom-inner-html _el-button) "success") )) (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 then if :x is 1 then throw \"bar\" otherwise then put \"success\" into me end catch e then 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= (dom-inner-html _el-button) "success") )) (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= (dom-inner-html _el-button) "bar") )) (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= (dom-inner-html _el-button) "foo") )) (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= (dom-inner-html _el-button) "bar") )) (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= (dom-inner-html _el-button) "bar") )) (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= (dom-inner-html _el-button) "bar") )) (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= (dom-inner-html _el-button) "bar") )) (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= (dom-inner-html _el-button) "foobar") )) (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 then if :x is 1 then wait 1ms then throw \"bar\" otherwise then 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= (dom-inner-html _el-button) "success") )) (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 then if :x is 1 then throw \"bar\" otherwise then 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= (dom-inner-html _el-button) "success") )) (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 then 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= (dom-inner-html _el-#d1) "clicked") )) (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-set-attr _el-d2 "id" "d2") (dom-set-attr _el-div "_" "on click from #d1 or click from #d2 then increment @count then put @count into me") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-d1 "click" nil) (dom-dispatch _el-d2 "click" nil) (assert= (dom-inner-html _el-div) "2") )) (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-set-inner-html _el-div "0") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1") (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1") )) (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= (dom-text-content _el-button) "foo") )) (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= (dom-text-content _el-button) "bar") )) (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 then 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= (dom-text-content _el-div) "clicked") )) ) ;; ── 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 then 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= (dom-inner-html _el-div) "42") )) (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-set-inner-html _el-script "init set window.foo to 42 end") (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-set-inner-html _el-script "init set window.foo to 10 init immediately set window.bar to window.foo") (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-set-inner-html _el-script "def foo() add .called to #d1 end") (dom-set-attr _el-div "_" "on click call foo()") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (dom-dispatch _el-script "click" nil) (assert (dom-has-class? _el-div "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-set-inner-html _el-script "def foo(str) put str into #d1.innerHTML end") (dom-set-attr _el-div "_" "on click call foo(\"called\")") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (dom-dispatch _el-script "click" nil) (assert= (dom-inner-html _el-div) "called") )) (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-set-inner-html _el-script "def utils.foo() add .called to #d1 end") (dom-set-attr _el-div "_" "on click call utils.foo()") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (dom-dispatch _el-script "click" nil) (assert (dom-has-class? _el-div "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-set-inner-html _el-script "def foo() log meend") (dom-set-attr _el-div "_" "on click call foo() then add .called to #d1") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (dom-dispatch _el-script "click" nil) (assert (dom-has-class? _el-div "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-set-inner-html _el-script "def foo() wait 1ms log meend") (dom-set-attr _el-div "_" "on click call foo() then add .called to #d1") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (dom-dispatch _el-script "click" nil) (assert (dom-has-class? _el-div "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-set-inner-html _el-script "def foo() return \"foo\"end") (dom-set-attr _el-div "_" "on click call foo() then put it into #d1.innerText") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (dom-dispatch _el-script "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-set-inner-html _el-script "def foo() exit end") (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-set-inner-html _el-script "def foo() wait 1ms return \"foo\"end") (dom-set-attr _el-div "_" "on click call foo() then put it into #d1.innerText") (dom-set-attr _el-d1 "id" "d1") (dom-append (dom-body) _el-script) (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-d1) (hs-activate! _el-div) (dom-dispatch _el-script "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-set-inner-html _el-script "def foo() return \"foo\"end") (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-set-inner-html _el-script "def foo() wait 1ms return \"foo\"end") (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-set-inner-html _el-script "def foo() throw \"bar\"catch e set window.bar to e end") (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-set-inner-html _el-script "def foo() throw \"bar\"catch e throw e end") (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-set-inner-html _el-script "def foo() throw \"bar\"catch e return 42 end") (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-set-inner-html _el-script "def doh() wait 10ms throw \"bar\"end def foo() call doh()catch e set window.bar to e end") (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-set-inner-html _el-script "def doh() wait 10ms throw \"bar\"end def foo() call doh()catch e set window.bar to e end") (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-set-inner-html _el-script "def foo() throw \"bar\"catch e wait 10ms throw e end") (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-set-inner-html _el-script "def foo() throw \"bar\"catch e wait 10ms return 42 end") (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")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-d3 (dom-create-element "div"))) (dom-set-attr _el-div "_" "def func() put 42 into #d3") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click call func()") (dom-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d3 "id" "d3") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (dom-append _el-div _el-d2) (dom-append _el-div _el-d3) (hs-activate! _el-div) (hs-activate! _el-d1) ;; 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")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-d3 (dom-create-element "div"))) (dom-set-attr _el-div "_" "def func() return 42") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click put func() into me") (dom-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d3 "id" "d3") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (dom-append _el-div _el-d2) (dom-append _el-div _el-d3) (hs-activate! _el-div) (hs-activate! _el-d1) ;; 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")) (_el-d1 (dom-create-element "div")) (_el-d2 (dom-create-element "div")) (_el-d3 (dom-create-element "div"))) (dom-set-attr _el-div "_" "def func() put 42 into me") (dom-set-attr _el-d1 "id" "d1") (dom-set-attr _el-d1 "_" "on click call func()") (dom-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d3 "id" "d3") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (dom-append _el-div _el-d2) (dom-append _el-div _el-d3) (hs-activate! _el-div) (hs-activate! _el-d1) ;; 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-set-inner-html _el-script "def foo() set window.bar to 10finally set window.bar to 20 end") (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-set-inner-html _el-script "def foo() set window.bar to 10 throw \"foo\"finally set window.bar to 20 end") (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-set-inner-html _el-script "def foo() set window.bar to 10 call throwsAsyncException()finally set window.bar to 20 end") (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-set-inner-html _el-script "def foo() wait a tick then set window.bar to 10finally set window.bar to 20 end") (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-set-inner-html _el-script "def foo() wait a tick then set window.bar to 10 throw \"foo\"finally set window.bar to 20 end") (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-set-inner-html _el-script "def foo() set x to 1 then exit then set x to 2 then return x end") (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-set-inner-html _el-script "def foo() return end") (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-set-inner-html _el-button "Ask") (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-out) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "Alice") )) (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-set-inner-html _el-button "Ask") (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-out) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "null") )) (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-set-inner-html _el-button "Go") (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-out) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "done") )) (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-set-inner-html _el-button "Go") (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-out) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "Yes") )) (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-set-inner-html _el-button "Go") (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-out) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "No") )) ) ;; ── dialog (10 tests) ── (defsuite "hs-upstream-dialog" (deftest "show opens a dialog as modal" (hs-cleanup!) (let ((_el-d (dom-create-element "dialog")) (_el-p (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-d "id" "d") (dom-set-inner-html _el-p "Hello") (dom-set-attr _el-button "_" "on click show #d") (dom-set-inner-html _el-button "Open") (dom-append (dom-body) _el-d) (dom-append _el-d _el-p) (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")) (_el-p (dom-create-element "p")) (_el-close (dom-create-element "button"))) (dom-set-attr _el-d "id" "d") (dom-set-inner-html _el-p "Hello") (dom-set-attr _el-close "id" "close") (dom-set-attr _el-close "_" "on click hide #d") (dom-set-inner-html _el-close "Close") (dom-append (dom-body) _el-d) (dom-append _el-d _el-p) (dom-append _el-d _el-close) (hs-activate! _el-close) (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")) (_el-p (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-d "id" "d") (dom-set-inner-html _el-p "Hello") (dom-set-attr _el-button "_" "on click show #d") (dom-set-inner-html _el-button "Show Again") (dom-append (dom-body) _el-d) (dom-append _el-d _el-p) (dom-append _el-d _el-button) (hs-activate! _el-button) (dom-dispatch _el-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-p (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-d "id" "d") (dom-set-inner-html _el-p "Hello") (dom-set-attr _el-button "_" "on click open #d") (dom-set-inner-html _el-button "Open") (dom-append (dom-body) _el-d) (dom-append _el-d _el-p) (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")) (_el-p (dom-create-element "p")) (_el-close (dom-create-element "button"))) (dom-set-attr _el-d "id" "d") (dom-set-inner-html _el-p "Hello") (dom-set-attr _el-close "id" "close") (dom-set-attr _el-close "_" "on click close #d") (dom-set-inner-html _el-close "Close") (dom-append (dom-body) _el-d) (dom-append _el-d _el-p) (dom-append _el-d _el-close) (hs-activate! _el-close) (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-summary (dom-create-element "summary")) (_el-p (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-d "id" "d") (dom-set-inner-html _el-summary "More") (dom-set-inner-html _el-p "Content") (dom-set-attr _el-button "_" "on click open #d") (dom-set-inner-html _el-button "Open") (dom-append (dom-body) _el-d) (dom-append _el-d _el-summary) (dom-append _el-d _el-p) (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-summary (dom-create-element "summary")) (_el-p (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-d "id" "d") (dom-set-inner-html _el-summary "More") (dom-set-inner-html _el-p "Content") (dom-set-attr _el-button "_" "on click close #d") (dom-set-inner-html _el-button "Close") (dom-append (dom-body) _el-d) (dom-append _el-d _el-summary) (dom-append _el-d _el-p) (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-p1 (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-p "id" "p") (dom-set-inner-html _el-p1 "Popover content") (dom-set-attr _el-button "_" "on click open #p") (dom-set-inner-html _el-button "Open") (dom-append (dom-body) _el-p) (dom-append _el-p _el-p1) (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")) (_el-p1 (dom-create-element "p")) (_el-close (dom-create-element "button"))) (dom-set-attr _el-p "id" "p") (dom-set-inner-html _el-p1 "Popover content") (dom-set-attr _el-close "id" "close") (dom-set-attr _el-close "_" "on click close #p") (dom-set-inner-html _el-close "Close") (dom-append (dom-body) _el-p) (dom-append _el-p _el-p1) (dom-append _el-p _el-close) (hs-activate! _el-close) (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-set-attr _el-button "_" "on click send myOpen to #d") (dom-set-inner-html _el-button "Open") (dom-append (dom-body) _el-d) (dom-append (dom-body) _el-button) (hs-activate! _el-d) (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-p (dom-create-element "p")) (_el-p2 (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-d1 "id" "d1") (dom-set-inner-html _el-p "hello") (dom-set-inner-html _el-p2 "world") (dom-set-attr _el-button "_" "on click empty #d1") (dom-append (dom-body) _el-d1) (dom-append _el-d1 _el-p) (dom-append _el-d1 _el-p2) (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-set-inner-html _el-div "content") (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-p (dom-create-element "p")) (_el-div2 (dom-create-element "div")) (_el-p3 (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-add-class _el-div "clearme") (dom-set-inner-html _el-p "a") (dom-add-class _el-div2 "clearme") (dom-set-inner-html _el-p3 "b") (dom-set-attr _el-button "_" "on click empty .clearme") (dom-append (dom-body) _el-div) (dom-append _el-div _el-p) (dom-append (dom-body) _el-div2) (dom-append _el-div2 _el-p3) (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] then empty :arr then put :arr.length into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "0") )) (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 then empty :s then put :s.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "0") )) (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 then empty :m then put :m.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "0") )) (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-set-attr _el-button "_" "on click empty #t1") (dom-set-inner-html _el-button "Empty") (dom-append (dom-body) _el-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-set-inner-html _el-ta1 "some text") (dom-set-attr _el-button "_" "on click empty #ta1") (dom-set-inner-html _el-button "Empty") (dom-append (dom-body) _el-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-set-attr _el-button "_" "on click empty #cb1") (dom-set-inner-html _el-button "Empty") (dom-append (dom-body) _el-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-option (dom-create-element "option")) (_el-option2 (dom-create-element "option")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-sel1 "id" "sel1") (dom-set-attr _el-option "value" "a") (dom-set-inner-html _el-option "A") (dom-set-attr _el-option2 "value" "b") (dom-set-inner-html _el-option2 "B") (dom-set-attr _el-button "_" "on click empty #sel1") (dom-set-inner-html _el-button "Empty") (dom-append (dom-body) _el-sel1) (dom-append _el-sel1 _el-option) (dom-append _el-sel1 _el-option2) (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-t2 (dom-create-element "input")) (_el-ta2 (dom-create-element "textarea")) (_el-cb2 (dom-create-element "input")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-f1 "id" "f1") (dom-set-attr _el-t2 "id" "t2") (dom-set-attr _el-t2 "type" "text") (dom-set-attr _el-t2 "value" "val") (dom-set-attr _el-ta2 "id" "ta2") (dom-set-inner-html _el-ta2 "text") (dom-set-attr _el-cb2 "id" "cb2") (dom-set-attr _el-cb2 "type" "checkbox") (dom-set-attr _el-button "_" "on click empty #f1") (dom-set-inner-html _el-button "Empty") (dom-append (dom-body) _el-f1) (dom-append _el-f1 _el-t2) (dom-append _el-f1 _el-ta2) (dom-append _el-f1 _el-cb2) (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-set-attr _el-button "_" "on click clear #t3") (dom-set-inner-html _el-button "Clear") (dom-append (dom-body) _el-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-p (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-d2 "id" "d2") (dom-set-inner-html _el-p "content") (dom-set-attr _el-button "_" "on click clear #d2") (dom-append (dom-body) _el-d2) (dom-append _el-d2 _el-p) (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-set-attr _el-button "_" "on click focus #i1") (dom-append (dom-body) _el-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"))) (dom-set-attr _el-div "_" "on click go to \"#test-hash\"") (dom-append (dom-body) _el-div) (hs-activate! _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-set-attr _el-target "id" "target") (dom-set-inner-html _el-target "Target") (dom-set-attr _el-div2 "_" "on click go to #target") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-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-set-attr _el-target "id" "target") (dom-set-inner-html _el-target "Target") (dom-set-attr _el-div2 "_" "on click go to the top of #target") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-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")) (_el-inner (dom-create-element "a"))) (dom-set-attr _el-outer "id" "outer") (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-set-attr _el-inner "id" "inner") (dom-set-attr _el-inner "_" "on click halt") (dom-set-attr _el-inner "href" "#shouldnot") (dom-set-inner-html _el-inner "click me") (dom-append (dom-body) _el-outer) (dom-append _el-outer _el-inner) (hs-activate! _el-outer) (hs-activate! _el-inner) (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-set-inner-html _el-div "test") (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")) (_el-inner (dom-create-element "div"))) (dom-set-attr _el-outer "id" "outer") (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-set-attr _el-inner "id" "inner") (dom-set-attr _el-inner "_" "on click halt the event then add .continued") (dom-set-inner-html _el-inner "click me") (dom-append (dom-body) _el-outer) (dom-append _el-outer _el-inner) (hs-activate! _el-outer) (hs-activate! _el-inner) (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")) (_el-inner (dom-create-element "div"))) (dom-set-attr _el-outer "id" "outer") (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-set-attr _el-inner "id" "inner") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-inner "click me") (dom-append (dom-body) _el-outer) (dom-append _el-outer _el-inner) (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")) (_el-inner (dom-create-element "div"))) (dom-set-attr _el-outer "id" "outer") (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-set-attr _el-inner "id" "inner") (dom-set-attr _el-inner "_" "on click halt bubbling then add .continued") (dom-set-inner-html _el-inner "click me") (dom-append (dom-body) _el-outer) (dom-append _el-outer _el-inner) (hs-activate! _el-outer) (hs-activate! _el-inner) (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")) (_el-inner (dom-create-element "div"))) (dom-set-attr _el-outer "id" "outer") (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-set-attr _el-inner "id" "inner") (dom-set-attr _el-inner "_" "on click halt default") (dom-set-inner-html _el-inner "click me") (dom-append (dom-body) _el-outer) (dom-append _el-outer _el-inner) (hs-activate! _el-outer) (hs-activate! _el-inner) (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-set-inner-html _el-target "old") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-target) (dom-append (dom-body) _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "target")) "new") )) (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-set-inner-html _el-target "old") (dom-set-attr _el-go "id" "go") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-go "go") (dom-append (dom-body) _el-target) (dom-append (dom-body) _el-go) (dom-dispatch (dom-query-by-id "go") "click" nil) (assert= (dom-text-content (dom-query-by-id "target")) "new") )) (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-set-inner-html _el-target "content") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-target) (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-span (dom-create-element "span")) (_el-target2 (dom-create-element "button")) (_el-span3 (dom-create-element "span")) (_el-span4 (dom-create-element "span"))) (dom-set-attr _el-target "id" "target") (dom-set-inner-html _el-span "first") (dom-set-attr _el-target2 "id" "target") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-span3 "first") (dom-set-inner-html _el-span4 "second") (dom-append (dom-body) _el-target) (dom-append _el-target _el-span) (dom-append (dom-body) _el-target2) (dom-append _el-target2 _el-span3) (dom-append _el-target2 _el-span4) (dom-dispatch (dom-query-by-id "go") "click" nil) )) (deftest "morph removes old children" (hs-cleanup!) (let ((_el-target (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-span2 (dom-create-element "span")) (_el-target3 (dom-create-element "button")) (_el-span4 (dom-create-element "span"))) (dom-set-attr _el-target "id" "target") (dom-set-inner-html _el-span "first") (dom-set-inner-html _el-span2 "second") (dom-set-attr _el-target3 "id" "target") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-span4 "first") (dom-append (dom-body) _el-target) (dom-append _el-target _el-span) (dom-append _el-target _el-span2) (dom-append (dom-body) _el-target3) (dom-append _el-target3 _el-span4) (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-p (dom-create-element "p")) (_el-target2 (dom-create-element "button")) (_el-inner (dom-create-element "p"))) (dom-set-attr _el-target "id" "target") (dom-set-inner-html _el-p "old") (dom-set-attr _el-target2 "id" "target") ;; HS source has bare quotes or embedded HTML (dom-set-attr _el-inner "id" "inner") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-inner "new") (dom-append (dom-body) _el-target) (dom-append _el-target _el-p) (dom-append (dom-body) _el-target2) (dom-append _el-target2 _el-inner) (dom-dispatch (dom-query-by-id "go") "click" nil) (assert= (dom-text-content (dom-query-by-id "inner")) "new") (dom-dispatch (dom-query-by-id "inner") "click" nil) (assert= (dom-text-content (dom-query-by-id "inner")) "clicked") )) (deftest "morph cleans up removed hyperscript elements" (hs-cleanup!) (let ((_el-target (dom-create-element "div")) (_el-child (dom-create-element "div")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-target "id" "target") (dom-set-attr _el-child "id" "child") (dom-set-attr _el-child "_" "on click put \"alive\" into me") (dom-set-inner-html _el-child "child") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-target) (dom-append _el-target _el-child) (dom-append (dom-body) _el-button) (hs-activate! _el-child) (dom-dispatch _el-button "click" nil) )) (deftest "morph reorders children by id" (hs-cleanup!) (let ((_el-target (dom-create-element "div")) (_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-target "id" "target") (dom-set-attr _el-a "id" "a") (dom-set-inner-html _el-a "A") (dom-set-attr _el-b "id" "b") (dom-set-inner-html _el-b "B") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-target) (dom-append _el-target _el-a) (dom-append _el-target _el-b) (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-child (dom-create-element "div")) (_el-go (dom-create-element "button"))) (dom-set-attr _el-target "id" "target") (dom-set-attr _el-child "id" "child") (dom-set-inner-html _el-child "old") (dom-set-attr _el-go "id" "go") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-go "go") (dom-append (dom-body) _el-target) (dom-append _el-target _el-child) (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-set-inner-html _el-target "original") (dom-set-attr _el-go "id" "go") (dom-set-attr _el-go "_" "on click set content to \"

morphed
\" then morph #target to content") (dom-set-inner-html _el-go "go") (dom-append (dom-body) _el-target) (dom-append (dom-body) _el-go) (hs-activate! _el-go) (dom-dispatch (dom-query-by-id "go") "click" nil) (assert= (dom-text-content (dom-query-by-id "target")) "morphed") )) ) ;; ── reset (8 tests) ── (defsuite "hs-upstream-reset" (deftest "can reset a form" (hs-cleanup!) (let ((_el-f1 (dom-create-element "form")) (_el-t1 (dom-create-element "input")) (_el-button (dom-create-element "button")) (_el-rst (dom-create-element "button"))) (dom-set-attr _el-f1 "id" "f1") (dom-set-attr _el-t1 "id" "t1") (dom-set-attr _el-t1 "type" "text") (dom-set-attr _el-t1 "value" "original") (dom-set-attr _el-button "_" "on click set #t1's value to 'changed'") (dom-set-attr _el-button "type" "button") (dom-set-inner-html _el-button "Change") (dom-set-attr _el-rst "id" "rst") (dom-set-attr _el-rst "_" "on click reset #f1") (dom-set-attr _el-rst "type" "button") (dom-set-inner-html _el-rst "Reset") (dom-append (dom-body) _el-f1) (dom-append _el-f1 _el-t1) (dom-append _el-f1 _el-button) (dom-append _el-f1 _el-rst) (hs-activate! _el-button) (hs-activate! _el-rst) (dom-dispatch (dom-query-by-id "rst") "click" nil) (assert= (dom-get-prop (dom-query-by-id "t1") "value") "original") )) (deftest "reset with no target resets me (form)" (hs-cleanup!) (let ((_el-form (dom-create-element "form")) (_el-t2 (dom-create-element "input"))) (dom-set-attr _el-form "_" "on custom reset") (dom-set-attr _el-t2 "id" "t2") (dom-set-attr _el-t2 "type" "text") (dom-set-attr _el-t2 "value" "default") (dom-append (dom-body) _el-form) (dom-append _el-form _el-t2) (hs-activate! _el-form) (dom-dispatch _el-form "custom" nil) (assert= (dom-get-prop (dom-query-by-id "t2") "value") "default") )) (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-set-attr _el-button "_" "on click reset #t3") (dom-set-inner-html _el-button "Reset") (dom-append (dom-body) _el-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") "hello") )) (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-set-attr _el-button "_" "on click reset #cb1") (dom-set-inner-html _el-button "Reset") (dom-append (dom-body) _el-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-set-attr _el-button "_" "on click reset #cb2") (dom-set-inner-html _el-button "Reset") (dom-append (dom-body) _el-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-set-inner-html _el-ta1 "original text") (dom-set-attr _el-button "_" "on click reset #ta1") (dom-set-inner-html _el-button "Reset") (dom-append (dom-body) _el-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") "original text") )) (deftest "can reset a select" (hs-cleanup!) (let ((_el-sel1 (dom-create-element "select")) (_el-option (dom-create-element "option")) (_el-option2 (dom-create-element "option")) (_el-option3 (dom-create-element "option")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-sel1 "id" "sel1") (dom-set-attr _el-option "value" "a") (dom-set-inner-html _el-option "A") (dom-set-attr _el-option2 "value" "b") (dom-set-inner-html _el-option2 "B") (dom-set-attr _el-option3 "value" "c") (dom-set-inner-html _el-option3 "C") (dom-set-attr _el-button "_" "on click reset #sel1") (dom-set-inner-html _el-button "Reset") (dom-append (dom-body) _el-sel1) (dom-append _el-sel1 _el-option) (dom-append _el-sel1 _el-option2) (dom-append _el-sel1 _el-option3) (dom-append (dom-body) _el-button) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-get-prop (dom-query-by-id "sel1") "value") "b") )) (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-add-class _el-input1 "resettable") (dom-set-attr _el-input1 "type" "text") (dom-set-attr _el-input1 "value" "two") (dom-set-attr _el-button "_" "on click reset .resettable") (dom-set-inner-html _el-button "Reset") (dom-append (dom-body) _el-input) (dom-append (dom-body) _el-input1) (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-set-attr _el-target "id" "target") (dom-set-inner-html _el-target "Target") (dom-set-attr _el-div2 "_" "on click scroll to #target") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-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-set-attr _el-target "id" "target") (dom-set-attr _el-target "style" "height: 200px") (dom-set-inner-html _el-target "Target") (dom-set-attr _el-div2 "_" "on click scroll to the top of #target") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-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-set-attr _el-div1 "_" "on click scroll down by 300px") (dom-append (dom-body) _el-div) (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-set-attr _el-div1 "_" "on click scroll up by 100px") (dom-append (dom-body) _el-div) (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-set-attr _el-div1 "_" "on click scroll by 200px") (dom-append (dom-body) _el-div) (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-div (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-set-attr _el-div "style" "height: 1000px") (dom-set-inner-html _el-div "tall") (dom-set-attr _el-go "id" "go") (dom-set-attr _el-go "_" "on click scroll #box down by 200px") (dom-set-inner-html _el-go "go") (dom-append (dom-body) _el-box) (dom-append _el-box _el-div) (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-div (dom-create-element "div")) (_el-item (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-set-attr _el-div "style" "height: 500px") (dom-set-inner-html _el-div "spacer") (dom-set-attr _el-item "id" "item") (dom-set-inner-html _el-item "target") (dom-set-attr _el-go "id" "go") (dom-set-attr _el-go "_" "on click scroll to #item in #box") (dom-set-inner-html _el-go "go") (dom-append (dom-body) _el-box) (dom-append _el-box _el-div) (dom-append _el-box _el-item) (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-div (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-set-attr _el-div "style" "width: 5000px; height: 50px") (dom-set-inner-html _el-div "wide") (dom-set-attr _el-go "id" "go") (dom-set-attr _el-go "_" "on click scroll #box right by 300px") (dom-set-inner-html _el-go "go") (dom-append (dom-body) _el-box) (dom-append _el-box _el-div) (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-set-attr _el-button "_" "on click select #inp") (dom-set-inner-html _el-button "Select") (dom-append (dom-body) _el-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-set-inner-html _el-ta "some text") (dom-set-attr _el-button "_" "on click select #ta") (dom-set-inner-html _el-button "Select") (dom-append (dom-body) _el-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-set-inner-html _el-text "Hello World") (dom-set-attr _el-button "_" "on click put the selection into #out") (dom-set-inner-html _el-button "Get") (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-text) (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-out) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "Hello") )) ) ;; ── 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= (dom-text-content (dom-query-by-id "d1")) "ba") )) (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-set-attr _el-a "id" "a") (dom-set-inner-html _el-a "x") (dom-set-attr _el-b "id" "b") (dom-set-inner-html _el-b "y") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-a) (dom-append (dom-body) _el-b) (hs-activate! _el-d1) (dom-dispatch (dom-query-by-id "d1") "click" nil) (assert= (dom-text-content (dom-query-by-id "a")) "world") (assert= (dom-text-content (dom-query-by-id "b")) "hello") )) (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= (dom-text-content (dom-query-by-id "d1")) "3,2,1") )) (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-set-attr _el-target "id" "target") (dom-set-attr _el-target "data-val" "x") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-target) (hs-activate! _el-d1) (dom-dispatch (dom-query-by-id "d1") "click" nil) (assert= (dom-text-content (dom-query-by-id "d1")) "new") (assert= (dom-get-attr (dom-query-by-id "target") "data-val") "old") )) ) ;; ── 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-set-attr _el-span "_" "bind $name and #name-input.value end then when $name changes put it into me") (dom-append (dom-body) _el-name-input) (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-set-attr _el-span "_" "bind $city to #city-input.value end then when $city changes put it into me") (dom-append (dom-body) _el-city-input) (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 then when $greeting changes put it into next ") (dom-set-attr _el-input "type" "text") (dom-set-attr _el-input "value" "hello") (dom-append (dom-body) _el-input) (dom-append (dom-body) _el-span) (hs-activate! _el-input) )) (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-set-attr _el-span "_" "when $isDarkMode changes put it into me") (dom-append (dom-body) _el-input) (dom-append (dom-body) _el-span) (hs-activate! _el-input) (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-set-inner-html _el-textarea "Hello world") (dom-set-attr _el-span "_" "when $bio changes put it into me") (dom-append (dom-body) _el-textarea) (dom-append (dom-body) _el-span) (hs-activate! _el-textarea) (hs-activate! _el-span) )) (deftest "shorthand on select binds to value" (hs-cleanup!) (let ((_el-select (dom-create-element "select")) (_el-option (dom-create-element "option")) (_el-option2 (dom-create-element "option")) (_el-option3 (dom-create-element "option")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-select "_" "bind $country to me") (dom-set-attr _el-option "value" "us") (dom-set-inner-html _el-option "United States") (dom-set-attr _el-option2 "value" "uk") (dom-set-inner-html _el-option2 "United Kingdom") (dom-set-attr _el-option3 "value" "fr") (dom-set-inner-html _el-option3 "France") (dom-set-attr _el-span "_" "when $country changes put it into me") (dom-append (dom-body) _el-select) (dom-append _el-select _el-option) (dom-append _el-select _el-option2) (dom-append _el-select _el-option3) (dom-append (dom-body) _el-span) (hs-activate! _el-select) (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-set-attr _el-span "_" "when $price changes put it into me") (dom-append (dom-body) _el-input) (dom-append (dom-body) _el-span) (hs-activate! _el-input) (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-set-inner-html _el-div "visible") (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-set-attr _el-span "_" "when $searchTerm changes put it into me") (dom-append (dom-body) _el-input) (dom-append (dom-body) _el-span) (hs-activate! _el-input) (hs-activate! _el-span) )) (deftest "form.reset() syncs variable back to default value" (hs-cleanup!) (let ((_el-test-form (dom-create-element "form")) (_el-input (dom-create-element "input")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-test-form "id" "test-form") (dom-set-attr _el-input "_" "bind $formField to me") (dom-set-attr _el-input "type" "text") (dom-set-attr _el-input "value" "default") (dom-set-attr _el-span "_" "when $formField changes put it into me") (dom-append (dom-body) _el-test-form) (dom-append _el-test-form _el-input) (dom-append (dom-body) _el-span) (hs-activate! _el-input) (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-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-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-set-attr _el-span "_" "when $color changes put it into me") (dom-append (dom-body) _el-input) (dom-append (dom-body) _el-input1) (dom-append (dom-body) _el-input2) (dom-append (dom-body) _el-span) (hs-activate! _el-input) (hs-activate! _el-input1) (hs-activate! _el-input2) (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-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-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-input) (dom-append (dom-body) _el-input1) (dom-append (dom-body) _el-input2) (hs-activate! _el-input) (hs-activate! _el-input1) (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-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-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-input) (dom-append (dom-body) _el-input1) (dom-append (dom-body) _el-input2) (hs-activate! _el-input) (hs-activate! _el-input1) (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-set-inner-html _el-div "test") (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-set-inner-html _el-div "test") (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-set-inner-html _el-div "test") (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-set-attr _el-div "_" "bind $search to value of #of-input") (dom-append (dom-body) _el-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-set-attr _el-div "_" "bind .dark and #dark-toggle's checked") (dom-set-inner-html _el-div "test") (dom-append (dom-body) _el-dark-toggle) (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-set-attr _el-h1 "_" "bind @data-title and #title-input's value") (dom-append (dom-body) _el-title-input) (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-set-attr _el-input "_" "bind my value and #slider's value") (dom-set-attr _el-input "type" "number") (dom-append (dom-body) _el-slider) (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-set-attr _el-div "_" "bind $name to #name-field") (dom-append (dom-body) _el-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-set-attr _el-div "_" "bind $agreed to #agree-cb") (dom-append (dom-body) _el-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-set-attr _el-div "_" "bind $qty to #qty-input") (dom-append (dom-body) _el-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-set-attr _el-input "_" "bind me to #range-slider") (dom-set-attr _el-input "type" "number") (dom-append (dom-body) _el-range-slider) (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-set-inner-html _el-div "initial") (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-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-input) (dom-append (dom-body) _el-input1) (hs-activate! _el-input) (hs-activate! _el-input1) )) (deftest "form reset listener is removed on cleanup" (hs-cleanup!) (let ((_el-form (dom-create-element "form")) (_el-binput (dom-create-element "input")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-binput "id" "binput") (dom-set-attr _el-binput "_" "bind $val to me") (dom-set-attr _el-binput "type" "text") (dom-set-attr _el-binput "value" "initial") (dom-set-attr _el-button "type" "reset") (dom-set-inner-html _el-button "Reset") (dom-append (dom-body) _el-form) (dom-append _el-form _el-binput) (dom-append _el-form _el-button) (hs-activate! _el-binput) )) ) ;; ── 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 then 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-set-inner-html _el-div "visible") (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-set-attr _el-h "id" "h") (dom-set-attr _el-h "_" "when $doubleHeight changes put it into me") (dom-set-attr _el-div "_" "live then set $doubleWidth to ($width * 2) then set $doubleHeight to ($height * 2) then end") (dom-append (dom-body) _el-w) (dom-append (dom-body) _el-h) (dom-append (dom-body) _el-div) (hs-activate! _el-w) (hs-activate! _el-h) (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-set-attr _el-h "id" "h") (dom-set-attr _el-h "_" "when $doubleHeight changes put it into me") (dom-set-attr _el-div "_" "live set $doubleWidth to ($width * 2) end then live set $doubleHeight to ($height * 2)") (dom-append (dom-body) _el-w) (dom-append (dom-body) _el-h) (dom-append (dom-body) _el-div) (hs-activate! _el-w) (hs-activate! _el-h) (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 then set $subtotal to ($price * $qty) then set $total to ($subtotal + $tax) then end then 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 then if $isActive add .active to me else remove .active from me end then end") (dom-set-inner-html _el-div "test") (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 then if $isVisible set *display to 'block' else set *display to 'none' end then end") (dom-set-inner-html _el-div "content") (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 then if $showFirst put $firstName into me else put $lastName into me end then 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 then 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 then 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 then live set my @data-mirror to $username") (dom-set-attr _el-input "type" "text") (dom-set-attr _el-input "value" "alice") (dom-set-attr _el-span "_" "when $username changes put it into me") (dom-append (dom-body) _el-input) (dom-append (dom-body) _el-span) (hs-activate! _el-input) (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-span (dom-create-element "span")) (_el-div (dom-create-element "div"))) (dom-set-attr _el-people-tmpl "id" "people-tmpl") (dom-set-inner-html _el-people-tmpl "#for p in people\\n") (dom-set-inner-html _el-span "\\${p.name}") (dom-set-attr _el-div "_" "live render #people-tmpl with people: $people then put it into my.innerHTML end") (dom-append (dom-body) _el-people-tmpl) (dom-append _el-people-tmpl _el-span) (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-span (dom-create-element "span")) (_el-div (dom-create-element "div"))) (dom-set-attr _el-items-tmpl "id" "items-tmpl") (dom-set-inner-html _el-items-tmpl "#for item in items\\n") (dom-set-inner-html _el-span "\\${item.label}") (dom-set-attr _el-div "_" "live render #items-tmpl with items: $items then put it into my.innerHTML end") (dom-append (dom-body) _el-items-tmpl) (dom-append _el-items-tmpl _el-span) (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-set-attr _el-output "_" "when #prop-input's value changes put it into me") (dom-append (dom-body) _el-prop-input) (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-set-attr _el-out "id" "out") (dom-append (dom-body) _el-box) (dom-append (dom-body) _el-out) (hs-activate! _el-box) )) (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-set-attr _el-out "id" "out") (dom-append (dom-body) _el-box) (dom-append (dom-body) _el-out) (hs-activate! _el-box) )) (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-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-box) (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 then when :count changes put it into me end then on click increment :count") (dom-set-inner-html _el-div "0") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "1") (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "2") )) (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-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "_" "when $shared changes put 'second' into me") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-d1) (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-set-inner-html _el-div "original") (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-set-attr _el-span "_" "when #reactive-input.value changes put it into me") (dom-append (dom-body) _el-reactive-input) (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-set-attr _el-span "_" "when #prog-input.value changes put it into me") (dom-append (dom-body) _el-prog-input) (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-set-attr _el-output "id" "output") (dom-set-attr _el-output "_" "when $derived changes put it into me") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-output) (hs-activate! _el-div) (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 then 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 then when :label changes put it into me end then on click set :label to 'clicked'") (dom-set-inner-html _el-div "initial") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content _el-div) "clicked") )) (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 then increment :count then put :count into me then 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 then when :value changes put it into me end then on click set :value to 'A-clicked'") (dom-set-inner-html _el-d1 "A") (dom-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "_" "init set :value to 'B' end then when :value changes put it into me end then on click set :value to 'B-clicked'") (dom-set-inner-html _el-d2 "B") (dom-append (dom-body) _el-d1) (dom-append (dom-body) _el-d2) (hs-activate! _el-d1) (hs-activate! _el-d2) (dom-dispatch (dom-query-by-id "d1") "click" nil) (assert= (dom-text-content (dom-query-by-id "d1")) "A-clicked") (assert= (dom-text-content (dom-query-by-id "d2")) "B") (dom-dispatch (dom-query-by-id "d2") "click" nil) (assert= (dom-text-content (dom-query-by-id "d2")) "B-clicked") (assert= (dom-text-content (dom-query-by-id "d1")) "A-clicked") )) (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-set-attr _el-span "_" "when (#nan-input.value * 1) changes put it into me") (dom-append (dom-body) _el-nan-input) (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-set-attr _el-span "_" "when #cb-input.checked changes put it into me") (dom-append (dom-body) _el-cb-input) (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-set-attr _el-span "_" "when (value of #of-input) changes put it into me") (dom-append (dom-body) _el-of-input) (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-set-inner-html _el-style-target "not fired") (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-set-attr _el-d-c "id" "d-c") (dom-set-attr _el-d-c "_" "when $a changes set $c to (it * 3)") (dom-set-attr _el-div "_" "live increment :runs then put ($ (runs:)' into me") (dom-append (dom-body) _el-d-b) (dom-append (dom-body) _el-d-c) (dom-append (dom-body) _el-div) (hs-activate! _el-d-b) (hs-activate! _el-d-c) (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
") (dom-set-inner-html _el-button "go") (dom-set-inner-html _el-span "empty") (dom-append (dom-body) _el-div) (dom-append _el-div _el-button) (dom-append _el-div _el-span) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content _el-span) "created") )) (deftest "child write updates the ancestor, not a local copy" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-button (dom-create-element "button")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-div "_" "init set ^shared to 0") (dom-set-attr _el-button "_" "on click set ^shared to 10") (dom-set-inner-html _el-button "set") (dom-set-attr _el-span "_" "on click put ^shared into me") (dom-set-inner-html _el-span "0") (dom-append (dom-body) _el-div) (dom-append _el-div _el-button) (dom-append _el-div _el-span) (hs-activate! _el-div) (hs-activate! _el-button) (hs-activate! _el-span) (dom-dispatch _el-button "click" nil) (dom-dispatch _el-span "click" nil) (assert= (dom-text-content _el-span) "10") )) (deftest "increment works on inherited var" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-div "_" "init set ^count to 0") (dom-set-attr _el-button "_" "on click put ^count into me") (dom-set-inner-html _el-button "0") (dom-append (dom-body) _el-div) (dom-append _el-div _el-button) (hs-activate! _el-div) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (dom-dispatch _el-button "click" nil) (dom-dispatch _el-button "click" nil) (dom-dispatch (dom-query "span") "click" nil) (assert= (dom-text-content (dom-query "span")) "3") )) (deftest "dom keyword works as scope modifier" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-div "_" "init set dom count to 42") (dom-set-attr _el-span "_" "on click put dom count into me") (dom-set-inner-html _el-span "0") (dom-append (dom-body) _el-div) (dom-append _el-div _el-span) (hs-activate! _el-div) (hs-activate! _el-span) (dom-dispatch _el-span "click" nil) (assert= (dom-text-content _el-span) "42") )) (deftest "set ^var on explicit element" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-button (dom-create-element "button")) (_el-span (dom-create-element "span"))) (dom-add-class _el-div "store") (dom-set-attr _el-button "_" "on click set ^data on closest .store to 'hello'") (dom-set-inner-html _el-button "set") (dom-set-attr _el-span "_" "on click put ^data on closest .store into me") (dom-set-inner-html _el-span "read") (dom-append (dom-body) _el-div) (dom-append _el-div _el-button) (dom-append _el-div _el-span) (hs-activate! _el-button) (hs-activate! _el-span) (dom-dispatch _el-button "click" nil) (dom-dispatch _el-span "click" nil) (assert= (dom-text-content _el-span) "hello") )) (deftest "on clause targets a specific ancestor" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-span (dom-create-element "span"))) (dom-add-class _el-div "outer") (dom-set-attr _el-div "_" "init set ^outerVal to 'outer'") (dom-add-class _el-div1 "inner") (dom-set-attr _el-div1 "_" "init set ^innerVal to 'inner'") (dom-set-attr _el-span "_" "on click put ^outerVal on closest .outer into me") (dom-set-inner-html _el-span "read") (dom-append (dom-body) _el-div) (dom-append _el-div _el-div1) (dom-append _el-div1 _el-span) (hs-activate! _el-div) (hs-activate! _el-div1) (hs-activate! _el-span) (dom-dispatch _el-span "click" nil) (assert= (dom-text-content _el-span) "outer") )) (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-set-attr _el-button "_" "on click set ^count on #state-holder to 99") (dom-set-inner-html _el-button "set") (dom-set-attr _el-span "_" "on click put ^count on #state-holder into me") (dom-set-inner-html _el-span "read") (dom-append (dom-body) _el-state-holder) (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-span) (hs-activate! _el-button) (hs-activate! _el-span) (dom-dispatch _el-button "click" nil) (dom-dispatch _el-span "click" nil) (assert= (dom-text-content _el-span) "99") )) (deftest "when reacts to ^var changes" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-div "_" "init set ^count to 0") (dom-set-attr _el-button "_" "when ^count changes put it into me") (dom-set-inner-html _el-button "0") (dom-append (dom-body) _el-div) (dom-append _el-div _el-button) (hs-activate! _el-div) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query "output")) "1") (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query "output")) "2") )) (deftest "always reacts to ^var changes" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-div "_" "init set ^name to 'alice'") (dom-set-attr _el-button "_" "on click set ^name to 'bob'") (dom-set-inner-html _el-button "rename") (dom-append (dom-body) _el-div) (dom-append _el-div _el-button) (hs-activate! _el-div) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) )) (deftest "multiple children react to same ^var" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-button (dom-create-element "button")) (_el-a (dom-create-element "span")) (_el-b (dom-create-element "span"))) (dom-set-attr _el-div "_" "init set ^color to 'red'") (dom-set-attr _el-button "_" "on click set ^color to 'blue'") (dom-set-inner-html _el-button "change") (dom-set-attr _el-a "id" "a") (dom-set-attr _el-a "_" "when ^color changes put it into me") (dom-set-attr _el-b "id" "b") (dom-set-attr _el-b "_" "when ^color changes put it into me") (dom-append (dom-body) _el-div) (dom-append _el-div _el-button) (dom-append _el-div _el-a) (dom-append _el-div _el-b) (hs-activate! _el-div) (hs-activate! _el-button) (hs-activate! _el-a) (hs-activate! _el-b) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "a")) "blue") (assert= (dom-text-content (dom-query-by-id "b")) "blue") )) (deftest "sibling subtrees react independently with ^var" (hs-cleanup!) (let ((_el-a (dom-create-element "div")) (_el-button (dom-create-element "button")) (_el-b (dom-create-element "div")) (_el-button3 (dom-create-element "button"))) (dom-set-attr _el-a "id" "a") (dom-set-attr _el-a "_" "init set ^val to 0") (dom-set-attr _el-button "_" "when ^val changes put it into me") (dom-set-inner-html _el-button "0") (dom-set-attr _el-b "id" "b") (dom-set-attr _el-b "_" "init set ^val to 0") (dom-set-attr _el-button3 "_" "when ^val changes put it into me") (dom-set-inner-html _el-button3 "0") (dom-append (dom-body) _el-a) (dom-append _el-a _el-button) (dom-append _el-button _el-b) (dom-append _el-b _el-button3) (hs-activate! _el-a) (hs-activate! _el-button) (hs-activate! _el-b) (hs-activate! _el-button3) (dom-dispatch (dom-query "#a button") "click" nil) (dom-dispatch (dom-query "#a button") "click" nil) (assert= (dom-text-content (dom-query "#a output")) "2") (assert= (dom-text-content (dom-query "#b output")) "0") (dom-dispatch (dom-query "#b button") "click" nil) (assert= (dom-text-content (dom-query "#b output")) "1") (assert= (dom-text-content (dom-query "#a output")) "2") )) (deftest "bind works with ^var" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-input (dom-create-element "input")) (_el-output (dom-create-element "output"))) (dom-set-attr _el-div "_" "init set ^search to ''") (dom-set-attr _el-input "_" "bind ^search and my value") (dom-set-attr _el-input "type" "text") (dom-set-attr _el-output "_" "when ^search changes put it into me") (dom-append (dom-body) _el-div) (dom-append _el-div _el-input) (dom-append _el-div _el-output) (hs-activate! _el-div) (hs-activate! _el-input) (hs-activate! _el-output) )) (deftest "derived ^var chains reactively" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-span2 (dom-create-element "span")) (_el-output (dom-create-element "output")) (_el-price-btn (dom-create-element "button")) (_el-qty-btn (dom-create-element "button"))) (dom-set-attr _el-div "_" "init set ^price to 10 then set ^qty to 2 then set ^total to 20") (dom-set-attr _el-span "_" "when ^price changes set ^total to (^price * ^qty)") (dom-set-attr _el-span2 "_" "when ^qty changes set ^total to (^price * ^qty)") (dom-set-attr _el-output "_" "when ^total changes put it into me") (dom-set-attr _el-price-btn "id" "price-btn") (dom-set-attr _el-price-btn "_" "on click set ^price to 25") (dom-set-inner-html _el-price-btn "set price") (dom-set-attr _el-qty-btn "id" "qty-btn") (dom-set-attr _el-qty-btn "_" "on click set ^qty to 5") (dom-set-inner-html _el-qty-btn "set qty") (dom-append (dom-body) _el-div) (dom-append _el-div _el-span) (dom-append _el-div _el-span2) (dom-append _el-div _el-output) (dom-append _el-div _el-price-btn) (dom-append _el-div _el-qty-btn) (hs-activate! _el-div) (hs-activate! _el-span) (hs-activate! _el-span2) (hs-activate! _el-output) (hs-activate! _el-price-btn) (hs-activate! _el-qty-btn) (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")) (_el-output (dom-create-element "output")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-div "_" "init set ^msg to 'hello'") (dom-set-attr _el-output "_" "when ^msg changes put it into me") (dom-set-attr _el-button "_" "on click set ^msg to 'updated'") (dom-set-inner-html _el-button "update") (dom-append (dom-body) _el-div) (dom-append _el-div _el-output) (dom-append _el-div _el-button) (hs-activate! _el-div) (hs-activate! _el-output) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) )) (deftest "dedup prevents re-fire on same ^var value" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-output (dom-create-element "output")) (_el-button (dom-create-element "button")) (_el-diff (dom-create-element "button"))) (dom-set-attr _el-div "_" "init set ^val to 'same'") (dom-set-attr _el-output "_" "when ^val changes increment :runs then put :runs into me") (dom-set-attr _el-button "_" "on click set ^val to 'same'") (dom-set-inner-html _el-button "same") (dom-set-attr _el-diff "id" "diff") (dom-set-attr _el-diff "_" "on click set ^val to 'different'") (dom-set-inner-html _el-diff "diff") (dom-append (dom-body) _el-div) (dom-append _el-div _el-output) (dom-append _el-div _el-button) (dom-append _el-div _el-diff) (hs-activate! _el-div) (hs-activate! _el-output) (hs-activate! _el-button) (hs-activate! _el-diff) (dom-dispatch (dom-query "button:text("same")") "click" nil) (assert= (dom-text-content _el-output) "1") (dom-dispatch (dom-query-by-id "diff") "click" nil) (assert= (dom-text-content _el-output) "2") )) ) ;; ── 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")) (_el-span (dom-create-element "span"))) (dom-set-inner-html _el-span "Hello World") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) )) (deftest "renders template expressions" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span"))) (dom-set-inner-html _el-span "Hello ${\"\\x24\"}{$ltName}!") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) )) (deftest "applies init script from _ attribute" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-template "_" "init set ^msg to 'initialized'") (dom-set-inner-html _el-span "${\"\\x24\"}{^msg}") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (hs-activate! _el-template) )) (deftest "reactively updates when dependencies change" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-button (dom-create-element "button")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-template "_" "init set ^count to 0") (dom-set-attr _el-button "_" "on click increment ^count") (dom-set-inner-html _el-button "+") (dom-set-inner-html _el-span "Count: ${\"\\x24\"}{^count}") (dom-append (dom-body) _el-template) (dom-append _el-template _el-button) (dom-append _el-template _el-span) (hs-activate! _el-template) (hs-activate! _el-button) (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")) (_el-button (dom-create-element "button")) (_el-output (dom-create-element "output"))) (dom-set-attr _el-template "_" "init set ^val to 0") (dom-set-attr _el-button "_" "on click increment ^val then put ^val into the next ") (dom-set-inner-html _el-button "+") (dom-set-inner-html _el-output "0") (dom-append (dom-body) _el-template) (dom-append _el-template _el-button) (dom-append _el-template _el-output) (hs-activate! _el-template) (hs-activate! _el-button) (dom-dispatch (dom-query "[data-live-template] button") "click" nil) )) (deftest "supports #for loops" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-ul (dom-create-element "ul")) (_el-li (dom-create-element "li"))) (dom-set-attr _el-template "_" "init set ^items to ['a', 'b', 'c']") (dom-set-inner-html _el-ul "#for item in ^items") (dom-set-inner-html _el-li "${\"\\x24\"}{item}") (dom-append (dom-body) _el-template) (dom-append _el-template _el-ul) (dom-append _el-ul _el-li) (hs-activate! _el-template) )) (deftest "supports #if conditionals" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-template "_" "init set ^show to true") (dom-set-inner-html _el-template "#if ^show") (dom-set-inner-html _el-span "visible") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (hs-activate! _el-template) )) (deftest "reacts to global state without init script" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-p (dom-create-element "p"))) (dom-set-inner-html _el-p "Hello, ${\"\\x24\"}{$ltGlobal}!") (dom-append (dom-body) _el-template) (dom-append _el-template _el-p) )) (deftest "wrapper has display:contents" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span"))) (dom-set-inner-html _el-span "test") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) )) (deftest "multiple live templates are independent" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_el-template2 (dom-create-element "template")) (_el-span3 (dom-create-element "span"))) (dom-set-attr _el-template "_" "init set ^x to 'first'") (dom-add-class _el-span "a") (dom-set-inner-html _el-span "${\"\\x24\"}{^x}") (dom-set-attr _el-template2 "_" "init set ^x to 'second'") (dom-add-class _el-span3 "b") (dom-set-inner-html _el-span3 "${\"\\x24\"}{^x}") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-template2) (dom-append _el-template2 _el-span3) (hs-activate! _el-template) (hs-activate! _el-template2) )) ) ;; ── 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-set-inner-html _el-target "old") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-target) (dom-append (dom-body) _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "target")) "new") )) (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-set-inner-html _el-target "old") (dom-set-attr _el-button "_" "on click make a then put \"moved\" into it then set #target to it") (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-target) (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-li (dom-create-element "li")) (_el-li2 (dom-create-element "li")) (_el-li3 (dom-create-element "li")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-list "id" "list") (dom-add-class _el-li "item") (dom-set-inner-html _el-li "a") (dom-add-class _el-li2 "item") (dom-set-inner-html _el-li2 "b") (dom-add-class _el-li3 "item") (dom-set-inner-html _el-li3 "c") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-list) (dom-append _el-list _el-li) (dom-append _el-list _el-li2) (dom-append _el-list _el-li3) (dom-append (dom-body) _el-button) (dom-dispatch _el-button "click" nil) )) (deftest "set replaces all matching elements" (hs-cleanup!) (let ((_el-box (dom-create-element "div")) (_el-p (dom-create-element "p")) (_el-p2 (dom-create-element "p")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-box "id" "box") (dom-set-inner-html _el-p "one") (dom-set-inner-html _el-p2 "two") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-box) (dom-append _el-box _el-p) (dom-append _el-box _el-p2) (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")) (_el-button (dom-create-element "button"))) (dom-add-class _el-div "wrapper") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-div) (dom-append _el-div _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query ".wrapper")) "replaced") )) (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-set-inner-html _el-target "old") (dom-set-attr _el-target1 "id" "target") ;; HS source has bare quotes or embedded HTML (dom-set-inner-html _el-target1 "new'\\\">go") (dom-append (dom-body) _el-target) (dom-append (dom-body) _el-target1) (dom-dispatch (dom-query-by-id "go") "click" nil) (assert= (dom-text-content (dom-query-by-id "target")) "new") (dom-dispatch (dom-query-by-id "target") "click" nil) (assert= (dom-text-content (dom-query-by-id "target")) "clicked") )) (deftest "swap #a with #b swaps DOM positions" (hs-cleanup!) (let ((_el-container (dom-create-element "div")) (_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-container "id" "container") (dom-set-attr _el-a "id" "a") (dom-set-inner-html _el-a "A") (dom-set-attr _el-b "id" "b") (dom-set-inner-html _el-b "B") (dom-set-attr _el-button "_" "on click swap #a with #b") (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-container) (dom-append _el-container _el-a) (dom-append _el-container _el-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-set-inner-html _el-target "old") (dom-set-attr _el-button "_" "on click put \"new\" into #target") (dom-set-inner-html _el-button "go") (dom-append (dom-body) _el-target) (dom-append (dom-body) _el-button) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "target")) "new") )) ) ;; ── collectionExpressions (22 tests) ── (defsuite "hs-upstream-collectionExpressions" (deftest "filters an array by condition" (assert= (eval-hs "set arr to [{name: \"a\", active: true}, {name: \"b\", active: false}, {name: \"c\", active: true}] then return arr where its active") (list "a" "c")) ) (deftest "filters with comparison" (assert= (eval-hs "set arr to [1, 2, 3, 4, 5] then return arr where it > 3") (list 4 5)) ) (deftest "works with DOM elements" (hs-cleanup!) (let ((_el-list (dom-create-element "ul")) (_el-li (dom-create-element "li")) (_el-li2 (dom-create-element "li")) (_el-li3 (dom-create-element "li")) (_el-button (dom-create-element "button")) (_el-out (dom-create-element "div"))) (dom-set-attr _el-list "id" "list") (dom-add-class _el-li "yes") (dom-set-inner-html _el-li "A") (dom-set-inner-html _el-li2 "B") (dom-add-class _el-li3 "yes") (dom-set-inner-html _el-li3 "C") (dom-set-attr _el-button "_" "on click set items to
  • in #list then set matches to items where it matches .yes then put matches mapped to its textContent into #out") (dom-set-inner-html _el-button "Go") (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-list) (dom-append _el-list _el-li) (dom-append _el-list _el-li2) (dom-append _el-list _el-li3) (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-out) (hs-activate! _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "AC") )) (deftest "sorts by a property" (assert= (eval-hs "set arr to [{name: \"Charlie\"}, {name: \"Alice\"}, {name: \"Bob\"}] then return arr sorted by its name") (list "Alice" "Bob" "Charlie")) ) (deftest "sorts descending" (assert= (eval-hs "set arr to [3, 1, 2] then return arr sorted by it descending") (list 3 2 1)) ) (deftest "sorts numbers by a computed key" (assert= (eval-hs "set arr to [{name: \"b\", age: 30}, {name: \"a\", age: 20}, {name: \"c\", age: 25}] then return arr sorted by its age") (list "a" "c" "b")) ) (deftest "maps to a property" (assert= (eval-hs "set arr to [{name: \"Alice\"}, {name: \"Bob\"}] then return arr mapped to its name") (list "Alice" "Bob")) ) (deftest "maps with an expression" (assert= (eval-hs "set arr to [1, 2, 3] then return arr mapped to (it * 2)") (list 2 4 6)) ) (deftest "where then mapped to" (assert= (eval-hs "set arr to [{name: \"Alice\", active: true}, {name: \"Bob\", active: false}, {name: \"Charlie\", active: true}] then return arr where its active mapped to its name") (list "Alice" "Charlie")) ) (deftest "sorted by then mapped to" (assert= (eval-hs "set arr to [{name: \"Charlie\", age: 30}, {name: \"Alice\", age: 20}] then return arr sorted by its age mapped to its name") (list "Alice" "Charlie")) ) (deftest "where then sorted by then mapped to" (assert= (eval-hs "set arr to [{name: \"Charlie\", active: true, age: 30}, {name: \"Alice\", active: false, age: 20}, {name: \"Bob\", active: true, age: 25}] then return arr where its active sorted by its age mapped to its name") (list "Bob" "Charlie")) ) (deftest "the result inside where refers to previous command result, not current element" (assert= (eval-hs "get 3 then set arr to [1, 2, 3, 4, 5] then return arr where it > the result") (list 4 5)) ) (deftest "where binds after in without parens" (hs-cleanup!) (let ((_el-container (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-span2 (dom-create-element "span")) (_el-span3 (dom-create-element "span"))) (dom-set-attr _el-container "id" "container") (dom-add-class _el-span "a") (dom-set-inner-html _el-span "A") (dom-add-class _el-span2 "b") (dom-set-inner-html _el-span2 "B") (dom-add-class _el-span3 "a") (dom-set-inner-html _el-span3 "C") (dom-append (dom-body) _el-container) (dom-append _el-container _el-span) (dom-append _el-container _el-span2) (dom-append _el-container _el-span3) )) (deftest "sorted by binds after in without parens" (hs-cleanup!) (let ((_el-list (dom-create-element "ul")) (_el-li (dom-create-element "li")) (_el-li2 (dom-create-element "li")) (_el-li3 (dom-create-element "li"))) (dom-set-attr _el-list "id" "list") (dom-set-inner-html _el-li "C") (dom-set-inner-html _el-li2 "A") (dom-set-inner-html _el-li3 "B") (dom-append (dom-body) _el-list) (dom-append _el-list _el-li) (dom-append _el-list _el-li2) (dom-append _el-list _el-li3) )) (deftest "where binds after property access" (assert= (eval-hs "obj.items where it > 2") (list 3 4)) ) (deftest "where after in with mapped to" (hs-cleanup!) (let ((_el-items (dom-create-element "ul")) (_el-li (dom-create-element "li")) (_el-li2 (dom-create-element "li")) (_el-li3 (dom-create-element "li"))) (dom-set-attr _el-items "id" "items") (dom-add-class _el-li "yes") (dom-set-inner-html _el-li "A") (dom-set-inner-html _el-li2 "B") (dom-add-class _el-li3 "yes") (dom-set-inner-html _el-li3 "C") (dom-append (dom-body) _el-items) (dom-append _el-items _el-li) (dom-append _el-items _el-li2) (dom-append _el-items _el-li3) )) (deftest "where binds after in on closest" (hs-cleanup!) (let ((_el-box (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-span2 (dom-create-element "span")) (_el-span3 (dom-create-element "span")) (_el-button (dom-create-element "button")) (_el-b2 (dom-create-element "button"))) (dom-set-attr _el-box "id" "box") (dom-add-class _el-span "a") (dom-set-inner-html _el-span "A") (dom-add-class _el-span2 "b") (dom-set-inner-html _el-span2 "B") (dom-add-class _el-span3 "a") (dom-set-inner-html _el-span3 "C") ;; HS source has bare quotes or embedded HTML (dom-set-attr _el-b2 "id" "b2") ;; HS source has bare quotes or embedded HTML (dom-append (dom-body) _el-box) (dom-append _el-box _el-span) (dom-append _el-box _el-span2) (dom-append _el-box _el-span3) (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-b2) (dom-dispatch (dom-query-by-id "b2") "click" nil) (assert= (dom-text-content (dom-query-by-id "b2")) "2") )) (deftest "where in init followed by on feature" (hs-cleanup!) (let ((_el-box (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-span2 (dom-create-element "span")) (_el-button (dom-create-element "button"))) (dom-set-attr _el-box "id" "box") (dom-add-class _el-span "a") (dom-set-inner-html _el-span "A") (dom-add-class _el-span2 "b") (dom-set-inner-html _el-span2 "B") ;; HS source has bare quotes or embedded HTML (dom-append (dom-body) _el-box) (dom-append _el-box _el-span) (dom-append _el-box _el-span2) (dom-append (dom-body) _el-button) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content _el-button) "1") )) (deftest "where in component init followed by on feature" (hs-cleanup!) (let ((_el-box (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-span2 (dom-create-element "span")) (_el-template (dom-create-element "template")) (_el-slot (dom-create-element "slot")) (_el-test-where-comp (dom-create-element "test-where-comp"))) (dom-set-attr _el-box "id" "box") (dom-add-class _el-span "a") (dom-set-inner-html _el-span "A") (dom-add-class _el-span2 "b") (dom-set-inner-html _el-span2 "B") (dom-set-attr _el-template "_" "set :items to in #box where it matches .a then on click put :items.length into me") (dom-set-attr _el-template "component" "test-where-comp") (dom-set-inner-html _el-test-where-comp "go") (dom-append (dom-body) _el-box) (dom-append _el-box _el-span) (dom-append _el-box _el-span2) (dom-append (dom-body) _el-template) (dom-append _el-template _el-slot) (dom-append (dom-body) _el-test-where-comp) (hs-activate! _el-template) (dom-dispatch _el-test-where-comp "click" nil) (assert= (dom-text-content _el-test-where-comp) "1") )) (deftest "where with is not me in component template" (hs-cleanup!) (let ((_el-box (dom-create-element "div")) (_el-input (dom-create-element "input")) (_el-input2 (dom-create-element "input")) (_el-template (dom-create-element "template")) (_el-input4 (dom-create-element "input")) (_el-test-where-me (dom-create-element "test-where-me"))) (dom-set-attr _el-box "id" "box") (dom-add-class _el-input "cb") (dom-set-attr _el-input "type" "checkbox") (dom-add-class _el-input2 "cb") (dom-set-attr _el-input2 "type" "checkbox") (dom-set-attr _el-template "component" "test-where-me") (dom-set-attr _el-input4 "_" "set :checkboxes to in #box where it is not me on change set checked of the :checkboxes to my checked") (dom-set-attr _el-input4 "type" "checkbox") (dom-append (dom-body) _el-box) (dom-append _el-box _el-input) (dom-append _el-input _el-input2) (dom-append _el-input2 _el-template) (dom-append _el-template _el-input4) (dom-append _el-input4 _el-test-where-me) (hs-activate! _el-input4) (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")) (_el-tr (dom-create-element "tr")) (_el-td (dom-create-element "td")) (_el-input (dom-create-element "input")) (_el-tr4 (dom-create-element "tr")) (_el-td5 (dom-create-element "td")) (_el-input6 (dom-create-element "input")) (_el-tr7 (dom-create-element "tr")) (_el-td8 (dom-create-element "td")) (_el-input9 (dom-create-element "input")) (_el-tr10 (dom-create-element "tr")) (_el-td11 (dom-create-element "td")) (_el-master (dom-create-element "input"))) (dom-add-class _el-input "cb") (dom-set-attr _el-input "type" "checkbox") (dom-add-class _el-input6 "cb") (dom-set-attr _el-input6 "type" "checkbox") (dom-add-class _el-input9 "cb") (dom-set-attr _el-input9 "type" "checkbox") (dom-set-attr _el-master "id" "master") (dom-set-attr _el-master "_" "set :checkboxes to in the closest where it is not me then on change set checked of the :checkboxes to my checked") (dom-set-attr _el-master "type" "checkbox") (dom-append (dom-body) _el-table) (dom-append _el-table _el-tr) (dom-append _el-tr _el-td) (dom-append _el-td _el-input) (dom-append _el-input _el-tr4) (dom-append _el-tr4 _el-td5) (dom-append _el-td5 _el-input6) (dom-append _el-input6 _el-tr7) (dom-append _el-tr7 _el-td8) (dom-append _el-td8 _el-input9) (dom-append _el-input9 _el-tr10) (dom-append _el-tr10 _el-td11) (dom-append _el-td11 _el-master) (hs-activate! _el-master) (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")) (_el-tr (dom-create-element "tr")) (_el-td (dom-create-element "td")) (_el-input (dom-create-element "input")) (_el-tr4 (dom-create-element "tr")) (_el-td5 (dom-create-element "td")) (_el-input6 (dom-create-element "input")) (_el-tr7 (dom-create-element "tr")) (_el-td8 (dom-create-element "td")) (_el-input9 (dom-create-element "input")) (_el-tr10 (dom-create-element "tr")) (_el-td11 (dom-create-element "td")) (_el-master (dom-create-element "input"))) (dom-add-class _el-input "cb") (dom-set-attr _el-input "type" "checkbox") (dom-add-class _el-input6 "cb") (dom-set-attr _el-input6 "type" "checkbox") (dom-add-class _el-input9 "cb") (dom-set-attr _el-input9 "type" "checkbox") (dom-set-attr _el-master "id" "master") (dom-set-attr _el-master "_" "set :checkboxes to in the closest
    where it is not me then on change set checked of the :checkboxes to my checked then on change from the closest
    then if no :checkboxes where it is checked then set my indeterminate to false then set my checked to false then else if no :checkboxes where it is not checked then set my indeterminate to false then set my checked to true then else then set my indeterminate to true then end") (dom-set-attr _el-master "type" "checkbox") (dom-append (dom-body) _el-table) (dom-append _el-table _el-tr) (dom-append _el-tr _el-td) (dom-append _el-td _el-input) (dom-append _el-input _el-tr4) (dom-append _el-tr4 _el-td5) (dom-append _el-td5 _el-input6) (dom-append _el-input6 _el-tr7) (dom-append _el-tr7 _el-td8) (dom-append _el-td8 _el-input9) (dom-append _el-input9 _el-tr10) (dom-append _el-tr10 _el-td11) (dom-append _el-td11 _el-master) (hs-activate! _el-master) (dom-dispatch (dom-query-by-id "master") "click" nil) )) ) ;; ── splitJoin (7 tests) ── (defsuite "hs-upstream-splitJoin" (deftest "splits a string by delimiter" (assert= (eval-hs "return \"a,b,c\" split by \",\"") (list "a" "b" "c")) ) (deftest "splits by whitespace" (assert= (eval-hs "return \"hello world\" split by \" \"") (list "hello" "world")) ) (deftest "joins an array with delimiter" (assert= (eval-hs "return [\"a\", \"b\", \"c\"] joined by \", \"") "a, b, c") ) (deftest "joins with empty string" (assert= (eval-hs "return [\"x\", \"y\", \"z\"] joined by \"\"") "xyz") ) (deftest "split then where then joined" (assert= (eval-hs "return \"a,,b,,c\" split by \",\" where it is not \"\" joined by \"-\"") "a-b-c") ) (deftest "split then sorted then joined" (assert= (eval-hs "return \"banana,apple,cherry\" split by \",\" sorted by it joined by \", \"") "apple, banana, cherry") ) (deftest "split then mapped then joined" (assert= (eval-hs "return \"hello world\" split by \" \" mapped to its length joined by \",\"") "5,5") ) ) ;; ── 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-span (dom-create-element "span")) (_el-test-hello (dom-create-element "test-hello"))) (dom-set-attr _el-template "component" "test-hello") (dom-set-inner-html _el-span "Hello World") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-hello) )) (deftest "renders template expressions" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_el-test-greet (dom-create-element "test-greet"))) (dom-set-attr _el-template "component" "test-greet") (dom-set-inner-html _el-span "Hello ${\"\\x24\"}{$name}!") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-greet) )) (deftest "applies _ hyperscript to component instance" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_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-set-inner-html _el-span "${\"\\x24\"}{^msg}") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-init) (hs-activate! _el-template) )) (deftest "processes _ on inner elements" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-button (dom-create-element "button")) (_el-span (dom-create-element "span")) (_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-set-attr _el-button "_" "on click increment ^count then put ^count into the next ") (dom-set-inner-html _el-button "+") (dom-set-inner-html _el-span "0") (dom-append (dom-body) _el-template) (dom-append _el-template _el-button) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-inner) (hs-activate! _el-template) (hs-activate! _el-button) (dom-dispatch (dom-query "test-inner button") "click" nil) )) (deftest "reactively updates template expressions" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-button (dom-create-element "button")) (_el-span (dom-create-element "span")) (_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-set-attr _el-button "_" "on click increment ^count") (dom-set-inner-html _el-button "+") (dom-set-inner-html _el-span "Count: ${\"\\x24\"}{^count}") (dom-append (dom-body) _el-template) (dom-append _el-template _el-button) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-reactive) (hs-activate! _el-template) (hs-activate! _el-button) (dom-dispatch (dom-query "test-reactive button") "click" nil) )) (deftest "supports multiple independent instances" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-button (dom-create-element "button")) (_el-span (dom-create-element "span")) (_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-set-attr _el-button "_" "on click increment ^count then put ^count into the next ") (dom-set-inner-html _el-button "+") (dom-set-inner-html _el-span "0") (dom-set-attr _el-a "id" "a") (dom-set-attr _el-b "id" "b") (dom-append (dom-body) _el-template) (dom-append _el-template _el-button) (dom-append _el-template _el-span) (dom-append (dom-body) _el-a) (dom-append (dom-body) _el-b) (hs-activate! _el-template) (hs-activate! _el-button) (dom-dispatch (dom-query "#a button") "click" nil) )) (deftest "reads attributes via @" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_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-set-inner-html _el-span "${\"\\x24\"}{^val}") (dom-set-attr _el-test-attrs "data-start" "42") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-attrs) (hs-activate! _el-template) )) (deftest "supports #for loops in template" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-ul (dom-create-element "ul")) (_el-li (dom-create-element "li")) (_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-set-inner-html _el-ul "#for item in ^items") (dom-set-inner-html _el-li "${\"\\x24\"}{item}") (dom-append (dom-body) _el-template) (dom-append _el-template _el-ul) (dom-append _el-ul _el-li) (dom-append (dom-body) _el-test-loop) (hs-activate! _el-template) )) (deftest "supports #if conditionals in template" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_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-set-inner-html _el-template "#if ^show") (dom-set-inner-html _el-span "visible") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-cond) (hs-activate! _el-template) )) (deftest "substitutes slot content into template" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-div (dom-create-element "div")) (_el-slot (dom-create-element "slot")) (_el-test-card (dom-create-element "test-card")) (_el-p (dom-create-element "p"))) (dom-set-attr _el-template "component" "test-card") (dom-add-class _el-div "card") (dom-set-inner-html _el-p "Hello from slot") (dom-append (dom-body) _el-template) (dom-append _el-template _el-div) (dom-append _el-div _el-slot) (dom-append (dom-body) _el-test-card) (dom-append _el-test-card _el-p) )) (deftest "blocks processing of inner hyperscript until render" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_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-set-attr _el-span "_" "on click put ^msg into me") (dom-set-inner-html _el-span "click me") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-block) (hs-activate! _el-template) (hs-activate! _el-span) (dom-dispatch (dom-query "test-block span") "click" nil) )) (deftest "supports named slots" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-header (dom-create-element "header")) (_el-slot (dom-create-element "slot")) (_el-main (dom-create-element "main")) (_el-slot4 (dom-create-element "slot")) (_el-footer (dom-create-element "footer")) (_el-slot6 (dom-create-element "slot")) (_el-test-named-slot (dom-create-element "test-named-slot")) (_el-h1 (dom-create-element "h1")) (_el-p (dom-create-element "p")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-template "component" "test-named-slot") (dom-set-attr _el-slot "name" "title") (dom-set-attr _el-slot6 "name" "footer") (dom-set-attr _el-h1 "slot" "title") (dom-set-inner-html _el-h1 "My Title") (dom-set-inner-html _el-p "Default content") (dom-set-attr _el-span "slot" "footer") (dom-set-inner-html _el-span "Footer text") (dom-append (dom-body) _el-template) (dom-append _el-template _el-header) (dom-append _el-header _el-slot) (dom-append _el-template _el-main) (dom-append _el-main _el-slot4) (dom-append _el-template _el-footer) (dom-append _el-footer _el-slot6) (dom-append (dom-body) _el-test-named-slot) (dom-append _el-test-named-slot _el-h1) (dom-append _el-test-named-slot _el-p) (dom-append _el-test-named-slot _el-span) )) (deftest "does not process slotted _ attributes prematurely" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-template (dom-create-element "template")) (_el-div2 (dom-create-element "div")) (_el-slot (dom-create-element "slot")) (_el-test-slot-hs (dom-create-element "test-slot-hs")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-div "_" "init set ^x to 42") (dom-set-attr _el-template "component" "test-slot-hs") (dom-add-class _el-div2 "wrap") (dom-set-attr _el-span "_" "on click put ^x into me") (dom-set-inner-html _el-span "before") (dom-append (dom-body) _el-div) (dom-append _el-div _el-template) (dom-append _el-template _el-div2) (dom-append _el-div2 _el-slot) (dom-append _el-div _el-test-slot-hs) (dom-append _el-test-slot-hs _el-span) (hs-activate! _el-div) (hs-activate! _el-span) (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")) (_el-template (dom-create-element "template")) (_el-div2 (dom-create-element "div")) (_el-slot (dom-create-element "slot")) (_el-test-scope-slot (dom-create-element "test-scope-slot")) (_el-span (dom-create-element "span"))) (dom-set-attr _el-div "_" "init set ^outer to 'from-outside'") (dom-set-attr _el-template "_" "init set ^outer to 'from-component'") (dom-set-attr _el-template "component" "test-scope-slot") (dom-add-class _el-div2 "inner") (dom-set-attr _el-span "_" "init put ^outer into me") (dom-set-inner-html _el-span "waiting") (dom-append (dom-body) _el-div) (dom-append _el-div _el-template) (dom-append _el-template _el-div2) (dom-append _el-div2 _el-slot) (dom-append _el-div _el-test-scope-slot) (dom-append _el-test-scope-slot _el-span) (hs-activate! _el-div) (hs-activate! _el-template) (hs-activate! _el-span) )) (deftest "component isolation prevents ^var leaking inward" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_el-test-isolated (dom-create-element "test-isolated"))) (dom-set-attr _el-div "_" "init set ^leaked to 'should-not-see'") (dom-set-attr _el-template "_" "init set ^internal to 'component-only'") (dom-set-attr _el-template "component" "test-isolated") (dom-set-attr _el-span "_" "init if ^leaked is not undefined put 'leaked!' into me else put ^internal into me") (dom-set-inner-html _el-span "waiting") (dom-append (dom-body) _el-div) (dom-append _el-div _el-template) (dom-append _el-template _el-span) (dom-append _el-div _el-test-isolated) (hs-activate! _el-div) (hs-activate! _el-template) (hs-activate! _el-span) )) (deftest "bind keeps ^var in sync with attribute changes" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_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-set-inner-html _el-span "${\"\\x24\"}{^count}") (dom-set-attr _el-test-bind-attr "data-count" "5") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-bind-attr) (hs-activate! _el-template) )) (deftest "attrs evaluates attribute as hyperscript in parent scope" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-ul (dom-create-element "ul")) (_el-li (dom-create-element "li")) (_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-set-inner-html _el-ul "#for item in ^list") (dom-set-inner-html _el-li "${\"\\x24\"}{item}") (dom-set-attr _el-test-args "items" "$stuff") (dom-append (dom-body) _el-template) (dom-append _el-template _el-ul) (dom-append _el-ul _el-li) (dom-append (dom-body) _el-test-args) (hs-activate! _el-template) )) (deftest "attrs works with bind for reactive pass-through" (hs-cleanup!) (let ((_el-template (dom-create-element "template")) (_el-span (dom-create-element "span")) (_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-set-inner-html _el-span "${\"\\x24\"}{^val}") (dom-set-attr _el-test-args-bind "count" "$count") (dom-set-attr _el-button "_" "on click increment $count") (dom-set-inner-html _el-button "+") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append (dom-body) _el-test-args-bind) (dom-append (dom-body) _el-button) (hs-activate! _el-template) (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-span (dom-create-element "span")) (_el-button (dom-create-element "button")) (_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-set-inner-html _el-span "${\"\\x24\"}{^count}") (dom-set-attr _el-button "_" "on click increment ^count") (dom-set-inner-html _el-button "+") (dom-set-attr _el-test-args-bidir "count" "$count") (dom-set-attr _el-p "_" "live put $count into me") (dom-append (dom-body) _el-template) (dom-append _el-template _el-span) (dom-append _el-template _el-button) (dom-append (dom-body) _el-test-args-bidir) (dom-append (dom-body) _el-p) (hs-activate! _el-template) (hs-activate! _el-button) (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 or embedded HTML (dom-append (dom-body) _el-d1) (dom-dispatch (dom-query-by-id "d1") "click" nil) (assert= (dom-text-content (dom-query-by-id "d1")) "bar") )) (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 or embedded HTML (dom-append (dom-body) _el-d1) (dom-dispatch (dom-query-by-id "d1") "click" nil) (assert= (dom-text-content (dom-query-by-id "d1")) "bar") )) (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= (dom-text-content _el-div) "yes") )) (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= (dom-text-content _el-div) "existing") )) (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= (dom-text-content _el-div) "0") )) (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= (dom-text-content _el-div) "fallback") )) (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= (dom-text-content _el-div) "false") )) (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= (dom-text-content _el-div) "boom") )) ) ;; ── 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-set-attr _el-div "_" "on click measure #other's top then set window.measurement to {top: top}") (dom-append (dom-body) _el-other) (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-set-attr _el-div "_" "on click measure top of #other then set window.measurement to {top: top}") (dom-append (dom-body) _el-other) (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-add-class _el-div1 "item") (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-div) (dom-append (dom-body) _el-div1) (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 or embedded HTML (dom-set-attr _el-s1 "id" "s1") (dom-set-attr _el-s1 "style" "display:none") (dom-set-inner-html _el-s1 "A") (dom-set-attr _el-s2 "id" "s2") (dom-set-attr _el-s2 "style" "display:none") (dom-set-inner-html _el-s2 "B") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-s1) (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 or embedded HTML (dom-set-attr _el-p "style" "display:none") (dom-set-inner-html _el-p "yes") (dom-set-attr _el-p2 "style" "display:none") (dom-set-inner-html _el-p2 "no") (dom-set-attr _el-out "id" "out") (dom-set-inner-html _el-out "--") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-p) (dom-append (dom-body) _el-p2) (dom-append (dom-body) _el-out) (dom-dispatch _el-div "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "some") )) ) ;; ── 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-set-attr _el-div "_" "on click add .foo to #bar then add .blah") (dom-append (dom-body) _el-bar) (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-set-attr _el-target "id" "target") (dom-set-attr _el-target "_" "on click from #source add .foo") (dom-append (dom-body) _el-source) (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= (dom-text-content _el-div) "clicked") )) (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")) (_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 blargh end on mouseenter also_bad") (dom-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "_" "on click put \"clicked\" into my.innerHTML") (dom-append (dom-body) _el-div) (dom-append _el-div _el-d1) (dom-append _el-div _el-d2) (hs-activate! _el-d1) (hs-activate! _el-d2) (dom-dispatch (dom-query-by-id "d2") "click" nil) (assert= (dom-text-content (dom-query-by-id "d2")) "clicked") )) (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= (dom-get-attr (dom-query-by-id "d1") "out") "10") )) ) ;; ── asExpression (17 tests) ── (defsuite "hs-upstream-asExpression" (deftest "converts value as Boolean" (assert= (eval-hs "1 as Boolean") true) (assert= (eval-hs "0 as Boolean") false) (assert= (eval-hs "'' as Boolean") false) (assert= (eval-hs "'hello' as Boolean") true) ) (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" (assert= (eval-hs "'{\"foo\":\"bar\"}' as JSON") "bar") ) (deftest "converts value as JSONString" (assert= (eval-hs "{foo:'bar'} as JSONString") "{"foo":"bar"}") ) (deftest "pipe operator chains conversions" (assert= (eval-hs "{foo:'bar'} as JSONString | JSON") "bar") ) (deftest "can use the an modifier if you'd like" (assert= (eval-hs "'{\"foo\":\"bar\"}' as an Object") "bar") ) (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" (assert= (eval-hs "{a:1, b:2} as Keys") (list "a" "b")) ) (deftest "converts object as Entries" (assert= (eval-hs "{a:1} as Entries") (list (list "a" 1))) ) (deftest "converts array as Reversed" (assert= (eval-hs "[1,2,3] as Reversed") (list 3 2 1)) ) (deftest "converts array as Unique" (assert= (eval-hs "[1,2,2,3,3] as Unique") (list 1 2 3)) ) (deftest "converts nested array as Flat" (assert= (eval-hs "[[1,2],[3,4]] as Flat") (list 1 2 3 4)) ) ) ;; ── 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") (dom-set-attr _el-arDiv "_" "on click set my @data-foo to \"blue\"") (dom-set-attr _el-arDiv "data-foo" "red") (dom-append (dom-body) _el-arDiv) (hs-activate! _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")) (_el-d1b (dom-create-element "div"))) (dom-set-attr _el-outerDiv2 "id" "outerDiv2") (dom-set-attr _el-outerDiv2 "foo" "bar") (dom-set-attr _el-d1b "id" "d1b") (dom-set-attr _el-d1b "_" "on click set closest @foo to \"doh\"") (dom-append (dom-body) _el-outerDiv2) (dom-append _el-outerDiv2 _el-d1b) (hs-activate! _el-d1b) (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")) (_el-tr (dom-create-element "tr")) (_el-td (dom-create-element "td")) (_el-input (dom-create-element "input")) (_el-input4 (dom-create-element "input")) (_el-master (dom-create-element "input")) (_el-table6 (dom-create-element "table")) (_el-out (dom-create-element "div"))) (dom-add-class _el-input "cb") (dom-set-attr _el-input "type" "checkbox") (dom-add-class _el-input4 "cb") (dom-set-attr _el-input4 "type" "checkbox") (dom-set-attr _el-master "id" "master") ;; HS source has bare quotes or embedded HTML (dom-set-attr _el-master "type" "checkbox") (dom-set-attr _el-master " 5") true) ) (deftest "no with where returns false when matches exist" (assert= (eval-hs "no [1, 2, 3] where it > 1") false) ) (deftest "no with where and is not" (assert= (eval-hs "no [1, 2, 3] where it is not 2") false) ) (deftest "no with where on DOM elements" (hs-cleanup!) (let ((_el-box (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-span2 (dom-create-element "span")) (_el-button (dom-create-element "button")) (_el-out (dom-create-element "div"))) (dom-set-attr _el-box "id" "box") (dom-add-class _el-span "a") (dom-set-inner-html _el-span "A") (dom-add-class _el-span2 "b") (dom-set-inner-html _el-span2 "B") ;; HS source has bare quotes or embedded HTML (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-box) (dom-append _el-box _el-span) (dom-append _el-box _el-span2) (dom-append (dom-body) _el-button) (dom-append (dom-body) _el-out) (dom-dispatch _el-button "click" nil) (assert= (dom-text-content (dom-query-by-id "out")) "none") )) ) ;; ── objectLiteral (1 tests) ── (defsuite "hs-upstream-objectLiteral" (deftest "allows trailing commas" ;; TODO: assert= (eval-hs "{foo:true, bar-baz:false,}") against { "foo": true, "bar-baz": false } ) ) ;; ── 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-add-class _el-div1 "c2") (dom-set-attr _el-div1 "foo" "bar") (dom-add-class _el-div2 "c3") (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-div1) (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-set-attr _el-d2 "id" "d2") (dom-set-inner-html _el-d2 "hello") (dom-append (dom-body) _el-d1) (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-set-inner-html _el-d1 "world") (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d1) (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-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "style" "color: red") (dom-append (dom-body) _el-d1) (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")) )