mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
fix(game-tests): 收敛 Game.Tests 测试告警
- 修复多组 YAML 与 persistence 测试中的 ConfigureAwait 使用与状态校验,清理低风险 analyzer 告警 - 重构 PersistenceTestUtilities 为单类型文件,消除测试辅助模型的文件命名告警 - 更新 analyzer-warning-reduction 跟踪与 trace,记录 RP-054 批次结果与 75 文件阈值停止点
This commit is contained in:
parent
6ff07ad3d9
commit
36507bbc52
@ -90,7 +90,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -124,7 +124,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterAllOfConfigStub>("monster");
|
||||
var reward = table.Get(1).Reward;
|
||||
@ -165,7 +165,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -210,7 +210,10 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
}
|
||||
""");
|
||||
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
var loader = new YamlConfigLoader(_rootPath)
|
||||
.RegisterTable<int, MonsterTagConfigStub>(
|
||||
@ -220,7 +223,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
static config => config.Id);
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -255,7 +258,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -295,7 +298,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -335,7 +338,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -375,7 +378,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -415,7 +418,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -455,7 +458,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -499,7 +502,7 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
|
||||
@ -75,7 +75,7 @@ public sealed class YamlConfigLoaderDependentRequiredTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -124,7 +124,7 @@ public sealed class YamlConfigLoaderDependentRequiredTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterRewardConfigStub>("monster");
|
||||
Assert.That(table.Count, Is.EqualTo(1));
|
||||
@ -169,7 +169,7 @@ public sealed class YamlConfigLoaderDependentRequiredTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterRewardConfigStub>("monster");
|
||||
var reward = table.Get(1).Reward;
|
||||
@ -217,7 +217,7 @@ public sealed class YamlConfigLoaderDependentRequiredTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -267,7 +267,7 @@ public sealed class YamlConfigLoaderDependentRequiredTests
|
||||
var loader = CreateCaseSensitiveRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -317,7 +317,7 @@ public sealed class YamlConfigLoaderDependentRequiredTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
|
||||
@ -74,7 +74,7 @@ public sealed class YamlConfigLoaderDependentSchemasTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -106,7 +106,7 @@ public sealed class YamlConfigLoaderDependentSchemasTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterDependentSchemasConfigStub>("monster");
|
||||
Assert.That(table.Count, Is.EqualTo(1));
|
||||
@ -133,7 +133,7 @@ public sealed class YamlConfigLoaderDependentSchemasTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterDependentSchemasConfigStub>("monster");
|
||||
var reward = table.Get(1).Reward;
|
||||
@ -174,7 +174,7 @@ public sealed class YamlConfigLoaderDependentSchemasTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -220,7 +220,7 @@ public sealed class YamlConfigLoaderDependentSchemasTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -264,7 +264,7 @@ public sealed class YamlConfigLoaderDependentSchemasTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -283,7 +283,10 @@ public sealed class YamlConfigLoaderDependentSchemasTests
|
||||
/// <param name="content">要写入的 YAML 或 schema 内容。</param>
|
||||
private void CreateConfigFile(string relativePath, string content)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
var filePath = Path.Combine(_rootPath, relativePath.Replace('/', Path.DirectorySeparatorChar));
|
||||
var directoryPath = Path.GetDirectoryName(filePath);
|
||||
@ -353,7 +356,10 @@ public sealed class YamlConfigLoaderDependentSchemasTests
|
||||
/// <returns>已注册测试表与 schema 路径的加载器。</returns>
|
||||
private YamlConfigLoader CreateMonsterRewardLoader()
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
return new YamlConfigLoader(_rootPath)
|
||||
.RegisterTable<int, MonsterDependentSchemasConfigStub>(
|
||||
|
||||
@ -75,7 +75,7 @@ public class YamlConfigLoaderEnumTests
|
||||
var loader = CreateLoader<MonsterRewardConfigStub>();
|
||||
var registry = new ConfigRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterRewardConfigStub>("monster");
|
||||
Assert.Multiple(() =>
|
||||
@ -127,7 +127,7 @@ public class YamlConfigLoaderEnumTests
|
||||
var loader = CreateLoader<MonsterRewardConfigStub>();
|
||||
var registry = new ConfigRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -176,7 +176,7 @@ public class YamlConfigLoaderEnumTests
|
||||
var loader = CreateLoader<MonsterDropItemIdsConfigStub>();
|
||||
var registry = new ConfigRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
|
||||
@ -105,7 +105,7 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -137,7 +137,7 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterConditionalConfigStub>("monster");
|
||||
var reward = table.Get(1).Reward;
|
||||
@ -170,7 +170,7 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -202,7 +202,7 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterConditionalConfigStub>("monster");
|
||||
var reward = table.Get(1).Reward;
|
||||
@ -250,7 +250,10 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
}
|
||||
""");
|
||||
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
var loader = new YamlConfigLoader(_rootPath)
|
||||
.RegisterTable<int, MonsterTagConfigStub>(
|
||||
@ -260,7 +263,7 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
static config => config.Id);
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -301,7 +304,7 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -342,7 +345,7 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -390,7 +393,7 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -409,7 +412,10 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
/// <param name="content">配置文件内容。</param>
|
||||
private void CreateConfigFile(string relativePath, string content)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
var filePath = Path.Combine(_rootPath, relativePath.Replace('/', Path.DirectorySeparatorChar));
|
||||
var directoryPath = Path.GetDirectoryName(filePath);
|
||||
@ -496,7 +502,10 @@ public sealed class YamlConfigLoaderIfThenElseTests
|
||||
/// <returns>已注册测试表与 schema 路径的加载器。</returns>
|
||||
private YamlConfigLoader CreateMonsterRewardLoader()
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
return new YamlConfigLoader(_rootPath)
|
||||
.RegisterTable<int, MonsterConditionalConfigStub>(
|
||||
|
||||
@ -70,7 +70,7 @@ public sealed class YamlConfigLoaderNegationTests
|
||||
var loader = CreateMonsterLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -118,7 +118,7 @@ public sealed class YamlConfigLoaderNegationTests
|
||||
var loader = CreateMonsterLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterConfigStub>("monster");
|
||||
|
||||
@ -172,7 +172,7 @@ public sealed class YamlConfigLoaderNegationTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -227,7 +227,7 @@ public sealed class YamlConfigLoaderNegationTests
|
||||
var loader = CreateMonsterRewardLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
await loader.LoadAsync(registry);
|
||||
await loader.LoadAsync(registry).ConfigureAwait(false);
|
||||
|
||||
var table = registry.GetTable<int, MonsterRewardConfigStub>("monster");
|
||||
|
||||
@ -272,7 +272,7 @@ public sealed class YamlConfigLoaderNegationTests
|
||||
var loader = CreateMonsterLoader();
|
||||
var registry = CreateRegistry();
|
||||
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
|
||||
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry).ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
|
||||
@ -191,7 +191,10 @@ public sealed class YamlConfigSchemaValidatorTests
|
||||
string relativePath,
|
||||
string content)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
var fullPath = Path.Combine(_rootPath, relativePath.Replace('/', Path.DirectorySeparatorChar));
|
||||
var directoryPath = Path.GetDirectoryName(fullPath);
|
||||
|
||||
@ -132,7 +132,7 @@ public sealed class YamlConfigTextValidatorTests
|
||||
"monster/generated.yaml",
|
||||
"""
|
||||
id: 1
|
||||
"""));
|
||||
""").ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
|
||||
@ -1,114 +0,0 @@
|
||||
using System;
|
||||
using GFramework.Game.Abstractions.Data;
|
||||
using GFramework.Game.Abstractions.Enums;
|
||||
|
||||
namespace GFramework.Game.Tests.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 为持久化测试提供稳定的测试数据位置实现。
|
||||
/// </summary>
|
||||
internal sealed class TestDataLocation : IDataLocation
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化测试数据位置。
|
||||
/// </summary>
|
||||
/// <param name="key">测试使用的存储键。</param>
|
||||
/// <param name="kinds">测试使用的存储类型。</param>
|
||||
/// <param name="namespaceValue">测试使用的命名空间。</param>
|
||||
/// <param name="metadata">附加测试元数据。</param>
|
||||
public TestDataLocation(
|
||||
string key,
|
||||
StorageKinds kinds = StorageKinds.Local,
|
||||
string? namespaceValue = null,
|
||||
IReadOnlyDictionary<string, string>? metadata = null)
|
||||
{
|
||||
Key = key;
|
||||
Kinds = kinds;
|
||||
Namespace = namespaceValue;
|
||||
Metadata = metadata;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取测试数据对应的存储键。
|
||||
/// </summary>
|
||||
public string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取测试数据使用的存储类型。
|
||||
/// </summary>
|
||||
public StorageKinds Kinds { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取测试数据使用的命名空间。
|
||||
/// </summary>
|
||||
public string? Namespace { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取附加到测试位置上的元数据。
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, string>? Metadata { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为基础存档仓库测试提供的简单存档模型。
|
||||
/// </summary>
|
||||
internal sealed class TestSaveData : IData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档中的名称字段。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为存档迁移测试提供的版本化存档模型。
|
||||
/// </summary>
|
||||
internal sealed class TestVersionedSaveData : IVersionedData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档中的名称字段。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档中的等级字段。
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档中的经验字段。
|
||||
/// </summary>
|
||||
public int Experience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置当前测试存档的版本号。
|
||||
/// </summary>
|
||||
public int Version { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档的最后修改时间。
|
||||
/// </summary>
|
||||
public DateTime LastModified { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为通用持久化测试提供的简单数据模型。
|
||||
/// </summary>
|
||||
internal sealed class TestSimpleData : IData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置测试数据中的整数值。
|
||||
/// </summary>
|
||||
public int Value { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为批量持久化测试提供的另一种数据模型,用于验证运行时类型不会在接口路径上退化。
|
||||
/// </summary>
|
||||
internal sealed class TestNamedData : IData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置测试数据中的名称值。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
@ -38,12 +38,12 @@ public class PersistenceTests
|
||||
using var storage = new FileStorage(root, new JsonSerializer(), ".json");
|
||||
|
||||
var saved = new TestSimpleData { Value = 5 };
|
||||
await storage.WriteAsync("folder/item", saved);
|
||||
await storage.WriteAsync("folder/item", saved).ConfigureAwait(false);
|
||||
|
||||
var loaded = await storage.ReadAsync<TestSimpleData>("folder/item");
|
||||
var loaded = await storage.ReadAsync<TestSimpleData>("folder/item").ConfigureAwait(false);
|
||||
Assert.That(loaded.Value, Is.EqualTo(saved.Value));
|
||||
|
||||
Assert.ThrowsAsync<ArgumentException>(async () => await storage.WriteAsync("../escape", new TestSimpleData()));
|
||||
Assert.ThrowsAsync<ArgumentException>(async () => await storage.WriteAsync("../escape", new TestSimpleData()).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -108,7 +108,7 @@ public class PersistenceTests
|
||||
.RegisterMigration(new TestSaveMigrationV2ToV3());
|
||||
|
||||
var loaded = await repository.LoadAsync(1);
|
||||
var persisted = await storage.ReadAsync<TestVersionedSaveData>("saves/slot_1/save");
|
||||
var persisted = await storage.ReadAsync<TestVersionedSaveData>("saves/slot_1/save").ConfigureAwait(false);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -185,7 +185,7 @@ public class PersistenceTests
|
||||
var repository = new SaveRepository<TestVersionedSaveData>(storage, config)
|
||||
.RegisterMigration(new TestSaveMigrationV1ToV2());
|
||||
|
||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(async () => await repository.LoadAsync(1));
|
||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(async () => await repository.LoadAsync(1).ConfigureAwait(false));
|
||||
Assert.That(exception!.Message, Does.Contain("from version 2"));
|
||||
}
|
||||
|
||||
@ -218,8 +218,8 @@ public class PersistenceTests
|
||||
var repository = new SaveRepository<TestVersionedSaveData>(storage, config)
|
||||
.RegisterMigration(new TestSaveMigrationV1ToV2ReturningV3());
|
||||
|
||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(async () => await repository.LoadAsync(1));
|
||||
var persisted = await storage.ReadAsync<TestVersionedSaveData>("saves/slot_1/save");
|
||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(async () => await repository.LoadAsync(1).ConfigureAwait(false));
|
||||
var persisted = await storage.ReadAsync<TestVersionedSaveData>("saves/slot_1/save").ConfigureAwait(false);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -270,7 +270,7 @@ public class PersistenceTests
|
||||
repository.RegisterMigration(new TestSaveMigrationV2ToV3());
|
||||
continueMigration.Set();
|
||||
|
||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(async () => await loadTask);
|
||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(async () => await loadTask.ConfigureAwait(false));
|
||||
var persisted = await storage.ReadAsync<TestVersionedSaveData>("saves/slot_1/save");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
|
||||
49
GFramework.Game.Tests/Data/TestDataLocation.cs
Normal file
49
GFramework.Game.Tests/Data/TestDataLocation.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using GFramework.Game.Abstractions.Data;
|
||||
using GFramework.Game.Abstractions.Enums;
|
||||
|
||||
namespace GFramework.Game.Tests.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 为持久化测试提供稳定的测试数据位置实现。
|
||||
/// </summary>
|
||||
internal sealed class TestDataLocation : IDataLocation
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化测试数据位置。
|
||||
/// </summary>
|
||||
/// <param name="key">测试使用的存储键。</param>
|
||||
/// <param name="kinds">测试使用的存储类型。</param>
|
||||
/// <param name="namespaceValue">测试使用的命名空间。</param>
|
||||
/// <param name="metadata">附加测试元数据。</param>
|
||||
public TestDataLocation(
|
||||
string key,
|
||||
StorageKinds kinds = StorageKinds.Local,
|
||||
string? namespaceValue = null,
|
||||
IReadOnlyDictionary<string, string>? metadata = null)
|
||||
{
|
||||
Key = key;
|
||||
Kinds = kinds;
|
||||
Namespace = namespaceValue;
|
||||
Metadata = metadata;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取测试数据对应的存储键。
|
||||
/// </summary>
|
||||
public string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取测试数据使用的存储类型。
|
||||
/// </summary>
|
||||
public StorageKinds Kinds { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取测试数据使用的命名空间。
|
||||
/// </summary>
|
||||
public string? Namespace { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取附加到测试位置上的元数据。
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, string>? Metadata { get; }
|
||||
}
|
||||
14
GFramework.Game.Tests/Data/TestNamedData.cs
Normal file
14
GFramework.Game.Tests/Data/TestNamedData.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using GFramework.Game.Abstractions.Data;
|
||||
|
||||
namespace GFramework.Game.Tests.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 为批量持久化测试提供的另一种数据模型,用于验证运行时类型不会在接口路径上退化。
|
||||
/// </summary>
|
||||
internal sealed class TestNamedData : IData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置测试数据中的名称值。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
14
GFramework.Game.Tests/Data/TestSaveData.cs
Normal file
14
GFramework.Game.Tests/Data/TestSaveData.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using GFramework.Game.Abstractions.Data;
|
||||
|
||||
namespace GFramework.Game.Tests.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 为基础存档仓库测试提供的简单存档模型。
|
||||
/// </summary>
|
||||
internal sealed class TestSaveData : IData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档中的名称字段。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
14
GFramework.Game.Tests/Data/TestSimpleData.cs
Normal file
14
GFramework.Game.Tests/Data/TestSimpleData.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using GFramework.Game.Abstractions.Data;
|
||||
|
||||
namespace GFramework.Game.Tests.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 为通用持久化测试提供的简单数据模型。
|
||||
/// </summary>
|
||||
internal sealed class TestSimpleData : IData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置测试数据中的整数值。
|
||||
/// </summary>
|
||||
public int Value { get; set; }
|
||||
}
|
||||
35
GFramework.Game.Tests/Data/TestVersionedSaveData.cs
Normal file
35
GFramework.Game.Tests/Data/TestVersionedSaveData.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using GFramework.Game.Abstractions.Data;
|
||||
|
||||
namespace GFramework.Game.Tests.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 为存档迁移测试提供的版本化存档模型。
|
||||
/// </summary>
|
||||
internal sealed class TestVersionedSaveData : IVersionedData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档中的名称字段。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档中的等级字段。
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档中的经验字段。
|
||||
/// </summary>
|
||||
public int Experience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置当前测试存档的版本号。
|
||||
/// </summary>
|
||||
public int Version { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置测试存档的最后修改时间。
|
||||
/// </summary>
|
||||
public DateTime LastModified { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
@ -6,34 +6,35 @@
|
||||
|
||||
## 当前恢复点
|
||||
|
||||
- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-053`
|
||||
- 当前阶段:`Phase 53`
|
||||
- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-054`
|
||||
- 当前阶段:`Phase 54`
|
||||
- 当前焦点:
|
||||
- `2026-04-24` 本轮按 `$gframework-batch-boot 75` 重新建立当前分支相对 `origin/main` 的 batch 基线,并从整仓 `Release` build 里挑选低风险热点
|
||||
- `GFramework.Godot` 已完成一轮独立 warning 清理:`GodotYamlConfigEnvironment` 的目录枚举逻辑已拆分 helper,`AbstractArchitecture` / `SceneBehaviorBase` 中需要保留 Godot 同步上下文的 await 已显式改为 `.ConfigureAwait(true)`
|
||||
- `GFramework.Godot.Tests` 已同步清理对应测试 warning:异步断言显式使用 `.ConfigureAwait(false)`,`RichTextMarkupTests` 中测试字典显式指定 `StringComparer.Ordinal`
|
||||
- 当前代码批次相对 `origin/main` 的待提交 diff 为 `6` 个文件、`107` 行变更,远低于 `$gframework-batch-boot 75` 的主停止阈值;本轮在这里收口,是因为下一批候选将进入 `GFramework.Game` 等高基线模块,而不再是同等级低风险切片
|
||||
- `2026-04-24` 本轮继续按 `$gframework-batch-boot 75` 推进,切入 `GFramework.Game.Tests` 的低风险测试 warning,而不进入 `YamlConfigLoaderTests.cs` 等高上下文热点
|
||||
- 已完成 `PersistenceTestUtilities` 的单类型拆分,并在多组 YAML / persistence 测试中补齐 `.ConfigureAwait(false)` 与字段态显式状态检查
|
||||
- `GFramework.Game.Tests` 当前 `Release` build 已从本轮入口观测值 `116 warning(s)` 收敛到 `71 warning(s)`,且本轮 touched files 已不再出现在 warning 输出里
|
||||
- 当前工作树相对 `origin/main` 的累计 diff 已达到 `76` 个文件、`986` 行变更,超过 `$gframework-batch-boot 75` 的主停止阈值;本轮必须在提交后停止继续扩批
|
||||
|
||||
## 当前活跃事实
|
||||
|
||||
- 之前记录的 plain `dotnet build` `0 Warning(s)` 属于增量构建假阴性,不能再作为 warning 检查真值
|
||||
- 本轮直接执行仓库根目录 `dotnet clean` 仍在 `ValidateSolutionConfiguration` 阶段失败,输出未提供具体 error 文本
|
||||
- 本轮直接执行仓库根目录 `dotnet build GFramework.sln -c Release` 成功,并给出 `1122 warning(s)` 的当前整仓观测值
|
||||
- `GFramework.Godot/GFramework.Godot.csproj -c Release` 在本轮收尾验证中已达到 `0 Warning(s)`、`0 Error(s)`
|
||||
- `GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release` 在串行复验中已达到 `0 Warning(s)`、`0 Error(s)`
|
||||
- 本轮已验证 `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~AbstractArchitectureModuleInstallationTests|FullyQualifiedName~GodotYamlConfigLoaderTests|FullyQualifiedName~RichTextMarkupTests"`,结果为 `Passed: 15`
|
||||
- `GFramework.Godot` 原先暴露的 `MA0051` 与 `MA0004` 热点都已清理完成;当前同域低风险切片基本耗尽
|
||||
- 本轮直接执行仓库根目录 `dotnet build GFramework.sln -c Release` 成功,并给出 `116 warning(s)` 的当前整仓入口观测值;其中低风险热点主要落在 `GFramework.Game.Tests`
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release` 在本轮收尾验证中为 `71 Warning(s)`、`0 Error(s)`;剩余 warning 已集中在未触碰的 `YamlConfigLoaderTests.cs`、`GeneratedConfigConsumerIntegrationTests.cs`、`GameConfigBootstrapTests.cs`、`ArchitectureConfigIntegrationTests.cs`、`JsonSerializerTests.cs`
|
||||
- 本轮已验证 `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~YamlConfigLoaderIfThenElseTests|FullyQualifiedName~YamlConfigLoaderDependentSchemasTests|FullyQualifiedName~YamlConfigLoaderDependentRequiredTests|FullyQualifiedName~YamlConfigLoaderNegationTests|FullyQualifiedName~YamlConfigLoaderAllOfTests|FullyQualifiedName~YamlConfigLoaderEnumTests|FullyQualifiedName~YamlConfigTextValidatorTests|FullyQualifiedName~YamlConfigSchemaValidatorTests|FullyQualifiedName~PersistenceTests"`,结果为 `Passed: 63`
|
||||
- `PersistenceTestUtilities.cs` 已拆分为 `TestDataLocation.cs`、`TestSaveData.cs`、`TestVersionedSaveData.cs`、`TestSimpleData.cs`、`TestNamedData.cs`,与仓库“一文件一主类型”风格对齐
|
||||
|
||||
## 当前风险
|
||||
|
||||
- 如果后续继续依赖增量 `dotnet build`,容易再次把 warning 数量误判为 0
|
||||
- 缓解措施:每轮 warning 检查前先执行 `dotnet clean`,再执行目标 `dotnet build`
|
||||
- 仓库根目录 `dotnet clean` 目前仍然无法给出新的 clean 基线
|
||||
- 缓解措施:若下一轮继续做整仓 warning reduction,先定位 `dotnet clean` 的 solution-level 失败原因,或明确继续沿用用户确认的 `1193 warning(s)` clean 基线与本轮 `1122 warning(s)` direct build 观测值
|
||||
- 缓解措施:若下一轮继续做整仓 warning reduction,先定位 `dotnet clean` 的 solution-level / project-level 失败原因,或明确继续沿用用户确认的 `1193 warning(s)` clean 基线与本轮 direct build 观测值
|
||||
- 当前 worktree 仍存在未跟踪的 `.codex` 目录
|
||||
- 缓解措施:提交当前批次时只暂存 analyzer-warning-reduction 相关源码与 `ai-plan` 文件,避免把工作目录辅助文件混入提交
|
||||
- 下一轮最明显的剩余热点将转入 `GFramework.Game` 等高 warning 基线模块
|
||||
- 缓解措施:恢复时先重新跑整仓 build 热点筛选,再决定是否接受更高上下文成本的 `GFramework.Game` 切片,或先排查 solution-level clean 失败原因
|
||||
- 当前批次已触发 `$gframework-batch-boot 75` 的主停止条件
|
||||
- 缓解措施:本轮提交后停止继续扩批;下一次继续前先评估是否需要基于更新后的 `origin/main` 重新选择基线,或切到新分支 / 新轮次处理剩余 `GFramework.Game.Tests` 热点
|
||||
- `GFramework.Game.Tests` 的剩余 warning 主要集中在大文件与集成测试文件
|
||||
- 缓解措施:后续若继续,优先把 `YamlConfigLoaderTests.cs` 单独作为一个高上下文切片处理,不要和其它 warning family 混批
|
||||
|
||||
## 活跃文档
|
||||
|
||||
@ -52,16 +53,15 @@
|
||||
- `dotnet clean GFramework.sln -c Release`
|
||||
- 结果:失败;停在 solution `ValidateSolutionConfiguration`,`0 Warning(s)`、`0 Error(s)`,未输出更具体的 error 文本
|
||||
- `dotnet build GFramework.sln -c Release`
|
||||
- 结果:成功;`1122 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet build GFramework.Godot/GFramework.Godot.csproj -c Release`
|
||||
- 结果:成功;`0 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet test GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release --filter "FullyQualifiedName~AbstractArchitectureModuleInstallationTests|FullyQualifiedName~GodotYamlConfigLoaderTests|FullyQualifiedName~RichTextMarkupTests"`
|
||||
- 结果:成功;`Passed: 15`、`Failed: 0`
|
||||
- `dotnet build GFramework.Godot.Tests/GFramework.Godot.Tests.csproj -c Release`
|
||||
- 首次并行验证:成功;`1 Warning(s)`、`0 Error(s)`;`MSB3026` 来自与并行 `dotnet test` 竞争同一输出 DLL
|
||||
- 串行复验:成功;`0 Warning(s)`、`0 Error(s)`
|
||||
- 结果:成功;`116 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet clean GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- 结果:失败;clean 阶段在 MSBuild 清理路径结束前返回 `0 Warning(s)`、`0 Error(s)`,未输出额外错误文本
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- 结果:成功;`71 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~YamlConfigLoaderIfThenElseTests|FullyQualifiedName~YamlConfigLoaderDependentSchemasTests|FullyQualifiedName~YamlConfigLoaderDependentRequiredTests|FullyQualifiedName~YamlConfigLoaderNegationTests|FullyQualifiedName~YamlConfigLoaderAllOfTests|FullyQualifiedName~YamlConfigLoaderEnumTests|FullyQualifiedName~YamlConfigTextValidatorTests|FullyQualifiedName~YamlConfigSchemaValidatorTests|FullyQualifiedName~PersistenceTests"`
|
||||
- 结果:成功;`Passed: 63`、`Failed: 0`
|
||||
|
||||
## 下一步建议
|
||||
|
||||
1. 提交当前 `GFramework.Godot` / `GFramework.Godot.Tests` warning 清理批次,并继续保持只纳入本 topic 相关文件
|
||||
2. 下一轮若继续使用 `$gframework-batch-boot 75`,先决定是优先排查 solution-level `dotnet clean` 失败,还是接受更高上下文成本进入 `GFramework.Game` warning 热点
|
||||
1. 提交当前 `GFramework.Game.Tests` warning 清理批次与 `RP-054` tracking 更新,然后停止当前 batch loop,因为 branch diff 已达 `76/75`
|
||||
2. 下一轮若继续 warning reduction,应先决定是重新整理 `origin/main` 基线,还是单独开一个高上下文批次处理 `YamlConfigLoaderTests.cs`
|
||||
|
||||
@ -2,6 +2,36 @@
|
||||
|
||||
# Analyzer Warning Reduction 追踪
|
||||
|
||||
## 2026-04-24 — RP-054
|
||||
|
||||
### 阶段:`GFramework.Game.Tests` 低风险测试 warning 批次(触发文件数停止阈值)
|
||||
|
||||
- 触发背景:
|
||||
- 用户要求“直接进入下一批”,继续沿 `$gframework-batch-boot 75` 自动推进 warning reduction
|
||||
- 以 `origin/main` 为基线时,上一批提交后分支累计 diff 仍只有 `8` 个文件,足够再落一个独立批次
|
||||
- 重新执行 `dotnet clean GFramework.sln -c Release` 仍停在 `ValidateSolutionConfiguration`,因此继续以直接 `dotnet build GFramework.sln -c Release` 的输出挑选低风险热点
|
||||
- 主线程实施:
|
||||
- 从整仓 `Release build` 的 `116 warning(s)` 入口观测值中,选择 `GFramework.Game.Tests` 的小型测试文件和 `PersistenceTestUtilities.cs` 作为当前批次,刻意避开 `YamlConfigLoaderTests.cs` 这类高上下文大文件
|
||||
- 在 `YamlConfigLoaderIfThenElseTests.cs`、`YamlConfigLoaderDependentSchemasTests.cs`、`YamlConfigLoaderDependentRequiredTests.cs`、`YamlConfigLoaderNegationTests.cs`、`YamlConfigLoaderAllOfTests.cs`、`YamlConfigLoaderEnumTests.cs`、`YamlConfigTextValidatorTests.cs`、`PersistenceTests.cs` 中补齐 `.ConfigureAwait(false)`,并把字段态 `_rootPath` 的 `ThrowIfNull` 改为显式 `InvalidOperationException`
|
||||
- 将 `PersistenceTestUtilities.cs` 拆分为 `TestDataLocation.cs`、`TestSaveData.cs`、`TestVersionedSaveData.cs`、`TestSimpleData.cs`、`TestNamedData.cs`,消除 `MA0048` 并对齐仓库的一文件一主类型风格
|
||||
- 在 `YamlConfigSchemaValidatorTests.cs` 中把字段态 `_rootPath` 的校验改成显式状态异常,避免继续触发 `MA0015`
|
||||
- 验证里程碑:
|
||||
- `dotnet clean GFramework.sln -c Release`
|
||||
- 结果:失败;停在 `ValidateSolutionConfiguration`,`0 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet build GFramework.sln -c Release`
|
||||
- 结果:成功;`116 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet clean GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- 结果:失败;clean 阶段提前结束,`0 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- 第一轮批次后:成功;`80 Warning(s)`、`0 Error(s)`
|
||||
- 收尾修正后:成功;`71 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~YamlConfigLoaderIfThenElseTests|FullyQualifiedName~YamlConfigLoaderDependentSchemasTests|FullyQualifiedName~YamlConfigLoaderDependentRequiredTests|FullyQualifiedName~YamlConfigLoaderNegationTests|FullyQualifiedName~YamlConfigLoaderAllOfTests|FullyQualifiedName~YamlConfigLoaderEnumTests|FullyQualifiedName~YamlConfigTextValidatorTests|FullyQualifiedName~YamlConfigSchemaValidatorTests|FullyQualifiedName~PersistenceTests"`
|
||||
- 结果:成功;`Passed: 63`、`Failed: 0`
|
||||
- 当前结论:
|
||||
- `GFramework.Game.Tests` 本轮入口热点已从 `116 warning(s)` 收敛到 `71 warning(s)`,且本轮 touched files 不再出现在 warning 输出中
|
||||
- 当前工作树相对 `origin/main` 的累计 diff 已达到 `76` 个文件、`986` 行,超过 `$gframework-batch-boot 75` 的主停止阈值
|
||||
- 按批处理技能规则,本轮必须在提交当前批次后停止;剩余候选应在新一轮里单独评估,尤其是 `YamlConfigLoaderTests.cs`
|
||||
|
||||
## 2026-04-24 — RP-053
|
||||
|
||||
### 阶段:`GFramework.Godot` / `GFramework.Godot.Tests` 小批次 warning 清理
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user