Skip to content

Commit

Permalink
Verify JsonSerializer support for init-only properties (dotnet#40150)
Browse files Browse the repository at this point in the history
  • Loading branch information
layomia authored and Jacksondr5 committed Aug 10, 2020
1 parent 08efdbb commit acc3c05
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ private class ClassWithMixedPropertyAccessors_PropertyAttributes
[InlineData(typeof(ClassWithPrivateField_WithJsonIncludeProperty))]
[InlineData(typeof(ClassWithInternalField_WithJsonIncludeProperty))]
[InlineData(typeof(ClassWithProtectedField_WithJsonIncludeProperty))]
[InlineData(typeof(ClassWithPrivate_InitOnlyProperty_WithJsonIncludeProperty))]
[InlineData(typeof(ClassWithInternal_InitOnlyProperty_WithJsonIncludeProperty))]
[InlineData(typeof(ClassWithProtected_InitOnlyProperty_WithJsonIncludeProperty))]
public static void NonPublicProperty_WithJsonInclude_Invalid(Type type)
{
InvalidOperationException ex = Assert.Throws<InvalidOperationException>(() => JsonSerializer.Deserialize("", type));
Expand Down Expand Up @@ -350,5 +353,23 @@ private class ClassWithProtectedField_WithJsonIncludeProperty
[JsonInclude]
protected string MyString = null;
}

private class ClassWithPrivate_InitOnlyProperty_WithJsonIncludeProperty
{
[JsonInclude]
private string MyString { get; init; }
}

private class ClassWithInternal_InitOnlyProperty_WithJsonIncludeProperty
{
[JsonInclude]
internal string MyString { get; init; }
}

private class ClassWithProtected_InitOnlyProperty_WithJsonIncludeProperty
{
[JsonInclude]
protected string MyString { get; init; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

using System.Collections.Generic;
using System.Collections.Concurrent;
using Xunit;
using System.Numerics;
using Xunit;

namespace System.Text.Json.Serialization.Tests
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Xunit;

namespace System.Text.Json.Serialization.Tests
{
public static partial class PropertyVisibilityTests
{
[Theory]
[InlineData(typeof(ClassWithInitOnlyProperty))]
[InlineData(typeof(StructWithInitOnlyProperty))]
public static void InitOnlyProperties_Work(Type type)
{
// Init-only property included by default.
object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type);
Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj));

// Init-only properties can be serialized.
Assert.Equal(@"{""MyInt"":1}", JsonSerializer.Serialize(obj));
}

[Theory]
[InlineData(typeof(Class_PropertyWith_PrivateInitOnlySetter))]
[InlineData(typeof(Class_PropertyWith_InternalInitOnlySetter))]
[InlineData(typeof(Class_PropertyWith_ProtectedInitOnlySetter))]
public static void NonPublicInitOnlySetter_Without_JsonInclude_Fails(Type type)
{
// Non-public init-only property setter ignored.
object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type);
Assert.Equal(0, (int)type.GetProperty("MyInt").GetValue(obj));

// Public getter can be used for serialization.
Assert.Equal(@"{""MyInt"":0}", JsonSerializer.Serialize(obj));
}

[Theory]
[InlineData(typeof(Class_PropertyWith_PrivateInitOnlySetter_WithAttribute))]
[InlineData(typeof(Class_PropertyWith_InternalInitOnlySetter_WithAttribute))]
[InlineData(typeof(Class_PropertyWith_ProtectedInitOnlySetter_WithAttribute))]
public static void NonPublicInitOnlySetter_With_JsonInclude_Works(Type type)
{
// Non-public init-only property setter included with [JsonInclude].
object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type);
Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj));

// Init-only properties can be serialized.
Assert.Equal(@"{""MyInt"":1}", JsonSerializer.Serialize(obj));
}

public class ClassWithInitOnlyProperty
{
public int MyInt { get; init; }
}

public struct StructWithInitOnlyProperty
{
public int MyInt { get; init; }
}

public class Class_PropertyWith_PrivateInitOnlySetter
{
public int MyInt { get; private init; }
}

public class Class_PropertyWith_InternalInitOnlySetter
{
public int MyInt { get; internal init; }
}

public class Class_PropertyWith_ProtectedInitOnlySetter
{
public int MyInt { get; protected init; }
}

public class Class_PropertyWith_PrivateInitOnlySetter_WithAttribute
{
[JsonInclude]
public int MyInt { get; private init; }
}

public class Class_PropertyWith_InternalInitOnlySetter_WithAttribute
{
[JsonInclude]
public int MyInt { get; internal init; }
}

public class Class_PropertyWith_ProtectedInitOnlySetter_WithAttribute
{
[JsonInclude]
public int MyInt { get; protected init; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
<Compile Include="Serialization\OptionsTests.cs" />
<Compile Include="Serialization\PolymorphicTests.cs" />
<Compile Include="Serialization\PropertyNameTests.cs" />
<Compile Include="Serialization\PropertyVisiblityTests.InitOnly.cs" />
<Compile Include="Serialization\PropertyVisibilityTests.NonPublicAccessors.cs" />
<Compile Include="Serialization\PropertyVisibilityTests.cs" />
<Compile Include="Serialization\ReadScenarioTests.cs" />
Expand Down

0 comments on commit acc3c05

Please sign in to comment.