Parser: - Relax (number? v) to v in parse-one-transition so (expr)unit works - Add (match-kw "then") before parse-cmd-list in parse-for-cmd - Handle "indexed by" syntax alongside "index" in for loops - Add "indexed" to hs-keywords to prevent unit-suffix consumption Compiler: - Use map-indexed instead of for-each for indexed for-loops Test generator: - Preserve \" escapes in process_hs_val via placeholder/restore Mock DOM: - Coerce insertAdjacentHTML values via dom_stringify (match browser) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8816 lines
380 KiB
Plaintext
8816 lines
380 KiB
Plaintext
;; Hyperscript behavioral tests — auto-generated from upstream _hyperscript test suite
|
|
;; Source: spec/tests/hyperscript-upstream-tests.json (831 tests, v0.9.14 + dev)
|
|
;; DO NOT EDIT — regenerate with: python3 tests/playwright/generate-sx-tests.py
|
|
|
|
;; ── Test helpers ──────────────────────────────────────────────────
|
|
|
|
(define hs-test-el
|
|
(fn (tag hs-src)
|
|
(let ((el (dom-create-element tag)))
|
|
(dom-set-attr el "_" hs-src)
|
|
(dom-append (dom-body) el)
|
|
(hs-activate! el)
|
|
el)))
|
|
|
|
(define hs-cleanup!
|
|
(fn ()
|
|
(dom-set-inner-html (dom-body) "")))
|
|
|
|
;; Evaluate a hyperscript expression and return its result.
|
|
;; Compiles the expression, wraps in a thunk, evaluates, returns result.
|
|
(define eval-hs
|
|
(fn (src)
|
|
(let ((sx (hs-to-sx (hs-compile src))))
|
|
(let ((handler (eval-expr-cek
|
|
(list (quote fn) (list (quote me)) (list (quote let) (list (list (quote it) nil) (list (quote event) nil)) sx)))))
|
|
(handler nil)))))
|
|
|
|
;; Evaluate with a specific me value (for "I am between" etc.)
|
|
(define eval-hs-with-me
|
|
(fn (src me-val)
|
|
(let ((sx (hs-to-sx (hs-compile src))))
|
|
(let ((handler (eval-expr-cek
|
|
(list (quote fn) (list (quote me)) (list (quote let) (list (list (quote it) nil) (list (quote event) nil)) sx)))))
|
|
(handler me-val)))))
|
|
|
|
;; ── 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 <p/> 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 <p/> 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")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(dom-set-attr _el-div "data-state" "active")
|
|
;; SKIP attr [@data-state (contains special chars)
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _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")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(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)
|
|
(hs-activate! _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)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-get-style (dom-query-by-id "d2") "opacity") "0")
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-get-style (dom-query-by-id "d2") "opacity") "1")
|
|
))
|
|
(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)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-get-style (dom-query-by-id "d2") "visibility") "hidden")
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-get-style (dom-query-by-id "d2") "visibility") "visible")
|
|
))
|
|
(deftest "can toggle *display between two values"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(dom-set-attr _el-div "style" "display:none")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _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")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(dom-set-attr _el-div "style" "opacity:0")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _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")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(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)
|
|
))
|
|
(deftest "can toggle a global variable between three values"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(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)
|
|
))
|
|
)
|
|
|
|
;; ── 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 \"<button id=\\\"b1\\\" _=\\\"on click put 42 into me\\\">40</button>\" into me")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (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 \"<button id=\\\"b1\\\" _=\\\"on click put 42 into me\\\">40</button>\" into <div#d1/>")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (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 \"<button id=\\\"b1\\\" _=\\\"on click put 42 into me\\\">40</button>\" before me")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (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 \"<button id=\\\"b1\\\" _=\\\"on click put 42 into me\\\">40</button>\" at the start of me")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (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 \"<button id=\\\"b1\\\" _=\\\"on click put 42 into me\\\">40</button>\" at the end of me")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (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 \"<button id=\\\"b1\\\" _=\\\"on click put 42 into me\\\">40</button>\" after me")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (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 <div/> 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 if window.tmp then put \"foo\" into me then else if not window.tmp then // do nothing then end catch e then // just here for the parsing... then")
|
|
(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 if window.tmp then else then if window.tmp then end put \"foo\" into me then end")
|
|
(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 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] log me then put x at end of me then wait 1ms then 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 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] put x at end of me then wait 1ms then 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!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def repeatForeverWithReturn() set retVal to 0 repeat forever set retVal to retVal + 1 if retVal == 5 then return retVal end end end")))
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click put repeatForeverWithReturn() into my.innerHTML")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (dom-inner-html _el-d1) "5")
|
|
))
|
|
(deftest "repeat forever works w/o keyword"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def repeatForeverWithReturn() set retVal to 0 repeat set retVal to retVal + 1 if retVal == 5 then return retVal end end end")))
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click put repeatForeverWithReturn() into my.innerHTML")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (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!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def repeatWhileTest() set retVal to 0 repeat while retVal < 5 set retVal to retVal + 1 end return retVal end")))
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click put repeatWhileTest() into my.innerHTML")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (dom-inner-html _el-d1) "5")
|
|
))
|
|
(deftest "until keyword works"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def repeatUntilTest() set retVal to 0 repeat until retVal == 5 set retVal to retVal + 1 end return retVal end")))
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click put repeatUntilTest() into my.innerHTML")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (dom-inner-html _el-d1) "5")
|
|
))
|
|
(deftest "until event keyword works"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def repeatUntilTest() repeat until event click from #untilTest wait 2ms end return 42 end")))
|
|
(let ((_el-untilTest (dom-create-element "div")))
|
|
(dom-set-attr _el-untilTest "id" "untilTest")
|
|
(dom-append (dom-body) _el-untilTest)
|
|
(dom-dispatch _el-untilTest "click" nil)
|
|
;; SKIP check: skip value.should.equal(42)
|
|
))
|
|
(deftest "only executes the init expression once"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def getArray() set window.called to (window.called or 0) + 1 return [1, 2, 3] end")))
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click for x in getArray() put x into my.innerHTML end")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (dom-inner-html _el-d1) "3")
|
|
;; SKIP check: skip window.called.should.equal(1)
|
|
))
|
|
(deftest "can nest loops"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "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")))
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click call sprayInto(me)")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
(assert= (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 put 'expected D. ' at end of me then end end")
|
|
(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 put x at end of me then end end")
|
|
(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 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 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 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 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 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 end 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 put x at end of me then end")
|
|
(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 put x at end of me then 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 "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 end 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 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)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-get-style (dom-query-by-id "foo") "width") "100px")
|
|
))
|
|
(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)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-get-style (dom-query-by-id "foo") "width") "100px")
|
|
))
|
|
(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)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-get-style (dom-query-by-id "foo") "width") "100px")
|
|
))
|
|
(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)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-get-style (dom-query-by-id "foo") "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)
|
|
))
|
|
(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")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(dom-append (dom-body) _el-div)
|
|
(dom-append (dom-body) _el-span)
|
|
(hs-activate! _el-div)
|
|
(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")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _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 '<span>This is my inner HTML</span>' to me then append '<b>With Tags</b>' to me")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-inner-html _el-div) "<span>This is my inner HTML</span><b>With Tags</b>")
|
|
))
|
|
(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 '<a>New Content</a>' 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 `<button id='b1' _='on click increment window.temp'>Test</button>` to me")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(dom-dispatch _el-div "click" nil)
|
|
;; SKIP check: skip window.temp.should.equal(1)
|
|
))
|
|
(deftest "new DOM content added by append will be live"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "on click make a <span.topping/> then append it to me")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert (dom-has-class? _el-div "topping"))
|
|
))
|
|
(deftest "can append a value to a set"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "on click set :s to [1,2] as Set 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 <p/> in me 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 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 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!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "on load put \"Loaded\" into #loadedDemo.innerHTML")))
|
|
(let ((_el-loadedDemo (dom-create-element "div")))
|
|
(dom-set-attr _el-loadedDemo "id" "loadedDemo")
|
|
(dom-append (dom-body) _el-loadedDemo)
|
|
;; SKIP check: skip byId("loadedDemo").innerText.should.equal("Loaded")
|
|
))
|
|
(deftest "can have a simple event filter"
|
|
(hs-cleanup!)
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click[false] log event then put \"Clicked\" into my.innerHTML")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch _el-d1 "click" nil)
|
|
;; SKIP check: skip byId("d1").innerText.should.equal("")
|
|
))
|
|
(deftest "can refer to event properties directly in filter"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "on click[buttons==0] log event then put \"Clicked\" into my.innerHTML")
|
|
(dom-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!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def throwBar() throw 'bar' end")))
|
|
(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 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"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can initialize immediately"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
)
|
|
|
|
;; ── def (27 tests) ──
|
|
(defsuite "hs-upstream-def"
|
|
(deftest "can define a basic no arg function"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def foo() add .called to #d1 end")))
|
|
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "on click call foo()")
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-append (dom-body) _el-div)
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert (dom-has-class? _el-div "called"))
|
|
))
|
|
(deftest "can define a basic one arg function"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def foo(str) put str into #d1.innerHTML end")))
|
|
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "on click call foo(\"called\")")
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-append (dom-body) _el-div)
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert= (dom-inner-html _el-div) "called")
|
|
))
|
|
(deftest "functions can be namespaced"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def utils.foo() add .called to #d1 end")))
|
|
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "on click call utils.foo()")
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-append (dom-body) _el-div)
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert (dom-has-class? _el-div "called"))
|
|
))
|
|
(deftest "is called synchronously"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def foo() log meend")))
|
|
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
|
(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-div)
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert (dom-has-class? _el-div "called"))
|
|
))
|
|
(deftest "can call asynchronously"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def foo() wait 1ms log meend")))
|
|
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
|
(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-div)
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
(assert (dom-has-class? _el-div "called"))
|
|
))
|
|
(deftest "can return a value synchronously"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def foo() return \"foo\"end")))
|
|
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
|
(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-div)
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
;; SKIP check: skip div.innerText.should.equal("")
|
|
;; SKIP check: skip div.innerText.should.equal("foo")
|
|
))
|
|
(deftest "can exit"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can return a value asynchronously"
|
|
(hs-cleanup!)
|
|
(eval-expr-cek (hs-to-sx (hs-compile "def foo() wait 1ms return \"foo\"end")))
|
|
(let ((_el-div (dom-create-element "div")) (_el-d1 (dom-create-element "div")))
|
|
(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-div)
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-div)
|
|
(dom-dispatch _el-div "click" nil)
|
|
;; SKIP check: skip div.innerText.should.equal("")
|
|
;; SKIP check: skip div.innerText.should.equal("foo")
|
|
))
|
|
(deftest "can interop with javascript"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can interop with javascript asynchronously"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can catch exceptions"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can rethrow in catch blocks"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can return in catch blocks"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can catch async exceptions"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can catch nested async exceptions"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can rethrow in async catch blocks"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can return in async catch blocks"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(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"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "finally blocks run when an exception occurs"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "finally blocks run when an exception expr occurs"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "async finally blocks run normally"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "async finally blocks run when an exception occurs"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "exit stops execution mid-function"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "can return without a value"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
)
|
|
|
|
;; ── 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)
|
|
(assert= (dom-text-content (dom-query ".clearme")) "")
|
|
(assert= (dom-text-content (dom-query ".clearme")) "")
|
|
))
|
|
(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)
|
|
(dom-focus (dom-query-by-id "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")
|
|
(dom-set-attr _el-inner "_" "\\\"on")
|
|
(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 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")
|
|
(dom-set-attr _el-target2 "_" "\\\"on")
|
|
(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)
|
|
(hs-activate! _el-target2)
|
|
(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")
|
|
(dom-set-attr _el-target3 "_" "\\\"on")
|
|
(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)
|
|
(hs-activate! _el-target3)
|
|
(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")
|
|
(dom-set-attr _el-target2 "_" "\\\"on")
|
|
(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)
|
|
(hs-activate! _el-target2)
|
|
(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 \\\"<div id=target>morphed</div>\\\" 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-set-prop (dom-query-by-id "t1") "value" "changed")
|
|
(dom-dispatch (dom-query-by-id "t1") "input" nil)
|
|
(assert= (dom-get-prop (dom-query-by-id "t1") "value") "changed")
|
|
(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-set-prop (dom-query-by-id "t2") "value" "modified")
|
|
(dom-dispatch (dom-query-by-id "t2") "input" nil)
|
|
(assert= (dom-get-prop (dom-query-by-id "t2") "value") "modified")
|
|
(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-set-prop (dom-query-by-id "t3") "value" "goodbye")
|
|
(dom-dispatch (dom-query-by-id "t3") "input" nil)
|
|
(assert= (dom-get-prop (dom-query-by-id "t3") "value") "goodbye")
|
|
(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-set-prop (dom-query-by-id "cb1") "checked" false)
|
|
(dom-dispatch (dom-query-by-id "cb1") "change" nil)
|
|
(assert (not (dom-get-prop (dom-query-by-id "cb1") "checked")))
|
|
(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-set-prop (dom-query-by-id "cb2") "checked" true)
|
|
(dom-dispatch (dom-query-by-id "cb2") "change" nil)
|
|
(assert (dom-get-prop (dom-query-by-id "cb2") "checked"))
|
|
(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-set-prop (dom-query-by-id "ta1") "value" "new text")
|
|
(dom-dispatch (dom-query-by-id "ta1") "input" nil)
|
|
(assert= (dom-get-prop (dom-query-by-id "ta1") "value") "new text")
|
|
(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-set-prop (dom-query-by-id "sel1") "value" "c")
|
|
(dom-dispatch (dom-query-by-id "sel1") "change" nil)
|
|
(assert= (dom-get-prop (dom-query-by-id "sel1") "value") "c")
|
|
(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-set-prop (dom-query ".resettable") "value" "changed1")
|
|
(dom-dispatch (dom-query ".resettable") "input" nil)
|
|
(dom-set-prop (dom-query ".resettable") "value" "changed2")
|
|
(dom-dispatch (dom-query ".resettable") "input" nil)
|
|
(dom-dispatch _el-button "click" nil)
|
|
(assert= (dom-get-prop (dom-query ".resettable") "value") "one")
|
|
(assert= (dom-get-prop (dom-query ".resettable") "value") "two")
|
|
))
|
|
)
|
|
|
|
;; ── 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 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 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 when $greeting changes put it into next <span/>")
|
|
(dom-set-attr _el-input "type" "text")
|
|
(dom-set-attr _el-input "value" "hello")
|
|
(dom-append (dom-body) _el-input)
|
|
(dom-append (dom-body) _el-span)
|
|
(hs-activate! _el-input)
|
|
(dom-set-prop _el-input "value" "goodbye")
|
|
(dom-dispatch _el-input "input" nil)
|
|
))
|
|
(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)
|
|
(dom-set-prop _el-input "checked" true)
|
|
(dom-dispatch _el-input "change" nil)
|
|
))
|
|
(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)
|
|
(dom-set-prop _el-textarea "value" "New bio")
|
|
(dom-dispatch _el-textarea "input" nil)
|
|
))
|
|
(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)
|
|
(dom-set-prop _el-select "value" "uk")
|
|
(dom-dispatch _el-select "change" nil)
|
|
))
|
|
(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)
|
|
(dom-set-prop _el-input "value" "user typed this")
|
|
(dom-dispatch _el-input "input" nil)
|
|
))
|
|
(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)
|
|
(dom-set-prop _el-input "value" "world")
|
|
(dom-dispatch _el-input "input" nil)
|
|
))
|
|
(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)
|
|
(dom-set-prop (dom-query-by-id "dark-toggle") "checked" true)
|
|
(dom-dispatch (dom-query-by-id "dark-toggle") "change" nil)
|
|
(dom-set-prop (dom-query-by-id "dark-toggle") "checked" false)
|
|
(dom-dispatch (dom-query-by-id "dark-toggle") "change" nil)
|
|
))
|
|
(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)
|
|
(dom-set-prop (dom-query-by-id "title-input") "value" "World")
|
|
(dom-dispatch (dom-query-by-id "title-input") "input" nil)
|
|
))
|
|
(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 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 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 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 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 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 end")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _el-div)
|
|
))
|
|
(deftest "multiple live on same element work independently"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "live set my @data-name to $firstName end live set my @data-age to $age")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _el-div)
|
|
))
|
|
(deftest "live and when on same element do not interfere"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "live set my @data-status to $status end when $status changes put 'Status: ' + it into me")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _el-div)
|
|
))
|
|
(deftest "bind and live on same element do not interfere"
|
|
(hs-cleanup!)
|
|
(let ((_el-input (dom-create-element "input")) (_el-span (dom-create-element "span")))
|
|
(dom-set-attr _el-input "_" "bind $username to me end live set my @data-mirror to $username")
|
|
(dom-set-attr _el-input "type" "text")
|
|
(dom-set-attr _el-input "value" "alice")
|
|
(dom-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)
|
|
(dom-set-prop _el-input "value" "bob")
|
|
(dom-dispatch _el-input "input" nil)
|
|
))
|
|
(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 when :count changes put it into me end 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 when $right changes put it into my @data-right")
|
|
(dom-append (dom-body) _el-div)
|
|
(hs-activate! _el-div)
|
|
))
|
|
(deftest "works with on handlers that modify the watched variable"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")))
|
|
(dom-set-attr _el-div "_" "init set :label to 'initial' end when :label changes put it into me end on click set :label to 'clicked'")
|
|
(dom-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 when :value changes put it into me end 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 when :value changes put it into me end 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)
|
|
(dom-set-prop (dom-query-by-id "cb-input") "checked" true)
|
|
(dom-dispatch (dom-query-by-id "cb-input") "change" nil)
|
|
))
|
|
(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)
|
|
(dom-set-prop (dom-query-by-id "of-input") "value" "changed")
|
|
(dom-dispatch (dom-query-by-id "of-input") "input" nil)
|
|
))
|
|
(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<div _=")
|
|
(dom-append (dom-body) _el-span)
|
|
(hs-activate! _el-span)
|
|
))
|
|
(deftest "cross-microtask ping-pong is caught by circular guard"
|
|
(hs-cleanup!)
|
|
(let ((_el-span (dom-create-element "span")))
|
|
(dom-set-attr _el-span "_" "when $ping changes put it into me")
|
|
(dom-append (dom-body) _el-span)
|
|
(hs-activate! _el-span)
|
|
))
|
|
(deftest "element moved in DOM retains reactivity"
|
|
(hs-cleanup!)
|
|
(let ((_el-container-a (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-container-b (dom-create-element "div")))
|
|
(dom-set-attr _el-container-a "id" "container-a")
|
|
(dom-set-attr _el-span "_" "when $movable changes put it into me")
|
|
(dom-set-attr _el-container-b "id" "container-b")
|
|
(dom-append (dom-body) _el-container-a)
|
|
(dom-append _el-container-a _el-span)
|
|
(dom-append (dom-body) _el-container-b)
|
|
(hs-activate! _el-span)
|
|
))
|
|
(deftest "rapid detach/reattach in same sync block does not kill effect"
|
|
(hs-cleanup!)
|
|
(let ((_el-thrash-parent (dom-create-element "div")))
|
|
(dom-set-attr _el-thrash-parent "id" "thrash-parent")
|
|
(dom-append (dom-body) _el-thrash-parent)
|
|
))
|
|
)
|
|
|
|
;; ── asyncError (2 tests) ──
|
|
(defsuite "hs-upstream-asyncError"
|
|
(deftest "rejected promise stops execution"
|
|
(hs-cleanup!)
|
|
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
|
|
(dom-set-attr _el-button "_" "on click call failAsync() then put 'should not reach' into #out then")
|
|
(dom-set-inner-html _el-button "Go")
|
|
(dom-set-attr _el-out "id" "out")
|
|
(dom-set-inner-html _el-out "original")
|
|
(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")) "original")
|
|
))
|
|
(deftest "rejected promise triggers catch block"
|
|
(hs-cleanup!)
|
|
(let ((_el-button (dom-create-element "button")) (_el-out (dom-create-element "div")))
|
|
(dom-set-attr _el-button "_" "on click call failAsync() then put 'unreachable' into #out then catch e then put e.message into #out then")
|
|
(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")) "boom")
|
|
))
|
|
)
|
|
|
|
;; ── dom-scope (25 tests) ──
|
|
(defsuite "hs-upstream-dom-scope"
|
|
(deftest "isolated stops ^var resolution"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-span (dom-create-element "span")))
|
|
(dom-set-attr _el-div "_" "init set ^color to 'red'")
|
|
(dom-set-attr _el-div1 "dom-scope" "isolated")
|
|
(dom-set-attr _el-span "_" "init if ^color is not undefined put 'leaked' into me else put 'blocked' into me")
|
|
(dom-set-inner-html _el-span "waiting")
|
|
(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-span)
|
|
))
|
|
(deftest "closest jumps to matching 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 ^val to 'from-outer'")
|
|
(dom-set-attr _el-div1 "_" "init set ^val to 'from-inner'")
|
|
(dom-set-attr _el-div1 "dom-scope" "isolated")
|
|
(dom-set-attr _el-span "_" "init put ^val into me")
|
|
(dom-set-attr _el-span "dom-scope" "closest .outer")
|
|
(dom-set-inner-html _el-span "none")
|
|
(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)
|
|
))
|
|
(deftest "closest with no match stops resolution"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")) (_el-span (dom-create-element "span")))
|
|
(dom-set-attr _el-div "_" "init set ^val to 'found'")
|
|
(dom-set-attr _el-span "_" "init if ^val is not undefined put 'leaked' into me else put 'blocked' into me")
|
|
(dom-set-attr _el-span "dom-scope" "closest .nonexistent")
|
|
(dom-set-inner-html _el-span "waiting")
|
|
(dom-append (dom-body) _el-div)
|
|
(dom-append _el-div _el-span)
|
|
(hs-activate! _el-div)
|
|
(hs-activate! _el-span)
|
|
))
|
|
(deftest "parent of jumps past matching ancestor to its parent"
|
|
(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 ^val to 'from-outer'")
|
|
(dom-add-class _el-div1 "middle")
|
|
(dom-set-attr _el-div1 "_" "init set ^val to 'from-middle'")
|
|
(dom-set-attr _el-div1 "dom-scope" "isolated")
|
|
(dom-set-attr _el-span "_" "init put ^val into me")
|
|
(dom-set-attr _el-span "dom-scope" "parent of .middle")
|
|
(dom-set-inner-html _el-span "none")
|
|
(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)
|
|
))
|
|
(deftest "isolated allows setting ^var on the isolated element itself"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-span (dom-create-element "span")))
|
|
(dom-set-attr _el-div "_" "init set ^outer to 'leaked'")
|
|
(dom-set-attr _el-div1 "_" "init set ^inner to 'contained'")
|
|
(dom-set-attr _el-div1 "dom-scope" "isolated")
|
|
(dom-set-attr _el-span "_" "init put ^inner into me")
|
|
(dom-set-inner-html _el-span "none")
|
|
(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)
|
|
))
|
|
(deftest "child reads ^var set by parent"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")) (_el-span (dom-create-element "span")))
|
|
(dom-set-attr _el-div "_" "init set ^count to 42")
|
|
(dom-set-attr _el-span "_" "on click put ^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 "child writes ^var and parent sees it"
|
|
(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 ^count to 0")
|
|
(dom-set-attr _el-button "_" "on click set ^count to 99")
|
|
(dom-set-inner-html _el-button "set")
|
|
(dom-set-attr _el-span "_" "on click put ^count 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) "99")
|
|
))
|
|
(deftest "deeply nested child reads ^var from grandparent"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-div2 (dom-create-element "div")) (_el-span (dom-create-element "span")))
|
|
(dom-set-attr _el-div "_" "init set ^name to 'alice'")
|
|
(dom-set-attr _el-span "_" "on click put ^name into me")
|
|
(dom-set-inner-html _el-span "empty")
|
|
(dom-append (dom-body) _el-div)
|
|
(dom-append _el-div _el-div1)
|
|
(dom-append _el-div1 _el-div2)
|
|
(dom-append _el-div2 _el-span)
|
|
(hs-activate! _el-div)
|
|
(hs-activate! _el-span)
|
|
(dom-dispatch _el-span "click" nil)
|
|
(assert= (dom-text-content _el-span) "alice")
|
|
))
|
|
(deftest "closest ancestor wins (shadowing)"
|
|
(hs-cleanup!)
|
|
(let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div")) (_el-span (dom-create-element "span")))
|
|
(dom-set-attr _el-div "_" "init set ^color to 'red'")
|
|
(dom-set-attr _el-div1 "_" "init set ^color to 'blue'")
|
|
(dom-set-attr _el-span "_" "on click put ^color into me")
|
|
(dom-set-inner-html _el-span "empty")
|
|
(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) "blue")
|
|
))
|
|
(deftest "sibling subtrees have independent ^vars"
|
|
(hs-cleanup!)
|
|
(let ((_el-a (dom-create-element "div")) (_el-span (dom-create-element "span")) (_el-b (dom-create-element "div")) (_el-span3 (dom-create-element "span")))
|
|
(dom-set-attr _el-a "id" "a")
|
|
(dom-set-attr _el-a "_" "init set ^val to 'A'")
|
|
(dom-set-attr _el-span "_" "on click put ^val into me")
|
|
(dom-set-inner-html _el-span "empty")
|
|
(dom-set-attr _el-b "id" "b")
|
|
(dom-set-attr _el-b "_" "init set ^val to 'B'")
|
|
(dom-set-attr _el-span3 "_" "on click put ^val into me")
|
|
(dom-set-inner-html _el-span3 "empty")
|
|
(dom-append (dom-body) _el-a)
|
|
(dom-append _el-a _el-span)
|
|
(dom-append (dom-body) _el-b)
|
|
(dom-append _el-b _el-span3)
|
|
(hs-activate! _el-a)
|
|
(hs-activate! _el-span)
|
|
(hs-activate! _el-b)
|
|
(hs-activate! _el-span3)
|
|
(dom-dispatch (dom-query "#a span") "click" nil)
|
|
(assert= (dom-text-content (dom-query "#a span")) "A")
|
|
(dom-dispatch (dom-query "#b span") "click" nil)
|
|
(assert= (dom-text-content (dom-query "#b span")) "B")
|
|
))
|
|
(deftest "write to ^var not found anywhere creates on current element"
|
|
(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-button "_" "on click set ^newvar to 'created' then put ^newvar into next <span/>")
|
|
(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)
|
|
(dom-set-prop _el-input "value" "hello")
|
|
(dom-dispatch _el-input "input" nil)
|
|
))
|
|
(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"
|
|
(assert= (eval-hs "42") 42)
|
|
(assert= (eval-hs "3.14") 3.14)
|
|
)
|
|
(deftest "works on boolean literals"
|
|
(assert= (eval-hs "true") true)
|
|
(assert= (eval-hs "false") false)
|
|
)
|
|
(deftest "works on null literal"
|
|
(assert= (eval-hs "null") nil)
|
|
)
|
|
(deftest "works on plain string literals"
|
|
(assert= (eval-hs "\"hello\"") "hello")
|
|
(assert= (eval-hs "'world'") "world")
|
|
)
|
|
(deftest "works on time expressions"
|
|
(assert= (eval-hs "200ms") 200)
|
|
(assert= (eval-hs "2s") 2000)
|
|
)
|
|
(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 <output/>")
|
|
(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 <span.replaced/> 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 <query/> 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= (map (fn (x) (get x "name")) (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 <li/> in #list 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= (map (fn (x) (get x "name")) (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= (map (fn (x) (get x "name")) (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")
|
|
(dom-set-attr _el-button "_" "\\\"on")
|
|
(dom-set-attr _el-b2 "id" "b2")
|
|
(dom-set-attr _el-b2 "_" "\\\"on")
|
|
(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)
|
|
(hs-activate! _el-button)
|
|
(hs-activate! _el-b2)
|
|
(dom-dispatch _el-button "click" nil)
|
|
(assert= (dom-text-content _el-button) "2")
|
|
(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")
|
|
(dom-set-attr _el-button "_" "\\\"set")
|
|
(dom-append (dom-body) _el-box)
|
|
(dom-append _el-box _el-span)
|
|
(dom-append _el-box _el-span2)
|
|
(dom-append (dom-body) _el-button)
|
|
(hs-activate! _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 <span/> 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 <input[type=checkbox]/> 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 <input[type=checkbox]/> in the closest <table/> 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 <input[type=checkbox]/> in the closest <table/> where it is not me then on change set checked of the :checkboxes to my checked then on change from the closest <table/> 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)
|
|
(dom-dispatch (dom-query ".cb") "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 <span/>")
|
|
(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 <span/>")
|
|
(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")
|
|
(dom-set-attr _el-d1 "_" "\\\"on")
|
|
(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")) "bar")
|
|
))
|
|
(deftest "can default of-expression properties"
|
|
(hs-cleanup!)
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "\\\"on")
|
|
(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")) "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"
|
|
(let ((haystack "a1b")) (eval-hs "pick matches of \"d*\" from haystack set window.test to it") (assert (not (nil? it))))
|
|
)
|
|
(deftest "can pick first n items"
|
|
(let ((arr (list 10 20 30 40 50))) (eval-hs "pick first 3 of arr set $test to it") (assert= it (list 10 20 30)))
|
|
)
|
|
(deftest "can pick last n items"
|
|
(let ((arr (list 10 20 30 40 50))) (eval-hs "pick last 2 of arr set $test to it") (assert= it (list 40 50)))
|
|
)
|
|
(deftest "can pick random item"
|
|
(let ((arr (list 10 20 30))) (eval-hs "pick random of arr set $test to it") (assert (not (nil? it))))
|
|
)
|
|
(deftest "can pick random n items"
|
|
(let ((arr (list 10 20 30 40 50))) (eval-hs "pick random 2 of arr set $test to it") (assert= (len it) 2))
|
|
)
|
|
(deftest "can pick items using 'of' syntax"
|
|
(let ((arr (list 10 11 12 13 14 15 16))) (eval-hs "pick items 1 to 3 of arr set $test to it") (assert= it (list 11 12)))
|
|
)
|
|
(deftest "can pick match using 'of' syntax"
|
|
(assert= (eval-hs "pick match of \"d+\" of haystack set window.test to it") (list "32"))
|
|
)
|
|
)
|
|
|
|
;; ── 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)
|
|
(assert (dom-has-class? (dom-query ".item") "done"))
|
|
))
|
|
)
|
|
|
|
;; ── 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")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(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)
|
|
(hs-activate! _el-div)
|
|
(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")))
|
|
(dom-set-attr _el-div "_" "\\\"on")
|
|
(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)
|
|
(hs-activate! _el-div)
|
|
(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= (host-get (eval-hs "'{\"foo\":\"bar\"}' as JSON") "foo") "bar")
|
|
)
|
|
(deftest "converts value as JSONString"
|
|
(assert= (eval-hs "{foo:'bar'} as JSONString") "{"foo":"bar"}")
|
|
)
|
|
(deftest "pipe operator chains conversions"
|
|
(assert= (host-get (eval-hs "{foo:'bar'} as JSONString | JSON") "foo") "bar")
|
|
)
|
|
(deftest "can use the an modifier if you'd like"
|
|
(assert= (host-get (eval-hs "'{\"foo\":\"bar\"}' as an Object") "foo") "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")
|
|
(dom-set-attr _el-master "_" "\\\"set")
|
|
(dom-set-attr _el-master "type" "checkbox")
|
|
(dom-set-attr _el-master "<input[type" "checkbox]/")
|
|
(dom-set-inner-html _el-master "in the closest")
|
|
(dom-set-attr _el-out "id" "out")
|
|
(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-input4)
|
|
(dom-append _el-input4 _el-master)
|
|
(dom-append _el-master _el-table6)
|
|
(dom-append _el-master _el-out)
|
|
(hs-activate! _el-master)
|
|
(dom-dispatch (dom-query-by-id "master") "click" nil)
|
|
(assert= (dom-text-content (dom-query-by-id "out")) "2")
|
|
))
|
|
(deftest "closest with to modifier still works after parse change"
|
|
(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-inner "id" "inner")
|
|
(dom-append (dom-body) _el-outer)
|
|
(dom-append _el-outer _el-inner)
|
|
))
|
|
)
|
|
|
|
;; ── comparisonOperator (40 tests) ──
|
|
(defsuite "hs-upstream-comparisonOperator"
|
|
(deftest "is a works with instanceof fallback"
|
|
(hs-cleanup!)
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click if I am a Element put \\\"yes\\\" into me")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch (dom-query-by-id "d1") "click" nil)
|
|
(assert= (dom-text-content (dom-query-by-id "d1")) "yes")
|
|
))
|
|
(deftest "is a Node works via instanceof"
|
|
(hs-cleanup!)
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click if I am a Node put \\\"yes\\\" into me")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch (dom-query-by-id "d1") "click" nil)
|
|
(assert= (dom-text-content (dom-query-by-id "d1")) "yes")
|
|
))
|
|
(deftest "is not a works with instanceof fallback"
|
|
(hs-cleanup!)
|
|
(let ((_el-d1 (dom-create-element "div")))
|
|
(dom-set-attr _el-d1 "id" "d1")
|
|
(dom-set-attr _el-d1 "_" "on click if \\\"hello\\\" is not a Element put \\\"yes\\\" into me")
|
|
(dom-append (dom-body) _el-d1)
|
|
(hs-activate! _el-d1)
|
|
(dom-dispatch (dom-query-by-id "d1") "click" nil)
|
|
(assert= (dom-text-content (dom-query-by-id "d1")) "yes")
|
|
))
|
|
(deftest "is ignoring case works"
|
|
(assert= (eval-hs "'Hello' is 'hello' ignoring case") true)
|
|
(assert= (eval-hs "'Hello' is 'HELLO' ignoring case") true)
|
|
(assert= (eval-hs "'Hello' is 'world' ignoring case") false)
|
|
)
|
|
(deftest "is not ignoring case works"
|
|
(assert= (eval-hs "'Hello' is not 'world' ignoring case") true)
|
|
(assert= (eval-hs "'Hello' is not 'hello' ignoring case") false)
|
|
)
|
|
(deftest "contains ignoring case works"
|
|
(assert= (eval-hs "'Hello World' contains 'hello' ignoring case") true)
|
|
(assert= (eval-hs "'Hello World' contains 'WORLD' ignoring case") true)
|
|
(assert= (eval-hs "'Hello World' contains 'missing' ignoring case") false)
|
|
)
|
|
(deftest "matches ignoring case works"
|
|
(assert= (eval-hs "'Hello' matches 'hello' ignoring case") true)
|
|
(assert= (eval-hs "'Hello' matches 'HELLO' ignoring case") true)
|
|
)
|
|
(deftest "starts with works"
|
|
(assert= (eval-hs "'hello world' starts with 'hello'") true)
|
|
(assert= (eval-hs "'hello world' starts with 'world'") false)
|
|
(assert= (eval-hs "'hello' starts with 'hello'") true)
|
|
(assert= (eval-hs "'' starts with 'x'") false)
|
|
)
|
|
(deftest "ends with works"
|
|
(assert= (eval-hs "'hello world' ends with 'world'") true)
|
|
(assert= (eval-hs "'hello world' ends with 'hello'") false)
|
|
(assert= (eval-hs "'hello' ends with 'hello'") true)
|
|
(assert= (eval-hs "'' ends with 'x'") false)
|
|
)
|
|
(deftest "does not start with works"
|
|
(assert= (eval-hs "'hello world' does not start with 'hello'") false)
|
|
(assert= (eval-hs "'hello world' does not start with 'world'") true)
|
|
)
|
|
(deftest "does not end with works"
|
|
(assert= (eval-hs "'hello world' does not end with 'world'") false)
|
|
(assert= (eval-hs "'hello world' does not end with 'hello'") true)
|
|
)
|
|
(deftest "starts with null is false"
|
|
(assert= (eval-hs "null starts with 'x'") false)
|
|
(assert= (eval-hs "null does not start with 'x'") true)
|
|
)
|
|
(deftest "ends with null is false"
|
|
(assert= (eval-hs "null ends with 'x'") false)
|
|
(assert= (eval-hs "null does not end with 'x'") true)
|
|
)
|
|
(deftest "starts with ignoring case works"
|
|
(assert= (eval-hs "'Hello World' starts with 'hello' ignoring case") true)
|
|
(assert= (eval-hs "'Hello World' starts with 'HELLO' ignoring case") true)
|
|
(assert= (eval-hs "'Hello World' starts with 'world' ignoring case") false)
|
|
)
|
|
(deftest "ends with ignoring case works"
|
|
(assert= (eval-hs "'Hello World' ends with 'world' ignoring case") true)
|
|
(assert= (eval-hs "'Hello World' ends with 'WORLD' ignoring case") true)
|
|
(assert= (eval-hs "'Hello World' ends with 'hello' ignoring case") false)
|
|
)
|
|
(deftest "starts with coerces to string"
|
|
(assert= (eval-hs "123 starts with '12'") true)
|
|
(assert= (eval-hs "123 starts with '23'") false)
|
|
)
|
|
(deftest "ends with coerces to string"
|
|
(assert= (eval-hs "123 ends with '23'") true)
|
|
(assert= (eval-hs "123 ends with '12'") false)
|
|
)
|
|
(deftest "is between works"
|
|
(assert= (eval-hs "5 is between 1 and 10") true)
|
|
(assert= (eval-hs "1 is between 1 and 10") true)
|
|
(assert= (eval-hs "10 is between 1 and 10") true)
|
|
(assert= (eval-hs "0 is between 1 and 10") false)
|
|
(assert= (eval-hs "11 is between 1 and 10") false)
|
|
)
|
|
(deftest "is not between works"
|
|
(assert= (eval-hs "5 is not between 1 and 10") false)
|
|
(assert= (eval-hs "0 is not between 1 and 10") true)
|
|
(assert= (eval-hs "11 is not between 1 and 10") true)
|
|
(assert= (eval-hs "1 is not between 1 and 10") false)
|
|
(assert= (eval-hs "10 is not between 1 and 10") false)
|
|
)
|
|
(deftest "between works with strings"
|
|
(assert= (eval-hs "'b' is between 'a' and 'c'") true)
|
|
(assert= (eval-hs "'d' is between 'a' and 'c'") false)
|
|
)
|
|
(deftest "I am between works"
|
|
(assert= (eval-hs-with-me "I am between 1 and 10" 5) true)
|
|
(assert= (eval-hs-with-me "I am between 1 and 10" 0) false)
|
|
)
|
|
(deftest "I am not between works"
|
|
(assert= (eval-hs-with-me "I am not between 1 and 10" 5) false)
|
|
(assert= (eval-hs-with-me "I am not between 1 and 10" 0) true)
|
|
)
|
|
(deftest "precedes works"
|
|
(hs-cleanup!)
|
|
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")) (_el-c (dom-create-element "div")))
|
|
(dom-set-attr _el-a "id" "a")
|
|
(dom-set-attr _el-b "id" "b")
|
|
(dom-set-attr _el-c "id" "c")
|
|
(dom-append (dom-body) _el-a)
|
|
(dom-append (dom-body) _el-b)
|
|
(dom-append (dom-body) _el-c)
|
|
))
|
|
(deftest "follows works"
|
|
(hs-cleanup!)
|
|
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")) (_el-c (dom-create-element "div")))
|
|
(dom-set-attr _el-a "id" "a")
|
|
(dom-set-attr _el-b "id" "b")
|
|
(dom-set-attr _el-c "id" "c")
|
|
(dom-append (dom-body) _el-a)
|
|
(dom-append (dom-body) _el-b)
|
|
(dom-append (dom-body) _el-c)
|
|
))
|
|
(deftest "does not precede works"
|
|
(hs-cleanup!)
|
|
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")))
|
|
(dom-set-attr _el-a "id" "a")
|
|
(dom-set-attr _el-b "id" "b")
|
|
(dom-append (dom-body) _el-a)
|
|
(dom-append (dom-body) _el-b)
|
|
))
|
|
(deftest "does not follow works"
|
|
(hs-cleanup!)
|
|
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")))
|
|
(dom-set-attr _el-a "id" "a")
|
|
(dom-set-attr _el-b "id" "b")
|
|
(dom-append (dom-body) _el-a)
|
|
(dom-append (dom-body) _el-b)
|
|
))
|
|
(deftest "precedes with null is false"
|
|
(assert= (eval-hs "null precedes null") false)
|
|
(assert= (eval-hs "null does not precede null") true)
|
|
)
|
|
(deftest "I precede works"
|
|
(hs-cleanup!)
|
|
(let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div")))
|
|
(dom-set-attr _el-a "id" "a")
|
|
(dom-set-attr _el-a "_" "\\\"on")
|
|
(dom-set-attr _el-b "id" "b")
|
|
(dom-append (dom-body) _el-a)
|
|
(dom-append (dom-body) _el-b)
|
|
(hs-activate! _el-a)
|
|
(dom-dispatch (dom-query-by-id "a") "click" nil)
|
|
(assert= (dom-text-content (dom-query-by-id "a")) "yes")
|
|
))
|
|
(deftest "is really works without equal to"
|
|
(assert= (eval-hs "2 is really 2") true)
|
|
(assert= (eval-hs "2 is really '2'") false)
|
|
)
|
|
(deftest "is not really works without equal to"
|
|
(assert= (eval-hs "2 is not really '2'") true)
|
|
(assert= (eval-hs "2 is not really 2") false)
|
|
)
|
|
(deftest "is equal works without to"
|
|
(assert= (eval-hs "2 is equal 2") true)
|
|
(assert= (eval-hs "2 is equal 1") false)
|
|
)
|
|
(deftest "is not equal works without to"
|
|
(assert= (eval-hs "2 is not equal 2") false)
|
|
(assert= (eval-hs "2 is not equal 1") true)
|
|
)
|
|
(deftest "am works as alias for is"
|
|
(assert= (eval-hs "2 am 2") true)
|
|
(assert= (eval-hs "2 am 1") false)
|
|
)
|
|
(deftest "is not undefined still works as equality"
|
|
(assert= (eval-hs "5 is not undefined") true)
|
|
(assert= (eval-hs "null is not undefined") false)
|
|
)
|
|
(deftest "is not null still works as equality"
|
|
(assert= (eval-hs "5 is not null") true)
|
|
(assert= (eval-hs "null is not null") false)
|
|
)
|
|
(deftest "is falls back to boolean property when rhs is undefined"
|
|
(hs-cleanup!)
|
|
(let ((_el-c1 (dom-create-element "input")) (_el-c2 (dom-create-element "input")))
|
|
(dom-set-attr _el-c1 "id" "c1")
|
|
(dom-set-attr _el-c1 "type" "checkbox")
|
|
(dom-set-attr _el-c1 "checked" "checked")
|
|
(dom-set-attr _el-c2 "id" "c2")
|
|
(dom-set-attr _el-c2 "type" "checkbox")
|
|
(dom-append (dom-body) _el-c1)
|
|
(dom-append (dom-body) _el-c2)
|
|
))
|
|
(deftest "is not falls back to boolean property when rhs is undefined"
|
|
(hs-cleanup!)
|
|
(let ((_el-c1 (dom-create-element "input")) (_el-c2 (dom-create-element "input")))
|
|
(dom-set-attr _el-c1 "id" "c1")
|
|
(dom-set-attr _el-c1 "type" "checkbox")
|
|
(dom-set-attr _el-c1 "checked" "checked")
|
|
(dom-set-attr _el-c2 "id" "c2")
|
|
(dom-set-attr _el-c2 "type" "checkbox")
|
|
(dom-append (dom-body) _el-c1)
|
|
(dom-append (dom-body) _el-c2)
|
|
))
|
|
(deftest "is boolean property works with disabled"
|
|
(hs-cleanup!)
|
|
(let ((_el-b1 (dom-create-element "button")) (_el-b2 (dom-create-element "button")))
|
|
(dom-set-attr _el-b1 "id" "b1")
|
|
(dom-set-inner-html _el-b1 "Disabled")
|
|
(dom-set-attr _el-b2 "id" "b2")
|
|
(dom-set-inner-html _el-b2 "Enabled")
|
|
(dom-append (dom-body) _el-b1)
|
|
(dom-append (dom-body) _el-b2)
|
|
))
|
|
(deftest "is still does equality when rhs variable exists"
|
|
(let ((x 5) (y 5)) (assert= (eval-hs "x is y") true))
|
|
(let ((x 5) (y 6)) (assert= (eval-hs "x is y") false))
|
|
)
|
|
(deftest "is boolean property works in where clause"
|
|
(hs-cleanup!)
|
|
(let ((_el-input (dom-create-element "input")) (_el-input1 (dom-create-element "input")) (_el-input2 (dom-create-element "input")))
|
|
(dom-add-class _el-input "cb")
|
|
(dom-set-attr _el-input "type" "checkbox")
|
|
(dom-set-attr _el-input "checked" "checked")
|
|
(dom-add-class _el-input1 "cb")
|
|
(dom-set-attr _el-input1 "type" "checkbox")
|
|
(dom-add-class _el-input2 "cb")
|
|
(dom-set-attr _el-input2 "type" "checkbox")
|
|
(dom-set-attr _el-input2 "checked" "checked")
|
|
(dom-append (dom-body) _el-input)
|
|
(dom-append (dom-body) _el-input1)
|
|
(dom-append (dom-body) _el-input2)
|
|
))
|
|
)
|
|
|
|
;; ── cookies (1 tests) ──
|
|
(defsuite "hs-upstream-cookies"
|
|
(deftest "length is 0 when no cookies are set"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
)
|
|
|
|
;; ── in (1 tests) ──
|
|
(defsuite "hs-upstream-in"
|
|
(deftest "null value in array returns empty"
|
|
(assert= (eval-hs "null in [1, 2, 3]") (list))
|
|
)
|
|
)
|
|
|
|
;; ── logicalOperator (3 tests) ──
|
|
(defsuite "hs-upstream-logicalOperator"
|
|
(deftest "and short-circuits when lhs promise resolves to false"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "or short-circuits when lhs promise resolves to true"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
(deftest "or evaluates rhs when lhs promise resolves to false"
|
|
(error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))
|
|
)
|
|
|
|
;; ── mathOperator (5 tests) ──
|
|
(defsuite "hs-upstream-mathOperator"
|
|
(deftest "array + array concats"
|
|
(assert= (eval-hs "[1, 2] + [3, 4]") (list 1 2 3 4))
|
|
)
|
|
(deftest "array + single value appends"
|
|
(assert= (eval-hs "[1, 2] + 3") (list 1 2 3))
|
|
)
|
|
(deftest "array + array does not mutate original"
|
|
(assert= (eval-hs "set a to [1, 2] then set b to a + [3] then return a") (list 1 2))
|
|
)
|
|
(deftest "array concat chains"
|
|
(assert= (eval-hs "[1] + [2] + [3]") (list 1 2 3))
|
|
)
|
|
(deftest "empty array + array works"
|
|
(assert= (eval-hs "[] + [1, 2]") (list 1 2))
|
|
)
|
|
)
|
|
|
|
;; ── no (5 tests) ──
|
|
(defsuite "hs-upstream-no"
|
|
(deftest "no returns false for non-empty array"
|
|
(assert= (eval-hs "no ['thing']") false)
|
|
)
|
|
(deftest "no with where filters then checks emptiness"
|
|
(assert= (eval-hs "no [1, 2, 3] where it > 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")
|
|
(dom-set-attr _el-button "_" "\\\"on")
|
|
(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)
|
|
(hs-activate! _el-button)
|
|
(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"))
|
|
)
|