acdream/tests/AcDream.App.Tests/Runtime/RuntimeInventoryOwnershipTests.cs
Erik 011efbeaa7 refactor(runtime): own inventory transaction state
Move the retail one-request-at-a-time gate, shared use busy references, external-container state, item mana, shortcuts, and desired-component snapshots into one Runtime-owned graph over J3's exact ClientObjectTable. Retained UI and session routing now borrow that owner; reset and shutdown preserve the existing order while failure/reentrancy tests protect the transaction boundary.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 08:20:32 +02:00

97 lines
3.1 KiB
C#

namespace AcDream.App.Tests.Runtime;
public sealed class RuntimeInventoryOwnershipTests
{
[Fact]
public void ProductionConstructsOnlyTheRuntimeInventoryOwner()
{
string source = ReadSource("Rendering", "GameWindow.cs");
Assert.Contains(
"_runtimeInventory = new RuntimeInventoryState(_runtimeEntityObjects);",
source,
StringComparison.Ordinal);
Assert.DoesNotContain(
"new AcDream.Core.Items.ItemManaState",
source,
StringComparison.Ordinal);
Assert.DoesNotContain(
"new DesiredComponentSnapshotState",
source,
StringComparison.Ordinal);
Assert.DoesNotContain(
"new ShortcutSnapshotState",
source,
StringComparison.Ordinal);
Assert.DoesNotContain(
"new AcDream.Core.Items.ExternalContainerState",
source,
StringComparison.Ordinal);
}
[Fact]
public void UiSessionAndShutdownBorrowTheExactRuntimeOwner()
{
string ui = ReadSource(
"Composition",
"InteractionRetainedUiComposition.cs");
string session = ReadSource("Net", "LiveSessionRuntimeFactory.cs");
string shutdown = ReadSource("Rendering", "GameWindowLifetime.cs");
Assert.Contains(
"transactions: d.Inventory.Transactions",
ui,
StringComparison.Ordinal);
Assert.Contains(
"OnShortcuts: _domain.Inventory.Shortcuts.Replace",
session,
StringComparison.Ordinal);
Assert.Contains(
"_domain.Inventory.Transactions.CompleteUse(error)",
session,
StringComparison.Ordinal);
Assert.Contains(
"OnDesiredComponents: _domain.Inventory.DesiredComponents.Replace",
session,
StringComparison.Ordinal);
AssertAppearsInOrder(
shutdown,
"\"runtime inventory state\"",
"\"runtime entity/object lifetime\"");
}
private static string ReadSource(params string[] relative)
{
string root = FindRepositoryRoot();
return File.ReadAllText(Path.Combine(
[root, "src", "AcDream.App", .. relative]));
}
private static string FindRepositoryRoot()
{
var current = new DirectoryInfo(AppContext.BaseDirectory);
while (current is not null)
{
if (File.Exists(Path.Combine(current.FullName, "AcDream.slnx")))
return current.FullName;
current = current.Parent;
}
throw new DirectoryNotFoundException("AcDream.slnx was not found.");
}
private static void AssertAppearsInOrder(
string source,
params string[] fragments)
{
int cursor = 0;
foreach (string fragment in fragments)
{
int index = source.IndexOf(
fragment,
cursor,
StringComparison.Ordinal);
Assert.True(index >= 0, $"Missing source fragment: {fragment}");
cursor = index + fragment.Length;
}
}
}