#nullable enable using SVSim.BattleEngine.Ambient; using NUnit.Framework; using System.Threading.Tasks; namespace SVSim.BattleEngine.Tests; [TestFixture, Parallelizable(ParallelScope.Self)] public class BattleAmbientTests { [Test] public void Current_IsNull_WhenNoScope() { Assert.That(BattleAmbient.Current, Is.Null); } [Test] public void Require_Throws_WhenNoScope() { Assert.Throws(() => BattleAmbient.Require()); } [Test] public void Enter_SetsCurrent_RestoresOnDispose() { var ctx = new BattleAmbientContext { ViewerId = 42 }; Assert.That(BattleAmbient.Current, Is.Null); using (var _ = BattleAmbient.Enter(ctx)) { Assert.That(BattleAmbient.Current, Is.SameAs(ctx)); Assert.That(BattleAmbient.Require().ViewerId, Is.EqualTo(42)); } Assert.That(BattleAmbient.Current, Is.Null); } [Test] public void Enter_Nested_RestoresPriorOnDispose() { var outer = new BattleAmbientContext { ViewerId = 1 }; var inner = new BattleAmbientContext { ViewerId = 2 }; using (var _o = BattleAmbient.Enter(outer)) { Assert.That(BattleAmbient.Current!.ViewerId, Is.EqualTo(1)); using (var _i = BattleAmbient.Enter(inner)) { Assert.That(BattleAmbient.Current!.ViewerId, Is.EqualTo(2)); } Assert.That(BattleAmbient.Current!.ViewerId, Is.EqualTo(1)); } } [Test] public async Task Enter_FlowsAcrossAwait() { var ctx = new BattleAmbientContext { ViewerId = 99 }; using (var _ = BattleAmbient.Enter(ctx)) { await Task.Yield(); Assert.That(BattleAmbient.Current, Is.SameAs(ctx)); } } [Test] public async Task Enter_IsolatedBetweenConcurrentTasks() { var ctxA = new BattleAmbientContext { ViewerId = 100 }; var ctxB = new BattleAmbientContext { ViewerId = 200 }; var taskA = Task.Run(async () => { using var _ = BattleAmbient.Enter(ctxA); await Task.Delay(20); return BattleAmbient.Current!.ViewerId; }); var taskB = Task.Run(async () => { using var _ = BattleAmbient.Enter(ctxB); await Task.Delay(20); return BattleAmbient.Current!.ViewerId; }); var results = await Task.WhenAll(taskA, taskB); Assert.That(results[0], Is.EqualTo(100)); Assert.That(results[1], Is.EqualTo(200)); } }