HS test generator: fix toHaveCSS, locals, and \"-escapes — +28 tests
Generator changes (tests/playwright/generate-sx-tests.py):
- toHaveCSS regex: balance parens so `'rgb(255, 0, 0)'` is captured intact
(was truncating at first `)`)
- Map browser-computed colors `rgb(R,G,B)` back to CSS keywords
(red/green/blue/black/white) — our DOM mock returns the inline value
- js_val_to_sx now handles object literals `{a: 1, b: {c: 2}}` → `{:a 1 :b {:c 2}}`
- Pattern 2 (`var x = await run(...)`) now captures locals via balanced-brace
scan and emits `eval-hs-locals` instead of `eval-hs`
- Pattern 1 with locals: emit `eval-hs-locals` (was wrapping in `let`, which
doesn't reach the inner HS env)
- Stop collapsing `\"` → `"` in raw HTML (line 218): the backslash escapes
are legitimate in single-quoted `_='...'` HS attribute values containing
nested HS scripts
Test-framework changes (regenerated into spec/tests/test-hyperscript-behavioral.sx):
- `_hs-wrap-body`: returns expression value if non-nil, else `it`. Lets bare
expressions (`foo.foo`) and `it`-mutating scripts (`pick first 3 of arr;
set $test to it`) both round-trip through the same wrapper
- `eval-hs-locals` now injects locals via `(let ((name (quote val)) ...) sx)`
rather than `apply handler (cons nil vals)` — works around a JIT loop on
some compiled forms (e.g. `bar.doh of foo` with undefined `bar`)
Also synced lib/hyperscript/*.sx → shared/static/wasm/sx/hs-*.sx (the WASM
test runner reads from the wasm/sx/ copies).
Net per-cluster pass counts (vs prior baseline):
- put: 23 → 29 (+6)
- set: 21 → 28 (+7)
- show: 7 → 15 (+8)
- expressions/propertyAccess: 3 → 9 (+6)
- expressions/possessiveExpression: 17 → 18 (+1)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -550,6 +550,14 @@
|
||||
(quote and)
|
||||
(list (quote >=) left lo)
|
||||
(list (quote <=) left hi))))))
|
||||
((or (and (or (= (tp-val) "a") (= (tp-val) "an")) (do (adv!) true)))
|
||||
(let
|
||||
((type-name (tp-val)))
|
||||
(do
|
||||
(adv!)
|
||||
(list
|
||||
(quote not)
|
||||
(list (quote type-check) left type-name)))))
|
||||
(true
|
||||
(let
|
||||
((right (parse-expr)))
|
||||
@@ -566,6 +574,10 @@
|
||||
(quote and)
|
||||
(list (quote >=) left lo)
|
||||
(list (quote <=) left hi)))))
|
||||
((or (and (or (= (tp-val) "a") (= (tp-val) "an")) (do (adv!) true)))
|
||||
(let
|
||||
((type-name (tp-val)))
|
||||
(do (adv!) (list (quote type-check) left type-name))))
|
||||
(true
|
||||
(let
|
||||
((right (parse-expr)))
|
||||
@@ -596,7 +608,7 @@
|
||||
(match-kw "case")
|
||||
(list (quote ends-with-ic?) left rhs))
|
||||
(list (quote ends-with?) left rhs)))))
|
||||
((and (= typ "keyword") (= val "matches"))
|
||||
((and (= typ "keyword") (or (= val "matches") (= val "match")))
|
||||
(do
|
||||
(adv!)
|
||||
(let
|
||||
@@ -638,7 +650,22 @@
|
||||
(quote as)
|
||||
left
|
||||
(str type-name ":" param)))))
|
||||
(list (quote as) left type-name))))))
|
||||
(let
|
||||
loop
|
||||
((result (list (quote as) left type-name)))
|
||||
(if
|
||||
(and (= (tp-type) "op") (= (tp-val) "|"))
|
||||
(do
|
||||
(adv!)
|
||||
(when
|
||||
(or (= (tp-val) "a") (= (tp-val) "an"))
|
||||
(adv!))
|
||||
(let
|
||||
((next-type (tp-val)))
|
||||
(do
|
||||
(adv!)
|
||||
(loop (list (quote as) result next-type)))))
|
||||
result)))))))
|
||||
((and (= typ "colon"))
|
||||
(do
|
||||
(adv!)
|
||||
@@ -713,7 +740,7 @@
|
||||
(list (quote strict-eq) left (parse-expr))))
|
||||
((and (= typ "keyword") (or (= val "contain") (= val "include") (= val "includes")))
|
||||
(do (adv!) (list (quote contains?) left (parse-expr))))
|
||||
((and (= typ "keyword") (= val "precedes"))
|
||||
((and (= typ "keyword") (or (= val "precedes") (= val "precede")))
|
||||
(do (adv!) (list (quote precedes?) left (parse-atom))))
|
||||
((and (= typ "keyword") (= val "follows"))
|
||||
(do (adv!) (list (quote follows?) left (parse-atom))))
|
||||
@@ -792,7 +819,7 @@
|
||||
(= (tp-val) "starts")
|
||||
(= (tp-val) "ends")
|
||||
(= (tp-val) "contains")
|
||||
(= (tp-val) "matches")
|
||||
(or (= (tp-val) "matches") (= (tp-val) "match"))
|
||||
(= (tp-val) "is")
|
||||
(= (tp-val) "does")
|
||||
(= (tp-val) "in")
|
||||
@@ -1082,38 +1109,67 @@
|
||||
(match-kw "between")
|
||||
(let
|
||||
((val1 (parse-atom)))
|
||||
(expect-kw! "and")
|
||||
(let
|
||||
((val2 (parse-atom)))
|
||||
(do
|
||||
(when (= (tp-type) "comma") (adv!))
|
||||
(if
|
||||
(match-kw "and")
|
||||
(let
|
||||
((val3 (parse-atom)))
|
||||
(if
|
||||
(match-kw "and")
|
||||
(and (= (tp-type) "keyword") (= (tp-val) "and"))
|
||||
(adv!)
|
||||
nil)
|
||||
(let
|
||||
((val2 (parse-atom)))
|
||||
(if
|
||||
(or
|
||||
(= (tp-type) "comma")
|
||||
(and
|
||||
(= (tp-type) "keyword")
|
||||
(= (tp-val) "and")))
|
||||
(do
|
||||
(when (= (tp-type) "comma") (adv!))
|
||||
(if
|
||||
(and
|
||||
(= (tp-type) "keyword")
|
||||
(= (tp-val) "and"))
|
||||
(adv!)
|
||||
nil)
|
||||
(let
|
||||
((val4 (parse-atom)))
|
||||
(list
|
||||
(quote toggle-style-cycle)
|
||||
prop
|
||||
tgt
|
||||
val1
|
||||
val2
|
||||
val3
|
||||
val4))
|
||||
(list
|
||||
(quote toggle-style-cycle)
|
||||
prop
|
||||
tgt
|
||||
val1
|
||||
val2
|
||||
val3)))
|
||||
(list
|
||||
(quote toggle-style-between)
|
||||
prop
|
||||
val1
|
||||
val2
|
||||
tgt))))
|
||||
((val3 (parse-atom)))
|
||||
(if
|
||||
(or
|
||||
(= (tp-type) "comma")
|
||||
(and
|
||||
(= (tp-type) "keyword")
|
||||
(= (tp-val) "and")))
|
||||
(do
|
||||
(when (= (tp-type) "comma") (adv!))
|
||||
(if
|
||||
(and
|
||||
(= (tp-type) "keyword")
|
||||
(= (tp-val) "and"))
|
||||
(adv!)
|
||||
nil)
|
||||
(let
|
||||
((val4 (parse-atom)))
|
||||
(list
|
||||
(quote toggle-style-cycle)
|
||||
prop
|
||||
tgt
|
||||
val1
|
||||
val2
|
||||
val3
|
||||
val4)))
|
||||
(list
|
||||
(quote toggle-style-cycle)
|
||||
prop
|
||||
tgt
|
||||
val1
|
||||
val2
|
||||
val3))))
|
||||
(list
|
||||
(quote toggle-style-between)
|
||||
prop
|
||||
val1
|
||||
val2
|
||||
tgt)))))
|
||||
(list (quote toggle-style) prop tgt)))))
|
||||
((= (tp-type) "attr")
|
||||
(let
|
||||
@@ -1422,7 +1478,7 @@
|
||||
(let
|
||||
((tgt (cond ((at-end?) (list (quote me))) ((and (= (tp-type) "keyword") (or (= (tp-val) "then") (= (tp-val) "end") (= (tp-val) "with") (= (tp-val) "when") (= (tp-val) "add") (= (tp-val) "remove") (= (tp-val) "set") (= (tp-val) "put") (= (tp-val) "toggle") (= (tp-val) "hide") (= (tp-val) "show"))) (list (quote me))) (true (parse-expr)))))
|
||||
(let
|
||||
((strategy (if (match-kw "with") (if (at-end?) "display" (let ((s (tp-val))) (adv!) s)) "display")))
|
||||
((strategy (if (match-kw "with") (if (at-end?) "display" (let ((s (tp-val))) (do (adv!) (cond ((at-end?) s) ((= (tp-type) "colon") (do (adv!) (let ((v (tp-val))) (do (adv!) (str s ":" v))))) ((= (tp-type) "local") (let ((v (tp-val))) (do (adv!) (str s ":" v)))) (true s))))) "display")))
|
||||
(let
|
||||
((when-cond (if (and (= (tp-type) "keyword") (= (tp-val) "when")) (do (adv!) (parse-expr)) nil)))
|
||||
(list (quote hide) tgt strategy when-cond))))))
|
||||
@@ -1433,7 +1489,7 @@
|
||||
(let
|
||||
((tgt (cond ((at-end?) (list (quote me))) ((and (= (tp-type) "keyword") (or (= (tp-val) "then") (= (tp-val) "end") (= (tp-val) "with") (= (tp-val) "when") (= (tp-val) "add") (= (tp-val) "remove") (= (tp-val) "set") (= (tp-val) "put") (= (tp-val) "toggle") (= (tp-val) "hide") (= (tp-val) "show"))) (list (quote me))) (true (parse-expr)))))
|
||||
(let
|
||||
((strategy (if (match-kw "with") (if (at-end?) "display" (let ((s (tp-val))) (adv!) s)) "display")))
|
||||
((strategy (if (match-kw "with") (if (at-end?) "display" (let ((s (tp-val))) (do (adv!) (cond ((at-end?) s) ((= (tp-type) "colon") (do (adv!) (let ((v (tp-val))) (do (adv!) (str s ":" v))))) ((= (tp-type) "local") (let ((v (tp-val))) (do (adv!) (str s ":" v)))) (true s))))) "display")))
|
||||
(let
|
||||
((when-cond (if (and (= (tp-type) "keyword") (= (tp-val) "when")) (do (adv!) (parse-expr)) nil)))
|
||||
(list (quote show) tgt strategy when-cond))))))
|
||||
@@ -1648,7 +1704,9 @@
|
||||
(let
|
||||
((n (parse-atom)))
|
||||
(do
|
||||
(expect-kw! "of")
|
||||
(if
|
||||
(not (or (match-kw "of") (match-kw "from")))
|
||||
(error (str "Expected 'of' or 'from' at position " p)))
|
||||
(let
|
||||
((coll (parse-expr)))
|
||||
(list (quote pick-first) coll n))))))
|
||||
@@ -1658,7 +1716,9 @@
|
||||
(let
|
||||
((n (parse-atom)))
|
||||
(do
|
||||
(expect-kw! "of")
|
||||
(if
|
||||
(not (or (match-kw "of") (match-kw "from")))
|
||||
(error (str "Expected 'of' or 'from' at position " p)))
|
||||
(let
|
||||
((coll (parse-expr)))
|
||||
(list (quote pick-last) coll n))))))
|
||||
@@ -1666,14 +1726,17 @@
|
||||
(do
|
||||
(adv!)
|
||||
(if
|
||||
(match-kw "of")
|
||||
(or (match-kw "of") (match-kw "from"))
|
||||
(let
|
||||
((coll (parse-expr)))
|
||||
(list (quote pick-random) coll nil))
|
||||
(let
|
||||
((n (parse-atom)))
|
||||
(do
|
||||
(expect-kw! "of")
|
||||
(if
|
||||
(not (or (match-kw "of") (match-kw "from")))
|
||||
(error
|
||||
(str "Expected 'of' or 'from' at position " p)))
|
||||
(let
|
||||
((coll (parse-expr)))
|
||||
(list (quote pick-random) coll n)))))))
|
||||
@@ -1687,7 +1750,10 @@
|
||||
(let
|
||||
((end-expr (parse-atom)))
|
||||
(do
|
||||
(expect-kw! "of")
|
||||
(if
|
||||
(not (or (match-kw "of") (match-kw "from")))
|
||||
(error
|
||||
(str "Expected 'of' or 'from' at position " p)))
|
||||
(let
|
||||
((coll (parse-expr)))
|
||||
(list (quote pick-items) coll start-expr end-expr))))))))
|
||||
@@ -1727,10 +1793,26 @@
|
||||
(let
|
||||
((haystack (parse-expr)))
|
||||
(list (quote pick-matches) regex haystack))))))
|
||||
((and (= typ "ident") (= val "item"))
|
||||
(do
|
||||
(adv!)
|
||||
(let
|
||||
((n (parse-expr)))
|
||||
(do
|
||||
(if
|
||||
(not (or (match-kw "of") (match-kw "from")))
|
||||
(error (str "Expected 'of' or 'from' at position " p)))
|
||||
(let
|
||||
((coll (parse-expr)))
|
||||
(list
|
||||
(quote pick-items)
|
||||
coll
|
||||
n
|
||||
(list (quote +) n 1)))))))
|
||||
(true
|
||||
(error
|
||||
(str
|
||||
"Expected first/last/random/items/match/matches after 'pick' at "
|
||||
"Expected first/last/random/item/items/match/matches after 'pick' at "
|
||||
p)))))))
|
||||
(define
|
||||
parse-go-cmd
|
||||
|
||||
Reference in New Issue
Block a user