forked from fsprojects/FSharp.Json
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Union.fs
198 lines (166 loc) · 7.1 KB
/
Union.fs
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
namespace FSharp.Json
module Union =
open NUnit.Framework
type TheRecord = {
Value: string
}
type TheUnion =
| NoFieldCase
| OneFieldCase of string
| ManyFieldsCase of string*int
| RecordCase of TheRecord
type OtherRecord = {
Union: TheUnion
}
[<Test>]
let ``No field case serialization`` () =
let value = NoFieldCase
let actual = Json.serializeU value
let expected = "\"NoFieldCase\""
Assert.AreEqual(expected, actual)
[<Test>]
let ``No field case serialization in record`` () =
let value = { OtherRecord.Union = NoFieldCase }
let actual = Json.serializeU value
let expected = """{"Union":"NoFieldCase"}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union no field case deserialization`` () =
let expected = { OtherRecord.Union = NoFieldCase }
let json = Json.serialize(expected)
let actual = Json.deserialize<OtherRecord> json
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union one field case serialization`` () =
let value = OneFieldCase "The string"
let actual = Json.serializeU value
let expected = """{"OneFieldCase":"The string"}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union one field case deserialization`` () =
let expected = OneFieldCase "The string"
let json = Json.serialize(expected)
let actual = Json.deserialize<TheUnion> json
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union many fields case serialization`` () =
let expected = ManyFieldsCase ("The string", 123)
let json = Json.serialize(expected)
let actual = Json.deserialize<TheUnion> json
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union record field case serialization`` () =
let expected = RecordCase {TheRecord.Value = "The string"}
let json = Json.serialize(expected)
let actual = Json.deserialize<TheUnion> json
Assert.AreEqual(expected, actual)
type TheCasesUnion =
| [<JsonUnionCase(Case="case1")>] StringCase of string
| [<JsonUnionCase(Case="case2")>] IntCase of int
[<Test>]
let ``Union custom case name serialization`` () =
let value = StringCase "The string"
let actual = Json.serializeU value
let expected = """{"case1":"The string"}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union custom case name deserialization`` () =
let expected = StringCase "The string"
let json = """{"case1":"The string"}"""
let actual = Json.deserialize<TheCasesUnion> json
Assert.AreEqual(expected, actual)
[<JsonUnion(Mode = UnionMode.CaseKeyAsFieldValue, CaseKeyField="casekey", CaseValueField="casevalue")>]
type TheAnnotatedUnion =
| StringCase of string
| IntCase of int
[<Test>]
let ``Union key-value serialization`` () =
let value = TheAnnotatedUnion.StringCase "The string"
let actual = Json.serializeU value
let expected = """{"casekey":"StringCase","casevalue":"The string"}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union key-value deserialization`` () =
let expected = TheAnnotatedUnion.StringCase "The string"
let json = """{"casekey":"StringCase","casevalue":"The string"}"""
let actual = Json.deserialize<TheAnnotatedUnion> json
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union key-value deserialization (more than 2 fields)`` () =
let expected = TheAnnotatedUnion.StringCase "The string"
let json = """{"casekey":"StringCase","casevalue":"The string","unrelated_property":"unrelated_value"}"""
let actual = Json.deserialize<TheAnnotatedUnion> json
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union cases serialization with snake case naming`` () =
let value = OneFieldCase "The string"
let config = JsonConfig.create(unformatted = true, jsonFieldNaming = Json.snakeCase)
let actual = Json.serializeEx config value
let expected = """{"one_field_case":"The string"}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union cases deserialization with snake case naming`` () =
let json = """{"one_field_case":"The string"}"""
let expected = OneFieldCase "The string"
let config = JsonConfig.create(jsonFieldNaming = Json.snakeCase)
let actual = Json.deserializeEx<TheUnion> config json
Assert.AreEqual(expected, actual)
[<JsonUnion(Mode = UnionMode.CaseKeyDiscriminatorField, CaseKeyField="discriminator")>]
type TheDiscriminatorUnion =
| StringCase of string
| RecordCase of TheRecord
[<Test>]
let ``Union discriminator record case serialization`` () =
let value = TheDiscriminatorUnion.RecordCase {TheRecord.Value = "The string"}
let actual = Json.serializeU value
let expected = """{"discriminator":"RecordCase","Value":"The string"}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union discriminator record case deserialization`` () =
let expected = TheDiscriminatorUnion.RecordCase {TheRecord.Value = "The string"}
let json = Json.serialize(expected)
let actual = Json.deserialize<TheDiscriminatorUnion> json
Assert.AreEqual(expected, actual)
type SingleCaseUnion = SingleCase of string
type SingleCaseRecord = {
value: SingleCaseUnion
}
[<Test>]
let ``Union single case serialization`` () =
let value = { SingleCaseRecord.value = SingleCase "The string" }
let actual = Json.serializeU value
let expected = """{"value":"The string"}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union single case deserialization`` () =
let expected = { SingleCaseRecord.value = SingleCase "The string" }
let json = Json.serialize(expected)
let actual = Json.deserialize<SingleCaseRecord> json
Assert.AreEqual(expected, actual)
type UnionWithOption =
| Main of string option
| Other
[<Test>]
let ``Union case with option serialization`` () =
let value = Main (Some "The string")
let actual = Json.serializeU value
let expected = """{"Main":"The string"}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union case with option deserialization`` () =
let json = """{"Main":"The string"}"""
let expected = Main (Some "The string")
let actual = Json.deserialize<UnionWithOption> json
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union case with option None serialization`` () =
let value = Main None
let actual = Json.serializeU value
let expected = """{"Main":null}"""
Assert.AreEqual(expected, actual)
[<Test>]
let ``Union case with option None deserialization`` () =
let json = """{"Main":null}"""
let expected = Main None
let actual = Json.deserialize<UnionWithOption> json
Assert.AreEqual(expected, actual)