Round 2 of the persistent-collections work. Add a real 32-way branching-trie persistent vector (src/jolt/pv.janet) with a tail buffer: O(log32 n) conj/assoc/nth/pop, with unchanged subtrees shared by identity. Vector literals and vec/vector/conj/assoc/subvec/etc. now produce and maintain these in the default (immutable) build, replacing the old tuple-based vectors. Every core seq op, the destructurer, IFn application, the printers, =, and the evaluator's literal/splice paths were taught to handle the pvec type. Define several Clojure seq fns that were silently leaking to Janet builtins (some, keep, interleave, flatten, mapcat, interpose) and broke once vectors became tables; normalize collections through realize-for-iteration everywhere. Build-time JOLT_MUTABLE flag now selects fast Janet-native mutable collections: in that mode vectors are arrays (conj appends in place, vector? true, print []), sharing one representation with lists. Default build is immutable. Tests: conformance 206/206, features 71/71, jank 119 (baseline). Test helpers normalized so Janet-level = compares against tuple literals regardless of repr. The 2 test-load-sci failures (bit-clear/get-method) pre-date this work.
212 lines
11 KiB
Text
212 lines
11 KiB
Text
# Systematic coverage tests for Clojure language features
|
|
(use ../src/jolt/api)
|
|
(defn ct-eval [ctx s] (normalize-pvecs (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!")
|