reiddraper / simple-check

QuickCheck for Clojure
http://reiddraper.github.io/simple-check/
286 stars 18 forks source link

Compose shrinks when creating generators #25

Closed reiddraper closed 10 years ago

reiddraper commented 10 years ago

This is a large (and I think entirely backward compatible) change to the way generators and shrinking works. Previously generators would generate random values of type A. Whatever type ended up being generated would be used to control how shrinking was done. This was a problem when you created implicit constraints in the generator, that were not seen in the type of the generated value. For example, multiplying an integer generator by two will always result in an even value. Further, choosing a random element from the vector [:foo :bar :baz] should shrink to one of those elements if the property fails. It should not see :foo, and then shrink that to :f. The fix is to change generators from generators of A's, to generators of shrink trees of A's. The top of the tree is the generated value, and the children are the first layer of shrinking. This tree is lazy. This allows generators to build on the shrink tree of their parent during generator composition. Some examples of what is now possible:

 ;; will only generator :foo, and will never shrink
(gen/return :foo)

;; will generate a non-empty vector of integers, and then
;; randomly choose one element. Shrinking will shrink toward
;; an earlier element in the vector
(gen/bind (gen/such-that not-empty (gen/vector gen/int))
          gen/elements)

;; will choose an element from the vector, and shrink
;; toward choosing an earlier element
(gen/elements [:foo :bar :baz])

;; will generate powers of two, that shrink to smaller powers
;; of two
(gen/fmap #(long (Math/pow 2 %)) gen/nat)

Fixes #22.

reiddraper commented 10 years ago

@ztellman @aphyr @cemerick @si14 @tcrayford any help funning existing tests would be awesome. I think this should be backward compatible, but can't be sure beyond the tests that are in the repo.

cemerick commented 10 years ago

"funning"? Running? You mean, smoking test suites out in the wild using this change?

BTW, I chuckled heartily when I read your summary of the change. Really clever, awesome.

tcrayford commented 10 years ago

@reiddraper : doesn't break anything of mine at all.

cmeiklejohn commented 10 years ago

Bro, always make sure to "fun" your "simple-sheck" tests.

si14 commented 10 years ago

Looks awesome to me!

reiddraper commented 10 years ago

"funning"? Running? You mean, smoking test suites out in the wild using this change?

@cemerick heh, yes