using System.Text.RegularExpressions; using AcDream.App.Physics; namespace AcDream.App.Tests.Physics; public sealed class LiveEntityNetworkBranchRoutingTests { [Fact] public void Vector_ProjectileStopsCanonicalAndOrdinaryRoutes() { var calls = new List(); LiveEntityVectorRoute route = LiveEntityVectorRouter.Route( () => { calls.Add("projectile"); return true; }, () => { calls.Add("canonical"); return true; }, () => calls.Add("ordinary")); Assert.Equal(LiveEntityVectorRoute.Projectile, route); Assert.Equal(["projectile"], calls); } [Fact] public void Vector_CanonicalBodyRunsOnlyAfterProjectileDeclines() { var calls = new List(); LiveEntityVectorRoute route = LiveEntityVectorRouter.Route( () => { calls.Add("projectile"); return false; }, () => { calls.Add("canonical"); return true; }, () => calls.Add("ordinary")); Assert.Equal(LiveEntityVectorRoute.CanonicalBody, route); Assert.Equal(["projectile", "canonical"], calls); } [Fact] public void Vector_OrdinaryRemoteIsTheLastFallback() { var calls = new List(); LiveEntityVectorRoute route = LiveEntityVectorRouter.Route( () => { calls.Add("projectile"); return false; }, () => { calls.Add("canonical"); return false; }, () => calls.Add("ordinary")); Assert.Equal(LiveEntityVectorRoute.OrdinaryRemote, route); Assert.Equal(["projectile", "canonical", "ordinary"], calls); } // C4 route 2 (2026-08-03): LocalForcePositionTransaction and its // ForcePosition_* coverage here are RETIRED, not adapted — the class is // deleted outright (docs/research/2026-08-03-c4-route-2-contract.md // §"The contract" item 2). Its three jobs (ownership validation, the // blip/commit, and the exactly-once ack including the displaced- // authority case its trailing isCurrent() covered) are now properties of // the Runtime-owned RuntimeAcceptedPositionDriveController and are tested // there: tests/AcDream.Runtime.Tests/Session/RuntimeAcceptedPositionDriveControllerTests.cs. /// /// R8 review fix (2026-08-03): source pins for the generic-tail /// double-write guard in LiveEntityNetworkUpdateController.OnPosition. /// A full behavioral fixture is impractical here for the SAME reason /// C3cF1ProductionWiringTests gives — the controller's dependency /// set is composition-only (67+ collaborators wired only by /// SessionPlayerComposition) — so this follows that file's exact /// established pattern: assert the STRUCTURE of the production source /// rather than construct the class. The Runtime-level behavioral /// coverage for the seam itself lives in /// RuntimeAcceptedPositionDriveControllerTests; these pins are what stop /// this App-layer call site from silently reintroducing the retired /// duplicate-write authority (the deleted LocalForcePositionTransaction /// pair + the generic render-tail writing the SAME accepted Position a /// second time — 670f307c's divergence class). /// public sealed class LiveEntityNetworkUpdateControllerForcePositionWiringTests { [Fact] public void LocalForcePositionTransactionIsNeverCalledFromThisFile() { string source = ReadSource("LiveEntityNetworkUpdateController.cs"); // The name may still appear in a comment explaining what // replaced it (contract §"the deleted LocalForcePositionTransaction"); // what must be gone is any actual call into it. Assert.DoesNotContain( "LocalForcePositionTransaction.Apply(", source, StringComparison.Ordinal); } [Fact] public void GenericTailWriteIsNeverDuplicatedForTheLocalForcePositionPath() { string source = ReadSource("LiveEntityNetworkUpdateController.cs"); // The generic render-tail's WorldEntity write is the ONE // remaining writer of an accepted Position — it must serve // remotes only, never a second local-player write alongside the // Runtime-committed one. Assert.Single( Regex.Matches(source, @"entity\.SetPosition\(worldPos\);") .Cast()); } [Fact] public void CommittedOrDeferredCellReturnsBeforeReachingTheGenericTail() { string source = ReadSource("LiveEntityNetworkUpdateController.cs"); // The Committed/DeferredCell branch must still return // immediately after its two preserved side effects — a missing // `return` here would fall through into the generic tail below // and resurrect the double-write. Assert.Matches( new Regex( @"ObserveAcceptedLocalPosition\(\s*" + @"update\.Position\.LandblockId\);\s*return;", RegexOptions.Singleline), source); } private static string ReadSource(string fileName) { DirectoryInfo? directory = new(AppContext.BaseDirectory); while (directory is not null) { if (File.Exists(Path.Combine(directory.FullName, "AcDream.slnx"))) { return File.ReadAllText(Path.Combine( directory.FullName, "src", "AcDream.App", "Physics", fileName)); } directory = directory.Parent; } throw new DirectoryNotFoundException("Could not find AcDream.slnx."); } } }