From a663f6f616df2ee551204bccaaf5c70812f41bf5 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Wed, 15 Jul 2026 11:27:27 +0200 Subject: [PATCH 1/4] Do not ignore multiple types when serializing to 3.0 --- .../Extensions/OpenApiTypeMapper.cs | 7 +- src/Microsoft.OpenApi/Models/OpenApiSchema.cs | 140 +++-- .../Models/OpenApiSchemaTests.cs | 491 ++++++++++++++++++ 3 files changed, 597 insertions(+), 41 deletions(-) diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs b/src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs index 8d557b4d1..1ad3a5b8f 100644 --- a/src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs @@ -69,7 +69,12 @@ internal static string ToFirstIdentifier(this JsonSchemaType schemaType) /// internal static string ToSingleIdentifier(this JsonSchemaType schemaType) { - return schemaType.ToIdentifiersInternal().Single(); + if (allSchemaTypes.TryGetValue(schemaType, out var schemaTypeString)) + { + return schemaTypeString; + } + + throw new InvalidOperationException($"ToSingleIdentifier is called with unexpected value '{schemaType}'. Callers must ensure this is called with a valid single value JsonSchemaType."); } /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index 2ae310294..5b80f8180 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -21,7 +21,7 @@ namespace Microsoft.OpenApi /// public class OpenApiSchema : IOpenApiExtensible, IOpenApiSchema, IOpenApiSchemaMissingProperties, IOpenApiSchemaWithUnevaluatedProperties, IMetadataContainer { - private static readonly IEnumerable s_singleNullElementList = [ JsonNullSentinel.JsonNull ]; + private static readonly IEnumerable s_singleNullElementList = [JsonNullSentinel.JsonNull]; /// public string? Title { get; set; } @@ -549,7 +549,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version } // type - var serializedTypeProperty = TrySerializeTypeProperty(writer, version); + var serializedTypeProperty = TrySerializeTypePropertyForVersion3AndLater(writer, version, callback); // allOf writer.WriteOptionalCollection(OpenApiConstants.AllOf, AllOf, callback); @@ -681,7 +681,7 @@ internal void WriteJsonSchemaKeywords(IOpenApiWriter writer, Action s.SerializeAsV2(w)); } - #pragma warning restore CS0618 +#pragma warning restore CS0618 } // properties @@ -996,32 +996,113 @@ private void SerializeAsV2( writer.WriteEndObject(); } - private bool TrySerializeTypeProperty(IOpenApiWriter writer, OpenApiSpecVersion version, JsonSchemaType? inferredType = null) + private bool TrySerializeTypePropertyForVersion2(IOpenApiWriter writer) { - // Use original type or inferred type when the explicit type is not set - var typeToUse = Type ?? inferredType; + if (Type is not { } type) + { + return false; + } - if (typeToUse is null) + var typeWithoutNull = type & ~JsonSchemaType.Null; + if (typeWithoutNull != 0 && !HasMultipleTypes(typeWithoutNull)) + { + writer.WriteProperty(OpenApiConstants.Type, typeWithoutNull.ToFirstIdentifier()); + return true; + } + + return false; + } + + /// + /// Tries to serialize the "type" property for OpenAPI v3 and later versions. + /// + /// + /// true if the Type was serializable using "type" property, and false if + /// it serialized using anyOf/oneOf or if it couldn't be serialized at all. + /// + private bool TrySerializeTypePropertyForVersion3AndLater(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) + { + if (Type is not { } type) { return false; } - switch (version) + if (version == OpenApiSpecVersion.OpenApi3_0) { - case OpenApiSpecVersion.OpenApi2_0 or OpenApiSpecVersion.OpenApi3_0: - var typeWithoutNull = typeToUse.Value & ~JsonSchemaType.Null; - if (typeWithoutNull != 0 && !HasMultipleTypes(typeWithoutNull)) + if (type == JsonSchemaType.Null) + { + return false; + } + + var typeWithoutNull = type & ~JsonSchemaType.Null; + var hasNull = typeWithoutNull != type; + var arrayWithoutNull = (from JsonSchemaType flag in jsonSchemaTypeValues + where typeWithoutNull.HasFlag(flag) + select flag).ToArray(); + + // - If we have more than one type (excluding null), we have to use anyOf/oneOf. + // - If we have exactly one type alone (without null), we emit the type property. + // - If we have exactly one non-null type and also we have the null type, we emit the type property and nullable: true (handled in SerializeNullable) + if (arrayWithoutNull.Length > 1) + { + // If the schema doesn't already have anyOf/oneOf, we can write multiple types as such. + var canWriteAsAnyOf = AnyOf is not { Count: > 0 }; + var canWriteAsOneOf = OneOf is not { Count: > 0 }; + if (canWriteAsAnyOf) + { + writer.WriteOptionalCollection(OpenApiConstants.AnyOf, ConstructChildSchemasForTypes(arrayWithoutNull, hasNull), callback); + return false; + } + else if (canWriteAsOneOf) { - writer.WriteProperty(OpenApiConstants.Type, typeWithoutNull.ToFirstIdentifier()); - return true; + writer.WriteOptionalCollection(OpenApiConstants.OneOf, ConstructChildSchemasForTypes(arrayWithoutNull, hasNull), callback); + return false; } - break; - default: - WriteUnifiedSchemaType(typeToUse.Value, writer); + } + else + { + writer.WriteProperty(OpenApiConstants.Type, arrayWithoutNull[0].ToSingleIdentifier()); return true; + } + } + else + { + var array = (from JsonSchemaType flag in jsonSchemaTypeValues + where type.HasFlag(flag) + select flag).ToArray(); + + if (array.Length > 1) + { + writer.WriteOptionalCollection(OpenApiConstants.Type, array, (w, s) => w.WriteValue(s.ToSingleIdentifier())); + } + else + { + writer.WriteProperty(OpenApiConstants.Type, array[0].ToSingleIdentifier()); + } + + return true; } return false; + + static OpenApiSchema[] ConstructChildSchemasForTypes(JsonSchemaType[] types, bool hasNull) + { + var schemas = new OpenApiSchema[types.Length + (hasNull ? 1 : 0)]; + for (int i = 0; i < types.Length; i++) + { + schemas[i] = new OpenApiSchema() + { + Type = types[i] + }; + } + + if (hasNull) + { + schemas[schemas.Length - 1] = new OpenApiSchema() { Type = JsonSchemaType.Null }; + } + + return schemas; + } } private static bool IsPowerOfTwo(int x) @@ -1035,27 +1116,6 @@ private static bool HasMultipleTypes(JsonSchemaType schemaType) return !IsPowerOfTwo(schemaTypeNumeric); } - private static void WriteUnifiedSchemaType(JsonSchemaType type, IOpenApiWriter writer) - { - var array = (from JsonSchemaType flag in jsonSchemaTypeValues - where type.HasFlag(flag) - select flag.ToFirstIdentifier()).ToArray(); - if (array.Length > 1) - { - writer.WriteOptionalCollection(OpenApiConstants.Type, array, (w, s) => - { - if (!string.IsNullOrEmpty(s) && s is not null) - { - w.WriteValue(s); - } - }); - } - else - { - writer.WriteProperty(OpenApiConstants.Type, array[0]); - } - } - private void SerializeNullable(IOpenApiWriter writer, OpenApiSpecVersion version) { if (HasNullType) diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs index b4b188617..f2c669f7c 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs @@ -1968,6 +1968,497 @@ public async Task SerializeNullableTypeWith3_1_And_Later(OpenApiSpecVersion vers Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); } + [Fact] + public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_NotIncludingOneOfOrAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer, + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingOneOfButNotAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer, + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingAnyOfButNotOneOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingBothOneOfAndAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_NotIncludingOneOfOrAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Null, + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "type": "string", + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_IncludingOneOfButNotAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Null, + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "type": "string", + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_IncludingAnyOfButNotOneOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Null, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_IncludingBothOneOfAndAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Null, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "nullable": true + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_NotIncludingOneOfOrAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null, + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "enum": [ + null + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_IncludingOneOfButNotAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null, + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "enum": [ + null + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_IncludingAnyOfButNotOneOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "enum": [ + null + ] + } + ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + + [Fact] + public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_IncludingBothOneOfAndAnyOf() + { + var schema = new OpenApiSchema() + { + Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null, + AnyOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + OneOf = + [ + new OpenApiSchema() + { + Enum = new List + { + JsonValue.Create("A"), + JsonValue.Create("B") + } + }, + ], + }; + var result = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + var expected = """ + { + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + } + private OpenApiSchema CreateNullableEnumSchema() { var schema = new OpenApiSchema(); From 21578cfa7536a87f8df8c64f263998bb41cb80a3 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Tue, 4 Aug 2026 09:19:55 +0200 Subject: [PATCH 2/4] Update tests --- .../Models/OpenApiSchemaTests.cs | 21 ++++++++++----- .../OpenApiSchemaV30CompatibilityTests.cs | 26 ++++++++++++++++--- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs index 09f76aa1e..7a6db9071 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs @@ -2461,9 +2461,11 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_NotIncl { "enum": [ null - ] + ], + "nullable": true } - ] + ], + "nullable": true } """; @@ -2501,7 +2503,8 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_Includi { "enum": [ null - ] + ], + "nullable": true } ], "oneOf": [ @@ -2511,7 +2514,8 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_Includi "B" ] } - ] + ], + "nullable": true } """; @@ -2549,7 +2553,8 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_Includi { "enum": [ null - ] + ], + "nullable": true } ], "anyOf": [ @@ -2559,7 +2564,8 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_Includi "B" ] } - ] + ], + "nullable": true } """; @@ -2613,7 +2619,8 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_Includi "B" ] } - ] + ], + "nullable": true } """; diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs index 4dc0e025b..54698a81b 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs @@ -120,13 +120,20 @@ public async Task NullableTypeAsV3ShouldRoundTripCorrectly() [Fact] public async Task SerializeMultipleNonNullTypesAsV3OmitsType() { - // Current behavior isn't good. It loses the information about multiple types. var schema = new OpenApiSchema { Type = JsonSchemaType.String | JsonSchemaType.Integer }; var actual = await schema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); var expected = """ { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ] } """; @@ -139,7 +146,6 @@ public async Task SerializeMultipleNonNullTypesAsV3OmitsType() [Fact] public async Task SerializeMultipleNonNullTypesWithNullAsV3OmitsTypeButKeepsNullable() { - // Current behavior isn't good. It loses the information about multiple types. var schema = new OpenApiSchema { Type = JsonSchemaType.String | JsonSchemaType.Integer | JsonSchemaType.Null @@ -149,7 +155,21 @@ public async Task SerializeMultipleNonNullTypesWithNullAsV3OmitsTypeButKeepsNull var expected = """ { - "nullable": true + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "enum": [ + null + ], + "nullable": true + } + ], + "nullable": true } """; From 1540ae463d9e1574972456d4a1bc41f07e2a9bcc Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Tue, 4 Aug 2026 09:52:05 +0200 Subject: [PATCH 3/4] Round-tripping --- .../Reader/V3/OpenApiSchemaDeserializer.cs | 40 +++ .../Models/OpenApiSchemaTests.cs | 251 ++++++++++++++++++ .../OpenApiSchemaV30CompatibilityTests.cs | 8 +- 3 files changed, 295 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs index bf0b7bca4..65c156d04 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs @@ -420,7 +420,47 @@ public static IOpenApiSchema LoadSchema(JsonNode node, OpenApiDocument hostDocum schema.Type = JsonSchemaType.Null; } + if (schema.Type is null) + { + if (schema.AnyOf is not null && + schema.AnyOf.All(childSchema => childSchema is OpenApiSchema schema && DoesSchemaRepresentSingleType(schema))) + { + JsonSchemaType types = GetAllTypes(schema.AnyOf); + schema.AnyOf = null; + schema.Type = types; + } + else if (schema.OneOf is not null && + schema.OneOf.All(childSchema => childSchema is OpenApiSchema schema && DoesSchemaRepresentSingleType(schema))) + { + JsonSchemaType types = GetAllTypes(schema.OneOf); + schema.OneOf = null; + schema.Type = types; + } + } + return schema; } + + private static JsonSchemaType GetAllTypes(IList schemas) + { + JsonSchemaType types = 0; + foreach (var schema in schemas) + { + types |= schema.Type!.Value; + } + + return types; + } + + private static bool DoesSchemaRepresentSingleType(OpenApiSchema schema) + { + return schema.Type is JsonSchemaType.Null or + JsonSchemaType.Boolean or + JsonSchemaType.Integer or + JsonSchemaType.Number or + JsonSchemaType.String or + JsonSchemaType.Object or + JsonSchemaType.Array; + } } } diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs index 7a6db9071..7a94ab513 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs @@ -11,6 +11,7 @@ using System.Text.Json.Serialization; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.OpenApi.Reader; using VerifyXunit; using Xunit; @@ -2151,6 +2152,19 @@ public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_NotIncludingOne """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "integer", "string" ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2194,6 +2208,27 @@ public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingOneOfB """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "integer", "string" ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2237,6 +2272,27 @@ public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingAnyOfB """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "integer", "string" ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2291,6 +2347,34 @@ public async Task SerializeMultipleTypesWith3_0_NotIncludingNull_IncludingBothOn """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Null(deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2309,6 +2393,19 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_NotIn """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "null", "string" ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2346,6 +2443,27 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_Inclu """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "null", "string" ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2383,6 +2501,27 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_Inclu """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "null", "string" ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2439,6 +2578,35 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndSingleType_Inclu """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "null", "string" ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2470,6 +2638,19 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_NotIncl """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "null", "integer", "string" ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2520,6 +2701,27 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_Includi """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.Null(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "null", "integer", "string" ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2570,6 +2772,27 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_Includi """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.Null(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Equal(schema.Type, deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "type": [ "null", "integer", "string" ], + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } [Fact] @@ -2625,6 +2848,34 @@ public async Task SerializeMultipleTypesWith3_0_IncludingNullAndTwoTypes_Includi """; Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(result))); + + var deserializedSchema = OpenApiModelFactory.Parse(expected, OpenApiSpecVersion.OpenApi3_0, new OpenApiDocument(), out _); + Assert.NotNull(deserializedSchema.OneOf); + Assert.NotNull(deserializedSchema.AnyOf); + Assert.Null(deserializedSchema.Type); + + var actual32 = await deserializedSchema.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + var expected32 = """ + { + "anyOf": [ + { + "enum": [ + "A", + "B" + ] + } + ], + "oneOf": [ + { + "enum": [ + "A", + "B" + ] + } + ] + } + """; + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected32), JsonNode.Parse(actual32))); } private OpenApiSchema CreateNullableEnumSchema() diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs index 54698a81b..9effd58e5 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs @@ -118,7 +118,7 @@ public async Task NullableTypeAsV3ShouldRoundTripCorrectly() } [Fact] - public async Task SerializeMultipleNonNullTypesAsV3OmitsType() + public async Task SerializeMultipleNonNullTypesAsV3DoesNotOmitType() { var schema = new OpenApiSchema { Type = JsonSchemaType.String | JsonSchemaType.Integer }; @@ -140,11 +140,11 @@ public async Task SerializeMultipleNonNullTypesAsV3OmitsType() Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); var deserializedSchema = ParseSchemaFromV30Document(actual); - Assert.Null(deserializedSchema.Type); + Assert.Equal(schema.Type, deserializedSchema.Type); } [Fact] - public async Task SerializeMultipleNonNullTypesWithNullAsV3OmitsTypeButKeepsNullable() + public async Task SerializeMultipleNonNullTypesWithNullAsV3DoesNotOmitType() { var schema = new OpenApiSchema { @@ -176,7 +176,7 @@ public async Task SerializeMultipleNonNullTypesWithNullAsV3OmitsTypeButKeepsNull Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); var deserializedSchema = ParseSchemaFromV30Document(actual); - Assert.Null(deserializedSchema.Type); + Assert.Equal(schema.Type, deserializedSchema.Type); } [Fact] From 64c665138b976b07df7b7e40152b5866887d1f18 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:30:33 +0200 Subject: [PATCH 4/4] chore(benchmark): update benchmark report artifacts (#4) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com> --- .../performance.Descriptions-report-github.md | 20 +++--- .../performance.Descriptions-report.csv | 12 ++-- .../performance.Descriptions-report.html | 22 +++--- .../performance.Descriptions-report.json | 2 +- .../performance.EmptyModels-report-github.md | 68 +++++++++---------- .../performance.EmptyModels-report.csv | 56 +++++++-------- .../performance.EmptyModels-report.html | 66 +++++++++--------- .../performance.EmptyModels-report.json | 2 +- 8 files changed, 124 insertions(+), 124 deletions(-) diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md index 2abba8670..ebabf3ebf 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md @@ -1,10 +1,10 @@ ``` BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat) -AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores -.NET SDK 10.0.301 - [Host] : .NET 8.0.28 (8.0.28, 8.0.2826.26413), X64 RyuJIT x86-64-v3 - ShortRun : .NET 8.0.28 (8.0.28, 8.0.2826.26413), X64 RyuJIT x86-64-v3 +AMD EPYC 9V74 2.60GHz, 1 CPU, 4 logical and 2 physical cores +.NET SDK 10.0.302 + [Host] : .NET 8.0.29 (8.0.29, 8.0.2926.32403), X64 RyuJIT x86-64-v3 + ShortRun : .NET 8.0.29 (8.0.29, 8.0.2926.32403), X64 RyuJIT x86-64-v3 Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3 @@ -12,9 +12,9 @@ WarmupCount=3 ``` | Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | |------------- |---------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| -| PetStoreYaml | 582.2 μs | 208.61 μs | 11.43 μs | 19.5313 | 3.9063 | - | 375.68 KB | -| PetStoreJson | 252.3 μs | 29.46 μs | 1.61 μs | 11.7188 | 1.9531 | - | 209.67 KB | -| GHESYaml | 1,005,560.1 μs | 211,112.24 μs | 11,571.77 μs | 22000.0000 | 18000.0000 | 3000.0000 | 311035.48 KB | -| GHESJson | 369,047.2 μs | 94,799.88 μs | 5,196.30 μs | 9000.0000 | 8000.0000 | 2000.0000 | 140644.21 KB | -| GHESNextYaml | 1,241,432.6 μs | 106,390.00 μs | 5,831.60 μs | 34000.0000 | 19000.0000 | 3000.0000 | 513301.23 KB | -| GHESNextJson | 626,499.0 μs | 70,802.74 μs | 3,880.94 μs | 22000.0000 | 10000.0000 | 2000.0000 | 345119.94 KB | +| PetStoreYaml | 529.6 μs | 159.05 μs | 8.72 μs | 19.5313 | 3.9063 | - | 375.68 KB | +| PetStoreJson | 211.9 μs | 12.09 μs | 0.66 μs | 12.6953 | 2.9297 | - | 209.67 KB | +| GHESYaml | 961,450.4 μs | 493,674.21 μs | 27,059.95 μs | 22000.0000 | 18000.0000 | 3000.0000 | 310249.58 KB | +| GHESJson | 341,906.3 μs | 72,259.82 μs | 3,960.80 μs | 9000.0000 | 8000.0000 | 2000.0000 | 139861.88 KB | +| GHESNextYaml | 1,140,795.3 μs | 75,343.64 μs | 4,129.84 μs | 34000.0000 | 19000.0000 | 3000.0000 | 512935.25 KB | +| GHESNextJson | 545,592.7 μs | 36,360.40 μs | 1,993.04 μs | 22000.0000 | 10000.0000 | 2000.0000 | 344761.41 KB | diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv index 316be68f2..953a9ceac 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv @@ -1,7 +1,7 @@ Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Gen0,Gen1,Gen2,Allocated -PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,582.2 μs,208.61 μs,11.43 μs,19.5313,3.9063,0.0000,375.68 KB -PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,252.3 μs,29.46 μs,1.61 μs,11.7188,1.9531,0.0000,209.67 KB -GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,005,560.1 μs","211,112.24 μs","11,571.77 μs",22000.0000,18000.0000,3000.0000,311035.48 KB -GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"369,047.2 μs","94,799.88 μs","5,196.30 μs",9000.0000,8000.0000,2000.0000,140644.21 KB -GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,241,432.6 μs","106,390.00 μs","5,831.60 μs",34000.0000,19000.0000,3000.0000,513301.23 KB -GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"626,499.0 μs","70,802.74 μs","3,880.94 μs",22000.0000,10000.0000,2000.0000,345119.94 KB +PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,529.6 μs,159.05 μs,8.72 μs,19.5313,3.9063,0.0000,375.68 KB +PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,211.9 μs,12.09 μs,0.66 μs,12.6953,2.9297,0.0000,209.67 KB +GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"961,450.4 μs","493,674.21 μs","27,059.95 μs",22000.0000,18000.0000,3000.0000,310249.58 KB +GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"341,906.3 μs","72,259.82 μs","3,960.80 μs",9000.0000,8000.0000,2000.0000,139861.88 KB +GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,140,795.3 μs","75,343.64 μs","4,129.84 μs",34000.0000,19000.0000,3000.0000,512935.25 KB +GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"545,592.7 μs","36,360.40 μs","1,993.04 μs",22000.0000,10000.0000,2000.0000,344761.41 KB diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html index 95b1dadc6..454727da1 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html @@ -2,7 +2,7 @@ -performance.Descriptions-20260714-121715 +performance.Descriptions-20260804-081600