From 95e3dcc5ec4a8b5028a3fd6705d55f77d1e1cca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Fri, 10 Jul 2020 22:43:16 +0200 Subject: [PATCH] Rewrite System.Text.Json stream tests to be async friendly and enable on WASM (#38663) The tests dealing are using a (De)SerializationWrapper so the same code can be used both for String and Stream types. It does that by wrapping the async Stream serialization calls in `Task.Run().GetAwaiter().GetResult()` to turn them into sync calls. However that doesn't work on WebAssembly since we can't wait on tasks as there's only a single thread. To fix this inverse the wrapper so the synchronous String calls are turned into async and use normal awaits for the Stream calls. This allows the test suite to pass on WebAssembly: `Tests run: 8349, Errors: 0, Failures: 0, Skipped: 11. Time: 475.528706s` --- .../tests/JsonDocumentTests.cs | 89 ++--- .../tests/Serialization/CacheTests.cs | 28 +- .../ConstructorTests.AttributePresence.cs | 119 +++--- .../ConstructorTests.Cache.cs | 79 ++-- .../ConstructorTests.Exceptions.cs | 95 ++--- .../ConstructorTests.ParameterMatching.cs | 371 +++++++++--------- .../ConstructorTests.Stream.cs | 84 ++-- .../Serialization/DeserializationWrapper.cs | 36 +- .../tests/Serialization/InvalidTypeTests.cs | 29 +- .../tests/Serialization/PolymorphicTests.cs | 163 ++++---- .../ReferenceHandlerTests.Deserialize.cs | 6 +- .../Serialization/SerializationWrapper.cs | 60 ++- .../tests/Serialization/Stream.Collections.cs | 11 +- .../tests/Serialization/Stream.ReadTests.cs | 4 +- .../tests/Utf8JsonReaderTests.MultiSegment.cs | 6 + .../tests/Utf8JsonReaderTests.cs | 8 +- src/libraries/tests.proj | 2 - 17 files changed, 596 insertions(+), 594 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/JsonDocumentTests.cs b/src/libraries/System.Text.Json/tests/JsonDocumentTests.cs index 86f1bc373e4bc..6a940b0757c7b 100644 --- a/src/libraries/System.Text.Json/tests/JsonDocumentTests.cs +++ b/src/libraries/System.Text.Json/tests/JsonDocumentTests.cs @@ -231,77 +231,75 @@ private static string ReadJson400KB(JsonElement obj) // If the internals change such that one of these is exercising substantially different // code, then it should switch to the full variation set. [MemberData(nameof(TestCases))] - public static void ParseJson_MemoryBytes(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_MemoryBytes(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.Parse(bytes.AsMemory())); + bytes => Task.FromResult(JsonDocument.Parse(bytes.AsMemory()))); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_String(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_String(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, - str => JsonDocument.Parse(str), + str => Task.FromResult(JsonDocument.Parse(str)), null); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_SeekableStream(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_SeekableStream(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.Parse(new MemoryStream(bytes))); + bytes => Task.FromResult(JsonDocument.Parse(new MemoryStream(bytes)))); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_SeekableStream_Async(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_SeekableStream_Async(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.ParseAsync(new MemoryStream(bytes)).GetAwaiter().GetResult()); + bytes => JsonDocument.ParseAsync(new MemoryStream(bytes))); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_UnseekableStream(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_UnseekableStream(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.Parse( + bytes => JsonDocument.ParseAsync( new WrappedMemoryStream(canRead: true, canWrite: false, canSeek: false, bytes))); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_UnseekableStream_Async(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_UnseekableStream_Async(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.ParseAsync( - new WrappedMemoryStream(canRead: true, canWrite: false, canSeek: false, bytes)). - GetAwaiter().GetResult()); + bytes => JsonDocument.ParseAsync(new WrappedMemoryStream(canRead: true, canWrite: false, canSeek: false, bytes))); } @@ -361,53 +359,52 @@ public static async Task ParseJson_UnseekableStream_Small_Async() [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_SeekableStream_WithBOM(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_SeekableStream_WithBOM(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.Parse(new MemoryStream(Utf8Bom.Concat(bytes).ToArray()))); + bytes => Task.FromResult(JsonDocument.Parse(new MemoryStream(Utf8Bom.Concat(bytes).ToArray())))); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_SeekableStream_Async_WithBOM(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_SeekableStream_Async_WithBOM(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.ParseAsync(new MemoryStream(Utf8Bom.Concat(bytes).ToArray())).GetAwaiter().GetResult()); + bytes => JsonDocument.ParseAsync(new MemoryStream(Utf8Bom.Concat(bytes).ToArray()))); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_UnseekableStream_WithBOM(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_UnseekableStream_WithBOM(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.Parse( - new WrappedMemoryStream(canRead: true, canWrite: false, canSeek: false, Utf8Bom.Concat(bytes).ToArray()))); + bytes => Task.FromResult(JsonDocument.Parse( + new WrappedMemoryStream(canRead: true, canWrite: false, canSeek: false, Utf8Bom.Concat(bytes).ToArray())))); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_UnseekableStream_Async_WithBOM(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_UnseekableStream_Async_WithBOM(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, bytes => JsonDocument.ParseAsync( - new WrappedMemoryStream(canRead: true, canWrite: false, canSeek: false, Utf8Bom.Concat(bytes).ToArray())). - GetAwaiter().GetResult()); + new WrappedMemoryStream(canRead: true, canWrite: false, canSeek: false, Utf8Bom.Concat(bytes).ToArray()))); } [Fact] @@ -486,34 +483,34 @@ public static Task ParseJson_UnseekableStream_Async_BadBOM(string json) [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_SequenceBytes_Single(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_SequenceBytes_Single(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.Parse(new ReadOnlySequence(bytes))); + bytes => Task.FromResult(JsonDocument.Parse(new ReadOnlySequence(bytes)))); } [Theory] [MemberData(nameof(ReducedTestCases))] - public static void ParseJson_SequenceBytes_Multi(bool compactData, TestCaseType type, string jsonString) + public static async Task ParseJson_SequenceBytes_Multi(bool compactData, TestCaseType type, string jsonString) { - ParseJson( + await ParseJsonAsync( compactData, type, jsonString, null, - bytes => JsonDocument.Parse(JsonTestHelper.SegmentInto(bytes, 31))); + bytes => Task.FromResult(JsonDocument.Parse(JsonTestHelper.SegmentInto(bytes, 31)))); } - private static void ParseJson( + private static async Task ParseJsonAsync( bool compactData, TestCaseType type, string jsonString, - Func stringDocBuilder, - Func bytesDocBuilder) + Func> stringDocBuilder, + Func> bytesDocBuilder) { // One, but not both, must be null. if ((stringDocBuilder == null) == (bytesDocBuilder == null)) @@ -527,7 +524,7 @@ private static void ParseJson( byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonString); - using (JsonDocument doc = stringDocBuilder?.Invoke(jsonString) ?? bytesDocBuilder?.Invoke(dataUtf8)) + using (JsonDocument doc = await (stringDocBuilder?.Invoke(jsonString) ?? bytesDocBuilder?.Invoke(dataUtf8))) { Assert.NotNull(doc); @@ -3650,7 +3647,7 @@ private static string GetCompactJson(TestCaseType testCaseType, string jsonStrin } [Fact] - public static void VerifyMultiThreadedDispose() + public static async Task VerifyMultiThreadedDispose() { Action disposeAction = (object document) => ((JsonDocument)document).Dispose(); @@ -3669,7 +3666,7 @@ public static void VerifyMultiThreadedDispose() } } - Task.WaitAll(tasks); + await Task.WhenAll(tasks); // When ArrayPool gets corrupted, the Rent method might return an already rented array, which is incorrect. // So we will rent as many arrays as calls to JsonElement.Dispose and check they are unique. diff --git a/src/libraries/System.Text.Json/tests/Serialization/CacheTests.cs b/src/libraries/System.Text.Json/tests/Serialization/CacheTests.cs index f18274ba7d673..96df1bb8a224b 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CacheTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CacheTests.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; @@ -11,18 +11,18 @@ namespace System.Text.Json.Serialization.Tests public static class CacheTests { [Fact, OuterLoop] - public static void MultipleThreads_SameType_DifferentJson_Looping() + public static async Task MultipleThreads_SameType_DifferentJson_Looping() { const int Iterations = 100; for (int i = 0; i < Iterations; i++) { - MultipleThreads_SameType_DifferentJson(); + await MultipleThreads_SameType_DifferentJson(); } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public static void MultipleThreads_SameType_DifferentJson() + [Fact] + public static async Task MultipleThreads_SameType_DifferentJson() { // Use local options to avoid obtaining already cached metadata from the default options. var options = new JsonSerializerOptions(); @@ -69,22 +69,22 @@ void SerializeObject() tasks[i + 3] = Task.Run(() => SerializeObject()); }; - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } [Fact, OuterLoop] - public static void MultipleThreads_DifferentTypes_Looping() + public static async Task MultipleThreads_DifferentTypes_Looping() { const int Iterations = 100; for (int i = 0; i < Iterations; i++) { - MultipleThreads_DifferentTypes(); + await MultipleThreads_DifferentTypes(); } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public static void MultipleThreads_DifferentTypes() + [Fact] + public static async Task MultipleThreads_DifferentTypes() { // Use local options to avoid obtaining already cached metadata from the default options. var options = new JsonSerializerOptions(); @@ -121,7 +121,7 @@ void Test(int i) tasks[i + 1] = Task.Run(() => Test(TestClassCount - 2)); } - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } [Fact] @@ -164,9 +164,9 @@ public static void PropertyCacheWithMinInputsLast() // this options is not the default options instance the tests will not use previously cached metadata. private static JsonSerializerOptions s_options = new JsonSerializerOptions(); - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Theory] [MemberData(nameof(WriteSuccessCases))] - public static void MultipleTypes(ITestClass testObj) + public static async Task MultipleTypes(ITestClass testObj) { Type type = testObj.GetType(); @@ -199,7 +199,7 @@ void Deserialize() tasks[i + 1] = Task.Run(() => Serialize()); }; - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } public static IEnumerable WriteSuccessCases diff --git a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.AttributePresence.cs b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.AttributePresence.cs index eaa0ccc24bda7..6082035309e6f 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.AttributePresence.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.AttributePresence.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Threading.Tasks; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -8,152 +9,152 @@ namespace System.Text.Json.Serialization.Tests public abstract partial class ConstructorTests { [Fact] - public void NonPublicCtors_NotSupported() + public async Task NonPublicCtors_NotSupported() { - void RunTest() + async Task RunTestAsync() { - NotSupportedException ex = Assert.Throws(() => Serializer.Deserialize("{}")); + NotSupportedException ex = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{}")); Assert.Contains("JsonConstructorAttribute", ex.ToString()); } - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); } [Fact] - public void SinglePublicParameterizedCtor_SingleParameterlessCtor_NoAttribute_Supported_UseParameterlessCtor() + public async Task SinglePublicParameterizedCtor_SingleParameterlessCtor_NoAttribute_Supported_UseParameterlessCtor() { - var obj1 = Serializer.Deserialize(@"{""MyInt"":1,""MyString"":""1""}"); + var obj1 = await Serializer.DeserializeWrapper(@"{""MyInt"":1,""MyString"":""1""}"); Assert.Equal(@"{""MyInt"":0,""MyString"":null}", JsonSerializer.Serialize(obj1)); } [Fact] - public void MultiplePublicParameterizedCtors_SingleParameterlessCtor_NoAttribute_Supported_UseParameterlessCtor() + public async Task MultiplePublicParameterizedCtors_SingleParameterlessCtor_NoAttribute_Supported_UseParameterlessCtor() { - void RunTest() + async Task RunTestAsync() { - var obj1 = Serializer.Deserialize(@"{""MyInt"":1,""MyString"":""1""}"); + var obj1 = await Serializer.DeserializeWrapper(@"{""MyInt"":1,""MyString"":""1""}"); Assert.Equal(@"{""MyInt"":0,""MyString"":null}", JsonSerializer.Serialize(obj1)); } - RunTest(); - RunTest(); + await RunTestAsync(); + await RunTestAsync(); } [Fact] - public void SinglePublicParameterizedCtor_NoPublicParameterlessCtor_NoAttribute_Supported() + public async Task SinglePublicParameterizedCtor_NoPublicParameterlessCtor_NoAttribute_Supported() { - void RunTest() + async Task RunTestAsync() { - var obj1 = Serializer.Deserialize(@"{""MyInt"":1}"); + var obj1 = await Serializer.DeserializeWrapper(@"{""MyInt"":1}"); Assert.Equal(@"{""MyInt"":1}", JsonSerializer.Serialize(obj1)); } - RunTest(); - RunTest(); + await RunTestAsync(); + await RunTestAsync(); } [Fact] - public void SinglePublicParameterizedCtor_NoPublicParameterlessCtor_WithAttribute_Supported() + public async Task SinglePublicParameterizedCtor_NoPublicParameterlessCtor_WithAttribute_Supported() { - void RunTest() + async Task RunTestAsync() { - var obj1 = Serializer.Deserialize(@"{""MyInt"":1}"); + var obj1 = await Serializer.DeserializeWrapper(@"{""MyInt"":1}"); Assert.Equal(@"{""MyInt"":1}", JsonSerializer.Serialize(obj1)); } - RunTest(); - RunTest(); - RunTest(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); } [Fact] - public void Class_MultiplePublicParameterizedCtors_NoPublicParameterlessCtor_NoAttribute_NotSupported() + public Task Class_MultiplePublicParameterizedCtors_NoPublicParameterlessCtor_NoAttribute_NotSupported() { - Assert.Throws(() => Serializer.Deserialize(@"{""MyInt"":1,""MyString"":""1""}")); + return Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""MyInt"":1,""MyString"":""1""}")); } [Fact] - public void Struct_MultiplePublicParameterizedCtors_NoPublicParameterlessCtor_NoAttribute_Supported_UseParameterlessCtor() + public async Task Struct_MultiplePublicParameterizedCtors_NoPublicParameterlessCtor_NoAttribute_Supported_UseParameterlessCtor() { - var obj = Serializer.Deserialize(@"{""myInt"":1,""myString"":""1""}"); + var obj = await Serializer.DeserializeWrapper(@"{""myInt"":1,""myString"":""1""}"); Assert.Equal(0, obj.MyInt); Assert.Null(obj.MyString); Assert.Equal(@"{""MyInt"":0,""MyString"":null}", JsonSerializer.Serialize(obj)); } [Fact] - public void NoPublicParameterlessCtor_MultiplePublicParameterizedCtors_WithAttribute_Supported() + public async Task NoPublicParameterlessCtor_MultiplePublicParameterizedCtors_WithAttribute_Supported() { - var obj1 = Serializer.Deserialize(@"{""MyInt"":1,""MyString"":""1""}"); + var obj1 = await Serializer.DeserializeWrapper(@"{""MyInt"":1,""MyString"":""1""}"); Assert.Equal(1, obj1.MyInt); Assert.Null(obj1.MyString); Assert.Equal(@"{""MyInt"":1,""MyString"":null}", JsonSerializer.Serialize(obj1)); - var obj2 = Serializer.Deserialize(@"{""MyInt"":1,""MyString"":""1""}"); + var obj2 = await Serializer.DeserializeWrapper(@"{""MyInt"":1,""MyString"":""1""}"); Assert.Equal(1, obj2.MyInt); Assert.Equal("1", obj2.MyString); Assert.Equal(@"{""MyInt"":1,""MyString"":""1""}", JsonSerializer.Serialize(obj2)); } [Fact] - public void PublicParameterlessCtor_MultiplePublicParameterizedCtors_WithAttribute_Supported() + public async Task PublicParameterlessCtor_MultiplePublicParameterizedCtors_WithAttribute_Supported() { - var obj = Serializer.Deserialize(@"{""MyInt"":1,""MyString"":""1""}"); + var obj = await Serializer.DeserializeWrapper(@"{""MyInt"":1,""MyString"":""1""}"); Assert.Equal(1, obj.MyInt); Assert.Null(obj.MyString); Assert.Equal(@"{""MyInt"":1,""MyString"":null}", JsonSerializer.Serialize(obj)); } [Fact] - public void MultipleAttributes_NotSupported() + public async Task MultipleAttributes_NotSupported() { - void RunTest() + async Task RunTestAsync() { - Assert.Throws(() => Serializer.Deserialize("{}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{}")); } - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); - RunTest(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); } [Fact] - public void AttributeIgnoredOnIEnumerable() + public async Task AttributeIgnoredOnIEnumerable() { - void RunTest() + async Task RunTestAsync() { - Assert.Throws(() => Serializer.Deserialize("[]")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("[]")); } - RunTest(); - RunTest(); + await RunTestAsync(); + await RunTestAsync(); } [Fact] - public void Struct_Use_DefaultCtor_ByDefault() + public async Task Struct_Use_DefaultCtor_ByDefault() { string json = @"{""X"":1,""Y"":2}"; // By default, serializer uses default ctor to deserializer structs - var point1 = Serializer.Deserialize(json); + var point1 = await Serializer.DeserializeWrapper(json); Assert.Equal(0, point1.X); Assert.Equal(0, point1.Y); - var point2 = Serializer.Deserialize(json); + var point2 = await Serializer.DeserializeWrapper(json); Assert.Equal(1, point2.X); Assert.Equal(2, point2.Y); } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Cache.cs b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Cache.cs index b37759f90d51f..369bc776a46cd 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Cache.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Cache.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Reflection; @@ -9,46 +9,47 @@ namespace System.Text.Json.Serialization.Tests { public abstract partial class ConstructorTests { - [Fact, OuterLoop] - public void MultipleThreadsLooping() + [Fact] + [OuterLoop] + public async Task MultipleThreadsLooping() { const int Iterations = 100; for (int i = 0; i < Iterations; i++) { - MultipleThreads(); + await MultipleThreads(); } } [Fact] - public void MultipleThreads() + public async Task MultipleThreads() { // Verify the test class has >32 properties since that is a threshold for using the fallback dictionary. Assert.True(typeof(ClassWithConstructor_SimpleAndComplexParameters).GetProperties(BindingFlags.Instance | BindingFlags.Public).Length > 32); - void DeserializeObject(string json, Type type, JsonSerializerOptions options) + async Task DeserializeObjectAsync(string json, Type type, JsonSerializerOptions options) { - var obj = Serializer.Deserialize(json, type, options); + var obj = await Serializer.DeserializeWrapper(json, type, options); ((ITestClassWithParameterizedCtor)obj).Verify(); } - void DeserializeObjectMinimal(Type type, JsonSerializerOptions options) + async Task DeserializeObjectMinimalAsync(Type type, JsonSerializerOptions options) { string json = (string)type.GetProperty("s_json_minimal").GetValue(null); - var obj = Serializer.Deserialize(json, type, options); + var obj = await Serializer.DeserializeWrapper(json, type, options); ((ITestClassWithParameterizedCtor)obj).VerifyMinimal(); }; - void DeserializeObjectFlipped(Type type, JsonSerializerOptions options) + async Task DeserializeObjectFlippedAsync(Type type, JsonSerializerOptions options) { string json = (string)type.GetProperty("s_json_flipped").GetValue(null); - DeserializeObject(json, type, options); + await DeserializeObjectAsync(json, type, options); }; - void DeserializeObjectNormal(Type type, JsonSerializerOptions options) + async Task DeserializeObjectNormalAsync(Type type, JsonSerializerOptions options) { string json = (string)type.GetProperty("s_json").GetValue(null); - DeserializeObject(json, type, options); + await DeserializeObjectAsync(json, type, options); }; void SerializeObject(Type type, JsonSerializerOptions options) @@ -57,7 +58,7 @@ void SerializeObject(Type type, JsonSerializerOptions options) JsonSerializer.Serialize(obj, options); }; - void RunTest(Type type) + async Task RunTestAsync(Type type) { // Use local options to avoid obtaining already cached metadata from the default options. var options = new JsonSerializerOptions(); @@ -69,41 +70,41 @@ void RunTest(Type type) for (int i = 0; i < tasks.Length; i += ConcurrentTestsCount) { // Create race condition to populate the sorted property cache with different json ordering. - tasks[i + 0] = Task.Run(() => DeserializeObjectMinimal(type, options)); - tasks[i + 1] = Task.Run(() => DeserializeObjectFlipped(type, options)); - tasks[i + 2] = Task.Run(() => DeserializeObjectNormal(type, options)); + tasks[i + 0] = Task.Run(() => DeserializeObjectMinimalAsync(type, options)); + tasks[i + 1] = Task.Run(() => DeserializeObjectFlippedAsync(type, options)); + tasks[i + 2] = Task.Run(() => DeserializeObjectNormalAsync(type, options)); // Ensure no exceptions on serialization tasks[i + 3] = Task.Run(() => SerializeObject(type, options)); }; - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } - RunTest(typeof(ClassWithConstructor_SimpleAndComplexParameters)); - RunTest(typeof(Person_Class)); - RunTest(typeof(Parameterized_Class_With_ComplexTuple)); + await RunTestAsync(typeof(ClassWithConstructor_SimpleAndComplexParameters)); + await RunTestAsync(typeof(Person_Class)); + await RunTestAsync(typeof(Parameterized_Class_With_ComplexTuple)); } [Fact] - public void PropertyCacheWithMinInputsFirst() + public async Task PropertyCacheWithMinInputsFirst() { // Use local options to avoid obtaining already cached metadata from the default options. var options = new JsonSerializerOptions(); string json = "{}"; - Serializer.Deserialize(json, options); + await Serializer.DeserializeWrapper(json, options); ClassWithConstructor_SimpleAndComplexParameters testObj = ClassWithConstructor_SimpleAndComplexParameters.GetInstance(); testObj.Verify(); json = JsonSerializer.Serialize(testObj, options); - testObj = Serializer.Deserialize(json, options); + testObj = await Serializer.DeserializeWrapper(json, options); testObj.Verify(); } [Fact] - public void PropertyCacheWithMinInputsLast() + public async Task PropertyCacheWithMinInputsLast() { // Use local options to avoid obtaining already cached metadata from the default options. var options = new JsonSerializerOptions(); @@ -112,11 +113,11 @@ public void PropertyCacheWithMinInputsLast() testObj.Verify(); string json = JsonSerializer.Serialize(testObj, options); - testObj = Serializer.Deserialize(json, options); + testObj = await Serializer.DeserializeWrapper(json, options); testObj.Verify(); json = "{}"; - Serializer.Deserialize(json, options); + await Serializer.DeserializeWrapper(json, options); } // Use a common options instance to encourage additional metadata collisions across types. Also since @@ -124,7 +125,7 @@ public void PropertyCacheWithMinInputsLast() private JsonSerializerOptions s_options = new JsonSerializerOptions(); [Fact] - public void MultipleTypes() + public async Task MultipleTypes() { void Serialize(object[] args) { @@ -136,15 +137,15 @@ void Serialize(object[] args) string json = JsonSerializer.Serialize(localTestObj, s_options); }; - void Deserialize(string json) + async Task DeserializeAsync(string json) { - ITestClass obj = (ITestClass)Serializer.Deserialize(json, s_options); + ITestClass obj = (ITestClass)await Serializer.DeserializeWrapper(json, s_options); obj.Verify(); }; - void RunTest(T testObj, object[] args) + async Task RunTestAsync(T testObj, object[] args) { - // Get the test json with the default options to avoid cache pollution of Deserialize() below. + // Get the test json with the default options to avoid cache pollution of DeserializeAsync() below. ((ITestClass)testObj).Initialize(); ((ITestClass)testObj).Verify(); string json = JsonSerializer.Serialize(testObj); @@ -155,20 +156,20 @@ void RunTest(T testObj, object[] args) for (int i = 0; i < tasks.Length; i += ConcurrentTestsCount) { - tasks[i + 0] = Task.Run(() => Deserialize(json)); + tasks[i + 0] = Task.Run(() => DeserializeAsync(json)); tasks[i + 1] = Task.Run(() => Serialize(args)); }; - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } - RunTest(new Point_2D(1, 2), new object[] { 1, 2 }); - RunTest(new Point_3D(1, 2, 3), new object[] { 1, 2, 3 }); - RunTest(new Point_2D_With_ExtData(1, 2), new object[] { 1, 2 }); + await RunTestAsync(new Point_2D(1, 2), new object[] { 1, 2 }); + await RunTestAsync(new Point_3D(1, 2, 3), new object[] { 1, 2, 3 }); + await RunTestAsync(new Point_2D_With_ExtData(1, 2), new object[] { 1, 2 }); Guid id = Guid.Parse("270bb22b-4816-4bd9-9acd-8ec5b1a896d3"); - RunTest(new Parameterized_Person_Simple(id), new object[] { id }); - RunTest(new Point_MembersHave_JsonPropertyName(1, 2), new object[] { 1, 2 }); + await RunTestAsync(new Parameterized_Person_Simple(id), new object[] { id }); + await RunTestAsync(new Point_MembersHave_JsonPropertyName(1, 2), new object[] { 1, 2 }); } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Exceptions.cs b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Exceptions.cs index 0b398f3b0b05c..9f1a85e618f22 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Exceptions.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Exceptions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Threading.Tasks; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -9,10 +10,10 @@ namespace System.Text.Json.Serialization.Tests public abstract partial class ConstructorTests { [Fact] - public void MultipleProperties_Cannot_BindTo_TheSame_ConstructorParameter() + public async Task MultipleProperties_Cannot_BindTo_TheSame_ConstructorParameter() { - InvalidOperationException ex = Assert.Throws( - () => Serializer.Deserialize("{}")); + InvalidOperationException ex = await Assert.ThrowsAsync( + () => Serializer.DeserializeWrapper("{}")); string exStr = ex.ToString(); Assert.Contains("'X'", exStr); @@ -20,8 +21,8 @@ public void MultipleProperties_Cannot_BindTo_TheSame_ConstructorParameter() Assert.Contains("(Int32, Int32)", exStr); Assert.Contains("System.Text.Json.Serialization.Tests.Point_MultipleMembers_BindTo_OneConstructorParameter", exStr); - ex = Assert.Throws( - () => Serializer.Deserialize("{}")); + ex = await Assert.ThrowsAsync( + () => Serializer.DeserializeWrapper("{}")); exStr = ex.ToString(); Assert.Contains("'X'", exStr); @@ -31,35 +32,35 @@ public void MultipleProperties_Cannot_BindTo_TheSame_ConstructorParameter() } [Fact] - public void All_ConstructorParameters_MustBindTo_ObjectMembers() + public async Task All_ConstructorParameters_MustBindTo_ObjectMembers() { - InvalidOperationException ex = Assert.Throws( - () => Serializer.Deserialize("{}")); + InvalidOperationException ex = await Assert.ThrowsAsync( + () => Serializer.DeserializeWrapper("{}")); string exStr = ex.ToString(); Assert.Contains("(Int32, Int32)", exStr); Assert.Contains("System.Text.Json.Serialization.Tests.Point_Without_Members", exStr); - ex = Assert.Throws( - () => Serializer.Deserialize("{}")); + ex = await Assert.ThrowsAsync( + () => Serializer.DeserializeWrapper("{}")); exStr = ex.ToString(); Assert.Contains("(Int32, Int32)", exStr); Assert.Contains("System.Text.Json.Serialization.Tests.Point_With_MismatchedMembers", exStr); - ex = Assert.Throws( - () => Serializer.Deserialize(@"{""MyInt"":1,""MyPoint"":{}}")); + ex = await Assert.ThrowsAsync( + () => Serializer.DeserializeWrapper(@"{""MyInt"":1,""MyPoint"":{}}")); exStr = ex.ToString(); Assert.Contains("(Int32, Int32)", exStr); Assert.Contains("System.Text.Json.Serialization.Tests.Point_With_MismatchedMembers", exStr); } [Fact] - public void LeadingReferenceMetadataNotSupported() + public async Task LeadingReferenceMetadataNotSupported() { string json = @"{""$id"":""1"",""Name"":""Jet"",""Manager"":{""$ref"":""1""}}"; // Metadata ignored by default. - var employee = Serializer.Deserialize(json); + var employee = await Serializer.DeserializeWrapper(json); Assert.Equal("Jet", employee.Name); Assert.Null(employee.Manager.Name); ; @@ -69,8 +70,8 @@ public void LeadingReferenceMetadataNotSupported() var options = new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.Preserve }; - NotSupportedException ex = Assert.Throws( - () => Serializer.Deserialize(json, options)); + NotSupportedException ex = await Assert.ThrowsAsync( + () => Serializer.DeserializeWrapper(json, options)); string exStr = ex.ToString(); Assert.Contains("System.Text.Json.Serialization.Tests.ConstructorTests+Employee", exStr); @@ -89,7 +90,7 @@ public Employee(string name) } [Fact] - public void RandomReferenceMetadataNotSupported() + public async Task RandomReferenceMetadataNotSupported() { string json = @"{""Name"":""Jet"",""$random"":10}"; @@ -103,16 +104,16 @@ public void RandomReferenceMetadataNotSupported() var options = new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.Preserve }; - NotSupportedException ex = Assert.Throws(() => Serializer.Deserialize(json, options)); + NotSupportedException ex = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(json, options)); string exStr = ex.ToString(); Assert.Contains("System.Text.Json.Serialization.Tests.ConstructorTests+Employee", exStr); Assert.Contains("$.$random", exStr); } [Fact] - public void ExtensionDataProperty_CannotBindTo_CtorParam() + public async Task ExtensionDataProperty_CannotBindTo_CtorParam() { - InvalidOperationException ex = Assert.Throws(() => Serializer.Deserialize("{}")); + InvalidOperationException ex = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{}")); string exStr = ex.ToString(); Assert.Contains("System.Collections.Generic.Dictionary`2[System.String,System.Text.Json.JsonElement] ExtensionData", exStr); Assert.Contains("System.Text.Json.Serialization.Tests.ConstructorTests+Class_ExtData_CtorParam", exStr); @@ -142,7 +143,7 @@ public void AnonymousObject_InvalidOperationException() } [Fact] - public void DeserializePathForObjectFails() + public async Task DeserializePathForObjectFails() { const string GoodJson = "{\"Property\u04671\":1}"; const string GoodJsonEscaped = "{\"Property\\u04671\":1}"; @@ -153,19 +154,19 @@ public void DeserializePathForObjectFails() ClassWithUnicodePropertyName obj; // Baseline. - obj = Serializer.Deserialize(GoodJson); + obj = await Serializer.DeserializeWrapper(GoodJson); Assert.Equal(1, obj.Property\u04671); - obj = Serializer.Deserialize(GoodJsonEscaped); + obj = await Serializer.DeserializeWrapper(GoodJsonEscaped); Assert.Equal(1, obj.Property\u04671); JsonException e; // Exception. - e = Assert.Throws(() => Serializer.Deserialize(BadJson)); + e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(BadJson)); Assert.Equal(Expected, e.Path); - e = Assert.Throws(() => Serializer.Deserialize(BadJsonEscaped)); + e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(BadJsonEscaped)); Assert.Equal(Expected, e.Path); } @@ -180,9 +181,9 @@ public ClassWithUnicodePropertyName(int property\u04671) } [Fact] - public void PathForChildPropertyFails() + public async Task PathForChildPropertyFails() { - JsonException e = Assert.Throws(() => Serializer.Deserialize(@"{""Child"":{""MyInt"":bad]}")); + JsonException e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Child"":{""MyInt"":bad]}")); Assert.Equal("$.Child.MyInt", e.Path); } @@ -205,37 +206,37 @@ public class ChildClass } [Fact] - public void PathForChildListFails() + public async Task PathForChildListFails() { - JsonException e = Assert.Throws(() => Serializer.Deserialize(@"{""Child"":{""MyIntArray"":[1, bad]}")); + JsonException e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Child"":{""MyIntArray"":[1, bad]}")); Assert.Contains("$.Child.MyIntArray", e.Path); } [Fact] - public void PathForChildDictionaryFails() + public async Task PathForChildDictionaryFails() { - JsonException e = Assert.Throws(() => Serializer.Deserialize(@"{""Child"":{""MyDictionary"":{""Key"": bad]")); + JsonException e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Child"":{""MyDictionary"":{""Key"": bad]")); Assert.Equal("$.Child.MyDictionary.Key", e.Path); } [Fact] - public void PathForSpecialCharacterFails() + public async Task PathForSpecialCharacterFails() { - JsonException e = Assert.Throws(() => Serializer.Deserialize(@"{""Child"":{""MyDictionary"":{""Key1"":{""Children"":[{""MyDictionary"":{""K.e.y"":""")); + JsonException e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Child"":{""MyDictionary"":{""Key1"":{""Children"":[{""MyDictionary"":{""K.e.y"":""")); Assert.Equal("$.Child.MyDictionary.Key1.Children[0].MyDictionary['K.e.y']", e.Path); } [Fact] - public void PathForSpecialCharacterNestedFails() + public async Task PathForSpecialCharacterNestedFails() { - JsonException e = Assert.Throws(() => Serializer.Deserialize(@"{""Child"":{""Children"":[{}, {""MyDictionary"":{""K.e.y"": {""MyInt"":bad")); + JsonException e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Child"":{""Children"":[{}, {""MyDictionary"":{""K.e.y"": {""MyInt"":bad")); Assert.Equal("$.Child.Children[1].MyDictionary['K.e.y'].MyInt", e.Path); } [Fact] - public void EscapingFails() + public async Task EscapingFails() { - JsonException e = Assert.Throws(() => Serializer.Deserialize("{\"A\u0467\":bad}")); + JsonException e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{\"A\u0467\":bad}")); Assert.Equal("$.A\u0467", e.Path); } @@ -251,9 +252,9 @@ public Parameterized_ClassWithUnicodeProperty(int a\u0467) [Fact] [ActiveIssue("JsonElement needs to support Path")] - public void ExtensionPropertyRoundTripFails() + public async Task ExtensionPropertyRoundTripFails() { - JsonException e = Assert.Throws(() => Serializer.Deserialize(@"{""MyNestedClass"":{""UnknownProperty"":bad}}")); + JsonException e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""MyNestedClass"":{""UnknownProperty"":bad}}")); Assert.Equal("$.MyNestedClass.UnknownProperty", e.Path); } @@ -273,43 +274,43 @@ public Parameterized_ClassWithExtensionProperty(SimpleTestClass myNestedClass, i } [Fact] - public void CaseInsensitiveFails() + public async Task CaseInsensitiveFails() { var options = new JsonSerializerOptions(); options.PropertyNameCaseInsensitive = true; // Baseline (no exception) { - var obj = Serializer.Deserialize(@"{""mydecimal"":1}", options); + var obj = await Serializer.DeserializeWrapper(@"{""mydecimal"":1}", options); Assert.Equal(1, obj.MyDecimal); } { - var obj = Serializer.Deserialize(@"{""MYDECIMAL"":1}", options); + var obj = await Serializer.DeserializeWrapper(@"{""MYDECIMAL"":1}", options); Assert.Equal(1, obj.MyDecimal); } JsonException e; - e = Assert.Throws(() => Serializer.Deserialize(@"{""mydecimal"":bad}", options)); + e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""mydecimal"":bad}", options)); Assert.Equal("$.mydecimal", e.Path); - e = Assert.Throws(() => Serializer.Deserialize(@"{""MYDECIMAL"":bad}", options)); + e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""MYDECIMAL"":bad}", options)); Assert.Equal("$.MYDECIMAL", e.Path); } [Fact] - public void ClassWithUnsupportedCollectionTypes() + public async Task ClassWithUnsupportedCollectionTypes() { Exception e; - e = Assert.Throws(() => Serializer.Deserialize(@"{""UnsupportedArray"":[]}")); + e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""UnsupportedArray"":[]}")); Assert.Contains("System.Int32[,]", e.ToString()); // The exception for element types do not contain the parent type and the property name // since the verification occurs later and is no longer bound to the parent type. Assert.DoesNotContain("ClassWithInvalidArray.UnsupportedArray", e.ToString()); - e = Assert.Throws(() => Serializer.Deserialize(@"{""UnsupportedDictionary"":{}}")); + e = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""UnsupportedDictionary"":{}}")); Assert.Contains("System.Int32[,]", e.ToString()); Assert.DoesNotContain("ClassWithInvalidDictionary.UnsupportedDictionary", e.ToString()); } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs index 1b7fb7c5e920e..7cf574598d7e3 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs @@ -1,8 +1,9 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Collections.Specialized; +using System.Threading.Tasks; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -27,191 +28,191 @@ public ConstructorTests(DeserializationWrapper serializer) } [Fact] - public void ReturnNullForNullObjects() + public async Task ReturnNullForNullObjects() { - Assert.Null(Serializer.Deserialize("null")); - Assert.Null(Serializer.Deserialize("null")); + Assert.Null(await Serializer.DeserializeWrapper("null")); + Assert.Null(await Serializer.DeserializeWrapper("null")); } [Fact] - public void JsonExceptionWhenAssigningNullToStruct() + public Task JsonExceptionWhenAssigningNullToStruct() { - Assert.Throws(() => Serializer.Deserialize("null")); + return Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("null")); } [Fact] - public void MatchJsonPropertyToConstructorParameters() + public async Task MatchJsonPropertyToConstructorParameters() { - Point_2D point = Serializer.Deserialize(@"{""X"":1,""Y"":2}"); + Point_2D point = await Serializer.DeserializeWrapper(@"{""X"":1,""Y"":2}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); - point = Serializer.Deserialize(@"{""Y"":2,""X"":1}"); + point = await Serializer.DeserializeWrapper(@"{""Y"":2,""X"":1}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); } [Fact] - public void UseDefaultValues_When_NoJsonMatch() + public async Task UseDefaultValues_When_NoJsonMatch() { // Using CLR value when `ParameterInfo.DefaultValue` is not set. - Point_2D point = Serializer.Deserialize(@"{""x"":1,""y"":2}"); + Point_2D point = await Serializer.DeserializeWrapper(@"{""x"":1,""y"":2}"); Assert.Equal(0, point.X); Assert.Equal(0, point.Y); - point = Serializer.Deserialize(@"{""y"":2,""x"":1}"); + point = await Serializer.DeserializeWrapper(@"{""y"":2,""x"":1}"); Assert.Equal(0, point.X); Assert.Equal(0, point.Y); - point = Serializer.Deserialize(@"{""x"":1,""Y"":2}"); + point = await Serializer.DeserializeWrapper(@"{""x"":1,""Y"":2}"); Assert.Equal(0, point.X); Assert.Equal(2, point.Y); - point = Serializer.Deserialize(@"{""y"":2,""X"":1}"); + point = await Serializer.DeserializeWrapper(@"{""y"":2,""X"":1}"); Assert.Equal(1, point.X); Assert.Equal(0, point.Y); - point = Serializer.Deserialize(@"{""X"":1}"); + point = await Serializer.DeserializeWrapper(@"{""X"":1}"); Assert.Equal(1, point.X); Assert.Equal(0, point.Y); - point = Serializer.Deserialize(@"{""Y"":2}"); + point = await Serializer.DeserializeWrapper(@"{""Y"":2}"); Assert.Equal(0, point.X); Assert.Equal(2, point.Y); - point = Serializer.Deserialize(@"{""X"":1}"); + point = await Serializer.DeserializeWrapper(@"{""X"":1}"); Assert.Equal(1, point.X); Assert.Equal(0, point.Y); - point = Serializer.Deserialize(@"{""Y"":2}"); + point = await Serializer.DeserializeWrapper(@"{""Y"":2}"); Assert.Equal(0, point.X); Assert.Equal(2, point.Y); - point = Serializer.Deserialize(@"{}"); + point = await Serializer.DeserializeWrapper(@"{}"); Assert.Equal(0, point.X); Assert.Equal(0, point.Y); - point = Serializer.Deserialize(@"{""a"":1,""b"":2}"); + point = await Serializer.DeserializeWrapper(@"{""a"":1,""b"":2}"); Assert.Equal(0, point.X); Assert.Equal(0, point.Y); // Using `ParameterInfo.DefaultValue` when set; using CLR value as fallback. - Point_3D point3d = Serializer.Deserialize(@"{""X"":1}"); + Point_3D point3d = await Serializer.DeserializeWrapper(@"{""X"":1}"); Assert.Equal(1, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(50, point3d.Z); - point3d = Serializer.Deserialize(@"{""y"":2}"); + point3d = await Serializer.DeserializeWrapper(@"{""y"":2}"); Assert.Equal(0, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(50, point3d.Z); - point3d = Serializer.Deserialize(@"{""Z"":3}"); + point3d = await Serializer.DeserializeWrapper(@"{""Z"":3}"); Assert.Equal(0, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(3, point3d.Z); - point3d = Serializer.Deserialize(@"{""X"":1}"); + point3d = await Serializer.DeserializeWrapper(@"{""X"":1}"); Assert.Equal(1, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(50, point3d.Z); - point3d = Serializer.Deserialize(@"{""Y"":2}"); + point3d = await Serializer.DeserializeWrapper(@"{""Y"":2}"); Assert.Equal(0, point3d.X); Assert.Equal(2, point3d.Y); Assert.Equal(50, point3d.Z); - point3d = Serializer.Deserialize(@"{""Z"":3}"); + point3d = await Serializer.DeserializeWrapper(@"{""Z"":3}"); Assert.Equal(0, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(3, point3d.Z); - point3d = Serializer.Deserialize(@"{""x"":1,""Y"":2}"); + point3d = await Serializer.DeserializeWrapper(@"{""x"":1,""Y"":2}"); Assert.Equal(0, point3d.X); Assert.Equal(2, point3d.Y); Assert.Equal(50, point3d.Z); - point3d = Serializer.Deserialize(@"{""Z"":3,""y"":2}"); + point3d = await Serializer.DeserializeWrapper(@"{""Z"":3,""y"":2}"); Assert.Equal(0, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(3, point3d.Z); - point3d = Serializer.Deserialize(@"{""x"":1,""Z"":3}"); + point3d = await Serializer.DeserializeWrapper(@"{""x"":1,""Z"":3}"); Assert.Equal(0, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(3, point3d.Z); - point3d = Serializer.Deserialize(@"{}"); + point3d = await Serializer.DeserializeWrapper(@"{}"); Assert.Equal(0, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(50, point3d.Z); - point3d = Serializer.Deserialize(@"{""a"":1,""b"":2}"); + point3d = await Serializer.DeserializeWrapper(@"{""a"":1,""b"":2}"); Assert.Equal(0, point3d.X); Assert.Equal(0, point3d.Y); Assert.Equal(50, point3d.Z); } [Fact] - public void CaseInsensitivityWorks() + public async Task CaseInsensitivityWorks() { var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; - Point_2D point = Serializer.Deserialize(@"{""x"":1,""y"":2}", options); + Point_2D point = await Serializer.DeserializeWrapper(@"{""x"":1,""y"":2}", options); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); - point = Serializer.Deserialize(@"{""y"":2,""x"":1}", options); + point = await Serializer.DeserializeWrapper(@"{""y"":2,""x"":1}", options); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); - point = Serializer.Deserialize(@"{""x"":1,""Y"":2}", options); + point = await Serializer.DeserializeWrapper(@"{""x"":1,""Y"":2}", options); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); - point = Serializer.Deserialize(@"{""y"":2,""X"":1}", options); + point = await Serializer.DeserializeWrapper(@"{""y"":2,""X"":1}", options); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); } [Fact] - public void VaryingOrderingOfJson() + public async Task VaryingOrderingOfJson() { - Point_3D point = Serializer.Deserialize(@"{""X"":1,""Y"":2,""Z"":3}"); + Point_3D point = await Serializer.DeserializeWrapper(@"{""X"":1,""Y"":2,""Z"":3}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); Assert.Equal(3, point.Z); - point = Serializer.Deserialize(@"{""X"":1,""Z"":3,""Y"":2}"); + point = await Serializer.DeserializeWrapper(@"{""X"":1,""Z"":3,""Y"":2}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); Assert.Equal(3, point.Z); - point = Serializer.Deserialize(@"{""Y"":2,""Z"":3,""X"":1}"); + point = await Serializer.DeserializeWrapper(@"{""Y"":2,""Z"":3,""X"":1}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); Assert.Equal(3, point.Z); - point = Serializer.Deserialize(@"{""Y"":2,""X"":1,""Z"":3}"); + point = await Serializer.DeserializeWrapper(@"{""Y"":2,""X"":1,""Z"":3}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); Assert.Equal(3, point.Z); - point = Serializer.Deserialize(@"{""Z"":3,""Y"":2,""X"":1}"); + point = await Serializer.DeserializeWrapper(@"{""Z"":3,""Y"":2,""X"":1}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); Assert.Equal(3, point.Z); - point = Serializer.Deserialize(@"{""Z"":3,""X"":1,""Y"":2}"); + point = await Serializer.DeserializeWrapper(@"{""Z"":3,""X"":1,""Y"":2}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); Assert.Equal(3, point.Z); } [Fact] - public void AsListElement() + public async Task AsListElement() { - List list = Serializer.Deserialize>(@"[{""Y"":2,""Z"":3,""X"":1},{""Z"":10,""Y"":30,""X"":20}]"); + List list = await Serializer.DeserializeWrapper>(@"[{""Y"":2,""Z"":3,""X"":1},{""Z"":10,""Y"":30,""X"":20}]"); Assert.Equal(1, list[0].X); Assert.Equal(2, list[0].Y); Assert.Equal(3, list[0].Z); @@ -221,9 +222,9 @@ public void AsListElement() } [Fact] - public void AsDictionaryValue() + public async Task AsDictionaryValue() { - Dictionary dict = Serializer.Deserialize>(@"{""0"":{""Y"":2,""Z"":3,""X"":1},""1"":{""Z"":10,""Y"":30,""X"":20}}"); + Dictionary dict = await Serializer.DeserializeWrapper>(@"{""0"":{""Y"":2,""Z"":3,""X"":1},""1"":{""Z"":10,""Y"":30,""X"":20}}"); Assert.Equal(1, dict["0"].X); Assert.Equal(2, dict["0"].Y); Assert.Equal(3, dict["0"].Z); @@ -233,9 +234,9 @@ public void AsDictionaryValue() } [Fact] - public void AsProperty_Of_ObjectWithParameterlessCtor() + public async Task AsProperty_Of_ObjectWithParameterlessCtor() { - WrapperForPoint_3D obj = Serializer.Deserialize(@"{""Point_3D"":{""Y"":2,""Z"":3,""X"":1}}"); + WrapperForPoint_3D obj = await Serializer.DeserializeWrapper(@"{""Point_3D"":{""Y"":2,""Z"":3,""X"":1}}"); Point_3D point = obj.Point_3D; Assert.Equal(1, point.X); Assert.Equal(2, point.Y); @@ -243,9 +244,9 @@ public void AsProperty_Of_ObjectWithParameterlessCtor() } [Fact] - public void AsProperty_Of_ObjectWithParameterizedCtor() + public async Task AsProperty_Of_ObjectWithParameterizedCtor() { - ClassWrapperForPoint_3D obj = Serializer.Deserialize(@"{""Point3D"":{""Y"":2,""Z"":3,""X"":1}}"); + ClassWrapperForPoint_3D obj = await Serializer.DeserializeWrapper(@"{""Point3D"":{""Y"":2,""Z"":3,""X"":1}}"); Point_3D point = obj.Point3D; Assert.Equal(1, point.X); Assert.Equal(2, point.Y); @@ -253,28 +254,28 @@ public void AsProperty_Of_ObjectWithParameterizedCtor() } [Fact] - public void At_Symbol_As_ParameterNamePrefix() + public async Task At_Symbol_As_ParameterNamePrefix() { - ClassWrapper_For_Int_String obj = Serializer.Deserialize(@"{""Int"":1,""String"":""1""}"); + ClassWrapper_For_Int_String obj = await Serializer.DeserializeWrapper(@"{""Int"":1,""String"":""1""}"); Assert.Equal(1, obj.Int); Assert.Equal("1", obj.String); } [Fact] - public void At_Symbol_As_ParameterNamePrefix_UseDefaultValues() + public async Task At_Symbol_As_ParameterNamePrefix_UseDefaultValues() { - ClassWrapper_For_Int_String obj = Serializer.Deserialize(@"{""@Int"":1,""@String"":""1""}"); + ClassWrapper_For_Int_String obj = await Serializer.DeserializeWrapper(@"{""@Int"":1,""@String"":""1""}"); Assert.Equal(0, obj.Int); Assert.Null(obj.String); } [Fact] - public void PassDefaultValueToComplexStruct() + public async Task PassDefaultValueToComplexStruct() { - ClassWrapperForPoint_3D obj = Serializer.Deserialize(@"{}"); + ClassWrapperForPoint_3D obj = await Serializer.DeserializeWrapper(@"{}"); Assert.True(obj.Point3D == default); - ClassWrapper_For_Int_Point_3D_String obj1 = Serializer.Deserialize(@"{}"); + ClassWrapper_For_Int_Point_3D_String obj1 = await Serializer.DeserializeWrapper(@"{}"); Assert.Equal(0, obj1.MyInt); Assert.Equal(0, obj1.MyPoint3DStruct.X); Assert.Equal(0, obj1.MyPoint3DStruct.Y); @@ -283,9 +284,9 @@ public void PassDefaultValueToComplexStruct() } [Fact] - public void Null_AsArgument_To_ParameterThat_CanBeNull() + public async Task Null_AsArgument_To_ParameterThat_CanBeNull() { - ClassWrapper_For_Int_Point_3D_String obj1 = Serializer.Deserialize(@"{""MyInt"":1,""MyPoint3DStruct"":{},""MyString"":null}"); + ClassWrapper_For_Int_Point_3D_String obj1 = await Serializer.DeserializeWrapper(@"{""MyInt"":1,""MyPoint3DStruct"":{},""MyString"":null}"); Assert.Equal(1, obj1.MyInt); Assert.Equal(0, obj1.MyPoint3DStruct.X); Assert.Equal(0, obj1.MyPoint3DStruct.Y); @@ -294,90 +295,90 @@ public void Null_AsArgument_To_ParameterThat_CanBeNull() } [Fact] - public void Null_AsArgument_To_ParameterThat_CanNotBeNull() + public async Task Null_AsArgument_To_ParameterThat_CanNotBeNull() { - Assert.Throws(() => Serializer.Deserialize(@"{""MyInt"":null,""MyString"":""1""}")); - Assert.Throws(() => Serializer.Deserialize(@"{""MyPoint3DStruct"":null,""MyString"":""1""}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""MyInt"":null,""MyString"":""1""}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""MyPoint3DStruct"":null,""MyString"":""1""}")); } [Fact] - public void OtherPropertiesAreSet() + public async Task OtherPropertiesAreSet() { - var personClass = Serializer.Deserialize(Person_Class.s_json); + var personClass = await Serializer.DeserializeWrapper(Person_Class.s_json); personClass.Verify(); - var personStruct = Serializer.Deserialize(Person_Struct.s_json); + var personStruct = await Serializer.DeserializeWrapper(Person_Struct.s_json); personStruct.Verify(); } [Fact] - public void ExtraProperties_AreIgnored() + public async Task ExtraProperties_AreIgnored() { - Point_2D point = Serializer.Deserialize(@"{ ""x"":1,""y"":2,""b"":3}"); + Point_2D point = await Serializer.DeserializeWrapper(@"{ ""x"":1,""y"":2,""b"":3}"); Assert.Equal(0, point.X); Assert.Equal(0, point.Y); } [Fact] - public void ExtraProperties_GoInExtensionData_IfPresent() + public async Task ExtraProperties_GoInExtensionData_IfPresent() { - Point_2D_With_ExtData point = Serializer.Deserialize(@"{""X"":1,""y"":2,""b"":3}"); + Point_2D_With_ExtData point = await Serializer.DeserializeWrapper(@"{""X"":1,""y"":2,""b"":3}"); Assert.Equal(1, point.X); Assert.Equal(2, point.ExtensionData["y"].GetInt32()); Assert.Equal(3, point.ExtensionData["b"].GetInt32()); } [Fact] - public void PropertiesNotSet_WhenJSON_MapsToConstructorParameters() + public async Task PropertiesNotSet_WhenJSON_MapsToConstructorParameters() { - var obj = Serializer.Deserialize(@"{""X"":1,""Y"":2}"); + var obj = await Serializer.DeserializeWrapper(@"{""X"":1,""Y"":2}"); Assert.Equal(40, obj.X); // Would be 1 if property were set directly after object construction. Assert.Equal(60, obj.Y); // Would be 2 if property were set directly after object construction. } [Fact] - public void IgnoreNullValues_DontSetNull_ToConstructorArguments_ThatCantBeNull() + public async Task IgnoreNullValues_DontSetNull_ToConstructorArguments_ThatCantBeNull() { // Throw JsonException when null applied to types that can't be null. Behavior should align with properties deserialized with setters. - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}")); - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}")); - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null}")); - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null}")); - Assert.Throws(() => Serializer.Deserialize(@"{""Int"":null}")); - Assert.Throws(() => Serializer.Deserialize(@"{""Int"":null}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Int"":null}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Int"":null}")); - Assert.Throws(() => Serializer.Deserialize(@"{""ImmutableArray"":null}")); - Assert.Throws(() => Serializer.Deserialize(@"{""ImmutableArray"":null}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""ImmutableArray"":null}")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""ImmutableArray"":null}")); // Throw even when IgnoreNullValues is true for symmetry with property deserialization, // until https://github.com/dotnet/runtime/issues/30795 is addressed. var options = new JsonSerializerOptions { IgnoreNullValues = true }; - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null}", options)); - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); - Assert.Throws(() => Serializer.Deserialize(@"{""Int"":null}", options)); - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Int"":null}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); - Assert.Throws(() => Serializer.Deserialize(@"{""ImmutableArray"":null}", options)); - Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""ImmutableArray"":null}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); } [Fact] - public void NumerousSimpleAndComplexParameters() + public async Task NumerousSimpleAndComplexParameters() { - var obj = Serializer.Deserialize(ClassWithConstructor_SimpleAndComplexParameters.s_json); + var obj = await Serializer.DeserializeWrapper(ClassWithConstructor_SimpleAndComplexParameters.s_json); obj.Verify(); } [Fact] - public void ClassWithPrimitives_Parameterless() + public async Task ClassWithPrimitives_Parameterless() { var point = new Parameterless_ClassWithPrimitives(); @@ -401,7 +402,7 @@ public void ClassWithPrimitives_Parameterless() string json = JsonSerializer.Serialize(point); - var deserialized = Serializer.Deserialize(json); + var deserialized = await Serializer.DeserializeWrapper(json); Assert.Equal(point.FirstInt, deserialized.FirstInt); Assert.Equal(point.SecondInt, deserialized.SecondInt); Assert.Equal(point.FirstString, deserialized.FirstString); @@ -422,7 +423,7 @@ public void ClassWithPrimitives_Parameterless() } [Fact] - public void ClassWithPrimitives() + public async Task ClassWithPrimitives() { var point = new Parameterized_ClassWithPrimitives_3Args(x: 234235, y: 912874, z: 434934); @@ -442,7 +443,7 @@ public void ClassWithPrimitives() string json = JsonSerializer.Serialize(point); - var deserialized = Serializer.Deserialize(json); + var deserialized = await Serializer.DeserializeWrapper(json); Assert.Equal(point.FirstInt, deserialized.FirstInt); Assert.Equal(point.SecondInt, deserialized.SecondInt); Assert.Equal(point.FirstString, deserialized.FirstString); @@ -463,7 +464,7 @@ public void ClassWithPrimitives() } [Fact] - public void ClassWithPrimitivesPerf() + public async Task ClassWithPrimitivesPerf() { var point = new Parameterized_ClassWithPrimitives_3Args(x: 234235, y: 912874, z: 434934); @@ -483,55 +484,55 @@ public void ClassWithPrimitivesPerf() string json = JsonSerializer.Serialize(point); - Serializer.Deserialize(json); - Serializer.Deserialize(json); + await Serializer.DeserializeWrapper(json); + await Serializer.DeserializeWrapper(json); } [Fact] - public void TupleDeserializationWorks() + public async Task TupleDeserializationWorks() { - var tuple = Serializer.Deserialize>(@"{""Item1"":""New York"",""Item2"":32.68}"); + var tuple = await Serializer.DeserializeWrapper>(@"{""Item1"":""New York"",""Item2"":32.68}"); Assert.Equal("New York", tuple.Item1); Assert.Equal(32.68, tuple.Item2); - var tupleWrapper = Serializer.Deserialize(@"{""Tuple"":{""Item1"":""New York"",""Item2"":32.68}}"); + var tupleWrapper = await Serializer.DeserializeWrapper(@"{""Tuple"":{""Item1"":""New York"",""Item2"":32.68}}"); tuple = tupleWrapper.Tuple; Assert.Equal("New York", tuple.Item1); Assert.Equal(32.68, tuple.Item2); - var tupleList = Serializer.Deserialize>>(@"[{""Item1"":""New York"",""Item2"":32.68}]"); + var tupleList = await Serializer.DeserializeWrapper>>(@"[{""Item1"":""New York"",""Item2"":32.68}]"); tuple = tupleList[0]; Assert.Equal("New York", tuple.Item1); Assert.Equal(32.68, tuple.Item2); } [Fact] - public void TupleDeserialization_MoreThanSevenItems() + public async Task TupleDeserialization_MoreThanSevenItems() { // Seven is okay string json = JsonSerializer.Serialize(Tuple.Create(1, 2, 3, 4, 5, 6, 7)); - var obj = Serializer.Deserialize>(json); + var obj = await Serializer.DeserializeWrapper>(json); Assert.Equal(json, JsonSerializer.Serialize(obj)); // More than seven arguments needs special casing and can be revisted. // Newtonsoft.Json fails in the same way. json = JsonSerializer.Serialize(Tuple.Create(1, 2, 3, 4, 5, 6, 7, 8)); - Assert.Throws(() => Serializer.Deserialize>(json)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper>(json)); // Invalid JSON representing a tuple with more than seven items yields an ArgumentException from the constructor. // System.ArgumentException : The last element of an eight element tuple must be a Tuple. // We pass the number 8, not a new Tuple(8). // Fixing this needs special casing. Newtonsoft behaves the same way. string invalidJson = @"{""Item1"":1,""Item2"":2,""Item3"":3,""Item4"":4,""Item5"":5,""Item6"":6,""Item7"":7,""Item1"":8}"; - Assert.Throws(() => Serializer.Deserialize>(invalidJson)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper>(invalidJson)); } [Fact] - public void TupleDeserialization_DefaultValuesUsed_WhenJsonMissing() + public async Task TupleDeserialization_DefaultValuesUsed_WhenJsonMissing() { // Seven items; only three provided. string input = @"{""Item2"":""2"",""Item3"":3,""Item6"":6}"; - var obj = Serializer.Deserialize>(input); + var obj = await Serializer.DeserializeWrapper>(input); string serialized = JsonSerializer.Serialize(obj); Assert.Contains(@"""Item1"":0", serialized); @@ -551,11 +552,11 @@ public void TupleDeserialization_DefaultValuesUsed_WhenJsonMissing() // System.ArgumentException : The last element of an eight element tuple must be a Tuple. // We pass the number 8, not a new Tuple(default(int)). // Fixing this needs special casing. Newtonsoft behaves the same way. - Assert.Throws(() => Serializer.Deserialize>(input)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper>(input)); } [Fact] - public void TupleDeserializationWorks_ClassWithParameterizedCtor() + public async Task TupleDeserializationWorks_ClassWithParameterizedCtor() { string classJson = ClassWithConstructor_SimpleAndComplexParameters.s_json; @@ -570,7 +571,7 @@ public void TupleDeserializationWorks_ClassWithParameterizedCtor() string complexTupleJson = sb.ToString(); - var complexTuple = Serializer.Deserialize(serialized); + Point_3D point = await Serializer.DeserializeWrapper(serialized); Assert.Equal(10, point.X); Assert.Equal(6, point.Y); Assert.Equal(50, point.Z); serialized = JsonSerializer.Serialize(new[] { new Point_3D(10, 6) }); - point = Serializer.Deserialize(serialized)[0]; + point = (await Serializer.DeserializeWrapper(serialized))[0]; Assert.Equal(10, point.X); Assert.Equal(6, point.Y); Assert.Equal(50, point.Z); serialized = JsonSerializer.Serialize(new WrapperForPoint_3D { Point_3D = new Point_3D(10, 6) }); - point = Serializer.Deserialize(serialized).Point_3D; + point = (await Serializer.DeserializeWrapper(serialized)).Point_3D; Assert.Equal(10, point.X); Assert.Equal(6, point.Y); Assert.Equal(50, point.Z); @@ -654,31 +655,31 @@ public void NoConstructorHandlingWhenObjectHasConverter() serialized = JsonSerializer.Serialize(new Point_3D(10, 6)); - point = Serializer.Deserialize(serialized, options); + point = await Serializer.DeserializeWrapper(serialized, options); Assert.Equal(4, point.X); Assert.Equal(4, point.Y); Assert.Equal(4, point.Z); serialized = JsonSerializer.Serialize(new[] { new Point_3D(10, 6) }); - point = Serializer.Deserialize(serialized, options)[0]; + point = (await Serializer.DeserializeWrapper(serialized, options))[0]; Assert.Equal(4, point.X); Assert.Equal(4, point.Y); Assert.Equal(4, point.Z); serialized = JsonSerializer.Serialize(new WrapperForPoint_3D { Point_3D = new Point_3D(10, 6) }); - point = Serializer.Deserialize(serialized, options).Point_3D; + point = (await Serializer.DeserializeWrapper(serialized, options)).Point_3D; Assert.Equal(4, point.X); Assert.Equal(4, point.Y); Assert.Equal(4, point.Z); } [Fact] - public void ConstructorHandlingHonorsCustomConverters() + public async Task ConstructorHandlingHonorsCustomConverters() { // Baseline, use internal converters for primitives - Point_2D point = Serializer.Deserialize(@"{""X"":2,""Y"":3}"); + Point_2D point = await Serializer.DeserializeWrapper(@"{""X"":2,""Y"":3}"); Assert.Equal(2, point.X); Assert.Equal(3, point.Y); @@ -686,15 +687,15 @@ public void ConstructorHandlingHonorsCustomConverters() var options = new JsonSerializerOptions(); options.Converters.Add(new ConverterForInt32()); - point = Serializer.Deserialize(@"{""X"":2,""Y"":3}", options); + point = await Serializer.DeserializeWrapper(@"{""X"":2,""Y"":3}", options); Assert.Equal(25, point.X); Assert.Equal(25, point.X); } [Fact] - public void CanDeserialize_ObjectWith_Ctor_With_64_Params() + public async Task CanDeserialize_ObjectWith_Ctor_With_64_Params() { - void RunTest() + async Task RunTestAsync() { StringBuilder sb = new StringBuilder(); sb.Append("{"); @@ -707,21 +708,21 @@ void RunTest() string input = sb.ToString(); - object obj = Serializer.Deserialize(input); + object obj = await Serializer.DeserializeWrapper(input); for (int i = 0; i < 64; i++) { Assert.Equal(i, (int)typeof(T).GetProperty($"Int{i}").GetValue(obj)); } } - RunTest(); - RunTest(); + await RunTestAsync(); + await RunTestAsync(); } [Fact] - public void Cannot_Deserialize_ObjectWith_Ctor_With_65_Params() + public async Task Cannot_Deserialize_ObjectWith_Ctor_With_65_Params() { - void RunTest() + async Task RunTestAsync() { Type type = typeof(T); @@ -747,46 +748,46 @@ void RunTest() string ctorAsString = sb.ToString(); - NotSupportedException ex = Assert.Throws(() => Serializer.Deserialize(input)); + NotSupportedException ex = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(input)); string strEx = ex.ToString(); Assert.Contains(ctorAsString, strEx); Assert.Contains(type.ToString(), strEx); - ex = Assert.Throws(() => Serializer.Deserialize("{}")); + ex = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{}")); strEx = ex.ToString(); Assert.Contains(ctorAsString, strEx); Assert.Contains(type.ToString(), strEx); } - RunTest(); - RunTest(); + await RunTestAsync(); + await RunTestAsync(); } [Fact] - public void Deserialize_ObjectWith_Ctor_With_65_Params_IfNull() + public async Task Deserialize_ObjectWith_Ctor_With_65_Params_IfNull() { - Assert.Null(Serializer.Deserialize("null")); - Assert.Throws(() => Serializer.Deserialize("null")); + Assert.Null(await Serializer.DeserializeWrapper("null")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("null")); } [Fact] - public void Escaped_ParameterNames_Work() + public async Task Escaped_ParameterNames_Work() { - Point_2D point = Serializer.Deserialize(@"{""\u0058"":1,""\u0059"":2}"); + Point_2D point = await Serializer.DeserializeWrapper(@"{""\u0058"":1,""\u0059"":2}"); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); } [Fact] - public void FirstParameterWins() + public async Task FirstParameterWins() { - Point_2D point = Serializer.Deserialize(@"{""X"":1,""Y"":2,""X"":4}"); + Point_2D point = await Serializer.DeserializeWrapper(@"{""X"":1,""Y"":2,""X"":4}"); Assert.Equal(4, point.X); // Not 1. Assert.Equal(2, point.Y); } [Fact] - public void SubsequentParameter_GoesToExtensionData() + public async Task SubsequentParameter_GoesToExtensionData() { string json = @"{ ""FirstName"":""Jet"", @@ -797,7 +798,7 @@ public void SubsequentParameter_GoesToExtensionData() ""Id"":""63cf821d-fd47-4782-8345-576d9228a534"" }"; - Parameterized_Person person = Serializer.Deserialize(json); + Parameterized_Person person = await Serializer.DeserializeWrapper(json); Assert.Equal("Jet", person.FirstName); Assert.Equal("Doe", person.LastName); Assert.Equal("63cf821d-fd47-4782-8345-576d9228a534", person.Id.ToString()); @@ -806,30 +807,30 @@ public void SubsequentParameter_GoesToExtensionData() } [Fact] - public void BitVector32_UsesStructDefaultCtor_MultipleParameterizedCtor() + public async Task BitVector32_UsesStructDefaultCtor_MultipleParameterizedCtor() { string serialized = JsonSerializer.Serialize(new BitVector32(1)); - Assert.Equal(0, Serializer.Deserialize(serialized).Data); + Assert.Equal(0, (await Serializer.DeserializeWrapper(serialized)).Data); } [Fact] - public void HonorExtensionDataGeneric() + public async Task HonorExtensionDataGeneric() { - var obj1 = Serializer.Deserialize(@"{""key"": ""value""}"); + var obj1 = await Serializer.DeserializeWrapper(@"{""key"": ""value""}"); Assert.Equal("value", obj1.ExtensionData["key"].GetString()); - var obj2 = Serializer.Deserialize(@"{""key"": ""value""}"); + var obj2 = await Serializer.DeserializeWrapper(@"{""key"": ""value""}"); Assert.Equal("value", ((JsonElement)obj2.ExtensionData["key"]).GetString()); - var obj3 = Serializer.Deserialize(@"{""key"": ""value""}"); + var obj3 = await Serializer.DeserializeWrapper(@"{""key"": ""value""}"); Assert.Equal("value", obj3.ExtensionData["key"].GetString()); - var obj4 = Serializer.Deserialize(@"{""key"": ""value""}"); + var obj4 = await Serializer.DeserializeWrapper(@"{""key"": ""value""}"); Assert.Equal("value", ((JsonElement)obj4.ExtensionData["key"]).GetString()); } [Fact] - public void ArgumentDeserialization_Honors_JsonPropertyName() + public async Task ArgumentDeserialization_Honors_JsonPropertyName() { Point_MembersHave_JsonPropertyName point = new Point_MembersHave_JsonPropertyName(1, 2); @@ -837,40 +838,40 @@ public void ArgumentDeserialization_Honors_JsonPropertyName() Assert.Contains(@"""XValue"":1", json); Assert.Contains(@"""YValue"":2", json); - point = Serializer.Deserialize(json); + point = await Serializer.DeserializeWrapper(json); point.Verify(); } [Fact] - public void ArgumentDeserialization_Honors_JsonPropertyName_CaseInsensitiveWorks() + public async Task ArgumentDeserialization_Honors_JsonPropertyName_CaseInsensitiveWorks() { string json = @"{""XVALUE"":1,""yvalue"":2}"; // Without case insensitivity, there's no match. - Point_MembersHave_JsonPropertyName point = Serializer.Deserialize(json); + Point_MembersHave_JsonPropertyName point = await Serializer.DeserializeWrapper(json); var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; - point = Serializer.Deserialize(json, options); + point = await Serializer.DeserializeWrapper(json, options); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); } [Fact] - public void ArgumentDeserialization_Honors_ConverterOnProperty() + public async Task ArgumentDeserialization_Honors_ConverterOnProperty() { - var point = Serializer.Deserialize(Point_MembersHave_JsonConverter.s_json); + var point = await Serializer.DeserializeWrapper(Point_MembersHave_JsonConverter.s_json); point.Verify(); } [Fact] - public void ArgumentDeserialization_Honors_JsonIgnore() + public async Task ArgumentDeserialization_Honors_JsonIgnore() { - var point = Serializer.Deserialize(Point_MembersHave_JsonIgnore.s_json); + var point = await Serializer.DeserializeWrapper(Point_MembersHave_JsonIgnore.s_json); point.Verify(); } [Fact] - public void ArgumentDeserialization_UseNamingPolicy_ToMatch() + public async Task ArgumentDeserialization_UseNamingPolicy_ToMatch() { var options = new JsonSerializerOptions { @@ -880,17 +881,17 @@ public void ArgumentDeserialization_UseNamingPolicy_ToMatch() string json = JsonSerializer.Serialize(new Point_ExtendedPropNames(1, 2), options); // If we don't use naming policy, then we can't match serialized properties to constructor parameters on deserialization. - var point = Serializer.Deserialize(json); + var point = await Serializer.DeserializeWrapper(json); Assert.Equal(0, point.XValue); Assert.Equal(0, point.YValue); - point = Serializer.Deserialize(json, options); + point = await Serializer.DeserializeWrapper(json, options); Assert.Equal(1, point.XValue); Assert.Equal(2, point.YValue); } [Fact] - public void ArgumentDeserialization_UseNamingPolicy_ToMatch_CaseInsensitiveWorks() + public async Task ArgumentDeserialization_UseNamingPolicy_ToMatch_CaseInsensitiveWorks() { var options1 = new JsonSerializerOptions { @@ -900,7 +901,7 @@ public void ArgumentDeserialization_UseNamingPolicy_ToMatch_CaseInsensitiveWorks string json = @"{""x_VaLUE"":1,""Y_vALue"":2}"; // If we don't use case sensitivity, then we can't match serialized properties to constructor parameters on deserialization. - Point_ExtendedPropNames point = Serializer.Deserialize(json, options1); + Point_ExtendedPropNames point = await Serializer.DeserializeWrapper(json, options1); Assert.Equal(0, point.XValue); Assert.Equal(0, point.YValue); @@ -910,37 +911,37 @@ public void ArgumentDeserialization_UseNamingPolicy_ToMatch_CaseInsensitiveWorks PropertyNameCaseInsensitive = true, }; - point = Serializer.Deserialize(json, options2); + point = await Serializer.DeserializeWrapper(json, options2); Assert.Equal(1, point.XValue); Assert.Equal(2, point.YValue); } [Fact] - public void ArgumentDeserialization_UseNamingPolicy_InvalidPolicyFails() + public async Task ArgumentDeserialization_UseNamingPolicy_InvalidPolicyFails() { var options = new JsonSerializerOptions { PropertyNamingPolicy = new NullNamingPolicy() }; - Assert.Throws(() => Serializer.Deserialize("{}", options)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{}", options)); } [Fact] - public void ComplexJson_As_LastCtorArg() + public async Task ComplexJson_As_LastCtorArg() { - Point_With_Array obj1 = Serializer.Deserialize(Point_With_Array.s_json); + Point_With_Array obj1 = await Serializer.DeserializeWrapper(Point_With_Array.s_json); ((ITestClass)obj1).Verify(); - Point_With_Dictionary obj2 = Serializer.Deserialize(Point_With_Dictionary.s_json); + Point_With_Dictionary obj2 = await Serializer.DeserializeWrapper(Point_With_Dictionary.s_json); ((ITestClass)obj2).Verify(); - Point_With_Object obj3 = Serializer.Deserialize(Point_With_Object.s_json); + Point_With_Object obj3 = await Serializer.DeserializeWrapper(Point_With_Object.s_json); ((ITestClass)obj3).Verify(); } [Fact] - public void NumerousPropertiesWork() + public async Task NumerousPropertiesWork() { StringBuilder sb = new StringBuilder(); sb.Append("{"); @@ -957,14 +958,14 @@ public void NumerousPropertiesWork() string json = sb.ToString(); - var point = Serializer.Deserialize(json); + var point = await Serializer.DeserializeWrapper(json); Assert.Equal(1, point.X); Assert.Equal(2, point.Y); Assert.Equal(66, point.Z); } [Fact] - public void ArgumentStateNotOverwritten() + public async Task ArgumentStateNotOverwritten() { ClassWithNestedClass obj = new ClassWithNestedClass(myClass: null, myPoint: default); ClassWithNestedClass obj1 = new ClassWithNestedClass(myClass: obj, myPoint: new Point_2D_Struct_WithAttribute(1, 2)); @@ -972,7 +973,7 @@ public void ArgumentStateNotOverwritten() string json = JsonSerializer.Serialize(obj2); - obj2 = Serializer.Deserialize(json); + obj2 = await Serializer.DeserializeWrapper(json); Assert.Equal(3, obj2.MyPoint.X); Assert.Equal(4, obj2.MyPoint.Y); @@ -988,11 +989,11 @@ public void ArgumentStateNotOverwritten() } [Fact] - public void FourArgsWork() + public async Task FourArgsWork() { string json = JsonSerializer.Serialize(new StructWithFourArgs(1, 2, 3, 4)); - var obj = Serializer.Deserialize(json); + var obj = await Serializer.DeserializeWrapper(json); Assert.Equal(1, obj.W); Assert.Equal(2, obj.X); Assert.Equal(3, obj.Y); @@ -1000,17 +1001,17 @@ public void FourArgsWork() } [Fact] - public void InvalidJsonFails() + public async Task InvalidJsonFails() { - Assert.Throws(() => Serializer.Deserialize("{1")); - Assert.Throws(() => Serializer.Deserialize("{x")); - Assert.Throws(() => Serializer.Deserialize("{{")); - Assert.Throws(() => Serializer.Deserialize("{true")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{1")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{x")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{{")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{true")); // Also test deserialization of objects with parameterless ctors - Assert.Throws(() => Serializer.Deserialize("{1")); - Assert.Throws(() => Serializer.Deserialize("{x")); - Assert.Throws(() => Serializer.Deserialize("{true")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{1")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{x")); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{true")); } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Stream.cs b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Stream.cs index 50f7efcca4da0..c06db5efa5f0c 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Stream.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.Stream.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; @@ -11,9 +11,9 @@ namespace System.Text.Json.Serialization.Tests public abstract partial class ConstructorTests { [Fact] - public void ReadSimpleObjectAsync() + public async Task ReadSimpleObjectAsync() { - async Task RunTest(byte[] testData) + async Task RunTestAsync(byte[] testData) { using (MemoryStream stream = new MemoryStream(testData)) { @@ -31,34 +31,34 @@ async Task RunTest(byte[] testData) Task[] tasks = new Task[14]; // Simple models can be deserialized. - tasks[0] = Task.Run(async () => await RunTest(Parameterized_IndexViewModel_Immutable.s_data)); + tasks[0] = Task.Run(async () => await RunTestAsync(Parameterized_IndexViewModel_Immutable.s_data)); // Complex models can be deserialized. - tasks[1] = Task.Run(async () => await RunTest(ClassWithConstructor_SimpleAndComplexParameters.s_data)); - tasks[2] = Task.Run(async () => await RunTest(Parameterized_Class_With_ComplexTuple.s_data)); + tasks[1] = Task.Run(async () => await RunTestAsync(ClassWithConstructor_SimpleAndComplexParameters.s_data)); + tasks[2] = Task.Run(async () => await RunTestAsync(Parameterized_Class_With_ComplexTuple.s_data)); // JSON that doesn't bind to ctor args are matched with properties or ignored (as appropriate). - tasks[3] = Task.Run(async () => await RunTest(Person_Class.s_data)); - tasks[4] = Task.Run(async () => await RunTest(Person_Struct.s_data)); + tasks[3] = Task.Run(async () => await RunTestAsync(Person_Class.s_data)); + tasks[4] = Task.Run(async () => await RunTestAsync(Person_Struct.s_data)); // JSON that doesn't bind to ctor args or properties are sent to ext data if avaiable. - tasks[5] = Task.Run(async () => await RunTest(Parameterized_Person.s_data)); - tasks[6] = Task.Run(async () => await RunTest(Parameterized_Person_ObjExtData.s_data)); + tasks[5] = Task.Run(async () => await RunTestAsync(Parameterized_Person.s_data)); + tasks[6] = Task.Run(async () => await RunTestAsync(Parameterized_Person_ObjExtData.s_data)); // Up to 64 ctor args are supported. - tasks[7] = Task.Run(async () => await RunTest(Class_With_Ctor_With_64_Params.Data)); + tasks[7] = Task.Run(async () => await RunTestAsync(Class_With_Ctor_With_64_Params.Data)); // Arg deserialization honors attributes on matching property. - tasks[8] = Task.Run(async () => await RunTest(Point_MembersHave_JsonPropertyName.s_data)); - tasks[9] = Task.Run(async () => await RunTest(Point_MembersHave_JsonConverter.s_data)); - tasks[10] = Task.Run(async () => await RunTest(Point_MembersHave_JsonIgnore.s_data)); + tasks[8] = Task.Run(async () => await RunTestAsync(Point_MembersHave_JsonPropertyName.s_data)); + tasks[9] = Task.Run(async () => await RunTestAsync(Point_MembersHave_JsonConverter.s_data)); + tasks[10] = Task.Run(async () => await RunTestAsync(Point_MembersHave_JsonIgnore.s_data)); // Complex JSON as last argument works - tasks[11] = Task.Run(async () => await RunTest(Point_With_Array.s_data)); - tasks[12] = Task.Run(async () => await RunTest(Point_With_Dictionary.s_data)); - tasks[13] = Task.Run(async () => await RunTest(Point_With_Object.s_data)); + tasks[11] = Task.Run(async () => await RunTestAsync(Point_With_Array.s_data)); + tasks[12] = Task.Run(async () => await RunTestAsync(Point_With_Dictionary.s_data)); + tasks[13] = Task.Run(async () => await RunTestAsync(Point_With_Object.s_data)); - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } [Fact] - public void ReadSimpleObjectWithTrailingTriviaAsync() + public async Task ReadSimpleObjectWithTrailingTriviaAsync() { - async Task RunTest(string testData) + async Task RunTestAsync(string testData) { byte[] data = Encoding.UTF8.GetBytes(testData + " /* Multi\r\nLine Comment */\t"); using (MemoryStream stream = new MemoryStream(data)) @@ -78,34 +78,34 @@ async Task RunTest(string testData) Task[] tasks = new Task[14]; // Simple models can be deserialized. - tasks[0] = Task.Run(async () => await RunTest(Parameterized_IndexViewModel_Immutable.s_json)); + tasks[0] = Task.Run(async () => await RunTestAsync(Parameterized_IndexViewModel_Immutable.s_json)); // Complex models can be deserialized. - tasks[1] = Task.Run(async () => await RunTest(ClassWithConstructor_SimpleAndComplexParameters.s_json)); - tasks[2] = Task.Run(async () => await RunTest(Parameterized_Class_With_ComplexTuple.s_json)); + tasks[1] = Task.Run(async () => await RunTestAsync(ClassWithConstructor_SimpleAndComplexParameters.s_json)); + tasks[2] = Task.Run(async () => await RunTestAsync(Parameterized_Class_With_ComplexTuple.s_json)); // JSON that doesn't bind to ctor args are matched with properties or ignored (as appropriate). - tasks[3] = Task.Run(async () => await RunTest(Person_Class.s_json)); - tasks[4] = Task.Run(async () => await RunTest(Person_Struct.s_json)); + tasks[3] = Task.Run(async () => await RunTestAsync(Person_Class.s_json)); + tasks[4] = Task.Run(async () => await RunTestAsync(Person_Struct.s_json)); // JSON that doesn't bind to ctor args or properties are sent to ext data if avaiable. - tasks[5] = Task.Run(async () => await RunTest(Parameterized_Person.s_json)); - tasks[6] = Task.Run(async () => await RunTest(Parameterized_Person_ObjExtData.s_json)); + tasks[5] = Task.Run(async () => await RunTestAsync(Parameterized_Person.s_json)); + tasks[6] = Task.Run(async () => await RunTestAsync(Parameterized_Person_ObjExtData.s_json)); // Up to 64 ctor args are supported. - tasks[7] = Task.Run(async () => await RunTest(Encoding.UTF8.GetString(Class_With_Ctor_With_64_Params.Data))); + tasks[7] = Task.Run(async () => await RunTestAsync(Encoding.UTF8.GetString(Class_With_Ctor_With_64_Params.Data))); // Arg8deserialization honors attributes on matching property. - tasks[8] = Task.Run(async () => await RunTest(Point_MembersHave_JsonPropertyName.s_json)); - tasks[9] = Task.Run(async () => await RunTest(Point_MembersHave_JsonConverter.s_json)); - tasks[10] = Task.Run(async () => await RunTest(Point_MembersHave_JsonIgnore.s_json)); + tasks[8] = Task.Run(async () => await RunTestAsync(Point_MembersHave_JsonPropertyName.s_json)); + tasks[9] = Task.Run(async () => await RunTestAsync(Point_MembersHave_JsonConverter.s_json)); + tasks[10] = Task.Run(async () => await RunTestAsync(Point_MembersHave_JsonIgnore.s_json)); // Complex JSON as last argument works - tasks[11] = Task.Run(async () => await RunTest(Point_With_Array.s_json)); - tasks[12] = Task.Run(async () => await RunTest(Point_With_Dictionary.s_json)); - tasks[13] = Task.Run(async () => await RunTest(Point_With_Object.s_json)); + tasks[11] = Task.Run(async () => await RunTestAsync(Point_With_Array.s_json)); + tasks[12] = Task.Run(async () => await RunTestAsync(Point_With_Dictionary.s_json)); + tasks[13] = Task.Run(async () => await RunTestAsync(Point_With_Object.s_json)); - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public void Cannot_DeserializeAsync_ObjectWith_Ctor_With_65_Params() + [Fact] + public async Task Cannot_DeserializeAsync_ObjectWith_Ctor_With_65_Params() { - async Task RunTest() + async Task RunTestAsync() { StringBuilder sb = new StringBuilder(); sb.Append("{"); @@ -141,10 +141,10 @@ async Task RunTest() Task[] tasks = new Task[2]; - tasks[0] = Task.Run(async () => await RunTest()); - tasks[1] = Task.Run(async () => await RunTest()); + tasks[0] = Task.Run(async () => await RunTestAsync()); + tasks[1] = Task.Run(async () => await RunTestAsync()); - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } [Fact] @@ -155,7 +155,7 @@ static string GetPropertyName(int index) => static byte[] GeneratePayload(int i, string value) { - string whiteSpace = new string(' ', 16 ); + string whiteSpace = new string(' ', 16); StringBuilder sb; diff --git a/src/libraries/System.Text.Json/tests/Serialization/DeserializationWrapper.cs b/src/libraries/System.Text.Json/tests/Serialization/DeserializationWrapper.cs index 65099e32cd7b3..b20b6f52f20ac 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/DeserializationWrapper.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/DeserializationWrapper.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.IO; @@ -16,55 +16,49 @@ public abstract class DeserializationWrapper public static DeserializationWrapper StringDeserializer => new StringDeserializerWrapper(); public static DeserializationWrapper StreamDeserializer => new StreamDeserializerWrapper(); - protected internal abstract T Deserialize(string json, JsonSerializerOptions options = null); + protected internal abstract Task DeserializeWrapper(string json, JsonSerializerOptions options = null); - protected internal abstract object Deserialize(string json, Type type, JsonSerializerOptions options = null); + protected internal abstract Task DeserializeWrapper(string json, Type type, JsonSerializerOptions options = null); private class StringDeserializerWrapper : DeserializationWrapper { - protected internal override T Deserialize(string json, JsonSerializerOptions options = null) + protected internal override Task DeserializeWrapper(string json, JsonSerializerOptions options = null) { - return JsonSerializer.Deserialize(json, options); + return Task.FromResult(JsonSerializer.Deserialize(json, options)); } - protected internal override object Deserialize(string json, Type type, JsonSerializerOptions options = null) + protected internal override Task DeserializeWrapper(string json, Type type, JsonSerializerOptions options = null) { - return JsonSerializer.Deserialize(json, type, options); + return Task.FromResult(JsonSerializer.Deserialize(json, type, options)); } } private class StreamDeserializerWrapper : DeserializationWrapper { - protected internal override T Deserialize(string json, JsonSerializerOptions options = null) + protected internal override async Task DeserializeWrapper(string json, JsonSerializerOptions options = null) { if (options == null) { options = _optionsWithSmallBuffer; } - return Task.Run(async () => + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { - using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) - { - return await JsonSerializer.DeserializeAsync(stream, options); - } - }).GetAwaiter().GetResult(); + return await JsonSerializer.DeserializeAsync(stream, options); + } } - protected internal override object Deserialize(string json, Type type, JsonSerializerOptions options = null) + protected internal override async Task DeserializeWrapper(string json, Type type, JsonSerializerOptions options = null) { if (options == null) { options = _optionsWithSmallBuffer; } - return Task.Run(async () => + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { - using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) - { - return await JsonSerializer.DeserializeAsync(stream, type, options); - } - }).GetAwaiter().GetResult(); + return await JsonSerializer.DeserializeAsync(stream, type, options); + } } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/InvalidTypeTests.cs b/src/libraries/System.Text.Json/tests/Serialization/InvalidTypeTests.cs index b4510f129602c..60c2a84bcb679 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/InvalidTypeTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/InvalidTypeTests.cs @@ -1,7 +1,8 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Threading.Tasks; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -50,9 +51,9 @@ public void DeserializeInvalidType(Type type) Assert.Contains(type.ToString(), ex.ToString()); } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Theory] [MemberData(nameof(TypesWithInvalidMembers_WithMembers))] - public void TypeWithInvalidMember(Type classType, Type invalidMemberType, string invalidMemberName) + public async Task TypeWithInvalidMember(Type classType, Type invalidMemberType, string invalidMemberName) { static void ValidateException(InvalidOperationException ex, Type classType, Type invalidMemberType, string invalidMemberName) { @@ -63,19 +64,19 @@ static void ValidateException(InvalidOperationException ex, Type classType, Type } object obj = Activator.CreateInstance(classType); - InvalidOperationException ex = Assert.Throws(() => Serializer.Serialize(obj, classType)); + InvalidOperationException ex = await Assert.ThrowsAsync(() => Serializer.SerializeWrapper(obj, classType)); ValidateException(ex, classType, invalidMemberType, invalidMemberName); - ex = Assert.Throws(() => Serializer.Serialize(null, classType)); + ex = await Assert.ThrowsAsync(() => Serializer.SerializeWrapper(null, classType)); ValidateException(ex, classType, invalidMemberType, invalidMemberName); ex = Assert.Throws(() => JsonSerializer.Deserialize("", classType)); ValidateException(ex, classType, invalidMemberType, invalidMemberName); } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Theory] [MemberData(nameof(OpenGenericTypes_ToSerialize))] - public void SerializeOpenGeneric(Type type) + public async Task SerializeOpenGeneric(Type type) { object obj; @@ -88,24 +89,24 @@ public void SerializeOpenGeneric(Type type) obj = Activator.CreateInstance(type.MakeGenericType(typeof(string), typeof(int))); } - Assert.Throws(() => Serializer.Serialize(obj, type)); + await Assert.ThrowsAsync(() => Serializer.SerializeWrapper(obj, type)); } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Theory] [MemberData(nameof(OpenGenericTypes))] - public void SerializeInvalidTypes_NullValue(Type type) + public async Task SerializeInvalidTypes_NullValue(Type type) { - InvalidOperationException ex = Assert.Throws(() => Serializer.Serialize(null, type)); + InvalidOperationException ex = await Assert.ThrowsAsync(() => Serializer.SerializeWrapper(null, type)); Assert.Contains(type.ToString(), ex.ToString()); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public void SerializeOpenGeneric_NullableOfT() + [Fact] + public async Task SerializeOpenGeneric_NullableOfT() { Type openNullableType = typeof(Nullable<>); object obj = Activator.CreateInstance(openNullableType.MakeGenericType(typeof(int))); - InvalidOperationException ex = Assert.Throws(() => Serializer.Serialize(obj, openNullableType)); + InvalidOperationException ex = await Assert.ThrowsAsync(() => Serializer.SerializeWrapper(obj, openNullableType)); Assert.Contains(openNullableType.ToString(), ex.ToString()); } diff --git a/src/libraries/System.Text.Json/tests/Serialization/PolymorphicTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PolymorphicTests.cs index 3129e1e7adefd..00cb5ad194634 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PolymorphicTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PolymorphicTests.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; +using System.Threading.Tasks; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -43,32 +44,32 @@ public PolymorphicTests(SerializationWrapper serializer) } [Fact] - public void PrimitivesAsRootObject() + public async Task PrimitivesAsRootObject() { - string json = Serializer.Serialize(1); + string json = await Serializer.SerializeWrapper(1); Assert.Equal("1", json); - json = Serializer.Serialize(1, typeof(object)); + json = await Serializer.SerializeWrapper(1, typeof(object)); Assert.Equal("1", json); - json = Serializer.Serialize("foo"); + json = await Serializer.SerializeWrapper("foo"); Assert.Equal(@"""foo""", json); - json = Serializer.Serialize("foo", typeof(object)); + json = await Serializer.SerializeWrapper("foo", typeof(object)); Assert.Equal(@"""foo""", json); - json = Serializer.Serialize(true); + json = await Serializer.SerializeWrapper(true); Assert.Equal(@"true", json); - json = Serializer.Serialize(true, typeof(object)); + json = await Serializer.SerializeWrapper(true, typeof(object)); Assert.Equal(@"true", json); - json = Serializer.Serialize(null); + json = await Serializer.SerializeWrapper(null); Assert.Equal(@"null", json); - json = Serializer.Serialize((object)null, typeof(object)); + json = await Serializer.SerializeWrapper((object)null, typeof(object)); Assert.Equal(@"null", json); decimal pi = 3.1415926535897932384626433833m; - json = Serializer.Serialize(pi); + json = await Serializer.SerializeWrapper(pi); Assert.Equal(@"3.1415926535897932384626433833", json); - json = Serializer.Serialize(pi, typeof(object)); + json = await Serializer.SerializeWrapper(pi, typeof(object)); Assert.Equal(@"3.1415926535897932384626433833", json); } @@ -102,7 +103,7 @@ public void ParseUntyped() } [Fact] - public void ArrayAsRootObject() + public async Task ArrayAsRootObject() { const string ExpectedJson = @"[1,true,{""City"":""MyCity""},null,""foo""]"; const string ReversedExpectedJson = @"[""foo"",null,{""City"":""MyCity""},true,1]"; @@ -113,193 +114,193 @@ public void ArrayAsRootObject() address.Initialize(); var array = new object[] { 1, true, address, null, "foo" }; - string json = Serializer.Serialize(array); + string json = await Serializer.SerializeWrapper(array); Assert.Equal(ExpectedJson, json); var dictionary = new Dictionary { { "City", "MyCity" } }; var arrayWithDictionary = new object[] { 1, true, dictionary, null, "foo" }; - json = Serializer.Serialize(arrayWithDictionary); + json = await Serializer.SerializeWrapper(arrayWithDictionary); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(array); + json = await Serializer.SerializeWrapper(array); Assert.Equal(ExpectedJson, json); List list = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(list); + json = await Serializer.SerializeWrapper(list); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(list); + json = await Serializer.SerializeWrapper(list); Assert.Equal(ExpectedJson, json); IEnumerable ienumerable = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(ienumerable); + json = await Serializer.SerializeWrapper(ienumerable); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(ienumerable); + json = await Serializer.SerializeWrapper(ienumerable); Assert.Equal(ExpectedJson, json); IList ilist = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(ilist); + json = await Serializer.SerializeWrapper(ilist); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(ilist); + json = await Serializer.SerializeWrapper(ilist); Assert.Equal(ExpectedJson, json); ICollection icollection = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(icollection); + json = await Serializer.SerializeWrapper(icollection); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(icollection); + json = await Serializer.SerializeWrapper(icollection); Assert.Equal(ExpectedJson, json); IEnumerable genericIEnumerable = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(genericIEnumerable); + json = await Serializer.SerializeWrapper(genericIEnumerable); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(genericIEnumerable); + json = await Serializer.SerializeWrapper(genericIEnumerable); Assert.Equal(ExpectedJson, json); IList genericIList = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(genericIList); + json = await Serializer.SerializeWrapper(genericIList); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(genericIList); + json = await Serializer.SerializeWrapper(genericIList); Assert.Equal(ExpectedJson, json); ICollection genericICollection = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(genericICollection); + json = await Serializer.SerializeWrapper(genericICollection); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(genericICollection); + json = await Serializer.SerializeWrapper(genericICollection); Assert.Equal(ExpectedJson, json); IReadOnlyCollection genericIReadOnlyCollection = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(genericIReadOnlyCollection); + json = await Serializer.SerializeWrapper(genericIReadOnlyCollection); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(genericIReadOnlyCollection); + json = await Serializer.SerializeWrapper(genericIReadOnlyCollection); Assert.Equal(ExpectedJson, json); IReadOnlyList genericIReadonlyList = new List { 1, true, address, null, "foo" }; - json = Serializer.Serialize(genericIReadonlyList); + json = await Serializer.SerializeWrapper(genericIReadonlyList); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(genericIReadonlyList); + json = await Serializer.SerializeWrapper(genericIReadonlyList); Assert.Equal(ExpectedJson, json); ISet iset = new HashSet { 1, true, address, null, "foo" }; - json = Serializer.Serialize(iset); + json = await Serializer.SerializeWrapper(iset); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(iset); + json = await Serializer.SerializeWrapper(iset); Assert.Equal(ExpectedJson, json); Stack stack = new Stack(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(stack); + json = await Serializer.SerializeWrapper(stack); Assert.Equal(ReversedExpectedJson, json); - json = Serializer.Serialize(stack); + json = await Serializer.SerializeWrapper(stack); Assert.Equal(ReversedExpectedJson, json); Queue queue = new Queue(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(queue); + json = await Serializer.SerializeWrapper(queue); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(queue); + json = await Serializer.SerializeWrapper(queue); Assert.Equal(ExpectedJson, json); HashSet hashset = new HashSet(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(hashset); + json = await Serializer.SerializeWrapper(hashset); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(hashset); + json = await Serializer.SerializeWrapper(hashset); Assert.Equal(ExpectedJson, json); LinkedList linkedlist = new LinkedList(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(linkedlist); + json = await Serializer.SerializeWrapper(linkedlist); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(linkedlist); + json = await Serializer.SerializeWrapper(linkedlist); Assert.Equal(ExpectedJson, json); ImmutableArray immutablearray = ImmutableArray.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(immutablearray); + json = await Serializer.SerializeWrapper(immutablearray); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(immutablearray); + json = await Serializer.SerializeWrapper(immutablearray); Assert.Equal(ExpectedJson, json); IImmutableList iimmutablelist = ImmutableList.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(iimmutablelist); + json = await Serializer.SerializeWrapper(iimmutablelist); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(iimmutablelist); + json = await Serializer.SerializeWrapper(iimmutablelist); Assert.Equal(ExpectedJson, json); IImmutableStack iimmutablestack = ImmutableStack.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(iimmutablestack); + json = await Serializer.SerializeWrapper(iimmutablestack); Assert.Equal(ReversedExpectedJson, json); - json = Serializer.Serialize(iimmutablestack); + json = await Serializer.SerializeWrapper(iimmutablestack); Assert.Equal(ReversedExpectedJson, json); IImmutableQueue iimmutablequeue = ImmutableQueue.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(iimmutablequeue); + json = await Serializer.SerializeWrapper(iimmutablequeue); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(iimmutablequeue); + json = await Serializer.SerializeWrapper(iimmutablequeue); Assert.Equal(ExpectedJson, json); IImmutableSet iimmutableset = ImmutableHashSet.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(iimmutableset); + json = await Serializer.SerializeWrapper(iimmutableset); foreach (string obj in expectedObjects) { Assert.Contains(obj, json); } - json = Serializer.Serialize(iimmutableset); + json = await Serializer.SerializeWrapper(iimmutableset); foreach (string obj in expectedObjects) { Assert.Contains(obj, json); } ImmutableHashSet immutablehashset = ImmutableHashSet.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(immutablehashset); + json = await Serializer.SerializeWrapper(immutablehashset); foreach (string obj in expectedObjects) { Assert.Contains(obj, json); } - json = Serializer.Serialize(immutablehashset); + json = await Serializer.SerializeWrapper(immutablehashset); foreach (string obj in expectedObjects) { Assert.Contains(obj, json); } ImmutableList immutablelist = ImmutableList.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(immutablelist); + json = await Serializer.SerializeWrapper(immutablelist); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(immutablelist); + json = await Serializer.SerializeWrapper(immutablelist); Assert.Equal(ExpectedJson, json); ImmutableStack immutablestack = ImmutableStack.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(immutablestack); + json = await Serializer.SerializeWrapper(immutablestack); Assert.Equal(ReversedExpectedJson, json); - json = Serializer.Serialize(immutablestack); + json = await Serializer.SerializeWrapper(immutablestack); Assert.Equal(ReversedExpectedJson, json); ImmutableQueue immutablequeue = ImmutableQueue.CreateRange(new List { 1, true, address, null, "foo" }); - json = Serializer.Serialize(immutablequeue); + json = await Serializer.SerializeWrapper(immutablequeue); Assert.Equal(ExpectedJson, json); - json = Serializer.Serialize(immutablequeue); + json = await Serializer.SerializeWrapper(immutablequeue); Assert.Equal(ExpectedJson, json); } [Fact] - public void SimpleTestClassAsRootObject() + public async Task SimpleTestClassAsRootObject() { // Sanity checks on test type. Assert.Equal(typeof(object), typeof(SimpleTestClassWithObject).GetProperty("MyInt16").PropertyType); @@ -310,20 +311,20 @@ public void SimpleTestClassAsRootObject() obj.Initialize(); // Verify with actual type. - string json = Serializer.Serialize(obj); + string json = await Serializer.SerializeWrapper(obj); Assert.Contains(@"""MyInt16"":1", json); Assert.Contains(@"""MyBooleanTrue"":true", json); Assert.Contains(@"""MyInt16Array"":[1]", json); // Verify with object type. - json = Serializer.Serialize(obj); + json = await Serializer.SerializeWrapper(obj); Assert.Contains(@"""MyInt16"":1", json); Assert.Contains(@"""MyBooleanTrue"":true", json); Assert.Contains(@"""MyInt16Array"":[1]", json); } [Fact] - public void NestedObjectAsRootObject() + public async Task NestedObjectAsRootObject() { void Verify(string json) { @@ -368,43 +369,43 @@ void Verify(string json) var obj = new ObjectWithObjectProperties(); - string json = Serializer.Serialize(obj); + string json = await Serializer.SerializeWrapper(obj); Verify(json); - json = Serializer.Serialize(obj); + json = await Serializer.SerializeWrapper(obj); Verify(json); } [Fact] - public void NestedObjectAsRootObjectIgnoreNullable() + public async Task NestedObjectAsRootObjectIgnoreNullable() { // Ensure that null properties are properly written and support ignore. var obj = new ObjectWithObjectProperties(); obj.NullableInt = null; - string json = Serializer.Serialize(obj); + string json = await Serializer.SerializeWrapper(obj); Assert.Contains(@"""NullableInt"":null", json); JsonSerializerOptions options = new JsonSerializerOptions(); options.IgnoreNullValues = true; - json = Serializer.Serialize(obj, options); + json = await Serializer.SerializeWrapper(obj, options); Assert.DoesNotContain(@"""NullableInt"":null", json); } [Fact] - public void StaticAnalysisBaseline() + public async Task StaticAnalysisBaseline() { Customer customer = new Customer(); customer.Initialize(); customer.Verify(); - string json = Serializer.Serialize(customer); + string json = await Serializer.SerializeWrapper(customer); Customer deserializedCustomer = JsonSerializer.Deserialize(json); deserializedCustomer.Verify(); } [Fact] - public void StaticAnalysis() + public async Task StaticAnalysis() { Customer customer = new Customer(); customer.Initialize(); @@ -413,7 +414,7 @@ public void StaticAnalysis() Person person = customer; // Generic inference used = - string json = Serializer.Serialize(person); + string json = await Serializer.SerializeWrapper(person); Customer deserializedCustomer = JsonSerializer.Deserialize(json); @@ -424,7 +425,7 @@ public void StaticAnalysis() } [Fact] - public void WriteStringWithRuntimeType() + public async Task WriteStringWithRuntimeType() { Customer customer = new Customer(); customer.Initialize(); @@ -432,7 +433,7 @@ public void WriteStringWithRuntimeType() Person person = customer; - string json = Serializer.Serialize(person, person.GetType()); + string json = await Serializer.SerializeWrapper(person, person.GetType()); Customer deserializedCustomer = JsonSerializer.Deserialize(json); @@ -442,7 +443,7 @@ public void WriteStringWithRuntimeType() } [Fact] - public void StaticAnalysisWithRelationship() + public async Task StaticAnalysisWithRelationship() { UsaCustomer usaCustomer = new UsaCustomer(); usaCustomer.Initialize(); @@ -454,7 +455,7 @@ public void StaticAnalysisWithRelationship() Customer customer = usaCustomer; // Generic inference used = - string json = Serializer.Serialize(customer); + string json = await Serializer.SerializeWrapper(customer); UsaCustomer deserializedCustomer = JsonSerializer.Deserialize(json); @@ -496,18 +497,18 @@ public void GenericDictionaryOfInterface_WithValidJson_ThrowsNotSupportedExcepti } [Fact] - public void AnonymousType() + public async Task AnonymousType() { const string Expected = @"{""x"":1,""y"":true}"; var value = new { x = 1, y = true }; // Strongly-typed. - string json = Serializer.Serialize(value); + string json = await Serializer.SerializeWrapper(value); Assert.Equal(Expected, json); // Boxed. object objValue = value; - json = Serializer.Serialize(objValue); + json = await Serializer.SerializeWrapper(objValue); Assert.Equal(Expected, json); } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ReferenceHandlerTests.Deserialize.cs b/src/libraries/System.Text.Json/tests/Serialization/ReferenceHandlerTests.Deserialize.cs index c63f55329a517..ae7ec150b903b 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ReferenceHandlerTests.Deserialize.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ReferenceHandlerTests.Deserialize.cs @@ -225,8 +225,8 @@ public static void ObjectPropertyLengthZero() Assert.Equal(1, root.ZeroLengthProperty); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public static void TestJsonPathDoesNotFailOnMultiThreads() + [Fact] + public static async Task TestJsonPathDoesNotFailOnMultiThreads() { const int ThreadCount = 8; const int ConcurrentTestsCount = 4; @@ -240,7 +240,7 @@ public static void TestJsonPathDoesNotFailOnMultiThreads() tasks[i] = Task.Run(() => TestRefTask()); } - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } private static void TestIdTask() diff --git a/src/libraries/System.Text.Json/tests/Serialization/SerializationWrapper.cs b/src/libraries/System.Text.Json/tests/Serialization/SerializationWrapper.cs index a92b388b5a6ab..9b933260f27a8 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/SerializationWrapper.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/SerializationWrapper.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.IO; @@ -19,96 +19,90 @@ public abstract class SerializationWrapper public static SerializationWrapper StreamSerializerWithSmallBuffer => new StreamSerializerWrapperWithSmallBuffer(); public static SerializationWrapper WriterSerializer => new WriterSerializerWrapper(); - protected internal abstract string Serialize(object value, Type inputType, JsonSerializerOptions options = null); + protected internal abstract Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null); - protected internal abstract string Serialize(T value, JsonSerializerOptions options = null); + protected internal abstract Task SerializeWrapper(T value, JsonSerializerOptions options = null); private class SpanSerializerWrapper : SerializationWrapper { - protected internal override string Serialize(object value, Type inputType, JsonSerializerOptions options = null) + protected internal override Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null) { byte[] result = JsonSerializer.SerializeToUtf8Bytes(value, inputType, options); - return Encoding.UTF8.GetString(result); + return Task.FromResult(Encoding.UTF8.GetString(result)); } - protected internal override string Serialize(T value, JsonSerializerOptions options = null) + protected internal override Task SerializeWrapper(T value, JsonSerializerOptions options = null) { byte[] result = JsonSerializer.SerializeToUtf8Bytes(value, options); - return Encoding.UTF8.GetString(result); + return Task.FromResult(Encoding.UTF8.GetString(result)); } } private class StringSerializerWrapper : SerializationWrapper { - protected internal override string Serialize(object value, Type inputType, JsonSerializerOptions options = null) + protected internal override Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null) { - return JsonSerializer.Serialize(value, inputType, options); + return Task.FromResult(JsonSerializer.Serialize(value, inputType, options)); } - protected internal override string Serialize(T value, JsonSerializerOptions options = null) + protected internal override Task SerializeWrapper(T value, JsonSerializerOptions options = null) { - return JsonSerializer.Serialize(value, options); + return Task.FromResult(JsonSerializer.Serialize(value, options)); } } private class StreamSerializerWrapper : SerializationWrapper { - protected internal override string Serialize(object value, Type inputType, JsonSerializerOptions options = null) + protected internal override async Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null) { - return Task.Run(async () => - { - using var stream = new MemoryStream(); - await JsonSerializer.SerializeAsync(stream, value, inputType, options); - return Encoding.UTF8.GetString(stream.ToArray()); - }).GetAwaiter().GetResult(); + using var stream = new MemoryStream(); + await JsonSerializer.SerializeAsync(stream, value, inputType, options); + return Encoding.UTF8.GetString(stream.ToArray()); } - protected internal override string Serialize(T value, JsonSerializerOptions options = null) + protected internal override async Task SerializeWrapper(T value, JsonSerializerOptions options = null) { - return Task.Run(async () => - { - using var stream = new MemoryStream(); - await JsonSerializer.SerializeAsync(stream, value, options); - return Encoding.UTF8.GetString(stream.ToArray()); - }).GetAwaiter().GetResult(); + using var stream = new MemoryStream(); + await JsonSerializer.SerializeAsync(stream, value, options); + return Encoding.UTF8.GetString(stream.ToArray()); } } private class StreamSerializerWrapperWithSmallBuffer : StreamSerializerWrapper { - protected internal override string Serialize(object value, Type inputType, JsonSerializerOptions options = null) + protected internal override Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null) { if (options == null) { options = _optionsWithSmallBuffer; } - return base.Serialize(value, inputType, options); + return base.SerializeWrapper(value, inputType, options); } - protected internal override string Serialize(T value, JsonSerializerOptions options = null) + protected internal override Task SerializeWrapper(T value, JsonSerializerOptions options = null) { - return base.Serialize(value, options); + return base.SerializeWrapper(value, options); } } private class WriterSerializerWrapper : SerializationWrapper { - protected internal override string Serialize(object value, Type inputType, JsonSerializerOptions options = null) + protected internal override Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null) { using MemoryStream stream = new MemoryStream(); using var writer = new Utf8JsonWriter(stream); JsonSerializer.Serialize(writer, value, inputType, options); - return Encoding.UTF8.GetString(stream.ToArray()); + return Task.FromResult(Encoding.UTF8.GetString(stream.ToArray())); } - protected internal override string Serialize(T value, JsonSerializerOptions options = null) + protected internal override Task SerializeWrapper(T value, JsonSerializerOptions options = null) { using MemoryStream stream = new MemoryStream(); using var writer = new Utf8JsonWriter(stream); JsonSerializer.Serialize(writer, value, options); - return Encoding.UTF8.GetString(stream.ToArray()); + return Task.FromResult(Encoding.UTF8.GetString(stream.ToArray())); } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/Stream.Collections.cs b/src/libraries/System.Text.Json/tests/Serialization/Stream.Collections.cs index 3a46b5149f710..4810dcb384103 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Stream.Collections.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Stream.Collections.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; @@ -18,14 +18,15 @@ public static partial class StreamTests { [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/35927", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoInterpreter))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/35927", TestPlatforms.Browser)] public static async Task HandleCollectionsAsync() { - await RunTest(); - await RunTest(); - await RunTest(); + await RunTestAsync(); + await RunTestAsync(); + await RunTestAsync(); } - private static async Task RunTest() + private static async Task RunTestAsync() { foreach ((Type, int) pair in CollectionTestData()) { diff --git a/src/libraries/System.Text.Json/tests/Serialization/Stream.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Stream.ReadTests.cs index d365fc580774f..1881fc82aabac 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Stream.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Stream.ReadTests.cs @@ -19,7 +19,7 @@ public static async Task ReadNullArgumentFail() await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync(new MemoryStream(), (Type)null)); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Fact] public static async Task ReadSimpleObjectAsync() { using (MemoryStream stream = new MemoryStream(SimpleTestClass.s_data)) @@ -34,7 +34,7 @@ public static async Task ReadSimpleObjectAsync() } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [Fact] public static async Task ReadSimpleObjectWithTrailingTriviaAsync() { byte[] data = Encoding.UTF8.GetBytes(SimpleTestClass.s_json + " /* Multi\r\nLine Comment */\t"); diff --git a/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.MultiSegment.cs b/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.MultiSegment.cs index a7bcbda8ebca5..6862a129f395b 100644 --- a/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.MultiSegment.cs +++ b/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.MultiSegment.cs @@ -485,6 +485,12 @@ public static void TestJsonReaderUtf8SegmentSizeOne(bool compactData, TestCaseTy [MemberData(nameof(LargeTestCases))] public static void TestJsonReaderLargeUtf8SegmentSizeOne(bool compactData, TestCaseType type, string jsonString) { + // Skipping really large JSON on Browser to prevent OOM + if (PlatformDetection.IsBrowser && (type == TestCaseType.Json40KB || type == TestCaseType.Json400KB || type == TestCaseType.ProjectLockJson)) + { + return; + } + ReadFullySegmentSizeOne(compactData, type, jsonString); } diff --git a/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs b/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs index 2945aeb71aaf4..50926d7af7244 100644 --- a/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs +++ b/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using Microsoft.DotNet.XUnitExtensions; using Newtonsoft.Json; using Xunit; @@ -1608,7 +1609,7 @@ public static void TestPartialJsonReaderSlicesSpecialNumbers(TestCaseType type, } } - [Theory] + [ConditionalTheory] [InlineData(1)] [InlineData(2)] [InlineData(4)] @@ -1625,6 +1626,11 @@ public static void TestPartialJsonReaderSlicesSpecialNumbers(TestCaseType type, [InlineData(512)] public static void TestDepth(int depth) { + if (PlatformDetection.IsMonoInterpreter && depth >= 256) + { + throw new SkipTestException("Takes very long to run on interpreter."); + } + foreach (JsonCommentHandling commentHandling in Enum.GetValues(typeof(JsonCommentHandling))) { for (int i = 0; i < depth; i++) diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 9d885854f756b..fc3cd91d0b7e0 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -21,8 +21,6 @@ - -