TCHECK-73: Ensure that gen/int returns a long
Commit 590cfae1 slightly changed the behavior of rand-range so that it
is no longer guaranteed to return an integer. Instead, it may return a
double if the lower and/or upper argument is a double. This directly
affects gen/int in cases where it is sized with a double.
Meanwhile, the recursive-gen function *always* uses a double for sizing
recursive generators, which means that inner generators will be sized
with a double, which means that gen/int will end up generating doubles.
This commit coerces the output of rand-range to long and adds
regression tests.
Justin Holguin authored 8 years ago
Gary Fredericks committed 8 years ago
184 | 184 |
;; Use -' to maintain accuracy with overflow protection.
|
185 | 185 |
width (-' upper lower -1)]
|
186 | 186 |
(if (< width Long/MAX_VALUE)
|
187 | |
(+ lower (long (Math/floor (* factor width))))
|
|
187 |
(long (+ lower (Math/floor (* factor width))))
|
188 | 188 |
;; Clamp down to upper because double math.
|
189 | |
(min upper (long (Math/floor (+ lower (* factor width))))))))
|
|
189 |
(long (min upper (Math/floor (+ lower (* factor width))))))))
|
190 | 190 |
|
191 | 191 |
(defn sized
|
192 | 192 |
"Create a generator that depends on the size parameter.
|
374 | 374 |
[a plus-fifty]
|
375 | 375 |
false))]
|
376 | 376 |
(-> result :shrunk :smallest))))))
|
|
377 |
|
|
378 |
;; gen/int returns an integer when size is a double; regression for TCHECK-73
|
|
379 |
;; ---------------------------------------------------------------------------
|
|
380 |
|
|
381 |
(def gen-double
|
|
382 |
(gen/fmap (fn [[x y]] (double (+ x (/ y 10))))
|
|
383 |
(gen/tuple gen/pos-int (gen/choose 0 9))))
|
|
384 |
|
|
385 |
(defspec gen-int-with-double-size 1000
|
|
386 |
(prop/for-all [size gen-double]
|
|
387 |
(integer? (gen/generate gen/int size))))
|
|
388 |
|
|
389 |
;; recursive-gen doesn't change ints to doubles; regression for TCHECK-73
|
|
390 |
;; ---------------------------------------------------------------------------
|
|
391 |
|
|
392 |
(defspec recursive-generator-test 100
|
|
393 |
(let [btree* (fn [g] (gen/hash-map
|
|
394 |
:value gen/int
|
|
395 |
:left g
|
|
396 |
:right g))
|
|
397 |
btree (gen/recursive-gen btree* (gen/return nil))
|
|
398 |
valid? (fn valid? [tree]
|
|
399 |
(and (integer? (:value tree))
|
|
400 |
(or (nil? (:left tree))
|
|
401 |
(valid? (:left tree)))
|
|
402 |
(or (nil? (:right tree))
|
|
403 |
(valid? (:right tree)))))]
|
|
404 |
(prop/for-all [t btree] (valid? t))))
|
377 | 405 |
|
378 | 406 |
;; edn rountrips
|
379 | 407 |
;; ---------------------------------------------------------------------------
|