Example #1
0
        public void StateMachine_AddGlobalTransition_TwoTransitionsWithSameTriggerFromToNoGuard_ThrowsDuplicateTransitionException()
        {
            var machine = new StateMachine<StubStateModel>();
            var state2 = new State<StubStateModel>("s2");
            var trigger1 = new Trigger("t1");
            var transition1 = new Transition<StubStateModel>(trigger1, null, state2);
            var transition2 = new Transition<StubStateModel>(trigger1, null, state2);

            machine.AddGlobalTransition(transition1);
            Assert.Throws<InvalidTransitionException>(() =>
                machine.AddGlobalTransition(transition2));
        }
Example #2
0
        StateMachine_AddGlobalTransition_TwoTransitionsWithSameTriggerFromToNoGuard_ThrowsDuplicateTransitionException()
        {
            var machine     = new StateMachine <StubStateModel>();
            var state2      = new State <StubStateModel>("s2");
            var trigger1    = new Trigger("t1");
            var transition1 = new Transition <StubStateModel>(trigger1, null, state2);
            var transition2 = new Transition <StubStateModel>(trigger1, null, state2);

            machine.AddGlobalTransition(transition1);
            Assert.Throws <InvalidTransitionException>(() =>
                                                       machine.AddGlobalTransition(transition2));
        }
Example #3
0
        public void StateMachine_AddGlobalTransition_TwoValidTranDiffTriggers_ReturnsOneForEachTransitionsOn()
        {
            var machine     = new StateMachine <StubStateModel>();
            var state2      = new State <StubStateModel>("s2");
            var state3      = new State <StubStateModel>("s2");
            var trigger1    = new Trigger("t1");
            var trigger2    = new Trigger("t2");
            var transition1 = new Transition <StubStateModel>(trigger1, null, state2, m => 1 == 2);
            var transition2 = new Transition <StubStateModel>(trigger2, null, state3, m => 1 == 1);

            machine.AddGlobalTransition(transition1);
            machine.AddGlobalTransition(transition2);

            Assert.Same(transition1, machine.GlobalTransitionsOn(trigger1).FirstOrDefault());
            Assert.Same(transition2, machine.GlobalTransitionsOn(trigger2).FirstOrDefault());
        }
Example #4
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]);
        }
Example #5
0
        public void StateMachine_AddGlobalTransition_TwoValidTranSameTrigger_ReturnsBothWithTransitionsOn()
        {
            var machine     = new StateMachine <StubStateModel>();
            var state2      = new State <StubStateModel>("s2");
            var state3      = new State <StubStateModel>("s2");
            var trigger1    = new Trigger("t1");
            var transition1 = new Transition <StubStateModel>(trigger1, null, state2, m => 1 == 2);
            var transition2 = new Transition <StubStateModel>(trigger1, null, state3, m => 1 == 1);

            machine.AddGlobalTransition(transition1);
            machine.AddGlobalTransition(transition2);

            var trans = machine.GlobalTransitionsOn(trigger1).ToList();

            Assert.Equal(transition1, trans[0]);
            Assert.Equal(transition2, trans[1]);
        }
Example #6
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);
        }
Example #7
0
        public void StateMachine_GlobalTransitionsOn_TriggerMatchingTwoTransitionsNotAnother_ReturnsTwoMatching()
        {
            var machine     = new StateMachine <StubStateModel>();
            var state2      = new State <StubStateModel>("s2");
            var state3      = new State <StubStateModel>("s2");
            var trigger1    = new Trigger("t1");
            var transition1 = new Transition <StubStateModel>(trigger1, null, state2, m => 1 == 2);
            var transition2 = new Transition <StubStateModel>(trigger1, null, state3, m => 1 == 1);

            machine.AddGlobalTransition(transition1);
            machine.AddGlobalTransition(transition2);

            var result = machine.GlobalTransitionsOn(new Trigger("t1"));

            Assert.NotNull(result);
            Assert.Equal(2, result.Count());
            Assert.Same(transition1, result.ToList()[0]);
            Assert.Same(transition2, result.ToList()[1]);
        }
Example #8
0
        public void StateMachine_AddGlobalTransition_SourceNonNull_ThrowsInvalidTransEx()
        {
            var machine     = new StateMachine <StubStateModel>();
            var state1      = new State <StubStateModel>("s1");
            var state2      = new State <StubStateModel>("s2");
            var trigger1    = new Trigger("t1");
            var transition1 = new Transition <StubStateModel>(trigger1, state1, state2);

            Assert.Throws <InvalidTransitionException>(() =>
                                                       machine.AddGlobalTransition(transition1));
        }
Example #9
0
        public void StateMachine_AddGlobalTransition_ValidTran_ReturnsWithTransitionsOnTrigger()
        {
            var machine     = new StateMachine <StubStateModel>();
            var state2      = new State <StubStateModel>("s2");
            var trigger1    = new Trigger("t1");
            var transition1 = new Transition <StubStateModel>(trigger1, null, state2);

            machine.AddGlobalTransition(transition1);

            Assert.Same(transition1, machine.GlobalTransitionsOn(trigger1).FirstOrDefault());
        }
Example #10
0
        public void StateMachine_AddGlobalTransition_SourceNonNull_ThrowsInvalidTransEx()
        {
            var machine = new StateMachine<StubStateModel>();
            var state1 = new State<StubStateModel>("s1");
            var state2 = new State<StubStateModel>("s2");
            var trigger1 = new Trigger("t1");
            var transition1 = new Transition<StubStateModel>(trigger1, state1, state2);

            Assert.Throws<InvalidTransitionException>(() =>
                machine.AddGlobalTransition(transition1));
        }
Example #11
0
        public void StateMachine_GlobalTransitionsOn_TriggerMatchingOneTransitionNotAnother_ReturnsOnlyMatchingONe()
        {
            var machine     = new StateMachine <StubStateModel>();
            var state2      = new State <StubStateModel>("s2");
            var trigger1    = new Trigger("t1");
            var transition1 = new Transition <StubStateModel>(trigger1, null, state2, m => 1 == 2);

            machine.AddGlobalTransition(transition1);

            var result = machine.GlobalTransitionsOn(new Trigger("t1"));

            Assert.NotNull(result);
            Assert.Equal(1, result.Count());
            Assert.Same(transition1, result.FirstOrDefault());
        }
Example #12
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);
        }
Example #13
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]);
        }
Example #14
0
        public void StateMachine_AddGlobalTransition_TwoValidTranSameTrigger_ReturnsBothWithTransitionsOn()
        {
            var machine = new StateMachine<StubStateModel>();
            var state2 = new State<StubStateModel>("s2");
            var state3 = new State<StubStateModel>("s2");
            var trigger1 = new Trigger("t1");
            var transition1 = new Transition<StubStateModel>(trigger1, null, state2, m => 1 == 2);
            var transition2 = new Transition<StubStateModel>(trigger1, null, state3, m => 1 == 1);

            machine.AddGlobalTransition(transition1);
            machine.AddGlobalTransition(transition2);

            var trans = machine.GlobalTransitionsOn(trigger1).ToList();
            Assert.Equal(transition1, trans[0]);
            Assert.Equal(transition2, trans[1]);
        }
Example #15
0
        public void StateMachine_AddGlobalTransition_TwoValidTranDiffTriggers_ReturnsOneForEachTransitionsOn()
        {
            var machine = new StateMachine<StubStateModel>();
            var state2 = new State<StubStateModel>("s2");
            var state3 = new State<StubStateModel>("s2");
            var trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");
            var transition1 = new Transition<StubStateModel>(trigger1, null, state2, m => 1 == 2);
            var transition2 = new Transition<StubStateModel>(trigger2, null, state3, m => 1 == 1);

            machine.AddGlobalTransition(transition1);
            machine.AddGlobalTransition(transition2);

            Assert.Same(transition1, machine.GlobalTransitionsOn(trigger1).FirstOrDefault());
            Assert.Same(transition2, machine.GlobalTransitionsOn(trigger2).FirstOrDefault());
        }
Example #16
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);
        }
Example #17
0
        public void StateMachine_GlobalTransitionsOn_TriggerMatchingOneTransitionNotAnother_ReturnsOnlyMatchingONe()
        {
            var machine = new StateMachine<StubStateModel>();
            var state2 = new State<StubStateModel>("s2");
            var trigger1 = new Trigger("t1");
            var transition1 = new Transition<StubStateModel>(trigger1, null, state2, m => 1 == 2);

            machine.AddGlobalTransition(transition1);

            var result = machine.GlobalTransitionsOn(new Trigger("t1"));
            Assert.NotNull(result);
            Assert.Equal(1, result.Count());
            Assert.Same(transition1, result.FirstOrDefault());
        }
Example #18
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);
        }
Example #19
0
        public void StateMachine_AddGlobalTransition_ValidTran_ReturnsWithTransitionsOnTrigger()
        {
            var machine = new StateMachine<StubStateModel>();
            var state2 = new State<StubStateModel>("s2");
            var trigger1 = new Trigger("t1");
            var transition1 = new Transition<StubStateModel>(trigger1, null, state2);

            machine.AddGlobalTransition(transition1);

            Assert.Same(transition1, machine.GlobalTransitionsOn(trigger1).FirstOrDefault());
        }
Example #20
0
        public void StateMachine_GlobalTransitionsOn_TriggerMatchingTwoTransitionsNotAnother_ReturnsTwoMatching()
        {
            var machine = new StateMachine<StubStateModel>();
            var state2 = new State<StubStateModel>("s2");
            var state3 = new State<StubStateModel>("s2");
            var trigger1 = new Trigger("t1");
            var transition1 = new Transition<StubStateModel>(trigger1, null, state2, m => 1 == 2);
            var transition2 = new Transition<StubStateModel>(trigger1, null, state3, m => 1 == 1);

            machine.AddGlobalTransition(transition1);
            machine.AddGlobalTransition(transition2);

            var result = machine.GlobalTransitionsOn(new Trigger("t1"));
            Assert.NotNull(result);
            Assert.Equal(2, result.Count());
            Assert.Same(transition1, result.ToList()[0]);
            Assert.Same(transition2, result.ToList()[1]);
        }