using System.Reflection;
using GFramework.Core.Abstractions.enums;
using GFramework.Core.Abstractions.state;
using GFramework.Core.Abstractions.system;
using GFramework.Core.architecture;
using GFramework.Core.command;
using GFramework.Core.environment;
using GFramework.Core.events;
using GFramework.Core.ioc;
using GFramework.Core.logging;
using GFramework.Core.query;
using GFramework.Core.state;
using NUnit.Framework;
namespace GFramework.Core.Tests.state;
///
/// ContextAwareStateMachine类的单元测试
/// 测试内容包括:
/// - 作为ISystem的集成测试
/// - Init方法 - 初始化上下文感知状态
/// - Init方法 - 设置Context属性
/// - Destroy方法 - 清理状态
/// - OnArchitecturePhase方法 - 接收架构阶段
/// - 上下文感知状态初始化
/// - 状态变更事件发送
/// - SetContext方法
/// - GetContext方法
/// - ISystem接口实现验证
/// - 与EventBus的集成测试
/// - 多状态注册和切换
/// - 状态机生命周期完整性
///
[TestFixture]
public class StateMachineSystemTests
{
[SetUp]
public void SetUp()
{
// 初始化 LoggerFactoryResolver 以支持 MicrosoftDiContainer
LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider();
_eventBus = new EventBus();
var container = new MicrosoftDiContainer();
// 直接初始化 logger 字段
var loggerField = typeof(MicrosoftDiContainer).GetField("_logger",
BindingFlags.NonPublic | BindingFlags.Instance);
loggerField?.SetValue(container,
LoggerFactoryResolver.Provider.CreateLogger(nameof(StateMachineSystemTests)));
container.RegisterPlurality(_eventBus);
container.RegisterPlurality(new CommandExecutor());
container.RegisterPlurality(new QueryExecutor());
container.RegisterPlurality(new DefaultEnvironment());
container.RegisterPlurality(new AsyncQueryExecutor());
_context = new ArchitectureContext(container);
_stateMachine = new TestStateMachineSystemV5();
_stateMachine.SetContext(_context);
}
private TestStateMachineSystemV5? _stateMachine;
private ArchitectureContext? _context;
private EventBus? _eventBus;
///
/// 测试ContextAwareStateMachine实现ISystem接口
///
[Test]
public void ContextAwareStateMachine_Should_Implement_ISystem_Interface()
{
Assert.That(_stateMachine, Is.InstanceOf());
}
///
/// 测试SetContext设置Context属性
///
[Test]
public void SetContext_Should_Set_Context_Property()
{
_stateMachine!.SetContext(_context!);
var context = _stateMachine.GetContext();
Assert.That(context, Is.SameAs(_context));
}
///
/// 测试GetContext返回Context属性
///
[Test]
public void GetContext_Should_Return_Context_Property()
{
_stateMachine!.SetContext(_context!);
var context = _stateMachine.GetContext();
Assert.That(context, Is.Not.Null);
Assert.That(context, Is.SameAs(_context));
}
///
/// 测试Init方法为所有ContextAware状态设置Context
///
[Test]
public void Init_Should_SetContext_On_All_ContextAware_States()
{
var state1 = new TestContextAwareStateV5();
var state2 = new TestContextAwareStateV5_2();
_stateMachine!.Register(state1);
_stateMachine.Register(state2);
Assert.That(state1.GetContext(), Is.Null);
Assert.That(state2.GetContext(), Is.Null);
_stateMachine.Init();
Assert.That(state1.GetContext(), Is.SameAs(_context));
Assert.That(state2.GetContext(), Is.SameAs(_context));
}
///
/// 测试Init方法不为非ContextAware状态设置Context
///
[Test]
public void Init_Should_Not_SetContext_On_NonContextAware_States()
{
var state = new TestStateV5();
_stateMachine!.Register(state);
_stateMachine.Init();
}
///
/// 测试Destroy方法不抛出异常
///
[Test]
public void Destroy_Should_Not_Throw_Exception()
{
Assert.That(() => _stateMachine!.Destroy(), Throws.Nothing);
}
///
/// 测试OnArchitecturePhase方法不抛出异常
///
[Test]
public void OnArchitecturePhase_Should_Not_Throw_Exception()
{
Assert.That(() => _stateMachine!.OnArchitecturePhase(ArchitecturePhase.Ready),
Throws.Nothing);
}
///
/// 测试ChangeTo发送StateChangedEvent事件
/// 验证当状态机切换到新状态时,会正确触发StateChangedEvent事件,并且事件中的旧状态为null(首次切换)
///
[Test]
public void ChangeTo_Should_Send_StateChangedEvent()
{
// 订阅StateChangedEvent事件以验证事件是否被正确发送
var eventReceived = false;
StateChangedEvent? receivedEvent = null;
_eventBus!.Register(e =>
{
eventReceived = true;
receivedEvent = e;
});
var state1 = new TestStateV5();
var state2 = new TestStateV5();
_stateMachine!.Register(state1);
_stateMachine.Register(state2);
_stateMachine.Init();
_stateMachine.ChangeTo();
Assert.That(eventReceived, Is.True);
Assert.That(receivedEvent!.OldState, Is.Null);
Assert.That(receivedEvent.NewState, Is.InstanceOf());
}
///
/// 测试ChangeTo发送StateChangedEvent事件(包含旧状态)
/// 验证当状态机从一个状态切换到另一个状态时,会正确触发StateChangedEvent事件,
/// 并且事件中包含正确的旧状态和新状态信息
///
[Test]
public void ChangeTo_Should_Send_StateChangedEvent_With_OldState()
{
// 订阅StateChangedEvent事件以验证事件是否被正确发送
var eventReceived = false;
StateChangedEvent? receivedEvent = null;
_eventBus!.Register(e =>
{
eventReceived = true;
receivedEvent = e;
});
var state1 = new TestStateV5();
var state2 = new TestStateV5();
_stateMachine!.Register(state1);
_stateMachine.Register(state2);
_stateMachine.Init();
_stateMachine.ChangeTo();
_stateMachine.ChangeTo();
Assert.That(eventReceived, Is.True);
Assert.That(receivedEvent!.OldState, Is.InstanceOf());
Assert.That(receivedEvent.NewState, Is.InstanceOf());
}
///
/// 测试CanChangeTo方法对于已注册状态的工作情况
/// 验证当状态已注册到状态机中时,CanChangeTo方法应返回true
///
[Test]
public void CanChangeTo_Should_Work_With_Registered_States()
{
var state = new TestStateV5();
_stateMachine!.Register(state);
var canChange = _stateMachine.CanChangeTo();
Assert.That(canChange, Is.True);
}
///
/// 测试可以注册多个状态
/// 验证状态机能够成功注册多个不同的状态实例,并且能够切换到这些已注册的状态
///
[Test]
public void Multiple_States_Should_Be_Registered()
{
var state1 = new TestStateV5 { Id = 1 };
var state2 = new TestStateV5 { Id = 2 };
var state3 = new TestStateV5 { Id = 3 };
_stateMachine!.Register(state1);
_stateMachine.Register(state2);
_stateMachine.Register(state3);
var canChange = _stateMachine.CanChangeTo();
Assert.That(canChange, Is.True);
}
///
/// 测试状态机生命周期完整
///
[Test]
public void StateMachine_Lifecycle_Should_Be_Complete()
{
var state1 = new TestStateV5();
var state2 = new TestStateV5();
_stateMachine!.Register(state1);
_stateMachine.Register(state2);
_stateMachine.Init();
Assert.That(_stateMachine.Current, Is.Null);
_stateMachine.ChangeTo();
Assert.That(_stateMachine.Current, Is.InstanceOf());
_stateMachine.Destroy();
}
}
#region Test Classes
///
/// 测试用的ContextAwareStateMachine派生类,用于访问内部状态字典
///
public class TestStateMachineSystemV5 : StateMachineSystem
{
///
/// 获取状态机内部的状态字典
///
/// 类型到状态实例的映射字典
public Dictionary GetStates()
{
return States;
}
}
///
/// 测试用的上下文感知状态基类实现
///
public class TestContextAwareStateV5 : ContextAwareStateBase
{
///
/// 进入状态时调用
///
/// 前一个状态
public override void OnEnter(IState? previous)
{
}
///
/// 退出状态时调用
///
/// 下一个状态
public override void OnExit(IState? next)
{
}
}
///
/// 第二个测试用的上下文感知状态基类实现
///
public class TestContextAwareStateV5_2 : ContextAwareStateBase
{
///
/// 进入状态时调用
///
/// 前一个状态
public override void OnEnter(IState? previous)
{
}
///
/// 退出状态时调用
///
/// 下一个状态
public override void OnExit(IState? next)
{
}
}
///
/// 测试用的普通状态实现
///
public class TestStateV5 : IState
{
///
/// 状态标识符
///
public int Id { get; set; }
///
/// 检查是否可以转换到指定状态
///
/// 目标状态
/// 始终返回true表示允许转换
public bool CanTransitionTo(IState next)
{
return true;
}
///
/// 进入状态时调用
///
/// 前一个状态
public void OnEnter(IState? previous)
{
}
///
/// 退出状态时调用
///
/// 下一个状态
public void OnExit(IState? next)
{
}
}
#endregion