using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using AMWD.Common.Utilities; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace AMWD.Common.Tests.Utilities { [TestClass] [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public class DelayedTaskWithResultTests { [TestMethod] public void ShouldCreateNewDelayedTaskNotStarting() { // arrange int executionCount = 0; var delay = TimeSpan.FromMilliseconds(100); var function = () => { executionCount++; return new[] { 42, 21 }; }; // act var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1))); var delayedTaskWithResult = DelayedTask.Create(function, delay); SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested); // assert Assert.IsNotNull(delayedTaskWithResult); Assert.AreEqual(delay, delayedTaskWithResult.Delay); Assert.IsFalse(delayedTaskWithResult.IsRunning); Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun); Assert.IsNull(delayedTaskWithResult.Exception); Assert.AreEqual(0, executionCount); } [TestMethod] public async Task ShouldCreateNewDelayedTaskStarting() { // arrange int executionCount = 0; var delay = TimeSpan.FromMilliseconds(100); var function = () => { executionCount++; return new[] { 42, 21 }; }; // act var delayedTaskWithResult = DelayedTask.Run(function, delay); int[] result = await delayedTaskWithResult; // assert Assert.IsNotNull(delayedTaskWithResult); Assert.AreEqual(delay, delayedTaskWithResult.Delay); Assert.IsFalse(delayedTaskWithResult.IsRunning); Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun); Assert.IsNull(delayedTaskWithResult.Exception); Assert.AreEqual(1, executionCount); CollectionAssert.AreEqual(new[] { 42, 21 }, result); } [TestMethod] public void ShouldHaveAnExceptionSet() { // arrange var delay = TimeSpan.FromMilliseconds(100); #pragma warning disable CS0162 // Unreachable Code detected. var function = () => { throw new Exception("TEST :D"); return new[] { 42, 21 }; }; #pragma warning restore CS0162 // Unreachable Code detected // act var delayedTaskWithResult = DelayedTask.Run(function, delay); var awaiter = delayedTaskWithResult.GetAwaiter(); SpinWait.SpinUntil(() => awaiter.IsCompleted); // assert Assert.IsNotNull(delayedTaskWithResult); Assert.IsFalse(delayedTaskWithResult.IsRunning); Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun); Assert.IsNotNull(delayedTaskWithResult.Exception); } [TestMethod] public void ShouldUseExceptionHandler() { // arrange string exceptionText = null; var delay = TimeSpan.FromMilliseconds(100); #pragma warning disable CS0162 // Unreachable Code detected. var function = () => { throw new Exception("TEST :D"); return new[] { 42, 21 }; }; #pragma warning restore CS0162 // Unreachable Code detected var exceptionHandler = (Exception ex) => { exceptionText = ex.Message; }; // act var delayedTaskWithResult = DelayedTask.Run(function, delay) .WithExceptionHandler(exceptionHandler); var awaiter = delayedTaskWithResult.GetAwaiter(); SpinWait.SpinUntil(() => awaiter.IsCompleted); // assert Assert.IsNotNull(delayedTaskWithResult); Assert.IsFalse(delayedTaskWithResult.IsRunning); Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun); Assert.IsNotNull(delayedTaskWithResult.Exception); Assert.AreEqual("TEST :D", exceptionText); } [TestMethod] public async Task ShouldReturnNormalTask() { // arrange int executionCount = 0; var delay = TimeSpan.FromMilliseconds(100); var function = () => { executionCount++; return new[] { 42, 21 }; }; var delayedTaskWithResult = DelayedTask.Create(function, delay); // act delayedTaskWithResult.Reset(); var task = delayedTaskWithResult.Task; int[] result = await task; // assert Assert.IsNotNull(delayedTaskWithResult); Assert.IsNotNull(task); Assert.IsInstanceOfType(task, typeof(Task)); Assert.IsFalse(delayedTaskWithResult.IsRunning); Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun); Assert.AreEqual(1, executionCount); Assert.AreEqual(TaskStatus.RanToCompletion, task.Status); CollectionAssert.AreEqual(new int[] { 42, 21 }, result); } } }