diff --git a/src/BizHawk.Common/checksums/SHA256Checksum.cs b/src/BizHawk.Common/checksums/SHA256Checksum.cs index 63199db60d..f27d9b53ff 100644 --- a/src/BizHawk.Common/checksums/SHA256Checksum.cs +++ b/src/BizHawk.Common/checksums/SHA256Checksum.cs @@ -17,6 +17,8 @@ namespace BizHawk.Common internal const string PREFIX = "SHA256"; + public /*static readonly*/const string EmptyFile = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"; + #if NET6_0 public static byte[] Compute(ReadOnlySpan data) => SHA256.HashData(data); diff --git a/src/BizHawk.Tests/Client.Common/Api/MemoryApiTests.cs b/src/BizHawk.Tests/Client.Common/Api/MemoryApiTests.cs index b127bd8fc6..ec6c5f1453 100644 --- a/src/BizHawk.Tests/Client.Common/Api/MemoryApiTests.cs +++ b/src/BizHawk.Tests/Client.Common/Api/MemoryApiTests.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using BizHawk.Common; using BizHawk.Client.Common; using BizHawk.Emulation.Common; @@ -15,7 +16,12 @@ namespace BizHawk.Tests.Client.Common.Api { /// and its overloads can't take -_- private static void AssertAreSequenceEqual(IReadOnlyList expected, IReadOnlyList actual, string message) - => Assert.IsTrue(actual.SequenceEqual(expected), message); + { + if (actual.SequenceEqual(expected)) return; + Console.WriteLine($"ex[{expected.Count}]: {string.Join(", ", expected.Select(static o => o?.ToString() ?? "null"))}"); + Console.WriteLine($"ac[{actual.Count}]: {string.Join(", ", actual.Select(static o => o?.ToString() ?? "null"))}"); + Assert.Fail(message); + } private IMemoryApi CreateDummyApi(byte[] memDomainContents) => new MemoryApi(Console.WriteLine) //TODO capture and check for error messages? @@ -106,5 +112,38 @@ namespace BizHawk.Tests.Client.Common.Api memApi => memApi.WriteByteRange(9, new byte[] { 0x01, 0x23, 0x45, 0x67 }), "fully above upper boundary"); } + + [TestMethod] + public void TestHash() + { + var memApi = CreateDummyApi(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }); + Assert.ThrowsException( + () => memApi.HashRegion(addr: -5, count: 3), + "fully below lower boundary"); + Assert.ThrowsException( + () => memApi.HashRegion(addr: -2, count: 4), + "crosses lower boundary"); + Assert.ThrowsException( + () => memApi.HashRegion(addr: -1, count: 10), + "crosses both boundaries"); + Assert.AreEqual( + "55C53F5D490297900CEFA825D0C8E8E9532EE8A118ABE7D8570762CD38BE9818", + memApi.HashRegion(addr: 0, count: 8), + "whole domain"); + Assert.AreEqual( + "233ABF8F525463C943A10F4DC3080B1BDA19D2EEAA4ACF4676F44689CED29232", + memApi.HashRegion(addr: 1, count: 5), + "strict contains"); + Assert.AreEqual( + SHA256Checksum.EmptyFile, + memApi.HashRegion(addr: 3, count: 0), + "empty"); + Assert.ThrowsException( + () => memApi.HashRegion(addr: 6, count: 3), + "crosses upper boundary"); + Assert.ThrowsException( + () => memApi.HashRegion(addr: 9, count: 4), + "fully above upper boundary"); + } } }