From 7cd778335781c1f75769a76c2ba56d76709a20b2 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Tue, 25 Aug 2020 13:22:21 -0700 Subject: [PATCH] Add tests mapping invalid JSON to objects with parameterized ctors (#41121) * Move invalid JSON tests to dedicated file * Add tests mapping invalid JSON to objects with parameterized ctors --- .../CollectionTests/CollectionTests.Dictionary.cs | 302 ------------------- .../tests/Serialization/InvalidJsonTests.cs | 335 +++++++++++++++++++++ .../tests/Serialization/TestClasses/TestClasses.cs | 10 + .../tests/System.Text.Json.Tests.csproj | 3 +- 4 files changed, 347 insertions(+), 303 deletions(-) create mode 100644 src/libraries/System.Text.Json/tests/Serialization/InvalidJsonTests.cs diff --git a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Dictionary.cs b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Dictionary.cs index 842aa8e..2c66ee7 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Dictionary.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Dictionary.cs @@ -6,7 +6,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Collections.Specialized; -using System.Reflection; using System.Text.Encodings.Web; using Xunit; @@ -313,297 +312,6 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal("Software Architect", obj["Job"]); } - [Theory] - [InlineData(typeof(ImmutableDictionary), "\"headers\"")] - [InlineData(typeof(Dictionary), "\"headers\"")] - [InlineData(typeof(PocoDictionary), "\"headers\"")] - public static void InvalidJsonForValueShouldFail(Type type, string json) - { - Assert.Throws(() => JsonSerializer.Deserialize(json, type)); - } - - public static IEnumerable InvalidJsonForIntValue() - { - yield return @"""1"""; - yield return "["; - yield return "}"; - yield return @"[""1""]"; - yield return "[true]"; - } - - public static IEnumerable InvalidJsonForPoco() - { - foreach (string value in InvalidJsonForIntValue()) - { - yield return value; - yield return "[" + value + "]"; - yield return "{" + value + "}"; - yield return @"{""Id"":" + value + "}"; - } - } - - public class ClassWithInt - { - public int Obj { get; set; } - } - - public class ClassWithIntList - { - public List Obj { get; set; } - } - - public class ClassWithIntArray - { - public int[] Obj { get; set; } - } - - public class ClassWithPoco - { - public Poco Obj { get; set; } - } - - public class ClassWithPocoArray - { - public Poco[] Obj { get; set; } - } - - public class ClassWithDictionaryOfIntArray - { - public Dictionary Obj { get; set; } - } - - public class ClassWithDictionaryOfPoco - { - public Dictionary Obj { get; set; } - } - - public class ClassWithDictionaryOfPocoList - { - public Dictionary> Obj { get; set; } - } - - public static IEnumerable TypesForInvalidJsonForCollectionTests() - { - static Type MakeClosedCollectionType(Type openCollectionType, Type elementType) - { - if (openCollectionType == typeof(Dictionary<,>)) - { - return typeof(Dictionary<,>).MakeGenericType(typeof(string), elementType); - } - else - { - return openCollectionType.MakeGenericType(elementType); - } - } - - Type[] elementTypes = new Type[] - { - typeof(int), - typeof(Poco), - typeof(ClassWithInt), - typeof(ClassWithIntList), - typeof(ClassWithPoco), - typeof(ClassWithPocoArray), - typeof(ClassWithDictionaryOfIntArray), - typeof(ClassWithDictionaryOfPoco), - typeof(ClassWithDictionaryOfPocoList), - }; - - Type[] collectionTypes = new Type[] - { - typeof(List<>), - typeof(Dictionary<,>), - }; - - foreach (Type type in elementTypes) - { - yield return type; - } - - List innerTypes = new List(elementTypes); - - // Create permutations of collections with 1 and 2 levels of nesting. - for (int i = 0; i < 2; i++) - { - foreach (Type collectionType in collectionTypes) - { - List newInnerTypes = new List(); - - foreach (Type elementType in innerTypes) - { - Type newCollectionType = MakeClosedCollectionType(collectionType, elementType); - newInnerTypes.Add(newCollectionType); - yield return newCollectionType; - } - - innerTypes = newInnerTypes; - } - } - } - - static IEnumerable GetInvalidJsonStringsForType(Type type) - { - if (type == typeof(int)) - { - foreach (string json in InvalidJsonForIntValue()) - { - yield return json; - } - yield break; - } - - if (type == typeof(Poco)) - { - foreach (string json in InvalidJsonForPoco()) - { - yield return json; - } - yield break; - } - - Type elementType; - - if (!typeof(IEnumerable).IsAssignableFrom(type)) - { - // Get type of "Obj" property. - elementType = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)[0].PropertyType; - } - else if (type.IsArray) - { - elementType = type.GetElementType(); - } - else if (!type.IsGenericType) - { - Assert.True(false, "Expected generic type"); - yield break; - } - else - { - Type genericTypeDef = type.GetGenericTypeDefinition(); - - if (genericTypeDef == typeof(List<>)) - { - elementType = type.GetGenericArguments()[0]; - } - else if (genericTypeDef == typeof(Dictionary<,>)) - { - elementType = type.GetGenericArguments()[1]; - } - else - { - Assert.True(false, "Expected List or Dictionary type"); - yield break; - } - } - - foreach (string invalidJson in GetInvalidJsonStringsForType(elementType)) - { - yield return "[" + invalidJson + "]"; - yield return "{" + invalidJson + "}"; - yield return @"{""Obj"":" + invalidJson + "}"; - } - } - - public static IEnumerable DataForInvalidJsonForTypeTests() - { - foreach (Type type in TypesForInvalidJsonForCollectionTests()) - { - foreach (string invalidJson in GetInvalidJsonStringsForType(type)) - { - yield return new object[] { type, invalidJson }; - } - } - - yield return new object[] { typeof(int[]), @"""test""" }; - yield return new object[] { typeof(int[]), @"1" }; - yield return new object[] { typeof(int[]), @"false" }; - yield return new object[] { typeof(int[]), @"{}" }; - yield return new object[] { typeof(int[]), @"{""test"": 1}" }; - yield return new object[] { typeof(int[]), @"[""test""" }; - yield return new object[] { typeof(int[]), @"[""test""]" }; - yield return new object[] { typeof(int[]), @"[true]" }; - yield return new object[] { typeof(int[]), @"[{}]" }; - yield return new object[] { typeof(int[]), @"[[]]" }; - yield return new object[] { typeof(int[]), @"[{""test"": 1}]" }; - yield return new object[] { typeof(int[]), @"[[true]]" }; - yield return new object[] { typeof(Dictionary), @"{""test"": {}}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": {""test"": 1}}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": ""test""}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": 1}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": true}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": [""test""}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": [""test""]}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": [[]]}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": [true]}" }; - yield return new object[] { typeof(Dictionary), @"{""test"": [{}]}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": ""test""}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": 1}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": false}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": {}}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": {""test"": 1}}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [""test""}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [""test""]}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [true]}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [{}]}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [[]]}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [{""test"": 1}]}" }; - yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [[true]]}" }; - yield return new object[] { typeof(Dictionary), @"""test""" }; - yield return new object[] { typeof(Dictionary), @"1" }; - yield return new object[] { typeof(Dictionary), @"false" }; - yield return new object[] { typeof(Dictionary), @"{"""": 1}" }; - yield return new object[] { typeof(Dictionary), @"{"""": {}}" }; - yield return new object[] { typeof(Dictionary), @"{"""": {"""":""""}}" }; - yield return new object[] { typeof(Dictionary), @"[""test""" }; - yield return new object[] { typeof(Dictionary), @"[""test""]" }; - yield return new object[] { typeof(Dictionary), @"[true]" }; - yield return new object[] { typeof(Dictionary), @"[{}]" }; - yield return new object[] { typeof(Dictionary), @"[[]]" }; - yield return new object[] { typeof(Dictionary), @"[{""test"": 1}]" }; - yield return new object[] { typeof(Dictionary), @"[[true]]" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":""test""}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":1}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":false}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":{"""": 1}}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":{"""": {}}}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":{"""": {"""":""""}}}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[""test""}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[""test""]}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[true]}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[{}]}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[[]]}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[{""test"": 1}]}" }; - yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[[true]]}" }; - yield return new object[] { typeof(Dictionary), @"{""key"":[{""Id"":3}]}" }; - yield return new object[] { typeof(Dictionary), @"{""key"":[""test""]}" }; - yield return new object[] { typeof(Dictionary), @"{""key"":[1]}" }; - yield return new object[] { typeof(Dictionary), @"{""key"":[false]}" }; - yield return new object[] { typeof(Dictionary), @"{""key"":[]}" }; - yield return new object[] { typeof(Dictionary), @"{""key"":1}" }; - yield return new object[] { typeof(Dictionary>), @"{""key"":{""Id"":3}}" }; - yield return new object[] { typeof(Dictionary>), @"{""key"":{}}" }; - yield return new object[] { typeof(Dictionary>), @"{""key"":[[]]}" }; - yield return new object[] { typeof(Dictionary>), @"{""key"":[]}" }; - yield return new object[] { typeof(Dictionary>), @"{""key"":1}" }; - } - - [Fact] - public static void InvalidJsonForTypeShouldFail() - { - foreach (object[] args in DataForInvalidJsonForTypeTests()) // ~140K tests, too many for theory to handle well with our infrastructure - { - var type = (Type)args[0]; - var invalidJson = (string)args[1]; - Assert.Throws(() => JsonSerializer.Deserialize(invalidJson, type)); - } - } - - [Fact] - public static void InvalidEmptyDictionaryInput() - { - Assert.Throws(() => JsonSerializer.Deserialize("{}")); - } - [Fact] public static void PocoWithDictionaryObject() { @@ -612,11 +320,6 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal("d", dict.key["c"]); } - public class PocoDictionary - { - public Dictionary key { get; set; } - } - [Fact] public static void DictionaryOfObject_NonPrimitiveTypes() { @@ -635,11 +338,6 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal(@"{""Id"":10}", element.ToString()); } - public class Poco - { - public int Id { get; set; } - } - [Fact] public static void DictionaryOfList() { diff --git a/src/libraries/System.Text.Json/tests/Serialization/InvalidJsonTests.cs b/src/libraries/System.Text.Json/tests/Serialization/InvalidJsonTests.cs new file mode 100644 index 0000000..71092e9 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/Serialization/InvalidJsonTests.cs @@ -0,0 +1,335 @@ +// 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; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Reflection; +using Xunit; + +namespace System.Text.Json.Serialization.Tests +{ + public static class InvalidJsonTests + { + [Theory] + [InlineData(typeof(ImmutableDictionary), "\"headers\"")] + [InlineData(typeof(Dictionary), "\"headers\"")] + [InlineData(typeof(PocoDictionary), "\"headers\"")] + public static void InvalidJsonForValueShouldFail(Type type, string json) + { + Assert.Throws(() => JsonSerializer.Deserialize(json, type)); + } + + public static IEnumerable InvalidJsonForIntValue() + { + yield return @"""1"""; + yield return "["; + yield return "}"; + yield return @"[""1""]"; + yield return "[true]"; + } + + public static IEnumerable InvalidJsonForPoco() + { + foreach (string value in InvalidJsonForIntValue()) + { + yield return value; + yield return "[" + value + "]"; + yield return "{" + value + "}"; + yield return @"{""Id"":" + value + "}"; + } + } + + public class PocoWithParameterizedCtor + { + public int Obj { get; set; } + } + + public class ClassWithInt + { + public int Obj { get; set; } + } + + public class ClassWithIntList + { + public List Obj { get; set; } + } + + public class ClassWithIntArray + { + public int[] Obj { get; set; } + } + + public class ClassWithPoco + { + public Poco Obj { get; set; } + } + + public class ClassWithParameterizedCtor_WithPoco + { + public PocoWithParameterizedCtor Obj { get; set; } + + public ClassWithParameterizedCtor_WithPoco(PocoWithParameterizedCtor obj) => Obj = obj; + } + + public class ClassWithPocoArray + { + public Poco[] Obj { get; set; } + } + + public class ClassWithParameterizedCtor_WithPocoArray + { + public PocoWithParameterizedCtor[] Obj { get; set; } + + public ClassWithParameterizedCtor_WithPocoArray(PocoWithParameterizedCtor[] obj) => Obj = obj; + } + + public class ClassWithDictionaryOfIntArray + { + public Dictionary Obj { get; set; } + } + + public class ClassWithDictionaryOfPoco + { + public Dictionary Obj { get; set; } + } + + public class ClassWithDictionaryOfPocoList + { + public Dictionary> Obj { get; set; } + } + + public class ClassWithParameterizedCtor_WithDictionaryOfPocoList + { + public Dictionary> Obj { get; set; } + + public ClassWithParameterizedCtor_WithDictionaryOfPocoList(Dictionary> obj) => Obj = obj; + } + + public static IEnumerable TypesForInvalidJsonForCollectionTests() + { + static Type MakeClosedCollectionType(Type openCollectionType, Type elementType) + { + if (openCollectionType == typeof(Dictionary<,>)) + { + return typeof(Dictionary<,>).MakeGenericType(typeof(string), elementType); + } + else + { + return openCollectionType.MakeGenericType(elementType); + } + } + + Type[] elementTypes = new Type[] + { + typeof(int), + typeof(Poco), + typeof(ClassWithInt), + typeof(ClassWithIntList), + typeof(ClassWithPoco), + typeof(ClassWithPocoArray), + typeof(ClassWithDictionaryOfIntArray), + typeof(ClassWithDictionaryOfPoco), + typeof(ClassWithDictionaryOfPocoList), + typeof(PocoWithParameterizedCtor), + typeof(ClassWithParameterizedCtor_WithPoco), + typeof(ClassWithParameterizedCtor_WithPocoArray), + typeof(ClassWithParameterizedCtor_WithDictionaryOfPocoList), + }; + + Type[] collectionTypes = new Type[] + { + typeof(List<>), + typeof(Dictionary<,>), + }; + + foreach (Type type in elementTypes) + { + yield return type; + } + + List innerTypes = new List(elementTypes); + + // Create permutations of collections with 1 and 2 levels of nesting. + for (int i = 0; i < 2; i++) + { + foreach (Type collectionType in collectionTypes) + { + List newInnerTypes = new List(); + + foreach (Type elementType in innerTypes) + { + Type newCollectionType = MakeClosedCollectionType(collectionType, elementType); + newInnerTypes.Add(newCollectionType); + yield return newCollectionType; + } + + innerTypes = newInnerTypes; + } + } + } + + static IEnumerable GetInvalidJsonStringsForType(Type type) + { + if (type == typeof(int)) + { + foreach (string json in InvalidJsonForIntValue()) + { + yield return json; + } + yield break; + } + + if (type == typeof(Poco)) + { + foreach (string json in InvalidJsonForPoco()) + { + yield return json; + } + yield break; + } + + Type elementType; + + if (!typeof(IEnumerable).IsAssignableFrom(type)) + { + // Get type of "Obj" property. + elementType = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)[0].PropertyType; + } + else if (type.IsArray) + { + elementType = type.GetElementType(); + } + else if (!type.IsGenericType) + { + Assert.True(false, "Expected generic type"); + yield break; + } + else + { + Type genericTypeDef = type.GetGenericTypeDefinition(); + + if (genericTypeDef == typeof(List<>)) + { + elementType = type.GetGenericArguments()[0]; + } + else if (genericTypeDef == typeof(Dictionary<,>)) + { + elementType = type.GetGenericArguments()[1]; + } + else + { + Assert.True(false, "Expected List or Dictionary type"); + yield break; + } + } + + foreach (string invalidJson in GetInvalidJsonStringsForType(elementType)) + { + yield return "[" + invalidJson + "]"; + yield return "{" + invalidJson + "}"; + yield return @"{""Obj"":" + invalidJson + "}"; + } + } + + public static IEnumerable DataForInvalidJsonForTypeTests() + { + foreach (Type type in TypesForInvalidJsonForCollectionTests()) + { + foreach (string invalidJson in GetInvalidJsonStringsForType(type)) + { + yield return new object[] { type, invalidJson }; + } + } + + yield return new object[] { typeof(int[]), @"""test""" }; + yield return new object[] { typeof(int[]), @"1" }; + yield return new object[] { typeof(int[]), @"false" }; + yield return new object[] { typeof(int[]), @"{}" }; + yield return new object[] { typeof(int[]), @"{""test"": 1}" }; + yield return new object[] { typeof(int[]), @"[""test""" }; + yield return new object[] { typeof(int[]), @"[""test""]" }; + yield return new object[] { typeof(int[]), @"[true]" }; + yield return new object[] { typeof(int[]), @"[{}]" }; + yield return new object[] { typeof(int[]), @"[[]]" }; + yield return new object[] { typeof(int[]), @"[{""test"": 1}]" }; + yield return new object[] { typeof(int[]), @"[[true]]" }; + yield return new object[] { typeof(Dictionary), @"{""test"": {}}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": {""test"": 1}}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": ""test""}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": 1}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": true}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": [""test""}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": [""test""]}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": [[]]}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": [true]}" }; + yield return new object[] { typeof(Dictionary), @"{""test"": [{}]}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": ""test""}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": 1}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": false}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": {}}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": {""test"": 1}}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [""test""}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [""test""]}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [true]}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [{}]}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [[]]}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [{""test"": 1}]}" }; + yield return new object[] { typeof(ClassWithIntArray), @"{""Obj"": [[true]]}" }; + yield return new object[] { typeof(Dictionary), @"""test""" }; + yield return new object[] { typeof(Dictionary), @"1" }; + yield return new object[] { typeof(Dictionary), @"false" }; + yield return new object[] { typeof(Dictionary), @"{"""": 1}" }; + yield return new object[] { typeof(Dictionary), @"{"""": {}}" }; + yield return new object[] { typeof(Dictionary), @"{"""": {"""":""""}}" }; + yield return new object[] { typeof(Dictionary), @"[""test""" }; + yield return new object[] { typeof(Dictionary), @"[""test""]" }; + yield return new object[] { typeof(Dictionary), @"[true]" }; + yield return new object[] { typeof(Dictionary), @"[{}]" }; + yield return new object[] { typeof(Dictionary), @"[[]]" }; + yield return new object[] { typeof(Dictionary), @"[{""test"": 1}]" }; + yield return new object[] { typeof(Dictionary), @"[[true]]" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":""test""}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":1}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":false}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":{"""": 1}}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":{"""": {}}}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":{"""": {"""":""""}}}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[""test""}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[""test""]}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[true]}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[{}]}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[[]]}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[{""test"": 1}]}" }; + yield return new object[] { typeof(ClassWithDictionaryOfIntArray), @"{""Obj"":[[true]]}" }; + yield return new object[] { typeof(Dictionary), @"{""key"":[{""Id"":3}]}" }; + yield return new object[] { typeof(Dictionary), @"{""key"":[""test""]}" }; + yield return new object[] { typeof(Dictionary), @"{""key"":[1]}" }; + yield return new object[] { typeof(Dictionary), @"{""key"":[false]}" }; + yield return new object[] { typeof(Dictionary), @"{""key"":[]}" }; + yield return new object[] { typeof(Dictionary), @"{""key"":1}" }; + yield return new object[] { typeof(Dictionary>), @"{""key"":{""Id"":3}}" }; + yield return new object[] { typeof(Dictionary>), @"{""key"":{}}" }; + yield return new object[] { typeof(Dictionary>), @"{""key"":[[]]}" }; + yield return new object[] { typeof(Dictionary>), @"{""key"":[]}" }; + yield return new object[] { typeof(Dictionary>), @"{""key"":1}" }; + } + + [Fact] + public static void InvalidJsonForTypeShouldFail() + { + foreach (object[] args in DataForInvalidJsonForTypeTests()) // ~140K tests, too many for theory to handle well with our infrastructure + { + var type = (Type)args[0]; + var invalidJson = (string)args[1]; + Assert.Throws(() => JsonSerializer.Deserialize(invalidJson, type)); + } + } + + [Fact] + public static void InvalidEmptyDictionaryInput() + { + Assert.Throws(() => JsonSerializer.Deserialize("{}")); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.cs index 34f96f7..e918abd 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.cs @@ -1955,4 +1955,14 @@ namespace System.Text.Json.Serialization.Tests yield return typeof(SortedList); // IDictionaryConverter } } + + public class PocoDictionary + { + public Dictionary key { get; set; } + } + + public class Poco + { + public int Id { get; set; } + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj index 74459b8..f3a485b 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);net461 true @@ -87,6 +87,7 @@ + -- 2.7.4