mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-07 16:36:52 +02:00
319 lines
10 KiB
C#
319 lines
10 KiB
C#
extern alias SerializationGenerator;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.Text;
|
|
using NUnit.Framework;
|
|
using Robust.Analyzers.Generators;
|
|
|
|
namespace Robust.Analyzers.Tests;
|
|
|
|
[TestFixture]
|
|
[TestOf(typeof(HasDependenciesGenerator))]
|
|
[Parallelizable(ParallelScope.All)]
|
|
public sealed class HasDependenciesGeneratorTest
|
|
{
|
|
[Test]
|
|
public void TestBasic()
|
|
{
|
|
var result = RunGenerator("""
|
|
using Robust.Shared.IoC;
|
|
|
|
public sealed partial class Foobar
|
|
{
|
|
[Dependency]
|
|
public string Foo;
|
|
}
|
|
""");
|
|
|
|
ExpectNoDiagnostics(result);
|
|
ExpectSource(
|
|
result,
|
|
"""
|
|
// <auto-generated />
|
|
|
|
[global::Robust.Shared.IoC.HasDependenciesGeneratedAttribute]
|
|
public partial class Foobar : global::Robust.Shared.IoC.IHasDependencies
|
|
{
|
|
[global::Robust.Shared.Analyzers.RobustAutoGenerated]
|
|
void global::Robust.Shared.IoC.IHasDependencies.Inject(global::Robust.Shared.IoC.IDependencyCollection dependencies)
|
|
{
|
|
Foo = dependencies.ResolveInject<global::string>(typeof(Foobar));
|
|
}
|
|
}
|
|
|
|
""");
|
|
}
|
|
|
|
[Test]
|
|
public void TestInheritGeneric()
|
|
{
|
|
var result = RunGenerator("""
|
|
using Robust.Shared.IoC;
|
|
|
|
public partial class Foo<T>
|
|
{
|
|
[Dependency] string _x = null!;
|
|
}
|
|
|
|
public sealed partial class Bar : Foo<int>
|
|
{
|
|
[Dependency]
|
|
public string _heck = null!;
|
|
}
|
|
""");
|
|
|
|
ExpectNoDiagnostics(result);
|
|
Assert.That(result.GeneratedSources, Has.Length.EqualTo(2));
|
|
|
|
ExpectNamedSource(
|
|
result,
|
|
"Foo`1.g.cs",
|
|
"""
|
|
// <auto-generated />
|
|
|
|
[global::Robust.Shared.IoC.HasDependenciesGeneratedAttribute]
|
|
public partial class Foo<T> : global::Robust.Shared.IoC.IHasDependencies
|
|
{
|
|
[global::Robust.Shared.Analyzers.RobustAutoGenerated]
|
|
void global::Robust.Shared.IoC.IHasDependencies.Inject(global::Robust.Shared.IoC.IDependencyCollection dependencies)
|
|
{
|
|
InjectImpl(dependencies);
|
|
}
|
|
|
|
[global::Robust.Shared.Analyzers.RobustAutoGenerated]
|
|
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
|
protected virtual void InjectImpl(global::Robust.Shared.IoC.IDependencyCollection dependencies)
|
|
{
|
|
_x = dependencies.ResolveInject<global::string>(typeof(Foo<T>));
|
|
}
|
|
}
|
|
|
|
""");
|
|
|
|
ExpectNamedSource(
|
|
result,
|
|
"Bar.g.cs",
|
|
"""
|
|
// <auto-generated />
|
|
|
|
[global::Robust.Shared.IoC.HasDependenciesGeneratedAttribute]
|
|
public partial class Bar
|
|
{
|
|
[global::Robust.Shared.Analyzers.RobustAutoGenerated]
|
|
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
|
protected override void InjectImpl(global::Robust.Shared.IoC.IDependencyCollection dependencies)
|
|
{
|
|
_heck = dependencies.ResolveInject<global::string>(typeof(Bar));
|
|
|
|
base.InjectImpl(dependencies);
|
|
}
|
|
}
|
|
|
|
""");
|
|
}
|
|
|
|
[Test]
|
|
public void TestGenericInherit()
|
|
{
|
|
var result = RunGenerator("""
|
|
using Robust.Shared.IoC;
|
|
|
|
public partial class Foo
|
|
{
|
|
[Dependency] string _x = null!;
|
|
}
|
|
|
|
public sealed partial class Bar<T> : Foo
|
|
{
|
|
[Dependency]
|
|
public string _heck = null!;
|
|
}
|
|
""");
|
|
|
|
ExpectNoDiagnostics(result);
|
|
Assert.That(result.GeneratedSources, Has.Length.EqualTo(2));
|
|
|
|
ExpectNamedSource(
|
|
result,
|
|
"Foo.g.cs",
|
|
"""
|
|
// <auto-generated />
|
|
|
|
[global::Robust.Shared.IoC.HasDependenciesGeneratedAttribute]
|
|
public partial class Foo : global::Robust.Shared.IoC.IHasDependencies
|
|
{
|
|
[global::Robust.Shared.Analyzers.RobustAutoGenerated]
|
|
void global::Robust.Shared.IoC.IHasDependencies.Inject(global::Robust.Shared.IoC.IDependencyCollection dependencies)
|
|
{
|
|
InjectImpl(dependencies);
|
|
}
|
|
|
|
[global::Robust.Shared.Analyzers.RobustAutoGenerated]
|
|
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
|
protected virtual void InjectImpl(global::Robust.Shared.IoC.IDependencyCollection dependencies)
|
|
{
|
|
_x = dependencies.ResolveInject<global::string>(typeof(Foo));
|
|
}
|
|
}
|
|
|
|
""");
|
|
|
|
ExpectNamedSource(
|
|
result,
|
|
"Bar`1.g.cs",
|
|
"""
|
|
// <auto-generated />
|
|
|
|
[global::Robust.Shared.IoC.HasDependenciesGeneratedAttribute]
|
|
public partial class Bar<T>
|
|
{
|
|
[global::Robust.Shared.Analyzers.RobustAutoGenerated]
|
|
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
|
protected override void InjectImpl(global::Robust.Shared.IoC.IDependencyCollection dependencies)
|
|
{
|
|
_heck = dependencies.ResolveInject<global::string>(typeof(Bar<T>));
|
|
|
|
base.InjectImpl(dependencies);
|
|
}
|
|
}
|
|
|
|
""");
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void TestReadOnly()
|
|
{
|
|
var result = RunGenerator("""
|
|
using Robust.Shared.IoC;
|
|
|
|
public sealed partial class Foobar
|
|
{
|
|
[Dependency]
|
|
public readonly string Foo;
|
|
}
|
|
""");
|
|
|
|
ExpectNoDiagnostics(result);
|
|
ExpectNoSource(result);
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void TestNotPartial()
|
|
{
|
|
var result = RunGenerator("""
|
|
using Robust.Shared.IoC;
|
|
|
|
public sealed class Foobar
|
|
{
|
|
[Dependency]
|
|
public string Foo;
|
|
}
|
|
""");
|
|
|
|
ExpectNoDiagnostics(result);
|
|
ExpectNoSource(result);
|
|
}
|
|
|
|
[Test]
|
|
public void TestNested()
|
|
{
|
|
var result = RunGenerator("""
|
|
using Robust.Shared.IoC;
|
|
|
|
public sealed partial class Real
|
|
{
|
|
public sealed partial class Foobar
|
|
{
|
|
[Dependency]
|
|
public string Foo;
|
|
}
|
|
}
|
|
""");
|
|
|
|
ExpectNoDiagnostics(result);
|
|
ExpectSource(
|
|
result,
|
|
"""
|
|
// <auto-generated />
|
|
|
|
public partial class Real
|
|
{
|
|
[global::Robust.Shared.IoC.HasDependenciesGeneratedAttribute]
|
|
public partial class Foobar : global::Robust.Shared.IoC.IHasDependencies
|
|
{
|
|
[global::Robust.Shared.Analyzers.RobustAutoGenerated]
|
|
void global::Robust.Shared.IoC.IHasDependencies.Inject(global::Robust.Shared.IoC.IDependencyCollection dependencies)
|
|
{
|
|
Foo = dependencies.ResolveInject<global::string>(typeof(Real.Foobar));
|
|
}
|
|
}
|
|
}
|
|
|
|
""");
|
|
}
|
|
|
|
private static void ExpectSource(GeneratorRunResult result, string expected)
|
|
{
|
|
Assert.That(result.GeneratedSources, Has.Length.EqualTo(1));
|
|
|
|
var source = result.GeneratedSources[0];
|
|
|
|
Assert.That(source.SourceText.ToString().ReplaceLineEndings(), Is.EqualTo(expected.ReplaceLineEndings()));
|
|
}
|
|
|
|
private static void ExpectNamedSource(GeneratorRunResult result, string name, string expected)
|
|
{
|
|
var source = result.GeneratedSources.Single(s => s.HintName == name);
|
|
|
|
Assert.That(source.SourceText.ToString().ReplaceLineEndings(), Is.EqualTo(expected.ReplaceLineEndings()));
|
|
}
|
|
|
|
private static void ExpectNoSource(GeneratorRunResult result)
|
|
{
|
|
Assert.That(result.GeneratedSources, Is.Empty);
|
|
}
|
|
|
|
private static void ExpectNoDiagnostics(GeneratorRunResult result)
|
|
{
|
|
Assert.That(result.Diagnostics, Is.Empty);
|
|
}
|
|
|
|
private static void ExpectDiagnostics(GeneratorRunResult result, (string code, LinePositionSpan span)[] diagnostics)
|
|
{
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(result.Diagnostics, Has.Length.EqualTo(diagnostics.Length));
|
|
foreach (var (code, span) in diagnostics)
|
|
{
|
|
Assert.That(
|
|
result.Diagnostics.Any(x => x.Id == code && x.Location.GetLineSpan().Span == span),
|
|
$"Expected diagnostic with code {code} and location {span}");
|
|
}
|
|
});
|
|
}
|
|
|
|
private static GeneratorRunResult RunGenerator(string source)
|
|
{
|
|
var compilation = (Compilation)CSharpCompilation.Create("compilation",
|
|
[
|
|
CSharpSyntaxTree.ParseText(source, path: "Source.cs"),
|
|
..TestHelper.GetEmbeddedSyntaxTrees(
|
|
"Robust.Shared.IoC.DependencyAttribute.cs",
|
|
"Robust.Shared.IoC.IHasDependencies.cs"),
|
|
],
|
|
new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) },
|
|
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
|
|
|
var generator = new HasDependenciesGenerator();
|
|
GeneratorDriver driver = CSharpGeneratorDriver.Create(generator);
|
|
driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out var newCompilation, out _);
|
|
var result = driver.GetRunResult();
|
|
|
|
return result.Results[0];
|
|
}
|
|
}
|