/* sbt -- Simple Build Tool * Copyright 2009 Mark Harrah */ package xsbt.test final class TestException(statement: Statement, msg: String, exception: Throwable) extends RuntimeException(statement.linePrefix + " " + msg, exception) class ScriptRunner { import scala.collection.mutable.HashMap def apply(statements: List[(StatementHandler, Statement)]) { val states = new HashMap[StatementHandler, Any] def processStatement(handler: StatementHandler, statement: Statement) { val state = states(handler).asInstanceOf[handler.State] val nextState = try { Right( handler(statement.command, statement.arguments, state) ) } catch { case e: Exception => Left(e) } nextState match { case Left(err) => if(statement.successExpected) { err match { case t: TestFailed => throw new TestException(statement, "Command failed: " + t.getMessage, null) case _ => throw new TestException(statement, "Command failed", err) } } else () case Right(s) => if(statement.successExpected) states(handler) = s else throw new TestException(statement, "Command succeeded but failure was expected", null) } } val handlers = Set() ++ statements.map(_._1) try { handlers.foreach { handler => states(handler) = handler.initialState } statements foreach( Function.tupled(processStatement) ) } finally { for(handler <- handlers; state <- states.get(handler)) { try { handler.finish(state.asInstanceOf[handler.State]) } catch { case e: Exception => () } } } } }