// Copyright (c) ppy Pty Ltd . 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.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Overlays.Dialog; using osu.Game.Overlays.Mods; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Footer; using osu.Game.Screens.Select; using osuTK.Input; using FooterButtonMods = osu.Game.Screens.SelectV2.FooterButtonMods; namespace osu.Game.Tests.Visual.SongSelectV2 { public partial class TestSceneSongSelect : SongSelectTestScene { #region Hotkeys [Test] public void TestDeleteHotkey() { LoadSongSelect(); ImportBeatmapForRuleset(0); AddAssert("beatmap imported", () => Beatmaps.GetAllUsableBeatmapSets().Any(), () => Is.True); // song select should automatically select the beatmap for us but this is not implemented yet. // todo: remove when that's the case. AddAssert("no beatmap selected", () => Beatmap.IsDefault); AddStep("select beatmap", () => Beatmap.Value = Beatmaps.GetWorkingBeatmap(Beatmaps.GetAllUsableBeatmapSets().Single().Beatmaps.First())); AddAssert("beatmap selected", () => !Beatmap.IsDefault); AddStep("press shift-delete", () => { InputManager.PressKey(Key.ShiftLeft); InputManager.Key(Key.Delete); InputManager.ReleaseKey(Key.ShiftLeft); }); AddUntilStep("delete dialog shown", () => DialogOverlay.CurrentDialog, Is.InstanceOf); AddStep("confirm deletion", () => DialogOverlay.CurrentDialog!.PerformAction()); AddAssert("beatmap set deleted", () => Beatmaps.GetAllUsableBeatmapSets().Any(), () => Is.False); } [Test] public void TestSpeedChange() { LoadSongSelect(); AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); decreaseModSpeed(); AddAssert("half time activated at 0.95x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(0.95).Within(0.005)); decreaseModSpeed(); AddAssert("half time speed changed to 0.9x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(0.9).Within(0.005)); increaseModSpeed(); AddAssert("half time speed changed to 0.95x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(0.95).Within(0.005)); increaseModSpeed(); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); increaseModSpeed(); AddAssert("double time activated at 1.05x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(1.05).Within(0.005)); increaseModSpeed(); AddAssert("double time speed changed to 1.1x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(1.1).Within(0.005)); decreaseModSpeed(); AddAssert("double time speed changed to 1.05x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(1.05).Within(0.005)); OsuModNightcore nc = new OsuModNightcore { SpeedChange = { Value = 1.05 } }; AddStep("select NC", () => SelectedMods.Value = new[] { nc }); increaseModSpeed(); AddAssert("nightcore speed changed to 1.1x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(1.1).Within(0.005)); decreaseModSpeed(); AddAssert("nightcore speed changed to 1.05x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(1.05).Within(0.005)); decreaseModSpeed(); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); decreaseModSpeed(); AddAssert("daycore activated at 0.95x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(0.95).Within(0.005)); decreaseModSpeed(); AddAssert("daycore activated at 0.95x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(0.9).Within(0.005)); increaseModSpeed(); AddAssert("daycore activated at 0.95x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(0.95).Within(0.005)); OsuModDoubleTime dt = new OsuModDoubleTime { SpeedChange = { Value = 1.02 }, AdjustPitch = { Value = true }, }; AddStep("select DT", () => SelectedMods.Value = new[] { dt }); decreaseModSpeed(); AddAssert("half time activated at 0.97x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(0.97).Within(0.005)); AddAssert("adjust pitch preserved", () => SelectedMods.Value.OfType().Single().AdjustPitch.Value, () => Is.True); OsuModHalfTime ht = new OsuModHalfTime { SpeedChange = { Value = 0.97 }, AdjustPitch = { Value = true }, }; Mod[] modlist = { ht, new OsuModHardRock(), new OsuModHidden() }; AddStep("select HT+HD", () => SelectedMods.Value = modlist); increaseModSpeed(); AddAssert("double time activated at 1.02x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(1.02).Within(0.005)); AddAssert("double time activated at 1.02x", () => SelectedMods.Value.OfType().Single().AdjustPitch.Value, () => Is.True); AddAssert("HD still enabled", () => SelectedMods.Value.OfType().SingleOrDefault(), () => Is.Not.Null); AddAssert("HR still enabled", () => SelectedMods.Value.OfType().SingleOrDefault(), () => Is.Not.Null); AddStep("select WU", () => SelectedMods.Value = new[] { new ModWindUp() }); increaseModSpeed(); AddAssert("windup still active", () => SelectedMods.Value.First() is ModWindUp); AddStep("select AS", () => SelectedMods.Value = new[] { new ModAdaptiveSpeed() }); increaseModSpeed(); AddAssert("adaptive speed still active", () => SelectedMods.Value.First() is ModAdaptiveSpeed); OsuModDoubleTime dtWithAdjustPitch = new OsuModDoubleTime { SpeedChange = { Value = 1.05 }, AdjustPitch = { Value = true }, }; AddStep("select DT x1.05", () => SelectedMods.Value = new[] { dtWithAdjustPitch }); decreaseModSpeed(); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); decreaseModSpeed(); AddAssert("half time activated at 0.95x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(0.95).Within(0.005)); AddAssert("half time has adjust pitch active", () => SelectedMods.Value.OfType().Single().AdjustPitch.Value, () => Is.True); AddStep("turn off adjust pitch", () => SelectedMods.Value.OfType().Single().AdjustPitch.Value = false); increaseModSpeed(); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); increaseModSpeed(); AddAssert("double time activated at 1.05x", () => SelectedMods.Value.OfType().Single().SpeedChange.Value, () => Is.EqualTo(1.05).Within(0.005)); AddAssert("double time has adjust pitch inactive", () => SelectedMods.Value.OfType().Single().AdjustPitch.Value, () => Is.False); void increaseModSpeed() => AddStep("increase mod speed", () => { InputManager.PressKey(Key.ControlLeft); InputManager.Key(Key.Up); InputManager.ReleaseKey(Key.ControlLeft); }); void decreaseModSpeed() => AddStep("decrease mod speed", () => { InputManager.PressKey(Key.ControlLeft); InputManager.Key(Key.Down); InputManager.ReleaseKey(Key.ControlLeft); }); } #endregion #region Footer [Test] public void TestFooterMods() { LoadSongSelect(); AddStep("one mod", () => SelectedMods.Value = new List { new OsuModHidden() }); AddStep("two mods", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModHardRock() }); AddStep("three mods", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModHardRock(), new OsuModDoubleTime() }); AddStep("four mods", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModClassic() }); AddStep("five mods", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModClassic(), new OsuModDifficultyAdjust() }); AddStep("modified", () => SelectedMods.Value = new List { new OsuModDoubleTime { SpeedChange = { Value = 1.2 } } }); AddStep("modified + one", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModDoubleTime { SpeedChange = { Value = 1.2 } } }); AddStep("modified + two", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModHardRock(), new OsuModDoubleTime { SpeedChange = { Value = 1.2 } } }); AddStep("modified + three", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModHardRock(), new OsuModClassic(), new OsuModDoubleTime { SpeedChange = { Value = 1.2 } } }); AddStep("modified + four", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModHardRock(), new OsuModClassic(), new OsuModDifficultyAdjust(), new OsuModDoubleTime { SpeedChange = { Value = 1.2 } } }); AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); AddWaitStep("wait", 3); AddStep("one mod", () => SelectedMods.Value = new List { new OsuModHidden() }); AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); AddWaitStep("wait", 3); AddStep("five mods", () => SelectedMods.Value = new List { new OsuModHidden(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModClassic(), new OsuModDifficultyAdjust() }); } [Test] public void TestFooterModOverlay() { LoadSongSelect(); AddStep("Press F1", () => { InputManager.MoveMouseTo(this.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); AddAssert("Overlay visible", () => this.ChildrenOfType().Single().State.Value == Visibility.Visible); AddStep("Hide", () => this.ChildrenOfType().Single().Hide()); } // add these test cases when functionality is implemented. // [Test] // public void TestFooterRandom() // { // loadSongSelect(); // // AddStep("press F2", () => InputManager.Key(Key.F2)); // AddAssert("next random invoked", () => nextRandomCalled && !previousRandomCalled); // } // // [Test] // public void TestFooterRandomViaMouse() // { // loadSongSelect(); // // AddStep("click button", () => // { // InputManager.MoveMouseTo(randomButton); // InputManager.Click(MouseButton.Left); // }); // AddAssert("next random invoked", () => nextRandomCalled && !previousRandomCalled); // } // // [Test] // public void TestFooterRewind() // { // loadSongSelect(); // // AddStep("press Shift+F2", () => // { // InputManager.PressKey(Key.LShift); // InputManager.PressKey(Key.F2); // InputManager.ReleaseKey(Key.F2); // InputManager.ReleaseKey(Key.LShift); // }); // AddAssert("previous random invoked", () => previousRandomCalled && !nextRandomCalled); // } // // [Test] // public void TestFooterRewindViaShiftMouseLeft() // { // loadSongSelect(); // // AddStep("shift + click button", () => // { // InputManager.PressKey(Key.LShift); // InputManager.MoveMouseTo(randomButton); // InputManager.Click(MouseButton.Left); // InputManager.ReleaseKey(Key.LShift); // }); // AddAssert("previous random invoked", () => previousRandomCalled && !nextRandomCalled); // } // // [Test] // public void TestFooterRewindViaMouseRight() // { // loadSongSelect(); // // AddStep("right click button", () => // { // InputManager.MoveMouseTo(randomButton); // InputManager.Click(MouseButton.Right); // }); // AddAssert("previous random invoked", () => previousRandomCalled && !nextRandomCalled); // } [Test] public void TestFooterShowOptions() { LoadSongSelect(); AddStep("enable options", () => { var optionsButton = this.ChildrenOfType().Last(); optionsButton.Enabled.Value = true; optionsButton.TriggerClick(); }); } [Test] public void TestFooterOptionsState() { LoadSongSelect(); AddToggleStep("set options enabled state", state => this.ChildrenOfType().Last().Enabled.Value = state); } #endregion } }