Browse Source
* Add VerifyEmptyDispatcherAfterTestAttribute * Use VerifyEmptyDispatcherAfterTest and fix failing tests * Remove unsupported timeout from sync xUnit testsrelease/11.2.3
committed by
Max Katz
24 changed files with 141 additions and 44 deletions
@ -1,7 +1,9 @@ |
|||
using System.Reflection; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
[assembly: AssemblyTitle("Avalonia.UnitTests")] |
|||
[assembly: AssemblyTitle("Avalonia.Base.UnitTests")] |
|||
|
|||
// Don't run tests in parallel.
|
|||
[assembly: CollectionBehavior(DisableTestParallelization = true)] |
|||
[assembly: VerifyEmptyDispatcherAfterTest] |
|||
|
|||
@ -1,7 +1,9 @@ |
|||
using System.Reflection; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
[assembly: AssemblyTitle("Avalonia.Controls.UnitTests")] |
|||
|
|||
// Don't run tests in parallel.
|
|||
[assembly: CollectionBehavior(DisableTestParallelization = true)] |
|||
[assembly: CollectionBehavior(DisableTestParallelization = true)] |
|||
[assembly: VerifyEmptyDispatcherAfterTest] |
|||
|
|||
@ -1,6 +1,8 @@ |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
// Required to avoid InvalidOperationException sometimes thrown
|
|||
// from Splat.MemoizingMRUCache.cs which is not thread-safe.
|
|||
// Thrown when trying to access WhenActivated concurrently.
|
|||
[assembly: CollectionBehavior(DisableTestParallelization = true)] |
|||
[assembly: CollectionBehavior(DisableTestParallelization = true)] |
|||
[assembly: VerifyEmptyDispatcherAfterTest] |
|||
|
|||
@ -0,0 +1,38 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Threading; |
|||
using Xunit; |
|||
using Xunit.Sdk; |
|||
|
|||
namespace Avalonia.UnitTests; |
|||
|
|||
public sealed class VerifyEmptyDispatcherAfterTestAttribute : BeforeAfterTestAttribute |
|||
{ |
|||
public override void After(MethodInfo methodUnderTest) |
|||
{ |
|||
if (typeof(ScopedTestBase).IsAssignableFrom(methodUnderTest.DeclaringType)) |
|||
return; |
|||
|
|||
var dispatcher = Dispatcher.UIThread; |
|||
var jobs = dispatcher.GetJobs(); |
|||
if (jobs.Count == 0) |
|||
return; |
|||
|
|||
dispatcher.ClearJobs(); |
|||
|
|||
// Ignore the Control.Loaded callback. It might happen synchronously or might be posted.
|
|||
if (jobs.Count == 1 && IsLoadedCallback(jobs[0])) |
|||
return; |
|||
|
|||
Assert.Fail( |
|||
$"The test left {jobs.Count} unprocessed dispatcher {(jobs.Count == 1 ? "job" : "jobs")}:\n" + |
|||
$"{string.Join(Environment.NewLine, jobs.Select(job => $" - {job.DebugDisplay}"))}\n" + |
|||
$"Consider using ScopedTestBase or UnitTestApplication.Start()."); |
|||
|
|||
static bool IsLoadedCallback(DispatcherOperation job) |
|||
=> job.Priority == DispatcherPriority.Loaded && |
|||
(job.Callback as Delegate)?.Method.DeclaringType?.DeclaringType == typeof(Control); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue