未验证 提交 f25b23e0 编写于 作者: E Eirik Tsarpalis 提交者: GitHub

Consolidate sync/async JsonSerializer test abstractions (#66729)

* Consolidate sync/async JsonSerializer test abstractions

* Rename wrapper properties
上级 bf1af7ff
......@@ -18,18 +18,23 @@ public abstract partial class CollectionTests
[MemberData(nameof(GetAsyncEnumerableSources))]
public async Task WriteRootLevelAsyncEnumerable<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer is null)
{
return;
}
JsonSerializerOptions options = new JsonSerializerOptions
{
DefaultBufferSize = bufferSize
};
string expectedJson = await JsonSerializerWrapperForString.SerializeWrapper(source);
string expectedJson = JsonSerializer.Serialize(source);
using var stream = new Utf8MemoryStream();
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
await JsonSerializerWrapperForStream.SerializeWrapper(stream, asyncEnumerable, options);
await StreamingSerializer.SerializeWrapper(stream, asyncEnumerable, options);
JsonTestHelper.AssertJsonEqual(expectedJson, stream.ToString());
JsonTestHelper.AssertJsonEqual(expectedJson, stream.AsString());
Assert.Equal(1, asyncEnumerable.TotalCreatedEnumerators);
Assert.Equal(1, asyncEnumerable.TotalDisposedEnumerators);
}
......@@ -38,18 +43,23 @@ public async Task WriteRootLevelAsyncEnumerable<TElement>(IEnumerable<TElement>
[MemberData(nameof(GetAsyncEnumerableSources))]
public async Task WriteNestedAsyncEnumerable<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer is null)
{
return;
}
JsonSerializerOptions options = new JsonSerializerOptions
{
DefaultBufferSize = bufferSize
};
string expectedJson = await JsonSerializerWrapperForString.SerializeWrapper(new { Data = source });
string expectedJson = JsonSerializer.Serialize(new { Data = source });
using var stream = new Utf8MemoryStream();
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
await JsonSerializerWrapperForStream.SerializeWrapper(stream, new { Data = asyncEnumerable }, options);
await StreamingSerializer.SerializeWrapper(stream, new { Data = asyncEnumerable }, options);
JsonTestHelper.AssertJsonEqual(expectedJson, stream.ToString());
JsonTestHelper.AssertJsonEqual(expectedJson, stream.AsString());
Assert.Equal(1, asyncEnumerable.TotalCreatedEnumerators);
Assert.Equal(1, asyncEnumerable.TotalDisposedEnumerators);
}
......@@ -58,18 +68,23 @@ public async Task WriteNestedAsyncEnumerable<TElement>(IEnumerable<TElement> sou
[MemberData(nameof(GetAsyncEnumerableSources))]
public async Task WriteNestedAsyncEnumerable_DTO<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer is null)
{
return;
}
JsonSerializerOptions options = new JsonSerializerOptions
{
DefaultBufferSize = bufferSize
};
string expectedJson = await JsonSerializerWrapperForString.SerializeWrapper(new { Data = source });
string expectedJson = JsonSerializer.Serialize(new { Data = source });
using var stream = new Utf8MemoryStream();
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
await JsonSerializerWrapperForStream.SerializeWrapper(stream, new AsyncEnumerableDto<TElement> { Data = asyncEnumerable }, options);
await StreamingSerializer.SerializeWrapper(stream, new AsyncEnumerableDto<TElement> { Data = asyncEnumerable }, options);
JsonTestHelper.AssertJsonEqual(expectedJson, stream.ToString());
JsonTestHelper.AssertJsonEqual(expectedJson, stream.AsString());
Assert.Equal(1, asyncEnumerable.TotalCreatedEnumerators);
Assert.Equal(1, asyncEnumerable.TotalDisposedEnumerators);
}
......@@ -78,6 +93,11 @@ public async Task WriteNestedAsyncEnumerable_DTO<TElement>(IEnumerable<TElement>
[MemberData(nameof(GetAsyncEnumerableSources))]
public async Task WriteNestedAsyncEnumerable_Nullable<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer is null)
{
return;
}
// Primarily tests the ability of NullableConverter to flow async serialization state
JsonSerializerOptions options = new JsonSerializerOptions
......@@ -86,13 +106,13 @@ public async Task WriteNestedAsyncEnumerable_Nullable<TElement>(IEnumerable<TEle
IncludeFields = true,
};
string expectedJson = await JsonSerializerWrapperForString.SerializeWrapper<(IEnumerable<TElement>, bool)?>((source, false), options);
string expectedJson = JsonSerializer.Serialize<(IEnumerable<TElement>, bool)?>((source, false), options);
using var stream = new Utf8MemoryStream();
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
await JsonSerializerWrapperForStream.SerializeWrapper<(IAsyncEnumerable<TElement>, bool)?>(stream, (asyncEnumerable, false), options);
await StreamingSerializer.SerializeWrapper<(IAsyncEnumerable<TElement>, bool)?>(stream, (asyncEnumerable, false), options);
JsonTestHelper.AssertJsonEqual(expectedJson, stream.ToString());
JsonTestHelper.AssertJsonEqual(expectedJson, stream.AsString());
Assert.Equal(1, asyncEnumerable.TotalCreatedEnumerators);
Assert.Equal(1, asyncEnumerable.TotalDisposedEnumerators);
}
......@@ -131,18 +151,23 @@ public class AsyncEnumerableDto<TElement>
[MemberData(nameof(GetAsyncEnumerableSources))]
public async Task WriteSequentialNestedAsyncEnumerables<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer is null)
{
return;
}
JsonSerializerOptions options = new JsonSerializerOptions
{
DefaultBufferSize = bufferSize
};
string expectedJson = await JsonSerializerWrapperForString.SerializeWrapper(new { Data1 = source, Data2 = source });
string expectedJson = JsonSerializer.Serialize(new { Data1 = source, Data2 = source });
using var stream = new Utf8MemoryStream();
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
await JsonSerializerWrapperForStream.SerializeWrapper(stream, new { Data1 = asyncEnumerable, Data2 = asyncEnumerable }, options);
await StreamingSerializer.SerializeWrapper(stream, new { Data1 = asyncEnumerable, Data2 = asyncEnumerable }, options);
JsonTestHelper.AssertJsonEqual(expectedJson, stream.ToString());
JsonTestHelper.AssertJsonEqual(expectedJson, stream.AsString());
Assert.Equal(2, asyncEnumerable.TotalCreatedEnumerators);
Assert.Equal(2, asyncEnumerable.TotalDisposedEnumerators);
}
......@@ -151,13 +176,18 @@ public async Task WriteSequentialNestedAsyncEnumerables<TElement>(IEnumerable<TE
[MemberData(nameof(GetAsyncEnumerableSources))]
public async Task WriteAsyncEnumerableOfAsyncEnumerables<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer is null)
{
return;
}
JsonSerializerOptions options = new JsonSerializerOptions
{
DefaultBufferSize = bufferSize
};
const int OuterEnumerableCount = 5;
string expectedJson = await JsonSerializerWrapperForString.SerializeWrapper(Enumerable.Repeat(source, OuterEnumerableCount));
string expectedJson = JsonSerializer.Serialize(Enumerable.Repeat(source, OuterEnumerableCount));
var innerAsyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
var outerAsyncEnumerable =
......@@ -165,9 +195,9 @@ public async Task WriteAsyncEnumerableOfAsyncEnumerables<TElement>(IEnumerable<T
Enumerable.Repeat(innerAsyncEnumerable, OuterEnumerableCount), delayInterval);
using var stream = new Utf8MemoryStream();
await JsonSerializerWrapperForStream.SerializeWrapper(stream, outerAsyncEnumerable, options);
await StreamingSerializer.SerializeWrapper(stream, outerAsyncEnumerable, options);
JsonTestHelper.AssertJsonEqual(expectedJson, stream.ToString());
JsonTestHelper.AssertJsonEqual(expectedJson, stream.AsString());
Assert.Equal(1, outerAsyncEnumerable.TotalCreatedEnumerators);
Assert.Equal(1, outerAsyncEnumerable.TotalDisposedEnumerators);
Assert.Equal(OuterEnumerableCount, innerAsyncEnumerable.TotalCreatedEnumerators);
......@@ -175,26 +205,31 @@ public async Task WriteAsyncEnumerableOfAsyncEnumerables<TElement>(IEnumerable<T
}
[Fact]
public async Task WriteRootLevelAsyncEnumerableSync_ThrowsNotSupportedException()
public void WriteRootLevelAsyncEnumerableSync_ThrowsNotSupportedException()
{
IAsyncEnumerable<int> asyncEnumerable = new MockedAsyncEnumerable<int>(Enumerable.Range(1, 10));
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.SerializeWrapper(asyncEnumerable));
Assert.Throws<NotSupportedException>(() => JsonSerializer.Serialize(asyncEnumerable));
}
[Fact]
public async Task WriteNestedAsyncEnumerableSync_ThrowsNotSupportedException()
public void WriteNestedAsyncEnumerableSync_ThrowsNotSupportedException()
{
IAsyncEnumerable<int> asyncEnumerable = new MockedAsyncEnumerable<int>(Enumerable.Range(1, 10));
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.SerializeWrapper(new { Data = asyncEnumerable }));
Assert.Throws<NotSupportedException>(() => JsonSerializer.Serialize(new { Data = asyncEnumerable }));
}
[Fact]
public async Task WriteAsyncEnumerable_ElementSerializationThrows_ShouldDisposeEnumerator()
{
if (StreamingSerializer is null)
{
return;
}
using var stream = new Utf8MemoryStream();
var asyncEnumerable = new MockedAsyncEnumerable<IEnumerable<int>>(Enumerable.Repeat(ThrowingEnumerable(), 2));
await Assert.ThrowsAsync<DivideByZeroException>(async () => await JsonSerializerWrapperForStream.SerializeWrapper(stream, new { Data = asyncEnumerable }));
await Assert.ThrowsAsync<DivideByZeroException>(async () => await StreamingSerializer.SerializeWrapper(stream, new { Data = asyncEnumerable }));
Assert.Equal(1, asyncEnumerable.TotalCreatedEnumerators);
Assert.Equal(1, asyncEnumerable.TotalDisposedEnumerators);
......@@ -208,27 +243,42 @@ static IEnumerable<int> ThrowingEnumerable()
[Fact]
public async Task ReadRootLevelAsyncEnumerable()
{
if (StreamingSerializer is null)
{
return;
}
var utf8Stream = new Utf8MemoryStream("[0,1,2,3,4]");
IAsyncEnumerable<int> result = await JsonSerializer.DeserializeAsync<IAsyncEnumerable<int>>(utf8Stream);
IAsyncEnumerable<int> result = await StreamingSerializer.DeserializeWrapper<IAsyncEnumerable<int>>(utf8Stream);
Assert.Equal(new int[] { 0, 1, 2, 3, 4 }, await result.ToListAsync());
}
[Fact]
public async Task ReadNestedAsyncEnumerable()
{
if (StreamingSerializer is null)
{
return;
}
var utf8Stream = new Utf8MemoryStream(@"{ ""Data"" : [0,1,2,3,4] }");
var result = await JsonSerializer.DeserializeAsync<AsyncEnumerableDto<int>>(utf8Stream);
var result = await StreamingSerializer.DeserializeWrapper<AsyncEnumerableDto<int>>(utf8Stream);
Assert.Equal(new int[] { 0, 1, 2, 3, 4 }, await result.Data.ToListAsync());
}
[Fact]
public async Task ReadAsyncEnumerableOfAsyncEnumerables()
{
if (StreamingSerializer is null)
{
return;
}
var utf8Stream = new Utf8MemoryStream("[[0,1,2,3,4], []]");
var result = await JsonSerializer.DeserializeAsync<IAsyncEnumerable<IAsyncEnumerable<int>>>(utf8Stream);
var result = await StreamingSerializer.DeserializeWrapper<IAsyncEnumerable<IAsyncEnumerable<int>>>(utf8Stream);
var resultArray = await result.ToListAsync();
Assert.Equal(2, resultArray.Count);
......@@ -239,8 +289,13 @@ public async Task ReadAsyncEnumerableOfAsyncEnumerables()
[Fact]
public async Task ReadRootLevelAsyncEnumerableDerivative_ThrowsNotSupportedException()
{
if (StreamingSerializer is null)
{
return;
}
var utf8Stream = new Utf8MemoryStream("[0,1,2,3,4]");
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializer.DeserializeAsync<MockedAsyncEnumerable<int>>(utf8Stream));
await Assert.ThrowsAsync<NotSupportedException>(async () => await StreamingSerializer.DeserializeWrapper<MockedAsyncEnumerable<int>>(utf8Stream));
}
public static IEnumerable<object[]> GetAsyncEnumerableSources()
......@@ -253,12 +308,17 @@ public static IEnumerable<object[]> GetAsyncEnumerableSources()
yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 3, 100);
yield return WrapArgs(Enumerable.Range(0, 100).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 20, 100);
static object[] WrapArgs<TSource>(IEnumerable<TSource> source, int delayInterval, int bufferSize) => new object[]{ source, delayInterval, bufferSize };
static object[] WrapArgs<TSource>(IEnumerable<TSource> source, int delayInterval, int bufferSize) => new object[] { source, delayInterval, bufferSize };
}
[Fact]
public async Task RegressionTest_DisposingEnumeratorOnPendingMoveNextAsyncOperation()
{
if (StreamingSerializer is null)
{
return;
}
// Regression test for https://github.com/dotnet/runtime/issues/57360
using var stream = new Utf8MemoryStream();
using var cts = new CancellationTokenSource(millisecondsDelay: 1000);
......@@ -278,9 +338,14 @@ static async IAsyncEnumerable<int> GetNumbersAsync()
[Fact]
public async Task RegressionTest_ExceptionOnFirstMoveNextShouldNotFlushBuffer()
{
if (StreamingSerializer is null)
{
return;
}
// Regression test for https://github.com/dotnet/aspnetcore/issues/36977
using var stream = new MemoryStream();
await Assert.ThrowsAsync<NotImplementedException>(async () => await JsonSerializer.SerializeAsync(stream, new { Data = GetFailingAsyncEnumerable() }));
await Assert.ThrowsAsync<NotImplementedException>(async () => await StreamingSerializer.SerializeWrapper(stream, new { Data = GetFailingAsyncEnumerable() }));
Assert.Equal(0, stream.Length);
static async IAsyncEnumerable<int> GetFailingAsyncEnumerable()
......@@ -364,19 +429,6 @@ private async IAsyncEnumerator<TElement> GetAsyncEnumeratorInner(CancellationTok
public IEnumerator<TElement> GetEnumerator() => throw new InvalidOperationException("Collection should not be enumerated synchronously.");
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public class Utf8MemoryStream : MemoryStream
{
public Utf8MemoryStream() : base()
{
}
public Utf8MemoryStream(string text) : base(Encoding.UTF8.GetBytes(text))
{
}
public override string ToString () => Encoding.UTF8.GetString(ToArray());
}
}
#endif
}
......@@ -12,17 +12,17 @@ public abstract partial class CollectionTests
[Fact]
public async Task Read_ConcurrentCollection()
{
ConcurrentDictionary<string, string> cd = await JsonSerializerWrapperForString.DeserializeWrapper<ConcurrentDictionary<string, string>>(@"{""key"":""value""}");
ConcurrentDictionary<string, string> cd = await Serializer.DeserializeWrapper<ConcurrentDictionary<string, string>>(@"{""key"":""value""}");
Assert.Equal(1, cd.Count);
Assert.Equal("value", cd["key"]);
ConcurrentQueue<string> qc = await JsonSerializerWrapperForString.DeserializeWrapper<ConcurrentQueue<string>>(@"[""1""]");
ConcurrentQueue<string> qc = await Serializer.DeserializeWrapper<ConcurrentQueue<string>>(@"[""1""]");
Assert.Equal(1, qc.Count);
bool found = qc.TryPeek(out string val);
Assert.True(found);
Assert.Equal("1", val);
ConcurrentStack<string> qs = await JsonSerializerWrapperForString.DeserializeWrapper<ConcurrentStack<string>>(@"[""1""]");
ConcurrentStack<string> qs = await Serializer.DeserializeWrapper<ConcurrentStack<string>>(@"[""1""]");
Assert.Equal(1, qs.Count);
found = qs.TryPeek(out val);
Assert.True(found);
......@@ -34,7 +34,7 @@ public async Task Read_ConcurrentCollection()
[InlineData(typeof(ConcurrentBag<string>), @"[""1""]")] // Not supported. Not IList, and we don't detect the add method for this collection.
public async Task Read_ConcurrentCollection_Throws(Type type, string json)
{
NotSupportedException ex = await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper(json, type));
NotSupportedException ex = await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper(json, type));
Assert.Contains(type.ToString(), ex.Message);
}
......@@ -45,26 +45,26 @@ public async Task Read_ConcurrentCollection_Throws(Type type, string json)
[InlineData(typeof(GenericConcurrentStackInternalConstructor<string>), @"[""1""]")]
public async Task Read_ConcurrentCollection_NoPublicConstructor_Throws(Type type, string json)
{
NotSupportedException ex = await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper(json, type));
NotSupportedException ex = await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper(json, type));
Assert.Contains(type.ToString(), ex.Message);
}
[Fact]
public async Task Write_ConcurrentCollection()
{
Assert.Equal(@"[""1""]", await JsonSerializerWrapperForString.SerializeWrapper(new BlockingCollection<string> { "1" }));
Assert.Equal(@"[""1""]", await Serializer.SerializeWrapper(new BlockingCollection<string> { "1" }));
Assert.Equal(@"[""1""]", await JsonSerializerWrapperForString.SerializeWrapper(new ConcurrentBag<string> { "1" }));
Assert.Equal(@"[""1""]", await Serializer.SerializeWrapper(new ConcurrentBag<string> { "1" }));
Assert.Equal(@"{""key"":""value""}", await JsonSerializerWrapperForString.SerializeWrapper(new ConcurrentDictionary<string, string> { ["key"] = "value" }));
Assert.Equal(@"{""key"":""value""}", await Serializer.SerializeWrapper(new ConcurrentDictionary<string, string> { ["key"] = "value" }));
ConcurrentQueue<string> qc = new ConcurrentQueue<string>();
qc.Enqueue("1");
Assert.Equal(@"[""1""]", await JsonSerializerWrapperForString.SerializeWrapper(qc));
Assert.Equal(@"[""1""]", await Serializer.SerializeWrapper(qc));
ConcurrentStack<string> qs = new ConcurrentStack<string>();
qs.Push("1");
Assert.Equal(@"[""1""]", await JsonSerializerWrapperForString.SerializeWrapper(qs));
Assert.Equal(@"[""1""]", await Serializer.SerializeWrapper(qs));
}
}
}
......@@ -20,7 +20,7 @@ public async Task CamelCaseDeserialize()
const string JsonString = @"[{""Key1"":1,""Key2"":2},{""Key1"":3,""Key2"":4}]";
// Without key policy, deserialize keys as they are.
Dictionary<string, int>[] obj = await JsonSerializerWrapperForString.DeserializeWrapper<Dictionary<string, int>[]>(JsonString);
Dictionary<string, int>[] obj = await Serializer.DeserializeWrapper<Dictionary<string, int>[]>(JsonString);
Assert.Equal(2, obj.Length);
......@@ -33,7 +33,7 @@ public async Task CamelCaseDeserialize()
Assert.Equal(4, obj[1]["Key2"]);
// Ensure we ignore key policy and deserialize keys as they are.
obj = await JsonSerializerWrapperForString.DeserializeWrapper<Dictionary<string, int>[]>(JsonString, options);
obj = await Serializer.DeserializeWrapper<Dictionary<string, int>[]>(JsonString, options);
Assert.Equal(2, obj.Length);
......@@ -58,12 +58,12 @@ public async Task IgnoreKeyPolicyForExtensionData()
};
// Ensure we ignore key policy for extension data and deserialize keys as they are.
ClassWithExtensionData myClass = await JsonSerializerWrapperForString.DeserializeWrapper<ClassWithExtensionData>(@"{""Key1"":1, ""Key2"":2}", options);
ClassWithExtensionData myClass = await Serializer.DeserializeWrapper<ClassWithExtensionData>(@"{""Key1"":1, ""Key2"":2}", options);
Assert.Equal(1, (myClass.ExtensionData["Key1"]).GetInt32());
Assert.Equal(2, (myClass.ExtensionData["Key2"]).GetInt32());
// Ensure we ignore key policy for extension data and serialize keys as they are.
Assert.Equal(@"{""Key1"":1,""Key2"":2}", await JsonSerializerWrapperForString.SerializeWrapper(myClass, options));
Assert.Equal(@"{""Key1"":1,""Key2"":2}", await Serializer.SerializeWrapper(myClass, options));
}
public class ClassWithExtensionData
......@@ -90,11 +90,11 @@ public async Task CamelCaseSerialize()
const string JsonCamel = @"[{""key1"":1,""key2"":2},{""key1"":3,""key2"":4}]";
// Without key policy option, serialize keys as they are.
string json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj);
string json = await Serializer.SerializeWrapper<object>(obj);
Assert.Equal(Json, json);
// With key policy option, serialize keys with camel casing.
json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj, options);
json = await Serializer.SerializeWrapper<object>(obj, options);
Assert.Equal(JsonCamel, json);
}
......@@ -115,11 +115,11 @@ public async Task CamelCaseSerialize_Null_Values()
const string JsonCamel = @"[{""key1"":null,""key2"":null}]";
// Without key policy option, serialize keys as they are.
string json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj);
string json = await Serializer.SerializeWrapper<object>(obj);
Assert.Equal(Json, json);
// With key policy option, serialize keys with camel casing.
json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj, options);
json = await Serializer.SerializeWrapper<object>(obj, options);
Assert.Equal(JsonCamel, json);
}
......@@ -140,11 +140,11 @@ public async Task CamelCaseSerialize_Null_Nullable_Values()
const string JsonCamel = @"[{""key1"":null,""key2"":null}]";
// Without key policy option, serialize keys as they are.
string json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj);
string json = await Serializer.SerializeWrapper<object>(obj);
Assert.Equal(Json, json);
// With key policy option, serialize keys with camel casing.
json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj, options);
json = await Serializer.SerializeWrapper<object>(obj, options);
Assert.Equal(JsonCamel, json);
}
......@@ -158,11 +158,11 @@ public async Task CustomNameDeserialize()
// Without key policy, deserialize keys as they are.
Dictionary<string, int> obj = await JsonSerializerWrapperForString.DeserializeWrapper<Dictionary<string, int>>(@"{""myint"":1}");
Dictionary<string, int> obj = await Serializer.DeserializeWrapper<Dictionary<string, int>>(@"{""myint"":1}");
Assert.Equal(1, obj["myint"]);
// Ensure we ignore key policy and deserialize keys as they are.
obj = await JsonSerializerWrapperForString.DeserializeWrapper<Dictionary<string, int>>(@"{""myint"":1}", options);
obj = await Serializer.DeserializeWrapper<Dictionary<string, int>>(@"{""myint"":1}", options);
Assert.Equal(1, obj["myint"]);
}
......@@ -180,11 +180,11 @@ public async Task CustomNameSerialize()
const string JsonCustomKey = @"{""MYINT1"":1,""MYINT2"":2}";
// Without key policy option, serialize keys as they are.
string json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj);
string json = await Serializer.SerializeWrapper<object>(obj);
Assert.Equal(Json, json);
// With key policy option, serialize keys honoring the custom key policy.
json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj, options);
json = await Serializer.SerializeWrapper<object>(obj, options);
Assert.Equal(JsonCustomKey, json);
}
......@@ -292,10 +292,10 @@ public async Task NullNamePolicy()
};
// A naming policy that returns null is not allowed.
await Assert.ThrowsAsync<InvalidOperationException>(async () => await JsonSerializerWrapperForString.SerializeWrapper(new Dictionary<string, int> { { "onlyKey", 1 } }, options));
await Assert.ThrowsAsync<InvalidOperationException>(async () => await Serializer.SerializeWrapper(new Dictionary<string, int> { { "onlyKey", 1 } }, options));
// We don't use policy on deserialize, so we populate dictionary.
Dictionary<string, int> obj = await JsonSerializerWrapperForString.DeserializeWrapper<Dictionary<string, int>>(@"{""onlyKey"": 1}", options);
Dictionary<string, int> obj = await Serializer.DeserializeWrapper<Dictionary<string, int>>(@"{""onlyKey"": 1}", options);
Assert.Equal(1, obj.Count);
Assert.Equal(1, obj["onlyKey"]);
......@@ -315,11 +315,11 @@ public async Task CustomNameSerialize_NullableValue()
const string JsonCustomKey = @"{""MYINT1"":1,""MYINT2"":2}";
// Without key policy option, serialize keys as they are.
string json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj);
string json = await Serializer.SerializeWrapper<object>(obj);
Assert.Equal(Json, json);
// With key policy option, serialize keys honoring the custom key policy.
json = await JsonSerializerWrapperForString.SerializeWrapper<object>(obj, options);
json = await Serializer.SerializeWrapper<object>(obj, options);
Assert.Equal(JsonCustomKey, json);
}
......@@ -332,10 +332,10 @@ public async Task NullNamePolicy_NullableValue()
};
// A naming policy that returns null is not allowed.
await Assert.ThrowsAsync<InvalidOperationException>(async () => await JsonSerializerWrapperForString.SerializeWrapper(new Dictionary<string, int?> { { "onlyKey", 1 } }, options));
await Assert.ThrowsAsync<InvalidOperationException>(async () => await Serializer.SerializeWrapper(new Dictionary<string, int?> { { "onlyKey", 1 } }, options));
// We don't use policy on deserialize, so we populate dictionary.
Dictionary<string, int?> obj = await JsonSerializerWrapperForString.DeserializeWrapper<Dictionary<string, int?>>(@"{""onlyKey"": 1}", options);
Dictionary<string, int?> obj = await Serializer.DeserializeWrapper<Dictionary<string, int?>>(@"{""onlyKey"": 1}", options);
Assert.Equal(1, obj.Count);
Assert.Equal(1, obj["onlyKey"]);
......@@ -351,7 +351,7 @@ public async Task KeyConflict_Serialize_WriteAll()
// The camel case policy resolves two keys to the same output key.
Dictionary<string, int> obj = new Dictionary<string, int> { { "myInt", 1 }, { "MyInt", 2 } };
string json = await JsonSerializerWrapperForString.SerializeWrapper(obj, options);
string json = await Serializer.SerializeWrapper(obj, options);
// Check that we write all.
Assert.Equal(@"{""myInt"":1,""myInt"":2}", json);
......@@ -375,7 +375,7 @@ public async Task CamelCaseSerialize_ApplyDictionaryKeyPolicy()
};
obj["KeyList"] = new List<int>() { 1, 2, 3 };
var json = await JsonSerializerWrapperForString.SerializeWrapper(obj, new JsonSerializerOptions()
var json = await Serializer.SerializeWrapper(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});
......@@ -400,7 +400,7 @@ public async Task SerializationWithJsonExtensionDataAttribute_IgoneDictionaryKey
{ "KeyList", new List<string>() },
{ "KeyDictionary", new Dictionary<string, string>() }
};
string json = await JsonSerializerWrapperForString.SerializeWrapper(obj, new JsonSerializerOptions()
string json = await Serializer.SerializeWrapper(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});
......@@ -421,7 +421,7 @@ public async Task CamelCaseSerialize_ForTypedDictionary_ApplyDictionaryKeyPolicy
{
{ "KeyDict", CreateCustomObject() }
};
var json = await JsonSerializerWrapperForString.SerializeWrapper(obj, new JsonSerializerOptions()
var json = await Serializer.SerializeWrapper(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});
......@@ -454,7 +454,7 @@ public async Task CamelCaseSerialize_ForNestedTypedDictionary_ApplyDictionaryKey
{ "KeyDict", new Dictionary<string,CustomClass>()
{{ "NestedKeyDict", CreateCustomObject() }}
}};
var json = await JsonSerializerWrapperForString.SerializeWrapper(obj, new JsonSerializerOptions()
var json = await Serializer.SerializeWrapper(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});
......@@ -475,7 +475,7 @@ public async Task CamelCaseSerialize_ForClassWithDictionaryProperty_ApplyDiction
obj.Data = new Dictionary<string, CustomClass> {
{"KeyObj", CreateCustomObject() }
};
var json = await JsonSerializerWrapperForString.SerializeWrapper(obj, new JsonSerializerOptions()
var json = await Serializer.SerializeWrapper(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});
......@@ -497,7 +497,7 @@ public async Task CamelCaseSerialize_ForKeyValuePairWithDictionaryValue_ApplyDic
("KeyPair", new Dictionary<string, CustomClass> {
{"KeyDict", CreateCustomObject() }
});
var json = await JsonSerializerWrapperForString.SerializeWrapper(obj, new JsonSerializerOptions()
var json = await Serializer.SerializeWrapper(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});
......
......@@ -12,18 +12,18 @@ public abstract partial class CollectionTests
[Fact]
public async Task Read_ObjectModelCollection()
{
Collection<bool> c = await JsonSerializerWrapperForString.DeserializeWrapper<Collection<bool>>("[true,false]");
Collection<bool> c = await Serializer.DeserializeWrapper<Collection<bool>>("[true,false]");
Assert.Equal(2, c.Count);
Assert.True(c[0]);
Assert.False(c[1]);
// Regression test for https://github.com/dotnet/runtime/issues/30686.
ObservableCollection<bool> oc = await JsonSerializerWrapperForString.DeserializeWrapper<ObservableCollection<bool>>("[true,false]");
ObservableCollection<bool> oc = await Serializer.DeserializeWrapper<ObservableCollection<bool>>("[true,false]");
Assert.Equal(2, oc.Count);
Assert.True(oc[0]);
Assert.False(oc[1]);
SimpleKeyedCollection kc = await JsonSerializerWrapperForString.DeserializeWrapper<SimpleKeyedCollection>("[true]");
SimpleKeyedCollection kc = await Serializer.DeserializeWrapper<SimpleKeyedCollection>("[true]");
Assert.Equal(1, kc.Count);
Assert.True(kc[0]);
}
......@@ -32,14 +32,14 @@ public async Task Read_ObjectModelCollection()
public async Task Read_ObjectModelCollection_Throws()
{
// No default constructor.
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<ReadOnlyCollection<bool>>("[true,false]"));
await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper<ReadOnlyCollection<bool>>("[true,false]"));
// No default constructor.
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<ReadOnlyObservableCollection<bool>>("[true,false]"));
await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper<ReadOnlyObservableCollection<bool>>("[true,false]"));
// No default constructor.
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<ReadOnlyDictionary<string, bool>>(@"{""true"":false}"));
await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper<ReadOnlyDictionary<string, bool>>(@"{""true"":false}"));
// Abstract types can't be instantiated. This means there's no default constructor, so the type is not supported for deserialization.
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<KeyedCollection<string, bool>>("[true]"));
await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper<KeyedCollection<string, bool>>("[true]"));
}
public class SimpleKeyedCollection : KeyedCollection<string, bool>
......
......@@ -14,23 +14,23 @@ public abstract partial class CollectionTests
public async Task Write_ObjectModelCollection()
{
Collection<bool> c = new Collection<bool>() { true, false };
Assert.Equal("[true,false]", await JsonSerializerWrapperForString.SerializeWrapper(c));
Assert.Equal("[true,false]", await Serializer.SerializeWrapper(c));
ObservableCollection<bool> oc = new ObservableCollection<bool>() { true, false };
Assert.Equal("[true,false]", await JsonSerializerWrapperForString.SerializeWrapper(oc));
Assert.Equal("[true,false]", await Serializer.SerializeWrapper(oc));
SimpleKeyedCollection kc = new SimpleKeyedCollection() { true, false };
Assert.Equal("[true,false]", await JsonSerializerWrapperForString.SerializeWrapper(kc));
Assert.Equal("[true,false]", await JsonSerializerWrapperForString.SerializeWrapper<KeyedCollection<string, bool>>(kc));
Assert.Equal("[true,false]", await Serializer.SerializeWrapper(kc));
Assert.Equal("[true,false]", await Serializer.SerializeWrapper<KeyedCollection<string, bool>>(kc));
ReadOnlyCollection<bool> roc = new ReadOnlyCollection<bool>(new List<bool> { true, false });
Assert.Equal("[true,false]", await JsonSerializerWrapperForString.SerializeWrapper(roc));
Assert.Equal("[true,false]", await Serializer.SerializeWrapper(roc));
ReadOnlyObservableCollection<bool> rooc = new ReadOnlyObservableCollection<bool>(oc);
Assert.Equal("[true,false]", await JsonSerializerWrapperForString.SerializeWrapper(rooc));
Assert.Equal("[true,false]", await Serializer.SerializeWrapper(rooc));
ReadOnlyDictionary<string, bool> rod = new ReadOnlyDictionary<string, bool>(new Dictionary<string, bool> { ["true"] = false });
Assert.Equal(@"{""true"":false}", await JsonSerializerWrapperForString.SerializeWrapper(rod));
Assert.Equal(@"{""true"":false}", await Serializer.SerializeWrapper(rod));
}
}
}
......@@ -12,19 +12,19 @@ public abstract partial class CollectionTests
[Fact]
public async Task Read_SpecializedCollection()
{
BitVector32 bv32 = await JsonSerializerWrapperForString.DeserializeWrapper<BitVector32>(@"{""Data"":4}");
BitVector32 bv32 = await Serializer.DeserializeWrapper<BitVector32>(@"{""Data"":4}");
// Data property is skipped because it doesn't have a setter.
Assert.Equal(0, bv32.Data);
HybridDictionary hd = await JsonSerializerWrapperForString.DeserializeWrapper<HybridDictionary>(@"{""key"":""value""}");
HybridDictionary hd = await Serializer.DeserializeWrapper<HybridDictionary>(@"{""key"":""value""}");
Assert.Equal(1, hd.Count);
Assert.Equal("value", ((JsonElement)hd["key"]).GetString());
IOrderedDictionary iod = await JsonSerializerWrapperForString.DeserializeWrapper<OrderedDictionary>(@"{""key"":""value""}");
IOrderedDictionary iod = await Serializer.DeserializeWrapper<OrderedDictionary>(@"{""key"":""value""}");
Assert.Equal(1, iod.Count);
Assert.Equal("value", ((JsonElement)iod["key"]).GetString());
ListDictionary ld = await JsonSerializerWrapperForString.DeserializeWrapper<ListDictionary>(@"{""key"":""value""}");
ListDictionary ld = await Serializer.DeserializeWrapper<ListDictionary>(@"{""key"":""value""}");
Assert.Equal(1, ld.Count);
Assert.Equal("value", ((JsonElement)ld["key"]).GetString());
}
......@@ -34,19 +34,19 @@ public async Task Read_SpecializedCollection_Throws()
{
// Add method for this collection only accepts strings, even though it only implements IList which usually
// indicates that the element type is typeof(object).
await Assert.ThrowsAsync<InvalidCastException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<StringCollection>(@"[""1"", ""2""]"));
await Assert.ThrowsAsync<InvalidCastException>(async () => await Serializer.DeserializeWrapper<StringCollection>(@"[""1"", ""2""]"));
// Not supported. Not IList, and we don't detect the add method for this collection.
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<StringDictionary>(@"[{""Key"": ""key"",""Value"":""value""}]"));
await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper<StringDictionary>(@"[{""Key"": ""key"",""Value"":""value""}]"));
// Int key is not allowed.
await Assert.ThrowsAsync<JsonException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<HybridDictionary>(@"{1:""value""}"));
await Assert.ThrowsAsync<JsonException>(async () => await Serializer.DeserializeWrapper<HybridDictionary>(@"{1:""value""}"));
// Runtime type in this case is IOrderedDictionary (we don't replace with concrete type), which we can't instantiate.
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<IOrderedDictionary>(@"{""first"":""John"",""second"":""Jane"",""third"":""Jet""}"));
await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper<IOrderedDictionary>(@"{""first"":""John"",""second"":""Jane"",""third"":""Jet""}"));
// Not supported. Not IList, and we don't detect the add method for this collection.
await Assert.ThrowsAsync<NotSupportedException>(async () => await JsonSerializerWrapperForString.DeserializeWrapper<NameValueCollection>(@"[""NameValueCollection""]"));
await Assert.ThrowsAsync<NotSupportedException>(async () => await Serializer.DeserializeWrapper<NameValueCollection>(@"[""NameValueCollection""]"));
}
}
}
......@@ -5,7 +5,7 @@ namespace System.Text.Json.Serialization.Tests
{
public abstract partial class CollectionTests : SerializerTests
{
public CollectionTests(JsonSerializerWrapperForString stringSerializerWrapper, JsonSerializerWrapperForStream streamSerializerWrapper)
: base(stringSerializerWrapper, streamSerializerWrapper) { }
public CollectionTests(JsonSerializerWrapper stringSerializerWrapper)
: base(stringSerializerWrapper) { }
}
}
......@@ -3,8 +3,13 @@
namespace System.Text.Json.Serialization.Tests
{
public sealed partial class ExtensionDataTestsDynamic : ExtensionDataTests
public sealed partial class ExtensionDataTestsDynamic_String : ExtensionDataTests
{
public ExtensionDataTestsDynamic() : base(JsonSerializerWrapperForString.StringSerializer) { }
public ExtensionDataTestsDynamic_String() : base(JsonSerializerWrapper.StringSerializer) { }
}
public sealed partial class ExtensionDataTestsDynamic_AsyncStream : ExtensionDataTests
{
public ExtensionDataTestsDynamic_AsyncStream() : base(JsonSerializerWrapper.AsyncStreamSerializer) { }
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册