Exemple #1
0
        public void ExitActionWithParameter(
            PassiveStateMachine <int, int> machine,
            string parameter)
        {
            const string Parameter = "parameter";

            "establish a state machine with exit action with parameter on a state"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.In(State)
                .ExecuteOnExitParametrized(p => parameter = p, Parameter)
                .On(Event).Goto(AnotherState);
            });

            "when leaving the state"._(() =>
            {
                machine.Initialize(State);
                machine.Start();
                machine.Fire(Event);
            });

            "it should execute the exit action"._(() =>
                                                  parameter.Should().NotBeNull());

            "it should pass parameter to the exit action"._(() =>
                                                            parameter.Should().Be(Parameter));
        }
Exemple #2
0
        public void MultipleExitActions(
            PassiveStateMachine <int, int> machine,
            bool exitAction1Executed,
            bool exitAction2Executed)
        {
            "establish a state machine with several exit actions on a state"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.In(State)
                .ExecuteOnExit(() => exitAction1Executed = true)
                .ExecuteOnExit(() => exitAction2Executed = true)
                .On(Event).Goto(AnotherState);
            });

            "when leaving the state"._(() =>
            {
                machine.Initialize(State);
                machine.Start();
                machine.Fire(Event);
            });

            "It should execute all exit actions"._(() =>
            {
                exitAction1Executed
                .Should().BeTrue("first action should be executed");

                exitAction2Executed
                .Should().BeTrue("second action should be executed");
            });
        }
Exemple #3
0
        public void EventsQueueing(
            IStateMachine <string, int> machine)
        {
            const int FirstEvent  = 0;
            const int SecondEvent = 1;

            bool arrived = false;

            "establish a passive state machine with transitions"._(() =>
            {
                machine = new PassiveStateMachine <string, int>();

                machine.In("A").On(FirstEvent).Goto("B");
                machine.In("B").On(SecondEvent).Goto("C");
                machine.In("C").ExecuteOnEntry(() => arrived = true);

                machine.Initialize("A");
            });

            "when firing an event onto the state machine"._(() =>
            {
                machine.Fire(FirstEvent);
                machine.Fire(SecondEvent);
                machine.Start();
            });

            "it should queue event at the end"._(() =>
                                                 arrived.Should().BeTrue("state machine should arrive at destination state"));
        }
        public void EntryActionWithParameter(
            PassiveStateMachine <int, int> machine,
            string parameter)
        {
            const string Parameter = "parameter";

            "establish a state machine with entry action with parameter on a state"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.In(State)
                .ExecuteOnEntryParametrized(p => parameter = p, Parameter);
            });

            "when entering the state"._(() =>
            {
                machine.Initialize(State);
                machine.Start();
            });

            "it should execute the entry action"._(() =>
                                                   parameter.Should().NotBeNull());

            "it should pass parameter to the entry action"._(() =>
                                                             parameter.Should().Be(Parameter));
        }
Exemple #5
0
        public void CustomTypesForStatesAndEvents(
            PassiveStateMachine <MyState, MyEvent> machine,
            bool arrivedInStateB)
        {
            "establish a state machine with custom types for states and events"._(() =>
            {
                machine = new PassiveStateMachine <MyState, MyEvent>();

                machine.In(new MyState("A"))
                .On(new MyEvent(1)).Goto(new MyState("B"));

                machine.In(new MyState("B"))
                .ExecuteOnEntry(() => arrivedInStateB = true);

                machine.Initialize(new MyState("A"));

                machine.Start();
            });

            "when using the state machine"._(() =>
                                             machine.Fire(new MyEvent(1)));

            "it should use equals to compare states and events"._(() =>
                                                                  arrivedInStateB.Should().BeTrue("state B should be current state"));
        }
Exemple #6
0
        public void MatchingGuard(
            PassiveStateMachine <int, int> machine,
            CurrentStateExtension currentStateExtension)
        {
            "establish a state machine with guarded transitions"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                currentStateExtension = new CurrentStateExtension();
                machine.AddExtension(currentStateExtension);

                machine.In(SourceState)
                .On(Event)
                .If(() => false).Goto(ErrorState)
                .If(() => true).Goto(DestinationState)
                .If(() => true).Goto(ErrorState)
                .Otherwise().Goto(ErrorState);

                machine.Initialize(SourceState);
                machine.Start();
            });

            "when an event is fired"._(() =>
                                       machine.Fire(Event));

            "it should take transition guarded with first matching guard"._(() =>
                                                                            currentStateExtension.CurrentState.Should().Be(DestinationState));
        }
        public void MultipleEntryActions(
            PassiveStateMachine <int, int> machine,
            bool entryAction1Executed,
            bool entryAction2Executed)
        {
            "establish a state machine with several entry actions on a state"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.In(State)
                .ExecuteOnEntry(() => entryAction1Executed = true)
                .ExecuteOnEntry(() => entryAction2Executed = true);
            });

            "when entering the state"._(() =>
            {
                machine.Initialize(State);
                machine.Start();
            });

            "It should execute all entry actions"._(() =>
            {
                entryAction1Executed
                .Should().BeTrue("first action should be executed");

                entryAction2Executed
                .Should().BeTrue("second action should be executed");
            });
        }
        public void Reinitialization(
            PassiveStateMachine <int, int> machine,
            Exception receivedException)
        {
            "establish an initialized state machine"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();
                machine.Initialize(TestState);
            });

            "when state machine is initialized again"._(() =>
            {
                try
                {
                    machine.Initialize(TestState);
                }
                catch (Exception e)
                {
                    receivedException = e;
                }
            });

            "should throw an invalid operation exception"._(() =>
            {
                receivedException
                .Should().BeAssignableTo <InvalidOperationException>();
                receivedException.Message
                .Should().Be(ExceptionMessages.StateMachineIsAlreadyInitialized);
            });
        }
Exemple #9
0
        public void OtherwiseGuard(
            PassiveStateMachine <int, int> machine,
            CurrentStateExtension currentStateExtension)
        {
            "establish a state machine with otherwise guard and no machting other guard"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                currentStateExtension = new CurrentStateExtension();
                machine.AddExtension(currentStateExtension);

                machine.In(SourceState)
                .On(Event)
                .If(() => false).Goto(ErrorState)
                .Otherwise().Goto(DestinationState);

                machine.Initialize(SourceState);
                machine.Start();
            });

            "when an event is fired"._(() =>
                                       machine.Fire(Event));

            "it should_take_transition_guarded_with_otherwise"._(() =>
                                                                 currentStateExtension.CurrentState.Should().Be(DestinationState));
        }
        public void Start(
            PassiveStateMachine <int, int> machine,
            bool entryActionExecuted)
        {
            "establish an initialized state machine"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.AddExtension(testExtension);

                machine.In(TestState)
                .ExecuteOnEntry(() => entryActionExecuted = true);

                machine.Initialize(TestState);
            });

            "when starting the state machine"._(() =>
                                                machine.Start());

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

            "should execute entry action of state to which state machine is initialized"._(() =>
                                                                                           entryActionExecuted.Should().BeTrue());
        }
        public void EventArgument(
            PassiveStateMachine <int, int> machine,
            int passedArgument)
        {
            const int Event        = 3;
            const int AnotherState = 3;
            const int Argument     = 17;

            "establish a state machine with an entry action taking an event argument"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.In(State)
                .On(Event).Goto(AnotherState);

                machine.In(AnotherState)
                .ExecuteOnEntry((int argument) => passedArgument = argument);
            });

            "when entering the state"._(() =>
            {
                machine.Initialize(State);
                machine.Start();
                machine.Fire(Event, Argument);
            });

            "it should pass event argument to entry action"._(() =>
                                                              passedArgument.Should().Be(Argument));
        }
Exemple #12
0
        public void NoMatchingGuard(
            PassiveStateMachine <int, int> machine,
            CurrentStateExtension currentStateExtension)
        {
            bool declined = false;

            "establish state machine with no matching guard"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                currentStateExtension = new CurrentStateExtension();
                machine.AddExtension(currentStateExtension);

                machine.In(SourceState)
                .On(Event)
                .If(() => false).Goto(ErrorState);

                machine.TransitionDeclined += (sender, e) => declined = true;

                machine.Initialize(SourceState);
                machine.Start();
            });

            "when an event is fired"._(() =>
                                       machine.Fire(Event));

            "it should notify about declined transition"._(() =>
                                                           declined.Should().BeTrue("TransitionDeclined event should be fired"));
        }
        public void Background()
        {
            this.receivedTransitionExceptionEventArgs = null;

            this.machine = new PassiveStateMachine <int, int>();

            this.machine.TransitionExceptionThrown += (s, e) => this.receivedTransitionExceptionEventArgs = e;
        }
Exemple #14
0
        public void ExceptionHandling(
            PassiveStateMachine <int, int> machine,
            bool exitAction1Executed,
            bool exitAction2Executed,
            bool exitAction3Executed)
        {
            var exception2        = new Exception();
            var exception3        = new Exception();
            var receivedException = new List <Exception>();

            "establish a state machine with several exit actions on a state and some of them throw an exception"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.In(State)
                .ExecuteOnExit(() => exitAction1Executed = true)
                .ExecuteOnExit(() =>
                {
                    exitAction2Executed = true;
                    throw exception2;
                })
                .ExecuteOnExit(() =>
                {
                    exitAction3Executed = true;
                    throw exception3;
                })
                .On(Event).Goto(AnotherState);

                machine.TransitionExceptionThrown += (s, e) => receivedException.Add(e.Exception);
            });

            "when entering the state"._(() =>
            {
                machine.Initialize(State);
                machine.Start();
                machine.Fire(Event);
            });

            "it should execute all entry actions on entry"._(() =>
            {
                exitAction1Executed
                .Should().BeTrue("action 1 should be executed");

                exitAction2Executed
                .Should().BeTrue("action 2 should be executed");

                exitAction3Executed
                .Should().BeTrue("action 3 should be executed");
            });

            "it should handle all exceptions of all throwing entry actions by firing the TransitionExceptionThrown event"._(() =>
                                                                                                                            receivedException
                                                                                                                            .Should().BeEquivalentTo(new object[]
            {
                exception2, exception3
            }));
        }
        public void CommonAncestor(
            PassiveStateMachine <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;

            bool commonAncestorStateLeft = false;

            "establish a hierarchical state machine"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.DefineHierarchyOn(CommonAncestorState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(ParentOfSourceState)
                .WithSubState(ParentOfDestinationState);

                machine.DefineHierarchyOn(ParentOfSourceState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(SourceState)
                .WithSubState(SiblingOfSourceState);

                machine.DefineHierarchyOn(ParentOfDestinationState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(DestinationState)
                .WithSubState(SiblingOfDestinationState);

                machine.In(SourceState)
                .On(Event).Goto(DestinationState);

                machine.In(CommonAncestorState)
                .ExecuteOnExit(() => commonAncestorStateLeft = true);

                machine.Initialize(SourceState);
                machine.Start();
            });

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

            "the state machine should remain inside common ancestor state"._(() =>
                                                                             commonAncestorStateLeft
                                                                             .Should().BeFalse());
        }
Exemple #16
0
        public void Report(
            IStateMachine <string, int> machine,
            IStateMachineReport <string, int> report)
        {
            "establish a state machine"._(() =>
                                          machine = new PassiveStateMachine <string, int>());

            "establish a state machine reporter"._(() =>
                                                   report = A.Fake <IStateMachineReport <string, int> >());

            "when creating a report"._(() =>
                                       machine.Report(report));

            "it should call the passed reporter"._(() =>
                                                   A.CallTo(() => report.Report(A <string> ._, A <IEnumerable <IState <string, int> > > ._, A <Initializable <string> > ._)));
        }
Exemple #17
0
        public void Loading(
            StateMachineSaver <State> saver,
            StateMachineLoader <State> loader,
            State sourceState,
            State targetState)
        {
            "establish a saved state machine with history"._(() =>
            {
                var machine = new PassiveStateMachine <State, Event>();
                DefineMachine(machine);
                machine.Initialize(State.A);
                machine.Start();
                machine.Fire(Event.S2);     // set history of super state S
                machine.Fire(Event.B);      // set current state to B

                saver  = new StateMachineSaver <State>();
                loader = new StateMachineLoader <State>();

                machine.Save(saver);
            });

            "when state machine is loaded"._(() =>
            {
                loader.SetCurrentState(saver.CurrentStateId);
                loader.SetHistoryStates(saver.HistoryStates);

                var loadedMachine = new PassiveStateMachine <State, Event>();
                DefineMachine(loadedMachine);
                loadedMachine.Load(loader);

                loadedMachine.TransitionCompleted += (sender, args) =>
                {
                    sourceState = args.StateId;
                    targetState = args.NewStateId;
                };

                loadedMachine.Start();
                loadedMachine.Fire(Event.S);
            });

            "it should reset current state"._(() =>
                                              sourceState.Should().Be(State.B));

            "it should reset all history states of super states"._(() =>
                                                                   targetState.Should().Be(State.S2));
        }
Exemple #18
0
        public void Background()
        {
            "establish initialized state machine"._(() =>
            {
                this.machine = new PassiveStateMachine <int, int>();

                this.extension = new RecordEventsExtension();
                this.machine.AddExtension(extension);

                this.machine.In(A)
                .On(Event).Goto(B);

                this.machine.In(B)
                .On(Event).Goto(A);

                this.machine.Initialize(A);
            });
        }
Exemple #19
0
        public void CustomFactory(
            PassiveStateMachine <string, int> machine,
            StandardFactory <string, int> factory)
        {
            "establish a custom factory"._(() =>
            {
                factory = A.Fake <StandardFactory <string, int> >();
            });

            "when creating a passive state machine"._(() =>
            {
                machine = new PassiveStateMachine <string, int>("_", factory);

                machine.In("initial").On(42).Goto("answer");
            });

            "it should use custom factory to create internal instances"._(() =>
                                                                          A.CallTo(factory).MustHaveHappened());
        }
        public void Initialize(
            PassiveStateMachine <int, int> machine,
            bool entryActionExecuted)
        {
            "establish a state machine"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.AddExtension(testExtension);

                machine.In(TestState)
                .ExecuteOnEntry(() => entryActionExecuted = true);
            });

            "when state machine is initialized"._(() =>
                                                  machine.Initialize(TestState));

            "should not yet execute any entry actions"._(() =>
                                                         entryActionExecuted.Should().BeFalse());
        }
Exemple #21
0
        public void AddingExtensions(
            IStateMachine <string, int> machine,
            IExtension <string, int> extension)
        {
            "establish a state machine"._(() =>
            {
                machine = new PassiveStateMachine <string, int>();

                extension = A.Fake <IExtension <string, int> >();
            });

            "when adding an extension"._(() =>
            {
                machine.AddExtension(extension);
                machine.Initialize("initial");
            });

            "it should notify extension about internal events"._(() =>
                                                                 A.CallTo(extension).MustHaveHappened());
        }
        public void Background()
        {
            "establish a hierarchical state machine"._(() =>
            {
                testExtension = new CurrentStateExtension();

                machine = new PassiveStateMachine <int, int>();

                machine.AddExtension(testExtension);

                machine.DefineHierarchyOn(SuperState)
                .WithHistoryType(HistoryType.None)
                .WithInitialSubState(LeafState);

                machine.In(SuperState)
                .ExecuteOnEntry(() => entryActionOfSuperStateExecuted = true);
                machine.In(LeafState)
                .ExecuteOnEntry(() => entryActionOfLeafStateExecuted = true);
            });
        }
        public void ExecutingTransition(
            PassiveStateMachine <int, int> machine,
            string actualParameter,
            bool exitActionExecuted,
            bool entryActionExecuted)
        {
            "establish a state machine with transitions"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.AddExtension(CurrentStateExtension);

                machine.In(SourceState)
                .ExecuteOnExit(() => exitActionExecuted = true)
                .On(Event).Goto(DestinationState).Execute <string>(p => actualParameter = p);

                machine.In(DestinationState)
                .ExecuteOnEntry(() => entryActionExecuted = true);

                machine.Initialize(SourceState);
                machine.Start();
            });

            "when firing an event onto the state machine"._(() =>
                                                            machine.Fire(Event, Parameter));

            "it should_execute_transition_by_switching_state"._(() =>
                                                                CurrentStateExtension.CurrentState.Should().Be(DestinationState));

            "it should_execute_transition_actions"._(() =>
                                                     actualParameter.Should().NotBeNull());

            "it should_pass_parameters_to_transition_action"._(() =>
                                                               actualParameter.Should().Be(Parameter));

            "it should_execute_exit_action_of_source_state"._(() =>
                                                              exitActionExecuted.Should().BeTrue());

            "it should_execute_entry_action_of_destination_state"._(() =>
                                                                    entryActionExecuted.Should().BeTrue());
        }
        public void StartingAnUninitializedStateMachine(
            PassiveStateMachine <int, int> machine,
            Exception receivedException)
        {
            "establish an uninitialized state machine"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();
            });

            "when starting the state machine"._(() =>
                                                receivedException = Catch.Exception(() =>
                                                                                    machine.Start()));

            "should throw an invalid operation exception"._(() =>
            {
                receivedException
                .Should().BeAssignableTo <InvalidOperationException>();
                receivedException.Message
                .Should().Be(ExceptionMessages.StateMachineNotInitialized);
            });
        }
        public void EntryAction(
            PassiveStateMachine <int, int> machine,
            bool entryActionExecuted)
        {
            "establish a state machine with entry action on a state"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.In(State)
                .ExecuteOnEntry(() => entryActionExecuted = true);
            });

            "when entering the state"._(() =>
            {
                machine.Initialize(State);
                machine.Start();
            });

            "it should execute the entry action"._(() =>
                                                   entryActionExecuted.Should().BeTrue());
        }
Exemple #26
0
        public void DefaultStateMachineName(
            PassiveStateMachine <string, int> machine,
            StateMachineNameReporter reporter)
        {
            "establish an instantiated passive state machine"._(() =>
            {
                machine = new PassiveStateMachine <string, int>();
            });

            "establish a state machine reporter"._(() =>
            {
                reporter = new StateMachineNameReporter();
            });

            "when the state machine report is generated"._(() =>
                                                           machine.Report(reporter));

            "it should use the type of the state machine as name for state machine"._(() =>
                                                                                      reporter.StateMachineName
                                                                                      .Should().Be("Appccelerate.StateMachine.PassiveStateMachine<System.String,System.Int32>"));
        }
Exemple #27
0
        public void LoadingAnInitializedStateMachine(
            PassiveStateMachine <string, int> machine,
            Exception receivedException)
        {
            "establish an initialized state machine"._(() =>
            {
                machine = new PassiveStateMachine <string, int>();
                machine.Initialize("initial");
            });

            "when state machine is loaded"._(() =>
            {
                receivedException = Catch.Exception(() => machine.Load(A.Fake <IStateMachineLoader <string> >()));
            });

            "it should throw invalid operation exception"._(() =>
            {
                receivedException.Should().BeOfType <InvalidOperationException>();
                receivedException.Message.Should().Be(ExceptionMessages.StateMachineIsAlreadyInitialized);
            });
        }
Exemple #28
0
        public void ExitAction(
            PassiveStateMachine <int, int> machine,
            bool exitActionExecuted)
        {
            "establish a state machine with exit action on a state"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.In(State)
                .ExecuteOnExit(() => exitActionExecuted = true)
                .On(Event).Goto(AnotherState);
            });

            "when leaving the state"._(() =>
            {
                machine.Initialize(State);
                machine.Start();
                machine.Fire(Event);
            });

            "it should execute the exit action"._(() =>
                                                  exitActionExecuted.Should().BeTrue());
        }
Exemple #29
0
        public void CustomStateMachineName(
            PassiveStateMachine <string, int> machine,
            StateMachineNameReporter reporter)
        {
            const string Name = "custom name";

            "establish an instantiated passive state machine with custom name"._(() =>
            {
                machine = new PassiveStateMachine <string, int>(Name);
            });

            "establish a state machine reporter"._(() =>
            {
                reporter = new StateMachineNameReporter();
            });

            "when the state machine report is generated"._(() =>
                                                           machine.Report(reporter));

            "it should use custom name for state machine"._(() =>
                                                            reporter.StateMachineName
                                                            .Should().Be(Name));
        }
        public void InitializeALoadedStateMachine(
            PassiveStateMachine <int, int> machine,
            Exception receivedException)
        {
            "establish a loaded state machine"._(() =>
            {
                machine = new PassiveStateMachine <int, int>();

                machine.Load(A.Fake <IStateMachineLoader <int> >());
            });

            "when initializing the state machine"._(() =>
                                                    receivedException = Catch.Exception(() =>
                                                                                        machine.Initialize(0)));

            "should throw an invalid operation exception"._(() =>
            {
                receivedException
                .Should().BeAssignableTo <InvalidOperationException>();
                receivedException.Message
                .Should().Be(ExceptionMessages.StateMachineIsAlreadyInitialized);
            });
        }