mirror of https://github.com/ppy/osu
Merge pull request #24405 from bdach/spinner-input-test
This commit is contained in:
commit
a7ff084be2
|
@ -0,0 +1,147 @@
|
|||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Extensions.TypeExtensions;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Replays;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
public partial class TestSceneSpinnerJudgement : RateAdjustedBeatmapTestScene
|
||||
{
|
||||
private const double time_spinner_start = 2000;
|
||||
private const double time_spinner_end = 4000;
|
||||
|
||||
private List<JudgementResult> judgementResults = new List<JudgementResult>();
|
||||
private ScoreAccessibleReplayPlayer currentPlayer = null!;
|
||||
|
||||
[Test]
|
||||
public void TestHitNothing()
|
||||
{
|
||||
performTest(new List<ReplayFrame>());
|
||||
|
||||
AddAssert("all min judgements", () => judgementResults.All(result => result.Type == result.Judgement.MinResult));
|
||||
}
|
||||
|
||||
[TestCase(1)]
|
||||
[TestCase(2)]
|
||||
[TestCase(5)]
|
||||
public void TestNumberOfSpins(int spins)
|
||||
{
|
||||
performTest(generateReplay(spins));
|
||||
|
||||
for (int i = 0; i < spins; ++i)
|
||||
assertResult<SpinnerTick>(i, HitResult.SmallBonus);
|
||||
|
||||
assertResult<SpinnerTick>(spins, HitResult.IgnoreMiss);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHitEverything()
|
||||
{
|
||||
performTest(generateReplay(20));
|
||||
|
||||
AddAssert("all max judgements", () => judgementResults.All(result => result.Type == result.Judgement.MaxResult));
|
||||
}
|
||||
|
||||
private static List<ReplayFrame> generateReplay(int spins)
|
||||
{
|
||||
var replayFrames = new List<ReplayFrame>();
|
||||
|
||||
const int frames_per_spin = 30;
|
||||
|
||||
for (int i = 0; i < spins * frames_per_spin; ++i)
|
||||
{
|
||||
float totalProgress = i / (float)(spins * frames_per_spin);
|
||||
float spinProgress = (i % frames_per_spin) / (float)frames_per_spin;
|
||||
double time = time_spinner_start + (time_spinner_end - time_spinner_start) * totalProgress;
|
||||
float posX = MathF.Cos(2 * MathF.PI * spinProgress);
|
||||
float posY = MathF.Sin(2 * MathF.PI * spinProgress);
|
||||
Vector2 finalPos = OsuPlayfield.BASE_SIZE / 2 + new Vector2(posX, posY) * 50;
|
||||
|
||||
replayFrames.Add(new OsuReplayFrame(time, finalPos, OsuAction.LeftButton));
|
||||
}
|
||||
|
||||
return replayFrames;
|
||||
}
|
||||
|
||||
private void performTest(List<ReplayFrame> frames)
|
||||
{
|
||||
AddStep("load player", () =>
|
||||
{
|
||||
Beatmap.Value = CreateWorkingBeatmap(new Beatmap<OsuHitObject>
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
new Spinner
|
||||
{
|
||||
StartTime = time_spinner_start,
|
||||
EndTime = time_spinner_end,
|
||||
Position = OsuPlayfield.BASE_SIZE / 2
|
||||
}
|
||||
},
|
||||
BeatmapInfo =
|
||||
{
|
||||
Difficulty = new BeatmapDifficulty(),
|
||||
Ruleset = new OsuRuleset().RulesetInfo
|
||||
},
|
||||
});
|
||||
|
||||
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });
|
||||
|
||||
p.OnLoadComplete += _ =>
|
||||
{
|
||||
p.ScoreProcessor.NewJudgement += result =>
|
||||
{
|
||||
if (currentPlayer == p) judgementResults.Add(result);
|
||||
};
|
||||
};
|
||||
|
||||
LoadScreen(currentPlayer = p);
|
||||
judgementResults = new List<JudgementResult>();
|
||||
});
|
||||
|
||||
AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0);
|
||||
AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen());
|
||||
AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value);
|
||||
}
|
||||
|
||||
private void assertResult<T>(int index, HitResult expectedResult)
|
||||
{
|
||||
AddAssert($"{typeof(T).ReadableName()} ({index}) judged as {expectedResult}",
|
||||
() => judgementResults.Where(j => j.HitObject is T).OrderBy(j => j.HitObject.StartTime).ElementAt(index).Type,
|
||||
() => Is.EqualTo(expectedResult));
|
||||
}
|
||||
|
||||
private partial class ScoreAccessibleReplayPlayer : ReplayPlayer
|
||||
{
|
||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||
|
||||
protected override bool PauseOnFocusLost => false;
|
||||
|
||||
public ScoreAccessibleReplayPlayer(Score score)
|
||||
: base(score, new PlayerConfiguration
|
||||
{
|
||||
AllowPause = false,
|
||||
ShowResults = false,
|
||||
})
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue