PageRenderTime 58ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Json45r7/Source/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs

https://bitbucket.org/wantstudios/bitbucketclient
C# | 501 lines | 406 code | 61 blank | 34 comment | 7 complexity | 58f94c7d05bc571573ab95095c7233b9 MD5 | raw file
  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. using System;
  26. using System.Collections.Generic;
  27. using Newtonsoft.Json.Converters;
  28. using Newtonsoft.Json.Tests.TestObjects;
  29. #if !NETFX_CORE
  30. using NUnit.Framework;
  31. #else
  32. using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
  33. using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
  34. using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
  35. #endif
  36. using System.IO;
  37. using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
  38. namespace Newtonsoft.Json.Tests.Serialization
  39. {
  40. [TestFixture]
  41. public class SerializationErrorHandlingTests : TestFixtureBase
  42. {
  43. [Test]
  44. public void ErrorDeserializingListHandled()
  45. {
  46. string json = @"[
  47. {
  48. ""Name"": ""Jim"",
  49. ""BirthDate"": ""\/Date(978048000000)\/"",
  50. ""LastModified"": ""\/Date(978048000000)\/""
  51. },
  52. {
  53. ""Name"": ""Jim"",
  54. ""BirthDate"": ""\/Date(978048000000)\/"",
  55. ""LastModified"": ""\/Date(978048000000)\/""
  56. }
  57. ]";
  58. VersionKeyedCollection c = JsonConvert.DeserializeObject<VersionKeyedCollection>(json);
  59. Assert.AreEqual(1, c.Count);
  60. Assert.AreEqual(1, c.Messages.Count);
  61. Assert.AreEqual("[1] - Error message for member 1 = An item with the same key has already been added.", c.Messages[0]);
  62. }
  63. [Test]
  64. public void DeserializingErrorInChildObject()
  65. {
  66. ListErrorObjectCollection c = JsonConvert.DeserializeObject<ListErrorObjectCollection>(@"[
  67. {
  68. ""Member"": ""Value1"",
  69. ""Member2"": null
  70. },
  71. {
  72. ""Member"": ""Value2""
  73. },
  74. {
  75. ""ThrowError"": ""Value"",
  76. ""Object"": {
  77. ""Array"": [
  78. 1,
  79. 2
  80. ]
  81. }
  82. },
  83. {
  84. ""ThrowError"": ""Handle this!"",
  85. ""Member"": ""Value3""
  86. }
  87. ]");
  88. Assert.AreEqual(3, c.Count);
  89. Assert.AreEqual("Value1", c[0].Member);
  90. Assert.AreEqual("Value2", c[1].Member);
  91. Assert.AreEqual("Value3", c[2].Member);
  92. Assert.AreEqual("Handle this!", c[2].ThrowError);
  93. }
  94. [Test]
  95. public void SerializingErrorInChildObject()
  96. {
  97. ListErrorObjectCollection c = new ListErrorObjectCollection
  98. {
  99. new ListErrorObject
  100. {
  101. Member = "Value1",
  102. ThrowError = "Handle this!",
  103. Member2 = "Member1"
  104. },
  105. new ListErrorObject
  106. {
  107. Member = "Value2",
  108. Member2 = "Member2"
  109. },
  110. new ListErrorObject
  111. {
  112. Member = "Value3",
  113. ThrowError = "Handle that!",
  114. Member2 = "Member3"
  115. }
  116. };
  117. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  118. Assert.AreEqual(@"[
  119. {
  120. ""Member"": ""Value1"",
  121. ""ThrowError"": ""Handle this!"",
  122. ""Member2"": ""Member1""
  123. },
  124. {
  125. ""Member"": ""Value2""
  126. },
  127. {
  128. ""Member"": ""Value3"",
  129. ""ThrowError"": ""Handle that!"",
  130. ""Member2"": ""Member3""
  131. }
  132. ]", json);
  133. }
  134. [Test]
  135. public void DeserializingErrorInDateTimeCollection()
  136. {
  137. DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject<DateTimeErrorObjectCollection>(@"[
  138. ""2009-09-09T00:00:00Z"",
  139. ""kjhkjhkjhkjh"",
  140. [
  141. 1
  142. ],
  143. ""1977-02-20T00:00:00Z"",
  144. null,
  145. ""2000-12-01T00:00:00Z""
  146. ]", new IsoDateTimeConverter());
  147. Assert.AreEqual(3, c.Count);
  148. Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
  149. Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
  150. Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
  151. }
  152. [Test]
  153. public void DeserializingErrorHandlingUsingEvent()
  154. {
  155. List<string> errors = new List<string>();
  156. JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings
  157. {
  158. Error = delegate(object sender, ErrorEventArgs args)
  159. {
  160. errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message);
  161. args.ErrorContext.Handled = true;
  162. },
  163. Converters = { new IsoDateTimeConverter() }
  164. });
  165. var c = serializer.Deserialize<List<DateTime>>(new JsonTextReader(new StringReader(@"[
  166. ""2009-09-09T00:00:00Z"",
  167. ""I am not a date and will error!"",
  168. [
  169. 1
  170. ],
  171. ""1977-02-20T00:00:00Z"",
  172. null,
  173. ""2000-12-01T00:00:00Z""
  174. ]")));
  175. // 2009-09-09T00:00:00Z
  176. // 1977-02-20T00:00:00Z
  177. // 2000-12-01T00:00:00Z
  178. // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.
  179. // Unexpected token parsing date. Expected String, got StartArray.
  180. // Cannot convert null value to System.DateTime.
  181. Assert.AreEqual(3, c.Count);
  182. Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
  183. Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
  184. Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
  185. Assert.AreEqual(3, errors.Count);
  186. #if !(NET20 || NET35 || WINDOWS_PHONE)
  187. Assert.AreEqual("[1] - 1 - The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.", errors[0]);
  188. #else
  189. Assert.AreEqual("[1] - 1 - The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.", errors[0]);
  190. #endif
  191. Assert.AreEqual("[2] - 2 - Unexpected token parsing date. Expected String, got StartArray. Path '[2]', line 4, position 10.", errors[1]);
  192. Assert.AreEqual("[4] - 4 - Cannot convert null value to System.DateTime. Path '[4]', line 8, position 13.", errors[2]);
  193. }
  194. [Test]
  195. public void DeserializingErrorInDateTimeCollectionWithAttributeWithEventNotCalled()
  196. {
  197. bool eventErrorHandlerCalled = false;
  198. DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject<DateTimeErrorObjectCollection>(
  199. @"[
  200. ""2009-09-09T00:00:00Z"",
  201. ""kjhkjhkjhkjh"",
  202. [
  203. 1
  204. ],
  205. ""1977-02-20T00:00:00Z"",
  206. null,
  207. ""2000-12-01T00:00:00Z""
  208. ]",
  209. new JsonSerializerSettings
  210. {
  211. Error = (s, a) => eventErrorHandlerCalled = true,
  212. Converters =
  213. {
  214. new IsoDateTimeConverter()
  215. }
  216. });
  217. Assert.AreEqual(3, c.Count);
  218. Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
  219. Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
  220. Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
  221. Assert.AreEqual(false, eventErrorHandlerCalled);
  222. }
  223. [Test]
  224. public void SerializePerson()
  225. {
  226. PersonError person = new PersonError
  227. {
  228. Name = "George Michael Bluth",
  229. Age = 16,
  230. Roles = null,
  231. Title = "Mister Manager"
  232. };
  233. string json = JsonConvert.SerializeObject(person, Formatting.Indented);
  234. Console.WriteLine(json);
  235. //{
  236. // "Name": "George Michael Bluth",
  237. // "Age": 16,
  238. // "Title": "Mister Manager"
  239. //}
  240. Assert.AreEqual(@"{
  241. ""Name"": ""George Michael Bluth"",
  242. ""Age"": 16,
  243. ""Title"": ""Mister Manager""
  244. }", json);
  245. }
  246. [Test]
  247. public void DeserializeNestedUnhandled()
  248. {
  249. List<string> errors = new List<string>();
  250. string json = @"[[""kjhkjhkjhkjh""]]";
  251. Exception e = null;
  252. try
  253. {
  254. JsonSerializer serializer = new JsonSerializer();
  255. serializer.Error += delegate(object sender, ErrorEventArgs args)
  256. {
  257. // only log an error once
  258. if (args.CurrentObject == args.ErrorContext.OriginalObject)
  259. errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message);
  260. };
  261. serializer.Deserialize(new StringReader(json), typeof(List<List<DateTime>>));
  262. }
  263. catch (Exception ex)
  264. {
  265. e = ex;
  266. }
  267. Assert.AreEqual(@"Could not convert string to DateTime: kjhkjhkjhkjh. Path '[0][0]', line 1, position 16.", e.Message);
  268. Assert.AreEqual(1, errors.Count);
  269. Assert.AreEqual(@"[0][0] - 0 - Could not convert string to DateTime: kjhkjhkjhkjh. Path '[0][0]', line 1, position 16.", errors[0]);
  270. }
  271. [Test]
  272. public void MultipleRequiredPropertyErrors()
  273. {
  274. string json = "{}";
  275. List<string> errors = new List<string>();
  276. JsonSerializer serializer = new JsonSerializer();
  277. serializer.Error += delegate(object sender, ErrorEventArgs args)
  278. {
  279. errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message);
  280. args.ErrorContext.Handled = true;
  281. };
  282. serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof (MyTypeWithRequiredMembers));
  283. Assert.AreEqual(2, errors.Count);
  284. Assert.AreEqual(" - Required1 - Required property 'Required1' not found in JSON. Path '', line 1, position 2.", errors[0]);
  285. Assert.AreEqual(" - Required2 - Required property 'Required2' not found in JSON. Path '', line 1, position 2.", errors[1]);
  286. }
  287. [Test]
  288. public void HandlingArrayErrors()
  289. {
  290. string json = "[\"a\",\"b\",\"45\",34]";
  291. List<string> errors = new List<string>();
  292. JsonSerializer serializer = new JsonSerializer();
  293. serializer.Error += delegate(object sender, ErrorEventArgs args)
  294. {
  295. errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message);
  296. args.ErrorContext.Handled = true;
  297. };
  298. serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof(int[]));
  299. Assert.AreEqual(2, errors.Count);
  300. Assert.AreEqual("[0] - 0 - Could not convert string to integer: a. Path '[0]', line 1, position 4.", errors[0]);
  301. Assert.AreEqual("[1] - 1 - Could not convert string to integer: b. Path '[1]', line 1, position 8.", errors[1]);
  302. }
  303. [Test]
  304. public void ErrorHandlingAndAvoidingRecursiveDepthError()
  305. {
  306. string json = "{'A':{'A':{'A':{'A':{'A':{}}}}}}";
  307. JsonSerializer serializer = new JsonSerializer() { };
  308. IList<string> errors = new List<string>();
  309. serializer.Error += (sender, e) =>
  310. {
  311. e.ErrorContext.Handled = true;
  312. errors.Add(e.ErrorContext.Path);
  313. };
  314. serializer.Deserialize<Nest>(new JsonTextReader(new StringReader(json)) { MaxDepth = 3 });
  315. Assert.AreEqual(1, errors.Count);
  316. Assert.AreEqual("A.A.A", errors[0]);
  317. }
  318. public class Nest
  319. {
  320. public Nest A { get; set; }
  321. }
  322. [Test]
  323. public void InfiniteErrorHandlingLoopFromInputError()
  324. {
  325. IList<string> errors = new List<string>();
  326. JsonSerializer serializer = new JsonSerializer();
  327. serializer.Error += (sender, e) =>
  328. {
  329. errors.Add(e.ErrorContext.Error.Message);
  330. e.ErrorContext.Handled = true;
  331. };
  332. ErrorPerson[] result = serializer.Deserialize<ErrorPerson[]>(new JsonTextReader(new ThrowingReader()));
  333. Assert.IsNull(result);
  334. Assert.AreEqual(3, errors.Count);
  335. Assert.AreEqual("too far", errors[0]);
  336. Assert.AreEqual("too far", errors[1]);
  337. Assert.AreEqual("Infinite loop detected from error handling. Path '[1023]', line 1, position 65536.", errors[2]);
  338. }
  339. [Test]
  340. public void InfiniteLoopArrayHandling()
  341. {
  342. IList<string> errors = new List<string>();
  343. object o = JsonConvert.DeserializeObject(
  344. "[0,x]",
  345. typeof (int[]),
  346. new JsonSerializerSettings
  347. {
  348. Error = (sender, arg) =>
  349. {
  350. errors.Add(arg.ErrorContext.Error.Message);
  351. arg.ErrorContext.Handled = true;
  352. }
  353. });
  354. Assert.IsNull(o);
  355. Assert.AreEqual(3, errors.Count);
  356. Assert.AreEqual("Unexpected character encountered while parsing value: x. Path '[0]', line 1, position 3.", errors[0]);
  357. Assert.AreEqual("Unexpected character encountered while parsing value: x. Path '[0]', line 1, position 3.", errors[1]);
  358. Assert.AreEqual("Infinite loop detected from error handling. Path '[0]', line 1, position 3.", errors[2]);
  359. }
  360. [Test]
  361. public void InfiniteLoopArrayHandlingInObject()
  362. {
  363. IList<string> errors = new List<string>();
  364. Dictionary<string, int[]> o = JsonConvert.DeserializeObject<Dictionary<string, int[]>>(
  365. "{'badarray':[0,x,2],'goodarray':[0,1,2]}",
  366. new JsonSerializerSettings
  367. {
  368. Error = (sender, arg) =>
  369. {
  370. errors.Add(arg.ErrorContext.Error.Message);
  371. arg.ErrorContext.Handled = true;
  372. }
  373. });
  374. Assert.IsNull(o);
  375. Assert.AreEqual(4, errors.Count);
  376. Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[0]);
  377. Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[1]);
  378. Assert.AreEqual("Infinite loop detected from error handling. Path 'badarray[0]', line 1, position 15.", errors[2]);
  379. Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[3]);
  380. }
  381. public class ThrowingReader : TextReader
  382. {
  383. int _position = 0;
  384. static string element = "{\"FirstName\":\"Din\",\"LastName\":\"Rav\",\"Item\":{\"ItemName\":\"temp\"}}";
  385. bool _firstRead = true;
  386. bool _readComma = false;
  387. public ThrowingReader()
  388. {
  389. }
  390. public override int Read(char[] buffer, int index, int count)
  391. {
  392. char[] temp = new char[buffer.Length];
  393. int charsRead = 0;
  394. if (_firstRead)
  395. {
  396. charsRead = new StringReader("[").Read(temp, index, count);
  397. _firstRead = false;
  398. }
  399. else
  400. {
  401. if (_readComma)
  402. {
  403. charsRead = new StringReader(",").Read(temp, index, count);
  404. _readComma = false;
  405. }
  406. else
  407. {
  408. charsRead = new StringReader(element).Read(temp, index, count);
  409. _readComma = true;
  410. }
  411. }
  412. _position += charsRead;
  413. if (_position > 65536)
  414. {
  415. throw new Exception("too far");
  416. }
  417. Array.Copy(temp, index, buffer, index, charsRead);
  418. return charsRead;
  419. }
  420. }
  421. }
  422. public class ErrorPerson
  423. {
  424. public string FirstName { get; set; }
  425. public string LastName { get; set; }
  426. public ErrorItem Item { get; set; }
  427. }
  428. public class ErrorItem
  429. {
  430. public string ItemName { get; set; }
  431. }
  432. [JsonObject]
  433. public class MyTypeWithRequiredMembers
  434. {
  435. [JsonProperty(Required = Required.AllowNull)]
  436. public string Required1;
  437. [JsonProperty(Required = Required.AllowNull)]
  438. public string Required2;
  439. }
  440. }