Code Coverage Statistics for Source File
Newtonsoft.Json.Tests\Serialization\TypeNameHandlingTests.cs
Symbol Coverage: 97.78% (88 of 90)
Branch Coverage: 55.17% (16 of 29)
Cyclomatic Complexity Avg: 1.00 Max:1
Code Lines: 269
Symbol Coverage Trend
View:
L | V | Source |
---|---|---|
1 |
#region License |
|
2 |
// Copyright (c) 2007 James Newton-King |
|
3 |
// |
|
4 |
// Permission is hereby granted, free of charge, to any person |
|
5 |
// obtaining a copy of this software and associated documentation |
|
6 |
// files (the "Software"), to deal in the Software without |
|
7 |
// restriction, including without limitation the rights to use, |
|
8 |
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
9 |
// copies of the Software, and to permit persons to whom the |
|
10 |
// Software is furnished to do so, subject to the following |
|
11 |
// conditions: |
|
12 |
// |
|
13 |
// The above copyright notice and this permission notice shall be |
|
14 |
// included in all copies or substantial portions of the Software. |
|
15 |
// |
|
16 |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
17 |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
|
18 |
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
19 |
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
20 |
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
|
21 |
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
22 |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
|
23 |
// OTHER DEALINGS IN THE SOFTWARE. |
|
24 |
#endregion |
|
25 |
||
26 |
using System; |
|
27 |
using System.Collections.Generic; |
|
28 |
using System.Linq; |
|
29 |
using System.Runtime.Serialization.Formatters; |
|
30 |
using System.Text; |
|
31 |
using Newtonsoft.Json.Linq; |
|
32 |
using Newtonsoft.Json.Tests.TestObjects; |
|
33 |
using NUnit.Framework; |
|
34 |
using Newtonsoft.Json.Utilities; |
|
35 |
using System.Net; |
|
36 |
||
37 |
namespace Newtonsoft.Json.Tests.Serialization |
|
38 |
{ |
|
39 |
public class TypeNameHandlingTests : TestFixtureBase |
|
40 |
{ |
|
41 |
[Test] |
|
42 |
public void WriteTypeNameForObjects() |
|
43 |
{ |
|
44 |
1 |
string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple);
|
45 |
||
46 |
1 |
EmployeeReference employee = new EmployeeReference();
|
47 |
||
48 |
1 |
string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings
|
49 |
1 |
{
|
50 |
1 |
TypeNameHandling = TypeNameHandling.Objects
|
51 |
1 |
});
|
52 |
||
53 |
1 |
Assert.AreEqual(@"{
|
54 |
1 |
""$id"": ""1"",
|
55 |
1 |
""$type"": """ + employeeRef + @""",
|
56 |
1 |
""Name"": null,
|
57 |
1 |
""Manager"": null
|
58 |
1 |
}", json);
|
59 |
1 |
}
|
60 |
||
61 |
[Test] |
|
62 |
public void DeserializeTypeName() |
|
63 |
{ |
|
64 |
1 |
string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple);
|
65 |
||
66 |
1 |
string json = @"{ |
67 |
1 |
""$id"": ""1"",
|
68 |
1 |
""$type"": """ + employeeRef + @""",
|
69 |
1 |
""Name"": ""Name!"",
|
70 |
1 |
""Manager"": null
|
71 |
1 |
}";
|
72 |
||
73 |
1 |
object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
|
74 |
1 |
{
|
75 |
1 |
TypeNameHandling = TypeNameHandling.Objects
|
76 |
1 |
});
|
77 |
||
78 |
1 |
Assert.IsInstanceOfType(typeof(EmployeeReference), employee);
|
79 |
1 |
Assert.AreEqual("Name!", ((EmployeeReference)employee).Name);
|
80 |
1 |
}
|
81 |
||
82 |
#if !SILVERLIGHT && !PocketPC |
|
83 |
[Test] |
|
84 |
public void DeserializeTypeNameFromGacAssembly() |
|
85 |
{ |
|
86 |
1 |
string cookieRef = ReflectionUtils.GetTypeName(typeof(Cookie), FormatterAssemblyStyle.Simple);
|
87 |
||
88 |
1 |
string json = @"{ |
89 |
1 |
""$id"": ""1"",
|
90 |
1 |
""$type"": """ + cookieRef + @"""
|
91 |
1 |
}";
|
92 |
||
93 |
1 |
object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
|
94 |
1 |
{
|
95 |
1 |
TypeNameHandling = TypeNameHandling.Objects
|
96 |
1 |
});
|
97 |
||
98 |
1 |
Assert.IsInstanceOfType(typeof(Cookie), cookie);
|
99 |
1 |
}
|
100 |
#endif |
|
101 |
||
102 |
[Test] |
|
103 |
public void SerializeGenericObjectListWithTypeName() |
|
104 |
{ |
|
105 |
1 |
string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
|
106 |
1 |
string personRef = typeof(Person).AssemblyQualifiedName;
|
107 |
||
108 |
1 |
List<object> values = new List<object>
|
109 |
1 |
{
|
110 |
1 |
new EmployeeReference
|
111 |
1 |
{
|
112 |
1 |
Name = "Bob",
|
113 |
1 |
Manager = new EmployeeReference {Name = "Frank"}
|
114 |
1 |
},
|
115 |
1 |
new Person
|
116 |
1 |
{
|
117 |
1 |
Department = "Department",
|
118 |
1 |
BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc),
|
119 |
1 |
LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc)
|
120 |
1 |
},
|
121 |
1 |
"String!",
|
122 |
1 |
int.MinValue
|
123 |
1 |
};
|
124 |
||
125 |
1 |
string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
|
126 |
1 |
{
|
127 |
1 |
TypeNameHandling = TypeNameHandling.Objects,
|
128 |
1 |
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
|
129 |
1 |
});
|
130 |
||
131 |
1 |
Assert.AreEqual(@"[
|
132 |
1 |
{
|
133 |
1 |
""$id"": ""1"",
|
134 |
1 |
""$type"": """ + employeeRef + @""",
|
135 |
1 |
""Name"": ""Bob"",
|
136 |
1 |
""Manager"": {
|
137 |
1 |
""$id"": ""2"",
|
138 |
1 |
""$type"": """ + employeeRef + @""",
|
139 |
1 |
""Name"": ""Frank"",
|
140 |
1 |
""Manager"": null
|
141 |
1 |
}
|
142 |
1 |
},
|
143 |
1 |
{
|
144 |
1 |
""$type"": """ + personRef + @""",
|
145 |
1 |
""Name"": null,
|
146 |
1 |
""BirthDate"": ""\/Date(978134400000)\/"",
|
147 |
1 |
""LastModified"": ""\/Date(978134400000)\/""
|
148 |
1 |
},
|
149 |
1 |
""String!"",
|
150 |
1 |
-2147483648
|
151 |
1 |
]", json);
|
152 |
1 |
}
|
153 |
||
154 |
[Test] |
|
155 |
public void DeserializeGenericObjectListWithTypeName() |
|
156 |
{ |
|
157 |
1 |
string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
|
158 |
1 |
string personRef = typeof(Person).AssemblyQualifiedName;
|
159 |
||
160 |
1 |
string json = @"[ |
161 |
1 |
{
|
162 |
1 |
""$id"": ""1"",
|
163 |
1 |
""$type"": """ + employeeRef + @""",
|
164 |
1 |
""Name"": ""Bob"",
|
165 |
1 |
""Manager"": {
|
166 |
1 |
""$id"": ""2"",
|
167 |
1 |
""$type"": """ + employeeRef + @""",
|
168 |
1 |
""Name"": ""Frank"",
|
169 |
1 |
""Manager"": null
|
170 |
1 |
}
|
171 |
1 |
},
|
172 |
1 |
{
|
173 |
1 |
""$type"": """ + personRef + @""",
|
174 |
1 |
""Name"": null,
|
175 |
1 |
""BirthDate"": ""\/Date(978134400000)\/"",
|
176 |
1 |
""LastModified"": ""\/Date(978134400000)\/""
|
177 |
1 |
},
|
178 |
1 |
""String!"",
|
179 |
1 |
-2147483648
|
180 |
1 |
]";
|
181 |
||
182 |
1 |
List<object> values = (List<object>)JsonConvert.DeserializeObject(json, typeof(List<object>), new JsonSerializerSettings
|
183 |
1 |
{
|
184 |
1 |
TypeNameHandling = TypeNameHandling.Objects,
|
185 |
1 |
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
|
186 |
1 |
});
|
187 |
||
188 |
1 |
Assert.AreEqual(4, values.Count);
|
189 |
||
190 |
1 |
EmployeeReference e = (EmployeeReference)values[0];
|
191 |
1 |
Person p = (Person)values[1];
|
192 |
||
193 |
1 |
Assert.AreEqual("Bob", e.Name);
|
194 |
1 |
Assert.AreEqual("Frank", e.Manager.Name);
|
195 |
||
196 |
1 |
Assert.AreEqual(null, p.Name);
|
197 |
1 |
Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate);
|
198 |
1 |
Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified);
|
199 |
||
200 |
1 |
Assert.AreEqual("String!", values[2]);
|
201 |
1 |
Assert.AreEqual(int.MinValue, values[3]);
|
202 |
1 |
}
|
203 |
||
204 |
[Test] |
|
205 |
[ExpectedException(typeof(JsonSerializationException))] |
|
206 |
public void DeserializeWithBadTypeName() |
|
207 |
{ |
|
208 |
1 |
string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
|
209 |
||
210 |
1 |
string json = @"{ |
211 |
1 |
""$id"": ""1"",
|
212 |
1 |
""$type"": """ + employeeRef + @""",
|
213 |
1 |
""Name"": ""Name!"",
|
214 |
1 |
""Manager"": null
|
215 |
1 |
}";
|
216 |
||
217 |
1 |
JsonConvert.DeserializeObject(json, typeof(Person), new JsonSerializerSettings
|
218 |
1 |
{
|
219 |
1 |
TypeNameHandling = TypeNameHandling.Objects,
|
220 |
1 |
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
|
221 |
1 |
});
|
222 |
0 |
}
|
223 |
||
224 |
[Test] |
|
225 |
public void DeserializeTypeNameWithNoTypeNameHandling() |
|
226 |
{ |
|
227 |
1 |
string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
|
228 |
||
229 |
1 |
string json = @"{ |
230 |
1 |
""$id"": ""1"",
|
231 |
1 |
""$type"": """ + employeeRef + @""",
|
232 |
1 |
""Name"": ""Name!"",
|
233 |
1 |
""Manager"": null
|
234 |
1 |
}";
|
235 |
||
236 |
1 |
JObject o = (JObject)JsonConvert.DeserializeObject(json);
|
237 |
||
238 |
1 |
Assert.AreEqual(@"{
|
239 |
1 |
""Name"": ""Name!"",
|
240 |
1 |
""Manager"": null
|
241 |
1 |
}", o.ToString());
|
242 |
1 |
}
|
243 |
||
244 |
[Test] |
|
245 |
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved.")] |
|
246 |
public void DeserializeTypeNameOnly() |
|
247 |
{ |
|
248 |
1 |
string json = @"{ |
249 |
1 |
""$id"": ""1"",
|
250 |
1 |
""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
|
251 |
1 |
""Name"": ""Name!"",
|
252 |
1 |
""Manager"": null
|
253 |
1 |
}";
|
254 |
||
255 |
1 |
JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
|
256 |
1 |
{
|
257 |
1 |
TypeNameHandling = TypeNameHandling.Objects
|
258 |
1 |
});
|
259 |
0 |
}
|
260 |
||
261 |
public interface ICorrelatedMessage |
|
262 |
{ |
|
263 |
string CorrelationId { get; set; } |
|
264 |
} |
|
265 |
||
266 |
public class SendHttpRequest : ICorrelatedMessage |
|
267 |
{ |
|
268 |
1 |
public SendHttpRequest()
|
269 |
{ |
|
270 |
1 |
RequestEncoding = "UTF-8";
|
271 |
1 |
Method = "GET";
|
272 |
1 |
}
|
273 |
public string Method { get; set; } |
|
274 |
public Dictionary<string, string> Headers { get; set; } |
|
275 |
public string Url { get; set; } |
|
276 |
public Dictionary<string, string> RequestData; |
|
277 |
public string RequestBodyText { get; set; } |
|
278 |
public string User { get; set; } |
|
279 |
public string Passwd { get; set; } |
|
280 |
public string RequestEncoding { get; set; } |
|
281 |
public string CorrelationId { get; set; } |
|
282 |
} |
|
283 |
||
284 |
[Test] |
|
285 |
public void DeserializeGenericTypeName() |
|
286 |
{ |
|
287 |
1 |
string typeName = typeof(SendHttpRequest).AssemblyQualifiedName;
|
288 |
||
289 |
1 |
string json = @"{ |
290 |
1 |
""$type"": """ + typeName + @""",
|
291 |
1 |
""RequestData"": {
|
292 |
1 |
""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"",
|
293 |
1 |
""Id"": ""siedemnaĆcie"",
|
294 |
1 |
""X"": ""323""
|
295 |
1 |
},
|
296 |
1 |
""Method"": ""GET"",
|
297 |
1 |
""Url"": ""http://www.onet.pl"",
|
298 |
1 |
""RequestEncoding"": ""UTF-8"",
|
299 |
1 |
""CorrelationId"": ""xyz""
|
300 |
1 |
}";
|
301 |
||
302 |
1 |
ICorrelatedMessage message = JsonConvert.DeserializeObject<ICorrelatedMessage>(json, new JsonSerializerSettings
|
303 |
1 |
{
|
304 |
1 |
TypeNameHandling = TypeNameHandling.Objects,
|
305 |
1 |
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
|
306 |
1 |
});
|
307 |
||
308 |
1 |
Assert.IsInstanceOfType(typeof(SendHttpRequest), message);
|
309 |
||
310 |
1 |
SendHttpRequest request = (SendHttpRequest)message;
|
311 |
1 |
Assert.AreEqual("xyz", request.CorrelationId);
|
312 |
1 |
Assert.AreEqual(2, request.RequestData.Count);
|
313 |
1 |
Assert.AreEqual("siedemnaĆcie", request.RequestData["Id"]);
|
314 |
1 |
}
|
315 |
||
316 |
[Test] |
|
317 |
public void SerializeObjectWithMultipleGenericLists() |
|
318 |
{ |
|
319 |
1 |
string containerTypeName = typeof(Container).AssemblyQualifiedName;
|
320 |
1 |
string productTypeName = typeof(Product).AssemblyQualifiedName;
|
321 |
||
322 |
1 |
Container container = new Container
|
323 |
1 |
{
|
324 |
1 |
In = new List<Product>(),
|
325 |
1 |
Out = new List<Product>()
|
326 |
1 |
};
|
327 |
||
328 |
1 |
string json = JsonConvert.SerializeObject(container, Formatting.Indented,
|
329 |
1 |
new JsonSerializerSettings
|
330 |
1 |
{
|
331 |
1 |
NullValueHandling = NullValueHandling.Ignore,
|
332 |
1 |
TypeNameHandling = TypeNameHandling.All,
|
333 |
1 |
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
|
334 |
1 |
});
|
335 |
||
336 |
1 |
Assert.AreEqual(@"{
|
337 |
1 |
""$type"": """ + containerTypeName + @""",
|
338 |
1 |
""In"": {
|
339 |
1 |
""$type"": ""System.Collections.Generic.List`1[[" + productTypeName + @"]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"",
|
340 |
1 |
""$values"": []
|
341 |
1 |
},
|
342 |
1 |
""Out"": {
|
343 |
1 |
""$type"": ""System.Collections.Generic.List`1[[" + productTypeName + @"]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"",
|
344 |
1 |
""$values"": []
|
345 |
1 |
}
|
346 |
1 |
}", json);
|
347 |
1 |
}
|
348 |
||
349 |
public class TypeNameProperty |
|
350 |
{ |
|
351 |
public string Name { get; set; } |
|
352 |
[JsonProperty(TypeNameHandling = TypeNameHandling.All)] |
|
353 |
public object Value { get; set; } |
|
354 |
} |
|
355 |
||
356 |
[Test] |
|
357 |
public void WriteObjectTypeNameForProperty() |
|
358 |
{ |
|
359 |
1 |
string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof(TypeNameProperty), FormatterAssemblyStyle.Simple);
|
360 |
||
361 |
1 |
TypeNameProperty typeNameProperty = new TypeNameProperty
|
362 |
1 |
{
|
363 |
1 |
Name = "Name!",
|
364 |
1 |
Value = new TypeNameProperty
|
365 |
1 |
{
|
366 |
1 |
Name = "Nested!"
|
367 |
1 |
}
|
368 |
1 |
};
|
369 |
||
370 |
1 |
string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
|
371 |
||
372 |
1 |
Assert.AreEqual(@"{
|
373 |
1 |
""Name"": ""Name!"",
|
374 |
1 |
""Value"": {
|
375 |
1 |
""$type"": """ + typeNamePropertyRef + @""",
|
376 |
1 |
""Name"": ""Nested!"",
|
377 |
1 |
""Value"": null
|
378 |
1 |
}
|
379 |
1 |
}", json);
|
380 |
||
381 |
1 |
TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
|
382 |
1 |
Assert.AreEqual("Name!", deserialized.Name);
|
383 |
1 |
Assert.IsInstanceOfType(typeof(TypeNameProperty), deserialized.Value);
|
384 |
||
385 |
1 |
TypeNameProperty nested = (TypeNameProperty)deserialized.Value;
|
386 |
1 |
Assert.AreEqual("Nested!", nested.Name);
|
387 |
1 |
Assert.AreEqual(null, nested.Value);
|
388 |
1 |
}
|
389 |
||
390 |
[Test] |
|
391 |
public void WriteListTypeNameForProperty() |
|
392 |
{ |
|
393 |
1 |
string listRef = ReflectionUtils.GetTypeName(typeof(List<int>), FormatterAssemblyStyle.Simple);
|
394 |
||
395 |
1 |
TypeNameProperty typeNameProperty = new TypeNameProperty
|
396 |
1 |
{
|
397 |
1 |
Name = "Name!",
|
398 |
1 |
Value = new List<int> { 1, 2, 3, 4, 5 }
|
399 |
1 |
};
|
400 |
||
401 |
1 |
string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
|
402 |
||
403 |
1 |
Assert.AreEqual(@"{
|
404 |
1 |
""Name"": ""Name!"",
|
405 |
1 |
""Value"": {
|
406 |
1 |
""$type"": """ + listRef + @""",
|
407 |
1 |
""$values"": [
|
408 |
1 |
1,
|
409 |
1 |
2,
|
410 |
1 |
3,
|
411 |
1 |
4,
|
412 |
1 |
5
|
413 |
1 |
]
|
414 |
1 |
}
|
415 |
1 |
}", json);
|
416 |
||
417 |
1 |
TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
|
418 |
1 |
Assert.AreEqual("Name!", deserialized.Name);
|
419 |
1 |
Assert.IsInstanceOfType(typeof(List<int>), deserialized.Value);
|
420 |
||
421 |
1 |
List<int> nested = (List<int>)deserialized.Value;
|
422 |
1 |
Assert.AreEqual(5, nested.Count);
|
423 |
1 |
Assert.AreEqual(1, nested[0]);
|
424 |
1 |
Assert.AreEqual(2, nested[1]);
|
425 |
1 |
Assert.AreEqual(3, nested[2]);
|
426 |
1 |
Assert.AreEqual(4, nested[3]);
|
427 |
1 |
Assert.AreEqual(5, nested[4]);
|
428 |
1 |
}
|
429 |
} |
|
430 |
} |