From 4572f1b6cab1bdede9a4066416ba8392d447f666 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 10 Jun 2010 08:19:15 -0400 Subject: [PATCH] update task tests --- tasks/src/test/scala/DemoTask.scala | 159 ++++++++++++++++++ .../scala/{TestRunner.scala => Execute.scala} | 27 +-- tasks/src/test/scala/TaskGen.scala | 9 +- tasks/src/test/scala/TaskRunnerCircular.scala | 26 +-- tasks/src/test/scala/TaskRunnerFork.scala | 14 +- tasks/src/test/scala/Test.scala | 77 ++------- tasks/src/test/scala/TestRunnerCall.scala | 9 +- tasks/src/test/scala/TestRunnerSort.scala | 25 ++- tasks/src/test/scala/checkResult.scala | 9 +- 9 files changed, 241 insertions(+), 114 deletions(-) create mode 100644 tasks/src/test/scala/DemoTask.scala rename tasks/src/test/scala/{TestRunner.scala => Execute.scala} (57%) diff --git a/tasks/src/test/scala/DemoTask.scala b/tasks/src/test/scala/DemoTask.scala new file mode 100644 index 000000000..8ed192794 --- /dev/null +++ b/tasks/src/test/scala/DemoTask.scala @@ -0,0 +1,159 @@ +/* sbt -- Simple Build Tool + * Copyright 2010 Mark Harrah + */ +package sbt + +import Types._ +import Task._ +import Execute._ + +sealed trait Task[+T] +sealed case class Pure[+T](eval: () => T) extends Task[T] +final case class Mapped[+T, In <: MList[Task]](in: In, f: In#Map[Result] => T) extends Task[T] +final case class MapAll[+T, In <: MList[Task]](in: In, f: In#Map[Result]#Raw => T) extends Task[T] +final case class FlatMapAll[+T, In <: MList[Task]](in: In, f: In#Map[Result]#Raw => Task[T]) extends Task[T] +final case class MapFailure[+T, In <: MList[Task]](in: In, f: Seq[Incomplete] => T) extends Task[T] +final case class FlatMapFailure[+T, In <: MList[Task]](in: In, f: Seq[Incomplete] => Task[T]) extends Task[T] +final case class FlatMapped[+T, In <: MList[Task]](in: In, f: In#Map[Result] => Task[T]) extends Task[T] +final case class DependsOn[+T](in: Task[T], deps: Seq[Task[_]]) extends Task[T] +final case class Join[+T, U](in: Seq[Task[U]], f: Seq[U] => Either[Task[T], T]) extends Task[T] { type Uniform = U } + +trait MultiInTask[M <: MList[Task]] +{ + def flatMap[T](f: M#Map[Result]#Raw => Task[T]): Task[T] + def flatMapR[T](f: M#Map[Result] => Task[T]): Task[T] + def mapH[T](f: M#Map[Result]#Raw => T): Task[T] + def mapR[T](f: M#Map[Result] => T): Task[T] + def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] + def mapFailure[T](f: Seq[Incomplete] => T): Task[T] +} +trait SingleInTask[S] +{ + def flatMapR[T](f: Result[S] => Task[T]): Task[T] + def flatMap[T](f: S => Task[T]): Task[T] + def map[T](f: S => T): Task[T] + def mapR[T](f: Result[S] => T): Task[T] + def flatFailure[T](f: Incomplete => Task[T]): Task[T] + def mapFailure[T](f: Incomplete => T): Task[T] + def dependsOn(tasks: Task[_]*): Task[S] +} +trait ForkTask[S, CC[_]] +{ + def fork[T](f: S => T): CC[Task[T]] +} +trait JoinTask[S, CC[_]] +{ + def join: Task[CC[S]] + def reduce(f: (S,S) => S): Task[S] +} +object Task +{ + def pure[T](f: => T): Task[T] = toPure(f _) + def pure[T](name: String, f: => T): Task[T] = new Pure(f _) { override def toString = name } + implicit def toPure[T](f: () => T): Task[T] = new Pure(f) + + implicit def toTasks[S](in: Seq[S]): Seq[Task[S]] = in.map(s => pure(s)) + implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toPure) + implicit def iterableTask[S](in: Seq[S]): ForkTask[S, Seq] = new ForkTask[S, Seq] { + def fork[T](f: S => T): Seq[Task[T]] = in.map(x => pure(x) map f) + } + implicit def joinTasks[S](in: Seq[S]): JoinTask[S, Seq] = joinTasks(toTasks(in)) + implicit def joinTasks[S](in: Seq[Task[S]]): JoinTask[S, Seq] = new JoinTask[S, Seq] { + def join: Task[Seq[S]] = new Join(in, (s: Seq[S]) => Right(s) ) + //def join[T](f: Iterable[S] => T): Task[Iterable[T]] = new MapAll( MList.fromTCList[Task](in), ml => f(ml.toList)) + //def joinR[T](f: Iterable[Result[S]] => T): Task[Iterable[Result[T]]] = new Mapped( MList.fromTCList[Task](in), ml => f(ml.toList)) + def reduce(f: (S,S) => S): Task[S] = Task.reduce(in.toIndexedSeq, f) + } + + + implicit def multInputTask[M <: MList[Task]](ml: M): MultiInTask[M] = new MultiInTask[M] { + def flatMap[T](f: M#Map[Result]#Raw => Task[T]): Task[T] = new FlatMapAll(ml, f) + def flatMapR[T](f: M#Map[Result] => Task[T]): Task[T] = new FlatMapped(ml, f) + def mapH[T](f: M#Map[Result]#Raw => T): Task[T] = new MapAll(ml, f) + def mapR[T](f: M#Map[Result] => T): Task[T] = new Mapped(ml, f) + def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] = new FlatMapFailure(ml, f) + def mapFailure[T](f: Seq[Incomplete] => T): Task[T] = new MapFailure(ml, f) + } + implicit def singleInputTask[S](in: Task[S]): SingleInTask[S] = new SingleInTask[S] { + private val ml = in :^: MNil + private def headM = (_: ml.Map[Result]).head + private def headH = (_: S :+: HNil).head + private def headS = (_: Seq[Incomplete]).head + def flatMapR[T](f: Result[S] => Task[T]): Task[T] = new FlatMapped[T, ml.type](ml, f ∙ headM) + def flatMap[T](f: S => Task[T]): Task[T] = new FlatMapAll[T, ml.type](ml, f ∙ headH) + def map[T](f: S => T): Task[T] = new MapAll[T, ml.type](ml, f ∙ headH) + def mapR[T](f: Result[S] => T): Task[T] = new Mapped[T, ml.type](ml, f ∙ headM) + def flatFailure[T](f: Incomplete => Task[T]): Task[T] = new FlatMapFailure(ml, f ∙ headS) + def mapFailure[T](f: Incomplete => T): Task[T] = new MapFailure(ml, f ∙ headS) + def dependsOn(tasks: Task[_]*): Task[S] = new DependsOn(in, tasks) + } + + implicit val taskToNode = new (Task ~> NodeT[Task]#Apply) { + def apply[T](t: Task[T]): Node[Task, T] = t match { + case Pure(eval) => toNode[T, MNil](MNil, _ => Right(eval()) ) + case Mapped(in, f) => toNode[T, in.type](in, right ∙ f ) + case MapAll(in, f) => toNode[T, in.type](in, right ∙ (f compose allM) ) + case MapFailure(in, f) => toNode[T, in.type](in, right ∙ (f compose failuresM)) + case FlatMapped(in, f) => toNode[T, in.type](in, left ∙ f ) + case FlatMapAll(in, f) => toNode[T, in.type](in, left ∙ (f compose allM) ) + case FlatMapFailure(in, f) => toNode[T, in.type](in, left ∙ (f compose failuresM)) + case DependsOn(in, tasks) => join[T, Any](tasks, (_: Seq[Result[_]]) => Left(in)) + case j@ Join(in, f) => join[T, j.Uniform](in, f compose all) + } + } + def join[T, D](tasks: Seq[Task[D]], f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] { + type Mixed = MNil + val mixedIn = MNil + type Uniform = D + val uniformIn = tasks + def work(mixed: MNil, uniform: Seq[Result[Uniform]]) = { + val inc = failures(uniform) + if(inc.isEmpty) f(uniform) else throw Incomplete(causes = inc) + } + } + def toNode[T, In <: MList[Task]](in: In, f: In#Map[Result] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] { + type Mixed = In + val mixedIn = in + type Uniform = Nothing + val uniformIn = Nil + def work(results: Mixed#Map[Result], units: Seq[Result[Uniform]]) = f(results) + } + def allM[In <: MList[Result]]: In => In#Raw = in => + { + val incs = failuresM(in) + if(incs.isEmpty) in.down(Result.tryValue) else throw Incomplete(causes = incs) + } + def all[D]: Seq[Result[D]] => Seq[D] = in => + { + val incs = failures(in) + if(incs.isEmpty) in.map(Result.tryValue.apply[D]) else throw Incomplete(causes = incs) + } + def failuresM[In <: MList[Result]]: In => Seq[Incomplete] = x => failures[Any](x.toList) + def failures[A]: Seq[Result[A]] => Seq[Incomplete] = _.collect { case Inc(i) => i } + + def run[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): Result[T] = + { + val (service, shutdown) = CompletionService[Task[_], Completed](maxWorkers) + + val x = new Execute[Task](checkCycles)(taskToNode) + try { x.run(root)(service) } finally { shutdown() } + } + def tryRun[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): T = + run(root, checkCycles, maxWorkers) match { + case Value(v) => v + case Inc(i) => throw i + } + + def reduce[S](i: IndexedSeq[Task[S]], f: (S, S) => S): Task[S] = + i match + { + case Seq() => error("Cannot reduce empty sequence") + case Seq(x) => x + case Seq(x, y) => reducePair(x, y, f) + case z => + val (a, b) = i.splitAt(i.size / 2) + reducePair( reduce(a, f), reduce(b, f), f ) + } + def reducePair[S](a: Task[S], b: Task[S], f: (S, S) => S): Task[S] = + (a :^: b :^: MNil) mapH { case x :+: y :+: HNil => f(x,y) } +} \ No newline at end of file diff --git a/tasks/src/test/scala/TestRunner.scala b/tasks/src/test/scala/Execute.scala similarity index 57% rename from tasks/src/test/scala/TestRunner.scala rename to tasks/src/test/scala/Execute.scala index ceba8527a..891ed4352 100644 --- a/tasks/src/test/scala/TestRunner.scala +++ b/tasks/src/test/scala/Execute.scala @@ -1,44 +1,49 @@ -import xsbt._ +/* sbt -- Simple Build Tool + * Copyright 2009, 2010 Mark Harrah + */ +package sbt import org.scalacheck._ import Prop._ import TaskGen._ +import Task._ -object TaskRunnerSpec extends Properties("TaskRunner") +object ExecuteSpec extends Properties("Execute") { val iGen = Arbitrary.arbInt.arbitrary property("evaluates simple task") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) => ("Workers: " + workers) |: - checkResult(TaskRunner(Task(i), workers), i) + checkResult(tryRun(pure(i), false, workers), i) } - property("evaluates simple static graph") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) => + // no direct dependencies currently + /*property("evaluates simple static graph") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) => ("Workers: " + workers) |: { - def result = TaskRunner(Task(i) dependsOn(Task(false),Task("a")), workers) + def result = tryRun(Task(i) dependsOn(pure(false),pure("a")), false, workers) checkResult(result, i) } - } + }*/ property("evaluates simple mapped task") = forAll(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) => ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: { - def result = TaskRunner(Task(i).map(_*times), workers) + def result = tryRun(pure(i).map(_*times), false, workers) checkResult(result, i*times) } } - property("evaluates chained mapped task") = forAllNoShrink(iGen, Gen.choose(0, 1000), MaxWorkersGen) { (i: Int, times: Int, workers: Int) => + property("evaluates chained mapped task") = forAllNoShrink(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) => ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: { - val initial = Task(0) map(identity[Int]) + val initial = pure(0) map(identity[Int]) def task = ( initial /: (0 until times) )( (t,ignore) => t.map(_ + i)) - checkResult(TaskRunner(task, workers), i*times) + checkResult(tryRun(task, false, workers), i*times) } } property("evaluates simple bind") = forAll(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) => ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: { - def result = TaskRunner(Task(i).bind(x => Task(x*times)), workers) + def result = tryRun(pure(i).flatMap(x => pure(x*times)), false, workers) checkResult(result, i*times) } } diff --git a/tasks/src/test/scala/TaskGen.scala b/tasks/src/test/scala/TaskGen.scala index 65ddbfbe5..f14f8eb76 100644 --- a/tasks/src/test/scala/TaskGen.scala +++ b/tasks/src/test/scala/TaskGen.scala @@ -1,11 +1,16 @@ +/* sbt -- Simple Build Tool + * Copyright 2009 Mark Harrah + */ +package sbt + import org.scalacheck._ import Gen.choose object TaskGen { // upper bounds to make the tests finish in reasonable time - val MaxTasks = 10000 - val MaxWorkers = 257 + val MaxTasks = 100 + val MaxWorkers = 29 val MaxJoin = 100 val MaxTasksGen = choose(0, MaxTasks) diff --git a/tasks/src/test/scala/TaskRunnerCircular.scala b/tasks/src/test/scala/TaskRunnerCircular.scala index aebf163bf..7dae59c31 100644 --- a/tasks/src/test/scala/TaskRunnerCircular.scala +++ b/tasks/src/test/scala/TaskRunnerCircular.scala @@ -1,8 +1,9 @@ -import xsbt._ +package sbt import org.scalacheck._ import Prop._ import TaskGen._ +import Task._ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") { @@ -10,32 +11,33 @@ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") property("Allows references to completed tasks") = forAllNoShrink(MaxTasksGen, MaxWorkersGen) { allowedReference _ } final def allowedReference(intermediate: Int, workers: Int) = { - val top = Task(intermediate) named("top") + val top = pure("top", intermediate) def iterate(task: Task[Int]): Task[Int] = - task bind { t => + task flatMap { t => if(t <= 0) top else - iterate(Task(t-1) named (t-1).toString) + iterate(pure((t-1).toString, t-1) ) } - try { checkResult(TaskRunner(iterate(top), workers), intermediate) } - catch { case e: CircularDependency => ("Unexpected exception: " + e) |: false } + try { checkResult(tryRun(iterate(top), true, workers), intermediate) } + catch { case i: Incomplete if cyclic(i) => ("Unexpected cyclic exception: " + i) |: false } } final def checkCircularReferences(intermediate: Int, workers: Int) = { - lazy val top = iterate(Task(intermediate) named"bottom", intermediate) + lazy val top = iterate(pure("bottom", intermediate), intermediate) def iterate(task: Task[Int], i: Int): Task[Int] = { lazy val it: Task[Int] = - task bind { t => + task flatMap { t => if(t <= 0) top else - iterate(Task(t-1) named (t-1).toString, i-1) - } named("it_" + i) + iterate(pure((t-1).toString, t-1), i-1) + } it } - try { TaskRunner(top, workers); false } - catch { case TasksFailed(failures) => failures.exists(_.exception.isInstanceOf[CircularDependency]) } + try { tryRun(top, true, workers); false } + catch { case i: Incomplete => cyclic(i) } } + def cyclic(i: Incomplete) = Incomplete.allExceptions(i).exists(_.isInstanceOf[Execute[Task]#CyclicException[_]]) } \ No newline at end of file diff --git a/tasks/src/test/scala/TaskRunnerFork.scala b/tasks/src/test/scala/TaskRunnerFork.scala index 8d72217bd..c5f7e5a69 100644 --- a/tasks/src/test/scala/TaskRunnerFork.scala +++ b/tasks/src/test/scala/TaskRunnerFork.scala @@ -1,22 +1,22 @@ -import xsbt._ +import sbt._ import org.scalacheck._ import Prop._ import Task._ import TaskGen._ -import Math.abs +import math.abs object TaskRunnerForkTest extends Properties("TaskRunner Fork") { property("fork m tasks and wait for all to complete") = forAll(MaxTasksGen, MaxWorkersGen) { (m: Int, workers: Int) => val values = (0 until m).toList - checkResult(TaskRunner(values.fork(f => () ).join.map(_.toList),workers), values) + checkResult(tryRun(values.fork(f => () ).join.map(_.toList),false, workers), values) true } property("Fork and reduce 2") = forAll(MaxTasksGen, MaxWorkersGen) { (m: Int, workers: Int) => (m > 1) ==> { val task = (0 to m) fork {_ * 10} reduce{_ + _} - checkResult(TaskRunner(task, workers), 5*(m+1)*m) + checkResult(tryRun(task, false, workers), 5*(m+1)*m) } } property("Double join") = forAll(MaxJoinGen, MaxJoinGen, MaxWorkersGen) { (a: Int, b: Int, workers: Int) => @@ -25,13 +25,13 @@ object TaskRunnerForkTest extends Properties("TaskRunner Fork") } def runDoubleJoin(a: Int, b: Int, workers: Int) { - def inner(i: Int) = List.range(0, b).map(j => Task(j) named(j.toString)).join.named("Join " + i) - TaskRunner( List.range(0,a).map(inner).join.named("Outermost join"), workers) + def inner(i: Int) = List.range(0, b).map(j => pure(j.toString, j)).join + tryRun( List.range(0,a).map(inner).join, false, workers) } property("fork and reduce") = forAll(TaskListGen, MaxWorkersGen) { (m: List[Int], workers: Int) => (!m.isEmpty) ==> { val expected = m.reduceLeft(_+_) - checkResult(TaskRunner( m.reduce(_ + _), workers), expected) + checkResult(tryRun( m.reduce(_ + _), false, workers), expected) } } } diff --git a/tasks/src/test/scala/Test.scala b/tasks/src/test/scala/Test.scala index 8929685ae..71121a844 100644 --- a/tasks/src/test/scala/Test.scala +++ b/tasks/src/test/scala/Test.scala @@ -4,60 +4,22 @@ package sbt import Types._ -import Node._ import Task._ import Execute._ -sealed trait Task[+T] -sealed case class Pure[+T](eval: () => T) extends Task[T] -sealed case class Mapped[+T, In <: MList[Task]](in: In, f: In#Map[Result] => T) extends Task[T] -sealed case class MapAll[+T, In <: MList[Task]](in: In, f: In#Map[Result]#Raw => T) extends Task[T] -sealed case class FlatMapAll[+T, In <: MList[Task]](in: In, f: In#Map[Result]#Raw => Task[T]) extends Task[T] -sealed case class FlatMapped[+T, In <: MList[Task]](in: In, f: In#Map[Result] => Task[T]) extends Task[T] - -object Task -{ - implicit val taskToNode = new (Task ~> NodeT[Task]#Apply) { - def apply[T](t: Task[T]): Node[Task, T] = t match { - case Pure(eval) => toNode[T, MNil](MNil, _ => Right(eval()) ) - case Mapped(in, f) => toNode[T, in.type](in, right ∙ f ) - case MapAll(in, f) => toNode[T, in.type](in, right ∙ (f compose all) ) - case FlatMapAll(in, f) => toNode[T, in.type](in, left ∙ (f compose all) ) - case FlatMapped(in, f) => toNode[T, in.type](in, left ∙ f ) - } - } - def toNode[T, In <: MList[Task]](in: In, f: In#Map[Result] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] { - type Inputs = In - val inputs = in - def unitDependencies = Nil - def work(results: Results, units: UnitResults[Task]) = f(results) - } - - def pure[T](name: String)(f: => T): Pure[T] = new Pure(f _) { override def toString = name } - def mapped[T, In0 <: MList[Task]](name: String)(in0: In0)(f0: In0#Map[Result] => T): Mapped[T, In0] = new Mapped(in0, f0) { override def toString = name } - def flat[T, In0 <: MList[Task]](name: String)(in0: In0)(f0: In0#Map[Result] => Task[T]): FlatMapped[T, In0] = new FlatMapped(in0, f0) { override def toString = name } - def mapAll[T, In0 <: MList[Task]](name: String)(in0: In0)(f0: In0#Map[Result]#Raw => T): MapAll[T, In0] = new MapAll(in0, f0) { override def toString = name } - def flatAll[T, In0 <: MList[Task]](name: String)(in0: In0)(f0: In0#Map[Result]#Raw => Task[T]): FlatMapAll[T, In0] = new FlatMapAll(in0, f0) { override def toString = name } - - def all[In <: MList[Result]]: In => In#Raw = in => - { - val incs = in.toList.collect { case Inc(i) => i } - if(incs.isEmpty) in.down(Result.tryValue) else throw Incomplete(causes = incs) - } -} object Test { - val a = pure("a")(3) - val b = pure[Boolean]("b")(error("test")) - val b2 = pure("b2")(true) - val c = pure("x")("asdf") + val a = pure(3) + val b = pure[Boolean](error("test")) + val b2 = pure(true) + val c = pure("asdf") val i3 = a :^: b :^: c :^: MNil val i32 = a :^: b2 :^: c :^: MNil val fh= (_: Int :+: Boolean :+: String :+: HNil) match { case aa :+: bb :+: cc :+: HNil => aa + " " + bb + " " + cc } - val h1 = mapAll("h1")(i3)(fh) - val h2 = mapAll("h2")(i32)(fh) + val h1 = i3 mapH fh + val h2 = i32 mapH fh val f: i3.Map[Result] => Any = { case Value(aa) :^: Value(bb) :^: Value(cc) :^: MNil => aa + " " + bb + " " + cc @@ -65,41 +27,24 @@ object Test val cs = x.toList.collect { case Inc(x) => x } // workaround for double definition bug throw Incomplete(causes = cs) } - val d2 = mapped("d2")(i32)(f) + val d2 = i32 mapR f val f2: i3.Map[Result] => Task[Any] = { case Value(aa) :^: Value(bb) :^: Value(cc) :^: MNil => new Pure(() => aa + " " + bb + " " + cc) case x => d3 } - lazy val d = flat("d")(i3)(f2) + lazy val d = i3 flatMapR f2 val f3: i3.Map[Result] => Task[Any] = { case Value(aa) :^: Value(bb) :^: Value(cc) :^: MNil => new Pure(() => aa + " " + bb + " " + cc) case x => d2 } - lazy val d3= flat("d3")(i3)(f3) + lazy val d3= i3 flatMapR f3 - def d4(i: Int): Task[Int] = flat("d4")(MNil){ _ => val x = math.random; if(x < 0.01) pure(x.toString)(i); else d4(i+1) } - - lazy val pureEval = - new (Pure ~> Result) { - def apply[T](p: Pure[T]): Result[T] = - try { Value(p.eval()) } - catch { case e: Exception => throw Incomplete(Incomplete.Error, directCause = Some(e)) } - } - - lazy val resultA = d.f( d.in.map(pureEval) ) - - def execute[T](root: Task[T]) = { - val (service, shutdown) = CompletionService[Task[_], Completed](2) - implicit val wrapped = CompletionService.manage(service)(x => println("Starting: " + x), x => println("Finished: " + x) ) - - val x = new Execute[Task](true)(taskToNode) - try { x.run(root) } finally { shutdown(); println(x.dump) } - } + def d4(i: Int): Task[Int] = MNil flatMap { _ => val x = math.random; if(x < 0.01) pure(i); else d4(i+1) } def go() { def run[T](root: Task[T]) = - println("Result : " + execute(root)) + println("Result : " + Task.run(root, true, 2)) run(a) run(b) diff --git a/tasks/src/test/scala/TestRunnerCall.scala b/tasks/src/test/scala/TestRunnerCall.scala index 2b8549937..6b1ea6fcc 100644 --- a/tasks/src/test/scala/TestRunnerCall.scala +++ b/tasks/src/test/scala/TestRunnerCall.scala @@ -1,8 +1,9 @@ -import xsbt._ +import sbt._ import org.scalacheck._ import Prop._ import TaskGen._ +import Task._ object TaskRunnerCallTest extends Properties("TaskRunner Call") { @@ -11,7 +12,7 @@ object TaskRunnerCallTest extends Properties("TaskRunner Call") val f = fibDirect(i) ("Workers: " + workers) |: ("i: " + i) |: ("fib(i): " + f) |: { - def result = TaskRunner( fibTask(i), workers) + def result = tryRun( fibTask(i), false, workers) checkResult(result, f) } } @@ -23,11 +24,11 @@ object TaskRunnerCallTest extends Properties("TaskRunner Call") (index, x1, x2) => { if(index == i) - Task(x2) + pure(x2) else iterate( (index+1, x2, x1+x2) ) } - def iterate(iteration: (Int,Int,Int)) = Task( iteration ) bind Function.tupled(next) + def iterate(iteration: (Int,Int,Int)) = pure( iteration ) flatMap next.tupled iterate( (1, 0, 1) ) } final def fibDirect(i: Int): Int = diff --git a/tasks/src/test/scala/TestRunnerSort.scala b/tasks/src/test/scala/TestRunnerSort.scala index b7d0daf8c..a96b79c8a 100644 --- a/tasks/src/test/scala/TestRunnerSort.scala +++ b/tasks/src/test/scala/TestRunnerSort.scala @@ -1,8 +1,13 @@ -import xsbt._ +/* sbt -- Simple Build Tool + * Copyright 2009, 2010 Mark Harrah + */ +package sbt import org.scalacheck._ import Prop._ import TaskGen._ +import Task._ +import Types._ object TaskRunnerSortTest extends Properties("TaskRunnerSort") { @@ -12,31 +17,33 @@ object TaskRunnerSortTest extends Properties("TaskRunnerSort") java.util.Arrays.sort(sorted) ("Workers: " + workers) |: ("Array: " + a.toList) |: { - def result = TaskRunner( sort(a.toArray), if(workers > 0) workers else 1) + def result = tryRun( sort(a.toSeq), false, if(workers > 0) workers else 1) checkResult(result.toList, sorted.toList) } } - final def sortDirect(a: RandomAccessSeq[Int]): RandomAccessSeq[Int] = + final def sortDirect(a: Seq[Int]): Seq[Int] = { if(a.length < 2) a else { val pivot = a(0) - val (lt,gte) = a.projection.drop(1).partition(_ < pivot) + val (lt,gte) = a.view.drop(1).partition(_ < pivot) sortDirect(lt) ++ List(pivot) ++ sortDirect(gte) } } - final def sort(a: RandomAccessSeq[Int]): Task[RandomAccessSeq[Int]] = + final def sort(a: Seq[Int]): Task[Seq[Int]] = { if(a.length < 200) - Task(sortDirect(a)) + pure(sortDirect(a)) else { - Task(a) bind { a => + pure(a) flatMap { a => val pivot = a(0) - val (lt,gte) = a.projection.drop(1).partition(_ < pivot) - (sort(lt), sort(gte)) map { _ ++ List(pivot) ++ _ } + val (lt,gte) = a.view.drop(1).partition(_ < pivot) + sort(lt) :^: sort(gte) :^: MNil mapH { + case l :+: g :+: HNil => l ++ List(pivot) ++ g + } } } } diff --git a/tasks/src/test/scala/checkResult.scala b/tasks/src/test/scala/checkResult.scala index a4f03b799..8459b143c 100644 --- a/tasks/src/test/scala/checkResult.scala +++ b/tasks/src/test/scala/checkResult.scala @@ -1,4 +1,7 @@ -package xsbt +/* sbt -- Simple Build Tool + * Copyright 2009 Mark Harrah + */ +package sbt import org.scalacheck.Prop._ @@ -14,8 +17,8 @@ object checkResult } catch { - case TasksFailed(failures) => - failures.foreach(f => f.exception.printStackTrace) + case i: Incomplete => + println(Incomplete.show(i, true)) "One or more tasks failed" |: false case e => e.printStackTrace