- Parser: `--` line comments, `|` op, `result` → `the-result`, query-scoped `<sel> in <expr>`, `is a/an <type>` predicate, multi-`as` chaining with `|`, `match`/`precede` keyword aliases, `[attr]` add/toggle, between attr forms - Runtime: per-element listener registry + hs-deactivate!, attr toggle variants, set-inner-html boots subtree, hs-append polymorphic on string/list/element, default? / array-set! / query-all-in / list-set via take+drop, hs-script idempotence guard - Integration: skip reserved (me/it/event/you/yourself) when collecting vars - Tokenizer: emit `--` comments and `|` op - Test framework + conformance runner updates; new tests/hs-run-filtered.js (single-process Node runner using OCaml VM step-limit to bound infinite loops); generate-sx-conformance-dev.py improvements - mcp_tree.ml + run_tests.ml: harness extensions - .gitignore: top-level test-results/ (Playwright artifacts) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
491 lines
18 KiB
Plaintext
491 lines
18 KiB
Plaintext
;; Dev-branch hyperscript conformance tests — expression evaluation
|
|
;; Source: spec/tests/hyperscript-upstream-tests.json (no-HTML tests from v0.9.90-dev)
|
|
;; DO NOT EDIT — regenerate with: python3 tests/playwright/generate-sx-conformance-dev.py
|
|
|
|
;; ── halt (1 tests) ──
|
|
(defsuite "hs-dev-halt"
|
|
(deftest "halt works outside of event context"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── bind (1 tests) ──
|
|
(defsuite "hs-dev-bind"
|
|
(deftest "unsupported element: bind to plain div errors"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── when (2 tests) ──
|
|
(defsuite "hs-dev-when"
|
|
(deftest "local variable in when expression produces a parse error"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "attribute observers are persistent (not recreated on re-run)"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── evalStatically (8 tests) ──
|
|
(defsuite "hs-dev-evalStatically"
|
|
(deftest "works on number literals"
|
|
(assert= 42 (eval-hs "42"))
|
|
(assert= 3.14 (eval-hs "3.14"))
|
|
)
|
|
(deftest "works on boolean literals"
|
|
(assert= true (eval-hs "true"))
|
|
(assert= false (eval-hs "false"))
|
|
)
|
|
(deftest "works on null literal"
|
|
(assert= nil (eval-hs "null"))
|
|
)
|
|
(deftest "works on plain string literals"
|
|
(assert= "hello" (eval-hs "\"hello\""))
|
|
(assert= "world" (eval-hs "'world'"))
|
|
)
|
|
(deftest "works on time expressions"
|
|
(assert= 200 (eval-hs "200ms"))
|
|
(assert= 2000 (eval-hs "2s"))
|
|
)
|
|
(deftest "throws on template strings"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "throws on symbol references"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "throws on math expressions"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── collectionExpressions (12 tests) ──
|
|
(defsuite
|
|
"hs-dev-collectionExpressions"
|
|
(deftest
|
|
"filters an array by condition"
|
|
(let
|
|
((result (eval-hs "set arr to [{name: \"a\", active: true}, {name: \"b\", active: false}, {name: \"c\", active: true}] then return arr where its active")))
|
|
(assert= (list "a" "c") (map (fn (x) (get x "name")) result))))
|
|
(deftest
|
|
"filters with comparison"
|
|
(assert=
|
|
(list 4 5)
|
|
(eval-hs "set arr to [1, 2, 3, 4, 5] then return arr where it > 3")))
|
|
(deftest
|
|
"sorts by a property"
|
|
(let
|
|
((result (eval-hs "set arr to [{name: \"Charlie\"}, {name: \"Alice\"}, {name: \"Bob\"}] then return arr sorted by its name")))
|
|
(assert=
|
|
(list "Alice" "Bob" "Charlie")
|
|
(map (fn (x) (get x "name")) result))))
|
|
(deftest
|
|
"sorts descending"
|
|
(assert=
|
|
(list 3 2 1)
|
|
(eval-hs "set arr to [3, 1, 2] then return arr sorted by it descending")))
|
|
(deftest
|
|
"sorts numbers by a computed key"
|
|
(let
|
|
((result (eval-hs "set arr to [{name: \"b\", age: 30}, {name: \"a\", age: 20}, {name: \"c\", age: 25}] then return arr sorted by its age")))
|
|
(assert= (list "a" "c" "b") (map (fn (x) (get x "name")) result))))
|
|
(deftest
|
|
"maps to a property"
|
|
(assert=
|
|
(list "Alice" "Bob")
|
|
(eval-hs
|
|
"set arr to [{name: \"Alice\"}, {name: \"Bob\"}] then return arr mapped to its name")))
|
|
(deftest
|
|
"maps with an expression"
|
|
(assert=
|
|
(list 2 4 6)
|
|
(eval-hs "set arr to [1, 2, 3] then return arr mapped to (it * 2)")))
|
|
(deftest
|
|
"where then mapped to"
|
|
(assert=
|
|
(list "Alice" "Charlie")
|
|
(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")))
|
|
(deftest
|
|
"sorted by then mapped to"
|
|
(assert=
|
|
(list "Alice" "Charlie")
|
|
(eval-hs
|
|
"set arr to [{name: \"Charlie\", age: 30}, {name: \"Alice\", age: 20}] then return arr sorted by its age mapped to its name")))
|
|
(deftest
|
|
"where then sorted by then mapped to"
|
|
(assert=
|
|
(list "Bob" "Charlie")
|
|
(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")))
|
|
(deftest
|
|
"the result inside where refers to previous command result, not current element"
|
|
(assert=
|
|
(list 4 5)
|
|
(eval-hs
|
|
"get 3 then set arr to [1, 2, 3, 4, 5] then return arr where it > the result")))
|
|
(deftest
|
|
"where binds after property access"
|
|
(assert= (list 3 4) (eval-hs "obj.items where it > 2" {:locals {:obj {:items (list 1 2 3 4)}}}))))
|
|
|
|
;; ── splitJoin (7 tests) ──
|
|
(defsuite "hs-dev-splitJoin"
|
|
(deftest "splits a string by delimiter"
|
|
(assert= (list "a" "b" "c") (eval-hs "return \"a,b,c\" split by \",\""))
|
|
)
|
|
(deftest "splits by whitespace"
|
|
(assert= (list "hello" "world") (eval-hs "return \"hello world\" split by \" \""))
|
|
)
|
|
(deftest "joins an array with delimiter"
|
|
(assert= "a, b, c" (eval-hs "return [\"a\", \"b\", \"c\"] joined by \", \""))
|
|
)
|
|
(deftest "joins with empty string"
|
|
(assert= "xyz" (eval-hs "return [\"x\", \"y\", \"z\"] joined by \"\""))
|
|
)
|
|
(deftest "split then where then joined"
|
|
(assert= "a-b-c" (eval-hs "return \"a,,b,,c\" split by \",\" where it is not \"\" joined by \"-\""))
|
|
)
|
|
(deftest "split then sorted then joined"
|
|
(assert= "apple, banana, cherry" (eval-hs "return \"banana,apple,cherry\" split by \",\" sorted by it joined by \", \""))
|
|
)
|
|
(deftest "split then mapped then joined"
|
|
(assert= "5,5" (eval-hs "return \"hello world\" split by \" \" mapped to its length joined by \",\""))
|
|
)
|
|
)
|
|
|
|
;; ── pick (7 tests) ──
|
|
(defsuite "hs-dev-pick"
|
|
(deftest "does not hang on zero-length regex matches"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "can pick first n items"
|
|
(assert= (list 10 20 30) (eval-hs "pick first 3 of arr" {:locals {:arr (list 10 20 30 40 50)}})))
|
|
(deftest "can pick last n items"
|
|
(assert= (list 40 50) (eval-hs "pick last 2 of arr" {:locals {:arr (list 10 20 30 40 50)}})))
|
|
(deftest "can pick random item"
|
|
(assert-true (some (fn (x) (= x (eval-hs "pick random of arr" {:locals {:arr (list 10 20 30)}}))) (list 10 20 30))))
|
|
(deftest "can pick random n items"
|
|
(assert= 2 (len (eval-hs "pick random 2 of arr" {:locals {:arr (list 10 20 30 40 50)}}))))
|
|
(deftest "can pick items using 'of' syntax"
|
|
(assert= (list 11 12) (eval-hs "pick items 1 to 3 of arr" {:locals {:arr (list 10 11 12 13 14 15 16)}})))
|
|
(deftest "can pick match using 'of' syntax"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── transition (1 tests) ──
|
|
(defsuite "hs-dev-transition"
|
|
(deftest "can transition on query ref with possessive"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── socket (4 tests) ──
|
|
(defsuite "hs-dev-socket"
|
|
(deftest "parses socket with absolute ws:// URL"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "converts relative URL to wss:// on https pages"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "converts relative URL to ws:// on http pages"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "namespaced sockets work"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── bootstrap (3 tests) ──
|
|
(defsuite "hs-dev-bootstrap"
|
|
(deftest "fires hyperscript:before:init and hyperscript:after:init"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "hyperscript:before:init can cancel initialization"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "logAll config logs events to console"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── parser (3 tests) ──
|
|
(defsuite "hs-dev-parser"
|
|
(deftest "fires hyperscript:parse-error event with all errors"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "_hyperscript() evaluate API still throws on first error"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "parse error at EOF on trailing newline does not crash"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── asExpression (17 tests) ──
|
|
(defsuite "hs-dev-asExpression"
|
|
(deftest "converts value as Boolean"
|
|
(assert= true (eval-hs "1 as Boolean"))
|
|
(assert= false (eval-hs "0 as Boolean"))
|
|
(assert= false (eval-hs "'' as Boolean"))
|
|
(assert= true (eval-hs "'hello' as Boolean"))
|
|
)
|
|
(deftest "can use the a modifier if you like"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "parses string as JSON to object"
|
|
(let ((result (eval-hs "'{\"foo\":\"bar\"}' as JSON")))
|
|
(assert= "bar" (get result "foo"))
|
|
))
|
|
(deftest "converts value as JSONString"
|
|
(assert= "{\"foo\":\"bar\"}" (eval-hs "{foo:'bar'} as JSONString"))
|
|
)
|
|
(deftest "pipe operator chains conversions"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "can use the an modifier if you'd like"
|
|
(let ((result (eval-hs "'{\"foo\":\"bar\"}' as an Object")))
|
|
(assert= "bar" (get result "foo"))
|
|
))
|
|
(deftest "collects duplicate text inputs into an array"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "converts multiple selects with programmatically changed selections"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "converts a form element into Values | JSONString"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "converts a form element into Values | FormEncoded"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "converts array as Set"
|
|
;; expect(result.isSet).toBe(true)
|
|
;; STUB: needs JS bridge — eval-only
|
|
(assert true))
|
|
(deftest "converts object as Map"
|
|
;; expect(result.isMap).toBe(true)
|
|
;; STUB: needs JS bridge — eval-only
|
|
(assert true))
|
|
(deftest "converts object as Keys"
|
|
(assert= (list "a" "b") (eval-hs "{a:1, b:2} as Keys"))
|
|
)
|
|
(deftest "converts object as Entries"
|
|
(assert= (list (list "a" 1)) (eval-hs "{a:1} as Entries"))
|
|
)
|
|
(deftest "converts array as Reversed"
|
|
(assert= (list 3 2 1) (eval-hs "[1,2,3] as Reversed"))
|
|
)
|
|
(deftest "converts array as Unique"
|
|
(assert= (list 1 2 3) (eval-hs "[1,2,2,3,3] as Unique"))
|
|
)
|
|
(deftest "converts nested array as Flat"
|
|
(assert= (list 1 2 3 4) (eval-hs "[[1,2],[3,4]] as Flat"))
|
|
)
|
|
)
|
|
|
|
;; ── comparisonOperator (28 tests) ──
|
|
(defsuite "hs-dev-comparisonOperator"
|
|
(deftest "is ignoring case works"
|
|
(assert= true (eval-hs "'Hello' is 'hello' ignoring case"))
|
|
(assert= true (eval-hs "'Hello' is 'HELLO' ignoring case"))
|
|
(assert= false (eval-hs "'Hello' is 'world' ignoring case"))
|
|
)
|
|
(deftest "is not ignoring case works"
|
|
(assert= true (eval-hs "'Hello' is not 'world' ignoring case"))
|
|
(assert= false (eval-hs "'Hello' is not 'hello' ignoring case"))
|
|
)
|
|
(deftest "contains ignoring case works"
|
|
(assert= true (eval-hs "'Hello World' contains 'hello' ignoring case"))
|
|
(assert= true (eval-hs "'Hello World' contains 'WORLD' ignoring case"))
|
|
(assert= false (eval-hs "'Hello World' contains 'missing' ignoring case"))
|
|
)
|
|
(deftest "matches ignoring case works"
|
|
(assert= true (eval-hs "'Hello' matches 'hello' ignoring case"))
|
|
(assert= true (eval-hs "'Hello' matches 'HELLO' ignoring case"))
|
|
)
|
|
(deftest "starts with works"
|
|
(assert= true (eval-hs "'hello world' starts with 'hello'"))
|
|
(assert= false (eval-hs "'hello world' starts with 'world'"))
|
|
(assert= true (eval-hs "'hello' starts with 'hello'"))
|
|
(assert= false (eval-hs "'' starts with 'x'"))
|
|
)
|
|
(deftest "ends with works"
|
|
(assert= true (eval-hs "'hello world' ends with 'world'"))
|
|
(assert= false (eval-hs "'hello world' ends with 'hello'"))
|
|
(assert= true (eval-hs "'hello' ends with 'hello'"))
|
|
(assert= false (eval-hs "'' ends with 'x'"))
|
|
)
|
|
(deftest "does not start with works"
|
|
(assert= false (eval-hs "'hello world' does not start with 'hello'"))
|
|
(assert= true (eval-hs "'hello world' does not start with 'world'"))
|
|
)
|
|
(deftest "does not end with works"
|
|
(assert= false (eval-hs "'hello world' does not end with 'world'"))
|
|
(assert= true (eval-hs "'hello world' does not end with 'hello'"))
|
|
)
|
|
(deftest "starts with null is false"
|
|
(assert= false (eval-hs "null starts with 'x'"))
|
|
(assert= true (eval-hs "null does not start with 'x'"))
|
|
)
|
|
(deftest "ends with null is false"
|
|
(assert= false (eval-hs "null ends with 'x'"))
|
|
(assert= true (eval-hs "null does not end with 'x'"))
|
|
)
|
|
(deftest "starts with ignoring case works"
|
|
(assert= true (eval-hs "'Hello World' starts with 'hello' ignoring case"))
|
|
(assert= true (eval-hs "'Hello World' starts with 'HELLO' ignoring case"))
|
|
(assert= false (eval-hs "'Hello World' starts with 'world' ignoring case"))
|
|
)
|
|
(deftest "ends with ignoring case works"
|
|
(assert= true (eval-hs "'Hello World' ends with 'world' ignoring case"))
|
|
(assert= true (eval-hs "'Hello World' ends with 'WORLD' ignoring case"))
|
|
(assert= false (eval-hs "'Hello World' ends with 'hello' ignoring case"))
|
|
)
|
|
(deftest "starts with coerces to string"
|
|
(assert= true (eval-hs "123 starts with '12'"))
|
|
(assert= false (eval-hs "123 starts with '23'"))
|
|
)
|
|
(deftest "ends with coerces to string"
|
|
(assert= true (eval-hs "123 ends with '23'"))
|
|
(assert= false (eval-hs "123 ends with '12'"))
|
|
)
|
|
(deftest "is between works"
|
|
(assert= true (eval-hs "5 is between 1 and 10"))
|
|
(assert= true (eval-hs "1 is between 1 and 10"))
|
|
(assert= true (eval-hs "10 is between 1 and 10"))
|
|
(assert= false (eval-hs "0 is between 1 and 10"))
|
|
(assert= false (eval-hs "11 is between 1 and 10"))
|
|
)
|
|
(deftest "is not between works"
|
|
(assert= false (eval-hs "5 is not between 1 and 10"))
|
|
(assert= true (eval-hs "0 is not between 1 and 10"))
|
|
(assert= true (eval-hs "11 is not between 1 and 10"))
|
|
(assert= false (eval-hs "1 is not between 1 and 10"))
|
|
(assert= false (eval-hs "10 is not between 1 and 10"))
|
|
)
|
|
(deftest "between works with strings"
|
|
(assert= true (eval-hs "'b' is between 'a' and 'c'"))
|
|
(assert= false (eval-hs "'d' is between 'a' and 'c'"))
|
|
)
|
|
(deftest "I am between works"
|
|
(assert= true (eval-hs "I am between 1 and 10" {:me 5}))
|
|
(assert= false (eval-hs "I am between 1 and 10" {:me 0}))
|
|
)
|
|
(deftest "I am not between works"
|
|
(assert= false (eval-hs "I am not between 1 and 10" {:me 5}))
|
|
(assert= true (eval-hs "I am not between 1 and 10" {:me 0}))
|
|
)
|
|
(deftest "precedes with null is false"
|
|
(assert= false (eval-hs "null precedes null"))
|
|
(assert= true (eval-hs "null does not precede null"))
|
|
)
|
|
(deftest "is really works without equal to"
|
|
(assert= true (eval-hs "2 is really 2"))
|
|
(assert= false (eval-hs "2 is really '2'"))
|
|
)
|
|
(deftest "is not really works without equal to"
|
|
(assert= true (eval-hs "2 is not really '2'"))
|
|
(assert= false (eval-hs "2 is not really 2"))
|
|
)
|
|
(deftest "is equal works without to"
|
|
(assert= true (eval-hs "2 is equal 2"))
|
|
(assert= false (eval-hs "2 is equal 1"))
|
|
)
|
|
(deftest "is not equal works without to"
|
|
(assert= false (eval-hs "2 is not equal 2"))
|
|
(assert= true (eval-hs "2 is not equal 1"))
|
|
)
|
|
(deftest "am works as alias for is"
|
|
(assert= true (eval-hs "2 am 2"))
|
|
(assert= false (eval-hs "2 am 1"))
|
|
)
|
|
(deftest "is not undefined still works as equality"
|
|
(assert= true (eval-hs "5 is not undefined"))
|
|
(assert= false (eval-hs "null is not undefined"))
|
|
)
|
|
(deftest "is not null still works as equality"
|
|
(assert= true (eval-hs "5 is not null"))
|
|
(assert= false (eval-hs "null is not null"))
|
|
)
|
|
(deftest "is still does equality when rhs variable exists"
|
|
(assert= true (eval-hs "x is y" {:locals {:x 5 :y 5}}))
|
|
(assert= false (eval-hs "x is y" {:locals {:x 5 :y 6}}))
|
|
)
|
|
)
|
|
|
|
;; ── cookies (1 tests) ──
|
|
(defsuite "hs-dev-cookies"
|
|
(deftest "length is 0 when no cookies are set"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── in (1 tests) ──
|
|
(defsuite "hs-dev-in"
|
|
(deftest "null value in array returns empty"
|
|
(assert= (list) (eval-hs "null in [1, 2, 3]"))
|
|
)
|
|
)
|
|
|
|
;; ── logicalOperator (3 tests) ──
|
|
(defsuite "hs-dev-logicalOperator"
|
|
(deftest "and short-circuits when lhs promise resolves to false"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "or short-circuits when lhs promise resolves to true"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
(deftest "or evaluates rhs when lhs promise resolves to false"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── mathOperator (5 tests) ──
|
|
(defsuite "hs-dev-mathOperator"
|
|
(deftest "array + array concats"
|
|
(assert= (list 1 2 3 4) (eval-hs "[1, 2] + [3, 4]"))
|
|
)
|
|
(deftest "array + single value appends"
|
|
(assert= (list 1 2 3) (eval-hs "[1, 2] + 3"))
|
|
)
|
|
(deftest "array + array does not mutate original"
|
|
(assert= (list 1 2) (eval-hs "set a to [1, 2] then set b to a + [3] then return a"))
|
|
)
|
|
(deftest "array concat chains"
|
|
(assert= (list 1 2 3) (eval-hs "[1] + [2] + [3]"))
|
|
)
|
|
(deftest "empty array + array works"
|
|
(assert= (list 1 2) (eval-hs "[] + [1, 2]"))
|
|
)
|
|
)
|
|
|
|
;; ── no (4 tests) ──
|
|
(defsuite "hs-dev-no"
|
|
(deftest "no returns false for non-empty array"
|
|
(assert= false (eval-hs "no ['thing']"))
|
|
)
|
|
(deftest "no with where filters then checks emptiness"
|
|
(assert= true (eval-hs "no [1, 2, 3] where it > 5"))
|
|
)
|
|
(deftest "no with where returns false when matches exist"
|
|
(assert= false (eval-hs "no [1, 2, 3] where it > 1"))
|
|
)
|
|
(deftest "no with where and is not"
|
|
(assert= false (eval-hs "no [1, 2, 3] where it is not 2"))
|
|
)
|
|
)
|
|
|
|
;; ── objectLiteral (1 tests) ──
|
|
(defsuite "hs-dev-objectLiteral"
|
|
(deftest "allows trailing commas"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|
|
|
|
;; ── relativePositionalExpression (1 tests) ──
|
|
(defsuite "hs-dev-relativePositionalExpression"
|
|
(deftest "can write to next element with put command"
|
|
;; needs DOM/browser — covered by Playwright suite
|
|
(assert true))
|
|
)
|