From dbf0f096e6daf9dfe0e6c4ebb1ab6bbe9c86b11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 19 May 2026 09:11:02 +0200 Subject: [PATCH] Add test harness for checking implementation correctness --- .../CatchScoreMultiplierTest.cs | 41 ++++++++++++++ .../ManiaScoreMultiplierTest.cs | 37 +++++++++++++ .../OsuScoreMultiplierTest.cs | 45 ++++++++++++++++ .../TaikoScoreMultiplierTest.cs | 41 ++++++++++++++ .../Rulesets/RulesetScoreMultiplierTest.cs | 53 +++++++++++++++++++ 5 files changed, 217 insertions(+) create mode 100644 osu.Game.Rulesets.Catch.Tests/CatchScoreMultiplierTest.cs create mode 100644 osu.Game.Rulesets.Mania.Tests/ManiaScoreMultiplierTest.cs create mode 100644 osu.Game.Rulesets.Osu.Tests/OsuScoreMultiplierTest.cs create mode 100644 osu.Game.Rulesets.Taiko.Tests/TaikoScoreMultiplierTest.cs create mode 100644 osu.Game/Tests/Rulesets/RulesetScoreMultiplierTest.cs diff --git a/osu.Game.Rulesets.Catch.Tests/CatchScoreMultiplierTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchScoreMultiplierTest.cs new file mode 100644 index 0000000000..a0f8a948c5 --- /dev/null +++ b/osu.Game.Rulesets.Catch.Tests/CatchScoreMultiplierTest.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Catch.Mods; +using osu.Game.Tests.Rulesets; + +namespace osu.Game.Rulesets.Catch.Tests +{ + public class CatchScoreMultiplierTest : RulesetScoreMultiplierTest + { + public CatchScoreMultiplierTest() + : base(new CatchRuleset()) + { + } + + [Test] + public void TestFlashlightOnNonDefaultSettings() + => TestModCombination([new CatchModFlashlight { ComboBasedSize = { Value = false } }]); + + [Test] + public void TestHalfTimeSpeeds([Values(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99)] double speedChange) + => TestModCombination([new CatchModHalfTime { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestDaycoreSpeeds([Values(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99)] double speedChange) + => TestModCombination([new CatchModDaycore { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestDoubleTimeSpeeds([Values(1.01, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2)] double speedChange) + => TestModCombination([new CatchModDoubleTime { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestNightcoreSpeeds([Values(1.01, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2)] double speedChange) + => TestModCombination([new CatchModNightcore { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestMultiplicativeCombination() + => TestModCombination([new CatchModHidden(), new CatchModHardRock()]); + } +} diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaScoreMultiplierTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaScoreMultiplierTest.cs new file mode 100644 index 0000000000..730210270e --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/ManiaScoreMultiplierTest.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Tests.Rulesets; + +namespace osu.Game.Rulesets.Mania.Tests +{ + public class ManiaScoreMultiplierTest : RulesetScoreMultiplierTest + { + public ManiaScoreMultiplierTest() + : base(new ManiaRuleset()) + { + } + + [Test] + public void TestHalfTimeSpeeds([Values(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99)] double speedChange) + => TestModCombination([new ManiaModHalfTime { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestDaycoreSpeeds([Values(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99)] double speedChange) + => TestModCombination([new ManiaModDaycore { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestDoubleTimeSpeeds([Values(1.01, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2)] double speedChange) + => TestModCombination([new ManiaModDoubleTime { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestNightcoreSpeeds([Values(1.01, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2)] double speedChange) + => TestModCombination([new ManiaModNightcore { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestMultiplicativeCombination() + => TestModCombination([new ManiaModEasy(), new ManiaModKey4()]); + } +} diff --git a/osu.Game.Rulesets.Osu.Tests/OsuScoreMultiplierTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuScoreMultiplierTest.cs new file mode 100644 index 0000000000..77e09f017f --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/OsuScoreMultiplierTest.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Tests.Rulesets; + +namespace osu.Game.Rulesets.Osu.Tests +{ + public class OsuScoreMultiplierTest : RulesetScoreMultiplierTest + { + public OsuScoreMultiplierTest() + : base(new OsuRuleset()) + { + } + + [Test] + public void TestFlashlightOnNonDefaultSettings() + => TestModCombination([new OsuModFlashlight { ComboBasedSize = { Value = false } }]); + + [Test] + public void TestHiddenOnNonDefaultSettings() + => TestModCombination([new OsuModHidden { OnlyFadeApproachCircles = { Value = true } }]); + + [Test] + public void TestHalfTimeSpeeds([Values(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99)] double speedChange) + => TestModCombination([new OsuModHalfTime { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestDaycoreSpeeds([Values(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99)] double speedChange) + => TestModCombination([new OsuModDaycore { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestDoubleTimeSpeeds([Values(1.01, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2)] double speedChange) + => TestModCombination([new OsuModDoubleTime { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestNightcoreSpeeds([Values(1.01, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2)] double speedChange) + => TestModCombination([new OsuModNightcore { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestMultiplicativeCombination() + => TestModCombination([new OsuModHidden(), new OsuModHardRock()]); + } +} diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoScoreMultiplierTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoScoreMultiplierTest.cs new file mode 100644 index 0000000000..53f8c043ac --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoScoreMultiplierTest.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Taiko.Mods; +using osu.Game.Tests.Rulesets; + +namespace osu.Game.Rulesets.Taiko.Tests +{ + public class TaikoScoreMultiplierTest : RulesetScoreMultiplierTest + { + public TaikoScoreMultiplierTest() + : base(new TaikoRuleset()) + { + } + + [Test] + public void TestFlashlightOnNonDefaultSettings() + => TestModCombination([new TaikoModFlashlight { ComboBasedSize = { Value = false } }]); + + [Test] + public void TestHalfTimeSpeeds([Values(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99)] double speedChange) + => TestModCombination([new TaikoModHalfTime { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestDaycoreSpeeds([Values(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99)] double speedChange) + => TestModCombination([new TaikoModDaycore { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestDoubleTimeSpeeds([Values(1.01, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2)] double speedChange) + => TestModCombination([new TaikoModDoubleTime { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestNightcoreSpeeds([Values(1.01, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2)] double speedChange) + => TestModCombination([new TaikoModNightcore { SpeedChange = { Value = speedChange } }]); + + [Test] + public void TestMultiplicativeCombination() + => TestModCombination([new TaikoModHidden(), new TaikoModHardRock()]); + } +} diff --git a/osu.Game/Tests/Rulesets/RulesetScoreMultiplierTest.cs b/osu.Game/Tests/Rulesets/RulesetScoreMultiplierTest.cs new file mode 100644 index 0000000000..fab314cdff --- /dev/null +++ b/osu.Game/Tests/Rulesets/RulesetScoreMultiplierTest.cs @@ -0,0 +1,53 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using NUnit.Framework; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Tests.Rulesets +{ + [TestFixture] + public abstract class RulesetScoreMultiplierTest + { + public Ruleset Ruleset { get; } + + protected RulesetScoreMultiplierTest(Ruleset ruleset) + { + Ruleset = ruleset; + } + + [Test] + public void TestDefaultMultiplierIsOne() + { + var calculator = Ruleset.CreateScoreMultiplierCalculator(); + Assert.That(calculator.CalculateFor([]), Is.EqualTo(1)); + } + + [Test] + public void TestMultipliersMatchForIndividualMods() + { + var mods = Ruleset.CreateAllMods(); + var calculator = Ruleset.CreateScoreMultiplierCalculator(); + + Assert.Multiple(() => + { + foreach (var mod in mods) + Assert.That(calculator.CalculateFor(mod.Yield()), Is.EqualTo(mod.ScoreMultiplier), message: $"Score multiplier not matching for mod {mod.Name}"); + }); + } + + protected void TestModCombination(IEnumerable mods) + { + var calculator = Ruleset.CreateScoreMultiplierCalculator(); + + double expected = 1; + foreach (var mod in mods) + expected *= mod.ScoreMultiplier; + + Assert.That(calculator.CalculateFor(mods), Is.EqualTo(expected)); + } + } +}