From f0a36de07ce39757d0a237e33903ba9946c547c7 Mon Sep 17 00:00:00 2001 From: gewuyou <95328647+GeWuYou@users.noreply.github.com> Date: Mon, 27 Apr 2026 19:44:07 +0800 Subject: [PATCH] =?UTF-8?q?test(core-tests):=20=E6=89=B9=E9=87=8F=E6=8B=86?= =?UTF-8?q?=E5=88=86=E6=B5=8B=E8=AF=95=E8=BE=85=E5=8A=A9=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E4=BB=A5=E6=B6=88=E5=87=8F=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 拆分 GFramework.Core.Tests 中多组测试辅助类型到独立文件以消减 MA0048 warning - 更新 analyzer-warning-reduction 的 tracking 与 trace 以记录批处理基线和下一恢复点 - 验证 GFramework.Core.Tests Release 构建清零并将仓库根权威 warning 基线压降到 288 --- .../AdditionalAssemblyNotification.cs | 8 + ...onalAssemblyNotificationHandlerRegistry.cs | 46 ++ ...itionalAssemblyNotificationHandlerState.cs | 33 ++ ...ArchitectureAdditionalCqrsHandlersTests.cs | 85 ---- .../Architectures/ArchitectureContextTests.cs | 148 ------- .../ArchitectureModulesBehaviorTests.cs | 54 --- .../Architectures/ModuleBehaviorRequest.cs | 10 + .../ModuleBehaviorRequestHandler.cs | 20 + .../Architectures/TestCommandV2.cs | 43 ++ .../Architectures/TestCommandWithResultV2.cs | 44 ++ .../Architectures/TestEventV2.cs | 12 + .../Architectures/TestModelV2.cs | 58 +++ .../Architectures/TestQueryV2.cs | 44 ++ .../Architectures/TestSystemV2.cs | 58 +++ .../Architectures/TestUtilityV2.cs | 35 ++ .../Architectures/TrackingPipelineBehavior.cs | 33 ++ .../Command/AbstractAsyncCommandTests.cs | 168 -------- .../Command/CommandExecutorTests.cs | 142 ------ .../Command/TestAsyncCommand.cs | 39 ++ .../Command/TestAsyncCommandChildV3.cs | 39 ++ .../Command/TestAsyncCommandV3.cs | 39 ++ .../TestAsyncCommandWithExceptionV3.cs | 28 ++ .../Command/TestAsyncCommandWithResult.cs | 33 ++ .../TestAsyncCommandWithResultChildV3.cs | 33 ++ .../Command/TestAsyncCommandWithResultV3.cs | 33 ++ GFramework.Core.Tests/Command/TestCommand.cs | 37 ++ .../Command/TestCommandInput.cs | 14 + .../Command/TestCommandInputV2.cs | 14 + .../Command/TestCommandWithResult.cs | 33 ++ .../Extensions/ObjectExtensionsTests.cs | 16 - GFramework.Core.Tests/Extensions/TestClass.cs | 17 + .../Query/AsyncQueryExecutorTests.cs | 157 ------- .../Query/QueryExecutorTests.cs | 63 --- .../Query/TestAsyncBooleanQuery.cs | 27 ++ .../Query/TestAsyncComplexQuery.cs | 33 ++ GFramework.Core.Tests/Query/TestAsyncQuery.cs | 27 ++ .../Query/TestAsyncQueryInput.cs | 14 + .../Query/TestAsyncQueryResult.cs | 17 + .../Query/TestAsyncQueryWithException.cs | 28 ++ .../Query/TestAsyncStringQuery.cs | 27 ++ GFramework.Core.Tests/Query/TestQuery.cs | 27 ++ GFramework.Core.Tests/Query/TestQueryInput.cs | 14 + .../Query/TestStringQuery.cs | 27 ++ .../Rule/ContextAwareTests.cs | 26 -- .../Rule/TestContextAware.cs | 28 ++ .../State/ConcreteAsyncStateV2.cs | 116 +++++ .../State/ConcreteStateV2.cs | 70 +++ .../State/ConcreteStateV3.cs | 59 +++ .../State/ConcreteStateV4.cs | 59 +++ .../State/ConditionalStateV2.cs | 64 +++ .../State/StateMachineSystemTests.cs | 138 ------ GFramework.Core.Tests/State/StateTests.cs | 406 ------------------ .../State/TestContextAwareStateV5.cs | 26 ++ .../State/TestContextAwareStateV5_2.cs | 26 ++ .../State/TestStateMachineSystemV5.cs | 21 + GFramework.Core.Tests/State/TestStateV5.cs | 40 ++ GFramework.Core.Tests/State/TestStateV5_2.cs | 40 ++ .../State/TrackingStateV2.cs | 59 +++ .../Utility/AbstractContextUtilityTests.cs | 85 ---- .../Utility/TestContextUtilityV1.cs | 51 +++ .../Utility/TestContextUtilityV2.cs | 41 ++ .../analyzer-warning-reduction-tracking.md | 37 +- .../analyzer-warning-reduction-trace.md | 44 ++ 63 files changed, 1811 insertions(+), 1502 deletions(-) create mode 100644 GFramework.Core.Tests/Architectures/AdditionalAssemblyNotification.cs create mode 100644 GFramework.Core.Tests/Architectures/AdditionalAssemblyNotificationHandlerRegistry.cs create mode 100644 GFramework.Core.Tests/Architectures/AdditionalAssemblyNotificationHandlerState.cs create mode 100644 GFramework.Core.Tests/Architectures/ModuleBehaviorRequest.cs create mode 100644 GFramework.Core.Tests/Architectures/ModuleBehaviorRequestHandler.cs create mode 100644 GFramework.Core.Tests/Architectures/TestCommandV2.cs create mode 100644 GFramework.Core.Tests/Architectures/TestCommandWithResultV2.cs create mode 100644 GFramework.Core.Tests/Architectures/TestEventV2.cs create mode 100644 GFramework.Core.Tests/Architectures/TestModelV2.cs create mode 100644 GFramework.Core.Tests/Architectures/TestQueryV2.cs create mode 100644 GFramework.Core.Tests/Architectures/TestSystemV2.cs create mode 100644 GFramework.Core.Tests/Architectures/TestUtilityV2.cs create mode 100644 GFramework.Core.Tests/Architectures/TrackingPipelineBehavior.cs create mode 100644 GFramework.Core.Tests/Command/TestAsyncCommand.cs create mode 100644 GFramework.Core.Tests/Command/TestAsyncCommandChildV3.cs create mode 100644 GFramework.Core.Tests/Command/TestAsyncCommandV3.cs create mode 100644 GFramework.Core.Tests/Command/TestAsyncCommandWithExceptionV3.cs create mode 100644 GFramework.Core.Tests/Command/TestAsyncCommandWithResult.cs create mode 100644 GFramework.Core.Tests/Command/TestAsyncCommandWithResultChildV3.cs create mode 100644 GFramework.Core.Tests/Command/TestAsyncCommandWithResultV3.cs create mode 100644 GFramework.Core.Tests/Command/TestCommand.cs create mode 100644 GFramework.Core.Tests/Command/TestCommandInput.cs create mode 100644 GFramework.Core.Tests/Command/TestCommandInputV2.cs create mode 100644 GFramework.Core.Tests/Command/TestCommandWithResult.cs create mode 100644 GFramework.Core.Tests/Extensions/TestClass.cs create mode 100644 GFramework.Core.Tests/Query/TestAsyncBooleanQuery.cs create mode 100644 GFramework.Core.Tests/Query/TestAsyncComplexQuery.cs create mode 100644 GFramework.Core.Tests/Query/TestAsyncQuery.cs create mode 100644 GFramework.Core.Tests/Query/TestAsyncQueryInput.cs create mode 100644 GFramework.Core.Tests/Query/TestAsyncQueryResult.cs create mode 100644 GFramework.Core.Tests/Query/TestAsyncQueryWithException.cs create mode 100644 GFramework.Core.Tests/Query/TestAsyncStringQuery.cs create mode 100644 GFramework.Core.Tests/Query/TestQuery.cs create mode 100644 GFramework.Core.Tests/Query/TestQueryInput.cs create mode 100644 GFramework.Core.Tests/Query/TestStringQuery.cs create mode 100644 GFramework.Core.Tests/Rule/TestContextAware.cs create mode 100644 GFramework.Core.Tests/State/ConcreteAsyncStateV2.cs create mode 100644 GFramework.Core.Tests/State/ConcreteStateV2.cs create mode 100644 GFramework.Core.Tests/State/ConcreteStateV3.cs create mode 100644 GFramework.Core.Tests/State/ConcreteStateV4.cs create mode 100644 GFramework.Core.Tests/State/ConditionalStateV2.cs create mode 100644 GFramework.Core.Tests/State/TestContextAwareStateV5.cs create mode 100644 GFramework.Core.Tests/State/TestContextAwareStateV5_2.cs create mode 100644 GFramework.Core.Tests/State/TestStateMachineSystemV5.cs create mode 100644 GFramework.Core.Tests/State/TestStateV5.cs create mode 100644 GFramework.Core.Tests/State/TestStateV5_2.cs create mode 100644 GFramework.Core.Tests/State/TrackingStateV2.cs create mode 100644 GFramework.Core.Tests/Utility/TestContextUtilityV1.cs create mode 100644 GFramework.Core.Tests/Utility/TestContextUtilityV2.cs diff --git a/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotification.cs b/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotification.cs new file mode 100644 index 00000000..c9d8b478 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotification.cs @@ -0,0 +1,8 @@ +using GFramework.Cqrs.Abstractions.Cqrs; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 用于验证额外程序集接入是否成功的测试通知。 +/// +public sealed record AdditionalAssemblyNotification : INotification; diff --git a/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotificationHandlerRegistry.cs b/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotificationHandlerRegistry.cs new file mode 100644 index 00000000..de430148 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotificationHandlerRegistry.cs @@ -0,0 +1,46 @@ +using GFramework.Core.Abstractions.Logging; +using GFramework.Cqrs; +using GFramework.Cqrs.Abstractions.Cqrs; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 模拟由 source-generator 为扩展程序集生成的 CQRS handler registry。 +/// +internal sealed class AdditionalAssemblyNotificationHandlerRegistry : ICqrsHandlerRegistry +{ + /// + /// 将扩展程序集中的通知处理器映射写入服务集合。 + /// + /// 目标服务集合。 + /// 日志记录器。 + /// + /// 当 时抛出。 + /// + public void Register(IServiceCollection services, ILogger logger) + { + ArgumentNullException.ThrowIfNull(services); + ArgumentNullException.ThrowIfNull(logger); + + services.AddTransient>(_ => CreateHandler()); + logger.Debug( + $"Registered CQRS handler proxy for {typeof(INotificationHandler).FullName}."); + } + + /// + /// 创建一个仅供显式程序集注册路径使用的动态通知处理器。 + /// + /// 用于记录通知触发次数的测试替身处理器。 + private static INotificationHandler CreateHandler() + { + var handler = new Mock>(); + handler + .Setup(target => target.Handle(It.IsAny(), It.IsAny())) + .Returns(() => + { + AdditionalAssemblyNotificationHandlerState.RecordInvocation(); + return ValueTask.CompletedTask; + }); + return handler.Object; + } +} diff --git a/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotificationHandlerState.cs b/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotificationHandlerState.cs new file mode 100644 index 00000000..4718a77f --- /dev/null +++ b/GFramework.Core.Tests/Architectures/AdditionalAssemblyNotificationHandlerState.cs @@ -0,0 +1,33 @@ +namespace GFramework.Core.Tests.Architectures; + +/// +/// 记录模拟扩展程序集通知处理器的执行次数。 +/// +public static class AdditionalAssemblyNotificationHandlerState +{ + private static int _invocationCount; + + /// + /// 获取当前测试进程中该处理器的执行次数。 + /// + /// + /// 该计数器通过原子读写维护,以支持 NUnit 并行执行环境中的并发访问。 + /// + public static int InvocationCount => Volatile.Read(ref _invocationCount); + + /// + /// 记录一次通知处理,供测试断言显式程序集接入后的运行时行为。 + /// + public static void RecordInvocation() + { + Interlocked.Increment(ref _invocationCount); + } + + /// + /// 清理共享计数器,避免测试间相互污染。 + /// + public static void Reset() + { + Interlocked.Exchange(ref _invocationCount, 0); + } +} diff --git a/GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs b/GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs index f191863d..fe2e50a5 100644 --- a/GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs +++ b/GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs @@ -121,88 +121,3 @@ public sealed class ArchitectureAdditionalCqrsHandlersTests return architecture; } } - -/// -/// 用于验证额外程序集接入是否成功的测试通知。 -/// -public sealed record AdditionalAssemblyNotification : INotification; - -/// -/// 记录模拟扩展程序集通知处理器的执行次数。 -/// -public static class AdditionalAssemblyNotificationHandlerState -{ - private static int _invocationCount; - - /// - /// 获取当前测试进程中该处理器的执行次数。 - /// - /// - /// 该计数器通过原子读写维护,以支持 NUnit 并行执行环境中的并发访问。 - /// - public static int InvocationCount => Volatile.Read(ref _invocationCount); - - /// - /// 记录一次通知处理,供测试断言显式程序集接入后的运行时行为。 - /// - public static void RecordInvocation() - { - Interlocked.Increment(ref _invocationCount); - } - - /// - /// 清理共享计数器,避免测试间相互污染。 - /// - public static void Reset() - { - Interlocked.Exchange(ref _invocationCount, 0); - } -} - -/// -/// 模拟由 source-generator 为扩展程序集生成的 CQRS handler registry。 -/// -internal sealed class AdditionalAssemblyNotificationHandlerRegistry : ICqrsHandlerRegistry -{ - /// - /// 将扩展程序集中的通知处理器映射写入服务集合。 - /// - /// 目标服务集合。 - /// 日志记录器。 - /// - /// 当 时抛出。 - /// - public void Register(IServiceCollection services, ILogger logger) - { - if (services is null) - { - throw new ArgumentNullException(nameof(services)); - } - - if (logger is null) - { - throw new ArgumentNullException(nameof(logger)); - } - - services.AddTransient>(_ => CreateHandler()); - logger.Debug( - $"Registered CQRS handler proxy for {typeof(INotificationHandler).FullName}."); - } - - /// - /// 创建一个仅供显式程序集注册路径使用的动态通知处理器。 - /// - /// 用于记录通知触发次数的测试替身处理器。 - private static INotificationHandler CreateHandler() - { - var handler = new Mock>(); - handler - .Setup(target => target.Handle(It.IsAny(), It.IsAny())) - .Returns(() => - { - AdditionalAssemblyNotificationHandlerState.RecordInvocation(); - return ValueTask.CompletedTask; - }); - return handler.Object; - } -} diff --git a/GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs b/GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs index 685655a5..e0f204c7 100644 --- a/GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs +++ b/GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs @@ -1,14 +1,10 @@ using System.Reflection; using GFramework.Core.Abstractions.Architectures; using GFramework.Core.Abstractions.Command; -using GFramework.Core.Abstractions.Enums; using GFramework.Core.Abstractions.Environment; using GFramework.Core.Abstractions.Ioc; using GFramework.Core.Abstractions.Logging; -using GFramework.Core.Abstractions.Model; using GFramework.Core.Abstractions.Query; -using GFramework.Core.Abstractions.Systems; -using GFramework.Core.Abstractions.Utility; using GFramework.Core.Architectures; using GFramework.Core.Command; using GFramework.Core.Environment; @@ -373,147 +369,3 @@ public class ArchitectureContextTests { } } - -#region Test Classes - -public class TestSystemV2 : ISystem -{ - private IArchitectureContext _context = null!; - public int Id { get; init; } - - public void SetContext(IArchitectureContext context) - { - _context = context; - } - - public IArchitectureContext GetContext() - { - return _context; - } - - public void Initialize() - { - } - - public void Destroy() - { - } - - public void OnArchitecturePhase(ArchitecturePhase phase) - { - } -} - -public class TestModelV2 : IModel -{ - private IArchitectureContext _context = null!; - public int Id { get; init; } - - public void SetContext(IArchitectureContext context) - { - _context = context; - } - - public IArchitectureContext GetContext() - { - return _context; - } - - public void Initialize() - { - } - - public void OnArchitecturePhase(ArchitecturePhase phase) - { - } - - public void Destroy() - { - } -} - -public class TestUtilityV2 : IUtility -{ - private IArchitectureContext _context = null!; - public int Id { get; init; } - - public void SetContext(IArchitectureContext context) - { - _context = context; - } - - public IArchitectureContext GetContext() - { - return _context; - } -} - -public class TestQueryV2 : IQuery -{ - private IArchitectureContext _context = null!; - public int Result { get; init; } - - public int Do() - { - return Result; - } - - public void SetContext(IArchitectureContext context) - { - _context = context; - } - - public IArchitectureContext GetContext() - { - return _context; - } -} - -public class TestCommandV2 : ICommand -{ - private IArchitectureContext _context = null!; - public bool Executed { get; private set; } - - public void Execute() - { - Executed = true; - } - - public void SetContext(IArchitectureContext context) - { - _context = context; - } - - public IArchitectureContext GetContext() - { - return _context; - } -} - -public class TestCommandWithResultV2 : ICommand -{ - private IArchitectureContext _context = null!; - public int Result { get; init; } - - public int Execute() - { - return Result; - } - - public void SetContext(IArchitectureContext context) - { - _context = context; - } - - public IArchitectureContext GetContext() - { - return _context; - } -} - -public class TestEventV2 -{ - public int Data { get; init; } -} - -#endregion diff --git a/GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs b/GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs index dff3af2c..a879804c 100644 --- a/GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs +++ b/GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs @@ -3,7 +3,6 @@ using GFramework.Core.Abstractions.Logging; using GFramework.Core.Abstractions.Utility; using GFramework.Core.Architectures; using GFramework.Core.Logging; -using GFramework.Cqrs.Abstractions.Cqrs; namespace GFramework.Core.Tests.Architectures; @@ -126,56 +125,3 @@ public class ArchitectureModulesBehaviorTests { } } - -/// -/// 用于验证管道行为注册是否生效的测试请求。 -/// -public sealed class ModuleBehaviorRequest : IRequest -{ -} - -/// -/// 处理测试请求的处理器。 -/// -public sealed class ModuleBehaviorRequestHandler : IRequestHandler -{ - /// - /// 返回固定结果,便于聚焦验证管道行为是否执行。 - /// - /// 请求实例。 - /// 取消令牌。 - /// 固定响应内容。 - public ValueTask Handle(ModuleBehaviorRequest request, CancellationToken cancellationToken) - { - return ValueTask.FromResult("handled"); - } -} - -/// -/// 记录请求通过管道次数的测试行为。 -/// -/// 请求类型。 -/// 响应类型。 -public sealed class TrackingPipelineBehavior : IPipelineBehavior - where TRequest : IRequest -{ - /// - /// 获取当前测试进程中该请求类型对应的行为触发次数。 - /// - public static int InvocationCount { get; set; } - - /// - /// 记录一次行为执行,然后继续执行下一个处理器。 - /// - /// 当前请求消息。 - /// 下一个处理委托。 - /// 取消令牌。 - /// 下游处理器的响应结果。 - public async ValueTask Handle( - TRequest message, MessageHandlerDelegate next, - CancellationToken cancellationToken) - { - InvocationCount++; - return await next(message, cancellationToken).ConfigureAwait(false); - } -} diff --git a/GFramework.Core.Tests/Architectures/ModuleBehaviorRequest.cs b/GFramework.Core.Tests/Architectures/ModuleBehaviorRequest.cs new file mode 100644 index 00000000..4d405b10 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/ModuleBehaviorRequest.cs @@ -0,0 +1,10 @@ +using GFramework.Cqrs.Abstractions.Cqrs; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 用于验证管道行为注册是否生效的测试请求。 +/// +public sealed class ModuleBehaviorRequest : IRequest +{ +} diff --git a/GFramework.Core.Tests/Architectures/ModuleBehaviorRequestHandler.cs b/GFramework.Core.Tests/Architectures/ModuleBehaviorRequestHandler.cs new file mode 100644 index 00000000..8bbf0f17 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/ModuleBehaviorRequestHandler.cs @@ -0,0 +1,20 @@ +using GFramework.Cqrs.Abstractions.Cqrs; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 处理测试请求的处理器。 +/// +public sealed class ModuleBehaviorRequestHandler : IRequestHandler +{ + /// + /// 返回固定结果,便于聚焦验证管道行为是否执行。 + /// + /// 请求实例。 + /// 取消令牌。 + /// 固定响应内容。 + public ValueTask Handle(ModuleBehaviorRequest request, CancellationToken cancellationToken) + { + return ValueTask.FromResult("handled"); + } +} diff --git a/GFramework.Core.Tests/Architectures/TestCommandV2.cs b/GFramework.Core.Tests/Architectures/TestCommandV2.cs new file mode 100644 index 00000000..d430cff1 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/TestCommandV2.cs @@ -0,0 +1,43 @@ +using GFramework.Core.Abstractions.Architectures; +using GFramework.Core.Abstractions.Command; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 为 提供的测试命令桩。 +/// +public sealed class TestCommandV2 : ICommand +{ + private IArchitectureContext _context = null!; + + /// + /// 获取命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 执行测试命令,并记录执行状态。 + /// + public void Execute() + { + Executed = true; + } + + /// + /// 关联当前命令所属的架构上下文。 + /// + /// 要保存的架构上下文。 + public void SetContext(IArchitectureContext context) + { + _context = context; + } + + /// + /// 获取当前命令已绑定的架构上下文。 + /// + /// 测试期间保存的架构上下文。 + public IArchitectureContext GetContext() + { + return _context; + } +} diff --git a/GFramework.Core.Tests/Architectures/TestCommandWithResultV2.cs b/GFramework.Core.Tests/Architectures/TestCommandWithResultV2.cs new file mode 100644 index 00000000..8e04fc34 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/TestCommandWithResultV2.cs @@ -0,0 +1,44 @@ +using GFramework.Core.Abstractions.Architectures; +using GFramework.Core.Abstractions.Command; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 为 提供的带返回值测试命令桩。 +/// +public sealed class TestCommandWithResultV2 : ICommand +{ + private IArchitectureContext _context = null!; + + /// + /// 获取或设置命令执行结果。 + /// + public int Result { get; init; } + + /// + /// 执行测试命令并返回预设结果。 + /// + /// 测试预设的命令结果。 + public int Execute() + { + return Result; + } + + /// + /// 关联当前命令所属的架构上下文。 + /// + /// 要保存的架构上下文。 + public void SetContext(IArchitectureContext context) + { + _context = context; + } + + /// + /// 获取当前命令已绑定的架构上下文。 + /// + /// 测试期间保存的架构上下文。 + public IArchitectureContext GetContext() + { + return _context; + } +} diff --git a/GFramework.Core.Tests/Architectures/TestEventV2.cs b/GFramework.Core.Tests/Architectures/TestEventV2.cs new file mode 100644 index 00000000..38faf9b1 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/TestEventV2.cs @@ -0,0 +1,12 @@ +namespace GFramework.Core.Tests.Architectures; + +/// +/// 为 提供的测试事件载荷。 +/// +public sealed class TestEventV2 +{ + /// + /// 获取或设置测试事件数据。 + /// + public int Data { get; init; } +} diff --git a/GFramework.Core.Tests/Architectures/TestModelV2.cs b/GFramework.Core.Tests/Architectures/TestModelV2.cs new file mode 100644 index 00000000..bc636a6d --- /dev/null +++ b/GFramework.Core.Tests/Architectures/TestModelV2.cs @@ -0,0 +1,58 @@ +using GFramework.Core.Abstractions.Architectures; +using GFramework.Core.Abstractions.Enums; +using GFramework.Core.Abstractions.Model; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 为 提供的测试模型桩。 +/// +public sealed class TestModelV2 : IModel +{ + private IArchitectureContext _context = null!; + + /// + /// 获取或设置测试用标识。 + /// + public int Id { get; init; } + + /// + /// 关联当前模型所属的架构上下文。 + /// + /// 要保存的架构上下文。 + public void SetContext(IArchitectureContext context) + { + _context = context; + } + + /// + /// 获取当前模型已绑定的架构上下文。 + /// + /// 测试期间保存的架构上下文。 + public IArchitectureContext GetContext() + { + return _context; + } + + /// + /// 初始化测试模型。 + /// + public void Initialize() + { + } + + /// + /// 接收架构阶段切换通知。 + /// + /// 当前架构阶段。 + public void OnArchitecturePhase(ArchitecturePhase phase) + { + } + + /// + /// 销毁测试模型。 + /// + public void Destroy() + { + } +} diff --git a/GFramework.Core.Tests/Architectures/TestQueryV2.cs b/GFramework.Core.Tests/Architectures/TestQueryV2.cs new file mode 100644 index 00000000..59e6020c --- /dev/null +++ b/GFramework.Core.Tests/Architectures/TestQueryV2.cs @@ -0,0 +1,44 @@ +using GFramework.Core.Abstractions.Architectures; +using GFramework.Core.Abstractions.Query; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 为 提供的测试查询桩。 +/// +public sealed class TestQueryV2 : IQuery +{ + private IArchitectureContext _context = null!; + + /// + /// 获取或设置查询返回值。 + /// + public int Result { get; init; } + + /// + /// 执行查询并返回预设结果。 + /// + /// 测试预设的查询结果。 + public int Do() + { + return Result; + } + + /// + /// 关联当前查询所属的架构上下文。 + /// + /// 要保存的架构上下文。 + public void SetContext(IArchitectureContext context) + { + _context = context; + } + + /// + /// 获取当前查询已绑定的架构上下文。 + /// + /// 测试期间保存的架构上下文。 + public IArchitectureContext GetContext() + { + return _context; + } +} diff --git a/GFramework.Core.Tests/Architectures/TestSystemV2.cs b/GFramework.Core.Tests/Architectures/TestSystemV2.cs new file mode 100644 index 00000000..0d8be394 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/TestSystemV2.cs @@ -0,0 +1,58 @@ +using GFramework.Core.Abstractions.Architectures; +using GFramework.Core.Abstractions.Enums; +using GFramework.Core.Abstractions.Systems; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 为 提供的测试系统桩。 +/// +public sealed class TestSystemV2 : ISystem +{ + private IArchitectureContext _context = null!; + + /// + /// 获取或设置测试用标识。 + /// + public int Id { get; init; } + + /// + /// 关联当前系统所属的架构上下文。 + /// + /// 要保存的架构上下文。 + public void SetContext(IArchitectureContext context) + { + _context = context; + } + + /// + /// 获取当前系统已绑定的架构上下文。 + /// + /// 测试期间保存的架构上下文。 + public IArchitectureContext GetContext() + { + return _context; + } + + /// + /// 初始化测试系统。 + /// + public void Initialize() + { + } + + /// + /// 销毁测试系统。 + /// + public void Destroy() + { + } + + /// + /// 接收架构阶段切换通知。 + /// + /// 当前架构阶段。 + public void OnArchitecturePhase(ArchitecturePhase phase) + { + } +} diff --git a/GFramework.Core.Tests/Architectures/TestUtilityV2.cs b/GFramework.Core.Tests/Architectures/TestUtilityV2.cs new file mode 100644 index 00000000..c29b8307 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/TestUtilityV2.cs @@ -0,0 +1,35 @@ +using GFramework.Core.Abstractions.Architectures; +using GFramework.Core.Abstractions.Utility; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 为 提供的测试工具桩。 +/// +public sealed class TestUtilityV2 : IUtility +{ + private IArchitectureContext _context = null!; + + /// + /// 获取或设置测试用标识。 + /// + public int Id { get; init; } + + /// + /// 关联当前工具所属的架构上下文。 + /// + /// 要保存的架构上下文。 + public void SetContext(IArchitectureContext context) + { + _context = context; + } + + /// + /// 获取当前工具已绑定的架构上下文。 + /// + /// 测试期间保存的架构上下文。 + public IArchitectureContext GetContext() + { + return _context; + } +} diff --git a/GFramework.Core.Tests/Architectures/TrackingPipelineBehavior.cs b/GFramework.Core.Tests/Architectures/TrackingPipelineBehavior.cs new file mode 100644 index 00000000..6caebc50 --- /dev/null +++ b/GFramework.Core.Tests/Architectures/TrackingPipelineBehavior.cs @@ -0,0 +1,33 @@ +using GFramework.Cqrs.Abstractions.Cqrs; + +namespace GFramework.Core.Tests.Architectures; + +/// +/// 记录请求通过管道次数的测试行为。 +/// +/// 请求类型。 +/// 响应类型。 +public sealed class TrackingPipelineBehavior : IPipelineBehavior + where TRequest : IRequest +{ + /// + /// 获取当前测试进程中该请求类型对应的行为触发次数。 + /// + public static int InvocationCount { get; set; } + + /// + /// 记录一次行为执行,然后继续执行下一个处理器。 + /// + /// 当前请求消息。 + /// 下一个处理委托。 + /// 取消令牌。 + /// 下游处理器的响应结果。 + public async ValueTask Handle( + TRequest message, + MessageHandlerDelegate next, + CancellationToken cancellationToken) + { + InvocationCount++; + return await next(message, cancellationToken).ConfigureAwait(false); + } +} diff --git a/GFramework.Core.Tests/Command/AbstractAsyncCommandTests.cs b/GFramework.Core.Tests/Command/AbstractAsyncCommandTests.cs index 5c02898b..f4665286 100644 --- a/GFramework.Core.Tests/Command/AbstractAsyncCommandTests.cs +++ b/GFramework.Core.Tests/Command/AbstractAsyncCommandTests.cs @@ -229,171 +229,3 @@ public class AbstractAsyncCommandTests Assert.That(result, Is.EqualTo(200)); } } - -/// -/// 测试用命令输入类V2 -/// -public sealed class TestCommandInputV2 : ICommandInput -{ - /// - /// 获取或设置值 - /// - public int Value { get; init; } -} - -/// -/// 测试用异步命令类V3(无返回值) -/// -public sealed class TestAsyncCommandV3 : AbstractAsyncCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestAsyncCommandV3(TestCommandInputV2 input) : base(input) - { - } - - /// - /// 获取命令是否已执行 - /// - public bool Executed { get; private set; } - - /// - /// 获取执行的值 - /// - public int ExecutedValue { get; private set; } - - /// - /// 执行异步命令的重写方法 - /// - /// 命令输入 - /// 表示异步操作的任务 - protected override Task OnExecuteAsync(TestCommandInputV2 input) - { - Executed = true; - ExecutedValue = input.Value; - return Task.CompletedTask; - } -} - -/// -/// 测试用异步命令类V3(有返回值) -/// -public sealed class TestAsyncCommandWithResultV3 : AbstractAsyncCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestAsyncCommandWithResultV3(TestCommandInputV2 input) : base(input) - { - } - - /// - /// 获取命令是否已执行 - /// - public bool Executed { get; private set; } - - /// - /// 执行异步命令并返回结果的重写方法 - /// - /// 命令输入 - /// 执行结果的异步任务 - protected override Task OnExecuteAsync(TestCommandInputV2 input) - { - Executed = true; - return Task.FromResult(input.Value * 2); - } -} - -/// -/// 测试用异步命令类(抛出异常) -/// -public sealed class TestAsyncCommandWithExceptionV3 : AbstractAsyncCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestAsyncCommandWithExceptionV3(TestCommandInputV2 input) : base(input) - { - } - - /// - /// 执行异步命令并抛出异常的重写方法 - /// - /// 命令输入 - /// 表示异步操作的任务 - /// 总是抛出异常 - protected override Task OnExecuteAsync(TestCommandInputV2 input) - { - throw new InvalidOperationException("Test exception"); - } -} - -/// -/// 测试用异步命令子类(无返回值) -/// -public sealed class TestAsyncCommandChildV3 : AbstractAsyncCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestAsyncCommandChildV3(TestCommandInputV2 input) : base(input) - { - } - - /// - /// 获取命令是否已执行 - /// - public bool Executed { get; private set; } - - /// - /// 获取执行的值 - /// - public int ExecutedValue { get; private set; } - - /// - /// 执行异步命令的重写方法(子类实现) - /// - /// 命令输入 - /// 表示异步操作的任务 - protected override Task OnExecuteAsync(TestCommandInputV2 input) - { - Executed = true; - ExecutedValue = input.Value * 2; - return Task.CompletedTask; - } -} - -/// -/// 测试用异步命令子类(有返回值) -/// -public sealed class TestAsyncCommandWithResultChildV3 : AbstractAsyncCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestAsyncCommandWithResultChildV3(TestCommandInputV2 input) : base(input) - { - } - - /// - /// 获取命令是否已执行 - /// - public bool Executed { get; private set; } - - /// - /// 执行异步命令并返回结果的重写方法(子类实现) - /// - /// 命令输入 - /// 执行结果的异步任务 - protected override Task OnExecuteAsync(TestCommandInputV2 input) - { - Executed = true; - return Task.FromResult(input.Value * 3); - } -} diff --git a/GFramework.Core.Tests/Command/CommandExecutorTests.cs b/GFramework.Core.Tests/Command/CommandExecutorTests.cs index f12130ad..1e684e11 100644 --- a/GFramework.Core.Tests/Command/CommandExecutorTests.cs +++ b/GFramework.Core.Tests/Command/CommandExecutorTests.cs @@ -1,5 +1,4 @@ using GFramework.Core.Command; -using GFramework.Cqrs.Abstractions.Cqrs.Command; namespace GFramework.Core.Tests.Command; @@ -121,144 +120,3 @@ public class CommandExecutorTests Assert.ThrowsAsync(() => _commandExecutor.SendAsync(null!)); } } - -/// -/// 测试用命令输入类,实现ICommandInput接口 -/// -public sealed class TestCommandInput : ICommandInput -{ - /// - /// 获取或设置值 - /// - public int Value { get; init; } -} - -/// -/// 测试用命令类,继承AbstractCommand -/// -public sealed class TestCommand : AbstractCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestCommand(TestCommandInput input) : base(input) - { - } - - /// - /// 获取命令是否已执行 - /// - public bool Executed { get; private set; } - - /// - /// 获取执行的值 - /// - public int ExecutedValue { get; private set; } - - /// - /// 执行命令的重写方法 - /// - /// 命令输入 - protected override void OnExecute(TestCommandInput input) - { - Executed = true; - ExecutedValue = 42; - } -} - -/// -/// 测试用带返回值的命令类,继承AbstractCommand -/// -public sealed class TestCommandWithResult : AbstractCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestCommandWithResult(TestCommandInput input) : base(input) - { - } - - /// - /// 获取命令是否已执行 - /// - public bool Executed { get; private set; } - - /// - /// 执行命令并返回结果的重写方法 - /// - /// 命令输入 - /// 执行结果 - protected override int OnExecute(TestCommandInput input) - { - Executed = true; - return input.Value * 2; - } -} - -/// -/// 测试用异步命令类,继承AbstractAsyncCommand -/// -public sealed class TestAsyncCommand : AbstractAsyncCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestAsyncCommand(TestCommandInput input) : base(input) - { - } - - /// - /// 获取命令是否已执行 - /// - public bool Executed { get; private set; } - - /// - /// 获取执行的值 - /// - public int ExecutedValue { get; private set; } - - /// - /// 执行异步命令的重写方法 - /// - /// 命令输入 - /// 表示异步操作的任务 - protected override Task OnExecuteAsync(TestCommandInput input) - { - Executed = true; - ExecutedValue = 42; - return Task.CompletedTask; - } -} - -/// -/// 测试用带返回值的异步命令类,继承AbstractAsyncCommand -/// -public sealed class TestAsyncCommandWithResult : AbstractAsyncCommand -{ - /// - /// 构造函数 - /// - /// 命令输入 - public TestAsyncCommandWithResult(TestCommandInput input) : base(input) - { - } - - /// - /// 获取命令是否已执行 - /// - public bool Executed { get; private set; } - - /// - /// 执行异步命令并返回结果的重写方法 - /// - /// 命令输入 - /// 执行结果的异步任务 - protected override Task OnExecuteAsync(TestCommandInput input) - { - Executed = true; - return Task.FromResult(input.Value * 2); - } -} diff --git a/GFramework.Core.Tests/Command/TestAsyncCommand.cs b/GFramework.Core.Tests/Command/TestAsyncCommand.cs new file mode 100644 index 00000000..34be2a9c --- /dev/null +++ b/GFramework.Core.Tests/Command/TestAsyncCommand.cs @@ -0,0 +1,39 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的异步测试命令。 +/// +public sealed class TestAsyncCommand : AbstractAsyncCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestAsyncCommand(TestCommandInput input) : base(input) + { + } + + /// + /// 获取一个值,该值指示命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 获取命令记录的执行结果值。 + /// + public int ExecutedValue { get; private set; } + + /// + /// 执行异步测试命令并记录执行状态。 + /// + /// 命令输入。 + /// 已完成的异步任务。 + protected override Task OnExecuteAsync(TestCommandInput input) + { + Executed = true; + ExecutedValue = 42; + return Task.CompletedTask; + } +} diff --git a/GFramework.Core.Tests/Command/TestAsyncCommandChildV3.cs b/GFramework.Core.Tests/Command/TestAsyncCommandChildV3.cs new file mode 100644 index 00000000..d31d546e --- /dev/null +++ b/GFramework.Core.Tests/Command/TestAsyncCommandChildV3.cs @@ -0,0 +1,39 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的子类化无返回值异步测试命令。 +/// +public sealed class TestAsyncCommandChildV3 : AbstractAsyncCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestAsyncCommandChildV3(TestCommandInputV2 input) : base(input) + { + } + + /// + /// 获取一个值,该值指示命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 获取子类记录的执行值。 + /// + public int ExecutedValue { get; private set; } + + /// + /// 执行子类测试命令并记录经过变换的输入值。 + /// + /// 命令输入。 + /// 已完成的异步任务。 + protected override Task OnExecuteAsync(TestCommandInputV2 input) + { + Executed = true; + ExecutedValue = input.Value * 2; + return Task.CompletedTask; + } +} diff --git a/GFramework.Core.Tests/Command/TestAsyncCommandV3.cs b/GFramework.Core.Tests/Command/TestAsyncCommandV3.cs new file mode 100644 index 00000000..eab5865f --- /dev/null +++ b/GFramework.Core.Tests/Command/TestAsyncCommandV3.cs @@ -0,0 +1,39 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的无返回值异步测试命令。 +/// +public sealed class TestAsyncCommandV3 : AbstractAsyncCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestAsyncCommandV3(TestCommandInputV2 input) : base(input) + { + } + + /// + /// 获取一个值,该值指示命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 获取命令记录的执行值。 + /// + public int ExecutedValue { get; private set; } + + /// + /// 执行测试命令并回写执行状态。 + /// + /// 命令输入。 + /// 已完成的异步任务。 + protected override Task OnExecuteAsync(TestCommandInputV2 input) + { + Executed = true; + ExecutedValue = input.Value; + return Task.CompletedTask; + } +} diff --git a/GFramework.Core.Tests/Command/TestAsyncCommandWithExceptionV3.cs b/GFramework.Core.Tests/Command/TestAsyncCommandWithExceptionV3.cs new file mode 100644 index 00000000..4dc9e2a7 --- /dev/null +++ b/GFramework.Core.Tests/Command/TestAsyncCommandWithExceptionV3.cs @@ -0,0 +1,28 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的异常路径异步测试命令。 +/// +public sealed class TestAsyncCommandWithExceptionV3 : AbstractAsyncCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestAsyncCommandWithExceptionV3(TestCommandInputV2 input) : base(input) + { + } + + /// + /// 执行测试命令并始终抛出预期异常。 + /// + /// 命令输入。 + /// 此方法不会正常返回。 + /// 始终抛出,用于验证异常传播行为。 + protected override Task OnExecuteAsync(TestCommandInputV2 input) + { + throw new InvalidOperationException("Test exception"); + } +} diff --git a/GFramework.Core.Tests/Command/TestAsyncCommandWithResult.cs b/GFramework.Core.Tests/Command/TestAsyncCommandWithResult.cs new file mode 100644 index 00000000..b3fac25f --- /dev/null +++ b/GFramework.Core.Tests/Command/TestAsyncCommandWithResult.cs @@ -0,0 +1,33 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的带返回值异步测试命令。 +/// +public sealed class TestAsyncCommandWithResult : AbstractAsyncCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestAsyncCommandWithResult(TestCommandInput input) : base(input) + { + } + + /// + /// 获取一个值,该值指示命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 执行异步测试命令并返回基于输入值计算的结果。 + /// + /// 命令输入。 + /// 输入值两倍的异步结果。 + protected override Task OnExecuteAsync(TestCommandInput input) + { + Executed = true; + return Task.FromResult(input.Value * 2); + } +} diff --git a/GFramework.Core.Tests/Command/TestAsyncCommandWithResultChildV3.cs b/GFramework.Core.Tests/Command/TestAsyncCommandWithResultChildV3.cs new file mode 100644 index 00000000..20661821 --- /dev/null +++ b/GFramework.Core.Tests/Command/TestAsyncCommandWithResultChildV3.cs @@ -0,0 +1,33 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的子类化带返回值异步测试命令。 +/// +public sealed class TestAsyncCommandWithResultChildV3 : AbstractAsyncCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestAsyncCommandWithResultChildV3(TestCommandInputV2 input) : base(input) + { + } + + /// + /// 获取一个值,该值指示命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 执行子类测试命令并返回经过变换的输入值。 + /// + /// 命令输入。 + /// 输入值三倍的异步结果。 + protected override Task OnExecuteAsync(TestCommandInputV2 input) + { + Executed = true; + return Task.FromResult(input.Value * 3); + } +} diff --git a/GFramework.Core.Tests/Command/TestAsyncCommandWithResultV3.cs b/GFramework.Core.Tests/Command/TestAsyncCommandWithResultV3.cs new file mode 100644 index 00000000..43e577b7 --- /dev/null +++ b/GFramework.Core.Tests/Command/TestAsyncCommandWithResultV3.cs @@ -0,0 +1,33 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的带返回值异步测试命令。 +/// +public sealed class TestAsyncCommandWithResultV3 : AbstractAsyncCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestAsyncCommandWithResultV3(TestCommandInputV2 input) : base(input) + { + } + + /// + /// 获取一个值,该值指示命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 执行测试命令并返回基于输入值计算的结果。 + /// + /// 命令输入。 + /// 输入值两倍的异步结果。 + protected override Task OnExecuteAsync(TestCommandInputV2 input) + { + Executed = true; + return Task.FromResult(input.Value * 2); + } +} diff --git a/GFramework.Core.Tests/Command/TestCommand.cs b/GFramework.Core.Tests/Command/TestCommand.cs new file mode 100644 index 00000000..54e3d6b6 --- /dev/null +++ b/GFramework.Core.Tests/Command/TestCommand.cs @@ -0,0 +1,37 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的同步测试命令。 +/// +public sealed class TestCommand : AbstractCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestCommand(TestCommandInput input) : base(input) + { + } + + /// + /// 获取一个值,该值指示命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 获取命令记录的执行结果值。 + /// + public int ExecutedValue { get; private set; } + + /// + /// 执行测试命令并记录同步执行状态。 + /// + /// 命令输入。 + protected override void OnExecute(TestCommandInput input) + { + Executed = true; + ExecutedValue = 42; + } +} diff --git a/GFramework.Core.Tests/Command/TestCommandInput.cs b/GFramework.Core.Tests/Command/TestCommandInput.cs new file mode 100644 index 00000000..2ca47099 --- /dev/null +++ b/GFramework.Core.Tests/Command/TestCommandInput.cs @@ -0,0 +1,14 @@ +using GFramework.Cqrs.Abstractions.Cqrs.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的测试命令输入。 +/// +public sealed class TestCommandInput : ICommandInput +{ + /// + /// 获取或设置测试值。 + /// + public int Value { get; init; } +} diff --git a/GFramework.Core.Tests/Command/TestCommandInputV2.cs b/GFramework.Core.Tests/Command/TestCommandInputV2.cs new file mode 100644 index 00000000..943f5d99 --- /dev/null +++ b/GFramework.Core.Tests/Command/TestCommandInputV2.cs @@ -0,0 +1,14 @@ +using GFramework.Cqrs.Abstractions.Cqrs.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的测试命令输入。 +/// +public sealed class TestCommandInputV2 : ICommandInput +{ + /// + /// 获取或设置用于驱动测试断言的输入值。 + /// + public int Value { get; init; } +} diff --git a/GFramework.Core.Tests/Command/TestCommandWithResult.cs b/GFramework.Core.Tests/Command/TestCommandWithResult.cs new file mode 100644 index 00000000..d1de53f5 --- /dev/null +++ b/GFramework.Core.Tests/Command/TestCommandWithResult.cs @@ -0,0 +1,33 @@ +using GFramework.Core.Command; + +namespace GFramework.Core.Tests.Command; + +/// +/// 表示 使用的带返回值同步测试命令。 +/// +public sealed class TestCommandWithResult : AbstractCommand +{ + /// + /// 初始化 的新实例。 + /// + /// 命令输入。 + public TestCommandWithResult(TestCommandInput input) : base(input) + { + } + + /// + /// 获取一个值,该值指示命令是否已经执行。 + /// + public bool Executed { get; private set; } + + /// + /// 执行测试命令并返回基于输入值计算的结果。 + /// + /// 命令输入。 + /// 输入值的两倍。 + protected override int OnExecute(TestCommandInput input) + { + Executed = true; + return input.Value * 2; + } +} diff --git a/GFramework.Core.Tests/Extensions/ObjectExtensionsTests.cs b/GFramework.Core.Tests/Extensions/ObjectExtensionsTests.cs index 411069a9..14209d8d 100644 --- a/GFramework.Core.Tests/Extensions/ObjectExtensionsTests.cs +++ b/GFramework.Core.Tests/Extensions/ObjectExtensionsTests.cs @@ -218,19 +218,3 @@ public class ObjectExtensionsTests Assert.That(executed, Is.False); } } - -/// -/// 测试用的简单类 -/// -public class TestClass -{ - /// - /// 获取或设置整数值 - /// - public int Value { get; set; } - - /// - /// 获取或设置名称字符串 - /// - public string Name { get; set; } = string.Empty; -} \ No newline at end of file diff --git a/GFramework.Core.Tests/Extensions/TestClass.cs b/GFramework.Core.Tests/Extensions/TestClass.cs new file mode 100644 index 00000000..e13683d0 --- /dev/null +++ b/GFramework.Core.Tests/Extensions/TestClass.cs @@ -0,0 +1,17 @@ +namespace GFramework.Core.Tests.Extensions; + +/// +/// 为 提供类型匹配断言所需的简单测试对象。 +/// +public class TestClass +{ + /// + /// 获取或设置用于数值分支断言的测试值。 + /// + public int Value { get; set; } + + /// + /// 获取或设置用于字符串结果断言的测试名称。 + /// + public string Name { get; set; } = string.Empty; +} diff --git a/GFramework.Core.Tests/Query/AsyncQueryExecutorTests.cs b/GFramework.Core.Tests/Query/AsyncQueryExecutorTests.cs index acf0cc84..574f5bc8 100644 --- a/GFramework.Core.Tests/Query/AsyncQueryExecutorTests.cs +++ b/GFramework.Core.Tests/Query/AsyncQueryExecutorTests.cs @@ -1,5 +1,4 @@ using GFramework.Core.Query; -using GFramework.Cqrs.Abstractions.Cqrs.Query; namespace GFramework.Core.Tests.Query; @@ -137,159 +136,3 @@ public class AsyncQueryExecutorTests Assert.That(result2, Is.EqualTo(40)); } } - -/// -/// 测试用异步查询输入类,实现IQueryInput接口 -/// -public sealed class TestAsyncQueryInput : IQueryInput -{ - /// - /// 获取或设置查询值 - /// - public int Value { get; init; } -} - -/// -/// 整数类型测试异步查询类,继承AbstractAsyncQuery -/// 实现具体的异步查询逻辑并返回整数结果 -/// -public sealed class TestAsyncQuery : AbstractAsyncQuery -{ - /// - /// 初始化TestAsyncQuery的新实例 - /// - /// 查询输入参数 - public TestAsyncQuery(TestAsyncQueryInput input) : base(input) - { - } - - /// - /// 执行异步查询操作的具体实现 - /// - /// 查询输入参数 - /// 查询结果,将输入值乘以2 - protected override Task OnDoAsync(TestAsyncQueryInput input) - { - return Task.FromResult(input.Value * 2); - } -} - -/// -/// 字符串类型测试异步查询类,继承AbstractAsyncQuery -/// 实现具体的异步查询逻辑并返回字符串结果 -/// -public sealed class TestAsyncStringQuery : AbstractAsyncQuery -{ - /// - /// 初始化TestAsyncStringQuery的新实例 - /// - /// 查询输入参数 - public TestAsyncStringQuery(TestAsyncQueryInput input) : base(input) - { - } - - /// - /// 执行异步查询操作的具体实现 - /// - /// 查询输入参数 - /// 格式化的字符串结果 - protected override Task OnDoAsync(TestAsyncQueryInput input) - { - return Task.FromResult($"Result: {input.Value * 2}"); - } -} - -/// -/// 布尔类型测试异步查询类,继承AbstractAsyncQuery -/// 实现具体的异步查询逻辑并返回布尔结果 -/// -public sealed class TestAsyncBooleanQuery : AbstractAsyncQuery -{ - /// - /// 初始化TestAsyncBooleanQuery的新实例 - /// - /// 查询输入参数 - public TestAsyncBooleanQuery(TestAsyncQueryInput input) : base(input) - { - } - - /// - /// 执行异步查询操作的具体实现 - /// - /// 查询输入参数 - /// 如果值大于0返回true,否则返回false - protected override Task OnDoAsync(TestAsyncQueryInput input) - { - return Task.FromResult(input.Value > 0); - } -} - -/// -/// 复杂对象类型测试异步查询类,继承AbstractAsyncQuery -/// 实现具体的异步查询逻辑并返回复杂对象结果 -/// -public sealed class TestAsyncComplexQuery : AbstractAsyncQuery -{ - /// - /// 初始化TestAsyncComplexQuery的新实例 - /// - /// 查询输入参数 - public TestAsyncComplexQuery(TestAsyncQueryInput input) : base(input) - { - } - - /// - /// 执行异步查询操作的具体实现 - /// - /// 查询输入参数 - /// 复杂对象查询结果 - protected override Task OnDoAsync(TestAsyncQueryInput input) - { - var result = new TestAsyncQueryResult - { - Value = input.Value * 2, - DoubleValue = input.Value * 3 - }; - return Task.FromResult(result); - } -} - -/// -/// 测试用异步查询类(抛出异常) -/// -public sealed class TestAsyncQueryWithException : AbstractAsyncQuery -{ - /// - /// 初始化TestAsyncQueryWithException的新实例 - /// - /// 查询输入参数 - public TestAsyncQueryWithException(TestAsyncQueryInput input) : base(input) - { - } - - /// - /// 执行异步查询操作并抛出异常 - /// - /// 查询输入参数 - /// 总是抛出异常 - protected override Task OnDoAsync(TestAsyncQueryInput input) - { - throw new InvalidOperationException("Test exception"); - } -} - -/// -/// 测试用复杂查询结果类 -/// -public sealed class TestAsyncQueryResult -{ - /// - /// 获取或设置值 - /// - public int Value { get; init; } - - /// - /// 获取或设置双倍值 - /// - public int DoubleValue { get; init; } -} diff --git a/GFramework.Core.Tests/Query/QueryExecutorTests.cs b/GFramework.Core.Tests/Query/QueryExecutorTests.cs index a9cde117..b6feeac3 100644 --- a/GFramework.Core.Tests/Query/QueryExecutorTests.cs +++ b/GFramework.Core.Tests/Query/QueryExecutorTests.cs @@ -1,5 +1,4 @@ using GFramework.Core.Query; -using GFramework.Cqrs.Abstractions.Cqrs.Query; namespace GFramework.Core.Tests.Query; @@ -60,65 +59,3 @@ public class QueryExecutorTests Assert.That(result, Is.EqualTo("Result: 10")); } } - -/// -/// 测试用查询输入类,实现IQueryInput接口 -/// 用于传递查询所需的参数信息 -/// -public sealed class TestQueryInput : IQueryInput -{ - /// - /// 获取或设置查询值 - /// - public int Value { get; init; } -} - -/// -/// 整数类型测试查询类,继承自AbstractQuery -/// 实现具体的查询逻辑并返回整数结果 -/// -public sealed class TestQuery : AbstractQuery -{ - /// - /// 初始化TestQuery的新实例 - /// - /// 查询输入参数 - public TestQuery(TestQueryInput input) : base(input) - { - } - - /// - /// 执行查询操作的具体实现 - /// - /// 查询输入参数 - /// 查询结果,将输入值乘以2 - protected override int OnDo(TestQueryInput input) - { - return input.Value * 2; - } -} - -/// -/// 字符串类型测试查询类,继承自AbstractQuery -/// 实现具体的查询逻辑并返回字符串结果 -/// -public sealed class TestStringQuery : AbstractQuery -{ - /// - /// 初始化TestStringQuery的新实例 - /// - /// 查询输入参数 - public TestStringQuery(TestQueryInput input) : base(input) - { - } - - /// - /// 执行查询操作的具体实现 - /// - /// 查询输入参数 - /// 格式化的字符串结果 - protected override string OnDo(TestQueryInput input) - { - return $"Result: {input.Value * 2}"; - } -} diff --git a/GFramework.Core.Tests/Query/TestAsyncBooleanQuery.cs b/GFramework.Core.Tests/Query/TestAsyncBooleanQuery.cs new file mode 100644 index 00000000..ccf2f635 --- /dev/null +++ b/GFramework.Core.Tests/Query/TestAsyncBooleanQuery.cs @@ -0,0 +1,27 @@ +using GFramework.Core.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供布尔结果的测试异步查询。 +/// +public sealed class TestAsyncBooleanQuery : AbstractAsyncQuery +{ + /// + /// 初始化 的新实例。 + /// + /// 查询输入参数。 + public TestAsyncBooleanQuery(TestAsyncQueryInput input) : base(input) + { + } + + /// + /// 执行异步查询并根据输入值是否大于零返回布尔结果。 + /// + /// 查询输入参数。 + /// 当输入值大于 0 时返回 ;否则返回 + protected override Task OnDoAsync(TestAsyncQueryInput input) + { + return Task.FromResult(input.Value > 0); + } +} diff --git a/GFramework.Core.Tests/Query/TestAsyncComplexQuery.cs b/GFramework.Core.Tests/Query/TestAsyncComplexQuery.cs new file mode 100644 index 00000000..8c0f5e35 --- /dev/null +++ b/GFramework.Core.Tests/Query/TestAsyncComplexQuery.cs @@ -0,0 +1,33 @@ +using GFramework.Core.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供复杂对象结果的测试异步查询。 +/// +public sealed class TestAsyncComplexQuery : AbstractAsyncQuery +{ + /// + /// 初始化 的新实例。 + /// + /// 查询输入参数。 + public TestAsyncComplexQuery(TestAsyncQueryInput input) : base(input) + { + } + + /// + /// 执行异步查询并构造组合结果对象。 + /// + /// 查询输入参数。 + /// 包含双倍值和三倍值的测试结果对象。 + protected override Task OnDoAsync(TestAsyncQueryInput input) + { + var result = new TestAsyncQueryResult + { + Value = input.Value * 2, + DoubleValue = input.Value * 3 + }; + + return Task.FromResult(result); + } +} diff --git a/GFramework.Core.Tests/Query/TestAsyncQuery.cs b/GFramework.Core.Tests/Query/TestAsyncQuery.cs new file mode 100644 index 00000000..1c0fceda --- /dev/null +++ b/GFramework.Core.Tests/Query/TestAsyncQuery.cs @@ -0,0 +1,27 @@ +using GFramework.Core.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供整数结果的测试异步查询。 +/// +public sealed class TestAsyncQuery : AbstractAsyncQuery +{ + /// + /// 初始化 的新实例。 + /// + /// 查询输入参数。 + public TestAsyncQuery(TestAsyncQueryInput input) : base(input) + { + } + + /// + /// 执行异步查询并返回输入值的两倍。 + /// + /// 查询输入参数。 + /// 将输入值乘以 2 的结果。 + protected override Task OnDoAsync(TestAsyncQueryInput input) + { + return Task.FromResult(input.Value * 2); + } +} diff --git a/GFramework.Core.Tests/Query/TestAsyncQueryInput.cs b/GFramework.Core.Tests/Query/TestAsyncQueryInput.cs new file mode 100644 index 00000000..f6aa942e --- /dev/null +++ b/GFramework.Core.Tests/Query/TestAsyncQueryInput.cs @@ -0,0 +1,14 @@ +using GFramework.Cqrs.Abstractions.Cqrs.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供输入值的测试查询输入。 +/// +public sealed class TestAsyncQueryInput : IQueryInput +{ + /// + /// 获取或设置查询值。 + /// + public int Value { get; init; } +} diff --git a/GFramework.Core.Tests/Query/TestAsyncQueryResult.cs b/GFramework.Core.Tests/Query/TestAsyncQueryResult.cs new file mode 100644 index 00000000..93f2b262 --- /dev/null +++ b/GFramework.Core.Tests/Query/TestAsyncQueryResult.cs @@ -0,0 +1,17 @@ +namespace GFramework.Core.Tests.Query; + +/// +/// 表示 使用的复杂测试查询结果。 +/// +public sealed class TestAsyncQueryResult +{ + /// + /// 获取或设置主结果值。 + /// + public int Value { get; init; } + + /// + /// 获取或设置派生的双重结果值。 + /// + public int DoubleValue { get; init; } +} diff --git a/GFramework.Core.Tests/Query/TestAsyncQueryWithException.cs b/GFramework.Core.Tests/Query/TestAsyncQueryWithException.cs new file mode 100644 index 00000000..a5a11da5 --- /dev/null +++ b/GFramework.Core.Tests/Query/TestAsyncQueryWithException.cs @@ -0,0 +1,28 @@ +using GFramework.Core.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供固定抛出异常的测试异步查询。 +/// +public sealed class TestAsyncQueryWithException : AbstractAsyncQuery +{ + /// + /// 初始化 的新实例。 + /// + /// 查询输入参数。 + public TestAsyncQueryWithException(TestAsyncQueryInput input) : base(input) + { + } + + /// + /// 执行异步查询并始终抛出测试异常。 + /// + /// 查询输入参数。 + /// 此方法不会返回结果。 + /// 始终抛出,模拟查询执行失败。 + protected override Task OnDoAsync(TestAsyncQueryInput input) + { + throw new InvalidOperationException("Test exception"); + } +} diff --git a/GFramework.Core.Tests/Query/TestAsyncStringQuery.cs b/GFramework.Core.Tests/Query/TestAsyncStringQuery.cs new file mode 100644 index 00000000..6224f0f7 --- /dev/null +++ b/GFramework.Core.Tests/Query/TestAsyncStringQuery.cs @@ -0,0 +1,27 @@ +using GFramework.Core.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供字符串结果的测试异步查询。 +/// +public sealed class TestAsyncStringQuery : AbstractAsyncQuery +{ + /// + /// 初始化 的新实例。 + /// + /// 查询输入参数。 + public TestAsyncStringQuery(TestAsyncQueryInput input) : base(input) + { + } + + /// + /// 执行异步查询并返回格式化的字符串结果。 + /// + /// 查询输入参数。 + /// 包含双倍值的格式化字符串。 + protected override Task OnDoAsync(TestAsyncQueryInput input) + { + return Task.FromResult($"Result: {input.Value * 2}"); + } +} diff --git a/GFramework.Core.Tests/Query/TestQuery.cs b/GFramework.Core.Tests/Query/TestQuery.cs new file mode 100644 index 00000000..d6a1acd2 --- /dev/null +++ b/GFramework.Core.Tests/Query/TestQuery.cs @@ -0,0 +1,27 @@ +using GFramework.Core.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供整数结果的测试同步查询。 +/// +public sealed class TestQuery : AbstractQuery +{ + /// + /// 初始化 的新实例。 + /// + /// 查询输入参数。 + public TestQuery(TestQueryInput input) : base(input) + { + } + + /// + /// 执行同步查询并返回输入值的双倍结果。 + /// + /// 查询输入参数。 + /// 输入值乘以 2 后的结果。 + protected override int OnDo(TestQueryInput input) + { + return input.Value * 2; + } +} diff --git a/GFramework.Core.Tests/Query/TestQueryInput.cs b/GFramework.Core.Tests/Query/TestQueryInput.cs new file mode 100644 index 00000000..e683e3aa --- /dev/null +++ b/GFramework.Core.Tests/Query/TestQueryInput.cs @@ -0,0 +1,14 @@ +using GFramework.Cqrs.Abstractions.Cqrs.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供输入值的测试查询输入。 +/// +public sealed class TestQueryInput : IQueryInput +{ + /// + /// 获取或设置查询值。 + /// + public int Value { get; init; } +} diff --git a/GFramework.Core.Tests/Query/TestStringQuery.cs b/GFramework.Core.Tests/Query/TestStringQuery.cs new file mode 100644 index 00000000..04c0df5a --- /dev/null +++ b/GFramework.Core.Tests/Query/TestStringQuery.cs @@ -0,0 +1,27 @@ +using GFramework.Core.Query; + +namespace GFramework.Core.Tests.Query; + +/// +/// 为 提供字符串结果的测试同步查询。 +/// +public sealed class TestStringQuery : AbstractQuery +{ + /// + /// 初始化 的新实例。 + /// + /// 查询输入参数。 + public TestStringQuery(TestQueryInput input) : base(input) + { + } + + /// + /// 执行同步查询并返回格式化后的字符串结果。 + /// + /// 查询输入参数。 + /// 包含双倍值的格式化字符串。 + protected override string OnDo(TestQueryInput input) + { + return $"Result: {input.Value * 2}"; + } +} diff --git a/GFramework.Core.Tests/Rule/ContextAwareTests.cs b/GFramework.Core.Tests/Rule/ContextAwareTests.cs index 7c659310..d446c3bc 100644 --- a/GFramework.Core.Tests/Rule/ContextAwareTests.cs +++ b/GFramework.Core.Tests/Rule/ContextAwareTests.cs @@ -99,29 +99,3 @@ public class ContextAwareTests Assert.DoesNotThrow(() => aware.GetContext()); } } - -/// -/// 用于测试的 ContextAware 实现类 -/// 继承自 ContextAwareBase,提供公共访问的上下文属性和回调状态跟踪 -/// -public class TestContextAware : ContextAwareBase -{ - /// - /// 获取内部上下文的公共访问属性 - /// - public IArchitectureContext? PublicContext => Context; - - /// - /// 跟踪 OnContextReady 方法是否被调用的状态 - /// - public bool OnContextReadyCalled { get; private set; } - - /// - /// 重写上下文就绪回调方法 - /// 设置 OnContextReadyCalled 标志为 true,用于测试验证 - /// - protected override void OnContextReady() - { - OnContextReadyCalled = true; - } -} \ No newline at end of file diff --git a/GFramework.Core.Tests/Rule/TestContextAware.cs b/GFramework.Core.Tests/Rule/TestContextAware.cs new file mode 100644 index 00000000..df2ba7cf --- /dev/null +++ b/GFramework.Core.Tests/Rule/TestContextAware.cs @@ -0,0 +1,28 @@ +using GFramework.Core.Abstractions.Architectures; +using GFramework.Core.Rule; + +namespace GFramework.Core.Tests.Rule; + +/// +/// 提供给 ContextAware 相关测试复用的上下文感知对象。 +/// +public class TestContextAware : ContextAwareBase +{ + /// + /// 获取当前测试对象已绑定的上下文实例。 + /// + public IArchitectureContext? PublicContext => Context; + + /// + /// 获取一个值,指示上下文就绪回调是否已经触发。 + /// + public bool OnContextReadyCalled { get; private set; } + + /// + /// 在上下文完成绑定后记录回调已被触发,供断言使用。 + /// + protected override void OnContextReady() + { + OnContextReadyCalled = true; + } +} diff --git a/GFramework.Core.Tests/State/ConcreteAsyncStateV2.cs b/GFramework.Core.Tests/State/ConcreteAsyncStateV2.cs new file mode 100644 index 00000000..7809026d --- /dev/null +++ b/GFramework.Core.Tests/State/ConcreteAsyncStateV2.cs @@ -0,0 +1,116 @@ +using GFramework.Core.Abstractions.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 异步具体状态实现类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).ConfigureAwait(false); + EnterCalled = true; + EnterCallCount++; + EnterFrom = from; + } + + /// + /// 异步退出当前状态时调用的方法。 + /// + /// 退出到哪个状态。 + public async Task OnExitAsync(IState? to) + { + await Task.Delay(1).ConfigureAwait(false); + ExitCalled = true; + ExitCallCount++; + ExitTo = to; + } + + /// + /// 异步判断是否可以转换到目标状态。 + /// + /// 目标状态。 + /// 如果可以转换则返回 ,否则返回 + public async Task CanTransitionToAsync(IState target) + { + await Task.Delay(1).ConfigureAwait(false); + 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"); + } + + /// + /// 判断是否可以转换到目标状态(同步版本,抛出异常表示不应被调用)。 + /// + /// 目标状态。 + /// 此方法不会正常返回。 + /// 总是抛出,表示异步状态不应走同步入口。 + public bool CanTransitionTo(IState target) + { + throw new InvalidOperationException("Sync CanTransitionTo should not be called for async state"); + } +} diff --git a/GFramework.Core.Tests/State/ConcreteStateV2.cs b/GFramework.Core.Tests/State/ConcreteStateV2.cs new file mode 100644 index 00000000..b424aa8a --- /dev/null +++ b/GFramework.Core.Tests/State/ConcreteStateV2.cs @@ -0,0 +1,70 @@ +using GFramework.Core.Abstractions.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 具体状态实现类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; + } + + /// + /// 判断是否可以转换到目标状态。 + /// + /// 目标状态。 + /// 如果可以转换则返回 ,否则返回 + public bool CanTransitionTo(IState target) + { + CanTransitionToAction?.Invoke(target); + return AllowTransitions; + } +} diff --git a/GFramework.Core.Tests/State/ConcreteStateV3.cs b/GFramework.Core.Tests/State/ConcreteStateV3.cs new file mode 100644 index 00000000..245d72f0 --- /dev/null +++ b/GFramework.Core.Tests/State/ConcreteStateV3.cs @@ -0,0 +1,59 @@ +using GFramework.Core.Abstractions.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 具体状态实现类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; + } + + /// + /// 判断是否可以转换到目标状态。 + /// + /// 目标状态。 + /// 始终返回 + public bool CanTransitionTo(IState target) + { + return true; + } +} diff --git a/GFramework.Core.Tests/State/ConcreteStateV4.cs b/GFramework.Core.Tests/State/ConcreteStateV4.cs new file mode 100644 index 00000000..3a919e11 --- /dev/null +++ b/GFramework.Core.Tests/State/ConcreteStateV4.cs @@ -0,0 +1,59 @@ +using GFramework.Core.Abstractions.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 具体状态实现类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; + } + + /// + /// 判断是否可以转换到目标状态。 + /// + /// 目标状态。 + /// 始终返回 + public bool CanTransitionTo(IState target) + { + return true; + } +} diff --git a/GFramework.Core.Tests/State/ConditionalStateV2.cs b/GFramework.Core.Tests/State/ConditionalStateV2.cs new file mode 100644 index 00000000..53715f4d --- /dev/null +++ b/GFramework.Core.Tests/State/ConditionalStateV2.cs @@ -0,0 +1,64 @@ +using GFramework.Core.Abstractions.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 条件状态实现类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; + } + + /// + /// 判断是否可以转换到目标状态。 + /// + /// 目标状态。 + /// 如果目标状态类型在允许列表中则返回 ,否则返回 + public bool CanTransitionTo(IState target) + { + return AllowedTransitions.Contains(target.GetType()); + } +} diff --git a/GFramework.Core.Tests/State/StateMachineSystemTests.cs b/GFramework.Core.Tests/State/StateMachineSystemTests.cs index 63cb5b22..cb22d56d 100644 --- a/GFramework.Core.Tests/State/StateMachineSystemTests.cs +++ b/GFramework.Core.Tests/State/StateMachineSystemTests.cs @@ -1,7 +1,6 @@ using System.Reflection; using GFramework.Core.Abstractions.Enums; using GFramework.Core.Abstractions.Logging; -using GFramework.Core.Abstractions.State; using GFramework.Core.Abstractions.Systems; using GFramework.Core.Architectures; using GFramework.Core.Command; @@ -238,140 +237,3 @@ public class StateMachineSystemTests Assert.That(eventCount, Is.EqualTo(3)); } } - -#region Test Classes - -/// -/// 测试用的ContextAwareStateMachine派生类,用于访问内部状态字典 -/// -public class TestStateMachineSystemV5 : StateMachineSystem -{ - /// - /// 获取状态机内部的状态字典 - /// - /// 类型到状态实例的映射字典 - public IDictionary 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) - { - } -} - -/// -/// 第二个测试用的普通状态实现,用于区分不同状态类型 -/// -public class TestStateV5_2 : 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 diff --git a/GFramework.Core.Tests/State/StateTests.cs b/GFramework.Core.Tests/State/StateTests.cs index d8ac2044..3feeb195 100644 --- a/GFramework.Core.Tests/State/StateTests.cs +++ b/GFramework.Core.Tests/State/StateTests.cs @@ -326,409 +326,3 @@ public class StateTests 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).ConfigureAwait(false); - EnterCalled = true; - EnterCallCount++; - EnterFrom = from; - } - - /// - /// 异步退出当前状态时调用的方法 - /// - /// 退出到哪个状态 - public async Task OnExitAsync(IState? to) - { - await Task.Delay(1).ConfigureAwait(false); - ExitCalled = true; - ExitCallCount++; - ExitTo = to; - } - - /// - /// 异步判断是否可以转换到目标状态 - /// - /// 目标状态 - /// 如果可以转换则返回true,否则返回false - public async Task CanTransitionToAsync(IState target) - { - await Task.Delay(1).ConfigureAwait(false); - 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"); - } -} diff --git a/GFramework.Core.Tests/State/TestContextAwareStateV5.cs b/GFramework.Core.Tests/State/TestContextAwareStateV5.cs new file mode 100644 index 00000000..e5903d9d --- /dev/null +++ b/GFramework.Core.Tests/State/TestContextAwareStateV5.cs @@ -0,0 +1,26 @@ +using GFramework.Core.Abstractions.State; +using GFramework.Core.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 为 提供最小化的上下文感知状态实现。 +/// +public class TestContextAwareStateV5 : ContextAwareStateBase +{ + /// + /// 进入状态时调用。该测试替身不需要额外行为。 + /// + /// 前一个状态。 + public override void OnEnter(IState? previous) + { + } + + /// + /// 退出状态时调用。该测试替身不需要额外行为。 + /// + /// 下一个状态。 + public override void OnExit(IState? next) + { + } +} diff --git a/GFramework.Core.Tests/State/TestContextAwareStateV5_2.cs b/GFramework.Core.Tests/State/TestContextAwareStateV5_2.cs new file mode 100644 index 00000000..b810c479 --- /dev/null +++ b/GFramework.Core.Tests/State/TestContextAwareStateV5_2.cs @@ -0,0 +1,26 @@ +using GFramework.Core.Abstractions.State; +using GFramework.Core.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 为 提供第二个可区分类型的上下文感知状态实现。 +/// +public class TestContextAwareStateV5_2 : ContextAwareStateBase +{ + /// + /// 进入状态时调用。该测试替身不需要额外行为。 + /// + /// 前一个状态。 + public override void OnEnter(IState? previous) + { + } + + /// + /// 退出状态时调用。该测试替身不需要额外行为。 + /// + /// 下一个状态。 + public override void OnExit(IState? next) + { + } +} diff --git a/GFramework.Core.Tests/State/TestStateMachineSystemV5.cs b/GFramework.Core.Tests/State/TestStateMachineSystemV5.cs new file mode 100644 index 00000000..f5c83853 --- /dev/null +++ b/GFramework.Core.Tests/State/TestStateMachineSystemV5.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using GFramework.Core.Abstractions.State; +using GFramework.Core.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 为 提供可观察内部状态注册表的测试状态机实现。 +/// +public class TestStateMachineSystemV5 : StateMachineSystem +{ + /// + /// 获取状态机当前维护的状态实例映射,供测试断言注册结果使用。 + /// + /// 状态类型到状态实例的只读视图。 + public IDictionary GetStates() + { + return States; + } +} diff --git a/GFramework.Core.Tests/State/TestStateV5.cs b/GFramework.Core.Tests/State/TestStateV5.cs new file mode 100644 index 00000000..64aee177 --- /dev/null +++ b/GFramework.Core.Tests/State/TestStateV5.cs @@ -0,0 +1,40 @@ +using GFramework.Core.Abstractions.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 为 提供最小化的普通状态实现。 +/// +public class TestStateV5 : IState +{ + /// + /// 获取或设置测试状态标识符。 + /// + public int Id { get; set; } + + /// + /// 判断是否允许转换到下一个状态。 + /// + /// 目标状态。 + /// 始终返回 以简化状态机切换测试。 + public bool CanTransitionTo(IState next) + { + return true; + } + + /// + /// 进入状态时调用。该测试替身不需要额外行为。 + /// + /// 前一个状态。 + public void OnEnter(IState? previous) + { + } + + /// + /// 退出状态时调用。该测试替身不需要额外行为。 + /// + /// 下一个状态。 + public void OnExit(IState? next) + { + } +} diff --git a/GFramework.Core.Tests/State/TestStateV5_2.cs b/GFramework.Core.Tests/State/TestStateV5_2.cs new file mode 100644 index 00000000..09a4e2a1 --- /dev/null +++ b/GFramework.Core.Tests/State/TestStateV5_2.cs @@ -0,0 +1,40 @@ +using GFramework.Core.Abstractions.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 为 提供第二个可区分类型的普通状态实现。 +/// +public class TestStateV5_2 : IState +{ + /// + /// 获取或设置测试状态标识符。 + /// + public int Id { get; set; } + + /// + /// 判断是否允许转换到下一个状态。 + /// + /// 目标状态。 + /// 始终返回 以简化状态机切换测试。 + public bool CanTransitionTo(IState next) + { + return true; + } + + /// + /// 进入状态时调用。该测试替身不需要额外行为。 + /// + /// 前一个状态。 + public void OnEnter(IState? previous) + { + } + + /// + /// 退出状态时调用。该测试替身不需要额外行为。 + /// + /// 下一个状态。 + public void OnExit(IState? next) + { + } +} diff --git a/GFramework.Core.Tests/State/TrackingStateV2.cs b/GFramework.Core.Tests/State/TrackingStateV2.cs new file mode 100644 index 00000000..0bd5cab3 --- /dev/null +++ b/GFramework.Core.Tests/State/TrackingStateV2.cs @@ -0,0 +1,59 @@ +using GFramework.Core.Abstractions.State; + +namespace GFramework.Core.Tests.State; + +/// +/// 跟踪状态实现类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; + } + + /// + /// 判断是否可以转换到目标状态。 + /// + /// 目标状态。 + /// 始终返回 + public bool CanTransitionTo(IState target) + { + return true; + } +} diff --git a/GFramework.Core.Tests/Utility/AbstractContextUtilityTests.cs b/GFramework.Core.Tests/Utility/AbstractContextUtilityTests.cs index 9fcdc0bb..aa0fe622 100644 --- a/GFramework.Core.Tests/Utility/AbstractContextUtilityTests.cs +++ b/GFramework.Core.Tests/Utility/AbstractContextUtilityTests.cs @@ -1,4 +1,3 @@ -using GFramework.Core.Abstractions.Logging; using GFramework.Core.Abstractions.Rule; using GFramework.Core.Abstractions.Utility; using GFramework.Core.Architectures; @@ -208,87 +207,3 @@ public class AbstractContextUtilityTests Assert.That(utility.Destroyed, Is.True); } } - -/// -/// 测试用上下文工具类V1 -/// -public sealed class TestContextUtilityV1 : AbstractContextUtility -{ - /// - /// 获取工具是否已初始化 - /// - public bool Initialized { get; private set; } - - /// - /// 获取工具是否已销毁 - /// - public bool Destroyed { get; set; } - - /// - /// 获取Init方法是否被调用 - /// - public bool InitCalled { get; private set; } - - /// - /// 获取Logger对象(用于测试) - /// - public ILogger? GetLogger() - { - return Logger; - } - - /// - /// 初始化方法 - /// - protected override void OnInit() - { - Initialized = true; - InitCalled = true; - } - - /// - /// 销毁方法 - /// - protected override void OnDestroy() - { - Destroyed = true; - } -} - -/// -/// 测试用上下文工具类V2,自定义初始化逻辑 -/// -public sealed class TestContextUtilityV2 : AbstractContextUtility -{ - /// - /// 获取工具是否已初始化 - /// - public bool Initialized { get; private set; } - - /// - /// 获取工具是否已销毁 - /// - public bool Destroyed { get; set; } - - /// - /// 获取自定义初始化是否完成 - /// - public bool CustomInitializationDone { get; private set; } - - /// - /// 初始化方法(自定义逻辑) - /// - protected override void OnInit() - { - Initialized = true; - CustomInitializationDone = true; - } - - /// - /// 销毁方法 - /// - protected override void OnDestroy() - { - Destroyed = true; - } -} \ No newline at end of file diff --git a/GFramework.Core.Tests/Utility/TestContextUtilityV1.cs b/GFramework.Core.Tests/Utility/TestContextUtilityV1.cs new file mode 100644 index 00000000..370c8d77 --- /dev/null +++ b/GFramework.Core.Tests/Utility/TestContextUtilityV1.cs @@ -0,0 +1,51 @@ +using GFramework.Core.Abstractions.Logging; +using GFramework.Core.Utility; + +namespace GFramework.Core.Tests.Utility; + +/// +/// 为 提供的基础上下文工具测试桩。 +/// +public sealed class TestContextUtilityV1 : AbstractContextUtility +{ + /// + /// 获取一个值,该值指示当前工具是否已完成初始化。 + /// + public bool Initialized { get; private set; } + + /// + /// 获取或设置一个值,该值指示当前工具是否已执行销毁逻辑。 + /// + public bool Destroyed { get; set; } + + /// + /// 获取一个值,该值指示测试初始化钩子是否已被调用。 + /// + public bool InitCalled { get; private set; } + + /// + /// 获取初始化阶段创建的日志记录器,供测试断言使用。 + /// + /// 初始化后缓存的日志记录器;初始化前返回 + public ILogger? GetLogger() + { + return Logger; + } + + /// + /// 记录初始化已发生,并标记测试钩子调用状态。 + /// + protected override void OnInit() + { + Initialized = true; + InitCalled = true; + } + + /// + /// 记录销毁流程已运行,供生命周期测试断言使用。 + /// + protected override void OnDestroy() + { + Destroyed = true; + } +} diff --git a/GFramework.Core.Tests/Utility/TestContextUtilityV2.cs b/GFramework.Core.Tests/Utility/TestContextUtilityV2.cs new file mode 100644 index 00000000..ce683b1e --- /dev/null +++ b/GFramework.Core.Tests/Utility/TestContextUtilityV2.cs @@ -0,0 +1,41 @@ +using GFramework.Core.Utility; + +namespace GFramework.Core.Tests.Utility; + +/// +/// 为 提供的自定义初始化上下文工具测试桩。 +/// +public sealed class TestContextUtilityV2 : AbstractContextUtility +{ + /// + /// 获取一个值,该值指示当前工具是否已完成初始化。 + /// + public bool Initialized { get; private set; } + + /// + /// 获取或设置一个值,该值指示当前工具是否已执行销毁逻辑。 + /// + public bool Destroyed { get; set; } + + /// + /// 获取一个值,该值指示自定义初始化步骤是否已完成。 + /// + public bool CustomInitializationDone { get; private set; } + + /// + /// 在基础初始化期间记录自定义初始化步骤已执行。 + /// + protected override void OnInit() + { + Initialized = true; + CustomInitializationDone = true; + } + + /// + /// 记录销毁流程已运行,供生命周期测试断言使用。 + /// + protected override void OnDestroy() + { + Destroyed = true; + } +} diff --git a/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md b/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md index 55ad6417..e0876fca 100644 --- a/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md +++ b/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md @@ -6,18 +6,24 @@ ## 当前恢复点 -- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-084` -- 当前阶段:`Phase 84` +- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-085` +- 当前阶段:`Phase 85` - 当前焦点: - - `2026-04-27` 已完成 PR `#297` 的 CodeRabbit follow-up,修复 `YamlConfigLoader` 的取消语义与 `IntegerTryParseDelegate` 可空性问题 - - 已补齐 `GFramework.Core.Tests/Ioc` 与 `GFramework.Core.Tests/Query` 中 review 指向的 XML 文档缺口,并让 `IPrioritizedService` 复用 `IMixedService.Name` 契约 - - 已新增 `YamlConfigLoaderTests` 回归测试,锁定“取消时保留 `OperationCanceledException`”这一行为 - - 当前分支的下一波 warning reduction 仍建议回到 `ArchitectureContextTests.cs`、`AsyncQueryExecutorTests.cs` 或 `YamlConfigSchemaValidator*` 的后续 slice + - `2026-04-27` 已按 `$gframework-batch-boot 100` 连续执行多波 `MA0048` 小切片,当前以 `GFramework.Core.Tests` 的测试辅助类型拆分为主 + - 本轮已完成 `ArchitectureContextTests`、`AsyncQueryExecutorTests`、`CommandExecutorTests`、`StateTests`、`StateMachineTests`、`StateMachineSystemTests`、`ArchitectureModulesBehaviorTests`、`ArchitectureAdditionalCqrsHandlersTests`、`QueryCoroutineExtensionsTests`、`ObjectPoolTests`、`AbstractContextUtilityTests` 等低风险单文件切片 + - 当前仓库根权威基线已从 `353 Warning(s)` / `279` 个唯一位点下降到 `288 Warning(s)` / `214` 个唯一位点 + - 当前分支下一波更适合转向 `GameContextTests.cs`、`ArchitectureServicesTests.cs`、`RegistryInitializationHookBaseTests.cs` 这类仍在 `GFramework.Core.Tests` 内、但已混入 `CS8766` / `MA0016` 的小型混合切片 ## 当前活跃事实 -- 当前 `origin/main` 基线提交为 `b6a9fef`(`2026-04-27T10:53:34+08:00`)。 +- 当前 `origin/main` 基线提交为 `7cfdd2c`(`2026-04-27T16:59:57+08:00`)。 - 当前直接验证结果: + - `dotnet build GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release` + - 最新结果:成功;`0 Warning(s)`、`0 Error(s)` + - `dotnet clean` + - 最新结果:成功;已刷新仓库根 non-incremental 基线 + - `dotnet build` + - 最新结果:成功;`288 Warning(s)`、`0 Error(s)`,唯一位点 `214` - `dotnet build GFramework.Game/GFramework.Game.csproj -c Release` - 最新结果:成功;`0 Warning(s)`、`0 Error(s)` - `dotnet build GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release` @@ -29,18 +35,21 @@ - `dotnet format GFramework.sln --verify-no-changes --include GFramework.Game/Config/YamlConfigLoader.cs GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs GFramework.Core.Tests/Ioc/IMixedService.cs GFramework.Core.Tests/Ioc/IPrioritizedService.cs GFramework.Core.Tests/Ioc/PrioritizedService.cs GFramework.Core.Tests/Query/TestAsyncQueryWithExceptionV4.cs` - 最新结果:成功;本次 PR follow-up 改动文件无需额外格式化 - 当前批次摘要: - - 本轮完成 PR `#297` 最新 head review 中仍然有效的 `3` 个 open threads 修复:`YamlConfigLoader` 取消语义、`IMixedService.Name` XML 文档、`IPrioritizedService` 相关契约整理 - - 本轮同时吸收 CodeRabbit folded nitpick 中仍然成立的 `2` 个点:`IntegerTryParseDelegate` 可空性对齐、`TestAsyncQueryWithExceptionV4.OnDoAsync` 的 `` 文档 - - 本轮新增一条精确回归测试,确保底层 YAML 文件读取在取消时继续抛出 `OperationCanceledException` 系列异常,而不是包装成 `ConfigLoadException` + - 本轮通过多批并行 worker 共完成 `20+` 个 `GFramework.Core.Tests` 文件的测试辅助类型拆分,集中消化纯 `MA0048` warning 热点 + - 本轮停止时共享工作树共有 `61` 个变更条目,仍低于 `$gframework-batch-boot 100` 的文件停止线 + - 本轮仓库根权威 warning 已从开始时的 `353` 下降到 `288`,且 `GFramework.Core.Tests` 受影响项目的 Release 构建已恢复到 `0 Warning(s)` / `0 Error(s)` - 当前建议保留到下一波次的候选: - - `GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs` 的 `7` 个 `MA0048` - - `GFramework.Core.Tests/Query/AsyncQueryExecutorTests.cs` 的 `7` 个 `MA0048` + - `GFramework.Core.Tests/Architectures/GameContextTests.cs` 的 `4` 个 `CS8766` 与 `2` 个 `MA0048` + - `GFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs` 的 `4` 个 `CS8766` 与 `1` 个 `MA0048` + - `GFramework.Core.Tests/Architectures/RegistryInitializationHookBaseTests.cs` 的 `1` 个 `MA0016` 与 `5` 个 `MA0048` - `GFramework.Game/Config/YamlConfigSchemaValidator.cs` 与 `YamlConfigSchemaValidator.ObjectKeywords.cs` 的高耦合 warning 热点 ## 当前风险 - `GFramework.Cqrs.Tests/Mediator/*` 仍有 `47` / `44` / `34` 个唯一 warning 位点,属于高 changed-file 风险的 `MA0048` 大波次。 - 缓解措施:优先继续处理 `6-7` 个 warning 的小文件切片,避免一次性推高文件数。 +- `GameContextTests.cs`、`ArchitectureServicesTests.cs` 这类混合 `CS8766` / `MA0048` 文件不再适合继续用“纯拆分”模式批量下发。 + - 缓解措施:下一波由主线程先局部修正可空签名,再决定是否继续并行拆分。 - `YamlConfigSchemaValidator*` 仍然聚集多类高耦合 warning。 - 缓解措施:继续把它们留在独立波次,不与测试项目的低风险拆分混提。 @@ -67,6 +76,6 @@ ## 下一步建议 -1. 提交本轮 PR `#297` review follow-up 与 `ai-plan` 同步。 -2. 下一波优先挑选 `ArchitectureContextTests.cs` 或 `AsyncQueryExecutorTests.cs` 这类 `7`-warning 的纯 `MA0048` 单文件切片。 +1. 提交本轮多批 `MA0048` warning reduction 与 `ai-plan` 同步。 +2. 下一波由主线程先处理 `GameContextTests.cs` / `ArchitectureServicesTests.cs` 的 `CS8766`,再决定是否继续拆分剩余 `MA0048`。 3. 继续将 `YamlConfigSchemaValidator*` 与 `GFramework.Cqrs.Tests/Mediator/*` 作为独立高风险波次处理。 diff --git a/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md b/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md index 20ac885c..13a7b22c 100644 --- a/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md +++ b/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md @@ -1,5 +1,49 @@ # Analyzer Warning Reduction 追踪 +## 2026-04-27 — RP-085 + +### 阶段:按 `$gframework-batch-boot 100` 并行消化 `GFramework.Core.Tests` 低风险 `MA0048` + +- 触发背景: + - 用户要求以仓库根 non-incremental 构建 warning 为准,并在上下文可控前提下把小切片分派给多个 subagent 并行处理 + - 本轮开始时,当前分支与 `origin/main@7cfdd2c` 无提交差异,适合从纯 `MA0048` 单文件切片起步 +- 主线程实施: + - 执行权威基线:`dotnet clean` + 仓库根 `dotnet build` + - 初始结果:`353 Warning(s)`、唯一位点 `279` + - 分四波次并行下发 `GFramework.Core.Tests` 小切片,累计完成 `20+` 个文件的测试辅助类型拆分 + - 主线程持续复核共享工作树、处理并发编译阻断,并在每一轮后复跑 `GFramework.Core.Tests` Release 构建 + - 在工作树达到 `61` 个变更条目时主动停止扩批,保留对 `100` 文件停止线的充分余量 +- 代表性已落地切片: + - `ArchitectureContextTests.cs` + - `AsyncQueryExecutorTests.cs` + - `CommandExecutorTests.cs` + - `StateTests.cs` + - `StateMachineTests.cs` + - `StateMachineSystemTests.cs` + - `ArchitectureModulesBehaviorTests.cs` + - `ArchitectureAdditionalCqrsHandlersTests.cs` + - `QueryCoroutineExtensionsTests.cs` + - `ObjectPoolTests.cs` + - `AbstractContextUtilityTests.cs` + - `EnvironmentTests.cs` + - `EventBusTests.cs` + - `ContextAwareTests.cs` +- 验证里程碑: + - `dotnet build GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release` + - 结果:成功;`0 Warning(s)`、`0 Error(s)` + - `dotnet clean` + - 结果:成功 + - `dotnet build` + - 结果:成功;`288 Warning(s)`、`0 Error(s)`,唯一位点 `214` +- 当前结论: + - 本轮主要收益来自 `GFramework.Core.Tests` 内的纯 `MA0048` 大范围收敛 + - 仓库根权威 warning 已从 `353` 降到 `288`,唯一位点从 `279` 降到 `214` + - 下一波不再适合继续盲目平铺纯拆分,因为剩余 `GFramework.Core.Tests` 热点已开始混入 `CS8766` / `MA0016` +- 下一步: + 1. 提交本轮 warning reduction 与 `ai-plan` 同步。 + 2. 下一波优先由主线程处理 `GameContextTests.cs` / `ArchitectureServicesTests.cs` 的混合 warning。 + 3. 保持 `YamlConfigSchemaValidator*` 与 `GFramework.Cqrs.Tests/Mediator/*` 为独立高风险波次。 + ## 2026-04-27 — RP-084 ### 阶段:收敛 PR #297 的 CodeRabbit follow-up