PageRenderTime 4ms CodeModel.GetById 4ms app.highlight 85ms RepoModel.GetById 1ms app.codeStats 1ms

/desktop_clients/Visual Studio/Crear beneficiarios/Json100r3/Source/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs

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

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