diff --git a/GFramework.Core.Tests/Architectures/TestArchitectureContextBehaviorTests.cs b/GFramework.Core.Tests/Architectures/TestArchitectureContextBehaviorTests.cs index 4c0889a1..d784ab1d 100644 --- a/GFramework.Core.Tests/Architectures/TestArchitectureContextBehaviorTests.cs +++ b/GFramework.Core.Tests/Architectures/TestArchitectureContextBehaviorTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using GFramework.Core.Abstractions.Architectures; using GFramework.Core.Abstractions.Command; @@ -13,6 +14,16 @@ namespace GFramework.Core.Tests.Architectures; [TestFixture] public class TestArchitectureContextBehaviorTests { + private static IEnumerable EventContextFactories() + { + yield return new TestCaseData( + new Func(() => new TestArchitectureContext())) + .SetArgDisplayNames(nameof(TestArchitectureContext)); + yield return new TestCaseData( + new Func(() => new TestArchitectureContextV3())) + .SetArgDisplayNames(nameof(TestArchitectureContextV3)); + } + /// /// 验证测试上下文会把事件注册与发送委托到同一个事件总线实例。 /// @@ -43,6 +54,42 @@ public class TestArchitectureContextBehaviorTests Assert.That(eventReceived, Is.True); } + /// + /// 验证两类架构测试替身都会对事件 API 的空参数执行显式校验。 + /// + /// 创建待验证测试上下文的工厂。 + [TestCaseSource(nameof(EventContextFactories))] + public void Event_APIs_Should_Validate_Null_Arguments(Func createContext) + { + var context = createContext(); + + Assert.That(() => context.SendEvent(null!), Throws.TypeOf()); + Assert.That(() => context.RegisterEvent(null!), Throws.TypeOf()); + Assert.That(() => context.UnRegisterEvent(null!), Throws.TypeOf()); + } + + /// + /// 验证两类架构测试替身在注销事件处理器后都不会继续分发同一回调。 + /// + /// 创建待验证测试上下文的工厂。 + [TestCaseSource(nameof(EventContextFactories))] + public void UnRegisterEvent_Should_Stop_Dispatch(Func createContext) + { + var context = createContext(); + var eventReceived = false; + + void Handler(TestEventV2 _) + { + eventReceived = true; + } + + context.RegisterEvent(Handler); + context.UnRegisterEvent(Handler); + context.SendEvent(); + + Assert.That(eventReceived, Is.False); + } + /// /// 验证测试上下文的旧版命令与查询入口会显式抛出未支持异常。 /// diff --git a/GFramework.Core.Tests/Resource/TestResourceLoader.cs b/GFramework.Core.Tests/Resource/TestResourceLoader.cs index 05ef4d13..c31bf941 100644 --- a/GFramework.Core.Tests/Resource/TestResourceLoader.cs +++ b/GFramework.Core.Tests/Resource/TestResourceLoader.cs @@ -6,9 +6,9 @@ using GFramework.Core.Abstractions.Resource; namespace GFramework.Core.Tests.Resource; - /// - /// 为 ResourceManager 测试提供可控数据源的资源加载器。 - /// +/// +/// 为 ResourceManager 测试提供可控数据源的资源加载器。 +/// public class TestResourceLoader : IResourceLoader { private readonly Dictionary _resourceData = new(StringComparer.Ordinal); 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 f6f40fd8..bc0e5d04 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,36 +6,32 @@ ## 当前恢复点 -- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-089` -- 当前阶段:`Phase 89` +- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-090` +- 当前阶段:`Phase 90` - 当前焦点: - - `2026-04-28` 重新执行 `$gframework-pr-review`,确认 `PR #300` 最新 head 上仍显示 `6` 条 CodeRabbit open threads;其中 `Task.CompletedTask` 强转与 failed-test 信号已是 stale - - 本轮继续补齐仍然成立的差异:`TestArchitectureContextV3` 共享事件总线、`RegistryInitializationHookBase.OnPhase` XML 异常文档、`CapturingLoggerFactoryProvider.MinLevel` 同步,以及 active trace 归档瘦身 - - 已扩展 `TestArchitectureContextBehaviorTests.cs` 覆盖 `TestArchitectureContextV3` 的共享事件总线行为 - - 已新增 `CapturingLoggerFactoryProvider_Should_Apply_Updated_MinLevel_To_Subsequent_Loggers`,验证后续 logger 会读取更新后的最小级别 + - `2026-04-28` 再次执行 `$gframework-pr-review`,确认 `PR #300` 最新 head 仍显示 `6` 条 CodeRabbit open threads,但本地复核后只有事件 API 回归覆盖仍然成立 + - 已在 `TestArchitectureContextBehaviorTests.cs` 补齐 `UnRegisterEvent` 行为与 `SendEvent` / `RegisterEvent` / `UnRegisterEvent` 的空参数契约测试 + - 已整理 `TestResourceLoader.cs` 的命名空间缩进,收口本轮顺手处理的局部格式噪音 + - `dotnet format --verify-no-changes` 当前仍会暴露 `GFramework.Core.Tests` 项目里跨多个无关文件的既有 `FINALNEWLINE`、`CHARSET`、`WHITESPACE` 基线,本轮不扩展到整项目格式波次 ## 当前活跃事实 - 当前 `origin/main` 基线提交为 `6cc87a9`(`2026-04-27T20:28:50+08:00`)。 - 当前直接验证结果: - - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release` - - 最新结果:成功;`0 Warning(s)`、`0 Error(s)` - `dotnet build GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release` - 最新结果:成功;`0 Warning(s)`、`0 Error(s)` - - `dotnet build GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release` - - 最新结果:成功;`125 Warning(s)`、`0 Error(s)`;warning 仍集中在既有 `Mediator/*` 文件,不在本轮 PR review follow-up 写集内 - - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~TestArchitectureContextBehaviorTests|FullyQualifiedName~RegistryInitializationHookBaseTests"` - - 最新结果:成功;`11` 通过、`0` 失败 - - `dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~CqrsHandlerRegistrarTests"` - - 最新结果:成功;`12` 通过、`0` 失败 + - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~TestArchitectureContextBehaviorTests"` + - 最新结果:成功;`9` 通过、`0` 失败 + - `dotnet format GFramework.Core.Tests/GFramework.Core.Tests.csproj --verify-no-changes --no-restore` + - 最新结果:失败;暴露 `GFramework.Core.Tests` 项目中跨多个未触碰文件的既有 `FINALNEWLINE`、`CHARSET`、`WHITESPACE` 诊断,本轮新增写集未引入 `git diff --check` 异常 - 当前批次摘要: - - 当前工作树包含 `8` 个已修改文件和 `1` 个新增归档 trace 文件,全部来自 `Core` / `Core.Tests` / `Cqrs.Tests` / `ai-plan` 的 `PR #300` follow-up - - 本轮没有触碰 `Mediator/*` 或 `YamlConfigSchemaValidator*` 的高耦合 warning 波次 + - 当前工作树包含 `4` 个已修改文件,分别位于 `GFramework.Core.Tests` 与 `ai-plan/public/analyzer-warning-reduction` + - 本轮没有触碰 `Mediator/*`、`YamlConfigSchemaValidator*` 或 `GFramework.Core.Tests` 的整项目格式基线波次 ## 当前风险 -- `GFramework.Cqrs.Tests` 当前项目级 Release 构建仍有 `125` 条既有 warning,主要集中在 `MediatorArchitectureIntegrationTests.cs`、`MediatorAdvancedFeaturesTests.cs` 与 `MediatorComprehensiveTests.cs`。 - - 缓解措施:本轮仅记录为现存 blocker,不在 `PR #300` 的 review follow-up 里扩展到 `Mediator/*` warning reduction 波次。 +- `dotnet format GFramework.Core.Tests/GFramework.Core.Tests.csproj --verify-no-changes` 当前会命中项目内大量历史格式诊断。 + - 缓解措施:本轮只记录为现存基线,不把 `PR #300` 的 review follow-up 扩展成整项目格式清理。 - `GFramework.Game/Config/YamlConfigSchemaValidator*` 仍然是仓库根 warning 热点,但与本轮 review 修复无交集。 - 缓解措施:继续保持为独立高耦合波次。 @@ -58,12 +54,12 @@ ## 验证说明 - 权威验证结果统一维护在“当前活跃事实”。 -- `GFramework.Core` 与 `GFramework.Core.Tests` 的当前受影响项目 Release 构建都已清零,并通过对应定向测试回归。 -- `GFramework.Cqrs.Tests` 的本轮 helper 改动已由 `CqrsHandlerRegistrarTests` 回归覆盖,但项目级 Release 构建仍暴露 `Mediator/*` 的既有 warning。 +- `GFramework.Core.Tests` 的当前受影响项目 Release 构建已清零,并通过对应定向测试回归。 +- `git diff --check` 结果为空,说明本轮新增改动没有引入新的尾随空格或冲突标记。 - warning reduction 的仓库级真值只以同轮 `dotnet clean` 后的 `dotnet build` 为准。 ## 下一步建议 1. 提交本轮 `PR #300` review follow-up 与 `ai-plan` 同步。 -2. 若继续处理 `GFramework.Cqrs.Tests` warning,下一轮单独切到 `Mediator/*` 波次,并先接受当前 `125` 条 warning 作为显式基线。 -3. `YamlConfigSchemaValidator*` 继续保持为独立高耦合波次,不与 `Mediator/*` 混提。 +2. 若需要继续收口 PR 线程,可单独评估是否接受 `TestArchitectureContext` / `TestArchitectureContextV3` 的共享 helper nitpick。 +3. 若要清理 `dotnet format` 基线,另开 `GFramework.Core.Tests` 格式治理切片,不与当前 PR review 修复混提。 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 ce044c93..3f293957 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,40 +1,37 @@ # Analyzer Warning Reduction 追踪 -## 2026-04-28 — RP-089 +## 2026-04-28 — RP-090 -### 阶段:复核 `PR #300` 最新 review 真值并收敛仍然成立的本地差异 +### 阶段:复核 `PR #300` 最新 review 真值并补齐事件 API 回归覆盖 - 触发背景: - 用户再次执行 `$gframework-pr-review` - - `fetch_current_pr_review.py --json-output /tmp/current-pr-review.json` 返回 `PR #300`,latest head 仍显示 `6` 条 CodeRabbit open threads;其中 `Task.CompletedTask` 强转与 failed-test 信号已是 stale,本地仍需处理的是 `TestArchitectureContextV3` 事件语义、`RegistryInitializationHookBase.OnPhase` XML 异常文档、`CapturingLoggerFactoryProvider.MinLevel` 同步,以及 active trace 过长问题 + - `fetch_current_pr_review.py --json-output /tmp/gframework-current-pr-review.json` 返回 `PR #300`,latest head 仍显示 `6` 条 CodeRabbit open threads;本地复核后,`Task.CompletedTask` 强转、`RegisterLifecycleHook` 语义、`TestResourceLoader` 文档与 `PartialGeneratedNotificationHandlerRegistry` XML 契约都已在当前 head 上成立,唯一仍未锁住的是事件 API 回归覆盖 - 主线程实施: - - 将 `TestArchitectureContextV3` 的事件发送/注册/注销统一接入共享 `EventBus`,避免静默 no-op - - 为 `RegistryInitializationHookBase.OnPhase` 补充 `ArgumentNullException` 异常契约 - - 让 `CapturingLoggerFactoryProvider.MinLevel` 与 `CreateLogger` 共享同一把锁,并新增回归测试覆盖更新后的最小级别行为 - - 将 active trace 的 `RP-083` ~ `RP-088` 迁移到 [analyzer-warning-reduction-history-rp083-rp088.md](../archive/traces/analyzer-warning-reduction-history-rp083-rp088.md),恢复单一恢复入口 + - 为 `TestArchitectureContext` 与 `TestArchitectureContextV3` 新增共享测试数据源,补齐 `SendEvent` / `RegisterEvent` / `UnRegisterEvent` 的空参数异常契约 + - 新增 `UnRegisterEvent_Should_Stop_Dispatch` 回归测试,防止后续把注销路径退化成 `no-op` + - 整理 `TestResourceLoader.cs` 的命名空间缩进,避免当前修改继续叠加局部格式噪音 - 验证里程碑: - - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release` - - 结果:成功;`0 Warning(s)`、`0 Error(s)` - `dotnet build GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release` - 结果:成功;`0 Warning(s)`、`0 Error(s)` - - `dotnet build GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release` - - 结果:成功;`125 Warning(s)`、`0 Error(s)`;warning 仍全部集中在既有 `Mediator/*` 文件 - - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~TestArchitectureContextBehaviorTests|FullyQualifiedName~RegistryInitializationHookBaseTests"` - - 结果:成功;`11` 通过、`0` 失败 - - `dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~CqrsHandlerRegistrarTests"` - - 结果:成功;`12` 通过、`0` 失败 + - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~TestArchitectureContextBehaviorTests"` + - 结果:成功;`9` 通过、`0` 失败 + - `dotnet format GFramework.Core.Tests/GFramework.Core.Tests.csproj --verify-no-changes --no-restore` + - 结果:失败;输出落在 `ObjectExtensionsTests.cs`、多处 `FINALNEWLINE` 与若干 `CHARSET` 基线文件,均不属于本轮写集 + - `git diff --check` + - 结果:成功;无新增 whitespace / conflict-marker 问题 ## 活跃风险 -- `GFramework.Cqrs.Tests/Mediator/*` 仍保留 `125` 条既有 warning。 - - 缓解措施:保持为下一轮独立 warning reduction 波次,不把当前 PR review follow-up 扩展到 `Mediator/*` 写集。 - GitHub PR 上的 open threads 在本地提交前仍可能显示为未关闭。 - 缓解措施:以当前工作树和定向验证作为真值,推送后再让 PR 线程重新比对最新 head。 +- `GFramework.Core.Tests` 项目当前存在独立于本轮改动的 `dotnet format` 基线。 + - 缓解措施:保持为后续单独格式治理切片,不在当前 PR review follow-up 中扩写。 ## 下一步 1. 提交本轮 `PR #300` follow-up 与 `ai-plan` 同步。 -2. 若继续推进 warning reduction,下一轮单独规划 `Mediator/*` 切片。 +2. 若继续收口 PR 线程,单独评估是否接受 `TestArchitectureContext` / `TestArchitectureContextV3` 的共享 helper nitpick。 ## 历史归档指针