feat: complete atom implementation, new macros, predicates, and test coverage
## Runtime (src/jolt/core.janet, +637/-99) ### Atom system (complete) - core-atom: :validator and :meta options, watches table, atom-validate/atom-notify-watches helpers - New functions: swap-vals!, reset-vals!, compare-and-set!, set-validator!, get-validator, add-watch, remove-watch - Validator: blocks invalid reset!/swap!; watches: notification with old/new values; metadata support - All 7 functions registered in core-bindings ### New predicates - integer?, boolean?, list? — all registered in core-bindings ### New math - abs, rand, rand-int — registered in core-bindings ### Control flow macros (7 new) - cond, case (with one-of-many list support), condp, dotimes, while, if-not, when-first - Registered as macros: cond, case, for, dotimes, while, condp, if-not, when-first ### Threading macros (7) - -> (thread-first), ->> (thread-last), some->, some->>, cond->, cond->>, as-> - Renamed to core-thread-first/core-thread-last to avoid collision with comparison operators ### for comprehension - Full Clojure for macro: :when, :let modifiers, nested bindings - Uses map/mapcat expansion, correct last-group optimization ### Sequence operations (15 new) - last, butlast, second, ffirst, fnext, nfirst, nnext, nthnext, nthrest - drop-last, take-nth, map-indexed, keep, keep-indexed, reductions ### Nil-safety fixes - core-reverse, core-sort, core-sort-by, core-distinct now handle nil input ## Tests (7 new files, 361 assertions across all tests) ### Ported from Clojure test suite (4 files) - clojure-logic-test.janet: 82 assertions (if/and/or/not/some?/nil-punning) - clojure-control-test.janet: 56 assertions (do/when/if-let/cond/dotimes/while/loop/case) - clojure-macros-test.janet: 21 assertions (->/->>/some->/some->>/cond->/cond->>/as->) - clojure-for-test.janet: 4 assertions (:when/:let/nested for) ### Systematic coverage - clojure-atom-test.janet: 31 assertions (creation/reset!/swap!/swap-vals!/reset-vals!/CAS/validator/watches/meta) - systematic-coverage.janet: 120+ assertions (predicates/math/comparison/logic/collections/seq-ops/destructuring) - logic-test.janet: earlier ported logic tests ### Existing tests updated - lazy-test.janet, phase7-test.janet: updated for nil-safe core functions ## Result 47 test files, all passing. 19 new functions/macros implemented. Clojure atom semantics complete: validators, watches, metadata, CAS, swap-vals!/reset-vals!.
This commit is contained in:
parent
82bce033a5
commit
e2e7fa1447
12 changed files with 1462 additions and 98 deletions
212
test/systematic-coverage.janet
Normal file
212
test/systematic-coverage.janet
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
# Systematic coverage tests for Clojure language features
|
||||
(use ../src/jolt/api)
|
||||
(defn ct-eval [ctx s] (eval-string ctx s))
|
||||
|
||||
(print "Systematic Coverage Tests")
|
||||
|
||||
# --- Type Predicates ---
|
||||
(print "1: type predicates...")
|
||||
(let [ctx (init)]
|
||||
(assert (= true (ct-eval ctx "(integer? 0)")) "integer? 0")
|
||||
(assert (= true (ct-eval ctx "(integer? 1)")) "integer? 1")
|
||||
(assert (= true (ct-eval ctx "(integer? -5)")) "integer? negative")
|
||||
(assert (= false (ct-eval ctx "(integer? 1.5)")) "integer? float")
|
||||
(assert (= false (ct-eval ctx "(integer? nil)")) "integer? nil")
|
||||
(assert (= false (ct-eval ctx "(integer? \"abc\")")) "integer? string")
|
||||
(assert (= true (ct-eval ctx "(boolean? true)")) "boolean? true")
|
||||
(assert (= true (ct-eval ctx "(boolean? false)")) "boolean? false")
|
||||
(assert (= false (ct-eval ctx "(boolean? 1)")) "boolean? falsy")
|
||||
(assert (= false (ct-eval ctx "(boolean? nil)")) "boolean? nil")
|
||||
(assert (= true (ct-eval ctx "(nil? nil)")) "nil? nil")
|
||||
(assert (= false (ct-eval ctx "(nil? false)")) "nil? false")
|
||||
(assert (= false (ct-eval ctx "(nil? 0)")) "nil? 0")
|
||||
(assert (= false (ct-eval ctx "(nil? [])")) "nil? empty vec")
|
||||
(assert (= false (ct-eval ctx "(some? nil)")) "some? nil")
|
||||
(assert (= true (ct-eval ctx "(some? false)")) "some? false")
|
||||
(assert (= true (ct-eval ctx "(some? 0)")) "some? 0")
|
||||
(assert (= true (ct-eval ctx "(some? [])")) "some? empty vec")
|
||||
(assert (= true (ct-eval ctx "(string? \"hello\")")) "string?")
|
||||
(assert (= false (ct-eval ctx "(string? 42)")) "string? false")
|
||||
(assert (= true (ct-eval ctx "(string? \"\")")) "string? empty")
|
||||
(assert (= true (ct-eval ctx "(number? 42)")) "number? int")
|
||||
(assert (= true (ct-eval ctx "(number? 3.14)")) "number? float")
|
||||
(assert (= false (ct-eval ctx "(number? \"42\")")) "number? string")
|
||||
(assert (= true (ct-eval ctx "(fn? inc)")) "fn? builtin")
|
||||
(assert (= false (ct-eval ctx "(fn? 42)")) "fn? false")
|
||||
(assert (= true (ct-eval ctx "(keyword? :foo)")) "keyword?")
|
||||
(assert (= false (ct-eval ctx "(keyword? \"foo\")")) "keyword? false")
|
||||
(assert (= true (ct-eval ctx "(symbol? 'abc)")) "symbol?")
|
||||
(assert (= false (ct-eval ctx "(symbol? :abc)")) "symbol? false")
|
||||
(assert (= true (ct-eval ctx "(map? {:a 1})")) "map?")
|
||||
(assert (= false (ct-eval ctx "(map? [1 2])")) "map? false")
|
||||
(assert (= true (ct-eval ctx "(set? #{1 2})")) "set?")
|
||||
(assert (= false (ct-eval ctx "(set? [1 2])")) "set? false")
|
||||
(assert (= true (ct-eval ctx "(seq? '(1 2))")) "seq? list")
|
||||
(assert (= true (ct-eval ctx "(seq? [1 2])")) "seq? vector")
|
||||
(assert (= true (ct-eval ctx "(coll? [1 2])")) "coll? vec")
|
||||
(assert (= true (ct-eval ctx "(coll? '(1 2))")) "coll? list")
|
||||
(assert (= true (ct-eval ctx "(coll? {})")) "coll? map")
|
||||
(assert (= true (ct-eval ctx "(true? true)")) "true? true")
|
||||
(assert (= false (ct-eval ctx "(true? 1)")) "true? 1")
|
||||
(assert (= true (ct-eval ctx "(false? false)")) "false? false")
|
||||
(assert (= false (ct-eval ctx "(false? nil)")) "false? nil")
|
||||
(assert (= true (ct-eval ctx "(identical? 42 42)")) "identical? same value"))
|
||||
(print " ok")
|
||||
|
||||
# --- Number Predicates ---
|
||||
(print "2: number predicates...")
|
||||
(let [ctx (init)]
|
||||
(assert (= true (ct-eval ctx "(zero? 0)")) "zero? 0")
|
||||
(assert (= false (ct-eval ctx "(zero? 1)")) "zero? 1")
|
||||
(assert (= false (ct-eval ctx "(zero? nil)")) "zero? nil")
|
||||
(assert (= true (ct-eval ctx "(pos? 1)")) "pos?")
|
||||
(assert (= false (ct-eval ctx "(pos? 0)")) "pos? 0")
|
||||
(assert (= false (ct-eval ctx "(pos? -1)")) "pos? -1")
|
||||
(assert (= true (ct-eval ctx "(neg? -1)")) "neg?")
|
||||
(assert (= false (ct-eval ctx "(neg? 0)")) "neg? 0")
|
||||
(assert (= false (ct-eval ctx "(neg? 1)")) "neg? 1")
|
||||
(assert (= true (ct-eval ctx "(even? 0)")) "even? 0")
|
||||
(assert (= true (ct-eval ctx "(even? 2)")) "even? 2")
|
||||
(assert (= false (ct-eval ctx "(even? 1)")) "even? 1")
|
||||
(assert (= true (ct-eval ctx "(odd? 1)")) "odd? 1")
|
||||
(assert (= true (ct-eval ctx "(odd? 3)")) "odd? 3")
|
||||
(assert (= false (ct-eval ctx "(odd? 2)")) "odd? 2"))
|
||||
(print " ok")
|
||||
|
||||
# --- Math ---
|
||||
(print "3: math operations...")
|
||||
(let [ctx (init)]
|
||||
(assert (= 0 (ct-eval ctx "(+)")) "+ 0 args")
|
||||
(assert (= 5 (ct-eval ctx "(+ 2 3)")) "+ 2 args")
|
||||
(assert (= 10 (ct-eval ctx "(+ 1 2 3 4)")) "+ varargs")
|
||||
(assert (= -5 (ct-eval ctx "(- 5)")) "- unary")
|
||||
(assert (= 2 (ct-eval ctx "(- 5 3)")) "- binary")
|
||||
(assert (= 1 (ct-eval ctx "(*)")) "* 0 args")
|
||||
(assert (= 6 (ct-eval ctx "(* 2 3)")) "*")
|
||||
(assert (= 0.5 (ct-eval ctx "(/ 2)")) "/ unary reciprocal")
|
||||
(assert (= 2 (ct-eval ctx "(/ 4 2)")) "/ binary")
|
||||
(assert (= 2 (ct-eval ctx "(quot 5 2)")) "quot")
|
||||
(assert (= 1 (ct-eval ctx "(rem 5 2)")) "rem")
|
||||
(assert (= 1 (ct-eval ctx "(mod 5 2)")) "mod")
|
||||
(assert (= 43 (ct-eval ctx "(inc 42)")) "inc")
|
||||
(assert (= 41 (ct-eval ctx "(dec 42)")) "dec")
|
||||
(assert (= 3 (ct-eval ctx "(max 1 2 3)")) "max")
|
||||
(assert (= 1 (ct-eval ctx "(min 1 2 3)")) "min")
|
||||
(assert (= 5 (ct-eval ctx "(abs -5)")) "abs negative")
|
||||
(assert (= 5 (ct-eval ctx "(abs 5)")) "abs positive")
|
||||
(assert (= 0 (ct-eval ctx "(abs 0)")) "abs 0")
|
||||
(assert (= 3.14 (ct-eval ctx "(abs -3.14)")) "abs float")
|
||||
(assert (= true (ct-eval ctx "(< (rand) 1)")) "rand < 1")
|
||||
(assert (= true (ct-eval ctx "(number? (rand-int 10))")) "rand-int type"))
|
||||
(print " ok")
|
||||
|
||||
# --- Comparison ---
|
||||
(print "4: comparison...")
|
||||
(let [ctx (init)]
|
||||
(assert (= true (ct-eval ctx "(= 1 1)")) "= same")
|
||||
(assert (= true (ct-eval ctx "(= 1 1 1)")) "= multi same")
|
||||
(assert (= false (ct-eval ctx "(= 1 2)")) "= different")
|
||||
(assert (= true (ct-eval ctx "(not= 1 2)")) "not= different")
|
||||
(assert (= false (ct-eval ctx "(not= 1 1)")) "not= same")
|
||||
(assert (= true (ct-eval ctx "(< 1 2)")) "<")
|
||||
(assert (= false (ct-eval ctx "(< 2 1)")) "< false")
|
||||
(assert (= true (ct-eval ctx "(> 2 1)")) ">")
|
||||
(assert (= true (ct-eval ctx "(<= 1 1)")) "<=")
|
||||
(assert (= true (ct-eval ctx "(>= 2 2)")) ">="))
|
||||
(print " ok")
|
||||
|
||||
# --- Boolean logic ---
|
||||
(print "5: boolean logic...")
|
||||
(let [ctx (init)]
|
||||
(assert (= true (ct-eval ctx "(and)")) "and empty")
|
||||
(assert (= true (ct-eval ctx "(and true)")) "and true")
|
||||
(assert (= nil (ct-eval ctx "(and nil)")) "and nil")
|
||||
(assert (= false (ct-eval ctx "(and false)")) "and false")
|
||||
(assert (= 3 (ct-eval ctx "(and 1 2 3)")) "and last")
|
||||
(assert (= nil (ct-eval ctx "(and 1 nil 3)")) "and short-circuit")
|
||||
(assert (= nil (ct-eval ctx "(or)")) "or empty")
|
||||
(assert (= true (ct-eval ctx "(or true)")) "or true")
|
||||
(assert (= nil (ct-eval ctx "(or nil)")) "or nil")
|
||||
(assert (= false (ct-eval ctx "(or false)")) "or false")
|
||||
(assert (= 1 (ct-eval ctx "(or nil false 1 2)")) "or first truthy")
|
||||
(assert (= false (ct-eval ctx "(or nil false)")) "or all falsy")
|
||||
(assert (= false (ct-eval ctx "(not true)")) "not true")
|
||||
(assert (= true (ct-eval ctx "(not nil)")) "not nil")
|
||||
(assert (= true (ct-eval ctx "(not false)")) "not false"))
|
||||
(print " ok")
|
||||
|
||||
# --- Collections ---
|
||||
(print "6: collections...")
|
||||
(let [ctx (init)]
|
||||
(assert (= true (ct-eval ctx "(empty? nil)")) "empty? nil")
|
||||
(assert (= true (ct-eval ctx "(empty? [])")) "empty? []")
|
||||
(assert (= true (ct-eval ctx "(empty? ())")) "empty? ()")
|
||||
(assert (= true (ct-eval ctx "(empty? {})")) "empty? {}")
|
||||
(assert (= true (ct-eval ctx "(empty? #{})")) "empty? #{}")
|
||||
(assert (= true (ct-eval ctx "(empty? \"\")")) "empty? empty string")
|
||||
(assert (= false (ct-eval ctx "(empty? [1])")) "empty? non-empty")
|
||||
(assert (= true (ct-eval ctx "(every? even? [2 4 6])")) "every? true")
|
||||
(assert (= false (ct-eval ctx "(every? even? [2 3 4])")) "every? false")
|
||||
(assert (= 3 (ct-eval ctx "(count [1 2 3])")) "count vector")
|
||||
(assert (= 2 (ct-eval ctx "(count {:a 1 :b 2})")) "count map")
|
||||
(assert (= 3 (ct-eval ctx "(count #{1 2 3})")) "count set")
|
||||
(assert (= 3 (ct-eval ctx "(count \"abc\")")) "count string"))
|
||||
(print " ok")
|
||||
|
||||
# --- Sequence Operations ---
|
||||
(print "7: sequence operations...")
|
||||
(let [ctx (init)]
|
||||
(assert (= 1 (ct-eval ctx "(first [1 2 3])")) "first")
|
||||
(assert (= nil (ct-eval ctx "(first [])")) "first empty")
|
||||
(assert (= nil (ct-eval ctx "(first nil)")) "first nil")
|
||||
(assert (= :a (ct-eval ctx "(nth [:a :b :c] 0)")) "nth 0")
|
||||
(assert (= :c (ct-eval ctx "(nth [:a :b :c] 2)")) "nth 2")
|
||||
(assert (= :d (ct-eval ctx "(nth [:a :b :c] 3 :d)")) "nth default")
|
||||
(assert (= nil (ct-eval ctx "(seq [])")) "seq empty -> nil")
|
||||
(assert (= nil (ct-eval ctx "(seq nil)")) "seq nil -> nil")
|
||||
(assert (= true (ct-eval ctx "(= [2 3 4] (map inc [1 2 3]))")) "map")
|
||||
(assert (= true (ct-eval ctx "(= [2 4] (filter even? [1 2 3 4]))")) "filter")
|
||||
(assert (= 6 (ct-eval ctx "(reduce + [1 2 3])")) "reduce")
|
||||
(assert (= 10 (ct-eval ctx "(reduce + 4 [1 2 3])")) "reduce init")
|
||||
(assert (= true (ct-eval ctx "(= [1 2] (take 2 [1 2 3 4]))")) "take")
|
||||
(assert (= true (ct-eval ctx "(= [3 4] (drop 2 [1 2 3 4]))")) "drop")
|
||||
(assert (= true (ct-eval ctx "(= [3 2 1] (reverse [1 2 3]))")) "reverse")
|
||||
(assert (= true (ct-eval ctx "(= 3 (count (distinct [1 1 2 2 3 3])))")) "distinct"))
|
||||
(print " ok")
|
||||
|
||||
# --- Collections: conj, assoc, dissoc, get ---
|
||||
(print "8: collection mutation...")
|
||||
(let [ctx (init)]
|
||||
(assert (= true (ct-eval ctx "(= [1 2 3] (conj [1 2] 3))")) "conj vector")
|
||||
(assert (= true (ct-eval ctx "(= (quote (0 1 2)) (conj (quote (1 2)) 0))")) "conj list prepend")
|
||||
(assert (= true (ct-eval ctx "(= {:a 1 :b 2} (assoc {:a 1} :b 2))")) "assoc")
|
||||
(assert (= true (ct-eval ctx "(= {:a 1} (dissoc {:a 1 :b 2} :b))")) "dissoc")
|
||||
(assert (= 1 (ct-eval ctx "(get {:a 1} :a)")) "get")
|
||||
(assert (= nil (ct-eval ctx "(get {:a 1} :z)")) "get missing")
|
||||
(assert (= :d (ct-eval ctx "(get {:a 1} :z :d)")) "get default")
|
||||
(assert (= true (ct-eval ctx "(contains? {:a 1} :a)")) "contains? map")
|
||||
(assert (= false (ct-eval ctx "(contains? {:a 1} :z)")) "contains? missing")
|
||||
(assert (= true (ct-eval ctx "(contains? [5 6 7] 1)")) "contains? vector")
|
||||
(assert (= false (ct-eval ctx "(contains? [5 6 7] 3)")) "contains? vector oob"))
|
||||
(print " ok")
|
||||
|
||||
# --- Higher-order functions ---
|
||||
(print "9: higher-order functions...")
|
||||
(let [ctx (init)]
|
||||
(assert (= 3 (ct-eval ctx "((comp inc inc) 1)")) "comp")
|
||||
(assert (= 42 (ct-eval ctx "(identity 42)")) "identity")
|
||||
(assert (= 99 (ct-eval ctx "((constantly 99) :anything)")) "constantly")
|
||||
(assert (= true (ct-eval ctx "(= 10 ((partial + 3 7)))")) "partial")
|
||||
(assert (= true (ct-eval ctx "((every-pred even? pos?) 4)")) "every-pred true")
|
||||
(assert (= false (ct-eval ctx "((every-pred even? pos?) -4)")) "every-pred false")
|
||||
(assert (= false (ct-eval ctx "((complement even?) 2)")) "complement"))
|
||||
(print " ok")
|
||||
|
||||
# --- Destructuring ---
|
||||
(print "10: destructuring...")
|
||||
(let [ctx (init)]
|
||||
(assert (= 1 (ct-eval ctx "(let [[x] [1 2 3]] x)")) "seq destructure first")
|
||||
(assert (= 2 (ct-eval ctx "(let [[_ y] [1 2 3]] y)")) "seq destructure second"))
|
||||
(print " ok")
|
||||
|
||||
(print "\nAll Systematic Coverage tests passed!")
|
||||
Loading…
Add table
Add a link
Reference in a new issue