mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 17:21:16 +08:00
- 新增 GfRichTextLabel 组件作为富文本标签宿主 - 实现 IRichTextEffectHost 接口用于效果控制器驱动 - 创建 RichTextEffectsController 处理效果装配逻辑 - 添加 RichTextProfile 配置资源类型 - 引入 RichTextEffectPlan 和 RichTextEffectPlanEntry 类型 - 在 CI 工作流中添加 GFramework.Godot.Tests 项目 - 优化 Godot 测试诊断条件判断逻辑 - 添加富文本效果控制器相关单元测试
130 lines
4.1 KiB
C#
130 lines
4.1 KiB
C#
namespace GFramework.Godot.Tests.Text;
|
||
|
||
/// <summary>
|
||
/// <see cref="RichTextEffectsController" /> 的纯托管行为测试。
|
||
/// </summary>
|
||
[TestFixture]
|
||
public sealed class RichTextEffectsControllerTests
|
||
{
|
||
/// <summary>
|
||
/// 验证启用框架效果时会开启宿主 BBCode,并在 Profile 为空时回退到内置默认配置。
|
||
/// </summary>
|
||
[Test]
|
||
public void RefreshEffects_Should_Enable_Bbcode_And_Use_BuiltIn_Default_Profile()
|
||
{
|
||
var host = new FakeRichTextEffectHost();
|
||
var controller = new RichTextEffectsController(
|
||
host,
|
||
() => null,
|
||
() => true,
|
||
() => false);
|
||
|
||
controller.RefreshEffects();
|
||
|
||
Assert.That(host.BbcodeEnabled, Is.True);
|
||
Assert.That(host.CapturedAnimatedEffectsEnabled, Has.Count.EqualTo(1));
|
||
Assert.That(host.CapturedAnimatedEffectsEnabled[0], Is.False);
|
||
Assert.That(host.CapturedProfiles, Has.Count.EqualTo(1));
|
||
Assert.That(host.CapturedProfiles[0].Effects.Select(static entry => entry.Key), Is.EqualTo(new[]
|
||
{
|
||
"green",
|
||
"red",
|
||
"gold",
|
||
"blue",
|
||
"fade_in",
|
||
"sine",
|
||
"jitter",
|
||
"fly_in"
|
||
}));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证关闭框架效果时不会触发新的效果安装,并会清空宿主的自定义效果集合。
|
||
/// </summary>
|
||
[Test]
|
||
public void RefreshEffects_Should_Clear_CustomEffects_When_Framework_Effects_Are_Disabled()
|
||
{
|
||
var host = new FakeRichTextEffectHost
|
||
{
|
||
BbcodeEnabled = true
|
||
};
|
||
host.SimulateInstalledEffects();
|
||
var controller = new RichTextEffectsController(
|
||
host,
|
||
() => RichTextEffectPlan.CreateBuiltInDefault(),
|
||
() => false,
|
||
() => true);
|
||
|
||
controller.RefreshEffects();
|
||
|
||
Assert.That(host.BbcodeEnabled, Is.True);
|
||
Assert.That(host.CustomEffectsInstalled, Is.False);
|
||
Assert.That(host.ClearCustomEffectsCallCount, Is.EqualTo(1));
|
||
Assert.That(host.CapturedProfiles, Is.Empty);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证控制器会在每次刷新时读取最新的配置访问器结果,避免缓存旧配置。
|
||
/// </summary>
|
||
[Test]
|
||
public void RefreshEffects_Should_Use_The_Current_Profile_From_Accessor()
|
||
{
|
||
var host = new FakeRichTextEffectHost();
|
||
var firstProfile = new RichTextEffectPlan(
|
||
[
|
||
new RichTextEffectPlanEntry("green")
|
||
]);
|
||
var secondProfile = new RichTextEffectPlan(
|
||
[
|
||
new RichTextEffectPlanEntry("gold")
|
||
]);
|
||
RichTextEffectPlan? currentProfile = firstProfile;
|
||
|
||
var controller = new RichTextEffectsController(
|
||
host,
|
||
() => currentProfile,
|
||
() => true,
|
||
() => true);
|
||
|
||
controller.RefreshEffects();
|
||
currentProfile = secondProfile;
|
||
controller.RefreshEffects();
|
||
|
||
Assert.That(host.CapturedProfiles, Has.Count.EqualTo(2));
|
||
Assert.That(host.CapturedProfiles[0], Is.SameAs(firstProfile));
|
||
Assert.That(host.CapturedProfiles[1], Is.SameAs(secondProfile));
|
||
}
|
||
|
||
private sealed class FakeRichTextEffectHost : IRichTextEffectHost
|
||
{
|
||
public List<RichTextEffectPlan> CapturedProfiles { get; } = [];
|
||
|
||
public List<bool> CapturedAnimatedEffectsEnabled { get; } = [];
|
||
|
||
public bool CustomEffectsInstalled { get; private set; }
|
||
|
||
public int ClearCustomEffectsCallCount { get; private set; }
|
||
public bool BbcodeEnabled { get; set; }
|
||
|
||
public void ApplyEffects(RichTextEffectPlan profile, bool animatedEffectsEnabled)
|
||
{
|
||
ArgumentNullException.ThrowIfNull(profile);
|
||
|
||
CapturedProfiles.Add(profile);
|
||
CapturedAnimatedEffectsEnabled.Add(animatedEffectsEnabled);
|
||
CustomEffectsInstalled = true;
|
||
}
|
||
|
||
public void ClearCustomEffects()
|
||
{
|
||
ClearCustomEffectsCallCount++;
|
||
CustomEffectsInstalled = false;
|
||
}
|
||
|
||
public void SimulateInstalledEffects()
|
||
{
|
||
CustomEffectsInstalled = true;
|
||
}
|
||
}
|
||
}
|