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

56 lines
1.6 KiB
Scala

/* sbt -- Simple Build Tool
* Copyright 2008 Mark Harrah */
package sbt
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.Params): 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("[", ",", "]")
}