Fix slider testscene failures

This commit is contained in:
smoogipoo 2021-06-30 19:43:34 +09:00
parent 181243d7ce
commit e23614556e

View File

@ -37,11 +37,13 @@ namespace osu.Game.Rulesets.Osu.Tests
private readonly BindableBool snakingIn = new BindableBool(); private readonly BindableBool snakingIn = new BindableBool();
private readonly BindableBool snakingOut = new BindableBool(); private readonly BindableBool snakingOut = new BindableBool();
private IBeatmap beatmap;
private const double duration_of_span = 3605; private const double duration_of_span = 3605;
private const double fade_in_modifier = -1200; private const double fade_in_modifier = -1200;
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
=> new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); => new ClockBackedTestWorkingBeatmap(this.beatmap = beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(RulesetConfigCache configCache) private void load(RulesetConfigCache configCache)
@ -51,8 +53,16 @@ namespace osu.Game.Rulesets.Osu.Tests
config.BindWith(OsuRulesetSetting.SnakingOutSliders, snakingOut); config.BindWith(OsuRulesetSetting.SnakingOutSliders, snakingOut);
} }
private Slider slider;
private DrawableSlider drawableSlider; private DrawableSlider drawableSlider;
[SetUp]
public void Setup() => Schedule(() =>
{
slider = null;
drawableSlider = null;
});
[SetUpSteps] [SetUpSteps]
public override void SetUpSteps() public override void SetUpSteps()
{ {
@ -67,21 +77,19 @@ namespace osu.Game.Rulesets.Osu.Tests
base.SetUpSteps(); base.SetUpSteps();
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
double startTime = hitObjects[sliderIndex].StartTime; retrieveSlider(sliderIndex);
addSeekStep(startTime);
retrieveDrawableSlider((Slider)hitObjects[sliderIndex]);
setSnaking(true); setSnaking(true);
ensureSnakingIn(startTime + fade_in_modifier); addEnsureSnakingInSteps(() => slider.StartTime + fade_in_modifier);
for (int i = 0; i < sliderIndex; i++) for (int i = 0; i < sliderIndex; i++)
{ {
// non-final repeats should not snake out // non-final repeats should not snake out
ensureNoSnakingOut(startTime, i); addEnsureNoSnakingOutStep(() => slider.StartTime, i);
} }
// final repeat should snake out // final repeat should snake out
ensureSnakingOut(startTime, sliderIndex); addEnsureSnakingOutSteps(() => slider.StartTime, sliderIndex);
} }
[TestCase(0)] [TestCase(0)]
@ -93,17 +101,15 @@ namespace osu.Game.Rulesets.Osu.Tests
base.SetUpSteps(); base.SetUpSteps();
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
double startTime = hitObjects[sliderIndex].StartTime; retrieveSlider(sliderIndex);
addSeekStep(startTime);
retrieveDrawableSlider((Slider)hitObjects[sliderIndex]);
setSnaking(false); setSnaking(false);
ensureNoSnakingIn(startTime + fade_in_modifier); addEnsureNoSnakingInSteps(() => slider.StartTime + fade_in_modifier);
for (int i = 0; i <= sliderIndex; i++) for (int i = 0; i <= sliderIndex; i++)
{ {
// no snaking out ever, including final repeat // no snaking out ever, including final repeat
ensureNoSnakingOut(startTime, i); addEnsureNoSnakingOutStep(() => slider.StartTime, i);
} }
} }
@ -116,7 +122,7 @@ namespace osu.Game.Rulesets.Osu.Tests
// repeat might have a chance to update its position depending on where in the frame its hit, // repeat might have a chance to update its position depending on where in the frame its hit,
// so some leniency is allowed here instead of checking strict equality // so some leniency is allowed here instead of checking strict equality
checkPositionChange(16600, sliderRepeat, positionAlmostSame); addCheckPositionChangeSteps(() => 16600, getSliderRepeat, positionAlmostSame);
} }
[Test] [Test]
@ -126,38 +132,46 @@ namespace osu.Game.Rulesets.Osu.Tests
setSnaking(true); setSnaking(true);
base.SetUpSteps(); base.SetUpSteps();
checkPositionChange(16600, sliderRepeat, positionDecreased); addCheckPositionChangeSteps(() => 16600, getSliderRepeat, positionDecreased);
} }
private void retrieveDrawableSlider(Slider slider) => AddUntilStep($"retrieve slider @ {slider.StartTime}", () => private void retrieveSlider(int index)
(drawableSlider = (DrawableSlider)Player.DrawableRuleset.Playfield.AllHitObjects.SingleOrDefault(d => d.HitObject == slider)) != null);
private void ensureSnakingIn(double startTime) => checkPositionChange(startTime, sliderEnd, positionIncreased);
private void ensureNoSnakingIn(double startTime) => checkPositionChange(startTime, sliderEnd, positionRemainsSame);
private void ensureSnakingOut(double startTime, int repeatIndex)
{ {
var repeatTime = timeAtRepeat(startTime, repeatIndex); AddStep("retrieve slider at index", () => slider = (Slider)beatmap.HitObjects[index]);
addSeekStep(() => slider);
retrieveDrawableSlider(() => slider);
}
private void retrieveDrawableSlider(Func<Slider> getSliderFunc)
{
AddUntilStep("retrieve drawable slider", () =>
(drawableSlider = (DrawableSlider)Player.DrawableRuleset.Playfield.AllHitObjects.SingleOrDefault(d => d.HitObject == getSliderFunc())) != null);
}
private void addEnsureSnakingInSteps(Func<double> startTime) => addCheckPositionChangeSteps(startTime, getSliderEnd, positionIncreased);
private void addEnsureNoSnakingInSteps(Func<double> startTime) => addCheckPositionChangeSteps(startTime, getSliderEnd, positionRemainsSame);
private void addEnsureSnakingOutSteps(Func<double> startTime, int repeatIndex)
{
if (repeatIndex % 2 == 0) if (repeatIndex % 2 == 0)
checkPositionChange(repeatTime, sliderStart, positionIncreased); addCheckPositionChangeSteps(timeAtRepeat(startTime, repeatIndex), getSliderStart, positionIncreased);
else else
checkPositionChange(repeatTime, sliderEnd, positionDecreased); addCheckPositionChangeSteps(timeAtRepeat(startTime, repeatIndex), getSliderEnd, positionDecreased);
} }
private void ensureNoSnakingOut(double startTime, int repeatIndex) => private void addEnsureNoSnakingOutStep(Func<double> startTime, int repeatIndex)
checkPositionChange(timeAtRepeat(startTime, repeatIndex), positionAtRepeat(repeatIndex), positionRemainsSame); => addCheckPositionChangeSteps(timeAtRepeat(startTime, repeatIndex), positionAtRepeat(repeatIndex), positionRemainsSame);
private double timeAtRepeat(double startTime, int repeatIndex) => startTime + 100 + duration_of_span * repeatIndex; private Func<double> timeAtRepeat(Func<double> startTime, int repeatIndex) => () => startTime() + 100 + duration_of_span * repeatIndex;
private Func<Vector2> positionAtRepeat(int repeatIndex) => repeatIndex % 2 == 0 ? (Func<Vector2>)sliderStart : sliderEnd; private Func<Vector2> positionAtRepeat(int repeatIndex) => repeatIndex % 2 == 0 ? (Func<Vector2>)getSliderStart : getSliderEnd;
private List<Vector2> sliderCurve => ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve; private List<Vector2> getSliderCurve() => ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve;
private Vector2 sliderStart() => sliderCurve.First(); private Vector2 getSliderStart() => getSliderCurve().First();
private Vector2 sliderEnd() => sliderCurve.Last(); private Vector2 getSliderEnd() => getSliderCurve().Last();
private Vector2 sliderRepeat() private Vector2 getSliderRepeat()
{ {
var drawable = Player.DrawableRuleset.Playfield.AllHitObjects.SingleOrDefault(d => d.HitObject == hitObjects[1]); var drawable = Player.DrawableRuleset.Playfield.AllHitObjects.SingleOrDefault(d => d.HitObject == beatmap.HitObjects[1]);
var repeat = drawable.ChildrenOfType<Container<DrawableSliderRepeat>>().First().Children.First(); var repeat = drawable.ChildrenOfType<Container<DrawableSliderRepeat>>().First().Children.First();
return repeat.Position; return repeat.Position;
} }
@ -167,7 +181,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private bool positionDecreased(Vector2 previous, Vector2 current) => current.X < previous.X && current.Y < previous.Y; private bool positionDecreased(Vector2 previous, Vector2 current) => current.X < previous.X && current.Y < previous.Y;
private bool positionAlmostSame(Vector2 previous, Vector2 current) => Precision.AlmostEquals(previous, current, 1); private bool positionAlmostSame(Vector2 previous, Vector2 current) => Precision.AlmostEquals(previous, current, 1);
private void checkPositionChange(double startTime, Func<Vector2> positionToCheck, Func<Vector2, Vector2, bool> positionAssertion) private void addCheckPositionChangeSteps(Func<double> startTime, Func<Vector2> positionToCheck, Func<Vector2, Vector2, bool> positionAssertion)
{ {
Vector2 previousPosition = Vector2.Zero; Vector2 previousPosition = Vector2.Zero;
@ -176,7 +190,7 @@ namespace osu.Game.Rulesets.Osu.Tests
addSeekStep(startTime); addSeekStep(startTime);
AddStep($"save {positionDescription} position", () => previousPosition = positionToCheck.Invoke()); AddStep($"save {positionDescription} position", () => previousPosition = positionToCheck.Invoke());
addSeekStep(startTime + 100); addSeekStep(() => startTime() + 100);
AddAssert($"{positionDescription} {assertionDescription}", () => AddAssert($"{positionDescription} {assertionDescription}", () =>
{ {
var currentPosition = positionToCheck.Invoke(); var currentPosition = positionToCheck.Invoke();
@ -193,19 +207,21 @@ namespace osu.Game.Rulesets.Osu.Tests
}); });
} }
private void addSeekStep(double time) private void addSeekStep(Func<Slider> slider)
{ {
AddStep($"seek to {time}", () => Player.GameplayClockContainer.Seek(time)); AddStep("seek to slider", () => Player.GameplayClockContainer.Seek(slider().StartTime));
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(slider().StartTime, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
} }
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap private void addSeekStep(Func<double> time)
{ {
HitObjects = hitObjects AddStep("seek to time", () => Player.GameplayClockContainer.Seek(time()));
}; AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time(), Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
}
private readonly List<HitObject> hitObjects = new List<HitObject> protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap { HitObjects = createHitObjects() };
private List<HitObject> createHitObjects() => new List<HitObject>
{ {
new Slider new Slider
{ {