|
9 | 9 | (ns cljs.seqs-test |
10 | 10 | (:refer-clojure :exclude [iter]) |
11 | 11 | (:require [cljs.test :refer-macros [deftest testing is]] |
| 12 | + [clojure.test.check :as tc] |
| 13 | + [clojure.test.check.clojure-test :refer-macros [defspec]] |
| 14 | + [clojure.test.check.generators :as gen] |
| 15 | + [clojure.test.check.properties :as prop :include-macros true] |
| 16 | + [clojure.test.check.random :as random] |
12 | 17 | [clojure.string :as s] |
13 | 18 | [clojure.set :as set])) |
14 | 19 |
|
|
237 | 242 | (is (true? (js-iterable? (js/Set.)))) |
238 | 243 | (is (false? (js-iterable? 1))) |
239 | 244 | (is (false? (js-iterable? nil))))) |
| 245 | + |
| 246 | +(deftest test-iteration-opts |
| 247 | + (let [genstep (fn [steps] |
| 248 | + (fn [k] (swap! steps inc) (inc k))) |
| 249 | + test (fn [expect & iteropts] |
| 250 | + (is (= expect |
| 251 | + (let [nsteps (atom 0) |
| 252 | + iter (apply iteration (genstep nsteps) iteropts) |
| 253 | + ret (doall (seq iter))] |
| 254 | + {:ret ret :steps @nsteps}) |
| 255 | + (let [nsteps (atom 0) |
| 256 | + iter (apply iteration (genstep nsteps) iteropts) |
| 257 | + ret (into [] iter)] |
| 258 | + {:ret ret :steps @nsteps}))))] |
| 259 | + (test {:ret [1 2 3 4] |
| 260 | + :steps 5} |
| 261 | + :initk 0 :somef #(< % 5)) |
| 262 | + (test {:ret [1 2 3 4 5] |
| 263 | + :steps 5} |
| 264 | + :initk 0 :kf (fn [ret] (when (< ret 5) ret))) |
| 265 | + (test {:ret ["1"] |
| 266 | + :steps 2} |
| 267 | + :initk 0 :somef #(< % 2) :vf str)) |
| 268 | + |
| 269 | + ;; kf does not stop on false |
| 270 | + (let [iter #(iteration (fn [k] |
| 271 | + (if (boolean? k) |
| 272 | + [10 :boolean] |
| 273 | + [k k])) |
| 274 | + :vf second |
| 275 | + :kf (fn [[k v]] |
| 276 | + (cond |
| 277 | + (= k 3) false |
| 278 | + (< k 14) (inc k))) |
| 279 | + :initk 0)] |
| 280 | + (is (= [0 1 2 3 :boolean 11 12 13 14] |
| 281 | + (into [] (iter)) |
| 282 | + (seq (iter)))))) |
| 283 | + |
| 284 | +(deftest test-iteration |
| 285 | + ;; equivalence to es6-iterator-seq |
| 286 | + (let [arr #js [1 nil 3 true false 4 6 nil 7]] |
| 287 | + (is (= (let [iter (es6-iterator arr)] |
| 288 | + (vec (iteration (fn [_] (.next iter)) |
| 289 | + :somef #(not (.-done %)) |
| 290 | + :vf #(.-value %)))) |
| 291 | + (let [iter (es6-iterator arr)] |
| 292 | + (vec (es6-iterator-seq iter)))))) |
| 293 | + |
| 294 | + ;; paginated API |
| 295 | + (let [items 12 pgsize 5 |
| 296 | + src (vec (repeatedly items #(random-uuid))) |
| 297 | + api (fn [tok] |
| 298 | + (let [tok (or tok 0)] |
| 299 | + (when (< tok items) |
| 300 | + {:tok (+ tok pgsize) |
| 301 | + :ret (subvec src tok (min (+ tok pgsize) items))})))] |
| 302 | + (is (= src |
| 303 | + (mapcat identity (iteration api :kf :tok :vf :ret)) |
| 304 | + (into [] cat (iteration api :kf :tok :vf :ret))))) |
| 305 | + |
| 306 | + (let [src [:a :b :c :d :e] |
| 307 | + api (fn [k] |
| 308 | + (let [k (or k 0)] |
| 309 | + (if (< k (count src)) |
| 310 | + {:item (nth src k) |
| 311 | + :k (inc k)})))] |
| 312 | + (is (= [:a :b :c] |
| 313 | + (vec (iteration api |
| 314 | + :somef (comp #{:a :b :c} :item) |
| 315 | + :kf :k |
| 316 | + :vf :item)) |
| 317 | + (vec (iteration api |
| 318 | + :kf #(some-> % :k #{0 1 2}) |
| 319 | + :vf :item)))))) |
| 320 | + |
| 321 | +(defn- make-rng [seed] |
| 322 | + (atom (random/make-random seed))) |
| 323 | + |
| 324 | +(defn- next-long [rng] |
| 325 | + (let [[r1 r2] (random/split @rng)] |
| 326 | + (reset! rng r2) |
| 327 | + (long (random/rand-long r1)))) |
| 328 | + |
| 329 | +(defspec iteration-seq-equals-reduce 1000 |
| 330 | + (prop/for-all [initk gen/small-integer |
| 331 | + seed gen/small-integer] |
| 332 | + (let [src (fn [] |
| 333 | + (let [rng (make-rng seed)] |
| 334 | + (iteration #(unchecked-add % (next-long rng)) |
| 335 | + :somef (complement #(zero? (mod % 1000))) |
| 336 | + :vf str |
| 337 | + :initk initk)))] |
| 338 | + (= (into [] (src)) |
| 339 | + (into [] (seq (src))))))) |
0 commit comments