From 30a24522ea1e693e7284af886cd8a6bd5cad5f4c Mon Sep 17 00:00:00 2001
From: Mike Hinchey <hincheymg@gmail.com>
Date: Fri, 7 Aug 2009 23:36:57 -0700
Subject: [PATCH] fix #167, tests for sequences, control, and numbers

---
 test/clojure/test_clojure/control.clj   |  169 +++++++++++++++++++++++++++++--
 test/clojure/test_clojure/numbers.clj   |   29 ++++++
 test/clojure/test_clojure/sequences.clj |   28 +++++-
 3 files changed, 216 insertions(+), 10 deletions(-)

diff --git a/test/clojure/test_clojure/control.clj b/test/clojure/test_clojure/control.clj
index 3a223d5..75f50a6 100644
--- a/test/clojure/test_clojure/control.clj
+++ b/test/clojure/test_clojure/control.clj
@@ -6,7 +6,7 @@
 ;   the terms of this license.
 ;   You must not remove this notice, or any other, from this software.
 
-; Author: Frantisek Sodomka
+; Author: Frantisek Sodomka, Mike Hinchey
 
 ;;
 ;;  Test "flow control" constructs.
@@ -60,15 +60,101 @@
   (maintains-identity (fn [_] (do _))) )
 
 
-; loop/recur
-; throw, try
+;; loop/recur
+(deftest test-loop
+  (are [x y] (= x y)
+       1 (loop []
+           1)
+       3 (loop [a 1]
+           (if (< a 3)
+             (recur (inc a))
+             a))
+       [2 4 6] (loop [a []
+                      b [1 2 3]]
+                 (if (seq b)
+                   (recur (conj a (* 2 (first b)))
+                          (next b))
+                   a))
+       [6 4 2] (loop [a ()
+                      b [1 2 3]]
+                 (if (seq b)
+                   (recur (conj a (* 2 (first b)))
+                          (next b))
+                   a))
+       )
+  )
+
+
+;; throw, try
+
+; if: see logic.clj
+
+(deftest test-when
+  (are [x y] (= x y)
+       1 (when true 1)
+       nil (when true)
+       nil (when false)
+       nil (when false (exception))
+       ))
+
+(deftest test-when-not
+  (are [x y] (= x y)
+       1 (when-not false 1)
+       nil (when-not true)
+       nil (when-not false)
+       nil (when-not true (exception))
+       ))
+
+(deftest test-if-not
+  (are [x y] (= x y)
+       1 (if-not false 1)
+       1 (if-not false 1 (exception))
+       nil (if-not true 1)
+       2 (if-not true 1 2)
+       nil (if-not true (exception))
+       1 (if-not true (exception) 1)
+       ))
 
-; [if (logic.clj)], if-not, if-let
-; when, when-not, when-let, when-first
+(deftest test-when-let
+  (are [x y] (= x y)
+       1 (when-let [a 1]
+           a)
+       2 (when-let [[a b] '(1 2)]
+           b)
+       nil (when-let [a false]
+             (exception))
+       ))
+
+(deftest test-if-let
+  (are [x y] (= x y)
+       1 (if-let [a 1]
+           a)
+       2 (if-let [[a b] '(1 2)]
+           b)
+       nil (if-let [a false]
+             (exception))
+       1 (if-let [a false]
+           a 1)
+       1 (if-let [[a b] nil]
+             b 1)
+       1 (if-let [a false]
+           (exception)
+           1)
+       ))
+
+(deftest test-when-first
+  (are [x y] (= x y)
+       1 (when-first [a [1 2]]
+           a)
+       2 (when-first [[a b] '((1 2) 3)]
+           b)
+       nil (when-first [a nil]
+             (exception))
+       ))
 
 
 (deftest test-cond
-  (are [x y]  (= x y)
+  (are [x y] (= x y)
       (cond) nil
 
       (cond nil true) nil
@@ -107,11 +193,78 @@
   (maintains-identity (fn [_] (cond true _))) )
 
 
-; condp
+(deftest test-condp
+  (are [x] (= :pass x)
+       (condp = 1
+         1 :pass
+         2 :fail)
+       (condp = 1
+         2 :fail
+         1 :pass)
+       (condp = 1
+         2 :fail
+         :pass)
+       (condp = 1
+         :pass)
+       (condp = 1
+         2 :fail
+         ;; doc of condp says result-expr is returned
+         ;; shouldn't it say similar to cond: "evaluates and returns
+         ;; the value of the corresponding expr and doesn't evaluate any of the
+         ;; other tests or exprs."
+         (identity :pass))
+       (condp + 1
+         1 :>> #(if (= % 2) :pass :fail))
+       (condp + 1
+         1 :>> #(if (= % 3) :fail :pass))
+       )
+  (is (thrown? IllegalArgumentException
+               (condp = 1)
+               ))
+  (is (thrown? IllegalArgumentException
+               (condp = 1
+                 2 :fail)
+               ))
+  )
+
 
 ; [for, doseq (for.clj)]
 
-; dotimes, while
+(deftest test-dotimes
+  ;; dotimes always returns nil
+  (is (= nil (dotimes [n 1] n)))
+  ;; test using an atom since dotimes is for modifying
+  ;; test executes n times
+  (is (= 3
+         (let [a (atom 0)]
+           (dotimes [n 3]
+             (swap! a inc))
+           @a)
+         ))
+  ;; test all values of n
+  (is (= [0 1 2]
+         (let [a (atom [])]
+           (dotimes [n 3]
+             (swap! a conj n))
+           @a)))
+  (is (= []
+         (let [a (atom [])]
+           (dotimes [n 0]
+             (swap! a conj n))
+           @a)))
+  )
+
+(deftest test-while
+  (is (= nil (while nil (throw (Exception. "never")))))
+  (is (= [0 nil]
+         ;; a will dec to 0
+         ;; while always returns nil
+         (let [a (atom 3)
+               w (while (pos? @a)
+                   (swap! a dec))]
+           [@a w])))
+  (is (thrown? Exception (while true (throw (Exception. "expected to throw")))))
+  )
 
 ; locking, monitor-enter, monitor-exit
 
diff --git a/test/clojure/test_clojure/numbers.clj b/test/clojure/test_clojure/numbers.clj
index 597cedf..98157eb 100644
--- a/test/clojure/test_clojure/numbers.clj
+++ b/test/clojure/test_clojure/numbers.clj
@@ -389,3 +389,32 @@
   (is (thrown? ArithmeticException (odd? 1/2)))
   (is (thrown? ArithmeticException (odd? (double 10)))))
 
+(defn- expt
+  "clojure.contrib.math/expt is a better and much faster impl, but this works.
+Math/pow overflows to Infinity."
+  [x n] (apply * (replicate n x)))
+
+(deftest test-bit-shift-left
+  (are [x y] (= x y)
+       2r10 (bit-shift-left 2r1 1)
+       2r100 (bit-shift-left 2r1 2)
+       2r1000 (bit-shift-left 2r1 3)
+       2r00101110 (bit-shift-left 2r00010111 1)
+       2r00101110 (apply bit-shift-left [2r00010111 1])
+       2r01 (bit-shift-left 2r10 -1)
+       (expt 2 32) (bit-shift-left 1 32)
+       (expt 2 10000) (bit-shift-left 1 10000)
+       ))
+
+(deftest test-bit-shift-right
+  (are [x y] (= x y)
+       2r0 (bit-shift-right 2r1 1)
+       2r010 (bit-shift-right 2r100 1)
+       2r001 (bit-shift-right 2r100 2)
+       2r000 (bit-shift-right 2r100 3)
+       2r0001011 (bit-shift-right 2r00010111 1)
+       2r0001011 (apply bit-shift-right [2r00010111 1])
+       2r100 (bit-shift-right 2r10 -1)
+       1 (bit-shift-right (expt 2 32) 32)
+       1 (bit-shift-right (expt 2 10000) 10000)
+       ))
diff --git a/test/clojure/test_clojure/sequences.clj b/test/clojure/test_clojure/sequences.clj
index 9096c69..d735507 100644
--- a/test/clojure/test_clojure/sequences.clj
+++ b/test/clojure/test_clojure/sequences.clj
@@ -980,5 +980,29 @@
       true (not-any? #{:a} [:b :b]) ))
 
 
-; TODO: some
-
+(deftest test-some
+  ;; always nil for nil or empty coll/seq
+  (are [x] (= (some pos? x) nil)
+       nil
+       () [] {} #{}
+       (lazy-seq [])
+       (into-array []))
+  
+  (are [x y] (= x y)
+       nil (some nil nil)
+       
+       true (some pos? [1])
+       true (some pos? [1 2])
+       
+       nil (some pos? [-1])
+       nil (some pos? [-1 -2])
+       true (some pos? [-1 2])
+       true (some pos? [1 -2])
+       
+       :a (some #{:a} [:a :a])
+       :a (some #{:a} [:b :a])
+       nil (some #{:a} [:b :b])
+       
+       :a (some #{:a} '(:a :b))
+       :a (some #{:a} #{:a :b})
+       ))
-- 
1.6.0.4

