GFramework/GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
gewuyou ff553977e3 chore(license): 补齐 Apache-2.0 文件头治理
- 新增许可证文件头检查与修复脚本

- 补充维护者手动修复 PR 工作流和 CI 校验

- 更新贡献指南中的文件头说明

- 补齐仓库维护源码和配置文件的许可证声明
2026-05-03 19:39:49 +08:00

133 lines
4.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0
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;
}
}
}