Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Have the size parameter really put a hard limit on the size of genera…
…ted recursive structures
- Loading branch information
1 parent
47607bc
commit b2ca742
Showing
3 changed files
with
115 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
test/shared/src/main/scala/org/scalacheck/SizeTestsDefinitions.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.scalacheck | ||
|
||
object SizeTestsDefinitions { | ||
// see https://github.com/rickynils/scalacheck/issues/305 | ||
sealed trait Tree { | ||
def depth: Int = { | ||
|
||
var max = 0 | ||
val m = new scala.collection.mutable.Queue[(Int, Branch)] | ||
|
||
def handle(t: Tree, s: Int) = | ||
t match { | ||
case Leaf => max = max max s | ||
case b: Branch => | ||
m += (s + 1) -> b | ||
} | ||
|
||
handle(this, 0) | ||
|
||
while (m.nonEmpty) { | ||
val (s, b) = m.dequeue | ||
handle(b.left, s) | ||
handle(b.right, s) | ||
} | ||
|
||
max | ||
} | ||
} | ||
case object Leaf extends Tree | ||
case class Branch(left: Tree, right: Tree) extends Tree | ||
|
||
object Tree { | ||
implicit val recursive = derive.Recursive[Tree](Gen.const(Leaf)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package org.scalacheck | ||
|
||
import utest._ | ||
|
||
import org.scalacheck.rng.Seed | ||
|
||
object SizeTests0 { | ||
import org.scalacheck.Shapeless._ | ||
|
||
import SizeTestsDefinitions._ | ||
|
||
val arbTree = Arbitrary(Arbitrary.arbitrary[Tree]) | ||
|
||
} | ||
|
||
object SizeTests extends TestSuite { | ||
|
||
import SizeTestsDefinitions._ | ||
|
||
assert(Leaf.depth == 0) | ||
assert(Branch(Leaf, Leaf).depth == 1) | ||
assert(Branch(Branch(Leaf, Leaf), Leaf).depth == 2) | ||
|
||
|
||
def stream[T: Arbitrary](p: Gen.Parameters, seed: rng.Seed): Stream[Option[T]] = { | ||
val r = Arbitrary.arbitrary[T].doPureApply(p, seed) | ||
r.retrieve #:: stream[T](p, r.seed) | ||
} | ||
|
||
// manually calculated, grows approx. like log(size) | ||
val maxDepths = Seq( | ||
10 -> 5, | ||
100 -> 8, | ||
300 -> 10 | ||
) | ||
|
||
val tests = TestSuite { | ||
'tree - { | ||
val seed = Seed.random() | ||
val inspect = 10000 | ||
|
||
for ((size, expectedMaxDepth) <- maxDepths) { | ||
val maxDepth = stream[Tree](Gen.Parameters.default.withSize(size), seed)(SizeTests0.arbTree) | ||
.map(_.get) // the corresponding generator doesn't fail thanks to the implicit derive.Recursive[Tree] in Tree's companion | ||
.map(_.depth) | ||
.take(inspect) | ||
.max | ||
|
||
assert(maxDepth == expectedMaxDepth) | ||
} | ||
} | ||
} | ||
|
||
} |