public void FluentStateMachineBuilder_AfterExit_DefiningState_AddsEvent()
        {
            var loggedEvents = new List <string>();
            Action <string, TransitionEventArgs <StubStateModel> > logEvent = (message, e) =>
            {
                loggedEvents.Add(string.Format("{0} from {1} to {2} on {3}",
                                               message, e.From, e.To, e.Trigger));
            };

            var machine = FluentStateMachine <StubStateModel> .Describe()
                          .State("s1")
                          .AfterExit(e => logEvent("AfterExit", e))
                          .TransitionsTo("s2").On("t")
                          .Initiates()
                          .State("s2")
                          .AfterExit(e => logEvent("AfterExit", e))
                          .TransitionsTo("s1").On("t")
                          .Compile();

            var model = new StubStateModel();

            model.CurrentState = machine.InitialState;

            machine.Trigger("t", model);
            Assert.Equal("s2", model.CurrentState.ToString());
            Assert.Equal(1, loggedEvents.Count());
            Assert.Equal("AfterExit from s1 to s2 on t", loggedEvents[0]);
        }
Пример #2
0
        public void IStateModelExtensions_AvailableTriggers_NullMachine_ThrowsNullEx()
        {
            var mockModel = new StubStateModel();

            Assert.Throws <ArgumentNullException>(() =>
                                                  mockModel.AvailableTriggers((IStateMachine <StubStateModel>)null));
        }
Пример #3
0
        public void StateMachine_AvailableTriggers_ConcatsModelsTransWithGlobal_ReturnsDistinctTrigsByName()
        {
            var model   = new StubStateModel();
            var machine = new StateMachine <StubStateModel>();

            var trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

            var state1 = new State <StubStateModel>("s1");
            var state2 = new State <StubStateModel>("s2");
            var state3 = new State <StubStateModel>("s3");
            var state4 = new State <StubStateModel>("s4");

            var statetrans1 = new Transition <StubStateModel>(trigger1, state1, state2);
            var statetrans2 = new Transition <StubStateModel>(trigger1, state1, state3);
            var statetrans3 = new Transition <StubStateModel>(trigger2, state1, state3);

            var globaltrans1 = new Transition <StubStateModel>(trigger2, null, state1);

            machine.AddGlobalTransition(globaltrans1);
            state1.AddTransition(statetrans1);
            state1.AddTransition(statetrans2);
            state1.AddTransition(statetrans3);

            model.CurrentState = state1;

            var result = machine.AvailableTriggers(model);

            Assert.Equal(2, result.Count());
            Assert.Equal(trigger1, result.ToList()[0]);
            Assert.Equal(trigger2, result.ToList()[1]);
        }
        public void IStateModelExtensions_AvailableTriggers_NullMachine_ThrowsNullEx()
        {
            var mockModel = new StubStateModel();

            Assert.Throws<ArgumentNullException>(() =>
                IStateModelExtensions.AvailableTriggers(mockModel, (IStateMachine<StubStateModel>)null));
        }
Пример #5
0
        public void FluentStateMachine_AvailableStates_ValidParms_CallsReturnsMachineAvailable()
        {
            var machineMock = new Mock<IStateMachine<StubStateModel>>();
            var state1 = new State<StubStateModel>("s1");
            var state2 = new State<StubStateModel>("s2");
            var state3 = new State<StubStateModel>("s3");

            var allStates = new List<State<StubStateModel>>();
            allStates.Add(state1);
            allStates.Add(state2);
            allStates.Add(state3);

            var model = new StubStateModel();

            machineMock.Setup(m => m.AvailableStates(model)).Returns(allStates).Verifiable();

            var fluentMachine = new FluentStateMachine<StubStateModel>(
                machineMock.Object,
                allStates,
                state2,
                null,
                null,
                null);

            var result = fluentMachine.AvailableStates(model);

            Assert.Same(allStates, result);
            machineMock.VerifyAll();
        }
Пример #6
0
        StateMachine_Trigger_TransitionFromCurrentToSame_ConfiggedNotToRaiseExcep_DoesNotRaiseTransitionChangeEvents()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionBeforeTransitionToSameState = false
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");

            var state1 = new State <StubStateModel>("state1");
            TransitionEventArgs <StubStateModel> transitioningArgs = null;

            state1.Entered += (s, e) => { transitioningArgs = e; };
            TransitionEventArgs <StubStateModel> transitionedArgs = null;

            state1.Exiting += (s, e) => { transitionedArgs = e; };

            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            // should not throw exception and that's good enough for us
            machine.Trigger(trigger1, model);

            // verify that no transition events occurred
            Assert.Null(transitioningArgs);
            Assert.Null(transitionedArgs);
        }
Пример #7
0
        public void IStateModelExtensions_Trigger_NullMachine_StringTrigger_ThrowsNullEx()
        {
            var mockModel = new StubStateModel();

            Assert.Throws <ArgumentNullException>(() =>
                                                  mockModel.Trigger("triggerName", (IStateMachine <StubStateModel>)null));
        }
Пример #8
0
        public void FluentStateMachine_AvailableStates_ValidParms_CallsReturnsMachineAvailable()
        {
            var machineMock = new Mock <IStateMachine <StubStateModel> >();
            var state1      = new State <StubStateModel>("s1");
            var state2      = new State <StubStateModel>("s2");
            var state3      = new State <StubStateModel>("s3");

            var allStates = new List <State <StubStateModel> >();

            allStates.Add(state1);
            allStates.Add(state2);
            allStates.Add(state3);

            var model = new StubStateModel();


            machineMock.Setup(m => m.AvailableStates(model)).Returns(allStates).Verifiable();

            var fluentMachine = new FluentStateMachine <StubStateModel>(
                machineMock.Object,
                allStates,
                state2,
                null,
                null,
                null);

            var result = fluentMachine.AvailableStates(model);

            Assert.Same(allStates, result);
            machineMock.VerifyAll();
        }
        public void FluentStateMachineBuilder_AfterExit_DefiningState_AddsEvent()
        {
            var loggedEvents = new List<string>();
            Action<string, TransitionEventArgs<StubStateModel>> logEvent = (message, e) =>
            {
                loggedEvents.Add(String.Format("{0} from {1} to {2} on {3}",
                        message, e.From, e.To, e.Trigger));
            };

            var machine = FluentStateMachine<StubStateModel>.Describe()
                .State("s1")
                    .AfterExit(e => logEvent("AfterExit", e))
                    .TransitionsTo("s2").On("t")
                    .Initiates()
                .State("s2")
                    .AfterExit(e => logEvent("AfterExit", e))
                    .TransitionsTo("s1").On("t")
                .Compile();

            var model = new StubStateModel();
            model.CurrentState = machine.InitialState;

            machine.Trigger("t", model);
            Assert.Equal("s2", model.CurrentState.ToString());
            Assert.Equal(1, loggedEvents.Count());
            Assert.Equal("AfterExit from s1 to s2 on t", loggedEvents[0]);
        }
Пример #10
0
        public void FluentStateMachine_Trigger_ValidParms_CallsReturnsMachineTrigger()
        {
            var machineMock = new Mock <IStateMachine <StubStateModel> >();
            var state1      = new State <StubStateModel>("s1");
            var state2      = new State <StubStateModel>("s2");
            var state3      = new State <StubStateModel>("s3");

            var allStates = new List <State <StubStateModel> >();

            allStates.Add(state1);
            allStates.Add(state2);
            allStates.Add(state3);

            var model = new StubStateModel();


            var fluentMachine = new FluentStateMachine <StubStateModel>(
                machineMock.Object,
                allStates,
                state2,
                null,
                null,
                null);

            machineMock.Setup(m => m.Trigger(It.Is <Trigger>(t => t.Name == "trigger1"), model)).Verifiable();

            fluentMachine.Trigger("trigger1", model);

            machineMock.VerifyAll();
        }
Пример #11
0
        public void StateMachine_AvailableTriggers_ModelStateNotState_ThrowInvalidStateModel()
        {
            var model   = new StubStateModel();
            var machine = new StateMachine <StubStateModel>();

            Assert.Throws <InvalidStateModelException>(() =>
                                                       machine.AvailableTriggers(model));
        }
Пример #12
0
        public void IStateModelExtensions_Trigger_NullTriggerName_ThrowsNullEx()
        {
            var mockModel   = new StubStateModel();
            var mockMachine = new Mock <IStateMachine <StubStateModel> >();

            Assert.Throws <ArgumentNullException>(() =>
                                                  mockModel.Trigger((string)null, mockMachine.Object));
        }
Пример #13
0
        StateMachine_Trigger_ValidTriggerAndTrans_ChoosesFirstTranWthPassGuardNonGlobal_SameAsCurrentState_NoRaised()
        {
            var model   = new StubStateModel();
            var machine = new StateMachine <StubStateModel>();
            TransitionEventArgs <StubStateModel> transitioningArgs = null;

            machine.Transitioning += (s, e) => { transitioningArgs = e; };
            TransitionEventArgs <StubStateModel> transitionedArgs = null;

            machine.Transitioned += (s, e) => { transitionedArgs = e; };

            var trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

            var state1Mock = new Mock <State <StubStateModel> >("s1");
            var state2Mock = new Mock <State <StubStateModel> >("s2");
            var state3Mock = new Mock <State <StubStateModel> >("s3");
            var state4Mock = new Mock <State <StubStateModel> >("s4");

            var state1 = state1Mock.Object;
            var state2 = state2Mock.Object;
            var state3 = state3Mock.Object;
            var state4 = state4Mock.Object;

            var statetrans1 = new Transition <StubStateModel>(trigger1, state1, state2, m => 1 == 2);
            var statetrans2 = new Transition <StubStateModel>(trigger1, state1, state3, m => 1 == 1);
            var statetrans3 = new Transition <StubStateModel>(trigger2, state1, state3);

            var globaltrans1 = new Transition <StubStateModel>(trigger1, null, state1, m => 1 == 1);

            machine.AddGlobalTransition(globaltrans1);
            state1.AddTransition(statetrans1);
            state1.AddTransition(statetrans2);
            state1.AddTransition(statetrans3);

            model.CurrentState = state1;

            // so when trigger1 is triggered on state model whose current state is state1,
            // it will fall through to the first matching transition with a passing guard, the second state transition to state 1
            // but since this is same state as current state, it shouldn't actually transition.  no events should be called.

            machine.Trigger(trigger1, model);

            // verify that no transition events were calledb
            state1Mock.Verify(s =>
                              s.RaiseEntered(
                                  It.IsAny <StubStateModel>(),
                                  It.IsAny <State <StubStateModel> >(),
                                  It.IsAny <Trigger>()), Times.Never());
            state1Mock.Verify(s =>
                              s.RaiseExiting(
                                  It.IsAny <StubStateModel>(),
                                  It.IsAny <State <StubStateModel> >(),
                                  It.IsAny <Trigger>()), Times.Never());
            Assert.Null(transitioningArgs);
            Assert.Null(transitionedArgs);
        }
Пример #14
0
        public void StateMachine_Trigger_ModelStateNotState_ThrowsInvalidStateModel()
        {
            var machine = new StateMachine <StubStateModel>();
            var model   = new StubStateModel();
            var trigger = new Trigger("trigger");

            Assert.Throws <InvalidStateModelException>(() =>
                                                       machine.Trigger(trigger, model));
        }
Пример #15
0
        public void IStateModelExtensions_Trigger_ValidParms_ObjTrigger_CallsTriggerOnMachine()
        {
            var mockModel   = new StubStateModel();
            var trigger     = new Trigger("trigger");
            var mockMachine = new Mock <IStateMachine <StubStateModel> >();

            mockMachine.Setup(m => m.Trigger(trigger, mockModel)).Verifiable();
            mockModel.Trigger(trigger, mockMachine.Object);
            mockMachine.VerifyAll();
        }
Пример #16
0
        public void IStateModelExtensions_Trigger_ValidParms_StringTrigger_CallsTriggerOnMachine()
        {
            var mockModel   = new StubStateModel();
            var mockMachine = new Mock <IStateMachine <StubStateModel> >();

            mockMachine.Setup(m => m.Trigger(It.Is <Trigger>(t => t.Name == "triggerName"), mockModel)).Verifiable();

            mockModel.Trigger("triggerName", mockMachine.Object);

            mockMachine.VerifyAll();
        }
Пример #17
0
        public void IStateModelExtensions_AvailableStates_ValidParms_CallsReturnsMachineAvailable()
        {
            var mockModel = new StubStateModel();
            var mockMachine = new Mock<IStateMachine<StubStateModel>>();
            var mockStates = new Mock<IEnumerable<State<StubStateModel>>>().Object;
            mockMachine.Setup(m => m.AvailableStates(mockModel)).Returns(mockStates).Verifiable();

            var result = IStateModelExtensions.AvailableStates(mockModel, mockMachine.Object);

            mockMachine.VerifyAll();
            Assert.Same(mockStates, result);
        }
        public void IStateMachineExtensinos_ValidParms_CallsTriggerOnMachineWithParms()
        {
            var mockMachine = new Mock<IStateMachine<StubStateModel>>();
            var mockModel = new StubStateModel();

            mockMachine.Setup(m =>
                m.Trigger(It.Is<Trigger>(t => t.Name == "trigger"), mockModel)).Verifiable();

            IStateMachineExtensions.Trigger(mockMachine.Object, "trigger", mockModel);

            mockMachine.VerifyAll();
        }
Пример #19
0
        public void IStateMachineExtensinos_ValidParms_CallsTriggerOnMachineWithParms()
        {
            var mockMachine = new Mock <IStateMachine <StubStateModel> >();
            var mockModel   = new StubStateModel();

            mockMachine.Setup(m =>
                              m.Trigger(It.Is <Trigger>(t => t.Name == "trigger"), mockModel)).Verifiable();

            mockMachine.Object.Trigger("trigger", mockModel);

            mockMachine.VerifyAll();
        }
Пример #20
0
        public void TransitionEventArgs_ValidParms_VerifyAssigns()
        {
            var model   = new StubStateModel();
            var from    = new State <StubStateModel>("from");
            var to      = new State <StubStateModel>("to");
            var trigger = new Trigger("trigger");
            var args    = new TransitionEventArgs <StubStateModel>(model, from, to, trigger);

            Assert.Same(from, args.From);
            Assert.Same(to, args.To);
            Assert.Same(model, args.Model);
            Assert.Same(trigger, args.Trigger);
        }
Пример #21
0
        public void IStateModelExtensions_AvailableTriggers_ValidParms_CallsReturnsTriggersAvailable()
        {
            var mockModel    = new StubStateModel();
            var mockTriggers = new Mock <IEnumerable <Trigger> >().Object;
            var mockMachine  = new Mock <IStateMachine <StubStateModel> >();

            mockMachine.Setup(m => m.AvailableTriggers(mockModel)).Returns(mockTriggers).Verifiable();

            var result = mockModel.AvailableTriggers(mockMachine.Object);

            mockMachine.VerifyAll();
            Assert.Same(mockTriggers, result);
        }
        public void FluentStateMachineBuilder_State_ValidParms_CreatesNewState()
        {
            var machine = FluentStateMachine <StubStateModel> .Describe()
                          .State("s1")
                          .Initiates()
                          .Compile();

            var model = new StubStateModel();

            model.CurrentState = machine.InitialState;

            Assert.Equal("s1", model.CurrentState.ToString());
        }
        public void FluentStateMachineBuilder_On_SetsTriggerForATransition()
        {
            var machine = FluentStateMachine <StubStateModel> .Describe()
                          .State("s1")
                          .TransitionsTo("s2").On("t")
                          .Initiates()
                          .State("s2")
                          .TransitionsTo("s1").On("t")
                          .Compile();

            var model = new StubStateModel();

            model.CurrentState = machine.InitialState;

            Assert.Equal("s1", model.CurrentState.ToString());
            machine.Trigger("t", model);
            Assert.Equal("s2", model.CurrentState.ToString());
        }
Пример #24
0
        StateMachine_Trigger_NoStateOrGlobalTransOnTrigger_ConfigRaiseOnNoTransFalse_NotThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoTransition = false
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var trigger2 = new Trigger("trigger2");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state2);
            model.CurrentState = state1;

            // no exception shoudl happen, and that's good enough for us.
            machine.Trigger(trigger2, model);
        }
Пример #25
0
        public void State_RaiseExiting_ValidParms_Handler_TriggersHandlerPassesParmsAndSelf()
        {
            var model     = new StubStateModel();
            var fromState = new State <StubStateModel>("from");
            var toState   = new State <StubStateModel>("to");
            var trigger   = new Trigger("trigger");

            TransitionEventArgs <StubStateModel> args = null;

            fromState.Exiting += (s, e) => { args = e; };

            fromState.RaiseExiting(model, toState, trigger);

            Assert.Equal(model, args.Model);
            Assert.Equal(fromState, args.From);
            Assert.Equal(toState, args.To);
            Assert.Equal(trigger, args.Trigger);
        }
        public void FluentStateMachineBuilder_When_WhileDefTrans_AddsGuardToTransition()
        {
            var machine = FluentStateMachine <StubStateModel> .Describe()
                          .State("s1")
                          .Initiates()
                          .TransitionsTo("s2").On("t").When(m => false)
                          .TransitionsTo("s3").On("t").When(m => true)
                          .State("s2")
                          .State("s3")
                          .Compile();

            var model = new StubStateModel();

            model.CurrentState = machine.InitialState;

            Assert.Equal("s1", model.CurrentState.ToString());
            machine.Trigger("t", model);
            Assert.Equal("s3", model.CurrentState.ToString());
        }
Пример #27
0
        StateMachine_Trigger_NoPassingTransitionOnTrigger_ConfigRaiseOnNoPassingTranTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoPassingTransition = true
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state2, m => 1 == 2);
            model.CurrentState = state1;

            // set up so that there's a matching transition, but the guard would fail when run

            Assert.Throws <InvalidTriggerException>(() =>
                                                    machine.Trigger(trigger1, model));
        }
Пример #28
0
        StateMachine_Trigger_NoPassingTransitionOnTrigger_ConfigRaiseOnNoPassingTranFalse_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoPassingTransition = false
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state2, m => 1 == 2);
            model.CurrentState = state1;

            // set up so that there's a matching transition, but the guard would fail when run

            // no exceptions should happen, and that's good enough for us
            machine.Trigger(trigger1, model);
        }
Пример #29
0
        public void StateMachine_Trigger_NoStateOrGlobalTransOnTrigger_ConfigRaiseOnNoTransTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoTransition = true
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var trigger2 = new Trigger("trigger2");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state2);
            model.CurrentState = state1;

            // set up so that current state of state 1 doesn't' define a trans for "trigger2", only "trigger1"

            Assert.Throws <InvalidTriggerException>(() =>
                                                    machine.Trigger(trigger2, model));
        }
Пример #30
0
        public void StateMachine_Trigger_TransitionsToSameState_ConfigRaiseOnSameStateTranFalse_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionBeforeTransitionToSameState = false
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            // should not throw exception and that's good enough for us
            machine.Trigger(trigger1, model);
        }
Пример #31
0
        public void StateMachine_Trigger_TransitionsToSameState_ConfigRaiseOnSameStateTranTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionBeforeTransitionToSameState = true
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            Assert.Throws <InvalidTriggerException>(() =>
                                                    machine.Trigger(trigger1, model));
        }
        public void FluentStateMachineBuilder_DefiningCallbacksOnAll_AllCallbacksCalledInOrder()
        {
            var loggedEvents = new List <string>();
            Action <string, TransitionEventArgs <StubStateModel> > logEvent = (message, e) =>
            {
                loggedEvents.Add(string.Format("{0} from {1} to {2} on {3}",
                                               message, e.From, e.To, e.Trigger));
            };

            var machine = FluentStateMachine <StubStateModel> .Describe()
                          .State("s1")
                          .BeforeEntry(e => logEvent("beforeEntry", e))
                          .AfterEntry(e => logEvent("afterEntry", e))
                          .BeforeExit(e => logEvent("beforeExit", e))
                          .AfterExit(e => logEvent("afterExit", e))
                          .TransitionsTo("s2").On("t")
                          .Initiates()
                          .State("s2")
                          .BeforeEntry(e => logEvent("beforeEntry", e))
                          .AfterEntry(e => logEvent("afterEntry", e))
                          .BeforeExit(e => logEvent("beforeExit", e))
                          .AfterExit(e => logEvent("afterExit", e))
                          .TransitionsTo("s1").On("t")
                          .BeforeTransition(e => logEvent("beforeTransition", e))
                          .AfterTransition(e => logEvent("afterTransition", e))
                          .Compile();

            var model = new StubStateModel();

            model.CurrentState = machine.InitialState;

            machine.Trigger("t", model);
            Assert.Equal("s2", model.CurrentState.ToString());
            Assert.Equal(6, loggedEvents.Count());
            Assert.Equal("beforeTransition from s1 to s2 on t", loggedEvents[0]);
            Assert.Equal("beforeExit from s1 to s2 on t", loggedEvents[1]);
            Assert.Equal("beforeEntry from s1 to s2 on t", loggedEvents[2]);
            Assert.Equal("afterExit from s1 to s2 on t", loggedEvents[3]);
            Assert.Equal("afterEntry from s1 to s2 on t", loggedEvents[4]);
            Assert.Equal("afterTransition from s1 to s2 on t", loggedEvents[5]);
        }
Пример #33
0
        public void StateMachine_Trigger_ValidTriggerAndTrans_ChoosesFirstTranWthPassGuard_SameAsCurrentState_NoRaised()
        {
            var model = new StubStateModel();
            var machine = new StateMachine<StubStateModel>();
            TransitionEventArgs<StubStateModel> transitioningArgs = null;
            machine.Transitioning += (s, e) => { transitioningArgs = e; };
            TransitionEventArgs<StubStateModel> transitionedArgs = null;
            machine.Transitioned += (s, e) => { transitionedArgs = e; };

            var trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

            var state1Mock = new Mock<State<StubStateModel>>("s1");
            var state2Mock = new Mock<State<StubStateModel>>("s2");
            var state3Mock = new Mock<State<StubStateModel>>("s3");
            var state4Mock = new Mock<State<StubStateModel>>("s4");

            var state1 = state1Mock.Object;
            var state2 = state2Mock.Object;
            var state3 = state3Mock.Object;
            var state4 = state4Mock.Object;

            var statetrans1 = new Transition<StubStateModel>(trigger1, state1, state2, m => 1 == 2);
            var statetrans2 = new Transition<StubStateModel>(trigger1, state1, state3, m => 1 == 3);
            var statetrans3 = new Transition<StubStateModel>(trigger2, state1, state3);

            var globaltrans1 = new Transition<StubStateModel>(trigger1, null, state1, m => 1 == 1);

            machine.AddGlobalTransition(globaltrans1);
            state1.AddTransition(statetrans1);
            state1.AddTransition(statetrans2);
            state1.AddTransition(statetrans3);

            model.CurrentState = state1;

            // so when trigger1 is triggered on state model whose current state is state1,
            // it will fall through to the first matching transition with a passing guard, the global transition to state 1
            // but since this is same state as current state, it shouldn't actually transition.  no events should be called.

            machine.Trigger(trigger1, model);

            // verify that no transition events were calledb
            state1Mock.Verify(s =>
                s.RaiseEntered(
                    It.IsAny<StubStateModel>(),
                    It.IsAny<State<StubStateModel>>(),
                    It.IsAny<Trigger>()), Times.Never());
            state1Mock.Verify(s =>
                s.RaiseExiting(
                    It.IsAny<StubStateModel>(),
                    It.IsAny<State<StubStateModel>>(),
                    It.IsAny<Trigger>()), Times.Never());
            Assert.Null(transitioningArgs);
            Assert.Null(transitionedArgs);
        }
Пример #34
0
        public void FluentStateMachine_Trigger_ValidParms_CallsReturnsMachineTrigger()
        {
            var machineMock = new Mock<IStateMachine<StubStateModel>>();
            var state1 = new State<StubStateModel>("s1");
            var state2 = new State<StubStateModel>("s2");
            var state3 = new State<StubStateModel>("s3");

            var allStates = new List<State<StubStateModel>>();
            allStates.Add(state1);
            allStates.Add(state2);
            allStates.Add(state3);

            var model = new StubStateModel();

            var fluentMachine = new FluentStateMachine<StubStateModel>(
                machineMock.Object,
                allStates,
                state2,
                null,
                null,
                null);

            machineMock.Setup(m => m.Trigger(It.Is<Trigger>(t => t.Name == "trigger1"), model)).Verifiable();

            fluentMachine.Trigger("trigger1", model);

            machineMock.VerifyAll();
        }
Пример #35
0
        public void StateMachine_Trigger_NoPassingTransitionOnTrigger_ConfigRaiseOnNoPassingTranFalse_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoPassingTransition = false };
            var machine = new StateMachine<StubStateModel>(config);
            var model = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1 = new State<StubStateModel>("state1");
            var state2 = new State<StubStateModel>("state2");
            state1.AddTransition(trigger1, state2, m => 1 == 2);
            model.CurrentState = state1;

            // set up so that there's a matching transition, but the guard would fail when run

            // no exceptions should happen, and that's good enough for us
            machine.Trigger(trigger1, model);
        }
Пример #36
0
        public void StateMachine_Trigger_ValidTriggerAndTrans_ChoosesFirstTranWthPassGuard_DiffAsCurrentState_Raised_Sets()
        {
            var model = new StubStateModel();
            var machine = new StateMachine<StubStateModel>();

            var transitioningEventArgs = new List<TransitionEventArgs<StubStateModel>>();
            machine.Transitioning += (s, e) => { transitioningEventArgs.Add(e); };

            var transitionedEventArgs = new List<TransitionEventArgs<StubStateModel>>();
            machine.Transitioned += (s, e) => { transitionedEventArgs.Add(e); };

            var trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

            var state1Mock = new Mock<State<StubStateModel>>("s1");
            var state2Mock = new Mock<State<StubStateModel>>("s2");
            var state3Mock = new Mock<State<StubStateModel>>("s3");
            var state4Mock = new Mock<State<StubStateModel>>("s4");

            var state1 = state1Mock.Object;
            var state2 = state2Mock.Object;
            var state3 = state3Mock.Object;
            var state4 = state4Mock.Object;

            var statetrans1 = new Transition<StubStateModel>(trigger1, state1, state2, m => 1 == 2);
            var statetrans2 = new Transition<StubStateModel>(trigger1, state1, state3, m => 1 == 3);
            var statetrans3 = new Transition<StubStateModel>(trigger2, state1, state3);

            var globaltrans1 = new Transition<StubStateModel>(trigger1, null, state2, m => 1 == 1);

            machine.AddGlobalTransition(globaltrans1);
            state1.AddTransition(statetrans1);
            state1.AddTransition(statetrans2);
            state1.AddTransition(statetrans3);

            model.CurrentState = state1;

            // so when trigger 1 is triggered on state model whose current state is state1,
            // it will fall through to the first maching transition with a passing guard, the global transition to state 2
            // it will then transition to state2.

            // make sure that transition events are called for moving from state 1 to state 2
            state1Mock.Setup(s => s.RaiseExiting(model, state2, trigger1)).Verifiable();
            state2Mock.Setup(s => s.RaiseEntered(model, state1, trigger1)).Verifiable();

            machine.Trigger(trigger1, model);

            // verify that no transition events were called that shouldn't have been
            state1Mock.Verify(s =>
                s.RaiseEntered(
                    It.IsAny<StubStateModel>(),
                    It.IsAny<State<StubStateModel>>(),
                    It.IsAny<Trigger>()), Times.Never());
            state2Mock.Verify(s =>
                s.RaiseExiting(
                    It.IsAny<StubStateModel>(),
                    It.IsAny<State<StubStateModel>>(),
                    It.IsAny<Trigger>()), Times.Never());
            Assert.Equal(1, transitioningEventArgs.Count);
            Assert.Equal(1, transitionedEventArgs.Count);

            Assert.Equal(state1, transitioningEventArgs[0].From);
            Assert.Equal(state2, transitioningEventArgs[0].To);
            Assert.Equal(trigger1, transitioningEventArgs[0].Trigger);
            Assert.Equal(model, transitioningEventArgs[0].Model);
            Assert.Equal(state1, transitionedEventArgs[0].From);
            Assert.Equal(state2, transitionedEventArgs[0].To);
            Assert.Equal(trigger1, transitionedEventArgs[0].Trigger);
            Assert.Equal(model, transitionedEventArgs[0].Model);
            Assert.Equal(state2, model.CurrentState);
        }
Пример #37
0
        public void StateMachine_Trigger_TransitionsToSameState_ConfigRaiseOnSameStateTranFalse_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration { RaiseExceptionBeforeTransitionToSameState = false };
            var machine = new StateMachine<StubStateModel>(config);
            var model = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1 = new State<StubStateModel>("state1");
            var state2 = new State<StubStateModel>("state2");
            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            // should not throw exception and that's good enough for us
            machine.Trigger(trigger1, model);
        }
Пример #38
0
        public void StateMachine_Trigger_NoPassingTransitionOnTrigger_ConfigRaiseOnNoPassingTranTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoPassingTransition = true };
            var machine = new StateMachine<StubStateModel>(config);
            var model = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1 = new State<StubStateModel>("state1");
            var state2 = new State<StubStateModel>("state2");
            state1.AddTransition(trigger1, state2, m => 1 == 2);
            model.CurrentState = state1;

            // set up so that there's a matching transition, but the guard would fail when run

            Assert.Throws<InvalidTriggerException>(() =>
                machine.Trigger(trigger1, model));
        }
        public void FluentStateMachineBuilder_TransitionsTo_Valid_CreatesNewTransition()
        {
            var machine = FluentStateMachine<StubStateModel>.Describe()
                .State("s1")
                    .Initiates()
                    .TransitionsTo("s2").On("t")
                .State("s2")
                    .TransitionsTo("s1").On("t")
                .Compile();

            var model = new StubStateModel();
            model.CurrentState = machine.InitialState;

            Assert.Equal("s1", model.CurrentState.ToString());
            machine.Trigger("t", model);
            Assert.Equal("s2", model.CurrentState.ToString());
            machine.Trigger("t", model);
            Assert.Equal("s1", model.CurrentState.ToString());
        }
        public void FluentStateMachineBuilder_When_WhileDefTrans_AddsGuardToTransition()
        {
            var machine = FluentStateMachine<StubStateModel>.Describe()
                .State("s1")
                    .Initiates()
                    .TransitionsTo("s2").On("t").When(m => false)
                    .TransitionsTo("s3").On("t").When(m => true)
                .State("s2")
                .State("s3")
                .Compile();

            var model = new StubStateModel();
            model.CurrentState = machine.InitialState;

            Assert.Equal("s1", model.CurrentState.ToString());
            machine.Trigger("t", model);
            Assert.Equal("s3", model.CurrentState.ToString());
        }
Пример #41
0
        StateMachine_Trigger_ValidTriggerAndTrans_ChoosesFirstTranWthPassGuardNonGlobal_DiffAsCurrentState_Raised_Sets()
        {
            var model   = new StubStateModel();
            var machine = new StateMachine <StubStateModel>();

            var transitioningEventArgs = new List <TransitionEventArgs <StubStateModel> >();

            machine.Transitioning += (s, e) => { transitioningEventArgs.Add(e); };

            var transitionedEventArgs = new List <TransitionEventArgs <StubStateModel> >();

            machine.Transitioned += (s, e) => { transitionedEventArgs.Add(e); };

            var trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

            var state1Mock = new Mock <State <StubStateModel> >("s1");
            var state2Mock = new Mock <State <StubStateModel> >("s2");
            var state3Mock = new Mock <State <StubStateModel> >("s3");
            var state4Mock = new Mock <State <StubStateModel> >("s4");

            var state1 = state1Mock.Object;
            var state2 = state2Mock.Object;
            var state3 = state3Mock.Object;
            var state4 = state4Mock.Object;

            var statetrans1 = new Transition <StubStateModel>(trigger1, state1, state2, m => 1 == 2);
            var statetrans2 = new Transition <StubStateModel>(trigger1, state2, state3, m => 1 == 1);
            var statetrans3 = new Transition <StubStateModel>(trigger2, state1, state3);

            var globaltrans1 = new Transition <StubStateModel>(trigger1, null, state2, m => 1 == 1);

            machine.AddGlobalTransition(globaltrans1);
            state1.AddTransition(statetrans1);
            state1.AddTransition(statetrans2);
            state1.AddTransition(statetrans3);

            model.CurrentState = state1;

            // so when trigger 1 is triggered on state model whose current state is state1,
            // it will fall through to the first maching transition with a passing guard, the second state transition to state 2
            // it will then transition to state2.

            // make sure that transition events are called for moving from state 1 to state 2
            state1Mock.Setup(s => s.RaiseExiting(model, state2, trigger1)).Verifiable();
            state2Mock.Setup(s => s.RaiseEntered(model, state1, trigger1)).Verifiable();

            machine.Trigger(trigger1, model);

            // verify that no transition events were called that shouldn't have been
            state1Mock.Verify(s =>
                              s.RaiseEntered(
                                  It.IsAny <StubStateModel>(),
                                  It.IsAny <State <StubStateModel> >(),
                                  It.IsAny <Trigger>()), Times.Never());
            state2Mock.Verify(s =>
                              s.RaiseExiting(
                                  It.IsAny <StubStateModel>(),
                                  It.IsAny <State <StubStateModel> >(),
                                  It.IsAny <Trigger>()), Times.Never());
            Assert.Equal(1, transitioningEventArgs.Count);
            Assert.Equal(1, transitionedEventArgs.Count);

            Assert.Equal(state1, transitioningEventArgs[0].From);
            Assert.Equal(state2, transitioningEventArgs[0].To);
            Assert.Equal(trigger1, transitioningEventArgs[0].Trigger);
            Assert.Equal(model, transitioningEventArgs[0].Model);
            Assert.Equal(state1, transitionedEventArgs[0].From);
            Assert.Equal(state2, transitionedEventArgs[0].To);
            Assert.Equal(trigger1, transitionedEventArgs[0].Trigger);
            Assert.Equal(model, transitionedEventArgs[0].Model);
            Assert.Equal(state2, model.CurrentState);
        }
Пример #42
0
        public void StateMachine_AvailableTriggers_ConcatsModelsTransWithGlobal_ReturnsDistinctTrigsByName()
        {
            var model = new StubStateModel();
            var machine = new StateMachine<StubStateModel>();

            var trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

            var state1 = new State<StubStateModel>("s1");
            var state2 = new State<StubStateModel>("s2");
            var state3 = new State<StubStateModel>("s3");
            var state4 = new State<StubStateModel>("s4");

            var statetrans1 = new Transition<StubStateModel>(trigger1, state1, state2);
            var statetrans2 = new Transition<StubStateModel>(trigger1, state1, state3);
            var statetrans3 = new Transition<StubStateModel>(trigger2, state1, state3);

            var globaltrans1 = new Transition<StubStateModel>(trigger2, null, state1);

            machine.AddGlobalTransition(globaltrans1);
            state1.AddTransition(statetrans1);
            state1.AddTransition(statetrans2);
            state1.AddTransition(statetrans3);

            model.CurrentState = state1;

            var result = machine.AvailableTriggers(model);

            Assert.Equal(2, result.Count());
            Assert.Equal(trigger1, result.ToList()[0]);
            Assert.Equal(trigger2, result.ToList()[1]);
        }
Пример #43
0
        public void IStateModelExtensions_Trigger_NullTrigger_ThrowsNullEx()
        {
            var mockModel = new StubStateModel();
            var mockMachine = new Mock<IStateMachine<StubStateModel>>();

            Assert.Throws<ArgumentNullException>(() =>
                IStateModelExtensions.Trigger(mockModel, (Trigger)null, mockMachine.Object));
        }
Пример #44
0
        public void IStateModelExtensions_Trigger_NullMachine_StringTrigger_ThrowsNullEx()
        {
            var mockModel = new StubStateModel();

            Assert.Throws<ArgumentNullException>(() =>
                IStateModelExtensions.Trigger(mockModel, "triggerName", (IStateMachine<StubStateModel>)null));
        }
Пример #45
0
 public void IStateModelExtensions_Trigger_NullMachine_ObjTrigger_ThrowsNullEx()
 {
     var mockModel = new StubStateModel();
     var trigger = new Trigger("trigger");
     Assert.Throws<ArgumentNullException>(() =>
         IStateModelExtensions.Trigger(mockModel, trigger, (IStateMachine<StubStateModel>)null));
 }
        public void FluentStateMachineBuilder_DefiningCallbacksOnAll_AllCallbacksCalledInOrder()
        {
            var loggedEvents = new List<string>();
            Action<string, TransitionEventArgs<StubStateModel>> logEvent = (message, e) =>
            {
                loggedEvents.Add(String.Format("{0} from {1} to {2} on {3}",
                        message, e.From, e.To, e.Trigger));
            };

            var machine = FluentStateMachine<StubStateModel>.Describe()
                .State("s1")
                    .BeforeEntry(e => logEvent("beforeEntry", e))
                    .AfterEntry(e => logEvent("afterEntry", e))
                    .BeforeExit(e => logEvent("beforeExit", e))
                    .AfterExit(e => logEvent("afterExit", e))
                    .TransitionsTo("s2").On("t")
                    .Initiates()
                .State("s2")
                    .BeforeEntry(e => logEvent("beforeEntry", e))
                    .AfterEntry(e => logEvent("afterEntry", e))
                    .BeforeExit(e => logEvent("beforeExit", e))
                    .AfterExit(e => logEvent("afterExit", e))
                    .TransitionsTo("s1").On("t")
                .BeforeTransition(e => logEvent("beforeTransition", e))
                .AfterTransition(e => logEvent("afterTransition", e))
                .Compile();

            var model = new StubStateModel();
            model.CurrentState = machine.InitialState;

            machine.Trigger("t", model);
            Assert.Equal("s2", model.CurrentState.ToString());
            Assert.Equal(6, loggedEvents.Count());
            Assert.Equal("beforeTransition from s1 to s2 on t", loggedEvents[0]);
            Assert.Equal("beforeExit from s1 to s2 on t", loggedEvents[1]);
            Assert.Equal("beforeEntry from s1 to s2 on t", loggedEvents[2]);
            Assert.Equal("afterExit from s1 to s2 on t", loggedEvents[3]);
            Assert.Equal("afterEntry from s1 to s2 on t", loggedEvents[4]);
            Assert.Equal("afterTransition from s1 to s2 on t", loggedEvents[5]);
        }
Пример #47
0
        public void StateMachine_Trigger_NoStateOrGlobalTransOnTrigger_ConfigRaiseOnNoTransTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoTransition = true };
            var machine = new StateMachine<StubStateModel>(config);
            var model = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var trigger2 = new Trigger("trigger2");
            var state1 = new State<StubStateModel>("state1");
            var state2 = new State<StubStateModel>("state2");
            state1.AddTransition(trigger1, state2);
            model.CurrentState = state1;

            // set up so that current state of state 1 doesn't' define a trans for "trigger2", only "trigger1"

            Assert.Throws<InvalidTriggerException>(() =>
                machine.Trigger(trigger2, model));
        }
Пример #48
0
        public void StateMachine_Trigger_ModelStateNotState_ThrowsInvalidStateModel()
        {
            var machine = new StateMachine<StubStateModel>();
            var model = new StubStateModel();
            var trigger = new Trigger("trigger");

            Assert.Throws<InvalidStateModelException>(() =>
                machine.Trigger(trigger, model));
        }
Пример #49
0
        public void StateMachine_Trigger_NoStateOrGlobalTransOnTrigger_ConfigRaiseOnNoTransFalse_NotThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoTransition = false };
            var machine = new StateMachine<StubStateModel>(config);
            var model = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var trigger2 = new Trigger("trigger2");
            var state1 = new State<StubStateModel>("state1");
            var state2 = new State<StubStateModel>("state2");
            state1.AddTransition(trigger1, state2);
            model.CurrentState = state1;

            // no exception shoudl happen, and that's good enough for us.
            machine.Trigger(trigger2, model);
        }
Пример #50
0
 public void IStateModelExtensions_Trigger_ValidParms_ObjTrigger_CallsTriggerOnMachine()
 {
     var mockModel = new StubStateModel();
     var trigger = new Trigger("trigger");
     var mockMachine = new Mock<IStateMachine<StubStateModel>>();
     mockMachine.Setup(m => m.Trigger(trigger, mockModel)).Verifiable();
     IStateModelExtensions.Trigger(mockModel, trigger, mockMachine.Object);
     mockMachine.VerifyAll();
 }
Пример #51
0
        public void StateMachine_Trigger_TransitionsToSameState_ConfigRaiseOnSameStateTranTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration { RaiseExceptionBeforeTransitionToSameState = true };
            var machine = new StateMachine<StubStateModel>(config);
            var model = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1 = new State<StubStateModel>("state1");
            var state2 = new State<StubStateModel>("state2");
            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            Assert.Throws<InvalidTriggerException>(() =>
                machine.Trigger(trigger1, model));
        }
Пример #52
0
 public void StateMachine_AvailableTriggers_ModelStateNotState_ThrowInvalidStateModel()
 {
     var model = new StubStateModel();
     var machine = new StateMachine<StubStateModel>();
     Assert.Throws<InvalidStateModelException>(() =>
         machine.AvailableTriggers(model));
 }
Пример #53
0
        public void IStateModelExtensions_Trigger_ValidParms_StringTrigger_CallsTriggerOnMachine()
        {
            var mockModel = new StubStateModel();
            var mockMachine = new Mock<IStateMachine<StubStateModel>>();
            mockMachine.Setup(m => m.Trigger(It.Is<Trigger>(t => t.Name == "triggerName"), mockModel)).Verifiable();

            IStateModelExtensions.Trigger(mockModel, "triggerName", mockMachine.Object);

            mockMachine.VerifyAll();
        }
Пример #54
0
        public void StateMachine_Trigger_TransitionFromCurrentToSame_ConfiggedNotToRaiseExcep_DoesNotRaiseTransitionChangeEvents()
        {
            var config = new StateMachineConfiguration { RaiseExceptionBeforeTransitionToSameState = false };
            var machine = new StateMachine<StubStateModel>(config);
            var model = new StubStateModel();
            var trigger1 = new Trigger("trigger1");

            var state1 = new State<StubStateModel>("state1");
            TransitionEventArgs<StubStateModel> transitioningArgs = null;
            state1.Entered += (s, e) => { transitioningArgs = e; };
            TransitionEventArgs<StubStateModel> transitionedArgs = null;
            state1.Exiting += (s, e) => { transitionedArgs = e; };

            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            // should not throw exception and that's good enough for us
            machine.Trigger(trigger1, model);

            // verify that no transition events occurred
            Assert.Null(transitioningArgs);
            Assert.Null(transitionedArgs);
        }
        public void FluentStateMachineBuilder_State_ValidParms_CreatesNewState()
        {
            var machine = FluentStateMachine<StubStateModel>.Describe()
                .State("s1")
                .Initiates()
                .Compile();

            var model = new StubStateModel();
            model.CurrentState = machine.InitialState;

            Assert.Equal("s1", model.CurrentState.ToString());
        }
Пример #56
0
        public void TransitionEventArgs_ValidParms_VerifyAssigns()
        {
            var model = new StubStateModel();
            var from = new State<StubStateModel>("from");
            var to = new State<StubStateModel>("to");
            var trigger = new Trigger("trigger");
            var args = new TransitionEventArgs<StubStateModel>(model, from, to, trigger);

            Assert.Same(from, args.From);
            Assert.Same(to, args.To);
            Assert.Same(model, args.Model);
            Assert.Same(trigger, args.Trigger);
        }
Пример #57
0
        public void State_RaiseExiting_ValidParms_Handler_TriggersHandlerPassesParmsAndSelf()
        {
            var model = new StubStateModel();
            var fromState = new State<StubStateModel>("from");
            var toState = new State<StubStateModel>("to");
            var trigger = new Trigger("trigger");

            TransitionEventArgs<StubStateModel> args = null;
            fromState.Exiting += (s, e) =>
            {
                args = e;
            };

            fromState.RaiseExiting(model, toState, trigger);

            Assert.Equal(model, args.Model);
            Assert.Equal(fromState, args.From);
            Assert.Equal(toState, args.To);
            Assert.Equal(trigger, args.Trigger);
        }