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;
}
}
}