GFramework/GFramework.SourceGenerators.Tests/Rule/ContextAwareGeneratorSnapshotTests.cs
gewuyou 6d4f9f2f94 fix(source-generators): 收口PR269生成器评审修复
- 重构 CqrsHandlerRegistryGenerator 为按职责拆分的 partial 生成器文件,保留现有注册输出与 fallback 契约
- 修复 ContextAwareGenerator 生成字段命名冲突并为 SetContextProvider 补充运行时 null 校验与异常文档
- 补充 Option<T> 的 XML remarks 契约说明与 ContextAwareGenerator 字段冲突快照测试
- 更新 analyzer-warning-reduction 跟踪与 trace,记录 PR #269 review follow-up 与验证结果
2026-04-23 09:58:30 +08:00

183 lines
8.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.IO;
using GFramework.Core.SourceGenerators.Rule;
using GFramework.SourceGenerators.Tests.Core;
namespace GFramework.SourceGenerators.Tests.Rule;
/// <summary>
/// 上下文感知生成器快照测试类
/// 用于测试ContextAwareGenerator源代码生成器的输出快照
/// </summary>
[TestFixture]
public class ContextAwareGeneratorSnapshotTests
{
/// <summary>
/// 测试ContextAwareGenerator源代码生成器的快照功能
/// 验证生成器对带有ContextAware特性的类的处理结果
/// </summary>
/// <returns>异步任务,无返回值</returns>
[Test]
public async Task Snapshot_ContextAwareGenerator()
{
// 定义测试用的源代码包含ContextAware特性和相关接口定义
const string source = """
using System;
namespace GFramework.Core.SourceGenerators.Abstractions.Rule
{
[AttributeUsage(AttributeTargets.Class)]
public sealed class ContextAwareAttribute : Attribute { }
}
namespace GFramework.Core.Abstractions.Rule
{
public interface IContextAware
{
void SetContext(
GFramework.Core.Abstractions.Architectures.IArchitectureContext context);
GFramework.Core.Abstractions.Architectures.IArchitectureContext GetContext();
}
}
namespace GFramework.Core.Abstractions.Architectures
{
public interface IArchitectureContext { }
public interface IArchitectureContextProvider
{
IArchitectureContext GetContext();
bool TryGetContext<T>(out T? context) where T : class, IArchitectureContext;
}
}
namespace GFramework.Core.Architectures
{
using GFramework.Core.Abstractions.Architectures;
public sealed class GameContextProvider : IArchitectureContextProvider
{
public IArchitectureContext GetContext() => null;
public bool TryGetContext<T>(out T? context) where T : class, IArchitectureContext
{
context = null;
return false;
}
}
public static class GameContext
{
public static IArchitectureContext GetFirstArchitectureContext() => null;
}
}
namespace TestApp
{
using GFramework.Core.SourceGenerators.Abstractions.Rule;
using GFramework.Core.Abstractions.Rule;
[ContextAware]
public partial class MyRule : IContextAware
{
}
}
""";
// 执行生成器快照测试,将生成的代码与预期快照进行比较
await GeneratorSnapshotTest<ContextAwareGenerator>.RunAsync(
source,
GetSnapshotFolder());
}
/// <summary>
/// 验证生成器在用户 partial 类型已经声明常见上下文字段名时仍能生成可编译代码。
/// </summary>
/// <returns>异步任务,无返回值。</returns>
[Test]
public async Task Snapshot_ContextAwareGenerator_With_User_Field_Name_Collisions()
{
const string source = """
using System;
namespace GFramework.Core.SourceGenerators.Abstractions.Rule
{
[AttributeUsage(AttributeTargets.Class)]
public sealed class ContextAwareAttribute : Attribute { }
}
namespace GFramework.Core.Abstractions.Rule
{
public interface IContextAware
{
void SetContext(
GFramework.Core.Abstractions.Architectures.IArchitectureContext context);
GFramework.Core.Abstractions.Architectures.IArchitectureContext GetContext();
}
}
namespace GFramework.Core.Abstractions.Architectures
{
public interface IArchitectureContext { }
public interface IArchitectureContextProvider
{
IArchitectureContext GetContext();
bool TryGetContext<T>(out T? context) where T : class, IArchitectureContext;
}
}
namespace GFramework.Core.Architectures
{
using GFramework.Core.Abstractions.Architectures;
public sealed class GameContextProvider : IArchitectureContextProvider
{
public IArchitectureContext GetContext() => null;
public bool TryGetContext<T>(out T? context) where T : class, IArchitectureContext
{
context = null;
return false;
}
}
}
namespace TestApp
{
using GFramework.Core.SourceGenerators.Abstractions.Rule;
using GFramework.Core.Abstractions.Rule;
using GFramework.Core.Abstractions.Architectures;
[ContextAware]
public partial class CollisionProneRule : IContextAware
{
private readonly string _context = "user-field";
private static readonly string _contextProvider = "user-provider";
private static readonly object _contextSync = new();
}
}
""";
await GeneratorSnapshotTest<ContextAwareGenerator>.RunAsync(
source,
GetSnapshotFolder());
}
/// <summary>
/// 将运行时测试目录映射回仓库内已提交的上下文感知生成器快照目录。
/// </summary>
/// <returns>快照目录的绝对路径。</returns>
private static string GetSnapshotFolder()
{
return Path.GetFullPath(
Path.Combine(
TestContext.CurrentContext.TestDirectory,
"..",
"..",
"..",
"Rule",
"snapshots",
"ContextAwareGenerator"));
}
}