Json.NET
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


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
}