using AcDream.App.Combat; namespace AcDream.App.Tests.Combat; public sealed class CombatFeedbackSlotTests { [Fact] public void ExpectedOwnerUnbindCannotClearReplacement() { var slot = new CombatFeedbackSlot(); List first = []; List second = []; Action firstTarget = first.Add; Action secondTarget = second.Add; slot.Bind(firstTarget); slot.Unbind(secondTarget); slot.Show("first"); Assert.Equal(["first"], first); Assert.Empty(second); slot.Unbind(firstTarget); slot.Bind(secondTarget); slot.Show("second"); Assert.Equal(["second"], second); } [Fact] public void RebindingADifferentTargetWhileBoundIsRejected() { var slot = new CombatFeedbackSlot(); slot.Bind(_ => { }); Assert.Throws(() => slot.Bind(_ => { })); } [Fact] public void AnUnboundSlotDropsItsMessages() { // #434/#436: this is the shipped behavior, not an aspiration — // nothing binds the slot in production, so combat refusal text // ("No monster target") is discarded. Pinned so the day it gets a // real binder, this test is the one that has to change. var slot = new CombatFeedbackSlot(); slot.Show("dropped"); } }