From a13148497025ac00555dd7c3070068e560c27d9d Mon Sep 17 00:00:00 2001 From: "Max A. Kiselev" Date: Sat, 4 Mar 2017 00:56:00 +0300 Subject: [PATCH] Added tests demonstrating InvalidCastException deserializing a class implementing IEnumerable with a converter --- Src/Newtonsoft.Json.Tests/JsonConvertTest.cs | 109 +++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs index be188bee..ad7ae628 100644 --- a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs @@ -50,6 +50,7 @@ using Test = Xunit.FactAttribute; using Assert = Newtonsoft.Json.Tests.XUnitAssert; #else using NUnit.Framework; +using System.Collections; #endif @@ -1630,5 +1631,113 @@ namespace Newtonsoft.Json.Tests public class NonGenericChildClass : GenericIntermediateClass { } + + [Test] + public void ShouldNotPopulateReadOnlyEnumerableObjectWithNonDefaultConstructor() + { + object actual = JsonConvert.DeserializeObject("{\"foo\":{}}"); + Assert.NotNull(actual); + } + + [Test] + public void ShouldNotPopulateReadOnlyEnumerableObjectWithDefaultConstructor() + { + object actual = JsonConvert.DeserializeObject("{\"foo\":{}}"); + Assert.NotNull(actual); + } + + [Test] + public void ShouldNotPopulateContructorArgumentEnumerableObject() + { + object actual = JsonConvert.DeserializeObject("{\"foo\":{}}"); + Assert.NotNull(actual); + } + + [Test] + public void ShouldNotPopulateEnumerableObjectProperty() + { + object actual = JsonConvert.DeserializeObject("{\"foo\":{}}"); + Assert.NotNull(actual); + } + + public sealed class HasReadOnlyEnumerableObject + { + [JsonProperty("foo")] + public EnumerableWithConverter Foo { get; } = new EnumerableWithConverter(); + + [JsonConstructor] + public HasReadOnlyEnumerableObject([JsonProperty("bar")] int bar) + { + + } + } + + public sealed class HasReadOnlyEnumerableObjectAndDefaultConstructor + { + [JsonProperty("foo")] + public EnumerableWithConverter Foo { get; } = new EnumerableWithConverter(); + + [JsonConstructor] + public HasReadOnlyEnumerableObjectAndDefaultConstructor() + { + + } + } + + public sealed class AcceptsEnumerableObjectToConstructor + { + [JsonConstructor] + public AcceptsEnumerableObjectToConstructor + ( + [JsonProperty("foo")] EnumerableWithConverter foo, + [JsonProperty("bar")] int bar + ) + { + + } + } + + public sealed class HasEnumerableObject + { + [JsonProperty("foo")] + public EnumerableWithConverter Foo { get; set; } = new EnumerableWithConverter(); + + [JsonConstructor] + public HasEnumerableObject([JsonProperty("bar")] int bar) + { + + } + } + + [JsonConverter(typeof(Converter))] + public sealed class EnumerableWithConverter : IEnumerable + { + public sealed class Converter : JsonConverter + { + public override bool CanConvert(Type objectType) + => objectType == typeof(Foo); + + public override object ReadJson + (JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + reader.Skip(); + return new EnumerableWithConverter(); + } + + public override void WriteJson + (JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteStartObject(); + writer.WriteEndObject(); + } + } + + public IEnumerator GetEnumerator() + { + yield break; + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } } } \ No newline at end of file