mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 20:22:55 +08:00
Merge branch 'master' into refactor-osu-difficulty-hit-object
This commit is contained in:
commit
7c3d1d630e
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -38,7 +38,7 @@ jobs:
|
|||||||
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
|
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
|
||||||
|
|
||||||
- name: Test
|
- 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
|
shell: pwsh
|
||||||
|
|
||||||
# Attempt to upload results even if test fails.
|
# Attempt to upload results even if test fails.
|
||||||
@ -48,7 +48,7 @@ jobs:
|
|||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
with:
|
with:
|
||||||
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
|
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:
|
build-only-android:
|
||||||
name: Build only (Android)
|
name: Build only (Android)
|
||||||
@ -77,10 +77,6 @@ jobs:
|
|||||||
run: msbuild osu.Android/osu.Android.csproj /restore /p:Configuration=Debug
|
run: msbuild osu.Android/osu.Android.csproj /restore /p:Configuration=Debug
|
||||||
|
|
||||||
build-only-ios:
|
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)
|
name: Build only (iOS)
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
@ -10,3 +10,6 @@ T:Microsoft.EntityFrameworkCore.Internal.EnumerableExtensions;Don't use internal
|
|||||||
T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal extension methods.
|
T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal extension methods.
|
||||||
T:NuGet.Packaging.CollectionExtensions;Don't use internal extension methods.
|
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: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.
|
||||||
|
@ -51,8 +51,8 @@
|
|||||||
<Reference Include="Java.Interop" />
|
<Reference Include="Java.Interop" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1112.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1203.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1119.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1207.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||||
|
@ -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);
|
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.GlobalRank > 0 ? $" (rank #{user.Value.Statistics.GlobalRank:N0})" : string.Empty);
|
||||||
|
|
||||||
// update ruleset
|
// 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;
|
presence.Assets.SmallImageText = ruleset.Value.Name;
|
||||||
|
|
||||||
client.SetPresence(presence);
|
client.SetPresence(presence);
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
namespace osu.Desktop.LegacyIpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A difficulty calculation request from the legacy client.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Synchronise any changes with osu!stable.
|
||||||
|
/// </remarks>
|
||||||
|
public class LegacyIpcDifficultyCalculationRequest
|
||||||
|
{
|
||||||
|
public string BeatmapFile { get; set; }
|
||||||
|
public int RulesetId { get; set; }
|
||||||
|
public int Mods { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +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.
|
||||||
|
|
||||||
|
namespace osu.Desktop.LegacyIpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A difficulty calculation response returned to the legacy client.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Synchronise any changes with osu!stable.
|
||||||
|
/// </remarks>
|
||||||
|
public class LegacyIpcDifficultyCalculationResponse
|
||||||
|
{
|
||||||
|
public double StarRating { get; set; }
|
||||||
|
}
|
||||||
|
}
|
53
osu.Desktop/LegacyIpc/LegacyIpcMessage.cs
Normal file
53
osu.Desktop/LegacyIpc/LegacyIpcMessage.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// 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.Platform;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace osu.Desktop.LegacyIpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An <see cref="IpcMessage"/> that can be used to communicate to and from legacy clients.
|
||||||
|
/// <para>
|
||||||
|
/// In order to deserialise types at either end, types must be serialised as their <see cref="System.Type.AssemblyQualifiedName"/>,
|
||||||
|
/// however this cannot be done since osu!stable and osu!lazer live in two different assemblies.
|
||||||
|
/// <br />
|
||||||
|
/// To get around this, this class exists which serialises a payload (<see cref="LegacyIpcMessage.Data"/>) as an <see cref="System.Object"/> type,
|
||||||
|
/// which can be deserialised at either end because it is part of the core library (mscorlib / System.Private.CorLib).
|
||||||
|
/// The payload contains the data to be sent over the IPC channel.
|
||||||
|
/// <br />
|
||||||
|
/// At either end, Json.NET deserialises the payload into a <see cref="JObject"/> which is manually converted back into the expected <see cref="LegacyIpcMessage.Data"/> type,
|
||||||
|
/// which then further contains another <see cref="JObject"/> representing the data sent over the IPC channel whose type can likewise be lazily matched through
|
||||||
|
/// <see cref="LegacyIpcMessage.Data.MessageType"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Synchronise any changes with osu-stable.
|
||||||
|
/// </remarks>
|
||||||
|
public class LegacyIpcMessage : IpcMessage
|
||||||
|
{
|
||||||
|
public LegacyIpcMessage()
|
||||||
|
{
|
||||||
|
// Types/assemblies are not inter-compatible, so always serialise/deserialise into objects.
|
||||||
|
base.Type = typeof(object).FullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new string Type => base.Type; // Hide setter.
|
||||||
|
|
||||||
|
public new object Value
|
||||||
|
{
|
||||||
|
get => base.Value;
|
||||||
|
set => base.Value = new Data
|
||||||
|
{
|
||||||
|
MessageType = value.GetType().Name,
|
||||||
|
MessageData = value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
public string MessageType { get; set; }
|
||||||
|
public object MessageData { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
121
osu.Desktop/LegacyIpc/LegacyTcpIpcProvider.cs
Normal file
121
osu.Desktop/LegacyIpc/LegacyTcpIpcProvider.cs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
// 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 Newtonsoft.Json.Linq;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Legacy;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Catch;
|
||||||
|
using osu.Game.Rulesets.Mania;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Taiko;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace osu.Desktop.LegacyIpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides IPC to legacy osu! clients.
|
||||||
|
/// </summary>
|
||||||
|
public class LegacyTcpIpcProvider : TcpIpcProvider
|
||||||
|
{
|
||||||
|
private static readonly Logger logger = Logger.GetLogger("legacy-ipc");
|
||||||
|
|
||||||
|
public LegacyTcpIpcProvider()
|
||||||
|
: base(45357)
|
||||||
|
{
|
||||||
|
MessageReceived += msg =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logger.Add("Processing legacy IPC message...");
|
||||||
|
logger.Add($" {msg.Value}", LogLevel.Debug);
|
||||||
|
|
||||||
|
// See explanation in LegacyIpcMessage for why this is done this way.
|
||||||
|
var legacyData = ((JObject)msg.Value).ToObject<LegacyIpcMessage.Data>();
|
||||||
|
object value = parseObject((JObject)legacyData!.MessageData, legacyData.MessageType);
|
||||||
|
|
||||||
|
return new LegacyIpcMessage
|
||||||
|
{
|
||||||
|
Value = onLegacyIpcMessageReceived(value)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Add($"Processing IPC message failed: {msg.Value}", exception: ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private object parseObject(JObject value, string type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case nameof(LegacyIpcDifficultyCalculationRequest):
|
||||||
|
return value.ToObject<LegacyIpcDifficultyCalculationRequest>()
|
||||||
|
?? throw new InvalidOperationException($"Failed to parse request {value}");
|
||||||
|
|
||||||
|
case nameof(LegacyIpcDifficultyCalculationResponse):
|
||||||
|
return value.ToObject<LegacyIpcDifficultyCalculationResponse>()
|
||||||
|
?? throw new InvalidOperationException($"Failed to parse request {value}");
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unsupported object type {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object onLegacyIpcMessageReceived(object message)
|
||||||
|
{
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case LegacyIpcDifficultyCalculationRequest req:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ruleset = getLegacyRulesetFromID(req.RulesetId);
|
||||||
|
|
||||||
|
Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)req.Mods).ToArray();
|
||||||
|
WorkingBeatmap beatmap = new FlatFileWorkingBeatmap(req.BeatmapFile, _ => ruleset);
|
||||||
|
|
||||||
|
return new LegacyIpcDifficultyCalculationResponse
|
||||||
|
{
|
||||||
|
StarRating = ruleset.CreateDifficultyCalculator(beatmap).Calculate(mods).StarRating
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new LegacyIpcDifficultyCalculationResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unsupported message type {message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Ruleset getLegacyRulesetFromID(int rulesetId)
|
||||||
|
{
|
||||||
|
switch (rulesetId)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return new OsuRuleset();
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return new TaikoRuleset();
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
return new CatchRuleset();
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
return new ManiaRuleset();
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException("Invalid ruleset id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using osu.Desktop.LegacyIpc;
|
||||||
using osu.Framework;
|
using osu.Framework;
|
||||||
using osu.Framework.Development;
|
using osu.Framework.Development;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
@ -18,8 +19,10 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
private const string base_game_name = @"osu";
|
private const string base_game_name = @"osu";
|
||||||
|
|
||||||
|
private static LegacyTcpIpcProvider legacyIpc;
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static int Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
// Back up the cwd before DesktopGameHost changes it
|
// Back up the cwd before DesktopGameHost changes it
|
||||||
string cwd = Environment.CurrentDirectory;
|
string cwd = Environment.CurrentDirectory;
|
||||||
@ -69,14 +72,29 @@ namespace osu.Desktop
|
|||||||
throw new TimeoutException(@"IPC took too long to send");
|
throw new TimeoutException(@"IPC took too long to send");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we want to allow multiple instances to be started when in debug.
|
// we want to allow multiple instances to be started when in debug.
|
||||||
if (!DebugUtils.IsDebugBuild)
|
if (!DebugUtils.IsDebugBuild)
|
||||||
{
|
{
|
||||||
Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error);
|
Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error);
|
||||||
return 0;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host.IsPrimaryInstance)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Logger.Log("Starting legacy IPC provider...");
|
||||||
|
legacyIpc = new LegacyTcpIpcProvider();
|
||||||
|
legacyIpc.Bind();
|
||||||
|
legacyIpc.StartAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Error(ex, "Failed to start legacy IPC provider");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,8 +102,6 @@ namespace osu.Desktop
|
|||||||
host.Run(new TournamentGame());
|
host.Run(new TournamentGame());
|
||||||
else
|
else
|
||||||
host.Run(new OsuGameDesktop(args));
|
host.Run(new OsuGameDesktop(args));
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,10 @@ namespace osu.Desktop.Updater
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// In the case of an error, a separate notification will be displayed.
|
||||||
notification.State = ProgressNotificationState.Cancelled;
|
notification.State = ProgressNotificationState.Cancelled;
|
||||||
|
notification.Close();
|
||||||
|
|
||||||
Logger.Error(e, @"update failed!");
|
Logger.Error(e, @"update failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
private Drawable setupSkinHierarchy(Drawable child, ISkin skin)
|
private Drawable setupSkinHierarchy(Drawable child, ISkin skin)
|
||||||
{
|
{
|
||||||
var legacySkinProvider = new SkinProvidingContainer(skins.GetSkin(DefaultLegacySkin.Info));
|
var legacySkinProvider = new SkinProvidingContainer(skins.GetSkin(DefaultLegacySkin.CreateInfo()));
|
||||||
var testSkinProvider = new SkinProvidingContainer(skin);
|
var testSkinProvider = new SkinProvidingContainer(skin);
|
||||||
var legacySkinTransformer = new SkinProvidingContainer(new CatchLegacySkinTransformer(testSkinProvider));
|
var legacySkinTransformer = new SkinProvidingContainer(new CatchLegacySkinTransformer(testSkinProvider));
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Database;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
@ -55,13 +56,13 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestDefaultSkin()
|
public void TestDefaultSkin()
|
||||||
{
|
{
|
||||||
AddStep("set default skin", () => skins.CurrentSkinInfo.Value = SkinInfo.Default);
|
AddStep("set default skin", () => skins.CurrentSkinInfo.Value = DefaultSkin.CreateInfo().ToLive());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLegacySkin()
|
public void TestLegacySkin()
|
||||||
{
|
{
|
||||||
AddStep("set legacy skin", () => skins.CurrentSkinInfo.Value = DefaultLegacySkin.Info);
|
AddStep("set legacy skin", () => skins.CurrentSkinInfo.Value = DefaultLegacySkin.CreateInfo().ToLive());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Caching;
|
using osu.Framework.Caching;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
@ -46,12 +45,6 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private EditorBeatmap beatmap { get; set; }
|
private EditorBeatmap beatmap { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IScrollingInfo scrollingInfo { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private Bindable<WorkingBeatmap> working { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
|
@ -7,16 +7,12 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
{
|
{
|
||||||
public class ManiaSelectionHandler : EditorSelectionHandler
|
public class ManiaSelectionHandler : EditorSelectionHandler
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private IScrollingInfo scrollingInfo { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private HitObjectComposer composer { get; set; }
|
private HitObjectComposer composer { get; set; }
|
||||||
|
|
||||||
|
@ -15,9 +15,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
public JudgementResult Result { get; private set; }
|
public JudgementResult Result { get; private set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private Column column { get; set; }
|
|
||||||
|
|
||||||
private SkinnableDrawable skinnableExplosion;
|
private SkinnableDrawable skinnableExplosion;
|
||||||
|
|
||||||
public PoolableHitExplosion()
|
public PoolableHitExplosion()
|
||||||
|
@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
AddStep("create slider", () =>
|
AddStep("create slider", () =>
|
||||||
{
|
{
|
||||||
var tintingSkin = skinManager.GetSkin(DefaultLegacySkin.Info);
|
var tintingSkin = skinManager.GetSkin(DefaultLegacySkin.CreateInfo());
|
||||||
tintingSkin.Configuration.ConfigDictionary["AllowSliderBallTint"] = "1";
|
tintingSkin.Configuration.ConfigDictionary["AllowSliderBallTint"] = "1";
|
||||||
|
|
||||||
Child = new SkinProvidingContainer(tintingSkin)
|
Child = new SkinProvidingContainer(tintingSkin)
|
||||||
|
@ -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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -26,12 +26,12 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public BindableFloat Scale { get; } = new BindableFloat(4)
|
public BindableFloat Scale { get; } = new BindableFloat(4)
|
||||||
{
|
{
|
||||||
Precision = 0.1f,
|
Precision = 0.1f,
|
||||||
MinValue = 2,
|
MinValue = 1.5f,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
[SettingSource("Style", "Change the animation style of the approach circles.", 1)]
|
[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)
|
public void ApplyToDrawableHitObject(DrawableHitObject drawable)
|
||||||
{
|
{
|
||||||
@ -52,9 +52,18 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
switch (style)
|
switch (style)
|
||||||
{
|
{
|
||||||
default:
|
case AnimationStyle.Linear:
|
||||||
return Easing.None;
|
return Easing.None;
|
||||||
|
|
||||||
|
case AnimationStyle.Gravity:
|
||||||
|
return Easing.InBack;
|
||||||
|
|
||||||
|
case AnimationStyle.InOut1:
|
||||||
|
return Easing.InOutCubic;
|
||||||
|
|
||||||
|
case AnimationStyle.InOut2:
|
||||||
|
return Easing.InOutQuint;
|
||||||
|
|
||||||
case AnimationStyle.Accelerate1:
|
case AnimationStyle.Accelerate1:
|
||||||
return Easing.In;
|
return Easing.In;
|
||||||
|
|
||||||
@ -64,9 +73,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
case AnimationStyle.Accelerate3:
|
case AnimationStyle.Accelerate3:
|
||||||
return Easing.InQuint;
|
return Easing.InQuint;
|
||||||
|
|
||||||
case AnimationStyle.Gravity:
|
|
||||||
return Easing.InBack;
|
|
||||||
|
|
||||||
case AnimationStyle.Decelerate1:
|
case AnimationStyle.Decelerate1:
|
||||||
return Easing.Out;
|
return Easing.Out;
|
||||||
|
|
||||||
@ -76,16 +82,14 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
case AnimationStyle.Decelerate3:
|
case AnimationStyle.Decelerate3:
|
||||||
return Easing.OutQuint;
|
return Easing.OutQuint;
|
||||||
|
|
||||||
case AnimationStyle.InOut1:
|
default:
|
||||||
return Easing.InOutCubic;
|
throw new ArgumentOutOfRangeException(nameof(style), style, @"Unsupported animation style");
|
||||||
|
|
||||||
case AnimationStyle.InOut2:
|
|
||||||
return Easing.InOutQuint;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AnimationStyle
|
public enum AnimationStyle
|
||||||
{
|
{
|
||||||
|
Linear,
|
||||||
Gravity,
|
Gravity,
|
||||||
InOut1,
|
InOut1,
|
||||||
InOut2,
|
InOut2,
|
||||||
|
@ -12,7 +12,6 @@ using osu.Framework.Input.Events;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -149,9 +148,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
centreHit.Colour = colours.Pink;
|
centreHit.Colour = colours.Pink;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
|
||||||
private GameplayClock gameplayClock { get; set; }
|
|
||||||
|
|
||||||
public bool OnPressed(KeyBindingPressEvent<TaikoAction> e)
|
public bool OnPressed(KeyBindingPressEvent<TaikoAction> e)
|
||||||
{
|
{
|
||||||
Drawable target = null;
|
Drawable target = null;
|
||||||
|
@ -2,14 +2,20 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets.Catch;
|
||||||
using osu.Game.Rulesets.Mania;
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Taiko;
|
using osu.Game.Rulesets.Taiko;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
@ -21,6 +27,14 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class LegacyScoreDecoderTest
|
public class LegacyScoreDecoderTest
|
||||||
{
|
{
|
||||||
|
private CultureInfo originalCulture;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
originalCulture = CultureInfo.CurrentCulture;
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestDecodeManiaReplay()
|
public void TestDecodeManiaReplay()
|
||||||
{
|
{
|
||||||
@ -30,7 +44,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
{
|
{
|
||||||
var score = decoder.Parse(resourceStream);
|
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(2, score.ScoreInfo.Statistics[HitResult.Great]);
|
||||||
Assert.AreEqual(1, score.ScoreInfo.Statistics[HitResult.Good]);
|
Assert.AreEqual(1, score.ScoreInfo.Statistics[HitResult.Good]);
|
||||||
@ -44,6 +58,59 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCultureInvariance()
|
||||||
|
{
|
||||||
|
var ruleset = new OsuRuleset().RulesetInfo;
|
||||||
|
var scoreInfo = new TestScoreInfo(ruleset);
|
||||||
|
var beatmap = new TestBeatmap(ruleset);
|
||||||
|
var score = new Score
|
||||||
|
{
|
||||||
|
ScoreInfo = scoreInfo,
|
||||||
|
Replay = new Replay
|
||||||
|
{
|
||||||
|
Frames = new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame(2000, OsuPlayfield.BASE_SIZE / 2, OsuAction.LeftButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// the "se" culture is used here, as it encodes the negative number sign as U+2212 MINUS SIGN,
|
||||||
|
// rather than the classic ASCII U+002D HYPHEN-MINUS.
|
||||||
|
CultureInfo.CurrentCulture = new CultureInfo("se");
|
||||||
|
|
||||||
|
var encodeStream = new MemoryStream();
|
||||||
|
|
||||||
|
var encoder = new LegacyScoreEncoder(score, beatmap);
|
||||||
|
encoder.Encode(encodeStream);
|
||||||
|
|
||||||
|
var decodeStream = new MemoryStream(encodeStream.GetBuffer());
|
||||||
|
|
||||||
|
var decoder = new TestLegacyScoreDecoder();
|
||||||
|
var decodedAfterEncode = decoder.Parse(decodeStream);
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.That(decodedAfterEncode, Is.Not.Null);
|
||||||
|
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.User.Username, Is.EqualTo(scoreInfo.User.Username));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.BeatmapInfoID, Is.EqualTo(scoreInfo.BeatmapInfoID));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.Ruleset, Is.EqualTo(scoreInfo.Ruleset));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.TotalScore, Is.EqualTo(scoreInfo.TotalScore));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.MaxCombo, Is.EqualTo(scoreInfo.MaxCombo));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.Date, Is.EqualTo(scoreInfo.Date));
|
||||||
|
|
||||||
|
Assert.That(decodedAfterEncode.Replay.Frames.Count, Is.EqualTo(1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown()
|
||||||
|
{
|
||||||
|
CultureInfo.CurrentCulture = originalCulture;
|
||||||
|
}
|
||||||
|
|
||||||
private class TestLegacyScoreDecoder : LegacyScoreDecoder
|
private class TestLegacyScoreDecoder : LegacyScoreDecoder
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<int, Ruleset> rulesets = new Ruleset[]
|
private static readonly Dictionary<int, Ruleset> rulesets = new Ruleset[]
|
||||||
|
@ -584,7 +584,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
OnlineID = 1,
|
OnlineID = 1,
|
||||||
Metadata = metadata,
|
Metadata = metadata,
|
||||||
Beatmaps = new List<BeatmapInfo>
|
Beatmaps =
|
||||||
{
|
{
|
||||||
new BeatmapInfo
|
new BeatmapInfo
|
||||||
{
|
{
|
||||||
@ -596,7 +596,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
OnlineID = 2,
|
OnlineID = 2,
|
||||||
Metadata = metadata,
|
Metadata = metadata,
|
||||||
Status = BeatmapSetOnlineStatus.Loved,
|
Status = BeatmapOnlineStatus.Loved,
|
||||||
BaseDifficulty = difficulty
|
BaseDifficulty = difficulty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1050,7 +1050,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
private static void checkSingleReferencedFileCount(OsuGameBase osu, int expected)
|
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)
|
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000)
|
||||||
|
@ -25,9 +25,6 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
|
|
||||||
private BeatmapSetInfo importedSet;
|
private BeatmapSetInfo importedSet;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmaps { get; set; }
|
|
||||||
|
|
||||||
private TestBeatmapDifficultyCache difficultyCache;
|
private TestBeatmapDifficultyCache difficultyCache;
|
||||||
|
|
||||||
private IBindable<StarDifficulty?> starDifficultyBindable;
|
private IBindable<StarDifficulty?> starDifficultyBindable;
|
||||||
@ -100,8 +97,8 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestKeyEqualsWithDifferentModInstances()
|
public void TestKeyEqualsWithDifferentModInstances()
|
||||||
{
|
{
|
||||||
var key1 = 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 { ID = 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, Is.EqualTo(key2));
|
||||||
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
@ -110,8 +107,8 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestKeyEqualsWithDifferentModOrder()
|
public void TestKeyEqualsWithDifferentModOrder()
|
||||||
{
|
{
|
||||||
var key1 = 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 { ID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() });
|
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, Is.EqualTo(key2));
|
||||||
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
@ -120,8 +117,8 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestKeyDoesntEqualWithDifferentModSettings()
|
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 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 { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
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, Is.Not.EqualTo(key2));
|
||||||
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
|
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
|
||||||
@ -130,8 +127,8 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestKeyEqualWithMatchingModSettings()
|
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 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 { ID = 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, Is.EqualTo(key2));
|
||||||
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
|
@ -12,6 +12,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.ObjectExtensions;
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
@ -474,7 +475,7 @@ namespace osu.Game.Tests.Database
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportThenDeleteThenImport()
|
public void TestImportThenDeleteThenImportOptimisedPath()
|
||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realmFactory, storage) =>
|
RunTestWithRealmAsync(async (realmFactory, storage) =>
|
||||||
{
|
{
|
||||||
@ -485,11 +486,39 @@ namespace osu.Game.Tests.Database
|
|||||||
|
|
||||||
deleteBeatmapSet(imported, realmFactory.Context);
|
deleteBeatmapSet(imported, realmFactory.Context);
|
||||||
|
|
||||||
|
Assert.IsTrue(imported.DeletePending);
|
||||||
|
|
||||||
var importedSecondTime = await LoadOszIntoStore(importer, realmFactory.Context);
|
var importedSecondTime = await LoadOszIntoStore(importer, realmFactory.Context);
|
||||||
|
|
||||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
// 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.ID == importedSecondTime.ID);
|
||||||
Assert.IsTrue(imported.Beatmaps.First().ID == importedSecondTime.Beatmaps.First().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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +579,7 @@ namespace osu.Game.Tests.Database
|
|||||||
new RealmBeatmap(ruleset, new RealmBeatmapDifficulty(), metadata)
|
new RealmBeatmap(ruleset, new RealmBeatmapDifficulty(), metadata)
|
||||||
{
|
{
|
||||||
OnlineID = 2,
|
OnlineID = 2,
|
||||||
Status = BeatmapSetOnlineStatus.Loved,
|
Status = BeatmapOnlineStatus.Loved,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -823,7 +852,11 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
IQueryable<RealmBeatmapSet>? resultSets = null;
|
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);
|
@"BeatmapSet did not import to the database in allocated time.", timeout);
|
||||||
|
|
||||||
// ensure we were stored to beatmap database backing...
|
// ensure we were stored to beatmap database backing...
|
||||||
@ -836,16 +869,16 @@ namespace osu.Game.Tests.Database
|
|||||||
// ReSharper disable once PossibleUnintendedReferenceComparison
|
// ReSharper disable once PossibleUnintendedReferenceComparison
|
||||||
IEnumerable<RealmBeatmap> queryBeatmaps() => realm.All<RealmBeatmap>().Where(s => s.BeatmapSet != null && s.BeatmapSet == set);
|
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);
|
Assert.AreEqual(12, queryBeatmaps().Count(), @"Beatmap count was not correct");
|
||||||
waitForOrAssert(() => queryBeatmapSets().Count() == 1, @"BeatmapSet did not import to the database in allocated time", timeout);
|
Assert.AreEqual(1, queryBeatmapSets().Count(), @"Beatmapset count was not correct");
|
||||||
|
|
||||||
int countBeatmapSetBeatmaps = 0;
|
int countBeatmapSetBeatmaps;
|
||||||
int countBeatmaps = 0;
|
int countBeatmaps;
|
||||||
|
|
||||||
waitForOrAssert(() =>
|
Assert.AreEqual(
|
||||||
(countBeatmapSetBeatmaps = queryBeatmapSets().First().Beatmaps.Count) ==
|
countBeatmapSetBeatmaps = queryBeatmapSets().First().Beatmaps.Count,
|
||||||
(countBeatmaps = queryBeatmaps().Count()),
|
countBeatmaps = queryBeatmaps().Count(),
|
||||||
$@"Incorrect database beatmap count post-import ({countBeatmaps} but should be {countBeatmapSetBeatmaps}).", timeout);
|
$@"Incorrect database beatmap count post-import ({countBeatmaps} but should be {countBeatmapSetBeatmaps}).");
|
||||||
|
|
||||||
foreach (RealmBeatmap b in set.Beatmaps)
|
foreach (RealmBeatmap b in set.Beatmaps)
|
||||||
Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineID == b.OnlineID));
|
Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineID == b.OnlineID));
|
||||||
@ -867,5 +900,15 @@ namespace osu.Game.Tests.Database
|
|||||||
|
|
||||||
Assert.Fail(failureMessage);
|
Assert.Fail(failureMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class NonOptimisedBeatmapImporter : BeatmapImporter
|
||||||
|
{
|
||||||
|
public NonOptimisedBeatmapImporter(RealmContextFactory realmFactory, Storage storage)
|
||||||
|
: base(realmFactory, storage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool HasCustomHashFunction => true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ using System;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Models;
|
||||||
|
|
||||||
#nullable enable
|
#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]
|
[Test]
|
||||||
public void TestBlockOperationsWithContention()
|
public void TestBlockOperationsWithContention()
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,6 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
using Realms;
|
using Realms;
|
||||||
@ -18,61 +17,57 @@ namespace osu.Game.Tests.Database
|
|||||||
public class RealmLiveTests : RealmTest
|
public class RealmLiveTests : RealmTest
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLiveCastability()
|
public void TestLiveEquality()
|
||||||
{
|
{
|
||||||
RunTestWithRealm((realmFactory, _) =>
|
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]
|
[Test]
|
||||||
public void TestValueAccessWithOpenContext()
|
public void TestAccessAfterAttach()
|
||||||
{
|
{
|
||||||
RunTestWithRealm((realmFactory, _) =>
|
RunTestWithRealm((realmFactory, _) =>
|
||||||
{
|
{
|
||||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
var beatmap = new RealmBeatmap(CreateRuleset(), new RealmBeatmapDifficulty(), new RealmBeatmapMetadata());
|
||||||
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();
|
var liveBeatmap = beatmap.ToLive();
|
||||||
}
|
|
||||||
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
|
|
||||||
|
|
||||||
Debug.Assert(liveBeatmap != null);
|
using (var context = realmFactory.CreateContext())
|
||||||
|
context.Write(r => r.Add(beatmap));
|
||||||
|
|
||||||
Task.Factory.StartNew(() =>
|
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
|
||||||
{
|
|
||||||
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();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[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]
|
[Test]
|
||||||
public void TestScopedReadWithoutContext()
|
public void TestScopedReadWithoutContext()
|
||||||
{
|
{
|
||||||
RunTestWithRealm((realmFactory, _) =>
|
RunTestWithRealm((realmFactory, _) =>
|
||||||
{
|
{
|
||||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||||
Task.Factory.StartNew(() =>
|
Task.Factory.StartNew(() =>
|
||||||
{
|
{
|
||||||
using (var threadContext = realmFactory.CreateContext())
|
using (var threadContext = realmFactory.CreateContext())
|
||||||
@ -101,7 +96,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealm((realmFactory, _) =>
|
RunTestWithRealm((realmFactory, _) =>
|
||||||
{
|
{
|
||||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||||
Task.Factory.StartNew(() =>
|
Task.Factory.StartNew(() =>
|
||||||
{
|
{
|
||||||
using (var threadContext = realmFactory.CreateContext())
|
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]
|
[Test]
|
||||||
public void TestValueAccessWithoutOpenContextFails()
|
public void TestValueAccessWithoutOpenContextFails()
|
||||||
{
|
{
|
||||||
RunTestWithRealm((realmFactory, _) =>
|
RunTestWithRealm((realmFactory, _) =>
|
||||||
{
|
{
|
||||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||||
Task.Factory.StartNew(() =>
|
Task.Factory.StartNew(() =>
|
||||||
{
|
{
|
||||||
using (var threadContext = realmFactory.CreateContext())
|
using (var threadContext = realmFactory.CreateContext())
|
||||||
@ -159,8 +208,8 @@ namespace osu.Game.Tests.Database
|
|||||||
|
|
||||||
using (var updateThreadContext = realmFactory.CreateContext())
|
using (var updateThreadContext = realmFactory.CreateContext())
|
||||||
{
|
{
|
||||||
updateThreadContext.All<RealmBeatmap>().SubscribeForNotifications(gotChange);
|
updateThreadContext.All<RealmBeatmap>().QueryAsyncWithNotifications(gotChange);
|
||||||
RealmLive<RealmBeatmap>? liveBeatmap = null;
|
ILive<RealmBeatmap>? liveBeatmap = null;
|
||||||
|
|
||||||
Task.Factory.StartNew(() =>
|
Task.Factory.StartNew(() =>
|
||||||
{
|
{
|
||||||
@ -183,23 +232,22 @@ namespace osu.Game.Tests.Database
|
|||||||
Assert.AreEqual(0, updateThreadContext.All<RealmBeatmap>().Count());
|
Assert.AreEqual(0, updateThreadContext.All<RealmBeatmap>().Count());
|
||||||
Assert.AreEqual(0, changesTriggered);
|
Assert.AreEqual(0, changesTriggered);
|
||||||
|
|
||||||
var resolved = liveBeatmap.Value;
|
liveBeatmap.PerformRead(resolved =>
|
||||||
|
|
||||||
// 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 =>
|
|
||||||
{
|
{
|
||||||
// can use with the main context.
|
// retrieval causes an implicit refresh. even changes that aren't related to the retrieval are fired at this point.
|
||||||
r.Remove(resolved);
|
// 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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +45,9 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
var rulesets = new RealmRulesetStore(realmFactory, storage);
|
var rulesets = new RealmRulesetStore(realmFactory, storage);
|
||||||
|
|
||||||
Assert.IsTrue((rulesets.AvailableRulesets.First() as RealmRuleset)?.IsManaged == false);
|
Assert.IsFalse(rulesets.AvailableRulesets.First().IsManaged);
|
||||||
Assert.IsTrue((rulesets.GetRuleset(0) as RealmRuleset)?.IsManaged == false);
|
Assert.IsFalse(rulesets.GetRuleset(0)?.IsManaged);
|
||||||
Assert.IsTrue((rulesets.GetRuleset("mania") as RealmRuleset)?.IsManaged == false);
|
Assert.IsFalse(rulesets.GetRuleset("mania")?.IsManaged);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Moq;
|
using Moq;
|
||||||
@ -13,7 +12,6 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Storyboards;
|
using osu.Game.Storyboards;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
using FileInfo = osu.Game.IO.FileInfo;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Editing.Checks
|
namespace osu.Game.Tests.Editing.Checks
|
||||||
{
|
{
|
||||||
@ -33,14 +31,10 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
{
|
{
|
||||||
BeatmapSet = new BeatmapSetInfo
|
BeatmapSet = new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
Files = new List<BeatmapSetFileInfo>(new[]
|
Files =
|
||||||
{
|
{
|
||||||
new BeatmapSetFileInfo
|
CheckTestHelpers.CreateMockFile("mp4"),
|
||||||
{
|
}
|
||||||
Filename = "abc123.mp4",
|
|
||||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@ -12,7 +12,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using FileInfo = osu.Game.IO.FileInfo;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Editing.Checks
|
namespace osu.Game.Tests.Editing.Checks
|
||||||
{
|
{
|
||||||
@ -25,25 +24,17 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
|
var file = CheckTestHelpers.CreateMockFile("jpg");
|
||||||
|
|
||||||
check = new CheckBackgroundQuality();
|
check = new CheckBackgroundQuality();
|
||||||
beatmap = new Beatmap<HitObject>
|
beatmap = new Beatmap<HitObject>
|
||||||
{
|
{
|
||||||
BeatmapInfo = new BeatmapInfo
|
BeatmapInfo = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Metadata = new BeatmapMetadata { BackgroundFile = "abc123.jpg" },
|
Metadata = new BeatmapMetadata { BackgroundFile = file.Filename },
|
||||||
BeatmapSet = new BeatmapSetInfo
|
BeatmapSet = new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
Files = new List<BeatmapSetFileInfo>(new[]
|
Files = { file }
|
||||||
{
|
|
||||||
new BeatmapSetFileInfo
|
|
||||||
{
|
|
||||||
Filename = "abc123.jpg",
|
|
||||||
FileInfo = new FileInfo
|
|
||||||
{
|
|
||||||
Hash = "abcdef"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -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.
|
// 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;
|
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);
|
Assert.That(check.Run(context), Is.Empty);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.IO;
|
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -22,22 +20,17 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
|
var file = CheckTestHelpers.CreateMockFile("jpg");
|
||||||
|
|
||||||
check = new CheckBackgroundPresence();
|
check = new CheckBackgroundPresence();
|
||||||
beatmap = new Beatmap<HitObject>
|
beatmap = new Beatmap<HitObject>
|
||||||
{
|
{
|
||||||
BeatmapInfo = new BeatmapInfo
|
BeatmapInfo = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Metadata = new BeatmapMetadata { BackgroundFile = "abc123.jpg" },
|
Metadata = new BeatmapMetadata { BackgroundFile = file.Filename },
|
||||||
BeatmapSet = new BeatmapSetInfo
|
BeatmapSet = new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
Files = new List<BeatmapSetFileInfo>(new[]
|
Files = { file }
|
||||||
{
|
|
||||||
new BeatmapSetFileInfo
|
|
||||||
{
|
|
||||||
Filename = "abc123.jpg",
|
|
||||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
18
osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs
Normal file
18
osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs
Normal 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.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ManagedBass;
|
using ManagedBass;
|
||||||
@ -14,7 +13,6 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK.Audio;
|
using osuTK.Audio;
|
||||||
using FileInfo = osu.Game.IO.FileInfo;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Editing.Checks
|
namespace osu.Game.Tests.Editing.Checks
|
||||||
{
|
{
|
||||||
@ -34,14 +32,7 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
{
|
{
|
||||||
BeatmapSet = new BeatmapSetInfo
|
BeatmapSet = new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
Files = new List<BeatmapSetFileInfo>(new[]
|
Files = { CheckTestHelpers.CreateMockFile("wav") }
|
||||||
{
|
|
||||||
new BeatmapSetFileInfo
|
|
||||||
{
|
|
||||||
Filename = "abc123.wav",
|
|
||||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -55,11 +46,7 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
public void TestDifferentExtension()
|
public void TestDifferentExtension()
|
||||||
{
|
{
|
||||||
beatmap.BeatmapInfo.BeatmapSet.Files.Clear();
|
beatmap.BeatmapInfo.BeatmapSet.Files.Clear();
|
||||||
beatmap.BeatmapInfo.BeatmapSet.Files.Add(new BeatmapSetFileInfo
|
beatmap.BeatmapInfo.BeatmapSet.Files.Add(CheckTestHelpers.CreateMockFile("jpg"));
|
||||||
{
|
|
||||||
Filename = "abc123.jpg",
|
|
||||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
|
||||||
});
|
|
||||||
|
|
||||||
// Should fail to load, but not produce an error due to the extension not being expected to load.
|
// 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)));
|
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.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Moq;
|
using Moq;
|
||||||
@ -10,7 +9,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using FileInfo = osu.Game.IO.FileInfo;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Editing.Checks
|
namespace osu.Game.Tests.Editing.Checks
|
||||||
{
|
{
|
||||||
@ -30,14 +28,10 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
{
|
{
|
||||||
BeatmapSet = new BeatmapSetInfo
|
BeatmapSet = new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
Files = new List<BeatmapSetFileInfo>(new[]
|
Files =
|
||||||
{
|
{
|
||||||
new BeatmapSetFileInfo
|
CheckTestHelpers.CreateMockFile("jpg"),
|
||||||
{
|
}
|
||||||
Filename = "abc123.jpg",
|
|
||||||
FileInfo = new FileInfo { Hash = "abcdef" }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -167,7 +167,7 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
private class TestSkin : LegacySkin
|
private class TestSkin : LegacySkin
|
||||||
{
|
{
|
||||||
public TestSkin(string resourceName, IStorageResourceProvider resources)
|
public TestSkin(string resourceName, IStorageResourceProvider resources)
|
||||||
: base(DefaultLegacySkin.Info, new TestResourceStore(resourceName), resources, "skin.ini")
|
: base(DefaultLegacySkin.CreateInfo(), new TestResourceStore(resourceName), resources, "skin.ini")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,6 @@ namespace osu.Game.Tests.Input
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private FrameworkConfigManager frameworkConfigManager { get; set; }
|
private FrameworkConfigManager frameworkConfigManager { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuConfigManager osuConfigManager { get; set; }
|
|
||||||
|
|
||||||
[TestCase(WindowMode.Windowed)]
|
[TestCase(WindowMode.Windowed)]
|
||||||
[TestCase(WindowMode.Borderless)]
|
[TestCase(WindowMode.Borderless)]
|
||||||
public void TestDisableConfining(WindowMode windowMode)
|
public void TestDisableConfining(WindowMode windowMode)
|
||||||
|
@ -29,9 +29,9 @@ namespace osu.Game.Tests.Models
|
|||||||
{
|
{
|
||||||
var mock = new Mock<IBeatmapSetInfo>();
|
var mock = new Mock<IBeatmapSetInfo>();
|
||||||
|
|
||||||
mock.Setup(m => m.Metadata!.Artist).Returns("artist");
|
mock.Setup(m => m.Metadata.Artist).Returns("artist");
|
||||||
mock.Setup(m => m.Metadata!.Title).Returns("title");
|
mock.Setup(m => m.Metadata.Title).Returns("title");
|
||||||
mock.Setup(m => m.Metadata!.Author.Username).Returns("author");
|
mock.Setup(m => m.Metadata.Author.Username).Returns("author");
|
||||||
|
|
||||||
Assert.That(mock.Object.GetDisplayString(), Is.EqualTo("artist - title (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>();
|
var mock = new Mock<IBeatmapSetInfo>();
|
||||||
|
|
||||||
mock.Setup(m => m.Metadata!.Artist).Returns("artist");
|
mock.Setup(m => m.Metadata.Artist).Returns("artist");
|
||||||
mock.Setup(m => m.Metadata!.Title).Returns("title");
|
mock.Setup(m => m.Metadata.Title).Returns("title");
|
||||||
mock.Setup(m => m.Metadata!.Author.Username).Returns(string.Empty);
|
mock.Setup(m => m.Metadata.Author.Username).Returns(string.Empty);
|
||||||
|
|
||||||
Assert.That(mock.Object.GetDisplayString(), Is.EqualTo("artist - title"));
|
Assert.That(mock.Object.GetDisplayString(), Is.EqualTo("artist - title"));
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Skills;
|
using osu.Game.Rulesets.Difficulty.Skills;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Tests.NonVisual
|
namespace osu.Game.Tests.NonVisual
|
||||||
{
|
{
|
||||||
@ -20,8 +22,10 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator().CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator().CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(1, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
|
new[] { typeof(ModNoMod) }
|
||||||
|
}, combinations);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -29,9 +33,11 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator(new ModA()).CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator(new ModA()).CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(2, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
Assert.IsTrue(combinations[1] is ModA);
|
new[] { typeof(ModNoMod) },
|
||||||
|
new[] { typeof(ModA) }
|
||||||
|
}, combinations);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -39,14 +45,13 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModB()).CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModB()).CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(4, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
Assert.IsTrue(combinations[1] is ModA);
|
new[] { typeof(ModNoMod) },
|
||||||
Assert.IsTrue(combinations[2] is MultiMod);
|
new[] { typeof(ModA) },
|
||||||
Assert.IsTrue(combinations[3] is ModB);
|
new[] { typeof(ModA), typeof(ModB) },
|
||||||
|
new[] { typeof(ModB) }
|
||||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
}, combinations);
|
||||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -54,10 +59,12 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModIncompatibleWithA()).CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModIncompatibleWithA()).CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(3, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
Assert.IsTrue(combinations[1] is ModA);
|
new[] { typeof(ModNoMod) },
|
||||||
Assert.IsTrue(combinations[2] is ModIncompatibleWithA);
|
new[] { typeof(ModA) },
|
||||||
|
new[] { typeof(ModIncompatibleWithA) }
|
||||||
|
}, combinations);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -65,22 +72,17 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModB(), new ModIncompatibleWithA(), new ModIncompatibleWithAAndB()).CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModB(), new ModIncompatibleWithA(), new ModIncompatibleWithAAndB()).CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(8, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
Assert.IsTrue(combinations[1] is ModA);
|
new[] { typeof(ModNoMod) },
|
||||||
Assert.IsTrue(combinations[2] is MultiMod);
|
new[] { typeof(ModA) },
|
||||||
Assert.IsTrue(combinations[3] is ModB);
|
new[] { typeof(ModA), typeof(ModB) },
|
||||||
Assert.IsTrue(combinations[4] is MultiMod);
|
new[] { typeof(ModB) },
|
||||||
Assert.IsTrue(combinations[5] is ModIncompatibleWithA);
|
new[] { typeof(ModB), typeof(ModIncompatibleWithA) },
|
||||||
Assert.IsTrue(combinations[6] is MultiMod);
|
new[] { typeof(ModIncompatibleWithA) },
|
||||||
Assert.IsTrue(combinations[7] is ModIncompatibleWithAAndB);
|
new[] { typeof(ModIncompatibleWithA), typeof(ModIncompatibleWithAAndB) },
|
||||||
|
new[] { typeof(ModIncompatibleWithAAndB) },
|
||||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
}, combinations);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -88,10 +90,12 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator(new ModAofA(), new ModIncompatibleWithAofA()).CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator(new ModAofA(), new ModIncompatibleWithAofA()).CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(3, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
Assert.IsTrue(combinations[1] is ModAofA);
|
new[] { typeof(ModNoMod) },
|
||||||
Assert.IsTrue(combinations[2] is ModIncompatibleWithAofA);
|
new[] { typeof(ModAofA) },
|
||||||
|
new[] { typeof(ModIncompatibleWithAofA) }
|
||||||
|
}, combinations);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -99,17 +103,13 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModB(), new ModC())).CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModB(), new ModC())).CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(4, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
Assert.IsTrue(combinations[1] is ModA);
|
new[] { typeof(ModNoMod) },
|
||||||
Assert.IsTrue(combinations[2] is MultiMod);
|
new[] { typeof(ModA) },
|
||||||
Assert.IsTrue(combinations[3] is MultiMod);
|
new[] { typeof(ModA), typeof(ModB), typeof(ModC) },
|
||||||
|
new[] { typeof(ModB), typeof(ModC) }
|
||||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
}, combinations);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -117,13 +117,12 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModB(), new ModIncompatibleWithA())).CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModB(), new ModIncompatibleWithA())).CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(3, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
Assert.IsTrue(combinations[1] is ModA);
|
new[] { typeof(ModNoMod) },
|
||||||
Assert.IsTrue(combinations[2] is MultiMod);
|
new[] { typeof(ModA) },
|
||||||
|
new[] { typeof(ModB), typeof(ModIncompatibleWithA) }
|
||||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModB);
|
}, combinations);
|
||||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModIncompatibleWithA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -131,13 +130,28 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
{
|
{
|
||||||
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModA(), new ModB())).CreateDifficultyAdjustmentModCombinations();
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModA(), new ModB())).CreateDifficultyAdjustmentModCombinations();
|
||||||
|
|
||||||
Assert.AreEqual(3, combinations.Length);
|
assertCombinations(new[]
|
||||||
Assert.IsTrue(combinations[0] is ModNoMod);
|
{
|
||||||
Assert.IsTrue(combinations[1] is ModA);
|
new[] { typeof(ModNoMod) },
|
||||||
Assert.IsTrue(combinations[2] is MultiMod);
|
new[] { typeof(ModA) },
|
||||||
|
new[] { typeof(ModA), typeof(ModB) }
|
||||||
|
}, combinations);
|
||||||
|
}
|
||||||
|
|
||||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
private void assertCombinations(Type[][] expectedCombinations, Mod[] actualCombinations)
|
||||||
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
{
|
||||||
|
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
|
private class ModA : Mod
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
{
|
{
|
||||||
private BeatmapInfo getExampleBeatmap() => new BeatmapInfo
|
private BeatmapInfo getExampleBeatmap() => new BeatmapInfo
|
||||||
{
|
{
|
||||||
Ruleset = new RulesetInfo { ID = 5 },
|
Ruleset = new RulesetInfo { OnlineID = 5 },
|
||||||
StarRating = 4.0d,
|
StarRating = 4.0d,
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
@ -38,7 +38,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
Length = 2500,
|
Length = 2500,
|
||||||
BPM = 160,
|
BPM = 160,
|
||||||
BeatDivisor = 12,
|
BeatDivisor = 12,
|
||||||
Status = BeatmapSetOnlineStatus.Loved
|
Status = BeatmapOnlineStatus.Loved
|
||||||
};
|
};
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -57,7 +57,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
var exampleBeatmapInfo = getExampleBeatmap();
|
var exampleBeatmapInfo = getExampleBeatmap();
|
||||||
var criteria = new FilterCriteria
|
var criteria = new FilterCriteria
|
||||||
{
|
{
|
||||||
Ruleset = new RulesetInfo { ID = 6 }
|
Ruleset = new RulesetInfo { OnlineID = 6 }
|
||||||
};
|
};
|
||||||
var carouselItem = new CarouselBeatmap(exampleBeatmapInfo);
|
var carouselItem = new CarouselBeatmap(exampleBeatmapInfo);
|
||||||
carouselItem.Filter(criteria);
|
carouselItem.Filter(criteria);
|
||||||
@ -70,7 +70,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
var exampleBeatmapInfo = getExampleBeatmap();
|
var exampleBeatmapInfo = getExampleBeatmap();
|
||||||
var criteria = new FilterCriteria
|
var criteria = new FilterCriteria
|
||||||
{
|
{
|
||||||
Ruleset = new RulesetInfo { ID = 6 },
|
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||||
AllowConvertedBeatmaps = true
|
AllowConvertedBeatmaps = true
|
||||||
};
|
};
|
||||||
var carouselItem = new CarouselBeatmap(exampleBeatmapInfo);
|
var carouselItem = new CarouselBeatmap(exampleBeatmapInfo);
|
||||||
@ -86,7 +86,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
var exampleBeatmapInfo = getExampleBeatmap();
|
var exampleBeatmapInfo = getExampleBeatmap();
|
||||||
var criteria = new FilterCriteria
|
var criteria = new FilterCriteria
|
||||||
{
|
{
|
||||||
Ruleset = new RulesetInfo { ID = 6 },
|
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||||
AllowConvertedBeatmaps = true,
|
AllowConvertedBeatmaps = true,
|
||||||
ApproachRate = new FilterCriteria.OptionalRange<float>
|
ApproachRate = new FilterCriteria.OptionalRange<float>
|
||||||
{
|
{
|
||||||
@ -107,7 +107,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
var exampleBeatmapInfo = getExampleBeatmap();
|
var exampleBeatmapInfo = getExampleBeatmap();
|
||||||
var criteria = new FilterCriteria
|
var criteria = new FilterCriteria
|
||||||
{
|
{
|
||||||
Ruleset = new RulesetInfo { ID = 6 },
|
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||||
AllowConvertedBeatmaps = true,
|
AllowConvertedBeatmaps = true,
|
||||||
BPM = new FilterCriteria.OptionalRange<double>
|
BPM = new FilterCriteria.OptionalRange<double>
|
||||||
{
|
{
|
||||||
@ -132,7 +132,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
var exampleBeatmapInfo = getExampleBeatmap();
|
var exampleBeatmapInfo = getExampleBeatmap();
|
||||||
var criteria = new FilterCriteria
|
var criteria = new FilterCriteria
|
||||||
{
|
{
|
||||||
Ruleset = new RulesetInfo { ID = 6 },
|
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||||
AllowConvertedBeatmaps = true,
|
AllowConvertedBeatmaps = true,
|
||||||
SearchText = terms
|
SearchText = terms
|
||||||
};
|
};
|
||||||
|
@ -162,9 +162,9 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
FilterQueryParser.ApplyQueries(filterCriteria, query);
|
FilterQueryParser.ApplyQueries(filterCriteria, query);
|
||||||
Assert.AreEqual("I want the pp", filterCriteria.SearchText.Trim());
|
Assert.AreEqual("I want the pp", filterCriteria.SearchText.Trim());
|
||||||
Assert.AreEqual(4, filterCriteria.SearchTerms.Length);
|
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.IsTrue(filterCriteria.OnlineStatus.IsLowerInclusive);
|
||||||
Assert.AreEqual(BeatmapSetOnlineStatus.Ranked, filterCriteria.OnlineStatus.Max);
|
Assert.AreEqual(BeatmapOnlineStatus.Ranked, filterCriteria.OnlineStatus.Max);
|
||||||
Assert.IsTrue(filterCriteria.OnlineStatus.IsUpperInclusive);
|
Assert.IsTrue(filterCriteria.OnlineStatus.IsUpperInclusive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,27 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
|
|||||||
[HeadlessTest]
|
[HeadlessTest]
|
||||||
public class StatefulMultiplayerClientTest : MultiplayerTestScene
|
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]
|
[Test]
|
||||||
public void TestPlayingUserTracking()
|
public void TestPlayingUserTracking()
|
||||||
{
|
{
|
||||||
|
@ -12,9 +12,9 @@ using osu.Game.Tests.Visual;
|
|||||||
namespace osu.Game.Tests.Online
|
namespace osu.Game.Tests.Online
|
||||||
{
|
{
|
||||||
[HeadlessTest]
|
[HeadlessTest]
|
||||||
public class TestSceneBeatmapManager : OsuTestScene
|
public class TestSceneBeatmapDownloading : OsuTestScene
|
||||||
{
|
{
|
||||||
private BeatmapManager beatmaps;
|
private BeatmapModelDownloader beatmaps;
|
||||||
private ProgressNotification recentNotification;
|
private ProgressNotification recentNotification;
|
||||||
|
|
||||||
private static readonly BeatmapSetInfo test_db_model = new BeatmapSetInfo
|
private static readonly BeatmapSetInfo test_db_model = new BeatmapSetInfo
|
||||||
@ -43,7 +43,7 @@ namespace osu.Game.Tests.Online
|
|||||||
};
|
};
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(BeatmapManager beatmaps)
|
private void load(BeatmapModelDownloader beatmaps)
|
||||||
{
|
{
|
||||||
this.beatmaps = beatmaps;
|
this.beatmaps = beatmaps;
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -33,6 +33,7 @@ namespace osu.Game.Tests.Online
|
|||||||
{
|
{
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
private TestBeatmapManager beatmaps;
|
private TestBeatmapManager beatmaps;
|
||||||
|
private TestBeatmapModelDownloader beatmapDownloader;
|
||||||
|
|
||||||
private string testBeatmapFile;
|
private string testBeatmapFile;
|
||||||
private BeatmapInfo testBeatmapInfo;
|
private BeatmapInfo testBeatmapInfo;
|
||||||
@ -46,6 +47,7 @@ namespace osu.Game.Tests.Online
|
|||||||
{
|
{
|
||||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||||
Dependencies.CacheAs<BeatmapManager>(beatmaps = new TestBeatmapManager(LocalStorage, ContextFactory, rulesets, API, audio, Resources, host, Beatmap.Default));
|
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]
|
[SetUp]
|
||||||
@ -80,13 +82,13 @@ namespace osu.Game.Tests.Online
|
|||||||
AddAssert("ensure beatmap unavailable", () => !beatmaps.IsAvailableLocally(testBeatmapSet));
|
AddAssert("ensure beatmap unavailable", () => !beatmaps.IsAvailableLocally(testBeatmapSet));
|
||||||
addAvailabilityCheckStep("state not downloaded", BeatmapAvailability.NotDownloaded);
|
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));
|
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));
|
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);
|
addAvailabilityCheckStep("state importing", BeatmapAvailability.Importing);
|
||||||
|
|
||||||
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
|
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
|
||||||
@ -143,7 +145,10 @@ namespace osu.Game.Tests.Online
|
|||||||
var beatmap = decoder.Decode(reader);
|
var beatmap = decoder.Decode(reader);
|
||||||
|
|
||||||
info = beatmap.BeatmapInfo;
|
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.BeatmapSet.Metadata = info.Metadata;
|
||||||
info.MD5Hash = stream.ComputeMD5Hash();
|
info.MD5Hash = stream.ComputeMD5Hash();
|
||||||
info.Hash = stream.ComputeSHA2Hash();
|
info.Hash = stream.ComputeSHA2Hash();
|
||||||
@ -168,22 +173,6 @@ namespace osu.Game.Tests.Online
|
|||||||
return new TestBeatmapModelManager(this, storage, contextFactory, rulesets, api, host);
|
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
|
internal class TestBeatmapModelManager : BeatmapModelManager
|
||||||
{
|
{
|
||||||
private readonly TestBeatmapManager testBeatmapManager;
|
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>
|
private class TestDownloadRequest : ArchiveDownloadRequest<IBeatmapSetInfo>
|
||||||
{
|
{
|
||||||
public new void SetProgress(float progress) => base.SetProgress(progress);
|
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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Framework.Testing;
|
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
|
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 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>();
|
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
||||||
|
|
||||||
beatmapManager.Delete(beatmapManager.QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == imported.BeatmapInfo.ID)));
|
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);
|
var secondImport = await LoadScoreIntoOsu(osu, imported);
|
||||||
Assert.That(secondImport, Is.Null);
|
Assert.That(secondImport, Is.Null);
|
||||||
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.Database;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
@ -163,32 +164,109 @@ namespace osu.Game.Tests.Skins.IO
|
|||||||
assertCorrectMetadata(import2, "name 1 [my custom skin 2]", "author 1", osu);
|
assertCorrectMetadata(import2, "name 1 [my custom skin 2]", "author 1", osu);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public Task TestExportThenImportDefaultSkin() => runSkinTest(osu =>
|
||||||
|
{
|
||||||
|
var skinManager = osu.Dependencies.Get<SkinManager>();
|
||||||
|
|
||||||
|
skinManager.EnsureMutableSkin();
|
||||||
|
|
||||||
|
MemoryStream exportStream = new MemoryStream();
|
||||||
|
|
||||||
|
Guid originalSkinId = skinManager.CurrentSkinInfo.Value.ID;
|
||||||
|
|
||||||
|
skinManager.CurrentSkinInfo.Value.PerformRead(s =>
|
||||||
|
{
|
||||||
|
Assert.IsFalse(s.Protected);
|
||||||
|
Assert.AreEqual(typeof(DefaultSkin), s.CreateInstance(skinManager).GetType());
|
||||||
|
|
||||||
|
new LegacySkinExporter(osu.Dependencies.Get<Storage>()).ExportModelTo(s, exportStream);
|
||||||
|
|
||||||
|
Assert.Greater(exportStream.Length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk"));
|
||||||
|
|
||||||
|
imported.Result.PerformRead(s =>
|
||||||
|
{
|
||||||
|
Assert.IsFalse(s.Protected);
|
||||||
|
Assert.AreNotEqual(originalSkinId, s.ID);
|
||||||
|
Assert.AreEqual(typeof(DefaultSkin), s.CreateInstance(skinManager).GetType());
|
||||||
|
});
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public Task TestExportThenImportClassicSkin() => runSkinTest(osu =>
|
||||||
|
{
|
||||||
|
var skinManager = osu.Dependencies.Get<SkinManager>();
|
||||||
|
|
||||||
|
skinManager.CurrentSkinInfo.Value = skinManager.DefaultLegacySkin.SkinInfo;
|
||||||
|
|
||||||
|
skinManager.EnsureMutableSkin();
|
||||||
|
|
||||||
|
MemoryStream exportStream = new MemoryStream();
|
||||||
|
|
||||||
|
Guid originalSkinId = skinManager.CurrentSkinInfo.Value.ID;
|
||||||
|
|
||||||
|
skinManager.CurrentSkinInfo.Value.PerformRead(s =>
|
||||||
|
{
|
||||||
|
Assert.IsFalse(s.Protected);
|
||||||
|
Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType());
|
||||||
|
|
||||||
|
new LegacySkinExporter(osu.Dependencies.Get<Storage>()).ExportModelTo(s, exportStream);
|
||||||
|
|
||||||
|
Assert.Greater(exportStream.Length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk"));
|
||||||
|
|
||||||
|
imported.Result.PerformRead(s =>
|
||||||
|
{
|
||||||
|
Assert.IsFalse(s.Protected);
|
||||||
|
Assert.AreNotEqual(originalSkinId, s.ID);
|
||||||
|
Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType());
|
||||||
|
});
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
});
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void assertCorrectMetadata(SkinInfo import1, string name, string creator, OsuGameBase osu)
|
private void assertCorrectMetadata(ILive<SkinInfo> import1, string name, string creator, OsuGameBase osu)
|
||||||
{
|
{
|
||||||
Assert.That(import1.Name, Is.EqualTo(name));
|
import1.PerformRead(i =>
|
||||||
Assert.That(import1.Creator, Is.EqualTo(creator));
|
{
|
||||||
|
Assert.That(i.Name, Is.EqualTo(name));
|
||||||
|
Assert.That(i.Creator, Is.EqualTo(creator));
|
||||||
|
|
||||||
// for extra safety let's reconstruct the skin, reading from the skin.ini.
|
// for extra safety let's reconstruct the skin, reading from the skin.ini.
|
||||||
var instance = import1.CreateInstance((IStorageResourceProvider)osu.Dependencies.Get(typeof(SkinManager)));
|
var instance = i.CreateInstance((IStorageResourceProvider)osu.Dependencies.Get(typeof(SkinManager)));
|
||||||
|
|
||||||
Assert.That(instance.Configuration.SkinInfo.Name, Is.EqualTo(name));
|
Assert.That(instance.Configuration.SkinInfo.Name, Is.EqualTo(name));
|
||||||
Assert.That(instance.Configuration.SkinInfo.Creator, Is.EqualTo(creator));
|
Assert.That(instance.Configuration.SkinInfo.Creator, Is.EqualTo(creator));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertImportedBoth(SkinInfo import1, SkinInfo import2)
|
private void assertImportedBoth(ILive<SkinInfo> import1, ILive<SkinInfo> import2)
|
||||||
{
|
{
|
||||||
Assert.That(import2.ID, Is.Not.EqualTo(import1.ID));
|
import1.PerformRead(i1 => import2.PerformRead(i2 =>
|
||||||
Assert.That(import2.Hash, Is.Not.EqualTo(import1.Hash));
|
{
|
||||||
Assert.That(import2.Files.Select(f => f.FileInfoID), Is.Not.EquivalentTo(import1.Files.Select(f => f.FileInfoID)));
|
Assert.That(i2.ID, Is.Not.EqualTo(i1.ID));
|
||||||
|
Assert.That(i2.Hash, Is.Not.EqualTo(i1.Hash));
|
||||||
|
Assert.That(i2.Files.First(), Is.Not.EqualTo(i1.Files.First()));
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertImportedOnce(SkinInfo import1, SkinInfo import2)
|
private void assertImportedOnce(ILive<SkinInfo> import1, ILive<SkinInfo> import2)
|
||||||
{
|
{
|
||||||
Assert.That(import2.ID, Is.EqualTo(import1.ID));
|
import1.PerformRead(i1 => import2.PerformRead(i2 =>
|
||||||
Assert.That(import2.Hash, Is.EqualTo(import1.Hash));
|
{
|
||||||
Assert.That(import2.Files.Select(f => f.FileInfoID), Is.EquivalentTo(import1.Files.Select(f => f.FileInfoID)));
|
Assert.That(i2.ID, Is.EqualTo(i1.ID));
|
||||||
|
Assert.That(i2.Hash, Is.EqualTo(i1.Hash));
|
||||||
|
Assert.That(i2.Files.First(), Is.EqualTo(i1.Files.First()));
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private MemoryStream createEmptyOsk()
|
private MemoryStream createEmptyOsk()
|
||||||
@ -255,10 +333,10 @@ namespace osu.Game.Tests.Skins.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<SkinInfo> loadSkinIntoOsu(OsuGameBase osu, ArchiveReader archive = null)
|
private async Task<ILive<SkinInfo>> loadSkinIntoOsu(OsuGameBase osu, ArchiveReader archive = null)
|
||||||
{
|
{
|
||||||
var skinManager = osu.Dependencies.Get<SkinManager>();
|
var skinManager = osu.Dependencies.Get<SkinManager>();
|
||||||
return (await skinManager.Import(archive)).Value;
|
return await skinManager.Import(archive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Tests.Skins
|
|||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).Result;
|
var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).Result;
|
||||||
skin = skins.GetSkin(imported.Value);
|
skin = imported.PerformRead(skinInfo => skins.GetSkin(skinInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -70,7 +70,7 @@ namespace osu.Game.Tests.Testing
|
|||||||
{
|
{
|
||||||
// temporary ID to let RulesetConfigCache pass our
|
// temporary ID to let RulesetConfigCache pass our
|
||||||
// config manager to the ruleset dependencies.
|
// config manager to the ruleset dependencies.
|
||||||
RulesetInfo.ID = -1;
|
RulesetInfo.OnlineID = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IResourceStore<byte[]> CreateResourceStore() => new NamespacedResourceStore<byte[]>(TestResources.GetStore(), @"Resources");
|
public override IResourceStore<byte[]> CreateResourceStore() => new NamespacedResourceStore<byte[]>(TestResources.GetStore(), @"Resources");
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
@ -122,7 +123,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
private void setCustomSkin()
|
private void setCustomSkin()
|
||||||
{
|
{
|
||||||
// feign a skin switch. this doesn't do anything except force CurrentSkin to become a LegacySkin.
|
// feign a skin switch. this doesn't do anything except force CurrentSkin to become a LegacySkin.
|
||||||
AddStep("set custom skin", () => skins.CurrentSkinInfo.Value = new SkinInfo { ID = 5 });
|
AddStep("set custom skin", () => skins.CurrentSkinInfo.Value = new SkinInfo().ToLive());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDefaultSkin() => AddStep("set default skin", () => skins.CurrentSkinInfo.SetDefault());
|
private void setDefaultSkin() => AddStep("set default skin", () => skins.CurrentSkinInfo.SetDefault());
|
||||||
|
@ -23,6 +23,11 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
{
|
{
|
||||||
public class TestSceneBeatmapCard : OsuTestScene
|
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 DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
|
||||||
|
|
||||||
private APIBeatmapSet[] testCases;
|
private APIBeatmapSet[] testCases;
|
||||||
@ -38,11 +43,10 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
var normal = CreateAPIBeatmapSet(Ruleset.Value);
|
var normal = CreateAPIBeatmapSet(Ruleset.Value);
|
||||||
normal.HasVideo = true;
|
normal.HasVideo = true;
|
||||||
normal.HasStoryboard = true;
|
normal.HasStoryboard = true;
|
||||||
normal.OnlineID = 241526;
|
|
||||||
|
|
||||||
var withStatistics = CreateAPIBeatmapSet(Ruleset.Value);
|
var withStatistics = CreateAPIBeatmapSet(Ruleset.Value);
|
||||||
withStatistics.Title = withStatistics.TitleUnicode = "play favourite stats";
|
withStatistics.Title = withStatistics.TitleUnicode = "play favourite stats";
|
||||||
withStatistics.Status = BeatmapSetOnlineStatus.Approved;
|
withStatistics.Status = BeatmapOnlineStatus.Approved;
|
||||||
withStatistics.FavouriteCount = 284_239;
|
withStatistics.FavouriteCount = 284_239;
|
||||||
withStatistics.PlayCount = 999_001;
|
withStatistics.PlayCount = 999_001;
|
||||||
withStatistics.Ranked = DateTimeOffset.Now.AddDays(-45);
|
withStatistics.Ranked = DateTimeOffset.Now.AddDays(-45);
|
||||||
@ -63,7 +67,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
var someDifficulties = getManyDifficultiesBeatmapSet(11);
|
var someDifficulties = getManyDifficultiesBeatmapSet(11);
|
||||||
someDifficulties.Title = someDifficulties.TitleUnicode = "favourited";
|
someDifficulties.Title = someDifficulties.TitleUnicode = "favourited";
|
||||||
someDifficulties.Title = someDifficulties.TitleUnicode = "some difficulties";
|
someDifficulties.Title = someDifficulties.TitleUnicode = "some difficulties";
|
||||||
someDifficulties.Status = BeatmapSetOnlineStatus.Qualified;
|
someDifficulties.Status = BeatmapOnlineStatus.Qualified;
|
||||||
someDifficulties.HasFavourited = true;
|
someDifficulties.HasFavourited = true;
|
||||||
someDifficulties.FavouriteCount = 1;
|
someDifficulties.FavouriteCount = 1;
|
||||||
someDifficulties.NominationStatus = new BeatmapSetNominationStatus
|
someDifficulties.NominationStatus = new BeatmapSetNominationStatus
|
||||||
@ -73,7 +77,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
};
|
};
|
||||||
|
|
||||||
var manyDifficulties = getManyDifficultiesBeatmapSet(100);
|
var manyDifficulties = getManyDifficultiesBeatmapSet(100);
|
||||||
manyDifficulties.Status = BeatmapSetOnlineStatus.Pending;
|
manyDifficulties.Status = BeatmapOnlineStatus.Pending;
|
||||||
|
|
||||||
var explicitMap = CreateAPIBeatmapSet(Ruleset.Value);
|
var explicitMap = CreateAPIBeatmapSet(Ruleset.Value);
|
||||||
explicitMap.Title = someDifficulties.TitleUnicode = "explicit beatmap";
|
explicitMap.Title = someDifficulties.TitleUnicode = "explicit beatmap";
|
||||||
@ -106,6 +110,9 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
explicitFeaturedMap,
|
explicitFeaturedMap,
|
||||||
longName
|
longName
|
||||||
};
|
};
|
||||||
|
|
||||||
|
foreach (var testCase in testCases)
|
||||||
|
testCase.OnlineID = online_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private APIBeatmapSet getUndownloadableBeatmapSet() => new APIBeatmapSet
|
private APIBeatmapSet getUndownloadableBeatmapSet() => new APIBeatmapSet
|
||||||
@ -191,9 +198,9 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
private void ensureSoleilyRemoved()
|
private void ensureSoleilyRemoved()
|
||||||
{
|
{
|
||||||
AddUntilStep("ensure manager loaded", () => beatmaps != null);
|
AddUntilStep("ensure manager loaded", () => beatmaps != null);
|
||||||
AddStep("remove soleily", () =>
|
AddStep("remove map", () =>
|
||||||
{
|
{
|
||||||
var beatmap = beatmaps.QueryBeatmapSet(b => b.OnlineID == 241526);
|
var beatmap = beatmaps.QueryBeatmapSet(b => b.OnlineID == online_id);
|
||||||
|
|
||||||
if (beatmap != null) beatmaps.Delete(beatmap);
|
if (beatmap != null) beatmaps.Delete(beatmap);
|
||||||
});
|
});
|
||||||
|
@ -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,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,
|
Origin = Anchor.Centre,
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
Spacing = new Vector2(0, 10),
|
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,
|
AutoSizeAxes = Axes.Both,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
|
@ -69,7 +69,10 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
|
|
||||||
AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
|
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);
|
AddUntilStep("Wait for beatmap selected", () => !Game.Beatmap.IsDefault);
|
||||||
AddStep("Open options", () => InputManager.Key(Key.F3));
|
AddStep("Open options", () => InputManager.Key(Key.F3));
|
||||||
|
@ -12,6 +12,7 @@ using osu.Framework.Testing;
|
|||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Database;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
@ -41,7 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestEmptyLegacyBeatmapSkinFallsBack()
|
public void TestEmptyLegacyBeatmapSkinFallsBack()
|
||||||
{
|
{
|
||||||
CreateSkinTest(SkinInfo.Default, () => new LegacyBeatmapSkin(new BeatmapInfo(), null, null));
|
CreateSkinTest(DefaultSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null, null));
|
||||||
AddUntilStep("wait for hud load", () => Player.ChildrenOfType<SkinnableTargetContainer>().All(c => c.ComponentsLoaded));
|
AddUntilStep("wait for hud load", () => Player.ChildrenOfType<SkinnableTargetContainer>().All(c => c.ComponentsLoaded));
|
||||||
AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(SkinnableTarget.MainHUDComponents, skinManager.CurrentSkin.Value));
|
AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(SkinnableTarget.MainHUDComponents, skinManager.CurrentSkin.Value));
|
||||||
}
|
}
|
||||||
@ -52,7 +53,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
AddStep("setup skins", () =>
|
AddStep("setup skins", () =>
|
||||||
{
|
{
|
||||||
skinManager.CurrentSkinInfo.Value = gameCurrentSkin;
|
skinManager.CurrentSkinInfo.Value = gameCurrentSkin.ToLive();
|
||||||
currentBeatmapSkin = getBeatmapSkin();
|
currentBeatmapSkin = getBeatmapSkin();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -233,7 +233,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
prepareTokenResponse(true);
|
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);
|
AddUntilStep("wait for token request", () => Player.TokenCreationRequested);
|
||||||
|
|
||||||
|
@ -43,83 +43,88 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Cached]
|
[Cached]
|
||||||
private GameplayState gameplayState = new GameplayState(new Beatmap(), new OsuRuleset(), Array.Empty<Mod>());
|
private GameplayState gameplayState = new GameplayState(new Beatmap(), new OsuRuleset(), Array.Empty<Mod>());
|
||||||
|
|
||||||
[SetUp]
|
[SetUpSteps]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
replay = new Replay();
|
AddStep("Reset recorder state", cleanUpState);
|
||||||
|
|
||||||
Add(new GridContainer
|
AddStep("Setup containers", () =>
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
replay = new Replay();
|
||||||
Content = new[]
|
|
||||||
|
Add(new GridContainer
|
||||||
{
|
{
|
||||||
new Drawable[]
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Content = new[]
|
||||||
{
|
{
|
||||||
recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
new Drawable[]
|
||||||
{
|
{
|
||||||
Recorder = recorder = new TestReplayRecorder(new Score
|
recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||||
{
|
{
|
||||||
Replay = replay,
|
Recorder = recorder = new TestReplayRecorder(new Score
|
||||||
ScoreInfo = { BeatmapInfo = gameplayState.Beatmap.BeatmapInfo }
|
|
||||||
})
|
|
||||||
{
|
|
||||||
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),
|
|
||||||
},
|
|
||||||
Child = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
{
|
||||||
new Box
|
Replay = replay,
|
||||||
|
ScoreInfo = { BeatmapInfo = gameplayState.Beatmap.BeatmapInfo }
|
||||||
|
})
|
||||||
|
{
|
||||||
|
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),
|
||||||
|
},
|
||||||
|
Child = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
Colour = Color4.Brown,
|
new Box
|
||||||
RelativeSizeAxes = Axes.Both,
|
{
|
||||||
},
|
Colour = Color4.Brown,
|
||||||
new OsuSpriteText
|
RelativeSizeAxes = Axes.Both,
|
||||||
{
|
},
|
||||||
Text = "Recording",
|
new OsuSpriteText
|
||||||
Scale = new Vector2(3),
|
{
|
||||||
Anchor = Anchor.Centre,
|
Text = "Recording",
|
||||||
Origin = Anchor.Centre,
|
Scale = new Vector2(3),
|
||||||
},
|
Anchor = Anchor.Centre,
|
||||||
new TestInputConsumer()
|
Origin = Anchor.Centre,
|
||||||
}
|
},
|
||||||
},
|
new TestInputConsumer()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Drawable[]
|
}
|
||||||
{
|
},
|
||||||
playbackManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
new Drawable[]
|
||||||
{
|
{
|
||||||
ReplayInputHandler = new TestFramedReplayInputHandler(replay)
|
playbackManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||||
{
|
{
|
||||||
GamefieldToScreenSpace = pos => playbackManager.ToScreenSpace(pos),
|
ReplayInputHandler = new TestFramedReplayInputHandler(replay)
|
||||||
},
|
|
||||||
Child = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
{
|
||||||
new Box
|
GamefieldToScreenSpace = pos => playbackManager.ToScreenSpace(pos),
|
||||||
|
},
|
||||||
|
Child = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
Colour = Color4.DarkBlue,
|
new Box
|
||||||
RelativeSizeAxes = Axes.Both,
|
{
|
||||||
},
|
Colour = Color4.DarkBlue,
|
||||||
new OsuSpriteText
|
RelativeSizeAxes = Axes.Both,
|
||||||
{
|
},
|
||||||
Text = "Playback",
|
new OsuSpriteText
|
||||||
Scale = new Vector2(3),
|
{
|
||||||
Anchor = Anchor.Centre,
|
Text = "Playback",
|
||||||
Origin = Anchor.Centre,
|
Scale = new Vector2(3),
|
||||||
},
|
Anchor = Anchor.Centre,
|
||||||
new TestInputConsumer()
|
Origin = Anchor.Centre,
|
||||||
}
|
},
|
||||||
},
|
new TestInputConsumer()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBasic()
|
public void TestBasic()
|
||||||
@ -184,7 +189,14 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[TearDownSteps]
|
[TearDownSteps]
|
||||||
public void TearDown()
|
public void TearDown()
|
||||||
{
|
{
|
||||||
AddStep("stop recorder", () => recorder.Expire());
|
AddStep("stop recorder", cleanUpState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanUpState()
|
||||||
|
{
|
||||||
|
// Ensure previous recorder is disposed else it may affect the global playing state of `SpectatorClient`.
|
||||||
|
recorder?.RemoveAndDisposeImmediately();
|
||||||
|
recorder = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TestFramedReplayInputHandler : FramedReplayInputHandler<TestReplayFrame>
|
public class TestFramedReplayInputHandler : FramedReplayInputHandler<TestReplayFrame>
|
||||||
|
@ -1,228 +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;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Framework.Input.Bindings;
|
|
||||||
using osu.Framework.Input.Events;
|
|
||||||
using osu.Framework.Input.StateChanges;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Rulesets.Osu;
|
|
||||||
using osu.Game.Rulesets.Replays;
|
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
using osu.Game.Scoring;
|
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Tests.Visual.UserInterface;
|
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
|
||||||
{
|
|
||||||
public class TestSceneReplayRecording : OsuTestScene
|
|
||||||
{
|
|
||||||
private readonly TestRulesetInputManager playbackManager;
|
|
||||||
|
|
||||||
private readonly TestRulesetInputManager recordingManager;
|
|
||||||
|
|
||||||
[Cached]
|
|
||||||
private GameplayState gameplayState = new GameplayState(new Beatmap(), new OsuRuleset(), Array.Empty<Mod>());
|
|
||||||
|
|
||||||
public TestSceneReplayRecording()
|
|
||||||
{
|
|
||||||
Replay replay = new Replay();
|
|
||||||
|
|
||||||
Add(new GridContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Content = new[]
|
|
||||||
{
|
|
||||||
new Drawable[]
|
|
||||||
{
|
|
||||||
recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
|
||||||
{
|
|
||||||
Recorder = new TestReplayRecorder(new Score
|
|
||||||
{
|
|
||||||
Replay = replay,
|
|
||||||
ScoreInfo = { BeatmapInfo = gameplayState.Beatmap.BeatmapInfo }
|
|
||||||
})
|
|
||||||
{
|
|
||||||
ScreenSpaceToGamefield = pos => recordingManager?.ToLocalSpace(pos) ?? Vector2.Zero,
|
|
||||||
},
|
|
||||||
Child = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
Colour = Color4.Brown,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = "Recording",
|
|
||||||
Scale = new Vector2(3),
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
|
||||||
new TestConsumer()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Drawable[]
|
|
||||||
{
|
|
||||||
playbackManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
|
||||||
{
|
|
||||||
ReplayInputHandler = new TestFramedReplayInputHandler(replay)
|
|
||||||
{
|
|
||||||
GamefieldToScreenSpace = pos => playbackManager?.ToScreenSpace(pos) ?? Vector2.Zero,
|
|
||||||
},
|
|
||||||
Child = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
Colour = Color4.DarkBlue,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = "Playback",
|
|
||||||
Scale = new Vector2(3),
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
|
||||||
new TestConsumer()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
playbackManager.ReplayInputHandler.SetFrameFromTime(Time.Current - 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TestFramedReplayInputHandler : FramedReplayInputHandler<TestReplayFrame>
|
|
||||||
{
|
|
||||||
public TestFramedReplayInputHandler(Replay replay)
|
|
||||||
: base(replay)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CollectPendingInputs(List<IInput> inputs)
|
|
||||||
{
|
|
||||||
inputs.Add(new MousePositionAbsoluteInput { Position = GamefieldToScreenSpace(CurrentFrame?.Position ?? Vector2.Zero) });
|
|
||||||
inputs.Add(new ReplayState<TestAction> { PressedActions = CurrentFrame?.Actions ?? new List<TestAction>() });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TestConsumer : CompositeDrawable, IKeyBindingHandler<TestAction>
|
|
||||||
{
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Parent.ReceivePositionalInputAt(screenSpacePos);
|
|
||||||
|
|
||||||
private readonly Box box;
|
|
||||||
|
|
||||||
public TestConsumer()
|
|
||||||
{
|
|
||||||
Size = new Vector2(30);
|
|
||||||
|
|
||||||
Origin = Anchor.Centre;
|
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
|
||||||
{
|
|
||||||
box = new Box
|
|
||||||
{
|
|
||||||
Colour = Color4.Black,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
|
||||||
{
|
|
||||||
Position = e.MousePosition;
|
|
||||||
return base.OnMouseMove(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OnPressed(KeyBindingPressEvent<TestAction> e)
|
|
||||||
{
|
|
||||||
if (e.Repeat)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
box.Colour = Color4.White;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnReleased(KeyBindingReleaseEvent<TestAction> e)
|
|
||||||
{
|
|
||||||
box.Colour = Color4.Black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TestRulesetInputManager : RulesetInputManager<TestAction>
|
|
||||||
{
|
|
||||||
public TestRulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
|
||||||
: base(ruleset, variant, unique)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override KeyBindingContainer<TestAction> CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
|
||||||
=> new TestKeyBindingContainer();
|
|
||||||
|
|
||||||
internal class TestKeyBindingContainer : KeyBindingContainer<TestAction>
|
|
||||||
{
|
|
||||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => new[]
|
|
||||||
{
|
|
||||||
new KeyBinding(InputKey.MouseLeft, TestAction.Down),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TestReplayFrame : ReplayFrame
|
|
||||||
{
|
|
||||||
public Vector2 Position;
|
|
||||||
|
|
||||||
public List<TestAction> Actions = new List<TestAction>();
|
|
||||||
|
|
||||||
public TestReplayFrame(double time, Vector2 position, params TestAction[] actions)
|
|
||||||
: base(time)
|
|
||||||
{
|
|
||||||
Position = position;
|
|
||||||
Actions.AddRange(actions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum TestAction
|
|
||||||
{
|
|
||||||
Down,
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class TestReplayRecorder : ReplayRecorder<TestAction>
|
|
||||||
{
|
|
||||||
public TestReplayRecorder(Score target)
|
|
||||||
: base(target)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override ReplayFrame HandleFrame(Vector2 mousePosition, List<TestAction> actions, ReplayFrame previousFrame) =>
|
|
||||||
new TestReplayFrame(Time.Current, mousePosition, actions.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,12 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Skinning;
|
|
||||||
using osu.Game.Skinning.Editor;
|
using osu.Game.Skinning.Editor;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
@ -16,9 +14,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
private SkinEditor skinEditor;
|
private SkinEditor skinEditor;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private SkinManager skinManager { get; set; }
|
|
||||||
|
|
||||||
protected override bool Autoplay => true;
|
protected override bool Autoplay => true;
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
|
@ -10,7 +10,6 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
@ -36,9 +35,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private Drawable hideTarget => hudOverlay.KeyCounter;
|
private Drawable hideTarget => hudOverlay.KeyCounter;
|
||||||
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuConfigManager config { get; set; }
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestComboCounterIncrementing()
|
public void TestComboCounterIncrementing()
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public void TestClientSendsCorrectRuleset()
|
public void TestClientSendsCorrectRuleset()
|
||||||
{
|
{
|
||||||
AddUntilStep("spectator client sending frames", () => spectatorClient.PlayingUserStates.ContainsKey(dummy_user_id));
|
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()
|
public override void TearDownSteps()
|
||||||
|
@ -51,7 +51,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
private TestReplayRecorder recorder;
|
private TestReplayRecorder recorder;
|
||||||
|
|
||||||
private readonly ManualClock manualClock = new ManualClock();
|
private ManualClock manualClock;
|
||||||
|
|
||||||
private OsuSpriteText latencyDisplay;
|
private OsuSpriteText latencyDisplay;
|
||||||
|
|
||||||
@ -66,113 +66,121 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Cached]
|
[Cached]
|
||||||
private GameplayState gameplayState = new GameplayState(new Beatmap(), new OsuRuleset(), Array.Empty<Mod>());
|
private GameplayState gameplayState = new GameplayState(new Beatmap(), new OsuRuleset(), Array.Empty<Mod>());
|
||||||
|
|
||||||
[SetUp]
|
[SetUpSteps]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
replay = new Replay();
|
AddStep("Reset recorder state", cleanUpState);
|
||||||
|
|
||||||
users.BindTo(spectatorClient.PlayingUsers);
|
AddStep("Setup containers", () =>
|
||||||
users.BindCollectionChanged((obj, args) =>
|
|
||||||
{
|
{
|
||||||
switch (args.Action)
|
replay = new Replay();
|
||||||
|
manualClock = new ManualClock();
|
||||||
|
|
||||||
|
spectatorClient.OnNewFrames += onNewFrames;
|
||||||
|
|
||||||
|
users.BindTo(spectatorClient.PlayingUsers);
|
||||||
|
users.BindCollectionChanged((obj, args) =>
|
||||||
{
|
{
|
||||||
case NotifyCollectionChangedAction.Add:
|
switch (args.Action)
|
||||||
Debug.Assert(args.NewItems != null);
|
|
||||||
|
|
||||||
foreach (int user in args.NewItems)
|
|
||||||
{
|
|
||||||
if (user == api.LocalUser.Value.Id)
|
|
||||||
spectatorClient.WatchUser(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NotifyCollectionChangedAction.Remove:
|
|
||||||
Debug.Assert(args.OldItems != null);
|
|
||||||
|
|
||||||
foreach (int user in args.OldItems)
|
|
||||||
{
|
|
||||||
if (user == api.LocalUser.Value.Id)
|
|
||||||
spectatorClient.StopWatchingUser(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
spectatorClient.OnNewFrames += onNewFrames;
|
|
||||||
|
|
||||||
Add(new GridContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Content = new[]
|
|
||||||
{
|
|
||||||
new Drawable[]
|
|
||||||
{
|
{
|
||||||
recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
case NotifyCollectionChangedAction.Add:
|
||||||
|
Debug.Assert(args.NewItems != null);
|
||||||
|
|
||||||
|
foreach (int user in args.NewItems)
|
||||||
|
{
|
||||||
|
if (user == api.LocalUser.Value.Id)
|
||||||
|
spectatorClient.WatchUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotifyCollectionChangedAction.Remove:
|
||||||
|
Debug.Assert(args.OldItems != null);
|
||||||
|
|
||||||
|
foreach (int user in args.OldItems)
|
||||||
|
{
|
||||||
|
if (user == api.LocalUser.Value.Id)
|
||||||
|
spectatorClient.StopWatchingUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new GridContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Content = new[]
|
||||||
{
|
{
|
||||||
Recorder = recorder = new TestReplayRecorder
|
new Drawable[]
|
||||||
{
|
{
|
||||||
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),
|
recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||||
},
|
|
||||||
Child = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
{
|
||||||
new Box
|
Recorder = recorder = new TestReplayRecorder
|
||||||
|
{
|
||||||
|
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),
|
||||||
|
},
|
||||||
|
Child = new Container
|
||||||
{
|
{
|
||||||
Colour = Color4.Brown,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Brown,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = "Sending",
|
||||||
|
Scale = new Vector2(3),
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
},
|
||||||
|
new TestInputConsumer()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = "Sending",
|
|
||||||
Scale = new Vector2(3),
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
|
||||||
new TestInputConsumer()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
new Drawable[]
|
||||||
|
{
|
||||||
|
playbackManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||||
|
{
|
||||||
|
Clock = new FramedClock(manualClock),
|
||||||
|
ReplayInputHandler = replayHandler = new TestFramedReplayInputHandler(replay)
|
||||||
|
{
|
||||||
|
GamefieldToScreenSpace = pos => playbackManager.ToScreenSpace(pos),
|
||||||
|
},
|
||||||
|
Child = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.DarkBlue,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = "Receiving",
|
||||||
|
Scale = new Vector2(3),
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
},
|
||||||
|
new TestInputConsumer()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Drawable[]
|
latencyDisplay = new OsuSpriteText()
|
||||||
{
|
};
|
||||||
playbackManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
|
||||||
{
|
|
||||||
Clock = new FramedClock(manualClock),
|
|
||||||
ReplayInputHandler = replayHandler = new TestFramedReplayInputHandler(replay)
|
|
||||||
{
|
|
||||||
GamefieldToScreenSpace = pos => playbackManager.ToScreenSpace(pos),
|
|
||||||
},
|
|
||||||
Child = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
Colour = Color4.DarkBlue,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = "Receiving",
|
|
||||||
Scale = new Vector2(3),
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
|
||||||
new TestInputConsumer()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
Add(latencyDisplay = new OsuSpriteText());
|
|
||||||
});
|
|
||||||
|
|
||||||
private void onNewFrames(int userId, FrameDataBundle frames)
|
private void onNewFrames(int userId, FrameDataBundle frames)
|
||||||
{
|
{
|
||||||
@ -189,6 +197,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestBasic()
|
public void TestBasic()
|
||||||
{
|
{
|
||||||
|
AddStep("Wait for user input", () => { });
|
||||||
}
|
}
|
||||||
|
|
||||||
private double latency = SpectatorClient.TIME_BETWEEN_SENDS;
|
private double latency = SpectatorClient.TIME_BETWEEN_SENDS;
|
||||||
@ -232,11 +241,15 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[TearDownSteps]
|
[TearDownSteps]
|
||||||
public void TearDown()
|
public void TearDown()
|
||||||
{
|
{
|
||||||
AddStep("stop recorder", () =>
|
AddStep("stop recorder", cleanUpState);
|
||||||
{
|
}
|
||||||
recorder.Expire();
|
|
||||||
spectatorClient.OnNewFrames -= onNewFrames;
|
private void cleanUpState()
|
||||||
});
|
{
|
||||||
|
// Ensure previous recorder is disposed else it may affect the global playing state of `SpectatorClient`.
|
||||||
|
recorder?.RemoveAndDisposeImmediately();
|
||||||
|
recorder = null;
|
||||||
|
spectatorClient.OnNewFrames -= onNewFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TestFramedReplayInputHandler : FramedReplayInputHandler<TestReplayFrame>
|
public class TestFramedReplayInputHandler : FramedReplayInputHandler<TestReplayFrame>
|
||||||
|
@ -30,25 +30,10 @@ namespace osu.Game.Tests.Visual.Menus
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestMusicNavigationActions()
|
public void TestMusicNavigationActions()
|
||||||
{
|
{
|
||||||
int importId = 0;
|
|
||||||
Queue<(IWorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null;
|
Queue<(IWorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null;
|
||||||
|
|
||||||
// ensure we have at least two beatmaps available to identify the direction the music controller navigated to.
|
// 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
|
AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()).Wait(), 5);
|
||||||
{
|
|
||||||
Beatmaps = new List<BeatmapInfo>
|
|
||||||
{
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
BaseDifficulty = new BeatmapDifficulty(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Artist = $"a test map {importId++}",
|
|
||||||
Title = "title",
|
|
||||||
}
|
|
||||||
}).Wait(), 5);
|
|
||||||
|
|
||||||
AddStep("import beatmap with track", () =>
|
AddStep("import beatmap with track", () =>
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Menus
|
|||||||
private TestToolbar toolbar;
|
private TestToolbar toolbar;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
|
@ -78,6 +78,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddAssert("playlist item is not expired", () => Client.APIRoom?.Playlist[1].Expired == false);
|
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)
|
private void addItem(Func<BeatmapInfo> beatmap)
|
||||||
{
|
{
|
||||||
AddStep("click edit button", () =>
|
AddStep("click edit button", () =>
|
||||||
@ -86,7 +93,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.IsLoaded);
|
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
|
||||||
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(beatmap()));
|
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(beatmap()));
|
||||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||||
}
|
}
|
||||||
|
@ -13,15 +13,16 @@ using osu.Framework.Platform;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Drawables;
|
using osu.Game.Beatmaps.Drawables;
|
||||||
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Overlays.BeatmapListing.Panels;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Screens.OnlinePlay;
|
using osu.Game.Screens.OnlinePlay;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osu.Game.Users.Drawables;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
@ -34,6 +35,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
private BeatmapManager manager;
|
private BeatmapManager manager;
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
|
|
||||||
|
[Cached(typeof(UserLookupCache))]
|
||||||
|
private readonly TestUserLookupCache userLookupCache = new TestUserLookupCache();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(GameHost host, AudioManager audio)
|
private void load(GameHost host, AudioManager audio)
|
||||||
{
|
{
|
||||||
@ -231,7 +235,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
assertDownloadButtonVisible(false);
|
assertDownloadButtonVisible(false);
|
||||||
|
|
||||||
void assertDownloadButtonVisible(bool visible) => AddUntilStep($"download button {(visible ? "shown" : "hidden")}",
|
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]
|
[Test]
|
||||||
@ -245,7 +249,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
createPlaylist(byOnlineId, byChecksum);
|
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]
|
[Test]
|
||||||
@ -304,6 +308,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded));
|
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)
|
private void moveToItem(int index, Vector2? offset = null)
|
||||||
=> AddStep($"move mouse to item {index}", () => InputManager.MoveMouseTo(playlist.ChildrenOfType<DifficultyIcon>().ElementAt(index), offset));
|
=> AddStep($"move mouse to item {index}", () => InputManager.MoveMouseTo(playlist.ChildrenOfType<DifficultyIcon>().ElementAt(index), offset));
|
||||||
|
|
||||||
@ -327,11 +340,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
=> AddAssert($"delete button {index} {(visible ? "is" : "is not")} visible",
|
=> AddAssert($"delete button {index} {(visible ? "is" : "is not")} visible",
|
||||||
() => (playlist.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistRemoveButton>().ElementAt(2 + index * 2).Alpha > 0) == 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", () =>
|
AddStep("create playlist", () =>
|
||||||
{
|
{
|
||||||
Child = playlist = new TestPlaylist(allowEdit, allowSelection)
|
Child = playlist = new TestPlaylist(allowEdit, allowSelection, showItemOwner)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -343,6 +356,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
playlist.Items.Add(new PlaylistItem
|
playlist.Items.Add(new PlaylistItem
|
||||||
{
|
{
|
||||||
ID = i,
|
ID = i,
|
||||||
|
OwnerID = 2,
|
||||||
Beatmap =
|
Beatmap =
|
||||||
{
|
{
|
||||||
Value = i % 2 == 1
|
Value = i % 2 == 1
|
||||||
@ -390,6 +404,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
playlist.Items.Add(new PlaylistItem
|
playlist.Items.Add(new PlaylistItem
|
||||||
{
|
{
|
||||||
ID = index++,
|
ID = index++,
|
||||||
|
OwnerID = 2,
|
||||||
Beatmap = { Value = b },
|
Beatmap = { Value = b },
|
||||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||||
RequiredMods =
|
RequiredMods =
|
||||||
@ -409,8 +424,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
public new IReadOnlyDictionary<PlaylistItem, RearrangeableListItem<PlaylistItem>> ItemMap => base.ItemMap;
|
public new IReadOnlyDictionary<PlaylistItem, RearrangeableListItem<PlaylistItem>> ItemMap => base.ItemMap;
|
||||||
|
|
||||||
public TestPlaylist(bool allowEdit, bool allowSelection)
|
public TestPlaylist(bool allowEdit, bool allowSelection, bool showItemOwner = false)
|
||||||
: base(allowEdit, allowSelection)
|
: base(allowEdit, allowSelection, showItemOwner: showItemOwner)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.IsLoaded);
|
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
|
||||||
|
|
||||||
BeatmapInfo otherBeatmap = null;
|
BeatmapInfo otherBeatmap = null;
|
||||||
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(otherBeatmap = beatmap()));
|
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(otherBeatmap = beatmap()));
|
||||||
|
@ -2,11 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
@ -18,12 +15,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
public class TestSceneMatchBeatmapDetailArea : OnlinePlayTestScene
|
public class TestSceneMatchBeatmapDetailArea : OnlinePlayTestScene
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmapManager { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesetStore { get; set; }
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public new void Setup() => Schedule(() =>
|
public new void Setup() => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
@ -204,7 +204,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
// edit playlist item
|
// edit playlist item
|
||||||
AddStep("Press select", () => InputManager.Key(Key.Enter));
|
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
|
// select beatmap
|
||||||
AddStep("Press select", () => InputManager.Key(Key.Enter));
|
AddStep("Press select", () => InputManager.Key(Key.Enter));
|
||||||
@ -253,7 +253,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, API.LocalUser.Value);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||||
@ -283,7 +283,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, API.LocalUser.Value);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||||
@ -336,7 +336,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, API.LocalUser.Value);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||||
@ -397,6 +397,44 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddUntilStep("user state is idle", () => client.LocalUser?.State == MultiplayerUserState.Idle);
|
AddUntilStep("user state is idle", () => client.LocalUser?.State == MultiplayerUserState.Idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPlayStartsWithCorrectBeatmapWhileAtSongSelect()
|
||||||
|
{
|
||||||
|
createRoom(() => new Room
|
||||||
|
{
|
||||||
|
Name = { Value = "Test Room" },
|
||||||
|
Playlist =
|
||||||
|
{
|
||||||
|
new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
|
||||||
|
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("Enter song select", () =>
|
||||||
|
{
|
||||||
|
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerScreenStack.CurrentScreen).CurrentSubScreen;
|
||||||
|
|
||||||
|
((MultiplayerMatchSubScreen)currentSubScreen).SelectBeatmap();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
||||||
|
|
||||||
|
AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID);
|
||||||
|
|
||||||
|
AddStep("Select next beatmap", () => InputManager.Key(Key.Down));
|
||||||
|
|
||||||
|
AddUntilStep("Beatmap doesn't match current item", () => Beatmap.Value.BeatmapInfo.OnlineID != client.Room?.Playlist.First().BeatmapID);
|
||||||
|
|
||||||
|
AddStep("start match externally", () => client.StartMatch());
|
||||||
|
|
||||||
|
AddUntilStep("play started", () => multiplayerScreenStack.CurrentScreen is Player);
|
||||||
|
|
||||||
|
AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLocalPlayDoesNotStartWhileSpectatingWithNoBeatmap()
|
public void TestLocalPlayDoesNotStartWhileSpectatingWithNoBeatmap()
|
||||||
{
|
{
|
||||||
@ -597,7 +635,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, API.LocalUser.Value);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||||
|
@ -47,6 +47,21 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
beatmaps = new List<BeatmapInfo>();
|
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)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
int beatmapId = 10 * 10 + i;
|
int beatmapId = 10 * 10 + i;
|
||||||
@ -54,29 +69,21 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
int length = RNG.Next(30000, 200000);
|
int length = RNG.Next(30000, 200000);
|
||||||
double bpm = RNG.NextSingle(80, 200);
|
double bpm = RNG.NextSingle(80, 200);
|
||||||
|
|
||||||
beatmaps.Add(new BeatmapInfo
|
var beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Ruleset = rulesets.GetRuleset(i % 4),
|
Ruleset = rulesets.GetRuleset(i % 4),
|
||||||
OnlineID = beatmapId,
|
OnlineID = beatmapId,
|
||||||
Length = length,
|
Length = length,
|
||||||
BPM = bpm,
|
BPM = bpm,
|
||||||
|
Metadata = metadata,
|
||||||
BaseDifficulty = new BeatmapDifficulty()
|
BaseDifficulty = new BeatmapDifficulty()
|
||||||
});
|
};
|
||||||
|
|
||||||
|
beatmaps.Add(beatmap);
|
||||||
|
beatmapSetInfo.Beatmaps.Add(beatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.Import(new BeatmapSetInfo
|
manager.Import(beatmapSetInfo).Wait();
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
@ -91,7 +98,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddStep("create song select", () => LoadScreen(songSelect = new TestMultiplayerMatchSongSelect(SelectedRoom.Value)));
|
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]
|
[Test]
|
||||||
@ -137,7 +144,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("set mods", () => SelectedMods.Value = new[] { new TaikoModDoubleTime() });
|
AddStep("set mods", () => SelectedMods.Value = new[] { new TaikoModDoubleTime() });
|
||||||
|
|
||||||
AddStep("confirm selection", () => songSelect.FinaliseSelection());
|
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("beatmap not changed", () => Beatmap.Value.BeatmapInfo.Equals(selectedBeatmap));
|
||||||
AddAssert("ruleset not changed", () => Ruleset.Value.Equals(new TaikoRuleset().RulesetInfo));
|
AddAssert("ruleset not changed", () => Ruleset.Value.Equals(new TaikoRuleset().RulesetInfo));
|
||||||
|
@ -0,0 +1,234 @@
|
|||||||
|
// 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.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Screens.OnlinePlay;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
|
{
|
||||||
|
public class TestSceneMultiplayerPlaylist : MultiplayerTestScene
|
||||||
|
{
|
||||||
|
private MultiplayerPlaylist list;
|
||||||
|
private BeatmapManager beatmaps;
|
||||||
|
private RulesetStore rulesets;
|
||||||
|
private BeatmapSetInfo importedSet;
|
||||||
|
private BeatmapInfo importedBeatmap;
|
||||||
|
|
||||||
|
[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));
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public new void Setup() => Schedule(() =>
|
||||||
|
{
|
||||||
|
Child = list = new MultiplayerPlaylist
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Size = new Vector2(0.4f, 0.8f)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public new void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("import beatmap", () =>
|
||||||
|
{
|
||||||
|
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
|
||||||
|
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
|
||||||
|
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("change to all players mode", () => Client.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNonExpiredItemsAddedToQueueList()
|
||||||
|
{
|
||||||
|
assertItemInQueueListStep(1, 0);
|
||||||
|
|
||||||
|
addItemStep();
|
||||||
|
assertItemInQueueListStep(2, 1);
|
||||||
|
|
||||||
|
addItemStep();
|
||||||
|
assertItemInQueueListStep(3, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestExpiredItemsAddedToHistoryList()
|
||||||
|
{
|
||||||
|
assertItemInQueueListStep(1, 0);
|
||||||
|
|
||||||
|
addItemStep(true);
|
||||||
|
assertItemInHistoryListStep(2, 0);
|
||||||
|
|
||||||
|
addItemStep(true);
|
||||||
|
assertItemInHistoryListStep(3, 0);
|
||||||
|
assertItemInHistoryListStep(2, 1);
|
||||||
|
|
||||||
|
// Initial item is still in the queue.
|
||||||
|
assertItemInQueueListStep(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestExpiredItemsMoveToQueueList()
|
||||||
|
{
|
||||||
|
addItemStep();
|
||||||
|
addItemStep();
|
||||||
|
|
||||||
|
AddStep("finish current item", () => Client.FinishCurrentItem());
|
||||||
|
|
||||||
|
assertItemInHistoryListStep(1, 0);
|
||||||
|
assertItemInQueueListStep(2, 0);
|
||||||
|
assertItemInQueueListStep(3, 1);
|
||||||
|
|
||||||
|
AddStep("finish current item", () => Client.FinishCurrentItem());
|
||||||
|
|
||||||
|
assertItemInHistoryListStep(2, 0);
|
||||||
|
assertItemInHistoryListStep(1, 1);
|
||||||
|
assertItemInQueueListStep(3, 0);
|
||||||
|
|
||||||
|
AddStep("finish current item", () => Client.FinishCurrentItem());
|
||||||
|
|
||||||
|
assertItemInHistoryListStep(3, 0);
|
||||||
|
assertItemInHistoryListStep(2, 1);
|
||||||
|
assertItemInHistoryListStep(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestListsClearedWhenRoomLeft()
|
||||||
|
{
|
||||||
|
addItemStep();
|
||||||
|
AddStep("finish current item", () => Client.FinishCurrentItem());
|
||||||
|
|
||||||
|
AddStep("leave room", () => RoomManager.PartRoom());
|
||||||
|
AddUntilStep("wait for room part", () => Client.Room == null);
|
||||||
|
|
||||||
|
AddUntilStep("item 0 not in lists", () => !inHistoryList(0) && !inQueueList(0));
|
||||||
|
AddUntilStep("item 1 not in lists", () => !inHistoryList(0) && !inQueueList(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Ignore("Expired items are initially removed from the room.")]
|
||||||
|
[Test]
|
||||||
|
public void TestJoinRoomWithMixedItemsAddedInCorrectLists()
|
||||||
|
{
|
||||||
|
AddStep("leave room", () => RoomManager.PartRoom());
|
||||||
|
AddUntilStep("wait for room part", () => Client.Room == null);
|
||||||
|
|
||||||
|
AddStep("join room with items", () =>
|
||||||
|
{
|
||||||
|
RoomManager.CreateRoom(new Room
|
||||||
|
{
|
||||||
|
Name = { Value = "test name" },
|
||||||
|
Playlist =
|
||||||
|
{
|
||||||
|
new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo },
|
||||||
|
Ruleset = { Value = Ruleset.Value }
|
||||||
|
},
|
||||||
|
new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo },
|
||||||
|
Ruleset = { Value = Ruleset.Value },
|
||||||
|
Expired = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for room join", () => RoomJoined);
|
||||||
|
|
||||||
|
assertItemInQueueListStep(1, 0);
|
||||||
|
assertItemInHistoryListStep(2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a step to create a new playlist item.
|
||||||
|
/// </summary>
|
||||||
|
private void addItemStep(bool expired = false) => AddStep("add item", () => Client.AddPlaylistItem(new MultiplayerPlaylistItem(new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = importedBeatmap },
|
||||||
|
BeatmapID = importedBeatmap.OnlineID ?? -1,
|
||||||
|
Expired = expired,
|
||||||
|
PlayedAt = DateTimeOffset.Now
|
||||||
|
})));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Asserts the position of a given playlist item in the queue list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="playlistItemId">The item id.</param>
|
||||||
|
/// <param name="visualIndex">The index at which the item should appear visually. The item with index 0 is at the top of the list.</param>
|
||||||
|
private void assertItemInQueueListStep(int playlistItemId, int visualIndex)
|
||||||
|
{
|
||||||
|
changeDisplayModeStep(MultiplayerPlaylistDisplayMode.Queue);
|
||||||
|
|
||||||
|
AddUntilStep($"{playlistItemId} in queue at pos = {visualIndex}", () =>
|
||||||
|
{
|
||||||
|
return !inHistoryList(playlistItemId)
|
||||||
|
&& this.ChildrenOfType<MultiplayerQueueList>()
|
||||||
|
.Single()
|
||||||
|
.ChildrenOfType<DrawableRoomPlaylistItem>()
|
||||||
|
.OrderBy(drawable => drawable.Position.Y)
|
||||||
|
.TakeWhile(drawable => drawable.Item.ID != playlistItemId)
|
||||||
|
.Count() == visualIndex;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Asserts the position of a given playlist item in the history list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="playlistItemId">The item id.</param>
|
||||||
|
/// <param name="visualIndex">The index at which the item should appear visually. The item with index 0 is at the top of the list.</param>
|
||||||
|
private void assertItemInHistoryListStep(int playlistItemId, int visualIndex)
|
||||||
|
{
|
||||||
|
changeDisplayModeStep(MultiplayerPlaylistDisplayMode.History);
|
||||||
|
|
||||||
|
AddUntilStep($"{playlistItemId} in history at pos = {visualIndex}", () =>
|
||||||
|
{
|
||||||
|
return !inQueueList(playlistItemId)
|
||||||
|
&& this.ChildrenOfType<MultiplayerHistoryList>()
|
||||||
|
.Single()
|
||||||
|
.ChildrenOfType<DrawableRoomPlaylistItem>()
|
||||||
|
.OrderBy(drawable => drawable.Position.Y)
|
||||||
|
.TakeWhile(drawable => drawable.Item.ID != playlistItemId)
|
||||||
|
.Count() == visualIndex;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeDisplayModeStep(MultiplayerPlaylistDisplayMode mode) => AddStep($"change list to {mode}", () => list.DisplayMode.Value = mode);
|
||||||
|
|
||||||
|
private bool inQueueList(int playlistItemId)
|
||||||
|
{
|
||||||
|
return this.ChildrenOfType<MultiplayerQueueList>()
|
||||||
|
.Single()
|
||||||
|
.Items.Any(i => i.ID == playlistItemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool inHistoryList(int playlistItemId)
|
||||||
|
{
|
||||||
|
return this.ChildrenOfType<MultiplayerHistoryList>()
|
||||||
|
.Single()
|
||||||
|
.Items.Any(i => i.ID == playlistItemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
PlaylistItem playlistItem = new PlaylistItem
|
PlaylistItem playlistItem = new PlaylistItem
|
||||||
{
|
{
|
||||||
BeatmapID = beatmapInfo.ID,
|
BeatmapID = beatmapInfo.OnlineID ?? -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
Stack.Push(screen = new MultiplayerResultsScreen(score, 1, playlistItem));
|
Stack.Push(screen = new MultiplayerResultsScreen(score, 1, playlistItem));
|
||||||
|
@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
PlaylistItem playlistItem = new PlaylistItem
|
PlaylistItem playlistItem = new PlaylistItem
|
||||||
{
|
{
|
||||||
BeatmapID = beatmapInfo.ID,
|
BeatmapID = beatmapInfo.OnlineID ?? -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
SortedDictionary<int, BindableInt> teamScores = new SortedDictionary<int, BindableInt>
|
SortedDictionary<int, BindableInt> teamScores = new SortedDictionary<int, BindableInt>
|
||||||
|
@ -2,14 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Extensions;
|
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
@ -21,15 +17,13 @@ using osu.Game.Rulesets.Osu;
|
|||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osu.Game.Tests.Visual.OnlinePlay;
|
using osu.Game.Tests.Visual.OnlinePlay;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
{
|
{
|
||||||
public class TestScenePlaylistsSongSelect : OnlinePlayTestScene
|
public class TestScenePlaylistsSongSelect : OnlinePlayTestScene
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmapManager { get; set; }
|
|
||||||
|
|
||||||
private BeatmapManager manager;
|
private BeatmapManager manager;
|
||||||
|
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
@ -42,43 +36,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
|
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++)
|
manager.Import(beatmapSet).Wait();
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
@ -94,7 +54,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddStep("create song select", () => LoadScreen(songSelect = new TestPlaylistsSongSelect(SelectedRoom.Value)));
|
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]
|
[Test]
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Testing;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets;
|
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);
|
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]
|
[Test]
|
||||||
public void TestChangeTypeViaMatchSettings()
|
public void TestChangeTypeViaMatchSettings()
|
||||||
{
|
{
|
||||||
@ -152,6 +180,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
|
||||||
AddWaitStep("wait for transition", 2);
|
AddWaitStep("wait for transition", 2);
|
||||||
|
|
||||||
|
AddUntilStep("create room button enabled", () => this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single().Enabled.Value);
|
||||||
AddStep("create room", () =>
|
AddStep("create room", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single());
|
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single());
|
||||||
|
39
osu.Game.Tests/Visual/Navigation/TestSceneEditDefaultSkin.cs
Normal file
39
osu.Game.Tests/Visual/Navigation/TestSceneEditDefaultSkin.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// 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.Testing;
|
||||||
|
using osu.Game.Overlays.Settings.Sections;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Skinning.Editor;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Navigation
|
||||||
|
{
|
||||||
|
public class TestSceneEditDefaultSkin : OsuGameTestScene
|
||||||
|
{
|
||||||
|
private SkinManager skinManager => Game.Dependencies.Get<SkinManager>();
|
||||||
|
private SkinEditorOverlay skinEditor => Game.Dependencies.Get<SkinEditorOverlay>();
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestEditDefaultSkin()
|
||||||
|
{
|
||||||
|
AddAssert("is default skin", () => skinManager.CurrentSkinInfo.Value.ID == SkinInfo.DEFAULT_SKIN);
|
||||||
|
|
||||||
|
AddStep("open settings", () => { Game.Settings.Show(); });
|
||||||
|
|
||||||
|
// Until step requires as settings has a delayed load.
|
||||||
|
AddUntilStep("export button disabled", () => Game.Settings.ChildrenOfType<SkinSection.ExportSkinButton>().SingleOrDefault()?.Enabled.Value == false);
|
||||||
|
|
||||||
|
// Will create a mutable skin.
|
||||||
|
AddStep("open skin editor", () => skinEditor.Show());
|
||||||
|
|
||||||
|
// Until step required as the skin editor may take time to load (and an extra scheduled frame for the mutable part).
|
||||||
|
AddUntilStep("is modified default skin", () => skinManager.CurrentSkinInfo.Value.ID != SkinInfo.DEFAULT_SKIN);
|
||||||
|
AddAssert("is not protected", () => skinManager.CurrentSkinInfo.Value.PerformRead(s => !s.Protected));
|
||||||
|
|
||||||
|
AddUntilStep("export button enabled", () => Game.Settings.ChildrenOfType<SkinSection.ExportSkinButton>().SingleOrDefault()?.Enabled.Value == true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
// 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.Game.Configuration;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Navigation
|
||||||
|
{
|
||||||
|
public class TestSceneMouseWheelVolumeAdjust : OsuGameTestScene
|
||||||
|
{
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
|
// Headless tests are always at minimum volume. This covers interactive tests, matching that initial value.
|
||||||
|
AddStep("Set volume to min", () => Game.Audio.Volume.Value = 0);
|
||||||
|
AddAssert("Volume is min", () => Game.Audio.AggregateVolume.Value == 0);
|
||||||
|
AddStep("Move mouse to centre", () => InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAdjustVolumeFromMainMenu()
|
||||||
|
{
|
||||||
|
// First scroll makes volume controls appear, second adjusts volume.
|
||||||
|
AddRepeatStep("Adjust volume using mouse wheel", () => InputManager.ScrollVerticalBy(5), 2);
|
||||||
|
AddUntilStep("Volume is above zero", () => Game.Audio.AggregateVolume.Value > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAdjustVolumeFromPlayerWheelEnabled()
|
||||||
|
{
|
||||||
|
loadToPlayerNonBreakTime();
|
||||||
|
|
||||||
|
// First scroll makes volume controls appear, second adjusts volume.
|
||||||
|
AddRepeatStep("Adjust volume using mouse wheel", () => InputManager.ScrollVerticalBy(5), 2);
|
||||||
|
AddAssert("Volume is above zero", () => Game.Audio.Volume.Value > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAdjustVolumeFromPlayerWheelDisabled()
|
||||||
|
{
|
||||||
|
AddStep("disable wheel volume adjust", () => Game.LocalConfig.SetValue(OsuSetting.MouseDisableWheel, true));
|
||||||
|
|
||||||
|
loadToPlayerNonBreakTime();
|
||||||
|
|
||||||
|
// First scroll makes volume controls appear, second adjusts volume.
|
||||||
|
AddRepeatStep("Adjust volume using mouse wheel", () => InputManager.ScrollVerticalBy(5), 2);
|
||||||
|
AddAssert("Volume is still zero", () => Game.Audio.Volume.Value == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAdjustVolumeFromPlayerWheelDisabledHoldingAlt()
|
||||||
|
{
|
||||||
|
AddStep("disable wheel volume adjust", () => Game.LocalConfig.SetValue(OsuSetting.MouseDisableWheel, true));
|
||||||
|
|
||||||
|
loadToPlayerNonBreakTime();
|
||||||
|
|
||||||
|
// First scroll makes volume controls appear, second adjusts volume.
|
||||||
|
AddRepeatStep("Adjust volume using mouse wheel holding alt", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.AltLeft);
|
||||||
|
InputManager.ScrollVerticalBy(5);
|
||||||
|
InputManager.ReleaseKey(Key.AltLeft);
|
||||||
|
}, 2);
|
||||||
|
|
||||||
|
AddAssert("Volume is above zero", () => Game.Audio.Volume.Value > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadToPlayerNonBreakTime()
|
||||||
|
{
|
||||||
|
Player player = null;
|
||||||
|
Screens.Select.SongSelect songSelect = null;
|
||||||
|
PushAndConfirm(() => songSelect = new TestSceneScreenNavigation.TestPlaySongSelect());
|
||||||
|
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
|
||||||
|
|
||||||
|
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
|
||||||
|
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
|
||||||
|
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
|
AddUntilStep("wait for player", () =>
|
||||||
|
{
|
||||||
|
// dismiss any notifications that may appear (ie. muted notification).
|
||||||
|
clickMouseInCentre();
|
||||||
|
return (player = Game.ScreenStack.CurrentScreen as Player) != null;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for play time active", () => !player.IsBreakTime.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clickMouseInCentre()
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -83,9 +83,6 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameBase gameBase { get; set; }
|
private OsuGameBase gameBase { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private GameHost host { get; set; }
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestNullRulesetHandled()
|
public void TestNullRulesetHandled()
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
@ -110,7 +109,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
Hash = Guid.NewGuid().ToString(),
|
Hash = Guid.NewGuid().ToString(),
|
||||||
OnlineID = i,
|
OnlineID = i,
|
||||||
Metadata = metadata,
|
Metadata = metadata,
|
||||||
Beatmaps = new List<BeatmapInfo>
|
Beatmaps =
|
||||||
{
|
{
|
||||||
new BeatmapInfo
|
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("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect);
|
||||||
AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapSetInfo.MatchesOnlineID(getImport()));
|
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)
|
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("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect);
|
||||||
AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.OnlineID == importedID * 2048);
|
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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
@ -41,7 +40,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
Hash = Guid.NewGuid().ToString(),
|
Hash = Guid.NewGuid().ToString(),
|
||||||
OnlineID = 1,
|
OnlineID = 1,
|
||||||
Metadata = metadata,
|
Metadata = metadata,
|
||||||
Beatmaps = new List<BeatmapInfo>
|
Beatmaps =
|
||||||
{
|
{
|
||||||
new BeatmapInfo
|
new BeatmapInfo
|
||||||
{
|
{
|
||||||
@ -155,15 +154,15 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
case ScorePresentType.Results:
|
case ScorePresentType.Results:
|
||||||
AddUntilStep("wait for results", () => lastWaitedScreen != Game.ScreenStack.CurrentScreen && Game.ScreenStack.CurrentScreen is ResultsScreen);
|
AddUntilStep("wait for results", () => lastWaitedScreen != Game.ScreenStack.CurrentScreen && Game.ScreenStack.CurrentScreen is ResultsScreen);
|
||||||
AddStep("store last waited screen", () => lastWaitedScreen = Game.ScreenStack.CurrentScreen);
|
AddStep("store last waited screen", () => lastWaitedScreen = Game.ScreenStack.CurrentScreen);
|
||||||
AddUntilStep("correct score displayed", () => ((ResultsScreen)Game.ScreenStack.CurrentScreen).Score.ID == getImport().ID);
|
AddUntilStep("correct score displayed", () => ((ResultsScreen)Game.ScreenStack.CurrentScreen).Score.Equals(getImport()));
|
||||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Ruleset.ID);
|
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.Equals(getImport().Ruleset));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ScorePresentType.Gameplay:
|
case ScorePresentType.Gameplay:
|
||||||
AddUntilStep("wait for player loader", () => lastWaitedScreen != Game.ScreenStack.CurrentScreen && Game.ScreenStack.CurrentScreen is ReplayPlayerLoader);
|
AddUntilStep("wait for player loader", () => lastWaitedScreen != Game.ScreenStack.CurrentScreen && Game.ScreenStack.CurrentScreen is ReplayPlayerLoader);
|
||||||
AddStep("store last waited screen", () => lastWaitedScreen = Game.ScreenStack.CurrentScreen);
|
AddStep("store last waited screen", () => lastWaitedScreen = Game.ScreenStack.CurrentScreen);
|
||||||
AddUntilStep("correct score displayed", () => ((ReplayPlayerLoader)Game.ScreenStack.CurrentScreen).Score.ID == getImport().ID);
|
AddUntilStep("correct score displayed", () => ((ReplayPlayerLoader)Game.ScreenStack.CurrentScreen).Score.Equals(getImport()));
|
||||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Ruleset.ID);
|
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.Equals(getImport().Ruleset));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,9 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
{
|
{
|
||||||
Player player = null;
|
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());
|
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
|
||||||
|
|
||||||
@ -98,7 +100,9 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
|
|
||||||
IWorkingBeatmap beatmap() => Game.Beatmap.Value;
|
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());
|
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
|
||||||
|
|
||||||
@ -130,7 +134,9 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
|
|
||||||
IWorkingBeatmap beatmap() => Game.Beatmap.Value;
|
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());
|
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
|
||||||
|
|
||||||
@ -257,7 +263,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
InputManager.ReleaseKey(Key.ControlLeft);
|
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);
|
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);
|
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);
|
AddAssert("Options overlay still visible", () => songSelect.BeatmapOptionsOverlay.State.Value == Visibility.Visible);
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,15 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Drawables;
|
||||||
using osu.Game.Online;
|
using osu.Game.Online;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Overlays.BeatmapListing.Panels;
|
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Online
|
namespace osu.Game.Tests.Visual.Online
|
||||||
{
|
{
|
||||||
public class TestSceneDirectDownloadButton : OsuTestScene
|
public class TestSceneBeatmapDownloadButton : OsuTestScene
|
||||||
{
|
{
|
||||||
private TestDownloadButton downloadButton;
|
private TestDownloadButton downloadButton;
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
return apiBeatmapSet;
|
return apiBeatmapSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestDownloadButton : BeatmapPanelDownloadButton
|
private class TestDownloadButton : BeatmapDownloadButton
|
||||||
{
|
{
|
||||||
public new bool DownloadEnabled => base.DownloadEnabled;
|
public new bool DownloadEnabled => base.DownloadEnabled;
|
||||||
|
|
@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMultipleRulesetsBeatmapSet()
|
public void TestMultipleRulesetsBeatmapSet()
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLoading()
|
public void TestLoading()
|
||||||
@ -200,7 +200,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
OnlineID = i * 10,
|
OnlineID = i * 10,
|
||||||
DifficultyName = $"Test #{i}",
|
DifficultyName = $"Test #{i}",
|
||||||
RulesetID = Ruleset.Value.ID ?? -1,
|
RulesetID = Ruleset.Value.OnlineID,
|
||||||
StarRating = 2 + i * 0.1,
|
StarRating = 2 + i * 0.1,
|
||||||
OverallDifficulty = 3.5f,
|
OverallDifficulty = 3.5f,
|
||||||
FailTimes = new APIFailTimes
|
FailTimes = new APIFailTimes
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Ratings = Enumerable.Range(0, 11).Select(_ => RNG.Next(10)).ToArray(),
|
Ratings = Enumerable.Range(0, 11).Select(_ => RNG.Next(10)).ToArray(),
|
||||||
Status = BeatmapSetOnlineStatus.Ranked
|
Status = BeatmapOnlineStatus.Ranked
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Platform;
|
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
@ -47,9 +46,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private Func<Channel, List<Message>> onGetMessages;
|
private Func<Channel, List<Message>> onGetMessages;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private GameHost host { get; set; }
|
|
||||||
|
|
||||||
public TestSceneChatOverlay()
|
public TestSceneChatOverlay()
|
||||||
{
|
{
|
||||||
channels = Enumerable.Range(1, 10)
|
channels = Enumerable.Range(1, 10)
|
||||||
|
@ -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)
|
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()));
|
AddStep("Run command", () => Add(new NowPlayingCommand()));
|
||||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
private TestUserListPanel evast;
|
private TestUserListPanel evast;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesetStore { get; set; }
|
private IRulesetStore rulesetStore { get; set; }
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Online.API;
|
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Profile;
|
using osu.Game.Overlays.Profile;
|
||||||
@ -20,9 +18,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
private readonly TestUserProfileOverlay profile;
|
private readonly TestUserProfileOverlay profile;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IAPIProvider api { get; set; }
|
|
||||||
|
|
||||||
public static readonly APIUser TEST_USER = new APIUser
|
public static readonly APIUser TEST_USER = new APIUser
|
||||||
{
|
{
|
||||||
Username = @"Somebody",
|
Username = @"Somebody",
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
@ -20,9 +19,6 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
{
|
{
|
||||||
public class TestSceneContractedPanelMiddleContent : OsuTestScene
|
public class TestSceneContractedPanelMiddleContent : OsuTestScene
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesetStore { get; set; }
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestShowPanel()
|
public void TestShowPanel()
|
||||||
{
|
{
|
||||||
|
@ -338,7 +338,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
: base(score, true)
|
: base(score, true)
|
||||||
{
|
{
|
||||||
Score.BeatmapInfo.OnlineID = 0;
|
Score.BeatmapInfo.OnlineID = 0;
|
||||||
Score.BeatmapInfo.Status = BeatmapSetOnlineStatus.Pending;
|
Score.BeatmapInfo.Status = BeatmapOnlineStatus.Pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -3,15 +3,11 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Utils;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -19,6 +15,7 @@ using osu.Game.Rulesets.Osu;
|
|||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Screens.Select.Carousel;
|
using osu.Game.Screens.Select.Carousel;
|
||||||
using osu.Game.Screens.Select.Filter;
|
using osu.Game.Screens.Select.Filter;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.SongSelect
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
@ -152,7 +149,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
const int total_set_count = 200;
|
const int total_set_count = 200;
|
||||||
|
|
||||||
for (int i = 0; i < total_set_count; i++)
|
for (int i = 0; i < total_set_count; i++)
|
||||||
sets.Add(createTestBeatmapSet(i + 1));
|
sets.Add(TestResources.CreateTestBeatmapSetInfo());
|
||||||
|
|
||||||
loadBeatmaps(sets);
|
loadBeatmaps(sets);
|
||||||
|
|
||||||
@ -183,7 +180,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
const int total_set_count = 20;
|
const int total_set_count = 20;
|
||||||
|
|
||||||
for (int i = 0; i < total_set_count; i++)
|
for (int i = 0; i < total_set_count; i++)
|
||||||
sets.Add(createTestBeatmapSet(i + 1));
|
sets.Add(TestResources.CreateTestBeatmapSetInfo(3));
|
||||||
|
|
||||||
loadBeatmaps(sets);
|
loadBeatmaps(sets);
|
||||||
|
|
||||||
@ -228,10 +225,9 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
loadBeatmaps();
|
loadBeatmaps();
|
||||||
|
|
||||||
// basic filtering
|
// basic filtering
|
||||||
|
|
||||||
setSelected(1, 1);
|
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: false, count: 1);
|
||||||
checkVisibleItemCount(diff: true, count: 3);
|
checkVisibleItemCount(diff: true, count: 3);
|
||||||
waitForSelection(3, 1);
|
waitForSelection(3, 1);
|
||||||
@ -275,16 +271,20 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestFilterRange()
|
public void TestFilterRange()
|
||||||
{
|
{
|
||||||
|
string searchText = null;
|
||||||
|
|
||||||
loadBeatmaps();
|
loadBeatmaps();
|
||||||
|
|
||||||
// buffer the selection
|
// buffer the selection
|
||||||
setSelected(3, 2);
|
setSelected(3, 2);
|
||||||
|
|
||||||
|
AddStep("get search text", () => searchText = carousel.SelectedBeatmapSet.Metadata.Title);
|
||||||
|
|
||||||
setSelected(1, 3);
|
setSelected(1, 3);
|
||||||
|
|
||||||
AddStep("Apply a range filter", () => carousel.Filter(new FilterCriteria
|
AddStep("Apply a range filter", () => carousel.Filter(new FilterCriteria
|
||||||
{
|
{
|
||||||
SearchText = "#3",
|
SearchText = searchText,
|
||||||
StarDifficulty = new FilterCriteria.OptionalRange<double>
|
StarDifficulty = new FilterCriteria.OptionalRange<double>
|
||||||
{
|
{
|
||||||
Min = 2,
|
Min = 2,
|
||||||
@ -327,7 +327,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
nextRandom();
|
nextRandom();
|
||||||
AddAssert("ensure repeat", () => selectedSets.Contains(carousel.SelectedBeatmapSet));
|
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));
|
AddStep("Filter Extra", () => carousel.Filter(new FilterCriteria { SearchText = "Extra 10" }, false));
|
||||||
checkInvisibleDifficultiesUnselectable();
|
checkInvisibleDifficultiesUnselectable();
|
||||||
checkInvisibleDifficultiesUnselectable();
|
checkInvisibleDifficultiesUnselectable();
|
||||||
@ -345,18 +345,21 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
loadBeatmaps();
|
loadBeatmaps();
|
||||||
|
|
||||||
AddStep("Add new set", () => carousel.UpdateBeatmapSet(createTestBeatmapSet(set_count + 1)));
|
var firstAdded = TestResources.CreateTestBeatmapSetInfo();
|
||||||
AddStep("Add new set", () => carousel.UpdateBeatmapSet(createTestBeatmapSet(set_count + 2)));
|
var secondAdded = TestResources.CreateTestBeatmapSetInfo();
|
||||||
|
|
||||||
|
AddStep("Add new set", () => carousel.UpdateBeatmapSet(firstAdded));
|
||||||
|
AddStep("Add new set", () => carousel.UpdateBeatmapSet(secondAdded));
|
||||||
|
|
||||||
checkVisibleItemCount(false, set_count + 2);
|
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);
|
checkVisibleItemCount(false, set_count + 1);
|
||||||
|
|
||||||
setSelected(set_count + 1, 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);
|
checkVisibleItemCount(false, set_count);
|
||||||
|
|
||||||
@ -372,7 +375,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
sets.Clear();
|
sets.Clear();
|
||||||
|
|
||||||
var rulesetBeatmapSet = createTestBeatmapSet(1);
|
var rulesetBeatmapSet = TestResources.CreateTestBeatmapSetInfo(1);
|
||||||
var taikoRuleset = rulesets.AvailableRulesets.ElementAt(1);
|
var taikoRuleset = rulesets.AvailableRulesets.ElementAt(1);
|
||||||
rulesetBeatmapSet.Beatmaps.ForEach(b =>
|
rulesetBeatmapSet.Beatmaps.ForEach(b =>
|
||||||
{
|
{
|
||||||
@ -397,12 +400,29 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSorting()
|
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));
|
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));
|
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]
|
[Test]
|
||||||
@ -412,20 +432,21 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
{
|
{
|
||||||
// index + 1 because we are using OnlineID which should never be zero.
|
var set = TestResources.CreateTestBeatmapSetInfo();
|
||||||
var set = createTestBeatmapSet(i + 1);
|
|
||||||
set.Metadata.Artist = "same artist";
|
set.Metadata.Artist = "same artist";
|
||||||
set.Metadata.Title = "same title";
|
set.Metadata.Title = "same title";
|
||||||
sets.Add(set);
|
sets.Add(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int idOffset = sets.First().OnlineID ?? 0;
|
||||||
|
|
||||||
loadBeatmaps(sets);
|
loadBeatmaps(sets);
|
||||||
|
|
||||||
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
|
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
|
||||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == index + 1).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));
|
AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false));
|
||||||
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == index + 1).All(b => b));
|
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == index + idOffset).All(b => b));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -435,7 +456,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
var set = createTestBeatmapSet(i);
|
var set = TestResources.CreateTestBeatmapSetInfo(3);
|
||||||
set.Beatmaps[0].StarRating = 3 - i;
|
set.Beatmaps[0].StarRating = 3 - i;
|
||||||
set.Beatmaps[2].StarRating = 6 + i;
|
set.Beatmaps[2].StarRating = 6 + i;
|
||||||
sets.Add(set);
|
sets.Add(set);
|
||||||
@ -504,7 +525,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("create hidden set", () =>
|
AddStep("create hidden set", () =>
|
||||||
{
|
{
|
||||||
hidingSet = createTestBeatmapSet(1);
|
hidingSet = TestResources.CreateTestBeatmapSetInfo(3);
|
||||||
hidingSet.Beatmaps[1].Hidden = true;
|
hidingSet.Beatmaps[1].Hidden = true;
|
||||||
|
|
||||||
hiddenList.Clear();
|
hiddenList.Clear();
|
||||||
@ -551,7 +572,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("add mixed ruleset beatmapset", () =>
|
AddStep("add mixed ruleset beatmapset", () =>
|
||||||
{
|
{
|
||||||
testMixed = createTestBeatmapSet(set_count + 1);
|
testMixed = TestResources.CreateTestBeatmapSetInfo(3);
|
||||||
|
|
||||||
for (int i = 0; i <= 2; i++)
|
for (int i = 0; i <= 2; i++)
|
||||||
{
|
{
|
||||||
@ -574,7 +595,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
BeatmapSetInfo testSingle = null;
|
BeatmapSetInfo testSingle = null;
|
||||||
AddStep("add single ruleset beatmapset", () =>
|
AddStep("add single ruleset beatmapset", () =>
|
||||||
{
|
{
|
||||||
testSingle = createTestBeatmapSet(set_count + 2);
|
testSingle = TestResources.CreateTestBeatmapSetInfo(3);
|
||||||
testSingle.Beatmaps.ForEach(b =>
|
testSingle.Beatmaps.ForEach(b =>
|
||||||
{
|
{
|
||||||
b.Ruleset = rulesets.AvailableRulesets.ElementAt(1);
|
b.Ruleset = rulesets.AvailableRulesets.ElementAt(1);
|
||||||
@ -594,7 +615,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
List<BeatmapSetInfo> manySets = new List<BeatmapSetInfo>();
|
List<BeatmapSetInfo> manySets = new List<BeatmapSetInfo>();
|
||||||
|
|
||||||
for (int i = 1; i <= 50; i++)
|
for (int i = 1; i <= 50; i++)
|
||||||
manySets.Add(createTestBeatmapSet(i));
|
manySets.Add(TestResources.CreateTestBeatmapSetInfo(3));
|
||||||
|
|
||||||
loadBeatmaps(manySets);
|
loadBeatmaps(manySets);
|
||||||
|
|
||||||
@ -627,18 +648,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
var set = createTestBeatmapSet(i);
|
manySets.Add(TestResources.CreateTestBeatmapSetInfo(3, new[]
|
||||||
|
|
||||||
foreach (var b in set.Beatmaps)
|
|
||||||
{
|
{
|
||||||
// all taiko except for first
|
// all taiko except for first
|
||||||
int ruleset = i > 0 ? 1 : 0;
|
rulesets.GetRuleset(i > 0 ? 1 : 0)
|
||||||
|
}));
|
||||||
b.Ruleset = rulesets.GetRuleset(ruleset);
|
|
||||||
b.RulesetID = ruleset;
|
|
||||||
}
|
|
||||||
|
|
||||||
manySets.Add(set);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -660,7 +674,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddStep("Restore different ruleset filter", () =>
|
AddStep("Restore different ruleset filter", () =>
|
||||||
{
|
{
|
||||||
carousel.Filter(new FilterCriteria { Ruleset = rulesets.GetRuleset(1) }, false);
|
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.Equals(manySets.First().Beatmaps.First()));
|
AddAssert("selection changed", () => !carousel.SelectedBeatmapInfo.Equals(manySets.First().Beatmaps.First()));
|
||||||
@ -678,7 +692,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("add mixed difficulty set", () =>
|
AddStep("add mixed difficulty set", () =>
|
||||||
{
|
{
|
||||||
set = createTestBeatmapSet(1);
|
set = TestResources.CreateTestBeatmapSetInfo(1);
|
||||||
set.Beatmaps.Clear();
|
set.Beatmaps.Clear();
|
||||||
|
|
||||||
for (int i = 1; i <= 15; i++)
|
for (int i = 1; i <= 15; i++)
|
||||||
@ -730,7 +744,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
beatmapSets = new List<BeatmapSetInfo>();
|
beatmapSets = new List<BeatmapSetInfo>();
|
||||||
|
|
||||||
for (int i = 1; i <= (count ?? set_count); i++)
|
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());
|
carousel.Filter(initialCriteria?.Invoke() ?? new FilterCriteria());
|
||||||
@ -766,7 +784,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddUntilStep($"selected is set{set}{(diff.HasValue ? $" diff{diff.Value}" : "")}", () =>
|
AddUntilStep($"selected is set{set}{(diff.HasValue ? $" diff{diff.Value}" : "")}", () =>
|
||||||
{
|
{
|
||||||
if (diff != null)
|
if (diff != null)
|
||||||
return carousel.SelectedBeatmapInfo.Equals(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);
|
return carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Contains(carousel.SelectedBeatmapInfo);
|
||||||
});
|
});
|
||||||
@ -834,88 +852,6 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddAssert("Selection is visible", selectedBeatmapVisible);
|
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
|
private class TestBeatmapCarousel : BeatmapCarousel
|
||||||
{
|
{
|
||||||
public bool PendingFilterTask => PendingFilter != null;
|
public bool PendingFilterTask => PendingFilter != null;
|
||||||
|
@ -82,7 +82,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
beatmaps.Add(testBeatmap);
|
beatmaps.Add(testBeatmap);
|
||||||
|
|
||||||
AddStep("set ruleset", () => Ruleset.Value = rulesetInfo);
|
setRuleset(rulesetInfo);
|
||||||
|
|
||||||
selectBeatmap(testBeatmap);
|
selectBeatmap(testBeatmap);
|
||||||
|
|
||||||
@ -167,6 +167,22 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
label => label.Statistic.Name == "BPM" && label.Statistic.Content == target.ToString(CultureInfo.InvariantCulture)));
|
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)
|
private void selectBeatmap([CanBeNull] IBeatmap b)
|
||||||
{
|
{
|
||||||
Container containerBefore = null;
|
Container containerBefore = null;
|
||||||
@ -220,7 +236,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
Title = "Verrrrry long Title"
|
Title = "Verrrrry long Title"
|
||||||
},
|
},
|
||||||
DifficultyName = "Verrrrrrrrrrrrrrrrrrrrrrrrrrrrry long Version",
|
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(rulesetStore = new RulesetStore(ContextFactory));
|
||||||
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
|
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;
|
return dependencies;
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestBeatmapStates()
|
public void TestBeatmapStates()
|
||||||
{
|
{
|
||||||
foreach (BeatmapSetOnlineStatus status in Enum.GetValues(typeof(BeatmapSetOnlineStatus)))
|
foreach (BeatmapOnlineStatus status in Enum.GetValues(typeof(BeatmapOnlineStatus)))
|
||||||
AddStep($"{status} beatmap", () => showBeatmapWithStatus(status));
|
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
|
leaderboard.BeatmapInfo = new BeatmapInfo
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@ using osu.Game.Rulesets.Catch;
|
|||||||
using osu.Game.Rulesets.Mania;
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Taiko;
|
using osu.Game.Rulesets.Taiko;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.SongSelect
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
@ -32,7 +33,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
switch (req)
|
switch (req)
|
||||||
{
|
{
|
||||||
case GetUserRequest userRequest:
|
case GetUserRequest userRequest:
|
||||||
userRequest.TriggerSuccess(getUser(userRequest.Ruleset.ID));
|
userRequest.TriggerSuccess(getUser(userRequest.Ruleset.OnlineID));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +90,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
for (int i = 0; i < import_count; ++i)
|
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;
|
BeatmapSetInfo catchSet = null, mixedSet = null;
|
||||||
|
|
||||||
AddStep("create catch beatmapset", () => catchSet = importBeatmapSet(1, new[] { new CatchRuleset().RulesetInfo }));
|
AddStep("create catch beatmapset", () => catchSet = importBeatmapSet(new[] { new CatchRuleset().RulesetInfo }));
|
||||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
|
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
|
||||||
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
|
|
||||||
|
|
||||||
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { catchSet, mixedSet }));
|
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { catchSet, mixedSet }));
|
||||||
|
|
||||||
@ -121,9 +121,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
BeatmapSetInfo osuSet = null, mixedSet = null;
|
BeatmapSetInfo osuSet = null, mixedSet = null;
|
||||||
|
|
||||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
|
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(new[] { new OsuRuleset().RulesetInfo }));
|
||||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
|
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
|
||||||
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new ManiaRuleset().RulesetInfo }));
|
|
||||||
|
|
||||||
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet }));
|
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet }));
|
||||||
|
|
||||||
@ -139,9 +138,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
BeatmapSetInfo osuSet = null, mixedSet = null;
|
BeatmapSetInfo osuSet = null, mixedSet = null;
|
||||||
|
|
||||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
|
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(new[] { new OsuRuleset().RulesetInfo }));
|
||||||
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(2,
|
AddStep("create mixed beatmapset", () => mixedSet = importBeatmapSet(new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new TaikoRuleset().RulesetInfo }));
|
||||||
new[] { new TaikoRuleset().RulesetInfo, new CatchRuleset().RulesetInfo, new TaikoRuleset().RulesetInfo }));
|
|
||||||
|
|
||||||
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet }));
|
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, mixedSet }));
|
||||||
|
|
||||||
@ -157,8 +155,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
BeatmapSetInfo osuSet = null, maniaSet = null;
|
BeatmapSetInfo osuSet = null, maniaSet = null;
|
||||||
|
|
||||||
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(1, new[] { new OsuRuleset().RulesetInfo }));
|
AddStep("create osu! beatmapset", () => osuSet = importBeatmapSet(new[] { new OsuRuleset().RulesetInfo }));
|
||||||
AddStep("create mania beatmapset", () => maniaSet = importBeatmapSet(2, Enumerable.Repeat(new ManiaRuleset().RulesetInfo, 10)));
|
AddStep("create mania beatmapset", () => maniaSet = importBeatmapSet(Enumerable.Repeat(new ManiaRuleset().RulesetInfo, 10)));
|
||||||
|
|
||||||
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, maniaSet }));
|
AddAssert("all sets imported", () => ensureAllBeatmapSetsImported(new[] { osuSet, maniaSet }));
|
||||||
|
|
||||||
@ -169,30 +167,19 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
presentAndConfirm(() => maniaSet, 5);
|
presentAndConfirm(() => maniaSet, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BeatmapSetInfo importBeatmapSet(int importID, IEnumerable<RulesetInfo> difficultyRulesets)
|
private BeatmapSetInfo importBeatmapSet(IEnumerable<RulesetInfo> difficultyRulesets)
|
||||||
{
|
{
|
||||||
var metadata = new BeatmapMetadata
|
var rulesets = difficultyRulesets.ToArray();
|
||||||
{
|
|
||||||
Artist = "SomeArtist",
|
|
||||||
AuthorString = "SomeAuthor",
|
|
||||||
Title = $"import {importID}"
|
|
||||||
};
|
|
||||||
|
|
||||||
var beatmapSet = new BeatmapSetInfo
|
var beatmapSet = TestResources.CreateTestBeatmapSetInfo(rulesets.Length, rulesets);
|
||||||
|
|
||||||
|
for (int i = 0; i < rulesets.Length; i++)
|
||||||
{
|
{
|
||||||
Hash = Guid.NewGuid().ToString(),
|
var beatmap = beatmapSet.Beatmaps[i];
|
||||||
OnlineID = importID,
|
|
||||||
Metadata = metadata,
|
beatmap.StarRating = i + 1;
|
||||||
Beatmaps = difficultyRulesets.Select((ruleset, difficultyIndex) => new BeatmapInfo
|
beatmap.DifficultyName = $"SR{i + 1}";
|
||||||
{
|
}
|
||||||
OnlineID = importID * 1024 + difficultyIndex,
|
|
||||||
Metadata = metadata,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty(),
|
|
||||||
Ruleset = ruleset,
|
|
||||||
StarRating = difficultyIndex + 1,
|
|
||||||
DifficultyName = $"SR{difficultyIndex + 1}"
|
|
||||||
}).ToList()
|
|
||||||
};
|
|
||||||
|
|
||||||
return Game.BeatmapManager.Import(beatmapSet).Result.Value;
|
return Game.BeatmapManager.Import(beatmapSet).Result.Value;
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,11 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions;
|
|
||||||
using osu.Framework.Utils;
|
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
@ -31,6 +27,7 @@ using osu.Game.Screens.Play;
|
|||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Screens.Select.Carousel;
|
using osu.Game.Screens.Select.Carousel;
|
||||||
using osu.Game.Screens.Select.Filter;
|
using osu.Game.Screens.Select.Filter;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.SongSelect
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
@ -258,8 +255,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
AddStep("import multi-ruleset map", () =>
|
AddStep("import multi-ruleset map", () =>
|
||||||
{
|
{
|
||||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||||
manager.Import(createTestBeatmapSet(usableRulesets)).Wait();
|
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).Wait();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -354,7 +351,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
target = manager.GetAllUsableBeatmapSets()
|
target = manager.GetAllUsableBeatmapSets()
|
||||||
.Last(b => b.Beatmaps.Any(bi => bi.RulesetID == 0)).Beatmaps.Last();
|
.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);
|
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();
|
.Last(b => b.Beatmaps.Any(bi => bi.RulesetID == 0)).Beatmaps.Last();
|
||||||
|
|
||||||
Beatmap.Value = manager.GetWorkingBeatmap(target);
|
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 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
|
// this is an important check, to make sure updateComponentFromBeatmap() was actually run
|
||||||
AddUntilStep("selection shown on wedge", () => songSelect.CurrentBeatmapDetailsBeatmap.BeatmapInfo.MatchesOnlineID(target));
|
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.
|
// special case for converts checked here.
|
||||||
return selectedPanel.ChildrenOfType<FilterableDifficultyIcon>().All(i =>
|
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);
|
AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmapInfo?.MatchesOnlineID(target) == true);
|
||||||
@ -665,8 +662,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("import multi-ruleset map", () =>
|
AddStep("import multi-ruleset map", () =>
|
||||||
{
|
{
|
||||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||||
manager.Import(createTestBeatmapSet(usableRulesets)).Wait();
|
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait();
|
||||||
});
|
});
|
||||||
|
|
||||||
int previousSetID = 0;
|
int previousSetID = 0;
|
||||||
@ -676,11 +673,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddStep("record set ID", () => previousSetID = ((IBeatmapSetInfo)Beatmap.Value.BeatmapSetInfo).OnlineID);
|
AddStep("record set ID", () => previousSetID = ((IBeatmapSetInfo)Beatmap.Value.BeatmapSetInfo).OnlineID);
|
||||||
AddAssert("selection changed once", () => changeCount == 1);
|
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);
|
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);
|
AddUntilStep("selection changed", () => changeCount > 1);
|
||||||
|
|
||||||
@ -705,8 +702,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("import multi-ruleset map", () =>
|
AddStep("import multi-ruleset map", () =>
|
||||||
{
|
{
|
||||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||||
manager.Import(createTestBeatmapSet(usableRulesets)).Wait();
|
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait();
|
||||||
});
|
});
|
||||||
|
|
||||||
DrawableCarouselBeatmapSet set = null;
|
DrawableCarouselBeatmapSet set = null;
|
||||||
@ -720,11 +717,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddUntilStep("Find an icon for different ruleset", () =>
|
AddUntilStep("Find an icon for different ruleset", () =>
|
||||||
{
|
{
|
||||||
difficultyIcon = set.ChildrenOfType<FilterableDifficultyIcon>()
|
difficultyIcon = set.ChildrenOfType<FilterableDifficultyIcon>()
|
||||||
.FirstOrDefault(icon => icon.Item.BeatmapInfo.Ruleset.ID == 3);
|
.FirstOrDefault(icon => icon.Item.BeatmapInfo.Ruleset.OnlineID == 3);
|
||||||
return difficultyIcon != null;
|
return difficultyIcon != null;
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0);
|
AddAssert("Check ruleset is osu!", () => Ruleset.Value.OnlineID == 0);
|
||||||
|
|
||||||
int previousSetID = 0;
|
int previousSetID = 0;
|
||||||
|
|
||||||
@ -737,7 +734,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
InputManager.Click(MouseButton.Left);
|
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 still same set", () => songSelect.Carousel.SelectedBeatmapInfo.BeatmapSet.OnlineID == previousSetID);
|
||||||
AddAssert("Selected beatmap is mania", () => Beatmap.Value.BeatmapInfo.Ruleset.OnlineID == 3);
|
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", () =>
|
AddStep("import huge difficulty count map", () =>
|
||||||
{
|
{
|
||||||
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
|
||||||
imported = manager.Import(createTestBeatmapSet(usableRulesets, 50)).Result.Value;
|
imported = manager.Import(TestResources.CreateTestBeatmapSetInfo(50, usableRulesets)).Result.Value;
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("select the first beatmap of import", () => Beatmap.Value = manager.GetWorkingBeatmap(imported.Beatmaps.First()));
|
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", () =>
|
AddUntilStep("Find group icon for different ruleset", () =>
|
||||||
{
|
{
|
||||||
return (groupIcon = set.ChildrenOfType<FilterableGroupedDifficultyIcon>()
|
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", () =>
|
AddStep("Click on group", () =>
|
||||||
{
|
{
|
||||||
@ -783,7 +780,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
InputManager.Click(MouseButton.Left);
|
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));
|
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());
|
AddUntilStep("wait for results screen presented", () => !songSelect.IsCurrentScreen());
|
||||||
|
|
||||||
AddAssert("check beatmap is correct for score", () => Beatmap.Value.BeatmapInfo.MatchesOnlineID(getPresentBeatmap()));
|
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]
|
[Test]
|
||||||
@ -849,7 +846,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddUntilStep("wait for results screen presented", () => !songSelect.IsCurrentScreen());
|
AddUntilStep("wait for results screen presented", () => !songSelect.IsCurrentScreen());
|
||||||
|
|
||||||
AddAssert("check beatmap is correct for score", () => Beatmap.Value.BeatmapInfo.MatchesOnlineID(getPresentBeatmap()));
|
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()
|
private void waitForInitialSelection()
|
||||||
@ -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 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 void importForRuleset(int id) => manager.Import(TestResources.CreateTestBeatmapSetInfo(3, rulesets.AvailableRulesets.Where(r => r.OnlineID == id).ToArray())).Wait();
|
||||||
|
|
||||||
private static int importId;
|
|
||||||
|
|
||||||
private int getImportId() => ++importId;
|
|
||||||
|
|
||||||
private void checkMusicPlaying(bool playing) =>
|
private void checkMusicPlaying(bool playing) =>
|
||||||
AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == 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 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()
|
private void createSongSelect()
|
||||||
{
|
{
|
||||||
@ -893,59 +886,13 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
AddStep("import test maps", () =>
|
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)
|
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)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
@ -135,6 +135,35 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("bpm is default", () => lastBpm != null && Precision.AlmostEquals(lastBpm.Value, 60));
|
AddAssert("bpm is default", () => lastBpm != null && Precision.AlmostEquals(lastBpm.Value, 60));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase(true)]
|
||||||
|
[TestCase(false)]
|
||||||
|
public void TestEarlyActivationEffectPoint(bool earlyActivating)
|
||||||
|
{
|
||||||
|
double earlyActivationMilliseconds = earlyActivating ? 100 : 0;
|
||||||
|
ControlPoint actualEffectPoint = null;
|
||||||
|
|
||||||
|
AddStep($"set early activation to {earlyActivationMilliseconds}", () => beatContainer.EarlyActivationMilliseconds = earlyActivationMilliseconds);
|
||||||
|
|
||||||
|
AddStep("seek before kiai effect point", () =>
|
||||||
|
{
|
||||||
|
ControlPoint expectedEffectPoint = Beatmap.Value.Beatmap.ControlPointInfo.EffectPoints.First(ep => ep.KiaiMode);
|
||||||
|
actualEffectPoint = null;
|
||||||
|
beatContainer.AllowMistimedEventFiring = false;
|
||||||
|
|
||||||
|
beatContainer.NewBeat = (i, timingControlPoint, effectControlPoint, channelAmplitudes) =>
|
||||||
|
{
|
||||||
|
if (Precision.AlmostEquals(gameplayClockContainer.CurrentTime + earlyActivationMilliseconds, expectedEffectPoint.Time, BeatSyncedContainer.MISTIMED_ALLOWANCE))
|
||||||
|
actualEffectPoint = effectControlPoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
gameplayClockContainer.Seek(expectedEffectPoint.Time - earlyActivationMilliseconds);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for effect point", () => actualEffectPoint != null);
|
||||||
|
|
||||||
|
AddAssert("effect has kiai", () => actualEffectPoint != null && ((EffectControlPoint)actualEffectPoint).KiaiMode);
|
||||||
|
}
|
||||||
|
|
||||||
private class TestBeatSyncedContainer : BeatSyncedContainer
|
private class TestBeatSyncedContainer : BeatSyncedContainer
|
||||||
{
|
{
|
||||||
private const int flash_layer_height = 150;
|
private const int flash_layer_height = 150;
|
||||||
@ -145,6 +174,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
set => base.AllowMistimedEventFiring = value;
|
set => base.AllowMistimedEventFiring = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public new double EarlyActivationMilliseconds
|
||||||
|
{
|
||||||
|
get => base.EarlyActivationMilliseconds;
|
||||||
|
set => base.EarlyActivationMilliseconds = value;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly InfoString timingPointCount;
|
private readonly InfoString timingPointCount;
|
||||||
private readonly InfoString currentTimingPoint;
|
private readonly InfoString currentTimingPoint;
|
||||||
private readonly InfoString beatCount;
|
private readonly InfoString beatCount;
|
||||||
|
@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
dependencies.Cache(rulesetStore = new RulesetStore(ContextFactory));
|
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(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];
|
beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Value.Beatmaps[0];
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLabelledEnumDropdown()
|
public void TestLabelledEnumDropdown()
|
||||||
=> AddStep(@"create dropdown", () => Child = new LabelledEnumDropdown<BeatmapSetOnlineStatus>
|
=> AddStep(@"create dropdown", () => Child = new LabelledEnumDropdown<BeatmapOnlineStatus>
|
||||||
{
|
{
|
||||||
Label = @"Beatmap status",
|
Label = @"Beatmap status",
|
||||||
Description = @"This is a description"
|
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();
|
waitForLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
public class TestSceneOsuDropdown : ThemeComparisonTestScene
|
public class TestSceneOsuDropdown : ThemeComparisonTestScene
|
||||||
{
|
{
|
||||||
protected override Drawable CreateContent() =>
|
protected override Drawable CreateContent() =>
|
||||||
new OsuEnumDropdown<BeatmapSetOnlineStatus>
|
new OsuEnumDropdown<BeatmapOnlineStatus>
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user