public void cancel_raises_property_changed_for_is_cancelled()
        {
            var sut = new ExecutionContext();
            var called = false;
            sut.ObservableForProperty(x => x.IsCancelled)
                .Subscribe(_ => called = true);

            Assert.False(called);
            sut.Cancel();
            Assert.True(called);
        }
        public void cancel_cancels_the_cancellation_token()
        {
            var sut = new ExecutionContext();
            var token = sut.CancellationToken;
            Assert.False(sut.IsCancelled);
            Assert.False(token.IsCancellationRequested);

            sut.Cancel();
            Assert.True(sut.IsCancelled);
            Assert.True(token.IsCancellationRequested);
        }
        public void execute_async_cancels_if_context_is_cancelled()
        {
            var sut = new SayActionBuilder()
                .Build();

            using (var context = new ExecutionContext())
            {
                context.Cancel();

                Assert.Throws<OperationCanceledException>(() => sut.ExecuteAsync(context));
            }
        }
        public void wait_while_paused_does_not_complete_if_the_context_is_cancelled()
        {
            var sut = new ExecutionContext();
            sut.IsPaused = true;

            var executed = false;
            sut
                .WaitWhilePaused()
                .Subscribe(_ => executed = true);

            sut.Cancel();
            Assert.False(executed);
        }
        public void wait_while_paused_async_cancels_if_the_context_is_cancelled()
        {
            var sut = new ExecutionContext();
            sut.IsPaused = true;

            var cancelled = false;
            sut
                .WaitWhilePausedAsync()
                .Catch<Unit, OperationCanceledException>(
                    _ =>
                    {
                        cancelled = true;
                        return Observable.Return(Unit.Default);
                    })
                .Subscribe();

            Assert.False(cancelled);

            sut.Cancel();

            Assert.True(cancelled);
        }
        public void execute_async_bails_out_if_context_is_cancelled()
        {
            var delayService = new DelayServiceMock();
            var delayCallCount = 0;

            using (var context = new ExecutionContext())
            {
                delayService
                    .When(x => x.DelayAsync(It.IsAny<TimeSpan>(), It.IsAny<CancellationToken>()))
                    .Do(
                        () =>
                        {
                            if (delayCallCount++ == 2)
                            {
                                context.Cancel();
                            }
                        })
                    .Return(Observable.Return(Unit.Default));

                var sut = new WaitActionBuilder()
                    .WithDelayService(delayService)
                    .WithDelay(TimeSpan.FromSeconds(50))
                    .Build();

                sut.ExecuteAsync(context);
                Assert.True(context.IsCancelled);

                delayService
                    .Verify(x => x.DelayAsync(It.IsAny<TimeSpan>(), It.IsAny<CancellationToken>()))
                    .WasCalledExactly(times: 3);
            }
        }
        public void execute_async_stops_executing_if_the_context_is_cancelled()
        {
            var action1 = new ActionMock(MockBehavior.Loose);
            var action2 = new ActionMock(MockBehavior.Loose);
            var action3 = new ActionMock(MockBehavior.Loose);
            var sut = new SequenceActionBuilder()
                .AddChild(action1)
                .AddChild(action2)
                .AddChild(action3)
                .Build();

            using (var context = new ExecutionContext())
            {
                action2
                    .When(x => x.ExecuteAsync(It.IsAny<ExecutionContext>()))
                    .Do(() => context.Cancel())
                    .Return(Observable.Return(Unit.Default));

                Assert.ThrowsAsync<OperationCanceledException>(async () => await sut.ExecuteAsync(context));

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

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

                action3
                    .Verify(x => x.ExecuteAsync(context))
                    .WasNotCalled();
            }
        }