Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 16 additions & 4 deletions src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,21 @@ public virtual void WriteValue(long value)
}

/// <summary>
/// Write dateTimeOffset value.
/// Write DateTime value.
/// </summary>
/// <param name="value">The decimal value.</param>
/// <param name="value">The DateTime value.</param>
public virtual void WriteValue(DateTime value)
{
this.WriteValue(value.ToString("o"));
}

/// <summary>
/// Write DateTimeOffset value.
/// </summary>
/// <param name="value">The DateTimeOffset value.</param>
public virtual void WriteValue(DateTimeOffset value)
{
WriteValueSeparator();
Writer.Write(value.ToString("o"));
this.WriteValue(value.ToString("o"));
}

/// <summary>
Expand Down Expand Up @@ -218,6 +226,10 @@ public virtual void WriteValue(object value)
{
WriteValue((decimal)value);
}
else if ( type == typeof(DateTime) || type == typeof(DateTime?) )
{
WriteValue((DateTime)value);
}
else if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?))
{
WriteValue((DateTimeOffset)value);
Expand Down
63 changes: 62 additions & 1 deletion test/Microsoft.OpenApi.Tests/Writers/OpenApiJsonWriterTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -134,6 +135,17 @@ public static IEnumerable<object[]> WriteMapAsJsonShouldMatchExpectedTestCasesCo
}
};

// DateTime
yield return new object[]
{
new Dictionary<string, object>
{
["property1"] = new DateTime(1970, 01, 01),
["property2"] = new DateTimeOffset(new DateTime(1970, 01, 01)),
["property3"] = new DateTime(2018, 04, 03),
}
};

// Nested map
yield return new object[]
{
Expand Down Expand Up @@ -183,7 +195,12 @@ public static IEnumerable<object[]> WriteMapAsJsonShouldMatchExpectedTestCasesCo

private void WriteValueRecursive(OpenApiJsonWriter writer, object value)
{
if (value == null || value.GetType().IsPrimitive || value is decimal || value is string)
if (value == null
|| value.GetType().IsPrimitive
|| value is decimal
|| value is string
|| value is DateTimeOffset
|| value is DateTime)
{
writer.WriteValue(value);
}
Expand Down Expand Up @@ -230,5 +247,49 @@ public void WriteMapAsJsonShouldMatchExpected(IDictionary<string, object> inputM
// Assert
parsedObject.ShouldBeEquivalentTo(expectedObject);
}

public static IEnumerable<object[]> WriteDateTimeAsJsonTestCases()
{
yield return new object[]
{
new DateTimeOffset(2018, 1, 1, 10, 20, 30, TimeSpan.Zero),
};

yield return new object[]
{
new DateTimeOffset(2018, 1, 1, 10, 20, 30, 100, TimeSpan.FromHours(14)),
};

yield return new object[]
{
DateTimeOffset.UtcNow + TimeSpan.FromDays(4)
};

yield return new object[]
{
DateTime.UtcNow + TimeSpan.FromDays(4)
};
}

[Theory]
[MemberData(nameof(WriteDateTimeAsJsonTestCases))]
public void WriteDateTimeAsJsonShouldMatchExpected(DateTimeOffset dateTimeOffset)
{
// Arrange
var outputString = new StringWriter();
var writer = new OpenApiJsonWriter(outputString);

// Act
writer.WriteValue(dateTimeOffset);

var writtenString = outputString.GetStringBuilder().ToString();
var expectedString = JsonConvert.SerializeObject(dateTimeOffset, new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffffffK",
});

// Assert
writtenString.Should().Be(expectedString);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ public void WriteOpenApiDateTimeAsJsonWorks(string inputString)
var dateTimeValue = new OpenApiDateTime(input);

var json = WriteAsJson(dateTimeValue);
var expectedJson = "\"" + input.ToString("o") + "\"";

// Assert
json.Should().Be(input.ToString("o"));
json.Should().Be(expectedJson);
}

[Theory]
Expand Down
65 changes: 63 additions & 2 deletions test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -171,6 +172,20 @@ public static IEnumerable<object[]> WriteMapAsYamlShouldMatchExpectedTestCasesCo
property11: ''"
};

// DateTime
yield return new object[]
{
new Dictionary<string, object>
{
["property1"] = new DateTime(1970, 01, 01),
["property2"] = new DateTimeOffset(new DateTime(1970, 01, 01), TimeSpan.FromHours(3)),
["property3"] = new DateTime(2018, 04, 03),
},
@"property1: '1970-01-01T00:00:00.0000000'
property2: '1970-01-01T00:00:00.0000000+03:00'
property3: '2018-04-03T00:00:00.0000000'"
};

// Nested map
yield return new object[]
{
Expand Down Expand Up @@ -237,13 +252,18 @@ public static IEnumerable<object[]> WriteMapAsYamlShouldMatchExpectedTestCasesCo

private void WriteValueRecursive(OpenApiYamlWriter writer, object value)
{
if (value == null || value.GetType().IsPrimitive || value is decimal || value is string)
if (value == null
|| value.GetType().IsPrimitive
|| value is decimal
|| value is string
|| value is DateTimeOffset
|| value is DateTime)
{
writer.WriteValue(value);
}
else if (value.GetType().IsGenericType &&
(typeof(IDictionary<,>).IsAssignableFrom(value.GetType().GetGenericTypeDefinition()) ||
typeof(Dictionary<,>).IsAssignableFrom(value.GetType().GetGenericTypeDefinition())))
typeof(Dictionary<,>).IsAssignableFrom(value.GetType().GetGenericTypeDefinition()) ) )
{
writer.WriteStartObject();
foreach (var elementValue in (dynamic)(value))
Expand Down Expand Up @@ -284,5 +304,46 @@ public void WriteMapAsYamlShouldMatchExpected(IDictionary<string, object> inputM
expectedYaml = expectedYaml.MakeLineBreaksEnvironmentNeutral();
actualYaml.Should().Be(expectedYaml);
}

public static IEnumerable<object[]> WriteDateTimeAsJsonTestCases()
{
yield return new object[]
{
new DateTimeOffset(2018, 1, 1, 10, 20, 30, TimeSpan.Zero)
};

yield return new object[]
{
new DateTimeOffset(2018, 1, 1, 10, 20, 30, 100, TimeSpan.FromHours(14))
};

yield return new object[]
{
DateTimeOffset.UtcNow + TimeSpan.FromDays(4)
};

yield return new object[]
{
DateTime.UtcNow + TimeSpan.FromDays(4)
};
}

[Theory]
[MemberData(nameof(WriteDateTimeAsJsonTestCases))]
public void WriteDateTimeAsJsonShouldMatchExpected(DateTimeOffset dateTimeOffset)
{
// Arrange
var outputString = new StringWriter();
var writer = new OpenApiYamlWriter(outputString);

// Act
writer.WriteValue(dateTimeOffset);

var writtenString = outputString.GetStringBuilder().ToString();
var expectedString = " '" + dateTimeOffset.ToString("o") + "'";

// Assert
writtenString.Should().Be(expectedString);
}
}
}