diff --git a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/InterceptSpec.scala b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/InterceptSpec.scala index b1e2037e0e..731bd2fe90 100644 --- a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/InterceptSpec.scala +++ b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/InterceptSpec.scala @@ -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) + } + } diff --git a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/WidenSpec.scala b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/WidenSpec.scala index 383ebaba8d..a108497478 100644 --- a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/WidenSpec.scala +++ b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/WidenSpec.scala @@ -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)