From: Layomi Akinrinade Date: Sat, 13 Apr 2019 01:44:18 +0000 (-0400) Subject: Add support for generic interface-based collections in JsonSerializer (dotnet/corefx... X-Git-Tag: submit/tizen/20210909.063632~11031^2~1897 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2d8ee2c01fde1412648b91639f219587d1bf0dc3;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Add support for generic interface-based collections in JsonSerializer (dotnet/corefx#36756) * Add support for generic interface-based collections in JsonSerializer Specifically, add enumerable converters for: * IEnumerable * ICollection * IList * IReadOnlyCollection * IReadOnlyList This partially addresses https://github.com/dotnet/corefx/issues/36643 * Address review comments * Add serialization tests for generic interface collection as members of class objects Commit migrated from https://github.com/dotnet/corefx/commit/cc01ec9a781c4af5afd495c5b80a1f7d9616bed2 --- diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 0c8fe87..b22566c 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -47,6 +47,7 @@ + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultEnumerableConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultEnumerableConverter.cs new file mode 100644 index 0000000..afddd65 --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultEnumerableConverter.cs @@ -0,0 +1,90 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text.Json.Serialization.Policies; + +namespace System.Text.Json.Serialization.Converters +{ + internal class JsonEnumerableT : ICollection, IEnumerable, IList, IReadOnlyCollection, IReadOnlyList + { + List _list; + + public JsonEnumerableT(IList sourceList) + { + // TODO: Change sourceList from IList to List so we can do a direct assignment here. + _list = new List(); + + foreach (object item in sourceList) + { + if (item is T itemT) + { + _list.Add(itemT); + } + } + } + + public T this[int index] { get => (T)_list[index]; set => _list[index] = value; } + + public int Count => _list.Count; + + public bool IsReadOnly => false; + + public void Add(T item) + { + _list.Add(item); + } + + public void Clear() + { + _list.Clear(); + } + + public bool Contains(T item) + { + return _list.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + _list.CopyTo(array, arrayIndex); + } + + public IEnumerator GetEnumerator() + { + return _list.GetEnumerator(); + } + + public int IndexOf(T item) + { + return _list.IndexOf(item); + } + + public void Insert(int index, T item) + { + _list.Insert(index, item); + } + + public bool Remove(T item) + { + return _list.Remove(item); + } + + public void RemoveAt(int index) + { + _list.RemoveAt(index); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + internal sealed class DefaultEnumerableConverter : JsonEnumerableConverter + { + public override IEnumerable CreateFromList(Type elementType, IList sourceList) + { + Type t = typeof(JsonEnumerableT<>).MakeGenericType(elementType); + return (IEnumerable)Activator.CreateInstance(t, sourceList); + } + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index 3ce5bbc..621277b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -275,7 +275,7 @@ namespace System.Text.Json.Serialization } - private static Type GetElementType(Type propertyType) + public static Type GetElementType(Type propertyType) { Type elementType = null; if (typeof(IEnumerable).IsAssignableFrom(propertyType)) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs index 7201cba..bcd3037 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections; using System.Reflection; using System.Text.Json.Serialization.Converters; using System.Text.Json.Serialization.Policies; @@ -10,9 +11,6 @@ namespace System.Text.Json.Serialization { internal abstract class JsonPropertyInfo { - // For now, just a global converter. - private static JsonEnumerableConverter s_jsonEnumerableConverter = new DefaultArrayConverter(); - internal ClassType ClassType; internal byte[] _name = default; @@ -70,7 +68,16 @@ namespace System.Text.Json.Serialization { if (RuntimePropertyType.IsArray) { - EnumerableConverter = s_jsonEnumerableConverter; + EnumerableConverter = new DefaultArrayConverter(); + } + else if (typeof(IEnumerable).IsAssignableFrom(RuntimePropertyType)) + { + Type elementType = JsonClassInfo.GetElementType(RuntimePropertyType); + + if (RuntimePropertyType.IsAssignableFrom(typeof(JsonEnumerableT<>).MakeGenericType(elementType))) + { + EnumerableConverter = new DefaultEnumerableConverter(); + } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs index d4db11d..a07b4d0 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs @@ -35,5 +35,75 @@ namespace System.Text.Json.Serialization.Tests TestClassWithGenericList obj = JsonSerializer.Parse(TestClassWithGenericList.s_data); obj.Verify(); } + + [Fact] + public static void ReadClassWithObjectIEnumerableT() + { + TestClassWithObjectIEnumerableT obj = JsonSerializer.Parse(TestClassWithObjectIEnumerableT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithObjectIListT() + { + TestClassWithObjectIListT obj = JsonSerializer.Parse(TestClassWithObjectIListT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithObjectICollectionT() + { + TestClassWithObjectICollectionT obj = JsonSerializer.Parse(TestClassWithObjectICollectionT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithObjectIReadOnlyCollectionT() + { + TestClassWithObjectIReadOnlyCollectionT obj = JsonSerializer.Parse(TestClassWithObjectIReadOnlyCollectionT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithObjectIReadOnlyListT() + { + TestClassWithObjectIReadOnlyListT obj = JsonSerializer.Parse(TestClassWithObjectIReadOnlyListT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithGenericIEnumerableT() + { + TestClassWithGenericIEnumerableT obj = JsonSerializer.Parse(TestClassWithGenericIEnumerableT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithGenericIListT() + { + TestClassWithGenericIListT obj = JsonSerializer.Parse(TestClassWithGenericIListT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithGenericICollectionT() + { + TestClassWithGenericICollectionT obj = JsonSerializer.Parse(TestClassWithGenericICollectionT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithGenericIReadOnlyCollectionT() + { + TestClassWithGenericIReadOnlyCollectionT obj = JsonSerializer.Parse(TestClassWithGenericIReadOnlyCollectionT.s_data); + obj.Verify(); + } + + [Fact] + public static void ReadClassWithGenericIReadOnlyListT() + { + TestClassWithGenericIReadOnlyListT obj = JsonSerializer.Parse(TestClassWithGenericIReadOnlyListT.s_data); + obj.Verify(); + } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/Array.WriteTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Array.WriteTests.cs index 5c0197f..1a63ef8 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Array.WriteTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Array.WriteTests.cs @@ -37,6 +37,31 @@ namespace System.Text.Json.Serialization.Tests string json; { + TestClassWithObjectList obj = new TestClassWithObjectList(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithObjectList obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithObjectList obj = JsonSerializer.Parse(TestClassWithObjectList.s_data); + obj.Verify(); + } + } + + + + [Fact] + public static void WriteClassWithGenericList() + { + string json; + + { TestClassWithGenericList obj = new TestClassWithGenericList(); obj.Initialize(); obj.Verify(); @@ -54,25 +79,231 @@ namespace System.Text.Json.Serialization.Tests } } + public static void WriteClassWithGenericIEnumerableT() + { + string json; + + { + TestClassWithGenericIEnumerableT obj = new TestClassWithGenericIEnumerableT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithGenericIEnumerableT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithGenericIEnumerableT obj = JsonSerializer.Parse(TestClassWithGenericIEnumerableT.s_data); + obj.Verify(); + } + } + [Fact] - public static void WriteClassWithGenericList() + public static void WriteClassWithGenericIListT() { string json; { - TestClassWithObjectList obj = new TestClassWithObjectList(); + TestClassWithGenericIListT obj = new TestClassWithGenericIListT(); obj.Initialize(); obj.Verify(); json = JsonSerializer.ToString(obj); } { - TestClassWithObjectList obj = JsonSerializer.Parse(json); + TestClassWithGenericIListT obj = JsonSerializer.Parse(json); obj.Verify(); } { - TestClassWithObjectList obj = JsonSerializer.Parse(TestClassWithObjectList.s_data); + TestClassWithGenericIListT obj = JsonSerializer.Parse(TestClassWithGenericIListT.s_data); + obj.Verify(); + } + } + + [Fact] + public static void WriteClassWithGenericICollectionT() + { + string json; + + { + TestClassWithGenericICollectionT obj = new TestClassWithGenericICollectionT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithGenericICollectionT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithGenericICollectionT obj = JsonSerializer.Parse(TestClassWithGenericICollectionT.s_data); + obj.Verify(); + } + } + + [Fact] + public static void WriteClassWithGenericIReadOnlyCollectionT() + { + string json; + + { + TestClassWithGenericIReadOnlyCollectionT obj = new TestClassWithGenericIReadOnlyCollectionT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithGenericIReadOnlyCollectionT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithGenericIReadOnlyCollectionT obj = JsonSerializer.Parse(TestClassWithGenericIReadOnlyCollectionT.s_data); + obj.Verify(); + } + } + + [Fact] + public static void WriteClassWithGenericIReadOnlyListT() + { + string json; + + { + TestClassWithGenericIReadOnlyListT obj = new TestClassWithGenericIReadOnlyListT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithGenericIReadOnlyListT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithGenericIReadOnlyListT obj = JsonSerializer.Parse(TestClassWithGenericIEnumerableT.s_data); + obj.Verify(); + } + } + + [Fact] + public static void WriteClassWithObjectIEnumerableT() + { + string json; + + { + TestClassWithObjectIEnumerableT obj = new TestClassWithObjectIEnumerableT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithObjectIEnumerableT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithObjectIEnumerableT obj = JsonSerializer.Parse(TestClassWithObjectIEnumerableT.s_data); + obj.Verify(); + } + } + + [Fact] + public static void WriteClassWithObjectIListT() + { + string json; + + { + TestClassWithObjectIListT obj = new TestClassWithObjectIListT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithObjectIListT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithObjectIListT obj = JsonSerializer.Parse(TestClassWithObjectIListT.s_data); + obj.Verify(); + } + } + + [Fact] + public static void WriteClassWithObjectICollectionT() + { + string json; + + { + TestClassWithObjectICollectionT obj = new TestClassWithObjectICollectionT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithObjectICollectionT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithObjectICollectionT obj = JsonSerializer.Parse(TestClassWithObjectICollectionT.s_data); + obj.Verify(); + } + } + + [Fact] + public static void WriteClassWithObjectIReadOnlyCollectionT() + { + string json; + + { + TestClassWithObjectIReadOnlyCollectionT obj = new TestClassWithObjectIReadOnlyCollectionT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithObjectIReadOnlyCollectionT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithObjectIReadOnlyCollectionT obj = JsonSerializer.Parse(TestClassWithObjectIReadOnlyCollectionT.s_data); + obj.Verify(); + } + } + + [Fact] + public static void WriteClassWithObjectIReadOnlyListT() + { + string json; + + { + TestClassWithObjectIReadOnlyListT obj = new TestClassWithObjectIReadOnlyListT(); + obj.Initialize(); + obj.Verify(); + json = JsonSerializer.ToString(obj); + } + + { + TestClassWithObjectIReadOnlyListT obj = JsonSerializer.Parse(json); + obj.Verify(); + } + + { + TestClassWithObjectIReadOnlyListT obj = JsonSerializer.Parse(TestClassWithObjectIEnumerableT.s_data); obj.Verify(); } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/Null.WriteTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Null.WriteTests.cs index 6dc32aa..2a53ce0 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Null.WriteTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Null.WriteTests.cs @@ -34,6 +34,11 @@ namespace System.Text.Json.Serialization.Tests obj.Address = null; obj.Array = null; obj.List = null; + obj.IEnumerableT = null; + obj.IListT = null; + obj.ICollectionT = null; + obj.IReadOnlyCollectionT = null; + obj.IReadOnlyListT = null; obj.NullableInt = null; obj.NullableIntArray = null; obj.Object = null; @@ -42,6 +47,11 @@ namespace System.Text.Json.Serialization.Tests Assert.Contains(@"""Address"":null", json); Assert.Contains(@"""List"":null", json); Assert.Contains(@"""Array"":null", json); + Assert.Contains(@"""IEnumerableT"":null", json); + Assert.Contains(@"""IListT"":null", json); + Assert.Contains(@"""ICollectionT"":null", json); + Assert.Contains(@"""IReadOnlyCollectionT"":null", json); + Assert.Contains(@"""IReadOnlyListT"":null", json); Assert.Contains(@"""NullableInt"":null", json); Assert.Contains(@"""Object"":null", json); Assert.Contains(@"""NullableIntArray"":null", json); diff --git a/src/libraries/System.Text.Json/tests/Serialization/PolymorphicTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PolymorphicTests.cs index 0f036ef..da88e2a 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PolymorphicTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PolymorphicTests.cs @@ -75,6 +75,41 @@ namespace System.Text.Json.Serialization.Tests json = JsonSerializer.ToString(list); Assert.Equal(ExpectedJson, json); + + IEnumerable ienumerable = new List { 1, true, address, null, "foo" }; + json = JsonSerializer.ToString(ienumerable); + Assert.Equal(ExpectedJson, json); + + json = JsonSerializer.ToString(ienumerable); + Assert.Equal(ExpectedJson, json); + + IList ilist = new List { 1, true, address, null, "foo" }; + json = JsonSerializer.ToString(ilist); + Assert.Equal(ExpectedJson, json); + + json = JsonSerializer.ToString(ilist); + Assert.Equal(ExpectedJson, json); + + ICollection icollection = new List { 1, true, address, null, "foo" }; + json = JsonSerializer.ToString(icollection); + Assert.Equal(ExpectedJson, json); + + json = JsonSerializer.ToString(icollection); + Assert.Equal(ExpectedJson, json); + + IReadOnlyCollection ireadonlycollection = new List { 1, true, address, null, "foo" }; + json = JsonSerializer.ToString(ireadonlycollection); + Assert.Equal(ExpectedJson, json); + + json = JsonSerializer.ToString(ireadonlycollection); + Assert.Equal(ExpectedJson, json); + + IReadOnlyList ireadonlylist = new List { 1, true, address, null, "foo" }; + json = JsonSerializer.ToString(ireadonlylist); + Assert.Equal(ExpectedJson, json); + + json = JsonSerializer.ToString(ireadonlylist); + Assert.Equal(ExpectedJson, json); } [Fact] @@ -109,6 +144,11 @@ namespace System.Text.Json.Serialization.Tests Assert.Contains(@"""Address"":{""City"":""MyCity""}", json); Assert.Contains(@"""List"":[""Hello"",""World""]", json); Assert.Contains(@"""Array"":[""Hello"",""Again""]", json); + Assert.Contains(@"""IEnumerableT"":[""Hello"",""World""]", json); + Assert.Contains(@"""IListT"":[""Hello"",""World""]", json); + Assert.Contains(@"""ICollectionT"":[""Hello"",""World""]", json); + Assert.Contains(@"""IReadOnlyCollectionT"":[""Hello"",""World""]", json); + Assert.Contains(@"""IReadOnlyListT"":[""Hello"",""World""]", json); Assert.Contains(@"""NullableInt"":42", json); Assert.Contains(@"""Object"":{}", json); Assert.Contains(@"""NullableIntArray"":[null,42,null]", json); diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.Polymorphic.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.Polymorphic.cs index c55f43f..f97e14c 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.Polymorphic.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.Polymorphic.cs @@ -110,6 +110,11 @@ namespace System.Text.Json.Serialization.Tests public object /*Address*/ Address { get; set; } public object /*List*/ List { get; set; } public object /*string[]*/ Array { get; set; } + public object /*IEnumerable*/ IEnumerableT { get; set; } + public object /*IList*/ IListT { get; set; } + public object /*ICollection*/ ICollectionT { get; set; } + public object /*IReadOnlyCollection*/ IReadOnlyCollectionT { get; set; } + public object /*IReadOnlyList*/ IReadOnlyListT { get; set; } public object /*int?*/ NullableInt { get; set; } public object /*object*/ Object { get; set; } public object /*int?[]*/ NullableIntArray { get; set; } @@ -129,6 +134,31 @@ namespace System.Text.Json.Serialization.Tests "Hello", "Again" }; + IEnumerableT = new List + { + "Hello", "World" + }; + + IListT = new List + { + "Hello", "World" + }; + + ICollectionT = new List + { + "Hello", "World" + }; + + IReadOnlyCollectionT = new List + { + "Hello", "World" + }; + + IReadOnlyListT = new List + { + "Hello", "World" + }; + NullableInt = new int?(42); Object = new object(); NullableIntArray = new int?[] { null, 42, null }; diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.cs index 9423414..c00cff0 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Linq; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -57,6 +58,12 @@ namespace System.Text.Json.Serialization.Tests public DateTime[] MyDateTimeArray { get; set; } public DateTimeOffset[] MyDateTimeOffsetArray { get; set; } public SampleEnum[] MyEnumArray { get; set; } + public List MyStringList { get; set; } + public IEnumerable MyStringIEnumerableT { get; set; } + public IList MyStringIListT { get; set; } + public ICollection MyStringICollectionT { get; set; } + public IReadOnlyCollection MyStringIReadOnlyCollectionT { get; set; } + public IReadOnlyList MyStringIReadOnlyListT { get; set; } public static readonly string s_json = $"{{{s_partialJsonProperties},{s_partialJsonArrays}}}"; public static readonly string s_json_flipped = $"{{{s_partialJsonArrays},{s_partialJsonProperties}}}"; @@ -99,7 +106,13 @@ namespace System.Text.Json.Serialization.Tests @"""MyDecimalArray"" : [3.3]," + @"""MyDateTimeArray"" : [""2019-01-30T12:01:02.0000000Z""]," + @"""MyDateTimeOffsetArray"" : [""2019-01-30T12:01:02.0000000+01:00""]," + - @"""MyEnumArray"" : [2]"; // int by default + @"""MyEnumArray"" : [2]," + // int by default + @"""MyStringList"" : [""Hello""]," + + @"""MyStringIEnumerableT"" : [""Hello""]," + + @"""MyStringIListT"" : [""Hello""]," + + @"""MyStringICollectionT"" : [""Hello""]," + + @"""MyStringIReadOnlyCollectionT"" : [""Hello""]," + + @"""MyStringIReadOnlyListT"" : [""Hello""]"; public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json); @@ -142,6 +155,13 @@ namespace System.Text.Json.Serialization.Tests MyDateTimeArray = new DateTime[] { new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc) }; MyDateTimeOffsetArray = new DateTimeOffset[] { new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)) }; MyEnumArray = new SampleEnum[] { SampleEnum.Two }; + + MyStringList = new List() { "Hello" }; + MyStringIEnumerableT = new string[] { "Hello" }; + MyStringIListT = new string[] { "Hello" }; + MyStringICollectionT = new string[] { "Hello" }; + MyStringIReadOnlyCollectionT = new string[] { "Hello" }; + MyStringIReadOnlyListT = new string[] { "Hello" }; } public void Verify() @@ -183,6 +203,13 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), MyDateTimeArray[0]); Assert.Equal(new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)), MyDateTimeOffsetArray[0]); Assert.Equal(SampleEnum.Two, MyEnumArray[0]); + + Assert.Equal("Hello", MyStringList[0]); + Assert.Equal("Hello", MyStringIEnumerableT.First()); + Assert.Equal("Hello", MyStringIListT[0]); + Assert.Equal("Hello", MyStringICollectionT.First()); + Assert.Equal("Hello", MyStringIReadOnlyCollectionT.First()); + Assert.Equal("Hello", MyStringIReadOnlyListT[0]); } } @@ -222,6 +249,12 @@ namespace System.Text.Json.Serialization.Tests public object MyDoubleArray { get; set; } public object MyDateTimeArray { get; set; } public object MyEnumArray { get; set; } + public object MyStringList { get; set; } + public object MyStringIEnumerableT { get; set; } + public object MyStringIListT { get; set; } + public object MyStringICollectionT { get; set; } + public object MyStringIReadOnlyCollectionT { get; set; } + public object MyStringIReadOnlyListT { get; set; } public static readonly string s_json = @"{" + @@ -258,7 +291,13 @@ namespace System.Text.Json.Serialization.Tests @"""MyDoubleArray"" : [2.2]," + @"""MyDecimalArray"" : [3.3]," + @"""MyDateTimeArray"" : [""2019-01-30T12:01:02.0000000Z""]," + - @"""MyEnumArray"" : [2]" + // int by default + @"""MyEnumArray"" : [2]," + // int by default + @"""MyStringList"" : [""Hello""]," + + @"""MyStringIEnumerableT"" : [""Hello""]," + + @"""MyStringIListT"" : [""Hello""]," + + @"""MyStringICollectionT"" : [""Hello""]," + + @"""MyStringIReadOnlyCollectionT"" : [""Hello""]," + + @"""MyStringIReadOnlyListT"" : [""Hello""]" + @"}"; public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json); @@ -300,6 +339,13 @@ namespace System.Text.Json.Serialization.Tests MyDecimalArray = new decimal[] { 3.3m }; MyDateTimeArray = new DateTime[] { new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc) }; MyEnumArray = new SampleEnum[] { SampleEnum.Two }; + + MyStringList = new List() { "Hello" }; + MyStringIEnumerableT = new string[] { "Hello" }; + MyStringIListT = new string[] { "Hello" }; + MyStringICollectionT = new string[] { "Hello" }; + MyStringIReadOnlyCollectionT = new string[] { "Hello" }; + MyStringIReadOnlyListT = new string[] { "Hello" }; } public void Verify() @@ -339,6 +385,13 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal(2.2d, ((double[])MyDoubleArray)[0]); Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), ((DateTime[])MyDateTimeArray)[0]); Assert.Equal(SampleEnum.Two, ((SampleEnum[])MyEnumArray)[0]); + + Assert.Equal("Hello", ((List)MyStringList)[0]); + Assert.Equal("Hello", ((IEnumerable)MyStringIEnumerableT).First()); + Assert.Equal("Hello", ((IList)MyStringIListT)[0]); + Assert.Equal("Hello", ((ICollection)MyStringICollectionT).First()); + Assert.Equal("Hello", ((IReadOnlyCollection)MyStringIReadOnlyCollectionT).First()); + Assert.Equal("Hello", ((IReadOnlyList)MyStringIReadOnlyListT)[0]); } } @@ -629,6 +682,185 @@ namespace System.Text.Json.Serialization.Tests } } + public class TestClassWithObjectIEnumerableT : ITestClass + { + public IEnumerable MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + SimpleTestClass.s_json + "," + + SimpleTestClass.s_json + + @"]" + + @"}"); + + public void Initialize() + { + SimpleTestClass obj1 = new SimpleTestClass(); + obj1.Initialize(); + + SimpleTestClass obj2 = new SimpleTestClass(); + obj2.Initialize(); + + MyData = new SimpleTestClass[] { obj1, obj2 }; + } + + public void Verify() + { + int count = 0; + + foreach (SimpleTestClass data in MyData) + { + data.Verify(); + count++; + } + + Assert.Equal(2, count); + } + } + + public class TestClassWithObjectIListT : ITestClass + { + public IList MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + SimpleTestClass.s_json + "," + + SimpleTestClass.s_json + + @"]" + + @"}"); + + public void Initialize() + { + MyData = new List(); + + { + SimpleTestClass obj = new SimpleTestClass(); + obj.Initialize(); + MyData.Add(obj); + } + + { + SimpleTestClass obj = new SimpleTestClass(); + obj.Initialize(); + MyData.Add(obj); + } + } + + public void Verify() + { + Assert.Equal(2, MyData.Count); + MyData[0].Verify(); + MyData[1].Verify(); + } + } + + public class TestClassWithObjectICollectionT : ITestClass + { + public ICollection MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + SimpleTestClass.s_json + "," + + SimpleTestClass.s_json + + @"]" + + @"}"); + + public void Initialize() + { + MyData = new List(); + + { + SimpleTestClass obj = new SimpleTestClass(); + obj.Initialize(); + MyData.Add(obj); + } + + { + SimpleTestClass obj = new SimpleTestClass(); + obj.Initialize(); + MyData.Add(obj); + } + } + + public void Verify() + { + Assert.Equal(2, MyData.Count); + + foreach (SimpleTestClass data in MyData) + { + data.Verify(); + } + } + } + + public class TestClassWithObjectIReadOnlyCollectionT : ITestClass + { + public IReadOnlyCollection MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + SimpleTestClass.s_json + "," + + SimpleTestClass.s_json + + @"]" + + @"}"); + + public void Initialize() + { + SimpleTestClass obj1 = new SimpleTestClass(); + obj1.Initialize(); + + SimpleTestClass obj2 = new SimpleTestClass(); + obj2.Initialize(); + + MyData = new SimpleTestClass[] { obj1, obj2 }; + } + + public void Verify() + { + Assert.Equal(2, MyData.Count); + + foreach (SimpleTestClass data in MyData) + { + data.Verify(); + } + } + } + + public class TestClassWithObjectIReadOnlyListT : ITestClass + { + public IReadOnlyList MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + SimpleTestClass.s_json + "," + + SimpleTestClass.s_json + + @"]" + + @"}"); + + public void Initialize() + { + SimpleTestClass obj1 = new SimpleTestClass(); + obj1.Initialize(); + + SimpleTestClass obj2 = new SimpleTestClass(); + obj2.Initialize(); + + MyData = new SimpleTestClass[] { obj1, obj2 }; + } + + public void Verify() + { + Assert.Equal(2, MyData.Count); + MyData[0].Verify(); + MyData[1].Verify(); + } + } + public class TestClassWithStringArray : ITestClass { public string[] MyData { get; set; } @@ -694,6 +926,181 @@ namespace System.Text.Json.Serialization.Tests } } + public class TestClassWithGenericIEnumerableT : ITestClass + { + public IEnumerable MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + @"""Hello""," + + @"""World""" + + @"]" + + @"}"); + + public void Initialize() + { + MyData = new List + { + "Hello", + "World" + }; + + int count = 0; + foreach (string data in MyData) + { + count++; + } + Assert.Equal(2, count); + } + + public void Verify() + { + string[] expected = { "Hello", "World" }; + int count = 0; + + foreach (string data in MyData) + { + Assert.Equal(expected[count], data); + count++; + } + + Assert.Equal(2, count); + } + } + + public class TestClassWithGenericIListT : ITestClass + { + public IList MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + @"""Hello""," + + @"""World""" + + @"]" + + @"}"); + + public void Initialize() + { + MyData = new List + { + "Hello", + "World" + }; + Assert.Equal(2, MyData.Count); + } + + public void Verify() + { + Assert.Equal("Hello", MyData[0]); + Assert.Equal("World", MyData[1]); + Assert.Equal(2, MyData.Count); + } + } + + public class TestClassWithGenericICollectionT : ITestClass + { + public ICollection MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + @"""Hello""," + + @"""World""" + + @"]" + + @"}"); + + public void Initialize() + { + MyData = new List + { + "Hello", + "World" + }; + Assert.Equal(2, MyData.Count); + } + + public void Verify() + { + string[] expected = { "Hello", "World" }; + int i = 0; + + foreach (string data in MyData) + { + Assert.Equal(expected[i++], data); + } + + Assert.Equal(2, MyData.Count); + } + } + + public class TestClassWithGenericIReadOnlyCollectionT : ITestClass + { + public IReadOnlyCollection MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + @"""Hello""," + + @"""World""" + + @"]" + + @"}"); + + public void Initialize() + { + MyData = new List + { + "Hello", + "World" + }; + Assert.Equal(2, MyData.Count); + } + + public void Verify() + { + string[] expected = { "Hello", "World" }; + int i = 0; + + foreach (string data in MyData) + { + Assert.Equal(expected[i++], data); + } + + Assert.Equal(2, MyData.Count); + } + } + + public class TestClassWithGenericIReadOnlyListT : ITestClass + { + public IReadOnlyList MyData { get; set; } + + public static readonly byte[] s_data = Encoding.UTF8.GetBytes( + @"{" + + @"""MyData"":[" + + @"""Hello""," + + @"""World""" + + @"]" + + @"}"); + + public void Initialize() + { + MyData = new List + { + "Hello", + "World" + }; + Assert.Equal(2, MyData.Count); + } + + public void Verify() + { + Assert.Equal("Hello", MyData[0]); + Assert.Equal("World", MyData[1]); + Assert.Equal(2, MyData.Count); + } + } + public class SimpleDerivedTestClass : SimpleTestClass { } diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestData.cs b/src/libraries/System.Text.Json/tests/Serialization/TestData.cs index 4cb5072..de39bd4 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestData.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestData.cs @@ -20,8 +20,18 @@ namespace System.Text.Json.Serialization.Tests yield return new object[] { typeof(TestClassWithNestedObjectInner), TestClassWithNestedObjectInner.s_data }; yield return new object[] { typeof(TestClassWithNestedObjectOuter), TestClassWithNestedObjectOuter.s_data }; yield return new object[] { typeof(TestClassWithObjectArray), TestClassWithObjectArray.s_data }; + yield return new object[] { typeof(TestClassWithObjectIEnumerableT), TestClassWithObjectIEnumerableT.s_data }; + yield return new object[] { typeof(TestClassWithObjectIListT), TestClassWithObjectIListT.s_data }; + yield return new object[] { typeof(TestClassWithObjectICollectionT), TestClassWithObjectICollectionT.s_data }; + yield return new object[] { typeof(TestClassWithObjectIReadOnlyCollectionT), TestClassWithObjectIReadOnlyCollectionT.s_data }; + yield return new object[] { typeof(TestClassWithObjectIReadOnlyListT), TestClassWithObjectIReadOnlyListT.s_data }; yield return new object[] { typeof(TestClassWithStringArray), TestClassWithStringArray.s_data }; yield return new object[] { typeof(TestClassWithGenericList), TestClassWithGenericList.s_data }; + yield return new object[] { typeof(TestClassWithGenericIEnumerableT), TestClassWithGenericIEnumerableT.s_data }; + yield return new object[] { typeof(TestClassWithGenericIListT), TestClassWithGenericIListT.s_data }; + yield return new object[] { typeof(TestClassWithGenericICollectionT), TestClassWithGenericICollectionT.s_data }; + yield return new object[] { typeof(TestClassWithGenericIReadOnlyCollectionT), TestClassWithGenericIReadOnlyCollectionT.s_data }; + yield return new object[] { typeof(TestClassWithGenericIReadOnlyListT), TestClassWithGenericIReadOnlyListT.s_data }; } } public static IEnumerable WriteSuccessCases @@ -36,8 +46,18 @@ namespace System.Text.Json.Serialization.Tests yield return new object[] { new TestClassWithNestedObjectInner() }; yield return new object[] { new TestClassWithNestedObjectOuter() }; yield return new object[] { new TestClassWithObjectArray() }; + yield return new object[] { new TestClassWithObjectIEnumerableT() }; + yield return new object[] { new TestClassWithObjectIListT() }; + yield return new object[] { new TestClassWithObjectICollectionT() }; + yield return new object[] { new TestClassWithObjectIReadOnlyCollectionT() }; + yield return new object[] { new TestClassWithObjectIReadOnlyListT() }; yield return new object[] { new TestClassWithStringArray() }; yield return new object[] { new TestClassWithGenericList() }; + yield return new object[] { new TestClassWithGenericIEnumerableT() }; + yield return new object[] { new TestClassWithGenericIListT() }; + yield return new object[] { new TestClassWithGenericICollectionT() }; + yield return new object[] { new TestClassWithGenericIReadOnlyCollectionT() }; + yield return new object[] { new TestClassWithGenericIReadOnlyListT() }; } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/Value.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Value.ReadTests.cs index 85967db..271c840 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Value.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Value.ReadTests.cs @@ -304,6 +304,291 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal(2, i[1]); } + [Fact] + public static void ReadIEnumerableTOfIEnumerableT() + { + IEnumerable> result = JsonSerializer.Parse>>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (IEnumerable ie in result) + { + foreach (int i in ie) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadIEnumerableTOfArray() + { + IEnumerable result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (int[] arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadArrayOfIEnumerableT() + { + IEnumerable[] result = JsonSerializer.Parse[]> (Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (IEnumerable arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadPrimitiveIEnumerableT() + { + IEnumerable result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[1,2]")); + int expected = 1; + + foreach (int i in result) + { + Assert.Equal(expected++, i); + } + } + + [Fact] + public static void ReadIListTOfIListT() + { + IList> result = JsonSerializer.Parse>>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (IList ie in result) + { + foreach (int i in ie) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadIListTOfArray() + { + IList result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (int[] arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadArrayOfIListT() + { + IList[] result = JsonSerializer.Parse[]>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (IList arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadPrimitiveIListT() + { + IList result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[1,2]")); + int expected = 1; + + foreach (int i in result) + { + Assert.Equal(expected++, i); + } + } + + [Fact] + public static void ReadICollectionTOfICollectionT() + { + ICollection> result = JsonSerializer.Parse>>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (ICollection ie in result) + { + foreach (int i in ie) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadICollectionTOfArray() + { + ICollection result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (int[] arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadArrayOfICollectionT() + { + ICollection[] result = JsonSerializer.Parse[]>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (ICollection arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadPrimitiveICollectionT() + { + ICollection result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[1,2]")); + int expected = 1; + + foreach (int i in result) + { + Assert.Equal(expected++, i); + } + } + + [Fact] + public static void ReadIReadOnlyCollectionTOfIReadOnlyCollectionT() + { + IReadOnlyCollection> result = JsonSerializer.Parse>>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (IReadOnlyCollection ie in result) + { + foreach (int i in ie) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadIReadOnlyCollectionTOfArray() + { + IReadOnlyCollection result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (int[] arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadArrayOfIReadOnlyCollectionT() + { + IReadOnlyCollection[] result = JsonSerializer.Parse[]>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (IReadOnlyCollection arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadPrimitiveIReadOnlyCollectionT() + { + IReadOnlyCollection result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[1,2]")); + int expected = 1; + + foreach (int i in result) + { + Assert.Equal(expected++, i); + } + } + + [Fact] + public static void ReadIReadOnlyListTOfIReadOnlyListT() + { + IReadOnlyList> result = JsonSerializer.Parse>>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (IReadOnlyList ie in result) + { + foreach (int i in ie) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadIReadOnlyListTOfArray() + { + IReadOnlyList result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (int[] arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadArrayOfIReadOnlyListT() + { + IReadOnlyList[] result = JsonSerializer.Parse[]>(Encoding.UTF8.GetBytes(@"[[1,2],[3,4]]")); + int expected = 1; + + foreach (IReadOnlyList arr in result) + { + foreach (int i in arr) + { + Assert.Equal(expected++, i); + } + } + } + + [Fact] + public static void ReadPrimitiveIReadOnlyListT() + { + IReadOnlyList result = JsonSerializer.Parse>(Encoding.UTF8.GetBytes(@"[1,2]")); + int expected = 1; + + foreach (int i in result) + { + Assert.Equal(expected++, i); + } + } + public class TestClassWithBadData { public TestChildClassWithBadData[] Children { get; set; } diff --git a/src/libraries/System.Text.Json/tests/Serialization/Value.WriteTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Value.WriteTests.cs index 32a1974..bd53182 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Value.WriteTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Value.WriteTests.cs @@ -139,5 +139,235 @@ namespace System.Text.Json.Serialization.Tests string json = JsonSerializer.ToString(input); Assert.Equal("[1,2]", json); } + + [Fact] + public static void WriteIEnumerableTOfIEnumerableT() + { + IEnumerable> input = new List> + { + new List() { 1, 2 }, + new List() { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteIEnumerableTOfArray() + { + IEnumerable input = new List + { + new int[] { 1, 2 }, + new int[] { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteArrayOfIEnumerableT() + { + IEnumerable[] input = new List[2]; + input[0] = new List() { 1, 2 }; + input[1] = new List() { 3, 4 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WritePrimitiveIEnumerableT() + { + IEnumerable input = new List { 1, 2 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[1,2]", json); + } + + [Fact] + public static void WriteIListTOfIListT() + { + IList> input = new List> + { + new List() { 1, 2 }, + new List() { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteIListTOfArray() + { + IList input = new List + { + new int[] { 1, 2 }, + new int[] { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteArrayOfIListT() + { + IList[] input = new List[2]; + input[0] = new List() { 1, 2 }; + input[1] = new List() { 3, 4 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WritePrimitiveIListT() + { + IList input = new List { 1, 2 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[1,2]", json); + } + + [Fact] + public static void WriteICollectionTOfICollectionT() + { + ICollection> input = new List> + { + new List() { 1, 2 }, + new List() { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteICollectionTOfArray() + { + ICollection input = new List + { + new int[] { 1, 2 }, + new int[] { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteArrayOfICollectionT() + { + ICollection[] input = new List[2]; + input[0] = new List() { 1, 2 }; + input[1] = new List() { 3, 4 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WritePrimitiveICollectionT() + { + ICollection input = new List { 1, 2 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[1,2]", json); + } + + [Fact] + public static void WriteIReadOnlyCollectionTOfIReadOnlyCollectionT() + { + IReadOnlyCollection> input = new List> + { + new List() { 1, 2 }, + new List() { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteIReadOnlyCollectionTOfArray() + { + IReadOnlyCollection input = new List + { + new int[] { 1, 2 }, + new int[] { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteArrayOfIReadOnlyCollectionT() + { + IReadOnlyCollection[] input = new List[2]; + input[0] = new List() { 1, 2 }; + input[1] = new List() { 3, 4 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WritePrimitiveIReadOnlyCollectionT() + { + IReadOnlyCollection input = new List { 1, 2 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[1,2]", json); + } + + [Fact] + public static void WriteIReadOnlyListTOfIReadOnlyListT() + { + IReadOnlyList> input = new List> + { + new List() { 1, 2 }, + new List() { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteIReadOnlyListTOfArray() + { + IReadOnlyList input = new List + { + new int[] { 1, 2 }, + new int[] { 3, 4 } + }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WriteArrayOfIReadOnlyListT() + { + IReadOnlyList[] input = new List[2]; + input[0] = new List() { 1, 2 }; + input[1] = new List() { 3, 4 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[[1,2],[3,4]]", json); + } + + [Fact] + public static void WritePrimitiveIReadOnlyListT() + { + IReadOnlyList input = new List { 1, 2 }; + + string json = JsonSerializer.ToString(input); + Assert.Equal("[1,2]", json); + } } }