Update README.md to include project description, developer documentation links, and license information.
CI / build-test (push) Successful in 1m6s
CI / build-test (push) Successful in 1m6s
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using MrGameEng.Assets.Generator;
|
||||
using Xunit;
|
||||
|
||||
namespace MrGameEng.Assets.Generator.Tests;
|
||||
|
||||
public class AssetHandlesGeneratorTests
|
||||
{
|
||||
private sealed class FakeAdditionalText(string path) : AdditionalText
|
||||
{
|
||||
public override string Path { get; } = path;
|
||||
|
||||
public override SourceText GetText(CancellationToken cancellationToken = default) =>
|
||||
SourceText.From(string.Empty);
|
||||
}
|
||||
|
||||
private sealed class FakeOptions(Dictionary<string, string> values) : AnalyzerConfigOptions
|
||||
{
|
||||
public override bool TryGetValue(string key, out string value) =>
|
||||
values.TryGetValue(key, out value!);
|
||||
}
|
||||
|
||||
private sealed class FakeOptionsProvider(Dictionary<string, string> values) : AnalyzerConfigOptionsProvider
|
||||
{
|
||||
public override AnalyzerConfigOptions GlobalOptions { get; } = new FakeOptions(values);
|
||||
|
||||
public override AnalyzerConfigOptions GetOptions(SyntaxTree tree) => GlobalOptions;
|
||||
|
||||
public override AnalyzerConfigOptions GetOptions(AdditionalText textFile) => GlobalOptions;
|
||||
}
|
||||
|
||||
private static string RunGenerator(string[] files, Dictionary<string, string>? options = null)
|
||||
{
|
||||
var driver = CSharpGeneratorDriver.Create(
|
||||
[new AssetHandlesGenerator().AsSourceGenerator()],
|
||||
additionalTexts: Array.ConvertAll(files, f => (AdditionalText)new FakeAdditionalText(f)),
|
||||
optionsProvider: new FakeOptionsProvider(options ?? new Dictionary<string, string>
|
||||
{
|
||||
["build_property.RootNamespace"] = "MyGame",
|
||||
}));
|
||||
|
||||
var compilation = CSharpCompilation.Create("test");
|
||||
var result = driver.RunGenerators(compilation).GetRunResult();
|
||||
return Assert.Single(Assert.Single(result.Results).GeneratedSources).SourceText.ToString();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GeneratesTypedHandles_ForKnownExtensions()
|
||||
{
|
||||
var source = RunGenerator(
|
||||
[
|
||||
@"D:\game\Assets\Textures\player.png",
|
||||
@"D:\game\Assets\Sounds\jump.wav",
|
||||
@"D:\game\Assets\Fonts\main.ttf",
|
||||
@"D:\game\Assets\Music\theme.ogg",
|
||||
]);
|
||||
|
||||
Assert.Contains("namespace MyGame;", source);
|
||||
Assert.Contains("public static partial class GameAssets", source);
|
||||
Assert.Contains("public static class Textures", source);
|
||||
Assert.Contains(
|
||||
"AssetRef<global::Microsoft.Xna.Framework.Graphics.Texture2D> Player = new(\"Textures/player.png\")",
|
||||
source);
|
||||
Assert.Contains(
|
||||
"AssetRef<global::Microsoft.Xna.Framework.Audio.SoundEffect> Jump = new(\"Sounds/jump.wav\")",
|
||||
source);
|
||||
Assert.Contains("AssetRef<global::FontStashSharp.FontSystem> Main", source);
|
||||
Assert.Contains("AssetRef<global::MrGameEng.Core.MusicTrack> Theme", source);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IgnoresUnknownExtensions_AndFilesOutsideAssets()
|
||||
{
|
||||
var source = RunGenerator(
|
||||
[
|
||||
@"D:\game\Assets\readme.md",
|
||||
@"D:\game\Other\image.png",
|
||||
@"D:\game\Assets\valid.png",
|
||||
]);
|
||||
|
||||
Assert.Contains("Valid", source);
|
||||
Assert.DoesNotContain("Readme", source);
|
||||
Assert.DoesNotContain("Image", source);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedDirectories_BecomeNestedClasses()
|
||||
{
|
||||
var source = RunGenerator([@"C:\proj\Assets\UI\Icons\save-icon.png"]);
|
||||
|
||||
Assert.Contains("public static class UI", source);
|
||||
Assert.Contains("public static class Icons", source);
|
||||
Assert.Contains("SaveIcon = new(\"UI/Icons/save-icon.png\")", source);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GeneratedCode_Compiles()
|
||||
{
|
||||
var source = RunGenerator([@"D:\game\Assets\player.png"]);
|
||||
|
||||
// Подменяем внешние типы заглушками, чтобы скомпилировать сгенерированный код изолированно.
|
||||
const string stubs = """
|
||||
namespace MrGameEng.Assets { public readonly record struct AssetRef<T>(string Path) where T : class; }
|
||||
namespace Microsoft.Xna.Framework.Graphics { public sealed class Texture2D; }
|
||||
""";
|
||||
|
||||
var compilation = CSharpCompilation.Create(
|
||||
"generated",
|
||||
[CSharpSyntaxTree.ParseText(source), CSharpSyntaxTree.ParseText(stubs)],
|
||||
[MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
|
||||
MetadataReference.CreateFromFile(System.Runtime.Loader.AssemblyLoadContext.Default
|
||||
.LoadFromAssemblyName(new System.Reflection.AssemblyName("System.Runtime")).Location)],
|
||||
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
||||
|
||||
var errors = compilation.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).ToList();
|
||||
Assert.Empty(errors);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("player", "Player")]
|
||||
[InlineData("save-icon", "SaveIcon")]
|
||||
[InlineData("8bit_font", "_8bitFont")]
|
||||
[InlineData("...", "_")]
|
||||
public void Identifier_SanitizesNames(string input, string expected)
|
||||
{
|
||||
Assert.Equal(expected, AssetHandlesGenerator.Identifier(input));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"D:\game\Assets\a.png", "a.png")]
|
||||
[InlineData("/home/user/game/Assets/sub/b.wav", "sub/b.wav")]
|
||||
[InlineData(@"D:\game\NotAssets\c.png", null)]
|
||||
[InlineData(@"D:\game\Assets\unknown.xyz", null)]
|
||||
public void ToAssetPath_ExtractsRelativePath(string fullPath, string? expected)
|
||||
{
|
||||
Assert.Equal(expected, AssetHandlesGenerator.ToAssetPath(fullPath));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MrGameEng.Assets.Generator\MrGameEng.Assets.Generator.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user