mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 21:34:28 +08:00
- 添加基于真实类型的命名空间常量定义,避免硬编码字符串 - 引入 Architecture、Extensions 和 CoroutineExtensions 命名空间自动发现 - 将 FindRepositoryRoot 方法重构为 ResolveRepositoryRoot 并使用 CallerFilePath - 更新断言逻辑以使用动态命名空间变量而非字面量字符串 - 移除对解决方案文件扫描的依赖,改用相对路径计算仓库根目录 - 添加方法参数验证和异常处理增强代码健壮性
80 lines
3.9 KiB
C#
80 lines
3.9 KiB
C#
using System.IO;
|
||
using System.Runtime.CompilerServices;
|
||
using GFramework.Core.Architectures;
|
||
using GFramework.Core.Coroutine.Extensions;
|
||
|
||
namespace GFramework.Core.Tests.Packaging;
|
||
|
||
/// <summary>
|
||
/// 验证运行时模块在构建期间会自动生成 transitive global usings 资产。
|
||
/// 该测试覆盖命名空间自动发现、框架侧过滤和消费者侧排除钩子的最终构建产物。
|
||
/// </summary>
|
||
[TestFixture]
|
||
public class TransitiveGlobalUsingsPackagingTests
|
||
{
|
||
/// <summary>
|
||
/// 使用真实类型派生架构命名空间,避免测试断言和命名空间重构脱节。
|
||
/// </summary>
|
||
private static readonly string ArchitectureNamespace = typeof(Architecture).Namespace
|
||
?? throw new InvalidOperationException(
|
||
"Architecture namespace should not be null.");
|
||
|
||
/// <summary>
|
||
/// 使用真实类型派生扩展命名空间,避免对字面量命名空间字符串的重复维护。
|
||
/// </summary>
|
||
private static readonly string ExtensionsNamespace = typeof(ContextAwareEnvironmentExtensions).Namespace
|
||
?? throw new InvalidOperationException(
|
||
"Extensions namespace should not be null.");
|
||
|
||
/// <summary>
|
||
/// 使用真实类型派生协程扩展命名空间,确保断言和源码自动发现保持一致。
|
||
/// </summary>
|
||
private static readonly string CoroutineExtensionsNamespace = typeof(CoroutineExtensions).Namespace
|
||
?? throw new InvalidOperationException(
|
||
"Coroutine extensions namespace should not be null.");
|
||
|
||
/// <summary>
|
||
/// 验证 GFramework.Core 在构建后会生成 transitive global usings props,
|
||
/// 且 props 内容来自源码自动发现,并保留消费者侧排除机制。
|
||
/// </summary>
|
||
[Test]
|
||
public void CoreBuild_Should_Generate_AutoDiscovered_TransitiveGlobalUsingsProps()
|
||
{
|
||
var repositoryRoot = ResolveRepositoryRoot();
|
||
var propsPath = Path.Combine(
|
||
repositoryRoot,
|
||
"GFramework.Core",
|
||
"obj",
|
||
"gframework",
|
||
"GeWuYou.GFramework.Core.props");
|
||
|
||
Assert.That(File.Exists(propsPath), Is.True, $"Expected generated props to exist: {propsPath}");
|
||
var propsContent = File.ReadAllText(propsPath);
|
||
|
||
Assert.That(propsContent, Does.Contain(ExtensionsNamespace));
|
||
Assert.That(propsContent, Does.Contain(ArchitectureNamespace));
|
||
Assert.That(propsContent, Does.Contain(CoroutineExtensionsNamespace));
|
||
Assert.That(propsContent, Does.Contain("Remove=\"@(GFrameworkExcludedUsing)\""));
|
||
Assert.That(propsContent, Does.Not.Contain("System.Runtime.CompilerServices"));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 基于当前测试源文件的已知位置解析仓库根目录。
|
||
/// 这里不扫描解决方案文件,避免测试对仓库布局演进产生额外脆弱性。
|
||
/// </summary>
|
||
/// <param name="sourceFilePath">由编译器注入的当前测试源文件绝对路径。</param>
|
||
/// <returns>仓库根目录绝对路径。</returns>
|
||
private static string ResolveRepositoryRoot([CallerFilePath] string sourceFilePath = "")
|
||
{
|
||
if (string.IsNullOrWhiteSpace(sourceFilePath))
|
||
{
|
||
throw new InvalidOperationException("Caller file path is required to resolve the repository root.");
|
||
}
|
||
|
||
var sourceDirectory = Path.GetDirectoryName(sourceFilePath)
|
||
?? throw new DirectoryNotFoundException(
|
||
$"Could not determine the directory for source file path: {sourceFilePath}");
|
||
|
||
return Path.GetFullPath(Path.Combine(sourceDirectory, "..", ".."));
|
||
}
|
||
} |