From c7f6b3a9b2dde291e6bf7a0ff63255519d1da235 Mon Sep 17 00:00:00 2001
From: GeWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Sun, 1 Feb 2026 12:28:20 +0800
Subject: [PATCH] =?UTF-8?q?test(coroutine):=20=E6=B7=BB=E5=8A=A0=E5=8D=8F?=
=?UTF-8?q?=E7=A8=8B=E7=BB=84=E5=90=88=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?=
=?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 创建了 CoroutineComposeExtensionsTests 测试类
- 实现了 Then(Action) 方法的完整测试覆盖
- 实现了 Then(IEnumerator) 方法的完整测试覆盖
- 添加了链式调用功能的测试验证
- 包含边界条件和异常处理的测试用例
- 覆盖了空协程、延迟指令等特殊情况
- 验证了多层嵌套协程的正确执行顺序
- [release ci]
---
.../CoroutineComposeExtensionsTests.cs | 349 ++++++++++++++++++
1 file changed, 349 insertions(+)
create mode 100644 GFramework.Core.Tests/coroutine/CoroutineComposeExtensionsTests.cs
diff --git a/GFramework.Core.Tests/coroutine/CoroutineComposeExtensionsTests.cs b/GFramework.Core.Tests/coroutine/CoroutineComposeExtensionsTests.cs
new file mode 100644
index 0000000..655cc6d
--- /dev/null
+++ b/GFramework.Core.Tests/coroutine/CoroutineComposeExtensionsTests.cs
@@ -0,0 +1,349 @@
+using GFramework.Core.Abstractions.coroutine;
+using GFramework.Core.coroutine.extensions;
+using GFramework.Core.coroutine.instructions;
+using NUnit.Framework;
+
+namespace GFramework.Core.Tests.coroutine;
+
+///
+/// CoroutineComposeExtensions的单元测试类
+/// 测试内容包括:
+/// - Then(Action) 方法:协程完成后执行动作
+/// - Then(IEnumerator) 方法:两个协程顺序组合
+///
+[TestFixture]
+public class CoroutineComposeExtensionsTests
+{
+ ///
+ /// 创建一个简单的测试协程,执行指定次数并记录执行
+ ///
+ private static IEnumerator CreateTestCoroutine(int steps, Action? onStep = null)
+ {
+ for (var i = 0; i < steps; i++)
+ {
+ onStep?.Invoke();
+ yield return new WaitOneFrame();
+ }
+ }
+
+ ///
+ /// 验证Then(Action)应该返回有效的协程
+ ///
+ [Test]
+ public void Then_Action_Should_Return_Valid_Coroutine()
+ {
+ var first = CreateTestCoroutine(1);
+ var combined = first.Then(() => { });
+
+ Assert.That(combined, Is.InstanceOf>());
+ }
+
+ ///
+ /// 验证Then(Action)应该先执行协程再执行动作
+ ///
+ [Test]
+ public void Then_Action_Should_Execute_Coroutine_Then_Action()
+ {
+ var executionOrder = new List();
+
+ var first = CreateTestCoroutine(2, () => executionOrder.Add("coroutine"));
+ var combined = first.Then(() => executionOrder.Add("action"));
+
+ // 执行组合协程
+ while (combined.MoveNext())
+ {
+ combined.Current.Update(0.016);
+ }
+
+ Assert.That(executionOrder.Count, Is.EqualTo(3));
+ Assert.That(executionOrder[0], Is.EqualTo("coroutine"));
+ Assert.That(executionOrder[1], Is.EqualTo("coroutine"));
+ Assert.That(executionOrder[2], Is.EqualTo("action"));
+ }
+
+ ///
+ /// 验证Then(Action)应该在空协程后立即执行动作
+ ///
+ [Test]
+ public void Then_Action_Should_Execute_Action_After_Empty_Coroutine()
+ {
+ var actionExecuted = false;
+
+ var first = CreateTestCoroutine(0);
+ var combined = first.Then(() => actionExecuted = true);
+
+ // 空协程应该立即完成并执行动作
+ var hasMore = combined.MoveNext();
+
+ Assert.That(hasMore, Is.False);
+ Assert.That(actionExecuted, Is.True);
+ }
+
+ ///
+ /// 验证Then(Action)应该正确传递yield指令
+ ///
+ [Test]
+ public void Then_Action_Should_Pass_Through_Yield_Instructions()
+ {
+ var yieldCount = 0;
+
+ var first = CreateTestCoroutine(3);
+ var combined = first.Then(() => { });
+
+ while (combined.MoveNext())
+ {
+ Assert.That(combined.Current, Is.InstanceOf());
+ yieldCount++;
+ }
+
+ Assert.That(yieldCount, Is.EqualTo(3));
+ }
+
+ ///
+ /// 验证Then(Action)应该支持链式调用
+ ///
+ [Test]
+ public void Then_Action_Should_Support_Chaining()
+ {
+ var executionOrder = new List();
+
+ var first = CreateTestCoroutine(1, () => executionOrder.Add(1));
+ var combined = first
+ .Then(() => executionOrder.Add(2))
+ .Then(() => executionOrder.Add(3));
+
+ while (combined.MoveNext())
+ {
+ combined.Current.Update(0.016);
+ }
+
+ Assert.That(executionOrder, Is.EqualTo(new[] { 1, 2, 3 }));
+ }
+
+ ///
+ /// 验证Then(Action)动作中的异常应该正常抛出
+ ///
+ [Test]
+ public void Then_Action_Should_Propagate_Exception_From_Action()
+ {
+ var first = CreateTestCoroutine(1);
+ var combined = first.Then(() => throw new InvalidOperationException("Test exception"));
+
+ // 第一步应该正常执行
+ Assert.That(combined.MoveNext(), Is.True);
+ combined.Current.Update(0.016);
+
+ // 动作执行时应该抛出异常
+ Assert.Throws(() => combined.MoveNext());
+ }
+
+ ///
+ /// 验证Then(IEnumerator)应该返回有效的协程
+ ///
+ [Test]
+ public void Then_Coroutine_Should_Return_Valid_Coroutine()
+ {
+ var first = CreateTestCoroutine(1);
+ var second = CreateTestCoroutine(1);
+ var combined = first.Then(second);
+
+ Assert.That(combined, Is.InstanceOf>());
+ }
+
+ ///
+ /// 验证Then(IEnumerator)应该顺序执行两个协程
+ ///
+ [Test]
+ public void Then_Coroutine_Should_Execute_In_Sequence()
+ {
+ var executionOrder = new List();
+
+ var first = CreateTestCoroutine(2, () => executionOrder.Add("first"));
+ var second = CreateTestCoroutine(2, () => executionOrder.Add("second"));
+ var combined = first.Then(second);
+
+ while (combined.MoveNext())
+ {
+ combined.Current.Update(0.016);
+ }
+
+ Assert.That(executionOrder.Count, Is.EqualTo(4));
+ Assert.That(executionOrder[0], Is.EqualTo("first"));
+ Assert.That(executionOrder[1], Is.EqualTo("first"));
+ Assert.That(executionOrder[2], Is.EqualTo("second"));
+ Assert.That(executionOrder[3], Is.EqualTo("second"));
+ }
+
+ ///
+ /// 验证Then(IEnumerator)应该正确处理空的第一个协程
+ ///
+ [Test]
+ public void Then_Coroutine_Should_Handle_Empty_First_Coroutine()
+ {
+ var secondExecuted = false;
+
+ var first = CreateTestCoroutine(0);
+ var second = CreateTestCoroutine(1, () => secondExecuted = true);
+ var combined = first.Then(second);
+
+ // 应该立即开始执行第二个协程
+ Assert.That(combined.MoveNext(), Is.True);
+ combined.Current.Update(0.016);
+ Assert.That(combined.MoveNext(), Is.False);
+
+ Assert.That(secondExecuted, Is.True);
+ }
+
+ ///
+ /// 验证Then(IEnumerator)应该正确处理空的第二个协程
+ ///
+ [Test]
+ public void Then_Coroutine_Should_Handle_Empty_Second_Coroutine()
+ {
+ var firstExecuteCount = 0;
+
+ var first = CreateTestCoroutine(2, () => firstExecuteCount++);
+ var second = CreateTestCoroutine(0);
+ var combined = first.Then(second);
+
+ while (combined.MoveNext())
+ {
+ combined.Current.Update(0.016);
+ }
+
+ Assert.That(firstExecuteCount, Is.EqualTo(2));
+ }
+
+ ///
+ /// 验证Then(IEnumerator)应该正确处理两个空协程
+ ///
+ [Test]
+ public void Then_Coroutine_Should_Handle_Both_Empty_Coroutines()
+ {
+ var first = CreateTestCoroutine(0);
+ var second = CreateTestCoroutine(0);
+ var combined = first.Then(second);
+
+ Assert.That(combined.MoveNext(), Is.False);
+ }
+
+ ///
+ /// 验证Then(IEnumerator)应该正确传递所有yield指令
+ ///
+ [Test]
+ public void Then_Coroutine_Should_Pass_Through_All_Yield_Instructions()
+ {
+ var yieldCount = 0;
+
+ var first = CreateTestCoroutine(3);
+ var second = CreateTestCoroutine(2);
+ var combined = first.Then(second);
+
+ while (combined.MoveNext())
+ {
+ Assert.That(combined.Current, Is.InstanceOf());
+ yieldCount++;
+ }
+
+ Assert.That(yieldCount, Is.EqualTo(5));
+ }
+
+ ///
+ /// 验证Then(IEnumerator)应该支持链式调用
+ ///
+ [Test]
+ public void Then_Coroutine_Should_Support_Chaining()
+ {
+ var executionOrder = new List();
+
+ var first = CreateTestCoroutine(1, () => executionOrder.Add(1));
+ var second = CreateTestCoroutine(1, () => executionOrder.Add(2));
+ var third = CreateTestCoroutine(1, () => executionOrder.Add(3));
+
+ var combined = first.Then(second).Then(third);
+
+ while (combined.MoveNext())
+ {
+ combined.Current.Update(0.016);
+ }
+
+ Assert.That(executionOrder, Is.EqualTo(new[] { 1, 2, 3 }));
+ }
+
+ ///
+ /// 验证Then应该支持混合链式调用(协程和动作)
+ ///
+ [Test]
+ public void Then_Should_Support_Mixed_Chaining()
+ {
+ var executionOrder = new List();
+
+ var first = CreateTestCoroutine(1, () => executionOrder.Add("coroutine1"));
+ var second = CreateTestCoroutine(1, () => executionOrder.Add("coroutine2"));
+
+ var combined = first
+ .Then(() => executionOrder.Add("action1"))
+ .Then(second)
+ .Then(() => executionOrder.Add("action2"));
+
+ while (combined.MoveNext())
+ {
+ combined.Current.Update(0.016);
+ }
+
+ Assert.That(executionOrder, Is.EqualTo(new[] { "coroutine1", "action1", "coroutine2", "action2" }));
+ }
+
+ ///
+ /// 验证Then应该处理带有延迟指令的协程
+ ///
+ [Test]
+ public void Then_Should_Handle_Delay_Instructions()
+ {
+ var actionExecuted = false;
+
+ IEnumerator DelayCoroutine()
+ {
+ yield return new Delay(0.5);
+ }
+
+ var combined = DelayCoroutine().Then(() => actionExecuted = true);
+
+ // 第一步返回延迟指令
+ Assert.That(combined.MoveNext(), Is.True);
+ Assert.That(combined.Current, Is.InstanceOf());
+
+ // 更新延迟指令直到完成
+ var delay = (Delay)combined.Current;
+ delay.Update(0.5);
+
+ // 完成后执行动作
+ Assert.That(combined.MoveNext(), Is.False);
+ Assert.That(actionExecuted, Is.True);
+ }
+
+ ///
+ /// 验证Then应该正确处理多层嵌套
+ ///
+ [Test]
+ public void Then_Should_Handle_Deep_Nesting()
+ {
+ var count = 0;
+
+ var coroutine = CreateTestCoroutine(1, () => count++);
+
+ // 深度嵌套
+ for (var i = 0; i < 10; i++)
+ {
+ var nextCoroutine = CreateTestCoroutine(1, () => count++);
+ coroutine = coroutine.Then(nextCoroutine);
+ }
+
+ while (coroutine.MoveNext())
+ {
+ coroutine.Current.Update(0.016);
+ }
+
+ Assert.That(count, Is.EqualTo(11));
+ }
+}
\ No newline at end of file