From 145028ccc0496728854b56f9cee8287fba654b67 Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 8 Mar 2026 02:04:42 +0000 Subject: [PATCH] Declare Phase 7c+7d page helpers in boundary.sx and register orchestration tests in app runner Adds optimistic-demo-data, action:add-demo-item, offline-demo-data to boundary spec. Adds orchestration test spec to in-app test runner with mocked platform functions. Co-Authored-By: Claude Opus 4.6 --- sx/sx/boundary.sx | 15 ++++++++++++++ sx/sxc/pages/helpers.py | 45 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/sx/sx/boundary.sx b/sx/sx/boundary.sx index 2831426..3082b67 100644 --- a/sx/sx/boundary.sx +++ b/sx/sx/boundary.sx @@ -79,3 +79,18 @@ :params () :returns "dict" :service "sx") + +(define-page-helper "optimistic-demo-data" + :params () + :returns "dict" + :service "sx") + +(define-page-helper "action:add-demo-item" + :params (label) + :returns "dict" + :service "sx") + +(define-page-helper "offline-demo-data" + :params () + :returns "dict" + :service "sx") diff --git a/sx/sxc/pages/helpers.py b/sx/sxc/pages/helpers.py index 0cb36e7..a732042 100644 --- a/sx/sxc/pages/helpers.py +++ b/sx/sxc/pages/helpers.py @@ -715,6 +715,7 @@ def _run_modular_tests(spec_name: str) -> dict: "render": {"file": "test-render.sx", "needs": ["render-html"]}, "deps": {"file": "test-deps.sx", "needs": []}, "engine": {"file": "test-engine.sx", "needs": []}, + "orchestration": {"file": "test-orchestration.sx", "needs": []}, } specs_to_run = list(SPECS.keys()) if spec_name == "all" else [spec_name] @@ -788,6 +789,50 @@ def _run_modular_tests(spec_name: str) -> dict: env["filter-params"] = filter_params except ImportError: eval_file("engine.sx") + elif sn == "orchestration": + # Mock platform functions for orchestration tests + _mock_ts = [1000] + env["now-ms"] = lambda: _mock_ts[0] + env["log-info"] = lambda *_a: NIL + env["log-warn"] = lambda *_a: NIL + env["execute-action"] = lambda act, pay, ok_cb, _err: (ok_cb(pay), NIL)[-1] + env["try-rerender-page"] = lambda *_a: NIL + env["persist-offline-data"] = lambda *_a: NIL + env["retrieve-offline-data"] = lambda: NIL + env["dict-delete!"] = lambda d, k: (d.pop(k, None), NIL)[-1] if isinstance(d, dict) else NIL + # DOM/browser stubs (never called by tests) + _noop = lambda *_a: NIL + for stub in [ + "try-parse-json", "dom-dispatch", "dom-query-selector", + "dom-get-attribute", "dom-set-attribute", "dom-set-text-content", + "dom-append", "dom-insert-html-adjacent", "dom-remove", + "dom-outer-html", "dom-inner-html", "dom-create-element", + "dom-set-inner-html", "dom-morph", "dom-get-tag", + "dom-query-selector-all", "dom-add-event-listener", + "dom-set-timeout", "dom-prevent-default", "dom-closest", + "dom-matches", "dom-get-id", "dom-set-id", "dom-form-data", + "dom-is-form", "browser-location-href", "browser-push-state", + "browser-replace-state", "sx-hydrate-elements", "render-to-dom", + "hoist-head-elements-full", "url-pathname", + ]: + if stub not in env: + env[stub] = _noop + # Load engine (orchestration depends on it) + try: + from shared.sx.ref.sx_ref import ( + parse_time, parse_trigger_spec, default_trigger, + parse_swap_spec, parse_retry_spec, filter_params, + ) + env["parse-time"] = parse_time + env["parse-trigger-spec"] = parse_trigger_spec + env["default-trigger"] = default_trigger + env["parse-swap-spec"] = parse_swap_spec + env["parse-retry-spec"] = parse_retry_spec + env["next-retry-ms"] = lambda cur, cap: min(cur * 2, cap) + env["filter-params"] = filter_params + except ImportError: + eval_file("engine.sx") + eval_file("orchestration.sx") eval_file(spec["file"])