public void ExecuteActions() { const int EventArgument = 17; int?action1Argument = null; int?action2Argument = null; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .On(Events.B) .Goto(States.B) .Execute <int>(argument => { action1Argument = argument; }) .Execute((int argument) => { action2Argument = argument; }); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, EventArgument, stateContainer, stateDefinitions); action1Argument.Should().Be(EventArgument); action2Argument.Should().Be(EventArgument); }
public void ExitActions() { var exit1 = false; var exit2 = false; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .ExecuteOnExit(() => exit1 = true) .ExecuteOnExit(() => exit2 = true) .On(Events.B).Goto(States.B); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, stateContainer, stateContainer, stateDefinitions); exit1.Should().BeTrue("exit action was not executed."); exit2.Should().BeTrue("exit action was not executed."); }
public void EventArgumentIsPassedToTheGuard() { const string EventArgument = "test"; string actualEventArgument = null; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .On(Events.A) .If <string>(argument => { actualEventArgument = argument; return(true); }) .Goto(States.B); var stateDefinitions = stateDefinitionBuilder .Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateDefinitions, States.A); testee.Fire(Events.A, EventArgument, stateContainer, stateDefinitions); actualEventArgument.Should().Be(EventArgument); }
public void GuardWithASingleArgument() { var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .On(Events.B) .If <int>(SingleIntArgumentGuardReturningFalse).Goto(States.C) .If(() => false).Goto(States.D) .If(() => false).Goto(States.E) .If <int>(SingleIntArgumentGuardReturningTrue).Goto(States.B); var stateDefinitions = stateDefinitionBuilder .Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, 3, stateContainer, stateDefinitions); stateContainer .CurrentStateId .Should() .BeEquivalentTo(Initializable <States> .Initialized(States.B)); }
public void InternalTransition() { var executed = false; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .On(Events.A) .Execute(() => executed = true); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateDefinitions, States.A); testee.Fire(Events.A, stateContainer, stateContainer, stateDefinitions); executed.Should().BeTrue("internal transition was not executed."); stateContainer .CurrentStateId .Should() .BeEquivalentTo(Initializable <States> .Initialized(States.A)); }
public void ExecuteTransitionBetweenStatesOnDifferentLevelsDownwards() { var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, this.stateDefinitions, States.B2); this.ClearRecords(); testee.Fire(Events.C1B, stateContainer, stateContainer, this.stateDefinitions); stateContainer .CurrentStateId .Should() .BeEquivalentTo(Initializable <States> .Initialized(States.C1B)); this.CheckRecord <ExitRecord>(States.B2); this.CheckRecord <ExitRecord>(States.B); this.CheckRecord <EntryRecord>(States.C); this.CheckRecord <EntryRecord>(States.C1); this.CheckRecord <EntryRecord>(States.C1B); this.CheckNoRemainingRecords(); }
public void ParametrizedExitAction() { const int Parameter = 3; var receivedValue = 0; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .ExecuteOnExitParametrized(value => receivedValue = value, Parameter) .On(Events.B).Goto(States.B); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, stateContainer, stateContainer, stateDefinitions); receivedValue.Should().Be(Parameter); }
public void ExecutesActions_WhenActionsWithAndWithoutArgumentAreDefined() { const int EventArgument = 17; var action1Executed = false; var action2Executed = false; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .On(Events.B) .Goto(States.B) .Execute <int>(argument => { action1Executed = true; }) .Execute((int argument) => { action2Executed = true; }); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, EventArgument, stateContainer, stateDefinitions); action1Executed.Should().BeTrue("action with argument should be executed"); action2Executed.Should().BeTrue("action without argument should be executed"); }
public void MissingTransition() { var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .On(Events.B) .Goto(States.B); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); var declined = false; testee.TransitionDeclined += (sender, e) => { declined = true; }; testee.EnterInitialState(stateContainer, stateDefinitions, States.A); testee.Fire(Events.C, stateContainer, stateContainer, stateDefinitions); declined.Should().BeTrue("Declined event was not fired"); stateContainer .CurrentStateId .Should() .BeEquivalentTo(Initializable <States> .Initialized(States.A)); }
public void ExecuteTransitionWithHistoryTypeDeep() { var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, this.stateDefinitions, States.D1B); testee.Fire(Events.A, stateContainer, stateContainer, this.stateDefinitions); this.ClearRecords(); testee.Fire(Events.D, stateContainer, stateContainer, this.stateDefinitions); stateContainer .CurrentStateId .Should() .BeEquivalentTo(Initializable <States> .Initialized(States.D1B)); this.CheckRecord <ExitRecord>(States.A); this.CheckRecord <EntryRecord>(States.D); this.CheckRecord <EntryRecord>(States.D1); this.CheckRecord <EntryRecord>(States.D1B); this.CheckNoRemainingRecords(); }
public void ExceptionIfNotInitialized() { var stateContainer = new StateContainer <States, Events>(); var stateDefinitions = new StateDefinitionsBuilder <States, Events>().Build(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); Action action = () => testee.Fire(Events.A, stateContainer, stateContainer, stateDefinitions); action.Should().Throw <InvalidOperationException>(); }
public void InternalTransition() { var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, this.stateDefinitions, States.A); this.ClearRecords(); testee.Fire(Events.A, stateContainer, stateContainer, this.stateDefinitions); stateContainer .CurrentStateId .Should() .BeEquivalentTo(Initializable <States> .Initialized(States.A)); }
public void InitializeToTopLevelState() { var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, this.stateDefinitions, States.A); stateContainer .CurrentStateId .Should() .BeEquivalentTo(Initializable <States> .Initialized(States.A)); this.CheckRecord <EntryRecord>(States.A); this.CheckNoRemainingRecords(); }
public void ExceptionThrowingGuard() { var eventArguments = new object[] { 1, 2, "test" }; var exception = new Exception(); States? recordedStateId = null; Events? recordedEventId = null; object recordedEventArgument = null; Exception recordedException = null; var stateDefinitionsBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionsBuilder.In(States.A) .On(Events.B) .If(() => throw exception) .Goto(States.B); var stateDefinitions = stateDefinitionsBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); var transitionDeclined = false; testee.TransitionDeclined += (sender, e) => transitionDeclined = true; testee.TransitionExceptionThrown += (sender, eventArgs) => { recordedStateId = eventArgs.StateId; recordedEventId = eventArgs.EventId; recordedEventArgument = eventArgs.EventArgument; recordedException = eventArgs.Exception; }; testee.EnterInitialState(stateContainer, stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, eventArguments, stateContainer, stateContainer, stateDefinitions); recordedStateId.Should().Be(States.A); recordedEventId.Should().Be(Events.B); recordedEventArgument.Should().Be(eventArguments); recordedException.Should().Be(exception); stateContainer.CurrentStateId.Should().BeEquivalentTo(Initializable <States> .Initialized(States.A)); transitionDeclined.Should().BeTrue("transition was not declined."); }
public void EntryActionWhenThrowingExceptionThenNotificationAndStateIsEntered() { var eventArguments = new object[] { 1, 2, "test" }; var exception = new Exception(); States? recordedStateId = null; Events? recordedEventId = null; object recordedEventArgument = null; Exception recordedException = null; var stateDefinitionsBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionsBuilder .In(States.A) .On(Events.B) .Goto(States.B); stateDefinitionsBuilder .In(States.B) .ExecuteOnEntry(() => throw exception); var stateDefinitions = stateDefinitionsBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.TransitionExceptionThrown += (sender, eventArgs) => { recordedStateId = eventArgs.StateId; recordedEventId = eventArgs.EventId; recordedEventArgument = eventArgs.EventArgument; recordedException = eventArgs.Exception; }; testee.EnterInitialState(stateContainer, stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, eventArguments, stateContainer, stateContainer, stateDefinitions); recordedStateId.Should().Be(States.A); recordedEventId.Should().Be(Events.B); recordedEventArgument.Should().Be(eventArguments); recordedException.Should().Be(exception); stateContainer.CurrentStateId.Should().BeEquivalentTo(Initializable <States> .Initialized(States.B)); }
public void ExecuteTransitionWithHistoryTypeNone() { var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, this.stateDefinitions, States.B2); testee.Fire(Events.A, stateContainer, stateContainer, this.stateDefinitions); this.ClearRecords(); testee.Fire(Events.B, stateContainer, stateContainer, this.stateDefinitions); this.CheckRecord <ExitRecord>(States.A); this.CheckRecord <EntryRecord>(States.B); this.CheckRecord <EntryRecord>(States.B1); this.CheckNoRemainingRecords(); }
public void EntryAction() { var entered = false; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .ExecuteOnEntry(() => entered = true); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, stateDefinitions, States.A); entered.Should().BeTrue("entry action was not executed."); }
public void InitializeStateWithSubStates() { var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); stateContainer.SetLastActiveStateFor(States.D, this.stateDefinitions[States.D1]); stateContainer.SetLastActiveStateFor(States.D1, this.stateDefinitions[States.D1A]); testee.EnterInitialState(stateContainer, stateContainer, this.stateDefinitions, States.D); stateContainer .CurrentStateId .Should() .BeEquivalentTo(Initializable <States> .Initialized(States.D1A)); this.CheckRecord <EntryRecord>(States.D); this.CheckRecord <EntryRecord>(States.D1); this.CheckRecord <EntryRecord>(States.D1A); this.CheckNoRemainingRecords(); }
public void ParameterizedEntryAction() { const int Parameter = 3; var receivedValue = 0; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .ExecuteOnEntryParametrized(parameter => receivedValue = parameter, Parameter); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateContainer, stateDefinitions, States.A); receivedValue.Should().Be(Parameter); }
public void ActionsWithoutArguments() { var executed = false; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .On(Events.B) .Execute(() => executed = true); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, stateContainer, stateContainer, stateDefinitions); executed.Should().BeTrue(); }
public void ActionsWithOneArgument() { const int ExpectedValue = 1; var value = 0; var stateDefinitionBuilder = new StateDefinitionsBuilder <States, Events>(); stateDefinitionBuilder .In(States.A) .On(Events.B) .Execute <int>(v => value = v); var stateDefinitions = stateDefinitionBuilder.Build(); var stateContainer = new StateContainer <States, Events>(); var testee = new StateMachineBuilder <States, Events>() .WithStateContainer(stateContainer) .Build(); testee.EnterInitialState(stateContainer, stateDefinitions, States.A); testee.Fire(Events.B, ExpectedValue, stateContainer, stateDefinitions); value.Should().Be(ExpectedValue); }