A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

38 lines
1.3 KiB

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);
}
}