-
Notifications
You must be signed in to change notification settings - Fork 4.6k
/
PropertyVisibilityTests.InitOnly.cs
136 lines (112 loc) · 5.02 KB
/
PropertyVisibilityTests.InitOnly.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Threading.Tasks;
using Xunit;
namespace System.Text.Json.Serialization.Tests
{
public abstract partial class PropertyVisibilityTests
{
[Theory]
[InlineData(typeof(ClassWithInitOnlyProperty))]
[InlineData(typeof(StructWithInitOnlyProperty))]
public virtual async Task InitOnlyProperties(Type type)
{
// Init-only property included by default.
object obj = await Serializer.DeserializeWrapper(@"{""MyInt"":1}", type);
Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj));
// Init-only properties can be serialized.
Assert.Equal(@"{""MyInt"":1}", await Serializer.SerializeWrapper(obj));
}
[Theory]
[InlineData(typeof(ClassWithCustomNamedInitOnlyProperty))]
[InlineData(typeof(StructWithCustomNamedInitOnlyProperty))]
public virtual async Task CustomNamedInitOnlyProperties(Type type)
{
// Regression test for https://github.com/dotnet/runtime/issues/82730
// Init-only property included by default.
object obj = await Serializer.DeserializeWrapper(@"{""CustomMyInt"":1}", type);
Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj));
// Init-only properties can be serialized.
Assert.Equal(@"{""CustomMyInt"":1}", await Serializer.SerializeWrapper(obj));
}
[Theory]
[InlineData(typeof(Class_PropertyWith_PrivateInitOnlySetter))]
[InlineData(typeof(Class_PropertyWith_InternalInitOnlySetter))]
[InlineData(typeof(Class_PropertyWith_ProtectedInitOnlySetter))]
public async Task NonPublicInitOnlySetter_Without_JsonInclude_Fails(Type type)
{
// Non-public init-only property setter ignored.
object obj = await Serializer.DeserializeWrapper(@"{""MyInt"":1}", type);
Assert.Equal(0, (int)type.GetProperty("MyInt").GetValue(obj));
// Public getter can be used for serialization.
Assert.Equal(@"{""MyInt"":0}", await Serializer.SerializeWrapper(obj, type));
}
[Theory]
[InlineData(typeof(Class_PropertyWith_PrivateInitOnlySetter_WithAttribute))]
[InlineData(typeof(Class_PropertyWith_InternalInitOnlySetter_WithAttribute))]
[InlineData(typeof(Class_PropertyWith_ProtectedInitOnlySetter_WithAttribute))]
public virtual async Task NonPublicInitOnlySetter_With_JsonInclude(Type type)
{
// Non-public init-only property setter included with [JsonInclude].
object obj = await Serializer.DeserializeWrapper(@"{""MyInt"":1}", type);
Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj));
// Init-only properties can be serialized.
Assert.Equal(@"{""MyInt"":1}", await Serializer.SerializeWrapper(obj));
}
[Fact]
public async Task NullableStructWithInitOnlyProperty()
{
// Regression test for https://github.com/dotnet/runtime/issues/86483
StructWithInitOnlyProperty? value = new StructWithInitOnlyProperty { MyInt = 42 };
string json = await Serializer.SerializeWrapper(value);
Assert.Equal("""{"MyInt":42}""", json);
StructWithInitOnlyProperty? deserializedValue = await Serializer.DeserializeWrapper<StructWithInitOnlyProperty?>(json);
Assert.Equal(deserializedValue, value);
}
public class ClassWithInitOnlyProperty
{
public int MyInt { get; init; }
}
public struct StructWithInitOnlyProperty
{
public int MyInt { get; init; }
}
public class ClassWithCustomNamedInitOnlyProperty
{
[JsonPropertyName("CustomMyInt")]
public int MyInt { get; init; }
}
public struct StructWithCustomNamedInitOnlyProperty
{
[JsonPropertyName("CustomMyInt")]
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; }
}
}
}