I am trying to generate optional parameters in ScalaCheck, without success.
There seems to be no direct mechanism for this. Gen.containerOf[Option, Thing](thingGenerator)
fails because it cannot find an implicit Buildable[Thing, Option]
.
I tried
for {
thing <- Gen.listOfN[Thing](1, thingGenerator)
} yield thing.headOption
But this doesn't work because listOfN
produces a list that is always of length N. As a result I always get a Some[Thing]
. Similarly, listOf1
does not work, because (a) it doesn't produce empty lists, but also (b) it is inefficient because I can't set a max limit on the number of elements.
How can I generate Option[Thing]
that includes Nones?
EDIT: I have found a solution, but it is not succinct. Is there a better way than this?
for {
thing <- for {
qty <- Gen.choose(0,1)
things <- Gen.listOfN[Thing](qty, thingGenerator)
} yield things.headOption
} yield thing
EDIT 2: I generalised this to
def optional[T](g: Gen[T]) =
for (qty <- Gen.choose(0, 1); xs <- Gen.listOfN[T](qty, g)) yield xs.headOption
So I don't have to write it more than once. But surely this is in the library already and I just missed it?
Now you can just use:
Gen.option(yourGen)
You can use pick
to randomly choose between a Some and a None generator:
val someThing = thingGenerator.map( Some.apply )
val noThing = Gen.value( None:Option[Thing] )
val optThing = Gen.oneOf( someThing, noThing )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With