From c5317a1f72f95c301282818f6da37237704643d1 Mon Sep 17 00:00:00 2001 From: Grzegorz Kossakowski Date: Mon, 25 Nov 2013 18:50:49 +0100 Subject: [PATCH] Work harder on generating unique values in generator for Analysis. The TestCaseGenerators uses global set for ensuring that certain generated values are unique. This is not the best design because the more properties you check the harder is to generate new sample inputs because of already accumulated values. This results in: [info] + Analysis.Simple Merge and Split: OK, proved property. [info] ! Analysis.Complex Merge and Split: Gave up after only 8 passed tests. 93 tests were discarded. I don't have an ambition to reduce the scope of this global set but at least I wanted to make generators to work a bit harder on generating samples. Instead of using `suchThat` method for filtering out non-unique samples we use `retryUntil` that never gives up (therefore it might not terminate). We had to upgrade to latest (1.11.1) version of scalacheck in order to have an access to `retryUntil` method. Also, I overridden the `identifier` to delegate to original `Gen.identifier` but with minimal size set to be to '3'. This means, the generated identifier will be of size 3 or larger which is needed in order to avoid collisions. --- .../inc/src/test/scala/sbt/inc/TestCaseGenerators.scala | 7 ++++++- project/Util.scala | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/compile/inc/src/test/scala/sbt/inc/TestCaseGenerators.scala b/compile/inc/src/test/scala/sbt/inc/TestCaseGenerators.scala index 04447eaa8..f00ff8303 100644 --- a/compile/inc/src/test/scala/sbt/inc/TestCaseGenerators.scala +++ b/compile/inc/src/test/scala/sbt/inc/TestCaseGenerators.scala @@ -27,7 +27,12 @@ object TestCaseGenerators { // Ensure that we generate unique class names and file paths every time. // Using repeated strings may lead to all sorts of undesirable interactions. val used = scala.collection.mutable.Set.empty[String] - def unique[T](g: Gen[T]) = g suchThat { o: T => used.add(o.toString) } + + def unique[T](g: Gen[T]) = g retryUntil { o: T => used.add(o.toString) } + + def identifier: Gen[String] = sized { size => + resize(Math.max(size, 3), Gen.identifier) + } def genFilePathSegment: Gen[String] = for { n <- choose(3, maxPathSegmentLen) // Segments have at least 3 characters. diff --git a/project/Util.scala b/project/Util.scala index cedfe1e40..9b7595a3c 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -50,7 +50,7 @@ object Util def testDependencies = libraryDependencies <++= includeTestDependencies { incl => if(incl) Seq( - "org.scalacheck" %% "scalacheck" % "1.11.0" % "test", + "org.scalacheck" %% "scalacheck" % "1.11.1" % "test", "org.specs2" %% "specs2" % "1.12.3" % "test", "junit" % "junit" % "4.11" % "test" )