diff --git a/core/jvm/src/test/scala/org/scalacheck/GenSpecification.scala b/core/jvm/src/test/scala/org/scalacheck/GenSpecification.scala index 45a9dace..02ff200e 100644 --- a/core/jvm/src/test/scala/org/scalacheck/GenSpecification.scala +++ b/core/jvm/src/test/scala/org/scalacheck/GenSpecification.scala @@ -582,7 +582,7 @@ object GenSpecification extends Properties("Gen") with GenSpecificationVersionSp seed = s1 } val avg = sum / n - s"average = $avg" |: avg >= 0.49 && avg <= 0.51 + (avg >= 0.49 && avg <= 0.51).labelImpl2(s"average = $avg") } property("uniform long #209") = { @@ -598,7 +598,7 @@ object GenSpecification extends Properties("Gen") with GenSpecificationVersionSp seed = s1 } val avg = sum / n - s"average = $avg" |: avg >= 0.49 && avg <= 0.51 + (avg >= 0.49 && avg <= 0.51).labelImpl2(s"average = $avg") } } //// @@ -651,7 +651,7 @@ object GenSpecification extends Properties("Gen") with GenSpecificationVersionSp val s0 = (1 to 30).map(_ => g(params0, Seed.random())).toSet val s1 = (1 to 30).map(_ => g(params1, Seed.random())).toSet val s2 = (1 to 30).map(_ => g(params0, seed)).toSet - (s"$s0" |: s0.size > 1) && (s"$s1" |: s1.size == 1) && (s"$s2" |: s2.size == 1) + (s0.size > 1).labelImpl2(s"$s0") && (s1.size == 1).labelImpl2(s"$s1") && (s2.size == 1).labelImpl2(s"$s2") } property("arbitrary[Boolean] is deterministic") = diff --git a/core/jvm/src/test/scala/org/scalacheck/PropertyFilterSpecification.scala b/core/jvm/src/test/scala/org/scalacheck/PropertyFilterSpecification.scala index 091c72d4..2d3994d7 100644 --- a/core/jvm/src/test/scala/org/scalacheck/PropertyFilterSpecification.scala +++ b/core/jvm/src/test/scala/org/scalacheck/PropertyFilterSpecification.scala @@ -43,7 +43,7 @@ object PropertyFilterSpecification extends Properties("PropertyFilter") { def props = actualNames.forall(expectedNames.contains) - (lengthProp && props) :| diff(filter, actualNames, expectedNames) + (lengthProp && props).labelImpl2(diff(filter, actualNames, expectedNames)) } property("filter properties by predicate") = diff --git a/core/jvm/src/test/scala/org/scalacheck/ShrinkSpecificationJVM.scala b/core/jvm/src/test/scala/org/scalacheck/ShrinkSpecificationJVM.scala index e8449cde..8deb1e06 100644 --- a/core/jvm/src/test/scala/org/scalacheck/ShrinkSpecificationJVM.scala +++ b/core/jvm/src/test/scala/org/scalacheck/ShrinkSpecificationJVM.scala @@ -25,14 +25,14 @@ object ShrinkSpecificationJVM extends Properties("Shrink JVM") { property("non-empty list") = forAll { (l: List[Int]) => (!l.isEmpty && l != List(0)) ==> { val ls = shrinkClosure(l) - ls.toList.toString |: (ls.contains(Nil) && ls.contains(List(0))) + (ls.contains(Nil) && ls.contains(List(0))).labelImpl2(ls.toList.toString) } } property("xmap vector from list") = forAll { (v: Vector[Int]) => (!v.isEmpty && v != Vector(0)) ==> { val vs = shrinkClosure(v) - Vector(vs: _*).toString |: (vs.contains(Vector.empty) && vs.contains(Vector(0))) + (vs.contains(Vector.empty) && vs.contains(Vector(0))).labelImpl2(Vector(vs: _*).toString) } } diff --git a/core/jvm/src/test/scala/org/scalacheck/TestSpecification.scala b/core/jvm/src/test/scala/org/scalacheck/TestSpecification.scala index 77f55b74..f7850f3c 100644 --- a/core/jvm/src/test/scala/org/scalacheck/TestSpecification.scala +++ b/core/jvm/src/test/scala/org/scalacheck/TestSpecification.scala @@ -53,11 +53,13 @@ object TestSpecification extends Properties("Test") { private def resultInvariant(f: (Test.Parameters, Test.Result) => Boolean): Prop = forAll { (prms: Test.Parameters, p: Prop) => val r = Test.check(prms, p) - s"${r.status}, s=${r.succeeded}, d=${r.discarded}, " + - s"minSuccessful=${prms.minSuccessfulTests}, " + - s"maxDiscardRatio=${prms.maxDiscardRatio}, " + - s"actualDiscardRatio=${r.discarded.toFloat / r.succeeded}, " + - s"workers=${prms.workers}" |: f(prms, r) + f(prms, r).labelImpl2( + s"${r.status}, s=${r.succeeded}, d=${r.discarded}, " + + s"minSuccessful=${prms.minSuccessfulTests}, " + + s"maxDiscardRatio=${prms.maxDiscardRatio}, " + + s"actualDiscardRatio=${r.discarded.toFloat / r.succeeded}, " + + s"workers=${prms.workers}" + ) } property("stopCondition") = resultInvariant { (prms, r) => @@ -110,8 +112,8 @@ object TestSpecification extends Properties("Test") { property("propGenException") = forAll { (prms: Test.Parameters) => Test.check(prms, genException).status match { - case x: PropException => true :| x.toString - case x => false :| x.toString + case x: PropException => true.labelImpl2(x.toString) + case x => false.labelImpl2(x.toString) } } @@ -185,8 +187,8 @@ object TestSpecification extends Properties("Test") { val res = Test.check(prms, prop) val n = xs.size val unique = xs.toSet - val p0 = Prop(unique(expected)) :| s"did not see $expected in $unique" - val p1 = Prop(unique.size > 1) :| s"saw $n duplicate values: $unique" + val p0 = Prop(unique(expected)).labelImpl2(s"did not see $expected in $unique") + val p1 = Prop(unique.size > 1).labelImpl2(s"saw $n duplicate values: $unique") p0 && p1 } @@ -209,8 +211,8 @@ object TestSpecification extends Properties("Test") { Test.check_(prms, prop) val n = xs.size val unique = xs.toSet - val p0 = Prop(unique(expected)) :| s"did not see $expected in $unique" - val p1 = Prop(unique.size > 1) :| s"saw $n duplicate values: $unique" + val p0 = Prop(unique(expected)).labelImpl2(s"did not see $expected in $unique") + val p1 = Prop(unique.size > 1).labelImpl2(s"saw $n duplicate values: $unique") p0 && p1 } } diff --git a/core/shared/src/main/scala/org/scalacheck/Prop.scala b/core/shared/src/main/scala/org/scalacheck/Prop.scala index dedb1ec8..95ad7e31 100644 --- a/core/shared/src/main/scala/org/scalacheck/Prop.scala +++ b/core/shared/src/main/scala/org/scalacheck/Prop.scala @@ -23,7 +23,7 @@ sealed class PropFromFun(f: Gen.Parameters => Prop.Result) extends Prop { @Platform.EnableReflectiveInstantiation sealed abstract class Prop extends Serializable { self => - import Prop.{Result, True, False, Undecided, provedToTrue, mergeRes} + import Prop.{Exception, Proof, Result, True, False, Undecided, provedToTrue, mergeRes} def apply(prms: Gen.Parameters): Result @@ -148,21 +148,43 @@ sealed abstract class Prop extends Serializable { self => override def toString = "Prop" + private[scalacheck] def labelImpl1(l: String) = map(_.label(l)) + + /** Put a label on the property to make test reports clearer */ + private[scalacheck] def label(l: String) = labelImpl1(l) + + /** Put a label on the property to make test reports clearer */ + private[scalacheck] def :|(l: String) = labelImpl1(l) + + /** Put a label on the property to make test reports clearer */ + private[scalacheck] def |:(l: String) = labelImpl1(l) + + /** Put a label on the property to make test reports clearer */ + private[scalacheck] def :|(l: Symbol) = labelImpl1(l.name) + /** Put a label on the property to make test reports clearer */ - def label(l: String) = map(_.label(l)) + private[scalacheck] def |:(l: Symbol) = labelImpl1(l.name) + + private[scalacheck] def labelImpl2(l: => String) = + map(r => r.status match { + case False | Exception(_) => r.label(l) + case Proof | True | Undecided => r + }) /** Put a label on the property to make test reports clearer */ - def :|(l: String) = label(l) + def label(l: => String) = labelImpl2(l) /** Put a label on the property to make test reports clearer */ - def |:(l: String) = label(l) + def :|(l: => String) = labelImpl2(l) /** Put a label on the property to make test reports clearer */ - def :|(l: Symbol) = label(l.name) + def |:(l: => String) = labelImpl2(l) /** Put a label on the property to make test reports clearer */ - def |:(l: Symbol) = label(l.name) + def :|(l: => Symbol)(implicit d: DummyImplicit) = labelImpl2(l.name) + /** Put a label on the property to make test reports clearer */ + def |:(l: => Symbol)(implicit d: DummyImplicit) = labelImpl2(l.name) } object Prop { @@ -341,16 +363,16 @@ object Prop { def ==>(p: => Prop) = Prop(b) ==> p /** See the documentation for [[org.scalacheck.Prop]] */ - def :|(l: String) = Prop(b) :| l + def :|(l: String) = Prop(b).labelImpl1(l) /** See the documentation for [[org.scalacheck.Prop]] */ - def |:(l: String) = l |: Prop(b) + def |:(l: String) = Prop(b).labelImpl1(l) /** See the documentation for [[org.scalacheck.Prop]] */ - def :|(l: Symbol) = Prop(b) :| l + def :|(l: Symbol) = Prop(b).labelImpl1(l.name) /** See the documentation for [[org.scalacheck.Prop]] */ - def |:(l: Symbol) = l |: Prop(b) + def |:(l: Symbol) = Prop(b).labelImpl1(l.name) } /** Implicit method that makes a number of property operators on values of type `Any` available in the current scope. @@ -399,7 +421,7 @@ object Prop { */ def ?=[T](x: T, y: T)(implicit pp: T => Pretty): Prop = if (x == y) proved - else falsified :| { + else falsified.labelImpl2 { val exp = Pretty.pretty[T](y, Pretty.Params(0)) val act = Pretty.pretty[T](x, Pretty.Params(0)) "Expected " + exp + " but got " + act diff --git a/core/shared/src/main/scala/org/scalacheck/commands/Commands.scala b/core/shared/src/main/scala/org/scalacheck/commands/Commands.scala index 4891dd8f..057ebca0 100644 --- a/core/shared/src/main/scala/org/scalacheck/commands/Commands.scala +++ b/core/shared/src/main/scala/org/scalacheck/commands/Commands.scala @@ -364,13 +364,13 @@ trait Commands { try { val (p1, s, rs1) = runSeqCmds(sut, as.s, as.seqCmds) val l1 = s"Initial State:\n ${as.s}\nSequential Commands:\n${prettyCmdsRes(as.seqCmds zip rs1, maxLength)}" - if (as.parCmds.isEmpty) p1 :| l1 + if (as.parCmds.isEmpty) p1.labelImpl2(l1) else propAnd( - p1.flatMap { r => if (!r.success) finalize; Prop(_ => r) } :| l1, { + p1.flatMap { r => if (!r.success) finalize; Prop(_ => r) }.labelImpl2(l1), { try { val (p2, rs2) = runParCmds(sut, s, as.parCmds) val l2 = rs2.map(prettyCmdsRes(_, maxLength)).mkString("\n\n") - p2 :| l1 :| s"Parallel Commands (starting in state = ${s})\n$l2" + p2.labelImpl2(l1).labelImpl2(s"Parallel Commands (starting in state = ${s})\n$l2") } finally finalize } ) diff --git a/core/shared/src/test/scala/org/scalacheck/PropSpecification.scala b/core/shared/src/test/scala/org/scalacheck/PropSpecification.scala index ce62b731..662e5125 100644 --- a/core/shared/src/test/scala/org/scalacheck/PropSpecification.scala +++ b/core/shared/src/test/scala/org/scalacheck/PropSpecification.scala @@ -218,7 +218,7 @@ object PropSpecification extends Properties("Prop") { val params = Gen.Parameters.default.withInitialSeed(999L) val x = p(params).success val set = (1 to 10).map(_ => p(params).success).toSet - Prop(set == Set(x)).label(s"$set == Set($x)") + Prop(set == Set(x)).labelImpl2(s"$set == Set($x)") } property("prop.useSeed is deterministic") = @@ -227,7 +227,7 @@ object PropSpecification extends Properties("Prop") { val p = p0.useSeed(rng.Seed(n)) val x = p(params).success val set = (1 to 10).map(_ => p(params).success).toSet - Prop(set == Set(x)).label(s"$set == Set($x)") + Prop(set == Set(x)).labelImpl2(s"$set == Set($x)") } property("prop.useSeed is deterministic (pt. 2)") = @@ -237,7 +237,7 @@ object PropSpecification extends Properties("Prop") { val p = p0.useSeed(rng.Seed(n)) val r1 = p(params).success val r2 = p(params).success - Prop(r1 == r2).label(s"$r1 == $r2") + Prop(r1 == r2).labelImpl2(s"$r1 == $r2") } property("disabling shrinking works") = { diff --git a/core/shared/src/test/scala/org/scalacheck/StatsSpecification.scala b/core/shared/src/test/scala/org/scalacheck/StatsSpecification.scala index 0a214693..b9acc830 100644 --- a/core/shared/src/test/scala/org/scalacheck/StatsSpecification.scala +++ b/core/shared/src/test/scala/org/scalacheck/StatsSpecification.scala @@ -87,7 +87,7 @@ object StatsSpecification extends Properties("Stats") { case class Bounds(min: Double, max: Double) { def contains(x: Double): Prop = - Prop(min <= x && x <= max) :| s"($min <= $x <= $max) was false" + Prop(min <= x && x <= max).labelImpl2(s"($min <= $x <= $max) was false") } implicit class MakeBounds(val n: Double) extends AnyVal {