Skip to content

Commit 3c4478d

Browse files
leifericfclaude
andcommitted
test: is-thrown skips the type symbol so body actually runs
`(is (thrown? <Type> body))` used to splice (rest expr) into a do-block. (rest expr) was (<Type> body), so evaluating <Type> was the FIRST thing the do-block did. When <Type> was unbound -- which it always is in mino, since there is no exception class hierarchy -- the lookup itself threw, the catch arm caught it, and the assertion passed regardless of what `body` did. Every test that expected a body throw was therefore silently green even when the body had been refactored to no longer throw. Detect the shape at macroexpansion time: (thrown? <Type> <body>...) -- JVM-clojure compatible (thrown? <body>) -- mino's single-arg shorthand When two or more forms follow `thrown?`, the first is the type symbol and is dropped before splicing the body; when a single form follows, it IS the body and is kept. mino's runtime cannot verify exception class membership, so the type symbol is documentation-only here; any throw from the body counts as a pass. Verified by manual reproducer: (is (thrown? Exception (+ 1 2))) now reports "expected exception but none thrown" rather than silently passing, and the full 4845-assertion suite still passes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent bfdc8fb commit 3c4478d

3 files changed

Lines changed: 31 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Changelog
22

3+
## v0.389.14 — `is-thrown` Correctly Checks the Body, Not the Type Symbol
4+
5+
`(is (thrown? Exception body))` used to silently pass whenever
6+
the type symbol was unbound: the macro spliced `(rest expr)` --
7+
which includes both the type symbol and the body -- into a
8+
`do` block, so evaluating `Exception` itself threw and the
9+
catch arm registered a pass before the body ever ran. Tests that
10+
expected the body to throw were therefore green regardless of
11+
what the body actually did.
12+
13+
The macro now detects the JVM-Clojure shape `(thrown? <type>
14+
<body>...)` vs the mino single-arg shorthand `(thrown? <body>)`
15+
by arity and skips the type symbol when present. mino has no
16+
exception class hierarchy, so the type symbol is treated as
17+
documentation; any throw from the body counts as a pass.
18+
319
## v0.389.13 — Lock-Invariant Assert on Regex Prim Entries
420

521
The regex engine in `src/regex/re.c` uses file-static globals

lib/clojure/test.clj

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,20 @@
5555
(and (symbol? sym) (= "thrown?" (name sym))))
5656

5757
(defmacro is-thrown [expr msg]
58-
`(try
59-
(do ~@(rest expr)
60-
(assert-fail! (pr-str '~expr) ~msg "expected exception but none thrown"))
61-
(catch __e (assert-pass!))))
58+
;; expr matches either of two shapes:
59+
;; (thrown? <type> <body>...) -- JVM-clojure compatible
60+
;; (thrown? <body>) -- mino single-arg shorthand
61+
;; mino has no exception class hierarchy; the type symbol is
62+
;; documentation-only, so any throw from the body counts as a
63+
;; pass. We detect the JVM shape by arity: 2+ elements after
64+
;; `thrown?` means the first is the type (skip it); 1 element
65+
;; is the body itself.
66+
(let [args (rest expr)
67+
body-forms (if (= 1 (count args)) args (rest args))]
68+
`(try
69+
(do ~@body-forms
70+
(assert-fail! (pr-str '~expr) ~msg "expected exception but none thrown"))
71+
(catch __e (assert-pass!)))))
6272

6373
(defmacro is-eq [expr msg]
6474
(let [gs-exp (gensym) gs-act (gensym)

src/mino.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
*/
2929
#define MINO_VERSION_MAJOR 0
3030
#define MINO_VERSION_MINOR 389
31-
#define MINO_VERSION_PATCH 13
31+
#define MINO_VERSION_PATCH 14
3232

3333
/*
3434
* Human-readable version string of the *linked* runtime, e.g. "0.48.0".

0 commit comments

Comments
 (0)