コード例 #1
0
        public void duration_is_the_maximum_duration_from_all_children()
        {
            var action1 = new ActionMock();
            var action2 = new ActionMock();
            var action3 = new ActionMock();
            var action4 = new ActionMock();

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromMilliseconds(150));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(3));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(5));

            action4
                .When(x => x.Duration)
                .Return(TimeSpan.FromMilliseconds(550));

            var sut = new ParallelActionBuilder()
                .AddChild(action1)
                .AddChild(action2)
                .AddChild(action3)
                .AddChild(action4)
                .Build();

            Assert.Equal(TimeSpan.FromSeconds(5), sut.Duration);
        }
コード例 #2
0
        public void duration_is_calculated_as_the_sum_of_child_durations()
        {
            var action1 = new ActionMock();
            var action2 = new ActionMock();
            var action3 = new ActionMock();

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(1));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(7));

            var sut = new SequenceActionBuilder()
                .WithChild(action1)
                .WithChild(action2)
                .WithChild(action3)
                .Build();

            Assert.Equal(TimeSpan.FromSeconds(18), sut.Duration);
        }
コード例 #3
0
        public void execute_executes_each_child_action()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);
            var action3 = new ActionMock(MockBehavior.Loose);
            var sut = new SequenceActionBuilder()
                .WithChild(action1)
                .WithChild(action2)
                .WithChild(action3)
                .Build();

            using (var context = new ExecutionContext())
            {
                sut.Execute(context).Subscribe();

                action1
                    .Verify(x => x.Execute(context))
                    .WasCalledExactlyOnce();

                action2
                    .Verify(x => x.Execute(context))
                    .WasCalledExactlyOnce();

                action3
                    .Verify(x => x.Execute(context))
                    .WasCalledExactlyOnce();
            }
        }
コード例 #4
0
        public void execute_async_logs_any_error_raised_by_the_inner_action()
        {
            var waitHandle = new ManualResetEventSlim();
            var logger = new LoggerMock(MockBehavior.Loose);
            var loggerService = new LoggerServiceMock(MockBehavior.Loose);
            var action = new ActionMock(MockBehavior.Loose);

            logger
                .When(x => x.Error(It.IsAny<string>()))
                .Do(waitHandle.Set);

            loggerService
                .When(x => x.GetLogger(It.IsAny<Type>()))
                .Return(logger);

            action
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Return(Observable.Throw<Unit>(new InvalidOperationException("Something bad happened")));

            var sut = new DoNotAwaitActionBuilder()
                .WithLoggerService(loggerService)
                .WithInnerAction(action)
                .Build();

            sut.ExecuteAsync(new ExecutionContext());

            Assert.True(waitHandle.Wait(TimeSpan.FromSeconds(3)));
        }
コード例 #5
0
        public void execute_async_executes_each_child_action()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);
            var action3 = new ActionMock(MockBehavior.Loose);
            var action4 = new ActionMock(MockBehavior.Loose);

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(1));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(2));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(3));

            action4
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(4));

            var sut = new ParallelActionBuilder()
                .AddChild(action1)
                .AddChild(action2)
                .AddChild(action3)
                .AddChild(action4)
                .Build();

            using (var context = new ExecutionContext())
            {
                sut.ExecuteAsync(context);

                action1
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasCalledExactlyOnce();

                action2
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasCalledExactlyOnce();

                action3
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasCalledExactlyOnce();

                action4
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasCalledExactlyOnce();
            }
        }
コード例 #6
0
        public void duration_always_returns_zero_regardless_of_inner_action_duration()
        {
            var action = new ActionMock();

            action
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(3));

            var sut = new DoNotAwaitActionBuilder()
                .WithInnerAction(action)
                .Build();

            Assert.Equal(TimeSpan.Zero, sut.Duration);
        }
コード例 #7
0
        public void duration_returns_duration_in_model(int durationInMs)
        {
            var action = new ActionMock(MockBehavior.Loose);

            action
                .When(x => x.Duration)
                .Return(TimeSpan.FromMilliseconds(durationInMs));

            var sut = new ExerciseViewModelBuilder()
                .WithModel(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action))
                .Build();

            Assert.Equal(TimeSpan.FromMilliseconds(durationInMs), sut.Duration);
        }
コード例 #8
0
        public void duration_returns_sum_of_action_durations()
        {
            var action1 = new ActionMock();
            var action2 = new ActionMock();
            var action3 = new ActionMock();

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(3));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(1));

            var eventMatcher1 = new EventMatcherMock();
            var eventMatcher2 = new EventMatcherMock();
            var eventMatcher3 = new EventMatcherMock();

            eventMatcher1
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is BeforeExerciseEvent);

            eventMatcher2
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is DuringRepetitionEvent);

            eventMatcher3
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is AfterSetEvent);

            var sut = new ExerciseBuilder()
                .WithSetCount(2)
                .WithRepetitionCount(3)
                .WithMatcherWithAction(new MatcherWithAction(eventMatcher1, action1))
                .WithMatcherWithAction(new MatcherWithAction(eventMatcher2, action2))
                .WithMatcherWithAction(new MatcherWithAction(eventMatcher3, action3))
                .Build();

            Assert.Equal(TimeSpan.FromSeconds(30), sut.Duration);
        }
コード例 #9
0
        public void execute_async_does_not_wait_for_inner_actions_execution_to_complete_before_itself_completing()
        {
            var action = new ActionMock();

            action
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Return(Observable.Never<Unit>());

            var sut = new DoNotAwaitActionBuilder()
                .WithInnerAction(action)
                .Build();

            var completed = false;
            sut
                .ExecuteAsync(new ExecutionContext())
                .Subscribe(_ => completed = true);

            Assert.True(completed);
        }
コード例 #10
0
        public void duration_is_the_sum_of_all_exercise_durations()
        {
            var action1 = new ActionMock();
            var action2 = new ActionMock();

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(1));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            var sut = new ExerciseProgramBuilder()
                .AddExercise(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action1))
                .AddExercise(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action2))
                .AddExercise(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action1))
                .Build();

            Assert.Equal(TimeSpan.FromSeconds(12), sut.Duration);
        }
コード例 #11
0
        public void skip_backwards_command_is_disabled_if_on_first_exercise()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock(MockBehavior.Loose);

            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.IsPaused = true;
                        return ec.WaitWhilePaused();
                    });

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .WithExercise(new ExerciseBuilder()
                        .WithBeforeExerciseAction(action)))
                .WithScheduler(scheduler)
                .Build();

            sut.StartCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            Assert.False(sut.SkipBackwardsCommand.CanExecute.FirstAsync().Wait());
        }
コード例 #12
0
        public void is_pause_visible_cycles_correctly_if_start_command_is_executed()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock(MockBehavior.Loose);
            action
                .When(x => x.Duration)
                .Return(TimeSpan.FromMinutes(1));
            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                        Observable
                            .Return(Unit.Default)
                            .Do(_ => { })
                            .Delay(TimeSpan.FromMinutes(1), scheduler)
                            .Do(_ => ec.AddProgress(TimeSpan.FromMinutes(1))));
            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(
                    new ExerciseProgramBuilder()
                        .WithExercise(
                            new ExerciseBuilder()
                                .WithBeforeExerciseAction(action)))
                .WithScheduler(scheduler)
                .Build();

            Assert.False(sut.IsPauseVisible);

            sut.StartCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();
            Assert.True(sut.IsPauseVisible);

            scheduler.AdvanceBy(TimeSpan.FromMinutes(10));
            Assert.False(sut.IsPauseVisible);
        }
コード例 #13
0
        public void progress_is_updated_throughout_execution()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock(MockBehavior.Loose);

            action
                .When(x => x.Duration)
                .Return(TimeSpan.FromMinutes(1));

            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.AddProgress(TimeSpan.FromSeconds(15));
                        ec.AddProgress(TimeSpan.FromSeconds(30));

                        ec.IsPaused = true;

                        return ec.WaitWhilePaused();
                    });

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .WithExercise(new ExerciseBuilder()
                        .WithBeforeExerciseAction(action)))
                .WithScheduler(scheduler)
                .Build();

            var progress = sut
                .WhenAnyValue(x => x.Progress)
                .CreateCollection();

            sut.StartCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            Assert.Equal(3, progress.Count);
            Assert.Equal(0, progress[0]);
            Assert.Equal(0.25, progress[1]);
            Assert.Equal(0.75, progress[2]);
        }
コード例 #14
0
        public void execute_executes_each_child_action_in_order()
        {
            var childCount = 10;
            var childExecutionOrder = new int[childCount];
            var executionOrder = 0;
            var childActions = Enumerable
                .Range(0, childCount)
                .Select(
                    (i, _) =>
                    {
                        var childAction = new ActionMock(MockBehavior.Loose);
                        childAction
                            .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                            .Do(() => childExecutionOrder[i] = Interlocked.Increment(ref executionOrder))
                            .Return(Observable.Return(Unit.Default));
                        return childAction;
                    })
                .ToList();
            
            var sut = new SequenceActionBuilder()
                .WithChildren(childActions)
                .Build();

            using (var context = new ExecutionContext())
            {
                sut.Execute(context).Subscribe();

                for (var i = 0; i < childExecutionOrder.Length; ++i)
                {
                    Assert.Equal(i + 1, childExecutionOrder[i]);
                }
            }
        }
コード例 #15
0
        public void progress_time_span_is_updated_throughout_execution()
        {
            var scheduler = new TestSchedulerService();
            var action = new ActionMock(MockBehavior.Loose);

            action
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.AddProgress(TimeSpan.FromSeconds(1));
                        ec.AddProgress(TimeSpan.FromSeconds(3));

                        ec.IsPaused = true;

                        return ec.WaitWhilePausedAsync();
                    });

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .AddExercise(new ExerciseBuilder()
                        .WithBeforeExerciseAction(action)))
                .WithSchedulerService(scheduler)
                .Build();

            var progressTimeSpan = sut
                .WhenAnyValue(x => x.ProgressTimeSpan)
                .CreateCollection();

            sut.StartCommand.Execute(null);
            scheduler.AdvanceMinimal();

            Assert.Equal(3, progressTimeSpan.Count);
            Assert.Equal(TimeSpan.Zero, progressTimeSpan[0]);
            Assert.Equal(TimeSpan.FromSeconds(1), progressTimeSpan[1]);
            Assert.Equal(TimeSpan.FromSeconds(4), progressTimeSpan[2]);
        }
コード例 #16
0
        public void execute_async_ensures_progress_of_child_actions_does_not_compound_when_skipping()
        {
            var action1 = new ActionMock();
            var action2 = new ActionMock();
            var action3 = new ActionMock();
            var action4 = new ActionMock();

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(3));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(8));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action4
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(4));

            action1
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Do<ExecutionContext>(ec => ec.AddProgress(action1.Duration))
                .Return(Observable.Return(Unit.Default));

            action2
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Do<ExecutionContext>(ec => ec.AddProgress(action2.Duration))
                .Return(Observable.Return(Unit.Default));

            action3
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Do<ExecutionContext>(ec => ec.AddProgress(action3.Duration))
                .Return(Observable.Return(Unit.Default));

            action4
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Do<ExecutionContext>(ec => ec.AddProgress(action4.Duration))
                .Return(Observable.Return(Unit.Default));

            var sut = new ParallelActionBuilder()
                .AddChild(action1)
                .AddChild(action2)
                .AddChild(action3)
                .AddChild(action4)
                .Build();

            using (var context = new ExecutionContext(TimeSpan.FromSeconds(5)))
            {
                sut.ExecuteAsync(context);

                Assert.Equal(TimeSpan.FromSeconds(10), context.Progress);

                action1
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasNotCalled();

                action4
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasNotCalled();
            }
        }
コード例 #17
0
        public void execute_async_correctly_handles_a_skip_ahead_value_that_exceeds_even_the_longest_child_actions_duration()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);
            var action3 = new ActionMock(MockBehavior.Loose);

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromMinutes(1));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(71));

            var sut = new ParallelActionBuilder()
                .AddChild(action1)
                .AddChild(action2)
                .AddChild(action3)
                .Build();

            using (var context = new ExecutionContext(TimeSpan.FromMinutes(3)))
            {
                sut.ExecuteAsync(context);

                action1
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasNotCalled();

                action2
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasNotCalled();

                action3
                    .Verify(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .WasNotCalled();

                Assert.Equal(TimeSpan.FromSeconds(71), context.Progress);
            }
        }
コード例 #18
0
        public void execute_async_context_can_be_paused_by_child_action_that_is_not_the_longest()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(8));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(13));

            action1
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Do<ExecutionContext>(ec => ec.IsPaused = true)
                .Return(Observable.Return(Unit.Default));

            var sut = new ParallelActionBuilder()
                .AddChild(action1)
                .AddChild(action2)
                .Build();

            using (var context = new ExecutionContext())
            {
                sut.ExecuteAsync(context);

                // can't assume certain actions did not execute because actions run in parallel, but we can check the context is paused
                Assert.True(context.IsPaused);
            }
        }
コード例 #19
0
        public void execute_skips_child_actions_that_are_shorter_than_the_skip_ahead_even_if_the_context_is_paused()
        {
            var action1 = new ActionMock();
            var action2 = new ActionMock();
            var action3 = new ActionMock(MockBehavior.Loose);

            action1
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Throw();

            action2
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Throw();

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(3));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(8));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(2));

            var sut = new SequenceActionBuilder()
                .WithChild(action1)
                .WithChild(action2)
                .WithChild(action3)
                .Build();

            using (var context = new ExecutionContext(TimeSpan.FromSeconds(11)))
            {
                context.IsPaused = true;
                sut.Execute(context).Subscribe();

                action3
                    .Verify(x => x.Execute(context))
                    .WasCalledExactlyOnce();
            }
        }
コード例 #20
0
        public void skip_forwards_command_skips_to_the_next_exercise()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock();

            action
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.IsPaused = true;

                        return ec.WaitWhilePaused();
                    });

            var exercise1 = new ExerciseBuilder()
                .WithName("Exercise 1")
                .WithBeforeExerciseAction(action)
                .Build();

            var exercise2 = new ExerciseBuilder()
                .WithName("Exercise 2")
                .WithBeforeExerciseAction(action)
                .Build();

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .WithExercise(exercise1)
                    .WithExercise(exercise2))
                .WithScheduler(scheduler)
                .Build();

            var progress = sut
                .WhenAnyValue(x => x.ProgressTimeSpan)
                .CreateCollection();

            sut.StartCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            sut.SkipForwardsCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            Assert.Equal(2, progress.Count);
            Assert.Equal(TimeSpan.Zero, progress[0]);
            Assert.Equal(TimeSpan.FromSeconds(10), progress[1]);
        }
コード例 #21
0
        public void skip_backwards_command_restarts_the_execution_context_from_the_start_of_the_previous_exercise_if_the_current_exercise_if_only_recently_started()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock();

            action
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.AddProgress(TimeSpan.FromSeconds(0.5));
                        ec.IsPaused = true;

                        return ec.WaitWhilePaused();
                    });

            var exercise1 = new ExerciseBuilder()
                .WithName("Exercise 1")
                .WithBeforeExerciseAction(action)
                .Build();

            var exercise2 = new ExerciseBuilder()
                .WithName("Exercise 2")
                .WithBeforeExerciseAction(action)
                .Build();

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .WithExercise(exercise1)
                    .WithExercise(exercise2))
                .WithScheduler(scheduler)
                .Build();

            var progress = sut
                .WhenAnyValue(x => x.ProgressTimeSpan)
                .CreateCollection();

            // start from the second exercise
            sut.StartCommand.ExecuteAsync(exercise1.Duration);
            scheduler.AdvanceMinimal();

            sut.SkipBackwardsCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            Assert.Equal(5, progress.Count);
            Assert.Equal(TimeSpan.Zero, progress[0]);
            Assert.Equal(TimeSpan.FromSeconds(10), progress[1]);
            Assert.Equal(TimeSpan.FromSeconds(10.5), progress[2]);
            Assert.Equal(TimeSpan.Zero, progress[3]);
            Assert.Equal(TimeSpan.FromSeconds(10), progress[4]);
        }
コード例 #22
0
        public void skip_backwards_command_is_enabled_if_sufficient_progress_has_been_made_through_first_exercise()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock(MockBehavior.Loose);

            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.AddProgress(TimeSpan.FromSeconds(1));
                        ec.IsPaused = true;
                        return ec.WaitWhilePaused();
                    });

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .WithExercise(new ExerciseBuilder()
                        .WithBeforeExerciseAction(action)))
                .WithScheduler(scheduler)
                .Build();

            // TODO: technically, I should just check CanExecute(null) at the end, but without this subscription the RxCommand does not update CanExecute correctly
            //       try changing this once I'm using new RxCommand
            var canExecute = sut
                .SkipBackwardsCommand
                .CanExecute
                .CreateCollection();

            sut.StartCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            Assert.Equal(2, canExecute.Count);
            Assert.False(canExecute[0]);
            Assert.True(canExecute[1]);
        }
コード例 #23
0
        public void execute_async_skips_exercises_that_are_shorter_than_the_skip_ahead()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);
            var action3 = new ActionMock(MockBehavior.Loose);

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(13));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(5));

            action1
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Throw();

            action2
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Throw();

            var sut = new ExerciseProgramBuilder()
                .AddExercise(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action1))
                .AddExercise(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action2))
                .AddExercise(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action3))
                .Build();

            using (var executionContext = new ExecutionContext(TimeSpan.FromSeconds(23)))
            {
                sut.ExecuteAsync(executionContext);

                action3
                    .Verify(x => x.ExecuteAsync(executionContext))
                    .WasCalledExactlyOnce();
            }
        }
コード例 #24
0
        public void execute_async_executes_each_exercise()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);

            var sut = new ExerciseProgramBuilder()
                .AddExercise(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action1))
                .AddExercise(new ExerciseBuilder()
                    .WithBeforeExerciseAction(action2))
                .Build();

            using (var executionContext = new ExecutionContext())
            {
                sut.ExecuteAsync(executionContext);

                action1
                    .Verify(x => x.ExecuteAsync(executionContext))
                    .WasCalledExactlyOnce();

                action2
                    .Verify(x => x.ExecuteAsync(executionContext))
                    .WasCalledExactlyOnce();
            }
        }
コード例 #25
0
        public void skip_backwards_command_restarts_the_execution_context_from_the_start_of_the_current_exercise_if_sufficient_progress_has_been_made()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock(MockBehavior.Loose);

            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.AddProgress(TimeSpan.FromSeconds(4));
                        ec.IsPaused = true;

                        return ec.WaitWhilePaused();
                    });

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .WithExercise(new ExerciseBuilder()
                        .WithBeforeExerciseAction(action)))
                .WithScheduler(scheduler)
                .Build();

            var progress = sut
                .WhenAnyValue(x => x.ProgressTimeSpan)
                .CreateCollection();

            sut.StartCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            sut.SkipBackwardsCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            Assert.Equal(3, progress.Count);
            Assert.Equal(TimeSpan.Zero, progress[0]);
            Assert.Equal(TimeSpan.FromSeconds(4), progress[1]);
            Assert.Equal(TimeSpan.Zero, progress[2]);
        }
コード例 #26
0
        public void execute_async_executes_all_appropriate_actions()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);
            var action3 = new ActionMock(MockBehavior.Loose);
            var eventMatcher1 = new EventMatcherMock();
            var eventMatcher2 = new EventMatcherMock();
            var eventMatcher3 = new EventMatcherMock();

            eventMatcher1
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is BeforeExerciseEvent);

            eventMatcher2
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is DuringRepetitionEvent);

            eventMatcher3
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is AfterSetEvent);

            var sut = new ExerciseBuilder()
                .WithSetCount(2)
                .WithRepetitionCount(3)
                .AddMatcherWithAction(new MatcherWithAction(eventMatcher1, action1))
                .AddMatcherWithAction(new MatcherWithAction(eventMatcher2, action2))
                .AddMatcherWithAction(new MatcherWithAction(eventMatcher3, action3))
                .Build();

            using (var executionContext = new ExecutionContext())
            {
                sut.ExecuteAsync(executionContext);

                action1
                    .Verify(x => x.ExecuteAsync(executionContext))
                    .WasCalledExactlyOnce();

                action2
                    .Verify(x => x.ExecuteAsync(executionContext))
                    .WasCalledExactly(times: 6);

                action3
                    .Verify(x => x.ExecuteAsync(executionContext))
                    .WasCalledExactly(times: 2);
            }
        }
コード例 #27
0
        public void skip_forwards_command_is_disabled_if_on_last_exercise()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock();

            action
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.IsPaused = true;

                        return ec.WaitWhilePaused();
                    });

            var exercise1 = new ExerciseBuilder()
                .WithName("Exercise 1")
                .WithBeforeExerciseAction(action)
                .Build();

            var exercise2 = new ExerciseBuilder()
                .WithName("Exercise 2")
                .WithBeforeExerciseAction(action)
                .Build();

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .WithExercise(exercise1)
                    .WithExercise(exercise2))
                .WithScheduler(scheduler)
                .Build();

            var canExecute = sut
                .SkipForwardsCommand
                .CanExecute
                .CreateCollection();

            sut.StartCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            sut.SkipForwardsCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();

            Assert.Equal(5, canExecute.Count);
            Assert.False(canExecute[0]);
            Assert.True(canExecute[1]);
            Assert.False(canExecute[2]);
            Assert.True(canExecute[3]);
            Assert.False(canExecute[4]);
        }
コード例 #28
0
        public void execute_async_does_not_skip_zero_duration_actions()
        {
            var action = new ActionMock(MockBehavior.Loose);
            var eventMatcher = new EventMatcherMock();

            eventMatcher
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is BeforeExerciseEvent);

            var sut = new ExerciseBuilder()
                .AddMatcherWithAction(new MatcherWithAction(eventMatcher, action))
                .Build();

            using (var executionContext = new ExecutionContext())
            {
                sut.ExecuteAsync(executionContext);

                action
                    .Verify(x => x.ExecuteAsync(executionContext))
                    .WasCalledExactlyOnce();
            }
        }
コード例 #29
0
        public void current_exercise_reflects_that_in_the_execution_context()
        {
            var scheduler = new TestScheduler();
            var action = new ActionMock();

            action
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action
                .When(x => x.Execute(It.IsAny<ExecutionContext>()))
                .Return<ExecutionContext>(
                    ec =>
                    {
                        ec.IsPaused = true;
                        return ec.WaitWhilePaused();
                    });

            var exercise1 = new ExerciseBuilder()
                .WithName("Exercise 1")
                .WithBeforeExerciseAction(action)
                .Build();

            var exercise2 = new ExerciseBuilder()
                .WithName("Exercise 2")
                .WithBeforeExerciseAction(action)
                .Build();

            var exercise3 = new ExerciseBuilder()
                .WithName("Exercise 3")
                .WithBeforeExerciseAction(action)
                .Build();

            var sut = new ExerciseProgramViewModelBuilder()
                .WithModel(new ExerciseProgramBuilder()
                    .WithExercise(exercise1)
                    .WithExercise(exercise2)
                    .WithExercise(exercise3))
                .WithScheduler(scheduler)
                .Build();

            sut.StartCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();
            Assert.Equal("Exercise 1", sut.CurrentExercise?.Name);

            sut.SkipForwardsCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();
            Assert.Equal("Exercise 2", sut.CurrentExercise?.Name);

            sut.SkipForwardsCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();
            Assert.Equal("Exercise 3", sut.CurrentExercise?.Name);

            sut.SkipBackwardsCommand.ExecuteAsync();
            scheduler.AdvanceMinimal();
            Assert.Equal("Exercise 2", sut.CurrentExercise?.Name);
        }
コード例 #30
0
        public void execute_async_skips_actions_that_are_shorter_than_the_skip_ahead_even_if_the_context_is_paused()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);
            var action3 = new ActionMock(MockBehavior.Loose);
            var eventMatcher1 = new EventMatcherMock();
            var eventMatcher2 = new EventMatcherMock();
            var eventMatcher3 = new EventMatcherMock();

            action1
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(10));

            action2
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(3));

            action3
                .When(x => x.Duration)
                .Return(TimeSpan.FromSeconds(1));

            action1
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Throw();

            action2
                .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                .Throw();

            eventMatcher1
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is BeforeExerciseEvent);

            eventMatcher2
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is BeforeExerciseEvent);

            eventMatcher3
                .When(x => x.Matches(It.IsAny<IEvent>()))
                .Return((IEvent @event) => @event is BeforeExerciseEvent);

            var sut = new ExerciseBuilder()
                .AddMatcherWithAction(new MatcherWithAction(eventMatcher1, action1))
                .AddMatcherWithAction(new MatcherWithAction(eventMatcher2, action2))
                .AddMatcherWithAction(new MatcherWithAction(eventMatcher3, action3))
                .Build();

            using (var executionContext = new ExecutionContext(TimeSpan.FromSeconds(13)))
            {
                executionContext.IsPaused = true;
                sut.ExecuteAsync(executionContext);

                action3
                    .Verify(x => x.ExecuteAsync(executionContext))
                    .WasCalledExactlyOnce();
            }
        }