diff --git a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs index 479d2aef83c6e..bf676b7b6f26b 100644 --- a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs +++ b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs @@ -405,6 +405,15 @@ public static void Equal(HashSet expected, HashSet actual) } } + /// Validates that the two sets contains the same elements. XUnit doesn't display the full collections. + public static void Equal(ISet expected, ISet actual) + { + if (!actual.SetEquals(expected)) + { + throw new XunitException($"Expected: {string.Join(", ", expected)}{Environment.NewLine}Actual: {string.Join(", ", actual)}"); + } + } + /// /// Validates that the actual collection contains same items as expected collection. If the test fails, this will display: /// 1. Count if two collection count are different; diff --git a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.AsyncEnumerable.cs b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.AsyncEnumerable.cs index 0ae7c05046fd5..7b87042daab86 100644 --- a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.AsyncEnumerable.cs +++ b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.AsyncEnumerable.cs @@ -23,12 +23,10 @@ public async Task WriteRootLevelAsyncEnumerable(IEnumerable return; } - JsonSerializerOptions options = new JsonSerializerOptions - { - DefaultBufferSize = bufferSize - }; + JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false); + options.DefaultBufferSize = bufferSize; - string expectedJson = JsonSerializer.Serialize(source); + string expectedJson = JsonSerializer.Serialize(source, options); using var stream = new Utf8MemoryStream(); var asyncEnumerable = new MockedAsyncEnumerable(source, delayInterval); @@ -48,37 +46,10 @@ public async Task WriteNestedAsyncEnumerable(IEnumerable sou return; } - JsonSerializerOptions options = new JsonSerializerOptions - { - DefaultBufferSize = bufferSize - }; + JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false); + options.DefaultBufferSize = bufferSize; - string expectedJson = JsonSerializer.Serialize(new { Data = source }); - - using var stream = new Utf8MemoryStream(); - var asyncEnumerable = new MockedAsyncEnumerable(source, delayInterval); - await StreamingSerializer.SerializeWrapper(stream, new AsyncEnumerableDto { Data = asyncEnumerable }, options); - - JsonTestHelper.AssertJsonEqual(expectedJson, stream.AsString()); - Assert.Equal(1, asyncEnumerable.TotalCreatedEnumerators); - Assert.Equal(1, asyncEnumerable.TotalDisposedEnumerators); - } - - [Theory] - [MemberData(nameof(GetAsyncEnumerableSources))] - public async Task WriteNestedAsyncEnumerable_DTO(IEnumerable source, int delayInterval, int bufferSize) - { - if (StreamingSerializer?.IsAsyncSerializer != true) - { - return; - } - - JsonSerializerOptions options = new JsonSerializerOptions - { - DefaultBufferSize = bufferSize - }; - - string expectedJson = JsonSerializer.Serialize(new { Data = source }); + string expectedJson = JsonSerializer.Serialize(new EnumerableDto { Data = source }, options); using var stream = new Utf8MemoryStream(); var asyncEnumerable = new MockedAsyncEnumerable(source, delayInterval); @@ -100,11 +71,9 @@ public async Task WriteNestedAsyncEnumerable_Nullable(IEnumerable, bool)?>((source, false), options); @@ -164,11 +133,22 @@ async IAsyncEnumerable CreateEnumerable([EnumeratorCancellation] Cancellati Assert.Equal(1, longRunningEnumerable.TotalDisposedEnumerators); } + public class EnumerableDto + { + public IEnumerable Data { get; set; } + } + public class AsyncEnumerableDto { public IAsyncEnumerable Data { get; set; } } + public class EnumerableDtoWithTwoProperties + { + public IEnumerable Data1 { get; set; } + public IEnumerable Data2 { get; set; } + } + public class AsyncEnumerableDtoWithTwoProperties { public IAsyncEnumerable Data1 { get; set; } @@ -184,12 +164,10 @@ public async Task WriteSequentialNestedAsyncEnumerables(IEnumerable { Data1 = source, Data2 = source }, options); using var stream = new Utf8MemoryStream(); var asyncEnumerable = new MockedAsyncEnumerable(source, delayInterval); @@ -209,13 +187,11 @@ public async Task WriteAsyncEnumerableOfAsyncEnumerables(IEnumerable(source, delayInterval); var outerAsyncEnumerable = diff --git a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Read.cs b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Read.cs index 98ea68cbdd7d3..a1b9b76f003ce 100644 --- a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Read.cs +++ b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Read.cs @@ -617,20 +617,19 @@ public async Task ReadNullableGenericStructISetWithNullJson() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/50721", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] public async Task ReadISetTOfHashSetT() { ISet> result = await Serializer.DeserializeWrapper>>(@"[[1,2],[3,4]]"); if (result.First().Contains(1)) { - Assert.Equal(new HashSet { 1, 2 }, result.First()); - Assert.Equal(new HashSet { 3, 4 }, result.Last()); + AssertExtensions.Equal(new HashSet { 1, 2 }, result.First()); + AssertExtensions.Equal(new HashSet { 3, 4 }, result.Last()); } else { - Assert.Equal(new HashSet { 3, 4 }, result.First()); - Assert.Equal(new HashSet { 1, 2 }, result.Last()); + AssertExtensions.Equal(new HashSet { 3, 4 }, result.First()); + AssertExtensions.Equal(new HashSet { 1, 2 }, result.Last()); } } diff --git a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Write.cs b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Write.cs index 935ec9e6c0050..a6131347de3cd 100644 --- a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Write.cs +++ b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Write.cs @@ -384,7 +384,6 @@ public async Task GenericStructISetWrapperT() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/50721", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] public async Task WriteISetTOfISetT() { ISet> input = new HashSet> @@ -433,7 +432,6 @@ public async Task WriteISetTOfISetT() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/50721", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] public async Task WriteISetTOfHashSetT() { ISet> input = new HashSet> @@ -449,13 +447,13 @@ public async Task WriteISetTOfHashSetT() if (input.First().Contains(1)) { - Assert.Equal(new HashSet { 1, 2 }, input.First()); - Assert.Equal(new HashSet { 3, 4 }, input.Last()); + AssertExtensions.Equal(new HashSet { 1, 2 }, input.First()); + AssertExtensions.Equal(new HashSet { 3, 4 }, input.Last()); } else { - Assert.Equal(new HashSet { 3, 4 }, input.First()); - Assert.Equal(new HashSet { 1, 2 }, input.Last()); + AssertExtensions.Equal(new HashSet { 3, 4 }, input.First()); + AssertExtensions.Equal(new HashSet { 1, 2 }, input.Last()); } } @@ -649,13 +647,13 @@ public async Task WriteHashSetTOfHashSetT() if (input.First().Contains(1)) { - Assert.Equal(new HashSet { 1, 2 }, input.First()); - Assert.Equal(new HashSet { 3, 4 }, input.Last()); + AssertExtensions.Equal(new HashSet { 1, 2 }, input.First()); + AssertExtensions.Equal(new HashSet { 3, 4 }, input.Last()); } else { - Assert.Equal(new HashSet { 3, 4 }, input.First()); - Assert.Equal(new HashSet { 1, 2 }, input.Last()); + AssertExtensions.Equal(new HashSet { 3, 4 }, input.First()); + AssertExtensions.Equal(new HashSet { 1, 2 }, input.Last()); } GenericHashSetWrapper input2 = new GenericHashSetWrapper(new List @@ -696,7 +694,6 @@ public async Task WriteHashSetTOfArray() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/50721", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] public async Task WriteArrayOfHashSetT() { HashSet[] input = new HashSet[2]; @@ -707,8 +704,8 @@ public async Task WriteArrayOfHashSetT() // Because order isn't guaranteed, roundtrip data to ensure write was accurate. input = await Serializer.DeserializeWrapper[]>(json); - Assert.Equal(new HashSet { 1, 2 }, input.First()); - Assert.Equal(new HashSet { 3, 4 }, input.Last()); + AssertExtensions.Equal(new HashSet { 1, 2 }, input.First()); + AssertExtensions.Equal(new HashSet { 3, 4 }, input.Last()); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.Cache.cs b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.Cache.cs index 2f121926b4cc9..de5ab8b147704 100644 --- a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.Cache.cs +++ b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.Cache.cs @@ -61,7 +61,7 @@ async Task SerializeObject(Type type, JsonSerializerOptions options) async Task RunTestAsync(Type type) { // Use local options to avoid obtaining already cached metadata from the default options. - var options = new JsonSerializerOptions(); + JsonSerializerOptions options = Serializer.CreateOptions(); const int ThreadCount = 8; const int ConcurrentTestsCount = 4; @@ -90,7 +90,7 @@ async Task RunTestAsync(Type type) public async Task PropertyCacheWithMinInputsFirst() { // Use local options to avoid obtaining already cached metadata from the default options. - var options = new JsonSerializerOptions(); + JsonSerializerOptions options = Serializer.CreateOptions(); string json = "{}"; await Serializer.DeserializeWrapper(json, options); @@ -107,7 +107,7 @@ public async Task PropertyCacheWithMinInputsFirst() public async Task PropertyCacheWithMinInputsLast() { // Use local options to avoid obtaining already cached metadata from the default options. - var options = new JsonSerializerOptions(); + JsonSerializerOptions options = Serializer.CreateOptions(); ObjWCtorMixedParams testObj = ObjWCtorMixedParams.GetInstance(); testObj.Verify(); diff --git a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs index 7770389075b6e..949784234f62c 100644 --- a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs +++ b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs @@ -1049,23 +1049,24 @@ public async Task InvalidJsonFails() await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{true")); } +#if !BUILDING_SOURCE_GENERATOR_TESTS // Anonymous types not supported in source gen [Fact] - public void AnonymousObject() + public async Task AnonymousObject() { var obj = new { Prop = 5 }; Type objType = obj.GetType(); // 'Prop' property binds with a ctor arg called 'Prop'. - object newObj = JsonSerializer.Deserialize("{}", objType); + object newObj = await Serializer.DeserializeWrapper("{}", objType); Assert.Equal(0, objType.GetProperty("Prop").GetValue(newObj)); - newObj = JsonSerializer.Deserialize(@"{""Prop"":5}", objType); + newObj = await Serializer.DeserializeWrapper(@"{""Prop"":5}", objType); Assert.Equal(5, objType.GetProperty("Prop").GetValue(newObj)); } [Fact] - public void AnonymousObject_NamingPolicy() + public async Task AnonymousObject_NamingPolicy() { const string Json = @"{""prop"":5}"; @@ -1074,7 +1075,7 @@ public void AnonymousObject_NamingPolicy() // 'Prop' property binds with a ctor arg called 'Prop'. - object newObj = JsonSerializer.Deserialize(Json, objType); + object newObj = await Serializer.DeserializeWrapper(Json, objType); // Verify no match if no naming policy Assert.Equal(0, objType.GetProperty("Prop").GetValue(newObj)); @@ -1083,10 +1084,11 @@ public void AnonymousObject_NamingPolicy() PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; - newObj = JsonSerializer.Deserialize(Json, objType, options); + newObj = await Serializer.DeserializeWrapper(Json, objType, options); // Verify match with naming policy Assert.Equal(5, objType.GetProperty("Prop").GetValue(newObj)); } +#endif public record MyRecord(int Prop); @@ -1329,29 +1331,29 @@ public class ClassWithIgnoredSameType } [Fact] - public void StructWithPropertyInit_DeseralizeEmptyObject() + public async Task StructWithPropertyInit_DeseralizeEmptyObject() { string json = @"{}"; - var obj = JsonSerializer.Deserialize(json); + var obj = await Serializer.DeserializeWrapper(json); Assert.Equal(42, obj.A); Assert.Equal(0, obj.B); } [Fact] - public void StructWithPropertyInit_OverrideInitedProperty() + public async Task StructWithPropertyInit_OverrideInitedProperty() { string json = @"{""A"":43}"; - var obj = JsonSerializer.Deserialize(json); + var obj = await Serializer.DeserializeWrapper(json); Assert.Equal(43, obj.A); Assert.Equal(0, obj.B); json = @"{""A"":0,""B"":44}"; - obj = JsonSerializer.Deserialize(json); + obj = await Serializer.DeserializeWrapper(json); Assert.Equal(0, obj.A); Assert.Equal(44, obj.B); json = @"{""B"":45}"; - obj = JsonSerializer.Deserialize(json); + obj = await Serializer.DeserializeWrapper(json); Assert.Equal(42, obj.A); // JSON doesn't set A property so it's expected to be 42 Assert.Equal(45, obj.B); } @@ -1364,10 +1366,10 @@ public struct StructWithPropertyInit } [Fact] - public void StructWithFieldInit_DeseralizeEmptyObject() + public async Task StructWithFieldInit_DeseralizeEmptyObject() { string json = @"{}"; - var obj = JsonSerializer.Deserialize(json); + var obj = await Serializer.DeserializeWrapper(json); Assert.Equal(0, obj.A); Assert.Equal(42, obj.B); } @@ -1380,10 +1382,10 @@ public struct StructWithFieldInit } [Fact] - public void StructWithExplicitParameterlessCtor_DeseralizeEmptyObject() + public async Task StructWithExplicitParameterlessCtor_DeseralizeEmptyObject() { string json = @"{}"; - var obj = JsonSerializer.Deserialize(json); + var obj = await Serializer.DeserializeWrapper(json); Assert.Equal(42, obj.A); } @@ -1431,18 +1433,17 @@ public async Task TestClassWithDefaultCtorParams() JsonTestHelper.AssertJsonEqual(json, await Serializer.SerializeWrapper(obj)); } -#if FIXED // https://github.com/dotnet/roslyn/issues/66900 [Fact] public async Task TestClassWithManyConstructorParameters() { ClassWithManyConstructorParameters value = ClassWithManyConstructorParameters.Create(); - string json = JsonSerializer.Serialize(value); + string json = await Serializer.SerializeWrapper(value); ClassWithManyConstructorParameters result = await Serializer.DeserializeWrapper(json); Assert.Equal(value, result); // Type is C# record that implements structural equality. } -#endif + public class ClassWithDefaultCtorParams { public Point_2D_Struct_WithAttribute Struct { get; } @@ -1543,6 +1544,7 @@ public class ClassWithDefaultCtorParams } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/79311", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public async Task TestTypeWithEnumParameters() { // Regression test for https://github.com/dotnet/runtime/issues/68647 diff --git a/src/libraries/System.Text.Json/tests/Common/ExtensionDataTests.cs b/src/libraries/System.Text.Json/tests/Common/ExtensionDataTests.cs index d3a6548226d71..5801c31e41085 100644 --- a/src/libraries/System.Text.Json/tests/Common/ExtensionDataTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/ExtensionDataTests.cs @@ -1,10 +1,10 @@ // 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.Linq; -using System.Reflection; using System.Text.Encodings.Web; using System.Text.Json.Nodes; using System.Threading.Tasks; @@ -428,104 +428,93 @@ public override void Write(Utf8JsonWriter writer, CustomOverflowDictionary), typeof(DictionaryOverflowConverter))] - [InlineData(typeof(Dictionary), typeof(JsonElementOverflowConverter))] - [InlineData(typeof(CustomOverflowDictionary), typeof(CustomObjectDictionaryOverflowConverter))] - [InlineData(typeof(CustomOverflowDictionary), typeof(CustomJsonElementDictionaryOverflowConverter))] - public void ExtensionProperty_SupportsWritingToCustomSerializerWithOptions(Type overflowType, Type converterType) - { - typeof(ExtensionDataTests) - .GetMethod(nameof(ExtensionProperty_SupportsWritingToCustomSerializerWithOptionsInternal), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod(overflowType, converterType) - .Invoke(null, null); - } - - private static void ExtensionProperty_SupportsWritingToCustomSerializerWithOptionsInternal() - where TDictionary : new() - where TConverter : JsonConverter, new() + [MemberData(nameof(GetCustomOverflowConverters))] + public async Task ExtensionProperty_SupportsWritingToCustomSerializerWithOptions(JsonConverter dictionaryConverter) + where TDictionary : IDictionary, new() { var root = new ClassWithExtensionData() { Overflow = new TDictionary() }; - var options = new JsonSerializerOptions(); - options.Converters.Add(new TConverter()); + var options = Serializer.CreateOptions(makeReadOnly: false); + options.Converters.Add(dictionaryConverter); - string json = JsonSerializer.Serialize(root, options); + string json = await Serializer.SerializeWrapper(root, options); Assert.Equal(@"{""MyCustomOverflowWrite"":""OverflowValueWrite""}", json); } - private interface IClassWithOverflow + public interface IClassWithOverflow { - public T Overflow { get; set; } + public IDictionary GetOverflow(); } - public class ClassWithExtensionDataWithAttributedConverter : IClassWithOverflow> + public class ClassWithExtensionDataWithAttributedConverter : IClassWithOverflow { [JsonExtensionData] [JsonConverter(typeof(DictionaryOverflowConverter))] public Dictionary Overflow { get; set; } + + public IDictionary GetOverflow() => Overflow; } - public class ClassWithJsonElementExtensionDataWithAttributedConverter : IClassWithOverflow> + public class ClassWithJsonElementExtensionDataWithAttributedConverter : IClassWithOverflow { [JsonExtensionData] [JsonConverter(typeof(JsonElementOverflowConverter))] public Dictionary Overflow { get; set; } + + public IDictionary GetOverflow() => Overflow; } - public class ClassWithCustomElementExtensionDataWithAttributedConverter : IClassWithOverflow> + public class ClassWithCustomElementExtensionDataWithAttributedConverter : IClassWithOverflow { [JsonExtensionData] [JsonConverter(typeof(CustomObjectDictionaryOverflowConverter))] public CustomOverflowDictionary Overflow { get; set; } + + public IDictionary GetOverflow() => Overflow; } - public class ClassWithCustomJsonElementExtensionDataWithAttributedConverter : IClassWithOverflow> + public class ClassWithCustomJsonElementExtensionDataWithAttributedConverter : IClassWithOverflow { [JsonExtensionData] [JsonConverter(typeof(CustomJsonElementDictionaryOverflowConverter))] public CustomOverflowDictionary Overflow { get; set; } + + public IDictionary GetOverflow() => Overflow; } [Theory] - [InlineData(typeof(ClassWithExtensionDataWithAttributedConverter), typeof(Dictionary))] - [InlineData(typeof(ClassWithJsonElementExtensionDataWithAttributedConverter), typeof(Dictionary))] - [InlineData(typeof(ClassWithCustomElementExtensionDataWithAttributedConverter), typeof(CustomOverflowDictionary))] - [InlineData(typeof(ClassWithCustomJsonElementExtensionDataWithAttributedConverter), typeof(CustomOverflowDictionary))] - public void ExtensionProperty_SupportsWritingToCustomSerializerWithExplicitConverter(Type attributedType, Type dictionaryType) + [MemberData(nameof(GetClassesWithCustomExtensionDataOverflowConverter))] + public async Task ExtensionProperty_SupportsWritingToCustomSerializerWithExplicitConverter(ClassWithOverflow obj) where ClassWithOverflow : IClassWithOverflow { - typeof(ExtensionDataTests) - .GetMethod(nameof(ExtensionProperty_SupportsWritingToCustomSerializerWithExplicitConverterInternal), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod(attributedType, dictionaryType) - .Invoke(null, null); + string json = await Serializer.SerializeWrapper(obj); + Assert.Equal(@"{""MyCustomOverflowWrite"":""OverflowValueWrite""}", json); } - private static void ExtensionProperty_SupportsWritingToCustomSerializerWithExplicitConverterInternal() - where TRoot : IClassWithOverflow, new() - where TDictionary : new() + [Theory] +#if BUILDING_SOURCE_GENERATOR_TESTS + [ActiveIssue("https://github.com/dotnet/runtime/issues/87005")] +#endif + [MemberData(nameof(GetCustomOverflowConverters))] + public async Task ExtensionProperty_IgnoresCustomSerializerWithOptions(JsonConverter dictionaryConverter) where TDictionary : IDictionary { - var root = new TRoot() - { - Overflow = new TDictionary() - }; + var options = Serializer.CreateOptions(makeReadOnly: false); + options.Converters.Add(dictionaryConverter); - string json = JsonSerializer.Serialize(root); - Assert.Equal(@"{""MyCustomOverflowWrite"":""OverflowValueWrite""}", json); + ClassWithExtensionData obj = await Serializer.DeserializeWrapper>(@"{""TestKey"":""TestValue""}", options); + Assert.Equal("TestValue", ((JsonElement)obj.Overflow["TestKey"]).GetString()); } - [Theory] - [InlineData(typeof(Dictionary), typeof(DictionaryOverflowConverter), typeof(object))] - [InlineData(typeof(Dictionary), typeof(JsonElementOverflowConverter), typeof(JsonElement))] - [InlineData(typeof(CustomOverflowDictionary), typeof(CustomObjectDictionaryOverflowConverter), typeof(object))] - [InlineData(typeof(CustomOverflowDictionary), typeof(CustomJsonElementDictionaryOverflowConverter), typeof(JsonElement))] - public void ExtensionProperty_IgnoresCustomSerializerWithOptions(Type overflowType, Type converterType, Type elementType) + public static IEnumerable GetCustomOverflowConverters() { - typeof(ExtensionDataTests) - .GetMethod(nameof(ExtensionProperty_IgnoresCustomSerializerWithOptionsInternal), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod(overflowType, elementType, converterType) - .Invoke(null, null); + yield return WrapArgs(new DictionaryOverflowConverter()); + yield return WrapArgs(new JsonElementOverflowConverter()); + yield return WrapArgs(new CustomObjectDictionaryOverflowConverter()); + yield return WrapArgs(new CustomJsonElementDictionaryOverflowConverter()); + + static object[] WrapArgs(JsonConverter converter) => new object[] { converter }; } [Fact] @@ -541,30 +530,22 @@ public async Task ExtensionProperty_IgnoresCustomSerializerWithOptions_JsonObjec Assert.Contains("JsonObject", ex.ToString()); } - private static void ExtensionProperty_IgnoresCustomSerializerWithOptionsInternal() - where TConverter : JsonConverter, new() - where TDictionary : IDictionary + [Theory] + [MemberData(nameof(GetClassesWithCustomExtensionDataOverflowConverter))] + public async Task ExtensionProperty_IgnoresCustomSerializerWithExplicitConverter(ClassWithOverflow obj) + where ClassWithOverflow : IClassWithOverflow { - var options = new JsonSerializerOptions(); - options.Converters.Add(new TConverter()); - - ClassWithExtensionData obj - = JsonSerializer.Deserialize>(@"{""TestKey"":""TestValue""}", options); - - Assert.Equal("TestValue", ((JsonElement)(object)obj.Overflow["TestKey"]).GetString()); + obj = await Serializer.DeserializeWrapper(@"{""TestKey"":""TestValue""}"); + Assert.Equal("TestValue", ((JsonElement)obj.GetOverflow()["TestKey"]).GetString()); } - [Theory] - [InlineData(typeof(ClassWithExtensionDataWithAttributedConverter), typeof(Dictionary), typeof(object))] - [InlineData(typeof(ClassWithJsonElementExtensionDataWithAttributedConverter), typeof(Dictionary), typeof(JsonElement))] - [InlineData(typeof(ClassWithCustomElementExtensionDataWithAttributedConverter), typeof(CustomOverflowDictionary), typeof(object))] - [InlineData(typeof(ClassWithCustomJsonElementExtensionDataWithAttributedConverter), typeof(CustomOverflowDictionary), typeof(JsonElement))] - public void ExtensionProperty_IgnoresCustomSerializerWithExplicitConverter(Type attributedType, Type dictionaryType, Type elementType) + public static IEnumerable GetClassesWithCustomExtensionDataOverflowConverter() { - typeof(ExtensionDataTests) - .GetMethod(nameof(ExtensionProperty_IgnoresCustomSerializerWithExplicitConverterInternal), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod(attributedType, dictionaryType, elementType) - .Invoke(null, null); + yield return WrapArgs(new ClassWithExtensionDataWithAttributedConverter { Overflow = new() }); + yield return WrapArgs(new ClassWithJsonElementExtensionDataWithAttributedConverter { Overflow = new() }); + yield return WrapArgs(new ClassWithCustomElementExtensionDataWithAttributedConverter { Overflow = new() }); + yield return WrapArgs(new ClassWithCustomJsonElementExtensionDataWithAttributedConverter { Overflow = new() }); + static object[] WrapArgs(IClassWithOverflow classWithOverflow) => new object[] { classWithOverflow }; } [Fact] @@ -576,16 +557,6 @@ ClassWithExtensionData obj Assert.Equal("TestValue", obj.Overflow["TestKey"].GetValue()); } - private static void ExtensionProperty_IgnoresCustomSerializerWithExplicitConverterInternal() - where TRoot : IClassWithOverflow, new() - where TDictionary : IDictionary - { - ClassWithExtensionData obj - = JsonSerializer.Deserialize>(@"{""TestKey"":""TestValue""}"); - - Assert.Equal("TestValue", ((JsonElement)(object)obj.Overflow["TestKey"]).GetString()); - } - [Fact] public async Task ExtensionPropertyObjectValue_Empty() { diff --git a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Dictionary.cs b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Dictionary.cs index 9a4b97befd6a1..45a649833f002 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Dictionary.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Dictionary.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Xunit; @@ -580,7 +581,16 @@ internal struct ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfString public ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfStringToJsonElement() {} [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] - public IDictionary Property { get; } = JsonSerializer.Deserialize>("""{"a":1,"b":2,"c":3}"""); + public IDictionary Property { get; } = ParseJsonObject("""{"a":1,"b":2,"c":3}""").ToDictionary(kv => kv.Key, kv => kv.Value); + } + + private static IEnumerable> ParseJsonObject(string json) + { + JsonDocument doc = JsonDocument.Parse(json); + foreach (var entry in doc.RootElement.EnumerateObject()) + { + yield return new KeyValuePair(entry.Name, entry.Value); + } } [Fact] @@ -625,7 +635,7 @@ internal struct ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfString { public ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfStringToJsonElementWithoutPopulateAttribute() {} - public IDictionary Property { get; } = JsonSerializer.Deserialize>("""{"a":1,"b":2,"c":3}"""); + public IDictionary Property { get; } = ParseJsonObject("""{"a":1,"b":2,"c":3}""").ToDictionary(kv => kv.Key, kv => kv.Value); } [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] @@ -633,7 +643,7 @@ internal struct ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfString { public ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfStringToJsonElementWithAttributeOnType() {} - public IDictionary Property { get; } = JsonSerializer.Deserialize>("""{"a":1,"b":2,"c":3}"""); + public IDictionary Property { get; } = ParseJsonObject("""{"a":1,"b":2,"c":3}""").ToDictionary(kv => kv.Key, kv => kv.Value); } [Fact] @@ -670,7 +680,7 @@ public async Task CreationHandlingSetWithAttribute_CanPopulate_IDictionary_Backe internal class ClassWithReadOnlyPropertyIDictionary_BackedBy_StructDictionaryOfStringToJsonElement { [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] - public IDictionary Property { get; } = JsonSerializer.Deserialize>("""{"a":1,"b":2,"c":3}"""); + public IDictionary Property { get; } = new StructDictionary(ParseJsonObject("""{"a":1,"b":2,"c":3}""")); } [Fact] @@ -716,13 +726,13 @@ public async Task CreationHandlingSetWithOptions_CanPopulate_IDictionary_BackedB internal class ClassWithReadOnlyPropertyIDictionary_BackedBy_StructDictionaryOfStringToJsonElementWithoutPopulateAttribute { - public IDictionary Property { get; } = JsonSerializer.Deserialize>("""{"a":1,"b":2,"c":3}"""); + public IDictionary Property { get; } = new StructDictionary(ParseJsonObject("""{"a":1,"b":2,"c":3}""")); } [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] internal class ClassWithReadOnlyPropertyIDictionary_BackedBy_StructDictionaryOfStringToJsonElementWithAttributeOnType { - public IDictionary Property { get; } = JsonSerializer.Deserialize>("""{"a":1,"b":2,"c":3}"""); + public IDictionary Property { get; } = new StructDictionary(ParseJsonObject("""{"a":1,"b":2,"c":3}""")); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs index 23ae7662d7253..afe884ad5e7db 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs @@ -582,7 +582,16 @@ internal struct ClassWithReadOnlyPropertyIList_BackedBy_ListOfJsonElement public ClassWithReadOnlyPropertyIList_BackedBy_ListOfJsonElement() {} [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] - public IList Property { get; } = JsonSerializer.Deserialize>("[1,2,3]"); + public IList Property { get; } = new List(ParseJsonArray("[1,2,3]")); + } + + private static IEnumerable ParseJsonArray(string json) + { + JsonDocument doc = JsonDocument.Parse(json); + foreach (JsonElement element in doc.RootElement.EnumerateArray()) + { + yield return element; + } } [Fact] @@ -627,7 +636,7 @@ internal struct ClassWithReadOnlyPropertyIList_BackedBy_ListOfJsonElementWithout { public ClassWithReadOnlyPropertyIList_BackedBy_ListOfJsonElementWithoutPopulateAttribute() {} - public IList Property { get; } = JsonSerializer.Deserialize>("[1,2,3]"); + public IList Property { get; } = new List(ParseJsonArray("[1,2,3]")); } [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] @@ -635,7 +644,7 @@ internal struct ClassWithReadOnlyPropertyIList_BackedBy_ListOfJsonElementWithAtt { public ClassWithReadOnlyPropertyIList_BackedBy_ListOfJsonElementWithAttributeOnType() {} - public IList Property { get; } = JsonSerializer.Deserialize>("[1,2,3]"); + public IList Property { get; } = new List(ParseJsonArray("[1,2,3]")); } [Fact] @@ -672,7 +681,7 @@ public async Task CreationHandlingSetWithAttribute_CanPopulate_IList_BackedBy_St internal class ClassWithReadOnlyPropertyIList_BackedBy_StructListOfJsonElement { [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] - public IList Property { get; } = JsonSerializer.Deserialize>("[1,2,3]"); + public IList Property { get; } = new StructList(ParseJsonArray("[1,2,3]")); } [Fact] @@ -718,13 +727,13 @@ public async Task CreationHandlingSetWithOptions_CanPopulate_IList_BackedBy_Stru internal class ClassWithReadOnlyPropertyIList_BackedBy_StructListOfJsonElementWithoutPopulateAttribute { - public IList Property { get; } = JsonSerializer.Deserialize>("[1,2,3]"); + public IList Property { get; } = new StructList(ParseJsonArray("[1,2,3]")); } [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] internal class ClassWithReadOnlyPropertyIList_BackedBy_StructListOfJsonElementWithAttributeOnType { - public IList Property { get; } = JsonSerializer.Deserialize>("[1,2,3]"); + public IList Property { get; } = new StructList(ParseJsonArray("[1,2,3]")); } [Fact] @@ -1229,7 +1238,7 @@ internal struct ClassWithReadOnlyPropertyQueue public ClassWithReadOnlyPropertyQueue() {} [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] - public Queue Property { get; } = JsonSerializer.Deserialize("[1,2,3]"); + public Queue Property { get; } = new Queue(ParseJsonArray("[1,2,3]").ToArray()); } [Fact] @@ -1274,7 +1283,7 @@ internal struct ClassWithReadOnlyPropertyQueueWithoutPopulateAttribute { public ClassWithReadOnlyPropertyQueueWithoutPopulateAttribute() {} - public Queue Property { get; } = JsonSerializer.Deserialize("[1,2,3]"); + public Queue Property { get; } = new Queue(ParseJsonArray("[1,2,3]").ToArray()); } [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] @@ -1282,7 +1291,7 @@ internal struct ClassWithReadOnlyPropertyQueueWithAttributeOnType { public ClassWithReadOnlyPropertyQueueWithAttributeOnType() {} - public Queue Property { get; } = JsonSerializer.Deserialize("[1,2,3]"); + public Queue Property { get; } = new Queue(ParseJsonArray("[1,2,3]").ToArray()); } [Fact] @@ -1677,7 +1686,7 @@ internal struct ClassWithReadOnlyPropertyStack public ClassWithReadOnlyPropertyStack() {} [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] - public Stack Property { get; } = JsonSerializer.Deserialize("[1,2,3]"); + public Stack Property { get; } = new Stack(ParseJsonArray("[1,2,3]").ToArray()); } [Fact] @@ -1722,7 +1731,7 @@ internal struct ClassWithReadOnlyPropertyStackWithoutPopulateAttribute { public ClassWithReadOnlyPropertyStackWithoutPopulateAttribute() {} - public Stack Property { get; } = JsonSerializer.Deserialize("[1,2,3]"); + public Stack Property { get; } = new Stack(ParseJsonArray("[1,2,3]").ToArray()); } [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] @@ -1730,7 +1739,7 @@ internal struct ClassWithReadOnlyPropertyStackWithAttributeOnType { public ClassWithReadOnlyPropertyStackWithAttributeOnType() {} - public Stack Property { get; } = JsonSerializer.Deserialize("[1,2,3]"); + public Stack Property { get; } = new Stack(ParseJsonArray("[1,2,3]").ToArray()); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Generic.cs b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Generic.cs index ca5e6c89b631e..1937f5fe73a19 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Generic.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Generic.cs @@ -8,7 +8,6 @@ using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Reflection; using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using Xunit; @@ -42,8 +41,15 @@ internal struct StructList : IList, IList set => _list[index] = (T)value; } + [JsonConstructor] public StructList() { } + public StructList(IEnumerable values) + { + _list.AddRange(values); + _count = _list.Count; + } + public void Add(T item) { _count++; @@ -261,8 +267,15 @@ internal struct StructDictionary : IDictionary, IDic // we track count separately to make sure tests are not passing by accident because we use reference to list inside of struct private int _count; + [JsonConstructor] public StructDictionary() { } + public StructDictionary(IEnumerable> entries) + { + _dict = entries.ToDictionary(kv => kv.Key, kv => kv.Value); + _count = _dict.Count; + } + public TValue this[TKey key] { get => _dict[key]; @@ -415,123 +428,99 @@ public async Task CreationHandlingSetWithAttribute_PopulateSetWithModifierWithIn } [Theory] - [InlineData(typeof(List))] - [InlineData(typeof(IList))] - [InlineData(typeof(IList))] - [InlineData(typeof(Queue))] - [InlineData(typeof(Queue))] - [InlineData(typeof(ConcurrentQueue))] - [InlineData(typeof(Stack))] - [InlineData(typeof(Stack))] - [InlineData(typeof(ConcurrentStack))] - [InlineData(typeof(ICollection))] - [InlineData(typeof(ISet))] - [InlineData(typeof(Dictionary))] - [InlineData(typeof(IDictionary))] - [InlineData(typeof(IDictionary))] - [InlineData(typeof(ConcurrentDictionary))] - [InlineData(typeof(SortedDictionary))] - public Task CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeNull(Type type) - { - return (Task)typeof(JsonCreationHandlingTests) - .GetMethod(nameof(CreationHandling_PopulatedPropertyDeserializeNullGeneric), BindingFlags.NonPublic | BindingFlags.Instance) - .MakeGenericMethod(type).Invoke(this, null); - } - - private async Task CreationHandling_PopulatedPropertyDeserializeNullGeneric() - { - JsonSerializerOptions options = Serializer.CreateOptions(); - string json = """{"Property":null}"""; - var obj = await Serializer.DeserializeWrapper>(json, options); - Assert.Null(obj.Property); - } + [MemberData(nameof(GetTestedCollectionTypes))] + public Task CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeNull(TypeWitness typeWitness) + => typeWitness.Accept(CreationHandling_PopulatedPropertyDeserializeNull_TestBody.Instance, Serializer); - [Theory] - [InlineData(typeof(List))] - [InlineData(typeof(IList))] - [InlineData(typeof(IList))] - [InlineData(typeof(Queue))] - [InlineData(typeof(Queue))] - [InlineData(typeof(ConcurrentQueue))] - [InlineData(typeof(Stack))] - [InlineData(typeof(Stack))] - [InlineData(typeof(ConcurrentStack))] - [InlineData(typeof(ICollection))] - [InlineData(typeof(ISet))] - [InlineData(typeof(Dictionary))] - [InlineData(typeof(IDictionary))] - [InlineData(typeof(IDictionary))] - [InlineData(typeof(ConcurrentDictionary))] - [InlineData(typeof(SortedDictionary))] - public Task CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeNullOnReadOnlyProperty(Type type) - { - return (Task)typeof(JsonCreationHandlingTests) - .GetMethod(nameof(CreationHandling_PopulatedPropertyDeserializeNullOnReadOnlyPropertyGeneric), BindingFlags.NonPublic | BindingFlags.Instance) - .MakeGenericMethod(type).Invoke(this, null); - } - - private async Task CreationHandling_PopulatedPropertyDeserializeNullOnReadOnlyPropertyGeneric() - { - JsonSerializerOptions options = Serializer.CreateOptions(); - string json = """{"Property":null}"""; - await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper>(json, options)); + private sealed class CreationHandling_PopulatedPropertyDeserializeNull_TestBody : ITypeVisitor + { + public readonly static CreationHandling_PopulatedPropertyDeserializeNull_TestBody Instance = new(); + public async Task Visit(JsonSerializerWrapper serializer) + { + string json = """{"Property":null}"""; + var obj = await serializer.DeserializeWrapper>(json); + Assert.Null(obj.Property); + } } [Theory] - [InlineData(typeof(List), true)] - [InlineData(typeof(IList), true)] - [InlineData(typeof(IList), true)] - [InlineData(typeof(Queue), true)] - [InlineData(typeof(Queue), true)] - [InlineData(typeof(ConcurrentQueue), true)] - [InlineData(typeof(Stack), true)] - [InlineData(typeof(Stack), true)] - [InlineData(typeof(ConcurrentStack), true)] - [InlineData(typeof(ICollection), true)] - [InlineData(typeof(ISet), true)] - [InlineData(typeof(Dictionary), false)] - [InlineData(typeof(IDictionary), false)] - [InlineData(typeof(IDictionary), false)] - [InlineData(typeof(ConcurrentDictionary), false)] - [InlineData(typeof(SortedDictionary), false)] - [InlineData(typeof(StructList?), true)] - [InlineData(typeof(StructCollection?), true)] - [InlineData(typeof(StructSet?), true)] - [InlineData(typeof(StructDictionary?), false)] - public Task CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeInitiallyNull(Type type, bool isArray) - { - return (Task)typeof(JsonCreationHandlingTests) - .GetMethod(nameof(CreationHandling_PopulatedPropertyDeserializeInitiallyNullGeneric), BindingFlags.NonPublic | BindingFlags.Instance) - .MakeGenericMethod(type).Invoke(this, new object[] { isArray }); - } - - private async Task CreationHandling_PopulatedPropertyDeserializeInitiallyNullGeneric(bool isArray) - { - JsonSerializerOptions options = Serializer.CreateOptions(); - string json = isArray ? """{"Property":[1,2,3]}""" : """{"Property":{"a":1,"b":2,"c":3}}"""; - - if (typeof(T).IsValueType) + [MemberData(nameof(GetTestedCollectionTypes))] + public Task CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeNullOnReadOnlyProperty(TypeWitness typeWitness) + => typeWitness.Accept(CreationHandling_PopulatedPropertyDeserializeNullOnReadOnlyPropertyGeneric_TestBody.Instance, Serializer); + + private sealed class CreationHandling_PopulatedPropertyDeserializeNullOnReadOnlyPropertyGeneric_TestBody : ITypeVisitor + { + public readonly static CreationHandling_PopulatedPropertyDeserializeNullOnReadOnlyPropertyGeneric_TestBody Instance = new(); + public async Task Visit(JsonSerializerWrapper serializer) { - await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper>("{}", options)); + string json = """{"Property":null}"""; + await Assert.ThrowsAsync(async () => await serializer.DeserializeWrapper>(json)); } - else - { - var obj = await Serializer.DeserializeWrapper>("{}", options); - Assert.Null(obj.Property); + } - obj = await Serializer.DeserializeWrapper>(json, options); - Assert.Null(obj.Property); - } + [Theory] + [MemberData(nameof(GetTestedCollectionTypes))] + public Task CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeInitiallyNull(TypeWitness typeWitness) + => typeWitness.Accept(CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeInitiallyNull_TestBody.Instance, Serializer); + private sealed class CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeInitiallyNull_TestBody : ITypeVisitor + { + public readonly static CreationHandlingSetWithAttribute_PopulatedPropertyDeserializeInitiallyNull_TestBody Instance = new(); + public async Task Visit(JsonSerializerWrapper serializer) { - var obj = await Serializer.DeserializeWrapper>("{}", options); - Assert.Null(obj.Property); + JsonTypeInfoKind kind = serializer.DefaultOptions.GetTypeInfo(typeof(T)).Kind; + Assert.True(kind is JsonTypeInfoKind.Enumerable or JsonTypeInfoKind.Dictionary); + string json = kind is JsonTypeInfoKind.Enumerable ? """{"Property":[1,2,3]}""" : """{"Property":{"a":1,"b":2,"c":3}}"""; + + if (typeof(T).IsValueType) + { + await Assert.ThrowsAsync(async () => await serializer.DeserializeWrapper>("{}")); + } + else + { + var obj = await serializer.DeserializeWrapper>("{}"); + Assert.Null(obj.Property); + + obj = await serializer.DeserializeWrapper>(json); + Assert.Null(obj.Property); + } + + { + var obj = await serializer.DeserializeWrapper>("{}"); + Assert.Null(obj.Property); - obj = await Serializer.DeserializeWrapper>(json, options); - Assert.NotNull(obj.Property); + obj = await serializer.DeserializeWrapper>(json); + Assert.NotNull(obj.Property); + } } } + public static IEnumerable GetTestedCollectionTypes() + { + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness>()); + yield return Wrap(new TypeWitness?>()); + yield return Wrap(new TypeWitness?>()); + yield return Wrap(new TypeWitness?>()); + yield return Wrap(new TypeWitness?>()); + + static object[] Wrap(TypeWitness witness) => new object[] { witness }; + } + private static void CheckGenericDictionaryContent(IDictionary dict, int expectedNumberOfElements = 6) { Assert.Equal(expectedNumberOfElements, dict.Count); diff --git a/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs b/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs index 159bd389dec0b..259e363555f35 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs @@ -65,18 +65,22 @@ public JsonSerializerOptions GetDefaultOptionsWithMetadataModifier(Action configure = null, - bool includeFields = false, - List customConverters = null, - Action modifier = null) + bool? includeFields = false, + List? customConverters = null, + Action? modifier = null, + bool makeReadOnly = true) { - IJsonTypeInfoResolver resolver = DefaultOptions.TypeInfoResolver; - resolver = modifier != null ? resolver.WithModifier(modifier) : resolver; + var options = new JsonSerializerOptions(DefaultOptions); - JsonSerializerOptions options = new() + if (includeFields != null) { - TypeInfoResolver = resolver, - IncludeFields = includeFields, - }; + options.IncludeFields = includeFields.Value; + } + + if (modifier != null && options.TypeInfoResolver != null) + { + options.TypeInfoResolver = DefaultOptions.TypeInfoResolver.WithModifier(modifier); + } if (customConverters != null) { @@ -88,7 +92,10 @@ public JsonSerializerOptions GetDefaultOptionsWithMetadataModifier(Action s_stripWhitespace.Replace(value, string.Empty); } + + /// + /// Generic visitor pattern used for safely invoking generic methods in AOT. + /// + public abstract class TypeWitness + { + public abstract TResult Accept(ITypeVisitor visitor, TState state); + } + + /// + /// Generic visitor pattern used for safely invoking generic methods in AOT. + /// + public sealed class TypeWitness : TypeWitness + { + public override TResult Accept(ITypeVisitor visitor, TState state) => visitor.Visit(state); + } + + /// + /// Generic visitor pattern used for safely invoking generic methods in AOT. + /// + public interface ITypeVisitor + { + public TResult Visit(TState state); + } } diff --git a/src/libraries/System.Text.Json/tests/Common/ReferenceHandlerTests/ReferenceHandlerTests.Serialize.cs b/src/libraries/System.Text.Json/tests/Common/ReferenceHandlerTests/ReferenceHandlerTests.Serialize.cs index caecc062d84ad..6fde273fed85b 100644 --- a/src/libraries/System.Text.Json/tests/Common/ReferenceHandlerTests/ReferenceHandlerTests.Serialize.cs +++ b/src/libraries/System.Text.Json/tests/Common/ReferenceHandlerTests/ReferenceHandlerTests.Serialize.cs @@ -29,7 +29,7 @@ public class Employee public Dictionary ContactsString { get; set; } = new Dictionary() { { "Bob", "555-5555" } }; } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNativeAot))] public async Task ExtensionDataDictionaryHandlesPreserveReferences() { Employee bob = new Employee { Name = "Bob" }; diff --git a/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.Constructor.cs b/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.Constructor.cs index 8f6df2d166749..285c5b7893473 100644 --- a/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.Constructor.cs +++ b/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.Constructor.cs @@ -659,60 +659,33 @@ public void Verify() Assert.Equal("f2c92fcc-459f-4287-90b6-a7cbd82aeb0e", Id.ToString()); Assert.Equal(24, Age); - string serialized = JsonSerializer.Serialize(this); - Assert.Contains(@"""Point2D"":{", serialized); - Assert.Contains(@"""ReadOnlyPoint2D"":{", serialized); - Assert.Contains(@"""Point2DWithExtDataClass"":{", serialized); - Assert.Contains(@"""ReadOnlyPoint2DWithExtDataClass"":{", serialized); - Assert.Contains(@"""Point3DStruct"":{", serialized); - Assert.Contains(@"""ReadOnlyPoint3DStruct"":{", serialized); - Assert.Contains(@"""Point2DWithExtData"":{", serialized); - Assert.Contains(@"""ReadOnlyPoint2DWithExtData"":{", serialized); - - serialized = JsonSerializer.Serialize(Point2D); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - - serialized = JsonSerializer.Serialize(ReadOnlyPoint2D); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - - serialized = JsonSerializer.Serialize(Point2DWithExtDataClass); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""b"":3", serialized); - - serialized = JsonSerializer.Serialize(ReadOnlyPoint2DWithExtDataClass); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""b"":3", serialized); - - serialized = JsonSerializer.Serialize(Point3DStruct); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""Z"":3", serialized); - - serialized = JsonSerializer.Serialize(ReadOnlyPoint3DStruct); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""Z"":3", serialized); - - serialized = JsonSerializer.Serialize(Point2DWithExtData); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""b"":3", serialized); - - serialized = JsonSerializer.Serialize(ReadOnlyPoint2DWithExtData); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""b"":3", serialized); + Point2D.Verify(); + ReadOnlyPoint2D.Verify(); + + Assert.Equal(1, Point2DWithExtDataClass.X); + Assert.Equal(2, Point2DWithExtDataClass.Y); + Assert.True(Point2DWithExtDataClass.ExtensionData.ContainsKey("b")); + + Assert.Equal(1, Point3DStruct.X); + Assert.Equal(2, Point3DStruct.Y); + Assert.Equal(3, Point3DStruct.Z); + + Assert.Equal(1, ReadOnlyPoint3DStruct.X); + Assert.Equal(2, ReadOnlyPoint3DStruct.Y); + Assert.Equal(3, ReadOnlyPoint3DStruct.Z); + + Assert.Equal(1, Point2DWithExtData.X); + Assert.Equal(2, Point2DWithExtData.Y); + Assert.True(Point2DWithExtData.ExtensionData.ContainsKey("b")); + + Assert.Equal(1, ReadOnlyPoint2DWithExtData.X); + Assert.Equal(2, ReadOnlyPoint2DWithExtData.Y); + Assert.True(ReadOnlyPoint2DWithExtData.ExtensionData.ContainsKey("b")); } public void VerifyMinimal() { - string serialized = JsonSerializer.Serialize(ReadOnlyPoint2D); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); + ReadOnlyPoint2D.Verify(); } } @@ -802,53 +775,28 @@ public void Verify() Assert.Equal("f2c92fcc-459f-4287-90b6-a7cbd82aeb0e", Id.ToString()); Assert.Equal(24, Age); - string serialized = JsonSerializer.Serialize(this); - Assert.Contains(@"""Point2D"":{", serialized); - Assert.Contains(@"""ReadOnlyPoint2D"":{", serialized); - Assert.Contains(@"""Point2DWithExtDataClass"":{", serialized); - Assert.Contains(@"""ReadOnlyPoint2DWithExtDataClass"":{", serialized); - Assert.Contains(@"""Point3DStruct"":{", serialized); - Assert.Contains(@"""ReadOnlyPoint3DStruct"":{", serialized); - Assert.Contains(@"""Point2DWithExtData"":{", serialized); - Assert.Contains(@"""ReadOnlyPoint2DWithExtData"":{", serialized); + Point2D.Verify(); + ReadOnlyPoint2D.Verify(); - serialized = JsonSerializer.Serialize(Point2D); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); + Assert.Equal(1, Point2DWithExtDataClass.X); + Assert.Equal(2, Point2DWithExtDataClass.Y); + Assert.True(Point2DWithExtDataClass.ExtensionData.ContainsKey("b")); - serialized = JsonSerializer.Serialize(ReadOnlyPoint2D); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); + Assert.Equal(1, Point3DStruct.X); + Assert.Equal(2, Point3DStruct.Y); + Assert.Equal(3, Point3DStruct.Z); - serialized = JsonSerializer.Serialize(Point2DWithExtDataClass); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""b"":3", serialized); + Assert.Equal(1, ReadOnlyPoint3DStruct.X); + Assert.Equal(2, ReadOnlyPoint3DStruct.Y); + Assert.Equal(3, ReadOnlyPoint3DStruct.Z); - serialized = JsonSerializer.Serialize(ReadOnlyPoint2DWithExtDataClass); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""b"":3", serialized); + Assert.Equal(1, Point2DWithExtData.X); + Assert.Equal(2, Point2DWithExtData.Y); + Assert.True(Point2DWithExtData.ExtensionData.ContainsKey("b")); - serialized = JsonSerializer.Serialize(Point3DStruct); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""Z"":3", serialized); - - serialized = JsonSerializer.Serialize(ReadOnlyPoint3DStruct); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""Z"":3", serialized); - - serialized = JsonSerializer.Serialize(Point2DWithExtData); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""b"":3", serialized); - - serialized = JsonSerializer.Serialize(ReadOnlyPoint2DWithExtData); - Assert.Contains(@"""X"":1", serialized); - Assert.Contains(@"""Y"":2", serialized); - Assert.Contains(@"""b"":3", serialized); + Assert.Equal(1, ReadOnlyPoint2DWithExtData.X); + Assert.Equal(2, ReadOnlyPoint2DWithExtData.Y); + Assert.True(ReadOnlyPoint2DWithExtData.ExtensionData.ContainsKey("b")); } } @@ -1014,7 +962,11 @@ public class ObjWCtorMixedParams : ITestClassWithParameterizedCtor } public static ObjWCtorMixedParams GetInstance() => +#if BUILDING_SOURCE_GENERATOR_TESTS + JsonSerializer.Deserialize(s_json, System.Text.Json.SourceGeneration.Tests.ConstructorTests_Default.ConstructorTestsContext_Default.Default.ObjWCtorMixedParams); +#else JsonSerializer.Deserialize(s_json); +#endif public static string s_json => $"{{{s_partialJson1},{s_partialJson2}}}"; @@ -2392,7 +2344,6 @@ public struct StructWithFourArgs public StructWithFourArgs(int w, int x, int y, int z) => (W, X, Y, Z) = (w, x, y, z); } -#if FIXED // https://github.com/dotnet/roslyn/issues/66900 public record ClassWithManyConstructorParameters( int P000, int P001, int P002, int P003, int P004, int P005, int P006, int P007, int P008, int P009, int P010, int P011, int P012, int P013, int P014, int P015, int P016, int P017, int P018, int P019, @@ -2600,5 +2551,4 @@ public static ClassWithManyConstructorParameters Create() P990: 990, P991: 991, P992: 992, P993: 993, P994: 994, P995: 995, P996: 996, P997: 997, P998: 998, P999: 999); } } -#endif } diff --git a/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.cs b/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.cs index 3d7c500741102..3a8a3b64c9fe4 100644 --- a/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.cs +++ b/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.cs @@ -461,7 +461,11 @@ public void Verify() { if (data is JsonElement element) { - SimpleTestClass obj = JsonSerializer.Deserialize(element.GetRawText()); +#if BUILDING_SOURCE_GENERATOR_TESTS + SimpleTestClass obj = JsonSerializer.Deserialize(element, System.Text.Json.SourceGeneration.Tests.CollectionTests_Default.CollectionTestsContext_Default.Default.SimpleTestClass); +#else + SimpleTestClass obj = JsonSerializer.Deserialize(element); +#endif obj.Verify(); } else @@ -510,7 +514,11 @@ public void Verify() { if (data is JsonElement element) { - SimpleTestClass obj = JsonSerializer.Deserialize(element.GetRawText()); +#if BUILDING_SOURCE_GENERATOR_TESTS + SimpleTestClass obj = JsonSerializer.Deserialize(element, System.Text.Json.SourceGeneration.Tests.CollectionTests_Default.CollectionTestsContext_Default.Default.SimpleTestClass); +#else + SimpleTestClass obj = JsonSerializer.Deserialize(element); +#endif obj.Verify(); } else @@ -561,7 +569,11 @@ public void Verify() { if (data is JsonElement element) { - SimpleTestClass obj = JsonSerializer.Deserialize(element.GetRawText()); +#if BUILDING_SOURCE_GENERATOR_TESTS + SimpleTestClass obj = JsonSerializer.Deserialize(element, System.Text.Json.SourceGeneration.Tests.CollectionTests_Default.CollectionTestsContext_Default.Default.SimpleTestClass); +#else + SimpleTestClass obj = JsonSerializer.Deserialize(element); +#endif obj.Verify(); } else diff --git a/src/libraries/System.Text.Json/tests/Common/UnsupportedTypesTests.cs b/src/libraries/System.Text.Json/tests/Common/UnsupportedTypesTests.cs index e28cfd5b556e6..a17831b43bd79 100644 --- a/src/libraries/System.Text.Json/tests/Common/UnsupportedTypesTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/UnsupportedTypesTests.cs @@ -27,6 +27,8 @@ public async Task DeserializeUnsupportedType(ValueWrapper wrapper) { _ = wrapper; // only used to instantiate T + Assert.NotNull(Serializer.GetTypeInfo(typeof(T))); // It should be possible to obtain metadata for the type. + string json = @"""Some string"""; // Any test payload is fine. Type type = GetNullableOfTUnderlyingType(typeof(T), out bool isNullableOfT); @@ -61,6 +63,8 @@ public async Task SerializeUnsupportedType(ValueWrapper wrapper) { T value = wrapper.value; + Assert.NotNull(Serializer.GetTypeInfo(typeof(T))); // It should be possible to obtain metadata for the type. + Type type = GetNullableOfTUnderlyingType(typeof(T), out bool isNullableOfT); string fullName = type.FullName; @@ -99,18 +103,19 @@ public async Task SerializeUnsupportedType(ValueWrapper wrapper) } #if !BUILDING_SOURCE_GENERATOR_TESTS - Type runtimeType = GetNullableOfTUnderlyingType(value.GetType(), out bool _); + // The reflection-based serializer will report the runtime type and not the declared type. + fullName = GetNullableOfTUnderlyingType(value.GetType(), out bool _).FullName; +#endif ex = await Assert.ThrowsAsync(async () => await Serializer.SerializeWrapper(value)); exAsStr = ex.ToString(); - Assert.Contains(runtimeType.FullName, exAsStr); + Assert.Contains(fullName, exAsStr); Assert.Contains("$", exAsStr); ClassWithType polyObj = new ClassWithType { Prop = value }; ex = await Assert.ThrowsAsync(async () => await Serializer.SerializeWrapper(polyObj)); exAsStr = ex.ToString(); - Assert.Contains(runtimeType.FullName, exAsStr); -#endif + Assert.Contains(fullName, exAsStr); } public static IEnumerable GetUnsupportedValues() diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/JsonSerializerContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/JsonSerializerContextTests.cs index a61ba2bc6a877..741754dd251f1 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/JsonSerializerContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/JsonSerializerContextTests.cs @@ -700,6 +700,7 @@ internal partial class SingleClassWithCustomConverterFactoryPropertyContext : Js // Regression test for https://github.com/dotnet/runtime/issues/61860 [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/79311", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static void SupportsGenericParameterWithCustomConverterFactory() { var value = new List { TestEnum.Cee }; diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs index 562dba39b59f4..4fcb6c1f30051 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs @@ -233,6 +233,7 @@ public override void EnsureFastPathGeneratedAsExpected() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/79311", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public void EnsureHelperMethodGenerated_TypeFactory() { // There are 2 helper methods generated for obtaining a converter from a factory: @@ -253,6 +254,7 @@ public void EnsureHelperMethodGenerated_TypeFactory() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/79311", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public void EnsureHelperMethodGenerated_ImplicitPropertyFactory() { // ContextWithImplicitStringEnum does not have an entry for EnumWrittenAsString since it is diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/CollectionTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/CollectionTests.cs index 1f82adaae84cc..a9b785a47fb61 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/CollectionTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/CollectionTests.cs @@ -343,16 +343,31 @@ public async Task DeserializeAsyncEnumerable() [JsonSerializable(typeof(StringIImmutableSetWrapper))] [JsonSerializable(typeof(IEnumerable))] [JsonSerializable(typeof(ICollection>))] + [JsonSerializable(typeof(IEnumerable))] + [JsonSerializable(typeof(IEnumerable))] + [JsonSerializable(typeof(IEnumerable))] + [JsonSerializable(typeof(IEnumerable>))] + [JsonSerializable(typeof(IEnumerable>))] + [JsonSerializable(typeof(IEnumerable>))] + [JsonSerializable(typeof((IEnumerable, bool)?))] + [JsonSerializable(typeof((IEnumerable, bool)?))] + [JsonSerializable(typeof((IEnumerable, bool)?))] [JsonSerializable(typeof(IAsyncEnumerable))] [JsonSerializable(typeof(IAsyncEnumerable))] [JsonSerializable(typeof(IAsyncEnumerable))] + [JsonSerializable(typeof(EnumerableDto))] + [JsonSerializable(typeof(EnumerableDto))] + [JsonSerializable(typeof(EnumerableDto))] [JsonSerializable(typeof(AsyncEnumerableDto))] [JsonSerializable(typeof(AsyncEnumerableDto))] [JsonSerializable(typeof(AsyncEnumerableDto))] + [JsonSerializable(typeof(AsyncEnumerableDto>))] + [JsonSerializable(typeof(EnumerableDtoWithTwoProperties))] + [JsonSerializable(typeof(EnumerableDtoWithTwoProperties))] + [JsonSerializable(typeof(EnumerableDtoWithTwoProperties))] [JsonSerializable(typeof(AsyncEnumerableDtoWithTwoProperties))] [JsonSerializable(typeof(AsyncEnumerableDtoWithTwoProperties))] [JsonSerializable(typeof(AsyncEnumerableDtoWithTwoProperties))] - [JsonSerializable(typeof(AsyncEnumerableDto>))] [JsonSerializable(typeof(MockedAsyncEnumerable))] [JsonSerializable(typeof(MockedAsyncEnumerable))] [JsonSerializable(typeof(MockedAsyncEnumerable))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs index 2b4a718dec4df..1a7d13eb0218c 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs @@ -141,9 +141,10 @@ protected ConstructorTests_Metadata(JsonSerializerWrapper stringWrapper) [JsonSerializable(typeof(LargeType_IgnoredProp_Bind_Param))] [JsonSerializable(typeof(ClassWithIgnoredSameType))] [JsonSerializable(typeof(ClassWithDefaultCtorParams))] -#if FIXED // https://github.com/dotnet/roslyn/issues/66900 + [JsonSerializable(typeof(StructWithPropertyInit))] + [JsonSerializable(typeof(StructWithFieldInit))] + [JsonSerializable(typeof(StructWithExplicitParameterlessCtor))] [JsonSerializable(typeof(ClassWithManyConstructorParameters))] -#endif [JsonSerializable(typeof(ClassWithInvalidArray))] [JsonSerializable(typeof(ClassWithInvalidDictionary))] [JsonSerializable(typeof(TypeWithEnumParameters))] @@ -284,9 +285,10 @@ public ConstructorTests_Default(JsonSerializerWrapper jsonSerializer) : base(jso [JsonSerializable(typeof(LargeType_IgnoredProp_Bind_Param))] [JsonSerializable(typeof(ClassWithIgnoredSameType))] [JsonSerializable(typeof(ClassWithDefaultCtorParams))] -#if FIXED // https://github.com/dotnet/roslyn/issues/66900 + [JsonSerializable(typeof(StructWithPropertyInit))] + [JsonSerializable(typeof(StructWithFieldInit))] + [JsonSerializable(typeof(StructWithExplicitParameterlessCtor))] [JsonSerializable(typeof(ClassWithManyConstructorParameters))] -#endif [JsonSerializable(typeof(ClassWithInvalidArray))] [JsonSerializable(typeof(ClassWithInvalidDictionary))] [JsonSerializable(typeof(TypeWithEnumParameters))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ExtensionDataTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ExtensionDataTests.cs index 6d5d8982145e1..ba67748368ff3 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ExtensionDataTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ExtensionDataTests.cs @@ -61,6 +61,10 @@ public ExtensionDataTests_Metadata() [JsonSerializable(typeof(ClassWithExtensionPropertyThreeGenericParameters))] [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(ClassWithExtensionData))] + [JsonSerializable(typeof(ClassWithExtensionData>))] + [JsonSerializable(typeof(ClassWithExtensionData>))] + [JsonSerializable(typeof(ClassWithExtensionData>))] + [JsonSerializable(typeof(ClassWithExtensionData>))] [JsonSerializable(typeof(int))] [JsonSerializable(typeof(DummyObj))] [JsonSerializable(typeof(DummyStruct))] @@ -121,6 +125,10 @@ public ExtensionDataTests_Default() [JsonSerializable(typeof(ClassWithExtensionPropertyThreeGenericParameters))] [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(ClassWithExtensionData))] + [JsonSerializable(typeof(ClassWithExtensionData>))] + [JsonSerializable(typeof(ClassWithExtensionData>))] + [JsonSerializable(typeof(ClassWithExtensionData>))] + [JsonSerializable(typeof(ClassWithExtensionData>))] [JsonSerializable(typeof(int))] [JsonSerializable(typeof(DummyObj))] [JsonSerializable(typeof(DummyStruct))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/UnsupportedTypesTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/UnsupportedTypesTests.cs index d00c183008cda..6220538d5b52d 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/UnsupportedTypesTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/UnsupportedTypesTests.cs @@ -23,6 +23,7 @@ public sealed partial class UnsupportedTypesTests_Metadata : UnsupportedTypesTes [JsonSerializable(typeof(ClassWithIntPtrConverter))] // Unsupported types: [JsonSerializable(typeof(Type))] + [JsonSerializable(typeof(ClassWithType))] [JsonSerializable(typeof(ClassWithType))] [JsonSerializable(typeof(ConstructorInfo))] [JsonSerializable(typeof(ClassWithType))] @@ -68,6 +69,7 @@ public sealed partial class UnsupportedTypesTests_Default : UnsupportedTypesTest [JsonSerializable(typeof(ClassWithIntPtrConverter))] // Unsupported types: [JsonSerializable(typeof(Type))] + [JsonSerializable(typeof(ClassWithType))] [JsonSerializable(typeof(ClassWithType))] [JsonSerializable(typeof(ConstructorInfo))] [JsonSerializable(typeof(ClassWithType))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn3.11.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn3.11.Tests.csproj index 378fb96ca49f1..bde7513156c63 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn3.11.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn3.11.Tests.csproj @@ -6,6 +6,10 @@ + + + + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Tests.csproj index 5d327473bd433..0fa1bccdb970b 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Tests.csproj @@ -11,6 +11,10 @@ + + + + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/roslyn3.11.rd.xml b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/roslyn3.11.rd.xml new file mode 100644 index 0000000000000..eedb1e4ecc710 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/roslyn3.11.rd.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/roslyn4.4.rd.xml b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/roslyn4.4.rd.xml new file mode 100644 index 0000000000000..f9656b2e23382 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/roslyn4.4.rd.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index fcbe99e9ea4e2..8ccaf5bc1bab5 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -412,10 +412,6 @@ - - - -