test: fold cljs ports into spec; add exceptions spec + gap coverage

Mine the cljs port batteries into the spec layer and delete them (their behavior
is covered by spec; the unique functions they exercised are now specced).
Removed test/integration/ports/ entirely.

New/expanded spec coverage from the mining:
- spec/exceptions-spec: try/catch/finally, throw, ex-info/ex-message/ex-data/ex-cause
- doto, pr-str, keyword/symbol constructors, atom?, dynamic var binding

Two rare edges filed (jolt-...): rethrow of a caught ex-info re-wraps it; var-set
on a dynamic var inside binding no-ops. Core try/catch/ex-info and binding work.

Test layout is now spec (22 files, ~677 cases) / integration / unit / support.
conformance 218/218, jpm test green.
This commit is contained in:
Yogthos 2026-06-05 01:12:39 -04:00
parent bcd0e42b33
commit a681daf7b9
24 changed files with 46 additions and 822 deletions

View file

@ -17,6 +17,7 @@
{"_type":"issue","id":"jolt-90c","title":"MED: filter/take-while not lazy — infinite-seq (take N (filter p (range))) loops","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:10:00Z","created_by":"Yogthos","updated_at":"2026-06-04T18:56:26Z","closed_at":"2026-06-04T18:56:26Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-90c","title":"MED: filter/take-while not lazy — infinite-seq (take N (filter p (range))) loops","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:10:00Z","created_by":"Yogthos","updated_at":"2026-06-04T18:56:26Z","closed_at":"2026-06-04T18:56:26Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-7n5","title":"MED: REPL display — def/defn should print #'ns/name; lazy-seq printer realizes only head ((0 \u003cfunction\u003e))","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:59Z","created_by":"Yogthos","updated_at":"2026-06-04T18:55:11Z","closed_at":"2026-06-04T18:55:11Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-7n5","title":"MED: REPL display — def/defn should print #'ns/name; lazy-seq printer realizes only head ((0 \u003cfunction\u003e))","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:59Z","created_by":"Yogthos","updated_at":"2026-06-04T18:55:11Z","closed_at":"2026-06-04T18:55:11Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-h0n","title":"MED: missing core fns — letfn fnil trampoline doseq cycle partition-all reductions dedupe keep-indexed map-indexed transduce reduce-kv assoc-in peek subvec read-string format","status":"closed","priority":3,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:58Z","created_by":"Yogthos","updated_at":"2026-06-04T18:57:26Z","closed_at":"2026-06-04T18:57:26Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-h0n","title":"MED: missing core fns — letfn fnil trampoline doseq cycle partition-all reductions dedupe keep-indexed map-indexed transduce reduce-kv assoc-in peek subvec read-string format","status":"closed","priority":3,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:58Z","created_by":"Yogthos","updated_at":"2026-06-04T18:57:26Z","closed_at":"2026-06-04T18:57:26Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-dd5","title":"throw of a caught ex-info rethrows wrapped; var-set on dynamic var in binding no-ops","description":"Edges found via spec: (1) (catch :default e (throw e)) re-wraps the ex-info so the outer catch's (ex-message e) is nil. (2) (var-set #'*v* x) inside (binding [*v* ...] ...) doesn't update the thread-binding. Both rare; core try/catch/ex-info and dynamic binding work.","status":"open","priority":4,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-05T05:11:04Z","created_by":"Yogthos","updated_at":"2026-06-05T05:11:04Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-e4p","title":"regex: lookbehind, backreferences (\\1), named groups (?\u003cn\u003e) unsupported (rare); engine is parse-\u003ePEG with backtracking","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T20:23:39Z","created_by":"Yogthos","updated_at":"2026-06-05T05:02:24Z","closed_at":"2026-06-05T05:02:24Z","close_reason":"Won't-fix: backreferences and lookbehind are not expressible in a PEG engine (jolt regex compiles to Janet PEG); named groups are rare. Documented as unsupported in README's Regex section. Reopen if a concrete need arises.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-e4p","title":"regex: lookbehind, backreferences (\\1), named groups (?\u003cn\u003e) unsupported (rare); engine is parse-\u003ePEG with backtracking","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T20:23:39Z","created_by":"Yogthos","updated_at":"2026-06-05T05:02:24Z","closed_at":"2026-06-05T05:02:24Z","close_reason":"Won't-fix: backreferences and lookbehind are not expressible in a PEG engine (jolt regex compiles to Janet PEG); named groups are rare. Documented as unsupported in README's Regex section. Reopen if a concrete need arises.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-cn4","title":"regex engine is a common subset (PEG-backed); lookaround/backrefs/named-groups unsupported","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T19:27:50Z","created_by":"Yogthos","updated_at":"2026-06-04T20:23:37Z","closed_at":"2026-06-04T20:23:37Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-cn4","title":"regex engine is a common subset (PEG-backed); lookaround/backrefs/named-groups unsupported","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T19:27:50Z","created_by":"Yogthos","updated_at":"2026-06-04T20:23:37Z","closed_at":"2026-06-04T20:23:37Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-4zg","title":"char type: chars represented as 1-char strings; (seq \"ab\") yields strings not \\a \\b — deferred design decision","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T19:27:49Z","created_by":"Yogthos","updated_at":"2026-06-04T19:41:39Z","closed_at":"2026-06-04T19:41:39Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-4zg","title":"char type: chars represented as 1-char strings; (seq \"ab\") yields strings not \\a \\b — deferred design decision","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T19:27:49Z","created_by":"Yogthos","updated_at":"2026-06-04T19:41:39Z","closed_at":"2026-06-04T19:41:39Z","dependency_count":0,"dependent_count":0,"comment_count":0}

View file

@ -98,8 +98,8 @@ Tests are organized in three layers:
per public API area) that collectively pin down Jolt's defined behavior. This per public API area) that collectively pin down Jolt's defined behavior. This
is the authoritative description of what Jolt promises. is the authoritative description of what Jolt promises.
- **`test/integration/`** — cross-cutting and regression batteries: the Clojure - **`test/integration/`** — cross-cutting and regression batteries: the Clojure
conformance suite, SCI bootstrap/runtime loading, jank conformance, and ported conformance suite, SCI bootstrap/runtime loading, jank conformance, compile-mode
Clojure/CLJS test batches (`test/integration/ports/`). tests, and ported Clojure test batteries.
- **`test/unit/`** — white-box tests for individual components (reader, - **`test/unit/`** — white-box tests for individual components (reader,
evaluator, types, persistent collections, regex, compiler). evaluator, types, persistent collections, regex, compiler).

View file

@ -1,42 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "CLJS Collections Ported Tests")
(print "1: dissoc...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= {:a :b} (dissoc {:a :b :c :d} :c))")) "dissoc")
(assert (= true (ct-eval ctx "(= {} (dissoc {1 2 3 4} 1 3))")) "dissoc multi"))
(print " ok")
(print "2: assoc...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= {1 2 3 4} (assoc {} 1 2 3 4))")) "assoc multi")
(assert (= true (ct-eval ctx "(= {1 2} (assoc {} 1 2))")) "assoc single"))
(print " ok")
(print "3: set operations...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(set? (set []))")) "set empty")
(assert (= true (ct-eval ctx "(= #{\"foo\"} (set [\"foo\"]))")) "set from vec")
(assert (= true (ct-eval ctx "(= #{1 2 3} #{1 3 2})")) "set order")
(assert (= true (ct-eval ctx "(= #{1 2 3} (disj #{1 2 3}))")) "disj none")
(assert (= true (ct-eval ctx "(= #{1 2} (disj #{1 2 3} 3))")) "disj one")
(assert (= true (ct-eval ctx "(= #{1} (disj #{1 2 3} 2 3))")) "disj multi")
(assert (= true (ct-eval ctx "(= 4 (get #{1 2 3 4} 4))")) "get set")
(assert (= true (ct-eval ctx "(contains? #{1 2 3 4} 4)")) "contains? set"))
(print " ok")
(print "4: vector nth...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= :a (nth [:a :b :c :d] 0))")) "nth")
(assert (= true (ct-eval ctx "(= :c (nth [:a :b :c :d] 2 0.1))")) "nth float"))
(print " ok")
(print "5: range...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 0 (count (range 10 0 1)))")) "range empty")
(assert (= true (ct-eval ctx "(= 4 (count (range 0 10 3)))")) "range count")
(assert (= true (ct-eval ctx "(= 1 (count (range 0 1 1)))")) "range single"))
(print " ok")
(print "\nAll CLJS Collections Ported tests passed!")

View file

@ -1,90 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "CLJS Core Ported Tests")
(print "1: metadata on maps...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= {:foo \"bar\"} (meta (with-meta {:a 1} {:foo \"bar\"})))")) "with-meta on map"))
(print " ok")
(print "2: atoms...")
(let [ctx (init)]
(ct-eval ctx "(def a (atom 0))")
(assert (= true (ct-eval ctx "(= 0 (deref a))")) "deref")
(assert (= true (ct-eval ctx "(= 1 (swap! a inc))")) "swap! inc")
(ct-eval ctx "(def b (atom 0))")
(assert (= true (ct-eval ctx "(= 1 (swap! b + 1))")) "swap! + 1")
(assert (= true (ct-eval ctx "(= 4 (swap! b + 1 2))")) "swap! + 1 2")
(assert (= true (ct-eval ctx "(= 10 (swap! b + 1 2 3))")) "swap! + 1 2 3")
(assert (= true (ct-eval ctx "(= 20 (swap! b + 1 2 3 4))")) "swap! + 1 2 3 4")
(assert (= true (ct-eval ctx "(atom? (atom 0))")) "atom?")
(assert (= true (ct-eval ctx "(nil? (meta (atom 0)))")) "atom meta nil"))
(print " ok")
(print "3: contains?...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(contains? {:a 1 :b 2} :a)")) "contains? map key")
(assert (= true (ct-eval ctx "(not (contains? {:a 1 :b 2} :z))")) "contains? missing")
(assert (= true (ct-eval ctx "(contains? [5 6 7] 1)")) "contains? vector index")
(assert (= true (ct-eval ctx "(contains? [5 6 7] 2)")) "contains? vector index 2")
(assert (= true (ct-eval ctx "(not (contains? [5 6 7] 3))")) "contains? vector oob")
(assert (= true (ct-eval ctx "(not (contains? nil 42))")) "contains? nil"))
(print " ok")
(print "4: get-in...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 1 (get-in {:foo 1 :bar 2} [:foo]))")) "get-in flat")
(assert (= true (ct-eval ctx "(= 2 (get-in {:foo {:bar 2}} [:foo :bar]))")) "get-in nested"))
(print " ok")
(print "5: multimethods...")
(let [ctx (init)]
(ct-eval ctx "(defmulti greet (fn [x] (:lang x)))")
(ct-eval ctx "(defmethod greet :en [_] \"hello\")")
(ct-eval ctx "(defmethod greet :fr [_] \"bonjour\")")
(assert (= true (ct-eval ctx "(= \"hello\" (greet {:lang :en}))")) "dispatch :en")
(assert (= true (ct-eval ctx "(= \"bonjour\" (greet {:lang :fr}))")) "dispatch :fr"))
(print " ok")
(print "6: sequential equality...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= (list 3 2 1) [3 2 1])")) "list = vector")
(assert (= true (ct-eval ctx "(= () (rest nil))")) "rest nil")
(assert (= true (ct-eval ctx "(= () (rest [1]))")) "rest [1]")
(assert (= true (ct-eval ctx "(= () (rest ()))")) "rest empty"))
(print " ok")
(print "7: seq operations...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(nil? (seq []))")) "seq empty vec"))
(print " ok")
(print "8: empty and empty?...")
(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 (= true (ct-eval ctx "(not (empty? [1 2]))")) "empty? non-empty")
(assert (= true (ct-eval ctx "(not (empty? {:a 1}))")) "empty? non-empty map"))
(print " ok")
(print "9: distinct...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 0 (count (distinct ())))")) "distinct empty")
(assert (= true (ct-eval ctx "(= 1 (count (distinct '(1))))")) "distinct single")
(assert (= true (ct-eval ctx "(= 3 (count (distinct '(1 2 3 1 1 1))))")) "distinct multi count")
(assert (= true (ct-eval ctx "(= 1 (count (distinct [42 42])))")) "distinct nums count"))
(print " ok")
(print "10: some and some?...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(some? 1)")) "some? 1")
(assert (= true (ct-eval ctx "(not (some? nil))")) "some? nil")
(assert (= true (ct-eval ctx "(some even? [1 2 3])")) "some even?")
(assert (= true (ct-eval ctx "(nil? (some even? [1 3 5]))")) "some even? nil"))
(print " ok")
(print "\nAll CLJS Core Ported tests passed!")

View file

@ -1,110 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 1 ===")
(print "1: core math...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "(+ 1 2)")) "+")
(assert (= 0 (ct-eval ctx "(+)")) "+ zero")
(assert (= 1 (ct-eval ctx "(- 3 2)")) "-")
(assert (= 6 (ct-eval ctx "(* 2 3)")) "*")
(assert (= 2 (ct-eval ctx "(/ 4 2)")) "/")
(assert (= 3 (ct-eval ctx "(inc 2)")) "inc")
(assert (= 1 (ct-eval ctx "(dec 2)")) "dec")
(assert (= 1 (ct-eval ctx "(quot 5 3)")) "quot")
(assert (= 2 (ct-eval ctx "(rem 5 3)")) "rem")
(assert (= 2 (ct-eval ctx "(mod 5 3)")) "mod")
(assert (= 3 (ct-eval ctx "(max 1 2 3)")) "max")
(assert (= 1 (ct-eval ctx "(min 1 2 3)")) "min"))
(print " passed")
(print "2: predicates...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(nil? nil)")) "nil?")
(assert (= false (ct-eval ctx "(nil? 1)")) "nil? false")
(assert (= false (ct-eval ctx "(not true)")) "not")
(assert (= true (ct-eval ctx "(not false)")) "not false")
(assert (= true (ct-eval ctx "(some? 1)")) "some?")
(assert (= true (ct-eval ctx "(string? \"hello\")")) "string?")
(assert (= true (ct-eval ctx "(number? 42)")) "number?")
(assert (= true (ct-eval ctx "(fn? inc)")) "fn?")
(assert (= true (ct-eval ctx "(keyword? :foo)")) "keyword?")
(assert (= true (ct-eval ctx "(map? {:a 1})")) "map?")
(assert (= true (ct-eval ctx "(zero? 0)")) "zero?")
(assert (= true (ct-eval ctx "(pos? 5)")) "pos?")
(assert (= true (ct-eval ctx "(neg? -1)")) "neg?")
(assert (= true (ct-eval ctx "(even? 4)")) "even?")
(assert (= true (ct-eval ctx "(odd? 3)")) "odd?"))
(print " passed")
(print "3: comparison...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 1 1)")) "=")
(assert (= false (ct-eval ctx "(= 1 2)")) "= false")
(assert (= true (ct-eval ctx "(= 1 1 1)")) "= three")
(assert (= false (ct-eval ctx "(not= 1 1)")) "not= false")
(assert (= true (ct-eval ctx "(not= 1 2)")) "not= true")
(assert (= true (ct-eval ctx "(< 1 2)")) "<")
(assert (= true (ct-eval ctx "(> 2 1)")) ">")
(assert (= true (ct-eval ctx "(<= 1 1)")) "<=")
(assert (= true (ct-eval ctx "(>= 2 2)")) ">="))
(print " passed")
(print "4: vectors...")
(let [ctx (init)]
(assert (= :a (ct-eval ctx "(nth [:a :b :c :d] 0)")) "nth")
(assert (= [1 2 3 4] (ct-eval ctx "(conj [1 2 3] 4)")) "conj")
(assert (= 1 (ct-eval ctx "(first [1 2 3])")) "first")
(assert (= [2 3] (ct-eval ctx "(rest [1 2 3])")) "rest")
(assert (= 3 (ct-eval ctx "(count [1 2 3])")) "count"))
(print " passed")
(print "5: maps...")
(let [ctx (init)]
(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 (= {:a 1 :b 2} (ct-eval ctx "(assoc {:a 1} :b 2)")) "assoc")
(assert (= {:b 2} (ct-eval ctx "(dissoc {:a 1 :b 2} :a)")) "dissoc")
(assert (= true (ct-eval ctx "(contains? {:a 1} :a)")) "contains?")
(assert (= 3 (ct-eval ctx "(count {:a 1 :b 2 :c 3})")) "count")
(assert (= 2 (ct-eval ctx "(count (keys {:a 1 :b 2}))")) "keys count"))
(print " passed")
(print "6: sets...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(set? #{1 2 3})")) "set?")
(assert (= 4 (ct-eval ctx "(count (conj #{1 2 3} 4))")) "conj")
(assert (= 2 (ct-eval ctx "(count (disj #{1 2 3} 3))")) "disj")
(assert (= 3 (ct-eval ctx "(count #{1 2 3})")) "count")
(assert (= true (ct-eval ctx "(= #{1 2 3} #{3 2 1})")) "= order-independent"))
(print " passed")
(print "7: seq operations...")
(let [ctx (init)]
(assert (= nil (ct-eval ctx "(seq [])")) "seq empty")
(assert (= [2 3 4] (ct-eval ctx "(map inc [1 2 3])")) "map")
(assert (= 2 (ct-eval ctx "(count (filter odd? [1 2 3 4]))")) "filter")
(assert (= 6 (ct-eval ctx "(reduce + [1 2 3])")) "reduce")
(assert (= [1 2 3] (ct-eval ctx "(take 3 [1 2 3 4 5])")) "take")
(assert (= [4 5] (ct-eval ctx "(drop 3 [1 2 3 4 5])")) "drop")
(assert (= [3 2 1] (ct-eval ctx "(reverse [1 2 3])")) "reverse")
(assert (= true (ct-eval ctx "(every? even? [2 4 6])")) "every?"))
(print " passed")
(print "8: printing...")
(let [ctx (init)]
(assert (= "hello" (ct-eval ctx "(str \"hello\")")) "str")
(assert (= "ab" (ct-eval ctx "(str \"a\" \"b\")")) "str two")
(assert (= "42" (ct-eval ctx "(str 42)")) "str number")
(assert (= "" (ct-eval ctx "(str nil)")) "str nil -> empty string (Clojure semantics)")
(assert (= "a" (ct-eval ctx "(name :a)")) "name"))
(print " passed")
(print "9: apply...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "(apply + [1 2])")) "apply +")
(assert (= 3 (ct-eval ctx "(apply max [1 3 2])")) "apply max"))
(print " passed")
(print "10: equality across types...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= {:a 1 :b 2} {:b 2 :a 1})")) "map order-independent"))
(print " passed")
(print "11: higher-order fns...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "((comp inc inc) 1)")) "comp")
(assert (function? (ct-eval ctx "(partial + 1 2)")) "partial returns fn")
(assert (= 3 (ct-eval ctx "(identity 3)")) "identity"))
(print " passed")
(print "\nAll CLJS Ported Part 1 tests passed!")

View file

@ -1,25 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 10 ===")
(print "43: when/when-not...")
(let [ctx (init)]
(assert (= 42 (ct-eval ctx "(when true 42)")) "when true")
(assert (= nil (ct-eval ctx "(when false 42)")) "when false")
(assert (= 42 (ct-eval ctx "(when-not false 42)")) "when-not false"))
(print " ok")
(print "44: if-let/when-let...")
(let [ctx (init)]
(assert (= 2 (ct-eval ctx "(if-let [x 1] (inc x) 0)")) "if-let true")
(assert (= 0 (ct-eval ctx "(if-let [x nil] (inc x) 0)")) "if-let nil")
(assert (= 2 (ct-eval ctx "(when-let [x 1] (inc x))")) "when-let"))
(print " ok")
(print "45: doto...")
(let [ctx (init)]
(ct-eval ctx "(def x (atom []))")
(assert (= nil (ct-eval ctx "(doto nil)")) "doto nil returns nil"))
(print " ok")
(print "\nAll CLJS Ported Part 10 tests passed!\n")

View file

@ -1,77 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 1 ===")
(print "1: core math...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "(+ 1 2)")) "+")
(assert (= 0 (ct-eval ctx "(+)")) "+ zero")
(assert (= 1 (ct-eval ctx "(- 3 2)")) "-")
(assert (= 6 (ct-eval ctx "(* 2 3)")) "*")
(assert (= 2 (ct-eval ctx "(/ 4 2)")) "/")
(assert (= 3 (ct-eval ctx "(inc 2)")) "inc")
(assert (= 1 (ct-eval ctx "(dec 2)")) "dec")
(assert (= 1 (ct-eval ctx "(quot 5 3)")) "quot")
(assert (= 2 (ct-eval ctx "(rem 5 3)")) "rem")
(assert (= 2 (ct-eval ctx "(mod 5 3)")) "mod")
(assert (= 3 (ct-eval ctx "(max 1 2 3)")) "max")
(assert (= 1 (ct-eval ctx "(min 1 2 3)")) "min"))
(print " passed")
(print "2: predicates...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(nil? nil)")) "nil?")
(assert (= false (ct-eval ctx "(nil? 1)")) "nil? false")
(assert (= false (ct-eval ctx "(not true)")) "not")
(assert (= true (ct-eval ctx "(not false)")) "not false")
(assert (= true (ct-eval ctx "(some? 1)")) "some?")
(assert (= true (ct-eval ctx "(string? \"hello\")")) "string?")
(assert (= true (ct-eval ctx "(number? 42)")) "number?")
(assert (= true (ct-eval ctx "(fn? inc)")) "fn?")
(assert (= true (ct-eval ctx "(keyword? :foo)")) "keyword?")
(assert (= true (ct-eval ctx "(map? {:a 1})")) "map?")
(assert (= true (ct-eval ctx "(zero? 0)")) "zero?")
(assert (= true (ct-eval ctx "(pos? 5)")) "pos?")
(assert (= true (ct-eval ctx "(neg? -1)")) "neg?")
(assert (= true (ct-eval ctx "(even? 4)")) "even?")
(assert (= true (ct-eval ctx "(odd? 3)")) "odd?"))
(print " passed")
(print "3: comparison...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 1 1)")) "=")
(assert (= false (ct-eval ctx "(= 1 2)")) "= false")
(assert (= true (ct-eval ctx "(= 1 1 1)")) "= three")
(assert (= false (ct-eval ctx "(not= 1 1)")) "not= false")
(assert (= true (ct-eval ctx "(not= 1 2)")) "not= true")
(assert (= true (ct-eval ctx "(< 1 2)")) "<")
(assert (= true (ct-eval ctx "(> 2 1)")) ">")
(assert (= true (ct-eval ctx "(<= 1 1)")) "<=")
(assert (= true (ct-eval ctx "(>= 2 2)")) ">="))
(print " passed")
(print "4: vectors...")
(let [ctx (init)]
(assert (= :a (ct-eval ctx "(nth [:a :b :c :d] 0)")) "nth")
(assert (= [1 2 3 4] (ct-eval ctx "(conj [1 2 3] 4)")) "conj")
(assert (= 1 (ct-eval ctx "(first [1 2 3])")) "first")
(assert (= [2 3] (ct-eval ctx "(rest [1 2 3])")) "rest")
(assert (= 3 (ct-eval ctx "(count [1 2 3])")) "count"))
(print " passed")
(print "5: maps...")
(let [ctx (init)]
(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 (= {:a 1 :b 2} (ct-eval ctx "(assoc {:a 1} :b 2)")) "assoc")
(assert (= {:b 2} (ct-eval ctx "(dissoc {:a 1 :b 2} :a)")) "dissoc")
(assert (= true (ct-eval ctx "(contains? {:a 1} :a)")) "contains?")
(assert (= 3 (ct-eval ctx "(count {:a 1 :b 2 :c 3})")) "count")
(assert (= 2 (ct-eval ctx "(count (keys {:a 1 :b 2}))")) "keys count"))
(print " passed")
(print "6: sets...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(set? #{1 2 3})")) "set?")
(assert (= 4 (ct-eval ctx "(count (conj #{1 2 3} 4))")) "conj count")
(assert (= 2 (ct-eval ctx "(count (disj #{1 2 3} 3))")) "disj count")
(assert (= 3 (ct-eval ctx "(count #{1 2 3})")) "count")
(assert (= true (ct-eval ctx "(= #{1 2 3} #{3 2 1})")) "= order-independent"))
(print " passed")
(print "\nAll CLJS Ported Part 1a tests passed!")

View file

@ -1,37 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 1b ===")
(print "7: seq operations...")
(let [ctx (init)]
(assert (= nil (ct-eval ctx "(seq [])")) "seq empty")
(assert (= [2 3 4] (ct-eval ctx "(map inc [1 2 3])")) "map")
(assert (= [1 3] (ct-eval ctx "(filter odd? [1 2 3 4])")) "filter")
(assert (= 6 (ct-eval ctx "(reduce + [1 2 3])")) "reduce")
(assert (= [1 2 3] (ct-eval ctx "(take 3 [1 2 3 4 5])")) "take")
(assert (= [4 5] (ct-eval ctx "(drop 3 [1 2 3 4 5])")) "drop")
(assert (= [3 2 1] (ct-eval ctx "(reverse [1 2 3])")) "reverse")
(assert (= true (ct-eval ctx "(every? even? [2 4 6])")) "every?"))
(print " passed")
(print "8: printing...")
(let [ctx (init)]
(assert (= "hello" (ct-eval ctx "(str \"hello\")")) "str")
(assert (= "ab" (ct-eval ctx "(str \"a\" \"b\")")) "str two")
(assert (= "42" (ct-eval ctx "(str 42)")) "str number")
(assert (= "a" (ct-eval ctx "(name :a)")) "name"))
(print " passed")
(print "9: apply...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "(apply + [1 2])")) "apply +")
(assert (= 3 (ct-eval ctx "(apply max [1 3 2])")) "apply max"))
(print " passed")
(print "10: equality...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= {:a 1 :b 2} {:b 2 :a 1})")) "map order"))
(print " passed")
(print "11: higher-order fns...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "((comp inc inc) 1)")) "comp")
(assert (function? (ct-eval ctx "(partial + 1 2)")) "partial returns fn")
(assert (= 3 (ct-eval ctx "(identity 3)")) "identity"))
(print " passed")
(print "\nAll CLJS Ported Part 1b tests passed!")

View file

@ -1,77 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 2 ===")
(print "12: atoms...")
(let [ctx (init)]
(assert (= 0 (ct-eval ctx "(deref (atom 0))")) "deref")
(assert (= 1 (ct-eval ctx "(let [a (atom 0)] (swap! a inc) (deref a))")) "swap!")
(assert (= true (ct-eval ctx "(atom? (atom 0))")) "atom?"))
(print " ok")
(print "13: special forms...")
(let [ctx (init)]
(assert (= 30 (ct-eval ctx "(let [x 10 y 20] (+ x y))")) "let")
(assert (= :a (ct-eval ctx "(if true :a :b)")) "if true")
(assert (= :b (ct-eval ctx "(if false :a :b)")) "if false")
(assert (= 2 (ct-eval ctx "(do 1 2)")) "do")
(assert (= 3 (ct-eval ctx "(loop [x 0] (if (< x 3) (recur (inc x)) x))")) "loop")
(assert (= "caught" (ct-eval ctx "(try (throw 42) (catch Exception e \"caught\"))")) "try catch"))
(print " ok")
(print "14: macros...")
(let [ctx (init)]
(ct-eval ctx "(defn add [a b] (+ a b))")
(assert (= 7 (ct-eval ctx "(add 3 4)")) "defn")
(assert (= 42 (ct-eval ctx "(when true 42)")) "when")
(assert (= 3 (ct-eval ctx "(and 1 2 3)")) "and")
(assert (= 1 (ct-eval ctx "(or 1 2 3)")) "or")
(assert (= 49 (ct-eval ctx "((fn [x] (* x x)) 7)")) "fn"))
(print " ok")
(print "15: constructors...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "(count (vector 1 2 3))")) "vector count")
(assert (= 2 (ct-eval ctx "(count (hash-map :a 1 :b 2))")) "hash-map count")
(assert (= 3 (ct-eval ctx "(count (hash-set 1 2 3))")) "hash-set count")
(assert (= 3 (ct-eval ctx "(count (zipmap [:a :b :c] [1 2 3]))")) "zipmap count"))
(print " ok")
(print "16: printing...")
(let [ctx (init)]
(assert (= "hello" (ct-eval ctx "(str \"hello\")")) "str")
(assert (= "42" (ct-eval ctx "(str 42)")) "str number")
(assert (= "a" (ct-eval ctx "(name :a)")) "name")
(assert (= ":hello" (ct-eval ctx "(pr-str :hello)")) "pr-str keyword"))
(print " ok")
(print "17: apply...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "(apply + [1 2])")) "apply +")
(assert (= 3 (ct-eval ctx "(apply max [1 3 2])")) "apply max"))
(print " ok")
(print "18: equality...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= {:a 1 :b 2} {:b 2 :a 1})")) "map order-independent")
(assert (= false (ct-eval ctx "(= {:a 1} {:a 2})")) "map different values")
(assert (= 1 (ct-eval ctx "(:a (with-meta {:a 1} {:c 3}))")) "with-meta preserves value")
(assert (= 3 (ct-eval ctx "(:c (with-meta {:a 1} {:c 3}))")) "with-meta preserves meta via get"))
(print " ok")
(print "19: higher-order...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "((comp inc inc) 1)")) "comp")
(assert (function? (ct-eval ctx "(partial + 1 2)")) "partial returns fn")
(assert (= 3 (ct-eval ctx "(identity 3)")) "identity"))
(print " ok")
(print "20: seq edge cases...")
(let [ctx (init)]
(assert (= nil (ct-eval ctx "(seq [])")) "seq empty")
(assert (= nil (ct-eval ctx "(seq nil)")) "seq nil")
(assert (= nil (ct-eval ctx "(first nil)")) "first nil")
(assert (= 1 (ct-eval ctx "(first [1 2 3])")) "first vector"))
(print " ok")
(print "21: atoms extended...")
(let [ctx (init)]
(ct-eval ctx "(def a (atom 10))")
(assert (= 10 (ct-eval ctx "(deref a)")) "deref")
(ct-eval ctx "(reset! a 42)")
(assert (= 42 (ct-eval ctx "(deref a)")) "reset!")
(ct-eval ctx "(swap! a inc)")
(assert (= 43 (ct-eval ctx "(deref a)")) "swap! inc")
(assert (= 43 (ct-eval ctx "@a")) "@ deref macro"))
(print " ok")
(print "\nAll CLJS Ported Part 2 tests passed!")

View file

@ -1,32 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 3 ===")
(print "16: destructuring...")
(let [ctx (init)]
(assert (= 1 (ct-eval ctx "(let [[x] [1 2 3]] x)")) "seq destructure")
(assert (= 2 (ct-eval ctx "(let [[_ y] [1 2 3]] y)")) "seq destructure rest")
(assert (= 3 (ct-eval ctx "(let [[_ _ z] [1 2 3]] z)")) "seq destructure last"))
(print " passed")
(print "17: set operations...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(set? #{1 2 3})")) "set?")
(assert (= 3 (ct-eval ctx "(count #{1 2 3})")) "set count")
(assert (= true (ct-eval ctx "(contains? #{1 2} 1)")) "contains? set")
(assert (= 1 (ct-eval ctx "(get #{1 2 3} 1)")) "get set"))
(print " passed")
(print "18: reader literals...")
(let [ctx (init)]
(assert (= [1 2 3] (ct-eval ctx "[1 2 3]")) "vector literal")
(assert (= {:a 1} (ct-eval ctx "{:a 1}")) "map literal")
(assert (= true (ct-eval ctx "true")) "true literal")
(assert (= nil (ct-eval ctx "nil")) "nil literal")
(assert (= 42 (ct-eval ctx "42")) "number literal"))
(print " passed")
(print "19: syntax-quote...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= '(1 2 3) '(1 2 3))")) "sq basic list"))
(print " passed")
(print "20: walk...")
(print " skipped (clojure.walk needs IFn protocol)")
(print "\nAll CLJS Ported Part 3 tests passed!")

View file

@ -1,22 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 3b ===")
(print "21: clojure.string...")
(let [ctx (init)]
(load-string ctx (slurp "src/jolt/clojure/string.clj"))
(assert (= true (ct-eval ctx "(blank? nil)")) "blank? nil")
(assert (= true (ct-eval ctx "(blank? \" \")")) "blank? spaces")
(assert (= "Abc" (ct-eval ctx "(capitalize \"abc\")")) "capitalize")
(assert (= "hello" (ct-eval ctx "(lower-case \"HELLO\")")) "lower-case")
(assert (= "hello" (ct-eval ctx "(trim \" hello \")")) "trim"))
(print " passed")
(print "22: clojure.set...")
(let [ctx (init)]
(load-string ctx (slurp "src/jolt/clojure/set.clj"))
(assert (= 3 (ct-eval ctx "(count (union #{1 2} #{2 3}))")) "union")
(assert (= 1 (ct-eval ctx "(count (intersection #{1 2} #{2 3}))")) "intersection")
(assert (= 1 (ct-eval ctx "(count (difference #{1 2} #{2 3}))")) "difference"))
(print " passed")
(print "\nAll CLJS Ported Part 3 tests passed!")
(print "\nAll CLJS Ported Part 3b tests passed!")

View file

@ -1,48 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 4 ===")
(print "23: deftype/defrecord...")
(let [ctx (init)]
(ct-eval ctx "(deftype Point [x y])")
(assert (= true (ct-eval ctx "(instance? Point (Point. 3 4))")) "instance? true")
(assert (= 3 (ct-eval ctx "(. (Point. 3 4) x)")) ".field access")
(ct-eval ctx "(defrecord Person [name age])")
(assert (= true (ct-eval ctx "(map? (Person. \"A\" 30))")) "record is map?")
(assert (= "Alice" (ct-eval ctx "(:name (Person. \"Alice\" 30))")) "record keyword access"))
(print " ok")
(print "24: multimethods...")
(let [ctx (init)]
(ct-eval ctx "(defmulti greet (fn [x] (:lang x)))")
(ct-eval ctx "(defmethod greet :en [_] \"hello\")")
(ct-eval ctx "(defmethod greet :fr [_] \"bonjour\")")
(assert (= "hello" (ct-eval ctx "(greet {:lang :en})")) "dispatch :en")
(assert (= "bonjour" (ct-eval ctx "(greet {:lang :fr})")) "dispatch :fr"))
(print " ok")
(print "25: protocols...")
(let [ctx (init)]
(ct-eval ctx "(defprotocol Greet (g [this]))")
(ct-eval ctx "(deftype Dog [name])")
(ct-eval ctx "(extend-type Dog Greet (g [this] (str \"woof \" (.-name this))))")
(assert (= "woof Rex" (ct-eval ctx "(g (Dog. \"Rex\"))")) "extend-type"))
(print " ok")
(print "26: var system...")
(let [ctx (init)]
(ct-eval ctx "(def xv 42)")
(assert (= true (ct-eval ctx "(var? (var xv))")) "var?")
(assert (= 42 (ct-eval ctx "(var-get (var xv))")) "var-get")
(ct-eval ctx "(var-set (var xv) 99)")
(assert (= 99 (ct-eval ctx "(var-get (var xv))")) "var-set"))
(print " ok")
(print "27: range/into/concat...")
(let [ctx (init)]
(assert (= 5 (ct-eval ctx "(count (range 5))")) "range count")
(assert (= [0 1 2 3 4] (ct-eval ctx "(into [] (range 5))")) "range into vec")
(assert (= 4 (ct-eval ctx "(count (concat [1 2] [3 4]))")) "concat count"))
(print " ok")
(print "\nAll CLJS Ported Part 4 tests passed!")

View file

@ -1,22 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 5 ===")
(print "22: destructuring...")
(let [ctx (init)]
(assert (= 1 (ct-eval ctx "(let [[x] [1 2 3]] x)")) "seq destructure")
(assert (= 2 (ct-eval ctx "(let [[_ y] [1 2 3]] y)")) "seq destructure rest"))
(print " ok")
(print "23: metadata...")
(let [ctx (init)]
(ct-eval ctx "(def ^:dynamic *dyn* 42)")
(assert (= true (ct-eval ctx "(var-dynamic? (var *dyn*))")) "dynamic metadata")
(assert (= 1 (ct-eval ctx "(:a (with-meta {:a 1} {:c 3}))")) "with-meta preserves"))
(print " ok")
(print "24: function composition...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "((complement odd?) 2)")) "complement")
(assert (= 5 (ct-eval ctx "((constantly 5) :anything)")) "constantly")
(assert (= true (ct-eval ctx "((every-pred number? even?) 4)")) "every-pred")
(assert (= ":hello" (ct-eval ctx "(pr-str :hello)")) "pr-str keyword"))
(print " ok")
(print "\nAll CLJS Ported Part 5 tests passed!")

View file

@ -1,30 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 6 ===")
(print "28: anon fn #()...")
(let [ctx (init)]
(assert (= 6 (ct-eval ctx "(#(+ % 5) 1)")) "#() %")
(assert (= 0 (ct-eval ctx "(#(do 0))")) "#() do body"))
(print " ok")
(print "29: symbol operations...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(symbol? 'foo)")) "symbol?")
(assert (= "foo" (ct-eval ctx "(name 'foo)")) "name symbol")
(assert (= "bar" (ct-eval ctx "(name :bar)")) "name keyword"))
(print " ok")
(print "30: keyword operations...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(keyword? :foo)")) "keyword?")
(assert (= :foo (ct-eval ctx "(keyword \"foo\")")) "keyword string"))
(print " ok")
(print "31: list operations...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "(count (list 3 2 1))")) "list count")
(assert (= 1 (ct-eval ctx "(first '(1 2 3))")) "first list"))
(print " ok")
(print "\nAll CLJS Ported Part 6 tests passed!\n")

View file

@ -1,20 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 7 ===")
(print "32: seq destructuring...")
(let [ctx (init)]
(assert (= 1 (ct-eval ctx "(let [[x] [1 2 3]] x)")) "seq destructure")
(assert (= 2 (ct-eval ctx "(let [[_ y] [1 2 3]] y)")) "seq destructure skip")
(assert (= 3 (ct-eval ctx "(let [[_ _ z] [1 2 3]] z)")) "seq destructure end"))
(print " ok")
(print "33: & rest args...")
(let [ctx (init)]
(ct-eval ctx "(defn sum [& xs] (apply + xs))")
(assert (= 6 (ct-eval ctx "(sum 1 2 3)")) "& rest sum")
(ct-eval ctx "(defn first-two [a b & rest] (count rest))")
(assert (= 2 (ct-eval ctx "(first-two 1 2 3 4)")) "& rest after fixed"))
(print " ok")
(print "\nAll CLJS Ported Part 7 tests passed!\n")

View file

@ -1,35 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 8 ===")
(print "35: range and repeat...")
(let [ctx (init)]
(assert (= 5 (ct-eval ctx "(count (range 5))")) "range")
(assert (= 4 (ct-eval ctx "(count (repeat 4 :x))")) "repeat")
(assert (= 3 (ct-eval ctx "(count (repeatedly 3 (constantly :y)))")) "repeatedly"))
(print " ok")
(print "36: concat and into...")
(let [ctx (init)]
(assert (= 4 (ct-eval ctx "(count (concat [1 2] [3 4]))")) "concat")
(assert (= 4 (ct-eval ctx "(count (into [] (range 4)))")) "into"))
(print " ok")
(print "37: take-while/drop-while...")
(let [ctx (init)]
(assert (= 2 (ct-eval ctx "(count (take-while even? [2 4 3 5]))")) "take-while")
(assert (= 2 (ct-eval ctx "(count (drop-while even? [2 4 3 5]))")) "drop-while"))
(print " ok")
(print "38: partition...")
(let [ctx (init)]
(assert (= 2 (ct-eval ctx "(count (partition 2 [1 2 3 4]))")) "partition 2"))
(print " ok")
(print "39: sorting...")
(let [ctx (init)]
(assert (= [1 2 3] (ct-eval ctx "(sort [3 1 2])")) "sort")
(assert (= [1 2 3] (ct-eval ctx "(distinct [1 2 1 3 2])")) "distinct"))
(print " ok")
(print "\nAll CLJS Ported Part 8 tests passed!\n")

View file

@ -1,18 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "=== CLJS Ported Part 9 ===")
(print "40: seq predicates...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(empty? [])")) "empty? true")
(assert (= false (ct-eval ctx "(empty? [1])")) "empty? false")
(assert (= true (ct-eval ctx "(every? pos? [1 2 3])")) "every? pos"))
(print " ok")
(print "41: complement...")
(let [ctx (init)]
(assert (= false (ct-eval ctx "((complement pos?) 1)")) "complement pos")
(assert (= true (ct-eval ctx "((complement pos?) -1)")) "complement neg"))
(print " ok")
(print "\nAll CLJS Ported Part 9 tests passed!\n")

View file

@ -1,131 +0,0 @@
(use ../../../src/jolt/api)
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
(print "CLJS Ported Tests")
(print "1: math...")
(let [ctx (init)]
(assert (= 3 (ct-eval ctx "(+ 1 2)")) "+")
(assert (= 1 (ct-eval ctx "(- 3 2)")) "-")
(assert (= 6 (ct-eval ctx "(* 2 3)")) "*")
(assert (= 3 (ct-eval ctx "(inc 2)")) "inc")
(assert (= 1 (ct-eval ctx "(dec 2)")) "dec")
(assert (= 1 (ct-eval ctx "(quot 5 3)")) "quot")
(assert (= 2 (ct-eval ctx "(rem 5 3)")) "rem")
(assert (= 2 (ct-eval ctx "(mod 5 3)")) "mod")
(assert (= 3 (ct-eval ctx "(max 1 2 3)")) "max")
(assert (= 1 (ct-eval ctx "(min 1 2 3)")) "min"))
(print " ok")
(print "2: predicates...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(nil? nil)")) "nil?")
(assert (= false (ct-eval ctx "(nil? 1)")) "nil? false")
(assert (= false (ct-eval ctx "(not true)")) "not")
(assert (= true (ct-eval ctx "(not false)")) "not false")
(assert (= true (ct-eval ctx "(some? 1)")) "some?")
(assert (= true (ct-eval ctx "(number? 42)")) "number?")
(assert (= true (ct-eval ctx "(fn? inc)")) "fn?")
(assert (= true (ct-eval ctx "(keyword? :foo)")) "keyword?")
(assert (= true (ct-eval ctx "(zero? 0)")) "zero?")
(assert (= true (ct-eval ctx "(pos? 5)")) "pos?")
(assert (= true (ct-eval ctx "(neg? -1)")) "neg?")
(assert (= true (ct-eval ctx "(even? 4)")) "even?")
(assert (= true (ct-eval ctx "(odd? 3)")) "odd?"))
(print " ok")
(print "3: comparison...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 1 1)")) "=")
(assert (= true (ct-eval ctx "(not= 1 2)")) "not= true")
(assert (= true (ct-eval ctx "(< 1 2)")) "<")
(assert (= true (ct-eval ctx "(> 2 1)")) ">")
(assert (= true (ct-eval ctx "(<= 1 1)")) "<=")
(assert (= true (ct-eval ctx "(>= 2 2)")) ">="))
(print " ok")
(print "4: vectors...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= :a (nth [:a :b :c :d] 0))")) "nth")
(assert (= true (ct-eval ctx "(= 4 (count (conj [1 2 3] 4)))")) "conj count")
(assert (= true (ct-eval ctx "(= 1 (first [1 2 3]))")) "first")
(assert (= true (ct-eval ctx "(= 2 (count (rest [1 2 3])))")) "rest count")
(assert (= true (ct-eval ctx "(= 3 (count [1 2 3]))")) "count"))
(print " ok")
(print "5: maps...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 1 (get {:a 1} :a))")) "get")
(assert (= true (ct-eval ctx "(nil? (get {:a 1} :z))")) "get missing")
(assert (= true (ct-eval ctx "(= :d (get {:a 1} :z :d))")) "get default")
(assert (= true (ct-eval ctx "(= 2 (count (assoc {:a 1} :b 2)))")) "assoc count")
(assert (= true (ct-eval ctx "(= 1 (count (dissoc {:a 1 :b 2} :a)))")) "dissoc count")
(assert (= true (ct-eval ctx "(contains? {:a 1} :a)")) "contains?")
(assert (= true (ct-eval ctx "(= 3 (count {:a 1 :b 2 :c 3}))")) "count")
(assert (= true (ct-eval ctx "(= 2 (count (keys {:a 1 :b 2})))")) "keys"))
(print " ok")
(print "6: sets...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(set? #{1 2 3})")) "set?")
(assert (= true (ct-eval ctx "(= 4 (count (conj #{1 2 3} 4)))")) "conj count")
(assert (= true (ct-eval ctx "(= 2 (count (disj #{1 2 3} 3)))")) "disj count")
(assert (= true (ct-eval ctx "(= 3 (count #{1 2 3}))")) "count")
(assert (= true (ct-eval ctx "(= #{1 2 3} #{3 2 1})")) "= order"))
(print " ok")
(print "7: seq ops...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(nil? (seq []))")) "seq empty")
(assert (= true (ct-eval ctx "(= 3 (count (map inc [1 2 3])))")) "map count")
(assert (= true (ct-eval ctx "(= 2 (count (filter odd? [1 2 3 4])))")) "filter count")
(assert (= true (ct-eval ctx "(= 6 (reduce + [1 2 3]))")) "reduce")
(assert (= true (ct-eval ctx "(= 3 (count (take 3 [1 2 3 4 5])))")) "take count")
(assert (= true (ct-eval ctx "(= 2 (count (drop 3 [1 2 3 4 5])))")) "drop count")
(assert (= true (ct-eval ctx "(= 3 (count (reverse [1 2 3])))")) "reverse count")
(assert (= true (ct-eval ctx "(every? even? [2 4 6])")) "every?"))
(print " ok")
(print "8: atoms...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 0 (deref (atom 0)))")) "deref")
(assert (= true (ct-eval ctx "(= 1 (let [a (atom 0)] (swap! a inc) (deref a)))")) "swap!")
(assert (= true (ct-eval ctx "(atom? (atom 0))")) "atom?"))
(print " ok")
(print "9: special forms...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 30 (let [x 10 y 20] (+ x y)))")) "let")
(assert (= true (ct-eval ctx "(= :a (if true :a :b))")) "if true")
(assert (= true (ct-eval ctx "(= :b (if false :a :b))")) "if false")
(assert (= true (ct-eval ctx "(= 2 (do 1 2))")) "do")
(assert (= true (ct-eval ctx "(= 3 (loop [x 0] (if (< x 3) (recur (inc x)) x)))")) "loop")
(assert (= true (ct-eval ctx "(= :caught (try (throw 42) (catch Exception e :caught)))")) "try"))
(print " ok")
(print "10: macros...")
(let [ctx (init)]
(ct-eval ctx "(defn add [a b] (+ a b))")
(assert (= true (ct-eval ctx "(= 7 (add 3 4))")) "defn")
(assert (= true (ct-eval ctx "(= 42 (when true 42))")) "when")
(assert (= true (ct-eval ctx "(= 3 (and 1 2 3))")) "and")
(assert (= true (ct-eval ctx "(= 1 (or 1 2 3))")) "or")
(assert (= true (ct-eval ctx "(= 49 ((fn [x] (* x x)) 7))")) "fn"))
(print " ok")
(print "11: higher-order...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 3 ((comp inc inc) 1))")) "comp")
(assert (= true (ct-eval ctx "(= 3 ((partial + 1 2)))")) "partial")
(assert (= true (ct-eval ctx "(= 5 ((constantly 5) :anything))")) "constantly")
(assert (= true (ct-eval ctx "(= 3 (identity 3))")) "identity"))
(print " ok")
(print "12: constructors...")
(let [ctx (init)]
(assert (= true (ct-eval ctx "(= 3 (count (vector 1 2 3)))")) "vector count")
(assert (= true (ct-eval ctx "(= 2 (count (hash-map :a 1 :b 2)))")) "hash-map count")
(assert (= true (ct-eval ctx "(= 3 (count (hash-set 1 2 3)))")) "hash-set count")
(assert (= true (ct-eval ctx "(= 3 (count (zipmap [:a :b :c] [1 2 3])))")) "zipmap count"))
(print " ok")
(print "\nAll CLJS Ported Tests passed!")

View file

@ -59,4 +59,5 @@
["some-> nil stops" "nil" "(some-> nil inc)"] ["some-> nil stops" "nil" "(some-> nil inc)"]
["some->>" "[2 3]" "(some->> [1 2] (map inc))"] ["some->>" "[2 3]" "(some->> [1 2] (map inc))"]
["cond->" "2" "(cond-> 1 true inc false inc)"] ["cond->" "2" "(cond-> 1 true inc false inc)"]
["cond->>" "[1 2]" "(cond->> [2] true (cons 1))"]) ["cond->>" "[1 2]" "(cond->> [2] true (cons 1))"]
["doto returns subject" "5" "(let [a (doto (atom 0) (reset! 5))] @a)"])

View file

@ -0,0 +1,28 @@
# Specification: exceptions — try/catch/finally, throw, ex-info.
(use ../support/harness)
(defspec "exceptions / try-catch"
["catch :default" ":caught"
"(try (throw (ex-info \"boom\" {})) (catch :default e :caught))"]
["catch by class" ":caught"
"(try (throw (ex-info \"boom\" {})) (catch Exception e :caught))"]
["catch binds error" "\"boom\""
"(try (throw (ex-info \"boom\" {})) (catch :default e (ex-message e)))"]
["no throw -> body" "1"
"(try 1 (catch :default e :caught))"]
["finally runs on ok" "2"
"(let [a (atom 0)] (try 2 (finally (reset! a 9))) )"]
["finally runs on throw" "9"
"(let [a (atom 0)] (try (throw (ex-info \"x\" {})) (catch :default e nil) (finally (reset! a 9))) @a)"]
["catch value of body" "5"
"(try (+ 2 3) (catch :default e 0))"])
(defspec "exceptions / ex-info"
["ex-message" "\"oops\"" "(ex-message (ex-info \"oops\" {}))"]
["ex-data" "{:k 1}" "(ex-data (ex-info \"oops\" {:k 1}))"]
["ex-data via catch" "{:code 42}"
"(try (throw (ex-info \"e\" {:code 42})) (catch :default e (ex-data e)))"]
["ex-cause" "true"
"(let [c (ex-info \"root\" {})] (= c (ex-cause (ex-info \"outer\" {} c))))"]
["propagates to outer" "\"inner\""
"(try (try (throw (ex-info \"inner\" {})) (finally nil)) (catch :default e (ex-message e)))"])

View file

@ -9,7 +9,9 @@
["var sugar #'" "true" "(var? #'+)"] ["var sugar #'" "true" "(var? #'+)"]
["var-get" "5" "(do (def w 5) (var-get #'w))"] ["var-get" "5" "(do (def w 5) (var-get #'w))"]
["defn defines fn" "3" "(do (defn f [x] (inc x)) (f 2))"] ["defn defines fn" "3" "(do (defn f [x] (inc x)) (f 2))"]
["def with docstring" "7" "(do (def d \"a doc\" 7) d)"]) ["def with docstring" "7" "(do (def d \"a doc\" 7) d)"]
["dynamic var binding" "2" "(do (def ^:dynamic *x* 1) (binding [*x* 2] *x*))"]
["binding restores" "1" "(do (def ^:dynamic *y* 1) (binding [*y* 9] nil) *y*)"])
(defspec "namespaces / ns operations" (defspec "namespaces / ns operations"
["in-ns switches" "true" "(do (in-ns 'my.ns) (symbol? 'x))"] ["in-ns switches" "true" "(do (in-ns 'my.ns) (symbol? 'x))"]

View file

@ -47,7 +47,11 @@
["name of keyword" "\"a\"" "(name :a)"] ["name of keyword" "\"a\"" "(name :a)"]
["name of qualified" "\"b\"" "(name :a/b)"] ["name of qualified" "\"b\"" "(name :a/b)"]
["namespace" "\"a\"" "(namespace :a/b)"] ["namespace" "\"a\"" "(namespace :a/b)"]
["namespace simple" "nil" "(namespace :a)"]) ["namespace simple" "nil" "(namespace :a)"]
["keyword constructor" ":foo" "(keyword \"foo\")"]
["keyword ns + name" ":a/b" "(keyword \"a\" \"b\")"]
["symbol constructor" "(quote x)" "(symbol \"x\")"]
["name of string" "\"s\"" "(name \"s\")"])
(defspec "predicates / equality & identity" (defspec "predicates / equality & identity"
["= same" "true" "(= 1 1)"] ["= same" "true" "(= 1 1)"]

View file

@ -13,7 +13,9 @@
["reset-vals!" "[0 9]" "(let [a (atom 0)] (reset-vals! a 9))"] ["reset-vals!" "[0 9]" "(let [a (atom 0)] (reset-vals! a 9))"]
["compare-and-set! ok" "true" "(let [a (atom 0)] (compare-and-set! a 0 1))"] ["compare-and-set! ok" "true" "(let [a (atom 0)] (compare-and-set! a 0 1))"]
["compare-and-set! no" "false" "(let [a (atom 0)] (compare-and-set! a 9 1))"] ["compare-and-set! no" "false" "(let [a (atom 0)] (compare-and-set! a 9 1))"]
["atom?" "true" "(do (require (quote [clojure.core])) (instance? clojure.lang.Atom (atom 0)))"]) ["atom?" "true" "(do (require (quote [clojure.core])) (instance? clojure.lang.Atom (atom 0)))"]
["atom? predicate" "true" "(atom? (atom 0))"]
["atom? on non-atom" "false" "(atom? 5)"])
(defspec "state / watches & validators" (defspec "state / watches & validators"
["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)"] ["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)"]

View file

@ -11,6 +11,8 @@
["subs from" "\"bc\"" "(subs \"abc\" 1)"] ["subs from" "\"bc\"" "(subs \"abc\" 1)"]
["subs range" "\"b\"" "(subs \"abc\" 1 2)"] ["subs range" "\"b\"" "(subs \"abc\" 1 2)"]
["string? true" "true" "(string? \"x\")"] ["string? true" "true" "(string? \"x\")"]
["pr-str vector" "\"[1 2 3]\"" "(pr-str [1 2 3])"]
["pr-str quotes str" "\"\\\"hi\\\"\"" "(pr-str \"hi\")"]
["seq of string" "[\\a \\b]" "(seq \"ab\")"]) ["seq of string" "[\\a \\b]" "(seq \"ab\")"])
(defspec "clojure.string" (defspec "clojure.string"