diff --git a/src/Microsoft.OpenApi/Models/OpenApiCallback.cs b/src/Microsoft.OpenApi/Models/OpenApiCallback.cs
index 8bd90ed7f..ab84a7b3b 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiCallback.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiCallback.cs
@@ -59,7 +59,7 @@ public void AddPathItem(RuntimeExpression expression, IOpenApiPathItem pathItem)
///
///
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -67,7 +67,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -97,7 +97,7 @@ internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion versio
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
// Callback object does not exist in V2.
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs
index fb0129bec..765a6ee53 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs
@@ -98,7 +98,7 @@ public OpenApiComponents(OpenApiComponents? components)
/// Serialize to Open API v3.1.
///
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);
@@ -136,7 +136,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
/// Serialize to v3.0
///
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);
@@ -338,7 +338,7 @@ private void RenderComponents(IOpenApiWriter writer, Action
/// Serialize to Open Api v2.0.
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
// Components object does not exist in V2.
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiContact.cs b/src/Microsoft.OpenApi/Models/OpenApiContact.cs
index b6ed82171..b3a567bd7 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiContact.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiContact.cs
@@ -54,7 +54,7 @@ public OpenApiContact(OpenApiContact contact)
/// Serialize to Open Api v3.1
///
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi3_1);
}
@@ -62,7 +62,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi3_0);
}
@@ -70,7 +70,7 @@ public void SerializeAsV3(IOpenApiWriter writer)
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi2_0);
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiEncoding.cs b/src/Microsoft.OpenApi/Models/OpenApiEncoding.cs
index cc9340317..e08126586 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiEncoding.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiEncoding.cs
@@ -76,7 +76,7 @@ public OpenApiEncoding(OpenApiEncoding encoding)
/// Serialize to Open Api v3.1
///
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -85,7 +85,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
/// Serialize to Open Api v3.0
///
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -124,7 +124,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
///
/// Serialize to Open Api v2.0.
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
// nothing here
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiExample.cs b/src/Microsoft.OpenApi/Models/OpenApiExample.cs
index 6ffb26f2e..09ba87d48 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiExample.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiExample.cs
@@ -50,13 +50,13 @@ internal OpenApiExample(IOpenApiExample example)
}
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1);
}
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0);
}
@@ -86,7 +86,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
}
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi2_0);
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs b/src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs
index 381ee53bb..9532eb54a 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs
@@ -46,7 +46,7 @@ public OpenApiExternalDocs(OpenApiExternalDocs externalDocs)
///
/// Serialize to Open Api v3.1.
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi3_1);
}
@@ -54,7 +54,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0.
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi3_0);
}
@@ -62,7 +62,7 @@ public void SerializeAsV3(IOpenApiWriter writer)
///
/// Serialize to Open Api v2.0.
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi2_0);
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs
index 62bb09b89..619233257 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs
@@ -83,7 +83,7 @@ internal OpenApiHeader(IOpenApiHeader header)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV31(writer));
}
@@ -91,7 +91,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -145,7 +145,7 @@ internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion versio
///
/// Serialize to OpenAPI V2 document without using reference.
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);
diff --git a/src/Microsoft.OpenApi/Models/OpenApiLicense.cs b/src/Microsoft.OpenApi/Models/OpenApiLicense.cs
index c3c36812c..18530f214 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiLicense.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiLicense.cs
@@ -52,7 +52,7 @@ public OpenApiLicense(OpenApiLicense license)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi3_1);
writer.WriteProperty(OpenApiConstants.Identifier, Identifier);
@@ -62,7 +62,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi3_0);
writer.WriteEndObject();
@@ -71,7 +71,7 @@ public void SerializeAsV3(IOpenApiWriter writer)
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
WriteInternal(writer, OpenApiSpecVersion.OpenApi2_0);
writer.WriteEndObject();
diff --git a/src/Microsoft.OpenApi/Models/OpenApiLink.cs b/src/Microsoft.OpenApi/Models/OpenApiLink.cs
index ea9202186..4e343c842 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiLink.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiLink.cs
@@ -56,13 +56,13 @@ internal OpenApiLink(IOpenApiLink link)
}
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, (writer, element) => element.SerializeAsV31(writer));
}
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, (writer, element) => element.SerializeAsV3(writer));
}
@@ -98,7 +98,7 @@ internal void SerializeInternal(IOpenApiWriter writer, Action
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
// Link object does not exist in V2.
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiMediaType.cs b/src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
index a16f8d11f..f71377866 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
@@ -67,7 +67,7 @@ public OpenApiMediaType(OpenApiMediaType? mediaType)
///
/// Serialize to Open Api v3.1.
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (w, element) => element.SerializeAsV31(w));
}
@@ -75,7 +75,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0.
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (w, element) => element.SerializeAsV3(w));
}
@@ -99,7 +99,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
// examples
if (Examples != null && Examples.Any())
{
- SerializeExamples(writer, Examples);
+ SerializeExamples(writer, Examples, callback);
}
// encoding
@@ -114,12 +114,12 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
///
/// Serialize to Open Api v2.0.
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
// Media type does not exist in V2.
}
- private static void SerializeExamples(IOpenApiWriter writer, Dictionary examples)
+ private static void SerializeExamples(IOpenApiWriter writer, Dictionary examples, Action callback)
{
/* Special case for writing out empty arrays as valid response examples
* Check if there is any example with an empty array as its value and set the flag `hasEmptyArray` to true
@@ -143,7 +143,7 @@ private static void SerializeExamples(IOpenApiWriter writer, Dictionary e.SerializeAsV3(w));
+ writer.WriteOptionalMap(OpenApiConstants.Examples, examples, callback);
}
}
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs b/src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs
index b46b41da1..59efdb5fe 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs
@@ -59,7 +59,7 @@ public OpenApiOAuthFlows(OpenApiOAuthFlows oAuthFlows)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -67,7 +67,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -109,7 +109,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
// OAuthFlows object does not exist in V2.
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs
index 3024f230a..b9160d36a 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs
@@ -158,7 +158,7 @@ public OpenApiOperation(OpenApiOperation operation)
///
/// Serialize to Open Api v3.1.
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -166,7 +166,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0.
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -228,7 +228,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
///
/// Serialize to Open Api v2.0.
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);
diff --git a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs
index a990ddcbb..d49ccda49 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs
@@ -100,13 +100,13 @@ internal OpenApiParameter(IOpenApiParameter parameter)
}
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -248,7 +248,7 @@ internal virtual void WriteRequestBodySchemaForV2(IOpenApiWriter writer, Diction
}
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);
diff --git a/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs b/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs
index a001b922c..a6b86ec69 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
-using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models.Interfaces;
using Microsoft.OpenApi.Writers;
@@ -67,7 +66,7 @@ internal OpenApiPathItem(IOpenApiPathItem pathItem)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -75,7 +74,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -84,7 +83,7 @@ public void SerializeAsV3(IOpenApiWriter writer)
/// Serialize inline PathItem in OpenAPI V2
///
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);
diff --git a/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs b/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs
index 302cfc5ae..afee60db9 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs
@@ -50,7 +50,7 @@ internal OpenApiRequestBody(IOpenApiRequestBody requestBody)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -58,7 +58,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -88,7 +88,7 @@ internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion versio
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
// RequestBody object does not exist in V2.
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs
index 13ab81152..d52b15781 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs
@@ -51,7 +51,7 @@ internal OpenApiResponse(IOpenApiResponse response)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -59,7 +59,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0.
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -92,7 +92,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
///
/// Serialize to OpenAPI V2 document without using reference.
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);
diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs
index 94d0d9299..bd78e8f9c 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs
@@ -323,13 +323,13 @@ internal OpenApiSchema(IOpenApiSchema schema)
}
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -490,7 +490,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
writer.WriteProperty(OpenApiConstants.WriteOnly, WriteOnly, false);
// xml
- writer.WriteOptionalObject(OpenApiConstants.Xml, Xml, (w, s) => s.SerializeAsV2(w));
+ writer.WriteOptionalObject(OpenApiConstants.Xml, Xml, callback);
// externalDocs
writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, callback);
@@ -514,7 +514,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
}
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
SerializeAsV2(writer: writer, parentRequiredProperties: new HashSet(), propertyName: null);
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs b/src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs
index f9d40682b..c76f33671 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs
@@ -35,7 +35,7 @@ public OpenApiSecurityRequirement()
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, (w, s) =>
{
@@ -49,7 +49,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, (w, s) =>
{
@@ -96,7 +96,7 @@ private void SerializeInternal(IOpenApiWriter writer, Action
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
SerializeInternal(writer, (w, s) => s.SerializeAsV2(w));
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs
index 992fe7986..83042912d 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs
@@ -67,7 +67,7 @@ internal OpenApiSecurityScheme(IOpenApiSecurityScheme securityScheme)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -75,7 +75,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -130,7 +130,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);
diff --git a/src/Microsoft.OpenApi/Models/OpenApiServer.cs b/src/Microsoft.OpenApi/Models/OpenApiServer.cs
index 9c5b3cfca..af75c9c44 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiServer.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiServer.cs
@@ -54,7 +54,7 @@ public OpenApiServer(OpenApiServer server)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}
@@ -62,7 +62,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
@@ -95,7 +95,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
// Server object does not exist in V2.
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiTag.cs b/src/Microsoft.OpenApi/Models/OpenApiTag.cs
index 253fab1de..74adcb2fe 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiTag.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiTag.cs
@@ -46,7 +46,7 @@ internal OpenApiTag(IOpenApiTag tag)
///
/// Serialize to Open Api v3.1
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1,
(writer, element) => element.SerializeAsV31(writer));
@@ -55,7 +55,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0,
(writer, element) => element.SerializeAsV3(writer));
@@ -84,7 +84,7 @@ internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion versio
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
writer.WriteStartObject();
diff --git a/src/Microsoft.OpenApi/Models/OpenApiXml.cs b/src/Microsoft.OpenApi/Models/OpenApiXml.cs
index ae8a94a46..552241d17 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiXml.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiXml.cs
@@ -66,7 +66,7 @@ public OpenApiXml(OpenApiXml xml)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV31(IOpenApiWriter writer)
+ public virtual void SerializeAsV31(IOpenApiWriter writer)
{
Write(writer, OpenApiSpecVersion.OpenApi3_1);
}
@@ -74,7 +74,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
///
/// Serialize to Open Api v3.0
///
- public void SerializeAsV3(IOpenApiWriter writer)
+ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
Write(writer, OpenApiSpecVersion.OpenApi3_0);
}
@@ -82,7 +82,7 @@ public void SerializeAsV3(IOpenApiWriter writer)
///
/// Serialize to Open Api v2.0
///
- public void SerializeAsV2(IOpenApiWriter writer)
+ public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Write(writer, OpenApiSpecVersion.OpenApi2_0);
}
diff --git a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
index cf5736be0..d6d8a21b5 100644
--- a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
+++ b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
@@ -1,4 +1,4 @@
-
+
net8.0
false
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiCallbackSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiCallbackSerializationTests.cs
new file mode 100644
index 000000000..c9d171ed7
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiCallbackSerializationTests.cs
@@ -0,0 +1,52 @@
+using System.IO;
+using System.Net.Http;
+using Microsoft.OpenApi.Expressions;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiCallbackSerializationTests
+ {
+ private readonly OpenApiCallback _callback;
+ private readonly Mock _pathItemMock = new() { CallBase = true };
+
+ public OpenApiCallbackSerializationTests()
+ {
+ _callback = (OpenApiCallback)OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"].Operations[HttpMethod.Get].Callbacks["onData"];
+ _callback.PathItems[RuntimeExpression.Build("{$request.body#/callbackUrl}")] = _pathItemMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _callback.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _pathItemMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _pathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _callback.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _pathItemMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _pathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiComponentsSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiComponentsSerializationTests.cs
new file mode 100644
index 000000000..f68d0d988
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiComponentsSerializationTests.cs
@@ -0,0 +1,122 @@
+using System.IO;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiComponentsSerializationTests
+ {
+ private readonly OpenApiComponents _components;
+ private readonly Mock _schemaMock = new() { CallBase = true };
+ private readonly Mock _requestBodyMock = new() { CallBase = true };
+ private readonly Mock _responseMock = new() { CallBase = true };
+ private readonly Mock _parameterMock = new() { CallBase = true };
+ private readonly Mock _headerMock = new() { CallBase = true };
+ private readonly Mock _securitySchemeMock = new() { CallBase = true };
+ private readonly Mock _linkMock = new() { CallBase = true };
+ private readonly Mock _callbackMock = new() { CallBase = true };
+ private readonly Mock _exampleMock = new() { CallBase = true };
+ private readonly Mock _pathItemMock = new() { CallBase = true };
+
+ public OpenApiComponentsSerializationTests()
+ {
+ _components = OpenApiDocumentMock.CreateCompleteOpenApiDocument().Components;
+ _components.Schemas["pet"] = _schemaMock.Object;
+ _components.RequestBodies["pet"] = _requestBodyMock.Object;
+ _components.Responses["200"] = _responseMock.Object;
+ _components.Parameters["limit"] = _parameterMock.Object;
+ _components.Headers["x-rate-limit"] = _headerMock.Object;
+ _components.SecuritySchemes["api_key"] = _securitySchemeMock.Object;
+ _components.Links["UserRepositories"] = _linkMock.Object;
+ _components.Callbacks["onData"] = _callbackMock.Object;
+ _components.Examples["cat"] = _exampleMock.Object;
+ _components.PathItems["/pets"] = _pathItemMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _components.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _schemaMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _schemaMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _requestBodyMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _requestBodyMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _responseMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _responseMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _parameterMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _parameterMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _headerMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _headerMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _securitySchemeMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _securitySchemeMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _linkMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _linkMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _callbackMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _callbackMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _exampleMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _exampleMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _pathItemMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _pathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _components.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _schemaMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _schemaMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _requestBodyMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _requestBodyMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _responseMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _responseMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _parameterMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _parameterMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _headerMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _headerMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _securitySchemeMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _securitySchemeMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _linkMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _linkMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _callbackMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _callbackMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _exampleMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _exampleMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _pathItemMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _pathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiDocumentMock.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiDocumentMock.cs
new file mode 100644
index 000000000..84accabea
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiDocumentMock.cs
@@ -0,0 +1,460 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text.Json.Nodes;
+using Microsoft.OpenApi.Expressions;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.Interfaces;
+using Microsoft.OpenApi.Models.References;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public static class OpenApiDocumentMock
+ {
+ public static OpenApiDocument CreateCompleteOpenApiDocument()
+ {
+ return new OpenApiDocument
+ {
+ Info = new OpenApiInfo
+ {
+ Title = "Sample API",
+ Version = "1.0.0"
+ },
+ Servers = new List
+ {
+ new()
+ {
+ Url = "https://api.example.com",
+ Description = "Production server"
+ }
+ },
+ Webhooks = new Dictionary
+ {
+ ["pets"] = new OpenApiPathItem
+ {
+ Operations = new()
+ {
+ [HttpMethod.Get] = new OpenApiOperation
+ {
+ Description = "Returns all pets from the system that the user has access to",
+ OperationId = "findPets",
+ Responses = new OpenApiResponses
+ {
+ ["200"] = new OpenApiResponse
+ {
+ Description = "pet response",
+ Content = new()
+ {
+ ["application/json"] = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Array,
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ Paths = new OpenApiPaths
+ {
+ ["/pets"] = new OpenApiPathItem
+ {
+ Servers =
+ [
+ new()
+ {
+ Url = "https://api.example.com",
+ Description = "Production server"
+ }
+ ],
+ Parameters =
+ [
+ new OpenApiParameter
+ {
+ Name = "limit",
+ In = ParameterLocation.Query,
+ Description = "How many items to return at one time (max 100)",
+ Required = false,
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Integer,
+ Format = "int32"
+ },
+ Examples = new Dictionary
+ {
+ ["cat"] = new OpenApiExample
+ {
+ Summary = "An example cat",
+ Value = JsonValue.Create("Fluffy")
+ }
+ },
+ Content = new Dictionary
+ {
+ ["application/json"] = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchemaReference("Pet")
+ }
+ }
+ }
+ ],
+ Operations = new Dictionary
+ {
+ [HttpMethod.Get] = new OpenApiOperation
+ {
+ Summary = "List all pets",
+ Callbacks = new Dictionary
+ {
+ ["onData"] = new OpenApiCallback
+ {
+ PathItems = new Dictionary
+ {
+ [RuntimeExpression.Build("{$request.body#/callbackUrl}")] = new OpenApiPathItem
+ {
+ Operations = new Dictionary
+ {
+ [HttpMethod.Post] = new OpenApiOperation
+ {
+ Responses = new OpenApiResponses
+ {
+ ["200"] = new OpenApiResponse { Description = "ok" }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ Parameters =
+ [
+ new OpenApiParameter
+ {
+ Name = "limit",
+ In = ParameterLocation.Query,
+ Description = "How many items to return at one time (max 100)",
+ Required = false,
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Integer,
+ Format = "int32"
+ }
+ }
+ ],
+ RequestBody = new OpenApiRequestBody
+ {
+ Content = new Dictionary
+ {
+ ["application/json"] = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchemaReference("Pet")
+ },
+ ["application/xml"] = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.String,
+ Xml = new OpenApiXml
+ {
+ Name = "name1",
+ Namespace = new Uri("http://example.com/schema/namespaceSample"),
+ }
+ },
+ }
+ }
+ },
+ Responses = new OpenApiResponses
+ {
+ ["200"] = new OpenApiResponse
+ {
+ Description = "A list of pets.",
+ Headers = new Dictionary
+ {
+ ["x-rate-limit"] = new OpenApiHeader
+ {
+ Description = "The number of allowed requests in the current period",
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Integer
+ },
+ Examples = new Dictionary
+ {
+ ["cat"] = new OpenApiExample
+ {
+ Summary = "An example cat",
+ Value = JsonValue.Create("Fluffy")
+ }
+ },
+ Content = new Dictionary
+ {
+ ["application/json"] = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Array,
+ Items = new OpenApiSchemaReference("Pet")
+ }
+ }
+ }
+ }
+ },
+ Links = new Dictionary
+ {
+ ["UserRepositories"] = new OpenApiLink
+ {
+ OperationId = "getRepositoriesByUsername",
+ Parameters = new Dictionary
+ {
+ ["username"] = new RuntimeExpressionAnyWrapper
+ {
+ Expression = RuntimeExpression.Build("$request.path.id")
+ }
+ }
+ }
+ },
+ Content = new Dictionary
+ {
+ ["application/json"] = new OpenApiMediaType
+ {
+ Encoding = new Dictionary
+ {
+ ["x-rate-limit"] = new OpenApiEncoding
+ {
+ Headers = new Dictionary
+ {
+ ["x-rate-limit"] = new OpenApiHeader
+ {
+ Description = "The number of allowed requests in the current period",
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Integer
+ }
+ }
+ }
+ }
+ },
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Array,
+ Items = new OpenApiSchemaReference("Pet")
+ },
+ Examples = new Dictionary
+ {
+ ["cat"] = new OpenApiExample
+ {
+ Summary = "An example cat",
+ Value = JsonValue.Create("Fluffy")
+ }
+ }
+ }
+ }
+ }
+ },
+ Security =
+ [
+ new OpenApiSecurityRequirement
+ {
+ [new OpenApiSecuritySchemeReference("securitySchemeName1")] = [],
+ [new OpenApiSecuritySchemeReference("securitySchemeName2")] =
+ [
+ "scope1",
+ "scope2"
+ ]
+ }
+ ],
+ Tags = new HashSet
+ {
+ new OpenApiTagReference("tagId1", new OpenApiDocument{ Tags = new HashSet() { new OpenApiTag{Name = "tagId1"}} })
+ },
+ }
+ }
+ }
+ },
+ Components = new OpenApiComponents
+ {
+ Schemas = new Dictionary
+ {
+ ["pet"] = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Object,
+ Properties = new Dictionary
+ {
+ ["id"] = new OpenApiSchema { Type = JsonSchemaType.Integer, Format = "int64" },
+ ["name"] = new OpenApiSchema { Type = JsonSchemaType.String },
+ ["tag"] = new OpenApiSchema { Type = JsonSchemaType.String }
+ },
+ Required = ["id", "name"]
+ }
+ },
+ Parameters = new Dictionary
+ {
+ ["limit"] = new OpenApiParameter
+ {
+ Name = "limit",
+ In = ParameterLocation.Query,
+ Description = "How many items to return at one time (max 100)",
+ Required = false,
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Integer,
+ Format = "int32"
+ }
+ }
+ },
+ Responses = new OpenApiResponses
+ {
+ ["200"] = new OpenApiResponse
+ {
+ Description = "A list of pets.",
+ Content = new Dictionary
+ {
+ ["application/json"] = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Array,
+ Items = new OpenApiSchemaReference("Pet")
+ }
+ }
+ }
+ }
+ },
+ RequestBodies = new Dictionary
+ {
+ ["pet"] = new OpenApiRequestBody
+ {
+ Content = new Dictionary
+ {
+ ["application/json"] = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchemaReference("Pet")
+ }
+ }
+ }
+ },
+ Links = new Dictionary
+ {
+ ["UserRepositories"] = new OpenApiLink
+ {
+ OperationId = "getRepositoriesByUsername",
+ Parameters = new Dictionary
+ {
+ ["username"] = new RuntimeExpressionAnyWrapper
+ {
+ Expression = RuntimeExpression.Build("$request.path.id")
+ }
+ }
+ }
+ },
+ Headers = new Dictionary
+ {
+ ["x-rate-limit"] = new OpenApiHeader
+ {
+ Description = "The number of allowed requests in the current period",
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Integer
+ }
+ }
+ },
+ Examples = new Dictionary
+ {
+ ["cat"] = new OpenApiExample
+ {
+ Summary = "An example cat",
+ Value = JsonValue.Create("Fluffy")
+ }
+ },
+ SecuritySchemes = new Dictionary
+ {
+ ["api_key"] = new OpenApiSecurityScheme
+ {
+ Type = SecuritySchemeType.ApiKey,
+ Name = "api_key",
+ In = ParameterLocation.Header
+ }
+ },
+ Callbacks = new Dictionary
+ {
+ ["onData"] = new OpenApiCallback
+ {
+ PathItems = new Dictionary
+ {
+ [RuntimeExpression.Build("{$request.body#/callbackUrl}")] = new OpenApiPathItem
+ {
+ Operations = new Dictionary
+ {
+ [HttpMethod.Post] = new OpenApiOperation
+ {
+ Responses = new OpenApiResponses
+ {
+ ["200"] = new OpenApiResponse { Description = "ok" }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ PathItems = new Dictionary
+ {
+ ["/pets"] = new OpenApiPathItem
+ {
+ Operations = new Dictionary
+ {
+ [HttpMethod.Get] = new OpenApiOperation
+ {
+ Summary = "List all pets",
+ Responses = new OpenApiResponses
+ {
+ ["200"] = new OpenApiResponse
+ {
+ Description = "A list of pets.",
+ Content = new Dictionary
+ {
+ ["application/json"] = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchema
+ {
+ Type = JsonSchemaType.Array,
+ Items = new OpenApiSchemaReference("Pet")
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ Security =
+ [
+ new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecuritySchemeReference("api_key"),
+ new List()
+ }
+ }
+ ],
+ Tags =
+ [
+ new OpenApiTag
+ {
+ Name = "pets",
+ Description = "Operations related to pets"
+ }
+ ],
+ ExternalDocs = new OpenApiExternalDocs
+ {
+ Description = "Find out more",
+ Url = new Uri("https://example.com/docs")
+ }
+ };
+ }
+ }
+
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiDocumentSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiDocumentSerializationTests.cs
new file mode 100644
index 000000000..8d44d2623
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiDocumentSerializationTests.cs
@@ -0,0 +1,91 @@
+using System.IO;
+using System.Linq;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiDocumentSerializationTests
+ {
+ private readonly OpenApiDocument _document;
+ private readonly Mock _pathItemMock = new() { CallBase = true };
+ private readonly Mock _webhookPathItemMock = new() { CallBase = true };
+ private readonly Mock _serverMock = new() { CallBase = true };
+ private readonly Mock _tagMock = new() { CallBase = true };
+ private readonly Mock _securityMock = new() { CallBase = true };
+ private readonly Mock _componentsMock = new() { CallBase = true };
+
+ public OpenApiDocumentSerializationTests()
+ {
+ _document = OpenApiDocumentMock.CreateCompleteOpenApiDocument();
+ _document.Paths["/pets"] = _pathItemMock.Object;
+ _document.Webhooks["pets"] = _webhookPathItemMock.Object;
+ _document.Servers[0] = _serverMock.Object;
+ _document.Tags.ToList()[0] = _tagMock.Object;
+ _document.Security[0] = _securityMock.Object;
+ _document.Components = _componentsMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _document.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _pathItemMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _pathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _webhookPathItemMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _webhookPathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _tagMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _tagMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _serverMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _serverMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _securityMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _securityMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _componentsMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _componentsMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _document.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _pathItemMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _pathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _serverMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _serverMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _webhookPathItemMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _webhookPathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _tagMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _tagMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _securityMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _securityMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _componentsMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _componentsMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiEncodingSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiEncodingSerializationTests.cs
new file mode 100644
index 000000000..48e580d8d
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiEncodingSerializationTests.cs
@@ -0,0 +1,51 @@
+using System.IO;
+using System.Net.Http;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiEncodingSerializationTests
+ {
+ private readonly OpenApiEncoding _encoding;
+ private readonly Mock _headerMock = new() { CallBase = true };
+
+ public OpenApiEncodingSerializationTests()
+ {
+ _encoding = OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Encoding["x-rate-limit"];
+ _encoding.Headers["x-encoding"] = _headerMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _encoding.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _headerMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _headerMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _encoding.SerializeAsV3(writer);
+
+ // Assert - fail if V2 method is called
+ _headerMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ _headerMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiHeaderSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiHeaderSerializationTests.cs
new file mode 100644
index 000000000..4d0fa5336
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiHeaderSerializationTests.cs
@@ -0,0 +1,67 @@
+using System.IO;
+using System.Net.Http;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiHeaderSerializationTests
+ {
+ private readonly OpenApiHeader _header;
+ private readonly Mock _schemaMock = new() { CallBase = true };
+ private readonly Mock _exampleMock = new() { CallBase = true };
+ private readonly Mock _mediaTypeMock = new() { CallBase = true };
+
+ public OpenApiHeaderSerializationTests()
+ {
+ _header = (OpenApiHeader)OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"].Operations[HttpMethod.Get].Responses["200"].Headers["x-rate-limit"];
+ _header.Schema = _schemaMock.Object;
+ _header.Examples["cat"] = _exampleMock.Object;
+ _header.Content["application/json"] = _mediaTypeMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _header.SerializeAsV31(writer);
+
+ // Assert
+ _schemaMock.Verify(h => h.SerializeAsV3(It.IsAny()), Times.Never);
+ _schemaMock.Verify(h => h.SerializeAsV2(It.IsAny()), Times.Never);
+
+ _exampleMock.Verify(h => h.SerializeAsV3(It.IsAny()), Times.Never);
+ _exampleMock.Verify(h => h.SerializeAsV2(It.IsAny()), Times.Never);
+
+ _mediaTypeMock.Verify(h => h.SerializeAsV3(It.IsAny()), Times.Never);
+ _mediaTypeMock.Verify(h => h.SerializeAsV2(It.IsAny()), Times.Never);
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _header.SerializeAsV3(writer);
+
+ // Assert
+ _schemaMock.Verify(h => h.SerializeAsV31(It.IsAny()), Times.Never);
+ _schemaMock.Verify(h => h.SerializeAsV2(It.IsAny()), Times.Never);
+
+ _exampleMock.Verify(h => h.SerializeAsV31(It.IsAny()), Times.Never);
+ _exampleMock.Verify(h => h.SerializeAsV2(It.IsAny()), Times.Never);
+
+ _mediaTypeMock.Verify(h => h.SerializeAsV31(It.IsAny()), Times.Never);
+ _mediaTypeMock.Verify(h => h.SerializeAsV2(It.IsAny()), Times.Never);
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiInfoSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiInfoSerializationTests.cs
new file mode 100644
index 000000000..8f79f53c5
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiInfoSerializationTests.cs
@@ -0,0 +1,58 @@
+using System.IO;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiInfoSerializationTests
+ {
+ private readonly OpenApiInfo _info;
+ private readonly Mock _contactMock = new() { CallBase = true };
+ private readonly Mock _licenseMock = new() { CallBase = true };
+
+ public OpenApiInfoSerializationTests()
+ {
+ _info = OpenApiDocumentMock.CreateCompleteOpenApiDocument().Info;
+ _info.Contact = _contactMock.Object;
+ _info.License = _licenseMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _info.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _contactMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _contactMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _licenseMock.Verify(l => l.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _licenseMock.Verify(l => l.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _info.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _contactMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _contactMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _licenseMock.Verify(l => l.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _licenseMock.Verify(l => l.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiMediaTypeSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiMediaTypeSerializationTests.cs
new file mode 100644
index 000000000..9504ae253
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiMediaTypeSerializationTests.cs
@@ -0,0 +1,68 @@
+using System.IO;
+using System.Net.Http;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiMediaTypeSerializationTests
+ {
+ private readonly OpenApiMediaType _mediaType;
+ private readonly Mock _schemaMock = new() { CallBase = true };
+ private readonly Mock _encodingMock = new() { CallBase = true };
+ private readonly Mock _exampleMock = new() { CallBase = true };
+
+ public OpenApiMediaTypeSerializationTests()
+ {
+ _mediaType = OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"];
+ _mediaType.Schema = _schemaMock.Object;
+ _mediaType.Examples["cat"] = _exampleMock.Object;
+ _mediaType.Examples["example"] = _exampleMock.Object;
+ _mediaType.Encoding["encoding"] = _encodingMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _mediaType.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _schemaMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _schemaMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _encodingMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _encodingMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _exampleMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _exampleMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _mediaType.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _schemaMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _schemaMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _encodingMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _encodingMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _exampleMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _exampleMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiOperationSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiOperationSerializationTests.cs
new file mode 100644
index 000000000..3106c2de2
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiOperationSerializationTests.cs
@@ -0,0 +1,93 @@
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.References;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiOperationSerializationTests
+ {
+ private readonly OpenApiOperation _operation;
+ private readonly Mock _callbackMock = new() { CallBase = true };
+ private readonly Mock _pathItemMock = new() { CallBase = true };
+ private readonly Mock _requestBodyMock = new() { CallBase = true };
+ private readonly Mock _responsesMock = new() { CallBase = true };
+ private readonly Mock _parameterMock = new() { CallBase = true };
+ private readonly Mock _securityRequirementMock = new() { CallBase = true };
+
+
+ public OpenApiOperationSerializationTests()
+ {
+ _operation = OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"].Operations[HttpMethod.Get];
+ _operation.Callbacks["onData"] = _callbackMock.Object;
+ _operation.Responses["200"] = _responsesMock.Object;
+ _operation.RequestBody = _requestBodyMock.Object;
+ _operation.Parameters[0] = _parameterMock.Object;
+ _operation.Security[0] = _securityRequirementMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _operation.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _callbackMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _callbackMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _pathItemMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _pathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _requestBodyMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _requestBodyMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _responsesMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _responsesMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _parameterMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _parameterMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _securityRequirementMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _securityRequirementMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _operation.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _callbackMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _callbackMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _pathItemMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _pathItemMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _requestBodyMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _requestBodyMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _responsesMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _responsesMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _parameterMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _parameterMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _securityRequirementMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _securityRequirementMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiParameterSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiParameterSerializationTests.cs
new file mode 100644
index 000000000..b6bb61bba
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiParameterSerializationTests.cs
@@ -0,0 +1,66 @@
+using System.IO;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiParameterSerializationTests
+ {
+ private readonly OpenApiParameter _parameter;
+ private readonly Mock _schemaMock = new() { CallBase = true };
+ private readonly Mock _contentMock = new() { CallBase = true };
+ private readonly Mock _exampleMock = new() { CallBase = true };
+
+ public OpenApiParameterSerializationTests()
+ {
+ _parameter = (OpenApiParameter)OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"].Parameters[0];
+ _parameter.Schema = _schemaMock.Object;
+ _parameter.Content["application/json"] = _contentMock.Object;
+ _parameter.Examples["example"] = _exampleMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _parameter.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _schemaMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _schemaMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _contentMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _contentMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _exampleMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _exampleMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _parameter.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _schemaMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _schemaMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _contentMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _contentMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _exampleMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _exampleMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiPathItemSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiPathItemSerializationTests.cs
new file mode 100644
index 000000000..12f63dcf6
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiPathItemSerializationTests.cs
@@ -0,0 +1,68 @@
+using System.IO;
+using System.Net.Http;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.Interfaces;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiPathItemSerializationTests
+ {
+ private readonly IOpenApiPathItem _pathItem;
+ private readonly Mock _operationMock = new() { CallBase = true };
+ private readonly Mock _serverMock = new() { CallBase = true };
+ private readonly Mock _parameterMock = new() { CallBase = true };
+
+ public OpenApiPathItemSerializationTests()
+ {
+ _pathItem = OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"];
+ _pathItem.Operations[HttpMethod.Get] = _operationMock.Object;
+ _pathItem.Servers[0] = _serverMock.Object ;
+ _pathItem.Parameters[0] = _parameterMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _pathItem.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _operationMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _operationMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _serverMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _serverMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _parameterMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _parameterMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _pathItem.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _operationMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _operationMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _serverMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _serverMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+
+ _parameterMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _parameterMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiRequestBodySerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiRequestBodySerializationTests.cs
new file mode 100644
index 000000000..b344930c7
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiRequestBodySerializationTests.cs
@@ -0,0 +1,52 @@
+using System.IO;
+using System.Net.Http;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.Interfaces;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiRequestBodySerializationTests
+ {
+ private readonly IOpenApiRequestBody _requestBody;
+ private readonly Mock _mediaTypeMock = new() { CallBase = true };
+
+ public OpenApiRequestBodySerializationTests()
+ {
+ _requestBody = OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"].Operations[HttpMethod.Get].RequestBody;
+ _requestBody.Content["application/json"] = _mediaTypeMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _requestBody.SerializeAsV31(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _mediaTypeMock.Verify(c => c.SerializeAsV3(It.IsAny()), Times.Never, "V3 method should not be called");
+ _mediaTypeMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _requestBody.SerializeAsV3(writer);
+
+ // Assert - fail if V2 or V3 methods are called
+ _mediaTypeMock.Verify(c => c.SerializeAsV31(It.IsAny()), Times.Never, "V31 method should not be called");
+ _mediaTypeMock.Verify(c => c.SerializeAsV2(It.IsAny()), Times.Never, "V2 method should not be called");
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs
new file mode 100644
index 000000000..fb6321d52
--- /dev/null
+++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs
@@ -0,0 +1,68 @@
+using System.IO;
+using System.Net.Http;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.Interfaces;
+using Microsoft.OpenApi.Writers;
+using Moq;
+using Xunit;
+
+namespace Microsoft.OpenApi.Tests.Mocks
+{
+ public class OpenApiResponseSerializationTests
+ {
+ private readonly IOpenApiResponse _response;
+ private readonly Mock _headerMock = new() { CallBase = true };
+ private readonly Mock _mediaTypeMock = new() { CallBase = true };
+ private readonly Mock _linkMock = new() { CallBase = true };
+
+ public OpenApiResponseSerializationTests()
+ {
+ _response = OpenApiDocumentMock.CreateCompleteOpenApiDocument().Paths["/pets"].Operations[HttpMethod.Get].Responses["200"];
+ _response.Headers["x-rate-limit"] = _headerMock.Object;
+ _response.Content["application/json"] = _mediaTypeMock.Object;
+ _response.Links["UserRepositories"] = _linkMock.Object;
+ }
+
+ [Fact]
+ public void SerializeAsV31_DoesNotCallV3OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _response.SerializeAsV31(writer);
+
+ // Assert
+ _headerMock.Verify(h => h.SerializeAsV3(It.IsAny()), Times.Never);
+ _headerMock.Verify(h => h.SerializeAsV2(It.IsAny()), Times.Never);
+
+ _mediaTypeMock.Verify(m => m.SerializeAsV3(It.IsAny()), Times.Never);
+ _mediaTypeMock.Verify(m => m.SerializeAsV2(It.IsAny()), Times.Never);
+
+ _linkMock.Verify(l => l.SerializeAsV3(It.IsAny()), Times.Never);
+ _linkMock.Verify(l => l.SerializeAsV2(It.IsAny()), Times.Never);
+ }
+
+ [Fact]
+ public void SerializeAsV3_DoesNotCallV31OrV2Serialization()
+ {
+ // Arrange
+ using var stringWriter = new StringWriter();
+ var writer = new OpenApiJsonWriter(stringWriter);
+
+ // Act
+ _response.SerializeAsV3(writer);
+
+ // Assert
+ _headerMock.Verify(h => h.SerializeAsV31(It.IsAny()), Times.Never);
+ _headerMock.Verify(h => h.SerializeAsV2(It.IsAny()), Times.Never);
+
+ _mediaTypeMock.Verify(m => m.SerializeAsV31(It.IsAny