Codebase list test-check-clojure / a0e950f
randomness preservation act Steve Miner authored 8 years ago Gary Fredericks committed 8 years ago
2 changed file(s) with 67 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
177177 [value]
178178 (rose/make-rose value (core/map int-rose-tree (shrink-int value))))
179179
180 ;; calc-long is factored out to support testing the surprisingly tricky double math. Note:
181 ;; An extreme long value does not have a precision-preserving representation as a double.
182 ;; Be careful about changing this code unless you understand what's happening in these
183 ;; examples:
184 ;;
185 ;; (= (long (- Integer/MAX_VALUE (double (- Integer/MAX_VALUE 10)))) 10)
186 ;; (= (long (- Long/MAX_VALUE (double (- Long/MAX_VALUE 10)))) 0)
187
188 (defn- calc-long
189 [factor lower upper]
190 ;; these pre- and post-conditions are disabled for deployment
191 #_ {:pre [(float? factor) (>= factor 0.0) (< factor 1.0)
192 (integer? lower) (integer? upper) (<= lower upper)]
193 :post [(integer? %)]}
194 ;; Use -' on width to maintain accuracy with overflow protection.
195 (let [width (-' upper lower -1)]
196 ;; Preserve long precision if the width is in the long range. Otherwise, we must accept
197 ;; less precision because doubles don't have enough bits to preserve long equivalence at
198 ;; extreme values.
199 (if (< width Long/MAX_VALUE)
200 (+ lower (long (Math/floor (* factor width))))
201 ;; Clamp down to upper because double math.
202 (min upper (long (Math/floor (+ lower (* factor width))))))))
203
180204 (defn- rand-range
181205 [rnd lower upper]
182206 {:pre [(<= lower upper)]}
183 (let [factor (random/rand-double rnd)
184 ;; Use -' to maintain accuracy with overflow protection.
185 width (-' upper lower -1)]
186 (if (< width Long/MAX_VALUE)
187 (long (+ lower (Math/floor (* factor width))))
188 ;; Clamp down to upper because double math.
189 (long (min upper (Math/floor (+ lower (* factor width))))))))
207 (calc-long (random/rand-double rnd) lower upper))
190208
191209 (defn sized
192210 "Create a generator that depends on the size parameter.
218236 (sized (fn [n] (resize (f n) generator)))))
219237
220238 (defn choose
221 "Create a generator that returns numbers in the range
222 `min-range` to `max-range`, inclusive."
239 "Create a generator that returns long integers in the range `lower` to `upper`, inclusive."
223240 [lower upper]
224 (make-gen
225 (fn [rnd _size]
226 (let [value (rand-range rnd lower upper)]
227 (rose/filter
241 ;; cast to long to support doubles as arguments per TCHECK-73
242 (let [lower (long lower)
243 upper (long upper)]
244 (make-gen
245 (fn [rnd _size]
246 (let [value (rand-range rnd lower upper)]
247 (rose/filter
228248 #(and (>= % lower) (<= % upper))
229 (int-rose-tree value))))))
249 (int-rose-tree value)))))))
230250
231251 (defn one-of
232252 "Create a generator that randomly chooses a value from the list of
402402 (or (nil? (:right tree))
403403 (valid? (:right tree)))))]
404404 (prop/for-all [t btree] (valid? t))))
405
406 (deftest calc-long-increasing
407 ;; access internal gen/calc-long function for testing
408 (are [low high] (apply < (map #(@#'gen/calc-long % low high) (range 0.0 0.9999 0.111)))
409 ;; low and high should not be too close, 100 is a reasonable spread
410 (- Long/MAX_VALUE 100) Long/MAX_VALUE
411 Long/MIN_VALUE (+ Long/MIN_VALUE 100)
412 Long/MIN_VALUE 0
413 0 100
414 -100 0
415 0 Long/MAX_VALUE
416 Long/MIN_VALUE Long/MAX_VALUE))
405417
406418 ;; edn rountrips
407419 ;; ---------------------------------------------------------------------------
584596 (defspec run-float-time 1e3
585597 (prop/for-all [a gen/int]
586598 (integer? a)))
599
600 ;; TCHECK-77 Regression
601 ;; ---------------------------------------------------------------------------
602
603 (deftest choose-distribution-sanity-check
604 (testing
605 "Should not get the same random value more than 90% of the time"
606 ;; This is a probabilistic test; the odds of a false-positive
607 ;; failure for the ranges with two elements should be roughly 1 in
608 ;; 10^162 (and even rarer for larger ranges), so it will never
609 ;; ever happen.
610 (are [low high] (let [xs (gen/sample (gen/choose low high) 1000)
611 count-of-most-frequent (apply max (vals (frequencies xs)))]
612 (< count-of-most-frequent 900))
613 (dec Long/MAX_VALUE) Long/MAX_VALUE
614 Long/MIN_VALUE (inc Long/MIN_VALUE)
615 Long/MIN_VALUE 0
616 0 1
617 -1 0
618 0 Long/MAX_VALUE
619 Long/MIN_VALUE Long/MAX_VALUE)))