public void InitializeALoadedStateMachine( AsyncPassiveStateMachine <int, int> machine, Exception receivedException) { "establish a loaded initialized state machine".x(async() => { machine = new AsyncPassiveStateMachine <int, int>(); var loader = new Persisting.StateMachineLoader <int>(); loader.SetCurrentState(new Initializable <int> { Value = 1 }); loader.SetHistoryStates(new Dictionary <int, int>()); await machine.Load(loader); }); "when initializing the state machine".x(async() => receivedException = await Catch.Exception(async() => await machine.Initialize(0))); "should throw an invalid operation exception".x(() => { receivedException .Should().BeAssignableTo <InvalidOperationException>(); receivedException.Message .Should().Be(ExceptionMessages.StateMachineIsAlreadyInitialized); }); }
public void LoadingNonInitializedStateMachine( AsyncPassiveStateMachine <State, Event> loadedMachine) { "when a non-initialized state machine is loaded".x(async() => { var loader = new StateMachineLoader <State>(); loader.SetCurrentState(new Initializable <State>()); loader.SetHistoryStates(new Dictionary <State, State>()); var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <State, Event>(); SetupStates(stateMachineDefinitionBuilder); loadedMachine = stateMachineDefinitionBuilder .WithInitialState(State.A) .Build() .CreatePassiveStateMachine(); await loadedMachine.Load(loader); }); "it should not be initialized already".x(async() => { var stateMachineSaver = new StateMachineSaver <State>(); await loadedMachine.Save(stateMachineSaver); stateMachineSaver .CurrentStateId .IsInitialized .Should() .BeFalse(); }); }
public void Loading( StateMachineSaver <State> saver, StateMachineLoader <State> loader, FakeExtension extension, State sourceState, State targetState) { "establish a saved state machine with history"._(async() => { var machine = new AsyncPassiveStateMachine <State, Event>(); DefineMachine(machine); await machine.Initialize(State.A); await machine.Start(); await machine.Fire(Event.S2); // set history of super state S await machine.Fire(Event.B); // set current state to B saver = new StateMachineSaver <State>(); loader = new StateMachineLoader <State>(); await machine.Save(saver); }); "when state machine is loaded"._(async() => { loader.SetCurrentState(saver.CurrentStateId); loader.SetHistoryStates(saver.HistoryStates); extension = new FakeExtension(); var loadedMachine = new AsyncPassiveStateMachine <State, Event>(); loadedMachine.AddExtension(extension); DefineMachine(loadedMachine); await loadedMachine.Load(loader); loadedMachine.TransitionCompleted += (sender, args) => { sourceState = args.StateId; targetState = args.NewStateId; }; await loadedMachine.Start(); await 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)); "it should notify extensions"._(() => extension.LoadedCurrentState .Should().BeEquivalentTo(State.B)); }
public void LoadingNonInitializedStateMachine( AsyncPassiveStateMachine <State, Event> loadedMachine) { "when a non-initialized state machine is loaded"._( async() => { var loader = new StateMachineLoader <State>(); loader.SetCurrentState(new Initializable <State>()); loader.SetHistoryStates(new Dictionary <State, State>()); loadedMachine = new AsyncPassiveStateMachine <State, Event>(); DefineMachine(loadedMachine); await loadedMachine.Load(loader); }); "it should not be initialized already"._( () => { Action act = () => loadedMachine.Initialize(State.S); act.ShouldNotThrow(); }); }
public void LoadingEventsForPassiveStateMachine( AsyncPassiveStateMachine <string, int> machine) { "establish a passive state machine".x(() => { var stateMachineDefinitionBuilder = new StateMachineDefinitionBuilder <string, int>(); stateMachineDefinitionBuilder .In("A") .On(1) .Goto("B"); stateMachineDefinitionBuilder .In("B") .On(2) .Goto("C"); stateMachineDefinitionBuilder .In("C") .On(3) .Goto("A"); machine = stateMachineDefinitionBuilder .WithInitialState("A") .Build() .CreatePassiveStateMachine(); }); "when it is loaded with Events".x(async() => { var firstEvent = new EventInformation <int>(2, null); var secondEvent = new EventInformation <int>(3, null); var priorityEvent = new EventInformation <int>(1, null); var loader = new StateMachineLoader <string, int>(); loader.SetEvents(new List <EventInformation <int> > { firstEvent, secondEvent, }); loader.SetPriorityEvents(new List <EventInformation <int> > { priorityEvent }); var extension = A.Fake <IExtension <string, int> >(); machine.AddExtension(extension); await machine.Load(loader); A.CallTo(() => extension.Loaded( A <IStateMachineInformation <string, int> > .Ignored, A <Initializable <string> > .Ignored, A <IReadOnlyDictionary <string, string> > .Ignored, A <IReadOnlyCollection <EventInformation <int> > > .That .Matches(c => c.Count == 2 && c.Contains(firstEvent) && c.Contains(secondEvent)), A <IReadOnlyCollection <EventInformation <int> > > .That .Matches(c => c.Count == 1 && c.Contains(priorityEvent)))) .MustHaveHappenedOnceExactly(); }); "it should process those events".x(async() => { var transitionRecords = new List <TransitionRecord>(); machine.TransitionCompleted += (sender, args) => transitionRecords.Add( new TransitionRecord(args.EventId, args.StateId, args.NewStateId)); await machine.Start(); transitionRecords .Should() .HaveCount(3) .And .IsEquivalentInOrder(new List <TransitionRecord> { new TransitionRecord(1, "A", "B"), new TransitionRecord(2, "B", "C"), new TransitionRecord(3, "C", "A") }); }); }