Move the coupled Spellbook and LocalPlayerState into one Runtime-owned character graph, route content, live-session, retained UI, reset, and shutdown through that exact owner, and delete the duplicate desired-component snapshot from inventory state. Preserve synchronous retail update and reset ordering while adding independent-instance and retryable-failure coverage. Co-authored-by: Codex <codex@openai.com>
106 lines
3.6 KiB
C#
106 lines
3.6 KiB
C#
namespace AcDream.App.Tests.Runtime;
|
|
|
|
public sealed class RuntimeCharacterOwnershipTests
|
|
{
|
|
[Fact]
|
|
public void ProductionConstructsOnlyTheRuntimeCharacterOwner()
|
|
{
|
|
string source = ReadSource("Rendering", "GameWindow.cs");
|
|
|
|
Assert.Contains(
|
|
"_runtimeCharacter = new RuntimeCharacterState();",
|
|
source,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain(
|
|
"new AcDream.Core.Spells.Spellbook",
|
|
source,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain(
|
|
"new AcDream.Core.Player.LocalPlayerState",
|
|
source,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"SpellBook =>\n _runtimeCharacter.Spellbook;",
|
|
Normalize(source),
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"LocalPlayer =>\n _runtimeCharacter.LocalPlayer;",
|
|
Normalize(source),
|
|
StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void SessionRoutingAndShutdownBorrowTheExactRuntimeOwner()
|
|
{
|
|
string session = ReadSource("Net", "LiveSessionRuntimeFactory.cs");
|
|
string router = ReadRuntimeSource(
|
|
"Session",
|
|
"LiveSessionEventRouter.cs");
|
|
string content = ReadSource(
|
|
"Composition",
|
|
"ContentEffectsAudioComposition.cs");
|
|
string ui = ReadSource(
|
|
"Composition",
|
|
"InteractionRetainedUiComposition.cs");
|
|
string inventory = ReadRuntimeSource(
|
|
"Gameplay",
|
|
"RuntimeInventoryState.cs");
|
|
string shutdown = ReadSource("Rendering", "GameWindowLifetime.cs");
|
|
|
|
Assert.Contains(
|
|
"RuntimeCharacterState Character",
|
|
session,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"character.Character.Spellbook",
|
|
router,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"character.Character.LocalPlayer",
|
|
router,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"_factory.InstallSpellMetadata(_dependencies.Character, magic)",
|
|
content,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"d.Character.Spellbook",
|
|
ui,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"d.Character.LocalPlayer",
|
|
ui,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain(
|
|
"DesiredComponentState",
|
|
inventory,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"\"runtime character state\"",
|
|
shutdown,
|
|
StringComparison.Ordinal);
|
|
}
|
|
|
|
private static string ReadSource(params string[] relative) =>
|
|
File.ReadAllText(Path.Combine(
|
|
[FindRepositoryRoot(), "src", "AcDream.App", .. relative]));
|
|
|
|
private static string ReadRuntimeSource(params string[] relative) =>
|
|
File.ReadAllText(Path.Combine(
|
|
[FindRepositoryRoot(), "src", "AcDream.Runtime", .. relative]));
|
|
|
|
private static string Normalize(string source) =>
|
|
source.Replace("\r\n", "\n", StringComparison.Ordinal);
|
|
|
|
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.");
|
|
}
|
|
}
|