Skip to content

Commit

Permalink
Merge pull request #31764 from peppy/beatmap-carousel-v2-grouping
Browse files Browse the repository at this point in the history
Add group support to beatmap carousel v2
  • Loading branch information
bdach authored Feb 4, 2025
2 parents 1e1fb54 + e454fa5 commit 6e59cab
Show file tree
Hide file tree
Showing 10 changed files with 631 additions and 195 deletions.
52 changes: 50 additions & 2 deletions osu.Game.Tests/Visual/SongSelect/BeatmapCarouselV2TestScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using osu.Game.Tests.Beatmaps;
using osu.Game.Tests.Resources;
using osuTK.Graphics;
using osuTK.Input;
using BeatmapCarousel = osu.Game.Screens.SelectV2.BeatmapCarousel;

namespace osu.Game.Tests.Visual.SongSelect
Expand Down Expand Up @@ -53,7 +54,7 @@ protected BeatmapCarouselV2TestScene()
}

[SetUpSteps]
public void SetUpSteps()
public virtual void SetUpSteps()
{
RemoveAllBeatmaps();

Expand Down Expand Up @@ -129,12 +130,59 @@ protected void CreateCarousel()
});
}

protected void SortBy(FilterCriteria criteria) => AddStep($"sort by {criteria.Sort}", () => Carousel.Filter(criteria));
protected void SortBy(FilterCriteria criteria) => AddStep($"sort {criteria.Sort} group {criteria.Group}", () => Carousel.Filter(criteria));

protected void WaitForDrawablePanels() => AddUntilStep("drawable panels loaded", () => Carousel.ChildrenOfType<ICarouselPanel>().Count(), () => Is.GreaterThan(0));
protected void WaitForSorting() => AddUntilStep("sorting finished", () => Carousel.IsFiltering, () => Is.False);
protected void WaitForScrolling() => AddUntilStep("scroll finished", () => Scroll.Current, () => Is.EqualTo(Scroll.Target));

protected void SelectNextPanel() => AddStep("select next panel", () => InputManager.Key(Key.Down));
protected void SelectPrevPanel() => AddStep("select prev panel", () => InputManager.Key(Key.Up));
protected void SelectNextGroup() => AddStep("select next group", () => InputManager.Key(Key.Right));
protected void SelectPrevGroup() => AddStep("select prev group", () => InputManager.Key(Key.Left));

protected void Select() => AddStep("select", () => InputManager.Key(Key.Enter));

protected void CheckNoSelection() => AddAssert("has no selection", () => Carousel.CurrentSelection, () => Is.Null);
protected void CheckHasSelection() => AddAssert("has selection", () => Carousel.CurrentSelection, () => Is.Not.Null);

protected void WaitForGroupSelection(int group, int panel)
{
AddUntilStep($"selected is group{group} panel{panel}", () =>
{
var groupingFilter = Carousel.Filters.OfType<BeatmapCarouselFilterGrouping>().Single();

GroupDefinition g = groupingFilter.GroupItems.Keys.ElementAt(group);
CarouselItem item = groupingFilter.GroupItems[g].ElementAt(panel);

return ReferenceEquals(Carousel.CurrentSelection, item.Model);
});
}

protected void WaitForSelection(int set, int? diff = null)
{
AddUntilStep($"selected is set{set}{(diff.HasValue ? $" diff{diff.Value}" : "")}", () =>
{
if (diff != null)
return ReferenceEquals(Carousel.CurrentSelection, BeatmapSets[set].Beatmaps[diff.Value]);

return BeatmapSets[set].Beatmaps.Contains(Carousel.CurrentSelection);
});
}

protected void ClickVisiblePanel<T>(int index)
where T : Drawable
{
AddStep($"click panel at index {index}", () =>
{
Carousel.ChildrenOfType<T>()
.Where(p => ((ICarouselPanel)p).Item?.IsVisible == true)
.Reverse()
.ElementAt(index)
.TriggerClick();
});
}

/// <summary>
/// Add requested beatmap sets count to list.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ public void TestBasics()
RemoveAllBeatmaps();
}

[Test]
public void TestOffScreenLoading()
{
AddStep("disable masking", () => Scroll.Masking = false);
AddStep("enable masking", () => Scroll.Masking = true);
}

[Test]
public void TestAddRemoveOneByOne()
{
Expand All @@ -43,7 +50,7 @@ public void TestAddRemoveOneByOne()
public void TestSorting()
{
AddBeatmaps(10);
SortBy(new FilterCriteria { Sort = SortMode.Difficulty });
SortBy(new FilterCriteria { Group = GroupMode.Difficulty, Sort = SortMode.Difficulty });
SortBy(new FilterCriteria { Sort = SortMode.Artist });
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
using osu.Game.Screens.SelectV2;

namespace osu.Game.Tests.Visual.SongSelect
{
[TestFixture]
public partial class TestSceneBeatmapCarouselV2GroupSelection : BeatmapCarouselV2TestScene
{
public override void SetUpSteps()
{
RemoveAllBeatmaps();

CreateCarousel();

SortBy(new FilterCriteria { Group = GroupMode.Difficulty, Sort = SortMode.Difficulty });
}

[Test]
public void TestOpenCloseGroupWithNoSelection()
{
AddBeatmaps(10, 5);
WaitForDrawablePanels();

AddAssert("no beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.Zero);
CheckNoSelection();

ClickVisiblePanel<GroupPanel>(0);
AddUntilStep("some beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.GreaterThan(0));
CheckNoSelection();

ClickVisiblePanel<GroupPanel>(0);
AddUntilStep("no beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.Zero);
CheckNoSelection();
}

[Test]
public void TestCarouselRemembersSelection()
{
AddBeatmaps(10);
WaitForDrawablePanels();

SelectNextGroup();

object? selection = null;

AddStep("store drawable selection", () => selection = getSelectedPanel()?.Item?.Model);

CheckHasSelection();
AddAssert("drawable selection non-null", () => selection, () => Is.Not.Null);
AddAssert("drawable selection matches carousel selection", () => selection, () => Is.EqualTo(Carousel.CurrentSelection));

RemoveAllBeatmaps();
AddUntilStep("no drawable selection", getSelectedPanel, () => Is.Null);

AddBeatmaps(10);
WaitForDrawablePanels();

CheckHasSelection();
AddAssert("no drawable selection", getSelectedPanel, () => Is.Null);

AddStep("add previous selection", () => BeatmapSets.Add(((BeatmapInfo)selection!).BeatmapSet!));

AddAssert("selection matches original carousel selection", () => selection, () => Is.EqualTo(Carousel.CurrentSelection));
AddUntilStep("drawable selection restored", () => getSelectedPanel()?.Item?.Model, () => Is.EqualTo(selection));
AddAssert("carousel item is visible", () => getSelectedPanel()?.Item?.IsVisible, () => Is.True);

ClickVisiblePanel<GroupPanel>(0);
AddUntilStep("carousel item not visible", getSelectedPanel, () => Is.Null);

ClickVisiblePanel<GroupPanel>(0);
AddUntilStep("carousel item is visible", () => getSelectedPanel()?.Item?.IsVisible, () => Is.True);

Check failure on line 79 in osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarouselV2GroupSelection.cs

View workflow job for this annotation

GitHub Actions / Results

osu.Game.Tests.Visual.SongSelect.TestSceneBeatmapCarouselV2GroupSelection ► TestCarouselRemembersSelection

Failed test found in: TestResults-Linux-MultiThreaded.trx TestResults-Linux-MultiThreaded.trx TestResults-Linux-SingleThread.trx TestResults-Linux-SingleThread.trx Error: "carousel item is visible" timed out: Expected: True But was: null
Raw output
"carousel item is visible" timed out: Expected: True
  But was:  null

   at osu.Game.Tests.Visual.SongSelect.TestSceneBeatmapCarouselV2GroupSelection.TestCarouselRemembersSelection() in /home/runner/work/osu/osu/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarouselV2GroupSelection.cs:line 79


BeatmapPanel? getSelectedPanel() => Carousel.ChildrenOfType<BeatmapPanel>().SingleOrDefault(p => p.Selected.Value);
}

[Test]
public void TestGroupSelectionOnHeader()
{
AddBeatmaps(10, 3);
WaitForDrawablePanels();

SelectNextGroup();
WaitForGroupSelection(0, 0);

SelectPrevPanel();
SelectPrevGroup();
WaitForGroupSelection(2, 9);
}

[Test]
public void TestKeyboardSelection()
{
AddBeatmaps(10, 3);
WaitForDrawablePanels();

SelectNextPanel();
SelectNextPanel();
SelectNextPanel();
SelectNextPanel();
CheckNoSelection();

// open first group
Select();
CheckNoSelection();
AddUntilStep("some beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.GreaterThan(0));

SelectNextPanel();
Select();
WaitForGroupSelection(0, 0);

SelectNextGroup();
WaitForGroupSelection(0, 1);

SelectNextGroup();
WaitForGroupSelection(0, 2);

SelectPrevGroup();
WaitForGroupSelection(0, 1);

SelectPrevGroup();
WaitForGroupSelection(0, 0);

SelectPrevGroup();
WaitForGroupSelection(2, 9);
}
}
}
Loading

0 comments on commit 6e59cab

Please sign in to comment.