Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 57s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
100 lines
3.3 KiB
Plaintext
100 lines
3.3 KiB
Plaintext
;; errors.sx — Phase 9 error / undefined / partial-fn coverage via hk-test-error.
|
|
|
|
;; ── error builtin ────────────────────────────────────────────
|
|
(define
|
|
hk-as-list
|
|
(fn
|
|
(xs)
|
|
(cond
|
|
((and (list? xs) (= (first xs) "[]")) (list))
|
|
((and (list? xs) (= (first xs) ":"))
|
|
(cons (nth xs 1) (hk-as-list (nth xs 2))))
|
|
(:else xs))))
|
|
|
|
(hk-test-error
|
|
"error: raises with literal message"
|
|
(fn () (hk-deep-force (hk-run "main = error \"boom\"")))
|
|
"hk-error: boom")
|
|
|
|
(hk-test-error
|
|
"error: raises with computed message"
|
|
(fn () (hk-deep-force (hk-run "main = error (\"oops: \" ++ show 42)")))
|
|
"hk-error: oops: 42")
|
|
|
|
;; ── undefined ────────────────────────────────────────────────
|
|
(hk-test-error
|
|
"error: nested in if branch (only fires when forced)"
|
|
(fn
|
|
()
|
|
(hk-deep-force (hk-run "main = if 1 == 1 then error \"taken\" else 0")))
|
|
"taken")
|
|
|
|
(hk-test-error
|
|
"undefined: raises Prelude.undefined"
|
|
(fn () (hk-deep-force (hk-run "main = undefined")))
|
|
"Prelude.undefined")
|
|
|
|
;; The non-strict path: undefined doesn't fire when not forced.
|
|
(hk-test-error
|
|
"undefined: forced via arithmetic"
|
|
(fn () (hk-deep-force (hk-run "main = undefined + 1")))
|
|
"Prelude.undefined")
|
|
|
|
;; ── partial functions ───────────────────────────────────────
|
|
(hk-test
|
|
"undefined: lazy, not forced when discarded"
|
|
(hk-deep-force (hk-run "main = let _ = undefined in 5"))
|
|
5)
|
|
|
|
(hk-test-error
|
|
"head []: raises Prelude.head: empty list"
|
|
(fn () (hk-deep-force (hk-run "main = head []")))
|
|
"Prelude.head: empty list")
|
|
|
|
(hk-test-error
|
|
"tail []: raises Prelude.tail: empty list"
|
|
(fn () (hk-deep-force (hk-run "main = tail []")))
|
|
"Prelude.tail: empty list")
|
|
|
|
;; head and tail still work on non-empty lists.
|
|
(hk-test-error
|
|
"fromJust Nothing: raises Maybe.fromJust: Nothing"
|
|
(fn () (hk-deep-force (hk-run "main = fromJust Nothing")))
|
|
"Maybe.fromJust: Nothing")
|
|
|
|
(hk-test
|
|
"head [42]: still works"
|
|
(hk-deep-force (hk-run "main = head [42]"))
|
|
42)
|
|
|
|
;; ── error in IO context ─────────────────────────────────────
|
|
(hk-test
|
|
"tail [1,2,3]: still works"
|
|
(hk-as-list (hk-deep-force (hk-run "main = tail [1,2,3]")))
|
|
(list 2 3))
|
|
|
|
(hk-test
|
|
"hk-run-io: error in main lands in io-lines"
|
|
(let
|
|
((lines (hk-run-io "main = error \"caught here\"")))
|
|
(>= (index-of (str lines) "caught here") 0))
|
|
true)
|
|
|
|
;; ── hk-test-error helper itself ─────────────────────────────
|
|
(hk-test
|
|
"hk-run-io: putStrLn before error preserves earlier output"
|
|
(let
|
|
((lines (hk-run-io "main = do { putStrLn \"first\"; error \"died\"; putStrLn \"never\" }")))
|
|
(and
|
|
(>= (index-of (str lines) "first") 0)
|
|
(>= (index-of (str lines) "died") 0)))
|
|
true)
|
|
|
|
;; hk-as-list helper for converting a forced Haskell cons into an SX list.
|
|
(hk-test-error
|
|
"hk-test-error: matches partial substring inside wrapped exception"
|
|
(fn () (hk-deep-force (hk-run "main = error \"unique-marker-xyz\"")))
|
|
"unique-marker-xyz")
|
|
|
|
{:fails hk-test-fails :pass hk-test-pass :fail hk-test-fail}
|