示例#1
0
        public void ExecuteAutoTransition_executes_AutoTransition_for_superState()
        {
            //Scenario: Sale has been paid for and goes to ChangeDue. If no change due, it should automatically transition to Complete.
            //ChangeDue is a substate of Open and Open has the autoForward defined for Pay.
            var sale = new Sale(saleID: 96)
            {
                State = SaleState.ChangeDue
            };

            var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.AddItem
                                                                                    , SaleState.Open
                                                                                    , SaleState.Open
                                                                                    , SaleState.ChangeDue
                                                                                    , "lastTransitionName");
            var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            IStateConfigurationInternal <Sale, SaleState, SaleEvent> openState      = stateMachine.ConfigureState(SaleState.Open) as IStateConfigurationInternal <Sale, SaleState, SaleEvent>;
            IStateConfigurationInternal <Sale, SaleState, SaleEvent> changeDueState = stateMachine.ConfigureState(SaleState.ChangeDue) as IStateConfigurationInternal <Sale, SaleState, SaleEvent>;

            changeDueState?.AddSuperstate(openState);
            openState?.AddAutoForwardTransition(SaleEvent.Pay, SaleState.Complete, sale1 => true /* condition indicates no change due */);
            var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale);

            var autoTransitionResult = changeDueState?.ExecuteAutoTransition(parameters, transitionResult);

            Assert.True(autoTransitionResult?.WasTransitioned);
            Assert.Equal(SaleState.Complete, sale.State);
            Assert.Equal(SaleState.Complete, autoTransitionResult?.CurrentState);
            Assert.Equal(SaleState.ChangeDue, autoTransitionResult?.PreviousState);
            Assert.Equal(SaleState.Open, autoTransitionResult?.StartingState);
        }
        public async Task ExecuteAutoTransitionAsync_executes_AutoTransition_for_superState()
        {
            var sale = new Sale(saleId: 96)
            {
                State = SaleState.ChangeDue
            };
            var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.Pay
                                                                                    , SaleState.Open
                                                                                    , SaleState.Open
                                                                                    , SaleState.ChangeDue
                                                                                    , "lastTransitionName");
            var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            IStateConfigurationInternal <Sale, SaleState, SaleEvent> openState      = stateMachine.ConfigureState(SaleState.Open) as IStateConfigurationInternal <Sale, SaleState, SaleEvent>;
            IStateConfigurationInternal <Sale, SaleState, SaleEvent> changeDueState = stateMachine.ConfigureState(SaleState.ChangeDue) as IStateConfigurationInternal <Sale, SaleState, SaleEvent>;

            Debug.Assert(changeDueState != null, nameof(changeDueState) + " != null");
            changeDueState.AddSuperstate(openState);
            Debug.Assert(openState != null, nameof(openState) + " != null");
            openState.AddAutoForwardTransition(SaleEvent.ChangeGiven, SaleState.Complete, (sale1, _) => Task.FromResult(result: true));
            var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.ChangeGiven, sale);

            var autoTransitionResult = await changeDueState.ExecuteAutoTransitionAsync(parameters, transitionResult);

            Assert.True(autoTransitionResult.WasTransitioned);
            Assert.Equal(SaleState.Complete, sale.State);
            Assert.Equal(SaleState.Complete, autoTransitionResult.CurrentState);
            Assert.Equal(SaleState.ChangeDue, autoTransitionResult.PreviousState);
            Assert.Equal(SaleState.Open, autoTransitionResult.StartingState);
        }
        /// <summary>
        /// Adds this state as a substate to the given superState.
        /// </summary>
        /// <param name="superStateConfiguration">The superState.</param>
        public void AddSuperstate(IStateConfigurationInternal <T, TState, TTrigger> superStateConfiguration)
        {
            if (IsSubstateOf(superStateConfiguration.State))
            {
                throw new ArgumentOutOfRangeException($"{State} is already a substate of {superStateConfiguration.State}.");
            }

            if (superStateConfiguration.IsSubstateOf(State))
            {
                throw new InvalidOperationException($"{superStateConfiguration.State} is already a substate of {State}.");
            }

            _superstateConfig = superStateConfiguration;
        }