diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/ApiConfigurationGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/ApiConfigurationGenerator.cs
index 946b325..6097593 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/ApiConfigurationGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/ApiConfigurationGenerator.cs
@@ -12,8 +12,11 @@ internal SourceCode GenerateClass() =>
using System;
namespace {{@namespace}};
-
- public sealed class {{ClassName}}
+
+ ///
+ /// Configuration for the generated web API.
+ ///
+ public sealed class {{ClassName}}
{
///
/// The uri to the exposed OpenAPI specification used to generate the API.
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/AuthGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/AuthGenerator.cs
index 44500a3..dc18a59 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/AuthGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/AuthGenerator.cs
@@ -31,8 +31,9 @@ public AuthGenerator(OpenApiDocument openApiDocument)
{
return null;
}
- return new SourceCode("SecuritySchemes.g.cs",
+ return new SourceCode("SecuritySchemes.g.cs",
$$"""
+using Microsoft.AspNetCore.Http;
using System.Collections.Immutable;
namespace {{@namespace}};
@@ -216,7 +217,12 @@ internal static class {{className}}
#nullable enable
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Security.Claims;
+using System.Threading.Tasks;
namespace {{@namespace}};
@@ -387,13 +393,15 @@ internal sealed class {{securityRequirementsFilterClassName}}(Operation operatio
protected override SecurityRequirements Requirements { get; } = new()
{{{string.Join(",",
securityRequirementGroups.Select(securityRequirementGroup =>
- securityRequirementGroup.AggregateToString(securityRequirement =>
+ securityRequirementGroup.Any() ? securityRequirementGroup.AggregateToString(securityRequirement =>
$$"""
new SecurityRequirement
{
["{{securityRequirement.Key}}"] = [{{string.Join(", ", securityRequirement.Value.Select(scope => $"\"{scope}\""))}}]
}
-""")))}}
+""") : """
+ new SecurityRequirement()
+ """))}}
};
private static Request ResolveRequest(HttpContext context) => (Request) context.Items[RequestItemKey]!;
@@ -409,9 +417,11 @@ internal sealed class {{securityRequirementsFilterClassName}}(Operation operatio
{
return null;
}
- return new SourceCode("SecuritySchemeOptions.g.cs",
+ return new SourceCode("SecuritySchemeOptions.g.cs",
$$"""
#nullable enable
+using System;
+
namespace {{@namespace}};
///
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/HttpRequestExtensionsGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/HttpRequestExtensionsGenerator.cs
index aeead94..cca4a69 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/HttpRequestExtensionsGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/HttpRequestExtensionsGenerator.cs
@@ -37,11 +37,17 @@ internal SourceCode GenerateHttpRequestExtensionsClass() =>
new($"{HttpRequestExtensionsClassName}.g.cs",
$$$""""
#nullable enable
+ using System;
using System.Collections.Concurrent;
+ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+ using System.Linq;
using System.Text.Json;
+ using System.Threading;
+ using System.Threading.Tasks;
using Corvus.Json;
using Microsoft.AspNetCore.Http;
+ using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
using OpenAPI.ParameterStyleParsers;
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/HttpResponseExtensionsGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/HttpResponseExtensionsGenerator.cs
index b0d12a7..596050e 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/HttpResponseExtensionsGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/HttpResponseExtensionsGenerator.cs
@@ -21,7 +21,10 @@ internal SourceCode GenerateHttpResponseExtensionsClass() =>
new($"{HttpResponseExtensionsClassName}.g.cs",
$$$""""
#nullable enable
+ using System;
using System.Collections.Concurrent;
+ using System.Collections.Generic;
+ using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using Corvus.Json;
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/JsonValidationExceptionGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/JsonValidationExceptionGenerator.cs
index e066b7e..c246048 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/JsonValidationExceptionGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/JsonValidationExceptionGenerator.cs
@@ -16,7 +16,9 @@ internal SourceCode GenerateJsonValidationExceptionClass() =>
#nullable enable
using Corvus.Json;
using System;
+ using System.Collections.Generic;
using System.Collections.Immutable;
+ using System.Linq;
using System.Text;
namespace {{@namespace}};
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/OperationGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/OperationGenerator.cs
index 7705151..fca5fc8 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/OperationGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/OperationGenerator.cs
@@ -31,9 +31,14 @@ internal SourceCode Generate(string @namespace,
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Linq;
using System.Security.Claims;
using System.Threading;
+using System.Threading.Tasks;
namespace {{@namespace}};
{{ new[]
@@ -72,7 +77,7 @@ internal partial class Operation
/// Create a request validation error response.
///
/// The invalid request
- /// The validation context describing the validation errors
+ /// The validation context describing the validation errors
///
private Response CreateRequestValidationErrorResponse(Request request, ValidationContext validationContext)
{
@@ -272,6 +277,10 @@ private static Diagnostic CreateMissingHandlersDiagnosticMessage(string @namespa
private static string GenerateMissingHandler(string @namespace) =>
$$"""
+ using System;
+ using System.Threading;
+ using System.Threading.Tasks;
+
namespace {{@namespace}}
{
internal partial class Operation
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/OperationRouterGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/OperationRouterGenerator.cs
index e452fe9..4c5893e 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/OperationRouterGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/OperationRouterGenerator.cs
@@ -12,11 +12,14 @@ internal SourceCode ForMinimalApi(List<(string Namespace, KeyValuePair
-/// Configure routes for OpenAPI operations
+/// Configure routes for OpenAPI operations
///
internal static class OperationRouter
{
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/RequestGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/RequestGenerator.cs
index 8322fe4..8b1bc59 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/RequestGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/RequestGenerator.cs
@@ -31,6 +31,12 @@ internal SourceCode GenerateRequestClass(string @namespace, string path)
$$"""
#nullable enable
using Corvus.Json;
+using Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
namespace {{@namespace}};
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/ResponseGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/ResponseGenerator.cs
index 984e90e..cae6ff0 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/ResponseGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/ResponseGenerator.cs
@@ -14,8 +14,13 @@ public SourceCode GenerateResponseClass(string @namespace, string path)
$$"""
#nullable enable
using Corvus.Json;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
+using System;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+using System.Linq;
using System.Text.Json;
using {{httpResponseExtensionsGenerator.Namespace}};
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/SchemaGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/SchemaGenerator.cs
index bcfdd66..f5ab7aa 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/SchemaGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/SchemaGenerator.cs
@@ -152,6 +152,7 @@ private List GenerateCode(SourceGeneratorHelpers.TypesToGenerat
optionalAsNullable: typesToGenerate.OptionalAsNullable,
disabledNamingHeuristics: [.. typesToGenerate.DisabledNamingHeuristics],
fileExtension: ".g.cs",
+ addExplicitUsings: true,
defaultAccessibility: typesToGenerate.DefaultAccessibility);
var languageProvider = CSharpLanguageProvider.DefaultWithOptions(options);
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/SequentialMediaTypesGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/SequentialMediaTypesGenerator.cs
index c9c15f5..6a48c6d 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/SequentialMediaTypesGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/SequentialMediaTypesGenerator.cs
@@ -27,8 +27,12 @@ internal string GetFullyQualifiedTypeName(
using Microsoft.AspNetCore.Authorization;
using System;
using System.Buffers;
+using System.Collections.Generic;
+using System.IO;
using System.IO.Pipelines;
using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
namespace {{@namespace}};
diff --git a/src/OpenAPI.WebApiGenerator/CodeGeneration/ValidationExtensionsGenerator.cs b/src/OpenAPI.WebApiGenerator/CodeGeneration/ValidationExtensionsGenerator.cs
index acb99a5..787f8e4 100644
--- a/src/OpenAPI.WebApiGenerator/CodeGeneration/ValidationExtensionsGenerator.cs
+++ b/src/OpenAPI.WebApiGenerator/CodeGeneration/ValidationExtensionsGenerator.cs
@@ -7,7 +7,10 @@ internal sealed class ValidationExtensionsGenerator(string @namespace)
$$"""
#nullable enable
using Corvus.Json;
+using System;
+using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Linq;
using System.Text.Json;
namespace {{@namespace}};
diff --git a/tests/Example.OpenApi20/Example.OpenApi20.csproj b/tests/Example.OpenApi20/Example.OpenApi20.csproj
index f73c2e0..fb54a8e 100644
--- a/tests/Example.OpenApi20/Example.OpenApi20.csproj
+++ b/tests/Example.OpenApi20/Example.OpenApi20.csproj
@@ -5,6 +5,7 @@
enable
enable
Example.OpenApi20
+ true
true
LastMajorVersionBinary/$(AssemblyName).dll
diff --git a/tests/Example.OpenApi20/Program.cs b/tests/Example.OpenApi20/Program.cs
index f33ae56..b5ed162 100644
--- a/tests/Example.OpenApi20/Program.cs
+++ b/tests/Example.OpenApi20/Program.cs
@@ -37,4 +37,7 @@
app.MapOperations();
app.Run();
+///
+/// Application entry point.
+///
public abstract partial class Program;
diff --git a/tests/Example.OpenApi30/Example.OpenApi30.csproj b/tests/Example.OpenApi30/Example.OpenApi30.csproj
index d38bf49..25e57fe 100644
--- a/tests/Example.OpenApi30/Example.OpenApi30.csproj
+++ b/tests/Example.OpenApi30/Example.OpenApi30.csproj
@@ -5,6 +5,7 @@
enable
enable
Example.OpenApi30
+ true
true
LastMajorVersionBinary/$(AssemblyName).dll
diff --git a/tests/Example.OpenApi30/Program.cs b/tests/Example.OpenApi30/Program.cs
index a54f3e7..2504213 100644
--- a/tests/Example.OpenApi30/Program.cs
+++ b/tests/Example.OpenApi30/Program.cs
@@ -44,4 +44,7 @@
app.MapOperations();
app.Run();
+///
+/// Application entry point.
+///
public abstract partial class Program;
diff --git a/tests/Example.OpenApi31/Example.OpenApi31.csproj b/tests/Example.OpenApi31/Example.OpenApi31.csproj
index 34288c8..d7cff7f 100644
--- a/tests/Example.OpenApi31/Example.OpenApi31.csproj
+++ b/tests/Example.OpenApi31/Example.OpenApi31.csproj
@@ -5,6 +5,7 @@
enable
enable
Example.OpenApi31
+ true
true
LastMajorVersionBinary/$(AssemblyName).dll
diff --git a/tests/Example.OpenApi31/Program.cs b/tests/Example.OpenApi31/Program.cs
index 6b40083..c5e9686 100644
--- a/tests/Example.OpenApi31/Program.cs
+++ b/tests/Example.OpenApi31/Program.cs
@@ -49,4 +49,7 @@
app.MapOperations();
app.Run();
+///
+/// Application entry point.
+///
public abstract partial class Program;
\ No newline at end of file
diff --git a/tests/Example.OpenApi32/Example.OpenApi32.csproj b/tests/Example.OpenApi32/Example.OpenApi32.csproj
index feb3185..9f7c92f 100644
--- a/tests/Example.OpenApi32/Example.OpenApi32.csproj
+++ b/tests/Example.OpenApi32/Example.OpenApi32.csproj
@@ -3,8 +3,8 @@
net9.0
enable
- enable
Example.OpenApi32
+ true
true
LastMajorVersionBinary/$(AssemblyName).dll
diff --git a/tests/Example.OpenApi32/Paths/FooFooId/Delete/Operation.Handler.cs b/tests/Example.OpenApi32/Paths/FooFooId/Delete/Operation.Handler.cs
index 57a5ad6..8b1bd55 100644
--- a/tests/Example.OpenApi32/Paths/FooFooId/Delete/Operation.Handler.cs
+++ b/tests/Example.OpenApi32/Paths/FooFooId/Delete/Operation.Handler.cs
@@ -1,3 +1,6 @@
+using System.Threading;
+using System.Threading.Tasks;
+
namespace Example.OpenApi32.Paths.FooFooId.Delete;
internal partial class Operation
diff --git a/tests/Example.OpenApi32/Paths/FooFooId/Put/Operation.Handler.cs b/tests/Example.OpenApi32/Paths/FooFooId/Put/Operation.Handler.cs
index 71f2e86..07ccf49 100644
--- a/tests/Example.OpenApi32/Paths/FooFooId/Put/Operation.Handler.cs
+++ b/tests/Example.OpenApi32/Paths/FooFooId/Put/Operation.Handler.cs
@@ -1,4 +1,8 @@
+using System;
using System.Collections.Immutable;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
using Corvus.Json;
namespace Example.OpenApi32.Paths.FooFooId.Put;
diff --git a/tests/Example.OpenApi32/Paths/FooFooIdEvents/Get/Operation.Handler.cs b/tests/Example.OpenApi32/Paths/FooFooIdEvents/Get/Operation.Handler.cs
index 06eb312..375e2c4 100644
--- a/tests/Example.OpenApi32/Paths/FooFooIdEvents/Get/Operation.Handler.cs
+++ b/tests/Example.OpenApi32/Paths/FooFooIdEvents/Get/Operation.Handler.cs
@@ -1,3 +1,6 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
using Example.OpenApi32.Components.Schemas;
namespace Example.OpenApi32.Paths.FooFooIdEvents.Get;
diff --git a/tests/Example.OpenApi32/Paths/FooFooIdEvents/Post/Operation.Handler.cs b/tests/Example.OpenApi32/Paths/FooFooIdEvents/Post/Operation.Handler.cs
index 8692acf..83c1955 100644
--- a/tests/Example.OpenApi32/Paths/FooFooIdEvents/Post/Operation.Handler.cs
+++ b/tests/Example.OpenApi32/Paths/FooFooIdEvents/Post/Operation.Handler.cs
@@ -1,4 +1,7 @@
-using Example.OpenApi32.Components.Schemas;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Example.OpenApi32.Components.Schemas;
namespace Example.OpenApi32.Paths.FooFooIdEvents.Post;
diff --git a/tests/Example.OpenApi32/Program.cs b/tests/Example.OpenApi32/Program.cs
index 1599f23..ac9d14d 100644
--- a/tests/Example.OpenApi32/Program.cs
+++ b/tests/Example.OpenApi32/Program.cs
@@ -1,7 +1,11 @@
+using System;
using Corvus.Json;
using Example.OpenApi.Auth;
using Example.OpenApi32;
using Microsoft.AspNetCore.Authentication.Certificate;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
var builder = WebApplication.CreateBuilder(args);
@@ -49,4 +53,7 @@
app.MapOperations();
app.Run();
+///
+/// Application entry point.
+///
public abstract partial class Program;
diff --git a/tests/Example.OpenApi32/openapi.json b/tests/Example.OpenApi32/openapi.json
index 1f59ed0..6b2e61b 100644
--- a/tests/Example.OpenApi32/openapi.json
+++ b/tests/Example.OpenApi32/openapi.json
@@ -73,7 +73,11 @@
"200": {
"description": "Successfully deleted"
}
- }
+ },
+ "security": [
+ {},
+ {"openIdConnect": []}
+ ]
},
"parameters": [
{
diff --git a/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.SecurityRequirements.cs b/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.SecurityRequirements.cs
new file mode 100644
index 0000000..379dad6
--- /dev/null
+++ b/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.SecurityRequirements.cs
@@ -0,0 +1,33 @@
+using System.IO;
+using System.Linq;
+using AwesomeAssertions;
+using Xunit;
+
+namespace OpenAPI.WebApiGenerator.Tests;
+
+public partial class ApiGeneratorTests
+{
+ [Theory]
+ [MemberData(nameof(AnonymousSecurityRequirementSpecs))]
+ public void GivenAnonymousSecurityRequirement_WhenGenerating_SecurityRequirementsFilterRepresentsEachRequirementObject(
+ string _, string openApiSpec)
+ {
+ var sourceCode = GetOperationSourceCode(openApiSpec);
+
+ sourceCode.Should().Contain("class SecurityRequirementsFilter");
+ sourceCode.Should().Contain("new SecurityRequirement", Exactly.Twice());
+ sourceCode.Should().Contain("[\"secret_key\"] = []", Exactly.Once());
+ }
+
+ private string GetOperationSourceCode(string openApiSpec)
+ {
+ var compilation = SetupGenerator(openApiSpec, out var diagnostics);
+ HasOnlyMissingHandler(diagnostics);
+
+ var operationSyntaxTree = compilation.SyntaxTrees
+ .FirstOrDefault(t => Path.GetFileName(t.FilePath).EndsWith("Operation.g.cs"));
+ operationSyntaxTree.Should().NotBeNull();
+
+ return operationSyntaxTree.ToString();
+ }
+}
\ No newline at end of file
diff --git a/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.Setup.cs b/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.Setup.cs
new file mode 100644
index 0000000..c037a82
--- /dev/null
+++ b/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.Setup.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Immutable;
+using System.IO;
+using System.Linq;
+using AwesomeAssertions;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using OpenAPI.WebApiGenerator.CodeGeneration;
+using OpenAPI.WebApiGenerator.Tests.Utils;
+
+namespace OpenAPI.WebApiGenerator.Tests;
+
+public partial class ApiGeneratorTests
+{
+ // Base framework references so generated types resolve; built once and shared.
+ private static readonly MetadataReference[] RuntimeReferences =
+ ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")!)
+ .Split(Path.PathSeparator)
+ .Where(path => !string.IsNullOrEmpty(path))
+ .Select(MetadataReference (path) => MetadataReference.CreateFromFile(path))
+ .ToArray();
+
+ private static void HasOnlyMissingHandler(ImmutableArray diagnostics)
+ {
+ diagnostics.Should().AllSatisfy(diagnostic =>
+ {
+ diagnostic.Severity.Should().Be(DiagnosticSeverity.Warning);
+ diagnostic.Id.Should().Be("AF1001", diagnostic.GetFormattedMessage());
+ });
+ }
+
+ private Compilation SetupGenerator(string openApiSpec, out ImmutableArray diagnostics)
+ {
+ var generator = new ApiGenerator();
+
+ GeneratorDriver driver = CSharpGeneratorDriver.Create(generator);
+
+ driver = driver.AddAdditionalTexts(
+ [
+ new InMemoryAdditionalText("openapi.json",
+ openApiSpec)
+ ]
+ );
+
+ const string assemblyName = nameof(ApiGeneratorTests);
+ var compilation = CSharpCompilation.Create(assemblyName,
+ references: RuntimeReferences,
+ options: new CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary));
+
+ driver.RunGeneratorsAndUpdateCompilation(compilation, out var newCompilation, out diagnostics,
+ Cancellation);
+
+ foreach (var tree in newCompilation.SyntaxTrees)
+ {
+ tree.GetDiagnostics().Should().NotContain(diagnostic =>
+ diagnostic.Severity == DiagnosticSeverity.Error ||
+ diagnostic.Severity == DiagnosticSeverity.Warning);
+ }
+
+ var errorsCausedByMissingReferences = new[]
+ {
+ "CS0518", // predefined type is not defined or imported
+ "CS0656", // missing compiler-required member
+ "CS0012", // type is defined in an assembly that is not referenced
+ "CS1069", // type could not be found in a namespace, per the using
+ "CS0234", // type or namespace does not exist in the namespace
+ "CS0246", // type or namespace could not be found
+ "CS0400", // The type or namespace name could not be found in the global namespace (are you missing an assembly reference?)
+ "CS8179", // Predefined type System.ValueTuple is not defined or imported
+ "CS0103", // name does not exist in the current context
+ "CS1061", // no definition for member (type unresolved)
+ "CS0538", // explicit interface declaration is not an interface
+ "CS1729", // type has no constructor with that many arguments
+ "CS0314", // type cannot be a type parameter (constraint unresolved)
+ "CS0305", // wrong number of type arguments (generic unresolved)
+ "CS0704", // non-virtual member lookup on unresolved type
+ "CS9174", // collection-expression init on unresolved type
+ "CS8137", // cannot define a member on an unresolved type
+ "CS1110", // cannot define an extension on an unresolved type
+ "CS0229", // ambiguity between members (unresolved base)
+ "CS0121", // ambiguous call (unresolved overloads)
+ "CS1955", // non-invocable member used like a method
+ "CS0161", // not all code paths return a value (unresolved return type)
+ "CS0315", // no boxing conversion for type parameter (constraint unresolved)
+ "CS8919"
+ };
+
+ var compilationDiagnostics = newCompilation.GetDiagnostics()
+ .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)
+ .Where(diagnostic => !errorsCausedByMissingReferences.Contains(diagnostic.Id))
+ .ToArray();
+
+ compilationDiagnostics.Should().BeEmpty(because:
+ "the generated code should be valid C#, but found:\n" +
+ string.Join("\n", compilationDiagnostics.Select(diagnostic => diagnostic.ToString())) +
+ "\n\n" +
+ string.Join("\n\n", compilationDiagnostics
+ .Select(diagnostic => diagnostic.Location.SourceTree)
+ .Distinct()
+ .Select(tree =>
+ $"""
+ // === {tree?.FilePath} ===
+ {tree?.GetText()}
+ """)));
+
+ return newCompilation;
+ }
+}
\ No newline at end of file
diff --git a/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.TheoryData.AnonymousSecurityRequirementSpecs.cs b/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.TheoryData.AnonymousSecurityRequirementSpecs.cs
new file mode 100644
index 0000000..c8e403a
--- /dev/null
+++ b/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.TheoryData.AnonymousSecurityRequirementSpecs.cs
@@ -0,0 +1,39 @@
+using Xunit;
+
+namespace OpenAPI.WebApiGenerator.Tests;
+
+public partial class ApiGeneratorTests
+{
+ public static TheoryData AnonymousSecurityRequirementSpecs => new()
+ {
+ {
+ "OpenAPI 3.1",
+ """
+ {
+ "openapi": "3.1.0",
+ "info": { "title": "foo", "version": "1.0" },
+ "paths": {
+ "/foo": {
+ "get": {
+ "operationId": "GetFoo",
+ "responses": {
+ "200": { "description": "Success" }
+ },
+ "security": [{}, { "secret_key": [] }]
+ }
+ }
+ },
+ "components": {
+ "securitySchemes": {
+ "secret_key": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "X-API-Key"
+ }
+ }
+ }
+ }
+ """
+ }
+ };
+}
\ No newline at end of file
diff --git a/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.cs b/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.cs
index 962cc67..6e17569 100644
--- a/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.cs
+++ b/tests/OpenAPI.WebApiGenerator.Tests/ApiGeneratorTests.cs
@@ -1,4 +1,3 @@
-using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Threading;
@@ -15,7 +14,7 @@ namespace OpenAPI.WebApiGenerator.Tests;
public partial class ApiGeneratorTests
{
private CancellationToken Cancellation => TestContext.Current.CancellationToken;
-
+
[Theory]
[InlineData("openapi-v2.json")]
[InlineData("openapi-v3.json")]
@@ -170,43 +169,4 @@ public void NoResponseContent_Generating_DefaultResponseConstructor(string _, st
.And.Subject.First()
.Parameters.Should().HaveCount(0);
}
-
- private static void HasOnlyMissingHandler(ImmutableArray diagnostics)
- {
- diagnostics.Should().AllSatisfy(diagnostic =>
- {
- diagnostic.Severity.Should().Be(DiagnosticSeverity.Warning);
- diagnostic.Id.Should().Be("AF1001", diagnostic.GetFormattedMessage());
- });
- }
-
- private Compilation SetupGenerator(string openApiSpec, out ImmutableArray diagnostics)
- {
- var generator = new ApiGenerator();
-
- GeneratorDriver driver = CSharpGeneratorDriver.Create(generator);
-
- driver = driver.AddAdditionalTexts(
- [
- new InMemoryAdditionalText("openapi.json",
- openApiSpec)
- ]
- );
-
- const string assemblyName = nameof(ApiGeneratorTests);
- var compilation = CSharpCompilation.Create(assemblyName,
- options: new CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary));
-
- driver.RunGeneratorsAndUpdateCompilation(compilation, out var newCompilation, out diagnostics,
- Cancellation);
-
- foreach (var tree in newCompilation.SyntaxTrees)
- {
- tree.GetDiagnostics().Should().NotContain(diagnostic =>
- diagnostic.Severity == DiagnosticSeverity.Error ||
- diagnostic.Severity == DiagnosticSeverity.Warning);
- }
-
- return newCompilation;
- }
}