mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 16:32:54 +08:00
Merge branch 'master' into realm-fix-async-write-after-disposal
This commit is contained in:
commit
447b496eff
@ -52,7 +52,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.628.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.628.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.629.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||
|
@ -24,21 +24,24 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
new object[] { LegacyMods.DoubleTime, new[] { typeof(CatchModDoubleTime) } },
|
||||
new object[] { LegacyMods.Relax, new[] { typeof(CatchModRelax) } },
|
||||
new object[] { LegacyMods.HalfTime, new[] { typeof(CatchModHalfTime) } },
|
||||
new object[] { LegacyMods.Nightcore, new[] { typeof(CatchModNightcore) } },
|
||||
new object[] { LegacyMods.Flashlight, new[] { typeof(CatchModFlashlight) } },
|
||||
new object[] { LegacyMods.Autoplay, new[] { typeof(CatchModAutoplay) } },
|
||||
new object[] { LegacyMods.Perfect, new[] { typeof(CatchModPerfect) } },
|
||||
new object[] { LegacyMods.Cinema, new[] { typeof(CatchModCinema) } },
|
||||
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(CatchModHardRock), typeof(CatchModDoubleTime) } }
|
||||
};
|
||||
|
||||
[TestCaseSource(nameof(catch_mod_mapping))]
|
||||
[TestCase(LegacyMods.Cinema, new[] { typeof(CatchModCinema) })]
|
||||
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(CatchModCinema) })]
|
||||
[TestCase(LegacyMods.Nightcore, new[] { typeof(CatchModNightcore) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(CatchModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect, new[] { typeof(CatchModPerfect) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(CatchModPerfect) })]
|
||||
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
|
||||
|
||||
[TestCaseSource(nameof(catch_mod_mapping))]
|
||||
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(CatchModCinema) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(CatchModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(CatchModPerfect) })]
|
||||
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
|
||||
|
||||
[TestCaseSource(nameof(catch_mod_mapping))]
|
||||
public new void TestToLegacy(LegacyMods legacyMods, Type[] givenMods) => base.TestToLegacy(legacyMods, givenMods);
|
||||
|
||||
protected override Ruleset CreateRuleset() => new CatchRuleset();
|
||||
|
@ -23,10 +23,8 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
new object[] { LegacyMods.SuddenDeath, new[] { typeof(ManiaModSuddenDeath) } },
|
||||
new object[] { LegacyMods.DoubleTime, new[] { typeof(ManiaModDoubleTime) } },
|
||||
new object[] { LegacyMods.HalfTime, new[] { typeof(ManiaModHalfTime) } },
|
||||
new object[] { LegacyMods.Nightcore, new[] { typeof(ManiaModNightcore) } },
|
||||
new object[] { LegacyMods.Flashlight, new[] { typeof(ManiaModFlashlight) } },
|
||||
new object[] { LegacyMods.Autoplay, new[] { typeof(ManiaModAutoplay) } },
|
||||
new object[] { LegacyMods.Perfect, new[] { typeof(ManiaModPerfect) } },
|
||||
new object[] { LegacyMods.Key4, new[] { typeof(ManiaModKey4) } },
|
||||
new object[] { LegacyMods.Key5, new[] { typeof(ManiaModKey5) } },
|
||||
new object[] { LegacyMods.Key6, new[] { typeof(ManiaModKey6) } },
|
||||
@ -34,7 +32,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
new object[] { LegacyMods.Key8, new[] { typeof(ManiaModKey8) } },
|
||||
new object[] { LegacyMods.FadeIn, new[] { typeof(ManiaModFadeIn) } },
|
||||
new object[] { LegacyMods.Random, new[] { typeof(ManiaModRandom) } },
|
||||
new object[] { LegacyMods.Cinema, new[] { typeof(ManiaModCinema) } },
|
||||
new object[] { LegacyMods.Key9, new[] { typeof(ManiaModKey9) } },
|
||||
new object[] { LegacyMods.KeyCoop, new[] { typeof(ManiaModDualStages) } },
|
||||
new object[] { LegacyMods.Key1, new[] { typeof(ManiaModKey1) } },
|
||||
@ -45,12 +42,18 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
};
|
||||
|
||||
[TestCaseSource(nameof(mania_mod_mapping))]
|
||||
[TestCase(LegacyMods.Cinema, new[] { typeof(ManiaModCinema) })]
|
||||
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(ManiaModCinema) })]
|
||||
[TestCase(LegacyMods.Nightcore, new[] { typeof(ManiaModNightcore) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(ManiaModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect, new[] { typeof(ManiaModPerfect) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(ManiaModPerfect) })]
|
||||
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
|
||||
|
||||
[TestCaseSource(nameof(mania_mod_mapping))]
|
||||
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(ManiaModCinema) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(ManiaModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(ManiaModPerfect) })]
|
||||
public new void TestToLegacy(LegacyMods legacyMods, Type[] givenMods) => base.TestToLegacy(legacyMods, givenMods);
|
||||
|
||||
protected override Ruleset CreateRuleset() => new ManiaRuleset();
|
||||
|
@ -25,24 +25,27 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
new object[] { LegacyMods.DoubleTime, new[] { typeof(OsuModDoubleTime) } },
|
||||
new object[] { LegacyMods.Relax, new[] { typeof(OsuModRelax) } },
|
||||
new object[] { LegacyMods.HalfTime, new[] { typeof(OsuModHalfTime) } },
|
||||
new object[] { LegacyMods.Nightcore, new[] { typeof(OsuModNightcore) } },
|
||||
new object[] { LegacyMods.Flashlight, new[] { typeof(OsuModFlashlight) } },
|
||||
new object[] { LegacyMods.Autoplay, new[] { typeof(OsuModAutoplay) } },
|
||||
new object[] { LegacyMods.SpunOut, new[] { typeof(OsuModSpunOut) } },
|
||||
new object[] { LegacyMods.Autopilot, new[] { typeof(OsuModAutopilot) } },
|
||||
new object[] { LegacyMods.Perfect, new[] { typeof(OsuModPerfect) } },
|
||||
new object[] { LegacyMods.Cinema, new[] { typeof(OsuModCinema) } },
|
||||
new object[] { LegacyMods.Target, new[] { typeof(OsuModTarget) } },
|
||||
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(OsuModHardRock), typeof(OsuModDoubleTime) } }
|
||||
};
|
||||
|
||||
[TestCaseSource(nameof(osu_mod_mapping))]
|
||||
[TestCase(LegacyMods.Cinema, new[] { typeof(OsuModCinema) })]
|
||||
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(OsuModCinema) })]
|
||||
[TestCase(LegacyMods.Nightcore, new[] { typeof(OsuModNightcore) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(OsuModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect, new[] { typeof(OsuModPerfect) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(OsuModPerfect) })]
|
||||
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
|
||||
|
||||
[TestCaseSource(nameof(osu_mod_mapping))]
|
||||
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(OsuModCinema) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(OsuModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(OsuModPerfect) })]
|
||||
public new void TestToLegacy(LegacyMods legacyMods, Type[] givenMods) => base.TestToLegacy(legacyMods, givenMods);
|
||||
|
||||
protected override Ruleset CreateRuleset() => new OsuRuleset();
|
||||
|
@ -24,22 +24,25 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
new object[] { LegacyMods.DoubleTime, new[] { typeof(TaikoModDoubleTime) } },
|
||||
new object[] { LegacyMods.Relax, new[] { typeof(TaikoModRelax) } },
|
||||
new object[] { LegacyMods.HalfTime, new[] { typeof(TaikoModHalfTime) } },
|
||||
new object[] { LegacyMods.Nightcore, new[] { typeof(TaikoModNightcore) } },
|
||||
new object[] { LegacyMods.Flashlight, new[] { typeof(TaikoModFlashlight) } },
|
||||
new object[] { LegacyMods.Autoplay, new[] { typeof(TaikoModAutoplay) } },
|
||||
new object[] { LegacyMods.Perfect, new[] { typeof(TaikoModPerfect) } },
|
||||
new object[] { LegacyMods.Random, new[] { typeof(TaikoModRandom) } },
|
||||
new object[] { LegacyMods.Cinema, new[] { typeof(TaikoModCinema) } },
|
||||
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(TaikoModHardRock), typeof(TaikoModDoubleTime) } }
|
||||
};
|
||||
|
||||
[TestCaseSource(nameof(taiko_mod_mapping))]
|
||||
[TestCase(LegacyMods.Cinema, new[] { typeof(TaikoModCinema) })]
|
||||
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(TaikoModCinema) })]
|
||||
[TestCase(LegacyMods.Nightcore, new[] { typeof(TaikoModNightcore) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(TaikoModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect, new[] { typeof(TaikoModPerfect) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(TaikoModPerfect) })]
|
||||
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
|
||||
|
||||
[TestCaseSource(nameof(taiko_mod_mapping))]
|
||||
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(TaikoModCinema) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(TaikoModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(TaikoModPerfect) })]
|
||||
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
|
||||
|
||||
[TestCaseSource(nameof(taiko_mod_mapping))]
|
||||
public new void TestToLegacy(LegacyMods legacyMods, Type[] givenMods) => base.TestToLegacy(legacyMods, givenMods);
|
||||
|
||||
protected override Ruleset CreateRuleset() => new TaikoRuleset();
|
||||
|
@ -91,6 +91,25 @@ namespace osu.Game.Tests.Database
|
||||
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTransactionRolledBackOnException()
|
||||
{
|
||||
RunTestWithRealm((realm, _) =>
|
||||
{
|
||||
var beatmap = new BeatmapInfo(CreateRuleset(), new BeatmapDifficulty(), new BeatmapMetadata());
|
||||
|
||||
realm.Run(r => r.Write(_ => r.Add(beatmap)));
|
||||
|
||||
var liveBeatmap = beatmap.ToLive(realm);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => liveBeatmap.PerformWrite(l => throw new InvalidOperationException()));
|
||||
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
|
||||
|
||||
liveBeatmap.PerformWrite(l => l.Hidden = true);
|
||||
Assert.IsTrue(liveBeatmap.PerformRead(l => l.Hidden));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestScopedReadWithoutContext()
|
||||
{
|
||||
|
@ -44,8 +44,7 @@ namespace osu.Game.Tests.NonVisual
|
||||
[Test]
|
||||
public void TestCustomDirectory()
|
||||
{
|
||||
string customPath = prepareCustomPath();
|
||||
|
||||
using (prepareCustomPath(out string customPath))
|
||||
using (var host = new CustomTestHeadlessGameHost())
|
||||
{
|
||||
using (var storageConfig = new StorageConfigManager(host.InitialStorage))
|
||||
@ -63,7 +62,6 @@ namespace osu.Game.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
cleanupPath(customPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,8 +69,7 @@ namespace osu.Game.Tests.NonVisual
|
||||
[Test]
|
||||
public void TestSubDirectoryLookup()
|
||||
{
|
||||
string customPath = prepareCustomPath();
|
||||
|
||||
using (prepareCustomPath(out string customPath))
|
||||
using (var host = new CustomTestHeadlessGameHost())
|
||||
{
|
||||
using (var storageConfig = new StorageConfigManager(host.InitialStorage))
|
||||
@ -97,7 +94,6 @@ namespace osu.Game.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
cleanupPath(customPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,8 +101,7 @@ namespace osu.Game.Tests.NonVisual
|
||||
[Test]
|
||||
public void TestMigration()
|
||||
{
|
||||
string customPath = prepareCustomPath();
|
||||
|
||||
using (prepareCustomPath(out string customPath))
|
||||
using (var host = new CustomTestHeadlessGameHost())
|
||||
{
|
||||
try
|
||||
@ -173,7 +168,6 @@ namespace osu.Game.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
cleanupPath(customPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,9 +175,8 @@ namespace osu.Game.Tests.NonVisual
|
||||
[Test]
|
||||
public void TestMigrationBetweenTwoTargets()
|
||||
{
|
||||
string customPath = prepareCustomPath();
|
||||
string customPath2 = prepareCustomPath();
|
||||
|
||||
using (prepareCustomPath(out string customPath))
|
||||
using (prepareCustomPath(out string customPath2))
|
||||
using (var host = new CustomTestHeadlessGameHost())
|
||||
{
|
||||
try
|
||||
@ -205,8 +198,6 @@ namespace osu.Game.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
cleanupPath(customPath);
|
||||
cleanupPath(customPath2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,8 +205,7 @@ namespace osu.Game.Tests.NonVisual
|
||||
[Test]
|
||||
public void TestMigrationToSameTargetFails()
|
||||
{
|
||||
string customPath = prepareCustomPath();
|
||||
|
||||
using (prepareCustomPath(out string customPath))
|
||||
using (var host = new CustomTestHeadlessGameHost())
|
||||
{
|
||||
try
|
||||
@ -228,7 +218,6 @@ namespace osu.Game.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
cleanupPath(customPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,9 +225,8 @@ namespace osu.Game.Tests.NonVisual
|
||||
[Test]
|
||||
public void TestMigrationFailsOnExistingData()
|
||||
{
|
||||
string customPath = prepareCustomPath();
|
||||
string customPath2 = prepareCustomPath();
|
||||
|
||||
using (prepareCustomPath(out string customPath))
|
||||
using (prepareCustomPath(out string customPath2))
|
||||
using (var host = new CustomTestHeadlessGameHost())
|
||||
{
|
||||
try
|
||||
@ -267,8 +255,6 @@ namespace osu.Game.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
cleanupPath(customPath);
|
||||
cleanupPath(customPath2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -276,8 +262,7 @@ namespace osu.Game.Tests.NonVisual
|
||||
[Test]
|
||||
public void TestMigrationToNestedTargetFails()
|
||||
{
|
||||
string customPath = prepareCustomPath();
|
||||
|
||||
using (prepareCustomPath(out string customPath))
|
||||
using (var host = new CustomTestHeadlessGameHost())
|
||||
{
|
||||
try
|
||||
@ -298,7 +283,6 @@ namespace osu.Game.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
cleanupPath(customPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -306,8 +290,7 @@ namespace osu.Game.Tests.NonVisual
|
||||
[Test]
|
||||
public void TestMigrationToSeeminglyNestedTarget()
|
||||
{
|
||||
string customPath = prepareCustomPath();
|
||||
|
||||
using (prepareCustomPath(out string customPath))
|
||||
using (var host = new CustomTestHeadlessGameHost())
|
||||
{
|
||||
try
|
||||
@ -328,7 +311,6 @@ namespace osu.Game.Tests.NonVisual
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
cleanupPath(customPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -343,14 +325,17 @@ namespace osu.Game.Tests.NonVisual
|
||||
return path;
|
||||
}
|
||||
|
||||
private static string prepareCustomPath() => Path.Combine(TestRunHeadlessGameHost.TemporaryTestDirectory, $"custom-path-{Guid.NewGuid()}");
|
||||
private static IDisposable prepareCustomPath(out string path)
|
||||
{
|
||||
path = Path.Combine(TestRunHeadlessGameHost.TemporaryTestDirectory, $"custom-path-{Guid.NewGuid()}");
|
||||
return new InvokeOnDisposal<string>(path, cleanupPath);
|
||||
}
|
||||
|
||||
private static void cleanupPath(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
Directory.Delete(path, true);
|
||||
if (Directory.Exists(path)) Directory.Delete(path, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -6,18 +6,14 @@ using NUnit.Framework;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets.Mania;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Components.Timelines.Summary;
|
||||
using osu.Game.Screens.Edit.GameplayTest;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
@ -36,20 +32,21 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
() => Game.Beatmap.Value.BeatmapSetInfo.Equals(beatmapSet)
|
||||
&& Game.ScreenStack.CurrentScreen is PlaySongSelect songSelect
|
||||
&& songSelect.IsLoaded);
|
||||
AddUntilStep("wait for completion notification", () => Game.Notifications.ChildrenOfType<ProgressCompletionNotification>().Count() == 1);
|
||||
AddStep("dismiss notifications", () => Game.Notifications.Hide());
|
||||
AddStep("switch ruleset", () => Game.Ruleset.Value = new ManiaRuleset().RulesetInfo);
|
||||
|
||||
AddStep("open editor", () => ((PlaySongSelect)Game.ScreenStack.CurrentScreen).Edit(beatmapSet.Beatmaps.First(beatmap => beatmap.Ruleset.OnlineID == 0)));
|
||||
AddUntilStep("wait for editor open", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.ReadyForUse);
|
||||
AddStep("test gameplay", () =>
|
||||
AddStep("test gameplay", () => ((Editor)Game.ScreenStack.CurrentScreen).TestGameplay());
|
||||
|
||||
AddUntilStep("wait for player", () =>
|
||||
{
|
||||
var testGameplayButton = this.ChildrenOfType<TestGameplayButton>().Single();
|
||||
InputManager.MoveMouseTo(testGameplayButton);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
// notifications may fire at almost any inopportune time and cause annoying test failures.
|
||||
// relentlessly attempt to dismiss any and all interfering overlays, which includes notifications.
|
||||
// this is theoretically not foolproof, but it's the best that can be done here.
|
||||
Game.CloseAllOverlays();
|
||||
return Game.ScreenStack.CurrentScreen is EditorPlayer editorPlayer && editorPlayer.IsLoaded;
|
||||
});
|
||||
|
||||
AddUntilStep("wait for player", () => Game.ScreenStack.CurrentScreen is EditorPlayer editorPlayer && editorPlayer.IsLoaded);
|
||||
AddAssert("current ruleset is osu!", () => Game.Ruleset.Value.Equals(new OsuRuleset().RulesetInfo));
|
||||
|
||||
AddStep("exit to song select", () => Game.PerformFromScreen(_ => { }, typeof(PlaySongSelect).Yield()));
|
||||
|
@ -6,10 +6,10 @@
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.Break;
|
||||
@ -31,19 +31,20 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
protected override void AddCheckSteps()
|
||||
{
|
||||
// It doesn't matter which ruleset is used - this beatmap is only used for reference.
|
||||
var beatmap = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||
|
||||
AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0);
|
||||
AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
|
||||
seekToBreak(0);
|
||||
|
||||
seekTo(beatmap.Beatmap.Breaks[0].StartTime);
|
||||
AddAssert("keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting);
|
||||
AddAssert("overlay displays 100% accuracy", () => Player.BreakOverlay.ChildrenOfType<BreakInfo>().Single().AccuracyDisplay.Current.Value == 1);
|
||||
|
||||
AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000));
|
||||
AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
||||
|
||||
seekToBreak(0);
|
||||
seekToBreak(1);
|
||||
|
||||
AddStep("seek to completion", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.Objects.Last().GetEndTime()));
|
||||
|
||||
seekTo(beatmap.Beatmap.HitObjects[^1].GetEndTime());
|
||||
AddUntilStep("results displayed", () => getResultsScreen()?.IsLoaded == true);
|
||||
|
||||
AddAssert("score has combo", () => getResultsScreen().Score.Combo > 100);
|
||||
@ -58,12 +59,18 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
ResultsScreen getResultsScreen() => Stack.CurrentScreen as ResultsScreen;
|
||||
}
|
||||
|
||||
private void seekToBreak(int breakIndex)
|
||||
private void seekTo(double time)
|
||||
{
|
||||
AddStep($"seek to break {breakIndex}", () => Player.GameplayClockContainer.Seek(destBreak().StartTime));
|
||||
AddUntilStep("wait for seek to complete", () => Player.DrawableRuleset.FrameStableClock.CurrentTime >= destBreak().StartTime);
|
||||
AddStep($"seek to {time}", () => Player.GameplayClockContainer.Seek(time));
|
||||
|
||||
BreakPeriod destBreak() => Beatmap.Value.Beatmap.Breaks.ElementAt(breakIndex);
|
||||
// Prevent test timeouts by seeking in 10 second increments.
|
||||
for (double t = 0; t < time; t += 10000)
|
||||
{
|
||||
double expectedTime = t;
|
||||
AddUntilStep($"current time >= {t}", () => Player.DrawableRuleset.FrameStableClock.CurrentTime >= expectedTime);
|
||||
}
|
||||
|
||||
AddUntilStep("wait for seek to complete", () => Player.DrawableRuleset.FrameStableClock.CurrentTime >= time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ namespace osu.Game.Tests.Visual.Online
|
||||
private TestChatOverlay chatOverlay;
|
||||
private ChannelManager channelManager;
|
||||
|
||||
private APIUser testUser;
|
||||
private readonly APIUser testUser = new APIUser { Username = "test user", Id = 5071479 };
|
||||
|
||||
private Channel[] testChannels;
|
||||
|
||||
private Channel testChannel1 => testChannels[0];
|
||||
@ -51,7 +52,6 @@ namespace osu.Game.Tests.Visual.Online
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
testUser = new APIUser { Username = "test user", Id = 5071479 };
|
||||
testChannels = Enumerable.Range(1, 10).Select(createPublicChannel).ToArray();
|
||||
|
||||
Child = new DependencyProvidingContainer
|
||||
|
@ -100,12 +100,13 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
[Test]
|
||||
public void TestPlaceholderConvertSetting()
|
||||
{
|
||||
changeRuleset(2);
|
||||
addRulesetImportStep(0);
|
||||
AddStep("change convert setting", () => config.SetValue(OsuSetting.ShowConvertedBeatmaps, false));
|
||||
|
||||
createSongSelect();
|
||||
|
||||
changeRuleset(2);
|
||||
|
||||
AddUntilStep("wait for placeholder visible", () => getPlaceholder()?.State.Value == Visibility.Visible);
|
||||
|
||||
AddStep("click link in placeholder", () => getPlaceholder().ChildrenOfType<DrawableLinkCompiler>().First().TriggerClick());
|
||||
|
@ -104,9 +104,12 @@ namespace osu.Game.Database
|
||||
|
||||
PerformRead(t =>
|
||||
{
|
||||
var transaction = t.Realm.BeginWrite();
|
||||
using (var transaction = t.Realm.BeginWrite())
|
||||
{
|
||||
perform(t);
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
RealmLiveStatistics.WRITES.Value++;
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Database;
|
||||
@ -19,8 +20,8 @@ namespace osu.Game.Models
|
||||
|
||||
public RealmNamedFileUsage(RealmFile file, string filename)
|
||||
{
|
||||
File = file;
|
||||
Filename = filename;
|
||||
File = file ?? throw new ArgumentNullException(nameof(file));
|
||||
Filename = filename ?? throw new ArgumentNullException(nameof(filename));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
|
@ -72,7 +72,7 @@ namespace osu.Game.Online.Rooms
|
||||
/// In many cases, this will *not* contain any usable information apart from OnlineID.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public IBeatmapInfo Beatmap { get; set; } = null!;
|
||||
public IBeatmapInfo Beatmap { get; private set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public IBindable<bool> Valid => valid;
|
||||
@ -81,6 +81,7 @@ namespace osu.Game.Online.Rooms
|
||||
|
||||
[JsonConstructor]
|
||||
private PlaylistItem()
|
||||
: this(new APIBeatmap())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ namespace osu.Game.Rulesets
|
||||
break;
|
||||
|
||||
case ModPerfect:
|
||||
value |= LegacyMods.Perfect;
|
||||
value |= LegacyMods.Perfect | LegacyMods.SuddenDeath;
|
||||
break;
|
||||
|
||||
case ModSuddenDeath:
|
||||
@ -151,7 +151,7 @@ namespace osu.Game.Rulesets
|
||||
break;
|
||||
|
||||
case ModNightcore:
|
||||
value |= LegacyMods.Nightcore;
|
||||
value |= LegacyMods.Nightcore | LegacyMods.DoubleTime;
|
||||
break;
|
||||
|
||||
case ModDoubleTime:
|
||||
@ -171,7 +171,7 @@ namespace osu.Game.Rulesets
|
||||
break;
|
||||
|
||||
case ModCinema:
|
||||
value |= LegacyMods.Cinema;
|
||||
value |= LegacyMods.Cinema | LegacyMods.Autoplay;
|
||||
break;
|
||||
|
||||
case ModAutoplay:
|
||||
|
@ -36,7 +36,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Realm" Version="10.14.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.628.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.629.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.628.0" />
|
||||
<PackageReference Include="Sentry" Version="3.17.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.31.0" />
|
||||
|
@ -61,7 +61,7 @@
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.628.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.629.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.628.0" />
|
||||
</ItemGroup>
|
||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
|
||||
@ -84,7 +84,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.14" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.628.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.629.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.31.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user