diff --git a/lib/hyperscript/compiler.sx b/lib/hyperscript/compiler.sx index d0ac73a9..3ae4c062 100644 --- a/lib/hyperscript/compiler.sx +++ b/lib/hyperscript/compiler.sx @@ -43,7 +43,7 @@ ((= th (quote ref)) (list (quote set!) (make-symbol (nth target 1)) value)) ((= th (quote local)) - (list (quote set!) (make-symbol (nth target 1)) value)) + (list (quote define) (make-symbol (nth target 1)) value)) ((= th (quote me)) (list (quote dom-set-inner-html) (quote me) value)) ((= th (quote it)) (list (quote set!) (quote it) value)) @@ -912,6 +912,20 @@ (nth ast 1))))) ((= head (quote remove-element)) (list (quote dom-remove) (hs-to-sx (nth ast 1)))) + ((= head (quote add-value)) + (let + ((val (hs-to-sx (nth ast 1))) (tgt (nth ast 2))) + (list + (quote set!) + (hs-to-sx tgt) + (list (quote hs-add-to!) val (hs-to-sx tgt))))) + ((= head (quote remove-value)) + (let + ((val (hs-to-sx (nth ast 1))) (tgt (nth ast 2))) + (list + (quote set!) + (hs-to-sx tgt) + (list (quote hs-remove-from!) val (hs-to-sx tgt))))) ((= head (quote empty-target)) (list (quote hs-empty-target!) (hs-to-sx (nth ast 1)))) ((= head (quote open-element)) @@ -946,6 +960,28 @@ (quote hs-toggle-class!) (hs-to-sx (nth ast 2)) (nth ast 1))) + ((= head (quote toggle-class-for)) + (list + (quote do) + (list + (quote hs-toggle-class!) + (hs-to-sx (nth ast 2)) + (nth ast 1)) + (list + (quote perform) + (list + (quote list) + (quote io-sleep) + (hs-to-sx (nth ast 3)))) + (list + (quote hs-toggle-class!) + (hs-to-sx (nth ast 2)) + (nth ast 1)))) + ((= head (quote set-on)) + (list + (quote hs-set-on!) + (hs-to-sx (nth ast 1)) + (hs-to-sx (nth ast 2)))) ((= head (quote toggle-between)) (list (quote hs-toggle-between!) diff --git a/lib/hyperscript/parser.sx b/lib/hyperscript/parser.sx index 036ef73b..8e5d3607 100644 --- a/lib/hyperscript/parser.sx +++ b/lib/hyperscript/parser.sx @@ -283,6 +283,12 @@ var-name collection (parse-expr)))))))) + ((and (= typ "keyword") (> (len tokens) (+ p 1)) (= (get (nth tokens (+ p 1)) "type") "paren-open")) + (do + (adv!) + (let + ((name val) (args (parse-call-args))) + (list (quote call) (list (quote ref) name) args)))) (true nil))))) (define parse-poss @@ -805,7 +811,14 @@ (cons (quote multi-add-class) (cons tgt (cons cls extra-classes)))))))) - nil))) + (let + ((value (parse-expr))) + (if + (match-kw "to") + (let + ((tgt (parse-expr))) + (list (quote add-value) value tgt)) + nil))))) (define parse-remove-cmd (fn @@ -870,8 +883,13 @@ (list (quote remove-css) props tgt))))) (true (let - ((target (parse-expr))) - (list (quote remove-element) target)))))) + ((value (parse-expr))) + (if + (match-kw "from") + (let + ((tgt (parse-expr))) + (list (quote remove-value) value tgt)) + (list (quote remove-element) value))))))) (define parse-toggle-cmd (fn @@ -897,7 +915,12 @@ ((cls (do (let ((v (tp-val))) (adv!) v)))) (let ((tgt (parse-tgt-kw "on" (list (quote me))))) - (list (quote toggle-class) cls tgt)))) + (if + (match-kw "for") + (let + ((dur (parse-expr))) + (list (quote toggle-class-for) cls tgt dur)) + (list (quote toggle-class) cls tgt))))) ((= (tp-type) "style") (let ((prop (do (let ((v (tp-val))) (adv!) v)))) @@ -1006,8 +1029,14 @@ () (let ((tgt (parse-expr))) - (expect-kw! "to") - (let ((value (parse-expr))) (list (quote set!) tgt value))))) + (cond + ((match-kw "to") + (let ((value (parse-expr))) (list (quote set!) tgt value))) + ((match-kw "on") + (let + ((target (parse-expr))) + (list (quote set-on) tgt target))) + (true (error (str "Expected to/on at position " p))))))) (define parse-put-cmd (fn @@ -1244,7 +1273,7 @@ (let ((body (parse-cmd-list))) (match-kw "end") - (list (quote for) "it" collection nil body))))) + (list (quote for) "it" collection body))))) (true (let ((mode (cond ((match-kw "forever") (list (quote forever))) ((match-kw "while") (list (quote while) (parse-expr))) ((match-kw "until") (list (quote until) (parse-expr))) (true (let ((n (parse-expr))) (if (match-kw "times") (list (quote times) n) (list (quote forever)))))))) @@ -1464,10 +1493,12 @@ () (let ((value (parse-expr))) - (expect-kw! "to") - (let - ((target (parse-expr))) - (list (quote append!) value target))))) + (if + (match-kw "to") + (let + ((target (parse-expr))) + (list (quote append!) value target)) + (list (quote append!) value (list (quote it))))))) (define parse-tell-cmd (fn diff --git a/lib/hyperscript/runtime.sx b/lib/hyperscript/runtime.sx index 2b157b2a..27962e61 100644 --- a/lib/hyperscript/runtime.sx +++ b/lib/hyperscript/runtime.sx @@ -136,9 +136,35 @@ ((= pos "end") (dom-insert-adjacent-html target "beforeend" value))))) ;; Find previous sibling matching a selector. -(define hs-navigate! (fn (url) (perform (list (quote io-navigate) url)))) +(define + hs-add-to! + (fn + (value target) + (if + (list? target) + (append target (list value)) + (host-call target "push" value)))) ;; First element matching selector within a scope. +(define + hs-remove-from! + (fn + (value target) + (if + (list? target) + (filter (fn (x) (not (= x value))) target) + (host-call target "splice" (host-call target "indexOf" value) 1)))) + +;; Last element matching selector. +(define + hs-set-on! + (fn + (props target) + (for-each (fn (k) (host-set! target k (get props k))) (keys props)))) + +;; First/last within a specific scope. +(define hs-navigate! (fn (url) (perform (list (quote io-navigate) url)))) + (define hs-scroll! (fn @@ -151,7 +177,9 @@ ((= position "bottom") (dict :block "end")) (true (dict :block "start"))))))) -;; Last element matching selector. +;; ── Iteration ─────────────────────────────────────────────────── + +;; Repeat a thunk N times. (define hs-halt! (fn @@ -161,14 +189,19 @@ (host-call event "preventDefault" (list)) (when (= mode "event") (host-call event "stopPropagation" (list)))))) -;; First/last within a specific scope. +;; Repeat forever (until break — relies on exception/continuation). (define hs-select! (fn (target) (host-call target "select" (list)))) +;; ── Fetch ─────────────────────────────────────────────────────── + +;; Fetch a URL, parse response according to format. +;; (hs-fetch url format) — format is "json" | "text" | "html" (define hs-reset! (fn (target) (host-call target "reset" (list)))) -;; ── Iteration ─────────────────────────────────────────────────── +;; ── Type coercion ─────────────────────────────────────────────── -;; Repeat a thunk N times. +;; Coerce a value to a type by name. +;; (hs-coerce value type-name) — type-name is "Int", "Float", "String", etc. (define hs-next (fn @@ -188,7 +221,10 @@ (true (find-next (dom-next-sibling el)))))) (find-next sibling))))) -;; Repeat forever (until break — relies on exception/continuation). +;; ── Object creation ───────────────────────────────────────────── + +;; Make a new object of a given type. +;; (hs-make type-name) — creates empty object/collection (define hs-previous (fn @@ -208,26 +244,27 @@ (true (find-prev (dom-get-prop el "previousElementSibling")))))) (find-prev sibling))))) -;; ── Fetch ─────────────────────────────────────────────────────── +;; ── Behavior installation ─────────────────────────────────────── -;; Fetch a URL, parse response according to format. -;; (hs-fetch url format) — format is "json" | "text" | "html" +;; Install a behavior on an element. +;; A behavior is a function that takes (me ...params) and sets up features. +;; (hs-install behavior-fn me ...args) (define hs-query-all (fn (sel) (host-call (dom-body) "querySelectorAll" sel))) -;; ── Type coercion ─────────────────────────────────────────────── +;; ── Measurement ───────────────────────────────────────────────── -;; Coerce a value to a type by name. -;; (hs-coerce value type-name) — type-name is "Int", "Float", "String", etc. +;; Measure an element's bounding rect, store as local variables. +;; Returns a dict with x, y, width, height, top, left, right, bottom. (define hs-query-first (fn (sel) (host-call (host-global "document") "querySelector" sel))) -;; ── Object creation ───────────────────────────────────────────── +;; ── Transition ────────────────────────────────────────────────── -;; Make a new object of a given type. -;; (hs-make type-name) — creates empty object/collection +;; Transition a CSS property to a value, optionally with duration. +;; (hs-transition target prop value duration) (define hs-query-last (fn @@ -236,17 +273,8 @@ ((all (dom-query-all (dom-body) sel))) (if (> (len all) 0) (nth all (- (len all) 1)) nil)))) -;; ── Behavior installation ─────────────────────────────────────── - -;; Install a behavior on an element. -;; A behavior is a function that takes (me ...params) and sets up features. -;; (hs-install behavior-fn me ...args) (define hs-first (fn (scope sel) (dom-query-all scope sel))) -;; ── Measurement ───────────────────────────────────────────────── - -;; Measure an element's bounding rect, store as local variables. -;; Returns a dict with x, y, width, height, top, left, right, bottom. (define hs-last (fn @@ -255,10 +283,6 @@ ((all (dom-query-all scope sel))) (if (> (len all) 0) (nth all (- (len all) 1)) nil)))) -;; ── Transition ────────────────────────────────────────────────── - -;; Transition a CSS property to a value, optionally with duration. -;; (hs-transition target prop value duration) (define hs-repeat-times (fn @@ -296,7 +320,11 @@ ((= type-name "Integer") (floor (+ value 0))) ((= type-name "Float") (+ value 0)) ((= type-name "Number") (+ value 0)) - ((= type-name "String") (str value)) + ((= type-name "String") + (if + (list? value) + (join "," (map (fn (x) (str x)) value)) + (str value))) ((= type-name "Bool") (not (hs-falsy? value))) ((= type-name "Boolean") (not (hs-falsy? value))) ((= type-name "Array") (if (list? value) value (list value))) @@ -395,6 +423,10 @@ (define hs-install (fn (behavior-fn) (behavior-fn me))) + + + + (define hs-measure (fn (target) (perform (list (quote io-measure) target)))) @@ -411,7 +443,8 @@ (str prop " " (/ duration 1000) "s"))) (dom-set-style target prop value) (when duration (hs-settle target)))) - +;; ── Sandbox/test runtime additions ────────────────────────────── +;; Property access — dot notation and .length (define hs-transition-from (fn @@ -425,11 +458,7 @@ (str prop " " (/ duration 1000) "s"))) (dom-set-style target prop (str to-val)) (when duration (hs-settle target)))) - - - - - +;; DOM query stub — sandbox returns empty list (define hs-type-check (fn @@ -449,34 +478,33 @@ (= (host-typeof value) "element") (= (host-typeof value) "text"))) (true (= (host-typeof value) (downcase type-name))))))) - +;; Method dispatch — obj.method(args) (define hs-type-check-strict (fn (value type-name) (if (nil? value) false (hs-type-check value type-name)))) -;; ── Sandbox/test runtime additions ────────────────────────────── -;; Property access — dot notation and .length -(define - hs-strict-eq - (fn (a b) (and (= (type-of a) (type-of b)) (= a b)))) -;; DOM query stub — sandbox returns empty list -(define - hs-eq-ignore-case - (fn (a b) (= (downcase (str a)) (downcase (str b))))) -;; Method dispatch — obj.method(args) -(define - hs-starts-with-ic? - (fn (str prefix) (starts-with? (downcase str) (downcase prefix)))) ;; ── 0.9.90 features ───────────────────────────────────────────── ;; beep! — debug logging, returns value unchanged +(define + hs-strict-eq + (fn (a b) (and (= (type-of a) (type-of b)) (= a b)))) +;; Property-based is — check obj.key truthiness +(define + hs-eq-ignore-case + (fn (a b) (= (downcase (str a)) (downcase (str b))))) +;; Array slicing (inclusive both ends) +(define + hs-starts-with-ic? + (fn (str prefix) (starts-with? (downcase str) (downcase prefix)))) +;; Collection: sorted by (define hs-contains-ignore-case? (fn (haystack needle) (contains? (downcase (str haystack)) (downcase (str needle))))) -;; Property-based is — check obj.key truthiness +;; Collection: sorted by descending (define hs-falsy? (fn @@ -488,7 +516,7 @@ ((and (list? v) (= (len v) 0)) true) ((= v 0) true) (true false)))) -;; Array slicing (inclusive both ends) +;; Collection: split by (define hs-matches? (fn @@ -499,7 +527,7 @@ ((= (host-typeof target) "element") (if (string? pattern) (host-call target "matches" pattern) false)) (true false)))) -;; Collection: sorted by +;; Collection: joined by (define hs-contains? (fn @@ -519,9 +547,9 @@ true (hs-contains? (rest collection) item))))) (true false)))) -;; Collection: sorted by descending + (define precedes? (fn (a b) (< (str a) (str b)))) -;; Collection: split by + (define hs-empty? (fn @@ -532,7 +560,7 @@ ((list? v) (= (len v) 0)) ((dict? v) (= (len (keys v)) 0)) (true false)))) -;; Collection: joined by + (define hs-empty-target! (fn diff --git a/shared/static/wasm/sx/hs-compiler.sx b/shared/static/wasm/sx/hs-compiler.sx index d0ac73a9..3ae4c062 100644 --- a/shared/static/wasm/sx/hs-compiler.sx +++ b/shared/static/wasm/sx/hs-compiler.sx @@ -43,7 +43,7 @@ ((= th (quote ref)) (list (quote set!) (make-symbol (nth target 1)) value)) ((= th (quote local)) - (list (quote set!) (make-symbol (nth target 1)) value)) + (list (quote define) (make-symbol (nth target 1)) value)) ((= th (quote me)) (list (quote dom-set-inner-html) (quote me) value)) ((= th (quote it)) (list (quote set!) (quote it) value)) @@ -912,6 +912,20 @@ (nth ast 1))))) ((= head (quote remove-element)) (list (quote dom-remove) (hs-to-sx (nth ast 1)))) + ((= head (quote add-value)) + (let + ((val (hs-to-sx (nth ast 1))) (tgt (nth ast 2))) + (list + (quote set!) + (hs-to-sx tgt) + (list (quote hs-add-to!) val (hs-to-sx tgt))))) + ((= head (quote remove-value)) + (let + ((val (hs-to-sx (nth ast 1))) (tgt (nth ast 2))) + (list + (quote set!) + (hs-to-sx tgt) + (list (quote hs-remove-from!) val (hs-to-sx tgt))))) ((= head (quote empty-target)) (list (quote hs-empty-target!) (hs-to-sx (nth ast 1)))) ((= head (quote open-element)) @@ -946,6 +960,28 @@ (quote hs-toggle-class!) (hs-to-sx (nth ast 2)) (nth ast 1))) + ((= head (quote toggle-class-for)) + (list + (quote do) + (list + (quote hs-toggle-class!) + (hs-to-sx (nth ast 2)) + (nth ast 1)) + (list + (quote perform) + (list + (quote list) + (quote io-sleep) + (hs-to-sx (nth ast 3)))) + (list + (quote hs-toggle-class!) + (hs-to-sx (nth ast 2)) + (nth ast 1)))) + ((= head (quote set-on)) + (list + (quote hs-set-on!) + (hs-to-sx (nth ast 1)) + (hs-to-sx (nth ast 2)))) ((= head (quote toggle-between)) (list (quote hs-toggle-between!) diff --git a/shared/static/wasm/sx/hs-parser.sx b/shared/static/wasm/sx/hs-parser.sx index 036ef73b..8e5d3607 100644 --- a/shared/static/wasm/sx/hs-parser.sx +++ b/shared/static/wasm/sx/hs-parser.sx @@ -283,6 +283,12 @@ var-name collection (parse-expr)))))))) + ((and (= typ "keyword") (> (len tokens) (+ p 1)) (= (get (nth tokens (+ p 1)) "type") "paren-open")) + (do + (adv!) + (let + ((name val) (args (parse-call-args))) + (list (quote call) (list (quote ref) name) args)))) (true nil))))) (define parse-poss @@ -805,7 +811,14 @@ (cons (quote multi-add-class) (cons tgt (cons cls extra-classes)))))))) - nil))) + (let + ((value (parse-expr))) + (if + (match-kw "to") + (let + ((tgt (parse-expr))) + (list (quote add-value) value tgt)) + nil))))) (define parse-remove-cmd (fn @@ -870,8 +883,13 @@ (list (quote remove-css) props tgt))))) (true (let - ((target (parse-expr))) - (list (quote remove-element) target)))))) + ((value (parse-expr))) + (if + (match-kw "from") + (let + ((tgt (parse-expr))) + (list (quote remove-value) value tgt)) + (list (quote remove-element) value))))))) (define parse-toggle-cmd (fn @@ -897,7 +915,12 @@ ((cls (do (let ((v (tp-val))) (adv!) v)))) (let ((tgt (parse-tgt-kw "on" (list (quote me))))) - (list (quote toggle-class) cls tgt)))) + (if + (match-kw "for") + (let + ((dur (parse-expr))) + (list (quote toggle-class-for) cls tgt dur)) + (list (quote toggle-class) cls tgt))))) ((= (tp-type) "style") (let ((prop (do (let ((v (tp-val))) (adv!) v)))) @@ -1006,8 +1029,14 @@ () (let ((tgt (parse-expr))) - (expect-kw! "to") - (let ((value (parse-expr))) (list (quote set!) tgt value))))) + (cond + ((match-kw "to") + (let ((value (parse-expr))) (list (quote set!) tgt value))) + ((match-kw "on") + (let + ((target (parse-expr))) + (list (quote set-on) tgt target))) + (true (error (str "Expected to/on at position " p))))))) (define parse-put-cmd (fn @@ -1244,7 +1273,7 @@ (let ((body (parse-cmd-list))) (match-kw "end") - (list (quote for) "it" collection nil body))))) + (list (quote for) "it" collection body))))) (true (let ((mode (cond ((match-kw "forever") (list (quote forever))) ((match-kw "while") (list (quote while) (parse-expr))) ((match-kw "until") (list (quote until) (parse-expr))) (true (let ((n (parse-expr))) (if (match-kw "times") (list (quote times) n) (list (quote forever)))))))) @@ -1464,10 +1493,12 @@ () (let ((value (parse-expr))) - (expect-kw! "to") - (let - ((target (parse-expr))) - (list (quote append!) value target))))) + (if + (match-kw "to") + (let + ((target (parse-expr))) + (list (quote append!) value target)) + (list (quote append!) value (list (quote it))))))) (define parse-tell-cmd (fn diff --git a/shared/static/wasm/sx/hs-runtime.sx b/shared/static/wasm/sx/hs-runtime.sx index 2b157b2a..27962e61 100644 --- a/shared/static/wasm/sx/hs-runtime.sx +++ b/shared/static/wasm/sx/hs-runtime.sx @@ -136,9 +136,35 @@ ((= pos "end") (dom-insert-adjacent-html target "beforeend" value))))) ;; Find previous sibling matching a selector. -(define hs-navigate! (fn (url) (perform (list (quote io-navigate) url)))) +(define + hs-add-to! + (fn + (value target) + (if + (list? target) + (append target (list value)) + (host-call target "push" value)))) ;; First element matching selector within a scope. +(define + hs-remove-from! + (fn + (value target) + (if + (list? target) + (filter (fn (x) (not (= x value))) target) + (host-call target "splice" (host-call target "indexOf" value) 1)))) + +;; Last element matching selector. +(define + hs-set-on! + (fn + (props target) + (for-each (fn (k) (host-set! target k (get props k))) (keys props)))) + +;; First/last within a specific scope. +(define hs-navigate! (fn (url) (perform (list (quote io-navigate) url)))) + (define hs-scroll! (fn @@ -151,7 +177,9 @@ ((= position "bottom") (dict :block "end")) (true (dict :block "start"))))))) -;; Last element matching selector. +;; ── Iteration ─────────────────────────────────────────────────── + +;; Repeat a thunk N times. (define hs-halt! (fn @@ -161,14 +189,19 @@ (host-call event "preventDefault" (list)) (when (= mode "event") (host-call event "stopPropagation" (list)))))) -;; First/last within a specific scope. +;; Repeat forever (until break — relies on exception/continuation). (define hs-select! (fn (target) (host-call target "select" (list)))) +;; ── Fetch ─────────────────────────────────────────────────────── + +;; Fetch a URL, parse response according to format. +;; (hs-fetch url format) — format is "json" | "text" | "html" (define hs-reset! (fn (target) (host-call target "reset" (list)))) -;; ── Iteration ─────────────────────────────────────────────────── +;; ── Type coercion ─────────────────────────────────────────────── -;; Repeat a thunk N times. +;; Coerce a value to a type by name. +;; (hs-coerce value type-name) — type-name is "Int", "Float", "String", etc. (define hs-next (fn @@ -188,7 +221,10 @@ (true (find-next (dom-next-sibling el)))))) (find-next sibling))))) -;; Repeat forever (until break — relies on exception/continuation). +;; ── Object creation ───────────────────────────────────────────── + +;; Make a new object of a given type. +;; (hs-make type-name) — creates empty object/collection (define hs-previous (fn @@ -208,26 +244,27 @@ (true (find-prev (dom-get-prop el "previousElementSibling")))))) (find-prev sibling))))) -;; ── Fetch ─────────────────────────────────────────────────────── +;; ── Behavior installation ─────────────────────────────────────── -;; Fetch a URL, parse response according to format. -;; (hs-fetch url format) — format is "json" | "text" | "html" +;; Install a behavior on an element. +;; A behavior is a function that takes (me ...params) and sets up features. +;; (hs-install behavior-fn me ...args) (define hs-query-all (fn (sel) (host-call (dom-body) "querySelectorAll" sel))) -;; ── Type coercion ─────────────────────────────────────────────── +;; ── Measurement ───────────────────────────────────────────────── -;; Coerce a value to a type by name. -;; (hs-coerce value type-name) — type-name is "Int", "Float", "String", etc. +;; Measure an element's bounding rect, store as local variables. +;; Returns a dict with x, y, width, height, top, left, right, bottom. (define hs-query-first (fn (sel) (host-call (host-global "document") "querySelector" sel))) -;; ── Object creation ───────────────────────────────────────────── +;; ── Transition ────────────────────────────────────────────────── -;; Make a new object of a given type. -;; (hs-make type-name) — creates empty object/collection +;; Transition a CSS property to a value, optionally with duration. +;; (hs-transition target prop value duration) (define hs-query-last (fn @@ -236,17 +273,8 @@ ((all (dom-query-all (dom-body) sel))) (if (> (len all) 0) (nth all (- (len all) 1)) nil)))) -;; ── Behavior installation ─────────────────────────────────────── - -;; Install a behavior on an element. -;; A behavior is a function that takes (me ...params) and sets up features. -;; (hs-install behavior-fn me ...args) (define hs-first (fn (scope sel) (dom-query-all scope sel))) -;; ── Measurement ───────────────────────────────────────────────── - -;; Measure an element's bounding rect, store as local variables. -;; Returns a dict with x, y, width, height, top, left, right, bottom. (define hs-last (fn @@ -255,10 +283,6 @@ ((all (dom-query-all scope sel))) (if (> (len all) 0) (nth all (- (len all) 1)) nil)))) -;; ── Transition ────────────────────────────────────────────────── - -;; Transition a CSS property to a value, optionally with duration. -;; (hs-transition target prop value duration) (define hs-repeat-times (fn @@ -296,7 +320,11 @@ ((= type-name "Integer") (floor (+ value 0))) ((= type-name "Float") (+ value 0)) ((= type-name "Number") (+ value 0)) - ((= type-name "String") (str value)) + ((= type-name "String") + (if + (list? value) + (join "," (map (fn (x) (str x)) value)) + (str value))) ((= type-name "Bool") (not (hs-falsy? value))) ((= type-name "Boolean") (not (hs-falsy? value))) ((= type-name "Array") (if (list? value) value (list value))) @@ -395,6 +423,10 @@ (define hs-install (fn (behavior-fn) (behavior-fn me))) + + + + (define hs-measure (fn (target) (perform (list (quote io-measure) target)))) @@ -411,7 +443,8 @@ (str prop " " (/ duration 1000) "s"))) (dom-set-style target prop value) (when duration (hs-settle target)))) - +;; ── Sandbox/test runtime additions ────────────────────────────── +;; Property access — dot notation and .length (define hs-transition-from (fn @@ -425,11 +458,7 @@ (str prop " " (/ duration 1000) "s"))) (dom-set-style target prop (str to-val)) (when duration (hs-settle target)))) - - - - - +;; DOM query stub — sandbox returns empty list (define hs-type-check (fn @@ -449,34 +478,33 @@ (= (host-typeof value) "element") (= (host-typeof value) "text"))) (true (= (host-typeof value) (downcase type-name))))))) - +;; Method dispatch — obj.method(args) (define hs-type-check-strict (fn (value type-name) (if (nil? value) false (hs-type-check value type-name)))) -;; ── Sandbox/test runtime additions ────────────────────────────── -;; Property access — dot notation and .length -(define - hs-strict-eq - (fn (a b) (and (= (type-of a) (type-of b)) (= a b)))) -;; DOM query stub — sandbox returns empty list -(define - hs-eq-ignore-case - (fn (a b) (= (downcase (str a)) (downcase (str b))))) -;; Method dispatch — obj.method(args) -(define - hs-starts-with-ic? - (fn (str prefix) (starts-with? (downcase str) (downcase prefix)))) ;; ── 0.9.90 features ───────────────────────────────────────────── ;; beep! — debug logging, returns value unchanged +(define + hs-strict-eq + (fn (a b) (and (= (type-of a) (type-of b)) (= a b)))) +;; Property-based is — check obj.key truthiness +(define + hs-eq-ignore-case + (fn (a b) (= (downcase (str a)) (downcase (str b))))) +;; Array slicing (inclusive both ends) +(define + hs-starts-with-ic? + (fn (str prefix) (starts-with? (downcase str) (downcase prefix)))) +;; Collection: sorted by (define hs-contains-ignore-case? (fn (haystack needle) (contains? (downcase (str haystack)) (downcase (str needle))))) -;; Property-based is — check obj.key truthiness +;; Collection: sorted by descending (define hs-falsy? (fn @@ -488,7 +516,7 @@ ((and (list? v) (= (len v) 0)) true) ((= v 0) true) (true false)))) -;; Array slicing (inclusive both ends) +;; Collection: split by (define hs-matches? (fn @@ -499,7 +527,7 @@ ((= (host-typeof target) "element") (if (string? pattern) (host-call target "matches" pattern) false)) (true false)))) -;; Collection: sorted by +;; Collection: joined by (define hs-contains? (fn @@ -519,9 +547,9 @@ true (hs-contains? (rest collection) item))))) (true false)))) -;; Collection: sorted by descending + (define precedes? (fn (a b) (< (str a) (str b)))) -;; Collection: split by + (define hs-empty? (fn @@ -532,7 +560,7 @@ ((list? v) (= (len v) 0)) ((dict? v) (= (len (keys v)) 0)) (true false)))) -;; Collection: joined by + (define hs-empty-target! (fn diff --git a/spec/tests/test-hyperscript-behavioral.sx b/spec/tests/test-hyperscript-behavioral.sx index 0c9af7d4..354a536d 100644 --- a/spec/tests/test-hyperscript-behavioral.sx +++ b/spec/tests/test-hyperscript-behavioral.sx @@ -3523,14 +3523,10 @@ ) ;; ── on (63 tests) ── -(defsuite - "hs-upstream-on" - (deftest - "can respond to events with dots in names" +(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"))) + (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") @@ -3539,13 +3535,11 @@ (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" + (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"))) + (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") @@ -3554,13 +3548,11 @@ (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" + (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"))) + (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") @@ -3569,79 +3561,64 @@ (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" + (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"))) + (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" + (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"))) + (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-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" + (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"))) + (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) - (assert= (dom-inner-html _el-div) "1"))) - (deftest - "supports " - elsewhere - " modifier" + ;; 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"))) + (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" + (assert (dom-has-class? _el-div "clicked")) + )) + (deftest "supports "from elsewhere" modifier" (hs-cleanup!) - (let - ((_el-div (dom-create-element "div"))) + (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" + (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"))) + (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") @@ -3651,13 +3628,11 @@ (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" + (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"))) + (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") @@ -3667,61 +3642,41 @@ (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" + (assert (dom-has-class? _el-d1 "fromBar")) + )) + (deftest "can fire an event on load" (hs-cleanup!) - (let - ((_el-d1 (dom-create-element "div"))) + (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))) - (deftest - "can be in a top level script tag" + (hs-activate! _el-d1) + ;; SKIP check: skip div.innerText.should.equal("Loaded") + )) + (deftest "can be in a top level script tag" (hs-cleanup!) - (let - ((_el-script (dom-create-element "script")) - (_el-loadedDemo (dom-create-element "div"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "on load put \"Loaded\" into #loadedDemo.innerHTML") + (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-script) - (dom-append (dom-body) _el-loadedDemo))) - (deftest - "can have a simple event filter" + (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"))) + (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-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))) - (deftest - "can refer to event properties directly in filter" + (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") + (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) @@ -3730,78 +3685,75 @@ (hs-activate! _el-div2) (dom-dispatch _el-div "click" nil) (dom-dispatch _el-div "click" nil) - (dom-dispatch _el-div "click" nil))) - (deftest - "can refer to event detail properties directly in filter" + (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") + (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))) - (deftest - "can click after a positive event filter" + (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") + (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))) - (deftest - "multiple event handlers at a time are allowed to execute with the every keyword" + (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") + (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))) - (deftest - "can have multiple event handlers" + (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") + (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))) - (deftest - "can have multiple event handlers, no end" + (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") + (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))) - (deftest - "can queue events" + (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"))) + (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) @@ -3810,16 +3762,15 @@ (dom-dispatch _el-div "foo" nil) (dom-dispatch _el-div "bar" nil) (dom-dispatch _el-div "bar" nil) - (dom-dispatch _el-div "bar" nil))) - (deftest - "can queue first event" + (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()") + (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) @@ -3827,16 +3778,15 @@ (dom-dispatch _el-div "foo" nil) (dom-dispatch _el-div "bar" nil) (dom-dispatch _el-div "bar" nil) - (dom-dispatch _el-div "bar" nil))) - (deftest - "can queue last event" + (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()") + (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) @@ -3844,16 +3794,15 @@ (dom-dispatch _el-div "foo" nil) (dom-dispatch _el-div "bar" nil) (dom-dispatch _el-div "bar" nil) - (dom-dispatch _el-div "bar" nil))) - (deftest - "can queue all events" + (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()") + (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) @@ -3861,39 +3810,39 @@ (dom-dispatch _el-div "foo" nil) (dom-dispatch _el-div "bar" nil) (dom-dispatch _el-div "bar" nil) - (dom-dispatch _el-div "bar" nil))) - (deftest - "queue none does not allow future queued events" + (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") + (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))) - (deftest - "can invoke on multiple events" + (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"))) + (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))) - (deftest - "can listen for events in another element (lazy)" + (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"))) + (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") @@ -3901,64 +3850,49 @@ (dom-append _el-div _el-d1) (dom-append _el-div _el-d2) (hs-activate! _el-div) - (dom-dispatch _el-div "click" nil))) - (deftest - "can filter events based on count" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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) @@ -3966,146 +3900,105 @@ (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" + (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") + (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" + (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") + (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" + (assert= (dom-inner-html _el-div) "Mutated") + )) + (deftest "can listen for specific attribute mutations" (hs-cleanup!) - (let - ((_el-div (dom-create-element "div"))) + (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" + (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"))) + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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"))) + (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-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" + (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"))) + (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-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") @@ -4121,549 +4014,349 @@ (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" + (assert= (dom-inner-html _el-div3) "behavior") + )) + (deftest "can catch exceptions thrown in js functions" (hs-cleanup!) - (let - ((_el-button (dom-create-element "button"))) + (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" + (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"))) + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (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") + (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" + (assert= (dom-inner-html _el-button) "success") + )) + (deftest "can ignore when target doesn't exist" (hs-cleanup!) - (let - ((_el-#d1 (dom-create-element "div"))) + (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-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" + (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"))) + (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-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" + (assert= (dom-inner-html _el-div) "2") + )) + (deftest "handles custom events with null detail" (hs-cleanup!) - (let - ((_el-d1 (dom-create-element "div"))) + (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-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-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") + (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" + (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") + (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" + (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") + (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" + (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") + (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")))) + (assert= (dom-text-content _el-div) "clicked") + )) +) ;; ── init (3 tests) ── -(defsuite - "hs-upstream-init" - (deftest - "can define an init block inline" +(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") + (let ((_el-div (dom-create-element "div"))) + (dom-set-attr _el-div "_" "init then set my.foo to 42 end on click put my.foo into my.innerHTML") (dom-append (dom-body) _el-div) (hs-activate! _el-div) (dom-dispatch _el-div "click" nil) - (assert= (dom-inner-html _el-div) "42"))) - (deftest - "can define an init block in a script" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html _el-script "init set window.foo to 42 end") - (dom-append (dom-body) _el-script))) - (deftest - "can initialize immediately" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "init set window.foo to 10 init immediately set window.bar to window.foo") - (dom-append (dom-body) _el-script)))) + (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" +(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"))) + (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" + (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"))) + (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" + (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"))) + (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" + (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"))) + (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" + (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"))) + (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" + (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") + (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))) - (deftest - "can exit" + (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!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html _el-script "def foo() exit end") - (dom-append (dom-body) _el-script))) - (deftest - "can return a value asynchronously" - (hs-cleanup!) - (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") + (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))) - (deftest - "can interop with javascript" + (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-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html _el-script "def foo() return \"foo\"end") - (dom-append (dom-body) _el-script))) - (deftest - "can interop with javascript asynchronously" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html _el-script "def foo() wait 1ms return \"foo\"end") - (dom-append (dom-body) _el-script))) - (deftest - "can catch exceptions" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() throw \"bar\"catch e set window.bar to e end") - (dom-append (dom-body) _el-script))) - (deftest - "can rethrow in catch blocks" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() throw \"bar\"catch e throw e end") - (dom-append (dom-body) _el-script))) - (deftest - "can return in catch blocks" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() throw \"bar\"catch e return 42 end") - (dom-append (dom-body) _el-script))) - (deftest - "can catch async exceptions" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def doh() wait 10ms throw \"bar\"end def foo() call doh()catch e set window.bar to e end") - (dom-append (dom-body) _el-script))) - (deftest - "can catch nested async exceptions" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def doh() wait 10ms throw \"bar\"end def foo() call doh()catch e set window.bar to e end") - (dom-append (dom-body) _el-script))) - (deftest - "can rethrow in async catch blocks" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() throw \"bar\"catch e wait 10ms throw e end") - (dom-append (dom-body) _el-script))) - (deftest - "can return in async catch blocks" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() throw \"bar\"catch e wait 10ms return 42 end") - (dom-append (dom-body) _el-script))) - (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"))) + (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()") @@ -4674,15 +4367,12 @@ (dom-append _el-div _el-d2) (dom-append _el-div _el-d3) (hs-activate! _el-div) - (hs-activate! _el-d1))) - (deftest - "can install a function on an element and use in children w/ return value" + (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"))) + (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") @@ -4693,15 +4383,12 @@ (dom-append _el-div _el-d2) (dom-append _el-div _el-d3) (hs-activate! _el-div) - (hs-activate! _el-d1))) - (deftest - "can install a function on an element and use me symbol correctly" + (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"))) + (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()") @@ -4712,75 +4399,24 @@ (dom-append _el-div _el-d2) (dom-append _el-div _el-d3) (hs-activate! _el-div) - (hs-activate! _el-d1))) - (deftest - "finally blocks run normally" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() set window.bar to 10finally set window.bar to 20 end") - (dom-append (dom-body) _el-script))) - (deftest - "finally blocks run when an exception occurs" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() set window.bar to 10 throw \"foo\"finally set window.bar to 20 end") - (dom-append (dom-body) _el-script))) - (deftest - "finally blocks run when an exception expr occurs" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() set window.bar to 10 call throwsAsyncException()finally set window.bar to 20 end") - (dom-append (dom-body) _el-script))) - (deftest - "async finally blocks run normally" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() wait a tick then set window.bar to 10finally set window.bar to 20 end") - (dom-append (dom-body) _el-script))) - (deftest - "async finally blocks run when an exception occurs" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() wait a tick then set window.bar to 10 throw \"foo\"finally set window.bar to 20 end") - (dom-append (dom-body) _el-script))) - (deftest - "exit stops execution mid-function" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html - _el-script - "def foo() set x to 1 then exit then set x to 2 then return x end") - (dom-append (dom-body) _el-script))) - (deftest - "can return without a value" - (hs-cleanup!) - (let - ((_el-script (dom-create-element "script"))) - (dom-set-attr _el-script "type" "text/hyperscript") - (dom-set-inner-html _el-script "def foo() return end") - (dom-append (dom-body) _el-script)))) + (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"