Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up async assertions #19385

Merged
merged 9 commits into from Jan 8, 2024
3 changes: 2 additions & 1 deletion src/Controls/tests/DeviceTests/ControlsHandlerTestBase.cs
Expand Up @@ -15,6 +15,7 @@
#if ANDROID || IOS || MACCATALYST
using ShellHandler = Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer;
#endif
using static Microsoft.Maui.DeviceTests.AssertHelpers;

namespace Microsoft.Maui.DeviceTests
{
Expand Down Expand Up @@ -561,7 +562,7 @@ protected async Task OnFrameSetToNotEmpty(VisualElement frameworkElement, TimeSp
await taskCompletionSource.Task.WaitAsync(timeOut.Value);

// Wait for the layout to propagate to the platform
await AssertionExtensions.Wait(
await AssertEventually(
() =>
{
var size = frameworkElement.GetBoundingBox().Size;
Expand Down
Expand Up @@ -257,9 +257,6 @@ public async Task DoesNotLeak()
});

await AssertionExtensions.WaitForGC(handlerReference, platformViewReference);

Assert.False(handlerReference.IsAlive, "Handler should not be alive!");
Assert.False(platformViewReference.IsAlive, "PlatformView should not be alive!");
}

[Fact("Ensures the border renders the expected size - Issue 15339")]
Expand Down
Expand Up @@ -10,6 +10,7 @@
using Microsoft.UI.Xaml;
using Xunit;
using WSetter = Microsoft.UI.Xaml.Setter;
using static Microsoft.Maui.DeviceTests.AssertHelpers;

namespace Microsoft.Maui.DeviceTests
{
Expand Down Expand Up @@ -151,13 +152,14 @@ public async Task ValidateItemsVirtualize()

await Task.Delay(2000);

await AssertionExtensions.Wait(() =>
bool listIsDoneGrowing()
{
// Wait until the list stops growing
prevChildCount = childCount;
childCount = listView.GetChildren<UI.Xaml.Controls.TextBlock>().Count();
return childCount == prevChildCount;
}, 10000);
}

await AssertEventually(listIsDoneGrowing, timeout: 10000);

// If this is broken we'll get way more than 1000 elements
Assert.True(childCount < 1000);
Expand Down
Expand Up @@ -15,6 +15,7 @@
using Microsoft.Maui.Platform;
using Xunit;
using Xunit.Abstractions;
using static Microsoft.Maui.DeviceTests.AssertHelpers;

namespace Microsoft.Maui.DeviceTests
{
Expand Down Expand Up @@ -80,7 +81,9 @@ public async Task CellSizeAccountsForMargin()

await collectionView.AttachAndRun<CollectionViewHandler>(async (handler) =>
{
await AssertionExtensions.Wait(() => buttons.Count > 1 && buttons.Last().Frame.Height > 0 && buttons.Last().IsLoaded);
bool expectation() => buttons.Count > 1 && buttons.Last().Frame.Height > 0 && buttons.Last().IsLoaded;

await AssertEventually(expectation);
var button = buttons.Last();
var bounds = GetCollectionViewCellBounds(button);
var buttonBounds = button.GetBoundingBox();
Expand Down Expand Up @@ -131,7 +134,6 @@ public async Task ItemsSourceDoesNotLeak()
});

await AssertionExtensions.WaitForGC(weakReference);
Assert.False(weakReference.IsAlive, "ObservableCollection should not be alive!");
Assert.NotNull(logicalChildren);
Assert.True(logicalChildren.Count <= 5, "_logicalChildren should not grow in size!");
}
Expand Down Expand Up @@ -196,7 +198,7 @@ public async Task CollectionViewCanSizeToContent(CollectionViewSizingTestCase te

if (n == 0)
{
await AssertionExtensions.Wait(() => collectionView.Frame.Width > 0 && collectionView.Frame.Height > 0);
await AssertEventually(() => collectionView.Frame.Width > 0 && collectionView.Frame.Height > 0);
}
else
{
Expand Down
Expand Up @@ -123,10 +123,6 @@ public async Task CellsDoNotLeak()
}

await AssertionExtensions.WaitForGC(labels.ToArray());
foreach (var reference in labels)
{
Assert.False(reference.IsAlive, "View should not be alive!");
}
}

Rect GetCollectionViewCellBounds(IView cellContent)
Expand Down
Expand Up @@ -8,6 +8,7 @@
using Microsoft.Maui.Platform;
using UIKit;
using Xunit;
using static Microsoft.Maui.DeviceTests.AssertHelpers;

namespace Microsoft.Maui.DeviceTests
{
Expand Down Expand Up @@ -263,7 +264,7 @@ public async Task NextMovesToNextEntry(ControlsPageTypesTestCase page)
await CreateHandlerAndAddToWindow(rootPage, async () =>
{
KeyboardAutoManager.GoToNextResponderOrResign(entry1.ToPlatform());
await AssertionExtensions.Wait(() => entry2.IsFocused);
await AssertEventually(() => entry2.IsFocused);
isFocused = entry2.IsFocused;
});

Expand Down
Expand Up @@ -13,7 +13,7 @@
using Microsoft.Maui.Hosting;
using Microsoft.Maui.Platform;
using Xunit;

using static Microsoft.Maui.DeviceTests.AssertHelpers;

#if IOS || MACCATALYST
using FlyoutViewHandler = Microsoft.Maui.Controls.Handlers.Compatibility.PhoneFlyoutPageRenderer;
Expand Down Expand Up @@ -208,7 +208,7 @@ public async Task DetailsPageMeasuresCorrectlyInSplitMode(bool isRtl)
if (!CanDeviceDoSplitMode(flyoutPage))
return;

await AssertionExtensions.Wait(() => flyoutPage.Flyout.GetBoundingBox().Width > 0);
await AssertEventually(() => flyoutPage.Flyout.GetBoundingBox().Width > 0);

var detailBounds = flyoutPage.Detail.GetBoundingBox();
var flyoutBounds = flyoutPage.Flyout.GetBoundingBox();
Expand Down Expand Up @@ -256,14 +256,14 @@ public async Task BackButtonEnabledChangesWithPushPopAndPageChanges()
Assert.False(IsBackButtonVisible(handler));

await first.PushAsync(new ContentPage());
await AssertionExtensions.Wait(() => IsBackButtonVisible(handler));
await AssertEventually(() => IsBackButtonVisible(handler));
Assert.True(IsBackButtonVisible(handler));

flyoutPage.Detail = second;
Assert.False(IsBackButtonVisible(handler));

await second.PushAsync(new ContentPage());
await AssertionExtensions.Wait(() => IsBackButtonVisible(handler));
await AssertEventually(() => IsBackButtonVisible(handler));
Assert.True(IsBackButtonVisible(handler));
});
}
Expand Down
@@ -1,20 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Foundation;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Handlers;
using Microsoft.Maui.Controls.Handlers.Compatibility;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Hosting;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Platform;
using UIKit;
using Xunit;
using static Microsoft.Maui.DeviceTests.AssertHelpers;

#if IOS || MACCATALYST
using FlyoutViewHandler = Microsoft.Maui.Controls.Handlers.Compatibility.PhoneFlyoutPageRenderer;
#endif
Expand Down Expand Up @@ -54,7 +48,7 @@ public async Task FlyoutPageTakesIntoAccountSafeAreaByDefault()
await CreateHandlerAndAddToWindow<PhoneFlyoutPageRenderer>(flyoutPage, async (handler) =>
{
var offset = (float)UIApplication.SharedApplication.GetSafeAreaInsetsForWindow().Top;
await AssertionExtensions.Wait(() => flyoutLabel.ToPlatform().GetLocationOnScreen().Y > 1);
await AssertEventually(() => flyoutLabel.ToPlatform().GetLocationOnScreen().Y > 1);
var flyoutLocation = flyoutLabel.ToPlatform().GetLocationOnScreen();
Assert.True(Math.Abs(offset - flyoutLocation.Y) < 1.0);
});
Expand All @@ -66,33 +60,31 @@ public async Task FlyoutPageTakesIntoAccountSafeAreaByDefault()
[InlineData(true)]
public async Task DetailsViewPopOverLayoutIsCorrectForIdiom(bool isRtl)
{
if (isRtl && System.OperatingSystem.IsIOSVersionAtLeast(17))
{
//skip till we figure the 1 pixel issue
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
return;
}
SetupBuilder();
var flyoutLabel = new Label() { Text = "Content" };
var flyoutLayout = new VerticalStackLayout() { BackgroundColor = Colors.Blue };
flyoutLayout.Add(flyoutLabel);

var flyoutPage = await InvokeOnMainThreadAsync(() => new FlyoutPage()
{
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover,
IsPresented = true,
Detail = new ContentPage()
{
Title = "Detail",
Content = new Label()
Content = new Label() { Text = "Detail", BackgroundColor = Colors.Red }
},
Flyout = new ContentPage()
{
Title = "Flyout",
Content = flyoutLabel
Content = flyoutLayout
},
FlowDirection = (isRtl) ? FlowDirection.RightToLeft : FlowDirection.LeftToRight
FlowDirection = isRtl ? FlowDirection.RightToLeft : FlowDirection.LeftToRight
});

await CreateHandlerAndAddToWindow<FlyoutViewHandler>(flyoutPage, async (handler) =>
{
await AssertionExtensions.Wait(() => flyoutPage.Flyout.GetBoundingBox().Width > 0);
await AssertEventually(() => flyoutPage.Flyout.GetBoundingBox().Width > 0);
var screenBounds = flyoutPage.GetBoundingBox();
var detailBounds = flyoutPage.Detail.GetBoundingBox();
var flyoutBounds = flyoutPage.Flyout.GetBoundingBox();
Expand All @@ -116,16 +108,7 @@ public async Task DetailsViewPopOverLayoutIsCorrectForIdiom(bool isRtl)
else
Assert.Equal(0, flyoutBounds.X);

flyoutPage.IsPresented = false;

await Task.Yield();
await AssertionExtensions.Wait(() =>
{
var flyoutBounds = flyoutPage.Flyout.GetBoundingBox();
return
-flyoutBounds.Width == flyoutBounds.X || //ltr
screenBounds.Width == flyoutBounds.X; //rtl
});
await CloseFlyout(flyoutPage);

var detailBoundsNotPresented = flyoutPage.Detail.GetBoundingBox();
var flyoutBoundsNotPresented = flyoutPage.Flyout.GetBoundingBox();
Expand All @@ -146,8 +129,36 @@ public async Task DetailsViewPopOverLayoutIsCorrectForIdiom(bool isRtl)
});
}


UIView FindPlatformFlyoutView(UIView uiView) =>
uiView.FindResponder<PhoneFlyoutPageRenderer>()?.View;

async Task CloseFlyout(FlyoutPage flyoutPage)
{
flyoutPage.IsPresented = false;

await Task.Yield();

bool flyoutHasExpectedBounds()
{
if (IsPad)
{
// When used on an iPad the flyout overlaps the details
var flyoutBounds = flyoutPage.Flyout.GetBoundingBox();
var screenBounds = flyoutPage.GetBoundingBox();
return
-flyoutBounds.Width == flyoutBounds.X || //ltr
screenBounds.Width == flyoutBounds.X; //rtl
}
else
{
// When used on an iPhone the details page just covers the flyout
// When the flyout opens the details page is moved to the right
var detailsBound = flyoutPage.Detail.GetBoundingBox();
return 0 == detailsBound.X;
}
}

await AssertEventually(flyoutHasExpectedBounds);
}
}
}
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Maui.Platform;
using UIKit;
using Xunit;
using static Microsoft.Maui.DeviceTests.AssertHelpers;

namespace Microsoft.Maui.DeviceTests
{
Expand Down Expand Up @@ -88,7 +89,7 @@ public async Task FrameHasShadowTest()
if (platformView.Element is IView element)
{
var platformShadow = element.Shadow;
await AssertionExtensions.Wait(() => platformShadow != null);
await AssertEventually(() => platformShadow != null);

Assert.Equal(platformShadow.Radius, expectedShadow.Radius);
Assert.Equal(platformShadow.Opacity, expectedShadow.Opacity);
Expand Down
Expand Up @@ -9,6 +9,7 @@
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using Xunit;
using static Microsoft.Maui.DeviceTests.AssertHelpers;

namespace Microsoft.Maui.DeviceTests
{
Expand Down Expand Up @@ -58,8 +59,13 @@ public async Task ImageSetFromStreamRenders()
await InvokeOnMainThreadAsync(async () =>
{
var handler = CreateHandler<LayoutHandler>(layout);
await image.Wait();
await handler.ToPlatform().AssertContainsColor(Colors.Red, MauiContext);
var rootView = handler.ToPlatform();

await rootView.AttachAndRun(async () =>
{
await image.WaitUntilLoaded();
await rootView.AssertContainsColor(Colors.Red, MauiContext);
});
});
}
}
Expand Down
6 changes: 2 additions & 4 deletions src/Controls/tests/DeviceTests/Elements/Image/ImageTests.cs
Expand Up @@ -43,7 +43,7 @@ public async Task ImageWithUndefinedSizeAndWithBackgroundSetRenders()
await InvokeOnMainThreadAsync(async () =>
{
var handler = CreateHandler<LayoutHandler>(layout);
await image.Wait();
await image.WaitUntilLoaded();
await handler.ToPlatform().AssertContainsColor(Colors.Red, MauiContext);
});
}
Expand All @@ -70,12 +70,10 @@ public async Task DoesNotLeak()
var handler = CreateHandler<LayoutHandler>(layout);
handlerReference = new WeakReference(image.Handler);
platformViewReference = new WeakReference(image.Handler.PlatformView);
await image.Wait();
await image.WaitUntilLoaded();
});

await AssertionExtensions.WaitForGC(handlerReference, platformViewReference);
Assert.False(handlerReference.IsAlive, "Handler should not be alive!");
Assert.False(platformViewReference.IsAlive, "PlatformView should not be alive!");
}
}
}
Expand Up @@ -45,7 +45,7 @@ public async Task LargeImagesResizeCorrectly()
{
var handler = CreateHandler<LayoutHandler>(layout);

await image.Wait();
await image.WaitUntilLoaded();

await handler.ToPlatform().AssertContainsColor(Colors.White, MauiContext);
await handler.ToPlatform().AssertDoesNotContainColor(Colors.Red, MauiContext);
Expand Down Expand Up @@ -82,7 +82,7 @@ public async Task AspectFitResizesOnSmallestDimensions(int widthRequest, int hei
{
var handler = CreateHandler<LayoutHandler>(layout);

await image.Wait();
await image.WaitUntilLoaded();

await handler.ToPlatform().AssertContainsColor(Colors.White, MauiContext);
});
Expand Down Expand Up @@ -113,7 +113,7 @@ public async Task ImagesRespectExplicitConstraints()
{
var handler = CreateHandler<LayoutHandler>(layout);

await image.Wait();
await image.WaitUntilLoaded();

await handler.ToPlatform().AssertContainsColor(Colors.White, MauiContext);
});
Expand Down
Expand Up @@ -305,10 +305,6 @@ public async Task CellsDoNotLeak()
});

await AssertionExtensions.WaitForGC(references.ToArray());
foreach (var reference in references)
{
Assert.False(reference.IsAlive, "Cell should not be alive!");
}
}

[Fact("Cells Repopulate After Null ItemsSource")]
Expand Down