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