Esempio n. 1
0
        public void Main()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region("Stopped", false);
            t.State("Stopped");
            t.Transition("T1", "Running", "Play");
            t.EndState();
            t.State("Loaded", StartMotor, StopMotor);
            t.Transition("T2", "Stopped", "Stop");
            t.Region("Running", false);
            t.State("Running", EngageHead, ReleaseHead);
            t.Transition("T3", "Paused", "Pause");
            t.EndState();
            t.State("Paused");
            t.Transition("T4", "Running", "Play");
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();

            StateMachine stateMachine = t.CreateStateMachine();

            stateMachine.Startup();
            stateMachine.SendTriggerEvent("Play");
            stateMachine.SendTriggerEvent("Pause");
            stateMachine.SendTriggerEvent("Stop");
            stateMachine.Finish();
        }
Esempio n. 2
0
        public void Finish_WithTransitionInExitAction_NotExecuted()
        {
            const string StateA   = "StateA";
            const string StateA1A = "StateA1A";
            const string Transi1  = "Transi1";

            const string Event1             = "Event1";
            bool         transitionExecuted = false;

            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(StateA, false);
            t.State(StateA, null, (s, ev, args) => s.SendTriggerEvent(Event1));
            t.Region(StateA1A, false);
            t.State(StateA1A);
            t.Transition(Transi1, new string[] { StateA1A }, new string[] { StateA1A }, Event1, null, (s, ev, args) => transitionExecuted = true);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();

            Assert.That(t.StateConfigurationMax, Is.EqualTo(2), "StateConfigurationMax wrong");
            Assert.That(t.ConcurrencyDegree, Is.EqualTo(1), "ConcurrencyDegree wrong");

            StateMachine stateMachine = t.CreateStateMachine(this);

            stateMachine.Startup();
            stateMachine.Finish();

            StateConfiguration nirvana = t.CreateStateConfiguration(new string[] { });

            Assert.That(stateMachine.ActiveStateConfiguration.ToString(), Is.EqualTo(nirvana.ToString()), "Active state not as expected.");

            Assert.That(transitionExecuted, Is.EqualTo(false), "Unintended transition during finish executed.");
        }
Esempio n. 3
0
        private void InitStateMachine()
        {
            this.introTimeout          = new DispatcherTimer();
            this.introTimeout.Interval = new TimeSpan(0, 0, 30);
            this.introTimeout.Tick    += new EventHandler(IntroTimeout_Tick);

            this.processTimeout          = new DispatcherTimer();
            this.processTimeout.Interval = new TimeSpan(0, 0, 15);
            this.processTimeout.Tick    += new EventHandler(ProcessTimeout_Tick);

            this.deliverTimeout          = new DispatcherTimer();
            this.deliverTimeout.Interval = new TimeSpan(0, 0, 5);
            this.deliverTimeout.Tick    += new EventHandler(DeliverTimeout_Tick);

            StateMachineTemplate t = new StateMachineTemplate();

            //## Begin StateMachineTemplate
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "TicketVendingNETMF"
            // at 07-22-2015 22:02:47 using StaMaShapes Version 2300
            t.Region(Intro, false);
            t.State(Intro, EnterIntro, ExitIntro);
            t.Transition("IntroAck", Idle, ButtonSelect, null, null);
            t.Transition("IntroTimeout", Idle, IntroTimeout, null, null);
            t.EndState();
            t.State(Idle, EnterIdle, ExitIdle);
            t.Transition("ProductSelected", Empty, ButtonSelect, null, null);
            t.EndState();
            t.State(ItemSelected, EnterItemSelected, ExitItemSelected);
            t.Region(Empty, false);
            t.State(Empty, EnterEmpty, ExitEmpty);
            t.Transition("ClientAbort1", Idle, ButtonCancel, null, null);
            t.Transition("CoinInserted1", CoinInserted, ButtonSelect, null, null);
            t.Transition("OperationTimeout1", Idle, ProcessTimeout, null, null);
            t.EndState();
            t.State(EmitRequired, null, ExitEmitRequired);
            t.Region(CoinInserted, false);
            t.State(CoinInserted, EnterCoinInserted, ExitCoinInserted);
            t.Transition("MakeDeal", CloseBargain, null, CheckBalance, null);
            t.Transition("CoinInserted2", CoinInserted, ButtonSelect, null, null);
            t.Transition("ClientAbort2", Delivering, ButtonCancel, null, null);
            t.Transition("OperationTimeout2", Delivering, ProcessTimeout, null, null);
            t.EndState();
            t.State(CloseBargain, EnterCloseBargain, null);
            t.Transition("Deliver", Delivering, null, null, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(Delivering, EnterDelivering, ExitDelivering);
            t.Transition("Delivered", Idle, DeliverTimeout, null, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            //## End StateMachineTemplate

            stateMachine = t.CreateStateMachine(this);
            stateMachine.TraceStateChange = this.TraceStateChange;

            stateMachine.Startup();
        }
        private void CompositeStateTransition_ToCompositeState_ExecutesActionsOrdered(string signalEvent, string[] expectedActions)
#endif
        {
            // Arrange
            ActionRecorder recorder = new ActionRecorder();

            StateMachineTemplate t = new StateMachineTemplate();

            t.Region("S1", false);
            t.State("S1", recorder.CreateAction("EnS1"), recorder.CreateAction("ExS1"));
            t.Transition("T1", "S1", "S2", "Ev1", null, null);
            t.Transition("T2", "S1", "S2A1", "Ev2", null, null);
            t.EndState();
            t.State("S2", recorder.CreateAction("EnS2"), recorder.CreateAction("ExS2"));
            t.Region("S2A2", false);
            t.State("S2A1", recorder.CreateAction("EnS2A1"), recorder.CreateAction("ExS2A1"));
            t.EndState();
            t.State("S2A2", recorder.CreateAction("EnS2A2"), recorder.CreateAction("ExS2A2"));
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            StateMachine stateMachine = t.CreateStateMachine();

            stateMachine.Startup();

            // Act
            stateMachine.SendTriggerEvent(signalEvent);

            // Assert
            Assert.That(recorder.RecordedActions, Is.EqualTo(expectedActions), "Unexpected action invocations");
        }
Esempio n. 5
0
        public void StateMachineTemplate_WithValidStructure_IsInitialized()
        {
            // Set up a typical tree without problems
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(State1, false);
            t.State(State1);
            t.Region(State1a1, false);
            t.State(State1a1);
            t.EndState();
            t.State(State1a2);
            t.Region(State1a2a1, false);
            t.State(State1a2a1);
            t.Transition(Transi3, new string[] { State1a2a1 }, new string[] { State1a2a2 }, 1, null, null);
            t.EndState();
            t.State(State1a2a2);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.Region(State1b1, false);
            t.State(State1b1);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(State2);
            t.EndState();
            t.EndRegion();

            Assert.That(t.Root, Is.Not.Null, "State machine template not complete.");
            Assert.That(t.StateConfigurationMax, Is.EqualTo(4), "StateConfigurationMax wrong");
            Assert.That(t.ConcurrencyDegree, Is.EqualTo(2), "ConcurrencyDegree wrong");
            Assert.That(t.HistoryMax, Is.EqualTo(0), "HistoryMax wrong");
        }
Esempio n. 6
0
        static StateConfigurationTests()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            //## Begin TestCreateStateConfiguration
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_StateConfigurationTests"
            // at 07-22-2015 22:05:06 using StaMaShapes Version 2300
            t.Region(StateA, false);
            t.State(StateA, null, null);
            t.Region(StateA1A, false);
            t.State(StateA1A, null, null);
            t.Region(StateA1A1A, false);
            t.State(StateA1A1A, null, null);
            t.EndState();
            t.State(StateA1A1B, null, null);
            t.EndState();
            t.EndRegion();
            t.Region(StateA1A2A, false);
            t.State(StateA1A2A, null, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(StateA1B, null, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(StateB, null, null);
            t.EndState();
            t.EndRegion();
            //## End TestCreateStateConfiguration

            m_stmTmplat = t;
        }
Esempio n. 7
0
        public void StateMachineTemplate_WithMissingCompositeState_Throws()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(State1, false);
            // t.State(State1) omitted.
            Assert.That(() => { t.Region(State2, false); }, Throws.TypeOf(typeof(StateMachineException)));
        }
Esempio n. 8
0
        public void SendTriggerEvent_WithExceptionThrowingExitAction_AllowsContinueAndExecutesExitActions()
        {
            const string StateA   = "StateA";
            const string StateA1A = "StateA1A";
            const string StateA1B = "StateA1B";
            const string StateB   = "StateB";

            const string Transi1 = "Transi1";
            const string Transi2 = "Transi2";

            const string Event1 = "Event1";
            const string EventGotoErrorState = "EventGotoErrorState";

            bool exceptionThrownOnce = false;

            ActionRecorder recorder = new ActionRecorder();

            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(StateA, false);
            t.State(StateA, null, recorder.CreateAction("ExitA"));
            t.Transition(Transi2, new string[] { StateA }, new string[] { StateB }, EventGotoErrorState, null, recorder.CreateAction("Transit2"));
            t.Region(StateA1A, false);
            t.State(StateA1A, null, (s, ev, args) => { if (!exceptionThrownOnce)
                                                       {
                                                           exceptionThrownOnce = true; throw new Exception();
                                                       }
                    });
            t.Transition(Transi1, new string[] { StateA1A }, new string[] { StateA1B }, Event1, null, recorder.CreateAction("Transit1"));
            t.EndState();
            t.State(StateA1B, recorder.CreateAction("EnterA1B"), recorder.CreateAction("ExitA1B"));
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(StateB, recorder.CreateAction("EnterB"), null);
            t.EndState();
            t.EndRegion();

            //StateMachine s = t.CreateStateMachine(this, InvokeActivityWrapper); // Just an idea.
            StateMachine stateMachine = t.CreateStateMachine();

            stateMachine.Startup();
            try
            {
                stateMachine.SendTriggerEvent(Event1);
            }
            catch (Exception)
            {
                stateMachine.SendTriggerEvent(EventGotoErrorState);
            }

            Assert.That(stateMachine.ActiveStateConfiguration.ToString(), Is.EqualTo(t.CreateStateConfiguration(new string[] { StateB }).ToString()), "Active state after error escape transition not as expected.");
            Assert.That(recorder.RecordedActions, Is.EqualTo(new String[] { "ExitA", "Transit2", "EnterB" }), "Unexpected sequence of actions during error escape transition.");
        }
Esempio n. 9
0
        public void StateMachineTemplate_WithDuplicateStateName_Throws()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(State1, false);
            t.State(State1);
            t.EndState();
            t.State(State2);
            t.Region(State2a1, false);
            t.State(State2a1);
            t.EndState();
            Assert.That(() => { t.State(State1); }, Throws.TypeOf(typeof(ArgumentOutOfRangeException)));
        }
Esempio n. 10
0
        public void StateMachineTemplate_WithTransitionSourceNotContainedInTransitionAnchor3_Throws()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            Exception thrownException = null;

            try
            {
                //## Begin BadTransiTargetsTest4
                // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_SyntaxCheckTests"
                // at 07-22-2015 22:05:03 using StaMaShapes Version 2300
                t.Region(State1, false);
                t.State(State1, null, null);
                t.Transition(Transi1, State2a1a1, State1, 1, null, null);
                t.Region(State1a1, false);
                t.State(State1a1, null, null);
                t.Region(State1a1a1, false);
                t.State(State1a1a1, null, null);
                t.EndState();
                t.State(State1a1a2, null, null);
                t.EndState();
                t.EndRegion();
                t.EndState();
                t.State(State1a2, null, null);
                t.EndState();
                t.EndRegion();
                t.EndState();
                t.State(State2, null, null);
                t.Region(State2a1, false);
                t.State(State2a1, null, null);
                t.Region(State2a1a1, false);
                t.State(State2a1a1, null, null);
                t.EndState();
                t.State(State2a1a2, null, null);
                t.EndState();
                t.EndRegion();
                t.EndState();
                t.State(State2a2, null, null);
                t.EndState();
                t.EndRegion();
                t.EndState();
                t.EndRegion();
                //## End BadTransiTargetsTest4
            }
            catch (Exception ex)
            {
                thrownException = ex;
            }
            Assert.That(thrownException, Is.Not.Null);
            Assert.That(thrownException.GetType(), Is.EqualTo(typeof(StateMachineException)));
        }
Esempio n. 11
0
        public void StateMachineTemplate_WithOpenRegion_IsNotInitialized()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(State1, false);

            Assert.That(t.Root, Is.Null, "Unexpected StateMachineTemplate initialization.");
        }
Esempio n. 12
0
        public void StateMachineTemplate_NestedEndRegionWithoutRegion_Throws()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(State1, false);
            t.State(State1);
            // t.EndState() omitted.
            Assert.That(() => { t.EndRegion(); }, Throws.TypeOf(typeof(StateMachineException)));
        }
Esempio n. 13
0
        public void StateMachineTemplate_WithDuplicateTransitionName_Throws()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(State1, false);
            t.State(State1);
            t.Transition(Transi1, new string[] { State1 }, new string[] { State2 }, 1, null, null);
            Assert.That(() => { t.Transition(Transi1, new string[] { State1 }, new string[] { State2 }, 1, null, null); }, Throws.TypeOf(typeof(ArgumentOutOfRangeException)));
        }
Esempio n. 14
0
        private void SendTriggerEvent_WithTwoTransitions_ExecutesExpected(bool useDoActions)
#endif
        {
            // Arrange
            string[] expectedExec;
            if (useDoActions)
            {
                expectedExec = new string[] { "EnS1", "DoS1",
                                              "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK",
                                              "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK",
                                              "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK",
                                              "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK",
                                              "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK", };
            }
            else
            {
                expectedExec = new string[] { "EnS1",
                                              "CHK", "ExS1", "EnS2", "CHK", "ExS2", "EnS1", "CHK",
                                              "CHK", "ExS1", "EnS2", "CHK", "ExS2", "EnS1", "CHK",
                                              "CHK", "ExS1", "EnS2", "CHK", "ExS2", "EnS1", "CHK",
                                              "CHK", "ExS1", "EnS2", "CHK", "ExS2", "EnS1", "CHK",
                                              "CHK", "ExS1", "EnS2", "CHK", "ExS2", "EnS1", "CHK", };
            }

            ActionRecorder recorder           = new ActionRecorder();
            bool           transition1Enabled = false;
            bool           transition2Enabled = false;

            StateMachineTemplate t = new StateMachineTemplate(useDoActions ? StateMachineOptions.UseDoActions : StateMachineOptions.None);

            t.Region("S1", false);
            t.State("S1", recorder.CreateAction("EnS1"), recorder.CreateAction("ExS1"), useDoActions ? recorder.CreateDoAction("DoS1") : NullDo);
            t.Transition("T1", "S1", "S2", null, (stm, ev, args) => transition1Enabled, (stm, ev, args) => { transition1Enabled = false; transition2Enabled = true; });
            t.EndState();
            t.State("S2", recorder.CreateAction("EnS2"), recorder.CreateAction("ExS2"), useDoActions ? recorder.CreateDoAction("DoS2") : NullDo);
            t.Transition("T2", "S2", "S1", null, (stm, ev, args) => transition2Enabled, (stm, ev, args) => { transition2Enabled = false; });
            t.EndState();
            t.EndRegion();
            StateMachine stateMachine = t.CreateStateMachine();

            stateMachine.TraceDispatchTriggerEvent = recorder.CreateTraceMethod("CHK");
            stateMachine.Startup();

            // Act
            for (int i = 0; i < 5; i++)
            {
                transition1Enabled = true;
                stateMachine.SendTriggerEvent(null);
            }

            // Assert
            Assert.That(recorder.RecordedActions, Is.EqualTo(expectedExec), "Unexpected action invocations");
        }
Esempio n. 15
0
        public void SaveStateResume_SampleCode_BehavesAsExpected()
        {
            #region DevelopersGuide_SaveStateAndResume
            StateMachineTemplate t = new StateMachineTemplate();
            t.Region("State1", false);
            t.State("State1");
            t.Transition("T1", "State2", "Event1");
            t.EndState();
            t.State("State2");
            t.Transition("T2", "State1", "Event2");
            t.EndState();
            t.EndRegion();

            // Create a state machine and start it
            StateMachine stateMachine1 = t.CreateStateMachine();
            stateMachine1.Startup();

            // stateMachine1 is now ready for receiving events
            stateMachine1.SendTriggerEvent("Event1");
            // Check that stateMachine1 has executed transition "T1" to state "State2"
            if (stateMachine1.ActiveStateConfiguration.ToString() != t.CreateStateConfiguration("State2").ToString())
            {
                throw new Exception("stateMachine1 in unexpected state");
            }

            // Save the current state of stateMachine1
            MemoryStream stream = new MemoryStream();
            stateMachine1.SaveState(stream);
            stream.Flush(); // Might write to persistent storage when using FileStream instead

            // For demonstration purposes reset the MemoryStream to enable reading from it
            // Real applications would open a FileStream
            stream.Position = 0;

            // Create a new state machine using the same structure and resume from saved state
            StateMachine stateMachine2 = t.CreateStateMachine();
            stateMachine2.Resume(stream, false);

            // stateMachine2 is ready for receiving events
            stateMachine2.SendTriggerEvent("Event2");
            // Check that stateMachine2 has executed transition "T2" to state "State1"
            if (stateMachine2.ActiveStateConfiguration.ToString() != t.CreateStateConfiguration("State1").ToString())
            {
                throw new Exception("stateMachine2 in unexpected state");
            }
            #endregion DevelopersGuide_SaveStateAndResume
        }
        private static StateMachineTemplate GetStateMachineTemplate()
        {
            if (m_stateMachineTemplate == null)
            {
                StateMachineTemplate t = new StateMachineTemplate();

                t.Region("State1", false);
                t.State("State1", EnterState1, ExitState1);
                t.Transition("Transition1to2", "State2", "Event1", null, null);
                t.EndState();
                t.State("State2", EnterState2, ExitState2);
                t.Transition("Transition2to1", "State1", "TimeoutState2", null, null);
                t.EndState();
                t.EndRegion();

                m_stateMachineTemplate = t;
            }

            return(m_stateMachineTemplate);
        }
Esempio n. 17
0
        public void SaveStateResume_StructureChanged_ThrowsAndStateMachineNotCorrupt()
        {
            // Arrange
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region("State1", false);
            t.State("State1");
            t.Transition("T1", "State2", null);
            t.EndState();
            t.State("State2");
            t.EndState();
            t.EndRegion();
            StateMachine s1 = t.CreateStateMachine();

            s1.Startup();

            StateMachineTemplate t2 = new StateMachineTemplate();

            t2.Region("State1", false);
            t2.State("State1");
            t2.Transition("T1", "State3", null);
            t2.EndState();
            t2.State("State3");
            t2.EndState();
            t2.EndRegion();
            StateMachine s2 = t2.CreateStateMachine();

            MemoryStream memoryStream = new MemoryStream();

            s1.SaveState(memoryStream);
            memoryStream.Flush();
            memoryStream.Position = 0;

            // Act, Assert
            Assert.That(delegate() { s2.Resume(memoryStream, false); }, Throws.TypeOf(typeof(ArgumentException)).With.Message.Contains("state machine structure").IgnoreCase);

            // Act
            s2.Startup();
            s2.SendTriggerEvent(null);
            Assert.That(s2.ActiveStateConfiguration.ToString(), Is.EqualTo(t2.CreateStateConfiguration("State3").ToString()), "Cannot run state machine after failed Resume.");
        }
Esempio n. 18
0
        public SampleSimpleStateMachineNETMF()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            t.Region("State1", false);
            t.State("State1", EnterState1, ExitState1);
            t.Transition("Transition1to2", "State2", "Event1", null, null);
            t.EndState();
            t.State("State2", EnterState2, ExitState2);
            t.Transition("Transition2to1", "State1", "TimeoutState2", null, null);
            t.EndState();
            t.EndRegion();

            m_stateMachine = t.CreateStateMachine();
            m_stateMachine.TraceStateChange = this.TraceStateChange;

            m_timeoutTimer       = new DispatcherTimer();
            m_timeoutTimer.Tick += TimeoutTimer_Tick;

            m_stateMachine.Startup();
        }
Esempio n. 19
0
        private void SaveStateResume_HappyPath_BehavesAsExpected(bool executeEntryActions)
#endif
        {
            // Arrange
            ActionRecorder recorder = new ActionRecorder();

            StateMachineTemplate t = new StateMachineTemplate(StateMachineOptions.UseDoActions);

            t.Region("StateA", false);
            t.State("StateA", recorder.CreateAction("EnterA"), recorder.CreateAction("ExitA"), recorder.CreateDoAction("DoA"));
            t.Transition("T1", "StateB", null);
            t.EndState();
            t.State("StateB", recorder.CreateAction("EnterB"), recorder.CreateAction("ExitB"), recorder.CreateDoAction("DoB"));
            t.EndState();
            t.EndRegion();

            StateMachine s1 = t.CreateStateMachine();

            s1.Startup();
            recorder.Clear();

            // Act
            MemoryStream memoryStream = new MemoryStream();

            s1.SaveState(memoryStream);
            memoryStream.Flush();
            memoryStream.Position = 0;
            StateMachine s2 = t.CreateStateMachine();

            s2.Resume(memoryStream, executeEntryActions);

            // Assert
            Assert.That(s2.ActiveStateConfiguration.ToString(), Is.EqualTo(s1.ActiveStateConfiguration.ToString()), "State mismatch after Resume.");
            String[] expectedActions = executeEntryActions ? new String[] { "EnterA", "DoA" } : new String[] { };
            Assert.That(recorder.RecordedActions, Is.EqualTo(expectedActions), "Unexpected entry or do actions during state machine resume.");
            recorder.Clear();
            s2.SendTriggerEvent(null);
            Assert.That(s2.ActiveStateConfiguration.ToString(), Is.EqualTo(t.CreateStateConfiguration("StateB").ToString()), "Cannot run state machine after Resume.");
            Assert.That(recorder.RecordedActions, Is.EqualTo(new String[] { "ExitA", "EnterB", "DoB" }), "Unexpected entry or do actions during state machine resume.");
        }
Esempio n. 20
0
        public SampleSimpleStateMachineNETFWK()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            //## Begin Structure
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "SampleSimpleStateMachineNETFWK"
            // at 07-22-2015 22:09:50 using StaMaShapes Version 2300
            t.Region("State1", false);
            t.State("State1", EnterState1, ExitState1);
            t.Transition("Transition1to2", "State2", "Event1", null, null);
            t.EndState();
            t.State("State2", EnterState2, ExitState2);
            t.Transition("Transition2to1", "State1", null, IsState2Timeout, null);
            t.EndState();
            t.EndRegion();
            //## End Structure

            m_stateMachine = t.CreateStateMachine();
            m_stateMachine.TraceStateChange = this.TraceStateChange;

            m_stateMachine.Startup();
        }
Esempio n. 21
0
        public void SendTriggerEvent_WithOneTransitionsAndDoChangesGuard_ExecutesExpected()
        {
            // Arrange
            string[] expectedExec;
            expectedExec = new string[] { "EnS1", "DoS1",
                                          "CHK", "DoS1", "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK",
                                          "CHK", "DoS1", "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK",
                                          "CHK", "DoS1", "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK",
                                          "CHK", "DoS1", "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK",
                                          "CHK", "DoS1", "CHK", "ExS1", "EnS2", "DoS2", "CHK", "ExS2", "EnS1", "DoS1", "CHK", };

            ActionRecorder recorder         = new ActionRecorder();
            int            transition1State = 0;

            StateMachineTemplate t = new StateMachineTemplate(StateMachineOptions.UseDoActions);

            t.Region("S1", false);
            t.State("S1", recorder.CreateAction("EnS1"), recorder.CreateAction("ExS1"), (stm) => { recorder.Add("DoS1"); transition1State += 1; });
            t.Transition("T1", "S1", "S2", null, (stm, ev, args) => transition1State == 1, null);
            t.EndState();
            t.State("S2", recorder.CreateAction("EnS2"), recorder.CreateAction("ExS2"), recorder.CreateDoAction("DoS2"));
            t.Transition("T2", "S2", "S1", null, (stm, ev, args) => true, null);
            t.EndState();
            t.EndRegion();
            StateMachine stateMachine = t.CreateStateMachine();

            stateMachine.TraceDispatchTriggerEvent = recorder.CreateTraceMethod("CHK");
            stateMachine.Startup();

            // Act
            for (int i = 0; i < 5; i++)
            {
                transition1State = 0;
                stateMachine.SendTriggerEvent(null);
            }

            // Assert
            Assert.That(recorder.RecordedActions, Is.EqualTo(expectedExec), "Unexpected action invocations");
        }
Esempio n. 22
0
        public void SendTriggerEvent_WithDeepNesting_ExecutesActionsInExpectedSequence()
        {
            bool flag = false;

            // Arrange
            const string Startup = "*Startup*";
            const string Finish  = "*Finish*";

            //## Begin StateAndTransitionNames5
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution4_DeepNesting"
            // at 07-22-2015 22:05:21 using StaMaShapes Version 2300
            const string State1  = "State1";
            const string Transi1 = "Transi1";
            const string Ev5     = "Ev5";
            const string State2  = "State2";
            const string Transi2 = "Transi2";
            const string Ev1     = "Ev1";
            const string State3  = "State3";
            const string Transi3 = "Transi3";
            const string Ev2     = "Ev2";
            const string State4  = "State4";
            const string State5  = "State5";
            const string State7  = "State7";
            const string State6  = "State6";
            const string Transi4 = "Transi4";
            const string Transi5 = "Transi5";
            const string State8  = "State8";
            const string State9  = "State9";
            const string State10 = "State10";
            const string Transi6 = "Transi6";
            const string Ev4     = "Ev4";
            const string State11 = "State11";
            const string Transi7 = "Transi7";
            const string Ev3     = "Ev3";
            const string Transi8 = "Transi8";
            const string State12 = "State12";
            const string Transi9 = "Transi9";
            const string State13 = "State13";
            //## End StateAndTransitionNames5

            //## Begin StateAndTransitionNames4
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution4_DeepNesting"
            // at 07-22-2015 22:05:21 using StaMaShapes Version 2300
            const string TransAct1To13  = "TransAct1To13";
            const string Entry2         = "Entry2";
            const string Exit2          = "Exit2";
            const string TransAct2To6   = "TransAct2To6";
            const string Entry3         = "Entry3";
            const string Exit3          = "Exit3";
            const string TransAct3To10  = "TransAct3To10";
            const string Entry7         = "Entry7";
            const string Exit7          = "Exit7";
            const string Entry6         = "Entry6";
            const string Exit6          = "Exit6";
            const string TransAct10To3  = "TransAct10To3";
            const string Entry11        = "Entry11";
            const string Exit11         = "Exit11";
            const string TransAct11To12 = "TransAct11To12";
            const string Entry12        = "Entry12";
            const string Exit12         = "Exit12";
            //## End StateAndTransitionNames4

            ActionRecorder recorder = new ActionRecorder();

            StateMachineTemplate t = new StateMachineTemplate(StateMachineOptions.UseDoActions);

            //## Begin StateMachineTemplate6
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution4_DeepNesting"
            // at 07-22-2015 22:05:21 using StaMaShapes Version 2300
            t.Region(State1, false);
            t.State(State1, null, null);
            t.Transition(Transi1, State13, Ev5, null, recorder.CreateAction(TransAct1To13));
            t.Region(State2, false);
            t.State(State2, recorder.CreateAction(Entry2), recorder.CreateAction(Exit2));
            t.Transition(Transi2, State6, Ev1, null, recorder.CreateAction(TransAct2To6));
            t.Region(State3, false);
            t.State(State3, recorder.CreateAction(Entry3), recorder.CreateAction(Exit3));
            t.Transition(Transi3, State10, Ev2, null, recorder.CreateAction(TransAct3To10));
            t.Region(State4, false);
            t.State(State4, null, null);
            t.Region(State5, false);
            t.State(State5, null, null);
            t.Region(State7, true);
            t.State(State7, recorder.CreateAction(Entry7), recorder.CreateAction(Exit7));
            t.EndState();
            t.State(State6, recorder.CreateAction(Entry6), recorder.CreateAction(Exit6));
            t.Transition(Transi4, State6, null, (stm, ev, args) => false, null);
            t.Transition(Transi5, State6, Ev2, (stm, ev, args) => false, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(State8, null, null);
            t.Region(State9, false);
            t.State(State9, null, null);
            t.Region(State10, false);
            t.State(State10, null, null);
            t.Transition(Transi6, State3, Ev4, null, recorder.CreateAction(TransAct10To3));
            t.Region(State11, true);
            t.State(State11, recorder.CreateAction(Entry11), recorder.CreateAction(Exit11));
            t.Transition(Transi7, State12, Ev3, null, recorder.CreateAction(TransAct11To12));
            t.Transition(Transi8, State12, null, (stm, ev, args) => flag, null);
            t.EndState();
            t.State(State12, recorder.CreateAction(Entry12), recorder.CreateAction(Exit12));
            t.Transition(Transi9, State11, null, (stm, ev, args) => !flag, (stm, ev, args) => flag = true);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(State13, null, null);
            t.EndState();
            t.EndRegion();
            //## End StateMachineTemplate6

            Assert.That(recorder.RecordedActions, Is.EqualTo(new String[] { }), "Precondition not met: Actions were executed during state machine creation.");

            StateMachine stateMachine = t.CreateStateMachine(this);

            stateMachine.TraceStateChange = delegate(StateMachine stateMachinex, StateConfiguration stateConfigurationFrom, StateConfiguration stateConfigurationTo, Transition transition)
            {
                System.Console.WriteLine("TestExecDeepNest: Transition from {0} to {1} using {2}",
                                         stateConfigurationFrom.ToString(),
                                         stateConfigurationTo.ToString(),
                                         (transition != null) ? transition.Name : "*");
            };

            stateMachine.TraceTestTransition = delegate(StateMachine stateMachinex, Transition transition, object triggerEvent, EventArgs eventArgs)
            {
                System.Console.WriteLine("TestExecDeepNest: Test transition {0} with event {1} in state {2}",
                                         transition.ToString(),
                                         (triggerEvent != null) ? triggerEvent.ToString() : "*",
                                         stateMachine.ActiveStateConfiguration.ToString());
            };

            stateMachine.TraceDispatchTriggerEvent = delegate(StateMachine stateMachinex, object triggerEvent, EventArgs eventArgs)
            {
                string eventName = (triggerEvent != null) ? triggerEvent.ToString() : "*";
                System.Console.WriteLine("TestExecDeepNest: Dispatch event {0} in state {1}", eventName, stateMachine.ActiveStateConfiguration.ToString());
            };

            foreach (TestData testData in new TestData[]
            {
                new TestData()
                {
                    EventToSend = Startup,
                    ExpectedState = t.CreateStateConfiguration(new String[] { State7 }),
                    ExpectedActions = new String[] { Entry2, Entry3, Entry7 },
                },

                new TestData()
                {
                    EventToSend = Ev1,
                    ExpectedState = t.CreateStateConfiguration(new string[] { State6 }),
                    ExpectedActions = new String[] { Exit7, Exit3, Exit2, TransAct2To6, Entry2, Entry3, Entry6 }
                },

                new TestData()
                {
                    EventToSend = Ev2,
                    ExpectedState = t.CreateStateConfiguration(new string[] { State11 }),
                    ExpectedActions = new String[] { Exit6, Exit3, Exit2, TransAct3To10, Entry11 }
                },

                new TestData()
                {
                    EventToSend = Ev3,
                    ExpectedState = t.CreateStateConfiguration(new string[] { State12 }),
                    ExpectedActions = new String[] { Exit11, TransAct11To12, Entry12, Exit12, Entry11, Exit11, Entry12 }
                },

                new TestData()
                {
                    EventToSend = Ev4,
                    ExpectedState = t.CreateStateConfiguration(new string[] { State6 }),
                    ExpectedActions = new String[] { Exit12, TransAct10To3, Entry2, Entry3, Entry6 }
                },

                new TestData()
                {
                    EventToSend = Ev5,
                    ExpectedState = t.CreateStateConfiguration(new string[] { State13 }),
                    ExpectedActions = new String[] { Exit6, Exit3, Exit2, TransAct1To13 }
                },

                new TestData()
                {
                    EventToSend = Finish,
                    ExpectedState = t.CreateStateConfiguration(new string[] { }),
                    ExpectedActions = new String[] { }
                },
            })
            {
                recorder.Clear();

                // Act
                switch (testData.EventToSend)
                {
                case Startup:
                    stateMachine.Startup();
                    break;

                case Finish:
                    stateMachine.Finish();
                    break;

                default:
                    stateMachine.SendTriggerEvent(testData.EventToSend);
                    break;
                }

                // Assert
                Assert.That(stateMachine.ActiveStateConfiguration.ToString(), Is.EqualTo(testData.ExpectedState.ToString()), testData.EventToSend + ": Active state not as expected.");
                Assert.That(recorder.RecordedActions, Is.EqualTo(testData.ExpectedActions), testData.EventToSend + ": Unexpected entry and exit actions during state machine processing.");
            }
        }
Esempio n. 23
0
        public void SendTriggerEvent_WithOrthogonalRegions_ExecutesActionsInExpectedSequence()
        {
            // Arrange
            const string Startup = "*Startup*";
            const string Finish  = "*Finish*";

            //## Begin StateAndTransitionNames57
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution1_OrthogonalRegions"
            // at 07-22-2015 22:05:11 using StaMaShapes Version 2300
            const string StateB     = "StateB";
            const string Transi8    = "Transi8";
            const string Event6     = "Event6";
            const string Transi6    = "Transi6";
            const string Transi3    = "Transi3";
            const string Event2     = "Event2";
            const string Transi5    = "Transi5";
            const string Event5     = "Event5";
            const string StateB1A   = "StateB1A";
            const string StateB1B   = "StateB1B";
            const string StateB2A   = "StateB2A";
            const string StateB2B   = "StateB2B";
            const string Transi9    = "Transi9";
            const string Event4     = "Event4";
            const string StateB2B1A = "StateB2B1A";
            const string StateB2B2A = "StateB2B2A";
            const string Transi4    = "Transi4";
            const string Event3     = "Event3";
            const string StateB2B2B = "StateB2B2B";
            const string StateB2B3A = "StateB2B3A";
            const string Transi7    = "Transi7";
            const string StateB2B3B = "StateB2B3B";
            const string StateC     = "StateC";
            const string StateA     = "StateA";
            const string Transi1    = "Transi1";
            const string Event1     = "Event1";
            //## End StateAndTransitionNames57

            //## Begin ActionNames
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution1_OrthogonalRegions"
            // at 07-22-2015 22:05:11 using StaMaShapes Version 2300
            const string EnterB     = "EnterB";
            const string ExitB      = "ExitB";
            const string DoB        = "DoB";
            const string EnterB1A   = "EnterB1A";
            const string ExitB1A    = "ExitB1A";
            const string DoB1A      = "DoB1A";
            const string EnterB1B   = "EnterB1B";
            const string ExitB1B    = "ExitB1B";
            const string DoB1B      = "DoB1B";
            const string EnterB2A   = "EnterB2A";
            const string ExitB2A    = "ExitB2A";
            const string DoB2A      = "DoB2A";
            const string EnterB2B   = "EnterB2B";
            const string ExitB2B    = "ExitB2B";
            const string DoB2B      = "DoB2B";
            const string EnterB2B1A = "EnterB2B1A";
            const string ExitB2B1A  = "ExitB2B1A";
            const string DoB2B1A    = "DoB2B1A";
            const string EnterB2B2A = "EnterB2B2A";
            const string ExitB2B2A  = "ExitB2B2A";
            const string DoB2B2A    = "DoB2B2A";
            const string EnterB2B2B = "EnterB2B2B";
            const string ExitB2B2B  = "ExitB2B2B";
            const string DoB2B2B    = "DoB2B2B";
            const string EnterB2B3A = "EnterB2B3A";
            const string ExitB2B3A  = "ExitB2B3A";
            const string DoB2B3A    = "DoB2B3A";
            const string EnterB2B3B = "EnterB2B3B";
            const string ExitB2B3B  = "ExitB2B3B";
            const string DoB2B3B    = "DoB2B3B";
            const string EnterC     = "EnterC";
            const string ExitC      = "ExitC";
            const string DoC        = "DoC";
            const string EnterA     = "EnterA";
            const string ExitA      = "ExitA";
            const string DoA        = "DoA";
            //## End ActionNames

            ActionRecorder recorder = new ActionRecorder();

            StateMachineTemplate t = new StateMachineTemplate(StateMachineOptions.UseDoActions);

            //## Begin StateMachineTemplate4
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution1_OrthogonalRegions"
            // at 07-22-2015 22:05:12 using StaMaShapes Version 2300
            t.Region(StateA, false);
            t.State(StateB, recorder.CreateAction(EnterB), recorder.CreateAction(ExitB), recorder.CreateDoAction(DoB));
            t.Transition(Transi8, StateB2A, StateC, Event6, null, null);
            t.Transition(Transi6, new string[] { StateB1B, StateB2B }, StateA, Event6, null, null);
            t.Transition(Transi3, StateB1A, new string[] { StateB1B, StateB2B }, Event2, null, null);
            t.Transition(Transi5, StateB2B2A, new string[] { StateB1B, StateB2B2A }, Event5, null, null);
            t.Region(StateB1A, false);
            t.State(StateB1A, recorder.CreateAction(EnterB1A), recorder.CreateAction(ExitB1A), recorder.CreateDoAction(DoB1A));
            t.EndState();
            t.State(StateB1B, recorder.CreateAction(EnterB1B), recorder.CreateAction(ExitB1B), recorder.CreateDoAction(DoB1B));
            t.EndState();
            t.EndRegion();
            t.Region(StateB2A, false);
            t.State(StateB2A, recorder.CreateAction(EnterB2A), recorder.CreateAction(ExitB2A), recorder.CreateDoAction(DoB2A));
            t.EndState();
            t.State(StateB2B, recorder.CreateAction(EnterB2B), recorder.CreateAction(ExitB2B), recorder.CreateDoAction(DoB2B));
            t.Transition(Transi9, StateB2B, Event4, null, null);
            t.Region(StateB2B1A, false);
            t.State(StateB2B1A, recorder.CreateAction(EnterB2B1A), recorder.CreateAction(ExitB2B1A), recorder.CreateDoAction(DoB2B1A));
            t.EndState();
            t.EndRegion();
            t.Region(StateB2B2A, false);
            t.State(StateB2B2A, recorder.CreateAction(EnterB2B2A), recorder.CreateAction(ExitB2B2A), recorder.CreateDoAction(DoB2B2A));
            t.Transition(Transi4, StateB2B2B, Event3, null, null);
            t.EndState();
            t.State(StateB2B2B, recorder.CreateAction(EnterB2B2B), recorder.CreateAction(ExitB2B2B), recorder.CreateDoAction(DoB2B2B));
            t.EndState();
            t.EndRegion();
            t.Region(StateB2B3A, true);
            t.State(StateB2B3A, recorder.CreateAction(EnterB2B3A), recorder.CreateAction(ExitB2B3A), recorder.CreateDoAction(DoB2B3A));
            t.Transition(Transi7, StateB2B3B, Event3, null, null);
            t.EndState();
            t.State(StateB2B3B, recorder.CreateAction(EnterB2B3B), recorder.CreateAction(ExitB2B3B), recorder.CreateDoAction(DoB2B3B));
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(StateC, recorder.CreateAction(EnterC), recorder.CreateAction(ExitC), recorder.CreateDoAction(DoC));
            t.EndState();
            t.State(StateA, recorder.CreateAction(EnterA), recorder.CreateAction(ExitA), recorder.CreateDoAction(DoA));
            t.Transition(Transi1, StateB, Event1, null, null);
            t.EndState();
            t.EndRegion();
            //## End StateMachineTemplate4

            StateMachine stateMachine = t.CreateStateMachine(this);

            stateMachine.TraceStateChange = delegate(StateMachine stateMachinex, StateConfiguration stateConfigurationFrom, StateConfiguration stateConfigurationTo, Transition transition)
            {
                System.Console.WriteLine("TestExecConcurrent: Transition from {0} to {1} using {2}",
                                         stateConfigurationFrom.ToString(),
                                         stateConfigurationTo.ToString(),
                                         (transition != null) ? transition.Name : "*");
            };

            stateMachine.TraceTestTransition = delegate(StateMachine stateMachinex, Transition transition, object triggerEvent, EventArgs eventArgs)
            {
                System.Console.WriteLine("TestExecConcurrent: Test transition {0} with event {1} in state {2}",
                                         transition.ToString(),
                                         (triggerEvent != null) ? triggerEvent.ToString() : "*",
                                         stateMachine.ActiveStateConfiguration.ToString());
            };

            stateMachine.TraceDispatchTriggerEvent = delegate(StateMachine stateMachinex, object triggerEvent, EventArgs eventArgs)
            {
                string eventName = (triggerEvent != null) ? triggerEvent.ToString() : "*";
                System.Console.WriteLine("TestExecConcurrent: Dispatch event {0} in state {1}", eventName, stateMachine.ActiveStateConfiguration.ToString());
            };

            Assert.That(recorder.RecordedActions, Is.EqualTo(new String[] {}), "Precondition not met: Actions were executed during state machine creation.");

            foreach (TestData testData in new TestData[]
            {
                new TestData()
                {
                    EventToSend = Startup,
                    ExpectedState = t.CreateStateConfiguration(new String[] { StateA }),
                    ExpectedActions = new String[] { EnterA, DoA, },
                },
                new TestData()
                {
                    EventToSend = Event1,
                    ExpectedState = t.CreateStateConfiguration(new String[] { StateB1A, StateB2A }),
                    ExpectedActions = new String[] { ExitA, EnterB, EnterB1A, EnterB2A, DoB, DoB1A, DoB2A, },
                },
                new TestData()
                {
                    EventToSend = Event2,
                    ExpectedState = t.CreateStateConfiguration(new String[] { StateB1B, StateB2B1A, StateB2B2A, StateB2B3A }),
                    ExpectedActions = new String[] { ExitB2A, ExitB1A, ExitB, EnterB, EnterB1B, EnterB2B, EnterB2B1A, EnterB2B2A, EnterB2B3A, DoB, DoB1B, DoB2B, DoB2B1A, DoB2B2A, DoB2B3A, },
                },
                new TestData()
                {
                    EventToSend = Event3,
                    ExpectedState = t.CreateStateConfiguration(new String[] { StateB1B, StateB2B1A, StateB2B2B, StateB2B3B }),
                    ExpectedActions = new String[] { ExitB2B2A, EnterB2B2B, ExitB2B3A, EnterB2B3B, DoB, DoB1B, DoB2B, DoB2B1A, DoB2B2B, DoB2B3B, },
                },
                new TestData()
                {
                    EventToSend = Event4,
                    ExpectedState = t.CreateStateConfiguration(new String[] { StateB1B, StateB2B1A, StateB2B2A, StateB2B3B }),
                    ExpectedActions = new String[] { ExitB2B3B, ExitB2B2B, ExitB2B1A, ExitB2B, EnterB2B, EnterB2B1A, EnterB2B2A, EnterB2B3B, DoB, DoB1B, DoB2B, DoB2B1A, DoB2B2A, DoB2B3B },
                },
                new TestData()
                {
                    EventToSend = Event5,
                    ExpectedState = t.CreateStateConfiguration(new String[] { StateB1B, StateB2B1A, StateB2B2A, StateB2B3B }),
                    ExpectedActions = new String[] { ExitB2B3B, ExitB2B2A, ExitB2B1A, ExitB2B, ExitB1B, ExitB, EnterB, EnterB1B, EnterB2B, EnterB2B1A, EnterB2B2A, EnterB2B3B, DoB, DoB1B, DoB2B, DoB2B1A, DoB2B2A, DoB2B3B, },
                },
                new TestData()
                {
                    EventToSend = Event6,
                    ExpectedState = t.CreateStateConfiguration(new String[] { StateA }),
                    ExpectedActions = new String[] { ExitB2B3B, ExitB2B2A, ExitB2B1A, ExitB2B, ExitB1B, ExitB, EnterA, DoA, },
                },
                new TestData()
                {
                    EventToSend = Finish,
                    ExpectedState = t.CreateStateConfiguration(new String[] { }),
                    ExpectedActions = new String[] { ExitA },
                },
            })
            {
                recorder.Clear();

                // Act
                switch (testData.EventToSend)
                {
                case Startup:
                    stateMachine.Startup();
                    break;

                case Finish:
                    stateMachine.Finish();
                    break;

                default:
                    stateMachine.SendTriggerEvent(testData.EventToSend);
                    break;
                }

                // Assert
                Assert.That(stateMachine.ActiveStateConfiguration.ToString(), Is.EqualTo(testData.ExpectedState.ToString()), testData.EventToSend + ": Active state not as expected.");
                Assert.That(recorder.RecordedActions, Is.EqualTo(testData.ExpectedActions), testData.EventToSend + ": Unexpected entry and exit actions during state machine processing.");
            }
        }
Esempio n. 24
0
        public void StartupSendFinish_WithTraceFunctions_NotifiesPreviousAndActiveStateProperly()
        {
            // Arrange
            const string StateA   = "StateA";
            const string StateA1A = "StateA1A";
            const string StateA1B = "StateA1B";
            const string Transi1  = "Transi1";

            const string Event1 = "Event1";

            StateMachineTemplate t = new StateMachineTemplate();

            t.Region(StateA, false);
            t.State(StateA);
            t.Region(StateA1A, false);
            t.State(StateA1A);
            t.Transition(Transi1, new string[] { StateA1B }, Event1);
            t.EndState();
            t.State(StateA1B);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();

            StateConfiguration nirvana = t.CreateStateConfiguration(new string[] { });

            StateMachine       stateMachine = t.CreateStateMachine(this);
            int                stateChangeNotificationCount   = 0;
            StateConfiguration stateConfigurationFromNotified = null;
            StateConfiguration stateConfigurationToNotified   = null;

            stateMachine.TraceStateChange = delegate(StateMachine stm, StateConfiguration stateConfigurationFrom, StateConfiguration stateConfigurationTo, Transition transition)
            {
                stateChangeNotificationCount  += 1;
                stateConfigurationFromNotified = (StateConfiguration)stateConfigurationFrom.Clone();
                stateConfigurationToNotified   = (StateConfiguration)stateConfigurationTo.Clone();
            };

            // Act
            stateMachine.Startup();

            // Assert
            Assert.That(stateChangeNotificationCount, Is.EqualTo(1));
            Assert.That(stateConfigurationFromNotified.ToString(), Is.EqualTo(nirvana.ToString()));
            Assert.That(stateConfigurationToNotified.ToString(), Is.EqualTo(t.CreateStateConfiguration(StateA1A).ToString()));

            // Act
            stateMachine.SendTriggerEvent(Event1);

            // Assert
            Assert.That(stateChangeNotificationCount, Is.EqualTo(2));
            Assert.That(stateConfigurationFromNotified.ToString(), Is.EqualTo(t.CreateStateConfiguration(StateA1A).ToString()));
            Assert.That(stateConfigurationToNotified.ToString(), Is.EqualTo(t.CreateStateConfiguration(StateA1B).ToString()));

            // Act
            stateMachine.Finish();

            // Assert
            Assert.That(stateChangeNotificationCount, Is.EqualTo(3));
            Assert.That(stateConfigurationFromNotified.ToString(), Is.EqualTo(t.CreateStateConfiguration(StateA1B).ToString()));
            Assert.That(stateConfigurationToNotified.ToString(), Is.EqualTo(nirvana.ToString()));
        }
Esempio n. 25
0
        public DlgMain()
        {
            StateMachineTemplate t = new StateMachineTemplate();

            //## Begin StateMachineTemplate
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "Clock Sample"
            // at 07-22-2015 22:02:44 using StaMaShapes Version 2300
            t.Region(Operating, false);
            t.State(Operating, null, null);
            t.Region(NormalDisplay, false);
            t.State(AlarmDisplay, EnterAlarmDisplay, ExitAlarmDisplay);
            t.Transition(AlarmDisplayAcknowledge, NormalDisplay, EventId.Up, null, null);
            t.Transition(AlarmDisplayTimeout, NormalDisplay, EventId.AlarmDisplayTimeout, null, null);
            t.EndState();
            t.State(NormalDisplay, null, null);
            t.Transition(AlarmTimeNow, new string[] { AlarmActive, NormalDisplay }, AlarmDisplay, EventId.AlarmTimeNow, null, null);
            t.Region(TimeMode, true);
            t.State(AlarmMode, null, null);
            t.Region(InspectAlarm, false);
            t.State(ChangeAlarmEnable, EnterChangeAlarmEnable, ExitChangeAlarmEnable);
            t.Transition(ChangeAlarmToggleAlarm, ChangeAlarmEnable, EventId.Up, null, ToggleAlarm);
            t.Transition(GoChangeAlarmHour, ChangeAlarmHour, EventId.Set, null, null);
            t.Transition(RevertDisplayAlarm3, InspectAlarm, EventId.Mode, null, null);
            t.Transition(ChangeAlarmEnableTimeout, InspectAlarm, EventId.ChangeAlarmEnableTimeout, null, null);
            t.EndState();
            t.State(ChangeAlarmHour, EnterChangeAlarmHour, ExitChangeAlarmHour);
            t.Transition(ChangeAlarmHourUp, ChangeAlarmHour, EventId.Up, null, IncrementAlarmHour);
            t.Transition(GoChangeAlarmMinutes, ChangeAlarmMinutes, EventId.Set, null, null);
            t.Transition(RevertDisplayAlarm1, InspectAlarm, EventId.Mode, null, null);
            t.Transition(ChangeAlarmHourTimeout, InspectAlarm, EventId.ChangeAlarmHourTimeout, null, null);
            t.EndState();
            t.State(ChangeAlarmMinutes, EnterChangeAlarmMinutes, ExitChangeAlarmMinutes);
            t.Transition(ChangeAlarmMinutesUp, ChangeAlarmMinutes, EventId.Up, null, IncrementAlarmMinutes);
            t.Transition(GoToggleAlarm, ChangeAlarmEnable, EventId.Set, null, null);
            t.Transition(RevertDisplayAlarm2, InspectAlarm, EventId.Mode, null, null);
            t.Transition(ChangeAlarmMinutesTimeout, InspectAlarm, EventId.ChangeAlarmMinutesTimeout, null, null);
            t.EndState();
            t.State(InspectAlarm, EnterInspectAlarm, ExitInspectAlarm);
            t.Transition(GotoStopwatchMode, StopwatchMode, EventId.Mode, null, null);
            t.Transition(GoChangeAlarm, ChangeAlarmHour, EventId.Set, null, null);
            t.Transition(InspectAlarmTimeout, TimeMode, EventId.InspectAlarmTimeout, null, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State(DateMode, EnterDateMode, ExitDateMode);
            t.Transition(GotoAlarmMode, InspectAlarm, EventId.Mode, null, null);
            t.Transition(DateModeTimeout, TimeMode, EventId.DateModeTimeout, null, null);
            t.EndState();
            t.State(StopwatchMode, null, null);
            t.Transition(GotoTimeMode, TimeMode, EventId.Mode, null, null);
            t.Transition(StopwatchModeReset, new string[] { StopwatchMode, StopwatchStopped }, StopwatchMode, EventId.Set, null, TriggerReset);
            t.Transition(StopwatchModeStart, new string[] { StopwatchMode, StopwatchStopped }, StopwatchMode, EventId.Up, null, TriggerStart);
            t.Transition(StopwatchModeStop, new string[] { StopwatchMode, StopwatchRunning }, StopwatchMode, EventId.Up, null, TriggerStop);
            t.EndState();
            t.State(TimeMode, null, null);
            t.Transition(GotoDateMode, DateMode, EventId.Mode, null, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            t.Region(StopwatchStopped, false);
            t.State(StopwatchRunning, null, null);
            t.Transition(StopwatchStop, StopwatchStopped, EventId.Stop, null, StopwatchDoStop);
            t.EndState();
            t.State(StopwatchStopped, null, null);
            t.Transition(StopwatchStart, StopwatchRunning, EventId.Start, null, StopwatchDoStart);
            t.Transition(StopwatchReset, StopwatchStopped, EventId.Reset, null, StopwatchDoReset);
            t.EndState();
            t.EndRegion();
            t.Region(AlarmDeactivated, false);
            t.State(AlarmActive, null, null);
            t.Transition(DeactivateAlarm, AlarmDeactivated, EventId.DeactivateAlarm, null, null);
            t.EndState();
            t.State(AlarmDeactivated, null, null);
            t.Transition(ActivateAlarm, AlarmActive, EventId.ActivateAlarm, null, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            //## End StateMachineTemplate


            m_stateShowTime         = t.CreateStateConfiguration(TimeMode);
            m_stateShowDate         = t.CreateStateConfiguration(DateMode);
            m_stateShowAlarm        = t.CreateStateConfiguration(AlarmMode);
            m_stateAlarmActive      = t.CreateStateConfiguration(AlarmActive);
            m_stateShowStopwatch    = t.CreateStateConfiguration(StopwatchMode);
            m_stateStopwatchRunning = t.CreateStateConfiguration(StopwatchRunning);
            m_stateAlarmDisplay     = t.CreateStateConfiguration(AlarmDisplay);


            m_alarmTime = m_alarmTime.AddHours((24 + DateTime.Now.Hour - 2) % 24);
            m_alarmTime = m_alarmTime.AddMinutes(DateTime.Now.Minute);

            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            m_timer.Interval = TICK_DELTA;

            EventId[] timerEvents = new EventId[] { EventId.DateModeTimeout,
                                                    EventId.InspectAlarmTimeout,
                                                    EventId.ChangeAlarmHourTimeout,
                                                    EventId.ChangeAlarmMinutesTimeout,
                                                    EventId.ChangeAlarmEnableTimeout,
                                                    EventId.AlarmDisplayTimeout };
            m_timers = new ListDictionary();
            foreach (EventId timerEvent in timerEvents)
            {
                System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(this.components);
                m_timers.Add(timerEvent, timer);
                timer.Tag      = timerEvent;
                timer.Tick    += new EventHandler(this.m_timer_Timeout);
                timer.Interval = TIMEOUT;
            }

            m_stateMachine = t.CreateStateMachine(this);

            m_stateMachine.TraceTestTransition       = StateMachine_TraceTestTransition;
            m_stateMachine.TraceDispatchTriggerEvent = StateMachine_TraceDispatchEvent;

            m_stateMachine.Startup();
            m_wndActiveState.Text = m_stateMachine.ActiveStateConfiguration.ToString();
        }
Esempio n. 26
0
        private void SaveStateResume_WithHistory_UsesHistoryStateAfterResume(bool executeEntryActions)
#endif
        {
            ActionRecorder recorder = new ActionRecorder();

            TemplateFactory createTemplate = delegate()
            {
                StateMachineTemplate t = new StateMachineTemplate(StateMachineOptions.UseDoActions);
                //## Begin StateMachineTemplateSaveStateResumeWithHistory
                // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_SaveStateResumeTests"
                // at 07-25-2015 16:55:36 using StaMaShapes Version 2300
                t.Region("StateA", false);
                t.State("StateA", recorder.CreateAction("EnterA"), recorder.CreateAction("ExitA"), recorder.CreateDoAction("DoA"));
                t.Region("StateA1A", true);
                t.State("StateA1A", recorder.CreateAction("EnterA1A"), recorder.CreateAction("ExitA1A"), recorder.CreateDoAction("DoA1A"));
                t.Transition("T1", "StateA1B", null, null, null);
                t.EndState();
                t.State("StateA1B", recorder.CreateAction("EnterA1B"), recorder.CreateAction("ExitA1B"), recorder.CreateDoAction("DoA1B"));
                t.Transition("T2", "StateB1A", "Event1", null, null);
                t.EndState();
                t.EndRegion();
                t.EndState();
                t.State("StateB", recorder.CreateAction("EnterB"), recorder.CreateAction("ExitB"), recorder.CreateDoAction("DoB"));
                t.Transition("T4", "StateA", "Event2", null, null);
                t.Region("StateB1A", true);
                t.State("StateB1A", recorder.CreateAction("EnterB1A"), recorder.CreateAction("ExitB1A"), recorder.CreateDoAction("DoB1A"));
                t.Transition("T3", "StateB1B", null, null, null);
                t.EndState();
                t.State("StateB1B", recorder.CreateAction("EnterB1B"), recorder.CreateAction("ExitB1B"), recorder.CreateDoAction("DoB1B"));
                t.EndState();
                t.EndRegion();
                t.EndState();
                t.EndRegion();
                //## End StateMachineTemplateSaveStateResumeWithHistory
                return(t);
            };

            StateMachineTemplate t1 = createTemplate();

            t1.SerializationSignatureGenerator = TestSignatureGenerator;
            StateMachine s1 = t1.CreateStateMachine();

            s1.Startup();
            s1.SendTriggerEvent(null);
            s1.SendTriggerEvent("Event1");

            StateConfiguration expectedActiveStateS1 = t1.CreateStateConfiguration("StateB1B");

            Assert.That(s1.ActiveStateConfiguration.ToString(), Is.EqualTo(expectedActiveStateS1.ToString()), "Precondition not met: Unexpected state save state.");
            Assert.That(recorder.RecordedActions, Is.EqualTo(new String[] { "EnterA", "EnterA1A", "DoA", "DoA1A", "ExitA1A", "EnterA1B", "DoA", "DoA1B", "ExitA1B", "ExitA", "EnterB", "EnterB1A", "DoB", "DoB1A", "ExitB1A", "EnterB1B", "DoB", "DoB1B" }), "Precondition not met: Unexpected action execution sequence.");
            recorder.Clear();

            // Act
            MemoryStream memoryStream = new MemoryStream();

            s1.SaveState(memoryStream);
            memoryStream.Flush();
            memoryStream.Position = 0;

            StateMachine s2 = t1.CreateStateMachine();

            s2.Resume(memoryStream, executeEntryActions);

            // Assert
            Assert.That(s2.ActiveStateConfiguration.ToString(), Is.EqualTo(s1.ActiveStateConfiguration.ToString()), "State mismatch after Resume.");
            String[] expectedActions = executeEntryActions ? new String[] { "EnterB", "EnterB1B", "DoB", "DoB1B" } : new String[] { };
            Assert.That(recorder.RecordedActions, Is.EqualTo(expectedActions), "Unexpected entry or do actions during state machine resume with history.");
            recorder.Clear();
            s2.SendTriggerEvent("Event2");
            Assert.That(s2.ActiveStateConfiguration.ToString(), Is.EqualTo(t1.CreateStateConfiguration("StateA1B").ToString()), "Unexpected state machine behavior after Resume.");
            Assert.That(recorder.RecordedActions, Is.EqualTo(new String[] { "ExitB1B", "ExitB", "EnterA", "EnterA1B", "DoA", "DoA1B" }), "Unexpected entry or do actions during state machine resume.");

            // Compatibility test assertions
            // Data obtained from
            // FileStream fileStream = new FileStream("TestData.dat", FileMode.Create);
            // s1.SaveState(fileStream);
            // fileStream.Close();
            // PowerShell> gc -encoding byte "TestData.dat" |% {write-host ("0x{0:X2}," -f $_) -noNewline ""}; write-host
            StringBuilder sb = new StringBuilder();

            Byte[] actualBytes = memoryStream.ToArray();
            for (int i = 0; i < actualBytes.Length; i++)
            {
                sb.Append("0x" + actualBytes[i].ToString("X2") + ", ");
            }
#if !MF_FRAMEWORK
            Console.WriteLine("Actual bytes:");
            Console.WriteLine(sb.ToString());
#else
            Debug.Print("Actual bytes:");
            Debug.Print(sb.ToString());
#endif
            Byte[] compatibilityTestData2300 = new Byte[] { 0xAA, 0x00, 0x23, 0xA1, 0x47, 0x28, 0x7E, 0x31, 0x2D, 0x7B, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, 0x28, 0x7E, 0x31, 0x23, 0x7B, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, 0x31, 0x41, 0x2C, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, 0x31, 0x42, 0x2C, 0x7D, 0x29, 0x2C, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x28, 0x7E, 0x31, 0x23, 0x7B, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x31, 0x41, 0x2C, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x31, 0x42, 0x2C, 0x7D, 0x29, 0x2C, 0x7D, 0x29, 0xA2, 0x01, 0x00, 0xA4, 0x01, 0x00, 0xA5, 0x08, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x31, 0x42, 0xA3, 0x02, 0x00, 0xA4, 0x01, 0x00, 0xA5, 0x08, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, 0x31, 0x42, 0xA4, 0x01, 0x00, 0xA5, 0x08, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x31, 0x42, };
            Assert.That(memoryStream.ToArray(), Is.EqualTo(compatibilityTestData2300), "Compatibility test failed. Written data different from version 2300.");

            MemoryStream         memoryStream2300 = new MemoryStream(compatibilityTestData2300);
            StateMachineTemplate t3 = createTemplate();
            t3.SerializationSignatureGenerator = null;
            StateMachine s3 = t3.CreateStateMachine();
            s3.Resume(memoryStream2300, false);
            Assert.That(s3.ActiveStateConfiguration.ToString(), Is.EqualTo(expectedActiveStateS1.ToString()), "State mismatch after Resume.");
        }
Esempio n. 27
0
        private void SerializationSignatureGenerator_WithValue_CalculatesSignatureAsExpected(String serializationSignatureGeneratorName, bool hasHistoryStateB1A)
#endif
        {
            // Arrange
            StateMachineTemplate t = new StateMachineTemplate(StateMachineOptions.UseDoActions);

            t.Region("StateA", false);
            t.State("StateA");
            t.Region("StateA1A", true);
            t.State("StateA1A");
            t.Transition("T1", "StateA1B", null, null, null);
            t.EndState();
            t.State("StateA1B");
            t.Transition("T2", "StateB1A", "Event1", null, null);
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.State("StateB");
            t.Transition("T4", "StateA", "Event2", null, null);
            t.Region("StateB1A", hasHistoryStateB1A);
            t.State("StateB1A");
            t.Transition("T3", "StateB1B", null, null, null);
            t.EndState();
            t.State("StateB1B");
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();

            String             expectedSignature;
            SignatureGenerator serializationSignatureGenerator;

            switch (serializationSignatureGeneratorName)
            {
            case "(null)":
                serializationSignatureGenerator = null;
                expectedSignature = String.Empty;
                break;

            case "TestSignatureGenerator":
                serializationSignatureGenerator = TestSignatureGenerator;
                expectedSignature = "(~1-{StateA(~1#{StateA1A,StateA1B,}),StateB(~1" + (hasHistoryStateB1A ? "#" : "-") + "{StateB1A,StateB1B,}),})";
                break;

            case "Default":
                Assert.That(t.SerializationSignatureGenerator, Is.Not.Null, "Precondition not met: Unexpected initial StateMachineTemplate.SerializationSignatureGenerator value.");
                serializationSignatureGenerator = t.SerializationSignatureGenerator;
#if !MF_FRAMEWORK
                expectedSignature = "6755BD36";
#else
                expectedSignature = "9AD6D03F";
#endif
                break;

            default:
                throw new ArgumentException("Invalid generator name.", "serializationSignatureGeneratorName");
            }

            // Act
            t.SerializationSignatureGenerator = serializationSignatureGenerator;

            // Assert
            Assert.That(t.SerializationSignatureGenerator, Is.EqualTo(serializationSignatureGenerator));

            // Act
            String signature = t.Signature;
            Console.WriteLine(signature);

            // Assert
            Assert.That(signature, Is.EqualTo(expectedSignature));
            Assert.That(() => { t.SerializationSignatureGenerator = TestSignatureGenerator; }, Throws.TypeOf(typeof(InvalidOperationException)));
        }
Esempio n. 28
0
        public void SendTriggerEvent_WithOrthogonalRegionsGuardState_ExecutesActionsInExpectedSequence()
        {
            // Arrange
            const string Startup = "*Startup*";
            const string Finish  = "*Finish*";

            //## Begin StateAndTransitionNames27
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution3_OrthogonalRegionsGuardState"
            // at 07-22-2015 22:05:18 using StaMaShapes Version 2300
            const string StateA   = "StateA";
            const string Transi3  = "Transi3";
            const string StateA1A = "StateA1A";
            const string Transi2  = "Transi2";
            const string StateA1B = "StateA1B";
            const string StateA2A = "StateA2A";
            const string Transi1  = "Transi1";
            const string StateA2B = "StateA2B";
            const string StateA2C = "StateA2C";
            //## End StateAndTransitionNames27

            //## Begin StateAndTransitionNames26
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution3_OrthogonalRegionsGuardState"
            // at 07-22-2015 22:05:17 using StaMaShapes Version 2300
            const string Event3 = "Event3";
            const string Event2 = "Event2";
            const string Event1 = "Event1";
            //## End StateAndTransitionNames26

            //## Begin StateAndTransitionNames29
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution3_OrthogonalRegionsGuardState"
            // at 07-22-2015 22:05:18 using StaMaShapes Version 2300
            const string EnterA   = "EnterA";
            const string ExitA    = "ExitA";
            const string EnterA1A = "EnterA1A";
            const string ExitA1A  = "ExitA1A";
            const string EnterA1B = "EnterA1B";
            const string ExitA1B  = "ExitA1B";
            const string EnterA2A = "EnterA2A";
            const string ExitA2A  = "ExitA2A";
            const string EnterA2B = "EnterA2B";
            const string ExitA2B  = "ExitA2B";
            const string EnterA2C = "EnterA2C";
            const string ExitA2C  = "ExitA2C";
            //## End StateAndTransitionNames29

            ActionRecorder recorder = new ActionRecorder();

            StateMachineTemplate t = new StateMachineTemplate(StateMachineOptions.UseDoActions);

            //## Begin StateMachineTemplate28
            // Generated from <file:S:\StaMa_State_Machine_Controller_Library\StaMaShapesMaster.vst> page "UT_Execution3_OrthogonalRegionsGuardState"
            // at 07-22-2015 22:05:18 using StaMaShapes Version 2300
            t.Region(StateA, false);
            t.State(StateA, recorder.CreateAction(EnterA), recorder.CreateAction(ExitA));
            t.Transition(Transi3, new string[] { StateA1B, StateA2B }, StateA2C, Event3, null, null);
            t.Region(StateA1A, false);
            t.State(StateA1A, recorder.CreateAction(EnterA1A), recorder.CreateAction(ExitA1A));
            t.Transition(Transi2, new string[] { StateA1A, StateA2B }, StateA1B, Event2, null, null);
            t.EndState();
            t.State(StateA1B, recorder.CreateAction(EnterA1B), recorder.CreateAction(ExitA1B));
            t.EndState();
            t.EndRegion();
            t.Region(StateA2A, false);
            t.State(StateA2A, recorder.CreateAction(EnterA2A), recorder.CreateAction(ExitA2A));
            t.Transition(Transi1, StateA2B, Event1, null, null);
            t.EndState();
            t.State(StateA2B, recorder.CreateAction(EnterA2B), recorder.CreateAction(ExitA2B));
            t.EndState();
            t.State(StateA2C, recorder.CreateAction(EnterA2C), recorder.CreateAction(ExitA2C));
            t.EndState();
            t.EndRegion();
            t.EndState();
            t.EndRegion();
            //## End StateMachineTemplate28

            Assert.That(recorder.RecordedActions, Is.EqualTo(new String[] {}), "Precondition not met: Actions were executed during state machine creation.");

            StateMachine stateMachine = t.CreateStateMachine(this);

            foreach (TestData testData in new TestData[]
            {
                new TestData()
                {
                    EventToSend = Startup,
                    ExpectedState = t.CreateStateConfiguration(new String[] { StateA1A, StateA2A }),
                    ExpectedActions = new String[] { EnterA, EnterA1A, EnterA2A },
                },

                new TestData()
                {
                    EventToSend = Event2,
                    ExpectedState = t.CreateStateConfiguration(new string[] { StateA1A, StateA2A }),
                    ExpectedActions = new String[] { }
                },

                new TestData()
                {
                    EventToSend = Event1,
                    ExpectedState = t.CreateStateConfiguration(new string[] { StateA1A, StateA2B }),
                    ExpectedActions = new String[] { ExitA2A, EnterA2B }
                },

                new TestData()
                {
                    EventToSend = Event2,
                    ExpectedState = t.CreateStateConfiguration(new string[] { StateA1B, StateA2B }),
                    ExpectedActions = new String[] { ExitA1A, EnterA1B }
                },

                new TestData()
                {
                    EventToSend = Event3,
                    ExpectedState = t.CreateStateConfiguration(new string[] { StateA1A, StateA2C }),
                    ExpectedActions = new String[] { ExitA2B, ExitA1B, ExitA, EnterA, EnterA1A, EnterA2C }
                },

                new TestData()
                {
                    EventToSend = Finish,
                    ExpectedState = t.CreateStateConfiguration(new string[] { }),
                    ExpectedActions = new String[] { ExitA2C, ExitA1A, ExitA }
                },
            })
            {
                recorder.Clear();

                // Act
                switch (testData.EventToSend)
                {
                case Startup:
                    stateMachine.Startup();
                    break;

                case Finish:
                    stateMachine.Finish();
                    break;

                default:
                    stateMachine.SendTriggerEvent(testData.EventToSend);
                    break;
                }

                // Assert
                Assert.That(stateMachine.ActiveStateConfiguration.ToString(), Is.EqualTo(testData.ExpectedState.ToString()), testData.EventToSend + ": Active state not as expected.");
                Assert.That(recorder.RecordedActions, Is.EqualTo(testData.ExpectedActions), testData.EventToSend + ": Unexpected entry and exit actions during state machine processing.");
            }
        }