Skip to content

Commit

Permalink
Merge pull request #910 from AurelienRichez/fix/fix-909
Browse files Browse the repository at this point in the history
fix wrong match in shrinker (fixes #909)
  • Loading branch information
rossabaker authored Aug 2, 2022
2 parents 4867326 + 4df1e67 commit 8689ae7
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
4 changes: 2 additions & 2 deletions core/shared/src/main/scala/org/scalacheck/Prop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ object Prop {
/*
* Returns the first failed result in Left or success in Right.
*/
def getFirstFailure(xs: Stream[T], exceptionFilter: Option[Class[_]]): Either[(T,Result),(T,Result)] = {
def getFirstFailure(xs: Stream[T], exceptionFilter: Option[Class[_ <: Throwable]]): Either[(T,Result),(T,Result)] = {
assert(!xs.isEmpty, "Stream cannot be empty")
val results = xs.map(x => (x, result(x)))
results.dropWhile {
Expand All @@ -788,7 +788,7 @@ object Prop {
def shrinker(x: T, r: Result, shrinks: Int, orig: T): Result = {
val xs = shrink(x)
val res = r.addArg(Arg(labels,x,shrinks,orig,pp(x),pp(orig)))
val originalException = Some(r.status).collect { case NonFatal(e) => e.getClass() }
val originalException = Some(r.status).collect { case Prop.Exception(e) => e.getClass }
if(xs.isEmpty) res else getFirstFailure(xs, originalException) match {
case Right((x2,r2)) => res
case Left((x2,r2)) => shrinker(x2, replOrig(r,r2), shrinks+1, orig)
Expand Down
24 changes: 24 additions & 0 deletions core/shared/src/test/scala/org/scalacheck/PropSpecification.scala
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,30 @@ object PropSpecification extends Properties("Prop") {
})
}

property("shrinking process always take the first value returned by the Shrink[T]") = {
// this shrinker split a string in 2
implicit val stringShrink: Shrink[String] = Shrink[String] {
def split(s: String): Stream[String] = {
if (s.length == 1) Stream.empty
else {
s.take(s.length / 2) #:: s.drop(s.length / 2) #:: Stream.empty
}
}
split
}

// shrinked value will be "1234", then shrinked to "12" because it also fails, and finally "1"
val prop = forAll(Gen.const("12345678")) { (a: String) =>
throw new RuntimeException("expected exception")
}

val result = prop(Gen.Parameters.default)
Prop(result.status match {
case Exception(_) => result.args.head.arg == "1"
case _ => false
})
}

// make sure the two forAlls are seeing independent values
property("regression #530: failure to slide seed") =
forAll((x: Int) => (x >= 0) ==> true) &&
Expand Down

0 comments on commit 8689ae7

Please sign in to comment.