-
Notifications
You must be signed in to change notification settings - Fork 407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Arbitrary functions fail when the Gen instance on their return type sometimes fails #300
Comments
So, just to be clear, the generator has to fail many times (by default 100) before the function generator fails. See I think this is the only reasonable behavior for a generator that can be filtered (it is roughly the same behavior as the original QuickCheck's). By contrast, @xuwei-k's ScalaProps library does not even include My sense is that ScalaCheck-Shapeless wasn't just failing some of the time, but a significant fraction of the time (e.g. 50% or more) which seems like it needed to be fixed anyway. |
@non Per the source, |
As @nrinaudo's example illustrates, it only takes one failure to make import org.scalacheck._
implicit val nonZero: Arbitrary[Int] = Arbitrary(Arbitrary.arbInt.arbitrary.suchThat(_ != 0))
val prop = Prop.forAll { (f: String => Int) => f("foo"); true }
prop.check gives
|
OK! Yes, there is a bug/typo, the method should read: def doPureApply(p: Gen.Parameters, seed: Seed, retries: Int = 100): Gen.R[T] = {
@tailrec def loop(r: Gen.R[T], i: Int): Gen.R[T] = {
if (r.retrieve.isDefined) r
else if (i > 0) loop(doApply(p, r.seed), i - 1)
else throw new Gen.RetrievalError()
}
loop(doApply(p, seed), retries)
} I've confirmed that with this change the property passes. I'll open a PR to fix this. Thanks for being persistent and reporting it! |
This commit fixes a bug pointed out by @alexarchambault. When constructing an `A => B` value from `Cogen[A]` and `Gen[B]`, we need to be able to reliably generate a `B` value given a `Seed`. The `doPureApply` method was given the ability to retry -- but unfortunately, it used the same result value (with the same seed) instead of trying a new one, defeating the retry code. This commit fixes that problem. It adds tests to ensure that filtered generators that can also produce real values can be used with Gen.function1. (If a generator can never produce values it will still be a problem.) Fixes typelevel#300.
This commit fixes a bug pointed out by @alexarchambault. When constructing an `A => B` value from `Cogen[A]` and `Gen[B]`, we need to be able to reliably generate a `B` value given a `Seed`. The `doPureApply` method was given the ability to retry -- but unfortunately, it used the same result value (with the same seed) instead of trying a new one, defeating the retry code. This commit fixes that problem. It adds tests to ensure that filtered generators that can also produce real values can be used with Gen.function1. (If a generator can never produce values it will still be a problem.) Fixes typelevel#300.
I'd appreciate your publishing this fix for Scala 2.11. Thanks a lot. |
This commit fixes a bug pointed out by @alexarchambault. When constructing an `A => B` value from `Cogen[A]` and `Gen[B]`, we need to be able to reliably generate a `B` value given a `Seed`. The `doPureApply` method was given the ability to retry -- but unfortunately, it used the same result value (with the same seed) instead of trying a new one, defeating the retry code. This commit fixes that problem. It adds tests to ensure that filtered generators that can also produce real values can be used with Gen.function1. (If a generator can never produce values it will still be a problem.) Fixes typelevel#300.
This commit fixes a bug pointed out by @alexarchambault. When constructing an `A => B` value from `Cogen[A]` and `Gen[B]`, we need to be able to reliably generate a `B` value given a `Seed`. The `doPureApply` method was given the ability to retry -- but unfortunately, it used the same result value (with the same seed) instead of trying a new one, defeating the retry code. This commit fixes that problem. It adds tests to ensure that filtered generators that can also produce real values can be used with Gen.function1. (If a generator can never produce values it will still be a problem.) Fixes typelevel#300.
This means, among other things, that any
Arbitrary
instance that relies onGen.suchThat
cannot be used to generate arbitrary functions.As an example:
And then:
See alexarchambault/scalacheck-shapeless#50 for a far more insidious example.
The text was updated successfully, but these errors were encountered: