using Xunit; using XWorld.Server.Host; namespace XWorld.Server.Host.Tests { public class GameModuleRegistryTests { private static GameModuleRegistry NewRegistry() => new GameModuleRegistry(new GameModuleLoader(), TestGames.Root); [Fact] public void Acquire_SameVersionTwice_LoadsOnce_RefCounts() { var reg = NewRegistry(); var a = reg.Acquire("rps", 1); var b = reg.Acquire("rps", 1); Assert.Same(a, b); // 复用同一模块 Assert.Equal(2, reg.RefCount("rps", 1)); } [Fact] public void Release_ToZero_WithoutSupersede_KeepsLoaded() { var reg = NewRegistry(); var m = reg.Acquire("rps", 1); reg.Release(m); Assert.Equal(0, reg.RefCount("rps", 1)); Assert.True(reg.IsLoaded("rps", 1)); // 未被淘汰则保留以复用 } [Fact] public void NewVersion_Supersedes_Old_And_OldUnloadsWhenRefZero() { var reg = NewRegistry(); var v1 = reg.Acquire("rps", 1); // v1 引用=1 var v2 = reg.Acquire("rps", 2); // 取 v2 → v1 被标记淘汰 Assert.True(reg.IsLoaded("rps", 1)); Assert.True(reg.IsLoaded("rps", 2)); reg.Release(v1); // v1 引用归零且被淘汰 → 卸载并移除 Assert.False(reg.IsLoaded("rps", 1)); Assert.True(reg.IsLoaded("rps", 2)); // v2 仍在 } [Fact] public void Acquire_FailedNewVersionLoad_DoesNotSupersedeExisting() { var reg = NewRegistry(); var v1 = reg.Acquire("rps", 1); Assert.ThrowsAny(() => reg.Acquire("rps", 99)); // v99 不存在,加载抛出 reg.Release(v1); // v1 引用归零 Assert.True(reg.IsLoaded("rps", 1)); // 未被错误淘汰,仍保留 } [Fact] public void Release_MoreThanAcquired_Throws() { var reg = NewRegistry(); var m = reg.Acquire("rps", 1); reg.Release(m); Assert.Throws(() => reg.Release(m)); } } }