Example #1
0
        public void Transform_SyncFaultedFunction_CancellationRequested_IgnoresTransform()
        {
            using var cts = new CancellationTokenSource();
            cts.Cancel();

            var executedTransform = false;

            var fault             = ExceptionUtilities.Unreachable;
            var cancellationToken = cts.Token;
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = (_, _) => new(Task.FromException <IntermediateType>(fault));
            Func <IntermediateType, StateType, ResultType> transform = (_, _) =>
            {
                executedTransform = true;
                return(new ResultType());
            };
            var arg = new StateType();

            var task = SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken).Preserve();

            Assert.True(task.IsCanceled);
            var exception = Assert.Throws <TaskCanceledException>(() => task.Result);

            Assert.Equal(cancellationToken, exception.CancellationToken);
            Assert.False(executedTransform);
        }
Example #2
0
        public async Task Transform_AsyncFaultedFunction_CancellationRequested_IgnoresTransform()
        {
            using var cts = new CancellationTokenSource();
            cts.Cancel();

            var executedTransform = false;

            var fault             = ExceptionUtilities.Unreachable;
            var cancellationToken = cts.Token;
            var gate = new ManualResetEventSlim();
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = async(_, _) =>
            {
                await Task.Yield();

                gate.Wait(CancellationToken.None);
                throw fault;
            };
            Func <IntermediateType, StateType, ResultType> transform = (_, _) =>
            {
                executedTransform = true;
                return(new ResultType());
            };
            var arg = new StateType();

            var task = SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken).Preserve();

            Assert.False(task.IsCompleted);

            gate.Set();
            var exception = await Assert.ThrowsAsync <TaskCanceledException>(() => task.AsTask());

            Assert.True(task.IsCanceled);
            Assert.Equal(cancellationToken, exception.CancellationToken);
            Assert.False(executedTransform);
        }
Example #3
0
        public void Transform_SyncCanceledFunction_NotRequested_IgnoresTransform()
        {
            using var unexpectedCts = new CancellationTokenSource();
            unexpectedCts.Cancel();

            var executedTransform = false;

            var cancellationToken = new CancellationToken(canceled: false);
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = (_, _) => new(Task.FromCanceled <IntermediateType>(unexpectedCts.Token));
            Func <IntermediateType, StateType, ResultType> transform = (_, _) =>
            {
                executedTransform = true;
                return(new ResultType());
            };
            var arg = new StateType();

            var task = SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken).Preserve();

            Assert.True(task.IsCanceled);
            var exception = Assert.Throws <TaskCanceledException>(() => task.Result);

            // ⚠ Due to the way cancellation is handled in ContinueWith, the resulting exception fails to preserve the
            // cancellation token applied when the intermediate task was cancelled.
            Assert.Equal(cancellationToken, exception.CancellationToken);
            Assert.False(executedTransform);
        }
Example #4
0
        public void Transform_SyncCompletedFunction_CompletedTransform()
        {
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = (_, _) => new(new IntermediateType());
            Func <IntermediateType, StateType, ResultType> transform = (_, _) => new();
            var arg = new StateType();
            var cancellationToken = new CancellationToken(canceled: false);

            var task = SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken).Preserve();

            Assert.True(task.IsCompletedSuccessfully);
            Assert.NotNull(task.Result);
        }
Example #5
0
        public void Transform_ArgumentValidation()
        {
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = (_, _) => new(new IntermediateType());
            Func <IntermediateType, StateType, ResultType> transform = (_, _) => new();
            var arg = new StateType();
            var cancellationToken = new CancellationToken(canceled: false);

#pragma warning disable CA2012 // Use ValueTasks correctly (the instance is never created)
            Assert.Throws <ArgumentNullException>("func", () => SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(null !, transform, arg, cancellationToken));
            Assert.Throws <ArgumentNullException>("transform", () => SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync <StateType, IntermediateType, ResultType>(func, null !, arg, cancellationToken));
#pragma warning restore CA2012 // Use ValueTasks correctly
        }
Example #6
0
        public void Transform_SyncCompletedFunction_FaultedTransform()
        {
            var fault = ExceptionUtilities.Unreachable;
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = (_, _) => new(new IntermediateType());
            Func <IntermediateType, StateType, ResultType> transform = (_, _) => throw fault;
            var arg = new StateType();
            var cancellationToken = new CancellationToken(canceled: false);

#pragma warning disable CA2012 // Use ValueTasks correctly (the instance is never created)
            var exception = Assert.Throws <InvalidOperationException>(() => SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken));
#pragma warning restore CA2012 // Use ValueTasks correctly
            Assert.Same(fault, exception);
        }
Example #7
0
        public async Task Transform_AsyncCompletedFunction_CompletedTransform()
        {
            var gate = new ManualResetEventSlim();
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = async(_, _) =>
            {
                await Task.Yield();

                gate.Wait(CancellationToken.None);
                return(new IntermediateType());
            };
            Func <IntermediateType, StateType, ResultType> transform = (_, _) => new();
            var arg = new StateType();
            var cancellationToken = new CancellationToken(canceled: false);

            var task = SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken).Preserve();

            Assert.False(task.IsCompleted);

            gate.Set();
            Assert.NotNull(await task);
        }
Example #8
0
        public void Transform_SyncFaultedFunction_IgnoresTransform()
        {
            var executedTransform = false;

            var fault             = ExceptionUtilities.Unreachable;
            var cancellationToken = new CancellationToken(canceled: false);
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = (_, _) => new(Task.FromException <IntermediateType>(fault));
            Func <IntermediateType, StateType, ResultType> transform = (_, _) =>
            {
                executedTransform = true;
                return(new ResultType());
            };
            var arg = new StateType();

            var task = SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken).Preserve();

            Assert.True(task.IsFaulted);
            var exception = Assert.Throws <InvalidOperationException>(() => task.Result);

            Assert.Same(fault, exception);
            Assert.False(executedTransform);
        }
Example #9
0
        public async Task Transform_AsyncCanceledFunction_NotRequested_IgnoresTransform()
        {
            using var unexpectedCts = new CancellationTokenSource();
            unexpectedCts.Cancel();

            var executedTransform = false;

            var cancellationToken = new CancellationToken(canceled: false);
            var gate = new ManualResetEventSlim();
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = async(_, _) =>
            {
                await Task.Yield();

                gate.Wait(CancellationToken.None);
                unexpectedCts.Token.ThrowIfCancellationRequested();
                throw ExceptionUtilities.Unreachable;
            };
            Func <IntermediateType, StateType, ResultType> transform = (_, _) =>
            {
                executedTransform = true;
                return(new ResultType());
            };
            var arg = new StateType();

            var task = SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken).Preserve();

            Assert.False(task.IsCompleted);

            gate.Set();
            var exception = await Assert.ThrowsAsync <TaskCanceledException>(async() => await task);

            Assert.True(task.IsCanceled);

            // ⚠ Due to the way cancellation is handled in ContinueWith, the resulting exception fails to preserve the
            // cancellation token applied when the intermediate task was cancelled.
            Assert.Equal(cancellationToken, exception.CancellationToken);
            Assert.False(executedTransform);
        }
Example #10
0
        public void Transform_SyncDirectFaultedFunction_CancellationRequested_IgnoresTransform()
        {
            using var cts = new CancellationTokenSource();
            cts.Cancel();

            var executedTransform = false;

            var fault             = ExceptionUtilities.Unreachable;
            var cancellationToken = cts.Token;
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = (_, _) => throw fault;
            Func <IntermediateType, StateType, ResultType> transform = (_, _) =>
            {
                executedTransform = true;
                return(new ResultType());
            };
            var arg = new StateType();

#pragma warning disable CA2012 // Use ValueTasks correctly (the instance is never created)
            var exception = Assert.Throws <InvalidOperationException>(() => SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken));
#pragma warning restore CA2012 // Use ValueTasks correctly
            Assert.Same(fault, exception);
            Assert.False(executedTransform);
        }
Example #11
0
        public async Task Transform_AsyncCompletedFunction_FaultedTransform()
        {
            var fault = ExceptionUtilities.Unreachable;
            var gate  = new ManualResetEventSlim();
            Func <StateType, CancellationToken, ValueTask <IntermediateType> > func = async(_, _) =>
            {
                await Task.Yield();

                gate.Wait(CancellationToken.None);
                return(new IntermediateType());
            };
            Func <IntermediateType, StateType, ResultType> transform = (_, _) => throw fault;
            var arg = new StateType();
            var cancellationToken = new CancellationToken(canceled: false);

            var task = SpecializedTasks.TransformWithoutIntermediateCancellationExceptionAsync(func, transform, arg, cancellationToken).Preserve();

            Assert.False(task.IsCompleted);

            gate.Set();
            var exception = await Assert.ThrowsAsync <InvalidOperationException>(() => task.AsTask());

            Assert.Same(fault, exception);
        }