From 703098c1d15672f6c90ffce054866d9f1872e76d Mon Sep 17 00:00:00 2001 From: Paul Welter Date: Mon, 13 Nov 2023 15:43:28 -0600 Subject: [PATCH] improve tests --- .gitignore | 3 + Backgrounder.sln | 5 +- .../BackgroundGeneratorTests.cs | 166 ++++++++++++++++++ .../Backgrounder.Generators.Tests.csproj | 7 + .../ModuleInitialization.cs | 9 + ...atorTests.RunComplexParameter.verified.txt | 38 ++++ ...torTests.RunMultipleParameter.verified.txt | 38 ++++ ...oundGeneratorTests.RunResults.verified.txt | 1 + ...ratorTests.RunSingleParameter.verified.txt | 38 ++++ ...eneratorTests.RunStaticMethod.verified.txt | 37 ++++ .../Backgrounder.Tests.csproj | 30 ---- test/Backgrounder.Tests/GlobalUsings.cs | 1 - 12 files changed, 340 insertions(+), 33 deletions(-) create mode 100644 test/Backgrounder.Generators.Tests/BackgroundGeneratorTests.cs create mode 100644 test/Backgrounder.Generators.Tests/ModuleInitialization.cs create mode 100644 test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunComplexParameter.verified.txt create mode 100644 test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunMultipleParameter.verified.txt create mode 100644 test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunResults.verified.txt create mode 100644 test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunSingleParameter.verified.txt create mode 100644 test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunStaticMethod.verified.txt delete mode 100644 test/Backgrounder.Tests/Backgrounder.Tests.csproj delete mode 100644 test/Backgrounder.Tests/GlobalUsings.cs diff --git a/.gitignore b/.gitignore index 8a30d25..cc489ea 100644 --- a/.gitignore +++ b/.gitignore @@ -396,3 +396,6 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml + +# Verify +*.received.txt diff --git a/Backgrounder.sln b/Backgrounder.sln index 9c29c07..924c823 100644 --- a/Backgrounder.sln +++ b/Backgrounder.sln @@ -21,14 +21,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Backgrounder.Generators", " EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{1AA0FC81-4621-47EC-9D4F-B64662B68CC8}" ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore src\Directory.Build.props = src\Directory.Build.props .github\workflows\dotnet.yml = .github\workflows\dotnet.yml README.md = README.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Backgrounder.Generators.Tests", "test\Backgrounder.Generators.Tests\Backgrounder.Generators.Tests.csproj", "{5688BE7D-01D0-4DAE-96B3-CD2D68739B83}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Backgrounder.Generators.Tests", "test\Backgrounder.Generators.Tests\Backgrounder.Generators.Tests.csproj", "{5688BE7D-01D0-4DAE-96B3-CD2D68739B83}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Backgrounder.Sample.Library", "samples\Backgrounder.Sample.Library\Backgrounder.Sample.Library.csproj", "{098517FD-EFBF-4B60-976B-DF26D5BA4493}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Backgrounder.Sample.Library", "samples\Backgrounder.Sample.Library\Backgrounder.Sample.Library.csproj", "{098517FD-EFBF-4B60-976B-DF26D5BA4493}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/test/Backgrounder.Generators.Tests/BackgroundGeneratorTests.cs b/test/Backgrounder.Generators.Tests/BackgroundGeneratorTests.cs new file mode 100644 index 0000000..0a349cb --- /dev/null +++ b/test/Backgrounder.Generators.Tests/BackgroundGeneratorTests.cs @@ -0,0 +1,166 @@ +using System.Collections.Immutable; + +using FluentAssertions; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace Backgrounder.Generators.Tests; + +[UsesVerify] +public class BackgroundGeneratorTests +{ + [Fact] + public Task GenerateSingleParameter() + { + var source = @" +using Backgrounder; + +namespace Backgrounder.Sample; + +public interface ISampleJob +{ + Task DoWork(int? jobId); +} + +public class SampleJob : ISampleJob +{ + [BackgroundOperation] + public Task DoWork(int? jobId) => Task.FromResult(jobId); +} +"; + + var (diagnostics, output) = GetGeneratedOutput(source); + + diagnostics.Should().BeEmpty(); + + return Verifier + .Verify(output) + .UseDirectory("Snapshots") + .ScrubLinesContaining("GeneratedCodeAttribute"); + } + + [Fact] + public Task GenerateMultipleParameter() + { + var source = @" +using Backgrounder; + +namespace Backgrounder.Sample; + +public interface ISampleJob +{ + Task DoWork(int jobId, string? name); +} + +public class SampleJob : ISampleJob +{ + [BackgroundOperation] + public Task DoWork(int jobId, string? name) => Task.FromResult(jobId); +} +"; + + var (diagnostics, output) = GetGeneratedOutput(source); + + diagnostics.Should().BeEmpty(); + + return Verifier + .Verify(output) + .UseDirectory("Snapshots") + .ScrubLinesContaining("GeneratedCodeAttribute"); + } + + [Fact] + public Task GenerateStaticMethod() + { + var source = @" +using Backgrounder; + +namespace Backgrounder.Sample; + +public class SampleJob +{ + [BackgroundOperation] + public static Task StaticWork(int jobId) + { + return Task.FromResult(jobId); + } +} +"; + + var (diagnostics, output) = GetGeneratedOutput(source); + + diagnostics.Should().BeEmpty(); + + return Verifier + .Verify(output) + .UseDirectory("Snapshots") + .ScrubLinesContaining("GeneratedCodeAttribute"); + } + + [Fact] + public Task GenerateComplexParameter() + { + var source = @" +using Backgrounder; + +namespace Backgrounder.Sample; + +public interface ISampleJob +{ + void CheckPerson(Person person); +} + +public class SampleJob : ISampleJob +{ + [BackgroundOperation] + public void CheckPerson(Person person) { } +} + +public class Person +{ + public string? Name { get; set; } + public string? Email { get; set; } +} +"; + + var (diagnostics, output) = GetGeneratedOutput(source); + + diagnostics.Should().BeEmpty(); + + return Verifier + .Verify(output) + .UseDirectory("Snapshots") + .ScrubLinesContaining("GeneratedCodeAttribute"); + } + + public static (ImmutableArray Diagnostics, string Output) GetGeneratedOutput(string source) + where T : IIncrementalGenerator, new() + { + var syntaxTree = CSharpSyntaxTree.ParseText(source); + var references = AppDomain.CurrentDomain.GetAssemblies() + .Where(_ => !_.IsDynamic && !string.IsNullOrWhiteSpace(_.Location)) + .Select(_ => MetadataReference.CreateFromFile(_.Location)) + .Concat(new[] + { + MetadataReference.CreateFromFile(typeof(T).Assembly.Location), + MetadataReference.CreateFromFile(typeof(BackgroundOperationAttribute).Assembly.Location), + }); + + var compilation = CSharpCompilation.Create( + "generator", + new[] { syntaxTree }, + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var originalTreeCount = compilation.SyntaxTrees.Length; + var generator = new T(); + + var driver = CSharpGeneratorDriver.Create(generator); + driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics); + + var trees = outputCompilation.SyntaxTrees.ToList(); + + return (diagnostics, trees.Count != originalTreeCount ? trees[trees.Count - 1].ToString() : string.Empty); + } +} diff --git a/test/Backgrounder.Generators.Tests/Backgrounder.Generators.Tests.csproj b/test/Backgrounder.Generators.Tests/Backgrounder.Generators.Tests.csproj index e642a72..28614df 100644 --- a/test/Backgrounder.Generators.Tests/Backgrounder.Generators.Tests.csproj +++ b/test/Backgrounder.Generators.Tests/Backgrounder.Generators.Tests.csproj @@ -11,7 +11,13 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + @@ -26,6 +32,7 @@ + diff --git a/test/Backgrounder.Generators.Tests/ModuleInitialization.cs b/test/Backgrounder.Generators.Tests/ModuleInitialization.cs new file mode 100644 index 0000000..0f630aa --- /dev/null +++ b/test/Backgrounder.Generators.Tests/ModuleInitialization.cs @@ -0,0 +1,9 @@ +using System.Runtime.CompilerServices; + +namespace Backgrounder.Generators.Tests; + +public static class ModuleInitialization +{ + [ModuleInitializer] + public static void Initialize() => VerifySourceGenerators.Initialize(); +} diff --git a/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunComplexParameter.verified.txt b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunComplexParameter.verified.txt new file mode 100644 index 0000000..151642d --- /dev/null +++ b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunComplexParameter.verified.txt @@ -0,0 +1,38 @@ +// +#nullable enable + +namespace Backgrounder.Sample +{ + /// + /// Extension methods for Backgrounder + /// + public static partial class SampleJobCheckPersonExtensions + { + public record CheckPersonMessageDAADBCDB(Backgrounder.Sample.Person person); + + /// + /// Enqueue the method Backgrounder.Sample.SampleJob.CheckPerson(Backgrounder.Sample.Person) for execution in the background + /// + public static async global::System.Threading.Tasks.Task CheckPerson(this global::Backgrounder.IBackgrounder backgrounder, Backgrounder.Sample.Person person) + { + var methodParameters = new CheckPersonMessageDAADBCDB(person); + await backgrounder.EnqueueAsync("Backgrounder.Sample.SampleJob.CheckPerson(Backgrounder.Sample.Person)", methodParameters); + } + + internal static global::System.Threading.Tasks.Task ExecuteCheckPersonDAADBCDB(global::System.IServiceProvider serviceProvider, byte[] messageBody) + { + var messageSerializer = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(serviceProvider); + var methodParameters = messageSerializer.Deserialize(messageBody); + var worker = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(serviceProvider); + worker.CheckPerson(methodParameters.person); + return global::System.Threading.Tasks.Task.CompletedTask; + } + + [global::System.Runtime.CompilerServices.ModuleInitializerAttribute] + internal static void RegisterCheckPersonDAADBCDB() + { + BackgroundRouter.Register("Backgrounder.Sample.SampleJob.CheckPerson(Backgrounder.Sample.Person)", Backgrounder.Sample.SampleJobCheckPersonExtensions.ExecuteCheckPersonDAADBCDB); + } + + } +} diff --git a/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunMultipleParameter.verified.txt b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunMultipleParameter.verified.txt new file mode 100644 index 0000000..acca8b1 --- /dev/null +++ b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunMultipleParameter.verified.txt @@ -0,0 +1,38 @@ +// +#nullable enable + +namespace Backgrounder.Sample +{ + /// + /// Extension methods for Backgrounder + /// + public static partial class SampleJobDoWorkExtensions + { + public record DoWorkMessage5A94B72F(int jobId, string? name); + + /// + /// Enqueue the method Backgrounder.Sample.SampleJob.DoWork(int, string?) for execution in the background + /// + public static async global::System.Threading.Tasks.Task DoWork(this global::Backgrounder.IBackgrounder backgrounder, int jobId, string? name) + { + var methodParameters = new DoWorkMessage5A94B72F(jobId, name); + await backgrounder.EnqueueAsync("Backgrounder.Sample.SampleJob.DoWork(int, string?)", methodParameters); + } + + internal static global::System.Threading.Tasks.Task ExecuteDoWork5A94B72F(global::System.IServiceProvider serviceProvider, byte[] messageBody) + { + var messageSerializer = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(serviceProvider); + var methodParameters = messageSerializer.Deserialize(messageBody); + var worker = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(serviceProvider); + worker.DoWork(methodParameters.jobId, methodParameters.name); + return global::System.Threading.Tasks.Task.CompletedTask; + } + + [global::System.Runtime.CompilerServices.ModuleInitializerAttribute] + internal static void RegisterDoWork5A94B72F() + { + BackgroundRouter.Register("Backgrounder.Sample.SampleJob.DoWork(int, string?)", Backgrounder.Sample.SampleJobDoWorkExtensions.ExecuteDoWork5A94B72F); + } + + } +} diff --git a/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunResults.verified.txt b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunResults.verified.txt new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunResults.verified.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunSingleParameter.verified.txt b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunSingleParameter.verified.txt new file mode 100644 index 0000000..7adc7db --- /dev/null +++ b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunSingleParameter.verified.txt @@ -0,0 +1,38 @@ +// +#nullable enable + +namespace Backgrounder.Sample +{ + /// + /// Extension methods for Backgrounder + /// + public static partial class SampleJobDoWorkExtensions + { + public record DoWorkMessage3299E5EA(int? jobId); + + /// + /// Enqueue the method Backgrounder.Sample.SampleJob.DoWork(int?) for execution in the background + /// + public static async global::System.Threading.Tasks.Task DoWork(this global::Backgrounder.IBackgrounder backgrounder, int? jobId) + { + var methodParameters = new DoWorkMessage3299E5EA(jobId); + await backgrounder.EnqueueAsync("Backgrounder.Sample.SampleJob.DoWork(int?)", methodParameters); + } + + internal static global::System.Threading.Tasks.Task ExecuteDoWork3299E5EA(global::System.IServiceProvider serviceProvider, byte[] messageBody) + { + var messageSerializer = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(serviceProvider); + var methodParameters = messageSerializer.Deserialize(messageBody); + var worker = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(serviceProvider); + worker.DoWork(methodParameters.jobId); + return global::System.Threading.Tasks.Task.CompletedTask; + } + + [global::System.Runtime.CompilerServices.ModuleInitializerAttribute] + internal static void RegisterDoWork3299E5EA() + { + BackgroundRouter.Register("Backgrounder.Sample.SampleJob.DoWork(int?)", Backgrounder.Sample.SampleJobDoWorkExtensions.ExecuteDoWork3299E5EA); + } + + } +} diff --git a/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunStaticMethod.verified.txt b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunStaticMethod.verified.txt new file mode 100644 index 0000000..14049c3 --- /dev/null +++ b/test/Backgrounder.Generators.Tests/Snapshots/BackgroundGeneratorTests.RunStaticMethod.verified.txt @@ -0,0 +1,37 @@ +// +#nullable enable + +namespace Backgrounder.Sample +{ + /// + /// Extension methods for Backgrounder + /// + public static partial class SampleJobStaticWorkExtensions + { + public record StaticWorkMessage34AA9206(int jobId); + + /// + /// Enqueue the method Backgrounder.Sample.SampleJob.StaticWork(int) for execution in the background + /// + public static async global::System.Threading.Tasks.Task StaticWork(this global::Backgrounder.IBackgrounder backgrounder, int jobId) + { + var methodParameters = new StaticWorkMessage34AA9206(jobId); + await backgrounder.EnqueueAsync("Backgrounder.Sample.SampleJob.StaticWork(int)", methodParameters); + } + + internal static global::System.Threading.Tasks.Task ExecuteStaticWork34AA9206(global::System.IServiceProvider serviceProvider, byte[] messageBody) + { + var messageSerializer = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(serviceProvider); + var methodParameters = messageSerializer.Deserialize(messageBody); + Backgrounder.Sample.SampleJob.StaticWork(methodParameters.jobId); + return global::System.Threading.Tasks.Task.CompletedTask; + } + + [global::System.Runtime.CompilerServices.ModuleInitializerAttribute] + internal static void RegisterStaticWork34AA9206() + { + BackgroundRouter.Register("Backgrounder.Sample.SampleJob.StaticWork(int)", Backgrounder.Sample.SampleJobStaticWorkExtensions.ExecuteStaticWork34AA9206); + } + + } +} diff --git a/test/Backgrounder.Tests/Backgrounder.Tests.csproj b/test/Backgrounder.Tests/Backgrounder.Tests.csproj deleted file mode 100644 index b59994b..0000000 --- a/test/Backgrounder.Tests/Backgrounder.Tests.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - net7.0 - enable - enable - - false - true - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - diff --git a/test/Backgrounder.Tests/GlobalUsings.cs b/test/Backgrounder.Tests/GlobalUsings.cs deleted file mode 100644 index 8c927eb..0000000 --- a/test/Backgrounder.Tests/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Xunit; \ No newline at end of file