Add test coverage of nested screen stacks not handling dialog dismissal properly

This commit is contained in:
Dean Herbert 2022-04-14 16:19:32 +09:00
parent 9af81adea7
commit f48a9ba90a

View File

@ -10,6 +10,7 @@ using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Overlays;
using osu.Game.Screens;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps.IO;
@ -171,6 +172,46 @@ namespace osu.Game.Tests.Visual.Navigation
}
}
[TestCase(true)]
[TestCase(false)]
public void TestPerformBlockedByDialogSubScreen(bool confirm)
{
TestScreenWithNestedStack screenWithNestedStack = null;
PushAndConfirm(() => screenWithNestedStack = new TestScreenWithNestedStack());
AddAssert("wait for nested screen", () => screenWithNestedStack.SubScreenStack.CurrentScreen == screenWithNestedStack.Blocker);
AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true));
AddUntilStep("wait for dialog", () => screenWithNestedStack.Blocker.ExitAttempts == 1);
AddWaitStep("wait a bit", 10);
AddUntilStep("wait for dialog display", () => Game.Dependencies.Get<DialogOverlay>().IsLoaded);
AddAssert("screen didn't change", () => Game.ScreenStack.CurrentScreen == screenWithNestedStack);
AddAssert("nested screen didn't change", () => screenWithNestedStack.SubScreenStack.CurrentScreen == screenWithNestedStack.Blocker);
AddAssert("did not perform", () => !actionPerformed);
AddAssert("only one exit attempt", () => screenWithNestedStack.Blocker.ExitAttempts == 1);
if (confirm)
{
AddStep("accept dialog", () => InputManager.Key(Key.Number1));
AddAssert("nested screen changed", () => screenWithNestedStack.SubScreenStack.CurrentScreen != screenWithNestedStack.Blocker);
AddUntilStep("did perform", () => actionPerformed);
}
else
{
AddStep("cancel dialog", () => InputManager.Key(Key.Number2));
AddAssert("screen didn't change", () => Game.ScreenStack.CurrentScreen == screenWithNestedStack);
AddAssert("nested screen didn't change", () => screenWithNestedStack.SubScreenStack.CurrentScreen == screenWithNestedStack.Blocker);
AddAssert("did not perform", () => !actionPerformed);
}
}
private void importAndWaitForSongSelect()
{
AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).WaitSafely());
@ -200,5 +241,30 @@ namespace osu.Game.Tests.Visual.Navigation
return base.OnExiting(next);
}
}
public class TestScreenWithNestedStack : OsuScreen, IHasSubScreenStack
{
public DialogBlockingScreen Blocker { get; private set; }
public ScreenStack SubScreenStack { get; } = new ScreenStack();
public TestScreenWithNestedStack()
{
AddInternal(SubScreenStack);
SubScreenStack.Push(Blocker = new DialogBlockingScreen());
}
public override bool OnExiting(IScreen next)
{
if (SubScreenStack.CurrentScreen != null)
{
SubScreenStack.CurrentScreen.Exit();
return true;
}
return base.OnExiting(next);
}
}
}
}