diff --git a/.editorconfig b/.editorconfig
index fd54f541b9..92b978a85c 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -31,3 +31,13 @@ trim_trailing_whitespace = true
[*.cs]
dotnet_sort_system_directives_first = true
+
+# Verify settings
+[*.{received,verified}.{txt,xml,json}]
+charset = "utf-8-bom"
+end_of_line = lf
+indent_size = unset
+indent_style = unset
+insert_final_newline = false
+tab_width = unset
+trim_trailing_whitespace = false
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
index e3eb50d710..644430043e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,5 @@
# Set the default end-of-line to UNIX
* text=auto eol=lf
+*.verified.txt text eol=lf working-tree-encoding=UTF-8
+*.verified.xml text eol=lf working-tree-encoding=UTF-8
+*.verified.json text eol=lf working-tree-encoding=UTF-8
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index b85290bd95..5bdb1b2704 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -33,6 +33,7 @@ updates:
xunit:
patterns:
- xunit*
+ - Verify.Xunit
schedule:
interval: weekly
day: wednesday
diff --git a/.gitignore b/.gitignore
index 6709dcea82..c12adce325 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@ test/WebSites/CliExample/wwwroot/api-docs/v1/*.json
test/WebSites/CliExampleWithFactory/wwwroot/api-docs/v1/*.json
test/WebSites/NswagClientExample/NSwagClient/
*ncrunch*
+*.received.*
diff --git a/Directory.Packages.props b/Directory.Packages.props
index b2c9b4f9f0..713a38c156 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -27,8 +27,9 @@
+
-
+
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithEndpointNameMetadata.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithEndpointNameMetadata.verified.txt
new file mode 100644
index 0000000000..aaaed8c375
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithEndpointNameMetadata.verified.txt
@@ -0,0 +1,31 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Post: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ OperationId: SomeEndpointName,
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: A0047BEEDFB7C084AF6BF3412F47917E1914849406956B23249FD5A555B9545157FBFF5C1EAFC073B55E59FDE9BDB1774670EFE402C7319D5EC6A6A43D94E439
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithProvidedOpenApiMetadata.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithProvidedOpenApiMetadata.verified.txt
new file mode 100644
index 0000000000..facec5635b
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithProvidedOpenApiMetadata.verified.txt
@@ -0,0 +1,31 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Post: {
+ OperationId: OperationIdSetInMetadata,
+ Parameters: [
+ {
+ UnresolvedReference: false,
+ Name: ParameterInMetadata,
+ Required: false,
+ Deprecated: false,
+ AllowEmptyValue: false,
+ Style: Simple,
+ Explode: false,
+ AllowReserved: false
+ }
+ ],
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: 76DE54DD44D94D07BC803E615ECB0F6D290C3B8803EFB5EADF02C6B180682B1C20BFDD4C9CD50F71D5AD7042B7B4570903F3AF1CC7970ABCA1CEE20FBF971FFD
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredMember.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredMember.verified.txt
new file mode 100644
index 0000000000..f8133b12f1
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredMember.verified.txt
@@ -0,0 +1,52 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Post: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ Parameters: [
+ {
+ UnresolvedReference: false,
+ Name: param,
+ In: Query,
+ Required: true,
+ Deprecated: false,
+ AllowEmptyValue: false,
+ Style: Form,
+ Explode: true,
+ AllowReserved: false,
+ Schema: {
+ Type: string,
+ ReadOnly: false,
+ WriteOnly: false,
+ AdditionalPropertiesAllowed: true,
+ Nullable: false,
+ Deprecated: false,
+ UnresolvedReference: false
+ }
+ }
+ ],
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: A2DDB9D84BC2303C2E8B82FEE969073D4DCAE3D40331C1ED8376E3F427E46C7CAE5AE2791BC5FE1FFFE026EBE90FC10DE8A0409D9F0B6EBC5DBE6CB294DD6A84
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithBindRequiredAttribute.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithBindRequiredAttribute.verified.txt
new file mode 100644
index 0000000000..f8133b12f1
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithBindRequiredAttribute.verified.txt
@@ -0,0 +1,52 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Post: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ Parameters: [
+ {
+ UnresolvedReference: false,
+ Name: param,
+ In: Query,
+ Required: true,
+ Deprecated: false,
+ AllowEmptyValue: false,
+ Style: Form,
+ Explode: true,
+ AllowReserved: false,
+ Schema: {
+ Type: string,
+ ReadOnly: false,
+ WriteOnly: false,
+ AdditionalPropertiesAllowed: true,
+ Nullable: false,
+ Deprecated: false,
+ UnresolvedReference: false
+ }
+ }
+ ],
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: A2DDB9D84BC2303C2E8B82FEE969073D4DCAE3D40331C1ED8376E3F427E46C7CAE5AE2791BC5FE1FFFE026EBE90FC10DE8A0409D9F0B6EBC5DBE6CB294DD6A84
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithRequiredAttribute.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithRequiredAttribute.verified.txt
new file mode 100644
index 0000000000..f8133b12f1
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithRequiredAttribute.verified.txt
@@ -0,0 +1,52 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Post: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ Parameters: [
+ {
+ UnresolvedReference: false,
+ Name: param,
+ In: Query,
+ Required: true,
+ Deprecated: false,
+ AllowEmptyValue: false,
+ Style: Form,
+ Explode: true,
+ AllowReserved: false,
+ Schema: {
+ Type: string,
+ ReadOnly: false,
+ WriteOnly: false,
+ AdditionalPropertiesAllowed: true,
+ Nullable: false,
+ Deprecated: false,
+ UnresolvedReference: false
+ }
+ }
+ ],
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: A2DDB9D84BC2303C2E8B82FEE969073D4DCAE3D40331C1ED8376E3F427E46C7CAE5AE2791BC5FE1FFFE026EBE90FC10DE8A0409D9F0B6EBC5DBE6CB294DD6A84
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRouteNameMetadata.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRouteNameMetadata.verified.txt
new file mode 100644
index 0000000000..9c7d1af46d
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRouteNameMetadata.verified.txt
@@ -0,0 +1,31 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Post: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ OperationId: SomeRouteName,
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: 8A51577C0837548151E3938DC7033AF6AFDE7FD4E5F6F2FE20CC8931B3D18A883C1FB3FE92120D0A44EC31DDE90DDEDE4A237B3138AD45A37278F8924958D5A7
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAcceptFromHeaderParameter.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAcceptFromHeaderParameter.verified.txt
new file mode 100644
index 0000000000..49c8aec81d
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAcceptFromHeaderParameter.verified.txt
@@ -0,0 +1,52 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Get: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ Parameters: [
+ {
+ UnresolvedReference: false,
+ Name: param,
+ In: Header,
+ Required: false,
+ Deprecated: false,
+ AllowEmptyValue: false,
+ Style: Simple,
+ Explode: false,
+ AllowReserved: false,
+ Schema: {
+ Type: string,
+ ReadOnly: false,
+ WriteOnly: false,
+ AdditionalPropertiesAllowed: true,
+ Nullable: false,
+ Deprecated: false,
+ UnresolvedReference: false
+ }
+ }
+ ],
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: E126911C7FB97665966DB7EA833EA70FDF82A779304ECD9B963D5A50C6E0AE51A3180983631720BDCD1BCDA3CAA7E79F0F0042120949EA990884D6188CE77AF1
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAuthorizationFromHeaderParameter.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAuthorizationFromHeaderParameter.verified.txt
new file mode 100644
index 0000000000..49c8aec81d
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAuthorizationFromHeaderParameter.verified.txt
@@ -0,0 +1,52 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Get: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ Parameters: [
+ {
+ UnresolvedReference: false,
+ Name: param,
+ In: Header,
+ Required: false,
+ Deprecated: false,
+ AllowEmptyValue: false,
+ Style: Simple,
+ Explode: false,
+ AllowReserved: false,
+ Schema: {
+ Type: string,
+ ReadOnly: false,
+ WriteOnly: false,
+ AdditionalPropertiesAllowed: true,
+ Nullable: false,
+ Deprecated: false,
+ UnresolvedReference: false
+ }
+ }
+ ],
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: E126911C7FB97665966DB7EA833EA70FDF82A779304ECD9B963D5A50C6E0AE51A3180983631720BDCD1BCDA3CAA7E79F0F0042120949EA990884D6188CE77AF1
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithContentTypeFromHeaderParameter.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithContentTypeFromHeaderParameter.verified.txt
new file mode 100644
index 0000000000..49c8aec81d
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithContentTypeFromHeaderParameter.verified.txt
@@ -0,0 +1,52 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Get: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ Parameters: [
+ {
+ UnresolvedReference: false,
+ Name: param,
+ In: Header,
+ Required: false,
+ Deprecated: false,
+ AllowEmptyValue: false,
+ Style: Simple,
+ Explode: false,
+ AllowReserved: false,
+ Schema: {
+ Type: string,
+ ReadOnly: false,
+ WriteOnly: false,
+ AdditionalPropertiesAllowed: true,
+ Nullable: false,
+ Deprecated: false,
+ UnresolvedReference: false
+ }
+ }
+ ],
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: E126911C7FB97665966DB7EA833EA70FDF82A779304ECD9B963D5A50C6E0AE51A3180983631720BDCD1BCDA3CAA7E79F0F0042120949EA990884D6188CE77AF1
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt
new file mode 100644
index 0000000000..73d6704137
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt
@@ -0,0 +1,45 @@
+{
+ Info: {
+ Title: Test API,
+ Version: V1
+ },
+ Paths: {
+ /resource: {
+ Operations: {
+ Get: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ },
+ Post: {
+ Tags: [
+ {
+ Name: Fake,
+ UnresolvedReference: false
+ }
+ ],
+ Responses: {
+ 200: {
+ Description: OK,
+ UnresolvedReference: false
+ }
+ },
+ Deprecated: false
+ }
+ },
+ UnresolvedReference: false
+ }
+ },
+ Components: {},
+ HashCode: 0F1036F23326E2BD7543491DEC0E03ABCA5BC97AF845BEE30C164155D616F306F6F6E21A77507DA6BE2A85DF1A17B1F07AE23E7608E37C971BAF1CBA2491E899
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs
new file mode 100644
index 0000000000..891f3cd308
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs
@@ -0,0 +1,246 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text.Json;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Abstractions;
+using Microsoft.AspNetCore.Mvc.ApiExplorer;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.AspNetCore.Routing;
+using Microsoft.OpenApi.Models;
+using Swashbuckle.AspNetCore.TestSupport;
+using VerifyXunit;
+using Xunit;
+
+namespace Swashbuckle.AspNetCore.SwaggerGen.Test;
+
+public class SwaggerGeneratorVerifyTests
+{
+ [Fact]
+ public Task ApiDescriptionsWithMatchingGroupName()
+ {
+ var subject = Subject(
+ apiDescriptions: new[]
+ {
+ ApiDescriptionFactory.Create(
+ c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "POST", relativePath: "resource"),
+
+ ApiDescriptionFactory.Create(
+ c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "GET", relativePath: "resource"),
+
+ ApiDescriptionFactory.Create(
+ c => nameof(c.ActionWithNoParameters), groupName: "v2", httpMethod: "POST", relativePath: "resource"),
+ },
+ options: new SwaggerGeneratorOptions
+ {
+ SwaggerDocs = new Dictionary
+ {
+ ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" }
+ }
+ }
+ );
+
+ var document = subject.GetSwagger("v1");
+
+ return Verifier.Verify(document);
+ }
+
+ [Fact]
+ public Task ActionWithRouteNameMetadata()
+ {
+ var subject = Subject(
+ apiDescriptions: new[]
+ {
+ ApiDescriptionFactory.Create(
+ c => nameof(c.ActionWithRouteNameMetadata), groupName: "v1", httpMethod: "POST", relativePath: "resource"),
+ }
+ );
+
+ var document = subject.GetSwagger("v1");
+
+ return Verifier.Verify(document);
+ }
+
+ [Fact]
+ public Task ActionWithEndpointNameMetadata()
+ {
+ var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter));
+ var actionDescriptor = new ActionDescriptor
+ {
+ EndpointMetadata = new List