Introduce a protected virtual CreateJsonReader method in JsonEventFormatter
(Currently just for Json.NET) Fixes #151 Signed-off-by: Jon Skeet <jonskeet@google.com>
This commit is contained in:
parent
55b6df12cd
commit
b8e566586c
|
|
@ -524,7 +524,24 @@ namespace CloudNative.CloudEvents.NewtonsoftJson
|
|||
}
|
||||
}
|
||||
|
||||
internal static JsonReader CreateJsonReader(Stream stream, Encoding encoding) =>
|
||||
/// <summary>
|
||||
/// Creates a <see cref="JsonReader"/> for the given stream. This may be overridden in derived classes to
|
||||
/// customize the JSON parsing process, subject to the constraints listed in the remarks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The default implementation always creates an instance of <see cref="JsonTextReader"/>, and derived classes
|
||||
/// may assume that (calling this implementation and casting the result before modifying it).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Implementations should ensure that <see cref="JsonReader.DateParseHandling"/> is set to <see cref="DateParseHandling.None"/>,
|
||||
/// as timestamp parsing is performed in a CloudEvent-specific way, and Json.NET's own implementation can obscure that.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="stream">The stream to read from. Will not be null.</param>
|
||||
/// <param name="encoding">The expected text encoding. May be null, in which case UTF-8 should be assumed.</param>
|
||||
/// <returns>A JsonReader suitable for reading the </returns>
|
||||
protected virtual JsonReader CreateJsonReader(Stream stream, Encoding encoding) =>
|
||||
new JsonTextReader(new StreamReader(stream, encoding ?? Encoding.UTF8, detectEncodingFromByteOrderMarks: true, bufferSize: 8192, leaveOpen: true))
|
||||
{
|
||||
DateParseHandling = DateParseHandling.None
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright 2021 Cloud Native Foundation.
|
||||
// Licensed under the Apache 2.0 license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
using CloudNative.CloudEvents.UnitTests;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Xunit;
|
||||
|
||||
namespace CloudNative.CloudEvents.NewtonsoftJson.UnitTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests for the specialization of <see cref="JsonEventFormatter.CreateJsonReader(System.IO.Stream, Encoding)"/>
|
||||
/// </summary>
|
||||
public class SpecializedJsonReaderTest
|
||||
{
|
||||
[Fact]
|
||||
public void DefaultImplementation_ReturnsJsonTextReader()
|
||||
{
|
||||
var formatter = new CreateJsonReaderExposingFormatter();
|
||||
var reader = formatter.CreateJsonReaderPublic(CreateJsonStream(), null);
|
||||
Assert.IsType<JsonTextReader>(reader);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultImplementation_NoPropertyNameTable()
|
||||
{
|
||||
var formatter = new JsonEventFormatter();
|
||||
var event1 = formatter.DecodeStructuredModeMessage(CreateJsonStream(), null, null);
|
||||
var event2 = formatter.DecodeStructuredModeMessage(CreateJsonStream(), null, null);
|
||||
|
||||
JObject data1 = (JObject)event1.Data;
|
||||
JObject data2 = (JObject)event2.Data;
|
||||
|
||||
var property1 = data1.Properties().Single();
|
||||
var property2 = data2.Properties().Single();
|
||||
Assert.Equal(property1.Name, property2.Name);
|
||||
Assert.NotSame(property1.Name, property2.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Specialization_WithPropertyNameTable()
|
||||
{
|
||||
var formatter = new PropertyNameTableFormatter();
|
||||
var event1 = formatter.DecodeStructuredModeMessage(CreateJsonStream(), null, null);
|
||||
var event2 = formatter.DecodeStructuredModeMessage(CreateJsonStream(), null, null);
|
||||
|
||||
JObject data1 = (JObject)event1.Data;
|
||||
JObject data2 = (JObject)event2.Data;
|
||||
|
||||
var property1 = data1.Properties().Single();
|
||||
var property2 = data2.Properties().Single();
|
||||
Assert.Equal(property1.Name, property2.Name);
|
||||
Assert.Same(property1.Name, property2.Name);
|
||||
}
|
||||
|
||||
private Stream CreateJsonStream()
|
||||
{
|
||||
var cloudEvent = new CloudEvent
|
||||
{
|
||||
Data = new { DataName = "DataValue" }
|
||||
}.PopulateRequiredAttributes();
|
||||
var bytes = new JsonEventFormatter().EncodeStructuredModeMessage(cloudEvent, out _);
|
||||
return new MemoryStream(bytes);
|
||||
}
|
||||
|
||||
private class CreateJsonReaderExposingFormatter : JsonEventFormatter
|
||||
{
|
||||
public JsonReader CreateJsonReaderPublic(Stream stream, Encoding encoding) =>
|
||||
base.CreateJsonReader(stream, encoding);
|
||||
}
|
||||
|
||||
private class PropertyNameTableFormatter : JsonEventFormatter
|
||||
{
|
||||
private readonly DefaultJsonNameTable table;
|
||||
|
||||
public PropertyNameTableFormatter()
|
||||
{
|
||||
// Names aren't automatically cached by JsonTextReader, so we need to prepopulate the table.
|
||||
table = new DefaultJsonNameTable();
|
||||
table.Add("DataName");
|
||||
}
|
||||
|
||||
protected override JsonReader CreateJsonReader(Stream stream, Encoding encoding)
|
||||
{
|
||||
var reader = (JsonTextReader) base.CreateJsonReader(stream, encoding);
|
||||
reader.PropertyNameTable = table;
|
||||
return reader;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue