mirror of
https://github.com/ppy/osu.git
synced 2026-05-23 00:20:38 +08:00
Compare commits
459 Commits
@@ -38,7 +38,7 @@ jobs:
|
||||
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
|
||||
|
||||
- name: Test
|
||||
run: dotnet test $pwd/*.Tests/bin/Debug/*/*.Tests.dll --blame-crash --blame-hang --blame-hang-timeout 5m --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx"
|
||||
run: dotnet test $pwd/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx"
|
||||
shell: pwsh
|
||||
|
||||
# Attempt to upload results even if test fails.
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
|
||||
path: ${{github.workspace}}/TestResults/**/*
|
||||
path: ${{github.workspace}}/TestResults/TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx
|
||||
|
||||
build-only-android:
|
||||
name: Build only (Android)
|
||||
@@ -77,10 +77,6 @@ jobs:
|
||||
run: msbuild osu.Android/osu.Android.csproj /restore /p:Configuration=Debug
|
||||
|
||||
build-only-ios:
|
||||
# While this workflow technically *can* run, it fails as iOS builds are blocked by multiple issues.
|
||||
# See https://github.com/ppy/osu-framework/issues/4677 for the details.
|
||||
# The job can be unblocked once those issues are resolved and game deployments can happen again.
|
||||
if: false
|
||||
name: Build only (iOS)
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 60
|
||||
|
||||
Generated
+1
@@ -0,0 +1 @@
|
||||
osu.iOS
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="com.jetbrains.rider.android.RiderAndroidMiscFileCreationComponent">
|
||||
<option name="ENSURE_MISC_FILE_EXISTS" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RiderProjectSettingsUpdater">
|
||||
<option name="vcsConfiguration" value="2" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -8,4 +8,8 @@ M:osu.Framework.Graphics.Sprites.SpriteText.#ctor;Use OsuSpriteText.
|
||||
M:osu.Framework.Bindables.IBindableList`1.GetBoundCopy();Fails on iOS. Use manual ctor + BindTo instead. (see https://github.com/mono/mono/issues/19900)
|
||||
T:Microsoft.EntityFrameworkCore.Internal.EnumerableExtensions;Don't use internal extension methods.
|
||||
T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal extension methods.
|
||||
M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast<T>() instead.
|
||||
T:NuGet.Packaging.CollectionExtensions;Don't use internal extension methods.
|
||||
M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast<T>() instead.
|
||||
M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead.
|
||||
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IQueryable<T>,NotificationCallbackDelegate<T>) instead.
|
||||
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead.
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.EmptyFreeform
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
return new DifficultyAttributes(mods, skills, 0);
|
||||
return new DifficultyAttributes(mods, 0);
|
||||
}
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Pippidon
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
return new DifficultyAttributes(mods, skills, 0);
|
||||
return new DifficultyAttributes(mods, 0);
|
||||
}
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.EmptyScrolling
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
return new DifficultyAttributes(mods, skills, 0);
|
||||
return new DifficultyAttributes(mods, 0);
|
||||
}
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Pippidon
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
return new DifficultyAttributes(mods, skills, 0);
|
||||
return new DifficultyAttributes(mods, 0);
|
||||
}
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
|
||||
|
||||
+2
-2
@@ -52,10 +52,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1112.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1118.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1127.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||
<PackageReference Include="Realm" Version="10.6.0" />
|
||||
<PackageReference Include="Realm" Version="10.7.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -108,7 +108,10 @@ namespace osu.Desktop
|
||||
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.GlobalRank > 0 ? $" (rank #{user.Value.Statistics.GlobalRank:N0})" : string.Empty);
|
||||
|
||||
// update ruleset
|
||||
presence.Assets.SmallImageKey = ruleset.Value.ID <= 3 ? $"mode_{ruleset.Value.ID}" : "mode_custom";
|
||||
int onlineID = ruleset.Value.OnlineID;
|
||||
bool isLegacyRuleset = onlineID >= 0 && onlineID <= ILegacyRuleset.MAX_LEGACY_RULESET_ID;
|
||||
|
||||
presence.Assets.SmallImageKey = isLegacyRuleset ? $"mode_{onlineID}" : "mode_custom";
|
||||
presence.Assets.SmallImageText = ruleset.Value.Name;
|
||||
|
||||
client.SetPresence(presence);
|
||||
|
||||
@@ -103,7 +103,10 @@ namespace osu.Desktop.Updater
|
||||
}
|
||||
else
|
||||
{
|
||||
// In the case of an error, a separate notification will be displayed.
|
||||
notification.State = ProgressNotificationState.Cancelled;
|
||||
notification.Close();
|
||||
|
||||
Logger.Error(e, @"update failed!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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 osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||
@@ -9,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new CatchDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
return new CatchDifficultyAttributes { Mods = mods };
|
||||
|
||||
// this is the same as osu!, so there's potential to share the implementation... maybe
|
||||
double preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate;
|
||||
@@ -42,7 +42,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
Mods = mods,
|
||||
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
||||
MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)),
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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 osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests.iOS
|
||||
@@ -9,7 +10,7 @@ namespace osu.Game.Rulesets.Mania.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new ManiaDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
return new ManiaDifficultyAttributes { Mods = mods };
|
||||
|
||||
HitWindows hitWindows = new ManiaHitWindows();
|
||||
hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty);
|
||||
@@ -51,7 +51,6 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
||||
GreatHitWindow = Math.Ceiling(getHitWindow300(mods) / clockRate),
|
||||
ScoreMultiplier = getScoreMultiplier(mods),
|
||||
MaxCombo = beatmap.HitObjects.Sum(h => h is HoldNote ? 2 : 1),
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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 osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.iOS
|
||||
@@ -9,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new OsuDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
return new OsuDifficultyAttributes { Mods = mods };
|
||||
|
||||
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
|
||||
double aimRatingNoSliders = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
||||
@@ -85,7 +85,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
||||
HitCircleCount = hitCirclesCount,
|
||||
SliderCount = sliderCount,
|
||||
SpinnerCount = spinnerCount,
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// 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;
|
||||
@@ -26,12 +26,12 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
public BindableFloat Scale { get; } = new BindableFloat(4)
|
||||
{
|
||||
Precision = 0.1f,
|
||||
MinValue = 2,
|
||||
MinValue = 1.5f,
|
||||
MaxValue = 10,
|
||||
};
|
||||
|
||||
[SettingSource("Style", "Change the animation style of the approach circles.", 1)]
|
||||
public Bindable<AnimationStyle> Style { get; } = new Bindable<AnimationStyle>();
|
||||
public Bindable<AnimationStyle> Style { get; } = new Bindable<AnimationStyle>(AnimationStyle.Gravity);
|
||||
|
||||
public void ApplyToDrawableHitObject(DrawableHitObject drawable)
|
||||
{
|
||||
@@ -52,9 +52,18 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
default:
|
||||
case AnimationStyle.Linear:
|
||||
return Easing.None;
|
||||
|
||||
case AnimationStyle.Gravity:
|
||||
return Easing.InBack;
|
||||
|
||||
case AnimationStyle.InOut1:
|
||||
return Easing.InOutCubic;
|
||||
|
||||
case AnimationStyle.InOut2:
|
||||
return Easing.InOutQuint;
|
||||
|
||||
case AnimationStyle.Accelerate1:
|
||||
return Easing.In;
|
||||
|
||||
@@ -64,9 +73,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
case AnimationStyle.Accelerate3:
|
||||
return Easing.InQuint;
|
||||
|
||||
case AnimationStyle.Gravity:
|
||||
return Easing.InBack;
|
||||
|
||||
case AnimationStyle.Decelerate1:
|
||||
return Easing.Out;
|
||||
|
||||
@@ -76,16 +82,14 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
case AnimationStyle.Decelerate3:
|
||||
return Easing.OutQuint;
|
||||
|
||||
case AnimationStyle.InOut1:
|
||||
return Easing.InOutCubic;
|
||||
|
||||
case AnimationStyle.InOut2:
|
||||
return Easing.InOutQuint;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(style), style, @"Unsupported animation style");
|
||||
}
|
||||
}
|
||||
|
||||
public enum AnimationStyle
|
||||
{
|
||||
Linear,
|
||||
Gravity,
|
||||
InOut1,
|
||||
InOut2,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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 osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests.iOS
|
||||
@@ -9,7 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new TaikoDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
return new TaikoDifficultyAttributes { Mods = mods };
|
||||
|
||||
var colour = (Colour)skills[0];
|
||||
var rhythm = (Rhythm)skills[1];
|
||||
@@ -96,7 +96,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
ColourStrain = colourRating,
|
||||
GreatHitWindow = hitWindows.WindowFor(HitResult.Great) / clockRate,
|
||||
MaxCombo = beatmap.HitObjects.Count(h => h is Hit),
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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 osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Tests.iOS
|
||||
@@ -9,7 +10,7 @@ namespace osu.Game.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
{
|
||||
var score = decoder.Parse(resourceStream);
|
||||
|
||||
Assert.AreEqual(3, score.ScoreInfo.Ruleset.ID);
|
||||
Assert.AreEqual(3, score.ScoreInfo.Ruleset.OnlineID);
|
||||
|
||||
Assert.AreEqual(2, score.ScoreInfo.Statistics[HitResult.Great]);
|
||||
Assert.AreEqual(1, score.ScoreInfo.Statistics[HitResult.Good]);
|
||||
|
||||
@@ -16,6 +16,7 @@ using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
@@ -363,15 +364,15 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
var files = osu.Dependencies.Get<FileStore>();
|
||||
|
||||
long originalLength;
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.StoragePath))
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.GetStoragePath()))
|
||||
originalLength = stream.Length;
|
||||
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.StoragePath, FileAccess.Write, FileMode.Create))
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.GetStoragePath(), FileAccess.Write, FileMode.Create))
|
||||
stream.WriteByte(0);
|
||||
|
||||
var importedSecondTime = await LoadOszIntoOsu(osu);
|
||||
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.StoragePath))
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.GetStoragePath()))
|
||||
Assert.AreEqual(stream.Length, originalLength, "Corruption was not fixed on second import");
|
||||
|
||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||
@@ -583,7 +584,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
{
|
||||
OnlineID = 1,
|
||||
Metadata = metadata,
|
||||
Beatmaps = new List<BeatmapInfo>
|
||||
Beatmaps =
|
||||
{
|
||||
new BeatmapInfo
|
||||
{
|
||||
@@ -595,7 +596,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
{
|
||||
OnlineID = 2,
|
||||
Metadata = metadata,
|
||||
Status = BeatmapSetOnlineStatus.Loved,
|
||||
Status = BeatmapOnlineStatus.Loved,
|
||||
BaseDifficulty = difficulty
|
||||
}
|
||||
}
|
||||
@@ -1049,7 +1050,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
|
||||
private static void checkSingleReferencedFileCount(OsuGameBase osu, int expected)
|
||||
{
|
||||
Assert.AreEqual(expected, osu.Dependencies.Get<FileStore>().QueryFiles(f => f.ReferenceCount == 1).Count());
|
||||
Assert.AreEqual(expected, osu.Dependencies.Get<DatabaseContextFactory>().Get().FileInfo.Count(f => f.ReferenceCount == 1));
|
||||
}
|
||||
|
||||
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000)
|
||||
|
||||
@@ -100,8 +100,8 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestKeyEqualsWithDifferentModInstances()
|
||||
{
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||
|
||||
Assert.That(key1, Is.EqualTo(key2));
|
||||
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||
@@ -110,8 +110,8 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestKeyEqualsWithDifferentModOrder()
|
||||
{
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() });
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() });
|
||||
|
||||
Assert.That(key1, Is.EqualTo(key2));
|
||||
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||
@@ -120,8 +120,8 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestKeyDoesntEqualWithDifferentModSettings()
|
||||
{
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
||||
|
||||
Assert.That(key1, Is.Not.EqualTo(key2));
|
||||
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
|
||||
@@ -130,8 +130,8 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestKeyEqualWithMatchingModSettings()
|
||||
{
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||
|
||||
Assert.That(key1, Is.EqualTo(key2));
|
||||
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||
@@ -164,9 +164,9 @@ namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
public Func<DifficultyCacheLookup, StarDifficulty> ComputeDifficulty { get; set; }
|
||||
|
||||
protected override Task<StarDifficulty> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken token = default)
|
||||
protected override Task<StarDifficulty?> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken token = default)
|
||||
{
|
||||
return Task.FromResult(ComputeDifficulty?.Invoke(lookup) ?? new StarDifficulty(BASE_STARS, 0));
|
||||
return Task.FromResult<StarDifficulty?>(ComputeDifficulty?.Invoke(lookup) ?? new StarDifficulty(BASE_STARS, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
@@ -40,7 +41,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
loadStarted.Set();
|
||||
Assert.Throws<OperationCanceledException>(() => working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo, cancellationToken: cts.Token));
|
||||
Assert.Throws<OperationCanceledException>(() => working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>(), cts.Token));
|
||||
loadCompleted.Set();
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
|
||||
@@ -58,7 +59,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
var working = new TestNeverLoadsWorkingBeatmap();
|
||||
|
||||
Assert.Throws<OperationCanceledException>(() => working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo));
|
||||
Assert.Throws(Is.InstanceOf<TimeoutException>(), () => working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo));
|
||||
|
||||
working.ResetEvent.Set();
|
||||
}
|
||||
|
||||
@@ -12,8 +12,10 @@ using NUnit.Framework;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO.Archives;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
@@ -73,6 +75,24 @@ namespace osu.Game.Tests.Database
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAccessFileAfterImport()
|
||||
{
|
||||
RunTestWithRealmAsync(async (realmFactory, storage) =>
|
||||
{
|
||||
using var importer = new BeatmapImporter(realmFactory, storage);
|
||||
using var store = new RealmRulesetStore(realmFactory, storage);
|
||||
|
||||
var imported = await LoadOszIntoStore(importer, realmFactory.Context);
|
||||
|
||||
var beatmap = imported.Beatmaps.First();
|
||||
var file = beatmap.File;
|
||||
|
||||
Assert.NotNull(file);
|
||||
Assert.AreEqual(beatmap.Hash, file!.File.Hash);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestImportThenDelete()
|
||||
{
|
||||
@@ -348,15 +368,15 @@ namespace osu.Game.Tests.Database
|
||||
var firstFile = imported.Files.First();
|
||||
|
||||
long originalLength;
|
||||
using (var stream = storage.GetStream(firstFile.File.StoragePath))
|
||||
using (var stream = storage.GetStream(firstFile.File.GetStoragePath()))
|
||||
originalLength = stream.Length;
|
||||
|
||||
using (var stream = storage.GetStream(firstFile.File.StoragePath, FileAccess.Write, FileMode.Create))
|
||||
using (var stream = storage.GetStream(firstFile.File.GetStoragePath(), FileAccess.Write, FileMode.Create))
|
||||
stream.WriteByte(0);
|
||||
|
||||
var importedSecondTime = await LoadOszIntoStore(importer, realmFactory.Context);
|
||||
|
||||
using (var stream = storage.GetStream(firstFile.File.StoragePath))
|
||||
using (var stream = storage.GetStream(firstFile.File.GetStoragePath()))
|
||||
Assert.AreEqual(stream.Length, originalLength, "Corruption was not fixed on second import");
|
||||
|
||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||
@@ -455,7 +475,7 @@ namespace osu.Game.Tests.Database
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestImportThenDeleteThenImport()
|
||||
public void TestImportThenDeleteThenImportOptimisedPath()
|
||||
{
|
||||
RunTestWithRealmAsync(async (realmFactory, storage) =>
|
||||
{
|
||||
@@ -466,11 +486,39 @@ namespace osu.Game.Tests.Database
|
||||
|
||||
deleteBeatmapSet(imported, realmFactory.Context);
|
||||
|
||||
Assert.IsTrue(imported.DeletePending);
|
||||
|
||||
var importedSecondTime = await LoadOszIntoStore(importer, realmFactory.Context);
|
||||
|
||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||
Assert.IsTrue(imported.Beatmaps.First().ID == importedSecondTime.Beatmaps.First().ID);
|
||||
Assert.IsFalse(imported.DeletePending);
|
||||
Assert.IsFalse(importedSecondTime.DeletePending);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestImportThenDeleteThenImportNonOptimisedPath()
|
||||
{
|
||||
RunTestWithRealmAsync(async (realmFactory, storage) =>
|
||||
{
|
||||
using var importer = new NonOptimisedBeatmapImporter(realmFactory, storage);
|
||||
using var store = new RealmRulesetStore(realmFactory, storage);
|
||||
|
||||
var imported = await LoadOszIntoStore(importer, realmFactory.Context);
|
||||
|
||||
deleteBeatmapSet(imported, realmFactory.Context);
|
||||
|
||||
Assert.IsTrue(imported.DeletePending);
|
||||
|
||||
var importedSecondTime = await LoadOszIntoStore(importer, realmFactory.Context);
|
||||
|
||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||
Assert.IsTrue(imported.Beatmaps.First().ID == importedSecondTime.Beatmaps.First().ID);
|
||||
Assert.IsFalse(imported.DeletePending);
|
||||
Assert.IsFalse(importedSecondTime.DeletePending);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -531,7 +579,7 @@ namespace osu.Game.Tests.Database
|
||||
new RealmBeatmap(ruleset, new RealmBeatmapDifficulty(), metadata)
|
||||
{
|
||||
OnlineID = 2,
|
||||
Status = BeatmapSetOnlineStatus.Loved,
|
||||
Status = BeatmapOnlineStatus.Loved,
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -804,7 +852,11 @@ namespace osu.Game.Tests.Database
|
||||
{
|
||||
IQueryable<RealmBeatmapSet>? resultSets = null;
|
||||
|
||||
waitForOrAssert(() => (resultSets = realm.All<RealmBeatmapSet>().Where(s => !s.DeletePending && s.OnlineID == 241526)).Any(),
|
||||
waitForOrAssert(() =>
|
||||
{
|
||||
realm.Refresh();
|
||||
return (resultSets = realm.All<RealmBeatmapSet>().Where(s => !s.DeletePending && s.OnlineID == 241526)).Any();
|
||||
},
|
||||
@"BeatmapSet did not import to the database in allocated time.", timeout);
|
||||
|
||||
// ensure we were stored to beatmap database backing...
|
||||
@@ -817,16 +869,16 @@ namespace osu.Game.Tests.Database
|
||||
// ReSharper disable once PossibleUnintendedReferenceComparison
|
||||
IEnumerable<RealmBeatmap> queryBeatmaps() => realm.All<RealmBeatmap>().Where(s => s.BeatmapSet != null && s.BeatmapSet == set);
|
||||
|
||||
waitForOrAssert(() => queryBeatmaps().Count() == 12, @"Beatmaps did not import to the database in allocated time", timeout);
|
||||
waitForOrAssert(() => queryBeatmapSets().Count() == 1, @"BeatmapSet did not import to the database in allocated time", timeout);
|
||||
Assert.AreEqual(12, queryBeatmaps().Count(), @"Beatmap count was not correct");
|
||||
Assert.AreEqual(1, queryBeatmapSets().Count(), @"Beatmapset count was not correct");
|
||||
|
||||
int countBeatmapSetBeatmaps = 0;
|
||||
int countBeatmaps = 0;
|
||||
int countBeatmapSetBeatmaps;
|
||||
int countBeatmaps;
|
||||
|
||||
waitForOrAssert(() =>
|
||||
(countBeatmapSetBeatmaps = queryBeatmapSets().First().Beatmaps.Count) ==
|
||||
(countBeatmaps = queryBeatmaps().Count()),
|
||||
$@"Incorrect database beatmap count post-import ({countBeatmaps} but should be {countBeatmapSetBeatmaps}).", timeout);
|
||||
Assert.AreEqual(
|
||||
countBeatmapSetBeatmaps = queryBeatmapSets().First().Beatmaps.Count,
|
||||
countBeatmaps = queryBeatmaps().Count(),
|
||||
$@"Incorrect database beatmap count post-import ({countBeatmaps} but should be {countBeatmapSetBeatmaps}).");
|
||||
|
||||
foreach (RealmBeatmap b in set.Beatmaps)
|
||||
Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineID == b.OnlineID));
|
||||
@@ -848,5 +900,15 @@ namespace osu.Game.Tests.Database
|
||||
|
||||
Assert.Fail(failureMessage);
|
||||
}
|
||||
|
||||
public class NonOptimisedBeatmapImporter : BeatmapImporter
|
||||
{
|
||||
public NonOptimisedBeatmapImporter(RealmContextFactory realmFactory, Storage storage)
|
||||
: base(realmFactory, storage)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool HasCustomHashFunction => true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Stores;
|
||||
|
||||
@@ -28,7 +29,7 @@ namespace osu.Game.Tests.Database
|
||||
realm.Write(() => files.Add(testData, realm));
|
||||
|
||||
Assert.True(files.Storage.Exists("0/05/054edec1d0211f624fed0cbca9d4f9400b0e491c43742af2c5b0abebf0c990d8"));
|
||||
Assert.True(files.Storage.Exists(realm.All<RealmFile>().First().StoragePath));
|
||||
Assert.True(files.Storage.Exists(realm.All<RealmFile>().First().GetStoragePath()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -74,7 +75,7 @@ namespace osu.Game.Tests.Database
|
||||
|
||||
Logger.Log($"Import complete at {timer.ElapsedMilliseconds}");
|
||||
|
||||
string path = file.StoragePath;
|
||||
string path = file.GetStoragePath();
|
||||
|
||||
Assert.True(realm.All<RealmFile>().Any());
|
||||
Assert.True(files.Storage.Exists(path));
|
||||
@@ -98,7 +99,7 @@ namespace osu.Game.Tests.Database
|
||||
|
||||
var file = realm.Write(() => files.Add(new MemoryStream(new byte[] { 0, 1, 2, 3 }), realm));
|
||||
|
||||
string path = file.StoragePath;
|
||||
string path = file.GetStoragePath();
|
||||
|
||||
Assert.True(realm.All<RealmFile>().Any());
|
||||
Assert.True(files.Storage.Exists(path));
|
||||
|
||||
@@ -5,6 +5,8 @@ using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Models;
|
||||
|
||||
#nullable enable
|
||||
|
||||
@@ -33,6 +35,39 @@ namespace osu.Game.Tests.Database
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to ensure that a `CreateContext` call nested inside a subscription doesn't cause any deadlocks
|
||||
/// due to context fetching semaphores.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestNestedContextCreationWithSubscription()
|
||||
{
|
||||
RunTestWithRealm((realmFactory, _) =>
|
||||
{
|
||||
bool callbackRan = false;
|
||||
|
||||
using (var context = realmFactory.CreateContext())
|
||||
{
|
||||
var subscription = context.All<RealmBeatmap>().QueryAsyncWithNotifications((sender, changes, error) =>
|
||||
{
|
||||
using (realmFactory.CreateContext())
|
||||
{
|
||||
callbackRan = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Force the callback above to run.
|
||||
using (realmFactory.CreateContext())
|
||||
{
|
||||
}
|
||||
|
||||
subscription?.Dispose();
|
||||
}
|
||||
|
||||
Assert.IsTrue(callbackRan);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBlockOperationsWithContention()
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Models;
|
||||
using Realms;
|
||||
@@ -18,61 +17,57 @@ namespace osu.Game.Tests.Database
|
||||
public class RealmLiveTests : RealmTest
|
||||
{
|
||||
[Test]
|
||||
public void TestLiveCastability()
|
||||
public void TestLiveEquality()
|
||||
{
|
||||
RunTestWithRealm((realmFactory, _) =>
|
||||
{
|
||||
RealmLive<RealmBeatmap> beatmap = realmFactory.CreateContext().Write(r => r.Add(new RealmBeatmap(CreateRuleset(), new RealmBeatmapDifficulty(), new RealmBeatmapMetadata()))).ToLive();
|
||||
ILive<RealmBeatmap> beatmap = realmFactory.CreateContext().Write(r => r.Add(new RealmBeatmap(CreateRuleset(), new RealmBeatmapDifficulty(), new RealmBeatmapMetadata()))).ToLive();
|
||||
|
||||
ILive<IBeatmapInfo> iBeatmap = beatmap;
|
||||
ILive<RealmBeatmap> beatmap2 = realmFactory.CreateContext().All<RealmBeatmap>().First().ToLive();
|
||||
|
||||
Assert.AreEqual(0, iBeatmap.Value.Length);
|
||||
Assert.AreEqual(beatmap, beatmap2);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestValueAccessWithOpenContext()
|
||||
public void TestAccessAfterAttach()
|
||||
{
|
||||
RunTestWithRealm((realmFactory, _) =>
|
||||
{
|
||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
using (var threadContext = realmFactory.CreateContext())
|
||||
{
|
||||
var beatmap = threadContext.Write(r => r.Add(new RealmBeatmap(CreateRuleset(), new RealmBeatmapDifficulty(), new RealmBeatmapMetadata())));
|
||||
var beatmap = new RealmBeatmap(CreateRuleset(), new RealmBeatmapDifficulty(), new RealmBeatmapMetadata());
|
||||
|
||||
liveBeatmap = beatmap.ToLive();
|
||||
}
|
||||
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
|
||||
var liveBeatmap = beatmap.ToLive();
|
||||
|
||||
Debug.Assert(liveBeatmap != null);
|
||||
using (var context = realmFactory.CreateContext())
|
||||
context.Write(r => r.Add(beatmap));
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
Assert.DoesNotThrow(() =>
|
||||
{
|
||||
using (realmFactory.CreateContext())
|
||||
{
|
||||
var resolved = liveBeatmap.Value;
|
||||
|
||||
Assert.IsTrue(resolved.Realm.IsClosed);
|
||||
Assert.IsTrue(resolved.IsValid);
|
||||
|
||||
// can access properties without a crash.
|
||||
Assert.IsFalse(resolved.Hidden);
|
||||
}
|
||||
});
|
||||
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
|
||||
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAccessNonManaged()
|
||||
{
|
||||
var beatmap = new RealmBeatmap(CreateRuleset(), new RealmBeatmapDifficulty(), new RealmBeatmapMetadata());
|
||||
var liveBeatmap = beatmap.ToLive();
|
||||
|
||||
Assert.IsFalse(beatmap.Hidden);
|
||||
Assert.IsFalse(liveBeatmap.Value.Hidden);
|
||||
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => liveBeatmap.PerformWrite(l => l.Hidden = true));
|
||||
|
||||
Assert.IsFalse(beatmap.Hidden);
|
||||
Assert.IsFalse(liveBeatmap.Value.Hidden);
|
||||
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestScopedReadWithoutContext()
|
||||
{
|
||||
RunTestWithRealm((realmFactory, _) =>
|
||||
{
|
||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
||||
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
using (var threadContext = realmFactory.CreateContext())
|
||||
@@ -101,7 +96,7 @@ namespace osu.Game.Tests.Database
|
||||
{
|
||||
RunTestWithRealm((realmFactory, _) =>
|
||||
{
|
||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
||||
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
using (var threadContext = realmFactory.CreateContext())
|
||||
@@ -122,12 +117,66 @@ namespace osu.Game.Tests.Database
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestValueAccessNonManaged()
|
||||
{
|
||||
RunTestWithRealm((realmFactory, _) =>
|
||||
{
|
||||
var beatmap = new RealmBeatmap(CreateRuleset(), new RealmBeatmapDifficulty(), new RealmBeatmapMetadata());
|
||||
var liveBeatmap = beatmap.ToLive();
|
||||
|
||||
Assert.DoesNotThrow(() =>
|
||||
{
|
||||
var __ = liveBeatmap.Value;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestValueAccessWithOpenContextFails()
|
||||
{
|
||||
RunTestWithRealm((realmFactory, _) =>
|
||||
{
|
||||
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
using (var threadContext = realmFactory.CreateContext())
|
||||
{
|
||||
var beatmap = threadContext.Write(r => r.Add(new RealmBeatmap(CreateRuleset(), new RealmBeatmapDifficulty(), new RealmBeatmapMetadata())));
|
||||
|
||||
liveBeatmap = beatmap.ToLive();
|
||||
}
|
||||
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
|
||||
|
||||
Debug.Assert(liveBeatmap != null);
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
// Can't be used, without a valid context.
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
var __ = liveBeatmap.Value;
|
||||
});
|
||||
|
||||
// Can't be used, even from within a valid context.
|
||||
using (realmFactory.CreateContext())
|
||||
{
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
var __ = liveBeatmap.Value;
|
||||
});
|
||||
}
|
||||
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestValueAccessWithoutOpenContextFails()
|
||||
{
|
||||
RunTestWithRealm((realmFactory, _) =>
|
||||
{
|
||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
||||
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
using (var threadContext = realmFactory.CreateContext())
|
||||
@@ -159,8 +208,8 @@ namespace osu.Game.Tests.Database
|
||||
|
||||
using (var updateThreadContext = realmFactory.CreateContext())
|
||||
{
|
||||
updateThreadContext.All<RealmBeatmap>().SubscribeForNotifications(gotChange);
|
||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
||||
updateThreadContext.All<RealmBeatmap>().QueryAsyncWithNotifications(gotChange);
|
||||
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
@@ -183,23 +232,22 @@ namespace osu.Game.Tests.Database
|
||||
Assert.AreEqual(0, updateThreadContext.All<RealmBeatmap>().Count());
|
||||
Assert.AreEqual(0, changesTriggered);
|
||||
|
||||
var resolved = liveBeatmap.Value;
|
||||
|
||||
// retrieval causes an implicit refresh. even changes that aren't related to the retrieval are fired at this point.
|
||||
Assert.AreEqual(2, updateThreadContext.All<RealmBeatmap>().Count());
|
||||
Assert.AreEqual(1, changesTriggered);
|
||||
|
||||
// even though the realm that this instance was resolved for was closed, it's still valid.
|
||||
Assert.IsTrue(resolved.Realm.IsClosed);
|
||||
Assert.IsTrue(resolved.IsValid);
|
||||
|
||||
// can access properties without a crash.
|
||||
Assert.IsFalse(resolved.Hidden);
|
||||
|
||||
updateThreadContext.Write(r =>
|
||||
liveBeatmap.PerformRead(resolved =>
|
||||
{
|
||||
// can use with the main context.
|
||||
r.Remove(resolved);
|
||||
// retrieval causes an implicit refresh. even changes that aren't related to the retrieval are fired at this point.
|
||||
// ReSharper disable once AccessToDisposedClosure
|
||||
Assert.AreEqual(2, updateThreadContext.All<RealmBeatmap>().Count());
|
||||
Assert.AreEqual(1, changesTriggered);
|
||||
|
||||
// can access properties without a crash.
|
||||
Assert.IsFalse(resolved.Hidden);
|
||||
|
||||
// ReSharper disable once AccessToDisposedClosure
|
||||
updateThreadContext.Write(r =>
|
||||
{
|
||||
// can use with the main context.
|
||||
r.Remove(resolved);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
@@ -13,7 +12,6 @@ using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Storyboards;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Tests.Resources;
|
||||
using FileInfo = osu.Game.IO.FileInfo;
|
||||
|
||||
namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
@@ -33,14 +31,10 @@ namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
Files = new List<BeatmapSetFileInfo>(new[]
|
||||
Files =
|
||||
{
|
||||
new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = "abc123.mp4",
|
||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
||||
}
|
||||
})
|
||||
CheckTestHelpers.CreateMockFile("mp4"),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 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.Collections.Generic;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
@@ -12,7 +12,6 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Checks;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using FileInfo = osu.Game.IO.FileInfo;
|
||||
|
||||
namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
@@ -25,25 +24,17 @@ namespace osu.Game.Tests.Editing.Checks
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var file = CheckTestHelpers.CreateMockFile("jpg");
|
||||
|
||||
check = new CheckBackgroundQuality();
|
||||
beatmap = new Beatmap<HitObject>
|
||||
{
|
||||
BeatmapInfo = new BeatmapInfo
|
||||
{
|
||||
Metadata = new BeatmapMetadata { BackgroundFile = "abc123.jpg" },
|
||||
Metadata = new BeatmapMetadata { BackgroundFile = file.Filename },
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
Files = new List<BeatmapSetFileInfo>(new[]
|
||||
{
|
||||
new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = "abc123.jpg",
|
||||
FileInfo = new FileInfo
|
||||
{
|
||||
Hash = "abcdef"
|
||||
}
|
||||
}
|
||||
})
|
||||
Files = { file }
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -54,7 +45,7 @@ namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
// While this is a problem, it is out of scope for this check and is caught by a different one.
|
||||
beatmap.Metadata.BackgroundFile = string.Empty;
|
||||
var context = getContext(null, new MemoryStream(System.Array.Empty<byte>()));
|
||||
var context = getContext(null, new MemoryStream(Array.Empty<byte>()));
|
||||
|
||||
Assert.That(check.Run(context), Is.Empty);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Checks;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
@@ -22,22 +20,17 @@ namespace osu.Game.Tests.Editing.Checks
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var file = CheckTestHelpers.CreateMockFile("jpg");
|
||||
|
||||
check = new CheckBackgroundPresence();
|
||||
beatmap = new Beatmap<HitObject>
|
||||
{
|
||||
BeatmapInfo = new BeatmapInfo
|
||||
{
|
||||
Metadata = new BeatmapMetadata { BackgroundFile = "abc123.jpg" },
|
||||
Metadata = new BeatmapMetadata { BackgroundFile = file.Filename },
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
Files = new List<BeatmapSetFileInfo>(new[]
|
||||
{
|
||||
new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = "abc123.jpg",
|
||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
||||
}
|
||||
})
|
||||
Files = { file }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// 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 osu.Game.Beatmaps;
|
||||
using osu.Game.IO;
|
||||
|
||||
namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
public static class CheckTestHelpers
|
||||
{
|
||||
public static BeatmapSetFileInfo CreateMockFile(string extension) =>
|
||||
new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = $"abc123.{extension}",
|
||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ManagedBass;
|
||||
@@ -14,7 +13,6 @@ using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK.Audio;
|
||||
using FileInfo = osu.Game.IO.FileInfo;
|
||||
|
||||
namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
@@ -34,14 +32,7 @@ namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
Files = new List<BeatmapSetFileInfo>(new[]
|
||||
{
|
||||
new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = "abc123.wav",
|
||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
||||
}
|
||||
})
|
||||
Files = { CheckTestHelpers.CreateMockFile("wav") }
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -55,11 +46,7 @@ namespace osu.Game.Tests.Editing.Checks
|
||||
public void TestDifferentExtension()
|
||||
{
|
||||
beatmap.BeatmapInfo.BeatmapSet.Files.Clear();
|
||||
beatmap.BeatmapInfo.BeatmapSet.Files.Add(new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = "abc123.jpg",
|
||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
||||
});
|
||||
beatmap.BeatmapInfo.BeatmapSet.Files.Add(CheckTestHelpers.CreateMockFile("jpg"));
|
||||
|
||||
// Should fail to load, but not produce an error due to the extension not being expected to load.
|
||||
Assert.IsEmpty(check.Run(getContext(null, allowMissing: true)));
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
@@ -10,7 +9,6 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Checks;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using FileInfo = osu.Game.IO.FileInfo;
|
||||
|
||||
namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
@@ -30,14 +28,10 @@ namespace osu.Game.Tests.Editing.Checks
|
||||
{
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
Files = new List<BeatmapSetFileInfo>(new[]
|
||||
Files =
|
||||
{
|
||||
new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = "abc123.jpg",
|
||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
||||
}
|
||||
})
|
||||
CheckTestHelpers.CreateMockFile("jpg"),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -29,9 +29,9 @@ namespace osu.Game.Tests.Models
|
||||
{
|
||||
var mock = new Mock<IBeatmapSetInfo>();
|
||||
|
||||
mock.Setup(m => m.Metadata!.Artist).Returns("artist");
|
||||
mock.Setup(m => m.Metadata!.Title).Returns("title");
|
||||
mock.Setup(m => m.Metadata!.Author.Username).Returns("author");
|
||||
mock.Setup(m => m.Metadata.Artist).Returns("artist");
|
||||
mock.Setup(m => m.Metadata.Title).Returns("title");
|
||||
mock.Setup(m => m.Metadata.Author.Username).Returns("author");
|
||||
|
||||
Assert.That(mock.Object.GetDisplayString(), Is.EqualTo("artist - title (author)"));
|
||||
}
|
||||
@@ -41,9 +41,9 @@ namespace osu.Game.Tests.Models
|
||||
{
|
||||
var mock = new Mock<IBeatmapSetInfo>();
|
||||
|
||||
mock.Setup(m => m.Metadata!.Artist).Returns("artist");
|
||||
mock.Setup(m => m.Metadata!.Title).Returns("title");
|
||||
mock.Setup(m => m.Metadata!.Author.Username).Returns(string.Empty);
|
||||
mock.Setup(m => m.Metadata.Artist).Returns("artist");
|
||||
mock.Setup(m => m.Metadata.Title).Returns("title");
|
||||
mock.Setup(m => m.Metadata.Author.Username).Returns(string.Empty);
|
||||
|
||||
Assert.That(mock.Object.GetDisplayString(), Is.EqualTo("artist - title"));
|
||||
}
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Difficulty.Skills;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Utils;
|
||||
|
||||
namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
@@ -20,8 +22,10 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator().CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(1, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) }
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -29,9 +33,11 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator(new ModA()).CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(2, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
Assert.IsTrue(combinations[1] is ModA);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) },
|
||||
new[] { typeof(ModA) }
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -39,14 +45,13 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModB()).CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(4, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
Assert.IsTrue(combinations[1] is ModA);
|
||||
Assert.IsTrue(combinations[2] is MultiMod);
|
||||
Assert.IsTrue(combinations[3] is ModB);
|
||||
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) },
|
||||
new[] { typeof(ModA) },
|
||||
new[] { typeof(ModA), typeof(ModB) },
|
||||
new[] { typeof(ModB) }
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -54,10 +59,12 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModIncompatibleWithA()).CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(3, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
Assert.IsTrue(combinations[1] is ModA);
|
||||
Assert.IsTrue(combinations[2] is ModIncompatibleWithA);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) },
|
||||
new[] { typeof(ModA) },
|
||||
new[] { typeof(ModIncompatibleWithA) }
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -65,22 +72,17 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModB(), new ModIncompatibleWithA(), new ModIncompatibleWithAAndB()).CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(8, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
Assert.IsTrue(combinations[1] is ModA);
|
||||
Assert.IsTrue(combinations[2] is MultiMod);
|
||||
Assert.IsTrue(combinations[3] is ModB);
|
||||
Assert.IsTrue(combinations[4] is MultiMod);
|
||||
Assert.IsTrue(combinations[5] is ModIncompatibleWithA);
|
||||
Assert.IsTrue(combinations[6] is MultiMod);
|
||||
Assert.IsTrue(combinations[7] is ModIncompatibleWithAAndB);
|
||||
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
||||
Assert.IsTrue(((MultiMod)combinations[4]).Mods[0] is ModB);
|
||||
Assert.IsTrue(((MultiMod)combinations[4]).Mods[1] is ModIncompatibleWithA);
|
||||
Assert.IsTrue(((MultiMod)combinations[6]).Mods[0] is ModIncompatibleWithA);
|
||||
Assert.IsTrue(((MultiMod)combinations[6]).Mods[1] is ModIncompatibleWithAAndB);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) },
|
||||
new[] { typeof(ModA) },
|
||||
new[] { typeof(ModA), typeof(ModB) },
|
||||
new[] { typeof(ModB) },
|
||||
new[] { typeof(ModB), typeof(ModIncompatibleWithA) },
|
||||
new[] { typeof(ModIncompatibleWithA) },
|
||||
new[] { typeof(ModIncompatibleWithA), typeof(ModIncompatibleWithAAndB) },
|
||||
new[] { typeof(ModIncompatibleWithAAndB) },
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -88,10 +90,12 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator(new ModAofA(), new ModIncompatibleWithAofA()).CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(3, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
Assert.IsTrue(combinations[1] is ModAofA);
|
||||
Assert.IsTrue(combinations[2] is ModIncompatibleWithAofA);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) },
|
||||
new[] { typeof(ModAofA) },
|
||||
new[] { typeof(ModIncompatibleWithAofA) }
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -99,17 +103,13 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModB(), new ModC())).CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(4, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
Assert.IsTrue(combinations[1] is ModA);
|
||||
Assert.IsTrue(combinations[2] is MultiMod);
|
||||
Assert.IsTrue(combinations[3] is MultiMod);
|
||||
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[2] is ModC);
|
||||
Assert.IsTrue(((MultiMod)combinations[3]).Mods[0] is ModB);
|
||||
Assert.IsTrue(((MultiMod)combinations[3]).Mods[1] is ModC);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) },
|
||||
new[] { typeof(ModA) },
|
||||
new[] { typeof(ModA), typeof(ModB), typeof(ModC) },
|
||||
new[] { typeof(ModB), typeof(ModC) }
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -117,13 +117,12 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModB(), new ModIncompatibleWithA())).CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(3, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
Assert.IsTrue(combinations[1] is ModA);
|
||||
Assert.IsTrue(combinations[2] is MultiMod);
|
||||
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModB);
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModIncompatibleWithA);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) },
|
||||
new[] { typeof(ModA) },
|
||||
new[] { typeof(ModB), typeof(ModIncompatibleWithA) }
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -131,13 +130,28 @@ namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModA(), new ModB())).CreateDifficultyAdjustmentModCombinations();
|
||||
|
||||
Assert.AreEqual(3, combinations.Length);
|
||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
||||
Assert.IsTrue(combinations[1] is ModA);
|
||||
Assert.IsTrue(combinations[2] is MultiMod);
|
||||
assertCombinations(new[]
|
||||
{
|
||||
new[] { typeof(ModNoMod) },
|
||||
new[] { typeof(ModA) },
|
||||
new[] { typeof(ModA), typeof(ModB) }
|
||||
}, combinations);
|
||||
}
|
||||
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
||||
private void assertCombinations(Type[][] expectedCombinations, Mod[] actualCombinations)
|
||||
{
|
||||
Assert.AreEqual(expectedCombinations.Length, actualCombinations.Length);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
for (int i = 0; i < expectedCombinations.Length; ++i)
|
||||
{
|
||||
Type[] expectedTypes = expectedCombinations[i];
|
||||
Type[] actualTypes = ModUtils.FlattenMod(actualCombinations[i]).Select(m => m.GetType()).ToArray();
|
||||
|
||||
Assert.That(expectedTypes, Is.EquivalentTo(actualTypes));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class ModA : Mod
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
{
|
||||
private BeatmapInfo getExampleBeatmap() => new BeatmapInfo
|
||||
{
|
||||
Ruleset = new RulesetInfo { ID = 5 },
|
||||
Ruleset = new RulesetInfo { OnlineID = 5 },
|
||||
StarRating = 4.0d,
|
||||
BaseDifficulty = new BeatmapDifficulty
|
||||
{
|
||||
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
Length = 2500,
|
||||
BPM = 160,
|
||||
BeatDivisor = 12,
|
||||
Status = BeatmapSetOnlineStatus.Loved
|
||||
Status = BeatmapOnlineStatus.Loved
|
||||
};
|
||||
|
||||
[Test]
|
||||
@@ -57,7 +57,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
var exampleBeatmapInfo = getExampleBeatmap();
|
||||
var criteria = new FilterCriteria
|
||||
{
|
||||
Ruleset = new RulesetInfo { ID = 6 }
|
||||
Ruleset = new RulesetInfo { OnlineID = 6 }
|
||||
};
|
||||
var carouselItem = new CarouselBeatmap(exampleBeatmapInfo);
|
||||
carouselItem.Filter(criteria);
|
||||
@@ -70,7 +70,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
var exampleBeatmapInfo = getExampleBeatmap();
|
||||
var criteria = new FilterCriteria
|
||||
{
|
||||
Ruleset = new RulesetInfo { ID = 6 },
|
||||
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||
AllowConvertedBeatmaps = true
|
||||
};
|
||||
var carouselItem = new CarouselBeatmap(exampleBeatmapInfo);
|
||||
@@ -86,7 +86,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
var exampleBeatmapInfo = getExampleBeatmap();
|
||||
var criteria = new FilterCriteria
|
||||
{
|
||||
Ruleset = new RulesetInfo { ID = 6 },
|
||||
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||
AllowConvertedBeatmaps = true,
|
||||
ApproachRate = new FilterCriteria.OptionalRange<float>
|
||||
{
|
||||
@@ -107,7 +107,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
var exampleBeatmapInfo = getExampleBeatmap();
|
||||
var criteria = new FilterCriteria
|
||||
{
|
||||
Ruleset = new RulesetInfo { ID = 6 },
|
||||
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||
AllowConvertedBeatmaps = true,
|
||||
BPM = new FilterCriteria.OptionalRange<double>
|
||||
{
|
||||
@@ -132,7 +132,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
var exampleBeatmapInfo = getExampleBeatmap();
|
||||
var criteria = new FilterCriteria
|
||||
{
|
||||
Ruleset = new RulesetInfo { ID = 6 },
|
||||
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||
AllowConvertedBeatmaps = true,
|
||||
SearchText = terms
|
||||
};
|
||||
|
||||
@@ -162,9 +162,9 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
FilterQueryParser.ApplyQueries(filterCriteria, query);
|
||||
Assert.AreEqual("I want the pp", filterCriteria.SearchText.Trim());
|
||||
Assert.AreEqual(4, filterCriteria.SearchTerms.Length);
|
||||
Assert.AreEqual(BeatmapSetOnlineStatus.Ranked, filterCriteria.OnlineStatus.Min);
|
||||
Assert.AreEqual(BeatmapOnlineStatus.Ranked, filterCriteria.OnlineStatus.Min);
|
||||
Assert.IsTrue(filterCriteria.OnlineStatus.IsLowerInclusive);
|
||||
Assert.AreEqual(BeatmapSetOnlineStatus.Ranked, filterCriteria.OnlineStatus.Max);
|
||||
Assert.AreEqual(BeatmapOnlineStatus.Ranked, filterCriteria.OnlineStatus.Max);
|
||||
Assert.IsTrue(filterCriteria.OnlineStatus.IsUpperInclusive);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,27 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
|
||||
[HeadlessTest]
|
||||
public class StatefulMultiplayerClientTest : MultiplayerTestScene
|
||||
{
|
||||
[Test]
|
||||
public void TestUserAddedOnJoin()
|
||||
{
|
||||
var user = new APIUser { Id = 33 };
|
||||
|
||||
AddRepeatStep("add user multiple times", () => Client.AddUser(user), 3);
|
||||
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUserRemovedOnLeave()
|
||||
{
|
||||
var user = new APIUser { Id = 44 };
|
||||
|
||||
AddStep("add user", () => Client.AddUser(user));
|
||||
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
|
||||
|
||||
AddRepeatStep("remove user multiple times", () => Client.RemoveUser(user), 3);
|
||||
AddAssert("room has 1 user", () => Client.Room?.Users.Count == 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPlayingUserTracking()
|
||||
{
|
||||
@@ -72,7 +93,7 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
|
||||
RoomManager.CreateRoom(newRoom);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for room join", () => Client.Room != null);
|
||||
AddUntilStep("wait for room join", () => RoomJoined);
|
||||
checkPlayingUserCount(1);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -12,9 +12,9 @@ using osu.Game.Tests.Visual;
|
||||
namespace osu.Game.Tests.Online
|
||||
{
|
||||
[HeadlessTest]
|
||||
public class TestSceneBeatmapManager : OsuTestScene
|
||||
public class TestSceneBeatmapDownloading : OsuTestScene
|
||||
{
|
||||
private BeatmapManager beatmaps;
|
||||
private BeatmapModelDownloader beatmaps;
|
||||
private ProgressNotification recentNotification;
|
||||
|
||||
private static readonly BeatmapSetInfo test_db_model = new BeatmapSetInfo
|
||||
@@ -43,7 +43,7 @@ namespace osu.Game.Tests.Online
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(BeatmapManager beatmaps)
|
||||
private void load(BeatmapModelDownloader beatmaps)
|
||||
{
|
||||
this.beatmaps = beatmaps;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -33,6 +33,7 @@ namespace osu.Game.Tests.Online
|
||||
{
|
||||
private RulesetStore rulesets;
|
||||
private TestBeatmapManager beatmaps;
|
||||
private TestBeatmapModelDownloader beatmapDownloader;
|
||||
|
||||
private string testBeatmapFile;
|
||||
private BeatmapInfo testBeatmapInfo;
|
||||
@@ -46,6 +47,7 @@ namespace osu.Game.Tests.Online
|
||||
{
|
||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||
Dependencies.CacheAs<BeatmapManager>(beatmaps = new TestBeatmapManager(LocalStorage, ContextFactory, rulesets, API, audio, Resources, host, Beatmap.Default));
|
||||
Dependencies.CacheAs<BeatmapModelDownloader>(beatmapDownloader = new TestBeatmapModelDownloader(beatmaps, API, host));
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
@@ -80,13 +82,13 @@ namespace osu.Game.Tests.Online
|
||||
AddAssert("ensure beatmap unavailable", () => !beatmaps.IsAvailableLocally(testBeatmapSet));
|
||||
addAvailabilityCheckStep("state not downloaded", BeatmapAvailability.NotDownloaded);
|
||||
|
||||
AddStep("start downloading", () => beatmaps.Download(testBeatmapSet));
|
||||
AddStep("start downloading", () => beatmapDownloader.Download(testBeatmapSet));
|
||||
addAvailabilityCheckStep("state downloading 0%", () => BeatmapAvailability.Downloading(0.0f));
|
||||
|
||||
AddStep("set progress 40%", () => ((TestDownloadRequest)beatmaps.GetExistingDownload(testBeatmapSet)).SetProgress(0.4f));
|
||||
AddStep("set progress 40%", () => ((TestDownloadRequest)beatmapDownloader.GetExistingDownload(testBeatmapSet)).SetProgress(0.4f));
|
||||
addAvailabilityCheckStep("state downloading 40%", () => BeatmapAvailability.Downloading(0.4f));
|
||||
|
||||
AddStep("finish download", () => ((TestDownloadRequest)beatmaps.GetExistingDownload(testBeatmapSet)).TriggerSuccess(testBeatmapFile));
|
||||
AddStep("finish download", () => ((TestDownloadRequest)beatmapDownloader.GetExistingDownload(testBeatmapSet)).TriggerSuccess(testBeatmapFile));
|
||||
addAvailabilityCheckStep("state importing", BeatmapAvailability.Importing);
|
||||
|
||||
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
|
||||
@@ -143,7 +145,10 @@ namespace osu.Game.Tests.Online
|
||||
var beatmap = decoder.Decode(reader);
|
||||
|
||||
info = beatmap.BeatmapInfo;
|
||||
info.BeatmapSet.Beatmaps = new List<BeatmapInfo> { info };
|
||||
|
||||
Debug.Assert(info.BeatmapSet != null);
|
||||
|
||||
info.BeatmapSet.Beatmaps.Add(info);
|
||||
info.BeatmapSet.Metadata = info.Metadata;
|
||||
info.MD5Hash = stream.ComputeMD5Hash();
|
||||
info.Hash = stream.ComputeSHA2Hash();
|
||||
@@ -168,22 +173,6 @@ namespace osu.Game.Tests.Online
|
||||
return new TestBeatmapModelManager(this, storage, contextFactory, rulesets, api, host);
|
||||
}
|
||||
|
||||
protected override BeatmapModelDownloader CreateBeatmapModelDownloader(IModelImporter<BeatmapSetInfo> manager, IAPIProvider api, GameHost host)
|
||||
{
|
||||
return new TestBeatmapModelDownloader(manager, api, host);
|
||||
}
|
||||
|
||||
internal class TestBeatmapModelDownloader : BeatmapModelDownloader
|
||||
{
|
||||
public TestBeatmapModelDownloader(IModelImporter<BeatmapSetInfo> importer, IAPIProvider apiProvider, GameHost gameHost)
|
||||
: base(importer, apiProvider, gameHost)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ArchiveDownloadRequest<IBeatmapSetInfo> CreateDownloadRequest(IBeatmapSetInfo set, bool minimiseDownloadSize)
|
||||
=> new TestDownloadRequest(set);
|
||||
}
|
||||
|
||||
internal class TestBeatmapModelManager : BeatmapModelManager
|
||||
{
|
||||
private readonly TestBeatmapManager testBeatmapManager;
|
||||
@@ -202,6 +191,17 @@ namespace osu.Game.Tests.Online
|
||||
}
|
||||
}
|
||||
|
||||
internal class TestBeatmapModelDownloader : BeatmapModelDownloader
|
||||
{
|
||||
public TestBeatmapModelDownloader(IModelImporter<BeatmapSetInfo> importer, IAPIProvider apiProvider, GameHost gameHost)
|
||||
: base(importer, apiProvider)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ArchiveDownloadRequest<IBeatmapSetInfo> CreateDownloadRequest(IBeatmapSetInfo set, bool minimiseDownloadSize)
|
||||
=> new TestDownloadRequest(set);
|
||||
}
|
||||
|
||||
private class TestDownloadRequest : ArchiveDownloadRequest<IBeatmapSetInfo>
|
||||
{
|
||||
public new void SetProgress(float progress) => base.SetProgress(progress);
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.OnlinePlay
|
||||
{
|
||||
[HeadlessTest]
|
||||
public class StatefulMultiplayerClientTest : MultiplayerTestScene
|
||||
{
|
||||
[Test]
|
||||
public void TestUserAddedOnJoin()
|
||||
{
|
||||
var user = new APIUser { Id = 33 };
|
||||
|
||||
AddRepeatStep("add user multiple times", () => Client.AddUser(user), 3);
|
||||
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUserRemovedOnLeave()
|
||||
{
|
||||
var user = new APIUser { Id = 44 };
|
||||
|
||||
AddStep("add user", () => Client.AddUser(user));
|
||||
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
|
||||
|
||||
AddRepeatStep("remove user multiple times", () => Client.RemoveUser(user), 3);
|
||||
AddAssert("room has 1 user", () => Client.Room?.Users.Count == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,18 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
|
||||
namespace osu.Game.Tests.Resources
|
||||
{
|
||||
@@ -56,5 +64,78 @@ namespace osu.Game.Tests.Resources
|
||||
}
|
||||
|
||||
private static string getTempFilename() => temp_storage.GetFullPath(Guid.NewGuid() + ".osz");
|
||||
|
||||
private static int importId;
|
||||
|
||||
/// <summary>
|
||||
/// Create a test beatmap set model.
|
||||
/// </summary>
|
||||
/// <param name="difficultyCount">Number of difficulties. If null, a random number between 1 and 20 will be used.</param>
|
||||
/// <param name="rulesets">Rulesets to cycle through when creating difficulties. If <c>null</c>, osu! ruleset will be used.</param>
|
||||
public static BeatmapSetInfo CreateTestBeatmapSetInfo(int? difficultyCount = null, RulesetInfo[] rulesets = null)
|
||||
{
|
||||
int j = 0;
|
||||
RulesetInfo getRuleset() => rulesets?[j++ % rulesets.Length] ?? new OsuRuleset().RulesetInfo;
|
||||
|
||||
int setId = Interlocked.Increment(ref importId);
|
||||
|
||||
var metadata = new BeatmapMetadata
|
||||
{
|
||||
// Create random metadata, then we can check if sorting works based on these
|
||||
Artist = "Some Artist " + RNG.Next(0, 9),
|
||||
Title = $"Some Song (set id {setId}) {Guid.NewGuid()}",
|
||||
AuthorString = "Some Guy " + RNG.Next(0, 9),
|
||||
};
|
||||
|
||||
var beatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineID = setId,
|
||||
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
|
||||
DateAdded = DateTimeOffset.UtcNow,
|
||||
Metadata = metadata
|
||||
};
|
||||
|
||||
foreach (var b in getBeatmaps(difficultyCount ?? RNG.Next(1, 20)))
|
||||
beatmapSet.Beatmaps.Add(b);
|
||||
|
||||
return beatmapSet;
|
||||
|
||||
IEnumerable<BeatmapInfo> getBeatmaps(int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int beatmapId = setId * 1000 + i;
|
||||
|
||||
int length = RNG.Next(30000, 200000);
|
||||
double bpm = RNG.NextSingle(80, 200);
|
||||
|
||||
float diff = (float)i / count * 10;
|
||||
|
||||
string version = "Normal";
|
||||
if (diff > 6.6)
|
||||
version = "Insane";
|
||||
else if (diff > 3.3)
|
||||
version = "Hard";
|
||||
|
||||
var rulesetInfo = getRuleset();
|
||||
|
||||
yield return new BeatmapInfo
|
||||
{
|
||||
OnlineID = beatmapId,
|
||||
DifficultyName = $"{version} {beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
|
||||
StarRating = diff,
|
||||
Length = length,
|
||||
BPM = bpm,
|
||||
Ruleset = rulesetInfo,
|
||||
RulesetID = rulesetInfo.ID ?? -1,
|
||||
Metadata = metadata,
|
||||
BaseDifficulty = new BeatmapDifficulty
|
||||
{
|
||||
OverallDifficulty = diff,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace osu.Game.Tests.Scores.IO
|
||||
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
||||
|
||||
beatmapManager.Delete(beatmapManager.QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == imported.BeatmapInfo.ID)));
|
||||
Assert.That(scoreManager.Query(s => s.ID == imported.ID).DeletePending, Is.EqualTo(true));
|
||||
Assert.That(scoreManager.Query(s => s.Equals(imported)).DeletePending, Is.EqualTo(true));
|
||||
|
||||
var secondImport = await LoadScoreIntoOsu(osu, imported);
|
||||
Assert.That(secondImport, Is.Null);
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace osu.Game.Tests.Testing
|
||||
{
|
||||
// temporary ID to let RulesetConfigCache pass our
|
||||
// config manager to the ruleset dependencies.
|
||||
RulesetInfo.ID = -1;
|
||||
RulesetInfo.OnlineID = -1;
|
||||
}
|
||||
|
||||
public override IResourceStore<byte[]> CreateResourceStore() => new NamespacedResourceStore<byte[]>(TestResources.GetStore(), @"Resources");
|
||||
|
||||
@@ -23,10 +23,18 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
||||
{
|
||||
public class TestSceneBeatmapCard : OsuTestScene
|
||||
{
|
||||
/// <summary>
|
||||
/// All cards on this scene use a common online ID to ensure that map download, preview tracks, etc. can be tested manually with online sources.
|
||||
/// </summary>
|
||||
private const int online_id = 163112;
|
||||
|
||||
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
|
||||
|
||||
private APIBeatmapSet[] testCases;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
#region Test case generation
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@@ -38,7 +46,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
||||
|
||||
var withStatistics = CreateAPIBeatmapSet(Ruleset.Value);
|
||||
withStatistics.Title = withStatistics.TitleUnicode = "play favourite stats";
|
||||
withStatistics.Status = BeatmapSetOnlineStatus.Approved;
|
||||
withStatistics.Status = BeatmapOnlineStatus.Approved;
|
||||
withStatistics.FavouriteCount = 284_239;
|
||||
withStatistics.PlayCount = 999_001;
|
||||
withStatistics.Ranked = DateTimeOffset.Now.AddDays(-45);
|
||||
@@ -59,7 +67,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
||||
var someDifficulties = getManyDifficultiesBeatmapSet(11);
|
||||
someDifficulties.Title = someDifficulties.TitleUnicode = "favourited";
|
||||
someDifficulties.Title = someDifficulties.TitleUnicode = "some difficulties";
|
||||
someDifficulties.Status = BeatmapSetOnlineStatus.Qualified;
|
||||
someDifficulties.Status = BeatmapOnlineStatus.Qualified;
|
||||
someDifficulties.HasFavourited = true;
|
||||
someDifficulties.FavouriteCount = 1;
|
||||
someDifficulties.NominationStatus = new BeatmapSetNominationStatus
|
||||
@@ -69,7 +77,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
||||
};
|
||||
|
||||
var manyDifficulties = getManyDifficultiesBeatmapSet(100);
|
||||
manyDifficulties.Status = BeatmapSetOnlineStatus.Pending;
|
||||
manyDifficulties.Status = BeatmapOnlineStatus.Pending;
|
||||
|
||||
var explicitMap = CreateAPIBeatmapSet(Ruleset.Value);
|
||||
explicitMap.Title = someDifficulties.TitleUnicode = "explicit beatmap";
|
||||
@@ -102,6 +110,9 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
||||
explicitFeaturedMap,
|
||||
longName
|
||||
};
|
||||
|
||||
foreach (var testCase in testCases)
|
||||
testCase.OnlineID = online_id;
|
||||
}
|
||||
|
||||
private APIBeatmapSet getUndownloadableBeatmapSet() => new APIBeatmapSet
|
||||
@@ -180,6 +191,19 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
||||
request.TriggerSuccess();
|
||||
return true;
|
||||
});
|
||||
|
||||
ensureSoleilyRemoved();
|
||||
}
|
||||
|
||||
private void ensureSoleilyRemoved()
|
||||
{
|
||||
AddUntilStep("ensure manager loaded", () => beatmaps != null);
|
||||
AddStep("remove map", () =>
|
||||
{
|
||||
var beatmap = beatmaps.QueryBeatmapSet(b => b.OnlineID == online_id);
|
||||
|
||||
if (beatmap != null) beatmaps.Delete(beatmap);
|
||||
});
|
||||
}
|
||||
|
||||
private Drawable createContent(OverlayColourScheme colourScheme, Func<APIBeatmapSet, Drawable> creationFunc)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps.Drawables.Cards;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Beatmaps
|
||||
{
|
||||
public class TestSceneBeatmapCardDifficultyList : OsuTestScene
|
||||
{
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
var beatmapSet = new APIBeatmapSet
|
||||
{
|
||||
Beatmaps = new[]
|
||||
{
|
||||
new APIBeatmap { RulesetID = 1, StarRating = 5.76, DifficultyName = "Oni" },
|
||||
new APIBeatmap { RulesetID = 1, StarRating = 3.20, DifficultyName = "Muzukashii" },
|
||||
new APIBeatmap { RulesetID = 1, StarRating = 2.45, DifficultyName = "Futsuu" },
|
||||
|
||||
new APIBeatmap { RulesetID = 0, StarRating = 2.04, DifficultyName = "Normal" },
|
||||
new APIBeatmap { RulesetID = 0, StarRating = 3.51, DifficultyName = "Hard" },
|
||||
new APIBeatmap { RulesetID = 0, StarRating = 5.25, DifficultyName = "Insane" },
|
||||
|
||||
new APIBeatmap { RulesetID = 2, StarRating = 2.64, DifficultyName = "Salad" },
|
||||
new APIBeatmap { RulesetID = 2, StarRating = 3.56, DifficultyName = "Platter" },
|
||||
new APIBeatmap { RulesetID = 2, StarRating = 4.65, DifficultyName = "Rain" },
|
||||
|
||||
new APIBeatmap { RulesetID = 3, StarRating = 1.93, DifficultyName = "[7K] Normal" },
|
||||
new APIBeatmap { RulesetID = 3, StarRating = 3.18, DifficultyName = "[7K] Hyper" },
|
||||
new APIBeatmap { RulesetID = 3, StarRating = 4.82, DifficultyName = "[7K] Another" },
|
||||
|
||||
new APIBeatmap { RulesetID = 4, StarRating = 9.99, DifficultyName = "Unknown?!" },
|
||||
}
|
||||
};
|
||||
|
||||
Child = new Container
|
||||
{
|
||||
Width = 300,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Background2
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(10),
|
||||
Child = new BeatmapCardDifficultyList(beatmapSet)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables.Cards.Buttons;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Beatmaps
|
||||
{
|
||||
public class TestSceneBeatmapCardDownloadButton : OsuTestScene
|
||||
{
|
||||
private DownloadButton downloadButton;
|
||||
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
[Resolved]
|
||||
private OsuConfigManager config { get; set; }
|
||||
|
||||
[Test]
|
||||
public void TestDownloadableBeatmapWithVideo()
|
||||
{
|
||||
createButton(true, true);
|
||||
assertDownloadEnabled(true);
|
||||
|
||||
AddStep("prefer no video", () => config.SetValue(OsuSetting.PreferNoVideo, true));
|
||||
AddAssert("tooltip text correct", () => downloadButton.TooltipText == BeatmapsetsStrings.PanelDownloadNoVideo);
|
||||
|
||||
AddStep("prefer video", () => config.SetValue(OsuSetting.PreferNoVideo, false));
|
||||
AddAssert("tooltip text correct", () => downloadButton.TooltipText == BeatmapsetsStrings.PanelDownloadVideo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUndownloadableBeatmap()
|
||||
{
|
||||
createButton(false);
|
||||
assertDownloadEnabled(false);
|
||||
AddAssert("tooltip text correct", () => downloadButton.TooltipText == BeatmapsetsStrings.AvailabilityDisabled);
|
||||
}
|
||||
|
||||
private void assertDownloadEnabled(bool enabled) => AddAssert($"download {(enabled ? "enabled" : "disabled")}", () => downloadButton.Enabled.Value == enabled);
|
||||
|
||||
private void createButton(bool downloadable, bool hasVideo = false)
|
||||
{
|
||||
AddStep("create button", () =>
|
||||
{
|
||||
Child = downloadButton = new DownloadButton(downloadable ? getDownloadableBeatmapSet(hasVideo) : getUndownloadableBeatmapSet())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(2)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private APIBeatmapSet getDownloadableBeatmapSet(bool hasVideo)
|
||||
{
|
||||
var normal = CreateAPIBeatmapSet(new OsuRuleset().RulesetInfo);
|
||||
normal.HasVideo = hasVideo;
|
||||
normal.HasStoryboard = true;
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
private APIBeatmapSet getUndownloadableBeatmapSet()
|
||||
{
|
||||
var beatmap = CreateAPIBeatmapSet(new OsuRuleset().RulesetInfo);
|
||||
beatmap.Artist = "test";
|
||||
beatmap.Title = "undownloadable";
|
||||
beatmap.AuthorString = "test";
|
||||
|
||||
beatmap.HasVideo = true;
|
||||
beatmap.HasStoryboard = true;
|
||||
|
||||
beatmap.Availability = new BeatmapSetOnlineAvailability
|
||||
{
|
||||
DownloadDisabled = true,
|
||||
ExternalLink = "https://osu.ppy.sh",
|
||||
};
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps.Drawables.Cards;
|
||||
using osu.Game.Beatmaps.Drawables.Cards.Buttons;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Beatmaps
|
||||
{
|
||||
public class TestSceneBeatmapCardThumbnail : OsuManualInputManagerTestScene
|
||||
{
|
||||
private PlayButton playButton => this.ChildrenOfType<PlayButton>().Single();
|
||||
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
[Test]
|
||||
public void TestThumbnailPreview()
|
||||
{
|
||||
BeatmapCardThumbnail thumbnail = null;
|
||||
|
||||
AddStep("create thumbnail", () =>
|
||||
{
|
||||
var beatmapSet = CreateAPIBeatmapSet(Ruleset.Value);
|
||||
beatmapSet.OnlineID = 241526; // ID hardcoded to ensure that the preview track exists online.
|
||||
|
||||
Child = thumbnail = new BeatmapCardThumbnail(beatmapSet)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(200)
|
||||
};
|
||||
});
|
||||
AddStep("enable dim", () => thumbnail.Dimmed.Value = true);
|
||||
AddUntilStep("button visible", () => playButton.IsPresent);
|
||||
|
||||
AddStep("click button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(playButton);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
AddUntilStep("wait for start", () => playButton.Playing.Value && playButton.Enabled.Value);
|
||||
iconIs(FontAwesome.Solid.Stop);
|
||||
|
||||
AddStep("click again", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(playButton);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
AddUntilStep("wait for stop", () => !playButton.Playing.Value && playButton.Enabled.Value);
|
||||
iconIs(FontAwesome.Solid.Play);
|
||||
|
||||
AddStep("click again", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(playButton);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
AddUntilStep("wait for start", () => playButton.Playing.Value && playButton.Enabled.Value);
|
||||
iconIs(FontAwesome.Solid.Stop);
|
||||
|
||||
AddStep("disable dim", () => thumbnail.Dimmed.Value = false);
|
||||
AddWaitStep("wait some", 3);
|
||||
AddAssert("button still visible", () => playButton.IsPresent);
|
||||
|
||||
// The track plays in real-time, so we need to check for progress in increments to avoid timeout.
|
||||
AddUntilStep("progress > 0.25", () => thumbnail.ChildrenOfType<PlayButton>().Single().Progress.Value > 0.25);
|
||||
AddUntilStep("progress > 0.5", () => thumbnail.ChildrenOfType<PlayButton>().Single().Progress.Value > 0.5);
|
||||
AddUntilStep("progress > 0.75", () => thumbnail.ChildrenOfType<PlayButton>().Single().Progress.Value > 0.75);
|
||||
|
||||
AddUntilStep("wait for track to end", () => !playButton.Playing.Value);
|
||||
AddUntilStep("button hidden", () => !playButton.IsPresent);
|
||||
}
|
||||
|
||||
private void iconIs(IconUsage usage) => AddUntilStep("icon is correct", () => playButton.ChildrenOfType<SpriteIcon>().Any(icon => icon.Icon.Equals(usage)));
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
||||
Origin = Anchor.Centre,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
ChildrenEnumerable = Enum.GetValues(typeof(BeatmapSetOnlineStatus)).Cast<BeatmapSetOnlineStatus>().Select(status => new BeatmapSetOnlineStatusPill
|
||||
ChildrenEnumerable = Enum.GetValues(typeof(BeatmapOnlineStatus)).Cast<BeatmapOnlineStatus>().Select(status => new BeatmapSetOnlineStatusPill
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
|
||||
@@ -69,7 +69,10 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
|
||||
|
||||
PushAndConfirm(() => new PlaySongSelect());
|
||||
Screens.Select.SongSelect songSelect = null;
|
||||
|
||||
PushAndConfirm(() => songSelect = new PlaySongSelect());
|
||||
AddUntilStep("wait for carousel load", () => songSelect.BeatmapSetsLoaded);
|
||||
|
||||
AddUntilStep("Wait for beatmap selected", () => !Game.Beatmap.IsDefault);
|
||||
AddStep("Open options", () => InputManager.Key(Key.F3));
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
prepareTokenResponse(true);
|
||||
|
||||
createPlayerTest(false, createRuleset: () => new OsuRuleset { RulesetInfo = { ID = rulesetId } });
|
||||
createPlayerTest(false, createRuleset: () => new OsuRuleset { RulesetInfo = { OnlineID = rulesetId ?? -1 } });
|
||||
|
||||
AddUntilStep("wait for token request", () => Player.TokenCreationRequested);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
{
|
||||
Recorder = recorder = new TestReplayRecorder(new Score
|
||||
{
|
||||
@@ -89,7 +89,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
},
|
||||
new Drawable[]
|
||||
{
|
||||
playbackManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
playbackManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
{
|
||||
ReplayInputHandler = new TestFramedReplayInputHandler(replay)
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
{
|
||||
Recorder = new TestReplayRecorder(new Score
|
||||
{
|
||||
@@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
},
|
||||
new Drawable[]
|
||||
{
|
||||
playbackManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
playbackManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
{
|
||||
ReplayInputHandler = new TestFramedReplayInputHandler(replay)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
public void TestClientSendsCorrectRuleset()
|
||||
{
|
||||
AddUntilStep("spectator client sending frames", () => spectatorClient.PlayingUserStates.ContainsKey(dummy_user_id));
|
||||
AddAssert("spectator client sent correct ruleset", () => spectatorClient.PlayingUserStates[dummy_user_id].RulesetID == Ruleset.Value.ID);
|
||||
AddAssert("spectator client sent correct ruleset", () => spectatorClient.PlayingUserStates[dummy_user_id].RulesetID == Ruleset.Value.OnlineID);
|
||||
}
|
||||
|
||||
public override void TearDownSteps()
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
{
|
||||
Recorder = recorder = new TestReplayRecorder
|
||||
{
|
||||
@@ -139,7 +139,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
},
|
||||
new Drawable[]
|
||||
{
|
||||
playbackManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
playbackManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||
{
|
||||
Clock = new FramedClock(manualClock),
|
||||
ReplayInputHandler = replayHandler = new TestFramedReplayInputHandler(replay)
|
||||
|
||||
@@ -30,25 +30,10 @@ namespace osu.Game.Tests.Visual.Menus
|
||||
[Test]
|
||||
public void TestMusicNavigationActions()
|
||||
{
|
||||
int importId = 0;
|
||||
Queue<(IWorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null;
|
||||
|
||||
// ensure we have at least two beatmaps available to identify the direction the music controller navigated to.
|
||||
AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(new BeatmapSetInfo
|
||||
{
|
||||
Beatmaps = new List<BeatmapInfo>
|
||||
{
|
||||
new BeatmapInfo
|
||||
{
|
||||
BaseDifficulty = new BeatmapDifficulty(),
|
||||
}
|
||||
},
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Artist = $"a test map {importId++}",
|
||||
Title = "title",
|
||||
}
|
||||
}).Wait(), 5);
|
||||
AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()).Wait(), 5);
|
||||
|
||||
AddStep("import beatmap with track", () =>
|
||||
{
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public abstract class QueueModeTestScene : ScreenTestScene
|
||||
{
|
||||
protected abstract QueueMode Mode { get; }
|
||||
|
||||
protected BeatmapInfo InitialBeatmap { get; private set; }
|
||||
protected BeatmapInfo OtherBeatmap { get; private set; }
|
||||
|
||||
protected IScreen CurrentScreen => multiplayerScreenStack.CurrentScreen;
|
||||
protected IScreen CurrentSubScreen => multiplayerScreenStack.MultiplayerScreen.CurrentSubScreen;
|
||||
|
||||
private BeatmapManager beatmaps;
|
||||
private RulesetStore rulesets;
|
||||
private BeatmapSetInfo importedSet;
|
||||
|
||||
private TestMultiplayerScreenStack multiplayerScreenStack;
|
||||
|
||||
protected TestMultiplayerClient Client => multiplayerScreenStack.Client;
|
||||
protected TestMultiplayerRoomManager RoomManager => multiplayerScreenStack.RoomManager;
|
||||
|
||||
[Cached(typeof(UserLookupCache))]
|
||||
private UserLookupCache lookupCache = new TestUserLookupCache();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(GameHost host, AudioManager audio)
|
||||
{
|
||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
|
||||
}
|
||||
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("import beatmap", () =>
|
||||
{
|
||||
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
|
||||
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
|
||||
InitialBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
|
||||
OtherBeatmap = importedSet.Beatmaps.Last(b => b.RulesetID == 0);
|
||||
});
|
||||
|
||||
AddStep("load multiplayer", () => LoadScreen(multiplayerScreenStack = new TestMultiplayerScreenStack()));
|
||||
AddUntilStep("wait for multiplayer to load", () => multiplayerScreenStack.IsLoaded);
|
||||
AddUntilStep("wait for lounge to load", () => this.ChildrenOfType<MultiplayerLoungeSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
||||
|
||||
AddUntilStep("wait for lounge", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().SingleOrDefault()?.IsLoaded == true);
|
||||
AddStep("open room", () => multiplayerScreenStack.ChildrenOfType<LoungeSubScreen>().Single().Open(new Room
|
||||
{
|
||||
Name = { Value = "Test Room" },
|
||||
QueueMode = { Value = Mode },
|
||||
Playlist =
|
||||
{
|
||||
new PlaylistItem
|
||||
{
|
||||
Beatmap = { Value = InitialBeatmap },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
||||
AddWaitStep("wait for transition", 2);
|
||||
|
||||
AddStep("create room", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for join", () => RoomManager.RoomJoined);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCreatedWithCorrectMode()
|
||||
{
|
||||
AddAssert("room created with correct mode", () => Client.APIRoom?.QueueMode.Value == Mode);
|
||||
}
|
||||
|
||||
protected void RunGameplay()
|
||||
{
|
||||
AddUntilStep("wait for idle", () => Client.LocalUser?.State == MultiplayerUserState.Idle);
|
||||
clickReadyButton();
|
||||
|
||||
AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
|
||||
clickReadyButton();
|
||||
|
||||
AddUntilStep("wait for player", () => multiplayerScreenStack.CurrentScreen is Player player && player.IsLoaded);
|
||||
AddStep("exit player", () => multiplayerScreenStack.MultiplayerScreen.MakeCurrent());
|
||||
}
|
||||
|
||||
private void clickReadyButton()
|
||||
{
|
||||
AddUntilStep("wait for ready button to be enabled", () => this.ChildrenOfType<MultiplayerReadyButton>().Single().ChildrenOfType<Button>().Single().Enabled.Value);
|
||||
|
||||
AddStep("click ready button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerReadyButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// 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;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneAllPlayersQueueMode : QueueModeTestScene
|
||||
{
|
||||
protected override QueueMode Mode => QueueMode.AllPlayers;
|
||||
|
||||
[Test]
|
||||
public void TestFirstItemSelectedByDefault()
|
||||
{
|
||||
AddAssert("first item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestItemAddedToTheEndOfQueue()
|
||||
{
|
||||
addItem(() => OtherBeatmap);
|
||||
AddAssert("playlist has 2 items", () => Client.APIRoom?.Playlist.Count == 2);
|
||||
AddAssert("last playlist item is different", () => Client.APIRoom?.Playlist[1].Beatmap.Value.OnlineID == OtherBeatmap.OnlineID);
|
||||
|
||||
addItem(() => InitialBeatmap);
|
||||
AddAssert("playlist has 3 items", () => Client.APIRoom?.Playlist.Count == 3);
|
||||
AddAssert("last playlist item is different", () => Client.APIRoom?.Playlist[2].Beatmap.Value.OnlineID == InitialBeatmap.OnlineID);
|
||||
|
||||
AddAssert("first item still selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSingleItemExpiredAfterGameplay()
|
||||
{
|
||||
RunGameplay();
|
||||
|
||||
AddAssert("playlist has only one item", () => Client.APIRoom?.Playlist.Count == 1);
|
||||
AddAssert("playlist item is expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
||||
AddAssert("last item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNextItemSelectedAfterGameplayFinish()
|
||||
{
|
||||
addItem(() => OtherBeatmap);
|
||||
addItem(() => InitialBeatmap);
|
||||
|
||||
RunGameplay();
|
||||
|
||||
AddAssert("first item expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
||||
AddAssert("next item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[1].ID);
|
||||
|
||||
RunGameplay();
|
||||
|
||||
AddAssert("second item expired", () => Client.APIRoom?.Playlist[1].Expired == true);
|
||||
AddAssert("next item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[2].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestItemsNotClearedWhenSwitchToHostOnlyMode()
|
||||
{
|
||||
addItem(() => OtherBeatmap);
|
||||
addItem(() => InitialBeatmap);
|
||||
|
||||
// Move to the "other" beatmap.
|
||||
RunGameplay();
|
||||
|
||||
AddStep("change queue mode", () => Client.ChangeSettings(queueMode: QueueMode.HostOnly));
|
||||
AddAssert("playlist has 3 items", () => Client.APIRoom?.Playlist.Count == 3);
|
||||
AddAssert("playlist item is the other beatmap", () => Client.CurrentMatchPlayingItem.Value?.BeatmapID == OtherBeatmap.OnlineID);
|
||||
AddAssert("playlist item is not expired", () => Client.APIRoom?.Playlist[1].Expired == false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCorrectItemSelectedAfterNewItemAdded()
|
||||
{
|
||||
addItem(() => OtherBeatmap);
|
||||
AddAssert("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
|
||||
}
|
||||
|
||||
private void addItem(Func<BeatmapInfo> beatmap)
|
||||
{
|
||||
AddStep("click edit button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen>().Single().AddOrEditPlaylistButton);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
|
||||
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(beatmap()));
|
||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,15 +13,16 @@ using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays.BeatmapListing.Panels;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.OnlinePlay;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Users.Drawables;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
|
||||
@@ -34,6 +35,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
private BeatmapManager manager;
|
||||
private RulesetStore rulesets;
|
||||
|
||||
[Cached(typeof(UserLookupCache))]
|
||||
private readonly TestUserLookupCache userLookupCache = new TestUserLookupCache();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(GameHost host, AudioManager audio)
|
||||
{
|
||||
@@ -231,7 +235,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
assertDownloadButtonVisible(false);
|
||||
|
||||
void assertDownloadButtonVisible(bool visible) => AddUntilStep($"download button {(visible ? "shown" : "hidden")}",
|
||||
() => playlist.ChildrenOfType<BeatmapPanelDownloadButton>().Single().Alpha == (visible ? 1 : 0));
|
||||
() => playlist.ChildrenOfType<BeatmapDownloadButton>().Single().Alpha == (visible ? 1 : 0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -245,7 +249,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
createPlaylist(byOnlineId, byChecksum);
|
||||
|
||||
AddAssert("download buttons shown", () => playlist.ChildrenOfType<BeatmapPanelDownloadButton>().All(d => d.IsPresent));
|
||||
AddAssert("download buttons shown", () => playlist.ChildrenOfType<BeatmapDownloadButton>().All(d => d.IsPresent));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -260,6 +264,59 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
createPlaylist(beatmap);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestExpiredItems()
|
||||
{
|
||||
AddStep("create playlist", () =>
|
||||
{
|
||||
Child = playlist = new TestPlaylist(false, false)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500, 300),
|
||||
Items =
|
||||
{
|
||||
new PlaylistItem
|
||||
{
|
||||
ID = 0,
|
||||
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
Expired = true,
|
||||
RequiredMods =
|
||||
{
|
||||
new OsuModHardRock(),
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModAutoplay()
|
||||
}
|
||||
},
|
||||
new PlaylistItem
|
||||
{
|
||||
ID = 1,
|
||||
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
RequiredMods =
|
||||
{
|
||||
new OsuModHardRock(),
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModAutoplay()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded));
|
||||
}
|
||||
|
||||
[TestCase(false)]
|
||||
[TestCase(true)]
|
||||
public void TestWithOwner(bool withOwner)
|
||||
{
|
||||
createPlaylist(false, false, withOwner);
|
||||
|
||||
AddAssert("owner visible", () => playlist.ChildrenOfType<UpdateableAvatar>().All(a => a.IsPresent == withOwner));
|
||||
}
|
||||
|
||||
private void moveToItem(int index, Vector2? offset = null)
|
||||
=> AddStep($"move mouse to item {index}", () => InputManager.MoveMouseTo(playlist.ChildrenOfType<DifficultyIcon>().ElementAt(index), offset));
|
||||
|
||||
@@ -280,13 +337,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
() => (playlist.ChildrenOfType<OsuRearrangeableListItem<PlaylistItem>.PlaylistItemHandle>().ElementAt(index).Alpha > 0) == visible);
|
||||
|
||||
private void assertDeleteButtonVisibility(int index, bool visible)
|
||||
=> AddAssert($"delete button {index} {(visible ? "is" : "is not")} visible", () => (playlist.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistRemoveButton>().ElementAt(2 + index * 2).Alpha > 0) == visible);
|
||||
=> AddAssert($"delete button {index} {(visible ? "is" : "is not")} visible",
|
||||
() => (playlist.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistRemoveButton>().ElementAt(2 + index * 2).Alpha > 0) == visible);
|
||||
|
||||
private void createPlaylist(bool allowEdit, bool allowSelection)
|
||||
private void createPlaylist(bool allowEdit, bool allowSelection, bool showItemOwner = false)
|
||||
{
|
||||
AddStep("create playlist", () =>
|
||||
{
|
||||
Child = playlist = new TestPlaylist(allowEdit, allowSelection)
|
||||
Child = playlist = new TestPlaylist(allowEdit, allowSelection, showItemOwner)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@@ -298,6 +356,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
playlist.Items.Add(new PlaylistItem
|
||||
{
|
||||
ID = i,
|
||||
OwnerID = 2,
|
||||
Beatmap =
|
||||
{
|
||||
Value = i % 2 == 1
|
||||
@@ -345,6 +404,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
playlist.Items.Add(new PlaylistItem
|
||||
{
|
||||
ID = index++,
|
||||
OwnerID = 2,
|
||||
Beatmap = { Value = b },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
RequiredMods =
|
||||
@@ -364,8 +424,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public new IReadOnlyDictionary<PlaylistItem, RearrangeableListItem<PlaylistItem>> ItemMap => base.ItemMap;
|
||||
|
||||
public TestPlaylist(bool allowEdit, bool allowSelection)
|
||||
: base(allowEdit, allowSelection)
|
||||
public TestPlaylist(bool allowEdit, bool allowSelection, bool showItemOwner = false)
|
||||
: base(allowEdit, allowSelection, showItemOwner: showItemOwner)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
// 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;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneHostOnlyQueueMode : QueueModeTestScene
|
||||
{
|
||||
protected override QueueMode Mode => QueueMode.HostOnly;
|
||||
|
||||
[Test]
|
||||
public void TestFirstItemSelectedByDefault()
|
||||
{
|
||||
AddAssert("first item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestItemStillSelectedAfterChangeToSameBeatmap()
|
||||
{
|
||||
selectNewItem(() => InitialBeatmap);
|
||||
|
||||
AddAssert("playlist item still selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestItemStillSelectedAfterChangeToOtherBeatmap()
|
||||
{
|
||||
selectNewItem(() => OtherBeatmap);
|
||||
|
||||
AddAssert("playlist item still selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNewItemCreatedAfterGameplayFinished()
|
||||
{
|
||||
RunGameplay();
|
||||
|
||||
AddAssert("playlist contains two items", () => Client.APIRoom?.Playlist.Count == 2);
|
||||
AddAssert("first playlist item expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
||||
AddAssert("second playlist item not expired", () => Client.APIRoom?.Playlist[1].Expired == false);
|
||||
AddAssert("second playlist item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[1].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOnlyLastItemChangedAfterGameplayFinished()
|
||||
{
|
||||
RunGameplay();
|
||||
|
||||
IBeatmapInfo firstBeatmap = null;
|
||||
AddStep("get first playlist item beatmap", () => firstBeatmap = Client.APIRoom?.Playlist[0].Beatmap.Value);
|
||||
|
||||
selectNewItem(() => OtherBeatmap);
|
||||
|
||||
AddAssert("first playlist item hasn't changed", () => Client.APIRoom?.Playlist[0].Beatmap.Value == firstBeatmap);
|
||||
AddAssert("second playlist item changed", () => Client.APIRoom?.Playlist[1].Beatmap.Value != firstBeatmap);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSettingsUpdatedWhenChangingQueueMode()
|
||||
{
|
||||
AddStep("change queue mode", () => Client.ChangeSettings(new MultiplayerRoomSettings
|
||||
{
|
||||
QueueMode = QueueMode.AllPlayers
|
||||
}));
|
||||
|
||||
AddUntilStep("api room updated", () => Client.APIRoom?.QueueMode.Value == QueueMode.AllPlayers);
|
||||
}
|
||||
|
||||
private void selectNewItem(Func<BeatmapInfo> beatmap)
|
||||
{
|
||||
AddStep("click edit button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen>().Single().AddOrEditPlaylistButton);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
|
||||
|
||||
BeatmapInfo otherBeatmap = null;
|
||||
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(otherBeatmap = beatmap()));
|
||||
|
||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||
AddUntilStep("selected item is new beatmap", () => Client.CurrentMatchPlayingItem.Value?.Beatmap.Value?.OnlineID == otherBeatmap.OnlineID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.OnlinePlay.Components;
|
||||
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
||||
using osu.Game.Screens.OnlinePlay.Match;
|
||||
@@ -203,7 +204,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
// edit playlist item
|
||||
AddStep("Press select", () => InputManager.Key(Key.Enter));
|
||||
AddUntilStep("wait for song select", () => InputManager.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault() != null);
|
||||
AddUntilStep("wait for song select", () => InputManager.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
||||
|
||||
// select beatmap
|
||||
AddStep("Press select", () => InputManager.Key(Key.Enter));
|
||||
@@ -213,7 +214,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("Press select", () => InputManager.Key(Key.Enter));
|
||||
|
||||
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
||||
AddUntilStep("wait for join", () => client.Room != null);
|
||||
AddUntilStep("wait for join", () => roomManager.RoomJoined);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -252,7 +253,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
}
|
||||
}
|
||||
});
|
||||
}, API.LocalUser.Value);
|
||||
});
|
||||
|
||||
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||
@@ -282,7 +283,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
}
|
||||
}
|
||||
});
|
||||
}, API.LocalUser.Value);
|
||||
});
|
||||
|
||||
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||
@@ -292,7 +293,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("join room", () => InputManager.Key(Key.Enter));
|
||||
|
||||
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
||||
AddUntilStep("wait for join", () => client.Room != null);
|
||||
AddUntilStep("wait for join", () => roomManager.RoomJoined);
|
||||
|
||||
AddAssert("Check participant count correct", () => client.APIRoom?.ParticipantCount.Value == 1);
|
||||
AddAssert("Check participant list contains user", () => client.APIRoom?.RecentParticipants.Count(u => u.Id == API.LocalUser.Value.Id) == 1);
|
||||
@@ -335,7 +336,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
}
|
||||
}
|
||||
});
|
||||
}, API.LocalUser.Value);
|
||||
});
|
||||
|
||||
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||
@@ -350,7 +351,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
|
||||
|
||||
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
||||
AddUntilStep("wait for join", () => client.Room != null);
|
||||
AddUntilStep("wait for join", () => roomManager.RoomJoined);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -579,6 +580,54 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddUntilStep("wait for results", () => multiplayerScreenStack.CurrentScreen is ResultsScreen);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRoomSettingsReQueriedWhenJoiningRoom()
|
||||
{
|
||||
AddStep("create room", () =>
|
||||
{
|
||||
roomManager.AddServerSideRoom(new Room
|
||||
{
|
||||
Name = { Value = "Test Room" },
|
||||
QueueMode = { Value = QueueMode.AllPlayers },
|
||||
Playlist =
|
||||
{
|
||||
new PlaylistItem
|
||||
{
|
||||
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
}
|
||||
}
|
||||
}, API.LocalUser.Value);
|
||||
});
|
||||
|
||||
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||
AddUntilStep("wait for room", () => this.ChildrenOfType<DrawableRoom>().Any());
|
||||
AddStep("select room", () => InputManager.Key(Key.Down));
|
||||
|
||||
AddStep("disable polling", () => this.ChildrenOfType<ListingPollingComponent>().Single().TimeBetweenPolls.Value = 0);
|
||||
AddStep("change server-side settings", () =>
|
||||
{
|
||||
roomManager.ServerSideRooms[0].Name.Value = "New name";
|
||||
roomManager.ServerSideRooms[0].Playlist.Add(new PlaylistItem
|
||||
{
|
||||
ID = 2,
|
||||
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
});
|
||||
});
|
||||
|
||||
AddStep("join room", () => InputManager.Key(Key.Enter));
|
||||
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
||||
AddUntilStep("wait for join", () => roomManager.RoomJoined);
|
||||
|
||||
AddAssert("local room has correct settings", () =>
|
||||
{
|
||||
var localRoom = this.ChildrenOfType<MultiplayerMatchSubScreen>().Single().Room;
|
||||
return localRoom.Name.Value == roomManager.ServerSideRooms[0].Name.Value
|
||||
&& localRoom.Playlist.SequenceEqual(roomManager.ServerSideRooms[0].Playlist);
|
||||
});
|
||||
}
|
||||
|
||||
private MultiplayerReadyButton readyButton => this.ChildrenOfType<MultiplayerReadyButton>().Single();
|
||||
|
||||
private void createRoom(Func<Room> room)
|
||||
@@ -595,7 +644,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for join", () => client.Room != null);
|
||||
AddUntilStep("wait for join", () => roomManager.RoomJoined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,21 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
beatmaps = new List<BeatmapInfo>();
|
||||
|
||||
var metadata = new BeatmapMetadata
|
||||
{
|
||||
Artist = "Some Artist",
|
||||
Title = "Some Beatmap",
|
||||
AuthorString = "Some Author"
|
||||
};
|
||||
|
||||
var beatmapSetInfo = new BeatmapSetInfo
|
||||
{
|
||||
OnlineID = 10,
|
||||
Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
Metadata = metadata,
|
||||
DateAdded = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
int beatmapId = 10 * 10 + i;
|
||||
@@ -54,29 +69,21 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
int length = RNG.Next(30000, 200000);
|
||||
double bpm = RNG.NextSingle(80, 200);
|
||||
|
||||
beatmaps.Add(new BeatmapInfo
|
||||
var beatmap = new BeatmapInfo
|
||||
{
|
||||
Ruleset = rulesets.GetRuleset(i % 4),
|
||||
OnlineID = beatmapId,
|
||||
Length = length,
|
||||
BPM = bpm,
|
||||
Metadata = metadata,
|
||||
BaseDifficulty = new BeatmapDifficulty()
|
||||
});
|
||||
};
|
||||
|
||||
beatmaps.Add(beatmap);
|
||||
beatmapSetInfo.Beatmaps.Add(beatmap);
|
||||
}
|
||||
|
||||
manager.Import(new BeatmapSetInfo
|
||||
{
|
||||
OnlineID = 10,
|
||||
Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Artist = "Some Artist",
|
||||
Title = "Some Beatmap",
|
||||
AuthorString = "Some Author"
|
||||
},
|
||||
Beatmaps = beatmaps,
|
||||
DateAdded = DateTimeOffset.UtcNow
|
||||
}).Wait();
|
||||
manager.Import(beatmapSetInfo).Wait();
|
||||
}
|
||||
|
||||
public override void SetUpSteps()
|
||||
@@ -91,7 +98,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
});
|
||||
|
||||
AddStep("create song select", () => LoadScreen(songSelect = new TestMultiplayerMatchSongSelect(SelectedRoom.Value)));
|
||||
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen());
|
||||
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen() && songSelect.BeatmapSetsLoaded);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -137,7 +144,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("set mods", () => SelectedMods.Value = new[] { new TaikoModDoubleTime() });
|
||||
|
||||
AddStep("confirm selection", () => songSelect.FinaliseSelection());
|
||||
AddStep("exit song select", () => songSelect.Exit());
|
||||
|
||||
AddUntilStep("song select exited", () => !songSelect.IsCurrentScreen());
|
||||
|
||||
AddAssert("beatmap not changed", () => Beatmap.Value.BeatmapInfo.Equals(selectedBeatmap));
|
||||
AddAssert("ruleset not changed", () => Ruleset.Value.Equals(new TaikoRuleset().RulesetInfo));
|
||||
|
||||
@@ -62,22 +62,23 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
[Test]
|
||||
public void TestCreatedRoom()
|
||||
{
|
||||
AddStep("set playlist", () =>
|
||||
AddStep("create room", () =>
|
||||
{
|
||||
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
||||
{
|
||||
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
});
|
||||
|
||||
// Needs to run after components update with the playlist item.
|
||||
Schedule(() =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
});
|
||||
|
||||
AddStep("click create button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for join", () => Client.Room != null);
|
||||
AddUntilStep("wait for join", () => RoomJoined);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -115,7 +116,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for room join", () => Client.Room != null);
|
||||
AddUntilStep("wait for room join", () => RoomJoined);
|
||||
|
||||
AddStep("join other user (ready)", () =>
|
||||
{
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
|
||||
@@ -27,6 +29,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
Stack.Push(player = new MultiplayerPlayer(Client.APIRoom, Client.CurrentMatchPlayingItem.Value, Client.Room?.Users.ToArray()));
|
||||
});
|
||||
|
||||
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen() && player.IsLoaded);
|
||||
AddStep("start gameplay", () => ((IMultiplayerClient)Client).MatchStarted());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -9,6 +9,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
@@ -198,11 +199,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
}, users);
|
||||
}
|
||||
|
||||
private void addClickButtonStep() => AddStep("click button", () =>
|
||||
private void addClickButtonStep()
|
||||
{
|
||||
InputManager.MoveMouseTo(button);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
AddUntilStep("wait for button to be ready", () => button.ChildrenOfType<Button>().Single().Enabled.Value);
|
||||
AddStep("click button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(button);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
}
|
||||
|
||||
private void verifyGameplayStartFlow()
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
PlaylistItem playlistItem = new PlaylistItem
|
||||
{
|
||||
BeatmapID = beatmapInfo.ID,
|
||||
BeatmapID = beatmapInfo.OnlineID ?? -1,
|
||||
};
|
||||
|
||||
Stack.Push(screen = new MultiplayerResultsScreen(score, 1, playlistItem));
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
PlaylistItem playlistItem = new PlaylistItem
|
||||
{
|
||||
BeatmapID = beatmapInfo.ID,
|
||||
BeatmapID = beatmapInfo.OnlineID ?? -1,
|
||||
};
|
||||
|
||||
SortedDictionary<int, BindableInt> teamScores = new SortedDictionary<int, BindableInt>
|
||||
|
||||
@@ -2,14 +2,10 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Utils;
|
||||
@@ -21,6 +17,7 @@ using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.OnlinePlay.Components;
|
||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osu.Game.Tests.Visual.OnlinePlay;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
@@ -42,43 +39,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
|
||||
|
||||
var beatmaps = new List<BeatmapInfo>();
|
||||
var beatmapSet = TestResources.CreateTestBeatmapSetInfo();
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int beatmapId = 10 * 10 + i;
|
||||
|
||||
int length = RNG.Next(30000, 200000);
|
||||
double bpm = RNG.NextSingle(80, 200);
|
||||
|
||||
beatmaps.Add(new BeatmapInfo
|
||||
{
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
OnlineID = beatmapId,
|
||||
DifficultyName = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
|
||||
Length = length,
|
||||
BPM = bpm,
|
||||
BaseDifficulty = new BeatmapDifficulty
|
||||
{
|
||||
OverallDifficulty = 3.5f,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
manager.Import(new BeatmapSetInfo
|
||||
{
|
||||
OnlineID = 10,
|
||||
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
// Create random metadata, then we can check if sorting works based on these
|
||||
Artist = "Some Artist " + RNG.Next(0, 9),
|
||||
Title = $"Some Song (set id 10), max bpm {beatmaps.Max(b => b.BPM):0.#})",
|
||||
AuthorString = "Some Guy " + RNG.Next(0, 9),
|
||||
},
|
||||
Beatmaps = beatmaps,
|
||||
DateAdded = DateTimeOffset.UtcNow,
|
||||
}).Wait();
|
||||
manager.Import(beatmapSet).Wait();
|
||||
}
|
||||
|
||||
public override void SetUpSteps()
|
||||
@@ -94,7 +57,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
});
|
||||
|
||||
AddStep("create song select", () => LoadScreen(songSelect = new TestPlaylistsSongSelect(SelectedRoom.Value)));
|
||||
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen());
|
||||
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen() && songSelect.BeatmapSetsLoaded);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -11,6 +11,7 @@ using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets;
|
||||
@@ -118,6 +119,33 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddAssert("user still on team 0", () => (client.Room?.Users.FirstOrDefault()?.MatchState as TeamVersusUserState)?.TeamID == 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSettingsUpdatedWhenChangingMatchType()
|
||||
{
|
||||
createRoom(() => new Room
|
||||
{
|
||||
Name = { Value = "Test Room" },
|
||||
Type = { Value = MatchType.HeadToHead },
|
||||
Playlist =
|
||||
{
|
||||
new PlaylistItem
|
||||
{
|
||||
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AddUntilStep("match type head to head", () => client.APIRoom?.Type.Value == MatchType.HeadToHead);
|
||||
|
||||
AddStep("change match type", () => client.ChangeSettings(new MultiplayerRoomSettings
|
||||
{
|
||||
MatchType = MatchType.TeamVersus
|
||||
}));
|
||||
|
||||
AddUntilStep("api room updated to team versus", () => client.APIRoom?.Type.Value == MatchType.TeamVersus);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestChangeTypeViaMatchSettings()
|
||||
{
|
||||
@@ -152,13 +180,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
||||
AddWaitStep("wait for transition", 2);
|
||||
|
||||
AddUntilStep("create room button enabled", () => this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single().Enabled.Value);
|
||||
AddStep("create room", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for join", () => client.Room != null);
|
||||
AddUntilStep("wait for join", () => multiplayerScreenStack.RoomManager.RoomJoined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// 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.Screens;
|
||||
@@ -110,7 +109,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
Hash = Guid.NewGuid().ToString(),
|
||||
OnlineID = i,
|
||||
Metadata = metadata,
|
||||
Beatmaps = new List<BeatmapInfo>
|
||||
Beatmaps =
|
||||
{
|
||||
new BeatmapInfo
|
||||
{
|
||||
@@ -141,7 +140,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
|
||||
AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect);
|
||||
AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapSetInfo.MatchesOnlineID(getImport()));
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Beatmaps.First().Ruleset.ID);
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.Equals(getImport().Beatmaps.First().Ruleset));
|
||||
}
|
||||
|
||||
private void presentSecondDifficultyAndConfirm(Func<BeatmapSetInfo> getImport, int importedID)
|
||||
@@ -151,7 +150,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
|
||||
AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect);
|
||||
AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.OnlineID == importedID * 2048);
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Beatmaps.First().Ruleset.ID);
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.Equals(getImport().Beatmaps.First().Ruleset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// 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.Screens;
|
||||
@@ -41,7 +40,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
Hash = Guid.NewGuid().ToString(),
|
||||
OnlineID = 1,
|
||||
Metadata = metadata,
|
||||
Beatmaps = new List<BeatmapInfo>
|
||||
Beatmaps =
|
||||
{
|
||||
new BeatmapInfo
|
||||
{
|
||||
@@ -155,15 +154,15 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
case ScorePresentType.Results:
|
||||
AddUntilStep("wait for results", () => lastWaitedScreen != Game.ScreenStack.CurrentScreen && Game.ScreenStack.CurrentScreen is ResultsScreen);
|
||||
AddStep("store last waited screen", () => lastWaitedScreen = Game.ScreenStack.CurrentScreen);
|
||||
AddUntilStep("correct score displayed", () => ((ResultsScreen)Game.ScreenStack.CurrentScreen).Score.ID == getImport().ID);
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Ruleset.ID);
|
||||
AddUntilStep("correct score displayed", () => ((ResultsScreen)Game.ScreenStack.CurrentScreen).Score.Equals(getImport()));
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.Equals(getImport().Ruleset));
|
||||
break;
|
||||
|
||||
case ScorePresentType.Gameplay:
|
||||
AddUntilStep("wait for player loader", () => lastWaitedScreen != Game.ScreenStack.CurrentScreen && Game.ScreenStack.CurrentScreen is ReplayPlayerLoader);
|
||||
AddStep("store last waited screen", () => lastWaitedScreen = Game.ScreenStack.CurrentScreen);
|
||||
AddUntilStep("correct score displayed", () => ((ReplayPlayerLoader)Game.ScreenStack.CurrentScreen).Score.ID == getImport().ID);
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Ruleset.ID);
|
||||
AddUntilStep("correct score displayed", () => ((ReplayPlayerLoader)Game.ScreenStack.CurrentScreen).Score.Equals(getImport()));
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.Equals(getImport().Ruleset));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,9 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
{
|
||||
Player player = null;
|
||||
|
||||
PushAndConfirm(() => new TestPlaySongSelect());
|
||||
Screens.Select.SongSelect songSelect = null;
|
||||
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
|
||||
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
|
||||
|
||||
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
|
||||
|
||||
@@ -98,7 +100,9 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
|
||||
IWorkingBeatmap beatmap() => Game.Beatmap.Value;
|
||||
|
||||
PushAndConfirm(() => new TestPlaySongSelect());
|
||||
Screens.Select.SongSelect songSelect = null;
|
||||
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
|
||||
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
|
||||
|
||||
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
|
||||
|
||||
@@ -130,7 +134,9 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
|
||||
IWorkingBeatmap beatmap() => Game.Beatmap.Value;
|
||||
|
||||
PushAndConfirm(() => new TestPlaySongSelect());
|
||||
Screens.Select.SongSelect songSelect = null;
|
||||
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
|
||||
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
|
||||
|
||||
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
|
||||
|
||||
@@ -257,7 +263,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
InputManager.ReleaseKey(Key.ControlLeft);
|
||||
});
|
||||
|
||||
AddAssert("Ruleset changed to osu!taiko", () => Game.Toolbar.ChildrenOfType<ToolbarRulesetSelector>().Single().Current.Value.ID == 1);
|
||||
AddAssert("Ruleset changed to osu!taiko", () => Game.Toolbar.ChildrenOfType<ToolbarRulesetSelector>().Single().Current.Value.OnlineID == 1);
|
||||
|
||||
AddAssert("Mods overlay still visible", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
|
||||
}
|
||||
@@ -278,7 +284,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
InputManager.ReleaseKey(Key.ControlLeft);
|
||||
});
|
||||
|
||||
AddAssert("Ruleset changed to osu!taiko", () => Game.Toolbar.ChildrenOfType<ToolbarRulesetSelector>().Single().Current.Value.ID == 1);
|
||||
AddAssert("Ruleset changed to osu!taiko", () => Game.Toolbar.ChildrenOfType<ToolbarRulesetSelector>().Single().Current.Value.OnlineID == 1);
|
||||
|
||||
AddAssert("Options overlay still visible", () => songSelect.BeatmapOptionsOverlay.State.Value == Visibility.Visible);
|
||||
}
|
||||
|
||||
+3
-3
@@ -6,15 +6,15 @@ using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Online;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays.BeatmapListing.Panels;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public class TestSceneDirectDownloadButton : OsuTestScene
|
||||
public class TestSceneBeatmapDownloadButton : OsuTestScene
|
||||
{
|
||||
private TestDownloadButton downloadButton;
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
return apiBeatmapSet;
|
||||
}
|
||||
|
||||
private class TestDownloadButton : BeatmapPanelDownloadButton
|
||||
private class TestDownloadButton : BeatmapDownloadButton
|
||||
{
|
||||
public new bool DownloadEnabled => base.DownloadEnabled;
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
OnlineID = i * 10,
|
||||
DifficultyName = $"Test #{i}",
|
||||
RulesetID = Ruleset.Value.ID ?? -1,
|
||||
RulesetID = Ruleset.Value.OnlineID,
|
||||
StarRating = 2 + i * 0.1,
|
||||
OverallDifficulty = 3.5f,
|
||||
FailTimes = new APIFailTimes
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
}
|
||||
},
|
||||
Ratings = Enumerable.Range(0, 11).Select(_ => RNG.Next(10)).ToArray(),
|
||||
Status = BeatmapSetOnlineStatus.Ranked
|
||||
Status = BeatmapOnlineStatus.Ranked
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
// 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.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays.BeatmapListing.Panels;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
[Cached(typeof(IPreviewTrackOwner))]
|
||||
public class TestSceneDirectPanel : OsuTestScene, IPreviewTrackOwner
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
var normal = getBeatmapSet();
|
||||
normal.HasVideo = true;
|
||||
normal.HasStoryboard = true;
|
||||
|
||||
var undownloadable = getUndownloadableBeatmapSet();
|
||||
var manyDifficulties = getManyDifficultiesBeatmapSet();
|
||||
|
||||
var explicitMap = getBeatmapSet();
|
||||
explicitMap.HasExplicitContent = true;
|
||||
|
||||
var featuredMap = getBeatmapSet();
|
||||
featuredMap.TrackId = 1;
|
||||
|
||||
var explicitFeaturedMap = getBeatmapSet();
|
||||
explicitFeaturedMap.HasExplicitContent = true;
|
||||
explicitFeaturedMap.TrackId = 2;
|
||||
|
||||
Child = new BasicScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Full,
|
||||
Padding = new MarginPadding(20),
|
||||
Spacing = new Vector2(5, 20),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new GridBeatmapPanel(normal),
|
||||
new GridBeatmapPanel(undownloadable),
|
||||
new GridBeatmapPanel(manyDifficulties),
|
||||
new GridBeatmapPanel(explicitMap),
|
||||
new GridBeatmapPanel(featuredMap),
|
||||
new GridBeatmapPanel(explicitFeaturedMap),
|
||||
new ListBeatmapPanel(normal),
|
||||
new ListBeatmapPanel(undownloadable),
|
||||
new ListBeatmapPanel(manyDifficulties),
|
||||
new ListBeatmapPanel(explicitMap),
|
||||
new ListBeatmapPanel(featuredMap),
|
||||
new ListBeatmapPanel(explicitFeaturedMap)
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
APIBeatmapSet getBeatmapSet() => CreateAPIBeatmapSet(Ruleset.Value);
|
||||
|
||||
APIBeatmapSet getUndownloadableBeatmapSet() => new APIBeatmapSet
|
||||
{
|
||||
OnlineID = 123,
|
||||
Title = "undownloadable beatmap",
|
||||
Artist = "test",
|
||||
Source = "more tests",
|
||||
Author = new APIUser
|
||||
{
|
||||
Username = "BanchoBot",
|
||||
Id = 3,
|
||||
},
|
||||
Availability = new BeatmapSetOnlineAvailability
|
||||
{
|
||||
DownloadDisabled = true,
|
||||
},
|
||||
Preview = @"https://b.ppy.sh/preview/12345.mp3",
|
||||
PlayCount = 123,
|
||||
FavouriteCount = 456,
|
||||
BPM = 111,
|
||||
HasVideo = true,
|
||||
HasStoryboard = true,
|
||||
Covers = new BeatmapSetOnlineCovers(),
|
||||
Beatmaps = new[]
|
||||
{
|
||||
new APIBeatmap
|
||||
{
|
||||
RulesetID = Ruleset.Value.ID ?? 0,
|
||||
DifficultyName = "Test",
|
||||
StarRating = 6.42,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
APIBeatmapSet getManyDifficultiesBeatmapSet()
|
||||
{
|
||||
var beatmaps = new List<APIBeatmap>();
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
beatmaps.Add(new APIBeatmap
|
||||
{
|
||||
RulesetID = i % 4,
|
||||
StarRating = 2 + i % 4 * 2,
|
||||
OverallDifficulty = 3.5f,
|
||||
});
|
||||
}
|
||||
|
||||
return new APIBeatmapSet
|
||||
{
|
||||
OnlineID = 1,
|
||||
Title = "undownloadable beatmap",
|
||||
Artist = "test",
|
||||
Source = "more tests",
|
||||
Author = new APIUser
|
||||
{
|
||||
Username = "BanchoBot",
|
||||
Id = 3,
|
||||
},
|
||||
HasVideo = true,
|
||||
HasStoryboard = true,
|
||||
Covers = new BeatmapSetOnlineCovers(),
|
||||
Beatmaps = beatmaps.ToArray(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
|
||||
AddStep("Set beatmap", () => Beatmap.Value = new DummyWorkingBeatmap(Audio, null)
|
||||
{
|
||||
BeatmapInfo = { OnlineID = hasOnlineId ? 1234 : (int?)null }
|
||||
BeatmapInfo = { OnlineID = hasOnlineId ? 1234 : -1 }
|
||||
});
|
||||
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand()));
|
||||
|
||||
@@ -338,7 +338,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
||||
: base(score, true)
|
||||
{
|
||||
Score.BeatmapInfo.OnlineID = 0;
|
||||
Score.BeatmapInfo.Status = BeatmapSetOnlineStatus.Pending;
|
||||
Score.BeatmapInfo.Status = BeatmapOnlineStatus.Pending;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
// 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.Graphics.UserInterface;
|
||||
using osu.Game.Overlays.Settings;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Settings
|
||||
{
|
||||
public class TestSceneSettingsNumberBox : OsuTestScene
|
||||
{
|
||||
private SettingsNumberBox numberBox;
|
||||
private OsuTextBox textBox;
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
{
|
||||
AddStep("create number box", () => Child = numberBox = new SettingsNumberBox());
|
||||
AddStep("get inner text box", () => textBox = numberBox.ChildrenOfType<OsuTextBox>().Single());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLargeInteger()
|
||||
{
|
||||
AddStep("set current to 1,000,000,000", () => numberBox.Current.Value = 1_000_000_000);
|
||||
AddAssert("text box text is correct", () => textBox.Text == "1000000000");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUserInput()
|
||||
{
|
||||
inputText("42");
|
||||
currentValueIs(42);
|
||||
currentTextIs("42");
|
||||
|
||||
inputText(string.Empty);
|
||||
currentValueIs(null);
|
||||
currentTextIs(string.Empty);
|
||||
|
||||
inputText("555");
|
||||
currentValueIs(555);
|
||||
currentTextIs("555");
|
||||
|
||||
inputText("-4444");
|
||||
// attempting to input the minus will raise an input error, the rest will pass through fine.
|
||||
currentValueIs(4444);
|
||||
currentTextIs("4444");
|
||||
|
||||
// checking the upper bound.
|
||||
inputText(int.MaxValue.ToString());
|
||||
currentValueIs(int.MaxValue);
|
||||
currentTextIs(int.MaxValue.ToString());
|
||||
|
||||
inputText(smallestOverflowValue.ToString());
|
||||
currentValueIs(int.MaxValue);
|
||||
currentTextIs(int.MaxValue.ToString());
|
||||
|
||||
inputText("0");
|
||||
currentValueIs(0);
|
||||
currentTextIs("0");
|
||||
|
||||
// checking that leading zeroes are stripped.
|
||||
inputText("00");
|
||||
currentValueIs(0);
|
||||
currentTextIs("0");
|
||||
|
||||
inputText("01");
|
||||
currentValueIs(1);
|
||||
currentTextIs("1");
|
||||
}
|
||||
|
||||
private void inputText(string text) => AddStep($"set textbox text to {text}", () => textBox.Text = text);
|
||||
private void currentValueIs(int? value) => AddAssert($"current value is {value?.ToString() ?? "null"}", () => numberBox.Current.Value == value);
|
||||
private void currentTextIs(string value) => AddAssert($"current text is {value}", () => textBox.Text == value);
|
||||
|
||||
/// <summary>
|
||||
/// The smallest number that overflows <see langword="int"/>.
|
||||
/// </summary>
|
||||
private static long smallestOverflowValue => 1L + int.MaxValue;
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets;
|
||||
@@ -19,6 +15,7 @@ using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Select.Carousel;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.SongSelect
|
||||
@@ -78,9 +75,9 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
AddStep("store selection", () => selection = carousel.SelectedBeatmapInfo);
|
||||
if (isIterating)
|
||||
AddUntilStep("selection changed", () => carousel.SelectedBeatmapInfo != selection);
|
||||
AddUntilStep("selection changed", () => !carousel.SelectedBeatmapInfo.Equals(selection));
|
||||
else
|
||||
AddUntilStep("selection not changed", () => carousel.SelectedBeatmapInfo == selection);
|
||||
AddUntilStep("selection not changed", () => carousel.SelectedBeatmapInfo.Equals(selection));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,7 +149,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
const int total_set_count = 200;
|
||||
|
||||
for (int i = 0; i < total_set_count; i++)
|
||||
sets.Add(createTestBeatmapSet(i + 1));
|
||||
sets.Add(TestResources.CreateTestBeatmapSetInfo());
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
@@ -183,7 +180,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
const int total_set_count = 20;
|
||||
|
||||
for (int i = 0; i < total_set_count; i++)
|
||||
sets.Add(createTestBeatmapSet(i + 1));
|
||||
sets.Add(TestResources.CreateTestBeatmapSetInfo(3));
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
@@ -228,10 +225,9 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
loadBeatmaps();
|
||||
|
||||
// basic filtering
|
||||
|
||||
setSelected(1, 1);
|
||||
|
||||
AddStep("Filter", () => carousel.Filter(new FilterCriteria { SearchText = "set #3!" }, false));
|
||||
AddStep("Filter", () => carousel.Filter(new FilterCriteria { SearchText = carousel.BeatmapSets.ElementAt(2).Metadata.Title }, false));
|
||||
checkVisibleItemCount(diff: false, count: 1);
|
||||
checkVisibleItemCount(diff: true, count: 3);
|
||||
waitForSelection(3, 1);
|
||||
@@ -275,16 +271,20 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
[Test]
|
||||
public void TestFilterRange()
|
||||
{
|
||||
string searchText = null;
|
||||
|
||||
loadBeatmaps();
|
||||
|
||||
// buffer the selection
|
||||
setSelected(3, 2);
|
||||
|
||||
AddStep("get search text", () => searchText = carousel.SelectedBeatmapSet.Metadata.Title);
|
||||
|
||||
setSelected(1, 3);
|
||||
|
||||
AddStep("Apply a range filter", () => carousel.Filter(new FilterCriteria
|
||||
{
|
||||
SearchText = "#3",
|
||||
SearchText = searchText,
|
||||
StarDifficulty = new FilterCriteria.OptionalRange<double>
|
||||
{
|
||||
Min = 2,
|
||||
@@ -327,7 +327,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
nextRandom();
|
||||
AddAssert("ensure repeat", () => selectedSets.Contains(carousel.SelectedBeatmapSet));
|
||||
|
||||
AddStep("Add set with 100 difficulties", () => carousel.UpdateBeatmapSet(createTestBeatmapSetWithManyDifficulties(set_count + 1)));
|
||||
AddStep("Add set with 100 difficulties", () => carousel.UpdateBeatmapSet(TestResources.CreateTestBeatmapSetInfo(100, rulesets.AvailableRulesets.ToArray())));
|
||||
AddStep("Filter Extra", () => carousel.Filter(new FilterCriteria { SearchText = "Extra 10" }, false));
|
||||
checkInvisibleDifficultiesUnselectable();
|
||||
checkInvisibleDifficultiesUnselectable();
|
||||
@@ -345,18 +345,21 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
loadBeatmaps();
|
||||
|
||||
AddStep("Add new set", () => carousel.UpdateBeatmapSet(createTestBeatmapSet(set_count + 1)));
|
||||
AddStep("Add new set", () => carousel.UpdateBeatmapSet(createTestBeatmapSet(set_count + 2)));
|
||||
var firstAdded = TestResources.CreateTestBeatmapSetInfo();
|
||||
var secondAdded = TestResources.CreateTestBeatmapSetInfo();
|
||||
|
||||
AddStep("Add new set", () => carousel.UpdateBeatmapSet(firstAdded));
|
||||
AddStep("Add new set", () => carousel.UpdateBeatmapSet(secondAdded));
|
||||
|
||||
checkVisibleItemCount(false, set_count + 2);
|
||||
|
||||
AddStep("Remove set", () => carousel.RemoveBeatmapSet(createTestBeatmapSet(set_count + 2)));
|
||||
AddStep("Remove set", () => carousel.RemoveBeatmapSet(firstAdded));
|
||||
|
||||
checkVisibleItemCount(false, set_count + 1);
|
||||
|
||||
setSelected(set_count + 1, 1);
|
||||
|
||||
AddStep("Remove set", () => carousel.RemoveBeatmapSet(createTestBeatmapSet(set_count + 1)));
|
||||
AddStep("Remove set", () => carousel.RemoveBeatmapSet(secondAdded));
|
||||
|
||||
checkVisibleItemCount(false, set_count);
|
||||
|
||||
@@ -372,7 +375,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
sets.Clear();
|
||||
|
||||
var rulesetBeatmapSet = createTestBeatmapSet(1);
|
||||
var rulesetBeatmapSet = TestResources.CreateTestBeatmapSetInfo(1);
|
||||
var taikoRuleset = rulesets.AvailableRulesets.ElementAt(1);
|
||||
rulesetBeatmapSet.Beatmaps.ForEach(b =>
|
||||
{
|
||||
@@ -397,12 +400,29 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
[Test]
|
||||
public void TestSorting()
|
||||
{
|
||||
loadBeatmaps();
|
||||
var sets = new List<BeatmapSetInfo>();
|
||||
|
||||
const string zzz_string = "zzzzz";
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
var set = TestResources.CreateTestBeatmapSetInfo();
|
||||
|
||||
if (i == 4)
|
||||
set.Metadata.Artist = zzz_string;
|
||||
|
||||
if (i == 16)
|
||||
set.Metadata.AuthorString = zzz_string;
|
||||
|
||||
sets.Add(set);
|
||||
}
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
AddStep("Sort by author", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Author }, false));
|
||||
AddAssert("Check zzzzz is at bottom", () => carousel.BeatmapSets.Last().Metadata.Author.Username == "zzzzz");
|
||||
AddAssert($"Check {zzz_string} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Author.Username == zzz_string);
|
||||
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
|
||||
AddAssert($"Check #{set_count} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Title.EndsWith($"#{set_count}!", StringComparison.Ordinal));
|
||||
AddAssert($"Check {zzz_string} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Artist == zzz_string);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -412,19 +432,21 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
var set = createTestBeatmapSet(i);
|
||||
var set = TestResources.CreateTestBeatmapSetInfo();
|
||||
set.Metadata.Artist = "same artist";
|
||||
set.Metadata.Title = "same title";
|
||||
sets.Add(set);
|
||||
}
|
||||
|
||||
int idOffset = sets.First().OnlineID ?? 0;
|
||||
|
||||
loadBeatmaps(sets);
|
||||
|
||||
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
|
||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.ID == index).All(b => b));
|
||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == index + idOffset).All(b => b));
|
||||
|
||||
AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false));
|
||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.ID == index).All(b => b));
|
||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == index + idOffset).All(b => b));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -434,7 +456,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var set = createTestBeatmapSet(i);
|
||||
var set = TestResources.CreateTestBeatmapSetInfo(3);
|
||||
set.Beatmaps[0].StarRating = 3 - i;
|
||||
set.Beatmaps[2].StarRating = 6 + i;
|
||||
sets.Add(set);
|
||||
@@ -443,12 +465,12 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
loadBeatmaps(sets);
|
||||
|
||||
AddStep("Filter to normal", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Difficulty, SearchText = "Normal" }, false));
|
||||
AddAssert("Check first set at end", () => carousel.BeatmapSets.First() == sets.Last());
|
||||
AddAssert("Check last set at start", () => carousel.BeatmapSets.Last() == sets.First());
|
||||
AddAssert("Check first set at end", () => carousel.BeatmapSets.First().Equals(sets.Last()));
|
||||
AddAssert("Check last set at start", () => carousel.BeatmapSets.Last().Equals(sets.First()));
|
||||
|
||||
AddStep("Filter to insane", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Difficulty, SearchText = "Insane" }, false));
|
||||
AddAssert("Check first set at start", () => carousel.BeatmapSets.First() == sets.First());
|
||||
AddAssert("Check last set at end", () => carousel.BeatmapSets.Last() == sets.Last());
|
||||
AddAssert("Check first set at start", () => carousel.BeatmapSets.First().Equals(sets.First()));
|
||||
AddAssert("Check last set at end", () => carousel.BeatmapSets.Last().Equals(sets.Last()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -503,7 +525,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("create hidden set", () =>
|
||||
{
|
||||
hidingSet = createTestBeatmapSet(1);
|
||||
hidingSet = TestResources.CreateTestBeatmapSetInfo(3);
|
||||
hidingSet.Beatmaps[1].Hidden = true;
|
||||
|
||||
hiddenList.Clear();
|
||||
@@ -550,7 +572,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("add mixed ruleset beatmapset", () =>
|
||||
{
|
||||
testMixed = createTestBeatmapSet(set_count + 1);
|
||||
testMixed = TestResources.CreateTestBeatmapSetInfo(3);
|
||||
|
||||
for (int i = 0; i <= 2; i++)
|
||||
{
|
||||
@@ -573,7 +595,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
BeatmapSetInfo testSingle = null;
|
||||
AddStep("add single ruleset beatmapset", () =>
|
||||
{
|
||||
testSingle = createTestBeatmapSet(set_count + 2);
|
||||
testSingle = TestResources.CreateTestBeatmapSetInfo(3);
|
||||
testSingle.Beatmaps.ForEach(b =>
|
||||
{
|
||||
b.Ruleset = rulesets.AvailableRulesets.ElementAt(1);
|
||||
@@ -593,7 +615,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
List<BeatmapSetInfo> manySets = new List<BeatmapSetInfo>();
|
||||
|
||||
for (int i = 1; i <= 50; i++)
|
||||
manySets.Add(createTestBeatmapSet(i));
|
||||
manySets.Add(TestResources.CreateTestBeatmapSetInfo(3));
|
||||
|
||||
loadBeatmaps(manySets);
|
||||
|
||||
@@ -626,18 +648,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var set = createTestBeatmapSet(i);
|
||||
|
||||
foreach (var b in set.Beatmaps)
|
||||
manySets.Add(TestResources.CreateTestBeatmapSetInfo(3, new[]
|
||||
{
|
||||
// all taiko except for first
|
||||
int ruleset = i > 0 ? 1 : 0;
|
||||
|
||||
b.Ruleset = rulesets.GetRuleset(ruleset);
|
||||
b.RulesetID = ruleset;
|
||||
}
|
||||
|
||||
manySets.Add(set);
|
||||
rulesets.GetRuleset(i > 0 ? 1 : 0)
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -659,10 +674,10 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddStep("Restore different ruleset filter", () =>
|
||||
{
|
||||
carousel.Filter(new FilterCriteria { Ruleset = rulesets.GetRuleset(1) }, false);
|
||||
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID);
|
||||
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.OnlineID ?? -1);
|
||||
});
|
||||
|
||||
AddAssert("selection changed", () => carousel.SelectedBeatmapInfo != manySets.First().Beatmaps.First());
|
||||
AddAssert("selection changed", () => !carousel.SelectedBeatmapInfo.Equals(manySets.First().Beatmaps.First()));
|
||||
}
|
||||
|
||||
AddAssert("Selection was random", () => eagerSelectedIDs.Count > 2);
|
||||
@@ -677,7 +692,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("add mixed difficulty set", () =>
|
||||
{
|
||||
set = createTestBeatmapSet(1);
|
||||
set = TestResources.CreateTestBeatmapSetInfo(1);
|
||||
set.Beatmaps.Clear();
|
||||
|
||||
for (int i = 1; i <= 15; i++)
|
||||
@@ -729,7 +744,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
beatmapSets = new List<BeatmapSetInfo>();
|
||||
|
||||
for (int i = 1; i <= (count ?? set_count); i++)
|
||||
beatmapSets.Add(createTestBeatmapSet(i, randomDifficulties));
|
||||
{
|
||||
beatmapSets.Add(randomDifficulties
|
||||
? TestResources.CreateTestBeatmapSetInfo()
|
||||
: TestResources.CreateTestBeatmapSetInfo(3));
|
||||
}
|
||||
}
|
||||
|
||||
carousel.Filter(initialCriteria?.Invoke() ?? new FilterCriteria());
|
||||
@@ -759,13 +778,13 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
}
|
||||
|
||||
private void ensureRandomFetchSuccess() =>
|
||||
AddAssert("ensure prev random fetch worked", () => selectedSets.Peek() == carousel.SelectedBeatmapSet);
|
||||
AddAssert("ensure prev random fetch worked", () => selectedSets.Peek().Equals(carousel.SelectedBeatmapSet));
|
||||
|
||||
private void waitForSelection(int set, int? diff = null) =>
|
||||
AddUntilStep($"selected is set{set}{(diff.HasValue ? $" diff{diff.Value}" : "")}", () =>
|
||||
{
|
||||
if (diff != null)
|
||||
return carousel.SelectedBeatmapInfo == carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Skip(diff.Value - 1).First();
|
||||
return carousel.SelectedBeatmapInfo?.Equals(carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Skip(diff.Value - 1).First()) == true;
|
||||
|
||||
return carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Contains(carousel.SelectedBeatmapInfo);
|
||||
});
|
||||
@@ -833,88 +852,6 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddAssert("Selection is visible", selectedBeatmapVisible);
|
||||
}
|
||||
|
||||
private BeatmapSetInfo createTestBeatmapSet(int id, bool randomDifficultyCount = false)
|
||||
{
|
||||
return new BeatmapSetInfo
|
||||
{
|
||||
ID = id,
|
||||
OnlineID = id,
|
||||
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
// Create random metadata, then we can check if sorting works based on these
|
||||
Artist = $"peppy{id.ToString().PadLeft(6, '0')}",
|
||||
Title = $"test set #{id}!",
|
||||
AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, id - 1)), 5))
|
||||
},
|
||||
Beatmaps = getBeatmaps(randomDifficultyCount ? RNG.Next(1, 20) : 3).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
private IEnumerable<BeatmapInfo> getBeatmaps(int count)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
float diff = (float)i / count * 10;
|
||||
|
||||
string version = "Normal";
|
||||
if (diff > 6.6)
|
||||
version = "Insane";
|
||||
else if (diff > 3.3)
|
||||
version = "Hard";
|
||||
|
||||
yield return new BeatmapInfo
|
||||
{
|
||||
OnlineID = id++ * 10,
|
||||
DifficultyName = version,
|
||||
StarRating = diff,
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
BaseDifficulty = new BeatmapDifficulty
|
||||
{
|
||||
OverallDifficulty = diff,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private BeatmapSetInfo createTestBeatmapSetWithManyDifficulties(int id)
|
||||
{
|
||||
var toReturn = new BeatmapSetInfo
|
||||
{
|
||||
ID = id,
|
||||
OnlineID = id,
|
||||
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
// Create random metadata, then we can check if sorting works based on these
|
||||
Artist = $"peppy{id.ToString().PadLeft(6, '0')}",
|
||||
Title = $"test set #{id}!",
|
||||
AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, id - 1)), 5))
|
||||
},
|
||||
Beatmaps = new List<BeatmapInfo>(),
|
||||
};
|
||||
|
||||
for (int b = 1; b < 101; b++)
|
||||
{
|
||||
toReturn.Beatmaps.Add(new BeatmapInfo
|
||||
{
|
||||
OnlineID = b * 10,
|
||||
Path = $"extra{b}.osu",
|
||||
DifficultyName = $"Extra {b}",
|
||||
Ruleset = rulesets.GetRuleset((b - 1) % 4),
|
||||
StarRating = 2,
|
||||
BaseDifficulty = new BeatmapDifficulty
|
||||
{
|
||||
OverallDifficulty = 3.5f,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
private class TestBeatmapCarousel : BeatmapCarousel
|
||||
{
|
||||
public bool PendingFilterTask => PendingFilter != null;
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
beatmaps.Add(testBeatmap);
|
||||
|
||||
AddStep("set ruleset", () => Ruleset.Value = rulesetInfo);
|
||||
setRuleset(rulesetInfo);
|
||||
|
||||
selectBeatmap(testBeatmap);
|
||||
|
||||
@@ -167,6 +167,22 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
label => label.Statistic.Name == "BPM" && label.Statistic.Content == target.ToString(CultureInfo.InvariantCulture)));
|
||||
}
|
||||
|
||||
private void setRuleset(RulesetInfo rulesetInfo)
|
||||
{
|
||||
Container containerBefore = null;
|
||||
|
||||
AddStep("set ruleset", () =>
|
||||
{
|
||||
// wedge content is only refreshed if the ruleset changes, so only wait for load in that case.
|
||||
if (!rulesetInfo.Equals(Ruleset.Value))
|
||||
containerBefore = infoWedge.DisplayedContent;
|
||||
|
||||
Ruleset.Value = rulesetInfo;
|
||||
});
|
||||
|
||||
AddUntilStep("wait for async load", () => infoWedge.DisplayedContent != containerBefore);
|
||||
}
|
||||
|
||||
private void selectBeatmap([CanBeNull] IBeatmap b)
|
||||
{
|
||||
Container containerBefore = null;
|
||||
@@ -220,7 +236,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
Title = "Verrrrry long Title"
|
||||
},
|
||||
DifficultyName = "Verrrrrrrrrrrrrrrrrrrrrrrrrrrrry long Version",
|
||||
Status = BeatmapSetOnlineStatus.Graveyard,
|
||||
Status = BeatmapOnlineStatus.Graveyard,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
dependencies.Cache(rulesetStore = new RulesetStore(ContextFactory));
|
||||
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
|
||||
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory, Scheduler));
|
||||
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, ContextFactory, Scheduler));
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
[Test]
|
||||
public void TestBeatmapStates()
|
||||
{
|
||||
foreach (BeatmapSetOnlineStatus status in Enum.GetValues(typeof(BeatmapSetOnlineStatus)))
|
||||
foreach (BeatmapOnlineStatus status in Enum.GetValues(typeof(BeatmapOnlineStatus)))
|
||||
AddStep($"{status} beatmap", () => showBeatmapWithStatus(status));
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
};
|
||||
}
|
||||
|
||||
private void showBeatmapWithStatus(BeatmapSetOnlineStatus status)
|
||||
private void showBeatmapWithStatus(BeatmapOnlineStatus status)
|
||||
{
|
||||
leaderboard.BeatmapInfo = new BeatmapInfo
|
||||
{
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<StarDifficulty> GetDifficultyAsync(IBeatmapInfo beatmapInfo, IRulesetInfo rulesetInfo = null, IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
public override async Task<StarDifficulty?> GetDifficultyAsync(IBeatmapInfo beatmapInfo, IRulesetInfo rulesetInfo = null, IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (blockCalculation)
|
||||
await calculationBlocker.Task.ConfigureAwait(false);
|
||||
|
||||
@@ -16,6 +16,7 @@ using osu.Game.Rulesets.Catch;
|
||||
using osu.Game.Rulesets.Mania;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Taiko;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.SongSelect
|
||||
@@ -32,7 +33,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
switch (req)
|
||||
{
|
||||
case GetUserRequest userRequest:
|
||||
userRequest.TriggerSuccess(getUser(userRequest.Ruleset.ID));
|
||||
userRequest.TriggerSuccess(getUser(userRequest.Ruleset.OnlineID));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -89,7 +90,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
for (int i = 0; i < import_count; ++i)
|
||||
{
|
||||
beatmapSets.Add(importBeatmapSet(i, Enumerable.Repeat(new OsuRuleset().RulesetInfo, 5)));
|
||||
beatmapSets.Add(importBeatmapSet(Enumerable.Repeat(new OsuRuleset().RulesetInfo, 5)));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -103,9 +104,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
BeatmapSetInfo catchSet = null, mixedSet = null;
|
||||
|
||||
AddStep("create catch beatmapset", () => catchSet = importBeatmapSet(1, new[] { new CatchRuleset().RulesetInfo }));
|
||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
|
||||
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
|
||||
AddStep("create catch beatmapset", () => catchSet = importBeatmapSet(new[] { new CatchRuleset().RulesetInfo }));
|
||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
|
||||
|
||||
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { catchSet, mixedSet }));
|
||||
|
||||
@@ -121,9 +121,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
BeatmapSetInfo osuSet = null, mixedSet = null;
|
||||
|
||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
|
||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
|
||||
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
|
||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(new[] { new OsuRuleset().RulesetInfo }));
|
||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
|
||||
|
||||
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet }));
|
||||
|
||||
@@ -139,9 +138,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
BeatmapSetInfo osuSet = null, mixedSet = null;
|
||||
|
||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
|
||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
|
||||
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new TaikoRuleset().RulesetInfo }));
|
||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(new[] { new OsuRuleset().RulesetInfo }));
|
||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new TaikoRuleset().RulesetInfo }));
|
||||
|
||||
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet }));
|
||||
|
||||
@@ -157,8 +155,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
BeatmapSetInfo osuSet = null, maniaSet = null;
|
||||
|
||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
|
||||
AddStep("create mania beatmapset", () => maniaSet = importBeatmapSet(2, Enumerable.Repeat(new ManiaRuleset().RulesetInfo, 10)));
|
||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(new[] { new OsuRuleset().RulesetInfo }));
|
||||
AddStep("create mania beatmapset", () => maniaSet = importBeatmapSet(Enumerable.Repeat(new ManiaRuleset().RulesetInfo, 10)));
|
||||
|
||||
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, maniaSet }));
|
||||
|
||||
@@ -169,30 +167,19 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
presentAndConfirm(() => maniaSet, 5);
|
||||
}
|
||||
|
||||
private BeatmapSetInfo importBeatmapSet(int importID, IEnumerable<RulesetInfo> difficultyRulesets)
|
||||
private BeatmapSetInfo importBeatmapSet(IEnumerable<RulesetInfo> difficultyRulesets)
|
||||
{
|
||||
var metadata = new BeatmapMetadata
|
||||
{
|
||||
Artist = "SomeArtist",
|
||||
AuthorString = "SomeAuthor",
|
||||
Title = $"import {importID}"
|
||||
};
|
||||
var rulesets = difficultyRulesets.ToArray();
|
||||
|
||||
var beatmapSet = new BeatmapSetInfo
|
||||
var beatmapSet = TestResources.CreateTestBeatmapSetInfo(rulesets.Length, rulesets);
|
||||
|
||||
for (int i = 0; i < rulesets.Length; i++)
|
||||
{
|
||||
Hash = Guid.NewGuid().ToString(),
|
||||
OnlineID = importID,
|
||||
Metadata = metadata,
|
||||
Beatmaps = difficultyRulesets.Select((ruleset, difficultyIndex) => new BeatmapInfo
|
||||
{
|
||||
OnlineID = importID * 1024 + difficultyIndex,
|
||||
Metadata = metadata,
|
||||
BaseDifficulty = new BeatmapDifficulty(),
|
||||
Ruleset = ruleset,
|
||||
StarRating = difficultyIndex + 1,
|
||||
DifficultyName = $"SR{difficultyIndex + 1}"
|
||||
}).ToList()
|
||||
};
|
||||
var beatmap = beatmapSet.Beatmaps[i];
|
||||
|
||||
beatmap.StarRating = i + 1;
|
||||
beatmap.DifficultyName = $"SR{i + 1}";
|
||||
}
|
||||
|
||||
return Game.BeatmapManager.Import(beatmapSet).Result.Value;
|
||||
}
|
||||
|
||||
@@ -3,15 +3,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
@@ -31,6 +27,7 @@ using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Select.Carousel;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.SongSelect
|
||||
@@ -148,7 +145,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddStep("select next and enter", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType<DrawableCarouselBeatmap>()
|
||||
.First(b => ((CarouselBeatmap)b.Item).BeatmapInfo != songSelect.Carousel.SelectedBeatmapInfo));
|
||||
.First(b => !((CarouselBeatmap)b.Item).BeatmapInfo.Equals(songSelect.Carousel.SelectedBeatmapInfo)));
|
||||
|
||||
InputManager.Click(MouseButton.Left);
|
||||
|
||||
@@ -175,7 +172,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddStep("select next and enter", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType<DrawableCarouselBeatmap>()
|
||||
.First(b => ((CarouselBeatmap)b.Item).BeatmapInfo != songSelect.Carousel.SelectedBeatmapInfo));
|
||||
.First(b => !((CarouselBeatmap)b.Item).BeatmapInfo.Equals(songSelect.Carousel.SelectedBeatmapInfo)));
|
||||
|
||||
InputManager.PressButton(MouseButton.Left);
|
||||
|
||||
@@ -258,8 +255,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
AddStep("import multi-ruleset map", () =>
|
||||
{
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
||||
manager.Import(createTestBeatmapSet(usableRulesets)).Wait();
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).Wait();
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -354,7 +351,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
target = manager.GetAllUsableBeatmapSets()
|
||||
.Last(b => b.Beatmaps.Any(bi => bi.RulesetID == 0)).Beatmaps.Last();
|
||||
|
||||
Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == 0);
|
||||
Ruleset.Value = rulesets.AvailableRulesets.First(r => r.OnlineID == 0);
|
||||
Beatmap.Value = manager.GetWorkingBeatmap(target);
|
||||
});
|
||||
|
||||
@@ -385,12 +382,12 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
.Last(b => b.Beatmaps.Any(bi => bi.RulesetID == 0)).Beatmaps.Last();
|
||||
|
||||
Beatmap.Value = manager.GetWorkingBeatmap(target);
|
||||
Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == 0);
|
||||
Ruleset.Value = rulesets.AvailableRulesets.First(r => r.OnlineID == 0);
|
||||
});
|
||||
|
||||
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo.Equals(target));
|
||||
|
||||
AddUntilStep("has correct ruleset", () => Ruleset.Value.ID == 0);
|
||||
AddUntilStep("has correct ruleset", () => Ruleset.Value.OnlineID == 0);
|
||||
|
||||
// this is an important check, to make sure updateComponentFromBeatmap() was actually run
|
||||
AddUntilStep("selection shown on wedge", () => songSelect.CurrentBeatmapDetailsBeatmap.BeatmapInfo.MatchesOnlineID(target));
|
||||
@@ -505,7 +502,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
// special case for converts checked here.
|
||||
return selectedPanel.ChildrenOfType<FilterableDifficultyIcon>().All(i =>
|
||||
i.IsFiltered || i.Item.BeatmapInfo.Ruleset.ID == targetRuleset || i.Item.BeatmapInfo.Ruleset.ID == 0);
|
||||
i.IsFiltered || i.Item.BeatmapInfo.Ruleset.OnlineID == targetRuleset || i.Item.BeatmapInfo.Ruleset.OnlineID == 0);
|
||||
});
|
||||
|
||||
AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmapInfo?.MatchesOnlineID(target) == true);
|
||||
@@ -644,7 +641,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddAssert("Selected beatmap correct", () => songSelect.Carousel.SelectedBeatmapInfo == filteredBeatmap);
|
||||
AddAssert("Selected beatmap correct", () => songSelect.Carousel.SelectedBeatmapInfo.Equals(filteredBeatmap));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -665,8 +662,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("import multi-ruleset map", () =>
|
||||
{
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
||||
manager.Import(createTestBeatmapSet(usableRulesets)).Wait();
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait();
|
||||
});
|
||||
|
||||
int previousSetID = 0;
|
||||
@@ -676,11 +673,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddStep("record set ID", () => previousSetID = ((IBeatmapSetInfo)Beatmap.Value.BeatmapSetInfo).OnlineID);
|
||||
AddAssert("selection changed once", () => changeCount == 1);
|
||||
|
||||
AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0);
|
||||
AddAssert("Check ruleset is osu!", () => Ruleset.Value.OnlineID == 0);
|
||||
|
||||
changeRuleset(3);
|
||||
|
||||
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.ID == 3);
|
||||
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.OnlineID == 3);
|
||||
|
||||
AddUntilStep("selection changed", () => changeCount > 1);
|
||||
|
||||
@@ -705,8 +702,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("import multi-ruleset map", () =>
|
||||
{
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
||||
manager.Import(createTestBeatmapSet(usableRulesets)).Wait();
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait();
|
||||
});
|
||||
|
||||
DrawableCarouselBeatmapSet set = null;
|
||||
@@ -720,11 +717,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddUntilStep("Find an icon for different ruleset", () =>
|
||||
{
|
||||
difficultyIcon = set.ChildrenOfType<FilterableDifficultyIcon>()
|
||||
.FirstOrDefault(icon => icon.Item.BeatmapInfo.Ruleset.ID == 3);
|
||||
.FirstOrDefault(icon => icon.Item.BeatmapInfo.Ruleset.OnlineID == 3);
|
||||
return difficultyIcon != null;
|
||||
});
|
||||
|
||||
AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0);
|
||||
AddAssert("Check ruleset is osu!", () => Ruleset.Value.OnlineID == 0);
|
||||
|
||||
int previousSetID = 0;
|
||||
|
||||
@@ -737,7 +734,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.ID == 3);
|
||||
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.OnlineID == 3);
|
||||
|
||||
AddAssert("Selected beatmap still same set", () => songSelect.Carousel.SelectedBeatmapInfo.BeatmapSet.OnlineID == previousSetID);
|
||||
AddAssert("Selected beatmap is mania", () => Beatmap.Value.BeatmapInfo.Ruleset.OnlineID == 3);
|
||||
@@ -754,8 +751,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("import huge difficulty count map", () =>
|
||||
{
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
||||
imported = manager.Import(createTestBeatmapSet(usableRulesets, 50)).Result.Value;
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||
imported = manager.Import(TestResources.CreateTestBeatmapSetInfo(50, usableRulesets)).Result.Value;
|
||||
});
|
||||
|
||||
AddStep("select the first beatmap of import", () => Beatmap.Value = manager.GetWorkingBeatmap(imported.Beatmaps.First()));
|
||||
@@ -771,10 +768,10 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddUntilStep("Find group icon for different ruleset", () =>
|
||||
{
|
||||
return (groupIcon = set.ChildrenOfType<FilterableGroupedDifficultyIcon>()
|
||||
.FirstOrDefault(icon => icon.Items.First().BeatmapInfo.Ruleset.ID == 3)) != null;
|
||||
.FirstOrDefault(icon => icon.Items.First().BeatmapInfo.Ruleset.OnlineID == 3)) != null;
|
||||
});
|
||||
|
||||
AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0);
|
||||
AddAssert("Check ruleset is osu!", () => Ruleset.Value.OnlineID == 0);
|
||||
|
||||
AddStep("Click on group", () =>
|
||||
{
|
||||
@@ -783,7 +780,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.ID == 3);
|
||||
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.OnlineID == 3);
|
||||
|
||||
AddAssert("Check first item in group selected", () => Beatmap.Value.BeatmapInfo.MatchesOnlineID(groupIcon.Items.First().BeatmapInfo));
|
||||
}
|
||||
@@ -817,7 +814,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddUntilStep("wait for results screen presented", () => !songSelect.IsCurrentScreen());
|
||||
|
||||
AddAssert("check beatmap is correct for score", () => Beatmap.Value.BeatmapInfo.MatchesOnlineID(getPresentBeatmap()));
|
||||
AddAssert("check ruleset is correct for score", () => Ruleset.Value.ID == 0);
|
||||
AddAssert("check ruleset is correct for score", () => Ruleset.Value.OnlineID == 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -849,7 +846,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddUntilStep("wait for results screen presented", () => !songSelect.IsCurrentScreen());
|
||||
|
||||
AddAssert("check beatmap is correct for score", () => Beatmap.Value.BeatmapInfo.MatchesOnlineID(getPresentBeatmap()));
|
||||
AddAssert("check ruleset is correct for score", () => Ruleset.Value.ID == 0);
|
||||
AddAssert("check ruleset is correct for score", () => Ruleset.Value.OnlineID == 0);
|
||||
}
|
||||
|
||||
private void waitForInitialSelection()
|
||||
@@ -858,7 +855,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddUntilStep("wait for difficulty panels visible", () => songSelect.Carousel.ChildrenOfType<DrawableCarouselBeatmap>().Any());
|
||||
}
|
||||
|
||||
private int getBeatmapIndex(BeatmapSetInfo set, BeatmapInfo info) => set.Beatmaps.FindIndex(b => b == info);
|
||||
private int getBeatmapIndex(BeatmapSetInfo set, BeatmapInfo info) => set.Beatmaps.IndexOf(info);
|
||||
|
||||
private int getCurrentBeatmapIndex() => getBeatmapIndex(songSelect.Carousel.SelectedBeatmapSet, songSelect.Carousel.SelectedBeatmapInfo);
|
||||
|
||||
@@ -869,18 +866,14 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
private void addRulesetImportStep(int id) => AddStep($"import test map for ruleset {id}", () => importForRuleset(id));
|
||||
|
||||
private void importForRuleset(int id) => manager.Import(createTestBeatmapSet(rulesets.AvailableRulesets.Where(r => r.ID == id).ToArray())).Wait();
|
||||
|
||||
private static int importId;
|
||||
|
||||
private int getImportId() => ++importId;
|
||||
private void importForRuleset(int id) => manager.Import(TestResources.CreateTestBeatmapSetInfo(3, rulesets.AvailableRulesets.Where(r => r.OnlineID == id).ToArray())).Wait();
|
||||
|
||||
private void checkMusicPlaying(bool playing) =>
|
||||
AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == playing);
|
||||
|
||||
private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => SelectedMods.Value = mods);
|
||||
|
||||
private void changeRuleset(int id) => AddStep($"change ruleset to {id}", () => Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == id));
|
||||
private void changeRuleset(int id) => AddStep($"change ruleset to {id}", () => Ruleset.Value = rulesets.AvailableRulesets.First(r => r.OnlineID == id));
|
||||
|
||||
private void createSongSelect()
|
||||
{
|
||||
@@ -893,59 +886,13 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
AddStep("import test maps", () =>
|
||||
{
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||
|
||||
for (int i = 0; i < 100; i += 10)
|
||||
manager.Import(createTestBeatmapSet(usableRulesets)).Wait();
|
||||
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).Wait();
|
||||
});
|
||||
}
|
||||
|
||||
private BeatmapSetInfo createTestBeatmapSet(RulesetInfo[] rulesets, int countPerRuleset = 6)
|
||||
{
|
||||
int j = 0;
|
||||
RulesetInfo getRuleset() => rulesets[j++ % rulesets.Length];
|
||||
|
||||
int setId = getImportId();
|
||||
|
||||
var beatmaps = new List<BeatmapInfo>();
|
||||
|
||||
for (int i = 0; i < countPerRuleset; i++)
|
||||
{
|
||||
int beatmapId = setId * 1000 + i;
|
||||
|
||||
int length = RNG.Next(30000, 200000);
|
||||
double bpm = RNG.NextSingle(80, 200);
|
||||
|
||||
beatmaps.Add(new BeatmapInfo
|
||||
{
|
||||
Ruleset = getRuleset(),
|
||||
OnlineID = beatmapId,
|
||||
DifficultyName = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
|
||||
Length = length,
|
||||
BPM = bpm,
|
||||
BaseDifficulty = new BeatmapDifficulty
|
||||
{
|
||||
OverallDifficulty = 3.5f,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return new BeatmapSetInfo
|
||||
{
|
||||
OnlineID = setId,
|
||||
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
// Create random metadata, then we can check if sorting works based on these
|
||||
Artist = "Some Artist " + RNG.Next(0, 9),
|
||||
Title = $"Some Song (set id {setId}, max bpm {beatmaps.Max(b => b.BPM):0.#})",
|
||||
AuthorString = "Some Guy " + RNG.Next(0, 9),
|
||||
},
|
||||
Beatmaps = beatmaps,
|
||||
DateAdded = DateTimeOffset.UtcNow,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
|
||||
dependencies.Cache(rulesetStore = new RulesetStore(ContextFactory));
|
||||
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
|
||||
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory, Scheduler));
|
||||
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, ContextFactory, Scheduler));
|
||||
|
||||
beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Value.Beatmaps[0];
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
|
||||
[Test]
|
||||
public void TestLabelledEnumDropdown()
|
||||
=> AddStep(@"create dropdown", () => Child = new LabelledEnumDropdown<BeatmapSetOnlineStatus>
|
||||
=> AddStep(@"create dropdown", () => Child = new LabelledEnumDropdown<BeatmapOnlineStatus>
|
||||
{
|
||||
Label = @"Beatmap status",
|
||||
Description = @"This is a description"
|
||||
|
||||
@@ -378,9 +378,9 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
});
|
||||
}
|
||||
|
||||
private void changeRuleset(int? id)
|
||||
private void changeRuleset(int? onlineId)
|
||||
{
|
||||
AddStep($"change ruleset to {(id?.ToString() ?? "none")}", () => { Ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(r => r.ID == id); });
|
||||
AddStep($"change ruleset to {(onlineId?.ToString() ?? "none")}", () => { Ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(r => r.OnlineID == onlineId); });
|
||||
waitForLoad();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
SelectedMods.Value = Array.Empty<Mod>();
|
||||
Ruleset.Value = new TestRulesetInfo();
|
||||
Ruleset.Value = CreateTestRulesetInfo();
|
||||
});
|
||||
|
||||
[Test]
|
||||
@@ -170,40 +170,32 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
ModSettingsContainer.Parent.Width = newWidth;
|
||||
}
|
||||
|
||||
public class TestRulesetInfo : RulesetInfo
|
||||
public static RulesetInfo CreateTestRulesetInfo() => new TestCustomisableModRuleset().RulesetInfo;
|
||||
|
||||
public class TestCustomisableModRuleset : Ruleset
|
||||
{
|
||||
public override Ruleset CreateInstance() => new TestCustomisableModRuleset();
|
||||
|
||||
public TestRulesetInfo()
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
{
|
||||
Available = true;
|
||||
}
|
||||
|
||||
public class TestCustomisableModRuleset : Ruleset
|
||||
{
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
if (type == ModType.Conversion)
|
||||
{
|
||||
if (type == ModType.Conversion)
|
||||
return new Mod[]
|
||||
{
|
||||
return new Mod[]
|
||||
{
|
||||
new TestModCustomisable1(),
|
||||
new TestModCustomisable2()
|
||||
};
|
||||
}
|
||||
|
||||
return Array.Empty<Mod>();
|
||||
new TestModCustomisable1(),
|
||||
new TestModCustomisable2()
|
||||
};
|
||||
}
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => throw new NotImplementedException();
|
||||
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException();
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new NotImplementedException();
|
||||
|
||||
public override string Description { get; } = "test";
|
||||
public override string ShortName { get; } = "tst";
|
||||
return Array.Empty<Mod>();
|
||||
}
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => throw new NotImplementedException();
|
||||
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException();
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new NotImplementedException();
|
||||
|
||||
public override string Description { get; } = "test";
|
||||
public override string ShortName { get; } = "tst";
|
||||
}
|
||||
|
||||
private class TestModCustomisable1 : TestModCustomisable
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
public class TestSceneOsuDropdown : ThemeComparisonTestScene
|
||||
{
|
||||
protected override Drawable CreateContent() =>
|
||||
new OsuEnumDropdown<BeatmapSetOnlineStatus>
|
||||
new OsuEnumDropdown<BeatmapOnlineStatus>
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// 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;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Overlays.Music;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
|
||||
private PlaylistOverlay playlistOverlay;
|
||||
|
||||
private BeatmapSetInfo first;
|
||||
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
@@ -43,19 +45,11 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
beatmapSets.Add(new BeatmapSetInfo
|
||||
{
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
// Create random metadata, then we can check if sorting works based on these
|
||||
Artist = "Some Artist " + RNG.Next(0, 9),
|
||||
Title = $"Some Song {i + 1}",
|
||||
AuthorString = "Some Guy " + RNG.Next(0, 9),
|
||||
},
|
||||
DateAdded = DateTimeOffset.UtcNow,
|
||||
});
|
||||
beatmapSets.Add(TestResources.CreateTestBeatmapSetInfo());
|
||||
}
|
||||
|
||||
first = beatmapSets.First();
|
||||
|
||||
playlistOverlay.BeatmapSets.BindTo(beatmapSets);
|
||||
});
|
||||
|
||||
@@ -66,7 +60,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
|
||||
AddStep("hold 1st item handle", () =>
|
||||
{
|
||||
var handle = this.ChildrenOfType<PlaylistItem.PlaylistItemHandle>().First();
|
||||
var handle = this.ChildrenOfType<OsuRearrangeableListItem<BeatmapSetInfo>.PlaylistItemHandle>().First();
|
||||
InputManager.MoveMouseTo(handle.ScreenSpaceDrawQuad.Centre);
|
||||
InputManager.PressButton(MouseButton.Left);
|
||||
});
|
||||
@@ -77,7 +71,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
InputManager.MoveMouseTo(item.ScreenSpaceDrawQuad.Centre);
|
||||
});
|
||||
|
||||
AddAssert("song 1 is 5th", () => beatmapSets[4].Metadata.Title == "Some Song 1");
|
||||
AddAssert("song 1 is 5th", () => beatmapSets[4] == first);
|
||||
|
||||
AddStep("release handle", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||
}
|
||||
|
||||
@@ -42,7 +42,12 @@ namespace osu.Game.Tournament.Tests.Components
|
||||
|
||||
private void success(APIBeatmap beatmap)
|
||||
{
|
||||
var mods = rulesets.GetRuleset(Ladder.Ruleset.Value.ID ?? 0).CreateInstance().AllMods;
|
||||
var ruleset = rulesets.GetRuleset(Ladder.Ruleset.Value.OnlineID);
|
||||
|
||||
if (ruleset == null)
|
||||
return;
|
||||
|
||||
var mods = ruleset.CreateInstance().AllMods;
|
||||
|
||||
foreach (var mod in mods)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
{
|
||||
using (HeadlessGameHost host = new HeadlessGameHost(nameof(TestCustomDirectory))) // don't use clean run as we are writing a config file.
|
||||
{
|
||||
string osuDesktopStorage = basePath(nameof(TestCustomDirectory));
|
||||
string osuDesktopStorage = PrepareBasePath(nameof(TestCustomDirectory));
|
||||
const string custom_tournament = "custom";
|
||||
|
||||
// need access before the game has constructed its own storage yet.
|
||||
@@ -60,6 +60,15 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(osuDesktopStorage))
|
||||
Directory.Delete(osuDesktopStorage, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,7 +78,7 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
{
|
||||
using (HeadlessGameHost host = new HeadlessGameHost(nameof(TestMigration))) // don't use clean run as we are writing test files for migration.
|
||||
{
|
||||
string osuRoot = basePath(nameof(TestMigration));
|
||||
string osuRoot = PrepareBasePath(nameof(TestMigration));
|
||||
string configFile = Path.Combine(osuRoot, "tournament.ini");
|
||||
|
||||
if (File.Exists(configFile))
|
||||
@@ -78,9 +87,9 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
// Recreate the old setup that uses "tournament" as the base path.
|
||||
string oldPath = Path.Combine(osuRoot, "tournament");
|
||||
|
||||
string videosPath = Path.Combine(oldPath, "videos");
|
||||
string modsPath = Path.Combine(oldPath, "mods");
|
||||
string flagsPath = Path.Combine(oldPath, "flags");
|
||||
string videosPath = Path.Combine(oldPath, "Videos");
|
||||
string modsPath = Path.Combine(oldPath, "Mods");
|
||||
string flagsPath = Path.Combine(oldPath, "Flags");
|
||||
|
||||
Directory.CreateDirectory(videosPath);
|
||||
Directory.CreateDirectory(modsPath);
|
||||
@@ -114,9 +123,9 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
|
||||
string migratedPath = Path.Combine(host.Storage.GetFullPath("."), "tournaments", "default");
|
||||
|
||||
videosPath = Path.Combine(migratedPath, "videos");
|
||||
modsPath = Path.Combine(migratedPath, "mods");
|
||||
flagsPath = Path.Combine(migratedPath, "flags");
|
||||
videosPath = Path.Combine(migratedPath, "Videos");
|
||||
modsPath = Path.Combine(migratedPath, "Mods");
|
||||
flagsPath = Path.Combine(migratedPath, "Flags");
|
||||
|
||||
videoFile = Path.Combine(videosPath, "video.mp4");
|
||||
modFile = Path.Combine(modsPath, "mod.png");
|
||||
@@ -136,18 +145,29 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
|
||||
try
|
||||
{
|
||||
host.Storage.Delete("tournament.ini");
|
||||
host.Storage.DeleteDirectory("tournaments");
|
||||
if (Directory.Exists(osuRoot))
|
||||
Directory.Delete(osuRoot, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
catch { }
|
||||
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string basePath(string testInstance) => Path.Combine(RuntimeInfo.StartupDirectory, "headless", testInstance);
|
||||
public static string PrepareBasePath(string testInstance)
|
||||
{
|
||||
string basePath = Path.Combine(RuntimeInfo.StartupDirectory, "headless", testInstance);
|
||||
|
||||
// manually clean before starting in case there are left-over files at the test site.
|
||||
if (Directory.Exists(basePath))
|
||||
Directory.Delete(basePath, true);
|
||||
|
||||
return basePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Tournament.IO;
|
||||
@@ -20,7 +19,7 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
// don't use clean run because files are being written before osu! launches.
|
||||
using (HeadlessGameHost host = new HeadlessGameHost(nameof(CheckIPCLocation)))
|
||||
{
|
||||
string basePath = Path.Combine(RuntimeInfo.StartupDirectory, "headless", nameof(CheckIPCLocation));
|
||||
string basePath = CustomTourneyDirectoryTest.PrepareBasePath(nameof(CheckIPCLocation));
|
||||
|
||||
// Set up a fake IPC client for the IPC Storage to switch to.
|
||||
string testStableInstallDirectory = Path.Combine(basePath, "stable-ce");
|
||||
@@ -42,9 +41,16 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Storage.DeleteDirectory(testStableInstallDirectory);
|
||||
host.Storage.DeleteDirectory("tournaments");
|
||||
host.Exit();
|
||||
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(basePath))
|
||||
Directory.Delete(basePath, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
||||
return tournament;
|
||||
}
|
||||
|
||||
public static void WaitForOrAssert(Func<bool> result, string failureMessage, int timeout = 90000)
|
||||
public static void WaitForOrAssert(Func<bool> result, string failureMessage, int timeout = 30000)
|
||||
{
|
||||
Task task = Task.Run(() =>
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user