diff --git a/akka-actor-tests/src/test/scala/akka/actor/FSMActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/FSMActorSpec.scala index ca6d90e721..3a2c1bb627 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/FSMActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/FSMActorSpec.scala @@ -7,7 +7,6 @@ package akka.actor import org.scalatest.{ BeforeAndAfterAll, BeforeAndAfterEach } import akka.testkit._ import TestEvent.Mute -import FSM._ import akka.util.duration._ import akka.event._ import com.typesafe.config.ConfigFactory @@ -52,7 +51,7 @@ object FSMActorSpec { } } case Event("hello", _) ⇒ stay replying "world" - case Event("bye", _) ⇒ stop(Shutdown) + case Event("bye", _) ⇒ stop(FSM.Shutdown) } when(Open) { @@ -63,7 +62,7 @@ object FSMActorSpec { } whenUnhandled { - case Ev(msg) ⇒ { + case Event(msg, _) ⇒ { log.warning("unhandled event " + msg + " in state " + stateName + " with data " + stateData) unhandledLatch.open stay @@ -82,7 +81,7 @@ object FSMActorSpec { } onTermination { - case StopEvent(Shutdown, Locked, _) ⇒ + case StopEvent(FSM.Shutdown, Locked, _) ⇒ // stop is called from lockstate with shutdown as reason... terminatedLatch.open } @@ -110,6 +109,8 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im "unlock the lock" in { + import FSM.{ Transition, CurrentState, SubscribeTransitionCallBack } + val latches = new Latches import latches._ @@ -163,7 +164,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im val fsm = TestActorRef(new Actor with FSM[Int, Null] { startWith(1, null) when(1) { - case Ev("go") ⇒ goto(2) + case Event("go", _) ⇒ goto(2) } }) val name = fsm.path.toString @@ -182,7 +183,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im lazy val fsm = new Actor with FSM[Int, Null] { override def preStart = { started.countDown } startWith(1, null) - when(1) { NullFunction } + when(1) { FSM.NullFunction } onTermination { case x ⇒ testActor ! x } @@ -190,7 +191,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im val ref = system.actorOf(Props(fsm)) Await.ready(started, timeout.duration) system.stop(ref) - expectMsg(1 second, fsm.StopEvent(Shutdown, 1, null)) + expectMsg(1 second, fsm.StopEvent(FSM.Shutdown, 1, null)) } "log events and transitions if asked to do so" in { @@ -204,12 +205,12 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im val fsm = TestActorRef(new Actor with LoggingFSM[Int, Null] { startWith(1, null) when(1) { - case Ev("go") ⇒ - setTimer("t", Shutdown, 1.5 seconds, false) + case Event("go", _) ⇒ + setTimer("t", FSM.Shutdown, 1.5 seconds, false) goto(2) } when(2) { - case Ev("stop") ⇒ + case Event("stop", _) ⇒ cancelTimer("t") stop } @@ -230,7 +231,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im expectMsgPF(1 second, hint = "processing Event(stop,null)") { case Logging.Debug(`name`, `fsmClass`, s: String) if s.startsWith("processing Event(stop,null) from Actor[") ⇒ true } - expectMsgAllOf(1 second, Logging.Debug(name, fsmClass, "canceling timer 't'"), Normal) + expectMsgAllOf(1 second, Logging.Debug(name, fsmClass, "canceling timer 't'"), FSM.Normal) expectNoMsg(1 second) system.eventStream.unsubscribe(testActor) } @@ -251,6 +252,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im }) fsmref ! "log" val fsm = fsmref.underlyingActor + import FSM.LogEntry expectMsg(1 second, IndexedSeq(LogEntry(1, 0, "log"))) fsmref ! "count" fsmref ! "log" diff --git a/akka-actor-tests/src/test/scala/akka/actor/FSMTimingSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/FSMTimingSpec.scala index bf5a1974ee..59468125eb 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/FSMTimingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/FSMTimingSpec.scala @@ -160,37 +160,37 @@ object FSMTimingSpec { startWith(Initial, 0) when(Initial) { - case Ev(TestSingleTimer) ⇒ + case Event(TestSingleTimer, _) ⇒ setTimer("tester", Tick, 500 millis, false) goto(TestSingleTimer) - case Ev(TestRepeatedTimer) ⇒ + case Event(TestRepeatedTimer, _) ⇒ setTimer("tester", Tick, 100 millis, true) goto(TestRepeatedTimer) using 4 - case Ev(TestStateTimeoutOverride) ⇒ + case Event(TestStateTimeoutOverride, _) ⇒ goto(TestStateTimeout) forMax (Duration.Inf) - case Ev(x: FSMTimingSpec.State) ⇒ goto(x) + case Event(x: FSMTimingSpec.State, _) ⇒ goto(x) } when(TestStateTimeout, stateTimeout = 500 millis) { - case Ev(StateTimeout) ⇒ goto(Initial) - case Ev(Cancel) ⇒ goto(Initial) replying (Cancel) + case Event(StateTimeout, _) ⇒ goto(Initial) + case Event(Cancel, _) ⇒ goto(Initial) replying (Cancel) } when(TestSingleTimer) { - case Ev(Tick) ⇒ + case Event(Tick, _) ⇒ tester ! Tick goto(Initial) } when(TestCancelTimer) { - case Ev(Tick) ⇒ + case Event(Tick, _) ⇒ setTimer("hallo", Tock, 1 milli, false) TestKit.awaitCond(context.asInstanceOf[ActorCell].mailbox.hasMessages, 1 second) cancelTimer("hallo") sender ! Tick setTimer("hallo", Tock, 500 millis, false) stay - case Ev(Tock) ⇒ + case Event(Tock, _) ⇒ tester ! Tock stay - case Ev(Cancel) ⇒ + case Event(Cancel, _) ⇒ cancelTimer("hallo") goto(Initial) } @@ -206,29 +206,29 @@ object FSMTimingSpec { } when(TestCancelStateTimerInNamedTimerMessage) { // FSM is suspended after processing this message and resumed 500ms later - case Ev(Tick) ⇒ + case Event(Tick, _) ⇒ suspend(self) setTimer("named", Tock, 1 millis, false) TestKit.awaitCond(context.asInstanceOf[ActorCell].mailbox.hasMessages, 1 second) stay forMax (1 millis) replying Tick - case Ev(Tock) ⇒ + case Event(Tock, _) ⇒ goto(TestCancelStateTimerInNamedTimerMessage2) } when(TestCancelStateTimerInNamedTimerMessage2) { - case Ev(StateTimeout) ⇒ + case Event(StateTimeout, _) ⇒ goto(Initial) - case Ev(Cancel) ⇒ + case Event(Cancel, _) ⇒ goto(Initial) replying Cancel } when(TestUnhandled) { - case Ev(SetHandler) ⇒ + case Event(SetHandler, _) ⇒ whenUnhandled { - case Ev(Tick) ⇒ + case Event(Tick, _) ⇒ tester ! Unhandled(Tick) stay } stay - case Ev(Cancel) ⇒ + case Event(Cancel, _) ⇒ whenUnhandled(NullFunction) goto(Initial) } diff --git a/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala index 8d8fc5e725..691be63a0b 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala @@ -5,7 +5,6 @@ package akka.actor import akka.testkit._ import akka.util.duration._ -import FSM._ import akka.util.Duration object FSMTransitionSpec { @@ -17,13 +16,13 @@ object FSMTransitionSpec { class MyFSM(target: ActorRef) extends Actor with FSM[Int, Unit] { startWith(0, Unit) when(0) { - case Ev("tick") ⇒ goto(1) + case Event("tick", _) ⇒ goto(1) } when(1) { - case Ev("tick") ⇒ goto(0) + case Event("tick", _) ⇒ goto(0) } whenUnhandled { - case Ev("reply") ⇒ stay replying "reply" + case Event("reply", _) ⇒ stay replying "reply" } initialize override def preRestart(reason: Throwable, msg: Option[Any]) { target ! "restarted" } @@ -32,10 +31,10 @@ object FSMTransitionSpec { class OtherFSM(target: ActorRef) extends Actor with FSM[Int, Int] { startWith(0, 0) when(0) { - case Ev("tick") ⇒ goto(1) using (1) + case Event("tick", _) ⇒ goto(1) using (1) } when(1) { - case Ev(_) ⇒ stay + case _ ⇒ stay } onTransition { case 0 -> 1 ⇒ target ! ((stateData, nextStateData)) @@ -56,6 +55,8 @@ class FSMTransitionSpec extends AkkaSpec with ImplicitSender { "A FSM transition notifier" must { "notify listeners" in { + import FSM.{ SubscribeTransitionCallBack, CurrentState, Transition } + val fsm = system.actorOf(Props(new MyFSM(testActor))) within(1 second) { fsm ! SubscribeTransitionCallBack(testActor) @@ -77,8 +78,8 @@ class FSMTransitionSpec extends AkkaSpec with ImplicitSender { })) within(300 millis) { - fsm ! SubscribeTransitionCallBack(forward) - expectMsg(CurrentState(fsm, 0)) + fsm ! FSM.SubscribeTransitionCallBack(forward) + expectMsg(FSM.CurrentState(fsm, 0)) system.stop(forward) fsm ! "tick" expectNoMsg diff --git a/akka-actor/src/main/scala/akka/actor/FSM.scala b/akka-actor/src/main/scala/akka/actor/FSM.scala index 5660811c00..b277142e76 100644 --- a/akka-actor/src/main/scala/akka/actor/FSM.scala +++ b/akka-actor/src/main/scala/akka/actor/FSM.scala @@ -48,6 +48,14 @@ object FSM { } } + /** + * This extractor is just convenience for matching a (S, S) pair, including a + * reminder what the new state is. + */ + object -> { + def unapply[S](in: (S, S)) = Some(in) + } + case class LogEntry[S, D](stateName: S, stateData: D, event: Any) case class State[S, D](stateName: S, stateData: D, timeout: Option[Duration] = None, stopReason: Option[Reason] = None, replies: List[Any] = Nil) { @@ -174,6 +182,10 @@ trait FSM[S, D] extends Listeners { type Timeout = Option[Duration] type TransitionHandler = PartialFunction[(S, S), Unit] + // “import” so that it is visible without an import + val -> = FSM.-> + val StateTimeout = FSM.StateTimeout + val log = Logging(context.system, this) /** @@ -284,14 +296,6 @@ trait FSM[S, D] extends Listeners { */ protected final def setStateTimeout(state: S, timeout: Timeout): Unit = stateTimeouts(state) = timeout - /** - * This extractor is just convenience for matching a (S, S) pair, including a - * reminder what the new state is. - */ - object -> { - def unapply[S](in: (S, S)) = Some(in) - } - /** * Set handler which is called upon each state transition, i.e. not when * staying in the same state. This may use the pair extractor defined in the @@ -533,9 +537,6 @@ trait FSM[S, D] extends Listeners { } case class Event(event: Any, stateData: D) - object Ev { - def unapply[D](e: Event): Option[Any] = Some(e.event) - } case class StopEvent[S, D](reason: Reason, currentState: S, stateData: D) } diff --git a/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala b/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala index 3a4608e840..2b2cb003a9 100644 --- a/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala @@ -89,10 +89,10 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { val fsm = TestFSMRef(new Actor with FSM[Int, String] { startWith(1, "") when(1) { - case Ev("go") ⇒ goto(2) using "go" + case Event("go", _) ⇒ goto(2) using "go" } when(2) { - case Ev("back") ⇒ goto(1) using "back" + case Event("back", _) ⇒ goto(1) using "back" } }) diff --git a/akka-testkit/src/test/scala/akka/testkit/TestFSMRefSpec.scala b/akka-testkit/src/test/scala/akka/testkit/TestFSMRefSpec.scala index d2ec767504..86c6a8c7c5 100644 --- a/akka-testkit/src/test/scala/akka/testkit/TestFSMRefSpec.scala +++ b/akka-testkit/src/test/scala/akka/testkit/TestFSMRefSpec.scala @@ -12,19 +12,17 @@ import akka.util.duration._ @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class TestFSMRefSpec extends AkkaSpec { - import FSM._ - "A TestFSMRef" must { "allow access to state data" in { val fsm = TestFSMRef(new Actor with FSM[Int, String] { startWith(1, "") when(1) { - case Ev("go") ⇒ goto(2) using "go" - case Ev(StateTimeout) ⇒ goto(2) using "timeout" + case Event("go", _) ⇒ goto(2) using "go" + case Event(StateTimeout, _) ⇒ goto(2) using "timeout" } when(2) { - case Ev("back") ⇒ goto(1) using "back" + case Event("back", _) ⇒ goto(1) using "back" } }, "test-fsm-ref-1") fsm.stateName must be(1)