Can now skip initial state
- Fixes #71 - If substate is entered directry, we don't go via initial state for particular state machine where transition ends. - Fixing other tests which assumed initial state is entered. - In terms of a history state, initial state is still entered.
This commit is contained in:
@@ -57,4 +57,12 @@ public interface StateMachineAccess<S, E> {
|
||||
*/
|
||||
void addStateChangeInterceptor(StateChangeInterceptor<S, E> interceptor);
|
||||
|
||||
/**
|
||||
* Sets if initial state is enabled when a state machine is
|
||||
* using sub states.
|
||||
*
|
||||
* @param enabled the new initial enabled
|
||||
*/
|
||||
void setInitialEnabled(boolean enabled);
|
||||
|
||||
}
|
||||
|
||||
@@ -46,4 +46,18 @@ public interface StateMachineAccessor<S, E> {
|
||||
*/
|
||||
List<StateMachineAccess<S, E>> withAllRegions();
|
||||
|
||||
/**
|
||||
* Execute given {@link StateMachineFunction} with a region.
|
||||
*
|
||||
* @param stateMachineAccess the state machine access
|
||||
*/
|
||||
void doWithRegion(StateMachineFunction<StateMachineAccess<S, E>> stateMachineAccess);
|
||||
|
||||
/**
|
||||
* Get a region.
|
||||
*
|
||||
* @return the state machine access
|
||||
*/
|
||||
StateMachineAccess<S, E> withRegion();
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import java.util.Collection;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.access.StateMachineAccess;
|
||||
import org.springframework.statemachine.access.StateMachineFunction;
|
||||
import org.springframework.statemachine.action.Action;
|
||||
import org.springframework.statemachine.support.StateMachineUtils;
|
||||
import org.springframework.statemachine.transition.Transition;
|
||||
@@ -161,10 +163,56 @@ public class StateMachineState<S, E> extends AbstractState<S, E> {
|
||||
}
|
||||
|
||||
if (getPseudoState() != null && getPseudoState().getKind() == PseudoStateKind.INITIAL) {
|
||||
// disable initial state if it looks like we're about
|
||||
// to transit directory into a non initial state
|
||||
// we do transit via initial state if we're returning
|
||||
// via history state
|
||||
boolean initialEnabled = true;
|
||||
if (context.getTransition() != null) {
|
||||
State<S, E> target = context.getTransition().getTarget();
|
||||
PseudoStateKind kind = target.getPseudoState() != null ? target.getPseudoState().getKind() : null;
|
||||
State<S, E> findDeepParent = findDeepParent(getSubmachine().getStates(), target);
|
||||
if (findDeepParent != null && findDeepParent.isSubmachineState()) {
|
||||
((StateMachineState<S, E>) findDeepParent).getSubmachine().getStateMachineAccessor()
|
||||
.doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
|
||||
|
||||
@Override
|
||||
public void apply(StateMachineAccess<S, E> function) {
|
||||
function.setInitialEnabled(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (getSubmachine().getStates().contains(target) && kind != PseudoStateKind.HISTORY_SHALLOW
|
||||
&& kind != PseudoStateKind.HISTORY_DEEP) {
|
||||
initialEnabled = false;
|
||||
}
|
||||
|
||||
}
|
||||
// need final for state machine access
|
||||
final boolean enabled = initialEnabled;
|
||||
getSubmachine().getStateMachineAccessor().doWithRegion(
|
||||
new StateMachineFunction<StateMachineAccess<S, E>>() {
|
||||
|
||||
@Override
|
||||
public void apply(StateMachineAccess<S, E> function) {
|
||||
function.setInitialEnabled(enabled);
|
||||
}
|
||||
});
|
||||
getSubmachine().start();
|
||||
}
|
||||
}
|
||||
|
||||
private State<S, E> findDeepParent(Collection<State<S, E>> states, State<S, E> state) {
|
||||
for (State<S, E> s : states) {
|
||||
if (s.getStates().contains(state)) {
|
||||
if (s != state) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendEvent(Message<E> event) {
|
||||
StateMachine<S, E> machine = getSubmachine();
|
||||
|
||||
@@ -104,6 +104,8 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
|
||||
private StateMachineExecutor<S, E> stateMachineExecutor;
|
||||
|
||||
private Boolean initialEnabled = null;
|
||||
|
||||
/**
|
||||
* Instantiates a new abstract state machine.
|
||||
*
|
||||
@@ -243,7 +245,7 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
notifyTransitionStart(t);
|
||||
callHandlers(t.getSource(), t.getTarget(), queuedMessage);
|
||||
if (t.getKind() == TransitionKind.INITIAL) {
|
||||
switchToState(t.getTarget(), queuedMessage, null, getRelayStateMachine());
|
||||
switchToState(t.getTarget(), queuedMessage, t, getRelayStateMachine());
|
||||
notifyStateMachineStarted(getRelayStateMachine());
|
||||
} else if (t.getKind() != TransitionKind.INTERNAL) {
|
||||
switchToState(t.getTarget(), queuedMessage, t, getRelayStateMachine());
|
||||
@@ -265,6 +267,10 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
}
|
||||
registerPseudoStateListener();
|
||||
|
||||
if (initialEnabled != null && !initialEnabled) {
|
||||
stateMachineExecutor.setInitialEnabled(false);
|
||||
}
|
||||
|
||||
// start fires first execution which should execute initial transition
|
||||
stateMachineExecutor.start();
|
||||
}
|
||||
@@ -274,6 +280,7 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
stateMachineExecutor.stop();
|
||||
notifyStateMachineStopped(this);
|
||||
currentState = null;
|
||||
initialEnabled = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -312,6 +319,14 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
return transitions;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setInitialEnabled(boolean enabled) {
|
||||
if (initialEnabled == null) {
|
||||
initialEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public StateMachineAccessor<S, E> getStateMachineAccessor() {
|
||||
@@ -353,6 +368,16 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doWithRegion(StateMachineFunction<StateMachineAccess<S, E>> stateMachineAccess) {
|
||||
stateMachineAccess.apply(AbstractStateMachine.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineAccess<S, E> withRegion() {
|
||||
return AbstractStateMachine.this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -538,7 +563,6 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
}
|
||||
entryToState(state, message, transition, stateMachine);
|
||||
notifyStateChanged(notifyFrom, state);
|
||||
StateContext<S, E> stateContext = buildStateContext(message, transition, stateMachine);
|
||||
} else if (currentState != null) {
|
||||
if (findDeep != null) {
|
||||
if (exit) {
|
||||
@@ -575,8 +599,11 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean shouldEntry = findDeep != currentState;
|
||||
currentState = findDeep;
|
||||
entryToState(currentState, message, transition, stateMachine);
|
||||
if (shouldEntry) {
|
||||
entryToState(currentState, message, transition, stateMachine);
|
||||
}
|
||||
|
||||
if (currentState.isSubmachineState()) {
|
||||
StateMachine<S, E> submachine = ((AbstractState<S, E>)currentState).getSubmachine();
|
||||
|
||||
@@ -37,6 +37,9 @@ public abstract class StateMachineUtils {
|
||||
* @return if sub is child of super
|
||||
*/
|
||||
public static <S, E> boolean isSubstate(State<S, E> left, State<S, E> right) {
|
||||
if (left == null) {
|
||||
return false;
|
||||
}
|
||||
Collection<State<S, E>> c = left.getStates();
|
||||
c.remove(left);
|
||||
return c.contains(right);
|
||||
|
||||
@@ -78,7 +78,8 @@ public abstract class AbstractStateMachineTests {
|
||||
|
||||
public static enum TestStates2 {
|
||||
BUSY, PLAYING, PAUSED,
|
||||
IDLE, CLOSED, OPEN
|
||||
IDLE, CLOSED, OPEN,
|
||||
PAUSED1, PAUSED2
|
||||
}
|
||||
|
||||
public static enum TestStates3 {
|
||||
|
||||
@@ -146,11 +146,11 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
assertThat(entryActionS1.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));
|
||||
assertThat(exitActionS1.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));
|
||||
|
||||
assertThat(entryActionS11.stateContexts.size(), is(2));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS11.stateContexts.size(), is(1));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(2));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS11.stateContexts.size(), is(1));
|
||||
assertThat(entryActionS1.stateContexts.size(), is(2));
|
||||
assertThat(entryActionS1.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS1.stateContexts.size(), is(1));
|
||||
}
|
||||
|
||||
@@ -336,9 +336,9 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
assertThat(entryActionS1.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));
|
||||
assertThat(exitActionS1.onExecuteLatch.await(1, TimeUnit.SECONDS), is(false));
|
||||
|
||||
assertThat(entryActionS11.stateContexts.size(), is(2));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS11.stateContexts.size(), is(1));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(2));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS11.stateContexts.size(), is(1));
|
||||
assertThat(entryActionS1.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS1.stateContexts.size(), is(0));
|
||||
@@ -371,11 +371,11 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
assertThat(entryActionS1.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));
|
||||
assertThat(exitActionS1.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));
|
||||
|
||||
assertThat(entryActionS11.stateContexts.size(), is(2));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS11.stateContexts.size(), is(1));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(2));
|
||||
assertThat(entryActionS11.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS11.stateContexts.size(), is(1));
|
||||
assertThat(entryActionS1.stateContexts.size(), is(2));
|
||||
assertThat(entryActionS1.stateContexts.size(), is(1));
|
||||
assertThat(exitActionS1.stateContexts.size(), is(1));
|
||||
|
||||
}
|
||||
|
||||
@@ -78,6 +78,15 @@ public class StateMachineAccessTests {
|
||||
list.add(MockStateMachine.this);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doWithRegion(StateMachineFunction<StateMachineAccess<String, String>> stateMachineAccess) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineAccess<String, String> withRegion() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -154,6 +163,10 @@ public class StateMachineAccessTests {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInitialEnabled(boolean enabled) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@ public class HistoryStateTests extends AbstractStateMachineTests {
|
||||
machine.sendEvent(TestEvents.E2);
|
||||
machine.sendEvent(TestEvents.E3);
|
||||
machine.sendEvent(TestEvents.E4);
|
||||
|
||||
assertThat(machine.getState().getIds(), contains(TestStates.S2, TestStates.S21, TestStates.S212));
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,54 @@ public class TransitionTests extends AbstractStateMachineTests {
|
||||
assertThat(machine.getState().getIds(), contains(TestStates.S2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransitDirectlyToSubstateSkipInitial() throws InterruptedException {
|
||||
context.register(BaseConfig.class, Config7.class);
|
||||
context.refresh();
|
||||
assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
|
||||
@SuppressWarnings("unchecked")
|
||||
ObjectStateMachine<TestStates2,TestEvents2> machine =
|
||||
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
|
||||
TestListener2 listener = new TestListener2();
|
||||
machine.addStateListener(listener);
|
||||
listener.reset(2);
|
||||
|
||||
machine.start();
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(2));
|
||||
assertThat(machine.getState().getIds(), contains(TestStates2.IDLE, TestStates2.CLOSED));
|
||||
|
||||
listener.reset(0, 2);
|
||||
machine.sendEvent(TestEvents2.PAUSE);
|
||||
assertThat(listener.stateEnteredLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateEnteredCount, is(2));
|
||||
assertThat(machine.getState().getIds(), contains(TestStates2.BUSY, TestStates2.PAUSED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransitDeepDirectlyToSubstateSkipInitial() throws InterruptedException {
|
||||
context.register(BaseConfig.class, Config8.class);
|
||||
context.refresh();
|
||||
assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
|
||||
@SuppressWarnings("unchecked")
|
||||
ObjectStateMachine<TestStates2,TestEvents2> machine =
|
||||
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
|
||||
TestListener2 listener = new TestListener2();
|
||||
machine.addStateListener(listener);
|
||||
listener.reset(2);
|
||||
|
||||
machine.start();
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(2));
|
||||
assertThat(machine.getState().getIds(), contains(TestStates2.IDLE, TestStates2.CLOSED));
|
||||
|
||||
listener.reset(0, 4);
|
||||
machine.sendEvent(TestEvents2.PAUSE);
|
||||
assertThat(listener.stateEnteredLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateEnteredCount, is(4));
|
||||
assertThat(machine.getState().getIds(), contains(TestStates2.BUSY, TestStates2.PAUSED, TestStates2.PAUSED2));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class Config1 extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {
|
||||
@@ -408,6 +456,106 @@ public class TransitionTests extends AbstractStateMachineTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class Config7 extends EnumStateMachineConfigurerAdapter<TestStates2, TestEvents2> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<TestStates2, TestEvents2> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial(TestStates2.IDLE)
|
||||
.state(TestStates2.IDLE)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(TestStates2.IDLE)
|
||||
.initial(TestStates2.CLOSED)
|
||||
.state(TestStates2.CLOSED)
|
||||
.state(TestStates2.OPEN)
|
||||
.and()
|
||||
.withStates()
|
||||
.state(TestStates2.BUSY)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(TestStates2.BUSY)
|
||||
.initial(TestStates2.PLAYING)
|
||||
.state(TestStates2.PLAYING)
|
||||
.state(TestStates2.PAUSED);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<TestStates2, TestEvents2> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source(TestStates2.CLOSED)
|
||||
.target(TestStates2.OPEN)
|
||||
.event(TestEvents2.EJECT)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(TestStates2.OPEN)
|
||||
.target(TestStates2.CLOSED)
|
||||
.event(TestEvents2.EJECT)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(TestStates2.CLOSED)
|
||||
.target(TestStates2.PAUSED)
|
||||
.event(TestEvents2.PAUSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class Config8 extends EnumStateMachineConfigurerAdapter<TestStates2, TestEvents2> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<TestStates2, TestEvents2> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial(TestStates2.IDLE)
|
||||
.state(TestStates2.IDLE)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(TestStates2.IDLE)
|
||||
.initial(TestStates2.CLOSED)
|
||||
.state(TestStates2.OPEN)
|
||||
.and()
|
||||
.withStates()
|
||||
.state(TestStates2.BUSY)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(TestStates2.BUSY)
|
||||
.initial(TestStates2.PLAYING)
|
||||
.state(TestStates2.PAUSED)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(TestStates2.PAUSED)
|
||||
.initial(TestStates2.PAUSED1)
|
||||
.state(TestStates2.PAUSED2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<TestStates2, TestEvents2> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source(TestStates2.CLOSED)
|
||||
.target(TestStates2.OPEN)
|
||||
.event(TestEvents2.EJECT)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(TestStates2.OPEN)
|
||||
.target(TestStates2.CLOSED)
|
||||
.event(TestEvents2.EJECT)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(TestStates2.CLOSED)
|
||||
.target(TestStates2.PAUSED2)
|
||||
.event(TestEvents2.PAUSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestListener extends StateMachineListenerAdapter<TestStates, TestEvents> {
|
||||
|
||||
volatile CountDownLatch stateChangedLatch = new CountDownLatch(1);
|
||||
@@ -415,8 +563,8 @@ public class TransitionTests extends AbstractStateMachineTests {
|
||||
|
||||
@Override
|
||||
public void stateChanged(State<TestStates, TestEvents> from, State<TestStates, TestEvents> to) {
|
||||
stateChangedLatch.countDown();
|
||||
stateChangedCount++;
|
||||
stateChangedLatch.countDown();
|
||||
}
|
||||
|
||||
public void reset(int c1) {
|
||||
@@ -426,4 +574,36 @@ public class TransitionTests extends AbstractStateMachineTests {
|
||||
|
||||
}
|
||||
|
||||
static class TestListener2 extends StateMachineListenerAdapter<TestStates2, TestEvents2> {
|
||||
|
||||
volatile CountDownLatch stateChangedLatch = new CountDownLatch(1);
|
||||
volatile int stateChangedCount = 0;
|
||||
volatile CountDownLatch stateEnteredLatch = new CountDownLatch(1);
|
||||
volatile int stateEnteredCount = 0;
|
||||
|
||||
@Override
|
||||
public void stateChanged(State<TestStates2, TestEvents2> from, State<TestStates2, TestEvents2> to) {
|
||||
stateChangedCount++;
|
||||
stateChangedLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateEntered(State<TestStates2, TestEvents2> state) {
|
||||
stateEnteredCount++;
|
||||
stateEnteredLatch.countDown();
|
||||
}
|
||||
|
||||
public void reset(int c1) {
|
||||
reset(c1, 0);
|
||||
}
|
||||
|
||||
public void reset(int c1, int c2) {
|
||||
stateChangedLatch = new CountDownLatch(c1);
|
||||
stateChangedCount = 0;
|
||||
stateEnteredLatch = new CountDownLatch(c2);
|
||||
stateEnteredCount = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -170,12 +170,10 @@ public class ShowcaseTests {
|
||||
public void testII() throws Exception {
|
||||
machine.sendEvent(Events.I);
|
||||
|
||||
listener.reset(1, 0, 0);
|
||||
// TODO: should think if need to bypass
|
||||
// S211 as initial state and go directly
|
||||
// to S212.
|
||||
listener.reset(2, 0, 0);
|
||||
machine.sendEvent(Events.I);
|
||||
listener.stateChangedLatch.await(1, TimeUnit.SECONDS);
|
||||
assertThat(listener.stateChangedLatch.await(1, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.statesEntered.size(), is(3));
|
||||
assertThat(machine.getState().getIds(), contains(States.S0, States.S2, States.S21, States.S212));
|
||||
}
|
||||
|
||||
@@ -216,7 +214,7 @@ public class ShowcaseTests {
|
||||
listener.stateChangedLatch.await(1, TimeUnit.SECONDS);
|
||||
assertThat(machine.getState().getIds(), contains(States.S0, States.S2, States.S21, States.S211));
|
||||
assertThat(listener.statesExited.size(), is(2));
|
||||
assertThat(listener.statesEntered.size(), is(3));
|
||||
assertThat(listener.statesEntered.size(), is(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -226,7 +224,7 @@ public class ShowcaseTests {
|
||||
listener.stateChangedLatch.await(1, TimeUnit.SECONDS);
|
||||
assertThat(machine.getState().getIds(), contains(States.S0, States.S2, States.S21, States.S211));
|
||||
assertThat(listener.statesExited.size(), is(2));
|
||||
assertThat(listener.statesEntered.size(), is(4));
|
||||
assertThat(listener.statesEntered.size(), is(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -236,7 +234,7 @@ public class ShowcaseTests {
|
||||
listener.stateChangedLatch.await(1, TimeUnit.SECONDS);
|
||||
assertThat(machine.getState().getIds(), contains(States.S0, States.S2, States.S21, States.S211));
|
||||
assertThat(listener.statesExited.size(), is(2));
|
||||
assertThat(listener.statesEntered.size(), is(4));
|
||||
assertThat(listener.statesEntered.size(), is(3));
|
||||
}
|
||||
|
||||
static class Config {
|
||||
|
||||
Reference in New Issue
Block a user