mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
- 创建 RichTextEffectBase 基类提供统一的标签命名和环境参数读取逻辑 - 实现 RichTextJitterEffect 抖动效果类,支持振幅和速度参数调节 - 添加 DefaultRichTextEffectRegistry 默认效果注册表管理内置效果映射 - 创建 GfRichTextLabel 组合式富文本标签宿主,集成效果装配逻辑 - 定义 IRichTextEffectRegistry 接口实现效果注册表抽象 - 开发 RichTextEffectsController 装配控制器负责效果集合管理 - 实现 RichTextMarkup 工具类提供语义化富文本标签构建辅助方法 - 添加相关单元测试验证效果控制器和标记工具的功能正确性
127 lines
4.0 KiB
C#
127 lines
4.0 KiB
C#
using GFramework.Godot.Text;
|
||
using Godot;
|
||
using Array = Godot.Collections.Array;
|
||
|
||
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 registry = new RecordingRegistry();
|
||
var controller = new RichTextEffectsController(
|
||
host,
|
||
() => registry,
|
||
() => null,
|
||
() => true,
|
||
() => false);
|
||
|
||
controller.RefreshEffects();
|
||
|
||
Assert.That(host.BbcodeEnabled, Is.True);
|
||
Assert.That(registry.CapturedAnimatedEffectsEnabled, Is.False);
|
||
Assert.That(registry.CapturedProfiles, Has.Count.EqualTo(1));
|
||
Assert.That(registry.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 existingEffects = new Array();
|
||
existingEffects.Add("placeholder");
|
||
|
||
var host = new FakeRichTextEffectHost
|
||
{
|
||
BbcodeEnabled = true,
|
||
CustomEffects = existingEffects
|
||
};
|
||
var registry = new RecordingRegistry();
|
||
var controller = new RichTextEffectsController(
|
||
host,
|
||
() => registry,
|
||
() => RichTextProfile.CreateBuiltInDefault(),
|
||
() => false,
|
||
() => true);
|
||
|
||
controller.RefreshEffects();
|
||
|
||
Assert.That(host.BbcodeEnabled, Is.True);
|
||
Assert.That(host.CustomEffects.Count, Is.EqualTo(0));
|
||
Assert.That(registry.CapturedProfiles, Is.Empty);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证控制器会在每次刷新时读取最新的注册表访问器结果,避免缓存旧注册表。
|
||
/// </summary>
|
||
[Test]
|
||
public void RefreshEffects_Should_Use_The_Current_Registry_From_Accessor()
|
||
{
|
||
var host = new FakeRichTextEffectHost();
|
||
var firstRegistry = new RecordingRegistry();
|
||
var secondRegistry = new RecordingRegistry();
|
||
IRichTextEffectRegistry currentRegistry = firstRegistry;
|
||
|
||
var controller = new RichTextEffectsController(
|
||
host,
|
||
() => currentRegistry,
|
||
() => RichTextProfile.CreateBuiltInDefault(),
|
||
() => true,
|
||
() => true);
|
||
|
||
controller.RefreshEffects();
|
||
currentRegistry = secondRegistry;
|
||
controller.RefreshEffects();
|
||
|
||
Assert.That(firstRegistry.CapturedProfiles, Has.Count.EqualTo(1));
|
||
Assert.That(secondRegistry.CapturedProfiles, Has.Count.EqualTo(1));
|
||
}
|
||
|
||
private sealed class FakeRichTextEffectHost : IRichTextEffectHost
|
||
{
|
||
public bool BbcodeEnabled { get; set; }
|
||
|
||
public Array CustomEffects { get; set; } = new();
|
||
}
|
||
|
||
private sealed class RecordingRegistry : IRichTextEffectRegistry
|
||
{
|
||
public List<RichTextProfile> CapturedProfiles { get; } = [];
|
||
|
||
public bool CapturedAnimatedEffectsEnabled { get; private set; }
|
||
|
||
public IReadOnlyList<RichTextEffect> CreateEffects(RichTextProfile profile, bool animatedEffectsEnabled)
|
||
{
|
||
CapturedProfiles.Add(profile);
|
||
CapturedAnimatedEffectsEnabled = animatedEffectsEnabled;
|
||
return System.Array.Empty<RichTextEffect>();
|
||
}
|
||
|
||
public RichTextEffect? CreateEffect(string key, bool animatedEffectsEnabled)
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
}
|