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))
|
new JsonTextReader(new StreamReader(stream, encoding ?? Encoding.UTF8, detectEncodingFromByteOrderMarks: true, bufferSize: 8192, leaveOpen: true))
|
||||||
{
|
{
|
||||||
DateParseHandling = DateParseHandling.None
|
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