mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 22:33:05 +08:00
Add failing test coverage
This commit is contained in:
parent
15a5fd7e4c
commit
1075b87fb8
@ -3,14 +3,18 @@
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.IO.Legacy;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets;
|
||||
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)
|
||||
{
|
||||
var encodeStream = new MemoryStream();
|
||||
|
Loading…
Reference in New Issue
Block a user