using GFramework.Core.Abstractions.State; using NUnit.Framework; namespace GFramework.Core.Tests.State; /// /// 测试状态模式实现的功能和行为 /// [TestFixture] public class StateTests { /// /// 验证状态类是否正确实现了IState接口 /// [Test] public void State_Should_Implement_IState_Interface() { var state = new ConcreteStateV2(); Assert.That(state is IState); } /// /// 验证进入状态时OnEnter方法被正确调用并记录来源状态 /// [Test] public void OnEnter_Should_BeCalled_When_State_Enters() { var state = new ConcreteStateV2(); var otherState = new ConcreteStateV3(); state.OnEnter(otherState); Assert.That(state.EnterCalled, Is.True); Assert.That(state.EnterFrom, Is.SameAs(otherState)); } /// /// 验证当传入null作为来源状态时的处理情况 /// [Test] public void OnEnter_WithNull_Should_Set_EnterFrom_ToNull() { var state = new ConcreteStateV2(); state.OnEnter(null); Assert.That(state.EnterCalled, Is.True); Assert.That(state.EnterFrom, Is.Null); } /// /// 验证退出状态时OnExit方法被正确调用并记录目标状态 /// [Test] public void OnExit_Should_BeCalled_When_State_Exits() { var state = new ConcreteStateV2(); var otherState = new ConcreteStateV3(); state.OnExit(otherState); Assert.That(state.ExitCalled, Is.True); Assert.That(state.ExitTo, Is.SameAs(otherState)); } /// /// 验证当传入null作为目标状态时的处理情况 /// [Test] public void OnExit_WithNull_Should_Set_ExitTo_ToNull() { var state = new ConcreteStateV2(); state.OnExit(null); Assert.That(state.ExitCalled, Is.True); Assert.That(state.ExitTo, Is.Null); } /// /// 验证允许转换时CanTransitionTo方法返回true /// [Test] public void CanTransitionTo_WithAllowTrue_Should_ReturnTrue() { var state = new ConcreteStateV2 { AllowTransitions = true }; var target = new ConcreteStateV3(); var result = state.CanTransitionTo(target); Assert.That(result, Is.True); } /// /// 验证不允许转换时CanTransitionTo方法返回false /// [Test] public void CanTransitionTo_WithAllowFalse_Should_ReturnFalse() { var state = new ConcreteStateV2 { AllowTransitions = false }; var target = new ConcreteStateV3(); var result = state.CanTransitionTo(target); Assert.That(result, Is.False); } /// /// 验证CanTransitionTo方法正确接收目标状态参数 /// [Test] public void CanTransitionTo_Should_Receive_TargetState() { var state = new ConcreteStateV2 { AllowTransitions = true }; var target = new ConcreteStateV3(); IState? receivedTarget = null; state.CanTransitionToAction = s => receivedTarget = s; state.CanTransitionTo(target); Assert.That(receivedTarget, Is.SameAs(target)); } /// /// 验证具有复杂转换规则的状态类功能 /// [Test] public void State_WithComplexTransitionRules_Should_Work() { var state1 = new ConditionalStateV2 { AllowedTransitions = new[] { typeof(ConcreteStateV3) } }; var state2 = new ConcreteStateV3(); var state3 = new ConcreteStateV4(); Assert.That(state1.CanTransitionTo(state2), Is.True); Assert.That(state1.CanTransitionTo(state3), Is.False); } /// /// 验证多个状态之间的协作功能 /// [Test] public void MultipleStates_Should_WorkTogether() { var state1 = new ConcreteStateV2(); var state2 = new ConcreteStateV3(); var state3 = new ConcreteStateV4(); state1.OnEnter(null); state2.OnEnter(state1); state3.OnEnter(state2); Assert.That(state1.EnterCalled, Is.True); Assert.That(state2.EnterCalled, Is.True); Assert.That(state3.EnterCalled, Is.True); Assert.That(state2.EnterFrom, Is.SameAs(state1)); Assert.That(state3.EnterFrom, Is.SameAs(state2)); } /// /// 验证状态对多次转换的跟踪能力 /// [Test] public void State_Should_Track_MultipleTransitions() { var state = new TrackingStateV2(); var other = new ConcreteStateV3(); state.OnEnter(other); state.OnExit(other); state.OnEnter(other); state.OnExit(null); Assert.That(state.EnterCallCount, Is.EqualTo(2)); Assert.That(state.ExitCallCount, Is.EqualTo(2)); } /// /// 验证相同类型状态间的转换处理 /// [Test] public void State_Should_Handle_SameState_Transition() { var state1 = new ConcreteStateV2(); var state2 = new ConcreteStateV3(); var state3 = new ConcreteStateV2(); state1.OnEnter(null); state2.OnEnter(state1); state3.OnEnter(state2); Assert.That(state1.EnterFrom, Is.Null); Assert.That(state2.EnterFrom, Is.SameAs(state1)); Assert.That(state3.EnterFrom, Is.SameAs(state2)); } /// /// 验证异步状态类是否正确实现了IAsyncState接口 /// [Test] public void AsyncState_Should_Implement_IAsyncState_Interface() { var state = new ConcreteAsyncStateV2(); Assert.That(state is IAsyncState); } /// /// 验证进入异步状态时OnEnterAsync方法被正确调用并记录来源状态 /// [Test] public async Task OnEnterAsync_Should_BeCalled_When_AsyncState_Enters() { var state = new ConcreteAsyncStateV2(); var otherState = new ConcreteStateV3(); await state.OnEnterAsync(otherState); Assert.That(state.EnterCalled, Is.True); Assert.That(state.EnterFrom, Is.SameAs(otherState)); } /// /// 验证当传入null作为来源状态时异步状态的处理情况 /// [Test] public async Task OnEnterAsync_WithNull_Should_Set_EnterFrom_ToNull() { var state = new ConcreteAsyncStateV2(); await state.OnEnterAsync(null); Assert.That(state.EnterCalled, Is.True); Assert.That(state.EnterFrom, Is.Null); } /// /// 验证退出异步状态时OnExitAsync方法被正确调用并记录目标状态 /// [Test] public async Task OnExitAsync_Should_BeCalled_When_AsyncState_Exits() { var state = new ConcreteAsyncStateV2(); var otherState = new ConcreteStateV3(); await state.OnExitAsync(otherState); Assert.That(state.ExitCalled, Is.True); Assert.That(state.ExitTo, Is.SameAs(otherState)); } /// /// 验证当传入null作为目标状态时异步状态的处理情况 /// [Test] public async Task OnExitAsync_WithNull_Should_Set_ExitTo_ToNull() { var state = new ConcreteAsyncStateV2(); await state.OnExitAsync(null); Assert.That(state.ExitCalled, Is.True); Assert.That(state.ExitTo, Is.Null); } /// /// 验证允许转换时CanTransitionToAsync方法返回true /// [Test] public async Task CanTransitionToAsync_WithAllowTrue_Should_ReturnTrue() { var state = new ConcreteAsyncStateV2 { AllowTransitions = true }; var target = new ConcreteStateV3(); var result = await state.CanTransitionToAsync(target); Assert.That(result, Is.True); } /// /// 验证不允许转换时CanTransitionToAsync方法返回false /// [Test] public async Task CanTransitionToAsync_WithAllowFalse_Should_ReturnFalse() { var state = new ConcreteAsyncStateV2 { AllowTransitions = false }; var target = new ConcreteStateV3(); var result = await state.CanTransitionToAsync(target); Assert.That(result, Is.False); } /// /// 验证CanTransitionToAsync方法正确接收目标状态参数 /// [Test] public async Task CanTransitionToAsync_Should_Receive_TargetState() { var state = new ConcreteAsyncStateV2 { AllowTransitions = true }; var target = new ConcreteStateV3(); IState? receivedTarget = null; state.CanTransitionToAsyncAction = s => receivedTarget = s; await state.CanTransitionToAsync(target); Assert.That(receivedTarget, Is.SameAs(target)); } /// /// 验证异步状态对多次转换的跟踪能力 /// [Test] public async Task AsyncState_Should_Track_MultipleTransitions() { var state = new ConcreteAsyncStateV2(); var other = new ConcreteStateV3(); await state.OnEnterAsync(other); await state.OnExitAsync(other); await state.OnEnterAsync(other); await state.OnExitAsync(null); Assert.That(state.EnterCallCount, Is.EqualTo(2)); Assert.That(state.ExitCallCount, Is.EqualTo(2)); } } /// /// 具体状态实现类V2版本,用于测试状态的基本功能 /// public sealed class ConcreteStateV2 : IState { /// /// 获取或设置是否允许转换 /// public bool AllowTransitions { get; set; } = true; /// /// 获取进入状态是否被调用的标志 /// public bool EnterCalled { get; private set; } /// /// 获取退出状态是否被调用的标志 /// public bool ExitCalled { get; private set; } /// /// 获取进入此状态的来源状态 /// public IState? EnterFrom { get; private set; } /// /// 获取从此状态退出的目标状态 /// public IState? ExitTo { get; private set; } /// /// 获取或设置转换到目标状态时执行的动作 /// public Action? CanTransitionToAction { get; set; } /// /// 进入当前状态时调用的方法 /// /// 从哪个状态进入 public void OnEnter(IState? from) { EnterCalled = true; EnterFrom = from; } /// /// 退出当前状态时调用的方法 /// /// 退出到哪个状态 public void OnExit(IState? to) { ExitCalled = true; ExitTo = to; } /// /// 判断是否可以转换到目标状态 /// /// 目标状态 /// 如果可以转换则返回true,否则返回false public bool CanTransitionTo(IState target) { CanTransitionToAction?.Invoke(target); return AllowTransitions; } } /// /// 具体状态实现类V3版本,用于测试状态的基本功能 /// public sealed class ConcreteStateV3 : IState { /// /// 获取进入状态是否被调用的标志 /// public bool EnterCalled { get; private set; } /// /// 获取退出状态是否被调用的标志 /// public bool ExitCalled { get; private set; } /// /// 获取进入此状态的来源状态 /// public IState? EnterFrom { get; private set; } /// /// 获取从此状态退出的目标状态 /// public IState? ExitTo { get; private set; } /// /// 进入当前状态时调用的方法 /// /// 从哪个状态进入 public void OnEnter(IState? from) { EnterCalled = true; EnterFrom = from; } /// /// 退出当前状态时调用的方法 /// /// 退出到哪个状态 public void OnExit(IState? to) { ExitCalled = true; ExitTo = to; } /// /// 判断是否可以转换到目标状态 /// /// 目标状态 /// 如果可以转换则返回true,否则返回false public bool CanTransitionTo(IState target) { return true; } } /// /// 具体状态实现类V4版本,用于测试状态的基本功能 /// public sealed class ConcreteStateV4 : IState { /// /// 获取进入状态是否被调用的标志 /// public bool EnterCalled { get; private set; } /// /// 获取退出状态是否被调用的标志 /// public bool ExitCalled { get; private set; } /// /// 获取进入此状态的来源状态 /// public IState? EnterFrom { get; private set; } /// /// 获取从此状态退出的目标状态 /// public IState? ExitTo { get; private set; } /// /// 进入当前状态时调用的方法 /// /// 从哪个状态进入 public void OnEnter(IState? from) { EnterCalled = true; EnterFrom = from; } /// /// 退出当前状态时调用的方法 /// /// 退出到哪个状态 public void OnExit(IState? to) { ExitCalled = true; ExitTo = to; } /// /// 判断是否可以转换到目标状态 /// /// 目标状态 /// 如果可以转换则返回true,否则返回false public bool CanTransitionTo(IState target) { return true; } } /// /// 条件状态实现类V2版本,支持基于类型的条件转换规则 /// public sealed class ConditionalStateV2 : IState { /// /// 获取或设置允许转换到的状态类型数组 /// public Type[] AllowedTransitions { get; set; } = Array.Empty(); /// /// 获取进入状态是否被调用的标志 /// public bool EnterCalled { get; private set; } /// /// 获取退出状态是否被调用的标志 /// public bool ExitCalled { get; private set; } /// /// 获取进入此状态的来源状态 /// public IState? EnterFrom { get; private set; } /// /// 获取从此状态退出的目标状态 /// public IState? ExitTo { get; private set; } /// /// 进入当前状态时调用的方法 /// /// 从哪个状态进入 public void OnEnter(IState? from) { EnterCalled = true; EnterFrom = from; } /// /// 退出当前状态时调用的方法 /// /// 退出到哪个状态 public void OnExit(IState? to) { ExitCalled = true; ExitTo = to; } /// /// 判断是否可以转换到目标状态 /// /// 目标状态 /// 如果目标状态类型在允许列表中则返回true,否则返回false public bool CanTransitionTo(IState target) { return AllowedTransitions.Contains(target.GetType()); } } /// /// 跟踪状态实现类V2版本,用于跟踪状态转换次数 /// public sealed class TrackingStateV2 : IState { /// /// 获取进入状态被调用的次数 /// public int EnterCallCount { get; private set; } /// /// 获取退出状态被调用的次数 /// public int ExitCallCount { get; private set; } /// /// 获取进入此状态的来源状态 /// public IState? EnterFrom { get; private set; } /// /// 获取从此状态退出的目标状态 /// public IState? ExitTo { get; private set; } /// /// 进入当前状态时调用的方法 /// /// 从哪个状态进入 public void OnEnter(IState? from) { EnterCallCount++; EnterFrom = from; } /// /// 退出当前状态时调用的方法 /// /// 退出到哪个状态 public void OnExit(IState? to) { ExitCallCount++; ExitTo = to; } /// /// 判断是否可以转换到目标状态 /// /// 目标状态 /// 总是返回true public bool CanTransitionTo(IState target) { return true; } } /// /// 异步具体状态实现类V2版本,用于测试异步状态的基本功能 /// public sealed class ConcreteAsyncStateV2 : IState, IAsyncState { /// /// 获取或设置是否允许转换 /// public bool AllowTransitions { get; set; } = true; /// /// 获取进入状态是否被调用的标志 /// public bool EnterCalled { get; private set; } /// /// 获取退出状态是否被调用的标志 /// public bool ExitCalled { get; private set; } /// /// 获取进入状态被调用的次数 /// public int EnterCallCount { get; private set; } /// /// 获取退出状态被调用的次数 /// public int ExitCallCount { get; private set; } /// /// 获取进入此状态的来源状态 /// public IState? EnterFrom { get; private set; } /// /// 获取从此状态退出的目标状态 /// public IState? ExitTo { get; private set; } /// /// 获取或设置转换到目标状态时执行的动作 /// public Action? CanTransitionToAsyncAction { get; set; } /// /// 异步进入当前状态时调用的方法 /// /// 从哪个状态进入 public async Task OnEnterAsync(IState? from) { await Task.Delay(1); EnterCalled = true; EnterCallCount++; EnterFrom = from; } /// /// 异步退出当前状态时调用的方法 /// /// 退出到哪个状态 public async Task OnExitAsync(IState? to) { await Task.Delay(1); ExitCalled = true; ExitCallCount++; ExitTo = to; } /// /// 异步判断是否可以转换到目标状态 /// /// 目标状态 /// 如果可以转换则返回true,否则返回false public async Task CanTransitionToAsync(IState target) { await Task.Delay(1); CanTransitionToAsyncAction?.Invoke(target); return AllowTransitions; } /// /// 进入当前状态时调用的方法(同步版本,抛出异常表示不应被调用) /// /// 从哪个状态进入 public void OnEnter(IState? from) { throw new InvalidOperationException("Sync OnEnter should not be called for async state"); } /// /// 退出当前状态时调用的方法(同步版本,抛出异常表示不应被调用) /// /// 退出到哪个状态 public void OnExit(IState? to) { throw new InvalidOperationException("Sync OnExit should not be called for async state"); } /// /// 判断是否可以转换到目标状态(同步版本,抛出异常表示不应被调用) /// /// 目标状态 /// 如果可以转换则返回true,否则返回false public bool CanTransitionTo(IState target) { throw new InvalidOperationException("Sync CanTransitionTo should not be called for async state"); } }