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()); }
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 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; string log = string.Empty; "establish a hierarchical state machine"._(() => { machine = new PassiveStateMachine <string, int>(); machine.DefineHierarchyOn(ParentOfSourceState) .WithHistoryType(HistoryType.None) .WithInitialSubState(SourceState) .WithSubState(SiblingOfSourceState); machine.DefineHierarchyOn(ParentOfDestinationState) .WithHistoryType(HistoryType.None) .WithInitialSubState(DestinationState) .WithSubState(SiblingOfDestinationState); machine.DefineHierarchyOn(GrandParentOfSourceState) .WithHistoryType(HistoryType.None) .WithInitialSubState(ParentOfSourceState); machine.DefineHierarchyOn(GrandParentOfDestinationState) .WithHistoryType(HistoryType.None) .WithInitialSubState(ParentOfDestinationState); machine.In(SourceState) .ExecuteOnExit(() => log += "exit" + SourceState) .On(Event).Goto(DestinationState); machine.In(ParentOfSourceState) .ExecuteOnExit(() => log += "exit" + ParentOfSourceState); machine.In(DestinationState) .ExecuteOnEntry(() => log += "enter" + DestinationState); machine.In(ParentOfDestinationState) .ExecuteOnEntry(() => log += "enter" + ParentOfDestinationState); machine.In(GrandParentOfSourceState) .ExecuteOnExit(() => log += "exit" + GrandParentOfSourceState); machine.In(GrandParentOfDestinationState) .ExecuteOnEntry(() => log += "enter" + GrandParentOfDestinationState); machine.Initialize(SourceState); machine.Start(); }); "when firing an event resulting in a transition without a common ancestor"._(() => machine.Fire(Event)); "it should execute exit action of source state"._(() => log.Should().Contain("exit" + SourceState)); "it should execute exit action of parents of source state (recursively)"._(() => log .Should().Contain("exit" + ParentOfSourceState) .And.Contain("exit" + GrandParentOfSourceState)); "it should execute entry action of parents of destination state (recursively)"._(() => log.Should().Contain("enter" + ParentOfDestinationState) .And.Contain("enter" + GrandParentOfDestinationState)); "it should execute entry action of destination state"._(() => log.Should().Contain("enter" + DestinationState)); "it should execute actions from source upwards and then downwards to destination state"._(() => { 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); }); }