From 0b752435c72aaa149714c24f40120ed997b4bc75 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 30 Oct 2023 15:34:22 -0400 Subject: [PATCH] - adds serialization helpers Signed-off-by: Vincent Biret --- .../SerializationHelpersTests.cs | 69 ++++++++++++++++ src/serialization/JsonSerializationHelpers.cs | 55 +++++++++++++ src/serialization/SerializationHelpers.cs | 81 +++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 Microsoft.Kiota.Abstractions.Tests/Serialization/SerializationHelpersTests.cs create mode 100644 src/serialization/JsonSerializationHelpers.cs create mode 100644 src/serialization/SerializationHelpers.cs diff --git a/Microsoft.Kiota.Abstractions.Tests/Serialization/SerializationHelpersTests.cs b/Microsoft.Kiota.Abstractions.Tests/Serialization/SerializationHelpersTests.cs new file mode 100644 index 00000000..4d72605e --- /dev/null +++ b/Microsoft.Kiota.Abstractions.Tests/Serialization/SerializationHelpersTests.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Microsoft.Kiota.Abstractions.Serialization; +using Microsoft.Kiota.Abstractions.Tests.Mocks; +using Moq; +using Xunit; + +namespace Microsoft.Kiota.Abstractions.Tests.Serialization; + +public class SerializationHelpersTests +{ + private const string _jsonContentType = "application/json"; + [Fact] + public void DefensiveObject() + { + Assert.Throws(() => SerializationHelpers.SerializeAsStream(null, (TestEntity)null)); + Assert.Throws(() => SerializationHelpers.SerializeAsStream(_jsonContentType, (TestEntity)null)); + } + [Fact] + public void DefensiveObjectCollection() + { + Assert.Throws(() => SerializationHelpers.SerializeAsStream(null, (IEnumerable)null)); + Assert.Throws(() => SerializationHelpers.SerializeAsStream(_jsonContentType, (IEnumerable)null)); + } + [Fact] + public void SerializesObject() + { + var mockSerializationWriter = new Mock(); + mockSerializationWriter.Setup(x => x.GetSerializedContent()).Returns(new MemoryStream(UTF8Encoding.UTF8.GetBytes("{'id':'123'}"))); + var mockSerializationWriterFactory = new Mock(); + mockSerializationWriterFactory.Setup(x => x.GetSerializationWriter(It.IsAny())).Returns(mockSerializationWriter.Object); + SerializationWriterFactoryRegistry.DefaultInstance.ContentTypeAssociatedFactories[_jsonContentType] = mockSerializationWriterFactory.Object; + + var result = SerializationHelpers.SerializeAsString(_jsonContentType, new TestEntity() + { + Id = "123" + }); + + Assert.Equal("{'id':'123'}", result); + + mockSerializationWriterFactory.Verify(x => x.GetSerializationWriter(It.IsAny()), Times.Once); + mockSerializationWriter.Verify(x => x.WriteObjectValue(It.IsAny(), It.IsAny()), Times.Once); + mockSerializationWriter.Verify(x => x.GetSerializedContent(), Times.Once); + } + [Fact] + public void SerializesObjectCollection() + { + var mockSerializationWriter = new Mock(); + mockSerializationWriter.Setup(x => x.GetSerializedContent()).Returns(new MemoryStream(UTF8Encoding.UTF8.GetBytes("[{'id':'123'}]"))); + var mockSerializationWriterFactory = new Mock(); + mockSerializationWriterFactory.Setup(x => x.GetSerializationWriter(It.IsAny())).Returns(mockSerializationWriter.Object); + SerializationWriterFactoryRegistry.DefaultInstance.ContentTypeAssociatedFactories[_jsonContentType] = mockSerializationWriterFactory.Object; + + var result = SerializationHelpers.SerializeAsString(_jsonContentType, new List { + new() + { + Id = "123" + } + }); + + Assert.Equal("[{'id':'123'}]", result); + + mockSerializationWriterFactory.Verify(x => x.GetSerializationWriter(It.IsAny()), Times.Once); + mockSerializationWriter.Verify(x => x.WriteCollectionOfObjectValues(It.IsAny(), It.IsAny>()), Times.Once); + mockSerializationWriter.Verify(x => x.GetSerializedContent(), Times.Once); + } +} \ No newline at end of file diff --git a/src/serialization/JsonSerializationHelpers.cs b/src/serialization/JsonSerializationHelpers.cs new file mode 100644 index 00000000..96c7913c --- /dev/null +++ b/src/serialization/JsonSerializationHelpers.cs @@ -0,0 +1,55 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. +// ------------------------------------------------------------------------------ + +using System.Collections.Generic; +using System.IO; +#if NET5_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + +namespace Microsoft.Kiota.Abstractions.Serialization; + +/// +/// Set of helper methods for JSON serialization +/// +public static class JsonSerializationHelpers +{ + private const string _jsonContentType = "application/json"; + /// + /// Serializes the given object into a string based on the content type. + /// + /// Type of the object to serialize + /// The object to serialize. + /// The serialized representation as a stream. + public static Stream SerializeAsStream(T value) where T : IParsable + => SerializationHelpers.SerializeAsStream(_jsonContentType, value); + + /// + /// Serializes the given object into a string based on the content type. + /// + /// Type of the object to serialize + /// The object to serialize. + /// The serialized representation as a string. + public static string SerializeAsString(T value) where T : IParsable + => SerializationHelpers.SerializeAsString(_jsonContentType, value); + + /// + /// Serializes the given object into a string based on the content type. + /// + /// Type of the object to serialize + /// The object to serialize. + /// The serialized representation as a stream. + public static Stream SerializeAsStream(IEnumerable value) where T : IParsable + => SerializationHelpers.SerializeAsStream(_jsonContentType, value); + + /// + /// Serializes the given object into a string based on the content type. + /// + /// Type of the object to serialize + /// The object to serialize. + /// The serialized representation as a string. + public static string SerializeAsString(IEnumerable value) where T : IParsable + => SerializationHelpers.SerializeAsString(_jsonContentType, value); + +} \ No newline at end of file diff --git a/src/serialization/SerializationHelpers.cs b/src/serialization/SerializationHelpers.cs new file mode 100644 index 00000000..2749ed5d --- /dev/null +++ b/src/serialization/SerializationHelpers.cs @@ -0,0 +1,81 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. +// ------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.IO; +#if NET5_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + + +namespace Microsoft.Kiota.Abstractions.Serialization; + +/// +/// Set of helper methods for serialization +/// +public static class SerializationHelpers +{ + /// + /// Serializes the given object into a string based on the content type. + /// + /// Type of the object to serialize + /// Content type to serialize the object to + /// The object to serialize. + /// The serialized representation as a stream. + public static Stream SerializeAsStream(string contentType, T value) where T : IParsable + { + using var writer = GetSerializationWriter(contentType, value); + writer.WriteObjectValue(string.Empty, value); + return writer.GetSerializedContent(); + } + /// + /// Serializes the given object into a string based on the content type. + /// + /// Type of the object to serialize + /// Content type to serialize the object to + /// The object to serialize. + /// The serialized representation as a string. + public static string SerializeAsString(string contentType, T value) where T : IParsable + { + using var stream = SerializeAsStream(contentType, value); + return GetStringFromStream(stream); + } + /// + /// Serializes the given object into a string based on the content type. + /// + /// Type of the object to serialize + /// Content type to serialize the object to + /// The object to serialize. + /// The serialized representation as a stream. + public static Stream SerializeAsStream(string contentType, IEnumerable value) where T : IParsable + { + using var writer = GetSerializationWriter(contentType, value); + writer.WriteCollectionOfObjectValues(string.Empty, value); + return writer.GetSerializedContent(); + } + /// + /// Serializes the given object into a string based on the content type. + /// + /// Type of the object to serialize + /// Content type to serialize the object to + /// The object to serialize. + /// The serialized representation as a string. + public static string SerializeAsString(string contentType, IEnumerable value) where T : IParsable + { + using var stream = SerializeAsStream(contentType, value); + return GetStringFromStream(stream); + } + private static string GetStringFromStream(Stream stream) + { + using var reader = new StreamReader(stream); + return reader.ReadToEndAsync().ConfigureAwait(false).GetAwaiter().GetResult(); // so the asp.net projects don't get an error + } + private static ISerializationWriter GetSerializationWriter(string contentType, object value) + { + if(string.IsNullOrEmpty(contentType)) throw new ArgumentNullException(nameof(contentType)); + if(value == null) throw new ArgumentNullException(nameof(value)); + return SerializationWriterFactoryRegistry.DefaultInstance.GetSerializationWriter(contentType); + } +} \ No newline at end of file