HS: null-safety piece 1 — eval-hs-error recognizer + helper (+18 tests unlocked)

Add recognizer for expect(await error("HS")).toBe("MSG") pattern in
generate-sx-tests.py, plus eval-hs-error SX helper in the generated
test file. All 18 runtimeErrors tests now generate real test cases
instead of SKIP stubs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 12:10:19 +00:00
parent fb72c4ab9c
commit 3316d402fd
2 changed files with 113 additions and 18 deletions

View File

@@ -2333,6 +2333,25 @@ def generate_eval_only_test(test, idx):
hs_expr = extract_hs_expr(m.group(2))
assertions.append(f' (assert-throws (eval-hs "{hs_expr}"))')
# Pattern 4: eval-hs-error — expect(await error("expr")).toBe("msg")
# These test that running HS raises an error with a specific message string.
for m in re.finditer(
r'(?:const\s+\w+\s*=\s*)?(?:await\s+)?error\((["\x27`])(.+?)\1\)'
r'(?:[^;]|\n)*?(?:expect\([^)]*\)\.toBe\(([^)]+)\)|\.toBe\(([^)]+)\))',
body, re.DOTALL
):
hs_expr = extract_hs_expr(m.group(2))
expected_raw = (m.group(3) or m.group(4) or '').strip()
# Strip only the outermost JS string delimiter (double or single quote)
# without touching inner quotes inside the string value.
if len(expected_raw) >= 2 and expected_raw[0] == expected_raw[-1] and expected_raw[0] in ('"', "'"):
inner = expected_raw[1:-1]
expected_sx = '"' + inner.replace('\\', '\\\\').replace('"', '\\"') + '"'
else:
expected_sx = js_val_to_sx(expected_raw)
hs_escaped = hs_expr.replace('\\', '\\\\').replace('"', '\\"')
assertions.append(f' (assert= (eval-hs-error "{hs_escaped}") {expected_sx})')
if not assertions:
return None # Can't convert this body pattern
@@ -2692,6 +2711,27 @@ output.append(' (nth _e 1)')
output.append(' (raise _e))))')
output.append(' (handler me-val))))))')
output.append('')
output.append(';; Evaluate a hyperscript expression, catch the first error raised, and')
output.append(';; return its message string. Used by runtimeErrors tests.')
output.append(';; Returns nil if no error is raised (test would then fail equality).')
output.append('(define eval-hs-error')
output.append(' (fn (src)')
output.append(' (let ((sx (hs-to-sx (hs-compile src))))')
output.append(' (let ((handler (eval-expr-cek')
output.append(' (list (quote fn) (list (quote me))')
output.append(' (list (quote let) (list (list (quote it) nil) (list (quote event) nil)) sx)))))')
output.append(' (guard')
output.append(' (_e')
output.append(' (true')
output.append(' (if')
output.append(' (string? _e)')
output.append(' _e')
output.append(' (if')
output.append(' (and (list? _e) (= (first _e) "hs-return"))')
output.append(' nil')
output.append(' (str _e)))))')
output.append(' (begin (handler nil) nil))))))')
output.append('')
# Group by category
categories = OrderedDict()