diff src/clojure/test_clojure/for.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojure/test_clojure/for.clj	Sat Aug 21 06:25:44 2010 -0400
     1.3 @@ -0,0 +1,128 @@
     1.4 +;   Copyright (c) Rich Hickey. All rights reserved.
     1.5 +;   The use and distribution terms for this software are covered by the
     1.6 +;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
     1.7 +;   which can be found in the file epl-v10.html at the root of this distribution.
     1.8 +;   By using this software in any fashion, you are agreeing to be bound by
     1.9 +;   the terms of this license.
    1.10 +;   You must not remove this notice, or any other, from this software.
    1.11 +
    1.12 +;;  Tests for the Clojure 'for' macro
    1.13 +;;
    1.14 +;;  by Chouser
    1.15 +;;  Created Dec 2008
    1.16 +
    1.17 +(ns clojure.test-clojure.for
    1.18 +  (:use clojure.test))
    1.19 +
    1.20 +(deftest Docstring-Example
    1.21 +  (is (= (take 100 (for [x (range 100000000)
    1.22 +                         y (range 1000000) :while (< y x)]
    1.23 +                     [x y]))
    1.24 +         '([1 0] [2 0] [2 1] [3 0] [3 1] [3 2] [4 0] [4 1] [4 2] [4 3]
    1.25 +           [5 0] [5 1] [5 2] [5 3] [5 4]
    1.26 +           [6 0] [6 1] [6 2] [6 3] [6 4] [6 5]
    1.27 +           [7 0] [7 1] [7 2] [7 3] [7 4] [7 5] [7 6]
    1.28 +           [8 0] [8 1] [8 2] [8 3] [8 4] [8 5] [8 6] [8 7]
    1.29 +           [9 0] [9 1] [9 2] [9 3] [9 4] [9 5] [9 6] [9 7] [9 8]
    1.30 +           [10 0] [10 1] [10 2] [10 3] [10 4] [10 5] [10 6] [10 7] [10 8] [10 9]
    1.31 +           [11 0] [11 1] [11 2] [11 3] [11 4] [11 5] [11 6] [11 7] [11 8] [11 9]
    1.32 +             [11 10]
    1.33 +           [12 0] [12 1] [12 2] [12 3] [12 4] [12 5] [12 6] [12 7] [12 8] [12 9]
    1.34 +             [12 10] [12 11]
    1.35 +           [13 0] [13 1] [13 2] [13 3] [13 4] [13 5] [13 6] [13 7] [13 8] [13 9]
    1.36 +             [13 10] [13 11] [13 12]
    1.37 +           [14 0] [14 1] [14 2] [14 3] [14 4] [14 5] [14 6] [14 7] [14 8]))))
    1.38 +
    1.39 +(defmacro deftest-both [txt & ises]
    1.40 +  `(do
    1.41 +     (deftest ~(symbol (str "For-" txt)) ~@ises)
    1.42 +     (deftest ~(symbol (str "Doseq-" txt))
    1.43 +              ~@(map (fn [[x-is [x-= [x-for binds body] value]]]
    1.44 +                       (when (and (= x-is 'is) (= x-= '=) (= x-for 'for))
    1.45 +                         `(is (= (let [acc# (atom [])]
    1.46 +                                   (doseq ~binds (swap! acc# conj ~body))
    1.47 +                                   @acc#)
    1.48 +                                 ~value))))
    1.49 +                     ises))))
    1.50 +
    1.51 +(deftest-both When
    1.52 +  (is (= (for [x (range 10) :when (odd? x)] x) '(1 3 5 7 9)))
    1.53 +  (is (= (for [x (range 4) y (range 4) :when (odd? y)] [x y])
    1.54 +         '([0 1] [0 3] [1 1] [1 3] [2 1] [2 3] [3 1] [3 3])))
    1.55 +  (is (= (for [x (range 4) y (range 4) :when (odd? x)] [x y])
    1.56 +         '([1 0] [1 1] [1 2] [1 3] [3 0] [3 1] [3 2] [3 3])))
    1.57 +  (is (= (for [x (range 4) :when (odd? x) y (range 4)] [x y])
    1.58 +         '([1 0] [1 1] [1 2] [1 3] [3 0] [3 1] [3 2] [3 3])))
    1.59 +  (is (= (for [x (range 5) y (range 5) :when (< x y)] [x y])
    1.60 +         '([0 1] [0 2] [0 3] [0 4] [1 2] [1 3] [1 4] [2 3] [2 4] [3 4]))))
    1.61 +
    1.62 +(defn only
    1.63 +  "Returns a lazy seq of increasing ints starting at 0.  Trying to get
    1.64 +  the nth+1 value of the seq throws an exception.  This is meant to
    1.65 +  help detecting over-eagerness in lazy seq consumers."
    1.66 +  [n]
    1.67 +  (lazy-cat (range n)
    1.68 +            (throw (Exception. "consumer went too far in lazy seq"))))
    1.69 +
    1.70 +(deftest-both While
    1.71 +  (is (= (for [x (only 6) :while (< x 5)] x) '(0 1 2 3 4)))
    1.72 +  (is (= (for [x (range 4) y (only 4) :while (< y 3)] [x y])
    1.73 +         '([0 0] [0 1] [0 2] [1 0] [1 1] [1 2]
    1.74 +           [2 0] [2 1] [2 2] [3 0] [3 1] [3 2])))
    1.75 +  (is (= (for [x (range 4) y (range 4) :while (< x 3)] [x y])
    1.76 +         '([0 0] [0 1] [0 2] [0 3] [1 0] [1 1] [1 2] [1 3]
    1.77 +           [2 0] [2 1] [2 2] [2 3])))
    1.78 +  (is (= (for [x (only 4) :while (< x 3) y (range 4)] [x y])
    1.79 +         '([0 0] [0 1] [0 2] [0 3] [1 0] [1 1] [1 2] [1 3]
    1.80 +           [2 0] [2 1] [2 2] [2 3])))
    1.81 +  (is (= (for [x (range 4) y (range 4) :while (even? x)] [x y])
    1.82 +         '([0 0] [0 1] [0 2] [0 3] [2 0] [2 1] [2 2] [2 3])))
    1.83 +  (is (= (for [x (only 2) :while (even? x) y (range 4)] [x y])
    1.84 +         '([0 0] [0 1] [0 2] [0 3])))
    1.85 +  (is (= (for [x (range 4) y (only 4) :while (< y x)] [x y])
    1.86 +         '([1 0] [2 0] [2 1] [3 0] [3 1] [3 2]))))
    1.87 +
    1.88 +(deftest-both While-and-When
    1.89 +  (is (= (for [x (only 6) :while (< x 5) y (range 4) :when (odd? y)] [x y])
    1.90 +         '([0 1] [0 3] [1 1] [1 3] [2 1] [2 3] [3 1] [3 3] [4 1] [4 3])))
    1.91 +  (is (= (for [x (range 4) :when (odd? x) y (only 6) :while (< y 5)] [x y])
    1.92 +         '([1 0] [1 1] [1 2] [1 3] [1 4] [3 0] [3 1] [3 2] [3 3] [3 4])))
    1.93 +  (is (= (for [x (only 6) :while (< x 5) y (range 4) :when (odd? (+ x y))]
    1.94 +           [x y])
    1.95 +         '([0 1] [0 3] [1 0] [1 2] [2 1] [2 3] [3 0] [3 2] [4 1] [4 3])))
    1.96 +  (is (= (for [x (range 4) :when (odd? x) y (only 2) :while (odd? (+ x y))]
    1.97 +           [x y])
    1.98 +         '([1 0] [3 0]))))
    1.99 +
   1.100 +(deftest-both While-and-When-Same-Binding
   1.101 +  (is (= (for [x (only 6) :while (< x 5) :when (odd? x)] x) '(1 3)))
   1.102 +  (is (= (for [x (only 6)
   1.103 +               :while (< x 5) ; if :while is false, :when should not be evaled
   1.104 +               :when (do (if (< x 5) (odd? x)))] x) '(1 3)))
   1.105 +  (is (= (for [a (range -2 5)
   1.106 +               :when (not= a 0) ; :when may guard :while
   1.107 +               :while (> (Math/abs (/ 1.0 a)) 1/3)] a) '(-2 -1 1 2))))
   1.108 +
   1.109 +(deftest-both Nesting
   1.110 +  (is (= (for [x '(a b) y (interpose x '(1 2)) z (list x y)] [x y z])
   1.111 +         '([a 1 a] [a 1 1] [a a a] [a a a] [a 2 a] [a 2 2]
   1.112 +           [b 1 b] [b 1 1] [b b b] [b b b] [b 2 b] [b 2 2])))
   1.113 +  (is (= (for [x ['a nil] y [x 'b]] [x y])
   1.114 +         '([a a] [a b] [nil nil] [nil b]))))
   1.115 +
   1.116 +(deftest-both Destructuring
   1.117 +  (is (= (for [{:syms [a b c]} (map #(zipmap '(a b c) (range % 5)) (range 3))
   1.118 +               x [a b c]]
   1.119 +           (Integer. (str a b c x)))
   1.120 +         '(120 121 122 1231 1232 1233 2342 2343 2344))))
   1.121 +
   1.122 +(deftest-both Let
   1.123 +  (is (= (for [x (range 3) y (range 3) :let [z (+ x y)] :when (odd? z)] [x y z])
   1.124 +         '([0 1 1] [1 0 1] [1 2 3] [2 1 3])))
   1.125 +  (is (= (for [x (range 6) :let [y (rem x 2)] :when (even? y) z [8 9]] [x z])
   1.126 +         '([0 8] [0 9] [2 8] [2 9] [4 8] [4 9]))))
   1.127 +
   1.128 +; :while must skip all subsequent chunks as well as the remainder of
   1.129 +; the current chunk:
   1.130 +(deftest-both Chunked-While
   1.131 +  (is (= (for [x (range 100) :while (even? x)] x) '(0))))