StateMachine_Trigger_TransitionFromCurrentToSame_ConfiggedNotToRaiseExcep_DoesNotRaiseTransitionChangeEvents() { var config = new StateMachineConfiguration { RaiseExceptionBeforeTransitionToSameState = false }; var machine = new StateMachine <StubStateModel>(config); var model = new StubStateModel(); var trigger1 = new Trigger("trigger1"); var state1 = new State <StubStateModel>("state1"); TransitionEventArgs <StubStateModel> transitioningArgs = null; state1.Entered += (s, e) => { transitioningArgs = e; }; TransitionEventArgs <StubStateModel> transitionedArgs = null; state1.Exiting += (s, e) => { transitionedArgs = e; }; state1.AddTransition(trigger1, state1); model.CurrentState = state1; // set up scenario where state would transition from current to same state. // so no true transition would not occur // should not throw exception and that's good enough for us machine.Trigger(trigger1, model); // verify that no transition events occurred Assert.Null(transitioningArgs); Assert.Null(transitionedArgs); }
public IFluentStateMachine <TStateModel> Compile(StateMachineConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException("configuration"); } return(builder.Compile(configuration)); }
public void StateMachine_ValidConfigPassed_SetsConfigAsCurrentConfig() { var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoTransition = true }; var machine = new StateMachine <StubStateModel>(config); Assert.Same(config, machine.Configuration); Assert.True(machine.Configuration.RaiseExceptionOnTriggerMatchingNoTransition); }
public StateMachine(StateMachineConfiguration config) { if (config == null) { throw new ArgumentNullException(); } this.Configure(config.States); this.Allow(config.Triggers); }
public static StateMachine <TState, TTrigger> Create <TState, TTrigger>(TState initialState, StateMachineConfiguration <TState, TTrigger> config) { Contract.Requires <ArgumentNullException>(initialState != null); Contract.Requires <ArgumentNullException>(config != null); var sm = new StateMachine <TState, TTrigger>(initialState, config); sm.UnhandledTriggerExecuted += InvalidTriggerException <TTrigger, TState> .Throw; return(sm); }
internal StateMachine(TState initialState, StateMachineConfiguration<TState, TTrigger> configuration) { Contract.Requires(configuration != null); Contract.Requires(initialState != null); currentStateRepresentation = configuration.GetStateRepresentation(initialState); if (currentStateRepresentation == null) { throw new InvalidOperationException("StateMachine has no state"); } IsEnabled = true; }
internal BlockingStateMachine(TState initialState, StateMachineConfiguration <TState, TTrigger> configuration) { Contract.Requires(configuration != null); Contract.Requires(initialState != null); CurrentStateRepresentation = configuration.GetInitialStateRepresentation(initialState); if (CurrentStateRepresentation == null) { throw new InvalidOperationException("StateMachine has an unreachable state"); } configDictionary = configuration.Config; }
public void FluentStateMachineBuilder_CompileConfig_ReturnsNewStateMachineWithDefinedParts_WithConfig() { var builder = new FluentStateMachineBuilder <StubStateModel>(); builder.State("s1", null); builder.Initiates(); var config = new StateMachineConfiguration { RaiseExceptionBeforeTransitionToSameState = true }; var machine = builder.Compile(config); Assert.NotNull(machine); Assert.Same(config, machine.Configuration); Assert.Equal(true, machine.Configuration.RaiseExceptionBeforeTransitionToSameState); }
StateMachine_Trigger_NoStateOrGlobalTransOnTrigger_ConfigRaiseOnNoTransFalse_NotThrowsInvalidTrigger() { var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoTransition = false }; var machine = new StateMachine <StubStateModel>(config); var model = new StubStateModel(); var trigger1 = new Trigger("trigger1"); var trigger2 = new Trigger("trigger2"); var state1 = new State <StubStateModel>("state1"); var state2 = new State <StubStateModel>("state2"); state1.AddTransition(trigger1, state2); model.CurrentState = state1; // no exception shoudl happen, and that's good enough for us. machine.Trigger(trigger2, model); }
public IFluentStateMachine <TStateModel> Compile(StateMachineConfiguration configuration) { if (CurrentState == initial) { throw new FluentSyntaxException( "Cannot compile an empty state machine. No statements have been made to define this state machine"); } Trigger(compileTrigger); var stateMachine = new StateMachine <TStateModel>(configuration); return(new FluentStateMachine <TStateModel>( stateMachine, states.Values.ToList(), workingInitialState, workingGlobalTransitionings, workingGlobalTransitioneds, workingGlobalTransitions)); }
StateMachine_Trigger_NoPassingTransitionOnTrigger_ConfigRaiseOnNoPassingTranTrue_ThrowsInvalidTrigger() { var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoPassingTransition = true }; var machine = new StateMachine <StubStateModel>(config); var model = new StubStateModel(); var trigger1 = new Trigger("trigger1"); var state1 = new State <StubStateModel>("state1"); var state2 = new State <StubStateModel>("state2"); state1.AddTransition(trigger1, state2, m => 1 == 2); model.CurrentState = state1; // set up so that there's a matching transition, but the guard would fail when run Assert.Throws <InvalidTriggerException>(() => machine.Trigger(trigger1, model)); }
StateMachine_Trigger_NoPassingTransitionOnTrigger_ConfigRaiseOnNoPassingTranFalse_ThrowsInvalidTrigger() { var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoPassingTransition = false }; var machine = new StateMachine <StubStateModel>(config); var model = new StubStateModel(); var trigger1 = new Trigger("trigger1"); var state1 = new State <StubStateModel>("state1"); var state2 = new State <StubStateModel>("state2"); state1.AddTransition(trigger1, state2, m => 1 == 2); model.CurrentState = state1; // set up so that there's a matching transition, but the guard would fail when run // no exceptions should happen, and that's good enough for us machine.Trigger(trigger1, model); }
public void StateMachine_Trigger_TransitionsToSameState_ConfigRaiseOnSameStateTranTrue_ThrowsInvalidTrigger() { var config = new StateMachineConfiguration { RaiseExceptionBeforeTransitionToSameState = true }; var machine = new StateMachine <StubStateModel>(config); var model = new StubStateModel(); var trigger1 = new Trigger("trigger1"); var state1 = new State <StubStateModel>("state1"); var state2 = new State <StubStateModel>("state2"); state1.AddTransition(trigger1, state1); model.CurrentState = state1; // set up scenario where state would transition from current to same state. // so no true transition would not occur Assert.Throws <InvalidTriggerException>(() => machine.Trigger(trigger1, model)); }
public void StateMachine_Trigger_TransitionsToSameState_ConfigRaiseOnSameStateTranFalse_ThrowsInvalidTrigger() { var config = new StateMachineConfiguration { RaiseExceptionBeforeTransitionToSameState = false }; var machine = new StateMachine <StubStateModel>(config); var model = new StubStateModel(); var trigger1 = new Trigger("trigger1"); var state1 = new State <StubStateModel>("state1"); var state2 = new State <StubStateModel>("state2"); state1.AddTransition(trigger1, state1); model.CurrentState = state1; // set up scenario where state would transition from current to same state. // so no true transition would not occur // should not throw exception and that's good enough for us machine.Trigger(trigger1, model); }
public static IStateMachine <TState, TTrigger> Create <TState, TTrigger>(TState initialState, StateMachineConfiguration <TState, TTrigger> config, bool blocking = false) { Contract.Requires <ArgumentNullException>(initialState != null); Contract.Requires <ArgumentNullException>(config != null); IStateMachine <TState, TTrigger> sm; if (blocking) { sm = new BlockingStateMachine <TState, TTrigger>(initialState, config); } else { sm = new StateMachine <TState, TTrigger>(initialState, config); } sm.UnhandledTriggerExecuted += InvalidTriggerException <TTrigger, TState> .Throw; return(sm); }
public void StateMachine_Trigger_NoStateOrGlobalTransOnTrigger_ConfigRaiseOnNoTransTrue_ThrowsInvalidTrigger() { var config = new StateMachineConfiguration { RaiseExceptionOnTriggerMatchingNoTransition = true }; var machine = new StateMachine <StubStateModel>(config); var model = new StubStateModel(); var trigger1 = new Trigger("trigger1"); var trigger2 = new Trigger("trigger2"); var state1 = new State <StubStateModel>("state1"); var state2 = new State <StubStateModel>("state2"); state1.AddTransition(trigger1, state2); model.CurrentState = state1; // set up so that current state of state 1 doesn't' define a trans for "trigger2", only "trigger1" Assert.Throws <InvalidTriggerException>(() => machine.Trigger(trigger2, model)); }
/// <summary> /// Initializes a new instance of the <see cref="StateMachine{T}"/> class. /// </summary> /// <param name="config">configuration</param> /// <param name="name">state machine name</param> /// <param name="id">state machine id</param> public StateMachine(StateMachineConfiguration <T> config, string name, long id) : base(name, id) { this.Config = config; }