mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
test(coroutine): 添加协程组合扩展方法的单元测试
- 创建了 CoroutineComposeExtensionsTests 测试类 - 实现了 Then(Action) 方法的完整测试覆盖 - 实现了 Then(IEnumerator) 方法的完整测试覆盖 - 添加了链式调用功能的测试验证 - 包含边界条件和异常处理的测试用例 - 覆盖了空协程、延迟指令等特殊情况 - 验证了多层嵌套协程的正确执行顺序 - [release ci]
This commit is contained in:
parent
5a056fca84
commit
c7f6b3a9b2
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// CoroutineComposeExtensions的单元测试类
|
||||
/// 测试内容包括:
|
||||
/// - Then(Action) 方法:协程完成后执行动作
|
||||
/// - Then(IEnumerator) 方法:两个协程顺序组合
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class CoroutineComposeExtensionsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建一个简单的测试协程,执行指定次数并记录执行
|
||||
/// </summary>
|
||||
private static IEnumerator<IYieldInstruction> CreateTestCoroutine(int steps, Action? onStep = null)
|
||||
{
|
||||
for (var i = 0; i < steps; i++)
|
||||
{
|
||||
onStep?.Invoke();
|
||||
yield return new WaitOneFrame();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(Action)应该返回有效的协程
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Then_Action_Should_Return_Valid_Coroutine()
|
||||
{
|
||||
var first = CreateTestCoroutine(1);
|
||||
var combined = first.Then(() => { });
|
||||
|
||||
Assert.That(combined, Is.InstanceOf<IEnumerator<IYieldInstruction>>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(Action)应该先执行协程再执行动作
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Then_Action_Should_Execute_Coroutine_Then_Action()
|
||||
{
|
||||
var executionOrder = new List<string>();
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(Action)应该在空协程后立即执行动作
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(Action)应该正确传递yield指令
|
||||
/// </summary>
|
||||
[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<IYieldInstruction>());
|
||||
yieldCount++;
|
||||
}
|
||||
|
||||
Assert.That(yieldCount, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(Action)应该支持链式调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Then_Action_Should_Support_Chaining()
|
||||
{
|
||||
var executionOrder = new List<int>();
|
||||
|
||||
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 }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(Action)动作中的异常应该正常抛出
|
||||
/// </summary>
|
||||
[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<InvalidOperationException>(() => combined.MoveNext());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(IEnumerator)应该返回有效的协程
|
||||
/// </summary>
|
||||
[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<IEnumerator<IYieldInstruction>>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(IEnumerator)应该顺序执行两个协程
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Then_Coroutine_Should_Execute_In_Sequence()
|
||||
{
|
||||
var executionOrder = new List<string>();
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(IEnumerator)应该正确处理空的第一个协程
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(IEnumerator)应该正确处理空的第二个协程
|
||||
/// </summary>
|
||||
[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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(IEnumerator)应该正确处理两个空协程
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(IEnumerator)应该正确传递所有yield指令
|
||||
/// </summary>
|
||||
[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<IYieldInstruction>());
|
||||
yieldCount++;
|
||||
}
|
||||
|
||||
Assert.That(yieldCount, Is.EqualTo(5));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then(IEnumerator)应该支持链式调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Then_Coroutine_Should_Support_Chaining()
|
||||
{
|
||||
var executionOrder = new List<int>();
|
||||
|
||||
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 }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then应该支持混合链式调用(协程和动作)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Then_Should_Support_Mixed_Chaining()
|
||||
{
|
||||
var executionOrder = new List<string>();
|
||||
|
||||
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" }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then应该处理带有延迟指令的协程
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Then_Should_Handle_Delay_Instructions()
|
||||
{
|
||||
var actionExecuted = false;
|
||||
|
||||
IEnumerator<IYieldInstruction> 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<Delay>());
|
||||
|
||||
// 更新延迟指令直到完成
|
||||
var delay = (Delay)combined.Current;
|
||||
delay.Update(0.5);
|
||||
|
||||
// 完成后执行动作
|
||||
Assert.That(combined.MoveNext(), Is.False);
|
||||
Assert.That(actionExecuted, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Then应该正确处理多层嵌套
|
||||
/// </summary>
|
||||
[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));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user