From d2b580cb3a6fbc03e2abe4e79d17148d4eb4ba1a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 11:04:39 +0000 Subject: [PATCH 1/4] test: add unit and API approval tests Co-authored-by: mauroservienti <1325611+mauroservienti@users.noreply.github.com> --- .github/workflows/ci.yml | 8 +- .../PublicApi.approved.txt | 11 +++ .../PublicApiApprovalTests.cs | 84 +++++++++++++++++++ ...ceComposer.AspNetCore.Testing.Tests.csproj | 26 ++++++ .../TestResults/results.trx | 64 ++++++++++++++ .../UnitTest1.cs | 76 +++++++++++++++++ src/ServiceComposer.AspNetCore.Testing.sln | 6 ++ 7 files changed, 271 insertions(+), 4 deletions(-) create mode 100644 src/ServiceComposer.AspNetCore.Testing.Tests/PublicApi.approved.txt create mode 100644 src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.cs create mode 100644 src/ServiceComposer.AspNetCore.Testing.Tests/ServiceComposer.AspNetCore.Testing.Tests.csproj create mode 100644 src/ServiceComposer.AspNetCore.Testing.Tests/TestResults/results.trx create mode 100644 src/ServiceComposer.AspNetCore.Testing.Tests/UnitTest1.cs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42976aa..3e679f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,10 +35,10 @@ jobs: 8.0.x 9.0.x 10.0.x - - name: Build - run: dotnet build src --configuration Release - - name: Tests - run: dotnet test src --configuration Release --no-build + - name: Build + run: dotnet build src/ServiceComposer.AspNetCore.Testing.sln --configuration Release + - name: Tests + run: dotnet test src/ServiceComposer.AspNetCore.Testing.sln --configuration Release --no-build - name: Upload packages if: matrix.name == 'Linux' uses: actions/upload-artifact@v6.0.0 diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApi.approved.txt b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApi.approved.txt new file mode 100644 index 0000000..b16993f --- /dev/null +++ b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApi.approved.txt @@ -0,0 +1,11 @@ +type ServiceComposer.AspNetCore.Testing.SelfContainedWebApplicationFactoryWithHost + ctor SelfContainedWebApplicationFactoryWithHost`1(System.Action configureServices, System.Action configure, System.String[] args) + property System.Action HostBuilderCustomization + property System.Action WebHostBuilderCustomization +type ServiceComposer.AspNetCore.Testing.SelfContainedWebApplicationFactoryWithWebHost + ctor SelfContainedWebApplicationFactoryWithWebHost`1(System.Action configureServices, System.Action configure) + ctor SelfContainedWebApplicationFactoryWithWebHost`1(System.Action configureServices, System.Action configure) + property System.Action BuilderCustomization +type ServiceComposer.AspNetCore.Testing.WebApplicationFactoryWithWebHost + ctor WebApplicationFactoryWithWebHost`1() + property System.Action BuilderCustomization diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.cs b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.cs new file mode 100644 index 0000000..d8c7769 --- /dev/null +++ b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.cs @@ -0,0 +1,84 @@ +using System.Reflection; +using System.Text; + +namespace ServiceComposer.AspNetCore.Testing.Tests; + +public class PublicApiApprovalTests +{ + [Fact] + public void Public_api_is_approved() + { + var actual = GeneratePublicApi(); + var approvedPath = Path.Combine(AppContext.BaseDirectory, "PublicApi.approved.txt"); + var approved = File.ReadAllText(approvedPath); + + Assert.Equal(Normalize(approved), Normalize(actual)); + } + + static string GeneratePublicApi() + { + var assembly = typeof(WebApplicationFactoryWithWebHost<>).Assembly; + var lines = new List(); + + foreach (var type in assembly.GetExportedTypes().OrderBy(t => t.FullName, StringComparer.Ordinal)) + { + lines.Add($"type {FormatTypeName(type)}"); + + foreach (var constructor in type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).OrderBy(c => c.ToString(), StringComparer.Ordinal)) + { + lines.Add($" ctor {FormatConstructor(constructor)}"); + } + + foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly).OrderBy(p => p.Name, StringComparer.Ordinal)) + { + lines.Add($" property {FormatTypeName(property.PropertyType)} {property.Name}"); + } + + foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly) + .Where(m => !m.IsSpecialName) + .OrderBy(m => m.ToString(), StringComparer.Ordinal)) + { + lines.Add($" method {FormatTypeName(method.ReturnType)} {method.Name}({string.Join(", ", method.GetParameters().Select(FormatParameter))})"); + } + } + + return string.Join(Environment.NewLine, lines); + } + + static string FormatConstructor(ConstructorInfo constructor) => $"{constructor.DeclaringType!.Name}({string.Join(", ", constructor.GetParameters().Select(FormatParameter))})"; + + static string FormatParameter(ParameterInfo parameter) => $"{FormatTypeName(parameter.ParameterType)} {parameter.Name}"; + + static string FormatTypeName(Type type) + { + if (type.IsGenericType) + { + var genericTypeName = type.GetGenericTypeDefinition().FullName!; + var tickIndex = genericTypeName.IndexOf('`'); + var typeName = tickIndex >= 0 ? genericTypeName[..tickIndex] : genericTypeName; + return $"{typeName}<{string.Join(", ", type.GetGenericArguments().Select(FormatTypeName))}>"; + } + + return type.FullName ?? type.Name; + } + + static string Normalize(string value) + { + var builder = new StringBuilder(value.Length); + using var reader = new StringReader(value); + string? line; + var first = true; + while ((line = reader.ReadLine()) != null) + { + if (!first) + { + builder.Append('\n'); + } + + builder.Append(line.TrimEnd()); + first = false; + } + + return builder.ToString(); + } +} diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/ServiceComposer.AspNetCore.Testing.Tests.csproj b/src/ServiceComposer.AspNetCore.Testing.Tests/ServiceComposer.AspNetCore.Testing.Tests.csproj new file mode 100644 index 0000000..2c8bcce --- /dev/null +++ b/src/ServiceComposer.AspNetCore.Testing.Tests/ServiceComposer.AspNetCore.Testing.Tests.csproj @@ -0,0 +1,26 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + + + + + + + diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/TestResults/results.trx b/src/ServiceComposer.AspNetCore.Testing.Tests/TestResults/results.trx new file mode 100644 index 0000000..8941584 --- /dev/null +++ b/src/ServiceComposer.AspNetCore.Testing.Tests/TestResults/results.trx @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v3.1.4+50e68bbb8b (64-bit .NET 10.0.2) +[xUnit.net 00:00:00.21] Discovering: ServiceComposer.AspNetCore.Testing.Tests +[xUnit.net 00:00:00.33] Discovered: ServiceComposer.AspNetCore.Testing.Tests +[xUnit.net 00:00:00.40] Starting: ServiceComposer.AspNetCore.Testing.Tests +info: Microsoft.Hosting.Lifetime[0] + Application started. Press Ctrl+C to shut down. +info: Microsoft.Hosting.Lifetime[0] + Hosting environment: Production +info: Microsoft.Hosting.Lifetime[0] + Content root path: /home/runner/work/ServiceComposer.AspNetCore.Testing/ServiceComposer.AspNetCore.Testing/src/ServiceComposer.AspNetCore.Testing.Tests +info: Microsoft.AspNetCore.Hosting.Diagnostics[1] + Request starting HTTP/1.1 GET http://localhost/ - - - +info: Microsoft.AspNetCore.Hosting.Diagnostics[2] + Request finished HTTP/1.1 GET http://localhost/ - 200 - - 26.0553ms +info: Microsoft.Hosting.Lifetime[0] + Application is shutting down... +[xUnit.net 00:00:00.90] Finished: ServiceComposer.AspNetCore.Testing.Tests + + + + \ No newline at end of file diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/UnitTest1.cs b/src/ServiceComposer.AspNetCore.Testing.Tests/UnitTest1.cs new file mode 100644 index 0000000..c4ab1ce --- /dev/null +++ b/src/ServiceComposer.AspNetCore.Testing.Tests/UnitTest1.cs @@ -0,0 +1,76 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace ServiceComposer.AspNetCore.Testing.Tests; + +public class SelfContainedWebApplicationFactoryTests +{ + [Fact] + public async Task SelfContainedFactoryWithHost_serves_request() + { + await using var factory = new SelfContainedWebApplicationFactoryWithHost( + services => services.AddSingleton(new Message("host")), + app => app.Run(async context => + { + var message = context.RequestServices.GetRequiredService(); + await context.Response.WriteAsync(message.Value); + })); + + var client = factory.CreateClient(); + var response = await client.GetStringAsync("/"); + + Assert.Equal("host", response); + } + + [Fact] + public async Task SelfContainedFactoryWithWebHost_invokes_builder_customization() + { + var builderCustomizationCalled = false; + await using var factory = new SelfContainedWebApplicationFactoryWithWebHost( + services => services.AddSingleton(new Message("webhost")), + app => app.Run(async context => + { + var message = context.RequestServices.GetRequiredService(); + await context.Response.WriteAsync(message.Value); + })) + { + BuilderCustomization = _ => builderCustomizationCalled = true + }; + + var client = factory.CreateClient(); + var response = await client.GetStringAsync("/"); + + Assert.Equal("webhost", response); + Assert.True(builderCustomizationCalled); + } + + [Fact] + public async Task WebApplicationFactoryWithWebHost_invokes_builder_customization() + { + var builderCustomizationCalled = false; + await using var factory = new WebApplicationFactoryWithWebHost + { + BuilderCustomization = _ => builderCustomizationCalled = true + }; + + var client = factory.CreateClient(); + var response = await client.GetStringAsync("/"); + + Assert.Equal("startup", response); + Assert.True(builderCustomizationCalled); + } + + class TestEntryPoint; + + class Startup + { + public void Configure(IApplicationBuilder app) + { + app.Run(context => context.Response.WriteAsync("startup")); + } + } + + record Message(string Value); +} diff --git a/src/ServiceComposer.AspNetCore.Testing.sln b/src/ServiceComposer.AspNetCore.Testing.sln index a7867d2..32a1cab 100644 --- a/src/ServiceComposer.AspNetCore.Testing.sln +++ b/src/ServiceComposer.AspNetCore.Testing.sln @@ -4,6 +4,8 @@ VisualStudioVersion = 15.0.26730.16 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceComposer.AspNetCore.Testing", "ServiceComposer.AspNetCore.Testing\ServiceComposer.AspNetCore.Testing.csproj", "{37843543-9921-4A2E-A62E-EC64E08A8BA6}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceComposer.AspNetCore.Testing.Tests", "ServiceComposer.AspNetCore.Testing.Tests\ServiceComposer.AspNetCore.Testing.Tests.csproj", "{83B393CD-C479-4306-B2B5-56EB3B75170E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -14,6 +16,10 @@ Global {37843543-9921-4A2E-A62E-EC64E08A8BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU {37843543-9921-4A2E-A62E-EC64E08A8BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU {37843543-9921-4A2E-A62E-EC64E08A8BA6}.Release|Any CPU.Build.0 = Release|Any CPU + {83B393CD-C479-4306-B2B5-56EB3B75170E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83B393CD-C479-4306-B2B5-56EB3B75170E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83B393CD-C479-4306-B2B5-56EB3B75170E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83B393CD-C479-4306-B2B5-56EB3B75170E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From b067461e2ac5248815bf791c3b03d0f67c00f874 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 11:04:47 +0000 Subject: [PATCH 2/4] chore: remove committed test result artifact Co-authored-by: mauroservienti <1325611+mauroservienti@users.noreply.github.com> --- .../TestResults/results.trx | 64 ------------------- 1 file changed, 64 deletions(-) delete mode 100644 src/ServiceComposer.AspNetCore.Testing.Tests/TestResults/results.trx diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/TestResults/results.trx b/src/ServiceComposer.AspNetCore.Testing.Tests/TestResults/results.trx deleted file mode 100644 index 8941584..0000000 --- a/src/ServiceComposer.AspNetCore.Testing.Tests/TestResults/results.trx +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v3.1.4+50e68bbb8b (64-bit .NET 10.0.2) -[xUnit.net 00:00:00.21] Discovering: ServiceComposer.AspNetCore.Testing.Tests -[xUnit.net 00:00:00.33] Discovered: ServiceComposer.AspNetCore.Testing.Tests -[xUnit.net 00:00:00.40] Starting: ServiceComposer.AspNetCore.Testing.Tests -info: Microsoft.Hosting.Lifetime[0] - Application started. Press Ctrl+C to shut down. -info: Microsoft.Hosting.Lifetime[0] - Hosting environment: Production -info: Microsoft.Hosting.Lifetime[0] - Content root path: /home/runner/work/ServiceComposer.AspNetCore.Testing/ServiceComposer.AspNetCore.Testing/src/ServiceComposer.AspNetCore.Testing.Tests -info: Microsoft.AspNetCore.Hosting.Diagnostics[1] - Request starting HTTP/1.1 GET http://localhost/ - - - -info: Microsoft.AspNetCore.Hosting.Diagnostics[2] - Request finished HTTP/1.1 GET http://localhost/ - 200 - - 26.0553ms -info: Microsoft.Hosting.Lifetime[0] - Application is shutting down... -[xUnit.net 00:00:00.90] Finished: ServiceComposer.AspNetCore.Testing.Tests - - - - \ No newline at end of file From 649859eca0167f6c60e932ecadc63f6022373533 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 11:07:52 +0000 Subject: [PATCH 3/4] test: rename factory test file for clarity Co-authored-by: mauroservienti <1325611+mauroservienti@users.noreply.github.com> --- .../{UnitTest1.cs => SelfContainedWebApplicationFactoryTests.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/ServiceComposer.AspNetCore.Testing.Tests/{UnitTest1.cs => SelfContainedWebApplicationFactoryTests.cs} (100%) diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/UnitTest1.cs b/src/ServiceComposer.AspNetCore.Testing.Tests/SelfContainedWebApplicationFactoryTests.cs similarity index 100% rename from src/ServiceComposer.AspNetCore.Testing.Tests/UnitTest1.cs rename to src/ServiceComposer.AspNetCore.Testing.Tests/SelfContainedWebApplicationFactoryTests.cs From 4e88e71a666238d4ea99fc14c0f7d540ca0387a6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 11:22:14 +0000 Subject: [PATCH 4/4] test: use PublicApiGenerator with Verify for API approval Co-authored-by: mauroservienti <1325611+mauroservienti@users.noreply.github.com> --- .../PublicApi.approved.txt | 11 --- ...lTests.Public_api_is_approved.verified.txt | 30 +++++++ .../PublicApiApprovalTests.cs | 80 ++----------------- ...ceComposer.AspNetCore.Testing.Tests.csproj | 3 +- 4 files changed, 37 insertions(+), 87 deletions(-) delete mode 100644 src/ServiceComposer.AspNetCore.Testing.Tests/PublicApi.approved.txt create mode 100644 src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.Public_api_is_approved.verified.txt diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApi.approved.txt b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApi.approved.txt deleted file mode 100644 index b16993f..0000000 --- a/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApi.approved.txt +++ /dev/null @@ -1,11 +0,0 @@ -type ServiceComposer.AspNetCore.Testing.SelfContainedWebApplicationFactoryWithHost - ctor SelfContainedWebApplicationFactoryWithHost`1(System.Action configureServices, System.Action configure, System.String[] args) - property System.Action HostBuilderCustomization - property System.Action WebHostBuilderCustomization -type ServiceComposer.AspNetCore.Testing.SelfContainedWebApplicationFactoryWithWebHost - ctor SelfContainedWebApplicationFactoryWithWebHost`1(System.Action configureServices, System.Action configure) - ctor SelfContainedWebApplicationFactoryWithWebHost`1(System.Action configureServices, System.Action configure) - property System.Action BuilderCustomization -type ServiceComposer.AspNetCore.Testing.WebApplicationFactoryWithWebHost - ctor WebApplicationFactoryWithWebHost`1() - property System.Action BuilderCustomization diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.Public_api_is_approved.verified.txt b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.Public_api_is_approved.verified.txt new file mode 100644 index 0000000..992ad5c --- /dev/null +++ b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.Public_api_is_approved.verified.txt @@ -0,0 +1,30 @@ +[assembly: System.Reflection.AssemblyMetadata("RepositoryUrl", "https://github.com/ServiceComposer/ServiceComposer.AspNetCore.Testing")] +[assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v10.0", FrameworkDisplayName=".NET 10.0")] +namespace ServiceComposer.AspNetCore.Testing +{ + public class SelfContainedWebApplicationFactoryWithHost : Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory + where TEntryPoint : class + { + public SelfContainedWebApplicationFactoryWithHost(System.Action configureServices, System.Action configure, string[] args = null) { } + public System.Action HostBuilderCustomization { get; set; } + public System.Action WebHostBuilderCustomization { get; set; } + protected override Microsoft.Extensions.Hosting.IHostBuilder CreateHostBuilder() { } + } + public class SelfContainedWebApplicationFactoryWithWebHost : Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory + where TEntryPoint : class + { + public SelfContainedWebApplicationFactoryWithWebHost(System.Action configureServices, System.Action configure) { } + public SelfContainedWebApplicationFactoryWithWebHost(System.Action configureServices, System.Action configure) { } + public System.Action BuilderCustomization { get; set; } + protected override void ConfigureWebHost(Microsoft.AspNetCore.Hosting.IWebHostBuilder builder) { } + protected override Microsoft.AspNetCore.Hosting.IWebHostBuilder CreateWebHostBuilder() { } + } + public class WebApplicationFactoryWithWebHost : Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory + where TStartup : class + { + public WebApplicationFactoryWithWebHost() { } + public System.Action BuilderCustomization { get; set; } + protected override void ConfigureWebHost(Microsoft.AspNetCore.Hosting.IWebHostBuilder builder) { } + protected override Microsoft.AspNetCore.Hosting.IWebHostBuilder CreateWebHostBuilder() { } + } +} \ No newline at end of file diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.cs b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.cs index d8c7769..027da55 100644 --- a/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.cs +++ b/src/ServiceComposer.AspNetCore.Testing.Tests/PublicApiApprovalTests.cs @@ -1,84 +1,14 @@ -using System.Reflection; -using System.Text; +using PublicApiGenerator; +using VerifyXunit; namespace ServiceComposer.AspNetCore.Testing.Tests; public class PublicApiApprovalTests { [Fact] - public void Public_api_is_approved() + public Task Public_api_is_approved() { - var actual = GeneratePublicApi(); - var approvedPath = Path.Combine(AppContext.BaseDirectory, "PublicApi.approved.txt"); - var approved = File.ReadAllText(approvedPath); - - Assert.Equal(Normalize(approved), Normalize(actual)); - } - - static string GeneratePublicApi() - { - var assembly = typeof(WebApplicationFactoryWithWebHost<>).Assembly; - var lines = new List(); - - foreach (var type in assembly.GetExportedTypes().OrderBy(t => t.FullName, StringComparer.Ordinal)) - { - lines.Add($"type {FormatTypeName(type)}"); - - foreach (var constructor in type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).OrderBy(c => c.ToString(), StringComparer.Ordinal)) - { - lines.Add($" ctor {FormatConstructor(constructor)}"); - } - - foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly).OrderBy(p => p.Name, StringComparer.Ordinal)) - { - lines.Add($" property {FormatTypeName(property.PropertyType)} {property.Name}"); - } - - foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly) - .Where(m => !m.IsSpecialName) - .OrderBy(m => m.ToString(), StringComparer.Ordinal)) - { - lines.Add($" method {FormatTypeName(method.ReturnType)} {method.Name}({string.Join(", ", method.GetParameters().Select(FormatParameter))})"); - } - } - - return string.Join(Environment.NewLine, lines); - } - - static string FormatConstructor(ConstructorInfo constructor) => $"{constructor.DeclaringType!.Name}({string.Join(", ", constructor.GetParameters().Select(FormatParameter))})"; - - static string FormatParameter(ParameterInfo parameter) => $"{FormatTypeName(parameter.ParameterType)} {parameter.Name}"; - - static string FormatTypeName(Type type) - { - if (type.IsGenericType) - { - var genericTypeName = type.GetGenericTypeDefinition().FullName!; - var tickIndex = genericTypeName.IndexOf('`'); - var typeName = tickIndex >= 0 ? genericTypeName[..tickIndex] : genericTypeName; - return $"{typeName}<{string.Join(", ", type.GetGenericArguments().Select(FormatTypeName))}>"; - } - - return type.FullName ?? type.Name; - } - - static string Normalize(string value) - { - var builder = new StringBuilder(value.Length); - using var reader = new StringReader(value); - string? line; - var first = true; - while ((line = reader.ReadLine()) != null) - { - if (!first) - { - builder.Append('\n'); - } - - builder.Append(line.TrimEnd()); - first = false; - } - - return builder.ToString(); + var publicApi = ApiGenerator.GeneratePublicApi(typeof(WebApplicationFactoryWithWebHost<>).Assembly); + return Verifier.Verify(publicApi); } } diff --git a/src/ServiceComposer.AspNetCore.Testing.Tests/ServiceComposer.AspNetCore.Testing.Tests.csproj b/src/ServiceComposer.AspNetCore.Testing.Tests/ServiceComposer.AspNetCore.Testing.Tests.csproj index 2c8bcce..367e041 100644 --- a/src/ServiceComposer.AspNetCore.Testing.Tests/ServiceComposer.AspNetCore.Testing.Tests.csproj +++ b/src/ServiceComposer.AspNetCore.Testing.Tests/ServiceComposer.AspNetCore.Testing.Tests.csproj @@ -10,6 +10,8 @@ + + @@ -20,7 +22,6 @@ -