using System.Text.RegularExpressions; namespace AcDream.App.Tests.Runtime; public sealed class RuntimeActionOwnershipTests { [Fact] public void ProductionConstructsOneCanonicalActionOwner() { string root = FindRepositoryRoot(); string gameWindow = ReadAppSource( root, "Rendering", "GameWindow.cs"); string program = ReadAppSource(root, "Program.cs"); Assert.Contains( "private readonly GameRuntime _runtime;", gameWindow, StringComparison.Ordinal); Assert.Contains( "_runtime = new GameRuntime(new GameRuntimeDependencies(", gameWindow, StringComparison.Ordinal); Assert.Contains( "_runtimeActions.Selection;", gameWindow, StringComparison.Ordinal); Assert.Contains( "_runtimeActions.Combat;", gameWindow, StringComparison.Ordinal); Assert.Contains( "window.Selection,", program, StringComparison.Ordinal); string[] productionFiles = Directory .EnumerateFiles( Path.Combine(root, "src", "AcDream.App"), "*.cs", SearchOption.AllDirectories) .Where(static path => !path.Contains( $"{Path.DirectorySeparatorChar}Studio{Path.DirectorySeparatorChar}", StringComparison.Ordinal)) .ToArray(); string production = string.Join( "\n", productionFiles.Select(File.ReadAllText)); Assert.Empty(Regex.Matches( production, @"\bnew\s+(?:AcDream\.Core\.Selection\.)?SelectionState\s*\(")); Assert.Empty(Regex.Matches( production, @"\bnew\s+(?:AcDream\.Core\.Combat\.)?CombatState\s*\(")); Assert.Empty(Regex.Matches( production, @"\bnew\s+(?:AcDream\.Runtime\.Gameplay\.)?InteractionState\s*\(")); Assert.Empty(Regex.Matches( production, @"\bnew\s+(?:AcDream\.Runtime\.Gameplay\.)?RuntimeInteractionTransactionState\s*\(")); Assert.Empty(Regex.Matches( production, @"\bnew\s+(?:AcDream\.Runtime\.Gameplay\.)?RuntimeCombatAttackState\s*\(")); Assert.Empty(Regex.Matches( production, @"\bnew\s+(?:AcDream\.Runtime\.Gameplay\.)?RuntimeCombatTargetState\s*\(")); Assert.Empty(Regex.Matches( production, @"\bnew\s+(?:AcDream\.Runtime\.Gameplay\.)?RuntimeCombatModeState\s*\(")); Assert.Empty(Regex.Matches( production, @"\bnew\s+(?:AcDream\.Runtime\.Gameplay\.)?RuntimeSpellCastState\s*\(")); Assert.Empty(Regex.Matches( production, @"\bnew\s+RuntimeActionState\s*\(")); } [Fact] public void UiSessionRuntimeAndShutdownBorrowTheExactActionChildren() { string root = FindRepositoryRoot(); string ui = ReadAppSource( root, "Composition", "InteractionRetainedUiComposition.cs"); string session = ReadAppSource( root, "Composition", "SessionPlayerComposition.cs"); string liveSession = ReadAppSource( root, "Net", "LiveSessionRuntimeFactory.cs"); string commands = ReadAppSource( root, "Runtime", "CurrentGameRuntimeCommandAdapter.cs"); string itemInteraction = ReadAppSource( root, "UI", "ItemInteractionController.cs"); string shutdown = ReadAppSource( root, "Rendering", "GameWindowLifetime.cs"); Assert.Contains("d.Actions.Interaction,", ui, StringComparison.Ordinal); Assert.Contains("d.Actions.Transactions,", ui, StringComparison.Ordinal); Assert.Contains("d.Actions.Selection", ui, StringComparison.Ordinal); Assert.Contains("d.Actions.Combat", ui, StringComparison.Ordinal); Assert.Contains( "_dependencies.Actions.CombatAttack", ui, StringComparison.Ordinal); Assert.Contains("d.Actions.SpellCast", ui, StringComparison.Ordinal); Assert.Contains("d.Actions.Selection", session, StringComparison.Ordinal); Assert.Contains("d.Actions.Combat", session, StringComparison.Ordinal); Assert.Contains("_domain.Actions.Combat", liveSession, StringComparison.Ordinal); Assert.Contains( "_domain.Actions.Transactions.CompleteUse(error)", liveSession, StringComparison.Ordinal); Assert.Contains("_actions.Selection", commands, StringComparison.Ordinal); Assert.Contains( "RuntimeInteractionTransactionState runtimeTransactions,", itemInteraction, StringComparison.Ordinal); Assert.DoesNotContain( "new InteractionState", itemInteraction, StringComparison.Ordinal); Assert.Contains( "new ResourceShutdownStage(\"game runtime root\"", shutdown, StringComparison.Ordinal); Assert.DoesNotContain( "RuntimeActionState Actions", shutdown, StringComparison.Ordinal); Assert.False(File.Exists(Path.Combine( root, "src", "AcDream.App", "UI", "InteractionState.cs"))); } private static string ReadAppSource(string root, params string[] relative) => 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; } } }