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 以支持 IocContainer LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider(); _eventBus = new EventBus(); var container = new IocContainer(); // 直接初始化 logger 字段 var loggerField = typeof(IocContainer).GetField("_logger", BindingFlags.NonPublic | BindingFlags.Instance); loggerField?.SetValue(container, LoggerFactoryResolver.Provider.CreateLogger(nameof(StateMachineSystemTests))); container.RegisterPlurality(_eventBus); container.RegisterPlurality(new CommandBus()); container.RegisterPlurality(new QueryBus()); container.RegisterPlurality(new DefaultEnvironment()); container.RegisterPlurality(new AsyncQueryBus()); _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事件以验证事件是否被正确发送 bool 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事件以验证事件是否被正确发送 bool 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() => 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) => true; /// /// 进入状态时调用 /// /// 前一个状态 public void OnEnter(IState? previous) { } /// /// 退出状态时调用 /// /// 下一个状态 public void OnExit(IState? next) { } } #endregion