From cabec85544de138ac493dd00bd447e67956cdb59 Mon Sep 17 00:00:00 2001
From: smoogipoo <smoogipoo@smgi.me>
Date: Fri, 29 Mar 2019 14:15:57 +0900
Subject: [PATCH] Rework TestCaseLoaderAnimation to avoid timing issues

---
 .../Visual/Menus/TestCaseLoaderAnimation.cs   | 87 +++++++++++--------
 1 file changed, 51 insertions(+), 36 deletions(-)

diff --git a/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs b/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs
index 1686436924..df12e14891 100644
--- a/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs
+++ b/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs
@@ -1,6 +1,7 @@
 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
 // See the LICENCE file in the repository root for full licence text.
 
+using System.Threading;
 using NUnit.Framework;
 using osu.Framework.Allocation;
 using osu.Framework.Graphics;
@@ -22,55 +23,76 @@ namespace osu.Game.Tests.Visual.Menus
 
         public TestCaseLoaderAnimation()
         {
-            Add(logo = new OsuLogo { Depth = float.MinValue });
+            Child = logo = new OsuLogo { Depth = float.MinValue };
         }
 
-        protected override void LoadComplete()
+        [Test]
+        public void TestInstantLoad()
         {
-            base.LoadComplete();
-
             bool logoVisible = false;
-            AddStep("almost instant display", () => LoadScreen(loader = new TestLoader(250)));
-            AddUntilStep("loaded", () =>
-            {
-                logoVisible = loader.Logo?.Alpha > 0;
-                return loader.Logo != null && loader.ScreenLoaded;
-            });
-            AddAssert("logo not visible", () => !logoVisible);
 
-            AddStep("short load", () => LoadScreen(loader = new TestLoader(800)));
-            AddUntilStep("loaded", () =>
+            AddStep("begin loading", () =>
+            {
+                loader = new TestLoader();
+                loader.AllowLoad.Set();
+
+                LoadScreen(loader);
+            });
+
+            AddAssert("loaded", () =>
             {
                 logoVisible = loader.Logo?.Alpha > 0;
                 return loader.Logo != null && loader.ScreenLoaded;
             });
-            AddAssert("logo visible", () => logoVisible);
+
+            AddAssert("logo was not visible", () => !logoVisible);
+        }
+
+        [Test]
+        public void TestShortLoad()
+        {
+            bool logoVisible = false;
+
+            AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
+            AddWaitStep("wait", 2);
+            AddStep("finish loading", () =>
+            {
+                logoVisible = loader.Logo?.Alpha > 0;
+                loader.AllowLoad.Set();
+            });
+
+            AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
+            AddAssert("logo was visible", () => logoVisible);
             AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
+        }
 
-            AddStep("longer load", () => LoadScreen(loader = new TestLoader(1400)));
-            AddUntilStep("loaded", () =>
+        [Test]
+        public void TestLongLoad()
+        {
+            bool logoVisible = false;
+
+            AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
+            AddWaitStep("wait", 10);
+            AddStep("finish loading", () =>
             {
                 logoVisible = loader.Logo?.Alpha > 0;
-                return loader.Logo != null && loader.ScreenLoaded;
+                loader.AllowLoad.Set();
             });
-            AddAssert("logo visible", () => logoVisible);
+
+            AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
+            AddAssert("logo was visible", () => logoVisible);
             AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
         }
 
         private class TestLoader : Loader
         {
-            private readonly double delay;
+            public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim();
 
             public OsuLogo Logo;
             private TestScreen screen;
 
             public bool ScreenLoaded => screen.IsCurrentScreen();
 
-            public TestLoader(double delay)
-            {
-                this.delay = delay;
-            }
-
             protected override void LogoArriving(OsuLogo logo, bool resuming)
             {
                 Logo = logo;
@@ -78,25 +100,18 @@ namespace osu.Game.Tests.Visual.Menus
             }
 
             protected override OsuScreen CreateLoadableScreen() => screen = new TestScreen();
-            protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(delay);
+            protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(AllowLoad);
 
             private class TestShaderPrecompiler : ShaderPrecompiler
             {
-                private readonly double delay;
-                private double startTime;
+                private readonly ManualResetEventSlim allowLoad;
 
-                public TestShaderPrecompiler(double delay)
+                public TestShaderPrecompiler(ManualResetEventSlim allowLoad)
                 {
-                    this.delay = delay;
+                    this.allowLoad = allowLoad;
                 }
 
-                protected override void LoadComplete()
-                {
-                    base.LoadComplete();
-                    startTime = Time.Current;
-                }
-
-                protected override bool AllLoaded => Time.Current > startTime + delay;
+                protected override bool AllLoaded => allowLoad.IsSet;
             }
 
             private class TestScreen : OsuScreen