sharpemu/tests/SharpEmu.Libs.Tests/Json/JsonExportRegistrationTests.cs

81 lines
3.2 KiB
C#

// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using SharpEmu.HLE;
using SharpEmu.Libs.Json;
using Xunit;
namespace SharpEmu.Libs.Tests.Json;
// These NIDs came back "unresolved" in the Quake (PPSA01880) import log right before its
// access violation. This asserts they now resolve to the Json handlers and dispatch cleanly,
// which is the plumbing the direct-call tests cannot cover.
[Collection("JsonObjectHeap")]
public sealed class JsonExportRegistrationTests
{
private static readonly (string Nid, string Name)[] ExpectedExports =
{
("qBMjqyBn3OM", "_ZN3sce4Json5ValueC1Ev"),
("5yHuiWXo2gg", "_ZN3sce4Json5Value3setEb"),
("QxVVYhP-mvg", "_ZN3sce4Json5Value3setEl"),
("SIe1ZmW7e7s", "_ZN3sce4Json5Value3setEm"),
("BSmWDIkV4w4", "_ZN3sce4Json5Value3setEd"),
("IKQimvG9Wqs", "_ZN3sce4Json5Value3setENS0_9ValueTypeE"),
("6l3Bv2gysNc", "_ZN3sce4Json5Value3setERKNS0_6StringE"),
("9KUZFjI1IxA", "_ZN3sce4Json6StringC1EPKc"),
("cG1VE2HMl6c", "_ZN3sce4Json6StringD1Ev"),
("+drDFyAS6u4", "_ZN3sce4Json11Initializer27setGlobalNullAccessCallbackEPFRKNS0_5ValueENS0_9ValueTypeEPS3_PvES7_"),
};
private static ModuleManager CreateRegisteredManager()
{
var manager = new ModuleManager();
manager.RegisterExports(SharpEmu.Generated.SysAbiExportRegistry.CreateExports(Generation.Gen5));
return manager;
}
[Fact]
public void QuakeUnresolvedJsonNids_ResolveToJsonExports()
{
var manager = CreateRegisteredManager();
foreach (var (nid, name) in ExpectedExports)
{
Assert.True(manager.TryGetExport(nid, out var export), $"NID {nid} did not register.");
Assert.Equal(name, export.Name);
Assert.Equal("libSceJson", export.LibraryName);
}
}
[Fact]
public void SetGlobalNullAccessCallback_StoresHookAndReturnsOk()
{
JsonObjectHeap.ResetForTests();
var manager = CreateRegisteredManager();
var ctx = new CpuContext(new FakeCpuMemory(0x1_0000_0000, 0x1000), Generation.Gen5);
ctx[CpuRegister.Rdi] = 0x1_0000_0000; // Initializer instance
ctx[CpuRegister.Rsi] = 0x8_0012_3456; // guest callback
ctx[CpuRegister.Rdx] = 0x1_0000_0800; // user context
Assert.True(manager.TryDispatch("+drDFyAS6u4", ctx, out var result));
Assert.Equal(OrbisGen2Result.ORBIS_GEN2_OK, result);
Assert.Equal(0UL, ctx[CpuRegister.Rax]);
Assert.Equal(0x8_0012_3456UL, JsonObjectHeap.GlobalNullAccessCallback);
Assert.Equal(0x1_0000_0800UL, JsonObjectHeap.GlobalNullAccessCallbackContext);
}
[Fact]
public void DispatchValueConstructor_RunsHandlerAndReturnsThis()
{
JsonObjectHeap.ResetForTests();
var manager = CreateRegisteredManager();
var ctx = new CpuContext(new FakeCpuMemory(0x1_0000_0000, 0x1000), Generation.Gen5);
ctx[CpuRegister.Rdi] = 0x1_0000_0000;
Assert.True(manager.TryDispatch("qBMjqyBn3OM", ctx, out var result));
Assert.Equal(OrbisGen2Result.ORBIS_GEN2_OK, result);
Assert.Equal(0x1_0000_0000UL, ctx[CpuRegister.Rax]);
Assert.Equal(JsonValueKind.Null, JsonObjectHeap.Values[0x1_0000_0000].Kind);
}
}