2 // Copyright (c) 2007 James Newton-King
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
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
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.
27 using System.Collections.Generic;
30 using Newtonsoft.Json.Converters;
31 using NUnit.Framework;
32 using Newtonsoft.Json.Linq;
35 namespace Newtonsoft.Json.Tests.Linq
37 public class JTokenTests : TestFixtureBase
40 public void ReadFrom()
42 JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(new StringReader("{'pie':true}")));
43 Assert.AreEqual(true, (bool)o["pie"]);
45 JArray a = (JArray)JToken.ReadFrom(new JsonTextReader(new StringReader("[1,2,3]")));
46 Assert.AreEqual(1, (int)a[0]);
47 Assert.AreEqual(2, (int)a[1]);
48 Assert.AreEqual(3, (int)a[2]);
50 JsonReader reader = new JsonTextReader(new StringReader("{'pie':true}"));
54 JProperty p = (JProperty)JToken.ReadFrom(reader);
55 Assert.AreEqual("pie", p.Name);
56 Assert.AreEqual(true, (bool)p.Value);
58 JConstructor c = (JConstructor)JToken.ReadFrom(new JsonTextReader(new StringReader("new Date(1)")));
59 Assert.AreEqual("Date", c.Name);
60 Assert.IsTrue(JToken.DeepEquals(new JValue(1), c.Values().ElementAt(0)));
64 v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"""stringvalue""")));
65 Assert.AreEqual("stringvalue", (string)v);
67 v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"1")));
68 Assert.AreEqual(1, (int)v);
70 v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"1.1")));
71 Assert.AreEqual(1.1, (double)v);
77 JObject o = (JObject)JToken.Load(new JsonTextReader(new StringReader("{'pie':true}")));
78 Assert.AreEqual(true, (bool)o["pie"]);
84 JObject o = (JObject)JToken.Parse("{'pie':true}");
85 Assert.AreEqual(true, (bool)o["pie"]);
91 JArray v = new JArray(new JConstructor("TestConstructor"), new JValue(new DateTime(2000, 12, 20)));
93 Assert.AreEqual(null, v.Parent);
97 new JProperty("Test1", v),
98 new JProperty("Test2", "Test2Value"),
99 new JProperty("Test3", "Test3Value"),
100 new JProperty("Test4", null)
103 Assert.AreEqual(o.Property("Test1"), v.Parent);
105 JProperty p = new JProperty("NewProperty", v);
107 // existing value should still have same parent
108 Assert.AreEqual(o.Property("Test1"), v.Parent);
110 // new value should be cloned
111 Assert.AreNotSame(p.Value, v);
113 Assert.AreEqual((DateTime)((JValue)p.Value[1]).Value, (DateTime)((JValue)v[1]).Value);
115 Assert.AreEqual(v, o["Test1"]);
117 Assert.AreEqual(null, o.Parent);
118 JProperty o1 = new JProperty("O1", o);
119 Assert.AreEqual(o, o1.Value);
121 Assert.AreNotEqual(null, o.Parent);
122 JProperty o2 = new JProperty("O2", o);
124 Assert.AreNotSame(o1.Value, o2.Value);
125 Assert.AreEqual(o1.Value.Children().Count(), o2.Value.Children().Count());
126 Assert.AreEqual(false, JToken.DeepEquals(o1, o2));
127 Assert.AreEqual(true, JToken.DeepEquals(o1.Value, o2.Value));
141 JToken next = a[0].Next;
142 Assert.AreEqual(6, (int)next);
145 Assert.IsTrue(JToken.DeepEquals(new JArray(7, 8), next));
148 Assert.IsTrue(JToken.DeepEquals(new JArray(9, 10), next));
155 public void Previous()
165 JToken previous = a[3].Previous;
166 Assert.IsTrue(JToken.DeepEquals(new JArray(7, 8), previous));
168 previous = previous.Previous;
169 Assert.AreEqual(6, (int)previous);
171 previous = previous.Previous;
172 Assert.AreEqual(5, (int)previous);
174 previous = previous.Previous;
175 Assert.IsNull(previous);
179 public void Children()
189 Assert.AreEqual(4, a.Count());
190 Assert.AreEqual(3, a.Children<JArray>().Count());
194 public void BeforeAfter()
204 Assert.AreEqual(5, (int)a[1].Previous);
205 Assert.AreEqual(2, a[2].BeforeSelf().Count());
206 //Assert.AreEqual(2, a[2].AfterSelf().Count());
210 public void Casting()
212 Assert.AreEqual(new DateTime(2000, 12, 20), (DateTime)new JValue(new DateTime(2000, 12, 20)));
213 #if !PocketPC && !NET20
214 Assert.AreEqual(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero), (DateTimeOffset)new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)));
215 Assert.AreEqual(null, (DateTimeOffset?)new JValue((DateTimeOffset?)null));
216 Assert.AreEqual(null, (DateTimeOffset?)(JValue)null);
218 Assert.AreEqual(true, (bool)new JValue(true));
219 Assert.AreEqual(true, (bool?)new JValue(true));
220 Assert.AreEqual(null, (bool?)((JValue)null));
221 Assert.AreEqual(null, (bool?)new JValue((object)null));
222 Assert.AreEqual(10, (long)new JValue(10));
223 Assert.AreEqual(null, (long?)new JValue((long?)null));
224 Assert.AreEqual(null, (long?)(JValue)null);
225 Assert.AreEqual(null, (int?)new JValue((int?)null));
226 Assert.AreEqual(null, (int?)(JValue)null);
227 Assert.AreEqual(null, (DateTime?)new JValue((DateTime?)null));
228 Assert.AreEqual(null, (DateTime?)(JValue)null);
229 Assert.AreEqual(null, (short?)new JValue((short?)null));
230 Assert.AreEqual(null, (short?)(JValue)null);
231 Assert.AreEqual(null, (float?)new JValue((float?)null));
232 Assert.AreEqual(null, (float?)(JValue)null);
233 Assert.AreEqual(null, (double?)new JValue((double?)null));
234 Assert.AreEqual(null, (double?)(JValue)null);
235 Assert.AreEqual(null, (decimal?)new JValue((decimal?)null));
236 Assert.AreEqual(null, (decimal?)(JValue)null);
237 Assert.AreEqual(null, (uint?)new JValue((uint?)null));
238 Assert.AreEqual(null, (uint?)(JValue)null);
239 Assert.AreEqual(null, (sbyte?)new JValue((sbyte?)null));
240 Assert.AreEqual(null, (sbyte?)(JValue)null);
241 Assert.AreEqual(null, (ulong?)new JValue((ulong?)null));
242 Assert.AreEqual(null, (ulong?)(JValue)null);
243 Assert.AreEqual(null, (uint?)new JValue((uint?)null));
244 Assert.AreEqual(null, (uint?)(JValue)null);
245 Assert.AreEqual(11.1f, (float)new JValue(11.1));
246 Assert.AreEqual(float.MinValue, (float)new JValue(float.MinValue));
247 Assert.AreEqual(1.1, (double)new JValue(1.1));
248 Assert.AreEqual(uint.MaxValue, (uint)new JValue(uint.MaxValue));
249 Assert.AreEqual(ulong.MaxValue, (ulong)new JValue(ulong.MaxValue));
250 Assert.AreEqual(ulong.MaxValue, (ulong)new JProperty("Test", new JValue(ulong.MaxValue)));
251 Assert.AreEqual(null, (string)new JValue((string)null));
252 Assert.AreEqual(5m, (decimal)(new JValue(5L)));
253 Assert.AreEqual(5m, (decimal?)(new JValue(5L)));
254 Assert.AreEqual(5f, (float)(new JValue(5L)));
255 Assert.AreEqual(5f, (float)(new JValue(5m)));
256 Assert.AreEqual(5f, (float?)(new JValue(5m)));
258 byte[] data = new byte[0];
259 Assert.AreEqual(data, (byte[])(new JValue(data)));
261 Assert.AreEqual(5, (int)(new JValue(StringComparison.OrdinalIgnoreCase)));
265 public void ImplicitCastingTo()
267 Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTime(2000, 12, 20)), (JValue)new DateTime(2000, 12, 20)));
268 #if !PocketPC && !NET20
269 Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)), (JValue)new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)));
270 Assert.IsTrue(JToken.DeepEquals(new JValue((DateTimeOffset?)null), (JValue)(DateTimeOffset?)null));
273 Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)true));
274 Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)(bool?)true));
275 Assert.IsTrue(JToken.DeepEquals(new JValue((bool?)null), (JValue)(bool?)null));
276 Assert.IsTrue(JToken.DeepEquals(new JValue(10), (JValue)10));
277 Assert.IsTrue(JToken.DeepEquals(new JValue((long?)null), (JValue)(long?)null));
278 Assert.IsTrue(JToken.DeepEquals(new JValue((DateTime?)null), (JValue)(DateTime?)null));
279 Assert.IsTrue(JToken.DeepEquals(new JValue(long.MaxValue), (JValue)long.MaxValue));
280 Assert.IsTrue(JToken.DeepEquals(new JValue((int?)null), (JValue)(int?)null));
281 Assert.IsTrue(JToken.DeepEquals(new JValue((short?)null), (JValue)(short?)null));
282 Assert.IsTrue(JToken.DeepEquals(new JValue((double?)null), (JValue)(double?)null));
283 Assert.IsTrue(JToken.DeepEquals(new JValue((uint?)null), (JValue)(uint?)null));
284 Assert.IsTrue(JToken.DeepEquals(new JValue((decimal?)null), (JValue)(decimal?)null));
285 Assert.IsTrue(JToken.DeepEquals(new JValue((ulong?)null), (JValue)(ulong?)null));
286 Assert.IsTrue(JToken.DeepEquals(new JValue((sbyte?)null), (JValue)(sbyte?)null));
287 Assert.IsTrue(JToken.DeepEquals(new JValue((ushort?)null), (JValue)(ushort?)null));
288 Assert.IsTrue(JToken.DeepEquals(new JValue(ushort.MaxValue), (JValue)ushort.MaxValue));
289 Assert.IsTrue(JToken.DeepEquals(new JValue(11.1f), (JValue)11.1f));
290 Assert.IsTrue(JToken.DeepEquals(new JValue(float.MinValue), (JValue)float.MinValue));
291 Assert.IsTrue(JToken.DeepEquals(new JValue(double.MinValue), (JValue)double.MinValue));
292 Assert.IsTrue(JToken.DeepEquals(new JValue(uint.MaxValue), (JValue)uint.MaxValue));
293 Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MaxValue), (JValue)ulong.MaxValue));
294 Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MinValue), (JValue)ulong.MinValue));
295 Assert.IsTrue(JToken.DeepEquals(new JValue((string)null), (JValue)(string)null));
296 Assert.IsTrue(JToken.DeepEquals(new JValue((DateTime?)null), (JValue)(DateTime?)null));
297 Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MaxValue), (JValue)decimal.MaxValue));
298 Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MaxValue), (JValue)(decimal?)decimal.MaxValue));
299 Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MinValue), (JValue)decimal.MinValue));
300 Assert.IsTrue(JToken.DeepEquals(new JValue(float.MaxValue), (JValue)(float?)float.MaxValue));
301 Assert.IsTrue(JToken.DeepEquals(new JValue(double.MaxValue), (JValue)(double?)double.MaxValue));
302 Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(double?)null));
304 Assert.IsFalse(JToken.DeepEquals(new JValue(true), (JValue)(bool?)null));
305 Assert.IsFalse(JToken.DeepEquals(new JValue((object)null), (JValue)(object)null));
307 byte[] emptyData = new byte[0];
308 Assert.IsTrue(JToken.DeepEquals(new JValue(emptyData), (JValue)emptyData));
309 Assert.IsFalse(JToken.DeepEquals(new JValue(emptyData), (JValue)new byte[1]));
310 Assert.IsTrue(JToken.DeepEquals(new JValue(Encoding.UTF8.GetBytes("Hi")), (JValue)Encoding.UTF8.GetBytes("Hi")));
324 Assert.AreEqual(a, a.Root);
325 Assert.AreEqual(a, a[0].Root);
326 Assert.AreEqual(a, ((JArray)a[2])[0].Root);
343 Assert.AreEqual(6, (int)a[0]);
347 Assert.AreEqual(6, (int)a[0]);
348 Assert.IsTrue(JToken.DeepEquals(new JArray(9, 10), a[1]));
349 Assert.AreEqual(2, a.Count());
353 Assert.AreEqual(6, (int)a[0]);
354 Assert.IsNull(t.Next);
355 Assert.IsNull(t.Previous);
356 Assert.IsNull(t.Parent);
360 Assert.AreEqual(0, a.Count());
362 Assert.IsNull(t.Next);
363 Assert.IsNull(t.Previous);
364 Assert.IsNull(t.Parent);
368 public void AfterSelf()
379 List<JToken> afterTokens = t.AfterSelf().ToList();
381 Assert.AreEqual(2, afterTokens.Count);
382 Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2), afterTokens[0]));
383 Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), afterTokens[1]));
387 public void BeforeSelf()
398 List<JToken> beforeTokens = t.BeforeSelf().ToList();
400 Assert.AreEqual(2, beforeTokens.Count);
401 Assert.IsTrue(JToken.DeepEquals(new JValue(5), beforeTokens[0]));
402 Assert.IsTrue(JToken.DeepEquals(new JArray(1), beforeTokens[1]));
406 public void HasValues()
416 Assert.IsTrue(a.HasValues);
420 public void Ancestors()
431 List<JToken> ancestors = t.Ancestors().ToList();
432 Assert.AreEqual(2, ancestors.Count());
433 Assert.AreEqual(a[1], ancestors[0]);
434 Assert.AreEqual(a, ancestors[1]);
438 public void Descendants()
448 List<JToken> descendants = a.Descendants().ToList();
449 Assert.AreEqual(10, descendants.Count());
450 Assert.AreEqual(5, (int)descendants[0]);
451 Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), descendants[descendants.Count - 4]));
452 Assert.AreEqual(1, (int)descendants[descendants.Count - 3]);
453 Assert.AreEqual(2, (int)descendants[descendants.Count - 2]);
454 Assert.AreEqual(3, (int)descendants[descendants.Count - 1]);
458 public void CreateWriter()
468 JsonWriter writer = a.CreateWriter();
469 Assert.IsNotNull(writer);
470 Assert.AreEqual(4, a.Count());
472 writer.WriteValue("String");
473 Assert.AreEqual(5, a.Count());
474 Assert.AreEqual("String", (string)a[4]);
476 writer.WriteStartObject();
477 writer.WritePropertyName("Property");
478 writer.WriteValue("PropertyValue");
481 Assert.AreEqual(6, a.Count());
482 Assert.IsTrue(JToken.DeepEquals(new JObject(new JProperty("Property", "PropertyValue")), a[5]));
486 public void AddFirst()
498 Assert.AreEqual("First", (string)a[0]);
499 Assert.AreEqual(a, a[0].Parent);
500 Assert.AreEqual(a[1], a[0].Next);
501 Assert.AreEqual(5, a.Count());
503 a.AddFirst("NewFirst");
504 Assert.AreEqual("NewFirst", (string)a[0]);
505 Assert.AreEqual(a, a[0].Parent);
506 Assert.AreEqual(a[1], a[0].Next);
507 Assert.AreEqual(6, a.Count());
509 Assert.AreEqual(a[0], a[0].Next.Previous);
513 public void RemoveAll()
523 JToken first = a.First;
524 Assert.AreEqual(5, (int)first);
527 Assert.AreEqual(0, a.Count());
529 Assert.IsNull(first.Parent);
530 Assert.IsNull(first.Next);
534 [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JArray.")]
535 public void AddPropertyToArray()
537 JArray a = new JArray();
538 a.Add(new JProperty("PropertyName"));
542 [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
543 public void AddValueToObject()
545 JObject o = new JObject();
550 public void Replace()
560 a[0].Replace(new JValue(int.MaxValue));
561 Assert.AreEqual(int.MaxValue, (int)a[0]);
562 Assert.AreEqual(4, a.Count());
564 a[1][0].Replace(new JValue("Test"));
565 Assert.AreEqual("Test", (string)a[1][0]);
567 a[2].Replace(new JValue(int.MaxValue));
568 Assert.AreEqual(int.MaxValue, (int)a[2]);
569 Assert.AreEqual(4, a.Count());
571 Assert.IsTrue(JToken.DeepEquals(new JArray(int.MaxValue, new JArray("Test"), int.MaxValue, new JArray(1, 2, 3)), a));
575 public void ToStringWithConverters()
579 new JValue(new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc))
582 string json = a.ToString(Formatting.Indented, new IsoDateTimeConverter());
585 ""2009-02-15T00:00:00Z""
588 json = JsonConvert.SerializeObject(a, new IsoDateTimeConverter());
590 Assert.AreEqual(@"[""2009-02-15T00:00:00Z""]", json);
594 public void ToStringWithNoIndenting()
598 new JValue(new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc))
601 string json = a.ToString(Formatting.None, new IsoDateTimeConverter());
603 Assert.AreEqual(@"[""2009-02-15T00:00:00Z""]", json);
607 public void AddAfterSelf()
617 a[1].AddAfterSelf("pie");
619 Assert.AreEqual(5, (int)a[0]);
620 Assert.AreEqual(1, a[1].Count());
621 Assert.AreEqual("pie", (string)a[2]);
622 Assert.AreEqual(5, a.Count());
624 a[4].AddAfterSelf("lastpie");
626 Assert.AreEqual("lastpie", (string)a[5]);
627 Assert.AreEqual("lastpie", (string)a.Last);
631 public void AddBeforeSelf()
641 a[1].AddBeforeSelf("pie");
643 Assert.AreEqual(5, (int)a[0]);
644 Assert.AreEqual("pie", (string)a[1]);
645 Assert.AreEqual(a, a[1].Parent);
646 Assert.AreEqual(a[2], a[1].Next);
647 Assert.AreEqual(5, a.Count());
649 a[0].AddBeforeSelf("firstpie");
651 Assert.AreEqual("firstpie", (string)a[0]);
652 Assert.AreEqual(5, (int)a[1]);
653 Assert.AreEqual("pie", (string)a[2]);
654 Assert.AreEqual(a, a[0].Parent);
655 Assert.AreEqual(a[1], a[0].Next);
656 Assert.AreEqual(6, a.Count());
658 a.Last.AddBeforeSelf("secondlastpie");
660 Assert.AreEqual("secondlastpie", (string)a[5]);
661 Assert.AreEqual(7, a.Count());
665 public void DeepClone()
674 new JProperty("First", new JValue(Encoding.UTF8.GetBytes("Hi"))),
675 new JProperty("Second", 1),
676 new JProperty("Third", null),
677 new JProperty("Fourth", new JConstructor("Date", 12345)),
678 new JProperty("Fifth", double.PositiveInfinity),
679 new JProperty("Sixth", double.NaN)
683 JArray a2 = (JArray)a.DeepClone();
685 Console.WriteLine(a2.ToString(Formatting.Indented));
687 Assert.IsTrue(a.DeepEquals(a2));
701 new JProperty("First", new JValue(Encoding.UTF8.GetBytes("Hi"))),
702 new JProperty("Second", 1),
703 new JProperty("Third", null),
704 new JProperty("Fourth", new JConstructor("Date", 12345)),
705 new JProperty("Fifth", double.PositiveInfinity),
706 new JProperty("Sixth", double.NaN)
712 JArray a2 = (JArray) c.Clone();
714 Assert.IsTrue(a.DeepEquals(a2));
719 public void DoubleDeepEquals()
724 double.PositiveInfinity,
725 double.NegativeInfinity
728 JArray a2 = (JArray)a.DeepClone();
730 Assert.IsTrue(a.DeepEquals(a2));
732 double d = 1 + 0.1 + 0.1 + 0.1;
734 JValue v1 = new JValue(d);
735 JValue v2 = new JValue(1.3);
737 Assert.IsTrue(v1.DeepEquals(v2));