1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Increase flexibility of player test cases

This commit is contained in:
Dean Herbert 2019-03-18 16:39:34 +09:00
parent 9cabd12c45
commit 8df47bc23e
14 changed files with 239 additions and 171 deletions

View File

@ -13,7 +13,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
public class TestCaseAutoJuiceStream : TestCasePlayer
public class TestCaseAutoJuiceStream : PlayerTestCase
{
public TestCaseAutoJuiceStream()
: base(new CatchRuleset())

View File

@ -8,11 +8,12 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseBananaShower : Game.Tests.Visual.TestCasePlayer
public class TestCaseBananaShower : PlayerTestCase
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -2,11 +2,12 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseCatchPlayer : Game.Tests.Visual.TestCasePlayer
public class TestCaseCatchPlayer : PlayerTestCase
{
public TestCaseCatchPlayer()
: base(new CatchRuleset())

View File

@ -4,11 +4,12 @@
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer
public class TestCaseCatchStacker : PlayerTestCase
{
public TestCaseCatchStacker()
: base(new CatchRuleset())

View File

@ -1,22 +1,28 @@
// 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;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Screens.Play;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseHyperDash : Game.Tests.Visual.TestCasePlayer
public class TestCaseHyperDash : PlayerTestCase
{
public TestCaseHyperDash()
: base(new CatchRuleset())
{
}
[BackgroundDependencyLoader]
private void load()
{
AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash);
}
protected override IBeatmap CreateBeatmap(Ruleset ruleset)
{
var beatmap = new Beatmap
@ -28,7 +34,7 @@ namespace osu.Game.Rulesets.Catch.Tests
}
};
// Should produce a hperdash
// Should produce a hyper-dash
beatmap.HitObjects.Add(new Fruit { StartTime = 816, X = 308 / 512f, NewCombo = true });
beatmap.HitObjects.Add(new Fruit { StartTime = 1008, X = 56 / 512f, });
@ -38,11 +44,5 @@ namespace osu.Game.Rulesets.Catch.Tests
return beatmap;
}
protected override void AddCheckSteps(Func<Player> player)
{
base.AddCheckSteps(player);
AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash);
}
}
}

View File

@ -4,12 +4,13 @@
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Visual;
using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseHitCircleLongCombo : Game.Tests.Visual.TestCasePlayer
public class TestCaseHitCircleLongCombo : PlayerTestCase
{
public TestCaseHitCircleLongCombo()
: base(new OsuRuleset())

View File

@ -2,11 +2,12 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseOsuPlayer : Game.Tests.Visual.TestCasePlayer
public class TestCaseOsuPlayer : PlayerTestCase
{
public TestCaseOsuPlayer()
: base(new OsuRuleset())

View File

@ -1,12 +0,0 @@
// 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 NUnit.Framework;
namespace osu.Game.Tests.Visual
{
[TestFixture]
public class TestCaseAllPlayers : TestCasePlayer
{
}
}

View File

@ -1,7 +1,6 @@
// 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;
using System.ComponentModel;
using System.Linq;
using osu.Game.Rulesets;
@ -11,7 +10,7 @@ using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
{
[Description("Player instantiated with an autoplay mod.")]
public class TestCaseAutoplay : TestCasePlayer
public class TestCaseAutoplay : AllPlayersTestCase
{
protected override Player CreatePlayer(Ruleset ruleset)
{
@ -24,11 +23,10 @@ namespace osu.Game.Tests.Visual
};
}
protected override void AddCheckSteps(Func<Player> player)
protected override void AddCheckSteps()
{
base.AddCheckSteps(player);
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).ScoreProcessor.TotalScore.Value > 0, "score above zero");
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys");
AddUntilStep(() => ((ScoreAccessiblePlayer)Player).ScoreProcessor.TotalScore.Value > 0, "score above zero");
AddUntilStep(() => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys");
}
private class ScoreAccessiblePlayer : Player

View File

@ -0,0 +1,56 @@
// 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;
using osu.Framework.Lists;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
{
public class TestCasePlayerReferenceLeaking : AllPlayersTestCase
{
private readonly WeakList<WorkingBeatmap> workingWeakReferences = new WeakList<WorkingBeatmap>();
private readonly WeakList<Player> playerWeakReferences = new WeakList<Player>();
protected override void AddCheckSteps()
{
AddUntilStep(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
int count = 0;
workingWeakReferences.ForEachAlive(_ => count++);
return count == 1;
}, "no leaked beatmaps");
AddUntilStep(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
int count = 0;
playerWeakReferences.ForEachAlive(_ => count++);
return count == 1;
}, "no leaked players");
}
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock clock)
{
var working = base.CreateWorkingBeatmap(beatmap, clock);
workingWeakReferences.Add(working);
return working;
}
protected override Player CreatePlayer(Ruleset ruleset)
{
var player = base.CreatePlayer(ruleset);
playerWeakReferences.Add(player);
return player;
}
}
}

View File

@ -1,7 +1,6 @@
// 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;
using System.ComponentModel;
using System.Linq;
using osu.Game.Rulesets;
@ -12,7 +11,7 @@ using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
{
[Description("Player instantiated with a replay.")]
public class TestCaseReplay : TestCasePlayer
public class TestCaseReplay : AllPlayersTestCase
{
protected override Player CreatePlayer(Ruleset ruleset)
{
@ -21,11 +20,10 @@ namespace osu.Game.Tests.Visual
return new ScoreAccessibleReplayPlayer(ruleset.GetAutoplayMod().CreateReplayScore(beatmap));
}
protected override void AddCheckSteps(Func<Player> player)
protected override void AddCheckSteps()
{
base.AddCheckSteps(player);
AddUntilStep(() => ((ScoreAccessibleReplayPlayer)player()).ScoreProcessor.TotalScore.Value > 0, "score above zero");
AddUntilStep(() => ((ScoreAccessibleReplayPlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys");
AddUntilStep(() => ((ScoreAccessibleReplayPlayer)Player).ScoreProcessor.TotalScore.Value > 0, "score above zero");
AddUntilStep(() => ((ScoreAccessibleReplayPlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys");
}
private class ScoreAccessibleReplayPlayer : ReplayPlayer

View File

@ -0,0 +1,94 @@
// 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.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Screens;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual
{
/// <summary>
/// A base class which runs <see cref="Player"/> test for all available rulesets.
/// Steps to be run for each ruleset should be added via <see cref="AddCheckSteps"/>.
/// </summary>
public abstract class AllPlayersTestCase : RateAdjustedBeatmapTestCase
{
protected Player Player;
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
Add(new Box
{
RelativeSizeAxes = Framework.Graphics.Axes.Both,
Colour = Color4.Black,
Depth = int.MaxValue
});
foreach (var r in rulesets.AvailableRulesets)
{
Player p = null;
AddStep(r.Name, () => p = loadPlayerFor(r));
AddUntilStep(() =>
{
if (p?.IsLoaded == true)
{
p = null;
return true;
}
return false;
}, "player loaded");
AddCheckSteps();
}
}
protected abstract void AddCheckSteps();
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo);
protected virtual WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock clock) =>
new TestWorkingBeatmap(beatmap, Clock);
private Player loadPlayerFor(RulesetInfo ri)
{
Ruleset.Value = ri;
var r = ri.CreateInstance();
var beatmap = CreateBeatmap(r);
var working = CreateWorkingBeatmap(beatmap, Clock);
Beatmap.Value = working;
Beatmap.Value.Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) };
Player?.Exit();
Player = null;
var player = CreatePlayer(r);
LoadComponentAsync(player, p =>
{
Player = p;
LoadScreen(p);
});
return player;
}
protected virtual Player CreatePlayer(Ruleset ruleset) => new Player
{
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
};
}
}

View File

@ -0,0 +1,60 @@
// 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.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual
{
public abstract class PlayerTestCase : RateAdjustedBeatmapTestCase
{
private readonly Ruleset ruleset;
protected Player Player;
protected PlayerTestCase(Ruleset ruleset)
{
this.ruleset = ruleset;
Add(new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Depth = int.MaxValue
});
AddStep(ruleset.RulesetInfo.Name, loadPlayer);
AddUntilStep(() => Player.IsLoaded, "player loaded");
}
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo);
private void loadPlayer()
{
var beatmap = CreateBeatmap(ruleset);
Beatmap.Value = new TestWorkingBeatmap(beatmap, Clock);
Beatmap.Value.Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) };
LoadComponentAsync(Player = CreatePlayer(ruleset), p =>
{
Player = p;
LoadScreen(p);
});
}
protected virtual Player CreatePlayer(Ruleset ruleset) => new Player
{
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
};
}
}

View File

@ -1,131 +0,0 @@
// 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;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Lists;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual
{
public abstract class TestCasePlayer : RateAdjustedBeatmapTestCase
{
private readonly Ruleset ruleset;
protected Player Player;
protected TestCasePlayer(Ruleset ruleset)
{
this.ruleset = ruleset;
}
protected TestCasePlayer()
{
}
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
Add(new Box
{
RelativeSizeAxes = Framework.Graphics.Axes.Both,
Colour = Color4.Black,
Depth = int.MaxValue
});
if (ruleset != null)
{
Player p = null;
AddStep(ruleset.RulesetInfo.Name, () => p = loadPlayerFor(ruleset));
AddCheckSteps(() => p);
}
else
{
foreach (var r in rulesets.AvailableRulesets)
{
Player p = null;
AddStep(r.Name, () => p = loadPlayerFor(r));
AddCheckSteps(() => p);
AddUntilStep(() =>
{
p = null;
GC.Collect();
GC.WaitForPendingFinalizers();
int count = 0;
workingWeakReferences.ForEachAlive(_ => count++);
return count == 1;
}, "no leaked beatmaps");
AddUntilStep(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
int count = 0;
playerWeakReferences.ForEachAlive(_ => count++);
return count == 1;
}, "no leaked players");
}
}
}
protected virtual void AddCheckSteps(Func<Player> player)
{
AddUntilStep(() => player().IsLoaded, "player loaded");
}
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo);
private readonly WeakList<WorkingBeatmap> workingWeakReferences = new WeakList<WorkingBeatmap>();
private readonly WeakList<Player> playerWeakReferences = new WeakList<Player>();
private Player loadPlayerFor(RulesetInfo ri)
{
Ruleset.Value = ri;
return loadPlayerFor(ri.CreateInstance());
}
private Player loadPlayerFor(Ruleset r)
{
var beatmap = CreateBeatmap(r);
var working = new TestWorkingBeatmap(beatmap, Clock);
workingWeakReferences.Add(working);
Beatmap.Value = working;
Beatmap.Value.Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) };
Player?.Exit();
var player = CreatePlayer(r);
playerWeakReferences.Add(player);
LoadComponentAsync(player, p =>
{
Player = p;
LoadScreen(p);
});
return player;
}
protected virtual Player CreatePlayer(Ruleset ruleset) => new Player
{
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
};
}
}