sbt/internal/util-collection/src/test/scala/DagSpecification.scala

50 lines
1.7 KiB
Scala

/* sbt -- Simple Build Tool
* Copyright 2008 Mark Harrah */
package sbt.internal.util
import org.scalacheck._
import Prop._
import scala.collection.mutable.HashSet
object DagSpecification extends Properties("Dag") {
property("No repeated nodes") = forAll { (dag: TestDag) => isSet(dag.topologicalSort) }
property("Sort contains node") = forAll { (dag: TestDag) => dag.topologicalSort.contains(dag) }
property("Dependencies precede node") = forAll { (dag: TestDag) => dependenciesPrecedeNodes(dag.topologicalSort) }
implicit lazy val arbTestDag: Arbitrary[TestDag] = Arbitrary(Gen.sized(dagGen))
private def dagGen(nodeCount: Int): Gen[TestDag] =
{
val nodes = new HashSet[TestDag]
def nonterminalGen(p: Gen.Parameters): Gen[TestDag] =
{
for (i <- 0 until nodeCount; nextDeps <- Gen.someOf(nodes).apply(p))
nodes += new TestDag(i, nextDeps)
for (nextDeps <- Gen.someOf(nodes)) yield new TestDag(nodeCount, nextDeps)
}
Gen.parameterized(nonterminalGen)
}
private def isSet[T](c: Seq[T]) = Set(c: _*).size == c.size
private def dependenciesPrecedeNodes(sort: List[TestDag]) =
{
val seen = new HashSet[TestDag]
def iterate(remaining: List[TestDag]): Boolean =
{
remaining match {
case Nil => true
case node :: tail =>
if (node.dependencies.forall(seen.contains) && !seen.contains(node)) {
seen += node
iterate(tail)
} else
false
}
}
iterate(sort)
}
}
class TestDag(id: Int, val dependencies: Iterable[TestDag]) extends Dag[TestDag] {
override def toString = id + "->" + dependencies.mkString("[", ",", "]")
}