Skip to content
This repository has been archived by the owner on Jul 9, 2024. It is now read-only.

Commit

Permalink
Merge pull request #220 from MihaMarkic/feature/async
Browse files Browse the repository at this point in the history
Implements IAsyncParseNodeFactory interface
  • Loading branch information
andrueastman authored May 9, 2024
2 parents e49e89c + 2025083 commit c7284b0
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 3 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.3.0] - 2024-05-13

### Added

- Implements IAsyncParseNodeFactory interface which adds async support

## [1.2.3] - 2024-04-25

### Changed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace Microsoft.Kiota.Serialization.Json.Tests
{
public class JsonAsyncParseNodeFactoryTests
{
private readonly JsonParseNodeFactory _jsonParseNodeFactory;
private const string TestJsonString = "{\"key\":\"value\"}";

public JsonAsyncParseNodeFactoryTests()
{
_jsonParseNodeFactory = new JsonParseNodeFactory();
}

[Fact]
public async Task GetsWriterForJsonContentType()
{
using var jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(TestJsonString));
var jsonWriter = await _jsonParseNodeFactory.GetRootParseNodeAsync(_jsonParseNodeFactory.ValidContentType, jsonStream);

// Assert
Assert.NotNull(jsonWriter);
Assert.IsAssignableFrom<JsonParseNode>(jsonWriter);
}

[Fact]
public async Task ThrowsArgumentOutOfRangeExceptionForInvalidContentType()
{
var streamContentType = "application/octet-stream";
using var jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(TestJsonString));
var exception = await Assert.ThrowsAsync<ArgumentOutOfRangeException>(
async () => await _jsonParseNodeFactory.GetRootParseNodeAsync(streamContentType, jsonStream));

// Assert
Assert.NotNull(exception);
Assert.Equal($"expected a {_jsonParseNodeFactory.ValidContentType} content type", exception.ParamName);
}

[Theory]
[InlineData(null)]
[InlineData("")]
public async Task ThrowsArgumentNullExceptionForNoContentType(string contentType)
{
using var jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(TestJsonString));
var exception = await Assert.ThrowsAsync<ArgumentNullException>(
async () => await _jsonParseNodeFactory.GetRootParseNodeAsync(contentType, jsonStream));

// Assert
Assert.NotNull(exception);
Assert.Equal("contentType", exception.ParamName);
}
}
}
27 changes: 25 additions & 2 deletions src/JsonParseNodeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
using System;
using System.IO;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Kiota.Abstractions.Serialization;

namespace Microsoft.Kiota.Serialization.Json
{
/// <summary>
/// The <see cref="IParseNodeFactory"/> implementation for json content types
/// </summary>
public class JsonParseNodeFactory : IParseNodeFactory
public class JsonParseNodeFactory : IAsyncParseNodeFactory
{
private readonly KiotaJsonSerializationContext _jsonJsonSerializationContext;

Expand Down Expand Up @@ -43,7 +45,8 @@ public JsonParseNodeFactory(KiotaJsonSerializationContext jsonJsonSerializationC
/// </summary>
/// <param name="contentType">The content type of the stream to be parsed</param>
/// <param name="content">The <see cref="Stream"/> containing json to parse.</param>
/// <returns>An instance of <see cref="IParseNode"/> for json manipulation</returns>
/// <returns>An instance of <see cref="IParseNode"/> for json manipulation</returns>
[Obsolete("Use GetRootParseNodeAsync instead")]
public IParseNode GetRootParseNode(string contentType, Stream content)
{
if(string.IsNullOrEmpty(contentType))
Expand All @@ -56,5 +59,25 @@ public IParseNode GetRootParseNode(string contentType, Stream content)
using var jsonDocument = JsonDocument.Parse(content);
return new JsonParseNode(jsonDocument.RootElement.Clone(), _jsonJsonSerializationContext);
}
/// <summary>
/// Asynchronously gets the root <see cref="IParseNode"/> of the json to be read.
/// </summary>
/// <param name="contentType">The content type of the stream to be parsed</param>
/// <param name="content">The <see cref="Stream"/> containing json to parse.</param>
/// <param name="cancellationToken">The cancellation token for the task</param>
/// <returns>An instance of <see cref="IParseNode"/> for json manipulation</returns>
public async Task<IParseNode> GetRootParseNodeAsync(string contentType, Stream content,
CancellationToken cancellationToken = default)
{
if(string.IsNullOrEmpty(contentType))
throw new ArgumentNullException(nameof(contentType));
else if(!ValidContentType.Equals(contentType, StringComparison.OrdinalIgnoreCase))
throw new ArgumentOutOfRangeException($"expected a {ValidContentType} content type");

_ = content ?? throw new ArgumentNullException(nameof(content));

using var jsonDocument = await JsonDocument.ParseAsync(content, cancellationToken: cancellationToken).ConfigureAwait(false);
return new JsonParseNode(jsonDocument.RootElement.Clone(), _jsonJsonSerializationContext);
}
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.Kiota.Serialization.Json.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageProjectUrl>https://aka.ms/kiota/docs</PackageProjectUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<Deterministic>true</Deterministic>
<VersionPrefix>1.2.3</VersionPrefix>
<VersionPrefix>1.3.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down

0 comments on commit c7284b0

Please sign in to comment.