public async Task ExecuteExitActionAsync_does_not_execute_if_cancelled()
        {
            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 StateMachineAsync <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            var openState    = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine);

            var openExitActionFired = false;

            openState.AddExitAction((sale1, _) => { openExitActionFired = true; return(Task.CompletedTask); });

            using (var cancelSource = new CancellationTokenSource())
            {
                var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale, cancelSource.Token);
                cancelSource.Cancel();

                await openState.ExecuteExitActionAsync(parameters, transitionResult);
            }

            Assert.False(openExitActionFired);
        }
        public async Task FireTriggerAsync_can_cancel_trigger_event()
        {
            var sut = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale => sale.State
                , stateMutator: (sale, newState) => sale.State = newState);

            sut.AddTriggerAction(SaleEvent.AddItem, (_, cancelToken) =>
            {
                Task.Delay(millisecondsDelay: 999999, cancellationToken: cancelToken).Wait();
                return(Task.CompletedTask);
            });

            var wasCancelled = false;

            using (var cancelSource = new CancellationTokenSource())
            {
                try
                {
                    cancelSource.Cancel(throwOnFirstException: true);
                    await Task.Run(async() => await sut.FireTriggerAsync(new Sale(saleID: 45), SaleEvent.AddItem, cancelSource.Token));

                    cancelSource.Cancel(throwOnFirstException: true);
                }
                catch (AggregateException ex)
                {
                    wasCancelled = ex.InnerExceptions.OfType <OperationCanceledException>().Any();
                }
            }

            Assert.True(wasCancelled);
        }
        public void AddAutoForwardTransitionWRequest_throws_ArgumentNullException_if_Condition_null()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            Assert.Throws <ArgumentNullException>(() => sut.AddAutoForwardTransition <string>(SaleEvent.Pay, SaleState.Complete, condition: null));
        }
        public async Task FireTriggerAsyncWRequest_withReferenceTypeInstance_triggerExecutes()
        {
            var testRequest = new Request(value: 123.45);

            var sut = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale2 => sale2.State
                , stateMutator: (sale3, newState) => sale3.State = newState);

            sut.ConfigureState(SaleState.Open)
            .AddTriggerAction <Request>(SaleEvent.Pay, async(saleInstance, request, token) =>
            {
                saleInstance.Balance = request.Value;
                await Task.Delay(millisecondsDelay: 100);
            })
            .AddTransition(SaleEvent.Pay, SaleState.Complete);

            var sale = new Sale(saleID: 45)
            {
                State = SaleState.Open
            };
            var stateTransitionResult = await sut.FireTriggerAsync(sale, SaleEvent.Pay, testRequest);

            Assert.NotNull(stateTransitionResult);
            Assert.Equal(SaleState.Complete, stateTransitionResult.CurrentState);
            Assert.Equal(SaleState.Complete, sale.State);
            Assert.Equal(sale.Balance, testRequest.Value);
        }
        public async Task FireTriggerAsync_executes_superState_if_currentState_not_successful()
        {
            var sale = new Sale(saleID: 96)
            {
                State = SaleState.ChangeDue
            };
            var stateMachine             = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            var openState                = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine);
            var changeDueState           = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);
            var openStatePayTriggerFired = false;

            openState
            .AddTriggerAction(SaleEvent.Pay, (sale1, _) => { openStatePayTriggerFired = true; return(Task.CompletedTask); })
            .AddTransition(SaleEvent.Pay, SaleState.Complete, name: "openStatePay");
            changeDueState.AddSuperstate(openState);
            var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale);

            var result = await changeDueState.FireTriggerAsync(parameters);

            Assert.True(openStatePayTriggerFired);
            Assert.True(result.WasTransitioned);
            Assert.Equal(SaleState.Complete, sale.State);
            Assert.Equal(SaleState.Complete, result.CurrentState);
            Assert.Equal(SaleState.ChangeDue, result.PreviousState);
            Assert.Equal(SaleState.ChangeDue, result.StartingState);
            Assert.Equal("openStatePay", result.LastTransitionName);
        }
        public async Task FireTriggerAsync_executes_autoTransition()
        {
            var sale = new Sale(saleID: 45)
            {
                State = SaleState.Open
            };
            var sut = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale2 => sale2.State
                , stateMutator: (sale3, newState) => sale3.State = newState);

            sut.ConfigureState(SaleState.Open)
            .AddTransition(SaleEvent.Pay, SaleState.ChangeDue, conditionAsync: null, name: "toChangeDue");

            sut.ConfigureState(SaleState.ChangeDue)
            .AddAutoForwardTransition(SaleEvent.Pay, SaleState.Complete, (sale1, _) => Task.FromResult(result: true), name: "toComplete");

            var result = await sut.FireTriggerAsync(sale, SaleEvent.Pay);

            Assert.Equal(SaleState.Complete, sale.State);
            Assert.True(result.WasTransitioned);
            Assert.Equal(SaleState.Complete, result.CurrentState);
            Assert.Equal(SaleState.ChangeDue, result.PreviousState);
            Assert.Equal(SaleState.Open, result.StartingState);
            Assert.Equal("toComplete", result.LastTransitionName);
        }
        public async Task FireTriggerAsyncWRequest_executes_entryExitActions_for_autoTransition()
        {
            var sale = new Sale(saleID: 45)
            {
                State = SaleState.Open
            };
            var sut = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale2 => sale2.State
                , stateMutator: (sale3, newState) => sale3.State = newState);

            sut.ConfigureState(SaleState.Open)
            .AddTransition(SaleEvent.Pay, SaleState.ChangeDue, conditionAsync: null, name: "toChangeDue");

            sut.ConfigureState(SaleState.ChangeDue)
            .AddAutoForwardTransition(SaleEvent.Pay, SaleState.Complete, (sale1, _) => Task.FromResult(result: true), name: "toComplete");

            var completeEntryActionFired = false;

            sut.ConfigureState(SaleState.Complete)
            .AddEntryAction((sale1, _) => { completeEntryActionFired = true; return(Task.CompletedTask); });

            var result = await sut.FireTriggerAsync(sale, SaleEvent.Pay, "stringParam");

            Assert.True(completeEntryActionFired);
            Assert.Equal(SaleState.Complete, sale.State);
            Assert.True(result.WasTransitioned);
            Assert.Equal(SaleState.Complete, result.CurrentState);
            Assert.Equal(SaleState.ChangeDue, result.PreviousState);
            Assert.Equal(SaleState.Open, result.StartingState);
            Assert.Equal("toComplete", result.LastTransitionName);
        }
        public async Task ExecuteReentryActionAsync_executes_ReentryAction()
        {
            var sale = new Sale(saleID: 96)
            {
                State = SaleState.Open
            };
            var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.AddItem
                                                                                    , SaleState.Open
                                                                                    , SaleState.Open
                                                                                    , SaleState.Open
                                                                                    , "lastTransitionName");
            var stateMachine   = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            var openState      = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine);
            var changeDueState = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            changeDueState.AddSuperstate(openState);
            var changeDueEntryActionFromOpenFired = false;

            changeDueState.AddReentryAction((sale1, _) => { changeDueEntryActionFromOpenFired = true; return(Task.CompletedTask); });
            var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale);

            await changeDueState.ExecuteReentryActionAsync(parameters, transitionResult);

            Assert.True(changeDueEntryActionFromOpenFired);
        }
        public async Task FireTriggerAsyncWRequest_addTransitionSignatureWRequest_transitionExecutesWithRequestInstance()
        {
            var testRequest = new Request(value: 123.45);

            var sut = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale2 => sale2.State
                , stateMutator: (sale3, newState) => sale3.State = newState);

            var result = default(double);

            sut.ConfigureState(SaleState.Open)
            .AddTransition <Request>(SaleEvent.Pay, SaleState.Complete, (saleInstance, request, token) =>
            {
                result = request.Value;
                return(Task.FromResult(result: true));
            });

            var sale = new Sale(saleID: 45)
            {
                State = SaleState.Open
            };
            var stateTransitionResult = await sut.FireTriggerAsync(sale, SaleEvent.Pay, testRequest);

            Assert.NotNull(stateTransitionResult);
            Assert.Equal(SaleState.Complete, stateTransitionResult.CurrentState);
            Assert.Equal(SaleState.Complete, sale.State);
            Assert.Equal(result, testRequest.Value);
        }
        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 StateMachineAsync <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            IStateConfigurationAsyncInternal <Sale, SaleState, SaleEvent> openState      = stateMachine.ConfigureState(SaleState.Open) as IStateConfigurationAsyncInternal <Sale, SaleState, SaleEvent>;
            IStateConfigurationAsyncInternal <Sale, SaleState, SaleEvent> changeDueState = stateMachine.ConfigureState(SaleState.ChangeDue) as IStateConfigurationAsyncInternal <Sale, SaleState, SaleEvent>;

            changeDueState.AddSuperstate(openState);
            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);
        }
        public void AddEntryAction_throws_ArgumentNullException_if_Action_null()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            Assert.Throws <ArgumentNullException>(() => sut.AddEntryAction(action: null));
        }
        public void AddDynamicTransitionWRequest_throws_ArgumentNullException_if_Function_null()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            Assert.Throws <ArgumentNullException>(() => sut.AddDynamicTransition <string>(SaleEvent.AddItem, stateFunction: null));
        }
        public async Task ExecuteEntryActionAsync_executes_for_super_state()
        {
            var entryActionCalled = false;
            var stateMachine      = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            var openConfig        = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine);

            openConfig.AddEntryAction((sale1, _) => { entryActionCalled = true; return(Task.CompletedTask); });
            var changeDueConfig = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            changeDueConfig.MakeSubStateOf(openConfig);
            var sale = new Sale(saleID: 96)
            {
                State = SaleState.ChangeDue
            };
            var parameters       = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale);
            var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.Pay
                                                                                    , SaleState.Open
                                                                                    , SaleState.Complete
                                                                                    , SaleState.ChangeDue
                                                                                    , "lastTransitionName");

            await changeDueConfig.ExecuteEntryActionAsync(parameters, transitionResult);

            Assert.True(entryActionCalled);
        }
        public void IsSubstateOf_returns_False_if_in_given_state()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            var openState    = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine);

            Assert.False(openState.IsSubstateOf(SaleState.Open));
            Assert.False(openState.IsSubstateOf(SaleState.Complete));
        }
        public void AddAutoFallbackTransitionWRequest_adds_transition()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            sut.AddAutoFallbackTransition <string>(SaleEvent.Pay, SaleState.ChangeDue, condition: (sale, s, _) => Task.FromResult(true));

            Assert.Single((stateMachine.ConfigureState(SaleState.ChangeDue) as StateConfigurationAsync <Sale, SaleState, SaleEvent>).AutoTransitions);
        }
        public void AddReentryAction_throws_InvalidOperationException_if_already_set()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            sut.AddReentryAction((sale, _) => Task.CompletedTask);

            Assert.Throws <InvalidOperationException>(() => sut.AddReentryAction((sale, _) => Task.CompletedTask));
        }
        public void ExecuteAutoTransitionAsync_can_be_cancelled()
        {
            var stopwatch = new Stopwatch();
            var sale      = new Sale(saleID: 96)
            {
                State = SaleState.ChangeDue
            };
            var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.Pay
                                                                                    , SaleState.ChangeDue
                                                                                    , SaleState.ChangeDue
                                                                                    , SaleState.ChangeDue
                                                                                    , "lastTransitionName");
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            sut.AddAutoForwardTransition(SaleEvent.ChangeGiven, SaleState.Complete, (sale1, cancelToken) =>
            {
                do
                {
                    Task.Delay(millisecondsDelay: 99).Wait();
                } while (!cancelToken.IsCancellationRequested);

                return(Task.FromResult(result: !cancelToken.IsCancellationRequested));
            });

            using (var mutex = new Mutex(initiallyOwned: false))
                using (var cancelSource = new CancellationTokenSource())
                {
                    var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.ChangeGiven, sale, cancelSource.Token);
                    StateTransitionResult <SaleState, SaleEvent> autoTransitionResult = null;

                    Task.Factory.StartNew(async() =>
                    {
                        mutex.WaitOne();
                        autoTransitionResult = await sut.ExecuteAutoTransitionAsync(parameters, transitionResult);
                        mutex.ReleaseMutex();
                    }, TaskCreationOptions.LongRunning);

                    try
                    {
                        stopwatch.Start();
                        Task.Delay(millisecondsDelay: 2345).Wait();
                        cancelSource.Cancel();
                        mutex.WaitOne();
                    }
                    catch (Exception ex)
                    {
                        cancelSource.Cancel();
                    }

                    Assert.True(autoTransitionResult.WasCancelled);
                    Assert.False(autoTransitionResult.ConditionMet);
                    Assert.True(autoTransitionResult.TransitionDefined);
                    Assert.Equal(SaleState.ChangeDue, sale.State);
                    Assert.Equal(SaleState.ChangeDue, autoTransitionResult.CurrentState);
                }
        }
        public void AddTriggerActionWRequest_throws_InvalidOperationException_if_already_set()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            sut.AddTriggerAction <string>(SaleEvent.Pay, (sale, stringParam, _) => Task.CompletedTask);

            Assert.Throws <InvalidOperationException>(() => sut.AddTriggerAction <string>(SaleEvent.Pay, (sale, stringParam, _) => Task.CompletedTask));
        }
        public void AddTransitionWRequest_add_transition()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            sut.AddTransition <string>(SaleEvent.AddItem, SaleState.Complete, (sale, stringParam, cancelToken) => Task.FromResult(true));

            Assert.Single(sut.Transitions);
        }
        public void AddDynamicTransitionWRequest_adds_transition()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            sut.AddDynamicTransition <string>(SaleEvent.AddItem, stateFunction: (sale, request) => SaleState.Complete);

            Assert.Single(sut.Transitions);
        }
        public void AddAutoForwardTransition_throws_InvalidOperationException_if_AutoTransition_already_set()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut          = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            sut.AddAutoForwardTransition(SaleEvent.Pay, SaleState.Complete, (sale, _) => Task.FromResult(result: true));

            Assert.Throws <InvalidOperationException>(() => sut.AddAutoForwardTransition(SaleEvent.Pay, SaleState.Complete, (sale, _) => Task.FromResult(result: true)));
        }
        public void AddSuperState_throws_ArgumentOutOfRangeException_if_configuredState_already_superState()
        {
            var stateMachine    = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var changeDueConfig = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);
            var openStateConfig = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine);

            changeDueConfig.AddSuperstate(openStateConfig);

            Assert.Throws <ArgumentOutOfRangeException>(() => openStateConfig.AddSuperstate(changeDueConfig));
        }
        public void IsSubstateOf_returns_True_if_in_given_state_is_subState()
        {
            var stateMachine   = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState);
            var openState      = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine);
            var changeDueState = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);

            changeDueState.AddSuperstate(openState);

            Assert.True(changeDueState.IsSubstateOf(SaleState.Open));
            Assert.False(openState.IsSubstateOf(SaleState.ChangeDue));
        }
Пример #24
0
        public void GetStateTransitionWithAsyncCondition_returns_StateTransitionAsync()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var result       = StateTransitionFactory <Sale, SaleState, SaleEvent> .GetStateTransition(stateMachine
                                                                                                       , toState : SaleState.Complete
                                                                                                       , conditionAsync : (sale, cancelToken) => Task.FromResult(true)
                                                                                                       , name : "test"
                                                                                                       , priority : 1);

            Assert.IsType <StateTransitionAsync <Sale, SaleState, SaleEvent> >(result);
        }
        public void ConfigureState_returns_existing_state_if_already_added()
        {
            var sut = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale => sale.State
                , stateMutator: (sale, newState) => sale.State = newState);

            var firstState  = sut.ConfigureState(SaleState.Complete);
            var secondState = sut.ConfigureState(SaleState.Complete);

            Assert.Same(firstState, secondState);
        }
        public void AddSuperState_throws_ArgumentOutOfRangeException_if_substate_is_already_superstate()
        {
            var stateMachine    = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var sut             = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine);
            var openStateConfig = new StateConfigurationAsync <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine);

            //First time works fine
            openStateConfig.AddSuperstate(sut);

            //Second time blows up
            Assert.Throws <ArgumentOutOfRangeException>(() => openStateConfig.AddSuperstate(sut));
        }
Пример #27
0
        public void GetStateTransactionWTRequestAsyncStateMachineStartStateAndTriggerState_returns_StateTransitionAutoDynamicAsync()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState);
            var result       = StateTransitionFactory <Sale, SaleState, SaleEvent> .GetStateTransition <string>(stateMachine
                                                                                                                , startState : SaleState.Open
                                                                                                                , stateFunction : (sale, stringParam) => SaleState.Complete
                                                                                                                , triggerState : SaleState.ChangeDue
                                                                                                                , name : "test"
                                                                                                                , priority : 1);

            Assert.IsType <StateTransitionAutoDynamicParameterizedAsync <Sale, SaleState, SaleEvent, string> >(result);
        }
        public void AddTriggerAction_throws_InvalidOperationException_if_action_already_added_for_trigger()
        {
            var sut = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale => sale.State
                , stateMutator: (sale, newState) => sale.State = newState);

            //1st one works fine
            sut.AddTriggerAction(SaleEvent.AddItem, (sale, _) => Task.Delay(millisecondsDelay: 1, cancellationToken: _));

            //Adding the same thing 2nd time throws exception
            Assert.Throws <InvalidOperationException>(() =>
                                                      sut.AddTriggerAction(SaleEvent.AddItem, (sale, _) => Task.Delay(millisecondsDelay: 1, cancellationToken: _)));
        }
Пример #29
0
        private StateMachineAsync <Sale, SaleState, SaleEvent> getTestStateMachine()
        {
            var stateMachine = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale => sale.State
                , stateMutator: (sale, newState) => sale.State = newState);

            stateMachine.ConfigureState(SaleState.Open)
            .AddTransition(SaleEvent.Pay, SaleState.Complete, (sale1, _) => Task.FromResult(Math.Abs(sale1.Balance) < 0.00001))
            .AddTransition(SaleEvent.Pay, SaleState.ChangeDue, (sale2, _) => Task.FromResult(sale2.Balance < 0));
            stateMachine.ConfigureState(SaleState.ChangeDue)
            .AddTransition(SaleEvent.ChangeGiven, SaleState.Complete);

            return(stateMachine);
        }
        public async Task FireTriggerAsync_executes_trigger_event_when_defined()
        {
            var sut = new StateMachineAsync <Sale, SaleState, SaleEvent>(
                stateAccessor: sale => sale.State
                , stateMutator: (sale, newState) => sale.State = newState);

            var triggerActionExecuted = false;

            sut.AddTriggerAction(SaleEvent.AddItem, (sale, _) => Task.Run(() => triggerActionExecuted = true, _));

            await sut.FireTriggerAsync(new Sale(saleID : 45), SaleEvent.AddItem, default(CancellationToken));

            Assert.True(triggerActionExecuted);
        }