Merge remote-tracking branch 'upstream/master' into cache-ruleset-dependencies-for-tests

This commit is contained in:
Salman Ahmed
2020-06-15 11:31:12 +03:00
815 changed files with 18208 additions and 6610 deletions

View File

@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual
/// Provides a clock, beat-divisor, and scrolling capability for test cases of editor components that
/// are preferrably tested within the presence of a clock and seek controls.
/// </summary>
public abstract class EditorClockTestScene : OsuTestScene
public abstract class EditorClockTestScene : OsuManualInputManagerTestScene
{
protected readonly BindableBeatDivisor BeatDivisor = new BindableBeatDivisor();
protected new readonly EditorClock Clock;
@ -30,8 +30,7 @@ namespace osu.Game.Tests.Visual
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.Cache(BeatDivisor);
dependencies.CacheAs<IFrameBasedClock>(Clock);
dependencies.CacheAs<IAdjustableClock>(Clock);
dependencies.CacheAs(Clock);
return dependencies;
}

View File

@ -1,36 +1,44 @@
// 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.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Testing;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Edit;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose.Components.Timeline;
namespace osu.Game.Tests.Visual
{
public abstract class EditorTestScene : ScreenTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Editor), typeof(EditorScreen) };
private readonly Ruleset ruleset;
protected EditorTestScene(Ruleset ruleset)
{
this.ruleset = ruleset;
}
protected Editor Editor { get; private set; }
[BackgroundDependencyLoader]
private void load()
{
Beatmap.Value = CreateWorkingBeatmap(ruleset.RulesetInfo);
Beatmap.Value = CreateWorkingBeatmap(Ruleset.Value);
}
public override void SetUpSteps()
{
base.SetUpSteps();
AddStep("Load editor", () => LoadScreen(new Editor()));
AddStep("load editor", () => LoadScreen(Editor = CreateEditor()));
AddUntilStep("wait for editor to load", () => Editor.ChildrenOfType<HitObjectComposer>().FirstOrDefault()?.IsLoaded == true
&& Editor.ChildrenOfType<TimelineArea>().FirstOrDefault()?.IsLoaded == true);
}
/// <summary>
/// Creates the ruleset for providing a corresponding beatmap to load the editor on.
/// </summary>
[NotNull]
protected abstract Ruleset CreateEditorRuleset();
protected sealed override Ruleset CreateRuleset() => CreateEditorRuleset();
protected virtual Editor CreateEditor() => new Editor();
}
}

View File

@ -10,13 +10,10 @@ namespace osu.Game.Tests.Visual
{
public abstract class ModPerfectTestScene : ModTestScene
{
private readonly Ruleset ruleset;
private readonly ModPerfect mod;
protected ModPerfectTestScene(Ruleset ruleset, ModPerfect mod)
: base(ruleset)
protected ModPerfectTestScene(ModPerfect mod)
{
this.ruleset = ruleset;
this.mod = mod;
}
@ -25,7 +22,7 @@ namespace osu.Game.Tests.Visual
Mod = mod,
Beatmap = new Beatmap
{
BeatmapInfo = { Ruleset = ruleset.RulesetInfo },
BeatmapInfo = { Ruleset = CreatePlayerRuleset().RulesetInfo },
HitObjects = { testData.HitObject }
},
Autoplay = !shouldMiss,
@ -41,12 +38,12 @@ namespace osu.Game.Tests.Visual
{
}
protected override bool AllowFail => true;
protected override bool CheckModsAllowFailure() => true;
public bool CheckFailed(bool failed)
{
if (!failed)
return ScoreProcessor.HasCompleted && !HealthProcessor.HasFailed;
return ScoreProcessor.HasCompleted.Value && !HealthProcessor.HasFailed;
return HealthProcessor.HasFailed;
}

View File

@ -14,16 +14,6 @@ namespace osu.Game.Tests.Visual
{
protected sealed override bool HasCustomSteps => true;
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(ModTestScene)
};
protected ModTestScene(Ruleset ruleset)
: base(ruleset)
{
}
private ModTestData currentTestData;
protected void CreateModTest(ModTestData testData) => CreateTest(() =>
@ -64,12 +54,14 @@ namespace osu.Game.Tests.Visual
protected class ModTestPlayer : TestPlayer
{
protected override bool AllowFail { get; }
private readonly bool allowFail;
protected override bool CheckModsAllowFailure() => allowFail;
public ModTestPlayer(bool allowFail)
: base(false, false)
{
AllowFail = allowFail;
this.allowFail = allowFail;
}
}

View File

@ -6,6 +6,8 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
@ -127,12 +129,21 @@ namespace osu.Game.Tests.Visual
}
}
localStorage = new Lazy<Storage>(() => new NativeStorage($"{GetType().Name}-{Guid.NewGuid()}"));
localStorage = new Lazy<Storage>(() => new NativeStorage(Path.Combine(RuntimeInfo.StartupDirectory, $"{GetType().Name}-{Guid.NewGuid()}")));
}
[Resolved]
protected AudioManager Audio { get; private set; }
/// <summary>
/// Creates the ruleset to be used for this test scene.
/// </summary>
/// <remarks>
/// When testing against ruleset-specific components, this method must be overriden to their corresponding ruleset.
/// </remarks>
[CanBeNull]
protected virtual Ruleset CreateRuleset() => null;
protected virtual IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset);
protected WorkingBeatmap CreateWorkingBeatmap(RulesetInfo ruleset) =>
@ -144,7 +155,7 @@ namespace osu.Game.Tests.Visual
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
Ruleset.Value = rulesets.AvailableRulesets.First();
Ruleset.Value = CreateRuleset()?.RulesetInfo ?? rulesets.AvailableRulesets.First();
}
protected override void Dispose(bool isDisposing)
@ -190,7 +201,7 @@ namespace osu.Game.Tests.Visual
/// <param name="audio">Audio manager. Required if a reference clock isn't provided.</param>
/// <param name="length">The length of the returned virtual track.</param>
public ClockBackedTestWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock referenceClock, AudioManager audio, double length = 60000)
: base(beatmap, storyboard)
: base(beatmap, storyboard, audio)
{
if (referenceClock != null)
{

View File

@ -4,24 +4,21 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.Timing;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose;
namespace osu.Game.Tests.Visual
{
[Cached(Type = typeof(IPlacementHandler))]
public abstract class PlacementBlueprintTestScene : OsuTestScene, IPlacementHandler
public abstract class PlacementBlueprintTestScene : OsuManualInputManagerTestScene, IPlacementHandler
{
protected Container HitObjectContainer;
protected readonly Container HitObjectContainer;
private PlacementBlueprint currentBlueprint;
private InputManager inputManager;
protected PlacementBlueprintTestScene()
{
Add(HitObjectContainer = CreateHitObjectContainer().With(c => c.Clock = new FramedClock(new StopwatchClock())));
@ -36,7 +33,7 @@ namespace osu.Game.Tests.Visual
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.CacheAs<IAdjustableClock>(new StopwatchClock());
dependencies.CacheAs(new EditorClock());
return dependencies;
}
@ -45,8 +42,7 @@ namespace osu.Game.Tests.Visual
{
base.LoadComplete();
inputManager = GetContainingInputManager();
Add(currentBlueprint = CreateBlueprint());
ResetPlacement();
}
public void BeginPlacement(HitObject hitObject)
@ -58,7 +54,13 @@ namespace osu.Game.Tests.Visual
if (commit)
AddHitObject(CreateHitObject(hitObject));
Remove(currentBlueprint);
ResetPlacement();
}
protected void ResetPlacement()
{
if (currentBlueprint != null)
Remove(currentBlueprint);
Add(currentBlueprint = CreateBlueprint());
}
@ -66,12 +68,16 @@ namespace osu.Game.Tests.Visual
{
}
protected override bool OnMouseMove(MouseMoveEvent e)
protected override void Update()
{
currentBlueprint.UpdatePosition(e.ScreenSpaceMousePosition);
return true;
base.Update();
currentBlueprint.UpdatePosition(SnapForBlueprint(currentBlueprint));
}
protected virtual SnapResult SnapForBlueprint(PlacementBlueprint blueprint) =>
new SnapResult(InputManager.CurrentState.Mouse.Position, null);
public override void Add(Drawable drawable)
{
base.Add(drawable);
@ -79,7 +85,7 @@ namespace osu.Game.Tests.Visual
if (drawable is PlacementBlueprint blueprint)
{
blueprint.Show();
blueprint.UpdatePosition(inputManager.CurrentState.Mouse.Position);
blueprint.UpdatePosition(SnapForBlueprint(blueprint));
}
}

View File

@ -3,6 +3,7 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Testing;
@ -19,15 +20,8 @@ namespace osu.Game.Tests.Visual
/// </summary>
protected virtual bool HasCustomSteps { get; } = false;
private readonly Ruleset ruleset;
protected TestPlayer Player;
protected PlayerTestScene(Ruleset ruleset)
{
this.ruleset = ruleset;
}
protected OsuConfigManager LocalConfig;
[BackgroundDependencyLoader]
@ -53,7 +47,7 @@ namespace osu.Game.Tests.Visual
action?.Invoke();
AddStep(ruleset.RulesetInfo.Name, LoadPlayer);
AddStep(CreatePlayerRuleset().Description, LoadPlayer);
AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1);
}
@ -63,11 +57,10 @@ namespace osu.Game.Tests.Visual
protected void LoadPlayer()
{
var ruleset = Ruleset.Value.CreateInstance();
var beatmap = CreateBeatmap(ruleset.RulesetInfo);
Beatmap.Value = CreateWorkingBeatmap(beatmap);
Ruleset.Value = ruleset.RulesetInfo;
SelectedMods.Value = Array.Empty<Mod>();
if (!AllowFail)
@ -88,6 +81,14 @@ namespace osu.Game.Tests.Visual
LoadScreen(Player);
}
/// <summary>
/// Creates the ruleset for setting up the <see cref="Player"/> component.
/// </summary>
[NotNull]
protected abstract Ruleset CreatePlayerRuleset();
protected sealed override Ruleset CreateRuleset() => CreatePlayerRuleset();
protected virtual TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false);
}
}

View File

@ -30,6 +30,11 @@ namespace osu.Game.Tests.Visual
set => scrollingInfo.TimeRange.Value = value;
}
public ScrollingDirection Direction
{
set => scrollingInfo.Direction.Value = value;
}
public IScrollingInfo ScrollingInfo => scrollingInfo;
[Cached(Type = typeof(IScrollingInfo))]
@ -42,7 +47,7 @@ namespace osu.Game.Tests.Visual
public void Flip() => scrollingInfo.Direction.Value = scrollingInfo.Direction.Value == ScrollingDirection.Up ? ScrollingDirection.Down : ScrollingDirection.Up;
private class TestScrollingInfo : IScrollingInfo
public class TestScrollingInfo : IScrollingInfo
{
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
@ -54,7 +59,7 @@ namespace osu.Game.Tests.Visual
IScrollAlgorithm IScrollingInfo.Algorithm => Algorithm;
}
private class TestScrollAlgorithm : IScrollAlgorithm
public class TestScrollAlgorithm : IScrollAlgorithm
{
public readonly SortedList<MultiplierControlPoint> ControlPoints = new SortedList<MultiplierControlPoint>();

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Graphics;
@ -32,9 +33,6 @@ namespace osu.Game.Tests.Visual
{
}
// Required to be part of the per-ruleset implementation to construct the newer version of the Ruleset.
protected abstract Ruleset CreateRulesetForSkinProvider();
[BackgroundDependencyLoader]
private void load(AudioManager audio, SkinManager skinManager)
{
@ -107,7 +105,7 @@ namespace osu.Game.Tests.Visual
{
new OutlineBox { Alpha = autoSize ? 1 : 0 },
mainProvider.WithChild(
new SkinProvidingContainer(CreateRulesetForSkinProvider().CreateLegacySkinProvider(mainProvider, beatmap))
new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider, beatmap))
{
Child = created,
RelativeSizeAxes = !autoSize ? Axes.Both : Axes.None,
@ -120,6 +118,14 @@ namespace osu.Game.Tests.Visual
};
}
/// <summary>
/// Creates the ruleset for adding the corresponding skin transforming component.
/// </summary>
[NotNull]
protected abstract Ruleset CreateRulesetForSkinProvider();
protected sealed override Ruleset CreateRuleset() => CreateRulesetForSkinProvider();
protected virtual IBeatmap CreateBeatmapForSkinProvider() => CreateWorkingBeatmap(Ruleset.Value).GetPlayableBeatmap(Ruleset.Value);
private class OutlineBox : CompositeDrawable