Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix for #530 #531

Merged
merged 1 commit into from
Aug 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/main/scala/org/scalacheck/Gen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 14 additions & 9 deletions src/main/scala/org/scalacheck/Prop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down
5 changes: 5 additions & 0 deletions src/test/scala/org/scalacheck/PropSpecification.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}