|
| 1 | +; Copyright (c) Rich Hickey. All rights reserved. |
| 2 | +; The use and distribution terms for this software are covered by the |
| 3 | +; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) |
| 4 | +; which can be found in the file epl-v10.html at the root of this distribution. |
| 5 | +; By using this software in any fashion, you are agreeing to be bound by |
| 6 | +; the terms of this license. |
| 7 | +; You must not remove this notice, or any other, from this software. |
| 8 | + |
| 9 | +(ns clojure.test-clojure.data-structures-interop |
| 10 | + (:require [clojure.test :refer :all] |
| 11 | + [clojure.test.check.generators :as gen] |
| 12 | + [clojure.test.check.properties :as prop] |
| 13 | + [clojure.test.check.clojure-test :refer (defspec)])) |
| 14 | + |
| 15 | +(defn gen-range [min max] |
| 16 | + (gen/bind (gen/choose min max) (fn [n] (gen/tuple (gen/return n) |
| 17 | + (gen/choose n max))))) |
| 18 | + |
| 19 | +(defn gen-subvec [generator] |
| 20 | + (gen/bind (gen/not-empty generator) |
| 21 | + (fn [v] (gen/bind (gen-range 0 (dec (count v))) |
| 22 | + (fn [[n m]] (gen/return (subvec v n m))))))) |
| 23 | + |
| 24 | +(defn gen-gvec |
| 25 | + ([] |
| 26 | + (gen/bind (gen/elements {:int gen/int |
| 27 | + :short (gen/fmap short gen/byte) |
| 28 | + :long (gen/fmap long gen/int) |
| 29 | + :float (gen/fmap float gen/int) |
| 30 | + :double (gen/fmap double gen/int) |
| 31 | + :byte gen/byte |
| 32 | + :char gen/char |
| 33 | + :boolean gen/boolean}) |
| 34 | + #(apply gen-gvec %))) |
| 35 | + ([type generator] |
| 36 | + (gen/bind (gen/list generator) #(gen/return (apply vector-of type %))))) |
| 37 | + |
| 38 | +(defn gen-hash-set [generator] |
| 39 | + (gen/fmap (partial apply hash-set) (gen/list generator))) |
| 40 | + |
| 41 | +(defn gen-sorted-set [generator] |
| 42 | + (gen/fmap (partial apply sorted-set) (gen/list generator))) |
| 43 | + |
| 44 | +(defn gen-array-map [key-gen val-gen] |
| 45 | + (gen/fmap (partial into (array-map)) (gen/map key-gen val-gen))) |
| 46 | + |
| 47 | +(defn gen-sorted-map [key-gen val-gen] |
| 48 | + (gen/fmap (partial into (sorted-map)) (gen/map key-gen val-gen))) |
| 49 | + |
| 50 | +(defn gen-array |
| 51 | + ([] |
| 52 | + (gen/bind (gen/elements {int-array gen/int |
| 53 | + short-array gen/int |
| 54 | + long-array (gen/fmap long gen/int) |
| 55 | + float-array (gen/fmap float gen/int) |
| 56 | + double-array (gen/fmap double gen/int) |
| 57 | + byte-array gen/byte |
| 58 | + char-array gen/char |
| 59 | + boolean-array gen/boolean |
| 60 | + object-array gen/string}) |
| 61 | + #(apply gen-array %))) |
| 62 | + ([array-fn generator] |
| 63 | + (gen/fmap array-fn (gen/list generator)))) |
| 64 | + |
| 65 | +(defn exaust-iterator-forward [^java.util.Iterator iter] |
| 66 | + (loop [_ iter] (when (.hasNext iter) (recur (.next iter)))) |
| 67 | + (try (.next iter) nil (catch Throwable t t))) |
| 68 | + |
| 69 | +(defn exaust-iterator-backward [^java.util.ListIterator iter] |
| 70 | + (loop [_ iter] (when (.hasPrevious iter) (recur (.previous iter)))) |
| 71 | + (try (.previous iter) nil (catch Throwable t t))) |
| 72 | + |
| 73 | +(defspec iterator-throws-exception-on-exaustion 100 |
| 74 | + (prop/for-all [[_ x] (gen/bind (gen/elements [['list (gen/list gen/int)] |
| 75 | + ['vector (gen/vector gen/int)] |
| 76 | + ['vector-of (gen-gvec)] |
| 77 | + ['subvec (gen-subvec (gen/vector gen/int))] |
| 78 | + ['hash-set (gen-hash-set gen/int)] |
| 79 | + ['sorted-set (gen-sorted-set gen/int)] |
| 80 | + ['hash-map (gen/hash-map gen/symbol gen/int)] |
| 81 | + ['array-map (gen-array-map gen/symbol gen/int)] |
| 82 | + ['sorted-map (gen-sorted-map gen/symbol gen/int)]]) |
| 83 | + (fn [[s g]] (gen/tuple (gen/return s) g)))] |
| 84 | + (instance? java.util.NoSuchElementException (exaust-iterator-forward (.iterator x))))) |
| 85 | + |
| 86 | +(defspec array-iterator-throws-exception-on-exaustion 100 |
| 87 | + (prop/for-all [arr (gen-array)] |
| 88 | + (let [iter (clojure.lang.ArrayIter/createFromObject arr)] |
| 89 | + (instance? java.util.NoSuchElementException (exaust-iterator-forward iter))))) |
| 90 | + |
| 91 | +(defspec list-iterator-throws-exception-on-forward-exaustion 50 |
| 92 | + (prop/for-all [[_ x] (gen/bind (gen/elements [['vector (gen/vector gen/int)] |
| 93 | + ['subvec (gen-subvec (gen/vector gen/int))] |
| 94 | + ['vector-of (gen-gvec)]]) |
| 95 | + (fn [[s g]] (gen/tuple (gen/return s) g)))] |
| 96 | + (instance? java.util.NoSuchElementException (exaust-iterator-forward (.listIterator x))))) |
| 97 | + |
| 98 | +(defspec list-iterator-throws-exception-on-backward-exaustion 50 |
| 99 | + (prop/for-all [[_ x] (gen/bind (gen/elements [['vector (gen/vector gen/int)] |
| 100 | + ['subvec (gen-subvec (gen/vector gen/int))] |
| 101 | + ['vector-of (gen-gvec)]]) |
| 102 | + (fn [[s g]] (gen/tuple (gen/return s) g)))] |
| 103 | + (instance? java.util.NoSuchElementException (exaust-iterator-backward (.listIterator x))))) |
| 104 | + |
| 105 | +(defspec map-keyset-iterator-throws-exception-on-exaustion 50 |
| 106 | + (prop/for-all [[_ m] (gen/bind (gen/elements [['hash-map (gen/hash-map gen/symbol gen/int) |
| 107 | + 'array-map (gen-array-map gen/symbol gen/int) |
| 108 | + 'sorted-map (gen-sorted-map gen/symbol gen/int)]]) |
| 109 | + (fn [[s g]] (gen/tuple (gen/return s) g)))] |
| 110 | + (let [iter (.iterator (.keySet m))] |
| 111 | + (instance? java.util.NoSuchElementException (exaust-iterator-forward iter))))) |
| 112 | + |
| 113 | +(defspec map-values-iterator-throws-exception-on-exaustion 50 |
| 114 | + (prop/for-all [[_ m] (gen/bind (gen/elements [['hash-map (gen/hash-map gen/symbol gen/int) |
| 115 | + 'array-map (gen-array-map gen/symbol gen/int) |
| 116 | + 'sorted-map (gen-sorted-map gen/symbol gen/int)]]) |
| 117 | + (fn [[s g]] (gen/tuple (gen/return s) g)))] |
| 118 | + (let [iter (.iterator (.values m))] |
| 119 | + (instance? java.util.NoSuchElementException (exaust-iterator-forward iter))))) |
| 120 | + |
| 121 | +(defspec map-keys-iterator-throws-exception-on-exaustion 50 |
| 122 | + (prop/for-all [m (gen-sorted-map gen/symbol gen/int)] |
| 123 | + (instance? java.util.NoSuchElementException (exaust-iterator-forward (.keys m))))) |
| 124 | + |
| 125 | +(defspec map-vals-iterator-throws-exception-on-exaustion 50 |
| 126 | + (prop/for-all [m (gen-sorted-map gen/symbol gen/int)] |
| 127 | + (instance? java.util.NoSuchElementException (exaust-iterator-forward (.vals m))))) |
| 128 | + |
| 129 | +(defspec map-reverse-iterator-throws-exception-on-exaustion 50 |
| 130 | + (prop/for-all [m (gen-sorted-map gen/symbol gen/int)] |
| 131 | + (instance? java.util.NoSuchElementException (exaust-iterator-forward (.reverseIterator m))))) |
0 commit comments