public void InvalidTriggerException_MessageEx_VerifyMessageEx() { var inner = new Exception(); var ex = new InvalidTriggerException("message", inner); Assert.Equal("message", ex.Message); Assert.Same(inner, ex.InnerException); }
public void InvalidTriggerException_Message_VerifyMessage() { var ex = new InvalidTriggerException("message"); Assert.Equal("message", ex.Message); }
public void Trigger(Trigger trigger, TStateModel model) { if (trigger == null) { throw new ArgumentNullException("trigger"); } if (model == null) { throw new ArgumentNullException("model"); } if (model.CurrentState == null || !(model.CurrentState is State <TStateModel>)) { throw new InvalidStateModelException( "State model's CurrentState object property must be of type State<TStateModel>"); } // get current state var currentState = (State <TStateModel>)model.CurrentState; // find all possible transitions (state+global) from current state with given trigger // doesn't yet take into account the passing of those transitions' guards lambdas var possibleTransitions = currentState .TransitionsOn(trigger) .Concat(GlobalTransitionsOn(trigger)); // if no possible transistions, throw exception about it if (Configuration.RaiseExceptionOnTriggerMatchingNoTransition && possibleTransitions.Count() == 0) { var availableTriggers = AvailableTriggers(model).ToList(); var ex = new InvalidTriggerException(string.Format( "State Model's CurrentState '{0}' does not define a Transition for trigger '{1}', nor does the state machine provide any global transitions on this trigger. Available Triggers from this state: {2}. This exception can be suppressed via the state machine's Configuration.RaiseExceptionOnTriggerMatchingNoTransitions property", model.CurrentState, trigger, string.Join(", ", availableTriggers.ConvertAll(t => t.Name).ToArray()))); ex.AvailableTriggers = availableTriggers; throw ex; } // out of the possible transitions, find the first whose guard passes var firstTransitionWithPassingGuard = possibleTransitions .FirstOrDefault(t => t.Guard(model)); // if no possible transition had a passign guard, throw exception about it. if (Configuration.RaiseExceptionOnTriggerMatchingNoPassingTransition && (firstTransitionWithPassingGuard == null || firstTransitionWithPassingGuard.Target == null)) { throw new InvalidTriggerException(string.Format( "State Model's CurrentState '{0}' and the state machine's global transitions define at least {1} transition(s) for the trigger '{2}', but none of their guard lambdas returned true. This exception can be suppressed via the state machine's Configuration.RaiseExceptionOnTriggerMatchingNoPassingTransitions property", model.CurrentState, possibleTransitions.Count().ToString(), trigger.Name)); } if (firstTransitionWithPassingGuard != null && firstTransitionWithPassingGuard.Target != null) { var nextState = firstTransitionWithPassingGuard.Target; // No transitions should happen if not effectively changing states, even if there's a matching transition if (nextState != currentState) { // run transition callbacks and set the new state on model if (Transitioning != null) { Transitioning(this, new TransitionEventArgs <TStateModel>(model, currentState, nextState, trigger)); } // raise events that occur before actual state change currentState.RaiseExiting(model, nextState, trigger); nextState.RaiseEntering(model, currentState, trigger); // change state model.CurrentState = nextState; // raise events that occur after actual state change currentState.RaiseExited(model, nextState, trigger); nextState.RaiseEntered(model, currentState, trigger); // run transition callbacks and set the new state on model if (Transitioned != null) { Transitioned(this, new TransitionEventArgs <TStateModel>(model, currentState, nextState, trigger)); } } // else if the next state is same as current, and machine is configured to // raise exception when that happens, go ahead and raise it else if (Configuration.RaiseExceptionBeforeTransitionToSameState) { throw new InvalidTriggerException(string.Format( "Trigger '{0}' would effectively transition State Model from its current state of '{1}' to the same state of '{2}', and the machine is currently configured to raise an exception when this happens. This exception can be suppressed via the state machine's Configuration.RaiseExceptionBeforeTransitionToSameState property.", trigger.Name, model.CurrentState, nextState)); } } }