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)"
|
echo "[SKIP] OCaml tests — binary not built (run: cd hosts/ocaml && dune build)"
|
||||||
fi
|
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)
|
# 5. Playwright tests (browser)
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user