osu/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs

235 lines
8.6 KiB
C#
Raw Normal View History

2017-12-13 10:56:16 +00:00
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
2017-12-13 10:56:16 +00:00
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel;
namespace osu.Game.Tests.Visual
{
internal class TestCaseBeatmapCarousel : OsuTestCase
{
2017-12-13 12:08:12 +00:00
private TestBeatmapCarousel carousel;
2017-12-13 10:56:16 +00:00
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(CarouselItem),
typeof(CarouselGroup),
typeof(CarouselGroupEagerSelect),
typeof(CarouselBeatmap),
typeof(CarouselBeatmapSet),
typeof(DrawableCarouselItem),
typeof(CarouselItemState),
typeof(DrawableCarouselBeatmap),
typeof(DrawableCarouselBeatmapSet),
};
[BackgroundDependencyLoader]
private void load()
{
2017-12-13 12:08:12 +00:00
Add(carousel = new TestBeatmapCarousel
2017-12-13 10:56:16 +00:00
{
RelativeSizeAxes = Axes.Both,
});
AddStep("Load Beatmaps", () =>
{
carousel.BeatmapSets = new[]
2017-12-13 10:56:16 +00:00
{
createTestBeatmapSet(1),
createTestBeatmapSet(2),
createTestBeatmapSet(3),
2017-12-13 12:08:12 +00:00
createTestBeatmapSet(4),
2017-12-13 10:56:16 +00:00
};
});
2017-12-13 12:08:12 +00:00
void checkSelected(int set, int diff) =>
AddAssert($"selected is set{set} diff{diff}", () =>
carousel.SelectedBeatmap == carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Skip(diff - 1).First());
2017-12-13 12:08:12 +00:00
2017-12-13 12:24:33 +00:00
void setSelected(int set, int diff) =>
AddStep($"select set{set} diff{diff}", () =>
carousel.SelectBeatmap(carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Skip(diff - 1).First()));
2017-12-13 12:24:33 +00:00
2017-12-13 12:08:12 +00:00
void advanceSelection(bool diff, int direction = 1, int count = 1)
{
if (count == 1)
AddStep($"select {(direction > 0 ? "next" : "prev")} {(diff ? "diff" : "set")}", () =>
carousel.SelectNext(direction, !diff));
else
{
AddRepeatStep($"select {(direction > 0 ? "next" : "prev")} {(diff ? "diff" : "set")}", () =>
carousel.SelectNext(direction, !diff), count);
}
}
void checkVisibleItemCount(bool diff, int count) =>
AddAssert($"{count} {(diff ? "diff" : "set")} visible", () =>
carousel.Items.Count(s => (diff ? s.Item is CarouselBeatmap : s.Item is CarouselBeatmapSet) && s.Item.Visible) == count);
AddUntilStep(() => carousel.BeatmapSets.Any(), "Wait for load");
2017-12-13 10:56:16 +00:00
// test traversal
2017-12-13 12:08:12 +00:00
advanceSelection(direction: 1, diff: false);
checkSelected(1, 1);
advanceSelection(direction: 1, diff: true);
checkSelected(1, 2);
2017-12-13 10:56:16 +00:00
2017-12-13 12:08:12 +00:00
advanceSelection(direction: -1, diff: false);
checkSelected(4, 1);
2017-12-13 10:56:16 +00:00
2017-12-13 12:08:12 +00:00
advanceSelection(direction: -1, diff: true);
checkSelected(3, 3);
2017-12-13 10:56:16 +00:00
2017-12-13 12:08:12 +00:00
advanceSelection(diff: false);
advanceSelection(diff: false);
checkSelected(1, 1);
2017-12-13 10:56:16 +00:00
2017-12-13 12:08:12 +00:00
advanceSelection(direction: -1, diff: true);
checkSelected(4, 3);
2017-12-13 10:56:16 +00:00
// test basic filtering
2017-12-13 12:08:12 +00:00
AddStep("Filter", () => carousel.Filter(new FilterCriteria { SearchText = "set #3" }, false));
checkVisibleItemCount(diff: false, count: 1);
checkVisibleItemCount(diff: true, count: 3);
checkSelected(3, 1);
2017-12-13 10:56:16 +00:00
2017-12-13 12:08:12 +00:00
advanceSelection(diff: true, count: 4);
checkSelected(3, 2);
AddStep("Un-filter (debounce)", () => carousel.Filter(new FilterCriteria()));
AddUntilStep(() => !carousel.PendingFilterTask, "Wait for debounce");
checkVisibleItemCount(diff: false, count: 4);
checkVisibleItemCount(diff: true, count: 3);
2017-12-13 12:24:33 +00:00
// test filtering some difficulties (and keeping current beatmap set selected).
setSelected(1, 2);
AddStep("Filter some difficulties", () => carousel.Filter(new FilterCriteria { SearchText = "Normal" }, false));
checkSelected(1, 1);
AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false));
checkSelected(1, 1);
// test random non-repeating algorithm
Stack<BeatmapSetInfo> selectedSets = new Stack<BeatmapSetInfo>();
void nextRandom() =>
AddStep("select random next", () =>
{
carousel.RandomAlgorithm.Value = RandomSelectAlgorithm.RandomPermutation;
if (!selectedSets.Any() && carousel.SelectedBeatmap != null)
selectedSets.Push(carousel.SelectedBeatmapSet);
carousel.SelectNextRandom();
selectedSets.Push(carousel.SelectedBeatmapSet);
});
void ensureRandomDidntRepeat() =>
AddAssert("ensure no repeats", () => selectedSets.Distinct().Count() == selectedSets.Count());
void prevRandom() => AddStep("select random last", () =>
{
carousel.SelectPreviousRandom();
selectedSets.Pop();
});
void ensureRandomFetchSuccess() =>
AddAssert("ensure prev random fetch worked", () => selectedSets.Peek() == carousel.SelectedBeatmapSet);
setSelected(1, 1);
nextRandom();
ensureRandomDidntRepeat();
nextRandom();
ensureRandomDidntRepeat();
nextRandom();
ensureRandomDidntRepeat();
prevRandom();
ensureRandomFetchSuccess();
prevRandom();
ensureRandomFetchSuccess();
nextRandom();
ensureRandomDidntRepeat();
nextRandom();
ensureRandomDidntRepeat();
nextRandom();
AddAssert("ensure repeat", () => selectedSets.Contains(carousel.SelectedBeatmapSet));
2017-12-13 10:56:16 +00:00
}
private BeatmapSetInfo createTestBeatmapSet(int i)
{
return new BeatmapSetInfo
{
OnlineBeatmapSetID = 1234 + i,
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
Metadata = new BeatmapMetadata
{
OnlineBeatmapSetID = 1234 + i,
// Create random metadata, then we can check if sorting works based on these
2017-12-13 12:08:12 +00:00
Artist = "peppy",
Title = "test set #" + i,
AuthorString = "peppy"
2017-12-13 10:56:16 +00:00
},
Beatmaps = new List<BeatmapInfo>(new[]
{
new BeatmapInfo
{
OnlineBeatmapID = 1234 + i,
Path = "normal.osu",
Version = "Normal",
BaseDifficulty = new BeatmapDifficulty
{
OverallDifficulty = 3.5f,
}
},
new BeatmapInfo
{
OnlineBeatmapID = 1235 + i,
Path = "hard.osu",
Version = "Hard",
BaseDifficulty = new BeatmapDifficulty
{
OverallDifficulty = 5,
}
},
new BeatmapInfo
{
OnlineBeatmapID = 1236 + i,
Path = "insane.osu",
Version = "Insane",
BaseDifficulty = new BeatmapDifficulty
{
OverallDifficulty = 7,
}
},
}),
};
}
2017-12-13 12:08:12 +00:00
private class TestBeatmapCarousel : BeatmapCarousel
{
public new List<DrawableCarouselItem> Items => base.Items;
public bool PendingFilterTask => FilterTask != null;
}
2017-12-13 10:56:16 +00:00
}
}