using System; using System.Threading; using System.Threading.Tasks; using AMWD.Common.Utilities; namespace AMWD.Common.Tests.Utilities { [TestClass] public class DelayedTaskWithResultTest { [TestMethod] public void ShouldCreateNewDelayedTaskNotStarting() { // arrange int executionCount = 0; var delay = TimeSpan.FromMilliseconds(100); int[] Function() { executionCount++; return [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] [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1861")] public async Task ShouldCreateNewDelayedTaskStarting() { // arrange int executionCount = 0; var delay = TimeSpan.FromMilliseconds(100); int[] Function() { executionCount++; return [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. static int[] Function() { throw new Exception("TEST :D"); return [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. static int[] Function() { throw new Exception("TEST :D"); return [42, 21]; } #pragma warning restore CS0162 // Unreachable Code detected void 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] [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1861")] public async Task ShouldReturnNormalTask() { // arrange int executionCount = 0; var delay = TimeSpan.FromMilliseconds(100); int[] Function() { executionCount++; return [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); } } }