All files
[pithos-ms-client] / trunk / Libraries / Json40r2 / Source / Src / Newtonsoft.Json.Tests / Linq / JObjectTests.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Linq;
5 using System.Text;
6 using Newtonsoft.Json.Tests.TestObjects;
7 using NUnit.Framework;
8 using Newtonsoft.Json.Linq;
9 using Newtonsoft.Json.Converters;
10 using System.IO;
11 using System.Collections;
12 using System.Collections.Specialized;
13 #if !PocketPC && !SILVERLIGHT
14 using System.Web.UI;
15 #endif
16
17 namespace Newtonsoft.Json.Tests.Linq
18 {
19   public class JObjectTests : TestFixtureBase
20   {
21     [Test]
22     public void TryGetValue()
23     {
24       JObject o = new JObject();
25       o.Add("PropertyNameValue", new JValue(1));
26       Assert.AreEqual(1, o.Children().Count());
27
28       JToken t;
29       Assert.AreEqual(false, o.TryGetValue("sdf", out t));
30       Assert.AreEqual(null, t);
31
32       Assert.AreEqual(false, o.TryGetValue(null, out t));
33       Assert.AreEqual(null, t);
34
35       Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
36       Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t));
37     }
38
39     [Test]
40     public void DictionaryItemShouldSet()
41     {
42       JObject o = new JObject();
43       o["PropertyNameValue"] = new JValue(1);
44       Assert.AreEqual(1, o.Children().Count());
45
46       JToken t;
47       Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
48       Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t));
49
50       o["PropertyNameValue"] = new JValue(2);
51       Assert.AreEqual(1, o.Children().Count());
52
53       Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
54       Assert.AreEqual(true, JToken.DeepEquals(new JValue(2), t));
55
56       o["PropertyNameValue"] = null;
57       Assert.AreEqual(1, o.Children().Count());
58
59       Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
60       Assert.AreEqual(true, JToken.DeepEquals(new JValue((object)null), t));
61     }
62
63     [Test]
64     public void Remove()
65     {
66       JObject o = new JObject();
67       o.Add("PropertyNameValue", new JValue(1));
68       Assert.AreEqual(1, o.Children().Count());
69
70       Assert.AreEqual(false, o.Remove("sdf"));
71       Assert.AreEqual(false, o.Remove(null));
72       Assert.AreEqual(true, o.Remove("PropertyNameValue"));
73
74       Assert.AreEqual(0, o.Children().Count());
75     }
76
77     [Test]
78     public void GenericCollectionRemove()
79     {
80       JValue v = new JValue(1);
81       JObject o = new JObject();
82       o.Add("PropertyNameValue", v);
83       Assert.AreEqual(1, o.Children().Count());
84
85       Assert.AreEqual(false, ((ICollection<KeyValuePair<string, JToken>>)o).Remove(new KeyValuePair<string, JToken>("PropertyNameValue1", new JValue(1))));
86       Assert.AreEqual(false, ((ICollection<KeyValuePair<string, JToken>>)o).Remove(new KeyValuePair<string, JToken>("PropertyNameValue", new JValue(2))));
87       Assert.AreEqual(false, ((ICollection<KeyValuePair<string, JToken>>)o).Remove(new KeyValuePair<string, JToken>("PropertyNameValue", new JValue(1))));
88       Assert.AreEqual(true, ((ICollection<KeyValuePair<string, JToken>>)o).Remove(new KeyValuePair<string, JToken>("PropertyNameValue", v)));
89
90       Assert.AreEqual(0, o.Children().Count());
91     }
92
93     [Test]
94     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property PropertyNameValue to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
95     public void DuplicatePropertyNameShouldThrow()
96     {
97       JObject o = new JObject();
98       o.Add("PropertyNameValue", null);
99       o.Add("PropertyNameValue", null);
100     }
101
102     [Test]
103     public void GenericDictionaryAdd()
104     {
105       JObject o = new JObject();
106
107       o.Add("PropertyNameValue", new JValue(1));
108       Assert.AreEqual(1, (int)o["PropertyNameValue"]);
109
110       o.Add("PropertyNameValue1", null);
111       Assert.AreEqual(null, ((JValue)o["PropertyNameValue1"]).Value);
112
113       Assert.AreEqual(2, o.Children().Count());
114     }
115
116     [Test]
117     public void GenericCollectionAdd()
118     {
119       JObject o = new JObject();
120       ((ICollection<KeyValuePair<string,JToken>>)o).Add(new KeyValuePair<string,JToken>("PropertyNameValue", new JValue(1)));
121
122       Assert.AreEqual(1, (int)o["PropertyNameValue"]);
123       Assert.AreEqual(1, o.Children().Count());
124     }
125
126     [Test]
127     public void GenericCollectionClear()
128     {
129       JObject o = new JObject();
130       o.Add("PropertyNameValue", new JValue(1));
131       Assert.AreEqual(1, o.Children().Count());
132
133       JProperty p = (JProperty)o.Children().ElementAt(0);
134
135       ((ICollection<KeyValuePair<string, JToken>>)o).Clear();
136       Assert.AreEqual(0, o.Children().Count());
137
138       Assert.AreEqual(null, p.Parent);
139     }
140
141     [Test]
142     public void GenericCollectionContains()
143     {
144       JValue v = new JValue(1);
145       JObject o = new JObject();
146       o.Add("PropertyNameValue", v);
147       Assert.AreEqual(1, o.Children().Count());
148
149       bool contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(new KeyValuePair<string, JToken>("PropertyNameValue", new JValue(1)));
150       Assert.AreEqual(false, contains);
151
152       contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(new KeyValuePair<string, JToken>("PropertyNameValue", v));
153       Assert.AreEqual(true, contains);
154
155       contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(new KeyValuePair<string, JToken>("PropertyNameValue", new JValue(2)));
156       Assert.AreEqual(false, contains);
157
158       contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(new KeyValuePair<string, JToken>("PropertyNameValue1", new JValue(1)));
159       Assert.AreEqual(false, contains);
160
161       contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(default(KeyValuePair<string, JToken>));
162       Assert.AreEqual(false, contains);
163     }
164
165     [Test]
166     public void GenericDictionaryContains()
167     {
168       JObject o = new JObject();
169       o.Add("PropertyNameValue", new JValue(1));
170       Assert.AreEqual(1, o.Children().Count());
171
172       bool contains = ((IDictionary<string, JToken>)o).ContainsKey("PropertyNameValue");
173       Assert.AreEqual(true, contains);
174     }
175
176     [Test]
177     public void GenericCollectionCopyTo()
178     {
179       JObject o = new JObject();
180       o.Add("PropertyNameValue", new JValue(1));
181       o.Add("PropertyNameValue2", new JValue(2));
182       o.Add("PropertyNameValue3", new JValue(3));
183       Assert.AreEqual(3, o.Children().Count());
184
185       KeyValuePair<string, JToken>[] a = new KeyValuePair<string,JToken>[5];
186
187       ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(a, 1);
188
189       Assert.AreEqual(default(KeyValuePair<string,JToken>), a[0]);
190       
191       Assert.AreEqual("PropertyNameValue", a[1].Key);
192       Assert.AreEqual(1, (int)a[1].Value);
193
194       Assert.AreEqual("PropertyNameValue2", a[2].Key);
195       Assert.AreEqual(2, (int)a[2].Value);
196
197       Assert.AreEqual("PropertyNameValue3", a[3].Key);
198       Assert.AreEqual(3, (int)a[3].Value);
199
200       Assert.AreEqual(default(KeyValuePair<string, JToken>), a[4]);
201     }
202
203     [Test]
204     [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
205 Parameter name: array")]
206     public void GenericCollectionCopyToNullArrayShouldThrow()
207     {
208       JObject o = new JObject();
209       ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(null, 0);
210     }
211
212     [Test]
213     [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"arrayIndex is less than 0.
214 Parameter name: arrayIndex")]
215     public void GenericCollectionCopyToNegativeArrayIndexShouldThrow()
216     {
217       JObject o = new JObject();
218       ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(new KeyValuePair<string, JToken>[1], -1);
219     }
220
221     [Test]
222     [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"arrayIndex is equal to or greater than the length of array.")]
223     public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow()
224     {
225       JObject o = new JObject();
226       ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(new KeyValuePair<string, JToken>[1], 1);
227     }
228
229     [Test]
230     [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.")]
231     public void GenericCollectionCopyToInsufficientArrayCapacity()
232     {
233       JObject o = new JObject();
234       o.Add("PropertyNameValue", new JValue(1));
235       o.Add("PropertyNameValue2", new JValue(2));
236       o.Add("PropertyNameValue3", new JValue(3));
237
238       ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(new KeyValuePair<string, JToken>[3], 1);
239     }
240
241     [Test]
242     public void FromObjectRaw()
243     {
244       PersonRaw raw = new PersonRaw
245       {
246         FirstName = "FirstNameValue",
247         RawContent = new JRaw("[1,2,3,4,5]"),
248         LastName = "LastNameValue"
249       };
250
251       JObject o = JObject.FromObject(raw);
252
253       Assert.AreEqual("FirstNameValue", (string)o["first_name"]);
254       Assert.AreEqual(JTokenType.Raw, ((JValue)o["RawContent"]).Type);
255       Assert.AreEqual("[1,2,3,4,5]", (string)o["RawContent"]);
256       Assert.AreEqual("LastNameValue", (string)o["last_name"]);
257     }
258
259     [Test]
260     public void JTokenReader()
261     {
262       PersonRaw raw = new PersonRaw
263       {
264         FirstName = "FirstNameValue",
265         RawContent = new JRaw("[1,2,3,4,5]"),
266         LastName = "LastNameValue"
267       };
268
269       JObject o = JObject.FromObject(raw);
270
271       JsonReader reader = new JTokenReader(o);
272
273       Assert.IsTrue(reader.Read());
274       Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
275
276       Assert.IsTrue(reader.Read());
277       Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
278
279       Assert.IsTrue(reader.Read());
280       Assert.AreEqual(JsonToken.String, reader.TokenType);
281
282       Assert.IsTrue(reader.Read());
283       Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
284
285       Assert.IsTrue(reader.Read());
286       Assert.AreEqual(JsonToken.Raw, reader.TokenType);
287
288       Assert.IsTrue(reader.Read());
289       Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
290
291       Assert.IsTrue(reader.Read());
292       Assert.AreEqual(JsonToken.String, reader.TokenType);
293
294       Assert.IsTrue(reader.Read());
295       Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
296
297       Assert.IsFalse(reader.Read());
298     }
299
300     [Test]
301     public void DeserializeFromRaw()
302     {
303       PersonRaw raw = new PersonRaw
304       {
305         FirstName = "FirstNameValue",
306         RawContent = new JRaw("[1,2,3,4,5]"),
307         LastName = "LastNameValue"
308       };
309
310       JObject o = JObject.FromObject(raw);
311
312       JsonReader reader = new JTokenReader(o);
313       JsonSerializer serializer = new JsonSerializer();
314       raw = (PersonRaw)serializer.Deserialize(reader, typeof(PersonRaw));
315
316       Assert.AreEqual("FirstNameValue", raw.FirstName);
317       Assert.AreEqual("LastNameValue", raw.LastName);
318       Assert.AreEqual("[1,2,3,4,5]", raw.RawContent.Value);
319     }
320
321     [Test]
322     [ExpectedException(typeof(Exception), ExpectedMessage = "Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray")]
323     public void Parse_ShouldThrowOnUnexpectedToken()
324     {
325       string json = @"[""prop""]";
326       JObject.Parse(json);
327     }
328
329     [Test]
330     public void ParseJavaScriptDate()
331     {
332       string json = @"[new Date(1207285200000)]";
333
334       JArray a = (JArray)JsonConvert.DeserializeObject(json);
335       JValue v = (JValue)a[0];
336
337       Assert.AreEqual(JsonConvert.ConvertJavaScriptTicksToDateTime(1207285200000), (DateTime)v);
338     }
339
340     [Test]
341     public void GenericValueCast()
342     {
343       string json = @"{""foo"":true}";
344       JObject o = (JObject)JsonConvert.DeserializeObject(json);
345       bool? value = o.Value<bool?>("foo");
346       Assert.AreEqual(true, value);
347
348       json = @"{""foo"":null}"; 
349       o = (JObject)JsonConvert.DeserializeObject(json);
350       value = o.Value<bool?>("foo");
351       Assert.AreEqual(null, value);
352     }
353
354     [Test]
355     [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Invalid property identifier character: ]. Line 3, position 9.")]
356     public void Blog()
357     {
358       JObject person = JObject.Parse(@"{
359         ""name"": ""James"",
360         ]!#$THIS IS: BAD JSON![{}}}}]
361       }");
362
363       // Invalid property identifier character: ]. Line 3, position 9.
364     }
365
366     [Test]
367     public void RawChildValues()
368     {
369       JObject o = new JObject();
370       o["val1"] = new JRaw("1");
371       o["val2"] = new JRaw("1");
372
373       string json = o.ToString();
374
375       Assert.AreEqual(@"{
376   ""val1"": 1,
377   ""val2"": 1
378 }", json);
379     }
380
381     [Test]
382     public void Iterate()
383     {
384       JObject o = new JObject();
385       o.Add("PropertyNameValue1", new JValue(1));
386       o.Add("PropertyNameValue2", new JValue(2));
387
388       JToken t = o;
389
390       int i = 1;
391       foreach (JProperty property in t)
392       {
393         Assert.AreEqual("PropertyNameValue" + i, property.Name);
394         Assert.AreEqual(i, (int)property.Value);
395
396         i++;
397       }
398     }
399
400     [Test]
401     public void KeyValuePairIterate()
402     {
403       JObject o = new JObject();
404       o.Add("PropertyNameValue1", new JValue(1));
405       o.Add("PropertyNameValue2", new JValue(2));
406
407       int i = 1;
408       foreach (KeyValuePair<string, JToken> pair in o)
409       {
410         Assert.AreEqual("PropertyNameValue" + i, pair.Key);
411         Assert.AreEqual(i, (int)pair.Value);
412
413         i++;
414       }
415     }
416
417     [Test]
418     public void WriteObjectNullStringValue()
419     {
420       string s = null;
421       JValue v = new JValue(s);
422       Assert.AreEqual(null, v.Value);
423       Assert.AreEqual(JTokenType.String, v.Type);
424
425       JObject o = new JObject();
426       o["title"] = v;
427
428       string output = o.ToString();
429       
430       Assert.AreEqual(@"{
431   ""title"": null
432 }", output);
433     }
434
435     [Test]
436     public void Example()
437     {
438       string json = @"{
439         ""Name"": ""Apple"",
440         ""Expiry"": new Date(1230422400000),
441         ""Price"": 3.99,
442         ""Sizes"": [
443           ""Small"",
444           ""Medium"",
445           ""Large""
446         ]
447       }";
448
449       JObject o = JObject.Parse(json);
450
451       string name = (string)o["Name"];
452       // Apple
453
454       JArray sizes = (JArray)o["Sizes"];
455
456       string smallest = (string)sizes[0];
457       // Small
458
459       Console.WriteLine(name);
460       Console.WriteLine(smallest);
461     }
462
463     [Test]
464     public void DeserializeClassManually()
465     {
466       string jsonText = @"{
467   ""short"":
468   {
469     ""original"":""http://www.foo.com/"",
470     ""short"":""krehqk"",
471     ""error"":
472     {
473       ""code"":0,
474       ""msg"":""No action taken""
475     }
476   }
477 }";
478
479       JObject json = JObject.Parse(jsonText);
480
481       Shortie shortie = new Shortie
482                         {
483                           Original = (string)json["short"]["original"],
484                           Short = (string)json["short"]["short"],
485                           Error = new ShortieException
486                                   {
487                                     Code = (int)json["short"]["error"]["code"],
488                                     ErrorMessage = (string)json["short"]["error"]["msg"]
489                                   }
490                         };
491
492       Console.WriteLine(shortie.Original);
493       // http://www.foo.com/
494
495       Console.WriteLine(shortie.Error.ErrorMessage);
496       // No action taken
497
498       Assert.AreEqual("http://www.foo.com/", shortie.Original);
499       Assert.AreEqual("krehqk", shortie.Short);
500       Assert.AreEqual(null, shortie.Shortened);
501       Assert.AreEqual(0, shortie.Error.Code);
502       Assert.AreEqual("No action taken", shortie.Error.ErrorMessage);
503     }
504
505     [Test]
506     public void JObjectContainingHtml()
507     {
508       JObject o = new JObject();
509       o["rc"] = new JValue(200);
510       o["m"] = new JValue("");
511       o["o"] = new JValue(@"<div class='s1'>
512     <div class='avatar'>                    
513         <a href='asdf'>asdf</a><br />
514         <strong>0</strong>
515     </div>
516     <div class='sl'>
517         <p>
518             444444444
519         </p>
520     </div>
521     <div class='clear'>
522     </div>                        
523 </div>");
524
525       Assert.AreEqual(@"{
526   ""rc"": 200,
527   ""m"": """",
528   ""o"": ""<div class='s1'>\r\n    <div class='avatar'>                    \r\n        <a href='asdf'>asdf</a><br />\r\n        <strong>0</strong>\r\n    </div>\r\n    <div class='sl'>\r\n        <p>\r\n            444444444\r\n        </p>\r\n    </div>\r\n    <div class='clear'>\r\n    </div>                        \r\n</div>""
529 }", o.ToString());
530     }
531
532     [Test]
533     public void ImplicitValueConversions()
534     {
535       JObject moss = new JObject();
536       moss["FirstName"] = new JValue("Maurice");
537       moss["LastName"] = new JValue("Moss");
538       moss["BirthDate"] = new JValue(new DateTime(1977, 12, 30));
539       moss["Department"] = new JValue("IT");
540       moss["JobTitle"] = new JValue("Support");
541
542       Console.WriteLine(moss.ToString());
543       //{
544       //  "FirstName": "Maurice",
545       //  "LastName": "Moss",
546       //  "BirthDate": "\/Date(252241200000+1300)\/",
547       //  "Department": "IT",
548       //  "JobTitle": "Support"
549       //}
550
551
552       JObject jen = new JObject();
553       jen["FirstName"] = "Jen";
554       jen["LastName"] = "Barber";
555       jen["BirthDate"] = new DateTime(1978, 3, 15);
556       jen["Department"] = "IT";
557       jen["JobTitle"] = "Manager";
558
559       Console.WriteLine(jen.ToString());
560       //{
561       //  "FirstName": "Jen",
562       //  "LastName": "Barber",
563       //  "BirthDate": "\/Date(258721200000+1300)\/",
564       //  "Department": "IT",
565       //  "JobTitle": "Manager"
566       //}
567     }
568
569     [Test]
570     public void ReplaceJPropertyWithJPropertyWithSameName()
571     {
572       JProperty p1 = new JProperty("Test1", 1);
573       JProperty p2 = new JProperty("Test2", "Two");
574
575       JObject o = new JObject(p1, p2);
576       IList l = o;
577       Assert.AreEqual(p1, l[0]);
578       Assert.AreEqual(p2, l[1]);
579
580       JProperty p3 = new JProperty("Test1", "III");
581
582       p1.Replace(p3);
583       Assert.AreEqual(null, p1.Parent);
584       Assert.AreEqual(l, p3.Parent);
585
586       Assert.AreEqual(p3, l[0]);
587       Assert.AreEqual(p2, l[1]);
588
589       Assert.AreEqual(2, l.Count);
590       Assert.AreEqual(2, o.Properties().Count());
591
592       JProperty p4 = new JProperty("Test4", "IV");
593
594       p2.Replace(p4);
595       Assert.AreEqual(null, p2.Parent);
596       Assert.AreEqual(l, p4.Parent);
597
598       Assert.AreEqual(p3, l[0]);
599       Assert.AreEqual(p4, l[1]);
600     }
601
602 #if !PocketPC && !SILVERLIGHT && !NET20
603     [Test]
604     public void PropertyChanging()
605     {
606       object changing = null;
607       object changed = null;
608       int changingCount = 0;
609       int changedCount = 0;
610
611       JObject o = new JObject();
612       o.PropertyChanging += (sender, args) =>
613         {
614           JObject s = (JObject) sender;
615           changing = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null;
616           changingCount++;
617         };
618       o.PropertyChanged += (sender, args) =>
619       {
620         JObject s = (JObject)sender;
621         changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null;
622         changedCount++;
623       };
624
625       o["StringValue"] = "value1";
626       Assert.AreEqual(null, changing);
627       Assert.AreEqual("value1", changed);
628       Assert.AreEqual("value1", (string)o["StringValue"]);
629       Assert.AreEqual(1, changingCount);
630       Assert.AreEqual(1, changedCount);
631
632       o["StringValue"] = "value1";
633       Assert.AreEqual(1, changingCount);
634       Assert.AreEqual(1, changedCount);
635
636       o["StringValue"] = "value2";
637       Assert.AreEqual("value1", changing);
638       Assert.AreEqual("value2", changed);
639       Assert.AreEqual("value2", (string)o["StringValue"]);
640       Assert.AreEqual(2, changingCount);
641       Assert.AreEqual(2, changedCount);
642
643       o["StringValue"] = null;
644       Assert.AreEqual("value2", changing);
645       Assert.AreEqual(null, changed);
646       Assert.AreEqual(null, (string)o["StringValue"]);
647       Assert.AreEqual(3, changingCount);
648       Assert.AreEqual(3, changedCount);
649
650       o["NullValue"] = null;
651       Assert.AreEqual(null, changing);
652       Assert.AreEqual(null, changed);
653       Assert.AreEqual(new JValue((object)null), o["NullValue"]);
654       Assert.AreEqual(4, changingCount);
655       Assert.AreEqual(4, changedCount);
656
657       o["NullValue"] = null;
658       Assert.AreEqual(4, changingCount);
659       Assert.AreEqual(4, changedCount);
660     }
661 #endif
662
663     [Test]
664     public void PropertyChanged()
665     {
666       object changed = null;
667       int changedCount = 0;
668
669       JObject o = new JObject();
670       o.PropertyChanged += (sender, args) =>
671       {
672         JObject s = (JObject)sender;
673         changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null;
674         changedCount++;
675       };
676
677       o["StringValue"] = "value1";
678       Assert.AreEqual("value1", changed);
679       Assert.AreEqual("value1", (string)o["StringValue"]);
680       Assert.AreEqual(1, changedCount);
681
682       o["StringValue"] = "value1";
683       Assert.AreEqual(1, changedCount);
684
685       o["StringValue"] = "value2";
686       Assert.AreEqual("value2", changed);
687       Assert.AreEqual("value2", (string)o["StringValue"]);
688       Assert.AreEqual(2, changedCount);
689
690       o["StringValue"] = null;
691       Assert.AreEqual(null, changed);
692       Assert.AreEqual(null, (string)o["StringValue"]);
693       Assert.AreEqual(3, changedCount);
694
695       o["NullValue"] = null;
696       Assert.AreEqual(null, changed);
697       Assert.AreEqual(new JValue((object)null), o["NullValue"]);
698       Assert.AreEqual(4, changedCount);
699
700       o["NullValue"] = null;
701       Assert.AreEqual(4, changedCount);
702     }
703
704     [Test]
705     public void IListContains()
706     {
707       JProperty p = new JProperty("Test", 1);
708       IList l = new JObject(p);
709
710       Assert.IsTrue(l.Contains(p));
711       Assert.IsFalse(l.Contains(new JProperty("Test", 1)));
712     }
713
714     [Test]
715     public void IListIndexOf()
716     {
717       JProperty p = new JProperty("Test", 1);
718       IList l = new JObject(p);
719
720       Assert.AreEqual(0, l.IndexOf(p));
721       Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1)));
722     }
723
724     [Test]
725     public void IListClear()
726     {
727       JProperty p = new JProperty("Test", 1);
728       IList l = new JObject(p);
729
730       Assert.AreEqual(1, l.Count);
731
732       l.Clear();
733
734       Assert.AreEqual(0, l.Count);
735     }
736
737     [Test]
738     public void IListCopyTo()
739     {
740       JProperty p1 = new JProperty("Test1", 1);
741       JProperty p2 = new JProperty("Test2", "Two");
742       IList l = new JObject(p1, p2);
743
744       object[] a = new object[l.Count];
745
746       l.CopyTo(a, 0);
747
748       Assert.AreEqual(p1, a[0]);
749       Assert.AreEqual(p2, a[1]);
750     }
751
752     [Test]
753     public void IListAdd()
754     {
755       JProperty p1 = new JProperty("Test1", 1);
756       JProperty p2 = new JProperty("Test2", "Two");
757       IList l = new JObject(p1, p2);
758
759       JProperty p3 = new JProperty("Test3", "III");
760
761       l.Add(p3);
762
763       Assert.AreEqual(3, l.Count);
764       Assert.AreEqual(p3, l[2]);
765     }
766
767     [Test]
768     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
769     public void IListAddBadToken()
770     {
771       JProperty p1 = new JProperty("Test1", 1);
772       JProperty p2 = new JProperty("Test2", "Two");
773       IList l = new JObject(p1, p2);
774
775       l.Add(new JValue("Bad!"));
776     }
777
778     [Test]
779     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Argument is not a JToken.")]
780     public void IListAddBadValue()
781     {
782       JProperty p1 = new JProperty("Test1", 1);
783       JProperty p2 = new JProperty("Test2", "Two");
784       IList l = new JObject(p1, p2);
785
786       l.Add("Bad!");
787     }
788
789     [Test]
790     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
791     public void IListAddPropertyWithExistingName()
792     {
793       JProperty p1 = new JProperty("Test1", 1);
794       JProperty p2 = new JProperty("Test2", "Two");
795       IList l = new JObject(p1, p2);
796
797       JProperty p3 = new JProperty("Test2", "II");
798
799       l.Add(p3);
800     }
801
802     [Test]
803     public void IListRemove()
804     {
805       JProperty p1 = new JProperty("Test1", 1);
806       JProperty p2 = new JProperty("Test2", "Two");
807       IList l = new JObject(p1, p2);
808
809       JProperty p3 = new JProperty("Test3", "III");
810
811       // won't do anything
812       l.Remove(p3);
813       Assert.AreEqual(2, l.Count);
814
815       l.Remove(p1);
816       Assert.AreEqual(1, l.Count);
817       Assert.IsFalse(l.Contains(p1));
818       Assert.IsTrue(l.Contains(p2));
819
820       l.Remove(p2);
821       Assert.AreEqual(0, l.Count);
822       Assert.IsFalse(l.Contains(p2));
823       Assert.AreEqual(null, p2.Parent);
824     }
825
826     [Test]
827     public void IListRemoveAt()
828     {
829       JProperty p1 = new JProperty("Test1", 1);
830       JProperty p2 = new JProperty("Test2", "Two");
831       IList l = new JObject(p1, p2);
832
833       // won't do anything
834       l.RemoveAt(0);
835
836       l.Remove(p1);
837       Assert.AreEqual(1, l.Count);
838
839       l.Remove(p2);
840       Assert.AreEqual(0, l.Count);
841     }
842
843     [Test]
844     public void IListInsert()
845     {
846       JProperty p1 = new JProperty("Test1", 1);
847       JProperty p2 = new JProperty("Test2", "Two");
848       IList l = new JObject(p1, p2);
849
850       JProperty p3 = new JProperty("Test3", "III");
851
852       l.Insert(1, p3);
853       Assert.AreEqual(l, p3.Parent);
854
855       Assert.AreEqual(p1, l[0]);
856       Assert.AreEqual(p3, l[1]);
857       Assert.AreEqual(p2, l[2]);
858     }
859
860     [Test]
861     public void IListIsReadOnly()
862     {
863       IList l = new JObject();
864       Assert.IsFalse(l.IsReadOnly);
865     }
866
867     [Test]
868     public void IListIsFixedSize()
869     {
870       IList l = new JObject();
871       Assert.IsFalse(l.IsFixedSize);
872     }
873
874     [Test]
875     public void IListSetItem()
876     {
877       JProperty p1 = new JProperty("Test1", 1);
878       JProperty p2 = new JProperty("Test2", "Two");
879       IList l = new JObject(p1, p2);
880
881       JProperty p3 = new JProperty("Test3", "III");
882
883       l[0] = p3;
884
885       Assert.AreEqual(p3, l[0]);
886       Assert.AreEqual(p2, l[1]);
887     }
888
889     [Test]
890     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
891     public void IListSetItemAlreadyExists()
892     {
893       JProperty p1 = new JProperty("Test1", 1);
894       JProperty p2 = new JProperty("Test2", "Two");
895       IList l = new JObject(p1, p2);
896
897       JProperty p3 = new JProperty("Test3", "III");
898
899       l[0] = p3;
900       l[1] = p3;
901     }
902
903     [Test]
904     [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
905     public void IListSetItemInvalid()
906     {
907       JProperty p1 = new JProperty("Test1", 1);
908       JProperty p2 = new JProperty("Test2", "Two");
909       IList l = new JObject(p1, p2);
910
911       l[0] = new JValue(true);
912     }
913
914     [Test]
915     public void IListSyncRoot()
916     {
917       JProperty p1 = new JProperty("Test1", 1);
918       JProperty p2 = new JProperty("Test2", "Two");
919       IList l = new JObject(p1, p2);
920
921       Assert.IsNotNull(l.SyncRoot);
922     }
923
924     [Test]
925     public void IListIsSynchronized()
926     {
927       JProperty p1 = new JProperty("Test1", 1);
928       JProperty p2 = new JProperty("Test2", "Two");
929       IList l = new JObject(p1, p2);
930
931       Assert.IsFalse(l.IsSynchronized);
932     }
933
934     [Test]
935     public void GenericListJTokenContains()
936     {
937       JProperty p = new JProperty("Test", 1);
938       IList<JToken> l = new JObject(p);
939
940       Assert.IsTrue(l.Contains(p));
941       Assert.IsFalse(l.Contains(new JProperty("Test", 1)));
942     }
943
944     [Test]
945     public void GenericListJTokenIndexOf()
946     {
947       JProperty p = new JProperty("Test", 1);
948       IList<JToken> l = new JObject(p);
949
950       Assert.AreEqual(0, l.IndexOf(p));
951       Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1)));
952     }
953
954     [Test]
955     public void GenericListJTokenClear()
956     {
957       JProperty p = new JProperty("Test", 1);
958       IList<JToken> l = new JObject(p);
959
960       Assert.AreEqual(1, l.Count);
961
962       l.Clear();
963
964       Assert.AreEqual(0, l.Count);
965     }
966
967     [Test]
968     public void GenericListJTokenCopyTo()
969     {
970       JProperty p1 = new JProperty("Test1", 1);
971       JProperty p2 = new JProperty("Test2", "Two");
972       IList<JToken> l = new JObject(p1, p2);
973
974       JToken[] a = new JToken[l.Count];
975
976       l.CopyTo(a, 0);
977
978       Assert.AreEqual(p1, a[0]);
979       Assert.AreEqual(p2, a[1]);
980     }
981
982     [Test]
983     public void GenericListJTokenAdd()
984     {
985       JProperty p1 = new JProperty("Test1", 1);
986       JProperty p2 = new JProperty("Test2", "Two");
987       IList<JToken> l = new JObject(p1, p2);
988
989       JProperty p3 = new JProperty("Test3", "III");
990
991       l.Add(p3);
992
993       Assert.AreEqual(3, l.Count);
994       Assert.AreEqual(p3, l[2]);
995     }
996
997     [Test]
998     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
999     public void GenericListJTokenAddBadToken()
1000     {
1001       JProperty p1 = new JProperty("Test1", 1);
1002       JProperty p2 = new JProperty("Test2", "Two");
1003       IList<JToken> l = new JObject(p1, p2);
1004
1005       l.Add(new JValue("Bad!"));
1006     }
1007
1008     [Test]
1009     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
1010     public void GenericListJTokenAddBadValue()
1011     {
1012       JProperty p1 = new JProperty("Test1", 1);
1013       JProperty p2 = new JProperty("Test2", "Two");
1014       IList<JToken> l = new JObject(p1, p2);
1015
1016       // string is implicitly converted to JValue
1017       l.Add("Bad!");
1018     }
1019
1020     [Test]
1021     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
1022     public void GenericListJTokenAddPropertyWithExistingName()
1023     {
1024       JProperty p1 = new JProperty("Test1", 1);
1025       JProperty p2 = new JProperty("Test2", "Two");
1026       IList<JToken> l = new JObject(p1, p2);
1027
1028       JProperty p3 = new JProperty("Test2", "II");
1029
1030       l.Add(p3);
1031     }
1032
1033     [Test]
1034     public void GenericListJTokenRemove()
1035     {
1036       JProperty p1 = new JProperty("Test1", 1);
1037       JProperty p2 = new JProperty("Test2", "Two");
1038       IList<JToken> l = new JObject(p1, p2);
1039
1040       JProperty p3 = new JProperty("Test3", "III");
1041
1042       // won't do anything
1043       Assert.IsFalse(l.Remove(p3));
1044       Assert.AreEqual(2, l.Count);
1045
1046       Assert.IsTrue(l.Remove(p1));
1047       Assert.AreEqual(1, l.Count);
1048       Assert.IsFalse(l.Contains(p1));
1049       Assert.IsTrue(l.Contains(p2));
1050
1051       Assert.IsTrue(l.Remove(p2));
1052       Assert.AreEqual(0, l.Count);
1053       Assert.IsFalse(l.Contains(p2));
1054       Assert.AreEqual(null, p2.Parent);
1055     }
1056
1057     [Test]
1058     public void GenericListJTokenRemoveAt()
1059     {
1060       JProperty p1 = new JProperty("Test1", 1);
1061       JProperty p2 = new JProperty("Test2", "Two");
1062       IList<JToken> l = new JObject(p1, p2);
1063
1064       // won't do anything
1065       l.RemoveAt(0);
1066
1067       l.Remove(p1);
1068       Assert.AreEqual(1, l.Count);
1069
1070       l.Remove(p2);
1071       Assert.AreEqual(0, l.Count);
1072     }
1073
1074     [Test]
1075     public void GenericListJTokenInsert()
1076     {
1077       JProperty p1 = new JProperty("Test1", 1);
1078       JProperty p2 = new JProperty("Test2", "Two");
1079       IList<JToken> l = new JObject(p1, p2);
1080
1081       JProperty p3 = new JProperty("Test3", "III");
1082
1083       l.Insert(1, p3);
1084       Assert.AreEqual(l, p3.Parent);
1085
1086       Assert.AreEqual(p1, l[0]);
1087       Assert.AreEqual(p3, l[1]);
1088       Assert.AreEqual(p2, l[2]);
1089     }
1090
1091     [Test]
1092     public void GenericListJTokenIsReadOnly()
1093     {
1094       IList<JToken> l = new JObject();
1095       Assert.IsFalse(l.IsReadOnly);
1096     }
1097
1098     [Test]
1099     public void GenericListJTokenSetItem()
1100     {
1101       JProperty p1 = new JProperty("Test1", 1);
1102       JProperty p2 = new JProperty("Test2", "Two");
1103       IList<JToken> l = new JObject(p1, p2);
1104
1105       JProperty p3 = new JProperty("Test3", "III");
1106
1107       l[0] = p3;
1108
1109       Assert.AreEqual(p3, l[0]);
1110       Assert.AreEqual(p2, l[1]);
1111     }
1112
1113     [Test]
1114     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
1115     public void GenericListJTokenSetItemAlreadyExists()
1116     {
1117       JProperty p1 = new JProperty("Test1", 1);
1118       JProperty p2 = new JProperty("Test2", "Two");
1119       IList<JToken> l = new JObject(p1, p2);
1120
1121       JProperty p3 = new JProperty("Test3", "III");
1122
1123       l[0] = p3;
1124       l[1] = p3;
1125     }
1126
1127 #if !SILVERLIGHT
1128     [Test]
1129     public void IBindingListSortDirection()
1130     {
1131       IBindingList l = new JObject();
1132       Assert.AreEqual(ListSortDirection.Ascending, l.SortDirection);
1133     }
1134
1135     [Test]
1136     public void IBindingListSortProperty()
1137     {
1138       IBindingList l = new JObject();
1139       Assert.AreEqual(null, l.SortProperty);
1140     }
1141
1142     [Test]
1143     public void IBindingListSupportsChangeNotification()
1144     {
1145       IBindingList l = new JObject();
1146       Assert.AreEqual(true, l.SupportsChangeNotification);
1147     }
1148
1149     [Test]
1150     public void IBindingListSupportsSearching()
1151     {
1152       IBindingList l = new JObject();
1153       Assert.AreEqual(false, l.SupportsSearching);
1154     }
1155
1156     [Test]
1157     public void IBindingListSupportsSorting()
1158     {
1159       IBindingList l = new JObject();
1160       Assert.AreEqual(false, l.SupportsSorting);
1161     }
1162
1163     [Test]
1164     public void IBindingListAllowEdit()
1165     {
1166       IBindingList l = new JObject();
1167       Assert.AreEqual(true, l.AllowEdit);
1168     }
1169
1170     [Test]
1171     public void IBindingListAllowNew()
1172     {
1173       IBindingList l = new JObject();
1174       Assert.AreEqual(true, l.AllowNew);
1175     }
1176
1177     [Test]
1178     public void IBindingListAllowRemove()
1179     {
1180       IBindingList l = new JObject();
1181       Assert.AreEqual(true, l.AllowRemove);
1182     }
1183
1184     [Test]
1185     public void IBindingListAddIndex()
1186     {
1187       IBindingList l = new JObject();
1188       // do nothing
1189       l.AddIndex(null);
1190     }
1191
1192     [Test]
1193     [ExpectedException(typeof(NotSupportedException))]
1194     public void IBindingListApplySort()
1195     {
1196       IBindingList l = new JObject();
1197       l.ApplySort(null, ListSortDirection.Ascending);
1198     }
1199
1200     [Test]
1201     [ExpectedException(typeof(NotSupportedException))]
1202     public void IBindingListRemoveSort()
1203     {
1204       IBindingList l = new JObject();
1205       l.RemoveSort();
1206     }
1207
1208     [Test]
1209     public void IBindingListRemoveIndex()
1210     {
1211       IBindingList l = new JObject();
1212       // do nothing
1213       l.RemoveIndex(null);
1214     }
1215
1216     [Test]
1217     [ExpectedException(typeof(NotSupportedException))]
1218     public void IBindingListFind()
1219     {
1220       IBindingList l = new JObject();
1221       l.Find(null, null);
1222     }
1223
1224     [Test]
1225     public void IBindingListIsSorted()
1226     {
1227       IBindingList l = new JObject();
1228       Assert.AreEqual(false, l.IsSorted);
1229     }
1230
1231     [Test]
1232     [ExpectedException(typeof(Exception), ExpectedMessage = "Could not determine new value to add to 'Newtonsoft.Json.Linq.JObject'.")]
1233     public void IBindingListAddNew()
1234     {
1235       IBindingList l = new JObject();
1236       l.AddNew();
1237     }
1238
1239     [Test]
1240     public void IBindingListAddNewWithEvent()
1241     {
1242       JObject o = new JObject();
1243       o.AddingNew += (s, e) => e.NewObject = new JProperty("Property!");
1244
1245       IBindingList l = o;
1246       object newObject = l.AddNew();
1247       Assert.IsNotNull(newObject);
1248
1249       JProperty p = (JProperty) newObject;
1250       Assert.AreEqual("Property!", p.Name);
1251       Assert.AreEqual(o, p.Parent);
1252     }
1253
1254     [Test]
1255     public void ITypedListGetListName()
1256     {
1257       JProperty p1 = new JProperty("Test1", 1);
1258       JProperty p2 = new JProperty("Test2", "Two");
1259       ITypedList l = new JObject(p1, p2);
1260
1261       Assert.AreEqual(string.Empty, l.GetListName(null));
1262     }
1263
1264     [Test]
1265     public void ITypedListGetItemProperties()
1266     {
1267       JProperty p1 = new JProperty("Test1", 1);
1268       JProperty p2 = new JProperty("Test2", "Two");
1269       ITypedList l = new JObject(p1, p2);
1270
1271       PropertyDescriptorCollection propertyDescriptors = l.GetItemProperties(null);
1272       Assert.IsNull(propertyDescriptors);
1273     }
1274
1275     [Test]
1276     public void ListChanged()
1277     {
1278       JProperty p1 = new JProperty("Test1", 1);
1279       JProperty p2 = new JProperty("Test2", "Two");
1280       JObject o = new JObject(p1, p2);
1281
1282       ListChangedType? changedType = null;
1283       int? index = null;
1284       
1285       o.ListChanged += (s, a) =>
1286         {
1287           changedType = a.ListChangedType;
1288           index = a.NewIndex;
1289         };
1290
1291       JProperty p3 = new JProperty("Test3", "III");
1292
1293       o.Add(p3);
1294       Assert.AreEqual(changedType, ListChangedType.ItemAdded);
1295       Assert.AreEqual(index, 2);
1296       Assert.AreEqual(p3, ((IList<JToken>)o)[index.Value]);
1297
1298       JProperty p4 = new JProperty("Test4", "IV");
1299
1300       ((IList<JToken>) o)[index.Value] = p4;
1301       Assert.AreEqual(changedType, ListChangedType.ItemChanged);
1302       Assert.AreEqual(index, 2);
1303       Assert.AreEqual(p4, ((IList<JToken>)o)[index.Value]);
1304       Assert.IsFalse(((IList<JToken>)o).Contains(p3));
1305       Assert.IsTrue(((IList<JToken>)o).Contains(p4));
1306
1307       o["Test1"] = 2;
1308       Assert.AreEqual(changedType, ListChangedType.ItemChanged);
1309       Assert.AreEqual(index, 0);
1310       Assert.AreEqual(2, (int)o["Test1"]);
1311     }
1312 #endif
1313 #if SILVERLIGHT || !(NET20 || NET35)
1314     [Test]
1315     public void CollectionChanged()
1316     {
1317       JProperty p1 = new JProperty("Test1", 1);
1318       JProperty p2 = new JProperty("Test2", "Two");
1319       JObject o = new JObject(p1, p2);
1320
1321       NotifyCollectionChangedAction? changedType = null;
1322       int? index = null;
1323
1324       o.CollectionChanged += (s, a) =>
1325       {
1326         changedType = a.Action;
1327         index = a.NewStartingIndex;
1328       };
1329
1330       JProperty p3 = new JProperty("Test3", "III");
1331
1332       o.Add(p3);
1333       Assert.AreEqual(changedType, NotifyCollectionChangedAction.Add);
1334       Assert.AreEqual(index, 2);
1335       Assert.AreEqual(p3, ((IList<JToken>)o)[index.Value]);
1336
1337       JProperty p4 = new JProperty("Test4", "IV");
1338
1339       ((IList<JToken>)o)[index.Value] = p4;
1340       Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace);
1341       Assert.AreEqual(index, 2);
1342       Assert.AreEqual(p4, ((IList<JToken>)o)[index.Value]);
1343       Assert.IsFalse(((IList<JToken>)o).Contains(p3));
1344       Assert.IsTrue(((IList<JToken>)o).Contains(p4));
1345
1346       o["Test1"] = 2;
1347       Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace);
1348       Assert.AreEqual(index, 0);
1349       Assert.AreEqual(2, (int)o["Test1"]);
1350     }
1351 #endif
1352
1353     [Test]
1354     public void GetGeocodeAddress()
1355     {
1356       string json = @"{
1357   ""name"": ""Address: 435 North Mulford Road Rockford, IL 61107"",
1358   ""Status"": {
1359     ""code"": 200,
1360     ""request"": ""geocode""
1361   },
1362   ""Placemark"": [ {
1363     ""id"": ""p1"",
1364     ""address"": ""435 N Mulford Rd, Rockford, IL 61107, USA"",
1365     ""AddressDetails"": {
1366    ""Accuracy"" : 8,
1367    ""Country"" : {
1368       ""AdministrativeArea"" : {
1369          ""AdministrativeAreaName"" : ""IL"",
1370          ""SubAdministrativeArea"" : {
1371             ""Locality"" : {
1372                ""LocalityName"" : ""Rockford"",
1373                ""PostalCode"" : {
1374                   ""PostalCodeNumber"" : ""61107""
1375                },
1376                ""Thoroughfare"" : {
1377                   ""ThoroughfareName"" : ""435 N Mulford Rd""
1378                }
1379             },
1380             ""SubAdministrativeAreaName"" : ""Winnebago""
1381          }
1382       },
1383       ""CountryName"" : ""USA"",
1384       ""CountryNameCode"" : ""US""
1385    }
1386 },
1387     ""ExtendedData"": {
1388       ""LatLonBox"": {
1389         ""north"": 42.2753076,
1390         ""south"": 42.2690124,
1391         ""east"": -88.9964645,
1392         ""west"": -89.0027597
1393       }
1394     },
1395     ""Point"": {
1396       ""coordinates"": [ -88.9995886, 42.2721596, 0 ]
1397     }
1398   } ]
1399 }";
1400
1401       JObject o = JObject.Parse(json);
1402
1403       string searchAddress = (string)o["Placemark"][0]["AddressDetails"]["Country"]["AdministrativeArea"]["SubAdministrativeArea"]["Locality"]["Thoroughfare"]["ThoroughfareName"];
1404       Assert.AreEqual("435 N Mulford Rd", searchAddress);
1405     }
1406
1407     [Test]
1408     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Set JObject values with invalid key value: 0. Object property name expected.")]
1409     public void SetValueWithInvalidPropertyName()
1410     {
1411       JObject o = new JObject();
1412       o[0] = new JValue(3);
1413     }
1414
1415     [Test]
1416     public void SetValue()
1417     {
1418       object key = "TestKey";
1419
1420       JObject o = new JObject();
1421       o[key] = new JValue(3);
1422
1423       Assert.AreEqual(3, (int)o[key]);
1424     }
1425
1426     [Test]
1427     public void ParseMultipleProperties()
1428     {
1429       string json = @"{
1430         ""Name"": ""Name1"",
1431         ""Name"": ""Name2""
1432       }";
1433
1434       JObject o = JObject.Parse(json);
1435       string value = (string)o["Name"];
1436
1437       Assert.AreEqual("Name2", value);
1438     }
1439
1440     [Test]
1441     public void WriteObjectNullDBNullValue()
1442     {
1443       DBNull dbNull = DBNull.Value;
1444       JValue v = new JValue(dbNull);
1445       Assert.AreEqual(DBNull.Value, v.Value);
1446       Assert.AreEqual(JTokenType.Null, v.Type);
1447
1448       JObject o = new JObject();
1449       o["title"] = v;
1450
1451       string output = o.ToString();
1452       
1453       Assert.AreEqual(@"{
1454   ""title"": null
1455 }", output);
1456     }
1457
1458     [Test]
1459     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not convert Object to String.")]
1460     public void InvalidValueCastExceptionMessage()
1461     {
1462       string json = @"{
1463   ""responseData"": {}, 
1464   ""responseDetails"": null, 
1465   ""responseStatus"": 200
1466 }";
1467
1468       JObject o = JObject.Parse(json);
1469
1470       string name = (string)o["responseData"];
1471     }
1472
1473     [Test]
1474     [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not convert Object to String.")]
1475     public void InvalidPropertyValueCastExceptionMessage()
1476     {
1477       string json = @"{
1478   ""responseData"": {}, 
1479   ""responseDetails"": null, 
1480   ""responseStatus"": 200
1481 }";
1482
1483       JObject o = JObject.Parse(json);
1484
1485       string name = (string)o.Property("responseData");
1486     }
1487
1488     [Test]
1489     [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "JSON integer 307953220000517141511 is too large or small for an Int64.")]
1490     public void NumberTooBigForInt64()
1491     {
1492       string json = @"{""code"": 307953220000517141511}";
1493
1494       JObject.Parse(json);
1495     }
1496
1497     [Test]
1498     [ExpectedException(typeof(Exception), ExpectedMessage = "Unexpected end of content while loading JObject.")]
1499     public void ParseIncomplete()
1500     {
1501       JObject.Parse("{ foo:");
1502     }
1503
1504     [Test]
1505     public void LoadFromNestedObject()
1506     {
1507       string jsonText = @"{
1508   ""short"":
1509   {
1510     ""error"":
1511     {
1512       ""code"":0,
1513       ""msg"":""No action taken""
1514     }
1515   }
1516 }";
1517
1518       JsonReader reader = new JsonTextReader(new StringReader(jsonText));
1519       reader.Read();
1520       reader.Read();
1521       reader.Read();
1522       reader.Read();
1523       reader.Read();
1524
1525       JObject o = (JObject)JToken.ReadFrom(reader);
1526       Assert.IsNotNull(o);
1527       Assert.AreEqual(@"{
1528   ""code"": 0,
1529   ""msg"": ""No action taken""
1530 }", o.ToString(Formatting.Indented));
1531     }
1532
1533     [Test]
1534     [ExpectedException(typeof(Exception), ExpectedMessage = "Unexpected end of content while loading JObject.")]
1535     public void LoadFromNestedObjectIncomplete()
1536     {
1537       string jsonText = @"{
1538   ""short"":
1539   {
1540     ""error"":
1541     {
1542       ""code"":0";
1543
1544       JsonReader reader = new JsonTextReader(new StringReader(jsonText));
1545       reader.Read();
1546       reader.Read();
1547       reader.Read();
1548       reader.Read();
1549       reader.Read();
1550
1551       JToken.ReadFrom(reader);
1552     }
1553
1554 #if !SILVERLIGHT
1555     [Test]
1556     public void GetProperties()
1557     {
1558       JObject o = JObject.Parse("{'prop1':12,'prop2':'hi!','prop3':null,'prop4':[1,2,3]}");
1559
1560       ICustomTypeDescriptor descriptor = o;
1561
1562       PropertyDescriptorCollection properties = descriptor.GetProperties();
1563       Assert.AreEqual(4, properties.Count);
1564
1565       PropertyDescriptor prop1 = properties[0];
1566       Assert.AreEqual("prop1", prop1.Name);
1567       Assert.AreEqual(typeof(long), prop1.PropertyType);
1568       Assert.AreEqual(typeof(JObject), prop1.ComponentType);
1569       Assert.AreEqual(false, prop1.CanResetValue(o));
1570       Assert.AreEqual(false, prop1.ShouldSerializeValue(o));
1571
1572       PropertyDescriptor prop2 = properties[1];
1573       Assert.AreEqual("prop2", prop2.Name);
1574       Assert.AreEqual(typeof(string), prop2.PropertyType);
1575       Assert.AreEqual(typeof(JObject), prop2.ComponentType);
1576       Assert.AreEqual(false, prop2.CanResetValue(o));
1577       Assert.AreEqual(false, prop2.ShouldSerializeValue(o));
1578
1579       PropertyDescriptor prop3 = properties[2];
1580       Assert.AreEqual("prop3", prop3.Name);
1581       Assert.AreEqual(typeof(object), prop3.PropertyType);
1582       Assert.AreEqual(typeof(JObject), prop3.ComponentType);
1583       Assert.AreEqual(false, prop3.CanResetValue(o));
1584       Assert.AreEqual(false, prop3.ShouldSerializeValue(o));
1585
1586       PropertyDescriptor prop4 = properties[3];
1587       Assert.AreEqual("prop4", prop4.Name);
1588       Assert.AreEqual(typeof(JArray), prop4.PropertyType);
1589       Assert.AreEqual(typeof(JObject), prop4.ComponentType);
1590       Assert.AreEqual(false, prop4.CanResetValue(o));
1591       Assert.AreEqual(false, prop4.ShouldSerializeValue(o));
1592     }
1593 #endif
1594   }
1595 }