mirror of
https://github.com/chylex/.NET-Community-Toolkit.git
synced 2025-04-13 20:15:45 +02:00
Adds Unit Tests and reverts IDisposable pattern
This commit is contained in:
parent
639d411272
commit
818633db90
Microsoft.Toolkit/Deferred
UnitTests/UnitTests.Shared
@ -4,14 +4,15 @@
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#pragma warning disable CA1001
|
||||
|
||||
namespace Microsoft.Toolkit.Deferred
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="EventArgs"/> which can retrieve a <see cref="EventDeferral"/> in order to process data asynchronously before an <see cref="EventHandler"/> completes and returns to the calling control.
|
||||
/// </summary>
|
||||
public class DeferredEventArgs : EventArgs, IDisposable
|
||||
public class DeferredEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a new <see cref="DeferredEventArgs"/> to use in cases where no <see cref="EventArgs"/> wish to be provided.
|
||||
@ -21,12 +22,6 @@ public class DeferredEventArgs : EventArgs, IDisposable
|
||||
private readonly object _eventDeferralLock = new object();
|
||||
|
||||
private EventDeferral? _eventDeferral;
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="DeferredEventArgs"/> class.
|
||||
/// </summary>
|
||||
~DeferredEventArgs() => Dispose(false);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="EventDeferral"/> which can be completed when deferred event is ready to continue.
|
||||
@ -36,7 +31,7 @@ public EventDeferral GetDeferral()
|
||||
{
|
||||
lock (_eventDeferralLock)
|
||||
{
|
||||
return _eventDeferral ?? (_eventDeferral = new EventDeferral());
|
||||
return _eventDeferral ??= new EventDeferral();
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,31 +56,5 @@ public EventDeferral GetDeferral()
|
||||
return eventDeferral;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recommended helper method pattern for <see cref="IDisposable"/>.
|
||||
/// </summary>
|
||||
/// <param name="disposing">Source of dispose request.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_eventDeferral?.Dispose();
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
// Dispose of unmanaged resources.
|
||||
Dispose(true);
|
||||
|
||||
// Suppress finalization.
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#pragma warning disable CA1063
|
||||
|
||||
namespace Microsoft.Toolkit.Deferred
|
||||
{
|
||||
/// <summary>
|
||||
@ -16,17 +18,11 @@ public class EventDeferral : IDisposable
|
||||
{
|
||||
//// TODO: If/when .NET 5 is base, we can upgrade to non-generic version
|
||||
private readonly TaskCompletionSource<object?> _taskCompletionSource = new TaskCompletionSource<object?>();
|
||||
private bool _disposed = false;
|
||||
|
||||
internal EventDeferral()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="EventDeferral"/> class.
|
||||
/// </summary>
|
||||
~EventDeferral() => Dispose(false);
|
||||
|
||||
/// <summary>
|
||||
/// Call when finished with the Deferral.
|
||||
/// </summary>
|
||||
@ -50,30 +46,10 @@ public async Task WaitForCompletion(CancellationToken cancellationToken)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recommended helper method pattern for <see cref="IDisposable"/>.
|
||||
/// </summary>
|
||||
/// <param name="disposing">Source of dispose request.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Complete();
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
// Dispose of unmanaged resources.
|
||||
Dispose(true);
|
||||
|
||||
// Suppress finalization.
|
||||
GC.SuppressFinalize(this);
|
||||
Complete();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.Deferred;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace UnitTests.Extensions
|
||||
{
|
||||
[TestClass]
|
||||
public class Test_EventHandlerExtensions
|
||||
{
|
||||
[TestCategory("Deferred")]
|
||||
[TestMethod]
|
||||
public void Test_EventHandlerExtensions_GettingDeferralCausesAwait()
|
||||
{
|
||||
var tsc = new TaskCompletionSource<bool>();
|
||||
|
||||
var testClass = new TestClass();
|
||||
|
||||
testClass.TestEvent += async (s, e) =>
|
||||
{
|
||||
var deferral = e.GetDeferral();
|
||||
|
||||
await tsc.Task;
|
||||
|
||||
deferral.Complete();
|
||||
};
|
||||
|
||||
var handlersTask = testClass.RaiseTestEvent();
|
||||
|
||||
Assert.IsFalse(handlersTask.IsCompleted);
|
||||
|
||||
tsc.SetResult(true);
|
||||
|
||||
Assert.IsTrue(handlersTask.IsCompleted);
|
||||
}
|
||||
|
||||
[TestCategory("Deferred")]
|
||||
[TestMethod]
|
||||
public void Test_EventHandlerExtensions_NotGettingDeferralCausesNoAwait()
|
||||
{
|
||||
var tsc = new TaskCompletionSource<bool>();
|
||||
|
||||
var testClass = new TestClass();
|
||||
|
||||
testClass.TestEvent += async (s, e) =>
|
||||
{
|
||||
await tsc.Task;
|
||||
};
|
||||
|
||||
var handlersTask = testClass.RaiseTestEvent();
|
||||
|
||||
Assert.IsTrue(handlersTask.IsCompleted);
|
||||
|
||||
tsc.SetResult(true);
|
||||
}
|
||||
|
||||
[TestCategory("Deferred")]
|
||||
[TestMethod]
|
||||
public void Test_EventHandlerExtensions_UsingDeferralCausesAwait()
|
||||
{
|
||||
var tsc = new TaskCompletionSource<bool>();
|
||||
|
||||
var testClass = new TestClass();
|
||||
|
||||
testClass.TestEvent += async (s, e) =>
|
||||
{
|
||||
using (e.GetDeferral())
|
||||
{
|
||||
await tsc.Task;
|
||||
}
|
||||
};
|
||||
|
||||
var handlersTask = testClass.RaiseTestEvent();
|
||||
|
||||
Assert.IsFalse(handlersTask.IsCompleted);
|
||||
|
||||
tsc.SetResult(true);
|
||||
|
||||
Assert.IsTrue(handlersTask.IsCompleted);
|
||||
}
|
||||
|
||||
[TestCategory("Deferred")]
|
||||
[DataTestMethod]
|
||||
[DataRow(0, 1)]
|
||||
[DataRow(1, 0)]
|
||||
public void Test_EventHandlerExtensions_MultipleHandlersCauseAwait(int firstToReleaseDeferral, int lastToReleaseDeferral)
|
||||
{
|
||||
var tsc = new[]
|
||||
{
|
||||
new TaskCompletionSource<bool>(),
|
||||
new TaskCompletionSource<bool>()
|
||||
};
|
||||
|
||||
var testClass = new TestClass();
|
||||
|
||||
testClass.TestEvent += async (s, e) =>
|
||||
{
|
||||
var deferral = e.GetDeferral();
|
||||
|
||||
await tsc[0].Task;
|
||||
|
||||
deferral.Complete();
|
||||
};
|
||||
|
||||
testClass.TestEvent += async (s, e) =>
|
||||
{
|
||||
var deferral = e.GetDeferral();
|
||||
|
||||
await tsc[1].Task;
|
||||
|
||||
deferral.Complete();
|
||||
};
|
||||
|
||||
var handlersTask = testClass.RaiseTestEvent();
|
||||
|
||||
Assert.IsFalse(handlersTask.IsCompleted);
|
||||
|
||||
tsc[firstToReleaseDeferral].SetResult(true);
|
||||
|
||||
Assert.IsFalse(handlersTask.IsCompleted);
|
||||
|
||||
tsc[lastToReleaseDeferral].SetResult(true);
|
||||
|
||||
Assert.IsTrue(handlersTask.IsCompleted);
|
||||
}
|
||||
|
||||
private class TestClass
|
||||
{
|
||||
public event EventHandler<DeferredEventArgs> TestEvent;
|
||||
|
||||
public Task RaiseTestEvent() => TestEvent.InvokeAsync(this, new DeferredEventArgs());
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Diagnostics\Test_Guard.Array.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Diagnostics\Test_Guard.Comparable.Numeric.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Diagnostics\Test_Guard.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\Test_EventHandlerExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\Test_TaskExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\Test_ArrayExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\Test_TypeExtensions.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user