using GFramework.Core.Abstractions.Architectures; using GFramework.Core.Abstractions.Enums; using GFramework.Core.Abstractions.Events; using GFramework.Core.Abstractions.Rule; using GFramework.Core.Architectures; using GFramework.Core.Events; using GFramework.Core.Ioc; using GFramework.Game.Abstractions.Setting; using GFramework.Game.Setting; using GFramework.Game.Setting.Events; namespace GFramework.Game.Tests.Setting; /// /// 覆盖 的系统层语义,确保系统对模型编排、事件发送和重置流程保持稳定。 /// [TestFixture] public sealed class SettingsSystemTests { /// /// 验证 会尝试应用全部 applicator,并为成功与失败结果分别发送事件。 /// /// 表示异步测试完成的任务。 [Test] public async Task ApplyAll_Should_Apply_All_Applicators_And_Publish_Result_Events() { var successfulApplicator = new PrimaryTestSettings(); var failingApplicator = new SecondaryTestSettings(throwOnApply: true); var model = new FakeSettingsModel(successfulApplicator, failingApplicator); var context = CreateContext(model); var system = CreateSystem(context); var applyingEventCount = 0; var appliedEventCount = 0; var failedEventCount = 0; context.RegisterEvent>(_ => applyingEventCount++); context.RegisterEvent>(eventData => { appliedEventCount++; if (!eventData.Success) { failedEventCount++; } }); await system.ApplyAll(); Assert.Multiple(() => { Assert.That(successfulApplicator.ApplyCount, Is.EqualTo(1)); Assert.That(failingApplicator.ApplyCount, Is.EqualTo(1)); Assert.That(applyingEventCount, Is.EqualTo(2)); Assert.That(appliedEventCount, Is.EqualTo(2)); Assert.That(failedEventCount, Is.EqualTo(1)); }); } /// /// 验证 会直接委托给模型层统一保存。 /// /// 表示异步测试完成的任务。 [Test] public async Task SaveAll_Should_Delegate_To_Model() { var model = new FakeSettingsModel(new PrimaryTestSettings()); var system = CreateSystem(CreateContext(model)); await system.SaveAll(); Assert.That(model.SaveAllCallCount, Is.EqualTo(1)); } /// /// 验证 会先委托模型统一重置,再重新应用全部 applicator。 /// /// 表示异步测试完成的任务。 [Test] public async Task ResetAll_Should_Reset_Model_And_Reapply_All_Applicators() { var primaryApplicator = new PrimaryTestSettings(); var secondaryApplicator = new SecondaryTestSettings(); var model = new FakeSettingsModel(primaryApplicator, secondaryApplicator); var system = CreateSystem(CreateContext(model)); await system.ResetAll(); Assert.Multiple(() => { Assert.That(model.ResetAllCallCount, Is.EqualTo(1)); Assert.That(primaryApplicator.ApplyCount, Is.EqualTo(1)); Assert.That(secondaryApplicator.ApplyCount, Is.EqualTo(1)); }); } /// /// 验证 会重置目标数据类型,并只重新应用对应的 applicator。 /// /// 表示异步测试完成的任务。 [Test] public async Task Reset_Should_Reset_Target_Data_And_Reapply_Target_Applicator() { var primaryApplicator = new PrimaryTestSettings(); var secondaryApplicator = new SecondaryTestSettings(); var model = new FakeSettingsModel(primaryApplicator, secondaryApplicator); var system = CreateSystem(CreateContext(model)); await system.Reset(); Assert.Multiple(() => { Assert.That(model.ResetTypes, Is.EquivalentTo(new[] { typeof(PrimaryTestSettings) })); Assert.That(primaryApplicator.ApplyCount, Is.EqualTo(1)); Assert.That(secondaryApplicator.ApplyCount, Is.Zero); }); } /// /// 创建带事件总线和设置模型的真实架构上下文。 /// /// 测试使用的设置模型。 /// 可供系统解析依赖与发送事件的上下文。 private static ArchitectureContext CreateContext(ISettingsModel model) { var container = new MicrosoftDiContainer(); container.Register(new EventBus()); container.Register(model); container.Freeze(); return new ArchitectureContext(container); } /// /// 创建并初始化绑定到指定上下文的设置系统。 /// /// 系统运行所需的架构上下文。 /// 已完成初始化的设置系统实例。 private static SettingsSystem CreateSystem(IArchitectureContext context) { var system = new SettingsSystem(); ((IContextAware)system).SetContext(context); system.Initialize(); return system; } /// /// 用于系统层测试的简化设置模型,记录系统对模型的调用行为。 /// private sealed class FakeSettingsModel : ISettingsModel { private readonly IReadOnlyDictionary _applicators; /// /// 初始化测试模型,并注册参与测试的 applicator 集合。 /// /// 测试使用的 applicator。 public FakeSettingsModel(params IResetApplyAbleSettings[] applicators) { _applicators = applicators.ToDictionary(applicator => applicator.GetType()); } /// /// 获取保存全量设置的调用次数。 /// public int SaveAllCallCount { get; private set; } /// /// 获取重置全部设置的调用次数。 /// public int ResetAllCallCount { get; private set; } /// /// 获取被请求重置的设置数据类型列表。 /// public List ResetTypes { get; } = []; /// public bool IsInitialized => true; /// public void SetContext(IArchitectureContext context) { } /// public IArchitectureContext GetContext() { throw new NotSupportedException("Fake settings model does not expose a context."); } /// public void OnArchitecturePhase(ArchitecturePhase phase) { } /// public void Initialize() { } /// public T GetData() where T : class, ISettingsData, new() { return new T(); } /// public IEnumerable AllData() { return []; } /// public ISettingsModel RegisterApplicator(T applicator) where T : class, IResetApplyAbleSettings { return this; } /// public T? GetApplicator() where T : class, IResetApplyAbleSettings { return _applicators.TryGetValue(typeof(T), out var applicator) ? (T)applicator : null; } /// public IEnumerable AllApplicators() { return _applicators.Values; } /// public ISettingsModel RegisterMigration(ISettingsMigration migration) { return this; } /// public Task InitializeAsync() { return Task.CompletedTask; } /// public Task SaveAllAsync() { SaveAllCallCount++; return Task.CompletedTask; } /// public Task ApplyAllAsync() { return Task.CompletedTask; } /// public void Reset() where T : class, ISettingsData, new() { ResetTypes.Add(typeof(T)); } /// public void ResetAll() { ResetAllCallCount++; } } /// /// 为系统层测试提供的最小设置数据实现。 /// private abstract class TestSettingsBase : ISettingsData, IResetApplyAbleSettings { /// public int Version { get; set; } = 1; /// public DateTime LastModified { get; } = DateTime.UtcNow; /// /// 获取测试用的数值字段,用于确认重置与加载行为。 /// public int Value { get; private set; } /// /// 获取应用操作被调用的次数。 /// public int ApplyCount { get; private set; } /// public ISettingsData Data => this; /// public Type DataType => GetType(); /// /// 获取或设置是否在应用时抛出异常。 /// protected bool ThrowOnApply { get; init; } /// public void Reset() { Value = 0; } /// public void LoadFrom(ISettingsData source) { if (source is TestSettingsBase data) { Value = data.Value; Version = data.Version; } } /// public async Task ApplyAsync() { ApplyCount++; await Task.Yield(); if (ThrowOnApply) { throw new InvalidOperationException("Test applicator failed."); } } } /// /// 代表主设置分支的测试设置对象。 /// private sealed class PrimaryTestSettings : TestSettingsBase { } /// /// 代表第二个设置分支的测试设置对象,可选择在应用时失败。 /// private sealed class SecondaryTestSettings : TestSettingsBase { /// /// 初始化第二个测试设置对象。 /// /// 是否在应用时抛出异常。 public SecondaryTestSettings(bool throwOnApply = false) { ThrowOnApply = throwOnApply; } } }