using System.IO; using GFramework.Core.SourceGenerators.Logging; using GFramework.SourceGenerators.Tests.Core; namespace GFramework.SourceGenerators.Tests.Logging; /// /// 验证 在常见日志声明配置下的快照输出保持稳定。 /// [TestFixture] public class LoggerGeneratorSnapshotTests { /// /// 验证默认配置下的类日志字段快照。 /// [Test] public Task Snapshot_DefaultConfiguration_Class() { return RunScenarioAsync( "DefaultConfiguration_Class", "[Log]", "public partial class MyService"); } /// /// 验证自定义 logger 名称会反映到生成快照。 /// [Test] public Task Snapshot_CustomName_Class() { return RunScenarioAsync( "CustomName_Class", "[Log(Name = \"CustomLogger\")]", "public partial class MyService"); } /// /// 验证自定义字段名会反映到生成快照。 /// [Test] public Task Snapshot_CustomFieldName_Class() { return RunScenarioAsync( "CustomFieldName_Class", "[Log(FieldName = \"MyLogger\")]", "public partial class MyService"); } /// /// 验证实例字段模式会反映到生成快照。 /// [Test] public Task Snapshot_InstanceField_Class() { return RunScenarioAsync( "InstanceField_Class", "[Log(IsStatic = false)]", "public partial class MyService"); } /// /// 验证公共字段可见性会反映到生成快照。 /// [Test] public Task Snapshot_PublicField_Class() { return RunScenarioAsync( "PublicField_Class", "[Log(AccessModifier = \"public\")]", "public partial class MyService"); } /// /// 验证泛型类声明的日志字段快照。 /// [Test] public Task Snapshot_GenericClass() { return RunScenarioAsync( "GenericClass", "[Log]", "public partial class MyService"); } /// /// 为给定场景组装最小测试源并执行快照校验。 /// /// 快照场景名称。 /// 目标类型上的 [Log(...)] 声明。 /// 目标 partial 类型声明。 /// 表示快照测试完成的异步任务。 private static Task RunScenarioAsync(string scenarioName, string logAttributeLine, string classDeclaration) { return GeneratorSnapshotTest.RunAsync( CreateSource(logAttributeLine, classDeclaration), GetSnapshotFolder(scenarioName)); } /// /// 生成日志源生成器测试所需的最小宿主源代码。 /// /// 目标类型上的 [Log(...)] 声明。 /// 目标 partial 类型声明。 /// 可直接送入快照测试的完整源码字符串。 private static string CreateSource(string logAttributeLine, string classDeclaration) { return string.Join( $"{Environment.NewLine}{Environment.NewLine}", CreateLoggingAttributeSource(), CreateLoggingContractsSource(), CreateLoggingRuntimeSource(), CreateTestAppSource(logAttributeLine, classDeclaration)); } /// /// 生成日志测试使用的 attribute 定义源码。 /// /// 包含 LogAttribute 的源码片段。 private static string CreateLoggingAttributeSource() { return """ using System; namespace GFramework.Core.SourceGenerators.Abstractions.Logging { [AttributeUsage(AttributeTargets.Class)] public sealed class LogAttribute : Attribute { public string Name { get; set; } public string FieldName { get; set; } public string AccessModifier { get; set; } public bool IsStatic { get; set; } = true; } } """; } /// /// 生成日志抽象契约源码,供测试编译图引用。 /// /// 包含 ILogger 的源码片段。 private static string CreateLoggingContractsSource() { return """ namespace GFramework.Core.Abstractions.Logging { public interface ILogger { void Info(string message); void Error(string message); void Warn(string message); void Debug(string message); void Trace(string message); void Fatal(string message); } } """; } /// /// 生成最小运行时宿主源码,供生成器解析 logger provider 依赖。 /// /// 包含 provider 与 mock logger 的源码片段。 private static string CreateLoggingRuntimeSource() { return """ namespace GFramework.Core.Logging { using GFramework.Core.Abstractions.Logging; public static class LoggerFactoryResolver { public static ILoggerProvider Provider { get; set; } public static ILoggerProvider CreateLogger(string name) { return Provider ?? new MockLoggerProvider(); } } public interface ILoggerProvider { ILogger CreateLogger(string name); } internal class MockLoggerProvider : ILoggerProvider { public ILogger CreateLogger(string name) { return new MockLogger(name); } } internal class MockLogger : ILogger { private readonly string _name; public MockLogger(string name) { _name = name; } public void Info(string message) { } public void Error(string message) { } public void Warn(string message) { } public void Debug(string message) { } public void Trace(string message) { } public void Fatal(string message) { } } } """; } /// /// 生成实际承载 [Log] 声明的测试类型源码。 /// /// 目标类型上的 [Log(...)] 声明。 /// 目标 partial 类型声明。 /// 测试应用命名空间下的目标类型源码片段。 private static string CreateTestAppSource(string logAttributeLine, string classDeclaration) { return $$""" namespace TestApp { using GFramework.Core.SourceGenerators.Abstractions.Logging; {{logAttributeLine}} {{classDeclaration}} { } } """; } /// /// 将运行时测试目录映射回仓库内已提交的日志生成器快照目录。 /// /// 快照场景名称。 /// 场景对应的绝对快照目录。 private static string GetSnapshotFolder(string scenarioName) { return Path.GetFullPath( Path.Combine( TestContext.CurrentContext.TestDirectory, "..", "..", "..", "Logging", "snapshots", "LoggerGenerator", scenarioName)); } }