Add CPP's testroms to GB testroms project
This commit is contained in:
parent
18a7201004
commit
aba3359dde
|
@ -0,0 +1,240 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using BizHawk.Common.CollectionExtensions;
|
||||
using BizHawk.Common.IOExtensions;
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using static BizHawk.Tests.Testroms.GB.GBHelper;
|
||||
|
||||
namespace BizHawk.Tests.Testroms.GB.CPPTestroms
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class CPPTestroms
|
||||
{
|
||||
public readonly struct CPPTestromsHexStrTestCase
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, string> ExpectedValues = new Dictionary<string, string>
|
||||
{
|
||||
["open-bus-ss-test"] = @"
|
||||
0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A1A1A1A1A
|
||||
1A1A1A1A1A1A1A1A1A1A1A1A2A2A2A2A2A2A2A2A
|
||||
2A2A2A2A2A2A2A2A3A3A3A3A3A3A3A3A3A3A3A3A
|
||||
3A3A3A3A46464646464646464646464646464646
|
||||
4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E56565656
|
||||
5656565656565656565656565E5E5E5E5E5E5E5E
|
||||
5E5E5E5E5E5E5E5E666666666666666666666666
|
||||
666666666E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E
|
||||
7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E86868686
|
||||
8686868686868686868686868E8E8E8E8E8E8E8E
|
||||
8E8E8E8E8E8E8E8E969696969696969696969696
|
||||
969696969E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E
|
||||
A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6AEAEAEAE
|
||||
AEAEAEAEAEAEAEAEAEAEAEAEB6B6B6B6B6B6B6B6
|
||||
B6B6B6B6B6B6B6B6BEBEBEBEBEBEBEBEBEBEBEBE
|
||||
BEBEBEBEA0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0
|
||||
C1FFC1FFC1FFC1FFC1FFC1FFC1FFC1FFD1FFD1FF
|
||||
D1FFD1FFD1FFD1FFD1FFD1FFE1FFE1FFE1FFE1FF
|
||||
".Replace("\t", "").Replace("\n", ""),
|
||||
["ramg-mbc3-test"] = @"
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
00000000000000000000010000000000FFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
".Replace("\t", "").Replace("\n", ""),
|
||||
["rtc-invalid-banks-test"] = @"
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
00010203FFFFFFFF08090A0B00FFFFFF00000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
".Replace("\t", "").Replace("\n", ""),
|
||||
};
|
||||
|
||||
public static readonly IReadOnlyList<string> KnownFailures = new[]
|
||||
{
|
||||
"open-bus-ss-test on CGB_C in GBHawk",
|
||||
"open-bus-ss-test on CGB_C in SameBoy",
|
||||
"open-bus-ss-test on CGB_C in SameBoy (no BIOS)",
|
||||
"open-bus-ss-test on DMG in GBHawk",
|
||||
"open-bus-ss-test on DMG in SameBoy",
|
||||
"open-bus-ss-test on DMG in SameBoy (no BIOS)",
|
||||
"ramg-mbc3-test on CGB_C in GBHawk",
|
||||
"ramg-mbc3-test on DMG in GBHawk",
|
||||
"rtc-invalid-banks-test on CGB_C in GBHawk",
|
||||
"rtc-invalid-banks-test on DMG in Gambatte",
|
||||
"rtc-invalid-banks-test on DMG in Gambatte (no BIOS)",
|
||||
"rtc-invalid-banks-test on DMG in GBHawk",
|
||||
"rtc-invalid-banks-test on DMG in SameBoy",
|
||||
"rtc-invalid-banks-test on DMG in SameBoy (no BIOS)",
|
||||
};
|
||||
|
||||
public readonly string ExpectedValue
|
||||
=> ExpectedValues[TestName];
|
||||
|
||||
public readonly string RomEmbedPath
|
||||
=> $"{SUITE_PREFIX}{TestName}.gb";
|
||||
|
||||
public readonly CoreSetup Setup;
|
||||
|
||||
public readonly string TestName;
|
||||
|
||||
public CPPTestromsHexStrTestCase(string testName, CoreSetup setup)
|
||||
{
|
||||
TestName = testName;
|
||||
Setup = setup;
|
||||
}
|
||||
|
||||
public readonly string DisplayName()
|
||||
=> $"{TestName} on {Setup}";
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
private sealed class CPPTestromsHexStrTestDataAttribute : Attribute, ITestDataSource
|
||||
{
|
||||
public IEnumerable<object?[]> GetData(MethodInfo methodInfo)
|
||||
{
|
||||
List<CPPTestromsHexStrTestCase> testCases = new();
|
||||
foreach (var setup in new[] { ConsoleVariant.CGB_C, ConsoleVariant.DMG }.SelectMany(CoreSetup.ValidSetupsFor))
|
||||
{
|
||||
testCases.Add(new("open-bus-ss-test", setup));
|
||||
testCases.Add(new("ramg-mbc3-test", setup));
|
||||
testCases.Add(new("rtc-invalid-banks-test", setup));
|
||||
}
|
||||
// testCases.RemoveAll(static testCase => testCase.Setup.Variant is not ConsoleVariant.DMG); // uncomment and modify to run a subset of the test cases...
|
||||
testCases.RemoveAll(static testCase => TestUtils.ShouldIgnoreCase(SUITE_ID, testCase.DisplayName())); // ...or use the global blocklist in TestUtils
|
||||
return testCases.OrderBy(static testCase => testCase.DisplayName())
|
||||
.Select(static testCase => new object?[] { testCase });
|
||||
}
|
||||
|
||||
public string GetDisplayName(MethodInfo methodInfo, object?[] data)
|
||||
=> $"{methodInfo.Name}({((CPPTestromsHexStrTestCase) data[0]!).DisplayName()})";
|
||||
}
|
||||
|
||||
private static readonly byte[,] GLYPHS = {
|
||||
{ 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000 },
|
||||
{ 0b1110, 0b0100, 0b1110, 0b1110, 0b1010, 0b1110, 0b1110, 0b1110, 0b1110, 0b1110, 0b1110, 0b1100, 0b1110, 0b1100, 0b1110, 0b1110 },
|
||||
{ 0b1010, 0b1100, 0b1010, 0b0010, 0b1010, 0b1000, 0b1000, 0b1010, 0b1010, 0b1010, 0b1010, 0b1010, 0b1010, 0b1010, 0b1000, 0b1000 },
|
||||
{ 0b1010, 0b0100, 0b0010, 0b0110, 0b1110, 0b1110, 0b1110, 0b0010, 0b1110, 0b1110, 0b1110, 0b1110, 0b1000, 0b1010, 0b1100, 0b1100 },
|
||||
{ 0b1010, 0b0100, 0b1110, 0b0010, 0b0010, 0b0010, 0b1010, 0b0010, 0b1010, 0b0010, 0b1010, 0b1010, 0b1000, 0b1010, 0b1000, 0b1000 },
|
||||
{ 0b1010, 0b0100, 0b1000, 0b1010, 0b0010, 0b1010, 0b1010, 0b0010, 0b1010, 0b1010, 0b1010, 0b1010, 0b1010, 0b1010, 0b1000, 0b1000 },
|
||||
{ 0b1110, 0b1110, 0b1110, 0b1110, 0b0010, 0b1110, 0b1110, 0b0010, 0b1110, 0b1110, 0b1010, 0b1100, 0b1110, 0b1100, 0b1110, 0b1000 },
|
||||
{ 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000 },
|
||||
};
|
||||
|
||||
private const string SUITE_ID = "CPPTestroms";
|
||||
|
||||
private const string SUITE_PREFIX = "res.CasualPokePlayer_test_roms_artifact.";
|
||||
|
||||
private static readonly IReadOnlyList<string> FilteredEmbedPaths = ReflectionCache.EmbeddedResourceList().Where(static s => s.StartsWith(SUITE_PREFIX)).ToList();
|
||||
|
||||
[ClassCleanup]
|
||||
public static void AfterAll()
|
||||
=> TestUtils.WriteMetricsToDisk();
|
||||
|
||||
[ClassInitialize]
|
||||
public static void BeforeAll(TestContext ctx)
|
||||
{
|
||||
if (!CPPTestromsHexStrTestCase.KnownFailures.IsSortedAsc()) throw new Exception(SUITE_ID + " known-failing testcase list must be sorted");
|
||||
TestUtils.PrepareDBAndOutput(SUITE_ID);
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[CPPTestromsHexStrTestData]
|
||||
public void RunCPPTestromsHexStrTest(CPPTestromsHexStrTestCase testCase)
|
||||
{
|
||||
static bool GlyphMatches(Bitmap b, int xOffset, int yOffset, byte v)
|
||||
{
|
||||
// `(xOffset, yOffset)` is the top-left of a 4x8 rectangle of pixels to read from `b`, which is compared against the glyph for the nybble `v`
|
||||
bool GlyphRowMatches(int y)
|
||||
{
|
||||
byte rowAsByte = 0;
|
||||
for (int x = xOffset, l = x + 4; x < l; x++)
|
||||
{
|
||||
rowAsByte <<= 1;
|
||||
if ((b.GetPixel(x, yOffset + y).ToArgb() & 0xFFFFFF) == 0) rowAsByte |= 1;
|
||||
}
|
||||
return rowAsByte == GLYPHS[y, v];
|
||||
}
|
||||
for (var y = 0; y < 8; y++) if (!GlyphRowMatches(y)) return false;
|
||||
return true;
|
||||
}
|
||||
TestUtils.ShortCircuitMissingRom(isPresent: FilteredEmbedPaths.Contains(testCase.RomEmbedPath));
|
||||
var caseStr = testCase.DisplayName();
|
||||
TestUtils.ShortCircuitKnownFailure(caseStr, CPPTestromsHexStrTestCase.KnownFailures, out var knownFail);
|
||||
var actualUnnormalised = DummyFrontend.RunAndScreenshot(
|
||||
InitGBCore(testCase.Setup, testCase.RomEmbedPath, ReflectionCache.EmbeddedResourceStream(testCase.RomEmbedPath).ReadAllBytes()),
|
||||
static fe => fe.FrameAdvanceBy(200)).AsBitmap();
|
||||
var glyphCount = testCase.ExpectedValue.Length;
|
||||
var screenshotMatches = true;
|
||||
var i = 0;
|
||||
var xOffset = 0;
|
||||
var yOffset = 0;
|
||||
while (i < glyphCount)
|
||||
{
|
||||
if (!GlyphMatches(actualUnnormalised, xOffset, yOffset, byte.Parse(testCase.ExpectedValue[i..(i + 1)], NumberStyles.HexNumber)))
|
||||
{
|
||||
screenshotMatches = false;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
xOffset += 4;
|
||||
if (xOffset is 160)
|
||||
{
|
||||
xOffset = 0;
|
||||
yOffset += 8;
|
||||
}
|
||||
}
|
||||
var state = TestUtils.SuccessState(screenshotMatches, knownFail);
|
||||
if (!ImageUtils.SkipFileIO(state))
|
||||
{
|
||||
ImageUtils.SaveScreenshot(NormaliseGBScreenshot(actualUnnormalised, testCase.Setup), (SUITE_ID, caseStr));
|
||||
Console.WriteLine($"should read: {string.Join("\n", testCase.ExpectedValue.Chunk(40).Select(static a => string.Concat(a)))}");
|
||||
}
|
||||
switch (state)
|
||||
{
|
||||
case TestUtils.TestSuccessState.ExpectedFailure:
|
||||
Assert.Inconclusive("expected failure, verified");
|
||||
break;
|
||||
case TestUtils.TestSuccessState.Failure:
|
||||
Assert.Fail("screenshot contains incorrect value");
|
||||
break;
|
||||
case TestUtils.TestSuccessState.UnexpectedSuccess:
|
||||
Assert.Fail("screenshot contains correct value unexpectedly (this is a good thing)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
cd "$(dirname "$(realpath "$0")")"
|
||||
../../BizHawk.Tests.Testroms.GB/.download_from_ci.sh BullyGB cgb-acid-hell cgb-acid2 dmg-acid2 mealybug-tearoom-tests rtc3test
|
||||
../../BizHawk.Tests.Testroms.GB/.download_from_ci.sh BullyGB CasualPokePlayer-test-roms cgb-acid-hell cgb-acid2 dmg-acid2 mealybug-tearoom-tests rtc3test
|
||||
|
|
Loading…
Reference in New Issue