diff --git a/spec/tests/test-hyperscript-behavioral.sx b/spec/tests/test-hyperscript-behavioral.sx index 9847409b..6833966d 100644 --- a/spec/tests/test-hyperscript-behavioral.sx +++ b/spec/tests/test-hyperscript-behavioral.sx @@ -27,8 +27,10 @@ ;; bare expressions (e.g. `foo.foo`) get the expression value back. (define _hs-wrap-body (fn (sx) + ;; Wrap body to capture return via `it`. `event` default is always nil. + ;; `it` is NOT shadowed here — callers (eval-hs-locals) may pre-bind it. (list (quote let) - (list (list (quote it) nil) (list (quote event) nil)) + (list (list (quote event) nil)) (list (quote let) (list (list (quote _ret) sx)) (list (quote if) (list (quote nil?) (quote _ret)) (quote it) (quote _ret)))))) @@ -5679,7 +5681,7 @@ (dom-append (dom-body) _el-pDiv) )) (deftest "can access its properties" - (assert= (eval-hs "its foo") "foo") + (assert= (eval-hs-locals "its foo" (list (list (quote it) {:foo "foo"}))) "foo") ) (deftest "can access multiple basic attributes" (hs-cleanup!) diff --git a/tests/playwright/generate-sx-tests.py b/tests/playwright/generate-sx-tests.py index 072b7676..399d0bc9 100644 --- a/tests/playwright/generate-sx-tests.py +++ b/tests/playwright/generate-sx-tests.py @@ -1760,6 +1760,14 @@ def generate_eval_only_test(test, idx): extra.append((m2.group(1), js_val_to_sx(m2.group(2).strip()))) if me_val_match: extra.append(('me', js_val_to_sx(me_val_match.group(1)))) + # `result: X` (or `it: X`) binds `it` — upstream `run("expr", { result: ... })` + # uses the value as the implicit `it` for possessive expressions like `its foo`. + result_match = re.search( + r'\b(?:result|it):\s*(\[[^\]]*\]|\{[^}]*(?:\{[^}]*\}[^}]*)?\}|"[^"]*"|\'[^\']*\'|[\w.]+)', + opts_str, + ) + if result_match: + extra.append(('it', js_val_to_sx(result_match.group(1)))) if me_num_match and not (window_setups or extra): assertions.append(f' (assert= (eval-hs-with-me "{hs_expr}" {me_num_match.group(1)}) {expected_sx})') else: @@ -1917,6 +1925,13 @@ def generate_eval_only_test(test, idx): args_str) if me_m: pairs.append(('me', js_val_to_sx(me_m.group(1)))) + # `result: ` binds `it` — upstream `run("its X", {result: obj})` + # passes `obj` as the implicit `it` for possessive expressions. + result_m = re.search( + r'\bresult:\s*(\{[^}]*(?:\{[^}]*\}[^}]*)?\}|\[[^\]]*\]|"[^"]*"|\'[^\']*\'|\d+(?:\.\d+)?)', + args_str) + if result_m: + pairs.append(('it', js_val_to_sx(result_m.group(1)))) lm = re.search(r'locals:\s*\{', args_str) if not lm: return pairs @@ -2453,8 +2468,10 @@ output.append(';; mutate `it` (e.g. `pick first 3 of arr; set $test to it`) get output.append(';; bare expressions (e.g. `foo.foo`) get the expression value back.') output.append('(define _hs-wrap-body') output.append(' (fn (sx)') +output.append(' ;; Wrap body to capture return via `it`. `event` default is always nil.') +output.append(' ;; `it` is NOT shadowed here — callers (eval-hs-locals) may pre-bind it.') output.append(' (list (quote let)') -output.append(' (list (list (quote it) nil) (list (quote event) nil))') +output.append(' (list (list (quote event) nil))') output.append(' (list (quote let)') output.append(' (list (list (quote _ret) sx))') output.append(' (list (quote if) (list (quote nil?) (quote _ret)) (quote it) (quote _ret))))))')