Lazy module loading (Step 5 piece 6 completion): - Add define-library wrappers + import declarations to 13 source .sx files - compile-modules.js generates module-manifest.json with dependency graph - compile-modules.js strips define-library/import before bytecode compilation (VM doesn't handle these as special forms) - sx-platform.js replaces hardcoded 24-file loadWebStack() with manifest-driven recursive loader — only downloads modules the page needs - Result: 12 modules loaded (was 24), zero errors, zero warnings - Fallback to full load if manifest missing VM transpilation prep (Step 6b): - Refactor lib/vm.sx: 20 accessor functions replace raw dict access - Factor out collect-n-from-stack, collect-n-pairs, pad-n-nils helpers - bootstrap_vm.py: transpiles 9 VM logic functions to OCaml - sx_vm_ref.ml: proof that vm.sx transpiles (preamble has stubs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
121 lines
2.8 KiB
Plaintext
121 lines
2.8 KiB
Plaintext
(define-library (sx harness-reactive)
|
|
(export assert-signal-value assert-signal-has-subscribers assert-signal-no-subscribers assert-signal-subscriber-count simulate-signal-set! simulate-signal-swap! assert-computed-dep-count assert-computed-depends-on count-effect-runs make-test-signal assert-batch-coalesces)
|
|
(begin
|
|
|
|
(define
|
|
assert-signal-value
|
|
:effects ()
|
|
(fn
|
|
((sig :as any) expected)
|
|
(let
|
|
((actual (deref sig)))
|
|
(assert=
|
|
actual
|
|
expected
|
|
(str "Expected signal value " expected ", got " actual)))))
|
|
|
|
(define
|
|
assert-signal-has-subscribers
|
|
:effects ()
|
|
(fn
|
|
((sig :as any))
|
|
(assert
|
|
(> (len (signal-subscribers sig)) 0)
|
|
"Expected signal to have subscribers")))
|
|
|
|
(define
|
|
assert-signal-no-subscribers
|
|
:effects ()
|
|
(fn
|
|
((sig :as any))
|
|
(assert
|
|
(= (len (signal-subscribers sig)) 0)
|
|
"Expected signal to have no subscribers")))
|
|
|
|
(define
|
|
assert-signal-subscriber-count
|
|
:effects ()
|
|
(fn
|
|
((sig :as any) (n :as number))
|
|
(let
|
|
((actual (len (signal-subscribers sig))))
|
|
(assert= actual n (str "Expected " n " subscribers, got " actual)))))
|
|
|
|
(define
|
|
simulate-signal-set!
|
|
:effects (mutation)
|
|
(fn ((sig :as any) value) (reset! sig value)))
|
|
|
|
(define
|
|
simulate-signal-swap!
|
|
:effects (mutation)
|
|
(fn ((sig :as any) (f :as lambda)) (swap! sig f)))
|
|
|
|
(define
|
|
assert-computed-dep-count
|
|
:effects ()
|
|
(fn
|
|
((sig :as any) (n :as number))
|
|
(let
|
|
((actual (len (signal-deps sig))))
|
|
(assert= actual n (str "Expected " n " deps, got " actual)))))
|
|
|
|
(define
|
|
assert-computed-depends-on
|
|
:effects ()
|
|
(fn
|
|
((computed-sig :as any) (dep-sig :as any))
|
|
(assert
|
|
(contains? (signal-deps computed-sig) dep-sig)
|
|
"Expected computed to depend on the given signal")))
|
|
|
|
(define
|
|
count-effect-runs
|
|
:effects (mutation)
|
|
(fn
|
|
((thunk :as lambda))
|
|
(let
|
|
((count (signal 0)))
|
|
(effect (fn () (deref count)))
|
|
(let
|
|
((run-count 0)
|
|
(tracker
|
|
(effect
|
|
(fn () (set! run-count (+ run-count 1)) (cek-call thunk nil)))))
|
|
run-count))))
|
|
|
|
(define
|
|
make-test-signal
|
|
:effects (mutation)
|
|
(fn
|
|
(initial-value)
|
|
(let
|
|
((sig (signal initial-value)) (history (list)))
|
|
(effect (fn () (append! history (deref sig))))
|
|
{:signal sig :history history})))
|
|
|
|
(define
|
|
assert-batch-coalesces
|
|
:effects (mutation)
|
|
(fn
|
|
((thunk :as lambda) (expected-notify-count :as number))
|
|
(let
|
|
((notify-count 0) (sig (signal 0)))
|
|
(effect (fn () (deref sig) (set! notify-count (+ notify-count 1))))
|
|
(set! notify-count 0)
|
|
(batch thunk)
|
|
(assert=
|
|
notify-count
|
|
expected-notify-count
|
|
(str
|
|
"Expected "
|
|
expected-notify-count
|
|
" notifications, got "
|
|
notify-count)))))
|
|
|
|
|
|
))
|
|
|
|
;; Re-export to global env
|
|
(import (sx harness-reactive))
|