using AcDream.Core.Spells; using Xunit; namespace AcDream.Core.Tests.Spells; public sealed class SpellbookTests { [Fact] public void OnSpellLearned_FiresEvent_Idempotent() { var book = new Spellbook(); int events = 0; book.SpellLearned += _ => events++; book.OnSpellLearned(0x3E1); // Flame Bolt I book.OnSpellLearned(0x3E1); // duplicate — no event Assert.Equal(1, events); Assert.Equal(1, book.LearnedCount); Assert.True(book.Knows(0x3E1)); } [Fact] public void OnSpellForgotten_FiresEvent() { var book = new Spellbook(); book.OnSpellLearned(0x3E1); uint seen = 0; book.SpellForgotten += id => seen = id; book.OnSpellForgotten(0x3E1); Assert.Equal(0x3E1u, seen); Assert.False(book.Knows(0x3E1)); } [Fact] public void OnEnchantmentAdded_FiresEvent_StoresByLayer() { var book = new Spellbook(); ActiveEnchantmentRecord added = default; book.EnchantmentAdded += r => added = r; book.OnEnchantmentAdded(spellId: 42, layerId: 7, duration: 300f, casterGuid: 0xBEEF); Assert.Equal(42u, added.SpellId); Assert.Equal(7u, added.LayerId); Assert.Equal(300f, added.Duration, 4); Assert.Equal(1, book.ActiveCount); } [Fact] public void OnEnchantmentAdded_SameLayer_Replaces() { var book = new Spellbook(); book.OnEnchantmentAdded(42, 7, 300f, 0); book.OnEnchantmentAdded(42, 7, 600f, 0); // refresh Assert.Equal(1, book.ActiveCount); foreach (var e in book.ActiveEnchantments) Assert.Equal(600f, e.Duration, 4); } [Fact] public void OnEnchantmentRemoved_FiresEvent() { var book = new Spellbook(); book.OnEnchantmentAdded(42, 7, 300f, 0); uint removedSpell = 0; book.EnchantmentRemoved += r => removedSpell = r.SpellId; book.OnEnchantmentRemoved(7, 42); Assert.Equal(42u, removedSpell); Assert.Equal(0, book.ActiveCount); } [Fact] public void OnPurgeAll_RemovesAllEnchantments_FiresPerRecord() { var book = new Spellbook(); book.OnEnchantmentAdded(1, 1, 100f, 0); book.OnEnchantmentAdded(2, 2, 100f, 0); book.OnEnchantmentAdded(3, 3, 100f, 0); int removals = 0; book.EnchantmentRemoved += _ => removals++; book.OnPurgeAll(); Assert.Equal(3, removals); Assert.Equal(0, book.ActiveCount); } }