test: fold ported-clojure batteries into spec

Mine the remaining integration 'ported Clojure' batteries into the spec layer
and delete them (clojure-atom/control/for/logic/macros, core, logic). A broad
function-coverage diff confirmed they exercised no clojure.core fn the spec
lacked; their distinctive value was the truthiness/boolean contract, now
captured in a dedicated spec.

New/expanded spec coverage:
- spec/truthiness-spec: only nil/false are falsy (0, "", [], {}, #{} are truthy);
  not / and / or return-value & short-circuit semantics; if-not/when-not/boolean
- assert (exceptions-spec), get-validator (state-spec)

Layout now: spec 23 files / 732 cases; integration trimmed to 10 genuine
cross-cutting batteries (conformance, SCI bootstrap/runtime, jank, compile-mode,
api, namespace, bootstrap, features, systematic-coverage). conformance 218/218,
jpm test green.
This commit is contained in:
Yogthos 2026-06-05 07:50:16 -04:00
parent a6491d025c
commit a0943cb944
11 changed files with 70 additions and 754 deletions

View file

@ -17,6 +17,12 @@
["catch value of body" "5"
"(try (+ 2 3) (catch :default e 0))"])
(defspec "exceptions / assert"
["assert true -> ok" ":ok" "(do (assert true) :ok)"]
["assert expr -> ok" ":ok" "(do (assert (= 1 1)) :ok)"]
["assert false throws" :throws "(assert false)"]
["assert nil throws" :throws "(assert nil)"])
(defspec "exceptions / ex-info"
["ex-message" "\"oops\"" "(ex-message (ex-info \"oops\" {}))"]
["ex-data" "{:k 1}" "(ex-data (ex-info \"oops\" {:k 1}))"]

View file

@ -21,7 +21,8 @@
["add-watch fires" "1" "(let [a (atom 0) seen (atom 0)] (add-watch a :k (fn [k r o n] (reset! seen 1))) (reset! a 5) @seen)"]
["remove-watch" "0" "(let [a (atom 0) seen (atom 0)] (add-watch a :k (fn [k r o n] (swap! seen inc))) (remove-watch a :k) (reset! a 5) @seen)"]
["set-validator! ok" "5" "(let [a (atom 0)] (set-validator! a number?) (reset! a 5) @a)"]
["set-validator! rejects" :throws "(let [a (atom 0)] (set-validator! a pos?) (reset! a -1))"])
["set-validator! rejects" :throws "(let [a (atom 0)] (set-validator! a pos?) (reset! a -1))"]
["get-validator" "true" "(let [a (atom 0)] (set-validator! a number?) (fn? (get-validator a)))"])
(defspec "state / volatiles & delays"
["volatile! deref" "0" "(let [v (volatile! 0)] @v)"]

View file

@ -0,0 +1,61 @@
# Specification: truthiness & boolean logic.
# The core Clojure rule: ONLY nil and false are logically false; every other
# value — including 0, 0.0, "", and empty collections — is logically true.
(use ../support/harness)
(defspec "truthiness / if (only nil & false are falsy)"
["nil is falsy" ":f" "(if nil :t :f)"]
["false is falsy" ":f" "(if false :t :f)"]
["zero is truthy" ":t" "(if 0 :t :f)"]
["zero float truthy" ":t" "(if 0.0 :t :f)"]
["empty string truthy" ":t" "(if \"\" :t :f)"]
["empty list truthy" ":t" "(if (list) :t :f)"]
["empty vector truthy" ":t" "(if [] :t :f)"]
["empty map truthy" ":t" "(if {} :t :f)"]
["empty set truthy" ":t" "(if #{} :t :f)"]
["number truthy" ":t" "(if 42 :t :f)"]
["string truthy" ":t" "(if \"x\" :t :f)"]
["keyword truthy" ":t" "(if :kw :t :f)"]
["symbol truthy" ":t" "(if (quote abc) :t :f)"]
["coll truthy" ":t" "(if [1 2] :t :f)"]
["map truthy" ":t" "(if {:a 1} :t :f)"]
["if no else -> nil" "nil" "(if false :t)"])
(defspec "truthiness / not"
["not nil" "true" "(not nil)"]
["not false" "true" "(not false)"]
["not zero" "false" "(not 0)"]
["not empty vector" "false" "(not [])"]
["not empty string" "false" "(not \"\")"]
["not number" "false" "(not 42)"]
["not true" "false" "(not true)"])
(defspec "truthiness / and"
["empty is true" "true" "(and)"]
["single value" "5" "(and 5)"]
["all truthy -> last" "3" "(and 1 2 3)"]
["stops at false" "false" "(and 1 false 3)"]
["stops at nil" "nil" "(and 1 nil 3)"]
["false alone" "false" "(and false)"]
["nil alone" "nil" "(and nil)"]
["zero is truthy" "0" "(and 1 0)"])
(defspec "truthiness / or"
["empty is nil" "nil" "(or)"]
["first truthy" "1" "(or 1 2)"]
["skips nil/false" "5" "(or nil false 5)"]
["all falsy -> last" "false" "(or nil false)"]
["nil chain -> false" "false" "(or nil nil nil false)"]
["zero is truthy" "0" "(or 0 1)"]
["false alone" "false" "(or false)"])
(defspec "truthiness / if-not & boolean"
["if-not false" ":yes" "(if-not false :yes :no)"]
["if-not truthy" ":no" "(if-not 0 :yes :no)"]
["when-not nil" "1" "(when-not nil 1)"]
["when-not truthy" "nil" "(when-not 5 1)"]
["boolean of nil" "false" "(boolean nil)"]
["boolean of false" "false" "(boolean false)"]
["boolean of 0" "true" "(boolean 0)"]
["boolean of value" "true" "(boolean :x)"]
["true?/false?" "true" "(and (true? true) (false? false) (not (true? 1)))"])