(defsuite "handler-bind-basic" (deftest "handler-bind returns body value when no signal" (assert-equal 42 (handler-bind (((fn (c) true) (fn (c) "handled"))) 42))) (deftest "signal with matching handler returns handler value" (assert-equal "handled: boom" (handler-bind (((fn (c) true) (fn (c) (str "handled: " c)))) (signal-condition "boom")))) (deftest "signal without handler errors" (assert-throws (fn () (signal-condition "unhandled")))) (deftest "signal returns handler value to call site" (assert-equal 51 (handler-bind (((fn (c) true) (fn (c) (* c 10)))) (+ 1 (signal-condition 5))))) (deftest "handler-bind multiple handlers picks first match" (assert-equal "got-b" (handler-bind (((fn (c) (= c "type-a")) (fn (c) "got-a")) ((fn (c) (= c "type-b")) (fn (c) "got-b"))) (signal-condition "type-b")))) (deftest "nested handler-bind inner takes precedence" (assert-equal "inner-handler" (handler-bind (((fn (c) true) (fn (c) "outer"))) (handler-bind (((fn (c) (= c "inner")) (fn (c) "inner-handler"))) (signal-condition "inner"))))) (deftest "handler-bind with multi-expression body" (assert-equal 10 (handler-bind (((fn (c) true) (fn (c) c))) (+ 1 2) (* 2 5))))) (defsuite "restart-case-basic" (deftest "restart-case returns body value when no signal" (assert-equal 3 (restart-case (+ 1 2) (use-default () 0)))) (deftest "invoke-restart finds and runs restart" (assert-equal 42 (handler-bind (((fn (c) true) (fn (c) (invoke-restart (quote use-default))))) (restart-case (do (signal-condition "bad") "unreachable") (use-default () 42))))) (deftest "invoke-restart with argument" (assert-equal 99 (handler-bind (((fn (c) true) (fn (c) (invoke-restart (quote use-value) 99)))) (restart-case (do (signal-condition "bad") "unreachable") (use-value (v) v))))) (deftest "invoke-restart unknown name errors" (assert-throws (fn () (invoke-restart (quote nonexistent))))) (deftest "nested restart-case uses inner restart" (assert-equal "inner-fallback" (handler-bind (((fn (c) true) (fn (c) (invoke-restart (quote fallback))))) (restart-case (restart-case (do (signal-condition "err") "unreachable") (fallback () "inner-fallback")) (fallback () "outer-fallback"))))) (deftest "signal + restart computes replacement value" (assert-equal 25 (handler-bind (((fn (c) true) (fn (c) (invoke-restart (quote use-value) (* c 3))))) (+ 10 (restart-case (signal-condition 5) (use-value (v) v))))))) (defsuite "comp-trace" (deftest "component call creates trace frame" (defcomp ~trace-inner () "inner") (assert-equal "inner" (~trace-inner))) (deftest "nested component calls work" (defcomp ~trace-child () "child") (defcomp ~trace-parent () (~trace-child)) (assert-equal "child" (~trace-parent))) (deftest "component error via cek-try" (defcomp ~broken-comp () (error "deliberate")) (let ((result (cek-try (fn () (~broken-comp))))) (assert-true (= (type-of result) "list")))))