예제 #1
0
        public async Task ExecuteAsync_WithSelectedTransitionAndCanceled_RunsCanceledActionAndThrowsOperationCanceledException()
        {
            var tracker = new TestTracker();

            using (var cts = new CancellationTokenSource())
            {
                var selectedTransition = new RuntimeTransition("Selected", A.Fake <ITransitionTarget>(), tracker.TransitionAction, null);
                var elseTransition     = new RuntimeTransition("Else", A.Fake <ITransitionTarget>(), tracker.TransitionAction, null);

                var state = A.Fake <ChoiceRuntimeStateBase>(builder =>
                                                            builder
                                                            .WithArgumentsForConstructor(new object[]
                {
                    "test",
                    tracker.StateEnterAction,
                    tracker.StateExitAction,
                    tracker.StateCanceledAction,
                    elseTransition,
                })
                                                            .CallsBaseMethods());

                A.CallTo(state)
                .Where(call => call.Method.Name == "SelectTransition")
                .WithReturnType <RuntimeTransition>()
                .ReturnsLazily(() =>
                {
                    cts.Cancel();
                    return(selectedTransition);
                });

                await Assert.ThrowsAsync <OperationCanceledException>(async() => await state.ExecuteAsync(cts.Token));
            }

            Assert.Equal(">test;!test;", tracker.ToString());
        }
예제 #2
0
        public async Task ExecuteAsync_WhenSelectorReturnsExistingOption_ReturnsTransitionForOption()
        {
            var tracker = new TestTracker();

            var selectedTransition = new RuntimeTransition("1", A.Fake <ITransitionTarget>(), null, null);
            var elseTransition     = new RuntimeTransition("False", A.Fake <ITransitionTarget>(), null, null);

            var state = new SwitchRuntimeState <int>(
                "test",
                tracker.StateEnterAction,
                tracker.StateExitAction,
                tracker.StateCanceledAction,
                elseTransition,
                new Dictionary <int, RuntimeTransition>
            {
                { 0, new RuntimeTransition("0", null, null, null) },
                { 1, selectedTransition },
                { 2, new RuntimeTransition("2", null, null, null) },
            },
                () => 1);

            var actual = await state.ExecuteAsync(CancellationToken.None);

            Assert.Equal(selectedTransition, actual);
        }
예제 #3
0
        public async Task ExecuteAsync_WithoutSelectedTransitionAndNotCanceled_ReturnElseTransitionAndRunsEnterAndExitActions()
        {
            var tracker = new TestTracker();

            var elseTransition = new RuntimeTransition("Else", A.Fake <ITransitionTarget>(), tracker.TransitionAction, null);

            var state = A.Fake <ChoiceRuntimeStateBase>(builder =>
                                                        builder
                                                        .WithArgumentsForConstructor(new object[]
            {
                "test",
                tracker.StateEnterAction,
                tracker.StateExitAction,
                tracker.StateCanceledAction,
                elseTransition,
            })
                                                        .CallsBaseMethods());

            A.CallTo(state)
            .Where(call => call.Method.Name == "SelectTransition")
            .WithReturnType <RuntimeTransition>()
            .Returns(null);

            var actual = await state.ExecuteAsync(CancellationToken.None);

            Assert.Equal(elseTransition, actual);

            Assert.Equal(">test;<test;", tracker.ToString());
        }
예제 #4
0
        public async Task ExecuteAsync_WithoutCancellationAndNonTargettedTransitions_RunsEnterAndExecutesTransitionsUntilTargettedTransitionAndExitActionsAndReturnsTargettedTransitionWithoutExecuting()
        {
            var tracker = new TestTracker();

            var targetedTransition    = new RuntimeTransition("Targeted", A.Fake <ITransitionTarget>(), tracker.TransitionAction, null);
            var nonTargetedTransition = new RuntimeTransition("NonTargeted", null, tracker.TransitionAction, null);

            var state = A.Fake <RuntimeStateBase>(builder =>
                                                  builder
                                                  .WithArgumentsForConstructor(new object[]
            {
                "test",
                tracker.StateEnterAction,
                tracker.StateExitAction,
                tracker.StateCanceledAction,
            })
                                                  .CallsBaseMethods());

            A.CallTo(state)
            .Where(call => call.Method.Name == "ExecuteStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .ReturnsNextFromSequence(nonTargetedTransition, nonTargetedTransition, targetedTransition);

            var actual = await state.ExecuteAsync(CancellationToken.None);

            Assert.Equal(targetedTransition, actual);
            Assert.Equal(">test;@test;@test;<test;", tracker.ToString());
        }
예제 #5
0
        public async Task ExecuteAsync_WithEventTransitionsNotCanceledWithTriggeredEventTransition_ReturnsEventTransitionAndAcknowledgesHandledEvent()
        {
            var tracker = new TestTracker();

            var eventName = "event";

            var eventTransition = new RuntimeTransition("Targeted", A.Fake <ITransitionTarget>(), tracker.TransitionAction, null);
            var stateTransition = new RuntimeTransition("State", A.Fake <ITransitionTarget>(), tracker.TransitionAction, null);

            var state = A.Fake <EventRuntimeStateBase>(
                x =>
            {
                x.WithArgumentsForConstructor(new object[]
                {
                    "test",
                    tracker.StateEnterAction,
                    tracker.StateExitAction,
                    tracker.StateCanceledAction,
                });

                x.CallsBaseMethods();
            });

            A.CallTo(state)
            .Where(call => call.Method.Name == "EnterStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .CallsBaseMethod();

            A.CallTo(state)
            .Where(call => call.Method.Name == "ExitStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .CallsBaseMethod();

            A.CallTo(state)
            .Where(call => call.Method.Name == "ExecuteEventStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .Returns(Task.FromResult <RuntimeTransition>(null))
            .Once();

            state.AddEventTransition(eventName, eventTransition);

            var executeTask = state.ExecuteAsync(CancellationToken.None);

            Assert.True(await state.PublishEventAsync(eventName));

            var actual = await executeTask;

            A.CallTo(state)
            .Where(call => call.Method.Name == "ExecuteEventStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .MustHaveHappened(Repeated.Exactly.Once);

            Assert.Equal(eventTransition, actual);
            Assert.Equal(">test;!test;", tracker.ToString());
        }
예제 #6
0
        public async Task ExecuteAsync_WithEventTransitionsNotCanceledWithoutTriggeredEventTransitionAndStateExecutionReturningNull_DoesntCompleteExecution()
        {
            var tracker = new TestTracker();

            var eventName = "event";

            var eventTransition = new RuntimeTransition("Event", A.Fake <ITransitionTarget>(), tracker.TransitionAction, null);

            var stateMock = A.Fake <EventRuntimeStateBase>(
                x =>
            {
                x.WithArgumentsForConstructor(new object[]
                {
                    "test",
                    tracker.StateEnterAction,
                    tracker.StateExitAction,
                    tracker.StateCanceledAction,
                });

                x.CallsBaseMethods();
            });

            A.CallTo(stateMock)
            .Where(call => call.Method.Name == "EnterStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .CallsBaseMethod();

            A.CallTo(stateMock)
            .Where(call => call.Method.Name == "ExitStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .CallsBaseMethod();

            A.CallTo(stateMock)
            .Where(call => call.Method.Name == "ExecuteEventStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .Returns(Task.FromResult <RuntimeTransition>(null))
            .Once();

            stateMock.AddEventTransition(eventName, eventTransition);

            var executeTask = stateMock.ExecuteAsync(CancellationToken.None);

            A.CallTo(stateMock)
            .Where(call => call.Method.Name == "ExecuteEventStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .MustHaveHappened(Repeated.Exactly.Once);

            Assert.False(executeTask.IsCompleted);
            Assert.Equal(">test;", tracker.ToString());
        }
예제 #7
0
        public async Task ExecuteAsync_WithoutEventTransitionsNotCanceled_ReturnsReturnValueOfExecuteEventStepAsync()
        {
            var tracker = new TestTracker();

            var stateTransition = new RuntimeTransition("Targeted", A.Fake <ITransitionTarget>(), tracker.TransitionAction, null);

            var stateMock = A.Fake <EventRuntimeStateBase>(
                x =>
            {
                x.WithArgumentsForConstructor(new object[]
                {
                    "test",
                    tracker.StateEnterAction,
                    tracker.StateExitAction,
                    tracker.StateCanceledAction,
                });

                x.CallsBaseMethods();
            });

            A.CallTo(stateMock)
            .Where(call => call.Method.Name == "EnterStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .CallsBaseMethod();

            A.CallTo(stateMock)
            .Where(call => call.Method.Name == "ExitStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .CallsBaseMethod();

            A.CallTo(stateMock)
            .Where(call => call.Method.Name == "ExecuteEventStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .Returns(Task.FromResult <RuntimeTransition>(stateTransition))
            .Once();

            var actual = await stateMock.ExecuteAsync(CancellationToken.None);

            A.CallTo(stateMock)
            .Where(call => call.Method.Name == "ExecuteEventStepAsync")
            .WithReturnType <Task <RuntimeTransition> >()
            .MustHaveHappened(Repeated.Exactly.Once);

            Assert.Equal(stateTransition, actual);
            Assert.Equal(">test;<test;", tracker.ToString());
        }
예제 #8
0
        public async Task ExecuteAsync_WhenPredicateReturnsFalse_ReturnsElseTransition()
        {
            var tracker = new TestTracker();

            var trueTransition = new RuntimeTransition("True", A.Fake <ITransitionTarget>(), null, null);
            var elseTransition = new RuntimeTransition("False", A.Fake <ITransitionTarget>(), null, null);

            var state = new IfElseRuntimeState(
                "test",
                tracker.StateEnterAction,
                tracker.StateExitAction,
                tracker.StateCanceledAction,
                elseTransition,
                trueTransition,
                () => false);

            var actual = await state.ExecuteAsync(CancellationToken.None);

            Assert.Equal(elseTransition, actual);
        }