Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 19 additions & 70 deletions src/Microsoft.OpenApi/Writers/OpenApiWriterAnyExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.OpenApi.Any;
Expand Down Expand Up @@ -68,13 +66,13 @@ public static void WriteAny(this IOpenApiWriter writer, JsonNode node)
writer.WriteObject(node as JsonObject);
break;
case JsonValueKind.String: // Primitive
writer.WritePrimitive(node);
writer.WritePrimitive(node.AsValue());
break;
case JsonValueKind.Number: // Primitive
writer.WritePrimitive(node);
writer.WritePrimitive(node.AsValue());
break;
case JsonValueKind.True or JsonValueKind.False: // Primitive
writer.WritePrimitive(node);
writer.WritePrimitive(node.AsValue());
break;
case JsonValueKind.Null: // null
writer.WriteNull();
Expand Down Expand Up @@ -109,72 +107,23 @@ private static void WriteObject(this IOpenApiWriter writer, JsonObject entity)
writer.WriteEndObject();
}

private static void WritePrimitive(this IOpenApiWriter writer, JsonNode primitive)
private static void WritePrimitive(this IOpenApiWriter writer, JsonValue jsonValue)
{
Utils.CheckArgumentNull(writer);

var valueKind = primitive.GetValueKind();

if (valueKind == JsonValueKind.String && primitive is JsonValue jsonStrValue)
{
if (jsonStrValue.TryGetValue<DateTimeOffset>(out var dto))
{
writer.WriteValue(dto);
}
else if (jsonStrValue.TryGetValue<DateTime>(out var dt))
{
writer.WriteValue(dt);
}
else if (jsonStrValue.TryGetValue<string>(out var strValue))
{
// check whether string is actual string or date time object
if (DateTimeOffset.TryParse(strValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTimeOffset))
{
writer.WriteValue(dateTimeOffset);
}
else if (DateTime.TryParse(strValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime))
{ // order matters, DTO needs to be checked first!!!
writer.WriteValue(dateTime);
}
else
{
writer.WriteValue(strValue);
}
}
}

else if (valueKind == JsonValueKind.Number && primitive is JsonValue jsonValue)
{

if (jsonValue.TryGetValue<decimal>(out var decimalValue))
{
writer.WriteValue(decimalValue);
}
else if (jsonValue.TryGetValue<double>(out var doubleValue))
{
writer.WriteValue(doubleValue);
}
else if (jsonValue.TryGetValue<float>(out var floatValue))
{
writer.WriteValue(floatValue);
}
else if (jsonValue.TryGetValue<long>(out var longValue))
{
writer.WriteValue(longValue);
}
else if (jsonValue.TryGetValue<int>(out var intValue))
{
writer.WriteValue(intValue);
}
}
else if (valueKind is JsonValueKind.False)
{
writer.WriteValue(false);
}
else if (valueKind is JsonValueKind.True)
{
writer.WriteValue(true);
}
if (jsonValue.TryGetValue(out string stringValue))
writer.WriteValue(stringValue);
else if (jsonValue.TryGetValue(out bool boolValue))
writer.WriteValue(boolValue);
// write number values
else if (jsonValue.TryGetValue(out decimal decimalValue))
writer.WriteValue(decimalValue);
else if (jsonValue.TryGetValue(out double doubleValue))
writer.WriteValue(doubleValue);
else if (jsonValue.TryGetValue(out float floatValue))
writer.WriteValue(floatValue);
else if (jsonValue.TryGetValue(out long longValue))
writer.WriteValue(longValue);
else if (jsonValue.TryGetValue(out int intValue))
writer.WriteValue(intValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,43 @@ public void ParseSchemaWithUnrecognizedKeywordsWorks()
Assert.Equal(2, schema.UnrecognizedKeywords.Count);
}

[Fact]
public void ParseSchemaExampleWithPrimitivesWorks()
{
var expected1 = @"{
""type"": ""string"",
""example"": ""2024-01-02""
}";

var expected2 = @"{
""type"": ""string"",
""example"": ""3.14""
}";
var schema = new OpenApiSchema()
{
Type = JsonSchemaType.String,
Example = JsonValue.Create("2024-01-02")
};

var schema2 = new OpenApiSchema()
{
Type = JsonSchemaType.String,
Example = JsonValue.Create("3.14")
};

var textWriter = new StringWriter();
var writer = new OpenApiJsonWriter(textWriter);
schema.SerializeAsV31(writer);
var actual1 = textWriter.ToString();
Assert.Equal(expected1.MakeLineBreaksEnvironmentNeutral(), actual1.MakeLineBreaksEnvironmentNeutral());

textWriter = new StringWriter();
writer = new OpenApiJsonWriter(textWriter);
schema2.SerializeAsV31(writer);
var actual2 = textWriter.ToString();
Assert.Equal(expected2.MakeLineBreaksEnvironmentNeutral(), actual2.MakeLineBreaksEnvironmentNeutral());
}

[Theory]
[InlineData(JsonSchemaType.Integer | JsonSchemaType.String, new[] { "integer", "string" })]
[InlineData(JsonSchemaType.Integer | JsonSchemaType.Null, new[] { "integer", "null" })]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,10 @@ from shouldBeTerse in shouldProduceTerseOutputValues
public async Task WriteOpenApiDateTimeAsJsonWorksAsync(string inputString, bool produceTerseOutput)
{
// Arrange
var input = DateTimeOffset.Parse(inputString, CultureInfo.InvariantCulture);
var dateTimeValue = input;
var dateTimeValue = JsonValue.Create(inputString);

var json = await WriteAsJsonAsync(dateTimeValue, produceTerseOutput);
var expectedJson = "\"" + input.ToString("o") + "\"";
var expectedJson = "\"" + inputString + "\"";

// Assert
Assert.Equal(expectedJson, json);
Expand Down