mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 07:22:54 +08:00
Add failing test coverage
This commit is contained in:
parent
15a5fd7e4c
commit
1075b87fb8
@ -3,14 +3,18 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.Beatmaps.Legacy;
|
||||||
|
using osu.Game.IO.Legacy;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets.Catch;
|
||||||
@ -247,6 +251,123 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AccuracyAndRankOfStableScorePreserved()
|
||||||
|
{
|
||||||
|
var memoryStream = new MemoryStream();
|
||||||
|
|
||||||
|
// local partial implementation of legacy score encoder
|
||||||
|
// this is done half for readability, half because `LegacyScoreEncoder` forces `LATEST_VERSION`
|
||||||
|
// and we want to emulate a stable score here
|
||||||
|
using (var sw = new SerializationWriter(memoryStream, true))
|
||||||
|
{
|
||||||
|
sw.Write((byte)0); // ruleset id (osu!)
|
||||||
|
sw.Write(20240116); // version (anything below `LegacyScoreEncoder.FIRST_LAZER_VERSION` is stable)
|
||||||
|
sw.Write(string.Empty.ComputeMD5Hash()); // beatmap hash, irrelevant to this test
|
||||||
|
sw.Write("username"); // irrelevant to this test
|
||||||
|
sw.Write(string.Empty.ComputeMD5Hash()); // score hash, irrelevant to this test
|
||||||
|
sw.Write((ushort)198); // count300
|
||||||
|
sw.Write((ushort)1); // count100
|
||||||
|
sw.Write((ushort)0); // count50
|
||||||
|
sw.Write((ushort)0); // countGeki
|
||||||
|
sw.Write((ushort)0); // countKatu
|
||||||
|
sw.Write((ushort)1); // countMiss
|
||||||
|
sw.Write(12345678); // total score, irrelevant to this test
|
||||||
|
sw.Write((ushort)1000); // max combo, irrelevant to this test
|
||||||
|
sw.Write(false); // full combo, irrelevant to this test
|
||||||
|
sw.Write((int)LegacyMods.Hidden); // mods
|
||||||
|
sw.Write(string.Empty); // hp graph, irrelevant
|
||||||
|
sw.Write(DateTime.Now); // date, irrelevant
|
||||||
|
sw.Write(Array.Empty<byte>()); // replay data, irrelevant
|
||||||
|
sw.Write((long)1234); // legacy online ID, irrelevant
|
||||||
|
}
|
||||||
|
|
||||||
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
var decoded = new TestLegacyScoreDecoder().Parse(memoryStream);
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.That(decoded.ScoreInfo.Accuracy, Is.EqualTo((double)(198 * 300 + 100) / (200 * 300)));
|
||||||
|
Assert.That(decoded.ScoreInfo.Rank, Is.EqualTo(ScoreRank.A));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AccuracyAndRankOfLazerScorePreserved()
|
||||||
|
{
|
||||||
|
var ruleset = new OsuRuleset().RulesetInfo;
|
||||||
|
|
||||||
|
var scoreInfo = TestResources.CreateTestScoreInfo(ruleset);
|
||||||
|
scoreInfo.Mods = new Mod[] { new OsuModFlashlight() };
|
||||||
|
scoreInfo.Statistics = new Dictionary<HitResult, int>
|
||||||
|
{
|
||||||
|
[HitResult.Great] = 199,
|
||||||
|
[HitResult.Miss] = 1,
|
||||||
|
[HitResult.LargeTickHit] = 1,
|
||||||
|
};
|
||||||
|
scoreInfo.MaximumStatistics = new Dictionary<HitResult, int>
|
||||||
|
{
|
||||||
|
[HitResult.Great] = 200,
|
||||||
|
[HitResult.LargeTickHit] = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
var beatmap = new TestBeatmap(ruleset);
|
||||||
|
var score = new Score
|
||||||
|
{
|
||||||
|
ScoreInfo = scoreInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
var decodedAfterEncode = encodeThenDecode(LegacyBeatmapDecoder.LATEST_VERSION, score, beatmap);
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.Accuracy, Is.EqualTo((double)(199 * 300 + 30) / (200 * 300 + 30)));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.Rank, Is.EqualTo(ScoreRank.SH));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AccuracyAndRankOfLazerScoreWithoutLegacyReplaySoloScoreInfoUsesBestEffortFallbackToLegacy()
|
||||||
|
{
|
||||||
|
var memoryStream = new MemoryStream();
|
||||||
|
|
||||||
|
// local partial implementation of legacy score encoder
|
||||||
|
// this is done half for readability, half because we want to emulate an old lazer score here
|
||||||
|
// that does not have everything that `LegacyScoreEncoder` now writes to the replay
|
||||||
|
using (var sw = new SerializationWriter(memoryStream, true))
|
||||||
|
{
|
||||||
|
sw.Write((byte)0); // ruleset id (osu!)
|
||||||
|
sw.Write(LegacyScoreEncoder.FIRST_LAZER_VERSION); // version
|
||||||
|
sw.Write(string.Empty.ComputeMD5Hash()); // beatmap hash, irrelevant to this test
|
||||||
|
sw.Write("username"); // irrelevant to this test
|
||||||
|
sw.Write(string.Empty.ComputeMD5Hash()); // score hash, irrelevant to this test
|
||||||
|
sw.Write((ushort)198); // count300
|
||||||
|
sw.Write((ushort)0); // count100
|
||||||
|
sw.Write((ushort)1); // count50
|
||||||
|
sw.Write((ushort)0); // countGeki
|
||||||
|
sw.Write((ushort)0); // countKatu
|
||||||
|
sw.Write((ushort)1); // countMiss
|
||||||
|
sw.Write(12345678); // total score, irrelevant to this test
|
||||||
|
sw.Write((ushort)1000); // max combo, irrelevant to this test
|
||||||
|
sw.Write(false); // full combo, irrelevant to this test
|
||||||
|
sw.Write((int)LegacyMods.Hidden); // mods
|
||||||
|
sw.Write(string.Empty); // hp graph, irrelevant
|
||||||
|
sw.Write(DateTime.Now); // date, irrelevant
|
||||||
|
sw.Write(Array.Empty<byte>()); // replay data, irrelevant
|
||||||
|
sw.Write((long)1234); // legacy online ID, irrelevant
|
||||||
|
// importantly, no compressed `LegacyReplaySoloScoreInfo` here
|
||||||
|
}
|
||||||
|
|
||||||
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
var decoded = new TestLegacyScoreDecoder().Parse(memoryStream);
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.That(decoded.ScoreInfo.Accuracy, Is.EqualTo((double)(198 * 300 + 50) / (200 * 300)));
|
||||||
|
Assert.That(decoded.ScoreInfo.Rank, Is.EqualTo(ScoreRank.A));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static Score encodeThenDecode(int beatmapVersion, Score score, TestBeatmap beatmap)
|
private static Score encodeThenDecode(int beatmapVersion, Score score, TestBeatmap beatmap)
|
||||||
{
|
{
|
||||||
var encodeStream = new MemoryStream();
|
var encodeStream = new MemoryStream();
|
||||||
|
Loading…
Reference in New Issue
Block a user