Some more BehaviorIntercept tests

* filter messages
* show how it can be used to implement PoisonPill
This commit is contained in:
Patrik Nordwall 2018-09-17 16:29:02 +02:00
parent e62240b4b3
commit af2d15a188
2 changed files with 65 additions and 11 deletions

View file

@ -7,20 +7,25 @@ package akka.actor.typed
import java.util.concurrent.atomic.AtomicBoolean
import akka.testkit.EventFilter
import akka.actor.testkit.typed.scaladsl.{ ActorTestKit, TestProbe }
import akka.actor.testkit.typed.scaladsl.TestProbe
import akka.actor.typed.scaladsl.Behaviors
import org.scalatest.WordSpecLike
import scala.concurrent.duration._
import akka.actor.ActorInitializationException
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
import com.typesafe.config.ConfigFactory
object InterceptSpec {
final case class Msg(hello: String, replyTo: ActorRef[String])
case object MyPoisonPill
}
class InterceptSpec extends ScalaTestWithActorTestKit(
"""
akka.loggers = [akka.testkit.TestEventListener]
""") with WordSpecLike {
import BehaviorInterceptor._
import InterceptSpec._
// FIXME eventfilter support in typed testkit
import scaladsl.adapter._
@ -268,4 +273,40 @@ class InterceptSpec extends ScalaTestWithActorTestKit(
}
"be useful for implementing PoisonPill" in {
def inner(count: Int): Behavior[Msg] = Behaviors.receiveMessage {
case Msg(hello, replyTo)
replyTo ! s"$hello-$count"
inner(count + 1)
}
val poisonInterceptor = new BehaviorInterceptor[Any, Msg] {
override def aroundReceive(ctx: ActorContext[Any], msg: Any, target: ReceiveTarget[Msg]): Behavior[Msg] =
msg match {
case MyPoisonPill Behaviors.stopped
case m: Msg target(ctx, m)
case _ Behaviors.unhandled
}
override def aroundSignal(ctx: ActorContext[Any], signal: Signal, target: SignalTarget[Msg]): Behavior[Msg] =
target.apply(ctx, signal)
}
val decorated: Behavior[Msg] =
Behaviors.intercept(poisonInterceptor)(inner(0)).narrow
val ref = spawn(decorated)
val probe = TestProbe[String]()
ref ! Msg("hello", probe.ref)
probe.expectMessage("hello-0")
ref ! Msg("hello", probe.ref)
probe.expectMessage("hello-1")
ref.upcast[Any] ! MyPoisonPill
probe.expectTerminated(ref, probe.remainingOrDefault)
}
}

View file

@ -13,23 +13,36 @@ import org.scalatest.WordSpecLike
class WidenSpec extends ScalaTestWithActorTestKit with WordSpecLike {
def intToString(probe: ActorRef[String]): Behavior[Int] = {
Behaviors.receiveMessage[String] { msg
probe ! msg
Behaviors.same
}.widen[Int] {
case n if n != 13 n.toString
}
}
"Widen" should {
"transform messages from an outer type to an inner type" in {
"transform from an outer type to an inner type" in {
val probe = TestProbe[String]()
val beh = Behaviors.receiveMessage[String] { msg
probe.ref ! msg
Behaviors.same
}.widen[Int] {
case n n.toString
}
val ref = spawn(beh)
val ref = spawn(intToString(probe.ref))
ref ! 42
probe.expectMessage("42")
}
"filter messages" in {
val probe = TestProbe[String]()
val ref = spawn(intToString(probe.ref))
ref ! 42
ref ! 13
ref ! 43
probe.expectMessage("42")
probe.expectMessage("43")
}
"not build up when the same widen is used many times (initially)" in {
val probe = TestProbe[String]()
val transformCount = new AtomicInteger(0)