Add OCaml bridge integration test for custom special forms
Tests that all 8 web definition forms (defhandler, defquery, defaction, defpage, defrelation, defstyle, deftype, defeffect) are registered and callable via the OCaml kernel. Catches the evaluator.sx env-shadowing bug where loading evaluator.sx creates a new *custom-special-forms* dict that shadows the native one. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
52
run-tests.sh
52
run-tests.sh
@@ -65,6 +65,58 @@ else
|
||||
echo "[SKIP] OCaml tests — binary not built (run: cd hosts/ocaml && dune build)"
|
||||
fi
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# 4. OCaml bridge integration (custom special forms, web-forms.sx)
|
||||
# -------------------------------------------------------------------
|
||||
run_suite "OCaml bridge — custom special forms + web-forms" \
|
||||
python3 -c "
|
||||
from shared.sx.ocaml_sync import OcamlSync
|
||||
bridge = OcamlSync()
|
||||
# Load exactly what the server does (no evaluator.sx!)
|
||||
for f in ['spec/parser.sx', 'spec/render.sx', 'web/adapter-html.sx', 'web/adapter-sx.sx', 'web/web-forms.sx', 'spec/freeze.sx']:
|
||||
bridge.load(f)
|
||||
ok = 0; fail = 0
|
||||
def check(name, expr, expected=None):
|
||||
global ok, fail
|
||||
try:
|
||||
r = bridge.eval(expr)
|
||||
if expected is not None and r != expected:
|
||||
print(f' FAIL: {name}: expected {expected!r}, got {r!r}'); fail += 1
|
||||
else:
|
||||
print(f' PASS: {name}'); ok += 1
|
||||
except Exception as e:
|
||||
print(f' FAIL: {name}: {e}'); fail += 1
|
||||
|
||||
# Custom special forms registered by web-forms.sx
|
||||
for form in ['defhandler', 'defquery', 'defaction', 'defpage', 'defrelation', 'defstyle', 'deftype', 'defeffect']:
|
||||
check(f'{form} registered', f'(has-key? *custom-special-forms* \"{form}\")', 'true')
|
||||
|
||||
# Custom forms callable via eval (not just via load)
|
||||
check('deftype via eval', '(deftype test-t number)', 'nil')
|
||||
check('defeffect via eval', '(defeffect test-e)', 'nil')
|
||||
check('defstyle via eval', '(defstyle my-s \"bold\")', 'bold')
|
||||
check('defhandler via eval', '(has-key? (defhandler test-h (&key x) x) \"__type\")', 'true')
|
||||
|
||||
# Extension lists populated
|
||||
check('definition-form-extensions populated', '(> (len *definition-form-extensions*) 0)', 'true')
|
||||
check('RENDER_HTML_FORMS has defstyle', '(contains? RENDER_HTML_FORMS \"defstyle\")', 'true')
|
||||
|
||||
print(f'\\nResults: {ok} passed, {fail} failed')
|
||||
import sys; sys.exit(1 if fail > 0 else 0)
|
||||
"
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# 5. Python SX tests (post-removal regression, components, parser)
|
||||
# -------------------------------------------------------------------
|
||||
run_suite "Python — post-removal regression" \
|
||||
python3 -m pytest shared/sx/tests/test_post_removal_bugs.py -v --tb=short
|
||||
|
||||
run_suite "Python — component rendering" \
|
||||
python3 -m pytest shared/sx/tests/test_components.py -v --tb=short
|
||||
|
||||
run_suite "Python — parser" \
|
||||
python3 -m pytest shared/sx/tests/test_parser.py -v --tb=short
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# 5. Playwright tests (browser)
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user