diff --git a/src/main/scala/org/scalacheck/Gen.scala b/src/main/scala/org/scalacheck/Gen.scala index 28c3f68de..b52589979 100644 --- a/src/main/scala/org/scalacheck/Gen.scala +++ b/src/main/scala/org/scalacheck/Gen.scala @@ -260,6 +260,15 @@ object Gen extends GenArities with GenVersionSpecific { /** Generator parameters, used by [[org.scalacheck.Gen.apply]] */ sealed abstract class Parameters extends Serializable { outer => + override def toString: String = { + val sb = new StringBuilder + sb.append("Parameters(") + sb.append(s"size=$size, ") + sb.append(s"initialSeed=$initialSeed, ") + sb.append(s"useLegacyShrinking=$useLegacyShrinking)") + sb.toString + } + /** * The size of the generated value. Generator implementations are * allowed to freely interpret (or ignore) this value. During test diff --git a/src/main/scala/org/scalacheck/Prop.scala b/src/main/scala/org/scalacheck/Prop.scala index 42499c8d1..37ff149df 100644 --- a/src/main/scala/org/scalacheck/Prop.scala +++ b/src/main/scala/org/scalacheck/Prop.scala @@ -50,7 +50,12 @@ sealed abstract class Prop extends Serializable { self => def map(f: Result => Result): Prop = Prop(prms => f(this(prms))) - def flatMap(f: Result => Prop): Prop = Prop(prms => f(this(prms))(prms)) + def flatMap(f: Result => Prop): Prop = + Prop { prms0 => + val res = this(prms0) + val prms1 = Prop.slideSeed(prms0) + f(res)(prms1) + } def combine(p: => Prop)(f: (Result, Result) => Result) = for(r1 <- this; r2 <- p) yield f(r1,r2) @@ -422,23 +427,23 @@ object Prop { /** Combines properties into one, which is true if and only if all the * properties are true */ - def all(ps: Prop*) = if(ps.isEmpty) proved else Prop(prms => - ps.map(p => p(prms)).reduceLeft(_ && _) - ) + def all(ps: Prop*): Prop = + ps.foldLeft(proved)(_ && _) /** Combines properties into one, which is true if at least one of the * properties is true */ - def atLeastOne(ps: Prop*) = if(ps.isEmpty) falsified else Prop(prms => - ps.map(p => p(prms)).reduceLeft(_ || _) - ) + def atLeastOne(ps: Prop*): Prop = + ps.foldLeft(falsified)(_ || _) /** A property that holds if at least one of the given generators * fails generating a value */ - def someFailing[T](gs: Seq[Gen[T]]) = atLeastOne(gs.map(_ == Gen.fail):_*) + def someFailing[T](gs: Seq[Gen[T]]): Prop = + atLeastOne(gs.map(_ == Gen.fail):_*) /** A property that holds iff none of the given generators * fails generating a value */ - def noneFailing[T](gs: Seq[Gen[T]]) = all(gs.map(_ !== Gen.fail):_*) + def noneFailing[T](gs: Seq[Gen[T]]): Prop = + all(gs.map(_ !== Gen.fail):_*) /** Returns true if the given statement throws an exception * of the specified type */ diff --git a/src/test/scala/org/scalacheck/PropSpecification.scala b/src/test/scala/org/scalacheck/PropSpecification.scala index 6a3fa5a0a..b05479d04 100644 --- a/src/test/scala/org/scalacheck/PropSpecification.scala +++ b/src/test/scala/org/scalacheck/PropSpecification.scala @@ -223,4 +223,9 @@ object PropSpecification extends Properties("Prop") { val prop = Prop.forAll(Bogus.gen) { b => Prop(false) } Prop(prop(params).failure && !Bogus.shrunk) } + + // make sure the two forAlls are seeing independent values + property("regression #530: failure to slide seed") = + forAll((x: Int) => (x >= 0) ==> true) && + forAll((x: Int) => (x < 0) ==> true) }