Skip to content

Commit

Permalink
Added DataLoader source generator snapshot tests (#7290)
Browse files Browse the repository at this point in the history
  • Loading branch information
glen-84 authored Jul 24, 2024
1 parent 33b0cc6 commit 33900c7
Show file tree
Hide file tree
Showing 10 changed files with 637 additions and 52 deletions.
1 change: 1 addition & 0 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PackageVersion Include="Aspire.Hosting.Redis" Version="8.0.0" />
<PackageVersion Include="AutoMapper" Version="10.1.1" />
<PackageVersion Include="BananaCakePop.Middleware" Version="$(BananaCakePopVersion)" />
<PackageVersion Include="Basic.Reference.Assemblies" Version="1.6.0" />
<PackageVersion Include="ChilliCream.Testing.Utilities" Version="0.2.0" />
<PackageVersion Include="coverlet.msbuild" Version="3.1.2" />
<PackageVersion Include="DiffPlex" Version="1.7.1" />
Expand Down
15 changes: 0 additions & 15 deletions src/HotChocolate/Core/HotChocolate.Core.sln
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Features", "sr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Features.Tests", "test\Features.Tests\HotChocolate.Features.Tests.csproj", "{EA77D317-8767-4DDE-8038-820D582C52D6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Types.Analyzers.DataLoader.Tests", "test\Types.Analyzers.DataLoader.Tests\HotChocolate.Types.Analyzers.DataLoader.Tests.csproj", "{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1001,18 +999,6 @@ Global
{EA77D317-8767-4DDE-8038-820D582C52D6}.Release|x64.Build.0 = Release|Any CPU
{EA77D317-8767-4DDE-8038-820D582C52D6}.Release|x86.ActiveCfg = Release|Any CPU
{EA77D317-8767-4DDE-8038-820D582C52D6}.Release|x86.Build.0 = Release|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Debug|x64.ActiveCfg = Debug|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Debug|x64.Build.0 = Debug|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Debug|x86.ActiveCfg = Debug|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Debug|x86.Build.0 = Debug|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Release|Any CPU.Build.0 = Release|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Release|x64.ActiveCfg = Release|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Release|x64.Build.0 = Release|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Release|x86.ActiveCfg = Release|Any CPU
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1088,7 +1074,6 @@ Global
{AE9AF1C7-578A-46A5-84FD-9BBA8EB8DE22} = {7462D089-D350-44D6-8131-896D949A65B7}
{669FA147-3B41-4841-921A-55B019C3AF26} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{EA77D317-8767-4DDE-8038-820D582C52D6} = {7462D089-D350-44D6-8131-896D949A65B7}
{DC27BCB9-CF45-4FD4-BECF-5D97494666A1} = {7462D089-D350-44D6-8131-896D949A65B7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E4D94C77-6657-4630-9D42-0A9AC5153A1B}
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Threading.Tasks;

namespace HotChocolate.Types;

public class DataLoaderTests
{
[Fact]
public async Task GenerateSource_BatchDataLoader_MatchesSnapshot()
{
await TestHelper.GetGeneratedSourceSnapshot(
"""
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using HotChocolate;

namespace TestNamespace;

internal static class TestClass
{
[DataLoader]
public static async Task<IReadOnlyDictionary<int, Entity>> GetEntityByIdAsync(
IReadOnlyList<int> entityIds,
CancellationToken cancellationToken) { }
}
""").MatchMarkdownAsync();
}

[Fact]
public async Task GenerateSource_GroupedDataLoader_MatchesSnapshot()
{
await TestHelper.GetGeneratedSourceSnapshot(
"""
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using HotChocolate;

namespace TestNamespace;

internal static class TestClass
{
[DataLoader]
public static async Task<ILookup<int, Entity>> GetEntitiesByIdAsync(
IReadOnlyList<int> entityIds,
CancellationToken cancellationToken) { }
}
""").MatchMarkdownAsync();
}

[Fact]
public async Task GenerateSource_CacheDataLoader_MatchesSnapshot()
{
await TestHelper.GetGeneratedSourceSnapshot(
"""
using System.Threading;
using System.Threading.Tasks;
using HotChocolate;

namespace TestNamespace;

internal static class TestClass
{
[DataLoader]
public static async Task<Entity> GetEntityByIdAsync(
int entityId,
CancellationToken cancellationToken) { }
}
""").MatchMarkdownAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
<ItemGroup>
<ProjectReference Include="..\..\src\Core\HotChocolate.Core.csproj" />
<ProjectReference Include="..\Utilities\HotChocolate.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Types.Analyzers\HotChocolate.Types.Analyzers.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\..\src\Types.Analyzers\HotChocolate.Types.Analyzers.csproj" OutputItemType="Analyzer" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Basic.Reference.Assemblies" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
</ItemGroup>

<ItemGroup>
Expand Down
154 changes: 154 additions & 0 deletions src/HotChocolate/Core/test/Types.Analyzers.Tests/TestHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.RegularExpressions;
using Basic.Reference.Assemblies;
using CookieCrumble;
using HotChocolate.Types.Analyzers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

namespace HotChocolate.Types;

internal static partial class TestHelper
{
public static Snapshot GetGeneratedSourceSnapshot([StringSyntax("csharp")] string sourceText)
{
// Parse the provided string into a C# syntax tree.
var syntaxTree = CSharpSyntaxTree.ParseText(sourceText);

IEnumerable<PortableExecutableReference> references = new[]
{
MetadataReference.CreateFromFile(typeof(DataLoaderAttribute).Assembly.Location)
};

// Create a Roslyn compilation for the syntax tree.
var compilation = CSharpCompilation.Create(
assemblyName: "Tests",
syntaxTrees: new[] { syntaxTree },
ReferenceAssemblies.Net80.Concat(references));

// Create an instance of our GraphQLServerGenerator incremental source generator.
var generator = new GraphQLServerGenerator();

// The GeneratorDriver is used to run our generator against a compilation.
GeneratorDriver driver = CSharpGeneratorDriver.Create(generator);

// Run the source generator.
driver = driver.RunGenerators(compilation);

// Create a snapshot.
return CreateSnapshot(driver);
}

private static Snapshot CreateSnapshot(GeneratorDriver driver)
{
var snapshot = new Snapshot();

foreach (var result in driver.GetRunResult().Results)
{
// Add sources.
var sources = result.GeneratedSources.OrderBy(s => s.HintName);

foreach (var source in sources)
{
var text = source.SourceText.ToString();

// Replace variable hash in class name.
if (source.HintName.StartsWith("HotChocolateMiddleware"))
{
text = MiddlewareFactoryHashRegex().Replace(
text,
m => m.Value.Replace(m.Groups[1].Value, "HASH"));
}

snapshot.Add(text, source.HintName);
}

// Add diagnostics.
if (result.Diagnostics.Any())
{
AddDiagnosticsToSnapshot(snapshot, result.Diagnostics);
}
}

return snapshot;
}

private static void AddDiagnosticsToSnapshot(
Snapshot snapshot,
ImmutableArray<Diagnostic> diagnostics)
{
using var stream = new MemoryStream();
using var jsonWriter = new Utf8JsonWriter(
stream,
new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Indented = true
});

jsonWriter.WriteStartArray();

foreach (var diagnostic in diagnostics)
{
jsonWriter.WriteStartObject();
jsonWriter.WriteString(nameof(diagnostic.Id), diagnostic.Id);

var descriptor = diagnostic.Descriptor;

jsonWriter.WriteString(nameof(descriptor.Title), descriptor.Title.ToString());
jsonWriter.WriteString(nameof(diagnostic.Severity), diagnostic.Severity.ToString());
jsonWriter.WriteNumber(nameof(diagnostic.WarningLevel), diagnostic.WarningLevel);

jsonWriter.WriteString(
nameof(diagnostic.Location),
diagnostic.Location.GetMappedLineSpan().ToString());

var description = descriptor.Description.ToString();
if (!string.IsNullOrWhiteSpace(description))
{
jsonWriter.WriteString(nameof(descriptor.Description), description);
}

var help = descriptor.HelpLinkUri;
if (!string.IsNullOrWhiteSpace(help))
{
jsonWriter.WriteString(nameof(descriptor.HelpLinkUri), help);
}

jsonWriter.WriteString(
nameof(descriptor.MessageFormat),
descriptor.MessageFormat.ToString());

jsonWriter.WriteString("Message", diagnostic.GetMessage());
jsonWriter.WriteString(nameof(descriptor.Category), descriptor.Category);

jsonWriter.WritePropertyName(nameof(descriptor.CustomTags));

jsonWriter.WriteStartArray();

foreach (var tag in descriptor.CustomTags)
{
jsonWriter.WriteStringValue(tag);
}

jsonWriter.WriteEndArray();

jsonWriter.WriteEndObject();
}

jsonWriter.WriteEndArray();
jsonWriter.Flush();

snapshot.Add(Encoding.UTF8.GetString(stream.ToArray()), "Diagnostics");
}

[GeneratedRegex("MiddlewareFactories([a-z0-9]{32})")]
private static partial Regex MiddlewareFactoryHashRegex();
}
Loading

0 comments on commit 33900c7

Please sign in to comment.