Add additional extension data tests (dotnet/corefx#40488)
authorSteve Harter <steveharter@users.noreply.github.com>
Fri, 23 Aug 2019 17:06:29 +0000 (12:06 -0500)
committerGitHub <noreply@github.com>
Fri, 23 Aug 2019 17:06:29 +0000 (12:06 -0500)
Commit migrated from https://github.com/dotnet/corefx/commit/5f0a73134598165820c037c0c7ed2c3fba92a038

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleDictionary.cs
src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs

index 6dc9427..5c576e0 100644 (file)
@@ -25,10 +25,9 @@ namespace System.Text.Json
                 enumerable = (IEnumerable)jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue);
                 if (enumerable == null)
                 {
-                    // If applicable, we only want to ignore object properties.
-                    if (state.Current.ExtensionDataStatus != ExtensionDataWriteStatus.Writing &&
-                        (state.Current.JsonClassInfo.ClassType != ClassType.Object ||
-                        !state.Current.JsonPropertyInfo.IgnoreNullValues))
+                    if ((state.Current.JsonClassInfo.ClassType != ClassType.Object || // Write null dictionary values
+                        !state.Current.JsonPropertyInfo.IgnoreNullValues) && // Ignore ClassType.Object properties if IgnoreNullValues is true
+                        state.Current.ExtensionDataStatus != ExtensionDataWriteStatus.Writing) // Ignore null extension property (which is a dictionary)
                     {
                         // Write a null object or enumerable.
                         state.Current.WriteObjectOrArrayStart(ClassType.Dictionary, writer, writeNull: true);
index 72c0a26..f3b3b4c 100644 (file)
@@ -370,6 +370,68 @@ namespace System.Text.Json.Serialization.Tests
             Assert.Equal(3, child.MyOverflow["MyIntMissingChild"].GetInt32());
         }
 
+        [Fact]
+        public static void DeserializeIntoObjectProperty()
+        {
+            ClassWithExtensionPropertyAsObject obj;
+            string json;
+
+            // Baseline dictionary.
+            json = @"{""MyDict"":{""Property1"":1}}";
+            obj = JsonSerializer.Deserialize<ClassWithExtensionPropertyAsObject>(json);
+            Assert.Equal(1, obj.MyOverflow.Count);
+            Assert.Equal(1, ((JsonElement)obj.MyOverflow["MyDict"]).EnumerateObject().First().Value.GetInt32());
+
+            // Attempt to deserialize directly into the overflow property; this is just added as a normal missing property like MyDict above.
+            json = @"{""MyOverflow"":{""Property1"":1}}";
+            obj = JsonSerializer.Deserialize<ClassWithExtensionPropertyAsObject>(json);
+            Assert.Equal(1, obj.MyOverflow.Count);
+            Assert.Equal(1, ((JsonElement)obj.MyOverflow["MyOverflow"]).EnumerateObject().First().Value.GetInt32());
+
+            // Attempt to deserialize null into the overflow property. This is also treated as a missing property.
+            json = @"{""MyOverflow"":null}";
+            obj = JsonSerializer.Deserialize<ClassWithExtensionPropertyAsObject>(json);
+            Assert.Equal(1, obj.MyOverflow.Count);
+            Assert.Null(obj.MyOverflow["MyOverflow"]);
+
+            // Attempt to deserialize object into the overflow property. This is also treated as a missing property.
+            json = @"{""MyOverflow"":{}}";
+            obj = JsonSerializer.Deserialize<ClassWithExtensionPropertyAsObject>(json);
+            Assert.Equal(1, obj.MyOverflow.Count);
+            Assert.Equal(JsonValueKind.Object, ((JsonElement)obj.MyOverflow["MyOverflow"]).ValueKind);
+        }
+
+        [Fact]
+        public static void DeserializeIntoJsonElementProperty()
+        {
+            ClassWithExtensionPropertyAsJsonElement obj;
+            string json;
+
+            // Baseline dictionary.
+            json = @"{""MyDict"":{""Property1"":1}}";
+            obj = JsonSerializer.Deserialize<ClassWithExtensionPropertyAsJsonElement>(json);
+            Assert.Equal(1, obj.MyOverflow.Count);
+            Assert.Equal(1, obj.MyOverflow["MyDict"].EnumerateObject().First().Value.GetInt32());
+
+            // Attempt to deserialize directly into the overflow property; this is just added as a normal missing property like MyDict above.
+            json = @"{""MyOverflow"":{""Property1"":1}}";
+            obj = JsonSerializer.Deserialize<ClassWithExtensionPropertyAsJsonElement>(json);
+            Assert.Equal(1, obj.MyOverflow.Count);
+            Assert.Equal(1, obj.MyOverflow["MyOverflow"].EnumerateObject().First().Value.GetInt32());
+
+            // Attempt to deserialize null into the overflow property. This is also treated as a missing property.
+            json = @"{""MyOverflow"":null}";
+            obj = JsonSerializer.Deserialize<ClassWithExtensionPropertyAsJsonElement>(json);
+            Assert.Equal(1, obj.MyOverflow.Count);
+            Assert.Equal(JsonValueKind.Null, obj.MyOverflow["MyOverflow"].ValueKind);
+
+            // Attempt to deserialize object into the overflow property. This is also treated as a missing property.
+            json = @"{""MyOverflow"":{}}";
+            obj = JsonSerializer.Deserialize<ClassWithExtensionPropertyAsJsonElement>(json);
+            Assert.Equal(1, obj.MyOverflow.Count);
+            Assert.Equal(JsonValueKind.Object, obj.MyOverflow["MyOverflow"].ValueKind);
+        }
+
         private class ClassWithInvalidExtensionPropertyStringString
         {
             [JsonExtensionData]