package org.squirrelframework.foundation.fsm.threadsafe;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.squirrelframework.foundation.fsm.StateMachineBuilderFactory;
import org.squirrelframework.foundation.fsm.StateMachineContext;
import org.squirrelframework.foundation.fsm.UntypedStateMachineBuilder;
import org.squirrelframework.foundation.fsm.annotation.AsyncExecute;
import org.squirrelframework.foundation.fsm.annotation.ListenerOrder;
import org.squirrelframework.foundation.fsm.annotation.OnTransitionBegin;
import org.squirrelframework.foundation.fsm.annotation.StateMachineParameters;
import org.squirrelframework.foundation.fsm.impl.AbstractUntypedStateMachine;
public class StateMachineContextTest {
enum FSMEvent {
ToA, ToB, ToC, ToD
}
@StateMachineParameters(stateType = String.class, eventType = FSMEvent.class, contextType = Integer.class)
static class StateMachineSample extends AbstractUntypedStateMachine {
StateMachineSample currentInstance;
@AsyncExecute
public void onAToB(String from, String to, FSMEvent event, Integer context) {
currentInstance = StateMachineContext.currentInstance();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
static class TestListener {
@ListenerOrder(1)
@OnTransitionBegin(when="from.equals(\"D\")&&context>10")
public void onTransitionBeginWithD(StateMachineSample fsm) {
System.out.println("Continue fire ToB event on thread "+Thread.currentThread().getName());
fsm.fire(FSMEvent.ToB, 10);
}
@ListenerOrder(10)
@OnTransitionBegin(when="from.equals(\"D\")&&context>15")
public void onTransitionBeginWithB(StateMachineSample fsm) {
System.out.println("Continue fire ToC event on thread "+Thread.currentThread().getName());
fsm.fire(FSMEvent.ToC, 10);
}
}
@Test
public void testMultipleEvents() {
System.out.println("Test run on thread "+Thread.currentThread().getName());
UntypedStateMachineBuilder builder = StateMachineBuilderFactory.create(StateMachineSample.class);
builder.externalTransition().from("D").to("A").on(FSMEvent.ToA);
builder.externalTransition().from("A").to("B").on(FSMEvent.ToB);
builder.externalTransition().from("B").to("C").on(FSMEvent.ToC);
builder.externalTransition().from("C").to("D").on(FSMEvent.ToD);
final StateMachineSample fsm = builder.newUntypedStateMachine("D");
fsm.addDeclarativeListener(new TestListener());
String expected1 = (String) fsm.test(FSMEvent.ToA, 5);
System.out.println("expected1: "+expected1);
assertThat(expected1, equalTo("A"));
String expected2 = (String) fsm.test(FSMEvent.ToA, 11);
System.out.println("expected2: "+expected2);
assertThat(expected2, equalTo("B"));
String expected3 = (String) fsm.test(FSMEvent.ToA, 21);
System.out.println("expected3: "+expected3);
assertThat(expected3, equalTo("C"));
}
@Test
public void testThreadLocal() {
UntypedStateMachineBuilder builder = StateMachineBuilderFactory.create(StateMachineSample.class);
builder.externalTransition().from("A").to("B").on(FSMEvent.ToB).callMethod("onAToB");
final StateMachineSample fsm = builder.newUntypedStateMachine("A");
assertTrue(StateMachineContext.currentInstance()==null);
fsm.fire(FSMEvent.ToB, 10);
assertTrue(fsm==fsm.currentInstance);
assertTrue(StateMachineContext.currentInstance()==null);
}
}