- Vector of value array added to sx_types.ml (prior commit) - Vector primitives in sx_primitives.ml (make-vector, vector-ref, vector-set!, vector-length, vector->list, list->vector) - R7RS vector tests - test-unified-reactive.sx: 34 tests specifying the unified reactive model (provide/context/peek/bind replacing signal/deref split). All 34 currently fail — implementation next. - WASM binary rebuilt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
662 lines
18 KiB
Plaintext
662 lines
18 KiB
Plaintext
(defsuite
|
|
"callcc-basic"
|
|
(deftest "simple escape" (assert= (call/cc (fn (k) (k 42))) 42))
|
|
(deftest "normal return (k unused)" (assert= (call/cc (fn (k) 99)) 99))
|
|
(deftest
|
|
"escape from nested expression"
|
|
(assert= (+ 1 (call/cc (fn (k) (+ 10 (k 42))))) 43))
|
|
(deftest
|
|
"call-with-current-continuation alias"
|
|
(assert= (call-with-current-continuation (fn (k) (k 77))) 77))
|
|
(deftest
|
|
"call/cc in let binding"
|
|
(assert= (let ((x (call/cc (fn (k) (k 5))))) (+ x 10)) 15))
|
|
(deftest
|
|
"call/cc in tail position"
|
|
(assert= (if true (call/cc (fn (k) (k 1))) 2) 1))
|
|
(deftest
|
|
"call/cc with no args to k"
|
|
(assert= (call/cc (fn (k) (k))) nil)))
|
|
|
|
(defsuite
|
|
"raise-basic"
|
|
(deftest
|
|
"raise with handler-bind"
|
|
(assert=
|
|
(handler-bind
|
|
(((fn (c) true) (fn (c) c)))
|
|
(+ 1 (raise-continuable 42)))
|
|
43))
|
|
(deftest
|
|
"raise-continuable returns to call site"
|
|
(assert=
|
|
(handler-bind
|
|
(((fn (c) true) (fn (c) (+ c 100))))
|
|
(+ 1 (raise-continuable 42)))
|
|
143))
|
|
(deftest
|
|
"raise non-continuable errors on handler return"
|
|
(assert=
|
|
(try-catch
|
|
(fn () (handler-bind (((fn (c) true) (fn (c) c))) (raise 42)))
|
|
(fn (e) "caught"))
|
|
"caught"))
|
|
(deftest
|
|
"unhandled raise gives host error"
|
|
(assert=
|
|
(try-catch (fn () (raise 99)) (fn (e) "unhandled"))
|
|
"unhandled")))
|
|
|
|
(defsuite
|
|
"guard-basic"
|
|
(deftest
|
|
"guard catches with matching clause"
|
|
(assert= (guard (exn ((number? exn) (+ exn 1))) (raise 41)) 42))
|
|
(deftest
|
|
"guard with else clause"
|
|
(assert= (guard (exn (else "caught")) (raise "boom")) "caught"))
|
|
(deftest
|
|
"guard passes through on no exception"
|
|
(assert= (guard (exn (else "caught")) (+ 1 2)) 3))
|
|
(deftest
|
|
"guard re-raises when no clause matches"
|
|
(assert=
|
|
(try-catch
|
|
(fn
|
|
()
|
|
(guard (exn ((number? exn) "number")) (raise "string-value")))
|
|
(fn (e) "re-raised"))
|
|
"re-raised"))
|
|
(deftest
|
|
"nested guard"
|
|
(assert=
|
|
(guard
|
|
(outer (else (str "outer: " (error-message outer))))
|
|
(guard (inner ((number? inner) (+ inner 1))) (raise 41)))
|
|
42)))
|
|
|
|
(defsuite
|
|
"with-exception-handler"
|
|
(deftest
|
|
"basic catch with continuable"
|
|
(assert=
|
|
(with-exception-handler
|
|
(fn (c) (+ c 100))
|
|
(fn () (+ 1 (raise-continuable 42))))
|
|
143)))
|
|
|
|
(defsuite
|
|
"error-objects"
|
|
(deftest
|
|
"make-error-object creates dict"
|
|
(assert (error-object? (make-error-object "test" (list)))))
|
|
(deftest
|
|
"error-message accessor"
|
|
(assert= (error-message (make-error-object "hello" (list))) "hello"))
|
|
(deftest
|
|
"error-object-irritants accessor"
|
|
(assert=
|
|
(error-object-irritants (make-error-object "msg" (list 1 2 3)))
|
|
(list 1 2 3)))
|
|
(deftest
|
|
"raise error object caught by guard"
|
|
(assert=
|
|
(guard
|
|
(exn ((error-object? exn) (error-message exn)))
|
|
(raise (make-error-object "test error" (list 1 2))))
|
|
"test error")))
|
|
|
|
(defsuite
|
|
"multi-map"
|
|
(deftest
|
|
"map over two lists"
|
|
(assert= (map + (list 1 2 3) (list 10 20 30)) (list 11 22 33)))
|
|
(deftest
|
|
"map over three lists"
|
|
(assert=
|
|
(map + (list 1 2) (list 10 20) (list 100 200))
|
|
(list 111 222)))
|
|
(deftest
|
|
"stops at shortest list"
|
|
(assert= (map + (list 1 2 3) (list 10 20)) (list 11 22)))
|
|
(deftest
|
|
"empty list returns empty"
|
|
(assert= (map + (list) (list 1 2)) (list)))
|
|
(deftest
|
|
"single list backwards compat"
|
|
(assert= (map (fn (x) (* x 2)) (list 1 2 3)) (list 2 4 6)))
|
|
(deftest
|
|
"map list constructor over two lists"
|
|
(assert=
|
|
(map (fn (a b) (list a b)) (list 1 2) (list 3 4))
|
|
(list (list 1 3) (list 2 4)))))
|
|
|
|
(defsuite
|
|
"cond-arrow"
|
|
(deftest
|
|
"basic arrow clause"
|
|
(assert= (cond (1 => (fn (x) (+ x 10)))) 11))
|
|
(deftest "arrow with identity" (assert= (cond (42 => (fn (x) x))) 42))
|
|
(deftest
|
|
"false clause skipped, else taken"
|
|
(assert= (cond (false => (fn (x) x)) (else 99)) 99))
|
|
(deftest
|
|
"arrow with complex expression"
|
|
(assert= (cond (42 => (fn (x) (* x 2)))) 84)))
|
|
|
|
(defsuite
|
|
"do-iteration"
|
|
(deftest "basic count" (assert= (do ((i 0 (+ i 1))) ((= i 5) i)) 5))
|
|
(deftest
|
|
"accumulator"
|
|
(assert= (do ((i 0 (+ i 1)) (sum 0 (+ sum i))) ((= i 4) sum)) 6))
|
|
(deftest
|
|
"collect into list"
|
|
(assert=
|
|
(do ((v (list) (append v (list i))) (i 0 (+ i 1))) ((= i 3) v))
|
|
(list 0 1 2)))
|
|
(deftest
|
|
"do as begin still works"
|
|
(assert= (let ((x 0)) (do (set! x 42)) x) 42)))
|
|
|
|
(defsuite
|
|
"r7rs-aliases"
|
|
(deftest
|
|
"car/cdr"
|
|
(assert= (car (list 1 2 3)) 1)
|
|
(assert= (cdr (list 1 2 3)) (list 2 3)))
|
|
(deftest "cadr" (assert= (cadr (list 1 2 3)) 2))
|
|
(deftest
|
|
"null?"
|
|
(assert (null? nil))
|
|
(assert (null? (list)))
|
|
(assert (not (null? (list 1)))))
|
|
(deftest
|
|
"pair?"
|
|
(assert (pair? (list 1)))
|
|
(assert (not (pair? (list))))
|
|
(assert (not (pair? 42))))
|
|
(deftest
|
|
"procedure?"
|
|
(assert (procedure? (fn () 1)))
|
|
(assert (procedure? +))
|
|
(assert (not (procedure? 42))))
|
|
(deftest
|
|
"integer?"
|
|
(assert (integer? 42))
|
|
(assert (integer? 0))
|
|
(assert (not (integer? 3.14)))
|
|
(assert (not (integer? "hello"))))
|
|
(deftest
|
|
"symbol->string"
|
|
(assert= (symbol->string (quote hello)) "hello"))
|
|
(deftest "number->string" (assert= (number->string 42) "42"))
|
|
(deftest
|
|
"boolean=?"
|
|
(assert (boolean=? true true))
|
|
(assert (boolean=? false false))
|
|
(assert (not (boolean=? true false)))))
|
|
|
|
(defsuite
|
|
"parameter-basic"
|
|
(deftest
|
|
"make-parameter creates parameter"
|
|
(let ((p (make-parameter 42))) (assert (parameter? p))))
|
|
(deftest
|
|
"parameter returns default value"
|
|
(let ((p (make-parameter 42))) (assert= 42 (p))))
|
|
(deftest
|
|
"parameter? false for non-parameters"
|
|
(do
|
|
(assert= false (parameter? 42))
|
|
(assert= false (parameter? "hello"))
|
|
(assert= false (parameter? (list 1 2)))))
|
|
(deftest
|
|
"two parameters are independent"
|
|
(let
|
|
((p1 (make-parameter 10)) (p2 (make-parameter 20)))
|
|
(do (assert= 10 (p1)) (assert= 20 (p2))))))
|
|
|
|
(defsuite
|
|
"parameterize-basic"
|
|
(deftest
|
|
"parameterize rebinds single parameter"
|
|
(let
|
|
((p (make-parameter 1)))
|
|
(assert= 99 (parameterize ((p 99)) (p)))))
|
|
(deftest
|
|
"parameterize restores after body"
|
|
(let
|
|
((p (make-parameter 1)))
|
|
(do (parameterize ((p 99)) (p)) (assert= 1 (p)))))
|
|
(deftest
|
|
"parameterize with multiple bindings"
|
|
(let
|
|
((p1 (make-parameter 10)) (p2 (make-parameter 20)))
|
|
(parameterize
|
|
((p1 100) (p2 200))
|
|
(do (assert= 100 (p1)) (assert= 200 (p2))))))
|
|
(deftest
|
|
"nested parameterize"
|
|
(let
|
|
((p (make-parameter 1)))
|
|
(parameterize
|
|
((p 10))
|
|
(do
|
|
(assert= 10 (p))
|
|
(parameterize ((p 100)) (assert= 100 (p)))
|
|
(assert= 10 (p))))))
|
|
(deftest
|
|
"parameterize with empty bindings"
|
|
(assert= 42 (parameterize () 42)))
|
|
(deftest
|
|
"parameterize body returns last expr"
|
|
(let
|
|
((p (make-parameter 0)))
|
|
(assert= 3 (parameterize ((p 3)) 1 2 (p))))))
|
|
|
|
(defsuite
|
|
"syntax-rules-basic"
|
|
(deftest
|
|
"simple constant pattern"
|
|
(do
|
|
(define-syntax my-const
|
|
(syntax-rules ()
|
|
((_) 42)))
|
|
(assert= 42 (my-const))))
|
|
(deftest
|
|
"pattern with variable"
|
|
(do
|
|
(define-syntax my-id
|
|
(syntax-rules ()
|
|
((_ x) x)))
|
|
(assert= 7 (my-id 7))))
|
|
(deftest
|
|
"variable in template expression"
|
|
(do
|
|
(define-syntax my-double
|
|
(syntax-rules ()
|
|
((_ x) (+ x x))))
|
|
(assert= 10 (my-double 5))))
|
|
(deftest
|
|
"multiple clauses by arity"
|
|
(do
|
|
(define-syntax my-if2
|
|
(syntax-rules ()
|
|
((_ test then) (if test then nil))
|
|
((_ test then else-expr) (if test then else-expr))))
|
|
(assert= 1 (my-if2 true 1))
|
|
(assert= 2 (my-if2 false 1 2))))
|
|
(deftest
|
|
"ellipsis collects zero-or-more"
|
|
(do
|
|
(define-syntax my-list
|
|
(syntax-rules ()
|
|
((_ x ...) (list x ...))))
|
|
(assert= (list 1 2 3) (my-list 1 2 3))
|
|
(assert= (list) (my-list))))
|
|
(deftest
|
|
"nested pattern"
|
|
(do
|
|
(define-syntax my-let1
|
|
(syntax-rules ()
|
|
((_ ((var val)) body) (let ((var val)) body))))
|
|
(assert= 10 (my-let1 ((x 10)) x))))
|
|
(deftest
|
|
"literal keyword matching"
|
|
(do
|
|
(define-syntax my-arrow
|
|
(syntax-rules (=>)
|
|
((_ x => y) (list x y))))
|
|
(assert= (list 1 2) (my-arrow 1 => 2))))
|
|
(deftest
|
|
"literal keyword no match falls through"
|
|
(do
|
|
(define-syntax my-cond
|
|
(syntax-rules (=>)
|
|
((_ x => fn-expr) (fn-expr x))
|
|
((_ x y) (list x y))))
|
|
(assert= (list 3 4) (my-cond 3 4))))
|
|
(deftest
|
|
"recursive macro with ellipsis"
|
|
(do
|
|
(define-syntax my-and
|
|
(syntax-rules ()
|
|
((_) true)
|
|
((_ e) e)
|
|
((_ e1 e2 ...) (if e1 (my-and e2 ...) false))))
|
|
(assert= true (my-and))
|
|
(assert= 5 (my-and 5))
|
|
(assert= true (my-and true true true))
|
|
(assert= false (my-and true false true))))
|
|
(deftest
|
|
"swap macro"
|
|
(do
|
|
(define-syntax my-swap!
|
|
(syntax-rules ()
|
|
((_ a b) (let ((tmp a)) (set! a b) (set! b tmp)))))
|
|
(let ((x 1) (y 2))
|
|
(my-swap! x y)
|
|
(assert= 2 x)
|
|
(assert= 1 y))))
|
|
(deftest
|
|
"when macro via syntax-rules"
|
|
(do
|
|
(define-syntax my-when
|
|
(syntax-rules ()
|
|
((_ test body ...) (if test (do body ...) nil))))
|
|
(assert= nil (my-when false 1 2 3))
|
|
(assert= 3 (my-when true 1 2 3))))
|
|
(deftest
|
|
"nested ellipsis in binding pairs"
|
|
(do
|
|
(define-syntax my-let
|
|
(syntax-rules ()
|
|
((_ ((var val) ...) body)
|
|
(let ((var val) ...) body))))
|
|
(assert= 6 (my-let ((a 1) (b 2) (c 3)) (+ a b c)))))
|
|
(deftest
|
|
"or macro with short-circuit"
|
|
(do
|
|
(define-syntax my-or
|
|
(syntax-rules ()
|
|
((_) false)
|
|
((_ e) e)
|
|
((_ e1 e2 ...)
|
|
(let ((t e1)) (if t t (my-or e2 ...))))))
|
|
(assert= false (my-or))
|
|
(assert= 42 (my-or 42))
|
|
(assert= 1 (my-or 1 2 3))
|
|
(assert= 3 (my-or false false 3))
|
|
(assert= false (my-or false false false)))))
|
|
|
|
(defsuite
|
|
"numeric-tower"
|
|
(deftest
|
|
"exact? recognizes integers"
|
|
(do
|
|
(assert (exact? 42))
|
|
(assert (exact? 0))
|
|
(assert (exact? -7))
|
|
(assert (not (exact? 3.14)))
|
|
(assert (not (exact? 0.5)))))
|
|
(deftest
|
|
"inexact? recognizes non-integers"
|
|
(do
|
|
(assert (inexact? 3.14))
|
|
(assert (inexact? 0.5))
|
|
(assert (not (inexact? 42)))
|
|
(assert (not (inexact? 0)))))
|
|
(deftest
|
|
"exact->inexact identity for floats"
|
|
(do
|
|
(assert (number? (exact->inexact 42)))
|
|
(assert= 42 (exact->inexact 42))
|
|
(assert= 3.14 (exact->inexact 3.14))))
|
|
(deftest
|
|
"inexact->exact rounds to integer"
|
|
(do
|
|
(assert (integer? (inexact->exact 3.7)))
|
|
(assert= 4 (inexact->exact 3.7))
|
|
(assert= 3 (inexact->exact 3))
|
|
(assert= -4 (inexact->exact -3.7))))
|
|
(deftest
|
|
"truncate toward zero"
|
|
(do
|
|
(assert= 3 (truncate 3.7))
|
|
(assert= -3 (truncate -3.7))
|
|
(assert= 3 (truncate 3.2))
|
|
(assert= -3 (truncate -3.2))
|
|
(assert= 5 (truncate 5))))
|
|
(deftest
|
|
"remainder sign follows dividend"
|
|
(do
|
|
(assert= 1 (remainder 7 3))
|
|
(assert= -1 (remainder -7 3))
|
|
(assert= 1 (remainder 7 -3))
|
|
(assert= -1 (remainder -7 -3))))
|
|
(deftest
|
|
"modulo sign follows divisor"
|
|
(do
|
|
(assert= 1 (modulo 7 3))
|
|
(assert= 2 (modulo -7 3))
|
|
(assert= -2 (modulo 7 -3))
|
|
(assert= -1 (modulo -7 -3))))
|
|
(deftest
|
|
"integer preservation through arithmetic"
|
|
(do
|
|
(assert (integer? (+ 3 4)))
|
|
(assert (integer? (* 3 4)))
|
|
(assert (integer? (- 10 3)))
|
|
(assert (not (integer? (/ 7 2))))
|
|
(assert (integer? (/ 6 3)))
|
|
(assert (integer? (floor 3.7)))
|
|
(assert (integer? (ceil 3.2)))
|
|
(assert (integer? (round 3.5)))
|
|
(assert (integer? (truncate 3.7))))))
|
|
|
|
(defsuite
|
|
"vectors"
|
|
(deftest
|
|
"make-vector creates vector of given size"
|
|
(let
|
|
((v (make-vector 5)))
|
|
(do (assert (vector? v)) (assert= 5 (vector-length v)))))
|
|
(deftest
|
|
"make-vector with fill value"
|
|
(let
|
|
((v (make-vector 3 42)))
|
|
(do
|
|
(assert= 42 (vector-ref v 0))
|
|
(assert= 42 (vector-ref v 1))
|
|
(assert= 42 (vector-ref v 2)))))
|
|
(deftest
|
|
"vector constructor from args"
|
|
(let
|
|
((v (vector 1 2 3)))
|
|
(do
|
|
(assert= 3 (vector-length v))
|
|
(assert= 1 (vector-ref v 0))
|
|
(assert= 2 (vector-ref v 1))
|
|
(assert= 3 (vector-ref v 2)))))
|
|
(deftest
|
|
"vector-set! mutates in place"
|
|
(let
|
|
((v (make-vector 3 0)))
|
|
(do
|
|
(vector-set! v 1 99)
|
|
(assert= 99 (vector-ref v 1))
|
|
(assert= 0 (vector-ref v 0)))))
|
|
(deftest
|
|
"vector->list conversion"
|
|
(assert= (list 1 2 3) (vector->list (vector 1 2 3))))
|
|
(deftest
|
|
"list->vector conversion"
|
|
(let
|
|
((v (list->vector (list 10 20 30))))
|
|
(do
|
|
(assert (vector? v))
|
|
(assert= 3 (vector-length v))
|
|
(assert= 20 (vector-ref v 1)))))
|
|
(deftest
|
|
"vector-fill! sets all elements"
|
|
(let
|
|
((v (vector 1 2 3)))
|
|
(do
|
|
(vector-fill! v 0)
|
|
(assert= 0 (vector-ref v 0))
|
|
(assert= 0 (vector-ref v 1))
|
|
(assert= 0 (vector-ref v 2)))))
|
|
(deftest
|
|
"vector-copy creates independent copy"
|
|
(let
|
|
((v1 (vector 1 2 3)))
|
|
(let
|
|
((v2 (vector-copy v1)))
|
|
(do
|
|
(vector-set! v2 0 99)
|
|
(assert= 1 (vector-ref v1 0))
|
|
(assert= 99 (vector-ref v2 0))))))
|
|
(deftest
|
|
"vector? predicate"
|
|
(do
|
|
(assert (vector? (vector 1 2)))
|
|
(assert (not (vector? (list 1 2))))
|
|
(assert (not (vector? 42)))))
|
|
(deftest
|
|
"vector equality"
|
|
(do
|
|
(assert= (vector 1 2 3) (vector 1 2 3))
|
|
(assert (not (= (vector 1 2) (vector 1 3)))))))
|
|
|
|
(defsuite
|
|
"capabilities"
|
|
(deftest
|
|
"current-capabilities nil when unrestricted"
|
|
(assert= nil (current-capabilities)))
|
|
(deftest
|
|
"has-capability? true when unrestricted"
|
|
(assert (has-capability? "anything")))
|
|
(deftest
|
|
"with-capabilities sets capabilities"
|
|
(with-capabilities
|
|
(list "io-fetch" "io-query")
|
|
(fn () (assert= (list "io-fetch" "io-query") (current-capabilities)))))
|
|
(deftest
|
|
"has-capability? checks active set"
|
|
(with-capabilities
|
|
(list "io-fetch")
|
|
(fn
|
|
()
|
|
(do
|
|
(assert (has-capability? "io-fetch"))
|
|
(assert (not (has-capability? "io-query")))))))
|
|
(deftest
|
|
"require-capability! passes when granted"
|
|
(with-capabilities
|
|
(list "io-fetch")
|
|
(fn () (require-capability! "io-fetch"))))
|
|
(deftest
|
|
"require-capability! raises when missing"
|
|
(with-capabilities
|
|
(list "io-fetch")
|
|
(fn () (assert (not (has-capability? "io-query"))))))
|
|
(deftest
|
|
"capabilities restore after body"
|
|
(do
|
|
(with-capabilities (list "io-fetch") (fn () nil))
|
|
(assert= nil (current-capabilities))))
|
|
(deftest
|
|
"capabilities restore after nested call"
|
|
(do
|
|
(with-capabilities
|
|
(list "io-fetch")
|
|
(fn
|
|
()
|
|
(with-capabilities
|
|
(list "io-query")
|
|
(fn () (assert (has-capability? "io-query"))))))
|
|
(assert= nil (current-capabilities))))
|
|
(deftest
|
|
"nested capabilities narrow scope"
|
|
(with-capabilities
|
|
(list "io-fetch" "io-query")
|
|
(fn
|
|
()
|
|
(with-capabilities
|
|
(list "io-fetch")
|
|
(fn
|
|
()
|
|
(do
|
|
(assert (has-capability? "io-fetch"))
|
|
(assert (not (has-capability? "io-query")))))))))
|
|
(deftest
|
|
"capability-restricted? predicate"
|
|
(do
|
|
(assert (not (capability-restricted?)))
|
|
(with-capabilities
|
|
(list "pure")
|
|
(fn () (assert (capability-restricted?)))))))
|
|
|
|
(defsuite
|
|
"unified-reactive"
|
|
(deftest
|
|
"provide-reactive! stores signal in scope"
|
|
(begin
|
|
(provide-reactive! "theme" "dark")
|
|
(let
|
|
((result (context "theme")))
|
|
(provide-pop-reactive! "theme")
|
|
(assert= "dark" result))))
|
|
(deftest
|
|
"provide-set! mutates reactive value"
|
|
(begin
|
|
(provide-reactive! "count" 0)
|
|
(assert= 0 (context "count"))
|
|
(provide-set! "count" 42)
|
|
(let
|
|
((result (context "count")))
|
|
(provide-pop-reactive! "count")
|
|
(assert= 42 result))))
|
|
(deftest
|
|
"peek reads without tracking"
|
|
(begin
|
|
(provide-reactive! "x" 10)
|
|
(tracking-start!)
|
|
(let
|
|
((v (peek "x")))
|
|
(let
|
|
((deps (tracking-stop!)))
|
|
(provide-pop-reactive! "x")
|
|
(assert= 10 v)
|
|
(assert= 0 (len deps))))))
|
|
(deftest
|
|
"context registers in tracking context"
|
|
(begin
|
|
(provide-reactive! "y" 20)
|
|
(tracking-start!)
|
|
(let
|
|
((v (context "y")))
|
|
(let
|
|
((deps (tracking-stop!)))
|
|
(provide-pop-reactive! "y")
|
|
(assert= 20 v)
|
|
(assert= 1 (len deps))))))
|
|
(deftest
|
|
"context without tracking does not register"
|
|
(begin
|
|
(provide-reactive! "z" 30)
|
|
(assert (not (tracking-active?)))
|
|
(let ((v (context "z"))) (provide-pop-reactive! "z") (assert= 30 v))))
|
|
(deftest
|
|
"nested reactive provides"
|
|
(begin
|
|
(provide-reactive! "n" "outer")
|
|
(provide-reactive! "n" "inner")
|
|
(assert= "inner" (context "n"))
|
|
(provide-pop-reactive! "n")
|
|
(assert= "outer" (context "n"))
|
|
(provide-pop-reactive! "n")))
|
|
(deftest
|
|
"peek falls back to non-reactive scope"
|
|
(begin
|
|
(scope-push! "plain" 42)
|
|
(let ((v (peek "plain"))) (scope-pop! "plain") (assert= 42 v))))
|
|
(deftest
|
|
"tracking-active? predicate"
|
|
(begin
|
|
(assert (not (tracking-active?)))
|
|
(tracking-start!)
|
|
(assert (tracking-active?))
|
|
(tracking-stop!)
|
|
(assert (not (tracking-active?)))))
|
|
(deftest
|
|
"provide-set! updates visible value"
|
|
(begin
|
|
(provide-reactive! "mut" "old")
|
|
(provide-set! "mut" "new")
|
|
(let
|
|
((v (context "mut")))
|
|
(provide-pop-reactive! "mut")
|
|
(assert= "new" v)))))
|