public void CommonAncestor(
            AsyncPassiveStateMachine <int, int> machine)
        {
            const int commonAncestorState       = 0;
            const int sourceState               = 1;
            const int parentOfSourceState       = 2;
            const int siblingOfSourceState      = 3;
            const int destinationState          = 4;
            const int parentOfDestinationState  = 5;
            const int siblingOfDestinationState = 6;
            const int Event = 0;

            var commonAncestorStateLeft = false;

            "establish a hierarchical state machine".x(async() =>
            {
                var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <int, int>();

                stateMachineDefinitionBuilder
                .DefineHierarchyOn(commonAncestorState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(parentOfSourceState)
                .WithSubState(parentOfDestinationState);

                stateMachineDefinitionBuilder
                .DefineHierarchyOn(parentOfSourceState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(sourceState)
                .WithSubState(siblingOfSourceState);

                stateMachineDefinitionBuilder
                .DefineHierarchyOn(parentOfDestinationState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(destinationState)
                .WithSubState(siblingOfDestinationState);

                stateMachineDefinitionBuilder
                .In(sourceState)
                .On(Event).Goto(destinationState);

                stateMachineDefinitionBuilder
                .In(commonAncestorState)
                .ExecuteOnExit(() => commonAncestorStateLeft = true);

                machine = stateMachineDefinitionBuilder
                          .WithInitialState(sourceState)
                          .Build()
                          .CreatePassiveStateMachine();

                await machine.Start();
            });

            "when firing an event resulting in a transition with a common ancestor".x(()
                                                                                      => machine.Fire(Event));

            "the state machine should remain inside common ancestor state".x(()
                                                                             => commonAncestorStateLeft
                                                                             .Should().BeFalse());
        }
Exemplo n.º 2
0
        public Elevator()
        {
            var builder = new StateMachineDefinitionBuilder <States, Events>();

            builder.DefineHierarchyOn(States.Healthy)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.OnFloor)
            .WithSubState(States.Moving);

            builder.DefineHierarchyOn(States.Moving)
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.MovingUp)
            .WithSubState(States.MovingDown);

            builder.DefineHierarchyOn(States.OnFloor)
            .WithHistoryType(HistoryType.None)
            .WithInitialSubState(States.DoorClosed)
            .WithSubState(States.DoorOpen);

            builder.In(States.Healthy)
            .ExecuteOnEntry(() => {
            })
            .On(Events.Error).Goto(States.Error);

            builder.In(States.Error)
            .On(Events.Reset).Goto(States.Healthy)
            .On(Events.Error);

            builder.In(States.OnFloor)
            .ExecuteOnEntry(this.AnnounceFloor)
            .ExecuteOnExit(Beep)
            .ExecuteOnExit(Beep)     // just beep a second time
            .On(Events.CloseDoor).Goto(States.DoorClosed)
            .On(Events.OpenDoor).Goto(States.DoorOpen)
            .On(Events.GoUp)
            .If(CheckOverload).Goto(States.MovingUp)
            .Otherwise().Execute(this.AnnounceOverload)
            .On(Events.GoDown)
            .If(CheckOverload).Goto(States.MovingDown)
            .Otherwise().Execute(this.AnnounceOverload);
            builder.In(States.Moving)
            .On(Events.Stop).Goto(States.OnFloor);

            builder.WithInitialState(States.OnFloor);

            var definition = builder
                             .Build();

            elevator = definition
                       .CreatePassiveStateMachine("Elevator");

            elevator.Start();
        }
Exemplo n.º 3
0
        public void ThrowsExceptionOnLoading_WhenSettingALastActiveStateThatIsNotASubState(string dummyName, Func <StateMachineDefinition <States, Events>, IStateMachine <States, Events> > createStateMachine)
        {
            var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <States, Events>();

            stateMachineDefinitionBuilder
            .In(States.A);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.B)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.B1)
            .WithSubState(States.B2);
            var stateMachineDefinition = stateMachineDefinitionBuilder
                                         .WithInitialState(States.A)
                                         .Build();

            var testee = createStateMachine(stateMachineDefinition);

            var loader = A.Fake <IStateMachineLoader <States> >();

            A.CallTo(() => loader.LoadHistoryStates())
            .Returns(new Dictionary <States, States>
            {
                { States.B, States.A }
            });

            Action action = () => testee.Load(loader);

            action.Should().Throw <InvalidOperationException>()
            .WithMessage(ExceptionMessages.CannotSetALastActiveStateThatIsNotASubState);
        }
Exemplo n.º 4
0
        public void DefineNonTreeHierarchy()
        {
            var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <States, Events>();

            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.A)
            .WithHistoryType(HistoryType.None)
            .WithInitialSubState(States.B);

            Action action =
                () =>
                stateMachineDefinitionBuilder
                .DefineHierarchyOn(States.C)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(States.B);

            action.Should().Throw <InvalidOperationException>();
        }
Exemplo n.º 5
0
        public void DefineHierarchySyntax()
        {
            var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <int, int>();

            stateMachineDefinitionBuilder
            .DefineHierarchyOn(1)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(2)
            .WithSubState(3)
            .WithSubState(4);
        }
        public void AddHierarchicalStatesInitialStateIsSuperStateItself()
        {
            var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <States, Events>();

            Action a = () =>
                       stateMachineDefinitionBuilder
                       .DefineHierarchyOn(States.B)
                       .WithHistoryType(HistoryType.None)
                       .WithInitialSubState(States.B)
                       .WithSubState(States.B1)
                       .WithSubState(States.B2);

            a.Should().Throw <ArgumentException>();
        }
        public void InitializationInSuperState(
            PassiveStateMachine <int, int> machine,
            CurrentStateExtension testExtension,
            bool entryActionOfLeafStateExecuted,
            bool entryActionOfSuperStateExecuted)
        {
            "establish a hierarchical state machine with super state as initial state".x(() =>
            {
                var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <int, int>();
                stateMachineDefinitionBuilder
                .DefineHierarchyOn(SuperState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(LeafState);
                stateMachineDefinitionBuilder
                .In(SuperState)
                .ExecuteOnEntry(() => entryActionOfSuperStateExecuted = true);
                stateMachineDefinitionBuilder
                .In(LeafState)
                .ExecuteOnEntry(() => entryActionOfLeafStateExecuted = true);
                machine = stateMachineDefinitionBuilder
                          .WithInitialState(SuperState)
                          .Build()
                          .CreatePassiveStateMachine();

                testExtension = new CurrentStateExtension();
                machine.AddExtension(testExtension);
            });

            "when initializing to a super state and starting the state machine".x(() =>
            {
                machine.Start();
            });

            "it should_set_current_state_of_state_machine_to_initial_leaf_state_of_the_state_to_which_it_is_initialized".x(() =>
                                                                                                                           testExtension.CurrentState
                                                                                                                           .Should().Be(LeafState));

            "it should_execute_entry_action_of_super_state_to_which_state_machine_is_initialized".x(() =>
                                                                                                    entryActionOfSuperStateExecuted
                                                                                                    .Should().BeTrue());

            "it should_execute_entry_actions_of_initial_sub_states_until_a_leaf_state_is_reached".x(() =>
                                                                                                    entryActionOfLeafStateExecuted
                                                                                                    .Should().BeTrue());
        }
        public void InitializationInLeafState(
            PassiveStateMachine <int, int> machine,
            CurrentStateExtension testExtension,
            bool entryActionOfLeafStateExecuted,
            bool entryActionOfSuperStateExecuted)
        {
            "establish a hierarchical state machine with leaf state as initial state".x(() =>
            {
                var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <int, int>();
                stateMachineDefinitionBuilder
                .DefineHierarchyOn(SuperState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(LeafState);
                stateMachineDefinitionBuilder
                .In(SuperState)
                .ExecuteOnEntry(() => entryActionOfSuperStateExecuted = true);
                stateMachineDefinitionBuilder
                .In(LeafState)
                .ExecuteOnEntry(() => entryActionOfLeafStateExecuted = true);
                machine = stateMachineDefinitionBuilder
                          .WithInitialState(LeafState)
                          .Build()
                          .CreatePassiveStateMachine();

                testExtension = new CurrentStateExtension();
                machine.AddExtension(testExtension);
            });

            "when starting the state machine".x(() =>
            {
                machine.Start();
            });

            "it should set current state of state machine to state to which it is initialized".x(() =>
                                                                                                 testExtension.CurrentState
                                                                                                 .Should().Be(LeafState));

            "it should execute entry action of state to which state machine is initialized".x(() =>
                                                                                              entryActionOfLeafStateExecuted
                                                                                              .Should().BeTrue());

            "it should execute entry action of super states of the state to which state machine is initialized".x(() =>
                                                                                                                  entryActionOfSuperStateExecuted
                                                                                                                  .Should().BeTrue());
        }
Exemplo n.º 9
0
        public void BeforeExecutingEntryActionsHierarchical(
            AsyncPassiveStateMachine <string, string> machine,
            IExtension <string, string> extension)
        {
            "establish an extension".x(()
                                       => extension = A.Fake <IExtension <string, string> >());

            "establish a hierarchical state machine using the extension".x(async() =>
            {
                var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <string, string>();
                stateMachineDefinitionBuilder
                .DefineHierarchyOn("A")
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState("A0");
                stateMachineDefinitionBuilder
                .In("0")
                .On("A0")
                .Goto("A0");
                machine = stateMachineDefinitionBuilder
                          .WithInitialState("0")
                          .Build()
                          .CreatePassiveStateMachine(Name);

                machine.AddExtension(extension);

                await machine.Start();
            });

            "when firing an event onto the state machine".x(()
                                                            => machine.Fire("A0"));

            "it should call EnteringState on registered extensions for entered super states of target state".x(()
                                                                                                               => A.CallTo(() => extension.EnteringState(
                                                                                                                               A <IStateMachineInformation <string, string> > .That.Matches(x => x.Name == Name && x.CurrentStateId.ExtractOrThrow() == "A0"),
                                                                                                                               A <IStateDefinition <string, string> > .That.Matches(x => x.Id == "A"),
                                                                                                                               A <ITransitionContext <string, string> > .That.Matches(x => x.EventId.Value == "A0")))
                                                                                                               .MustHaveHappened());

            "it should call EnteringState on registered extensions for entered leaf target state".x(()
                                                                                                    => A.CallTo(() => extension.EnteringState(
                                                                                                                    A <IStateMachineInformation <string, string> > .That.Matches(x => x.Name == Name && x.CurrentStateId.ExtractOrThrow() == "A0"),
                                                                                                                    A <IStateDefinition <string, string> > .That.Matches(x => x.Id == "A0"),
                                                                                                                    A <ITransitionContext <string, string> > .That.Matches(x => x.EventId.Value == "A0")))
                                                                                                    .MustHaveHappened());
        }
Exemplo n.º 10
0
        public void SetsHistoryStatesOnLoadingFromPersistedState()
        {
            var exitedD2 = false;

            var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <States, Events>();

            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.D)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.D1)
            .WithSubState(States.D2);
            stateMachineDefinitionBuilder
            .In(States.A)
            .On(Events.D).Goto(States.D)
            .On(Events.A);
            stateMachineDefinitionBuilder
            .In(States.D2)
            .ExecuteOnExit(() => exitedD2 = true)
            .On(Events.A).Goto(States.A);
            var testee = stateMachineDefinitionBuilder
                         .WithInitialState(States.A)
                         .Build()
                         .CreatePassiveStateMachine();

            var loader = A.Fake <IStateMachineLoader <States, Events> >();

            A.CallTo(() => loader.LoadHistoryStates())
            .Returns(new Dictionary <States, States>
            {
                { States.D, States.D2 }
            });
            A.CallTo(() => loader.LoadCurrentState())
            .Returns(Initializable <States> .UnInitialized());

            testee.Load(loader);
            testee.Start();
            testee.Fire(Events.D); // should go to loaded last active state D2, not initial state D1
            exitedD2 = false;
            testee.Fire(Events.A);

            testee.Stop();

            exitedD2.Should().BeTrue();
        }
Exemplo n.º 11
0
 private static void SetupStates(StateMachineDefinitionBuilder <State, Event> builder)
 {
     builder
     .In(State.A)
     .On(Event.S2).Goto(State.S2)
     .On(Event.X);
     builder
     .In(State.B)
     .On(Event.S).Goto(State.S)
     .On(Event.X);
     builder
     .DefineHierarchyOn(State.S)
     .WithHistoryType(HistoryType.Deep)
     .WithInitialSubState(State.S1)
     .WithSubState(State.S2);
     builder
     .In(State.S)
     .On(Event.B).Goto(State.B);
 }
Exemplo n.º 12
0
        public void FireEvent(string dummyName, Func <StateMachineDefinition <States, Events>, IStateMachine <States, Events> > createStateMachine)
        {
            var exceptions = new List <EventArgs>();
            var transitionBeginMessages     = new List <TransitionEventArgs <States, Events> >();
            var transitionCompletedMessages = new List <TransitionCompletedEventArgs <States, Events> >();
            var transitionDeclinedMessages  = new List <TransitionEventArgs <States, Events> >();

            var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <States, Events>();

            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.B)
            .WithHistoryType(HistoryType.None)
            .WithInitialSubState(States.B1)
            .WithSubState(States.B2);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.C)
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.C1)
            .WithSubState(States.C2);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.C1)
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.C1A)
            .WithSubState(States.C1B);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.D)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.D1)
            .WithSubState(States.D2);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.D1)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.D1A)
            .WithSubState(States.D1B);
            stateMachineDefinitionBuilder
            .In(States.A)
            .On(Events.B).Goto(States.B);
            var stateMachineDefinition = stateMachineDefinitionBuilder
                                         .WithInitialState(States.A)
                                         .Build();

            var testee = createStateMachine(stateMachineDefinition);

            testee.TransitionExceptionThrown += (sender, e) => exceptions.Add(e);
            testee.TransitionBegin           += (sender, e) => transitionBeginMessages.Add(e);
            testee.TransitionCompleted       += (sender, e) => transitionCompletedMessages.Add(e);
            testee.TransitionDeclined        += (sender, e) => transitionDeclinedMessages.Add(e);

            var allTransitionsCompleted = SetUpWaitForAllTransitions(testee, 1);

            object eventArgument = "test";

            testee.Start();

            testee.Fire(Events.B, eventArgument);

            WaitForAllTransitions(allTransitionsCompleted);

            transitionBeginMessages.Should().HaveCount(1);
            transitionBeginMessages.Single().StateId.Should().Be(States.A);
            transitionBeginMessages.Single().EventId.Should().Be(Events.B);
            transitionBeginMessages.Single().EventArgument.Should().Be(eventArgument);

            transitionCompletedMessages.Should().HaveCount(1);
            transitionCompletedMessages.Single().StateId.Should().Be(States.A);
            transitionCompletedMessages.Single().EventId.Should().Be(Events.B);
            transitionCompletedMessages[0].EventArgument.Should().Be(eventArgument);
            transitionCompletedMessages.Single().NewStateId.Should().Be(States.B1);

            exceptions.Should().BeEmpty();
            transitionDeclinedMessages.Should().BeEmpty();

            testee.Stop();
        }
Exemplo n.º 13
0
        public Elevator()
        {
            var builder = new StateMachineDefinitionBuilder <States, Events>();

            builder.DefineHierarchyOn(States.Healthy)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.OnFloor)
            .WithSubState(States.Moving);

            builder.DefineHierarchyOn(States.Moving)
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.MovingUp)
            .WithSubState(States.MovingDown);

            builder.DefineHierarchyOn(States.OnFloor)
            .WithHistoryType(HistoryType.None)
            .WithInitialSubState(States.DoorClosed)
            .WithSubState(States.DoorOpen);

            builder.In(States.Healthy)
            .On(Events.Error).Goto(States.Error);

            builder.In(States.Error)
            .On(Events.Reset).Goto(States.Healthy)
            .On(Events.Error);

            builder.In(States.OnFloor)
            .On(Events.CloseDoor).Goto(States.DoorClosed)
            .On(Events.OpenDoor).Goto(States.DoorOpen)
            .On(Events.GoUp).Goto(States.MovingUp)
            .On(Events.GoDown).Goto(States.MovingDown);

            builder.In(States.Moving)
            .On(Events.Stop).Goto(States.OnFloor);

            builder.In(States.Healthy).ExecuteOnEntry(
                () =>
            {
                AddMessage("Entry States.Healthy");
            });

            builder.In(States.DoorClosed).ExecuteOnEntry(
                () =>
            {
                AddMessage("Entry States.DoorClosed");
            });

            builder.In(States.DoorOpen).ExecuteOnEntry(
                () =>
            {
                AddMessage("Entry States.DoorOpen");
            });

            builder.In(States.Error).ExecuteOnEntry(
                () =>
            {
                AddMessage("Entry States.Error");
            });

            builder.In(States.Moving).ExecuteOnEntry(
                () =>
            {
                AddMessage("Entry States.Moving");
            });

            builder.In(States.MovingDown).ExecuteOnEntry(
                () =>
            {
                AddMessage("Entry States.MovingDown");
            });

            builder.In(States.MovingUp).ExecuteOnEntry(
                () =>
            {
                AddMessage("Entry States.MovingUp");
            });

            builder.In(States.OnFloor).ExecuteOnEntry(
                () =>
            {
                AddMessage("Entry States.OnFloor");
            });



            builder.WithInitialState(States.OnFloor);

            var definition = builder
                             .Build();

            elevator = definition
                       .CreatePassiveStateMachine("Elevator");

            elevator.Start();
        }
        public void YEdGraphMl(string dummyName, Func <string, StateMachineDefinition <States, Events>, IAsyncStateMachine <States, Events> > createStateMachine)
        {
            var builder = new StateMachineDefinitionBuilder <States, Events>();

            builder
            .DefineHierarchyOn(States.Healthy)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.OnFloor)
            .WithSubState(States.Moving);
            builder
            .DefineHierarchyOn(States.Moving)
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.MovingUp)
            .WithSubState(States.MovingDown);
            builder
            .DefineHierarchyOn(States.OnFloor)
            .WithHistoryType(HistoryType.None)
            .WithInitialSubState(States.DoorClosed)
            .WithSubState(States.DoorOpen);
            builder
            .In(States.Healthy)
            .On(Events.ErrorOccured).Goto(States.Error);
            builder
            .In(States.Error)
            .On(Events.Reset).Goto(States.Healthy)
            .On(Events.ErrorOccured);
            builder
            .In(States.OnFloor)
            .ExecuteOnEntry(AnnounceFloor)
            .ExecuteOnExit(Beep)
            .ExecuteOnExit(Beep)
            .On(Events.CloseDoor).Goto(States.DoorClosed)
            .On(Events.OpenDoor).Goto(States.DoorOpen)
            .On(Events.GoUp)
            .If(CheckOverload).Goto(States.MovingUp)
            .Otherwise()
            .Execute(AnnounceOverload)
            .Execute(Beep)
            .On(Events.GoDown)
            .If(CheckOverload).Goto(States.MovingDown)
            .Otherwise().Execute(AnnounceOverload);
            builder
            .In(States.Moving)
            .On(Events.Stop).Goto(States.OnFloor);

            var stateMachineDefinition = builder
                                         .WithInitialState(States.OnFloor)
                                         .Build();

            var elevator = createStateMachine("Elevator", stateMachineDefinition);

            var stream     = new MemoryStream();
            var textWriter = new StreamWriter(stream);
            var testee     = new YEdStateMachineReportGenerator <States, Events>(textWriter);

            elevator.Report(testee);

            stream.Position = 0;
            var reader = new StreamReader(stream);
            var report = reader.ReadToEnd();

            const string ExpectedReport = "<?xml version=\"1.0\" encoding=\"utf-8\"?><graphml xmlns:y=\"http://www.yworks.com/xml/graphml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:yed=\"http://www.yworks.com/xml/yed/3\" xmlns:schemaLocation=\"http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd\" xmlns=\"http://graphml.graphdrawing.org/xmlns\">  <!--Created by Appccelerate.StateMachine.YEdStateMachineReportGenerator-->  <key for=\"graphml\" id=\"d0\" yfiles.type=\"resources\" />  <key for=\"port\" id=\"d1\" yfiles.type=\"portgraphics\" />  <key for=\"port\" id=\"d2\" yfiles.type=\"portgeometry\" />  <key for=\"port\" id=\"d3\" yfiles.type=\"portuserdata\" />  <key attr.name=\"url\" attr.type=\"string\" for=\"node\" id=\"d4\" />  <key attr.name=\"description\" attr.type=\"string\" for=\"node\" id=\"d5\" />  <key for=\"node\" id=\"d6\" yfiles.type=\"nodegraphics\" />  <key attr.name=\"Beschreibung\" attr.type=\"string\" for=\"graph\" id=\"d7\">    <default />  </key>  <key attr.name=\"url\" attr.type=\"string\" for=\"edge\" id=\"d8\" />  <key attr.name=\"description\" attr.type=\"string\" for=\"edge\" id=\"d9\" />  <key for=\"edge\" id=\"d10\" yfiles.type=\"edgegraphics\" />  <graph edgedefault=\"directed\" id=\"G\">    <node id=\"Healthy\">      <data key=\"d6\">        <y:ProxyAutoBoundsNode>          <y:Realizers active=\"0\">            <y:GroupNode>              <y:NodeLabel alignment=\"right\" autoSizePolicy=\"node_width\" backgroundColor=\"#EBEBEB\" modelName=\"internal\" modelPosition=\"t\">Healthy</y:NodeLabel>              <y:State closed=\"false\" innerGraphDisplayEnabled=\"true\" />            </y:GroupNode>          </y:Realizers>        </y:ProxyAutoBoundsNode>      </data>      <graph edgedefault=\"directed\" id=\"Healthy:\">        <node id=\"OnFloor\">          <data key=\"d6\">            <y:ProxyAutoBoundsNode>              <y:Realizers active=\"0\">                <y:GroupNode>                  <y:NodeLabel alignment=\"right\" autoSizePolicy=\"node_width\" backgroundColor=\"#EBEBEB\" modelName=\"internal\" modelPosition=\"t\">(AnnounceFloor)OnFloor(Beep, Beep)</y:NodeLabel>                  <y:State closed=\"false\" innerGraphDisplayEnabled=\"true\" />                  <y:BorderStyle width=\"2.0\" />                </y:GroupNode>              </y:Realizers>            </y:ProxyAutoBoundsNode>          </data>          <graph edgedefault=\"directed\" id=\"OnFloor:\">            <node id=\"DoorClosed\">              <data key=\"d6\">                <y:ShapeNode>                  <y:NodeLabel>DoorClosed</y:NodeLabel>                  <y:Shape type=\"ellipse\" />                  <y:BorderStyle width=\"2.0\" />                </y:ShapeNode>              </data>            </node>            <node id=\"DoorOpen\">              <data key=\"d6\">                <y:ShapeNode>                  <y:NodeLabel>DoorOpen</y:NodeLabel>                  <y:Shape type=\"ellipse\" />                </y:ShapeNode>              </data>            </node>          </graph>        </node>        <node id=\"Moving\">          <data key=\"d6\">            <y:ProxyAutoBoundsNode>              <y:Realizers active=\"0\">                <y:GroupNode>                  <y:NodeLabel alignment=\"right\" autoSizePolicy=\"node_width\" backgroundColor=\"#EBEBEB\" modelName=\"internal\" modelPosition=\"t\">Moving</y:NodeLabel>                  <y:State closed=\"false\" innerGraphDisplayEnabled=\"true\" />                </y:GroupNode>              </y:Realizers>            </y:ProxyAutoBoundsNode>          </data>          <graph edgedefault=\"directed\" id=\"Moving:\">            <node id=\"MovingUp\">              <data key=\"d6\">                <y:ShapeNode>                  <y:NodeLabel>MovingUp</y:NodeLabel>                  <y:Shape type=\"ellipse\" />                  <y:BorderStyle width=\"2.0\" />                </y:ShapeNode>              </data>            </node>            <node id=\"MovingDown\">              <data key=\"d6\">                <y:ShapeNode>                  <y:NodeLabel>MovingDown</y:NodeLabel>                  <y:Shape type=\"ellipse\" />                </y:ShapeNode>              </data>            </node>          </graph>        </node>      </graph>    </node>    <node id=\"Error\">      <data key=\"d6\">        <y:ShapeNode>          <y:NodeLabel>Error</y:NodeLabel>          <y:Shape type=\"ellipse\" />        </y:ShapeNode>      </data>    </node>    <edge id=\"ErrorOccured0\" source=\"Healthy\" target=\"Error\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"line\" />          <y:Arrows source=\"none\" target=\"standard\" />          <y:EdgeLabel>ErrorOccured</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"CloseDoor1\" source=\"OnFloor\" target=\"DoorClosed\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"line\" />          <y:Arrows source=\"none\" target=\"standard\" />          <y:EdgeLabel>CloseDoor</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"OpenDoor2\" source=\"OnFloor\" target=\"DoorOpen\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"line\" />          <y:Arrows source=\"none\" target=\"standard\" />          <y:EdgeLabel>OpenDoor</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"GoUp3\" source=\"OnFloor\" target=\"MovingUp\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"line\" />          <y:Arrows source=\"none\" target=\"standard\" />          <y:EdgeLabel>[CheckOverload]GoUp</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"GoUp4\" source=\"OnFloor\" target=\"OnFloor\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"dashed\" />          <y:Arrows source=\"none\" target=\"plain\" />          <y:EdgeLabel>GoUp(AnnounceOverload, Beep)</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"GoDown5\" source=\"OnFloor\" target=\"MovingDown\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"line\" />          <y:Arrows source=\"none\" target=\"standard\" />          <y:EdgeLabel>[CheckOverload]GoDown</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"GoDown6\" source=\"OnFloor\" target=\"OnFloor\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"dashed\" />          <y:Arrows source=\"none\" target=\"plain\" />          <y:EdgeLabel>GoDown(AnnounceOverload)</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"Stop7\" source=\"Moving\" target=\"OnFloor\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"line\" />          <y:Arrows source=\"none\" target=\"standard\" />          <y:EdgeLabel>Stop</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"Reset8\" source=\"Error\" target=\"Healthy\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"line\" />          <y:Arrows source=\"none\" target=\"standard\" />          <y:EdgeLabel>Reset</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>    <edge id=\"ErrorOccured9\" source=\"Error\" target=\"Error\">      <data key=\"d10\">        <y:PolyLineEdge>          <y:LineStyle type=\"dashed\" />          <y:Arrows source=\"none\" target=\"plain\" />          <y:EdgeLabel>ErrorOccured</y:EdgeLabel>        </y:PolyLineEdge>      </data>    </edge>  </graph>  <data key=\"d0\">    <y:Resources />  </data></graphml>";

            var cleanedReport = report.Replace("\n", string.Empty).Replace("\r", string.Empty);

            cleanedReport
            .Should()
            .Be(
                ExpectedReport
                .IgnoringNewlines());
        }
Exemplo n.º 15
0
        public void Report(string dummyName, Func <string, StateMachineDefinition <States, Events>, IStateMachine <States, Events> > createStateMachine)
        {
            var stateStream       = new MemoryStream();
            var transitionsStream = new MemoryStream();

            var testee = new CsvStateMachineReportGenerator <States, Events>(stateStream, transitionsStream);

            var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <States, Events>();

            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.Healthy)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.OnFloor)
            .WithSubState(States.Moving);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.Moving)
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.MovingUp)
            .WithSubState(States.MovingDown);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.OnFloor)
            .WithHistoryType(HistoryType.None)
            .WithInitialSubState(States.DoorClosed)
            .WithSubState(States.DoorOpen);
            stateMachineDefinitionBuilder
            .In(States.Healthy)
            .On(Events.ErrorOccurred).Goto(States.Error);
            stateMachineDefinitionBuilder
            .In(States.Error)
            .On(Events.Reset).Goto(States.Healthy)
            .On(Events.ErrorOccurred);
            stateMachineDefinitionBuilder
            .In(States.OnFloor)
            .ExecuteOnEntry(AnnounceFloor)
            .ExecuteOnExit(Beep)
            .ExecuteOnExit(Beep)
            .On(Events.CloseDoor).Goto(States.DoorClosed)
            .On(Events.OpenDoor).Goto(States.DoorOpen)
            .On(Events.GoUp)
            .If(CheckOverload)
            .Goto(States.MovingUp)
            .Otherwise()
            .Execute(AnnounceOverload)
            .Execute(Beep)
            .On(Events.GoDown)
            .If(CheckOverload)
            .Goto(States.MovingDown)
            .Otherwise()
            .Execute(AnnounceOverload);
            stateMachineDefinitionBuilder
            .In(States.Moving)
            .On(Events.Stop).Goto(States.OnFloor);
            var stateMachineDefinition = stateMachineDefinitionBuilder
                                         .WithInitialState(States.OnFloor)
                                         .Build();

            var elevator = createStateMachine("Elevator", stateMachineDefinition);

            elevator.Report(testee);

            string statesReport;
            string transitionsReport;

            stateStream.Position = 0;
            using (var reader = new StreamReader(stateStream))
            {
                statesReport = reader.ReadToEnd();
            }

            transitionsStream.Position = 0;
            using (var reader = new StreamReader(transitionsStream))
            {
                transitionsReport = reader.ReadToEnd();
            }

            const string ExpectedTransitionsReport = "Source;Event;Guard;Target;ActionsHealthy;ErrorOccurred;;Error;OnFloor;CloseDoor;;DoorClosed;OnFloor;OpenDoor;;DoorOpen;OnFloor;GoUp;CheckOverload;MovingUp;OnFloor;GoUp;;internal transition;AnnounceOverload, BeepOnFloor;GoDown;CheckOverload;MovingDown;OnFloor;GoDown;;internal transition;AnnounceOverloadMoving;Stop;;OnFloor;Error;Reset;;Healthy;Error;ErrorOccurred;;internal transition;";
            const string ExpectedStatesReport      = "Source;Entry;Exit;ChildrenHealthy;;;OnFloor, MovingOnFloor;AnnounceFloor;Beep, Beep;DoorClosed, DoorOpenMoving;;;MovingUp, MovingDownMovingUp;;;MovingDown;;;DoorClosed;;;DoorOpen;;;Error;;;";

            statesReport
            .IgnoringNewlines()
            .Should()
            .Be(
                ExpectedStatesReport
                .IgnoringNewlines());

            transitionsReport
            .IgnoringNewlines()
            .Should()
            .Be(
                ExpectedTransitionsReport
                .IgnoringNewlines());

            stateStream.Dispose();
        }
Exemplo n.º 16
0
        public static void ini()
        {
            var builder = new StateMachineDefinitionBuilder <States, Events>();

            /*
             *  None: The state enters into its initial sub state. The sub state itself enters its initial sub state and so on until the innermost nested state is reached.
             *  Deep: The state enters into its last active sub state. The sub state itself enters into its last active state and so on until the innermost nested state is reached.
             *  Shallow: The state enters into its last active sub state. The sub state itself enters its initial sub state and so on until the innermost nested state is reached.
             */
            builder.DefineHierarchyOn(States.Program_Ready)      // 准备编程
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.Program_Start)           // 开始编程
            .WithSubState(States.Program_Camera_Ready)           // 准备相机
            .WithSubState(States.Program_Camera_Runing)          // 拍摄
            .WithSubState(States.Program_Cmaera_Completed)       // 拍摄完成
            .WithSubState(States.Program_Completed);             // 编程完成

            builder.DefineHierarchyOn(States.Program_Test_Ready) // 准备测试
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.Work_Ready)              // 准备运行
            .WithSubState(States.Program_Test_Completed);        // 测试完成

            builder.DefineHierarchyOn(States.Work_Ready)         // 准备运行
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.Work_Start)              // 开始运行
            .WithSubState(States.Work_Camera_Ready)              // 准备相机
            .WithSubState(States.Work_Camera_Runing)             // 拍摄
            .WithSubState(States.Work_Camera_Completed)          // 相机拍摄完成
            .WithSubState(States.Work_Done);                     // 一次运行完成


            builder.In(States.WaitingFor)                       // 登录完成后
            .On(Events.OnNewProject).Goto(States.Program_Ready) // 准备编程
            .On(Events.OnWork).Goto(States.Work_Ready);         // 准备运行

            builder.In(States.Program_Completed)                // 编程完成后
            .On(Events.OnTest).Goto(States.Program_Test_Ready)  // 准备测试
            .On(Events.OnWork).Goto(States.Work_Ready);         // 准备运行

            #region 异常 停止 恢复
            builder.In(States.Program_Ready)
            .On(Events.OnError).Goto(States.Error)
            .On(Events.OnStop).Goto(States.Stoped)
            .On(Events.OnResume).Goto(States.Program_Ready);

            builder.In(States.Program_Test_Ready)
            .On(Events.OnError).Goto(States.Error)
            .On(Events.OnStop).Goto(States.Stoped)
            .On(Events.OnResume).Goto(States.Program_Test_Ready);

            builder.In(States.Work_Ready)
            .On(Events.OnError).Goto(States.Program_Ready)
            .On(Events.OnStop).Goto(States.Stoped)
            .On(Events.OnResume).Goto(States.Work_Ready);
            #endregion

            builder.In(States.None)
            //.ExecuteOnEntry(logineddddddd)
            //.ExecuteOnExit(logineddddddd)
            //.ExecuteOnExit(Beep) // just beep a second time

            .On(Events.OnLogin).Goto(States.Logined).Execute(logineddddddd);
            //.On(Events.OnLogin).If<string>(Login.translation).Goto(States.Logined).Execute(logineddddddd)
            //.Otherwise().Execute(logine2ddddddd);
            //.On(Events.OnAutoCkeck)
            //    .If().Goto(States.WaitingFor)
            //    .Otherwise().Goto(States.Logined).Execute(this.AnnounceCheckFail);



            builder.WithInitialState(States.None);

            var definition = builder
                             .Build();

            machine = definition
                      .CreatePassiveStateMachine("Elevator");

            machine.Start();
        }
Exemplo n.º 17
0
        public void Report(string dummyName, Func <string, StateMachineDefinition <States, Events>, IStateMachine <States, Events> > createStateMachine)
        {
            var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <States, Events>();

            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.B)
            .WithHistoryType(HistoryType.None)
            .WithInitialSubState(States.B1)
            .WithSubState(States.B2);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.C)
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.C1)
            .WithSubState(States.C2);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.C1)
            .WithHistoryType(HistoryType.Shallow)
            .WithInitialSubState(States.C1A)
            .WithSubState(States.C1B);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.D)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.D1)
            .WithSubState(States.D2);
            stateMachineDefinitionBuilder
            .DefineHierarchyOn(States.D1)
            .WithHistoryType(HistoryType.Deep)
            .WithInitialSubState(States.D1A)
            .WithSubState(States.D1B);
            stateMachineDefinitionBuilder
            .In(States.A)
            .ExecuteOnEntry(EnterA)
            .ExecuteOnExit(ExitA)
            .On(Events.A)
            .On(Events.B).Goto(States.B)
            .On(Events.C).If(AlwaysTrue).Goto(States.C1)
            .On(Events.C).If(AlwaysFalse).Goto(States.C2);
            stateMachineDefinitionBuilder
            .In(States.B)
            .On(Events.A).Goto(States.A).Execute(Action);
            stateMachineDefinitionBuilder
            .In(States.B1)
            .On(Events.B2).Goto(States.B1);
            stateMachineDefinitionBuilder
            .In(States.B2)
            .On(Events.B1).Goto(States.B2);
            var stateMachineDefinition = stateMachineDefinitionBuilder
                                         .WithInitialState(States.A)
                                         .Build();

            var stateMachine = createStateMachine("Test Machine", stateMachineDefinition);

            var testee = new StateMachineReportGenerator <States, Events>();

            stateMachine.Report(testee);

            var actualReport = testee.Result;

            const string ExpectedReport =
                @"Test Machine: initial state = A
    B: initial state = B1 history type = None
        entry action: 
        exit action: 
        A -> A actions: Action guard: 
        B1: initial state = None history type = None
            entry action: 
            exit action: 
            B2 -> B1 actions:  guard: 
        B2: initial state = None history type = None
            entry action: 
            exit action: 
            B1 -> B2 actions:  guard: 
    C: initial state = C1 history type = Shallow
        entry action: 
        exit action: 
        C1: initial state = C1A history type = Shallow
            entry action: 
            exit action: 
            C1A: initial state = None history type = None
                entry action: 
                exit action: 
            C1B: initial state = None history type = None
                entry action: 
                exit action: 
        C2: initial state = None history type = None
            entry action: 
            exit action: 
    D: initial state = D1 history type = Deep
        entry action: 
        exit action: 
        D1: initial state = D1A history type = Deep
            entry action: 
            exit action: 
            D1A: initial state = None history type = None
                entry action: 
                exit action: 
            D1B: initial state = None history type = None
                entry action: 
                exit action: 
        D2: initial state = None history type = None
            entry action: 
            exit action: 
    A: initial state = None history type = None
        entry action: EnterA
        exit action: ExitA
        A -> internal actions:  guard: 
        B -> B actions:  guard: 
        C -> C1 actions:  guard: AlwaysTrue
        C -> C2 actions:  guard: AlwaysFalse
";

            actualReport
            .IgnoringNewlines()
            .Should()
            .Be(
                ExpectedReport
                .IgnoringNewlines());
        }
Exemplo n.º 18
0
        public void NoCommonAncestor(
            PassiveStateMachine <string, int> machine)
        {
            const string SourceState                   = "SourceState";
            const string ParentOfSourceState           = "ParentOfSourceState";
            const string SiblingOfSourceState          = "SiblingOfSourceState";
            const string DestinationState              = "DestinationState";
            const string ParentOfDestinationState      = "ParentOfDestinationState";
            const string SiblingOfDestinationState     = "SiblingOfDestinationState";
            const string GrandParentOfSourceState      = "GrandParentOfSourceState";
            const string GrandParentOfDestinationState = "GrandParentOfDestinationState";
            const int    Event = 0;

            var log = string.Empty;

            "establish a hierarchical state machine".x(() =>
            {
                var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <string, int>();
                stateMachineDefinitionBuilder
                .DefineHierarchyOn(ParentOfSourceState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(SourceState)
                .WithSubState(SiblingOfSourceState);
                stateMachineDefinitionBuilder
                .DefineHierarchyOn(ParentOfDestinationState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(DestinationState)
                .WithSubState(SiblingOfDestinationState);
                stateMachineDefinitionBuilder
                .DefineHierarchyOn(GrandParentOfSourceState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(ParentOfSourceState);
                stateMachineDefinitionBuilder
                .DefineHierarchyOn(GrandParentOfDestinationState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(ParentOfDestinationState);
                stateMachineDefinitionBuilder
                .In(SourceState)
                .ExecuteOnExit(() => log += "exit" + SourceState)
                .On(Event).Goto(DestinationState);
                stateMachineDefinitionBuilder
                .In(ParentOfSourceState)
                .ExecuteOnExit(() => log += "exit" + ParentOfSourceState);
                stateMachineDefinitionBuilder
                .In(DestinationState)
                .ExecuteOnEntry(() => log += "enter" + DestinationState);
                stateMachineDefinitionBuilder
                .In(ParentOfDestinationState)
                .ExecuteOnEntry(() => log += "enter" + ParentOfDestinationState);
                stateMachineDefinitionBuilder
                .In(GrandParentOfSourceState)
                .ExecuteOnExit(() => log += "exit" + GrandParentOfSourceState);
                stateMachineDefinitionBuilder
                .In(GrandParentOfDestinationState)
                .ExecuteOnEntry(() => log += "enter" + GrandParentOfDestinationState);
                machine = stateMachineDefinitionBuilder
                          .WithInitialState(SourceState)
                          .Build()
                          .CreatePassiveStateMachine();

                machine.Start();
            });

            "when firing an event resulting in a transition without a common ancestor".x(() =>
                                                                                         machine.Fire(Event));

            "it should execute exit action of source state".x(() =>
                                                              log.Should().Contain("exit" + SourceState));

            "it should execute exit action of parents of source state (recursively)".x(() =>
                                                                                       log
                                                                                       .Should().Contain("exit" + ParentOfSourceState)
                                                                                       .And.Contain("exit" + GrandParentOfSourceState));

            "it should execute entry action of parents of destination state (recursively)".x(() =>
                                                                                             log
                                                                                             .Should().Contain("enter" + ParentOfDestinationState)
                                                                                             .And.Contain("enter" + GrandParentOfDestinationState));

            "it should execute entry action of destination state".x(() =>
                                                                    log.Should().Contain("enter" + DestinationState));

            "it should execute actions from source upwards and then downwards to destination state".x(() =>
            {
                string[] states =
                {
                    SourceState,
                    ParentOfSourceState,
                    GrandParentOfSourceState,
                    GrandParentOfDestinationState,
                    ParentOfDestinationState,
                    DestinationState
                };

                var statesInOrderOfAppearanceInLog = states
                                                     .OrderBy(s => log.IndexOf(s.ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal));
                statesInOrderOfAppearanceInLog
                .Should().Equal(states);
            });
        }