PageRenderTime 38ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs

https://bitbucket.org/Ecarestia/newtonsoft.json
C# | 2538 lines | 2208 code | 234 blank | 96 comment | 44 complexity | 3549c8bf3b2937013152eeb8adb41132 MD5 | raw file

Large files files are truncated, but you can click here to view the full 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;
  27. using System.Collections.Specialized;
  28. using System.Runtime.Serialization;
  29. #if !(NET35 || NET20 || PORTABLE || PORTABLE40)
  30. using System.Collections.Concurrent;
  31. #endif
  32. using System.Collections.Generic;
  33. using System.Collections.ObjectModel;
  34. using System.Globalization;
  35. using System.IO;
  36. #if NET20
  37. using Newtonsoft.Json.Utilities.LinqBridge;
  38. #else
  39. using System.Linq;
  40. #endif
  41. using System.Text;
  42. using System.Xml;
  43. using Newtonsoft.Json.Linq;
  44. using Newtonsoft.Json.Serialization;
  45. using Newtonsoft.Json.Tests.TestObjects;
  46. using Newtonsoft.Json.Tests.TestObjects.Events;
  47. using Newtonsoft.Json.Tests.TestObjects.Organization;
  48. using Newtonsoft.Json.Utilities;
  49. #if DNXCORE50
  50. using Xunit;
  51. using Test = Xunit.FactAttribute;
  52. using Assert = Newtonsoft.Json.Tests.XUnitAssert;
  53. #else
  54. using NUnit.Framework;
  55. #endif
  56. #if !NET20 && !PORTABLE40
  57. using System.Xml.Linq;
  58. #endif
  59. namespace Newtonsoft.Json.Tests.Serialization
  60. {
  61. [TestFixture]
  62. public class JsonSerializerCollectionsTests : TestFixtureBase
  63. {
  64. [Test]
  65. public void DoubleKey_WholeValue()
  66. {
  67. Dictionary<double, int> dictionary = new Dictionary<double, int> { { 1d, 1 } };
  68. string output = JsonConvert.SerializeObject(dictionary);
  69. Assert.AreEqual(@"{""1"":1}", output);
  70. Dictionary<double, int> deserializedValue = JsonConvert.DeserializeObject<Dictionary<double, int>>(output);
  71. Assert.AreEqual(1d, deserializedValue.First().Key);
  72. }
  73. [Test]
  74. public void DoubleKey_MaxValue()
  75. {
  76. Dictionary<double, int> dictionary = new Dictionary<double, int> { { double.MaxValue, 1 } };
  77. string output = JsonConvert.SerializeObject(dictionary);
  78. Assert.AreEqual(@"{""1.7976931348623157E+308"":1}", output);
  79. Dictionary<double, int> deserializedValue = JsonConvert.DeserializeObject<Dictionary<double, int>>(output);
  80. Assert.AreEqual(double.MaxValue, deserializedValue.First().Key);
  81. }
  82. [Test]
  83. public void FloatKey_MaxValue()
  84. {
  85. Dictionary<float, int> dictionary = new Dictionary<float, int> { { float.MaxValue, 1 } };
  86. string output = JsonConvert.SerializeObject(dictionary);
  87. Assert.AreEqual(@"{""3.40282347E+38"":1}", output);
  88. Dictionary<float, int> deserializedValue = JsonConvert.DeserializeObject<Dictionary<float, int>>(output);
  89. Assert.AreEqual(float.MaxValue, deserializedValue.First().Key);
  90. }
  91. public class TestCollectionPrivateParameterized : IEnumerable<int>
  92. {
  93. private readonly List<int> _bars;
  94. public TestCollectionPrivateParameterized()
  95. {
  96. _bars = new List<int>();
  97. }
  98. [JsonConstructor]
  99. private TestCollectionPrivateParameterized(IEnumerable<int> bars)
  100. {
  101. _bars = new List<int>(bars);
  102. }
  103. public void Add(int bar)
  104. {
  105. _bars.Add(bar);
  106. }
  107. public IEnumerator<int> GetEnumerator() => _bars.GetEnumerator();
  108. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  109. }
  110. [Test]
  111. public void CollectionJsonConstructorPrivateParameterized()
  112. {
  113. TestCollectionPrivateParameterized c1 = new TestCollectionPrivateParameterized();
  114. c1.Add(0);
  115. c1.Add(1);
  116. c1.Add(2);
  117. string json = JsonConvert.SerializeObject(c1);
  118. TestCollectionPrivateParameterized c2 = JsonConvert.DeserializeObject<TestCollectionPrivateParameterized>(json);
  119. List<int> values = c2.ToList();
  120. Assert.AreEqual(3, values.Count);
  121. Assert.AreEqual(0, values[0]);
  122. Assert.AreEqual(1, values[1]);
  123. Assert.AreEqual(2, values[2]);
  124. }
  125. public class TestCollectionPrivate : List<int>
  126. {
  127. [JsonConstructor]
  128. private TestCollectionPrivate()
  129. {
  130. }
  131. public static TestCollectionPrivate Create()
  132. {
  133. return new TestCollectionPrivate();
  134. }
  135. }
  136. [Test]
  137. public void CollectionJsonConstructorPrivate()
  138. {
  139. TestCollectionPrivate c1 = TestCollectionPrivate.Create();
  140. c1.Add(0);
  141. c1.Add(1);
  142. c1.Add(2);
  143. string json = JsonConvert.SerializeObject(c1);
  144. TestCollectionPrivate c2 = JsonConvert.DeserializeObject<TestCollectionPrivate>(json);
  145. List<int> values = c2.ToList();
  146. Assert.AreEqual(3, values.Count);
  147. Assert.AreEqual(0, values[0]);
  148. Assert.AreEqual(1, values[1]);
  149. Assert.AreEqual(2, values[2]);
  150. }
  151. public class TestCollectionMultipleParameters : List<int>
  152. {
  153. [JsonConstructor]
  154. public TestCollectionMultipleParameters(string s1, string s2)
  155. {
  156. }
  157. }
  158. [Test]
  159. public void CollectionJsonConstructorMultipleParameters()
  160. {
  161. ExceptionAssert.Throws<JsonException>(
  162. () => JsonConvert.SerializeObject(new TestCollectionMultipleParameters(null, null)),
  163. "Constructor for 'Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+TestCollectionMultipleParameters' must have no parameters or a single parameter that implements 'System.Collections.Generic.IEnumerable`1[System.Int32]'.");
  164. }
  165. public class TestCollectionBadIEnumerableParameter : List<int>
  166. {
  167. [JsonConstructor]
  168. public TestCollectionBadIEnumerableParameter(List<string> l)
  169. {
  170. }
  171. }
  172. [Test]
  173. public void CollectionJsonConstructorBadIEnumerableParameter()
  174. {
  175. ExceptionAssert.Throws<JsonException>(
  176. () => JsonConvert.SerializeObject(new TestCollectionBadIEnumerableParameter(null)),
  177. "Constructor for 'Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+TestCollectionBadIEnumerableParameter' must have no parameters or a single parameter that implements 'System.Collections.Generic.IEnumerable`1[System.Int32]'.");
  178. }
  179. #if !(DNXCORE50 || PORTABLE)
  180. public class TestCollectionNonGeneric : ArrayList
  181. {
  182. [JsonConstructor]
  183. public TestCollectionNonGeneric(IEnumerable l)
  184. : base(l.Cast<object>().ToList())
  185. {
  186. }
  187. }
  188. [Test]
  189. public void CollectionJsonConstructorNonGeneric()
  190. {
  191. string json = @"[1,2,3]";
  192. TestCollectionNonGeneric l = JsonConvert.DeserializeObject<TestCollectionNonGeneric>(json);
  193. Assert.AreEqual(3, l.Count);
  194. Assert.AreEqual(1, l[0]);
  195. Assert.AreEqual(2, l[1]);
  196. Assert.AreEqual(3, l[2]);
  197. }
  198. #endif
  199. public class TestDictionaryPrivateParameterized : Dictionary<string, int>
  200. {
  201. public TestDictionaryPrivateParameterized()
  202. {
  203. }
  204. [JsonConstructor]
  205. private TestDictionaryPrivateParameterized(IEnumerable<KeyValuePair<string, int>> bars)
  206. : base(bars.ToDictionary(k => k.Key, k => k.Value))
  207. {
  208. }
  209. }
  210. [Test]
  211. public void DictionaryJsonConstructorPrivateParameterized()
  212. {
  213. TestDictionaryPrivateParameterized c1 = new TestDictionaryPrivateParameterized();
  214. c1.Add("zero", 0);
  215. c1.Add("one", 1);
  216. c1.Add("two", 2);
  217. string json = JsonConvert.SerializeObject(c1);
  218. TestDictionaryPrivateParameterized c2 = JsonConvert.DeserializeObject<TestDictionaryPrivateParameterized>(json);
  219. Assert.AreEqual(3, c2.Count);
  220. Assert.AreEqual(0, c2["zero"]);
  221. Assert.AreEqual(1, c2["one"]);
  222. Assert.AreEqual(2, c2["two"]);
  223. }
  224. public class TestDictionaryPrivate : Dictionary<string, int>
  225. {
  226. [JsonConstructor]
  227. private TestDictionaryPrivate()
  228. {
  229. }
  230. public static TestDictionaryPrivate Create()
  231. {
  232. return new TestDictionaryPrivate();
  233. }
  234. }
  235. [Test]
  236. public void DictionaryJsonConstructorPrivate()
  237. {
  238. TestDictionaryPrivate c1 = TestDictionaryPrivate.Create();
  239. c1.Add("zero", 0);
  240. c1.Add("one", 1);
  241. c1.Add("two", 2);
  242. string json = JsonConvert.SerializeObject(c1);
  243. TestDictionaryPrivate c2 = JsonConvert.DeserializeObject<TestDictionaryPrivate>(json);
  244. Assert.AreEqual(3, c2.Count);
  245. Assert.AreEqual(0, c2["zero"]);
  246. Assert.AreEqual(1, c2["one"]);
  247. Assert.AreEqual(2, c2["two"]);
  248. }
  249. public class TestDictionaryMultipleParameters : Dictionary<string, int>
  250. {
  251. [JsonConstructor]
  252. public TestDictionaryMultipleParameters(string s1, string s2)
  253. {
  254. }
  255. }
  256. [Test]
  257. public void DictionaryJsonConstructorMultipleParameters()
  258. {
  259. ExceptionAssert.Throws<JsonException>(
  260. () => JsonConvert.SerializeObject(new TestDictionaryMultipleParameters(null, null)),
  261. "Constructor for 'Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+TestDictionaryMultipleParameters' must have no parameters or a single parameter that implements 'System.Collections.Generic.IEnumerable`1[System.Collections.Generic.KeyValuePair`2[System.String,System.Int32]]'.");
  262. }
  263. public class TestDictionaryBadIEnumerableParameter : Dictionary<string, int>
  264. {
  265. [JsonConstructor]
  266. public TestDictionaryBadIEnumerableParameter(Dictionary<string, string> l)
  267. {
  268. }
  269. }
  270. [Test]
  271. public void DictionaryJsonConstructorBadIEnumerableParameter()
  272. {
  273. ExceptionAssert.Throws<JsonException>(
  274. () => JsonConvert.SerializeObject(new TestDictionaryBadIEnumerableParameter(null)),
  275. "Constructor for 'Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+TestDictionaryBadIEnumerableParameter' must have no parameters or a single parameter that implements 'System.Collections.Generic.IEnumerable`1[System.Collections.Generic.KeyValuePair`2[System.String,System.Int32]]'.");
  276. }
  277. #if !(DNXCORE50 || PORTABLE)
  278. public class TestDictionaryNonGeneric : Hashtable
  279. {
  280. [JsonConstructor]
  281. public TestDictionaryNonGeneric(IDictionary d)
  282. : base(d)
  283. {
  284. }
  285. }
  286. [Test]
  287. public void DictionaryJsonConstructorNonGeneric()
  288. {
  289. string json = @"{'zero':0,'one':1,'two':2}";
  290. TestDictionaryNonGeneric d = JsonConvert.DeserializeObject<TestDictionaryNonGeneric>(json);
  291. Assert.AreEqual(3, d.Count);
  292. Assert.AreEqual(0, d["zero"]);
  293. Assert.AreEqual(1, d["one"]);
  294. Assert.AreEqual(2, d["two"]);
  295. }
  296. #endif
  297. #if !(DNXCORE50)
  298. public class NameValueCollectionTestClass
  299. {
  300. public NameValueCollection Collection { get; set; }
  301. }
  302. [Test]
  303. public void DeserializeNameValueCollection()
  304. {
  305. ExceptionAssert.Throws<JsonSerializationException>(
  306. () => JsonConvert.DeserializeObject<NameValueCollectionTestClass>("{Collection:[]}"),
  307. "Cannot create and populate list type System.Collections.Specialized.NameValueCollection. Path 'Collection', line 1, position 13.");
  308. }
  309. #endif
  310. #if !(NET35 || NET20 || PORTABLE || PORTABLE40)
  311. public class SomeObject
  312. {
  313. public string Text1 { get; set; }
  314. }
  315. public class CustomConcurrentDictionary : ConcurrentDictionary<string, List<SomeObject>>
  316. {
  317. [OnDeserialized]
  318. internal void OnDeserializedMethod(StreamingContext context)
  319. {
  320. ((IDictionary)this).Add("key2", new List<SomeObject>
  321. {
  322. new SomeObject
  323. {
  324. Text1 = "value2"
  325. }
  326. });
  327. }
  328. }
  329. [Test]
  330. public void SerializeCustomConcurrentDictionary()
  331. {
  332. IDictionary d = new CustomConcurrentDictionary();
  333. d.Add("key", new List<SomeObject>
  334. {
  335. new SomeObject
  336. {
  337. Text1 = "value1"
  338. }
  339. });
  340. string json = JsonConvert.SerializeObject(d, Formatting.Indented);
  341. Assert.AreEqual(@"{
  342. ""key"": [
  343. {
  344. ""Text1"": ""value1""
  345. }
  346. ]
  347. }", json);
  348. CustomConcurrentDictionary d2 = JsonConvert.DeserializeObject<CustomConcurrentDictionary>(json);
  349. Assert.AreEqual(2, d2.Count);
  350. Assert.AreEqual("value1", d2["key"][0].Text1);
  351. Assert.AreEqual("value2", d2["key2"][0].Text1);
  352. }
  353. #endif
  354. [Test]
  355. public void NonZeroBasedArray()
  356. {
  357. var onebasedArray = Array.CreateInstance(typeof(string), new[] { 3 }, new[] { 2 });
  358. for (var i = onebasedArray.GetLowerBound(0); i <= onebasedArray.GetUpperBound(0); i++)
  359. {
  360. onebasedArray.SetValue(i.ToString(CultureInfo.InvariantCulture), new[] { i, });
  361. }
  362. string output = JsonConvert.SerializeObject(onebasedArray, Formatting.Indented);
  363. StringAssert.AreEqual(@"[
  364. ""2"",
  365. ""3"",
  366. ""4""
  367. ]", output);
  368. }
  369. [Test]
  370. public void NonZeroBasedMultiArray()
  371. {
  372. // lets create a two dimensional array, each rank is 1-based of with a capacity of 4.
  373. var onebasedArray = Array.CreateInstance(typeof(string), new[] { 3, 3 }, new[] { 1, 2 });
  374. // Iterate of the array elements and assign a random double
  375. for (var i = onebasedArray.GetLowerBound(0); i <= onebasedArray.GetUpperBound(0); i++)
  376. {
  377. for (var j = onebasedArray.GetLowerBound(1); j <= onebasedArray.GetUpperBound(1); j++)
  378. {
  379. onebasedArray.SetValue(i + "_" + j, new[] { i, j });
  380. }
  381. }
  382. // Now lets try and serialize the Array
  383. string output = JsonConvert.SerializeObject(onebasedArray, Formatting.Indented);
  384. StringAssert.AreEqual(@"[
  385. [
  386. ""1_2"",
  387. ""1_3"",
  388. ""1_4""
  389. ],
  390. [
  391. ""2_2"",
  392. ""2_3"",
  393. ""2_4""
  394. ],
  395. [
  396. ""3_2"",
  397. ""3_3"",
  398. ""3_4""
  399. ]
  400. ]", output);
  401. }
  402. [Test]
  403. public void MultiDObjectArray()
  404. {
  405. object[,] myOtherArray =
  406. {
  407. { new KeyValuePair<string, double>("my value", 0.8), "foobar" },
  408. { true, 0.4d },
  409. { 0.05f, 6 }
  410. };
  411. string myOtherArrayAsString = JsonConvert.SerializeObject(myOtherArray, Formatting.Indented);
  412. StringAssert.AreEqual(@"[
  413. [
  414. {
  415. ""Key"": ""my value"",
  416. ""Value"": 0.8
  417. },
  418. ""foobar""
  419. ],
  420. [
  421. true,
  422. 0.4
  423. ],
  424. [
  425. 0.05,
  426. 6
  427. ]
  428. ]", myOtherArrayAsString);
  429. JObject o = JObject.Parse(@"{
  430. ""Key"": ""my value"",
  431. ""Value"": 0.8
  432. }");
  433. object[,] myOtherResult = JsonConvert.DeserializeObject<object[,]>(myOtherArrayAsString);
  434. Assert.IsTrue(JToken.DeepEquals(o, (JToken)myOtherResult[0, 0]));
  435. Assert.AreEqual("foobar", myOtherResult[0, 1]);
  436. Assert.AreEqual(true, myOtherResult[1, 0]);
  437. Assert.AreEqual(0.4, myOtherResult[1, 1]);
  438. Assert.AreEqual(0.05, myOtherResult[2, 0]);
  439. Assert.AreEqual(6L, myOtherResult[2, 1]);
  440. }
  441. public class EnumerableClass<T> : IEnumerable<T>
  442. {
  443. private readonly IList<T> _values;
  444. public EnumerableClass(IEnumerable<T> values)
  445. {
  446. _values = new List<T>(values);
  447. }
  448. public IEnumerator<T> GetEnumerator()
  449. {
  450. return _values.GetEnumerator();
  451. }
  452. IEnumerator IEnumerable.GetEnumerator()
  453. {
  454. return GetEnumerator();
  455. }
  456. }
  457. [Test]
  458. public void DeserializeIEnumerableFromConstructor()
  459. {
  460. string json = @"[
  461. 1,
  462. 2,
  463. null
  464. ]";
  465. var result = JsonConvert.DeserializeObject<EnumerableClass<int?>>(json);
  466. Assert.AreEqual(3, result.Count());
  467. Assert.AreEqual(1, result.ElementAt(0));
  468. Assert.AreEqual(2, result.ElementAt(1));
  469. Assert.AreEqual(null, result.ElementAt(2));
  470. }
  471. public class EnumerableClassFailure<T> : IEnumerable<T>
  472. {
  473. private readonly IList<T> _values;
  474. public EnumerableClassFailure()
  475. {
  476. _values = new List<T>();
  477. }
  478. public IEnumerator<T> GetEnumerator()
  479. {
  480. return _values.GetEnumerator();
  481. }
  482. IEnumerator IEnumerable.GetEnumerator()
  483. {
  484. return GetEnumerator();
  485. }
  486. }
  487. [Test]
  488. public void DeserializeIEnumerableFromConstructor_Failure()
  489. {
  490. string json = @"[
  491. ""One"",
  492. ""II"",
  493. ""3""
  494. ]";
  495. ExceptionAssert.Throws<JsonSerializationException>(() => JsonConvert.DeserializeObject<EnumerableClassFailure<string>>(json), "Cannot create and populate list type Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+EnumerableClassFailure`1[System.String]. Path '', line 1, position 1.");
  496. }
  497. public class PrivateDefaultCtorList<T> : List<T>
  498. {
  499. private PrivateDefaultCtorList()
  500. {
  501. }
  502. }
  503. [Test]
  504. public void DeserializePrivateListCtor()
  505. {
  506. ExceptionAssert.Throws<JsonSerializationException>(() => JsonConvert.DeserializeObject<PrivateDefaultCtorList<int>>("[1,2]"), "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+PrivateDefaultCtorList`1[System.Int32]. Path '', line 1, position 1.");
  507. var list = JsonConvert.DeserializeObject<PrivateDefaultCtorList<int>>("[1,2]", new JsonSerializerSettings
  508. {
  509. ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
  510. });
  511. Assert.AreEqual(2, list.Count);
  512. }
  513. public class PrivateDefaultCtorWithIEnumerableCtorList<T> : List<T>
  514. {
  515. private PrivateDefaultCtorWithIEnumerableCtorList()
  516. {
  517. }
  518. public PrivateDefaultCtorWithIEnumerableCtorList(IEnumerable<T> values)
  519. : base(values)
  520. {
  521. Add(default(T));
  522. }
  523. }
  524. [Test]
  525. public void DeserializePrivateListConstructor()
  526. {
  527. var list = JsonConvert.DeserializeObject<PrivateDefaultCtorWithIEnumerableCtorList<int>>("[1,2]");
  528. Assert.AreEqual(3, list.Count);
  529. Assert.AreEqual(1, list[0]);
  530. Assert.AreEqual(2, list[1]);
  531. Assert.AreEqual(0, list[2]);
  532. }
  533. [Test]
  534. public void DeserializeNonIsoDateDictionaryKey()
  535. {
  536. Dictionary<DateTime, string> d = JsonConvert.DeserializeObject<Dictionary<DateTime, string>>(@"{""04/28/2013 00:00:00"":""test""}");
  537. Assert.AreEqual(1, d.Count);
  538. DateTime key = DateTime.Parse("04/28/2013 00:00:00", CultureInfo.InvariantCulture);
  539. Assert.AreEqual("test", d[key]);
  540. }
  541. [Test]
  542. public void DeserializeNonGenericList()
  543. {
  544. IList l = JsonConvert.DeserializeObject<IList>("['string!']");
  545. Assert.AreEqual(typeof(List<object>), l.GetType());
  546. Assert.AreEqual(1, l.Count);
  547. Assert.AreEqual("string!", l[0]);
  548. }
  549. #if !(NET40 || NET35 || NET20 || PORTABLE40)
  550. [Test]
  551. public void DeserializeReadOnlyListInterface()
  552. {
  553. IReadOnlyList<int> list = JsonConvert.DeserializeObject<IReadOnlyList<int>>("[1,2,3]");
  554. Assert.AreEqual(3, list.Count);
  555. Assert.AreEqual(1, list[0]);
  556. Assert.AreEqual(2, list[1]);
  557. Assert.AreEqual(3, list[2]);
  558. }
  559. [Test]
  560. public void DeserializeReadOnlyCollectionInterface()
  561. {
  562. IReadOnlyCollection<int> list = JsonConvert.DeserializeObject<IReadOnlyCollection<int>>("[1,2,3]");
  563. Assert.AreEqual(3, list.Count);
  564. Assert.AreEqual(1, list.ElementAt(0));
  565. Assert.AreEqual(2, list.ElementAt(1));
  566. Assert.AreEqual(3, list.ElementAt(2));
  567. }
  568. [Test]
  569. public void DeserializeReadOnlyCollection()
  570. {
  571. ReadOnlyCollection<int> list = JsonConvert.DeserializeObject<ReadOnlyCollection<int>>("[1,2,3]");
  572. Assert.AreEqual(3, list.Count);
  573. Assert.AreEqual(1, list[0]);
  574. Assert.AreEqual(2, list[1]);
  575. Assert.AreEqual(3, list[2]);
  576. }
  577. [Test]
  578. public void DeserializeReadOnlyDictionaryInterface()
  579. {
  580. IReadOnlyDictionary<string, int> dic = JsonConvert.DeserializeObject<IReadOnlyDictionary<string, int>>("{'one':1,'two':2}");
  581. Assert.AreEqual(2, dic.Count);
  582. Assert.AreEqual(1, dic["one"]);
  583. Assert.AreEqual(2, dic["two"]);
  584. CustomAssert.IsInstanceOfType(typeof(ReadOnlyDictionary<string, int>), dic);
  585. }
  586. [Test]
  587. public void DeserializeReadOnlyDictionary()
  588. {
  589. ReadOnlyDictionary<string, int> dic = JsonConvert.DeserializeObject<ReadOnlyDictionary<string, int>>("{'one':1,'two':2}");
  590. Assert.AreEqual(2, dic.Count);
  591. Assert.AreEqual(1, dic["one"]);
  592. Assert.AreEqual(2, dic["two"]);
  593. }
  594. public class CustomReadOnlyDictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>
  595. {
  596. private readonly IDictionary<TKey, TValue> _dictionary;
  597. public CustomReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
  598. {
  599. _dictionary = dictionary;
  600. }
  601. public bool ContainsKey(TKey key)
  602. {
  603. return _dictionary.ContainsKey(key);
  604. }
  605. public IEnumerable<TKey> Keys
  606. {
  607. get { return _dictionary.Keys; }
  608. }
  609. public bool TryGetValue(TKey key, out TValue value)
  610. {
  611. return _dictionary.TryGetValue(key, out value);
  612. }
  613. public IEnumerable<TValue> Values
  614. {
  615. get { return _dictionary.Values; }
  616. }
  617. public TValue this[TKey key]
  618. {
  619. get { return _dictionary[key]; }
  620. }
  621. public int Count
  622. {
  623. get { return _dictionary.Count; }
  624. }
  625. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
  626. {
  627. return _dictionary.GetEnumerator();
  628. }
  629. IEnumerator IEnumerable.GetEnumerator()
  630. {
  631. return _dictionary.GetEnumerator();
  632. }
  633. }
  634. [Test]
  635. public void SerializeCustomReadOnlyDictionary()
  636. {
  637. IDictionary<string, int> d = new Dictionary<string, int>
  638. {
  639. { "one", 1 },
  640. { "two", 2 }
  641. };
  642. CustomReadOnlyDictionary<string, int> dic = new CustomReadOnlyDictionary<string, int>(d);
  643. string json = JsonConvert.SerializeObject(dic, Formatting.Indented);
  644. StringAssert.AreEqual(@"{
  645. ""one"": 1,
  646. ""two"": 2
  647. }", json);
  648. }
  649. public class CustomReadOnlyCollection<T> : IReadOnlyCollection<T>
  650. {
  651. private readonly IList<T> _values;
  652. public CustomReadOnlyCollection(IList<T> values)
  653. {
  654. _values = values;
  655. }
  656. public int Count
  657. {
  658. get { return _values.Count; }
  659. }
  660. public IEnumerator<T> GetEnumerator()
  661. {
  662. return _values.GetEnumerator();
  663. }
  664. IEnumerator IEnumerable.GetEnumerator()
  665. {
  666. return _values.GetEnumerator();
  667. }
  668. }
  669. [Test]
  670. public void SerializeCustomReadOnlyCollection()
  671. {
  672. IList<int> l = new List<int>
  673. {
  674. 1,
  675. 2,
  676. 3
  677. };
  678. CustomReadOnlyCollection<int> list = new CustomReadOnlyCollection<int>(l);
  679. string json = JsonConvert.SerializeObject(list, Formatting.Indented);
  680. StringAssert.AreEqual(@"[
  681. 1,
  682. 2,
  683. 3
  684. ]", json);
  685. }
  686. #endif
  687. [Test]
  688. public void TestEscapeDictionaryStrings()
  689. {
  690. const string s = @"host\user";
  691. string serialized = JsonConvert.SerializeObject(s);
  692. Assert.AreEqual(@"""host\\user""", serialized);
  693. Dictionary<int, object> d1 = new Dictionary<int, object>();
  694. d1.Add(5, s);
  695. Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1));
  696. Dictionary<string, object> d2 = new Dictionary<string, object>();
  697. d2.Add(s, 5);
  698. Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2));
  699. }
  700. public class GenericListTestClass
  701. {
  702. public List<string> GenericList { get; set; }
  703. public GenericListTestClass()
  704. {
  705. GenericList = new List<string>();
  706. }
  707. }
  708. [Test]
  709. public void DeserializeExistingGenericList()
  710. {
  711. GenericListTestClass c = new GenericListTestClass();
  712. c.GenericList.Add("1");
  713. c.GenericList.Add("2");
  714. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  715. GenericListTestClass newValue = JsonConvert.DeserializeObject<GenericListTestClass>(json);
  716. Assert.AreEqual(2, newValue.GenericList.Count);
  717. Assert.AreEqual(typeof(List<string>), newValue.GenericList.GetType());
  718. }
  719. [Test]
  720. public void DeserializeSimpleKeyValuePair()
  721. {
  722. List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
  723. list.Add(new KeyValuePair<string, string>("key1", "value1"));
  724. list.Add(new KeyValuePair<string, string>("key2", "value2"));
  725. string json = JsonConvert.SerializeObject(list);
  726. Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json);
  727. List<KeyValuePair<string, string>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, string>>>(json);
  728. Assert.AreEqual(2, result.Count);
  729. Assert.AreEqual("key1", result[0].Key);
  730. Assert.AreEqual("value1", result[0].Value);
  731. Assert.AreEqual("key2", result[1].Key);
  732. Assert.AreEqual("value2", result[1].Value);
  733. }
  734. [Test]
  735. public void DeserializeComplexKeyValuePair()
  736. {
  737. DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc);
  738. List<KeyValuePair<string, WagePerson>> list = new List<KeyValuePair<string, WagePerson>>();
  739. list.Add(new KeyValuePair<string, WagePerson>("key1", new WagePerson
  740. {
  741. BirthDate = dateTime,
  742. Department = "Department1",
  743. LastModified = dateTime,
  744. HourlyWage = 1
  745. }));
  746. list.Add(new KeyValuePair<string, WagePerson>("key2", new WagePerson
  747. {
  748. BirthDate = dateTime,
  749. Department = "Department2",
  750. LastModified = dateTime,
  751. HourlyWage = 2
  752. }));
  753. string json = JsonConvert.SerializeObject(list, Formatting.Indented);
  754. StringAssert.AreEqual(@"[
  755. {
  756. ""Key"": ""key1"",
  757. ""Value"": {
  758. ""HourlyWage"": 1.0,
  759. ""Name"": null,
  760. ""BirthDate"": ""2000-12-01T23:01:01Z"",
  761. ""LastModified"": ""2000-12-01T23:01:01Z""
  762. }
  763. },
  764. {
  765. ""Key"": ""key2"",
  766. ""Value"": {
  767. ""HourlyWage"": 2.0,
  768. ""Name"": null,
  769. ""BirthDate"": ""2000-12-01T23:01:01Z"",
  770. ""LastModified"": ""2000-12-01T23:01:01Z""
  771. }
  772. }
  773. ]", json);
  774. List<KeyValuePair<string, WagePerson>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, WagePerson>>>(json);
  775. Assert.AreEqual(2, result.Count);
  776. Assert.AreEqual("key1", result[0].Key);
  777. Assert.AreEqual(1, result[0].Value.HourlyWage);
  778. Assert.AreEqual("key2", result[1].Key);
  779. Assert.AreEqual(2, result[1].Value.HourlyWage);
  780. }
  781. [Test]
  782. public void StringListAppenderConverterTest()
  783. {
  784. Movie p = new Movie();
  785. p.ReleaseCountries = new List<string> { "Existing" };
  786. JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings
  787. {
  788. Converters = new List<JsonConverter> { new StringListAppenderConverter() }
  789. });
  790. Assert.AreEqual(2, p.ReleaseCountries.Count);
  791. Assert.AreEqual("Existing", p.ReleaseCountries[0]);
  792. Assert.AreEqual("Appended", p.ReleaseCountries[1]);
  793. }
  794. [Test]
  795. public void StringAppenderConverterTest()
  796. {
  797. Movie p = new Movie();
  798. p.Name = "Existing,";
  799. JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings
  800. {
  801. Converters = new List<JsonConverter> { new StringAppenderConverter() }
  802. });
  803. Assert.AreEqual("Existing,Appended", p.Name);
  804. }
  805. [Test]
  806. public void DeserializeIDictionary()
  807. {
  808. IDictionary dictionary = JsonConvert.DeserializeObject<IDictionary>("{'name':'value!'}");
  809. Assert.AreEqual(1, dictionary.Count);
  810. Assert.AreEqual("value!", dictionary["name"]);
  811. }
  812. [Test]
  813. public void DeserializeIList()
  814. {
  815. IList list = JsonConvert.DeserializeObject<IList>("['1', 'two', 'III']");
  816. Assert.AreEqual(3, list.Count);
  817. }
  818. [Test]
  819. public void NullableValueGenericDictionary()
  820. {
  821. IDictionary<string, int?> v1 = new Dictionary<string, int?>
  822. {
  823. { "First", 1 },
  824. { "Second", null },
  825. { "Third", 3 }
  826. };
  827. string json = JsonConvert.SerializeObject(v1, Formatting.Indented);
  828. StringAssert.AreEqual(@"{
  829. ""First"": 1,
  830. ""Second"": null,
  831. ""Third"": 3
  832. }", json);
  833. IDictionary<string, int?> v2 = JsonConvert.DeserializeObject<IDictionary<string, int?>>(json);
  834. Assert.AreEqual(3, v2.Count);
  835. Assert.AreEqual(1, v2["First"]);
  836. Assert.AreEqual(null, v2["Second"]);
  837. Assert.AreEqual(3, v2["Third"]);
  838. }
  839. #if !(NET35 || NET20 || PORTABLE || PORTABLE40)
  840. [Test]
  841. public void DeserializeConcurrentDictionary()
  842. {
  843. IDictionary<string, TestObjects.Component> components = new Dictionary<string, TestObjects.Component>
  844. {
  845. { "Key!", new TestObjects.Component() }
  846. };
  847. GameObject go = new GameObject
  848. {
  849. Components = new ConcurrentDictionary<string, TestObjects.Component>(components),
  850. Id = "Id!",
  851. Name = "Name!"
  852. };
  853. string originalJson = JsonConvert.SerializeObject(go, Formatting.Indented);
  854. StringAssert.AreEqual(@"{
  855. ""Components"": {
  856. ""Key!"": {}
  857. },
  858. ""Id"": ""Id!"",
  859. ""Name"": ""Name!""
  860. }", originalJson);
  861. GameObject newObject = JsonConvert.DeserializeObject<GameObject>(originalJson);
  862. Assert.AreEqual(1, newObject.Components.Count);
  863. Assert.AreEqual("Id!", newObject.Id);
  864. Assert.AreEqual("Name!", newObject.Name);
  865. }
  866. #endif
  867. [Test]
  868. public void DeserializeKeyValuePairArray()
  869. {
  870. string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]";
  871. IList<KeyValuePair<string, IList<string>>> values = JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>>>(json);
  872. Assert.AreEqual(2, values.Count);
  873. Assert.AreEqual("aaa", values[0].Key);
  874. Assert.AreEqual(2, values[0].Value.Count);
  875. Assert.AreEqual("1", values[0].Value[0]);
  876. Assert.AreEqual("2", values[0].Value[1]);
  877. Assert.AreEqual("bbb", values[1].Key);
  878. Assert.AreEqual(2, values[1].Value.Count);
  879. Assert.AreEqual("3", values[1].Value[0]);
  880. Assert.AreEqual("4", values[1].Value[1]);
  881. }
  882. [Test]
  883. public void DeserializeNullableKeyValuePairArray()
  884. {
  885. string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, null, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]";
  886. IList<KeyValuePair<string, IList<string>>?> values = JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>?>>(json);
  887. Assert.AreEqual(3, values.Count);
  888. Assert.AreEqual("aaa", values[0].Value.Key);
  889. Assert.AreEqual(2, values[0].Value.Value.Count);
  890. Assert.AreEqual("1", values[0].Value.Value[0]);
  891. Assert.AreEqual("2", values[0].Value.Value[1]);
  892. Assert.AreEqual(null, values[1]);
  893. Assert.AreEqual("bbb", values[2].Value.Key);
  894. Assert.AreEqual(2, values[2].Value.Value.Count);
  895. Assert.AreEqual("3", values[2].Value.Value[0]);
  896. Assert.AreEqual("4", values[2].Value.Value[1]);
  897. }
  898. [Test]
  899. public void DeserializeNullToNonNullableKeyValuePairArray()
  900. {
  901. string json = @"[ null ]";
  902. ExceptionAssert.Throws<JsonSerializationException>(() => { JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>>>(json); }, "Cannot convert null value to KeyValuePair. Path '[0]', line 1, position 6.");
  903. }
  904. #if !(NET40 || NET35 || NET20 || PORTABLE40)
  905. public class PopulateReadOnlyTestClass
  906. {
  907. public IList<int> NonReadOnlyList { get; set; }
  908. public IDictionary<string, int> NonReadOnlyDictionary { get; set; }
  909. public IList<int> Array { get; set; }
  910. public IList<int> List { get; set; }
  911. public IDictionary<string, int> Dictionary { get; set; }
  912. public IReadOnlyCollection<int> IReadOnlyCollection { get; set; }
  913. public ReadOnlyCollection<int> ReadOnlyCollection { get; set; }
  914. public IReadOnlyList<int> IReadOnlyList { get; set; }
  915. public IReadOnlyDictionary<string, int> IReadOnlyDictionary { get; set; }
  916. public ReadOnlyDictionary<string, int> ReadOnlyDictionary { get; set; }
  917. public PopulateReadOnlyTestClass()
  918. {
  919. NonReadOnlyList = new List<int> { 1 };
  920. NonReadOnlyDictionary = new Dictionary<string, int> { { "first", 2 } };
  921. Array = new[] { 3 };
  922. List = new ReadOnlyCollection<int>(new[] { 4 });
  923. Dictionary = new ReadOnlyDictionary<string, int>(new Dictionary<string, int> { { "first", 5 } });
  924. IReadOnlyCollection = new ReadOnlyCollection<int>(new[] { 6 });
  925. ReadOnlyCollection = new ReadOnlyCollection<int>(new[] { 7 });
  926. IReadOnlyList = new ReadOnlyCollection<int>(new[] { 8 });
  927. IReadOnlyDictionary = new ReadOnlyDictionary<string, int>(new Dictionary<string, int> { { "first", 9 } });
  928. ReadOnlyDictionary = new ReadOnlyDictionary<string, int>(new Dictionary<string, int> { { "first", 10 } });
  929. }
  930. }
  931. [Test]
  932. public void SerializeReadOnlyCollections()
  933. {
  934. PopulateReadOnlyTestClass c1 = new PopulateReadOnlyTestClass();
  935. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  936. StringAssert.AreEqual(@"{
  937. ""NonReadOnlyList"": [
  938. 1
  939. ],
  940. ""NonReadOnlyDictionary"": {
  941. ""first"": 2
  942. },
  943. ""Array"": [
  944. 3
  945. ],
  946. ""List"": [
  947. 4
  948. ],
  949. ""Dictionary"": {
  950. ""first"": 5
  951. },
  952. ""IReadOnlyCollection"": [
  953. 6
  954. ],
  955. ""ReadOnlyCollection"": [
  956. 7
  957. ],
  958. ""IReadOnlyList"": [
  959. 8
  960. ],
  961. ""IReadOnlyDictionary"": {
  962. ""first"": 9
  963. },
  964. ""ReadOnlyDictionary"": {
  965. ""first"": 10
  966. }
  967. }", json);
  968. }
  969. [Test]
  970. public void PopulateReadOnlyCollections()
  971. {
  972. string json = @"{
  973. ""NonReadOnlyList"": [
  974. 11
  975. ],
  976. ""NonReadOnlyDictionary"": {
  977. ""first"": 12
  978. },
  979. ""Array"": [
  980. 13
  981. ],
  982. ""List"": [
  983. 14
  984. ],
  985. ""Dictionary"": {
  986. ""first"": 15
  987. },
  988. ""IReadOnlyCollection"": [
  989. 16
  990. ],
  991. ""ReadOnlyCollection"": [
  992. 17
  993. ],
  994. ""IReadOnlyList"": [
  995. 18
  996. ],
  997. ""IReadOnlyDictionary"": {
  998. ""first"": 19
  999. },
  1000. ""ReadOnlyDictionary"": {
  1001. ""first"": 20
  1002. }
  1003. }";
  1004. var c2 = JsonConvert.DeserializeObject<PopulateReadOnlyTestClass>(json);
  1005. Assert.AreEqual(1, c2.NonReadOnlyDictionary.Count);
  1006. Assert.AreEqual(12, c2.NonReadOnlyDictionary["first"]);
  1007. Assert.AreEqual(2, c2.NonReadOnlyList.Count);
  1008. Assert.AreEqual(1, c2.NonReadOnlyList[0]);
  1009. Assert.AreEqual(11, c2.NonReadOnlyList[1]);
  1010. Assert.AreEqual(1, c2.Array.Count);
  1011. Assert.AreEqual(13, c2.Array[0]);
  1012. }
  1013. #endif
  1014. [Test]
  1015. public void SerializeArray2D()
  1016. {
  1017. Array2D aa = new Array2D();
  1018. aa.Before = "Before!";
  1019. aa.After = "After!";
  1020. aa.Coordinates = new[,] { { 1, 1 }, { 1, 2 }, { 2, 1 }, { 2, 2 } };
  1021. string json = JsonConvert.SerializeObject(aa);
  1022. Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json);
  1023. }
  1024. [Test]
  1025. public void SerializeArray3D()
  1026. {
  1027. Array3D aa = new Array3D();
  1028. aa.Before = "Before!";
  1029. aa.After = "After!";
  1030. aa.Coordinates = new[,,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } };
  1031. string json = JsonConvert.SerializeObject(aa);
  1032. Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}", json);
  1033. }
  1034. [Test]
  1035. public void SerializeArray3DWithConverter()
  1036. {
  1037. Array3DWithConverter aa = new Array3DWithConverter();
  1038. aa.Before = "Before!";
  1039. aa.After = "After!";
  1040. aa.Coordinates = new[,,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } };
  1041. string json = JsonConvert.SerializeObject(aa, Formatting.Indented);
  1042. StringAssert.AreEqual(@"{
  1043. ""Before"": ""Before!"",
  1044. ""Coordinates"": [
  1045. [
  1046. [
  1047. 1.0,
  1048. 1.0,
  1049. 1.0
  1050. ],
  1051. [
  1052. 1.0,
  1053. 1.0,
  1054. 2.0
  1055. ]
  1056. ],
  1057. [
  1058. [
  1059. 1.0,
  1060. 2.0,
  1061. 1.0
  1062. ],
  1063. [
  1064. 1.0,
  1065. 2.0,
  1066. 2.0
  1067. ]
  1068. ],
  1069. [
  1070. [
  1071. 2.0,
  1072. 1.0,
  1073. 1.0
  1074. ],
  1075. [
  1076. 2.0,
  1077. 1.0,
  1078. 2.0
  1079. ]
  1080. ],
  1081. [
  1082. [
  1083. 2.0,
  1084. 2.0,
  1085. 1.0
  1086. ],
  1087. [
  1088. 2.0,
  1089. 2.0,
  1090. 2.0
  1091. ]
  1092. ]
  1093. ],
  1094. ""After"": ""After!""
  1095. }", json);
  1096. }
  1097. [Test]
  1098. public void DeserializeArray3DWithConverter()
  1099. {
  1100. string json = @"{
  1101. ""Before"": ""Before!"",
  1102. ""Coordinates"": [
  1103. [
  1104. [
  1105. 1.0,
  1106. 1.0,
  1107. 1.0
  1108. ],
  1109. [
  1110. 1.0,
  1111. 1.0,
  1112. 2.0
  1113. ]
  1114. ],
  1115. [
  1116. [
  1117. 1.0,
  1118. 2.0,
  1119. 1.0
  1120. ],
  1121. [
  1122. 1.0,
  1123. 2.0,
  1124. 2.0
  1125. ]
  1126. ],
  1127. [
  1128. [
  1129. 2.0,
  1130. 1.0,
  1131. 1.0
  1132. ],
  1133. [
  1134. 2.0,
  1135. 1.0,
  1136. 2.0
  1137. ]
  1138. ],
  1139. [
  1140. [
  1141. 2.0,
  1142. 2.0,
  1143. 1.0
  1144. ],
  1145. [
  1146. 2.0,
  1147. 2.0,
  1148. 2.0
  1149. ]
  1150. ]
  1151. ],
  1152. ""After"": ""After!""
  1153. }";
  1154. Array3DWithConverter aa = JsonConvert.DeserializeObject<Array3DWithConverter>(json);
  1155. Assert.AreEqual("Before!", aa.Before);
  1156. Assert.AreEqual("After!", aa.After);
  1157. Assert.AreEqual(4, aa.Coordinates.GetLength(0));
  1158. Assert.AreEqual(2, aa.Coordinates.GetLength(1));
  1159. Assert.AreEqual(3, aa.Coordinates.GetLength(2));
  1160. Assert.AreEqual(1, aa.Coordinates[0, 0, 0]);
  1161. Assert.AreEqual(2, aa.Coordinates[1, 1, 1]);
  1162. }
  1163. [Test]
  1164. public void DeserializeArray2D()
  1165. {
  1166. string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}";
  1167. Array2D aa = JsonConvert.DeserializeObject<Array2D>(json);
  1168. Assert.AreEqual("Before!", aa.Before);
  1169. Assert.AreEqual("After!", aa.After);
  1170. Assert.AreEqual(4, aa.Coordinates.GetLength(0));
  1171. Assert.AreEqual(2, aa.Coordinates.GetLength(1));
  1172. Assert.AreEqual(1, aa.Coordinates[0, 0]);
  1173. Assert.AreEqual(2, aa.Coordinates[1, 1]);
  1174. string after = JsonConvert.SerializeObject(aa);
  1175. Assert.AreEqual(json, after);
  1176. }
  1177. [Test]
  1178. public void DeserializeArray2D_WithTooManyItems()
  1179. {
  1180. string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2,3],[2,1],[2,2]],""After"":""After!""}";
  1181. ExceptionAssert.Throws<Exception>(() => JsonConvert.DeserializeObject<Array2D>(json), "Cannot deserialize non-cubical array as multidimensional array.");
  1182. }
  1183. [Test]
  1184. public void DeserializeArray2D_WithTooFewItems()
  1185. {
  1186. string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1],[2,1],[2,2]],""After"":""After!""}";
  1187. ExceptionAssert.Throws<Exception>(() => JsonConvert.DeserializeObject<Array2D>(json), "Cannot deserialize non-cubical array as multidimensional array.");
  1188. }
  1189. [Test]
  1190. public void DeserializeArray3D()
  1191. {
  1192. string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}";
  1193. Array3D aa = JsonConvert.DeserializeObject<Array3D>(json);
  1194. Assert.AreEqual("Before!", aa.Before);
  1195. Assert.AreEqual("After!", aa.After);
  1196. Assert.AreEqual(4, aa.Coordinates.GetLength(0));
  1197. Assert.AreEqual(2, aa.Coordinates.GetLength(1));
  1198. Assert.AreEqual(3, aa.Coordinates.GetLength(2));
  1199. Assert.AreEqual(1, aa.Coordinates[0, 0, 0]);
  1200. Assert.AreEqual(2, aa.Coordinates[1, 1, 1]);
  1201. string after = JsonConvert.SerializeObject(aa);
  1202. Assert.AreEqual(json, after);
  1203. }
  1204. [Test]
  1205. public void DeserializeArray3D_WithTooManyItems()
  1206. {
  1207. string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}";
  1208. ExceptionAssert.Throws<Exception>(() => JsonConvert.DeserializeObject<Array3D>(json), "Cannot deserialize non-cubical array as multidimensional array.");
  1209. }
  1210. [Test]
  1211. public void DeserializeArray3D_WithBadItems()
  1212. {
  1213. string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],{}]],""After"":""After!""}";
  1214. ExceptionAssert.Throws<JsonSerializationException>(() => JsonConvert.DeserializeObject<Array3D>(json), "Unexpected token when deserializing multidimensional array: StartObject. Path 'Coordinates[3][1]', line 1, position 99.");
  1215. }
  1216. [Test]
  1217. public void DeserializeArray3D_WithTooFewItems()
  1218. {
  1219. string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}";
  1220. ExceptionAssert.Throws<Exception>(() => JsonConvert.DeserializeObject<Array3D>(json), "Cannot deserialize non-cubical array as multidimensional array.");
  1221. }
  1222. [Test]
  1223. public void SerializeEmpty3DArray()
  1224. {
  1225. Array3D aa = new Array3D();
  1226. aa.Before = "Before!";
  1227. aa.After = "After!";
  1228. aa.Coordinates = new int[0, 0, 0];
  1229. string json = JsonConvert.SerializeObject(aa);
  1230. Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}", json);
  1231. }
  1232. [Test]
  1233. public void DeserializeEmpty3DArray()
  1234. {
  1235. string json = @"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}";
  1236. Array3D aa = JsonConvert.DeserializeObject<Array3D>(json);
  1237. Assert.AreEqual("Before!", aa.Before);
  1238. Assert.AreEqual("After!", aa.After);
  1239. Assert.AreEqual(0, aa.Coordinates.GetLength(0));
  1240. Assert.AreEqual(0, aa.Coordinates.GetLength(1));
  1241. Assert.AreEqual(0, aa.Coordinates.GetLength(2));
  1242. string after = JsonConvert.SerializeObject(aa);
  1243. Assert.AreEqual(json, after);
  1244. }
  1245. [Test]
  1246. public void DeserializeIncomplete3DArray()
  1247. {
  1248. string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/[1/*hi*/,/*hi*/1/*hi*/,1]/*hi*/,/*hi*/[1,1";
  1249. ExceptionAssert.Throws<JsonException>(() => JsonConvert.DeserializeObject<Array3D>(json));
  1250. }
  1251. [Test]
  1252. public void DeserializeIncompleteNotTopLevel3DArray()
  1253. {
  1254. string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/";
  1255. ExceptionAssert.Throws<JsonException>(() => JsonConvert.DeserializeObject<Array3D>(json));
  1256. }
  1257. [Test]
  1258. public void DeserializeNull3DArray()
  1259. {
  1260. string json = @"{""Before"":""Before!"",""Coordinates"":null,""After"":""After!""}";
  1261. Array3D aa = JsonConvert.DeserializeObject<Array3D>(json);
  1262. Assert.AreEqual("Before!", aa.Before);
  1263. Assert.AreEqual("After!", aa.After);
  1264. Assert.AreEqual(null, aa.Coordinates);
  1265. string after = JsonConvert.SerializeObject(aa);
  1266. Assert.AreEqual(json, after);
  1267. }
  1268. [Test]
  1269. public void DeserializeSemiEmpty3DArray()
  1270. {
  1271. string json = @"{""Before"":""Before!"",""Coordinates"":[[]],""After"":""After!""}";
  1272. Array3D aa = JsonConvert.DeserializeObject<Array3D>(json);
  1273. Assert.AreEqual("Before!", aa.Before);
  1274. Assert.AreEqual("After!", aa.After);
  1275. Assert.AreEqual(1, aa.Coordinates.GetLength(0));
  1276. Assert.AreEqual(0, aa.Coordinates.GetLength(1));
  1277. Assert.AreEqual(0, aa.Coordinates.GetLength(2));
  1278. string after = JsonConvert.SerializeObject(aa);
  1279. Assert.AreEqual(json, after);
  1280. }
  1281. [Test]
  1282. public void SerializeReferenceTracked3DArray()
  1283. {
  1284. Event1 e1 = new Event1
  1285. {
  1286. EventName = "EventName!"
  1287. };
  1288. Event1[,] array1 = new[,] { { e1, e1 }, { e1, e1 } };
  1289. IList<Event1[,]> values1 = new List<Event1[,]>
  1290. {
  1291. array1,
  1292. array1
  1293. };
  1294. string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings
  1295. {
  1296. PreserveReferencesHandling = PreserveReferencesHandling.All,
  1297. Formatting = Formatting.Indented
  1298. });
  1299. StringAssert.AreEqual(@"{
  1300. ""$id"": ""1"",
  1301. ""$values"": [
  1302. {
  1303. ""$id"": ""2"",
  1304. ""$values"": [
  1305. [
  1306. {
  1307. ""$id"": "…

Large files files are truncated, but you can click here to view the full file