public void CancellationTokenCancelsOperation() { var sm = new StateMachine("sm"); var initial = sm.CreateInitialState("initial"); var doingOperation = sm.CreateState("doingOperation"); var completedOperation = sm.CreateState("completedOperation"); var evt = new Event("evt"); initial.TransitionOn(evt).To(doingOperation); doingOperation.TransitionOn(evt).To(completedOperation); var cts = new CancellationTokenSource(); var op = new Operation<State>(evt, doingOperation, completedOperation); var task = op.TryFireAsync(cts.Token); Assert.False(task.IsCompleted); Assert.False(task.IsCanceled); cts.Cancel(); Assert.True(task.IsCanceled); // Check nothing explodes evt.Fire(); }
public void IndicatesWhetherInState() { var sm = new StateMachine("State Machine"); var state1 = sm.CreateInitialState("State 1"); var state2 = sm.CreateState("State 2"); var state3 = sm.CreateState("State 3"); var evt = sm.CreateEvent("Event"); var group1 = new StateGroup("Group 1"); var group2 = new StateGroup("Group 2"); state1.AddToGroup(group1); state2.AddToGroup(group2); state3.AddToGroup(group2); state1.TransitionOn(evt).To(state2); state2.TransitionOn(evt).To(state3); Assert.True(group1.IsCurrent); Assert.False(group2.IsCurrent); evt.Fire(); Assert.False(group1.IsCurrent); Assert.True(group2.IsCurrent); evt.Fire(); Assert.False(group1.IsCurrent); Assert.True(group2.IsCurrent); }
public void TransitionAddedToState() { var stateMachine = new StateMachine("State Machine"); var state1 = stateMachine.CreateState("State 1"); var state2 = stateMachine.CreateState("State 2"); var evt = stateMachine.CreateEvent("Event"); state1.TransitionOn(evt).To(state2); Assert.AreEqual(1, state1.Transitions.Count); Assert.AreEqual(state1, state1.Transitions[0].From); Assert.AreEqual(state2, state1.Transitions[0].To); Assert.AreEqual(evt, state1.Transitions[0].Event); Assert.False(state1.Transitions[0].IsInnerTransition); }
public void ForcefullyTransitioningFromChildStateMachineCallsExitHandlerOnCurrentState() { StateHandlerInfo<State> state22ExitInfo = null; var sm = new StateMachine("State Machine"); var evt1 = new Event("Event 1"); var state1 = sm.CreateInitialState("State 1"); var state2 = sm.CreateState("State 2"); var subSm = state2.CreateChildStateMachine(); var state21 = subSm.CreateInitialState("State 2.1"); var state22 = subSm.CreateState("State 2.2").WithExit(i => state22ExitInfo = i); state1.TransitionOn(evt1).To(state2); state21.TransitionOn(evt1).To(state22); // Enter state2, and start child state machine evt1.Fire(); // Enter State 2.2 evt1.Fire(); // Transition from state2 to state1, exiting the child state machine sm.ForceTransition(state1, evt1); Assert.NotNull(state22ExitInfo); Assert.AreEqual(state22, state22ExitInfo.From); Assert.AreEqual(state1, state22ExitInfo.To); Assert.AreEqual(evt1, state22ExitInfo.Event); }
public void FirstRegisteredTransitionWins() { var sm = new StateMachine("state machine"); var initial = sm.CreateInitialState("initial"); var state1 = sm.CreateState("state1"); var state2 = sm.CreateState("state2"); var evt = new Event("evt"); initial.TransitionOn(evt).To(state2).WithGuard(i => true); initial.TransitionOn(evt).To(state1); evt.Fire(); Assert.AreEqual(state2, sm.CurrentState); }
public void NoEventsAreQueuedIfAGuardThrowsAnException() { var sm = new StateMachine("sm"); var state1 = sm.CreateInitialState("state1"); var state2 = sm.CreateState("state2"); var evt = new Event("evt"); var evt2 = new Event("evt2"); var exception = new Exception("foo"); state1.TransitionOn(evt).To(state2).WithGuard(i => { evt.Fire(); throw exception; }); state1.TransitionOn(evt2).To(state2); state2.TransitionOn(evt).To(state1); Assert.Throws<Exception>(() => evt.Fire()); // Make sure that an event wasn't queued evt2.Fire(); Assert.AreEqual(state2, sm.CurrentState); }
public void TransitionNotFoundRaisedWhenTransitionNotFoundOnChild() { var sm = new StateMachine("sm"); var initial = sm.CreateInitialState("initial"); var state1 = sm.CreateState("state 1"); var child = initial.CreateChildStateMachine(); var childInitial = child.CreateInitialState("childInitial"); var evt = new Event("evt"); state1.InnerSelfTransitionOn(evt); TransitionNotFoundEventArgs<State> ea = null; sm.TransitionNotFound += (o, e) => { ea = e; }; evt.TryFire(); Assert.NotNull(ea); Assert.AreEqual(evt, ea.Event); Assert.AreEqual(initial, ea.From); Assert.AreEqual(sm, ea.StateMachine); Assert.AreEqual(EventFireMethod.TryFire, ea.EventFireMethod); }
public void CurrentChildStateReflectsCurrentStateOfChild() { var sm = new StateMachine("state machine"); var initialState = sm.CreateInitialState("initial state"); var state1 = sm.CreateState("state1"); var childSm = state1.CreateChildStateMachine(); var childInitialState = childSm.CreateInitialState("childInitialState"); var childState1 = childSm.CreateState("childState1"); var evt = new Event("evt"); var evt2 = new Event("evt2"); initialState.TransitionOn(evt).To(state1); childInitialState.TransitionOn(evt).To(childState1); state1.TransitionOn(evt2).To(initialState); Assert.AreEqual(initialState, sm.CurrentChildState); evt.Fire(); Assert.AreEqual(childInitialState, sm.CurrentChildState); evt.Fire(); Assert.AreEqual(childState1, sm.CurrentChildState); evt2.Fire(); Assert.AreEqual(initialState, sm.CurrentChildState); }
public void FormatsStateMachinesWithNoNames() { var sm = new StateMachine(); var state1 = sm.CreateInitialState(); var state2 = sm.CreateState(); var child1 = state1.CreateChildStateMachine(); var state11 = child1.CreateInitialState(); var state12 = child1.CreateState(); var child2 = state2.CreateChildStateMachine(); var state21 = child2.CreateInitialState(); var state22 = child2.CreateState(); var evt1 = new Event(); var evt2 = new Event<string>(); state1.InnerSelfTransitionOn(evt1); state1.TransitionOn(evt2).To(state2); state11.TransitionOn(evt2).ToDynamic(_ => state12); state12.TransitionOn(evt1).To(state11); state21.TransitionOn(evt1).To(state22); var dot = sm.FormatDot(); var dgml = sm.FormatDgml(); }
public void FormatsStateMachines() { var sm = new StateMachine("sm"); var state1 = sm.CreateInitialState("state1"); var state2 = sm.CreateState("state2"); var child1 = state1.CreateChildStateMachine("child1"); var state11 = child1.CreateInitialState("state11"); var state12 = child1.CreateState("state12"); var child2 = state2.CreateChildStateMachine("child2"); var state21 = child2.CreateInitialState("state21"); var state22 = child2.CreateState("state22"); var evt1 = new Event("evt1"); var evt2 = new Event<string>("evt2"); state1.InnerSelfTransitionOn(evt1); state1.TransitionOn(evt2).To(state2); state11.TransitionOn(evt2).ToDynamic(_ => state12); state12.TransitionOn(evt1).To(state11); state21.TransitionOn(evt1).To(state22); state21.TransitionOn(evt2).To(state22); var dot = sm.FormatDot(colorize: true); var dgml = sm.FormatDgml(colorize: true); }
public void FireThrowsIfEventFireThrows() { var sm = new StateMachine("sm"); var initial = sm.CreateInitialState("initial"); var operation = sm.CreateState("state2"); var success = sm.CreateState("success"); var evt = new Event("evt"); operation.TransitionOn(evt).To(operation); var op = new Operation<State>(evt, operation, success); var task = op.FireAsync(); Assert.True(task.IsFaulted); Assert.Throws<TransitionNotFoundException>(() => task.GetAwaiter().GetResult()); }
public void StateMachineStartsInInitialState() { var sm = new StateMachine("state machine"); var initialState = sm.CreateInitialState("initial state"); var state1 = sm.CreateState("state1"); Assert.AreEqual(initialState, sm.CurrentState); Assert.AreEqual(initialState, sm.InitialState); }
public void EventFireInTransitionHandlerIsQueued() { var sm = new StateMachine("sm"); var initial = sm.CreateInitialState("initial"); var state1 = sm.CreateState("state1"); var state2 = sm.CreateState("state2"); var state3 = sm.CreateState("state3"); var evt = sm.CreateEvent("evt"); var evt2 = sm.CreateEvent("evt2"); initial.TransitionOn(evt).To(state1).WithHandler(i => evt2.Fire()); initial.TransitionOn(evt2).To(state2); state1.TransitionOn(evt2).To(state3); evt.Fire(); Assert.AreEqual(state3, sm.CurrentState); }
public void ThrowsIfForcedTransitionOnAChildEvent() { var sm = new StateMachine("State Machine"); var state1 = sm.CreateInitialState("Initial State"); var state2 = sm.CreateState("State 2"); var subSm = state1.CreateChildStateMachine(); var evt = subSm.CreateEvent("Event"); Assert.Throws<InvalidEventTransitionException>(() => sm.ForceTransition(state2, evt)); }
public void TryFireReturnsFalseIfTransitionNotFound() { var sm = new StateMachine("sm"); var initialState = sm.CreateInitialState("initialState"); var state1 = sm.CreateState("state1"); var evt = new Event("evt"); state1.InnerSelfTransitionOn(evt); Assert.False(evt.TryFire()); }
public void DoesNotThrowIfTransitionAddedAfterAGuardedTransition() { var sm = new StateMachine("sm"); var state1 = sm.CreateInitialState("state1"); var state2 = sm.CreateState("state2"); var evt = new Event("evt"); state1.TransitionOn(evt).To(state2).WithGuard(i => true); Assert.DoesNotThrow(() => state1.TransitionOn(evt).To(state1)); }
public void AddStatesAddsStates() { var sm = new StateMachine("sm"); var state1 = sm.CreateInitialState("state1"); var state2 = sm.CreateState("state2"); var group = new StateGroup("group"); group.AddStates(state1, state2); Assert.That(group.States, Is.EquivalentTo(new[] { state1, state2 })); }
public void ChildStateMachineStartsInNoStateIfParentStateIsNotInitialState() { var parent = new StateMachine("parent"); var initial = parent.CreateInitialState("initial"); var state1 = parent.CreateState("state1"); var child = state1.CreateChildStateMachine(); var childInitial = child.CreateInitialState("childInitial"); Assert.AreEqual(null, child.CurrentState); Assert.AreEqual(childInitial, child.InitialState); }
public void DoesNotThrowIfTransitionAddedAfterADynamicTransition() { var sm = new StateMachine("sm"); var state1 = sm.CreateInitialState("state1"); var state2 = sm.CreateState("state2"); var evt = new Event("evt"); state1.TransitionOn(evt).ToDynamic(i => null); Assert.DoesNotThrow(() => state1.TransitionOn(evt).To(state1)); }
public void RecursiveFireDoesNotThrowIfTransitionNotFound() { var sm = new StateMachine("sm"); var initialState = sm.CreateInitialState("initialState"); var state1 = sm.CreateState("state1"); var evt = sm.CreateEvent("evt"); var evt2 = sm.CreateEvent("evt2"); initialState.TransitionOn(evt).To(state1).WithHandler(i => Assert.DoesNotThrow(() => evt2.Fire())); try { evt.TryFire(); } catch { } }
public void OuterEventTryFireReturnsTrueIfRecursiveTransitionNotFoundAndFiredWithTryFire() { var sm = new StateMachine("sm"); var initialState = sm.CreateInitialState("initialState"); var state1 = sm.CreateState("state1"); var evt = sm.CreateEvent("evt"); var evt2 = sm.CreateEvent("evt2"); initialState.TransitionOn(evt).To(state1).WithHandler(i => evt2.TryFire()); Assert.True(evt.TryFire()); }
public void EventsFiredFromHandlersCallsSynchronizer() { var sm = new StateMachine("sm"); var initial = sm.CreateInitialState("initial"); var state1 = sm.CreateState("state1"); var state2 = sm.CreateState("state2"); var evt = new Event("evt"); initial.TransitionOn(evt).To(state1).WithHandler(i => evt.Fire()); state1.TransitionOn(evt).To(state2); var synchornizer = new Mock<IStateMachineSynchronizer>(); sm.Synchronizer = synchornizer.Object; // Fire the first, capture the second bool calledOnce = false; Func<bool> fireFunc = null; synchornizer.Setup(x => x.FireEvent(It.IsAny<Func<bool>>(), EventFireMethod.Fire)) .Callback<Func<bool>, EventFireMethod>((func, _) => { if (!calledOnce) { // Need to set this before invoking func(), as we'll recurse calledOnce = true; func(); } else { fireFunc = func; } }); evt.Fire(); Assert.AreEqual(state1, sm.CurrentState); Assert.NotNull(fireFunc); fireFunc(); Assert.AreEqual(state2, sm.CurrentState); }
public void CorrectHandlersAreInvokedInNormalTransition() { var events = new List<string>(); var sm = new StateMachine("State Machine"); var evt = sm.CreateEvent("Event"); var state1 = sm.CreateInitialState("State 1").WithExit(i => events.Add("State 1 Exit")); var state2 = sm.CreateState("State 2").WithEntry(i => events.Add("State 2 Entry")); var transition = state1.TransitionOn(evt).To(state2).WithHandler(i => events.Add("Transition 1 2")); evt.Fire(); Assert.That(events, Is.EquivalentTo(new[] { "State 1 Exit", "Transition 1 2", "State 2 Entry" })); }
public void EventTTryFireUsesDefaultEventData() { var sm = new StateMachine("sm"); var state1 = sm.CreateInitialState("state1"); var state2 = sm.CreateState("state2"); var evt = new Event<int>("evt"); int? eventData = null; state1.TransitionOn(evt).To(state2).WithHandler(i => eventData = i.EventData); ((IEvent)evt).TryFire(); Assert.AreEqual(0, eventData); }
public void InnerTransitionAddedToState() { var stateMachine = new StateMachine("State Machine"); var state1 = stateMachine.CreateState("State 1"); var evt = new Event("Event"); state1.InnerSelfTransitionOn(evt); Assert.AreEqual(1, state1.Transitions.Count); Assert.AreEqual(state1, state1.Transitions[0].From); Assert.AreEqual(state1, state1.Transitions[0].To); Assert.AreEqual(evt, state1.Transitions[0].Event); Assert.True(state1.Transitions[0].IsInnerTransition); }
public void CurrentStateReflectsCurrentState() { var sm = new StateMachine("state machine"); var initialState = sm.CreateInitialState("initial state"); var state1 = sm.CreateState("state1"); var evt = new Event("evt"); initialState.TransitionOn(evt).To(state1); Assert.AreEqual(initialState, sm.CurrentState); evt.Fire(); Assert.AreEqual(state1, sm.CurrentState); }
public void OperationCompletesWhenASuccessStateIsReached() { var sm = new StateMachine("sm"); var initial = sm.CreateInitialState("initial"); var doingOperation = sm.CreateState("doingOperation"); var completedOperation = sm.CreateState("completedOperation"); var evt = new Event("evt"); initial.TransitionOn(evt).To(doingOperation); doingOperation.TransitionOn(evt).To(completedOperation); var op = new Operation<State>(evt, doingOperation, completedOperation); var task = op.TryFireAsync(); Assert.False(task.IsCompleted); Assert.AreEqual(doingOperation, sm.CurrentState); evt.TryFire(); Assert.True(task.IsCompleted); Assert.True(task.Result); }
public void ResetResetsCurrentStateOfStateMachine() { var sm = new StateMachine("sm"); var initial = sm.CreateInitialState("initial"); var state1 = sm.CreateState("state1"); var evt = sm.CreateEvent("evt"); initial.TransitionOn(evt).To(state1); evt.Fire(); sm.Reset(); Assert.AreEqual(initial, sm.CurrentState); }
public void FireThrowsIfTransitionNotFound() { var sm = new StateMachine("sm"); var initialState = sm.CreateInitialState("initialState"); var state1 = sm.CreateState("state1"); var evt = new Event("evt"); state1.TransitionOn(evt).To(initialState); var e = Assert.Throws<TransitionNotFoundException>(() => evt.Fire()); Assert.AreEqual(initialState, e.From); Assert.AreEqual(evt, e.Event); Assert.AreEqual(sm, e.StateMachine); }
public void DynamicTransitionStateSelectorIsSettable() { var sm = new StateMachine("sm"); var state1 = sm.CreateInitialState("state1"); var state2 = sm.CreateState("state2"); var evt = new Event("evt"); var transition = state1.TransitionOn(evt).ToDynamic(i => state2); transition.StateSelector = i => null; evt.TryFire(); Assert.AreEqual(state1, sm.CurrentState); }