Represents a possible trigger that can cause a transition, on any number of State instances or types.
Example #1
0
 public void StateExtensions_AddTransition_NullState_ThrowsNullex()
 {
     var trigger = new Trigger("trigger");
     var toState = new State<StubStateModel>("to");
     Assert.Throws<ArgumentNullException>(() =>
         StateExtensions.AddTransition((State<StubStateModel>)null, trigger, toState));
 }
Example #2
0
 public void StateExtensions_AddTransition_NullTo_ThrowsNullex()
 {
     var fromState = new State<StubStateModel>("from");
     var trigger = new Trigger("trigger");
     Assert.Throws<ArgumentNullException>(() =>
         StateExtensions.AddTransition(fromState, trigger, (State<StubStateModel>)null));
 }
Example #3
0
 public void StateExtensions_AddTransition_NullState_WithGuard_ThrowsNullex()
 {
     var trigger = new Trigger("trigger");
     var toState = new State<StubStateModel>("to");
     Func<StubStateModel, bool> guard = s => true;
     Assert.Throws<ArgumentNullException>(() =>
         StateExtensions.AddTransition((State<StubStateModel>)null, trigger, toState, guard));
 }
Example #4
0
 public void StateExtensions_AddTransition_NullGuard_ThrowsNullex()
 {
     var fromState = new State<StubStateModel>("from");
     var trigger = new Trigger("trigger");
     var toState = new State<StubStateModel>("to");
     Func<StubStateModel, bool> guard = null;
     Assert.Throws<ArgumentNullException>(() =>
         StateExtensions.AddTransition(fromState, trigger, (State<StubStateModel>)null, guard));
 }
 public void StateExtensions_AddTransition_NullGuard_ThrowsNullex()
 {
     var machine = new Mock<IStateMachine<StubStateModel>>().Object;
     var trigger = new Trigger("trigger");
     var toState = new State<StubStateModel>("to");
     Func<StubStateModel, bool> guard = null;
     Assert.Throws<ArgumentNullException>(() =>
         IStateMachineExtensions.AddGlobalTransition(machine, trigger, (State<StubStateModel>)null, guard));
 }
Example #6
0
        public void State_Addtransition_SourceDifferentThanState_ThrowsInvalidTransEx()
        {
            var state1 = new State<StubStateModel>("s1");
            var state2 = new State<StubStateModel>("s2");
            var trigger1 = new Trigger("t1");
            var transition1 = new Transition<StubStateModel>(trigger1, state2, state1);

            Assert.Throws<InvalidTransitionException>(() =>
                state1.AddTransition(transition1));
        }
Example #7
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 #8
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 #9
0
        public void State_AddTransition_TwoTransitionsWithSameTriggerFromToNoGuard_ThrowsDuplicateTransitionException()
        {
            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);
            var transition2 = new Transition<StubStateModel>(trigger1, state1, state2);

            state1.AddTransition(transition1);
            Assert.Throws<InvalidTransitionException>(() =>
                state1.AddTransition(transition2));
        }
Example #10
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());
        }
        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);
        }
Example #12
0
 public void Trigger_ToString_VerifySameAsName()
 {
     var name = "trigger";
     var trigger = new Trigger(name);
     Assert.Equal(name, trigger.ToString());
 }
Example #13
0
 public void Trigger_Name_VerifyAssign()
 {
     var name = "trigger";
     var trigger = new Trigger(name);
     Assert.Equal(name, trigger.Name);
 }
Example #14
0
 public void Trigger_GetHashCode_VerifySameAsNameHash()
 {
     var name = "trigger";
     var trigger = new Trigger(name);
     Assert.Equal(name.GetHashCode(), trigger.GetHashCode());
 }
Example #15
0
 public void Trigger_Equals_TwoInstances_SameName_ReturnTrue()
 {
     var trigger1 = new Trigger("trigger");
     var trigger2 = new Trigger("trigger");
     Assert.True(trigger1.Equals(trigger2));
 }
Example #16
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));
        }
Example #17
0
        public void Transition_ValidParms_GuardReturnsTrue()
        {
            var trigger = new Trigger("trigger");
            var from = new State<StubStateModel>("from");
            var to = new State<StubStateModel>("to");

            var transition = new Transition<StubStateModel>(trigger, from, to);

            Assert.True(transition.Guard(new StubStateModel()));
        }
        public void FluentStateMachine_InitialState_SameValueAsConstructor()
        {
            var machine = new StateMachine<StubStateModel>();
            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 trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

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

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

            Assert.Same(state2, fluentMachine.InitialState);
        }
        public void FluentStateMachine_GlobalTransition_AddsEachOneToMachine()
        {
            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 trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

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

            // create some global trans
            var transition1 = new Transition<StubStateModel>(trigger1, null, state2);
            var transition2 = new Transition<StubStateModel>(trigger2, null, state3);
            // put them in an ienum
            var transitions = new List<Transition<StubStateModel>>();
            transitions.Add(transition1);
            transitions.Add(transition2);

            // set up verifications for items being added to machine mock
            var globalTransitionsAdded = new List<Transition<StubStateModel>>();
            machineMock.Setup(s => s.AddGlobalTransition(It.IsAny<Transition<StubStateModel>>()))
                .Callback<Transition<StubStateModel>>(t => globalTransitionsAdded.Add(t));

            // create a fluent machine, and validate each was added to machine

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

            Assert.Equal(2, globalTransitionsAdded.Count);
            Assert.Equal(transition1, globalTransitionsAdded[0]);
            Assert.Equal(transition2, globalTransitionsAdded[1]);
        }
Example #20
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 #21
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 #22
0
 public void StateExtensions_AddTransition_ValidParms_WithGuard_CallsAddOnFromState()
 {
     var fromStateMock = new Mock<State<StubStateModel>>("from");
     var trigger = new Trigger("trigger");
     var toState = new State<StubStateModel>("to");
     Func<StubStateModel, bool> guard = s => true;
     fromStateMock.Setup(s => s.AddTransition(It.Is<Transition<StubStateModel>>(
         t => t.Source.Name == "from" && t.Target.Name == "to" && t.Trigger.Name == "trigger" && t.Guard == guard))).Verifiable();
     StateExtensions.AddTransition(fromStateMock.Object, trigger, toState, guard);
     fromStateMock.VerifyAll();
 }
Example #23
0
        public void StateMachine_Trigger_ValidlyTransitions_RaisesAllEventsInCorrectOrder()
        {
            var calls = new List<string>();
            var model = new TrackableStateModel();
            var state1 = new State<TrackableStateModel>("s1");
            var state2 = new State<TrackableStateModel>("s2");
            var trigger = new Trigger("t1");
            var transition = new Transition<TrackableStateModel>(trigger, state1, state2);
            state1.AddTransition(transition);
            model.CurrentState = state1;

            var stateMachine = new StateMachine<TrackableStateModel>();

            Action<object, TransitionEventArgs<TrackableStateModel>> entering = (s, e) => calls.Add(String.Format("entering {0} from {1} on {2}", e.To, e.From, e.Trigger));
            Action<object, TransitionEventArgs<TrackableStateModel>> entered = (s, e) => calls.Add(String.Format("entered {0} from {1} on {2}", e.To, e.From, e.Trigger));
            Action<object, TransitionEventArgs<TrackableStateModel>> exiting = (s, e) => calls.Add(String.Format("exiting {0} to {1} on {2}", e.From, e.To, e.Trigger));
            Action<object, TransitionEventArgs<TrackableStateModel>> exited = (s, e) => calls.Add(String.Format("exited {0} to {1} on {2}", e.From, e.To, e.Trigger));

            model.Setting += (s, e) => calls.Add("setting new current state on model");

            state1.Entering += (s, e) => entering(s, e);
            state1.Entered += (s, e) => entered(s, e);
            state1.Exiting += (s, e) => exiting(s, e);
            state1.Exited += (s, e) => exited(s, e);

            state2.Entering += (s, e) => entering(s, e);
            state2.Entered += (s, e) => entered(s, e);
            state2.Exiting += (s, e) => exiting(s, e);
            state2.Exited += (s, e) => exited(s, e);

            stateMachine.Transitioning += (s, e) => calls.Add(String.Format("transitioning from {0} to {1} on {2}", e.From, e.To, e.Trigger));
            stateMachine.Transitioned += (s, e) => calls.Add(String.Format("transitioned from {0} to {1} on {2}", e.From, e.To, e.Trigger));

            stateMachine.Trigger(trigger, model);

            Assert.Equal(7, calls.Count);
            Assert.Equal("transitioning from s1 to s2 on t1", calls[0]);
            Assert.Equal("exiting s1 to s2 on t1", calls[1]);
            Assert.Equal("entering s2 from s1 on t1", calls[2]);
            Assert.Equal("setting new current state on model", calls[3]);
            Assert.Equal("exited s1 to s2 on t1", calls[4]);
            Assert.Equal("entered s2 from s1 on t1", calls[5]);
            Assert.Equal("transitioned from s1 to s2 on t1", calls[6]);
        }
 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();
 }
        public void FluentStateMachine_GlobalTransitioneds_AddsEachOneToMachine()
        {
            var machine = new StateMachine<StubStateModel>();
            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 trigger1 = new Trigger("t1");
            var trigger2 = new Trigger("t2");

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

            // transition arg
            var arg = new TransitionEventArgs<StubStateModel>(new StubStateModel(),
                state1, state2, trigger1);

            // create some global transitionings
            Action<TransitionEventArgs<StubStateModel>> callback1 = e => { };
            Action<TransitionEventArgs<StubStateModel>> callback2 = e => { };
            Action<TransitionEventArgs<StubStateModel>> callback3 = e => { };

            // put them in an ienum
            var callbacks = new List<Action<TransitionEventArgs<StubStateModel>>>();
            callbacks.Add(callback1);
            callbacks.Add(callback2);
            callbacks.Add(callback3);

            // create a fluent machine, and validate each was added to machine
            //machineMock.Raise(m => m.Transitioning += null, arg);
            //machineMock.SetupAllProperties();

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

            //machineMock.VerifyAll();
        }
Example #26
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 #27
0
        public void Transition_ValidParms_AppliesAllParamToProps()
        {
            var trigger = new Trigger("trigger");
            var from = new State<StubStateModel>("from");
            var to = new State<StubStateModel>("to");

            var transition = new Transition<StubStateModel>(trigger, from, to);

            Assert.Same(trigger, transition.Trigger);
            Assert.Same(from, transition.Source);
            Assert.Same(to, transition.Target);
        }
 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));
 }
Example #29
0
        public void Transition_ValidParms_WithGuard_AppliesAllParamToProps()
        {
            var trigger = new Trigger("trigger");
            var from = new State<StubStateModel>("from");
            var to = new State<StubStateModel>("to");
            Func<StubStateModel, bool> guard = s => true;

            var transition = new Transition<StubStateModel>(trigger, from, to, guard);

            Assert.Same(trigger, transition.Trigger);
            Assert.Same(from, transition.Source);
            Assert.Same(to, transition.Target);
            Assert.Same(guard, transition.Guard);
        }
        public void IStateModelExtensions_Trigger_NullModel_ObjTrigger_ThrowsNullEx()
        {
            var mockMachine = new Mock<IStateMachine<StubStateModel>>();
            var trigger = new Trigger("trigger");

            Assert.Throws<ArgumentNullException>(() =>
                IStateModelExtensions.Trigger(null, trigger, mockMachine.Object));
        }