diff options
author | Daniel Solano Gómez <clojure@sattvik.com> | 2010-04-21 13:43:47 -0500 |
---|---|---|
committer | Stuart Halloway <stu@thinkrelevance.com> | 2010-04-27 15:35:10 -0400 |
commit | a3d1d494e9e574599c50dd83749183c66f653192 (patch) | |
tree | c250e40af2e5e8577a3e909a1070487940282ce6 | |
parent | 5ad8870076bf991dd6f81e596be424d5d965956b (diff) |
Add Comparable support to Vec, with tests. Fixes #266.
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
-rw-r--r-- | src/clj/clojure/gvec.clj | 17 | ||||
-rw-r--r-- | test/clojure/test_clojure/vectors.clj | 198 |
2 files changed, 214 insertions, 1 deletions
diff --git a/src/clj/clojure/gvec.clj b/src/clj/clojure/gvec.clj index f9e65ba5..ce4fb7d7 100644 --- a/src/clj/clojure/gvec.clj +++ b/src/clj/clojure/gvec.clj @@ -335,6 +335,23 @@ (aset arr subidx (.doAssoc this (- level (int 5)) (aget arr subidx) i val)) (VecNode. (.edit node) arr)))) + java.lang.Comparable + (compareTo [this o] + (if (identical? this o) + 0 + (let [ocnt (.count (cast clojure.lang.IPersistentVector o))] + (cond + (< cnt ocnt) -1 + (> cnt ocnt) 1 + :else + (loop [i (int 0)] + (if (= i cnt) + 0 + (let [comp (clojure.lang.Util/compare (.nth this i) (.nth o i))] + (if (= 0 comp) + (recur (inc i)) + comp)))))))) + java.lang.Iterable (iterator [this] (let [i (java.util.concurrent.atomic.AtomicInteger. 0)] diff --git a/test/clojure/test_clojure/vectors.clj b/test/clojure/test_clojure/vectors.clj index 35341e85..00408d22 100644 --- a/test/clojure/test_clojure/vectors.clj +++ b/test/clojure/test_clojure/vectors.clj @@ -6,7 +6,7 @@ ; the terms of this license. ; You must not remove this notice, or any other, from this software. -; Author: Stuart Halloway +; Author: Stuart Halloway, Daniel Solano Gómez (ns clojure.test-clojure.vectors (:use clojure.test)) @@ -78,3 +78,199 @@ vs vs-32 vs-32 vs vs nil)))) + +(deftest test-vec + (let [ nums (range 1 100) + ; randomly replaces a single item with the given value + rand-replace (fn[val] + (let [r (rand-int 100)] + (concat (take r nums) [val] (drop (inc r) nums)))) + ; all num sequences in map + num-seqs {:standard nums + :empty '() + ; different lengths + :longer (concat nums [100]) + :shorter (drop-last nums) + ; greater by value + :first-greater (concat [100] (next nums)) + :last-greater (concat (drop-last nums) [100]) + :rand-greater-1 (rand-replace 100) + :rand-greater-2 (rand-replace 100) + :rand-greater-3 (rand-replace 100) + ; lesser by value + :first-lesser (concat [0] (next nums)) + :last-lesser (concat (drop-last nums) [0]) + :rand-lesser-1 (rand-replace 0) + :rand-lesser-2 (rand-replace 0) + :rand-lesser-3 (rand-replace 0)} + ; a way to create compare values based on num-seqs + create-vals (fn[base-val] + (zipmap (keys num-seqs) + (map #(into base-val %1) (vals num-seqs)))) + ; Vecs made of int primitives + int-vecs (create-vals (vector-of :int)) + ; Vecs made of long primitives + long-vecs (create-vals (vector-of :long)) + ; standard boxing vectors + regular-vecs (create-vals []) + ; the standard int Vec for comparisons + int-vec (:standard int-vecs)] + (testing "compare" + (testing "identical" + (is (= 0 (compare int-vec int-vec)))) + (testing "equivalent" + (are [x y] (= 0 (compare x y)) + ; standard + int-vec (:standard long-vecs) + (:standard long-vecs) int-vec + int-vec (:standard regular-vecs) + (:standard regular-vecs) int-vec + ; empty + (:empty int-vecs) (:empty long-vecs) + (:empty long-vecs) (:empty int-vecs))) + (testing "lesser" + (are [x] (= -1 (compare int-vec x)) + (:longer int-vecs) + (:longer long-vecs) + (:longer regular-vecs) + (:first-greater int-vecs) + (:first-greater long-vecs) + (:first-greater regular-vecs) + (:last-greater int-vecs) + (:last-greater long-vecs) + (:last-greater regular-vecs) + (:rand-greater-1 int-vecs) + (:rand-greater-1 long-vecs) + (:rand-greater-1 regular-vecs) + (:rand-greater-2 int-vecs) + (:rand-greater-2 long-vecs) + (:rand-greater-2 regular-vecs) + (:rand-greater-3 int-vecs) + (:rand-greater-3 long-vecs) + (:rand-greater-3 regular-vecs)) + (are [x] (= -1 (compare x int-vec)) + nil + (:empty int-vecs) + (:empty long-vecs) + (:empty regular-vecs) + (:shorter int-vecs) + (:shorter long-vecs) + (:shorter regular-vecs) + (:first-lesser int-vecs) + (:first-lesser long-vecs) + (:first-lesser regular-vecs) + (:last-lesser int-vecs) + (:last-lesser long-vecs) + (:last-lesser regular-vecs) + (:rand-lesser-1 int-vecs) + (:rand-lesser-1 long-vecs) + (:rand-lesser-1 regular-vecs) + (:rand-lesser-2 int-vecs) + (:rand-lesser-2 long-vecs) + (:rand-lesser-2 regular-vecs) + (:rand-lesser-3 int-vecs) + (:rand-lesser-3 long-vecs) + (:rand-lesser-3 regular-vecs))) + (testing "greater" + (are [x] (= 1 (compare int-vec x)) + nil + (:empty int-vecs) + (:empty long-vecs) + (:empty regular-vecs) + (:shorter int-vecs) + (:shorter long-vecs) + (:shorter regular-vecs) + (:first-lesser int-vecs) + (:first-lesser long-vecs) + (:first-lesser regular-vecs) + (:last-lesser int-vecs) + (:last-lesser long-vecs) + (:last-lesser regular-vecs) + (:rand-lesser-1 int-vecs) + (:rand-lesser-1 long-vecs) + (:rand-lesser-1 regular-vecs) + (:rand-lesser-2 int-vecs) + (:rand-lesser-2 long-vecs) + (:rand-lesser-2 regular-vecs) + (:rand-lesser-3 int-vecs) + (:rand-lesser-3 long-vecs) + (:rand-lesser-3 regular-vecs)) + (are [x] (= 1 (compare x int-vec)) + (:longer int-vecs) + (:longer long-vecs) + (:longer regular-vecs) + (:first-greater int-vecs) + (:first-greater long-vecs) + (:first-greater regular-vecs) + (:last-greater int-vecs) + (:last-greater long-vecs) + (:last-greater regular-vecs) + (:rand-greater-1 int-vecs) + (:rand-greater-1 long-vecs) + (:rand-greater-1 regular-vecs) + (:rand-greater-2 int-vecs) + (:rand-greater-2 long-vecs) + (:rand-greater-2 regular-vecs) + (:rand-greater-3 int-vecs) + (:rand-greater-3 long-vecs) + (:rand-greater-3 regular-vecs)))) + (testing "Comparable.compareTo" + (testing "incompatible" + (is (thrown? NullPointerException (.compareTo int-vec nil))) + (are [x] (thrown? ClassCastException (.compareTo int-vec x)) + '() + {} + #{} + (sorted-set) + (sorted-map) + nums + 1)) + (testing "identical" + (is (= 0 (.compareTo int-vec int-vec)))) + (testing "equivalent" + (are [x] (= 0 (.compareTo int-vec x)) + (:standard long-vecs) + (:standard regular-vecs))) + (testing "lesser" + (are [x] (= -1 (.compareTo int-vec x)) + (:longer int-vecs) + (:longer long-vecs) + (:longer regular-vecs) + (:first-greater int-vecs) + (:first-greater long-vecs) + (:first-greater regular-vecs) + (:last-greater int-vecs) + (:last-greater long-vecs) + (:last-greater regular-vecs) + (:rand-greater-1 int-vecs) + (:rand-greater-1 long-vecs) + (:rand-greater-1 regular-vecs) + (:rand-greater-2 int-vecs) + (:rand-greater-2 long-vecs) + (:rand-greater-2 regular-vecs) + (:rand-greater-3 int-vecs) + (:rand-greater-3 long-vecs) + (:rand-greater-3 regular-vecs))) + (testing "greater" + (are [x] (= 1 (.compareTo int-vec x)) + (:empty int-vecs) + (:empty long-vecs) + (:empty regular-vecs) + (:shorter int-vecs) + (:shorter long-vecs) + (:shorter regular-vecs) + (:first-lesser int-vecs) + (:first-lesser long-vecs) + (:first-lesser regular-vecs) + (:last-lesser int-vecs) + (:last-lesser long-vecs) + (:last-lesser regular-vecs) + (:rand-lesser-1 int-vecs) + (:rand-lesser-1 long-vecs) + (:rand-lesser-1 regular-vecs) + (:rand-lesser-2 int-vecs) + (:rand-lesser-2 long-vecs) + (:rand-lesser-2 regular-vecs) + (:rand-lesser-3 int-vecs) + (:rand-lesser-3 long-vecs) + (:rand-lesser-3 regular-vecs)))))) |