2019-01-24 16:43:03 +08:00
// 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.
2018-04-13 17:19:50 +08:00
using System ;
2022-09-08 13:49:43 +08:00
using System.Diagnostics ;
2018-04-13 17:19:50 +08:00
using System.Linq ;
2022-08-29 14:23:34 +08:00
using System.Threading.Tasks ;
2018-04-13 17:19:50 +08:00
using NUnit.Framework ;
using osu.Framework.Allocation ;
2019-05-31 13:40:53 +08:00
using osu.Framework.Audio ;
2019-02-21 18:04:31 +08:00
using osu.Framework.Bindables ;
2022-08-29 14:23:34 +08:00
using osu.Framework.Extensions ;
2022-07-30 23:50:41 +08:00
using osu.Framework.Extensions.IEnumerableExtensions ;
2022-09-08 13:49:43 +08:00
using osu.Framework.Extensions.ObjectExtensions ;
2022-05-06 03:08:19 +08:00
using osu.Framework.Graphics.Containers ;
2023-10-28 18:13:13 +08:00
using osu.Framework.Input ;
2019-01-22 19:37:41 +08:00
using osu.Framework.Platform ;
2019-02-15 16:01:06 +08:00
using osu.Framework.Screens ;
2020-01-27 11:21:17 +08:00
using osu.Framework.Testing ;
2022-08-29 14:23:34 +08:00
using osu.Framework.Utils ;
2018-04-13 17:19:50 +08:00
using osu.Game.Beatmaps ;
2019-08-27 13:31:34 +08:00
using osu.Game.Configuration ;
2022-01-27 18:35:04 +08:00
using osu.Game.Database ;
2021-11-15 17:46:11 +08:00
using osu.Game.Extensions ;
2021-11-04 17:02:44 +08:00
using osu.Game.Online.API.Requests.Responses ;
2022-06-07 15:32:15 +08:00
using osu.Game.Online.Chat ;
2019-10-08 15:37:34 +08:00
using osu.Game.Overlays ;
2023-09-22 02:01:59 +08:00
using osu.Game.Overlays.Dialog ;
2022-05-06 03:08:19 +08:00
using osu.Game.Overlays.Mods ;
2022-08-29 14:23:34 +08:00
using osu.Game.Overlays.Notifications ;
2018-04-13 17:19:50 +08:00
using osu.Game.Rulesets ;
2024-04-15 20:07:08 +08:00
using osu.Game.Rulesets.Mania.Mods ;
2018-08-14 13:18:46 +08:00
using osu.Game.Rulesets.Mods ;
2019-06-14 19:18:22 +08:00
using osu.Game.Rulesets.Osu ;
2018-08-14 13:18:46 +08:00
using osu.Game.Rulesets.Osu.Mods ;
2020-05-04 12:31:49 +08:00
using osu.Game.Scoring ;
2020-02-03 15:04:32 +08:00
using osu.Game.Screens.Play ;
2018-04-13 17:19:50 +08:00
using osu.Game.Screens.Select ;
using osu.Game.Screens.Select.Carousel ;
using osu.Game.Screens.Select.Filter ;
2021-11-24 16:59:23 +08:00
using osu.Game.Tests.Resources ;
2020-01-27 11:21:17 +08:00
using osuTK.Input ;
2018-04-13 17:19:50 +08:00
2019-03-25 00:02:36 +08:00
namespace osu.Game.Tests.Visual.SongSelect
2018-04-13 17:19:50 +08:00
{
[TestFixture]
2022-11-24 13:32:20 +08:00
public partial class TestScenePlaySongSelect : ScreenTestScene
2018-04-13 17:19:50 +08:00
{
2022-09-08 13:49:43 +08:00
private BeatmapManager manager = null ! ;
private RulesetStore rulesets = null ! ;
private MusicController music = null ! ;
private WorkingBeatmap defaultBeatmap = null ! ;
private OsuConfigManager config = null ! ;
private TestSongSelect ? songSelect ;
2018-07-18 11:58:45 +08:00
2018-04-13 17:19:50 +08:00
[BackgroundDependencyLoader]
2019-05-31 13:40:53 +08:00
private void load ( GameHost host , AudioManager audio )
2018-04-13 17:19:50 +08:00
{
2024-08-28 18:19:04 +08:00
DetachedBeatmapStore detachedBeatmapStore ;
2022-01-11 14:33:54 +08:00
// These DI caches are required to ensure for interactive runs this test scene doesn't nuke all user beatmaps in the local install.
// At a point we have isolated interactive test runs enough, this can likely be removed.
2022-02-16 16:13:51 +08:00
Dependencies . Cache ( rulesets = new RealmRulesetStore ( Realm ) ) ;
2022-01-25 11:58:15 +08:00
Dependencies . Cache ( Realm ) ;
2022-07-28 15:19:05 +08:00
Dependencies . Cache ( manager = new BeatmapManager ( LocalStorage , Realm , null , audio , Resources , host , defaultBeatmap = Beatmap . Default ) ) ;
2024-08-28 18:19:04 +08:00
Dependencies . Cache ( detachedBeatmapStore = new DetachedBeatmapStore ( ) ) ;
2018-04-13 17:19:50 +08:00
2019-10-08 15:37:34 +08:00
Dependencies . Cache ( music = new MusicController ( ) ) ;
// required to get bindables attached
Add ( music ) ;
2024-08-28 18:19:04 +08:00
Add ( detachedBeatmapStore ) ;
2019-10-08 15:37:34 +08:00
2019-08-27 13:31:34 +08:00
Dependencies . Cache ( config = new OsuConfigManager ( LocalStorage ) ) ;
2018-07-18 11:58:45 +08:00
}
2018-04-13 17:19:50 +08:00
2020-01-31 12:54:26 +08:00
public override void SetUpSteps ( )
2019-06-14 19:18:22 +08:00
{
2020-01-31 12:54:26 +08:00
base . SetUpSteps ( ) ;
2022-01-25 13:30:32 +08:00
AddStep ( "reset defaults" , ( ) = >
2020-01-31 12:54:26 +08:00
{
Ruleset . Value = new OsuRuleset ( ) . RulesetInfo ;
2022-03-30 06:08:22 +08:00
2020-01-31 15:14:55 +08:00
Beatmap . SetDefault ( ) ;
2022-03-30 06:08:22 +08:00
SelectedMods . SetDefault ( ) ;
2022-01-25 13:30:32 +08:00
2022-01-27 18:35:04 +08:00
songSelect = null ;
2020-01-31 12:54:26 +08:00
} ) ;
2022-01-25 13:30:32 +08:00
2022-09-08 13:49:43 +08:00
AddStep ( "delete all beatmaps" , ( ) = > manager . Delete ( ) ) ;
2020-01-31 12:54:26 +08:00
}
2018-04-13 17:19:50 +08:00
2024-05-19 00:38:31 +08:00
[Test]
public void TestSpeedChange ( )
{
createSongSelect ( ) ;
changeMods ( ) ;
2024-05-24 18:59:24 +08:00
decreaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "half time activated at 0.95x" , ( ) = > songSelect ! . Mods . Value . OfType < ModHalfTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 0.95 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
decreaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "half time speed changed to 0.9x" , ( ) = > songSelect ! . Mods . Value . OfType < ModHalfTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 0.9 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "half time speed changed to 0.95x" , ( ) = > songSelect ! . Mods . Value . OfType < ModHalfTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 0.95 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-19 00:38:31 +08:00
AddAssert ( "no mods selected" , ( ) = > songSelect ! . Mods . Value . Count = = 0 ) ;
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "double time activated at 1.05x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDoubleTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 1.05 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "double time speed changed to 1.1x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDoubleTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 1.1 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
decreaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "double time speed changed to 1.05x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDoubleTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 1.05 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
OsuModNightcore nc = new OsuModNightcore
{
SpeedChange = { Value = 1.05 }
} ;
changeMods ( nc ) ;
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "nightcore speed changed to 1.1x" , ( ) = > songSelect ! . Mods . Value . OfType < ModNightcore > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 1.1 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
decreaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "nightcore speed changed to 1.05x" , ( ) = > songSelect ! . Mods . Value . OfType < ModNightcore > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 1.05 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
decreaseModSpeed ( ) ;
2024-05-19 00:38:31 +08:00
AddAssert ( "no mods selected" , ( ) = > songSelect ! . Mods . Value . Count = = 0 ) ;
2024-05-24 18:59:24 +08:00
decreaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "daycore activated at 0.95x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDaycore > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 0.95 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
decreaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "daycore activated at 0.95x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDaycore > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 0.9 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "daycore activated at 0.95x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDaycore > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 0.95 ) . Within ( 0.005 ) ) ;
2024-05-19 00:38:31 +08:00
OsuModDoubleTime dt = new OsuModDoubleTime
{
SpeedChange = { Value = 1.02 } ,
AdjustPitch = { Value = true } ,
} ;
changeMods ( dt ) ;
2024-05-24 18:59:24 +08:00
decreaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "half time activated at 0.97x" , ( ) = > songSelect ! . Mods . Value . OfType < ModHalfTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 0.97 ) . Within ( 0.005 ) ) ;
AddAssert ( "adjust pitch preserved" , ( ) = > songSelect ! . Mods . Value . OfType < ModHalfTime > ( ) . Single ( ) . AdjustPitch . Value , ( ) = > Is . True ) ;
2024-05-19 00:38:31 +08:00
OsuModHalfTime ht = new OsuModHalfTime
{
SpeedChange = { Value = 0.97 } ,
AdjustPitch = { Value = true } ,
} ;
Mod [ ] modlist = { ht , new OsuModHardRock ( ) , new OsuModHidden ( ) } ;
changeMods ( modlist ) ;
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "double time activated at 1.02x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDoubleTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 1.02 ) . Within ( 0.005 ) ) ;
AddAssert ( "double time activated at 1.02x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDoubleTime > ( ) . Single ( ) . AdjustPitch . Value , ( ) = > Is . True ) ;
AddAssert ( "HD still enabled" , ( ) = > songSelect ! . Mods . Value . OfType < ModHidden > ( ) . SingleOrDefault ( ) , ( ) = > Is . Not . Null ) ;
AddAssert ( "HR still enabled" , ( ) = > songSelect ! . Mods . Value . OfType < ModHardRock > ( ) . SingleOrDefault ( ) , ( ) = > Is . Not . Null ) ;
2024-05-19 00:38:31 +08:00
changeMods ( new ModWindUp ( ) ) ;
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-19 00:38:31 +08:00
AddAssert ( "windup still active" , ( ) = > songSelect ! . Mods . Value . First ( ) is ModWindUp ) ;
changeMods ( new ModAdaptiveSpeed ( ) ) ;
2024-05-24 18:59:24 +08:00
increaseModSpeed ( ) ;
2024-05-24 18:04:09 +08:00
AddAssert ( "adaptive speed still active" , ( ) = > songSelect ! . Mods . Value . First ( ) is ModAdaptiveSpeed ) ;
2024-05-24 18:59:24 +08:00
2024-09-30 14:38:11 +08:00
OsuModDoubleTime dtWithAdjustPitch = new OsuModDoubleTime
{
SpeedChange = { Value = 1.05 } ,
AdjustPitch = { Value = true } ,
} ;
changeMods ( dtWithAdjustPitch ) ;
decreaseModSpeed ( ) ;
AddAssert ( "no mods selected" , ( ) = > songSelect ! . Mods . Value . Count = = 0 ) ;
decreaseModSpeed ( ) ;
AddAssert ( "half time activated at 0.95x" , ( ) = > songSelect ! . Mods . Value . OfType < ModHalfTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 0.95 ) . Within ( 0.005 ) ) ;
AddAssert ( "half time has adjust pitch active" , ( ) = > songSelect ! . Mods . Value . OfType < ModHalfTime > ( ) . Single ( ) . AdjustPitch . Value , ( ) = > Is . True ) ;
2024-09-30 14:46:45 +08:00
AddStep ( "turn off adjust pitch" , ( ) = > songSelect ! . Mods . Value . OfType < ModHalfTime > ( ) . Single ( ) . AdjustPitch . Value = false ) ;
increaseModSpeed ( ) ;
AddAssert ( "no mods selected" , ( ) = > songSelect ! . Mods . Value . Count = = 0 ) ;
increaseModSpeed ( ) ;
AddAssert ( "double time activated at 1.05x" , ( ) = > songSelect ! . Mods . Value . OfType < ModDoubleTime > ( ) . Single ( ) . SpeedChange . Value , ( ) = > Is . EqualTo ( 1.05 ) . Within ( 0.005 ) ) ;
AddAssert ( "double time has adjust pitch inactive" , ( ) = > songSelect ! . Mods . Value . OfType < ModDoubleTime > ( ) . Single ( ) . AdjustPitch . Value , ( ) = > Is . False ) ;
2024-05-24 18:59:24 +08:00
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 ) ;
} ) ;
2024-05-19 00:38:31 +08:00
}
2022-06-07 15:32:15 +08:00
[Test]
public void TestPlaceholderBeatmapPresence ( )
{
createSongSelect ( ) ;
AddUntilStep ( "wait for placeholder visible" , ( ) = > getPlaceholder ( ) ? . State . Value = = Visibility . Visible ) ;
addRulesetImportStep ( 0 ) ;
AddUntilStep ( "wait for placeholder hidden" , ( ) = > getPlaceholder ( ) ? . State . Value = = Visibility . Hidden ) ;
2022-09-08 13:49:43 +08:00
AddStep ( "delete all beatmaps" , ( ) = > manager . Delete ( ) ) ;
2022-06-07 15:32:15 +08:00
AddUntilStep ( "wait for placeholder visible" , ( ) = > getPlaceholder ( ) ? . State . Value = = Visibility . Visible ) ;
}
2022-07-01 14:28:55 +08:00
[Test]
public void TestPlaceholderStarDifficulty ( )
{
addRulesetImportStep ( 0 ) ;
AddStep ( "change star filter" , ( ) = > config . SetValue ( OsuSetting . DisplayStarsMinimum , 10.0 ) ) ;
createSongSelect ( ) ;
AddUntilStep ( "wait for placeholder visible" , ( ) = > getPlaceholder ( ) ? . State . Value = = Visibility . Visible ) ;
AddStep ( "click link in placeholder" , ( ) = > getPlaceholder ( ) . ChildrenOfType < DrawableLinkCompiler > ( ) . First ( ) . TriggerClick ( ) ) ;
AddUntilStep ( "star filter reset" , ( ) = > config . Get < double > ( OsuSetting . DisplayStarsMinimum ) = = 0.0 ) ;
AddUntilStep ( "wait for placeholder visible" , ( ) = > getPlaceholder ( ) ? . State . Value = = Visibility . Hidden ) ;
}
2022-06-07 15:32:15 +08:00
[Test]
public void TestPlaceholderConvertSetting ( )
{
addRulesetImportStep ( 0 ) ;
AddStep ( "change convert setting" , ( ) = > config . SetValue ( OsuSetting . ShowConvertedBeatmaps , false ) ) ;
createSongSelect ( ) ;
2022-06-30 03:45:02 +08:00
changeRuleset ( 2 ) ;
2022-06-07 15:32:15 +08:00
AddUntilStep ( "wait for placeholder visible" , ( ) = > getPlaceholder ( ) ? . State . Value = = Visibility . Visible ) ;
AddStep ( "click link in placeholder" , ( ) = > getPlaceholder ( ) . ChildrenOfType < DrawableLinkCompiler > ( ) . First ( ) . TriggerClick ( ) ) ;
AddUntilStep ( "convert setting changed" , ( ) = > config . Get < bool > ( OsuSetting . ShowConvertedBeatmaps ) ) ;
AddUntilStep ( "wait for placeholder visible" , ( ) = > getPlaceholder ( ) ? . State . Value = = Visibility . Hidden ) ;
}
2019-11-13 17:54:33 +08:00
[Test]
public void TestSingleFilterOnEnter ( )
{
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 0" , ( ) = > songSelect ? . FilterCount , ( ) = > Is . EqualTo ( 0 ) ) ;
2019-11-13 17:54:33 +08:00
}
2020-01-27 11:21:17 +08:00
[Test]
public void TestChangeBeatmapBeforeEnter ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
2020-05-04 13:43:47 +08:00
waitForInitialSelection ( ) ;
2020-01-27 17:26:44 +08:00
2022-09-08 13:49:43 +08:00
WorkingBeatmap ? selected = null ;
2020-01-27 11:21:17 +08:00
AddStep ( "store selected beatmap" , ( ) = > selected = Beatmap . Value ) ;
AddStep ( "select next and enter" , ( ) = >
{
2020-11-05 22:41:56 +08:00
InputManager . Key ( Key . Down ) ;
InputManager . Key ( Key . Enter ) ;
2020-01-27 11:21:17 +08:00
} ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2020-01-27 11:21:17 +08:00
AddAssert ( "ensure selection changed" , ( ) = > selected ! = Beatmap . Value ) ;
}
[Test]
public void TestChangeBeatmapAfterEnter ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
2020-05-04 13:43:47 +08:00
waitForInitialSelection ( ) ;
2020-01-27 17:26:44 +08:00
2022-09-08 13:49:43 +08:00
WorkingBeatmap ? selected = null ;
2020-01-27 11:21:17 +08:00
AddStep ( "store selected beatmap" , ( ) = > selected = Beatmap . Value ) ;
AddStep ( "select next and enter" , ( ) = >
{
2020-11-05 22:41:56 +08:00
InputManager . Key ( Key . Enter ) ;
InputManager . Key ( Key . Down ) ;
2020-01-27 11:21:17 +08:00
} ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2020-01-27 11:21:17 +08:00
AddAssert ( "ensure selection didn't change" , ( ) = > selected = = Beatmap . Value ) ;
}
[Test]
public void TestChangeBeatmapViaMouseBeforeEnter ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
2020-01-27 17:26:44 +08:00
AddUntilStep ( "wait for initial selection" , ( ) = > ! Beatmap . IsDefault ) ;
2022-09-08 13:49:43 +08:00
WorkingBeatmap ? selected = null ;
2020-01-27 11:21:17 +08:00
AddStep ( "store selected beatmap" , ( ) = > selected = Beatmap . Value ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "wait for beatmaps to load" , ( ) = > songSelect ! . Carousel . ChildrenOfType < DrawableCarouselBeatmap > ( ) . Any ( ) ) ;
2021-10-12 21:07:57 +08:00
2020-01-27 11:21:17 +08:00
AddStep ( "select next and enter" , ( ) = >
{
2022-09-08 13:49:43 +08:00
InputManager . MoveMouseTo ( songSelect ! . Carousel . ChildrenOfType < DrawableCarouselBeatmap > ( )
2023-01-09 02:02:48 +08:00
. First ( b = > ! ( ( CarouselBeatmap ) b . Item ! ) . BeatmapInfo . Equals ( songSelect ! . Carousel . SelectedBeatmapInfo ) ) ) ;
2020-01-27 11:21:17 +08:00
2020-11-05 22:41:56 +08:00
InputManager . Click ( MouseButton . Left ) ;
2020-01-27 11:21:17 +08:00
2020-11-05 22:41:56 +08:00
InputManager . Key ( Key . Enter ) ;
2020-01-27 11:21:17 +08:00
} ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2020-01-27 11:21:17 +08:00
AddAssert ( "ensure selection changed" , ( ) = > selected ! = Beatmap . Value ) ;
}
[Test]
public void TestChangeBeatmapViaMouseAfterEnter ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
2020-05-04 13:43:47 +08:00
waitForInitialSelection ( ) ;
2020-01-27 17:26:44 +08:00
2022-09-08 13:49:43 +08:00
WorkingBeatmap ? selected = null ;
2020-01-27 11:21:17 +08:00
AddStep ( "store selected beatmap" , ( ) = > selected = Beatmap . Value ) ;
AddStep ( "select next and enter" , ( ) = >
{
2022-09-08 13:49:43 +08:00
InputManager . MoveMouseTo ( songSelect ! . Carousel . ChildrenOfType < DrawableCarouselBeatmap > ( )
2023-01-09 02:02:48 +08:00
. First ( b = > ! ( ( CarouselBeatmap ) b . Item ! ) . BeatmapInfo . Equals ( songSelect ! . Carousel . SelectedBeatmapInfo ) ) ) ;
2020-01-27 11:21:17 +08:00
InputManager . PressButton ( MouseButton . Left ) ;
2020-11-05 22:41:56 +08:00
InputManager . Key ( Key . Enter ) ;
2020-01-27 11:21:17 +08:00
InputManager . ReleaseButton ( MouseButton . Left ) ;
} ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2020-01-27 11:21:17 +08:00
AddAssert ( "ensure selection didn't change" , ( ) = > selected = = Beatmap . Value ) ;
}
2019-12-10 01:30:23 +08:00
[Test]
public void TestNoFilterOnSimpleResume ( )
{
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
AddStep ( "push child screen" , ( ) = > Stack . Push ( new TestSceneOsuScreenStack . TestScreen ( "test child" ) ) ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2019-12-10 01:30:23 +08:00
2022-09-08 13:49:43 +08:00
AddStep ( "return" , ( ) = > songSelect ! . MakeCurrent ( ) ) ;
AddUntilStep ( "wait for current" , ( ) = > songSelect ! . IsCurrentScreen ( ) ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 0" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 0 ) ) ;
2019-12-10 01:30:23 +08:00
}
[Test]
public void TestFilterOnResumeAfterChange ( )
{
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 0 ) ;
2021-03-17 15:10:16 +08:00
AddStep ( "change convert setting" , ( ) = > config . SetValue ( OsuSetting . ShowConvertedBeatmaps , false ) ) ;
2019-12-10 01:30:23 +08:00
createSongSelect ( ) ;
AddStep ( "push child screen" , ( ) = > Stack . Push ( new TestSceneOsuScreenStack . TestScreen ( "test child" ) ) ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2019-12-10 01:30:23 +08:00
2021-03-17 15:10:16 +08:00
AddStep ( "change convert setting" , ( ) = > config . SetValue ( OsuSetting . ShowConvertedBeatmaps , true ) ) ;
2019-12-10 01:30:23 +08:00
2022-09-08 13:49:43 +08:00
AddStep ( "return" , ( ) = > songSelect ! . MakeCurrent ( ) ) ;
AddUntilStep ( "wait for current" , ( ) = > songSelect ! . IsCurrentScreen ( ) ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 1" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 1 ) ) ;
2019-12-10 01:30:23 +08:00
}
2022-07-30 23:50:41 +08:00
[Test]
public void TestCarouselSelectionUpdatesOnResume ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
AddStep ( "push child screen" , ( ) = > Stack . Push ( new TestSceneOsuScreenStack . TestScreen ( "test child" ) ) ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2022-07-30 23:50:41 +08:00
AddStep ( "update beatmap" , ( ) = >
{
var selectedBeatmap = Beatmap . Value . BeatmapInfo ;
var anotherBeatmap = Beatmap . Value . BeatmapSetInfo . Beatmaps . Except ( selectedBeatmap . Yield ( ) ) . First ( ) ;
Beatmap . Value = manager . GetWorkingBeatmap ( anotherBeatmap ) ;
} ) ;
2022-09-08 13:49:43 +08:00
AddStep ( "return" , ( ) = > songSelect ! . MakeCurrent ( ) ) ;
AddUntilStep ( "wait for current" , ( ) = > songSelect ! . IsCurrentScreen ( ) ) ;
AddAssert ( "carousel updated" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . Equals ( Beatmap . Value . BeatmapInfo ) = = true ) ;
2022-07-30 23:50:41 +08:00
}
2019-10-08 15:37:34 +08:00
[Test]
public void TestAudioResuming ( )
{
createSongSelect ( ) ;
2023-09-28 14:59:06 +08:00
// We need to use one real beatmap to trigger the "same-track-transfer" logic that we're looking to test here.
// See `SongSelect.ensurePlayingSelected` and `WorkingBeatmap.TryTransferTrack`.
AddStep ( "import test beatmap" , ( ) = > manager . Import ( new ImportTask ( TestResources . GetTestBeatmapForImport ( ) ) ) . WaitSafely ( ) ) ;
2019-10-08 15:37:34 +08:00
addRulesetImportStep ( 0 ) ;
checkMusicPlaying ( true ) ;
2022-09-08 13:49:43 +08:00
AddStep ( "select first" , ( ) = > songSelect ! . Carousel . SelectBeatmap ( songSelect ! . Carousel . BeatmapSets . First ( ) . Beatmaps . First ( ) ) ) ;
2019-10-08 15:37:34 +08:00
checkMusicPlaying ( true ) ;
AddStep ( "manual pause" , ( ) = > music . TogglePause ( ) ) ;
checkMusicPlaying ( false ) ;
2023-09-28 14:59:06 +08:00
// Track should not have changed, so music should still not be playing.
2022-09-08 13:49:43 +08:00
AddStep ( "select next difficulty" , ( ) = > songSelect ! . Carousel . SelectNext ( skipDifficulties : false ) ) ;
2019-10-08 15:37:34 +08:00
checkMusicPlaying ( false ) ;
2022-09-08 13:49:43 +08:00
AddStep ( "select next set" , ( ) = > songSelect ! . Carousel . SelectNext ( ) ) ;
2019-10-08 15:37:34 +08:00
checkMusicPlaying ( true ) ;
}
[TestCase(false)]
[TestCase(true)]
public void TestAudioRemainsCorrectOnRulesetChange ( bool rulesetsInSameBeatmap )
{
createSongSelect ( ) ;
// start with non-osu! to avoid convert confusion
changeRuleset ( 1 ) ;
if ( rulesetsInSameBeatmap )
2019-11-11 19:53:22 +08:00
{
2019-10-08 15:37:34 +08:00
AddStep ( "import multi-ruleset map" , ( ) = >
{
2021-11-22 13:26:24 +08:00
var usableRulesets = rulesets . AvailableRulesets . Where ( r = > r . OnlineID ! = 2 ) . ToArray ( ) ;
2022-01-25 14:23:51 +08:00
manager . Import ( TestResources . CreateTestBeatmapSetInfo ( rulesets : usableRulesets ) ) ;
2019-10-08 15:37:34 +08:00
} ) ;
2019-11-11 19:53:22 +08:00
}
2019-10-08 15:37:34 +08:00
else
{
addRulesetImportStep ( 1 ) ;
addRulesetImportStep ( 0 ) ;
}
checkMusicPlaying ( true ) ;
AddStep ( "manual pause" , ( ) = > music . TogglePause ( ) ) ;
checkMusicPlaying ( false ) ;
changeRuleset ( 0 ) ;
checkMusicPlaying ( ! rulesetsInSameBeatmap ) ;
}
2018-07-20 10:32:00 +08:00
[Test]
2018-07-18 11:58:45 +08:00
public void TestDummy ( )
{
2019-02-15 20:50:40 +08:00
createSongSelect ( ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "dummy selected" , ( ) = > songSelect ! . CurrentBeatmap = = defaultBeatmap ) ;
2018-04-13 17:19:50 +08:00
2022-09-08 13:49:43 +08:00
AddUntilStep ( "dummy shown on wedge" , ( ) = > songSelect ! . CurrentBeatmapDetailsBeatmap = = defaultBeatmap ) ;
2018-04-13 17:19:50 +08:00
2018-07-18 11:58:45 +08:00
addManyTestMaps ( ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "random map selected" , ( ) = > songSelect ! . CurrentBeatmap ! = defaultBeatmap ) ;
2018-07-18 11:58:45 +08:00
}
2018-04-13 17:19:50 +08:00
2018-07-20 10:32:00 +08:00
[Test]
2018-07-18 11:58:45 +08:00
public void TestSorting ( )
{
2019-02-15 20:50:40 +08:00
createSongSelect ( ) ;
2018-07-18 11:58:45 +08:00
addManyTestMaps ( ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "random map selected" , ( ) = > songSelect ! . CurrentBeatmap ! = defaultBeatmap ) ;
2018-04-13 17:19:50 +08:00
2021-03-17 15:10:16 +08:00
AddStep ( @"Sort by Artist" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . Artist ) ) ;
AddStep ( @"Sort by Title" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . Title ) ) ;
AddStep ( @"Sort by Author" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . Author ) ) ;
AddStep ( @"Sort by DateAdded" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . DateAdded ) ) ;
AddStep ( @"Sort by BPM" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . BPM ) ) ;
AddStep ( @"Sort by Length" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . Length ) ) ;
AddStep ( @"Sort by Difficulty" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . Difficulty ) ) ;
2021-05-10 05:10:38 +08:00
AddStep ( @"Sort by Source" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . Source ) ) ;
2018-04-13 17:19:50 +08:00
}
2018-07-18 11:58:45 +08:00
[Test]
2018-08-14 13:19:26 +08:00
public void TestImportUnderDifferentRuleset ( )
2018-04-13 17:19:50 +08:00
{
2019-02-15 20:50:40 +08:00
createSongSelect ( ) ;
2019-10-08 15:37:47 +08:00
addRulesetImportStep ( 2 ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "no selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo = = null ) ;
2018-07-20 10:32:00 +08:00
}
2018-07-19 17:51:08 +08:00
2018-07-20 10:32:00 +08:00
[Test]
2018-08-14 13:19:26 +08:00
public void TestImportUnderCurrentRuleset ( )
2018-07-20 10:32:00 +08:00
{
2019-02-15 20:50:40 +08:00
createSongSelect ( ) ;
2018-07-20 10:32:00 +08:00
changeRuleset ( 2 ) ;
2019-06-10 17:34:24 +08:00
addRulesetImportStep ( 2 ) ;
addRulesetImportStep ( 1 ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . Ruleset . OnlineID = = 2 ) ;
2018-07-19 17:51:08 +08:00
2018-07-20 10:32:00 +08:00
changeRuleset ( 1 ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . Ruleset . OnlineID = = 1 ) ;
2018-07-19 17:51:08 +08:00
2018-07-20 10:32:00 +08:00
changeRuleset ( 0 ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "no selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo = = null ) ;
2018-07-18 11:58:45 +08:00
}
2022-08-29 14:23:34 +08:00
[Test]
2023-12-21 17:17:03 +08:00
[Ignore("temporary while peppy investigates. probably realm batching related.")]
2022-08-29 14:23:34 +08:00
public void TestSelectionRetainedOnBeatmapUpdate ( )
{
createSongSelect ( ) ;
changeRuleset ( 0 ) ;
2022-09-08 13:49:43 +08:00
Live < BeatmapSetInfo > ? original = null ;
2022-08-29 14:23:34 +08:00
int originalOnlineSetID = 0 ;
AddStep ( @"Sort by artist" , ( ) = > config . SetValue ( OsuSetting . SongSelectSortingMode , SortMode . Artist ) ) ;
AddStep ( "import original" , ( ) = >
{
original = manager . Import ( new ImportTask ( TestResources . GetQuickTestBeatmapForImport ( ) ) ) . GetResultSafely ( ) ;
2022-09-08 13:49:43 +08:00
Debug . Assert ( original ! = null ) ;
originalOnlineSetID = original . Value . OnlineID ;
2022-08-29 14:23:34 +08:00
} ) ;
// This will move the beatmap set to a different location in the carousel.
AddStep ( "Update original with bogus info" , ( ) = >
{
2022-09-08 13:49:43 +08:00
Debug . Assert ( original ! = null ) ;
2022-08-29 14:23:34 +08:00
original . PerformWrite ( set = >
{
foreach ( var beatmap in set . Beatmaps )
{
beatmap . Metadata . Artist = "ZZZZZ" ;
beatmap . OnlineID = 12804 ;
}
} ) ;
} ) ;
AddRepeatStep ( "import other beatmaps" , ( ) = >
{
var testBeatmapSetInfo = TestResources . CreateTestBeatmapSetInfo ( ) ;
foreach ( var beatmap in testBeatmapSetInfo . Beatmaps )
beatmap . Metadata . Artist = ( ( char ) RNG . Next ( 'A' , 'Z' ) ) . ToString ( ) ;
manager . Import ( testBeatmapSetInfo ) ;
} , 10 ) ;
2023-12-19 02:02:23 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . BeatmapSet ? . OnlineID , ( ) = > Is . EqualTo ( originalOnlineSetID ) ) ;
2022-09-08 13:49:43 +08:00
Task < Live < BeatmapSetInfo > ? > updateTask = null ! ;
2022-08-29 14:23:34 +08:00
2022-09-08 13:49:43 +08:00
AddStep ( "update beatmap" , ( ) = >
{
Debug . Assert ( original ! = null ) ;
updateTask = manager . ImportAsUpdate ( new ProgressNotification ( ) , new ImportTask ( TestResources . GetQuickTestBeatmapForImport ( ) ) , original . Value ) ;
} ) ;
2022-08-29 14:23:34 +08:00
AddUntilStep ( "wait for update completion" , ( ) = > updateTask . IsCompleted ) ;
2023-12-19 02:02:23 +08:00
AddUntilStep ( "retained selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . BeatmapSet ? . OnlineID , ( ) = > Is . EqualTo ( originalOnlineSetID ) ) ;
2022-08-29 14:23:34 +08:00
}
2020-04-17 17:50:58 +08:00
[Test]
public void TestPresentNewRulesetNewBeatmap ( )
{
createSongSelect ( ) ;
changeRuleset ( 2 ) ;
addRulesetImportStep ( 2 ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . Ruleset . OnlineID = = 2 ) ;
2020-04-17 17:50:58 +08:00
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 0 ) ;
2022-09-08 13:49:43 +08:00
BeatmapInfo ? target = null ;
2020-04-17 17:50:58 +08:00
AddStep ( "select beatmap/ruleset externally" , ( ) = >
{
target = manager . GetAllUsableBeatmapSets ( )
2022-01-27 14:19:48 +08:00
. Last ( b = > b . Beatmaps . Any ( bi = > bi . Ruleset . OnlineID = = 0 ) ) . Beatmaps . Last ( ) ;
2020-04-17 17:50:58 +08:00
2021-11-22 13:26:24 +08:00
Ruleset . Value = rulesets . AvailableRulesets . First ( r = > r . OnlineID = = 0 ) ;
2020-04-17 17:50:58 +08:00
Beatmap . Value = manager . GetWorkingBeatmap ( target ) ;
} ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . Equals ( target ) = = true ) ;
2020-04-17 17:50:58 +08:00
// this is an important check, to make sure updateComponentFromBeatmap() was actually run
2022-09-08 13:49:43 +08:00
AddUntilStep ( "selection shown on wedge" , ( ) = > songSelect ! . CurrentBeatmapDetailsBeatmap . BeatmapInfo . MatchesOnlineID ( target ) ) ;
2020-04-17 17:50:58 +08:00
}
[Test]
public void TestPresentNewBeatmapNewRuleset ( )
{
createSongSelect ( ) ;
changeRuleset ( 2 ) ;
addRulesetImportStep ( 2 ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . Ruleset . OnlineID = = 2 ) ;
2020-04-17 17:50:58 +08:00
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 0 ) ;
2022-09-08 13:49:43 +08:00
BeatmapInfo ? target = null ;
2020-04-17 17:50:58 +08:00
AddStep ( "select beatmap/ruleset externally" , ( ) = >
{
target = manager . GetAllUsableBeatmapSets ( )
2022-01-27 14:19:48 +08:00
. Last ( b = > b . Beatmaps . Any ( bi = > bi . Ruleset . OnlineID = = 0 ) ) . Beatmaps . Last ( ) ;
2020-04-17 17:50:58 +08:00
Beatmap . Value = manager . GetWorkingBeatmap ( target ) ;
2021-11-22 13:26:24 +08:00
Ruleset . Value = rulesets . AvailableRulesets . First ( r = > r . OnlineID = = 0 ) ;
2020-04-17 17:50:58 +08:00
} ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . Equals ( target ) = = true ) ;
2020-04-17 17:50:58 +08:00
2021-11-22 13:26:24 +08:00
AddUntilStep ( "has correct ruleset" , ( ) = > Ruleset . Value . OnlineID = = 0 ) ;
2020-04-17 17:50:58 +08:00
// this is an important check, to make sure updateComponentFromBeatmap() was actually run
2022-09-08 13:49:43 +08:00
AddUntilStep ( "selection shown on wedge" , ( ) = > songSelect ! . CurrentBeatmapDetailsBeatmap . BeatmapInfo . MatchesOnlineID ( target ) ) ;
2020-04-17 17:50:58 +08:00
}
2019-11-14 12:28:13 +08:00
[Test]
public void TestModsRetainedBetweenSongSelect ( )
{
2019-12-13 20:45:38 +08:00
AddAssert ( "empty mods" , ( ) = > ! SelectedMods . Value . Any ( ) ) ;
2019-11-14 12:28:13 +08:00
createSongSelect ( ) ;
addRulesetImportStep ( 0 ) ;
changeMods ( new OsuModHardRock ( ) ) ;
createSongSelect ( ) ;
2019-12-13 20:45:38 +08:00
AddAssert ( "mods retained" , ( ) = > SelectedMods . Value . Any ( ) ) ;
2019-11-14 12:28:13 +08:00
}
2019-01-10 14:25:07 +08:00
[Test]
public void TestStartAfterUnMatchingFilterDoesNotStart ( )
{
2019-02-15 20:50:40 +08:00
createSongSelect ( ) ;
2019-01-10 14:25:07 +08:00
addManyTestMaps ( ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ! = null ) ;
2019-01-10 14:25:07 +08:00
bool startRequested = false ;
AddStep ( "set filter and finalize" , ( ) = >
{
2022-09-08 13:49:43 +08:00
songSelect ! . StartRequested = ( ) = > startRequested = true ;
2019-01-10 14:25:07 +08:00
2022-09-08 13:49:43 +08:00
songSelect ! . Carousel . Filter ( new FilterCriteria { SearchText = "somestringthatshouldn'tbematchable" } ) ;
songSelect ! . FinaliseSelection ( ) ;
2019-01-10 14:25:07 +08:00
2022-09-08 13:49:43 +08:00
songSelect ! . StartRequested = null ;
2019-01-10 14:25:07 +08:00
} ) ;
AddAssert ( "start not requested" , ( ) = > ! startRequested ) ;
}
2023-12-06 10:17:32 +08:00
[Test]
public void TestSearchTextWithRulesetCriteria ( )
{
createSongSelect ( ) ;
addRulesetImportStep ( 0 ) ;
AddStep ( "disallow convert display" , ( ) = > config . SetValue ( OsuSetting . ShowConvertedBeatmaps , false ) ) ;
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ! = null ) ;
AddStep ( "set filter to match all" , ( ) = > songSelect ! . FilterControl . CurrentTextSearch . Value = "Some" ) ;
changeRuleset ( 1 ) ;
AddUntilStep ( "has no selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo = = null ) ;
}
2020-02-10 15:59:49 +08:00
[TestCase(false)]
[TestCase(true)]
public void TestExternalBeatmapChangeWhileFiltered ( bool differentRuleset )
{
createSongSelect ( ) ;
2021-12-20 18:24:40 +08:00
// ensure there is at least 1 difficulty for each of the rulesets
// (catch is excluded inside of addManyTestMaps).
addManyTestMaps ( 3 ) ;
2020-02-10 15:59:49 +08:00
changeRuleset ( 0 ) ;
2020-03-12 16:10:51 +08:00
// used for filter check below
2021-03-17 15:10:16 +08:00
AddStep ( "allow convert display" , ( ) = > config . SetValue ( OsuSetting . ShowConvertedBeatmaps , true ) ) ;
2020-03-12 16:10:51 +08:00
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ! = null ) ;
2020-02-10 15:59:49 +08:00
2023-12-13 14:15:22 +08:00
AddStep ( "set filter text" , ( ) = > songSelect ! . FilterControl . ChildrenOfType < FilterControl . FilterControlTextBox > ( ) . First ( ) . Text = "nonono" ) ;
2020-02-10 15:59:49 +08:00
AddUntilStep ( "dummy selected" , ( ) = > Beatmap . Value is DummyWorkingBeatmap ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has no selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo = = null ) ;
2020-02-11 16:41:48 +08:00
2022-09-08 13:49:43 +08:00
BeatmapInfo ? target = null ;
2020-02-10 15:59:49 +08:00
2020-03-12 16:10:51 +08:00
int targetRuleset = differentRuleset ? 1 : 0 ;
2020-02-10 15:59:49 +08:00
AddStep ( "select beatmap externally" , ( ) = >
{
2020-03-12 17:39:43 +08:00
target = manager . GetAllUsableBeatmapSets ( )
2022-01-27 14:19:48 +08:00
. First ( b = > b . Beatmaps . Any ( bi = > bi . Ruleset . OnlineID = = targetRuleset ) )
2021-12-20 16:11:15 +08:00
. Beatmaps
2022-01-27 14:19:48 +08:00
. First ( bi = > bi . Ruleset . OnlineID = = targetRuleset ) ;
2020-02-10 15:59:49 +08:00
Beatmap . Value = manager . GetWorkingBeatmap ( target ) ;
} ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ! = null ) ;
2020-02-11 16:41:48 +08:00
2020-03-12 16:10:51 +08:00
AddAssert ( "selected only shows expected ruleset (plus converts)" , ( ) = >
{
2023-01-09 02:02:48 +08:00
var selectedPanel = songSelect ! . Carousel . ChildrenOfType < DrawableCarouselBeatmapSet > ( ) . First ( s = > s . Item ! . State . Value = = CarouselItemState . Selected ) ;
2020-03-12 16:10:51 +08:00
// special case for converts checked here.
2020-10-13 11:50:39 +08:00
return selectedPanel . ChildrenOfType < FilterableDifficultyIcon > ( ) . All ( i = >
2021-11-22 13:26:24 +08:00
i . IsFiltered | | i . Item . BeatmapInfo . Ruleset . OnlineID = = targetRuleset | | i . Item . BeatmapInfo . Ruleset . OnlineID = = 0 ) ;
2020-03-12 16:10:51 +08:00
} ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "carousel has correct" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . MatchesOnlineID ( target ) = = true ) ;
2021-11-17 10:34:46 +08:00
AddUntilStep ( "game has correct" , ( ) = > Beatmap . Value . BeatmapInfo . MatchesOnlineID ( target ) ) ;
2020-02-10 15:59:49 +08:00
2023-12-13 14:15:22 +08:00
AddStep ( "reset filter text" , ( ) = > songSelect ! . FilterControl . ChildrenOfType < FilterControl . FilterControlTextBox > ( ) . First ( ) . Text = string . Empty ) ;
2020-02-10 15:59:49 +08:00
2021-11-17 10:34:46 +08:00
AddAssert ( "game still correct" , ( ) = > Beatmap . Value ? . BeatmapInfo . MatchesOnlineID ( target ) = = true ) ;
2022-09-08 13:49:43 +08:00
AddAssert ( "carousel still correct" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo . MatchesOnlineID ( target ) ) ;
2020-02-10 15:59:49 +08:00
}
2020-03-11 01:59:24 +08:00
[Test]
public void TestExternalBeatmapChangeWhileFilteredThenRefilter ( )
{
createSongSelect ( ) ;
2021-12-20 18:24:40 +08:00
// ensure there is at least 1 difficulty for each of the rulesets
// (catch is excluded inside of addManyTestMaps).
addManyTestMaps ( 3 ) ;
2020-03-11 01:59:24 +08:00
changeRuleset ( 0 ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ! = null ) ;
2020-03-11 01:59:24 +08:00
2023-12-13 14:15:22 +08:00
AddStep ( "set filter text" , ( ) = > songSelect ! . FilterControl . ChildrenOfType < FilterControl . FilterControlTextBox > ( ) . First ( ) . Text = "nonono" ) ;
2020-03-11 01:59:24 +08:00
AddUntilStep ( "dummy selected" , ( ) = > Beatmap . Value is DummyWorkingBeatmap ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has no selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo = = null ) ;
2020-03-11 01:59:24 +08:00
2022-09-08 13:49:43 +08:00
BeatmapInfo ? target = null ;
2020-03-11 01:59:24 +08:00
AddStep ( "select beatmap externally" , ( ) = >
{
2021-12-20 16:11:15 +08:00
target = manager
. GetAllUsableBeatmapSets ( )
2022-01-27 14:19:48 +08:00
. First ( b = > b . Beatmaps . Any ( bi = > bi . Ruleset . OnlineID = = 1 ) )
2021-12-20 16:11:15 +08:00
. Beatmaps . First ( ) ;
2020-03-11 01:59:24 +08:00
Beatmap . Value = manager . GetWorkingBeatmap ( target ) ;
} ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "has selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ! = null ) ;
2020-03-11 01:59:24 +08:00
2022-09-08 13:49:43 +08:00
AddUntilStep ( "carousel has correct" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . MatchesOnlineID ( target ) = = true ) ;
2021-11-17 10:34:46 +08:00
AddUntilStep ( "game has correct" , ( ) = > Beatmap . Value . BeatmapInfo . MatchesOnlineID ( target ) ) ;
2020-03-11 01:59:24 +08:00
2023-12-13 14:15:22 +08:00
AddStep ( "set filter text" , ( ) = > songSelect ! . FilterControl . ChildrenOfType < FilterControl . FilterControlTextBox > ( ) . First ( ) . Text = "nononoo" ) ;
2020-03-11 01:59:24 +08:00
AddUntilStep ( "game lost selection" , ( ) = > Beatmap . Value is DummyWorkingBeatmap ) ;
2022-09-08 13:49:43 +08:00
AddAssert ( "carousel lost selection" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo = = null ) ;
2020-03-11 01:59:24 +08:00
}
2020-02-03 15:04:32 +08:00
[Test]
2022-03-30 06:08:22 +08:00
public void TestAutoplayShortcut ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
AddUntilStep ( "wait for selection" , ( ) = > ! Beatmap . IsDefault ) ;
AddStep ( "press ctrl+enter" , ( ) = >
{
InputManager . PressKey ( Key . ControlLeft ) ;
InputManager . Key ( Key . Enter ) ;
InputManager . ReleaseKey ( Key . ControlLeft ) ;
} ) ;
AddUntilStep ( "wait for player" , ( ) = > Stack . CurrentScreen is PlayerLoader ) ;
2022-09-08 13:49:43 +08:00
AddAssert ( "autoplay selected" , ( ) = > songSelect ! . Mods . Value . Single ( ) is ModAutoplay ) ;
2022-03-30 06:08:22 +08:00
2022-09-08 13:49:43 +08:00
AddUntilStep ( "wait for return to ss" , ( ) = > songSelect ! . IsCurrentScreen ( ) ) ;
2022-03-30 06:08:22 +08:00
2022-09-08 13:49:43 +08:00
AddAssert ( "no mods selected" , ( ) = > songSelect ! . Mods . Value . Count = = 0 ) ;
2022-03-30 06:08:22 +08:00
}
[Test]
public void TestAutoplayShortcutKeepsAutoplayIfSelectedAlready ( )
2020-02-03 15:04:32 +08:00
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
2022-03-09 00:18:53 +08:00
AddUntilStep ( "wait for selection" , ( ) = > ! Beatmap . IsDefault ) ;
2022-03-30 06:08:22 +08:00
changeMods ( new OsuModAutoplay ( ) ) ;
AddStep ( "press ctrl+enter" , ( ) = >
{
InputManager . PressKey ( Key . ControlLeft ) ;
InputManager . Key ( Key . Enter ) ;
InputManager . ReleaseKey ( Key . ControlLeft ) ;
} ) ;
AddUntilStep ( "wait for player" , ( ) = > Stack . CurrentScreen is PlayerLoader ) ;
2022-09-08 13:49:43 +08:00
AddAssert ( "autoplay selected" , ( ) = > songSelect ! . Mods . Value . Single ( ) is ModAutoplay ) ;
2022-03-30 06:08:22 +08:00
2022-09-08 13:49:43 +08:00
AddUntilStep ( "wait for return to ss" , ( ) = > songSelect ! . IsCurrentScreen ( ) ) ;
2022-03-30 06:08:22 +08:00
2022-09-08 13:49:43 +08:00
AddAssert ( "autoplay still selected" , ( ) = > songSelect ! . Mods . Value . Single ( ) is ModAutoplay ) ;
2022-03-30 06:08:22 +08:00
}
[Test]
public void TestAutoplayShortcutReturnsInitialModsOnExit ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
AddUntilStep ( "wait for selection" , ( ) = > ! Beatmap . IsDefault ) ;
changeMods ( new OsuModRelax ( ) ) ;
2020-02-03 15:04:32 +08:00
AddStep ( "press ctrl+enter" , ( ) = >
{
InputManager . PressKey ( Key . ControlLeft ) ;
2020-11-05 22:41:56 +08:00
InputManager . Key ( Key . Enter ) ;
2020-02-03 15:04:32 +08:00
InputManager . ReleaseKey ( Key . ControlLeft ) ;
} ) ;
AddUntilStep ( "wait for player" , ( ) = > Stack . CurrentScreen is PlayerLoader ) ;
2022-09-08 13:49:43 +08:00
AddAssert ( "only autoplay selected" , ( ) = > songSelect ! . Mods . Value . Single ( ) is ModAutoplay ) ;
2020-02-03 15:04:32 +08:00
2022-09-08 13:49:43 +08:00
AddUntilStep ( "wait for return to ss" , ( ) = > songSelect ! . IsCurrentScreen ( ) ) ;
2020-02-03 15:04:32 +08:00
2022-09-08 13:49:43 +08:00
AddAssert ( "relax returned" , ( ) = > songSelect ! . Mods . Value . Single ( ) is ModRelax ) ;
2020-02-03 15:04:32 +08:00
}
2019-06-12 15:45:29 +08:00
[Test]
public void TestHideSetSelectsCorrectBeatmap ( )
{
2021-11-22 13:26:51 +08:00
Guid ? previousID = null ;
2019-06-12 15:45:29 +08:00
createSongSelect ( ) ;
addRulesetImportStep ( 0 ) ;
2022-09-08 13:49:43 +08:00
AddStep ( "Move to last difficulty" , ( ) = > songSelect ! . Carousel . SelectBeatmap ( songSelect ! . Carousel . BeatmapSets . First ( ) . Beatmaps . Last ( ) ) ) ;
AddStep ( "Store current ID" , ( ) = > previousID = songSelect ! . Carousel . SelectedBeatmapInfo ! . ID ) ;
AddStep ( "Hide first beatmap" , ( ) = > manager . Hide ( songSelect ! . Carousel . SelectedBeatmapSet ! . Beatmaps . First ( ) ) ) ;
AddAssert ( "Selected beatmap has not changed" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . ID = = previousID ) ;
2019-06-12 15:45:29 +08:00
}
2020-02-15 09:23:24 +08:00
[Test]
public void TestDifficultyIconSelecting ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
2022-03-09 00:18:53 +08:00
AddUntilStep ( "wait for selection" , ( ) = > ! Beatmap . IsDefault ) ;
2022-09-08 13:49:43 +08:00
DrawableCarouselBeatmapSet set = null ! ;
2020-02-16 09:51:55 +08:00
AddStep ( "Find the DrawableCarouselBeatmapSet" , ( ) = >
{
2022-09-08 13:49:43 +08:00
set = songSelect ! . Carousel . ChildrenOfType < DrawableCarouselBeatmapSet > ( ) . First ( ) ;
2020-02-16 09:51:55 +08:00
} ) ;
2022-09-08 13:49:43 +08:00
FilterableDifficultyIcon difficultyIcon = null ! ;
2021-10-12 21:07:57 +08:00
AddUntilStep ( "Find an icon" , ( ) = >
2020-02-16 09:51:55 +08:00
{
2022-09-08 13:49:43 +08:00
var foundIcon = set . ChildrenOfType < FilterableDifficultyIcon > ( )
. FirstOrDefault ( icon = > getDifficultyIconIndex ( set , icon ) ! = getCurrentBeatmapIndex ( ) ) ;
if ( foundIcon = = null )
return false ;
difficultyIcon = foundIcon ;
return true ;
2020-02-16 09:51:55 +08:00
} ) ;
2020-03-12 15:42:26 +08:00
2020-02-15 09:23:24 +08:00
AddStep ( "Click on a difficulty" , ( ) = >
{
2020-02-16 09:51:55 +08:00
InputManager . MoveMouseTo ( difficultyIcon ) ;
2020-02-15 09:23:24 +08:00
2020-11-05 22:41:56 +08:00
InputManager . Click ( MouseButton . Left ) ;
2020-02-15 09:23:24 +08:00
} ) ;
2020-03-12 15:42:26 +08:00
2020-02-16 09:51:55 +08:00
AddAssert ( "Selected beatmap correct" , ( ) = > getCurrentBeatmapIndex ( ) = = getDifficultyIconIndex ( set , difficultyIcon ) ) ;
2020-02-15 09:23:24 +08:00
2020-02-16 09:51:55 +08:00
double? maxBPM = null ;
2022-09-08 13:49:43 +08:00
AddStep ( "Filter some difficulties" , ( ) = > songSelect ! . Carousel . Filter ( new FilterCriteria
2020-02-15 09:23:24 +08:00
{
BPM = new FilterCriteria . OptionalRange < double >
{
2022-09-08 13:49:43 +08:00
Min = maxBPM = songSelect ! . Carousel . SelectedBeatmapSet ! . MaxBPM ,
2020-02-15 09:23:24 +08:00
IsLowerInclusive = true
}
} ) ) ;
2022-09-08 13:49:43 +08:00
BeatmapInfo ? filteredBeatmap = null ;
FilterableDifficultyIcon ? filteredIcon = null ;
2020-03-12 14:34:58 +08:00
2020-02-16 09:51:55 +08:00
AddStep ( "Get filtered icon" , ( ) = >
{
2022-09-08 13:49:43 +08:00
var selectedSet = songSelect ! . Carousel . SelectedBeatmapSet ;
Debug . Assert ( selectedSet ! = null ) ;
2022-01-11 14:40:18 +08:00
filteredBeatmap = selectedSet . Beatmaps . First ( b = > b . BPM < maxBPM ) ;
int filteredBeatmapIndex = getBeatmapIndex ( selectedSet , filteredBeatmap ) ;
2020-10-13 11:50:39 +08:00
filteredIcon = set . ChildrenOfType < FilterableDifficultyIcon > ( ) . ElementAt ( filteredBeatmapIndex ) ;
2020-02-16 09:51:55 +08:00
} ) ;
2020-02-15 09:23:24 +08:00
AddStep ( "Click on a filtered difficulty" , ( ) = >
{
2023-06-22 14:58:05 +08:00
Debug . Assert ( filteredIcon ! = null ) ;
2020-02-16 09:51:55 +08:00
InputManager . MoveMouseTo ( filteredIcon ) ;
2020-02-15 09:23:24 +08:00
2020-11-05 22:41:56 +08:00
InputManager . Click ( MouseButton . Left ) ;
2020-02-15 09:23:24 +08:00
} ) ;
2020-03-12 14:34:58 +08:00
2022-09-08 13:49:43 +08:00
AddAssert ( "Selected beatmap correct" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . Equals ( filteredBeatmap ) = = true ) ;
2020-02-15 09:23:24 +08:00
}
2020-03-12 15:42:26 +08:00
[Test]
2020-12-01 00:19:36 +08:00
public void TestChangingRulesetOnMultiRulesetBeatmap ( )
{
int changeCount = 0 ;
2021-03-17 15:10:16 +08:00
AddStep ( "change convert setting" , ( ) = > config . SetValue ( OsuSetting . ShowConvertedBeatmaps , false ) ) ;
2020-12-01 00:19:36 +08:00
AddStep ( "bind beatmap changed" , ( ) = >
{
Beatmap . ValueChanged + = onChange ;
changeCount = 0 ;
} ) ;
changeRuleset ( 0 ) ;
createSongSelect ( ) ;
AddStep ( "import multi-ruleset map" , ( ) = >
{
2021-11-22 13:26:24 +08:00
var usableRulesets = rulesets . AvailableRulesets . Where ( r = > r . OnlineID ! = 2 ) . ToArray ( ) ;
2022-01-25 14:23:51 +08:00
manager . Import ( TestResources . CreateTestBeatmapSetInfo ( 3 , usableRulesets ) ) ;
2020-12-01 00:19:36 +08:00
} ) ;
int previousSetID = 0 ;
AddUntilStep ( "wait for selection" , ( ) = > ! Beatmap . IsDefault ) ;
2021-11-15 17:46:11 +08:00
AddStep ( "record set ID" , ( ) = > previousSetID = ( ( IBeatmapSetInfo ) Beatmap . Value . BeatmapSetInfo ) . OnlineID ) ;
2020-12-01 00:19:36 +08:00
AddAssert ( "selection changed once" , ( ) = > changeCount = = 1 ) ;
2021-11-22 13:26:24 +08:00
AddAssert ( "Check ruleset is osu!" , ( ) = > Ruleset . Value . OnlineID = = 0 ) ;
2020-12-01 00:19:36 +08:00
changeRuleset ( 3 ) ;
2021-11-22 13:26:24 +08:00
AddUntilStep ( "Check ruleset changed to mania" , ( ) = > Ruleset . Value . OnlineID = = 3 ) ;
2020-12-01 00:19:36 +08:00
AddUntilStep ( "selection changed" , ( ) = > changeCount > 1 ) ;
2021-11-15 17:46:11 +08:00
AddAssert ( "Selected beatmap still same set" , ( ) = > Beatmap . Value . BeatmapSetInfo . OnlineID = = previousSetID ) ;
AddAssert ( "Selected beatmap is mania" , ( ) = > Beatmap . Value . BeatmapInfo . Ruleset . OnlineID = = 3 ) ;
2020-12-01 00:19:36 +08:00
AddAssert ( "selection changed only fired twice" , ( ) = > changeCount = = 2 ) ;
AddStep ( "unbind beatmap changed" , ( ) = > Beatmap . ValueChanged - = onChange ) ;
2021-03-17 15:10:16 +08:00
AddStep ( "change convert setting" , ( ) = > config . SetValue ( OsuSetting . ShowConvertedBeatmaps , true ) ) ;
2020-12-01 00:19:36 +08:00
2020-12-01 00:37:53 +08:00
// ReSharper disable once AccessToModifiedClosure
2020-12-01 00:19:36 +08:00
void onChange ( ValueChangedEvent < WorkingBeatmap > valueChangedEvent ) = > changeCount + + ;
}
[Test]
2020-03-12 15:42:26 +08:00
public void TestDifficultyIconSelectingForDifferentRuleset ( )
{
changeRuleset ( 0 ) ;
createSongSelect ( ) ;
AddStep ( "import multi-ruleset map" , ( ) = >
{
2021-11-22 13:26:24 +08:00
var usableRulesets = rulesets . AvailableRulesets . Where ( r = > r . OnlineID ! = 2 ) . ToArray ( ) ;
2022-01-25 14:23:51 +08:00
manager . Import ( TestResources . CreateTestBeatmapSetInfo ( 3 , usableRulesets ) ) ;
2020-03-12 15:42:26 +08:00
} ) ;
2022-09-08 13:49:43 +08:00
DrawableCarouselBeatmapSet ? set = null ;
2020-03-12 15:42:26 +08:00
AddUntilStep ( "Find the DrawableCarouselBeatmapSet" , ( ) = >
{
2022-09-08 13:49:43 +08:00
set = songSelect ! . Carousel . ChildrenOfType < DrawableCarouselBeatmapSet > ( ) . FirstOrDefault ( ) ;
2020-03-12 15:42:26 +08:00
return set ! = null ;
} ) ;
2022-09-08 13:49:43 +08:00
FilterableDifficultyIcon ? difficultyIcon = null ;
2021-10-05 17:06:24 +08:00
AddUntilStep ( "Find an icon for different ruleset" , ( ) = >
2020-03-12 15:42:26 +08:00
{
2020-10-13 11:50:39 +08:00
difficultyIcon = set . ChildrenOfType < FilterableDifficultyIcon > ( )
2021-11-22 13:26:24 +08:00
. FirstOrDefault ( icon = > icon . Item . BeatmapInfo . Ruleset . OnlineID = = 3 ) ;
2021-10-05 17:06:24 +08:00
return difficultyIcon ! = null ;
2020-03-12 15:42:26 +08:00
} ) ;
2021-11-22 13:26:24 +08:00
AddAssert ( "Check ruleset is osu!" , ( ) = > Ruleset . Value . OnlineID = = 0 ) ;
2020-03-12 15:42:26 +08:00
2020-03-16 10:30:53 +08:00
int previousSetID = 0 ;
2021-11-15 17:46:11 +08:00
AddStep ( "record set ID" , ( ) = > previousSetID = ( ( IBeatmapSetInfo ) Beatmap . Value . BeatmapSetInfo ) . OnlineID ) ;
2020-03-16 10:30:53 +08:00
2020-03-12 15:42:26 +08:00
AddStep ( "Click on a difficulty" , ( ) = >
{
2023-06-22 14:58:05 +08:00
Debug . Assert ( difficultyIcon ! = null ) ;
2020-03-12 15:42:26 +08:00
InputManager . MoveMouseTo ( difficultyIcon ) ;
2020-11-05 22:41:56 +08:00
InputManager . Click ( MouseButton . Left ) ;
2020-03-12 15:42:26 +08:00
} ) ;
2021-11-22 13:26:24 +08:00
AddUntilStep ( "Check ruleset changed to mania" , ( ) = > Ruleset . Value . OnlineID = = 3 ) ;
2020-03-16 10:30:53 +08:00
2022-09-08 13:49:43 +08:00
AddAssert ( "Selected beatmap still same set" , ( ) = > songSelect ! . Carousel . SelectedBeatmapInfo ? . BeatmapSet ? . OnlineID = = previousSetID ) ;
2021-11-15 17:46:11 +08:00
AddAssert ( "Selected beatmap is mania" , ( ) = > Beatmap . Value . BeatmapInfo . Ruleset . OnlineID = = 3 ) ;
2020-03-12 15:42:26 +08:00
}
2020-03-12 15:30:21 +08:00
[Test]
public void TestGroupedDifficultyIconSelecting ( )
{
changeRuleset ( 0 ) ;
createSongSelect ( ) ;
2022-09-08 13:49:43 +08:00
BeatmapSetInfo ? imported = null ;
2020-03-12 18:46:21 +08:00
2020-03-12 15:30:21 +08:00
AddStep ( "import huge difficulty count map" , ( ) = >
{
2021-11-22 13:26:24 +08:00
var usableRulesets = rulesets . AvailableRulesets . Where ( r = > r . OnlineID ! = 2 ) . ToArray ( ) ;
2022-01-25 14:23:51 +08:00
imported = manager . Import ( TestResources . CreateTestBeatmapSetInfo ( 50 , usableRulesets ) ) ? . Value ;
2020-03-12 15:30:21 +08:00
} ) ;
2022-09-08 13:49:43 +08:00
AddStep ( "select the first beatmap of import" , ( ) = > Beatmap . Value = manager . GetWorkingBeatmap ( imported ? . Beatmaps . First ( ) ) ) ;
2020-03-12 18:46:21 +08:00
2022-09-08 13:49:43 +08:00
DrawableCarouselBeatmapSet ? set = null ;
2020-03-12 15:30:21 +08:00
AddUntilStep ( "Find the DrawableCarouselBeatmapSet" , ( ) = >
{
2022-09-08 13:49:43 +08:00
set = songSelect ! . Carousel . ChildrenOfType < DrawableCarouselBeatmapSet > ( ) . FirstOrDefault ( ) ;
2020-03-12 15:30:21 +08:00
return set ! = null ;
} ) ;
2022-09-08 13:49:43 +08:00
GroupedDifficultyIcon groupIcon = null ! ;
2021-10-12 21:07:57 +08:00
AddUntilStep ( "Find group icon for different ruleset" , ( ) = >
2020-03-12 15:30:21 +08:00
{
2022-09-08 13:49:43 +08:00
var foundIcon = set . ChildrenOfType < GroupedDifficultyIcon > ( )
. FirstOrDefault ( icon = > icon . Items . First ( ) . BeatmapInfo . Ruleset . OnlineID = = 3 ) ;
if ( foundIcon = = null )
return false ;
groupIcon = foundIcon ;
return true ;
2020-03-12 15:30:21 +08:00
} ) ;
2021-11-22 13:26:24 +08:00
AddAssert ( "Check ruleset is osu!" , ( ) = > Ruleset . Value . OnlineID = = 0 ) ;
2020-03-12 15:30:21 +08:00
AddStep ( "Click on group" , ( ) = >
{
InputManager . MoveMouseTo ( groupIcon ) ;
2020-11-05 22:41:56 +08:00
InputManager . Click ( MouseButton . Left ) ;
2020-03-12 15:30:21 +08:00
} ) ;
2021-11-22 13:26:24 +08:00
AddUntilStep ( "Check ruleset changed to mania" , ( ) = > Ruleset . Value . OnlineID = = 3 ) ;
2020-03-12 15:30:21 +08:00
2021-11-15 17:46:11 +08:00
AddAssert ( "Check first item in group selected" , ( ) = > Beatmap . Value . BeatmapInfo . MatchesOnlineID ( groupIcon . Items . First ( ) . BeatmapInfo ) ) ;
2020-03-12 15:30:21 +08:00
}
2020-05-04 12:31:49 +08:00
[Test]
public void TestChangeRulesetWhilePresentingScore ( )
{
2022-01-27 14:19:48 +08:00
BeatmapInfo getPresentBeatmap ( ) = > manager . GetAllUsableBeatmapSets ( ) . Where ( s = > ! s . DeletePending ) . SelectMany ( s = > s . Beatmaps ) . First ( b = > b . Ruleset . OnlineID = = 0 ) ;
BeatmapInfo getSwitchBeatmap ( ) = > manager . GetAllUsableBeatmapSets ( ) . Where ( s = > ! s . DeletePending ) . SelectMany ( s = > s . Beatmaps ) . First ( b = > b . Ruleset . OnlineID = = 1 ) ;
2020-05-04 14:19:36 +08:00
2020-05-04 12:31:49 +08:00
changeRuleset ( 0 ) ;
createSongSelect ( ) ;
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 1 ) ;
AddStep ( "present score" , ( ) = >
{
// this ruleset change should be overridden by the present.
2020-05-04 14:19:36 +08:00
Ruleset . Value = getSwitchBeatmap ( ) . Ruleset ;
2020-05-04 12:31:49 +08:00
2022-09-08 13:49:43 +08:00
songSelect ! . PresentScore ( new ScoreInfo
2020-05-04 12:31:49 +08:00
{
2021-11-04 17:02:44 +08:00
User = new APIUser { Username = "woo" } ,
2021-10-04 16:35:53 +08:00
BeatmapInfo = getPresentBeatmap ( ) ,
2020-05-04 14:19:36 +08:00
Ruleset = getPresentBeatmap ( ) . Ruleset
2020-05-04 12:31:49 +08:00
} ) ;
} ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2020-05-04 12:31:49 +08:00
2021-11-15 17:46:11 +08:00
AddAssert ( "check beatmap is correct for score" , ( ) = > Beatmap . Value . BeatmapInfo . MatchesOnlineID ( getPresentBeatmap ( ) ) ) ;
2021-11-22 13:26:24 +08:00
AddAssert ( "check ruleset is correct for score" , ( ) = > Ruleset . Value . OnlineID = = 0 ) ;
2020-05-04 12:31:49 +08:00
}
[Test]
public void TestChangeBeatmapWhilePresentingScore ( )
{
2022-01-27 14:19:48 +08:00
BeatmapInfo getPresentBeatmap ( ) = > manager . GetAllUsableBeatmapSets ( ) . Where ( s = > ! s . DeletePending ) . SelectMany ( s = > s . Beatmaps ) . First ( b = > b . Ruleset . OnlineID = = 0 ) ;
BeatmapInfo getSwitchBeatmap ( ) = > manager . GetAllUsableBeatmapSets ( ) . Where ( s = > ! s . DeletePending ) . SelectMany ( s = > s . Beatmaps ) . First ( b = > b . Ruleset . OnlineID = = 1 ) ;
2020-05-04 12:31:49 +08:00
2020-05-04 14:19:36 +08:00
changeRuleset ( 0 ) ;
2020-05-04 12:31:49 +08:00
addRulesetImportStep ( 0 ) ;
addRulesetImportStep ( 1 ) ;
2020-05-04 14:19:36 +08:00
createSongSelect ( ) ;
2022-03-09 00:18:53 +08:00
AddUntilStep ( "wait for selection" , ( ) = > ! Beatmap . IsDefault ) ;
2020-05-04 12:31:49 +08:00
AddStep ( "present score" , ( ) = >
{
// this beatmap change should be overridden by the present.
2020-05-04 14:19:36 +08:00
Beatmap . Value = manager . GetWorkingBeatmap ( getSwitchBeatmap ( ) ) ;
2020-05-04 12:31:49 +08:00
2022-09-08 13:49:43 +08:00
songSelect ! . PresentScore ( TestResources . CreateTestScoreInfo ( getPresentBeatmap ( ) ) ) ;
2020-05-04 12:31:49 +08:00
} ) ;
2023-07-07 09:09:24 +08:00
waitForDismissed ( ) ;
2020-05-04 12:31:49 +08:00
2021-11-15 17:46:11 +08:00
AddAssert ( "check beatmap is correct for score" , ( ) = > Beatmap . Value . BeatmapInfo . MatchesOnlineID ( getPresentBeatmap ( ) ) ) ;
2021-11-22 13:26:24 +08:00
AddAssert ( "check ruleset is correct for score" , ( ) = > Ruleset . Value . OnlineID = = 0 ) ;
2020-05-04 12:31:49 +08:00
}
2022-05-06 03:08:19 +08:00
[Test]
public void TestModOverlayToggling ( )
{
changeRuleset ( 0 ) ;
createSongSelect ( ) ;
AddStep ( "toggle mod overlay on" , ( ) = > InputManager . Key ( Key . F1 ) ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "mod overlay shown" , ( ) = > songSelect ! . ModSelect . State . Value = = Visibility . Visible ) ;
2022-05-06 03:08:19 +08:00
AddStep ( "toggle mod overlay off" , ( ) = > InputManager . Key ( Key . F1 ) ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "mod overlay hidden" , ( ) = > songSelect ! . ModSelect . State . Value = = Visibility . Hidden ) ;
2022-05-06 03:08:19 +08:00
}
2022-11-15 20:57:42 +08:00
[Test]
2022-11-17 08:57:27 +08:00
public void TestBeatmapOptionsDisabled ( )
2022-11-15 20:57:42 +08:00
{
createSongSelect ( ) ;
addRulesetImportStep ( 0 ) ;
2022-11-17 08:57:27 +08:00
AddAssert ( "options enabled" , ( ) = > songSelect . ChildrenOfType < FooterButtonOptions > ( ) . Single ( ) . Enabled . Value ) ;
2022-11-15 20:57:42 +08:00
AddStep ( "delete all beatmaps" , ( ) = > manager . Delete ( ) ) ;
2023-01-20 03:38:54 +08:00
AddUntilStep ( "wait for no beatmap" , ( ) = > Beatmap . IsDefault ) ;
2022-11-17 08:57:27 +08:00
AddAssert ( "options disabled" , ( ) = > ! songSelect . ChildrenOfType < FooterButtonOptions > ( ) . Single ( ) . Enabled . Value ) ;
2022-11-15 20:57:42 +08:00
}
2023-04-10 13:04:07 +08:00
[Test]
public void TestTextBoxBeatmapDifficultyCount ( )
{
createSongSelect ( ) ;
2023-04-18 11:59:41 +08:00
AddAssert ( "0 matching shown" , ( ) = > songSelect . ChildrenOfType < FilterControl > ( ) . Single ( ) . InformationalText = = "0 matches" ) ;
2023-04-10 13:04:07 +08:00
addRulesetImportStep ( 0 ) ;
2023-04-18 11:59:41 +08:00
AddAssert ( "3 matching shown" , ( ) = > songSelect . ChildrenOfType < FilterControl > ( ) . Single ( ) . InformationalText = = "3 matches" ) ;
2023-04-10 13:04:07 +08:00
AddStep ( "delete all beatmaps" , ( ) = > manager . Delete ( ) ) ;
AddUntilStep ( "wait for no beatmap" , ( ) = > Beatmap . IsDefault ) ;
2023-04-18 11:59:41 +08:00
AddAssert ( "0 matching shown" , ( ) = > songSelect . ChildrenOfType < FilterControl > ( ) . Single ( ) . InformationalText = = "0 matches" ) ;
2023-04-10 13:04:07 +08:00
}
2024-07-08 19:05:07 +08:00
[Test]
[Solo]
public void TestHardDeleteHandledCorrectly ( )
{
createSongSelect ( ) ;
addRulesetImportStep ( 0 ) ;
AddAssert ( "3 matching shown" , ( ) = > songSelect . ChildrenOfType < FilterControl > ( ) . Single ( ) . InformationalText = = "3 matches" ) ;
AddStep ( "hard delete beatmap" , ( ) = > Realm . Write ( r = > r . RemoveRange ( r . All < BeatmapSetInfo > ( ) . Where ( s = > ! s . Protected ) ) ) ) ;
AddUntilStep ( "0 matching shown" , ( ) = > songSelect . ChildrenOfType < FilterControl > ( ) . Single ( ) . InformationalText = = "0 matches" ) ;
}
2023-09-22 02:01:59 +08:00
[Test]
public void TestDeleteHotkey ( )
{
createSongSelect ( ) ;
addRulesetImportStep ( 0 ) ;
AddAssert ( "3 matching shown" , ( ) = > songSelect . ChildrenOfType < FilterControl > ( ) . Single ( ) . InformationalText = = "3 matches" ) ;
AddStep ( "press shift-delete" , ( ) = >
{
InputManager . PressKey ( Key . ShiftLeft ) ;
InputManager . Key ( Key . Delete ) ;
InputManager . ReleaseKey ( Key . ShiftLeft ) ;
} ) ;
AddUntilStep ( "delete dialog shown" , ( ) = > DialogOverlay . CurrentDialog , Is . InstanceOf < BeatmapDeleteDialog > ) ;
AddStep ( "confirm deletion" , ( ) = > DialogOverlay . CurrentDialog ! . PerformAction < PopupDialogDangerousButton > ( ) ) ;
AddAssert ( "0 matching shown" , ( ) = > songSelect . ChildrenOfType < FilterControl > ( ) . Single ( ) . InformationalText = = "0 matches" ) ;
}
2023-10-28 18:13:13 +08:00
[Test]
public void TestCutInFilterTextBox ( )
{
createSongSelect ( ) ;
2023-12-13 13:42:32 +08:00
AddStep ( "set filter text" , ( ) = > songSelect ! . FilterControl . ChildrenOfType < FilterControl . FilterControlTextBox > ( ) . First ( ) . Text = "nonono" ) ;
2023-10-28 18:13:13 +08:00
AddStep ( "select all" , ( ) = > InputManager . Keys ( PlatformAction . SelectAll ) ) ;
AddStep ( "press ctrl-x" , ( ) = >
{
InputManager . PressKey ( Key . ControlLeft ) ;
InputManager . Key ( Key . X ) ;
InputManager . ReleaseKey ( Key . ControlLeft ) ;
} ) ;
2023-12-13 13:42:32 +08:00
AddAssert ( "filter text cleared" , ( ) = > songSelect ! . FilterControl . ChildrenOfType < FilterControl . FilterControlTextBox > ( ) . First ( ) . Text , ( ) = > Is . Empty ) ;
2023-10-28 18:13:13 +08:00
}
2024-04-15 20:07:08 +08:00
[Test]
public void TestNonFilterableModChange ( )
{
addRulesetImportStep ( 0 ) ;
createSongSelect ( ) ;
// Mod that is guaranteed to never re-filter.
AddStep ( "add non-filterable mod" , ( ) = > SelectedMods . Value = new Mod [ ] { new OsuModCinema ( ) } ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 0" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 0 ) ) ;
2024-04-15 20:07:08 +08:00
// Removing the mod should still not re-filter.
AddStep ( "remove non-filterable mod" , ( ) = > SelectedMods . Value = Array . Empty < Mod > ( ) ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 0" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 0 ) ) ;
2024-04-15 20:07:08 +08:00
}
[Test]
public void TestFilterableModChange ( )
{
addRulesetImportStep ( 3 ) ;
createSongSelect ( ) ;
// Change to mania ruleset.
AddStep ( "filter to mania ruleset" , ( ) = > Ruleset . Value = rulesets . AvailableRulesets . First ( r = > r . OnlineID = = 3 ) ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 2" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 1 ) ) ;
2024-04-15 20:07:08 +08:00
// Apply a mod, but this should NOT re-filter because there's no search text.
AddStep ( "add filterable mod" , ( ) = > SelectedMods . Value = new Mod [ ] { new ManiaModKey3 ( ) } ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 1" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 1 ) ) ;
2024-04-15 20:07:08 +08:00
// Set search text. Should re-filter.
AddStep ( "set search text to match mods" , ( ) = > songSelect ! . FilterControl . CurrentTextSearch . Value = "keys=3" ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 2" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 2 ) ) ;
2024-04-15 20:07:08 +08:00
// Change filterable mod. Should re-filter.
AddStep ( "change new filterable mod" , ( ) = > SelectedMods . Value = new Mod [ ] { new ManiaModKey5 ( ) } ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 3" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 3 ) ) ;
2024-04-15 20:07:08 +08:00
// Add non-filterable mod. Should NOT re-filter.
AddStep ( "apply non-filterable mod" , ( ) = > SelectedMods . Value = new Mod [ ] { new ManiaModNoFail ( ) , new ManiaModKey5 ( ) } ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 3" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 3 ) ) ;
2024-04-15 20:07:08 +08:00
// Remove filterable mod. Should re-filter.
AddStep ( "remove filterable mod" , ( ) = > SelectedMods . Value = new Mod [ ] { new ManiaModNoFail ( ) } ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 4" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 4 ) ) ;
2024-04-15 20:07:08 +08:00
// Remove non-filterable mod. Should NOT re-filter.
AddStep ( "remove filterable mod" , ( ) = > SelectedMods . Value = Array . Empty < Mod > ( ) ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 4" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 4 ) ) ;
2024-04-15 20:07:08 +08:00
// Add filterable mod. Should re-filter.
AddStep ( "add filterable mod" , ( ) = > SelectedMods . Value = new Mod [ ] { new ManiaModKey3 ( ) } ) ;
2024-08-28 19:14:33 +08:00
AddAssert ( "filter count is 5" , ( ) = > songSelect ! . FilterCount , ( ) = > Is . EqualTo ( 5 ) ) ;
2024-04-15 20:07:08 +08:00
}
2020-05-04 13:43:47 +08:00
private void waitForInitialSelection ( )
{
AddUntilStep ( "wait for initial selection" , ( ) = > ! Beatmap . IsDefault ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "wait for difficulty panels visible" , ( ) = > songSelect ! . Carousel . ChildrenOfType < DrawableCarouselBeatmap > ( ) . Any ( ) ) ;
2020-05-04 13:43:47 +08:00
}
2021-11-22 16:15:26 +08:00
private int getBeatmapIndex ( BeatmapSetInfo set , BeatmapInfo info ) = > set . Beatmaps . IndexOf ( info ) ;
2020-02-16 09:51:55 +08:00
2022-09-08 13:49:43 +08:00
private NoResultsPlaceholder ? getPlaceholder ( ) = > songSelect ! . ChildrenOfType < NoResultsPlaceholder > ( ) . FirstOrDefault ( ) ;
2022-06-07 15:32:15 +08:00
2022-09-08 13:49:43 +08:00
private int getCurrentBeatmapIndex ( )
{
Debug . Assert ( songSelect ! . Carousel . SelectedBeatmapSet ! = null ) ;
Debug . Assert ( songSelect ! . Carousel . SelectedBeatmapInfo ! = null ) ;
return getBeatmapIndex ( songSelect ! . Carousel . SelectedBeatmapSet , songSelect ! . Carousel . SelectedBeatmapInfo ) ;
}
2020-02-16 09:51:55 +08:00
2020-10-13 11:50:39 +08:00
private int getDifficultyIconIndex ( DrawableCarouselBeatmapSet set , FilterableDifficultyIcon icon )
2020-02-16 09:51:55 +08:00
{
2020-10-13 11:50:39 +08:00
return set . ChildrenOfType < FilterableDifficultyIcon > ( ) . ToList ( ) . FindIndex ( i = > i = = icon ) ;
2020-02-16 09:51:55 +08:00
}
2022-01-27 18:35:04 +08:00
private void addRulesetImportStep ( int id )
{
2022-09-08 13:49:43 +08:00
Live < BeatmapSetInfo > ? imported = null ;
2022-01-27 18:35:04 +08:00
AddStep ( $"import test map for ruleset {id}" , ( ) = > imported = importForRuleset ( id ) ) ;
// This is specifically for cases where the add is happening post song select load.
// For cases where song select is null, the assertions are provided by the load checks.
2022-09-08 13:49:43 +08:00
AddUntilStep ( "wait for imported to arrive in carousel" , ( ) = > songSelect = = null | | songSelect ! . Carousel . BeatmapSets . Any ( s = > s . ID = = imported ? . ID ) ) ;
2022-01-27 18:35:04 +08:00
}
2019-06-12 15:45:29 +08:00
2022-09-08 13:49:43 +08:00
private Live < BeatmapSetInfo > ? importForRuleset ( int id ) = > manager . Import ( TestResources . CreateTestBeatmapSetInfo ( 3 , rulesets . AvailableRulesets . Where ( r = > r . OnlineID = = id ) . ToArray ( ) ) ) ;
2018-07-20 10:32:00 +08:00
2019-10-08 15:37:34 +08:00
private void checkMusicPlaying ( bool playing ) = >
AddUntilStep ( $"music {(playing ? "" : " not ")}playing" , ( ) = > music . IsPlaying = = playing ) ;
2019-12-13 20:45:38 +08:00
private void changeMods ( params Mod [ ] mods ) = > AddStep ( $"change mods to {string.Join(" , ", mods.Select(m => m.Acronym))}" , ( ) = > SelectedMods . Value = mods ) ;
2018-08-14 13:18:46 +08:00
2021-11-22 13:26:24 +08:00
private void changeRuleset ( int id ) = > AddStep ( $"change ruleset to {id}" , ( ) = > Ruleset . Value = rulesets . AvailableRulesets . First ( r = > r . OnlineID = = id ) ) ;
2018-07-20 10:32:00 +08:00
2019-02-15 20:50:40 +08:00
private void createSongSelect ( )
{
AddStep ( "create song select" , ( ) = > LoadScreen ( songSelect = new TestSongSelect ( ) ) ) ;
2022-09-08 13:49:43 +08:00
AddUntilStep ( "wait for present" , ( ) = > songSelect ! . IsCurrentScreen ( ) ) ;
AddUntilStep ( "wait for carousel loaded" , ( ) = > songSelect ! . Carousel . IsAlive ) ;
2019-02-15 20:50:40 +08:00
}
2021-12-20 18:24:40 +08:00
/// <summary>
/// Imports test beatmap sets to show in the carousel.
/// </summary>
/// <param name="difficultyCountPerSet">
/// The exact count of difficulties to create for each beatmap set.
/// A <see langword="null"/> value causes the count of difficulties to be selected randomly.
/// </param>
private void addManyTestMaps ( int? difficultyCountPerSet = null )
2018-07-18 11:58:45 +08:00
{
AddStep ( "import test maps" , ( ) = >
{
2021-11-22 13:26:24 +08:00
var usableRulesets = rulesets . AvailableRulesets . Where ( r = > r . OnlineID ! = 2 ) . ToArray ( ) ;
2018-07-18 11:58:45 +08:00
2021-12-20 16:09:08 +08:00
for ( int i = 0 ; i < 10 ; i + + )
2022-01-25 14:23:51 +08:00
manager . Import ( TestResources . CreateTestBeatmapSetInfo ( difficultyCountPerSet , usableRulesets ) ) ;
2018-07-18 11:58:45 +08:00
} ) ;
}
2019-10-15 15:14:06 +08:00
protected override void Dispose ( bool isDisposing )
{
base . Dispose ( isDisposing ) ;
2022-09-08 13:49:43 +08:00
if ( rulesets . IsNotNull ( ) )
rulesets . Dispose ( ) ;
2019-10-15 15:14:06 +08:00
}
2019-11-13 17:54:33 +08:00
2023-07-07 09:09:24 +08:00
private void waitForDismissed ( ) = > AddUntilStep ( "wait for not current" , ( ) = > ! songSelect . AsNonNull ( ) . IsCurrentScreen ( ) ) ;
2022-11-24 13:32:20 +08:00
private partial class TestSongSelect : PlaySongSelect
2019-11-13 17:54:33 +08:00
{
2022-09-08 13:49:43 +08:00
public Action ? StartRequested ;
2019-11-13 17:54:33 +08:00
2020-02-10 15:59:49 +08:00
public new FilterControl FilterControl = > base . FilterControl ;
2019-11-13 17:54:33 +08:00
public WorkingBeatmap CurrentBeatmap = > Beatmap . Value ;
2021-11-15 17:46:11 +08:00
public IWorkingBeatmap CurrentBeatmapDetailsBeatmap = > BeatmapDetails . Beatmap ;
2019-11-13 17:54:33 +08:00
public new BeatmapCarousel Carousel = > base . Carousel ;
2022-05-11 04:29:57 +08:00
public new ModSelectOverlay ModSelect = > base . ModSelect ;
2019-11-13 17:54:33 +08:00
2020-05-04 12:31:49 +08:00
public new void PresentScore ( ScoreInfo score ) = > base . PresentScore ( score ) ;
2024-08-28 17:56:09 +08:00
public int FilterCount ;
2019-11-13 17:54:33 +08:00
protected override bool OnStart ( )
{
StartRequested ? . Invoke ( ) ;
return base . OnStart ( ) ;
}
2024-08-28 17:56:09 +08:00
[BackgroundDependencyLoader]
private void load ( )
2019-11-13 17:54:33 +08:00
{
2024-08-28 17:56:09 +08:00
FilterControl . FilterChanged + = _ = > FilterCount + + ;
2019-11-13 17:54:33 +08:00
}
}
2018-04-13 17:19:50 +08:00
}
}