Specs2 with Akka and jodatime support
package mojolly
package testing
import org.scala_tools.time.Imports._
import akka.util.Duration.timeFactor
/**
* Multiplying numbers used in test timeouts by a factor, set by system property.
* Useful for Jenkins builds (where the machine may need more time).
*/
trait TimeHelpers {
def testTime(t: Int): Int = (timeFactor * t).toInt
def testTime(t: Long): Long = (timeFactor * t).toLong
def testTime(t: Float): Float = (timeFactor * t).toFloat
def testTime(t: Double): Double = timeFactor * t
object sleep {
def ->(duration:Duration) = Thread.sleep(testTime(duration.millis))
}
}
package org.scala_tools.time
import akka.util.{FiniteDuration, Duration => AkkaDuration }
import java.util.concurrent.TimeUnit
trait AkkaImplicits {
implicit def forceAkkaDuration(builder: DurationBuilder): AkkaDuration = {
builder.underlying.getMillis match {
case Int.MaxValue => AkkaDuration.Inf
case Int.MinValue => AkkaDuration.MinusInf
case 0 => new FiniteDuration(0, TimeUnit.NANOSECONDS)
case v => AkkaDuration(v, TimeUnit.MILLISECONDS)
}
}
}
import akka.testkit._
import akka.actor._
import Actor.actorOf
class MyActor extends Actor {
protected def receive = {
case m => self.sender foreach { _ ! (m + " reply") }
}
}
class MyActorSpec extends AkkaSpecification {
def is =
"My actor should" ^
"reply to a message" ! context.repliesToMessage ^ end
def context = new ActorContext
class ActorContext extends TestKit {
def repliesToMessage = {
val sut = actorOf[MyActor].start()
sut ! "hello"
receiveOne(2.seconds) must_== "hello reply"
}
}
}
trait ActorSpecification extends BaseSpecification
with ArgumentsArgs
with ArgumentsShortcuts
with MustThrownMatchers
with ShouldThrownMatchers
with FormattingFragments
with StandardResults
with StandardMatchResults
with PendingUntilFixed
with TimeHelpers
with Contexts {
/** transform a context to a result to allow the implicit passing of a context to each example */
implicit def contextToResult[T](t: MatchResult[T])(implicit context: Context = defaultContext): Result = context(asResult(t))
/** use an available outside context to transform a function returning a MatchResult into a result */
implicit def outsideFunctionToResult[T, S](implicit o: Outside[T]) = (f: T => MatchResult[S]) => { o((t1:T) => f(t1).toResult) }
override def map(fs: => Fragments) = super.map(fs) ^ Step(Actor.registry.shutdownAll()) ^ Step(Scheduler.restart())
}