reiddraper / simple-check

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

Integer generators wrapping at 99? #32

Closed Misophistful closed 10 years ago

Misophistful commented 10 years ago

Disclaimer: I'm brand new to simple-check, so there's a very good chance that I've misunderstood how generators should be used.

I'm trying to write a generator that creates a range of positive integers between 0 and 1000. However, my attempt at doing this (gen/sample gen/nat 1000) doesn't generate any integers larger than 99. In fact, when I evaluate (gen/sample gen/nat 101) I can see the 101st value wrapping back around to 0.

Is this expected behaviour? If so, what is an alternative approach for generating positive integers larger than 99?

reiddraper commented 10 years ago

tl;dr, try (gen/sample (gen/choose 0 1000))

There's a couple of things going on that are causing the confusion. First, generators (which are actually functions), accept two parameters under the covers: a random number generator, and a 'size' parameter. The size parameter is used to determine how 'big' the generated value should be. When you run a test, the size parameter starts at 0, and then goes up to 200 (by default). This is done so that we don't start off testing your code with a large collection/value, when it might fail quickly on a small one. Additionally, the gen/int generator uses this size parameter to determine the max value it will generate, in fact, it's defined like this: def int (sized (fn [size] (choose (- size) size))). So by default, gen/int will only generate numbers in the range -200 - 200. I'm thinking about changing this in the future, but I'm not quite sure what the correct behavior should be. In the meantime, if you'd like to generate numbers in a given range, gen/choose is designed for exactly this.

I'm closing the issue, but feel free to keep asking questions here.

Misophistful commented 10 years ago

gen/choose was exactly what I was looking for, thank you.

Though I feel like I'm still misunderstanding something around gen/int and gen/nat, as I still can't get them to generate a number larger than 99 (or smaller than -99). How do I force them to generate numbers in the -200 - 200 range you mentioned?

Also, could you explain the use-case for gen/sample? Is it just a helper function to see the output of a generator, which you only use while developing a test? Or does it have a use in "live" tests?

reiddraper commented 10 years ago

Though I feel like I'm still misunderstanding something around gen/int and gen/nat, as I still can't get them to generate a number larger than 99 (or smaller than -99). How do I force them to generate numbers in the -200 - 200 range you mentioned?

Both gen/sample and core/quick-check will use a size-sequence (just the range 0 -> max-size). They, however, use different max sizes, as you can see here and here. You can always create your own lazy-sequence of randomly generated values like this:

(take 1000 (gen/sample-seq gen/int 1000))

Also, could you explain the use-case for gen/sample? Is it just a helper function to see the output of a generator, which you only use while developing a test? Or does it have a use in "live" tests?

It's intended for use just for developing your generators. I tend to just play with it from the REPL.

Misophistful commented 10 years ago

Thank you for taking the time to explain it to me. Now I understand when to use gen/sample and why it was wrapping at 99.