Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added generator tests #1765

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions Refit.GeneratorTests/Fixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Refit.Generator;

namespace Refit.GeneratorTests;

public static class Fixture
{
static readonly MetadataReference RefitAssembly = MetadataReference.CreateFromFile(
typeof(GetAttribute).Assembly.Location,
documentation: XmlDocumentationProvider.CreateFromFile(
Path.ChangeExtension(typeof(GetAttribute).Assembly.Location, ".xml")
)
);

private static readonly Type[] ImportantAssemblies = {
typeof(Binder),
typeof(GetAttribute),
typeof(System.Reactive.Unit),
typeof(Enumerable),
typeof(Newtonsoft.Json.JsonConvert),
typeof(FactAttribute),
typeof(HttpContent),
typeof(Attribute)
};

private static Assembly[] AssemblyReferencesForCodegen =>
AppDomain.CurrentDomain
.GetAssemblies()
.Concat(ImportantAssemblies.Select(x=>x.Assembly))
.Distinct()
.Where(a => !a.IsDynamic)
.ToArray();

public static Task VerifyForBody(string body)
{
var source =
$$"""
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Refit;

namespace RefitGeneratorTest;

public interface IGeneratedClient
{
{{body}}
}
""";

return VerifyGenerator(source);
}

private static CSharpCompilation CreateLibrary(params string[] source)
{
var references = new List<MetadataReference>();
var assemblies = AssemblyReferencesForCodegen;
foreach (var assembly in assemblies)
{
if (!assembly.IsDynamic)
{
references.Add(MetadataReference.CreateFromFile(assembly.Location));
}
}

references.Add(RefitAssembly);
var compilation = CSharpCompilation.Create(
"compilation",
source.Select(s => CSharpSyntaxTree.ParseText(s)),
references,
new CSharpCompilationOptions(OutputKind.ConsoleApplication)
);

return compilation;
}

private static Task<VerifyResult> VerifyGenerator(string source)
{
var compilation = CreateLibrary(source);

var generator = new InterfaceStubGenerator();
var driver = CSharpGeneratorDriver.Create(generator);

var ranDriver = driver.RunGenerators(compilation);
var settings = new VerifySettings();
var verify = VerifyXunit.Verifier.Verify(ranDriver, settings);
return verify.ToTask();
}
}
19 changes: 19 additions & 0 deletions Refit.GeneratorTests/ModuleInitializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Runtime.CompilerServices;
using VerifyTests.DiffPlex;

namespace Refit.GeneratorTests;

public static class ModuleInitializer
{
// ModuleInitializer should only be used in apps
#pragma warning disable CA2255
[ModuleInitializer]
#pragma warning restore CA2255
public static void Init()
{
DerivePathInfo((file, _, type, method) => new(Path.Combine(Path.GetDirectoryName(file), "_snapshots"), type.Name, method.Name));

VerifySourceGenerators.Initialize();
VerifyDiffPlex.Initialize(OutputType.Compact);
}
}
46 changes: 46 additions & 0 deletions Refit.GeneratorTests/Refit.GeneratorTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\Refit\targets\refit.props" />

<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<NoWarn>$(NoWarn);CS1591;CA1819;CA2000;CA2007;CA1056;CA1707;CA1861;xUnit1031</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="xunit" Version="2.5.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/>
<PackageReference Include="System.Collections.Immutable" Version="9.0.0-preview.5.24306.7" />
<PackageReference Include="Verify.DiffPlex" Version="2.3.0" />
<PackageReference Include="Verify.SourceGenerators" Version="2.2.0" />
<PackageReference Include="Verify.Xunit" Version="22.1.4" />
<PackageReference Include="System.Reactive" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing" Version="1.1.2-beta1.24314.1" />
<ProjectReference Include="..\Refit.Newtonsoft.Json\Refit.Newtonsoft.Json.csproj" />
<ProjectReference Include="..\Refit.Xml\Refit.Xml.csproj" />
<ProjectReference Include="..\InterfaceStubGenerator.Roslyn38\InterfaceStubGenerator.Roslyn38.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="true" />
<ProjectReference Include="..\InterfaceStubGenerator.Roslyn40\InterfaceStubGenerator.Roslyn40.csproj" />
<ProjectReference Include="..\Refit\Refit.csproj" />
</ItemGroup>

<ItemGroup>
<None Include="..\Refit.GeneratorTests\_snapshots\**">
<Link>%(RecursiveDir)\resources\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Using Include="Xunit"/>
</ItemGroup>

<ItemGroup>
<Folder Include="_snapshots\" />
</ItemGroup>
</Project>
25 changes: 25 additions & 0 deletions Refit.GeneratorTests/ReturnTypeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Refit.GeneratorTests;

[UsesVerify]
public class ReturnTypeTests
{
[Fact]
public Task GenericTaskShouldWork()
{
return Fixture.VerifyForBody(
"""
[Get("/users")]
Task<string> Get();
""");
}

[Fact]
public Task VoidTaskShouldWork()
{
return Fixture.VerifyForBody(
"""
[Post("/users")]
Task Post();
""");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//HintName: Generated.g.cs

#pragma warning disable
namespace Refit.Implementation
{

/// <inheritdoc />
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.Diagnostics.DebuggerNonUserCode]
[global::RefitInternalGenerated.PreserveAttribute]
[global::System.Reflection.Obfuscation(Exclude=true)]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
internal static partial class Generated
{
#if NET5_0_OR_GREATER
[System.Runtime.CompilerServices.ModuleInitializer]
[System.Diagnostics.CodeAnalysis.DynamicDependency(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(global::Refit.Implementation.Generated))]
public static void Initialize()
{
}
#endif
}
}
#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//HintName: IGeneratedClient.g.cs
#nullable disable
#pragma warning disable
namespace Refit.Implementation
{

partial class Generated
{

/// <inheritdoc />
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.Diagnostics.DebuggerNonUserCode]
[global::RefitInternalGenerated.PreserveAttribute]
[global::System.Reflection.Obfuscation(Exclude=true)]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
partial class RefitGeneratorTestIGeneratedClient
: global::RefitGeneratorTest.IGeneratedClient

{
/// <inheritdoc />
public global::System.Net.Http.HttpClient Client { get; }
readonly global::Refit.IRequestBuilder requestBuilder;

/// <inheritdoc />
public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient client, global::Refit.IRequestBuilder requestBuilder)
{
Client = client;
this.requestBuilder = requestBuilder;
}



/// <inheritdoc />
public async global::System.Threading.Tasks.Task<string> Get()
{
var ______arguments = global::System.Array.Empty<object>();
var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty<global::System.Type>() );
try
{
return await ((global::System.Threading.Tasks.Task<string>)______func(this.Client, ______arguments)).ConfigureAwait(false);
}
catch (global::System.Exception ______ex)
{
throw ______ex;
}
}

/// <inheritdoc />
async global::System.Threading.Tasks.Task<string> global::RefitGeneratorTest.IGeneratedClient.Get()
{
var ______arguments = global::System.Array.Empty<object>();
var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty<global::System.Type>() );
try
{
return await ((global::System.Threading.Tasks.Task<string>)______func(this.Client, ______arguments)).ConfigureAwait(false);
}
catch (global::System.Exception ______ex)
{
throw ______ex;
}
}
}
}
}

#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//HintName: PreserveAttribute.g.cs

#pragma warning disable
namespace RefitInternalGenerated
{
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.AttributeUsage (global::System.AttributeTargets.Class | global::System.AttributeTargets.Struct | global::System.AttributeTargets.Enum | global::System.AttributeTargets.Constructor | global::System.AttributeTargets.Method | global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Event | global::System.AttributeTargets.Interface | global::System.AttributeTargets.Delegate)]
sealed class PreserveAttribute : global::System.Attribute
{
//
// Fields
//
public bool AllMembers;

public bool Conditional;
}
}
#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//HintName: Generated.g.cs

#pragma warning disable
namespace Refit.Implementation
{

/// <inheritdoc />
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.Diagnostics.DebuggerNonUserCode]
[global::RefitInternalGenerated.PreserveAttribute]
[global::System.Reflection.Obfuscation(Exclude=true)]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
internal static partial class Generated
{
#if NET5_0_OR_GREATER
[System.Runtime.CompilerServices.ModuleInitializer]
[System.Diagnostics.CodeAnalysis.DynamicDependency(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(global::Refit.Implementation.Generated))]
public static void Initialize()
{
}
#endif
}
}
#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//HintName: IGeneratedClient.g.cs
#nullable disable
#pragma warning disable
namespace Refit.Implementation
{

partial class Generated
{

/// <inheritdoc />
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.Diagnostics.DebuggerNonUserCode]
[global::RefitInternalGenerated.PreserveAttribute]
[global::System.Reflection.Obfuscation(Exclude=true)]
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
partial class RefitGeneratorTestIGeneratedClient
: global::RefitGeneratorTest.IGeneratedClient

{
/// <inheritdoc />
public global::System.Net.Http.HttpClient Client { get; }
readonly global::Refit.IRequestBuilder requestBuilder;

/// <inheritdoc />
public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient client, global::Refit.IRequestBuilder requestBuilder)
{
Client = client;
this.requestBuilder = requestBuilder;
}



/// <inheritdoc />
public async global::System.Threading.Tasks.Task Post()
{
var ______arguments = global::System.Array.Empty<object>();
var ______func = requestBuilder.BuildRestResultFuncForMethod("Post", global::System.Array.Empty<global::System.Type>() );
try
{
await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false);
}
catch (global::System.Exception ______ex)
{
throw ______ex;
}
}

/// <inheritdoc />
async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Post()
{
var ______arguments = global::System.Array.Empty<object>();
var ______func = requestBuilder.BuildRestResultFuncForMethod("Post", global::System.Array.Empty<global::System.Type>() );
try
{
await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false);
}
catch (global::System.Exception ______ex)
{
throw ______ex;
}
}
}
}
}

#pragma warning restore
Loading
Loading