Files
rose-ash/shared/sx/tests/test_bootstrapper.py
giles 3749fe9625
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m51s
Fix bootstrapper dict literal transpilation: emit values through emit()
The SX parser produces native Python dicts for {:key val} syntax, but
both JSEmitter and PyEmitter had no dict case in emit() — falling through
to str(expr) which output raw AST. This broke client-side routing because
process-page-scripts used {"parsed" (parse-route-pattern ...)} and the
function call was emitted as a JS array of Symbols instead of an actual
function call.

Add _emit_native_dict() to both bootstrappers + 8 unit tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 16:24:44 +00:00

64 lines
2.1 KiB
Python

"""Test bootstrapper transpilation: JSEmitter and PyEmitter."""
from __future__ import annotations
import pytest
from shared.sx.parser import parse
from shared.sx.ref.bootstrap_js import JSEmitter
from shared.sx.ref.bootstrap_py import PyEmitter
class TestJSEmitterNativeDict:
"""JS bootstrapper must handle native Python dicts from {:key val} syntax."""
def test_simple_string_values(self):
expr = parse('{"name" "hello"}')
assert isinstance(expr, dict)
js = JSEmitter().emit(expr)
assert js == '{"name": "hello"}'
def test_function_call_value(self):
"""Dict value containing a function call must emit the call, not raw AST."""
expr = parse('{"parsed" (parse-route-pattern (get page "path"))}')
js = JSEmitter().emit(expr)
assert "parseRoutePattern" in js
assert "Symbol" not in js
assert js == '{"parsed": parseRoutePattern(get(page, "path"))}'
def test_multiple_keys(self):
expr = parse('{"a" 1 "b" (+ x 2)}')
js = JSEmitter().emit(expr)
assert '"a": 1' in js
assert '"b": (x + 2)' in js
def test_nested_dict(self):
expr = parse('{"outer" {"inner" 42}}')
js = JSEmitter().emit(expr)
assert '{"outer": {"inner": 42}}' == js
def test_nil_value(self):
expr = parse('{"key" nil}')
js = JSEmitter().emit(expr)
assert '"key": NIL' in js
class TestPyEmitterNativeDict:
"""Python bootstrapper must handle native Python dicts from {:key val} syntax."""
def test_simple_string_values(self):
expr = parse('{"name" "hello"}')
py = PyEmitter().emit(expr)
assert py == "{'name': 'hello'}"
def test_function_call_value(self):
"""Dict value containing a function call must emit the call, not raw AST."""
expr = parse('{"parsed" (parse-route-pattern (get page "path"))}')
py = PyEmitter().emit(expr)
assert "parse_route_pattern" in py
assert "Symbol" not in py
def test_multiple_keys(self):
expr = parse('{"a" 1 "b" (+ x 2)}')
py = PyEmitter().emit(expr)
assert "'a': 1" in py
assert "'b': (x + 2)" in py