Reputation: 6014
I'm using QuickCheck to do generative testing in Clojure.
However I don't know it well and often I end up doing convoluted things. One thing that I need to do quite often is something like that:
However I have no idea as to how to do that cleanly using QuickCheck.
Here's an even simpler, silly, example which doesn't work:
(prop/for-all [a (gen/choose 1 10)
b (gen/such-that #(= a %) (gen/choose 1 10))]
(= a b))
It doesn't work because a cannot be resolved (prop/for-all
isn't like a let
statement).
So how can I generate the three primes, with the condition that the two latter ones are inferior to the first one?
Upvotes: 1
Views: 107
Reputation: 3212
In test.check
we can use gen/bind
as the bind operator in the generator monad, so we can use this to make generators which depend on other generators.
For example, to generate pairs [a b]
where we must have (>= a b)
we can use this generator:
(def pair-gen (gen/bind (gen/choose 1 10)
(fn [a]
(gen/bind (gen/choose 1 a)
(fn [b]
(gen/return [a b]))))))
To satisfy ourselves:
(c/quick-check 10000
(prop/for-all [[a b] pair-gen]
(>= a b)))
gen/bind
takes a generator g
and a function f
. It generates a value from g
, let's call it x
. gen/bind
then returns the value of (f x)
, which must be a new generator. gen/return
is a generator which only generates its argument (so above I used it to return the pairs).
Upvotes: 3