"When a program is in a state S and an event E occurs then do an action A and change to another state S1"
If the above sounds too theoritical to understand ....
hope you could understand !!!
sealed trait FSMSignal
case class SignalColorData
class SignalChangeFSMActor extends Actor
with FSM[FSMSignal, SignalColorData] {
.....
}
// state -
sealed trait FSMSignal
case object RedSignal extends FSMSignal
case object YellowSignal extends FSMSignal
case object GreenSignal extends FSMSignal
// data
case class SignalColorData
// event
case object ChangeSignal
case object RetainSignal
class SignalChangeFSMActor extends Actor with FSM[FSMSignal, SignalColorData] {
// initial state of FSM
startWith(RedSignal, SignalColorData())
when(RedSignal) {
case Event(ChangeSignal, _) => goto(YellowSignal)
case Event(RetainSignal, _) => stay
}
when(YellowSignal) {
case Event(ChangeSignal, _) => goto(GreenSignal)
case Event(RetainSignal, _) => stay
}
when(GreenSignal) {
case Event(ChangeSignal, _) => goto(RedSignal)
case Event(RetainSignal, _) => stay
}
onTransition {
case RedSignal -> YellowSignal =>
println("Changing from red to yellow signal - get ready to go")
case YellowSignal -> GreenSignal =>
println("Changing from yellow to green signal - wroooom")
case GreenSignal -> RedSignal =>
println("Changing from green to red signal - stop !!! :(")
}
initialize
}
class FSMActorTest(as: ActorSystem) extends TestKit(as)
with ImplicitSender
with WordSpecLike
with Matchers
with BeforeAndAfterAll {
// all our test cases
}
val fsmRef = TestFSMRef(new SignalChangeFSMActor)
"Our signal emulating FSMActor" must {
"be red at initial stage " in {
assert(fsmRef.stateName == RedSignal)
assert(fsmRef.stateData == SignalColorData())
}
"change to yellow after AlternateColour event occured " in {
fsmRef ! ChangeSignal // send an event to FSM
assert(fsmRef.stateName == YellowSignal)
assert(fsmRef.stateData == SignalColorData())
}
"change to green after AlternateColour event occured" in {
fsmRef ! ChangeSignal
assert(fsmRef.stateName == GreenSignal)
assert(fsmRef.stateData == SignalColorData())
}
"retain should not change the fsm state" in {
fsmRef ! RetainSignal
assert(fsmRef.stateName == GreenSignal)
assert(fsmRef.stateData == SignalColorData())
}
}