From 70e16724c936be35da778e8a1fd9e15c294ef50e Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Fri, 16 Jan 2026 12:35:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(test):=20=E5=AE=8C=E6=88=90ContextAwareSta?= =?UTF-8?q?teMachine=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E8=A6=86?= =?UTF-8?q?=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建了ContextAwareStateMachineTests.cs,包含12个测试用例 - 覆盖了状态机的集成测试、上下文感知功能、状态变更事件等核心功能 - 测试了Init方法的上下文初始化、状态变更事件发送、多状态注册等功能 - 更新测试覆盖率从~45%提升至~47%,总测试数从286个增加到298个 - 完成第一批所有5个核心 --- GFramework.Core.Tests/TEST_COVERAGE_PLAN.md | 28 +- .../state/ContextAwareStateMachineTests.cs | 245 ++++++++++++++++++ 2 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 GFramework.Core.Tests/state/ContextAwareStateMachineTests.cs diff --git a/GFramework.Core.Tests/TEST_COVERAGE_PLAN.md b/GFramework.Core.Tests/TEST_COVERAGE_PLAN.md index d7803ed..159bc0d 100644 --- a/GFramework.Core.Tests/TEST_COVERAGE_PLAN.md +++ b/GFramework.Core.Tests/TEST_COVERAGE_PLAN.md @@ -2,7 +2,7 @@ > **生成日期**: 2026-01-16 > **最后更新**: 2026-01-16 -> **当前版本**: Core测试覆盖率 ~45% +> **当前版本**: Core测试覆盖率 ~47% > **目标**: 提升Core模块测试覆盖率至 85%+ --- @@ -247,8 +247,6 @@ **源文件路径**: `GFramework.Core/state/ContextAwareStateMachine.cs` -**注意**: 此文件已创建但被删除,需要重新创建 - **需要测试的内容**: - ✅ 作为 ISystem 的集成测试 - ✅ Init 方法 - 初始化上下文感知状态 @@ -266,11 +264,13 @@ **预计测试数**: 12-15 个 +**实际测试数**: 12 个 + **优先级**: 🔴 高 **创建路径**: `GFramework.Core.Tests/state/ContextAwareStateMachineTests.cs` -**状态**: ⚠️ 需要重新创建 +**状态**: ✅ 已创建 --- @@ -762,10 +762,10 @@ ## 🎯 目标达成路径 ### 当前状态 -- **现有测试数**: 286 个 -- **测试覆盖率**: ~45% -- **缺失测试**: 122-178 个 -- **已完成文件**: 4/26 (ArchitectureConfigurationTests.cs, ArchitectureContextTests.cs, ArchitectureServicesTests.cs, ArchitectureEventsTests.cs) +- **现有测试数**: 298 个 +- **测试覆盖率**: ~47% +- **缺失测试**: 110-166 个 +- **已完成文件**: 5/26 (第一批全部完成) ### 第一批完成 1/5 - **当前测试数**: 240 个 @@ -783,9 +783,14 @@ - **当前测试数**: 286 个 - **当前覆盖率**: ~45% -### 第一批完成后 -- **预计测试数**: 228 + 53-67 = 281-295 个 -- **预计覆盖率**: ~50-55% +### 第一批完成 5/5 ✅ +- **当前测试数**: 298 个 +- **当前覆盖率**: ~47% +- **第一批总计**: 70 个测试(预计 53-67 个) + +### 第二批预计完成后 +- **预计测试数**: 298 + 46-57 = 344-355 个 +- **预计覆盖率**: ~55-60% ### 第二批完成后 - **预计测试数**: 281-295 + 46-57 = 327-352 个 @@ -840,6 +845,7 @@ | 2026-01-16 | 完成 ArchitectureContextTests.cs | 创建了22个测试用例,涵盖构造函数、命令/查询/事件发送、组件获取等功能 | | 2026-01-16 | 完成 ArchitectureServicesTests.cs | 创建了15个测试用例,涵盖服务初始化、上下文管理、服务独立性等功能 | | 2026-01-16 | 完成 ArchitectureEventsTests.cs | 创建了9个测试用例,涵盖生命周期事件、事件订阅、事件顺序等功能 | +| 2026-01-16 | 完成 ContextAwareStateMachineTests.cs | 创建了12个测试用例,涵盖状态机集成、上下文感知、状态变更事件等功能 | | | | | --- diff --git a/GFramework.Core.Tests/state/ContextAwareStateMachineTests.cs b/GFramework.Core.Tests/state/ContextAwareStateMachineTests.cs new file mode 100644 index 0000000..4a0acba --- /dev/null +++ b/GFramework.Core.Tests/state/ContextAwareStateMachineTests.cs @@ -0,0 +1,245 @@ +using GFramework.Core.Abstractions.architecture; +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.query; +using GFramework.Core.state; +using NUnit.Framework; + +namespace GFramework.Core.Tests.state; + +[TestFixture] +public class ContextAwareStateMachineTests +{ + private TestContextAwareStateMachineV5? _stateMachine; + private ArchitectureContext? _context; + private EventBus? _eventBus; + + [SetUp] + public void SetUp() + { + _eventBus = new EventBus(); + _context = new ArchitectureContext( + new IocContainer(), + _eventBus, + new CommandBus(), + new QueryBus(), + new DefaultEnvironment()); + + _stateMachine = new TestContextAwareStateMachineV5(); + _stateMachine.SetContext(_context); + } + + [Test] + public void ContextAwareStateMachine_Should_Implement_ISystem_Interface() + { + Assert.That(_stateMachine, Is.InstanceOf()); + } + + [Test] + public void SetContext_Should_Set_Context_Property() + { + _stateMachine!.SetContext(_context!); + + var context = _stateMachine.GetContext(); + Assert.That(context, Is.SameAs(_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)); + } + + [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)); + } + + [Test] + public void Init_Should_Not_SetContext_On_NonContextAware_States() + { + var state = new TestStateV5(); + + _stateMachine!.Register(state); + _stateMachine.Init(); + } + + [Test] + public void Destroy_Should_Not_Throw_Exception() + { + Assert.That(() => _stateMachine!.Destroy(), Throws.Nothing); + } + + [Test] + public void OnArchitecturePhase_Should_Not_Throw_Exception() + { + Assert.That(() => _stateMachine!.OnArchitecturePhase(ArchitecturePhase.Ready), + Throws.Nothing); + } + + [Test] + public void ChangeTo_Should_Send_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()); + } + + [Test] + public void ChangeTo_Should_Send_StateChangedEvent_With_OldState() + { + 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()); + } + + [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 + +public class TestContextAwareStateMachineV5 : ContextAwareStateMachine +{ + 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; } + + public bool CanTransitionTo(IState next) => true; + + public void OnEnter(IState? previous) + { + } + + public void OnExit(IState? next) + { + } +} + +#endregion