public async Task ReadSimpleObjectWithTrailingTriviaAsync()
        {
            async Task RunTestAsync <T>(string testData)
            {
                byte[] data = Encoding.UTF8.GetBytes(testData + " /* Multi\r\nLine Comment */\t");
                using (MemoryStream stream = new MemoryStream(data))
                {
                    JsonSerializerOptions options = new JsonSerializerOptions
                    {
                        DefaultBufferSize   = 1,
                        ReadCommentHandling = JsonCommentHandling.Skip,
                    };

                    var obj = await JsonSerializerWrapperForStream.DeserializeWrapper <T>(stream, options);

                    ((ITestClass)obj).Verify();
                }
            }

            // Array size is the count of the following tests.
            Task[] tasks = new Task[14];

            // Simple models can be deserialized.
            tasks[0] = Task.Run(async() => await RunTestAsync <Parameterized_IndexViewModel_Immutable>(Parameterized_IndexViewModel_Immutable.s_json));
            // Complex models can be deserialized.
            tasks[1] = Task.Run(async() => await RunTestAsync <ObjWCtorMixedParams>(ObjWCtorMixedParams.s_json));
            tasks[2] = Task.Run(async() => await RunTestAsync <Parameterized_Class_With_ComplexTuple>(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 RunTestAsync <Person_Class>(Person_Class.s_json));
            tasks[4] = Task.Run(async() => await RunTestAsync <Person_Struct>(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 RunTestAsync <Parameterized_Person>(Parameterized_Person.s_json));
            tasks[6] = Task.Run(async() => await RunTestAsync <Parameterized_Person_ObjExtData>(Parameterized_Person_ObjExtData.s_json));
            // Up to 64 ctor args are supported.
            tasks[7] = Task.Run(async() => await RunTestAsync <Class_With_Ctor_With_64_Params>(Encoding.UTF8.GetString(Class_With_Ctor_With_64_Params.Data)));
            // Arg8deserialization honors attributes on matching property.
            tasks[8]  = Task.Run(async() => await RunTestAsync <Point_MembersHave_JsonPropertyName>(Point_MembersHave_JsonPropertyName.s_json));
            tasks[9]  = Task.Run(async() => await RunTestAsync <Point_MembersHave_JsonConverter>(Point_MembersHave_JsonConverter.s_json));
            tasks[10] = Task.Run(async() => await RunTestAsync <Point_MembersHave_JsonIgnore>(Point_MembersHave_JsonIgnore.s_json));
            // Complex JSON as last argument works
            tasks[11] = Task.Run(async() => await RunTestAsync <Point_With_Array>(Point_With_Array.s_json));
            tasks[12] = Task.Run(async() => await RunTestAsync <Point_With_Dictionary>(Point_With_Dictionary.s_json));
            tasks[13] = Task.Run(async() => await RunTestAsync <Point_With_Object>(Point_With_Object.s_json));

            await Task.WhenAll(tasks);
        }
        public async Task ReadSimpleObjectAsync()
        {
            async Task RunTestAsync <T>(byte[] testData)
            {
                using (MemoryStream stream = new MemoryStream(testData))
                {
                    JsonSerializerOptions options = new JsonSerializerOptions
                    {
                        DefaultBufferSize = 1
                    };

                    var obj = await JsonSerializerWrapperForStream.DeserializeWrapper <T>(stream, options);

                    ((ITestClass)obj).Verify();
                }
            }

            // Array size is the count of the following tests.
            Task[] tasks = new Task[16];

            // Simple models can be deserialized.
            tasks[0] = Task.Run(async() => await RunTestAsync <Parameterized_IndexViewModel_Immutable>(Parameterized_IndexViewModel_Immutable.s_data));
            // Complex models can be deserialized.
            tasks[1] = Task.Run(async() => await RunTestAsync <ClassWithConstructor_SimpleAndComplexParameters>(ClassWithConstructor_SimpleAndComplexParameters.s_data));
            tasks[2] = Task.Run(async() => await RunTestAsync <Parameterized_Class_With_ComplexTuple>(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 RunTestAsync <Person_Class>(Person_Class.s_data));
            tasks[4] = Task.Run(async() => await RunTestAsync <Person_Struct>(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 RunTestAsync <Parameterized_Person>(Parameterized_Person.s_data));
            tasks[6] = Task.Run(async() => await RunTestAsync <Parameterized_Person_ObjExtData>(Parameterized_Person_ObjExtData.s_data));
            // Up to 64 ctor args are supported.
            tasks[7] = Task.Run(async() => await RunTestAsync <Class_With_Ctor_With_64_Params>(Class_With_Ctor_With_64_Params.Data));
            // Arg deserialization honors attributes on matching property.
            tasks[8]  = Task.Run(async() => await RunTestAsync <Point_MembersHave_JsonPropertyName>(Point_MembersHave_JsonPropertyName.s_data));
            tasks[9]  = Task.Run(async() => await RunTestAsync <Point_MembersHave_JsonConverter>(Point_MembersHave_JsonConverter.s_data));
            tasks[10] = Task.Run(async() => await RunTestAsync <Point_MembersHave_JsonIgnore>(Point_MembersHave_JsonIgnore.s_data));
            tasks[11] = Task.Run(async() => await RunTestAsync <Point_MembersHave_JsonInclude>(Point_MembersHave_JsonInclude.s_data));
            tasks[12] = Task.Run(async() => await RunTestAsync <ClassWithFiveArgs_MembersHave_JsonNumberHandlingAttributes>(ClassWithFiveArgs_MembersHave_JsonNumberHandlingAttributes.s_data));
            // Complex JSON as last argument works
            tasks[13] = Task.Run(async() => await RunTestAsync <Point_With_Array>(Point_With_Array.s_data));
            tasks[14] = Task.Run(async() => await RunTestAsync <Point_With_Dictionary>(Point_With_Dictionary.s_data));
            tasks[15] = Task.Run(async() => await RunTestAsync <Point_With_Object>(Point_With_Object.s_data));

            await Task.WhenAll(tasks);
        }
        public async Task Cannot_DeserializeAsync_ObjectWith_Ctor_With_65_Params()
        {
            async Task RunTestAsync <T>()
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("{");
                for (int i = 0; i < 64; i++)
                {
                    sb.Append($@"""Int{i}"":{i},");
                }
                sb.Append($@"""Int64"":64");
                sb.Append("}");

                string input = sb.ToString();

                using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(input)))
                {
                    JsonSerializerOptions options = new JsonSerializerOptions
                    {
                        DefaultBufferSize = 1
                    };

                    await Assert.ThrowsAsync <NotSupportedException>(async() => await JsonSerializerWrapperForStream.DeserializeWrapper <T>(stream, options));
                }

                using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes("{}")))
                {
                    JsonSerializerOptions options = new JsonSerializerOptions
                    {
                        DefaultBufferSize = 1
                    };

                    await Assert.ThrowsAsync <NotSupportedException>(async() => await JsonSerializerWrapperForStream.DeserializeWrapper <T>(stream, options));
                }
            }

            Task[] tasks = new Task[2];

            tasks[0] = Task.Run(async() => await RunTestAsync <Class_With_Ctor_With_65_Params>());
            tasks[1] = Task.Run(async() => await RunTestAsync <Struct_With_Ctor_With_65_Params>());

            await Task.WhenAll(tasks);
        }