#region License // Copyright (c) 2007 James Newton-King // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. #endregion using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; #if !(NET20 || NET35 || PORTABLE) using System.Numerics; #endif using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Tests.TestObjects; using Newtonsoft.Json.Tests.TestObjects.Organization; #if DNXCORE50 using Xunit; using Test = Xunit.FactAttribute; using Assert = Newtonsoft.Json.Tests.XUnitAssert; #else using NUnit.Framework; #endif using Newtonsoft.Json.Linq; using System.IO; using System.Collections; #if !(DNXCORE50) using System.Web.UI; #endif #if NET20 using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; #endif using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Linq { [TestFixture] public class JObjectTests : TestFixtureBase { #if !(NET35 || NET20 || PORTABLE40) [Test] public void EmbedJValueStringInNewJObject() { string s = null; var v = new JValue(s); dynamic o = JObject.FromObject(new { title = v }); string output = o.ToString(); StringAssert.AreEqual(@"{ ""title"": null }", output); Assert.AreEqual(null, v.Value); Assert.IsNull((string)o.title); } #endif [Test] public void ReadWithSupportMultipleContent() { string json = @"{ 'name': 'Admin' }{ 'name': 'Publisher' }"; IList roles = new List(); JsonTextReader reader = new JsonTextReader(new StringReader(json)); reader.SupportMultipleContent = true; while (true) { JObject role = (JObject)JToken.ReadFrom(reader); roles.Add(role); if (!reader.Read()) { break; } } Assert.AreEqual(2, roles.Count); Assert.AreEqual("Admin", (string)roles[0]["name"]); Assert.AreEqual("Publisher", (string)roles[1]["name"]); } [Test] public void JObjectWithComments() { string json = @"{ /*comment2*/ ""Name"": /*comment3*/ ""Apple"" /*comment4*/, /*comment5*/ ""ExpiryDate"": ""\/Date(1230422400000)\/"", ""Price"": 3.99, ""Sizes"": /*comment6*/ [ /*comment7*/ ""Small"", /*comment8*/ ""Medium"" /*comment9*/, /*comment10*/ ""Large"" /*comment11*/ ] /*comment12*/ } /*comment13*/"; JToken o = JToken.Parse(json); Assert.AreEqual("Apple", (string)o["Name"]); } [Test] public void WritePropertyWithNoValue() { var o = new JObject(); o.Add(new JProperty("novalue")); StringAssert.AreEqual(@"{ ""novalue"": null }", o.ToString()); } [Test] public void Keys() { var o = new JObject(); var d = (IDictionary)o; Assert.AreEqual(0, d.Keys.Count); o["value"] = true; Assert.AreEqual(1, d.Keys.Count); } [Test] public void TryGetValue() { JObject o = new JObject(); o.Add("PropertyNameValue", new JValue(1)); Assert.AreEqual(1, o.Children().Count()); JToken t; Assert.AreEqual(false, o.TryGetValue("sdf", out t)); Assert.AreEqual(null, t); Assert.AreEqual(false, o.TryGetValue(null, out t)); Assert.AreEqual(null, t); Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t)); } [Test] public void DictionaryItemShouldSet() { JObject o = new JObject(); o["PropertyNameValue"] = new JValue(1); Assert.AreEqual(1, o.Children().Count()); JToken t; Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t)); o["PropertyNameValue"] = new JValue(2); Assert.AreEqual(1, o.Children().Count()); Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); Assert.AreEqual(true, JToken.DeepEquals(new JValue(2), t)); o["PropertyNameValue"] = null; Assert.AreEqual(1, o.Children().Count()); Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); Assert.AreEqual(true, JToken.DeepEquals(JValue.CreateNull(), t)); } [Test] public void Remove() { JObject o = new JObject(); o.Add("PropertyNameValue", new JValue(1)); Assert.AreEqual(1, o.Children().Count()); Assert.AreEqual(false, o.Remove("sdf")); Assert.AreEqual(false, o.Remove(null)); Assert.AreEqual(true, o.Remove("PropertyNameValue")); Assert.AreEqual(0, o.Children().Count()); } [Test] public void GenericCollectionRemove() { JValue v = new JValue(1); JObject o = new JObject(); o.Add("PropertyNameValue", v); Assert.AreEqual(1, o.Children().Count()); Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue1", new JValue(1)))); Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", new JValue(2)))); Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", new JValue(1)))); Assert.AreEqual(true, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", v))); Assert.AreEqual(0, o.Children().Count()); } [Test] public void DuplicatePropertyNameShouldThrow() { ExceptionAssert.Throws(() => { JObject o = new JObject(); o.Add("PropertyNameValue", null); o.Add("PropertyNameValue", null); }, "Can not add property PropertyNameValue to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object."); } [Test] public void GenericDictionaryAdd() { JObject o = new JObject(); o.Add("PropertyNameValue", new JValue(1)); Assert.AreEqual(1, (int)o["PropertyNameValue"]); o.Add("PropertyNameValue1", null); Assert.AreEqual(null, ((JValue)o["PropertyNameValue1"]).Value); Assert.AreEqual(2, o.Children().Count()); } [Test] public void GenericCollectionAdd() { JObject o = new JObject(); ((ICollection>)o).Add(new KeyValuePair("PropertyNameValue", new JValue(1))); Assert.AreEqual(1, (int)o["PropertyNameValue"]); Assert.AreEqual(1, o.Children().Count()); } [Test] public void GenericCollectionClear() { JObject o = new JObject(); o.Add("PropertyNameValue", new JValue(1)); Assert.AreEqual(1, o.Children().Count()); JProperty p = (JProperty)o.Children().ElementAt(0); ((ICollection>)o).Clear(); Assert.AreEqual(0, o.Children().Count()); Assert.AreEqual(null, p.Parent); } [Test] public void GenericCollectionContains() { JValue v = new JValue(1); JObject o = new JObject(); o.Add("PropertyNameValue", v); Assert.AreEqual(1, o.Children().Count()); bool contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", new JValue(1))); Assert.AreEqual(false, contains); contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", v)); Assert.AreEqual(true, contains); contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", new JValue(2))); Assert.AreEqual(false, contains); contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue1", new JValue(1))); Assert.AreEqual(false, contains); contains = ((ICollection>)o).Contains(default(KeyValuePair)); Assert.AreEqual(false, contains); } [Test] public void GenericDictionaryContains() { JObject o = new JObject(); o.Add("PropertyNameValue", new JValue(1)); Assert.AreEqual(1, o.Children().Count()); bool contains = ((IDictionary)o).ContainsKey("PropertyNameValue"); Assert.AreEqual(true, contains); } [Test] public void GenericCollectionCopyTo() { JObject o = new JObject(); o.Add("PropertyNameValue", new JValue(1)); o.Add("PropertyNameValue2", new JValue(2)); o.Add("PropertyNameValue3", new JValue(3)); Assert.AreEqual(3, o.Children().Count()); KeyValuePair[] a = new KeyValuePair[5]; ((ICollection>)o).CopyTo(a, 1); Assert.AreEqual(default(KeyValuePair), a[0]); Assert.AreEqual("PropertyNameValue", a[1].Key); Assert.AreEqual(1, (int)a[1].Value); Assert.AreEqual("PropertyNameValue2", a[2].Key); Assert.AreEqual(2, (int)a[2].Value); Assert.AreEqual("PropertyNameValue3", a[3].Key); Assert.AreEqual(3, (int)a[3].Value); Assert.AreEqual(default(KeyValuePair), a[4]); } [Test] public void GenericCollectionCopyToNullArrayShouldThrow() { ExceptionAssert.Throws(() => { JObject o = new JObject(); ((ICollection>)o).CopyTo(null, 0); }, @"Value cannot be null. Parameter name: array"); } [Test] public void GenericCollectionCopyToNegativeArrayIndexShouldThrow() { ExceptionAssert.Throws(() => { JObject o = new JObject(); ((ICollection>)o).CopyTo(new KeyValuePair[1], -1); }, @"arrayIndex is less than 0. Parameter name: arrayIndex"); } [Test] public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow() { ExceptionAssert.Throws(() => { JObject o = new JObject(); ((ICollection>)o).CopyTo(new KeyValuePair[1], 1); }, @"arrayIndex is equal to or greater than the length of array."); } [Test] public void GenericCollectionCopyToInsufficientArrayCapacity() { ExceptionAssert.Throws(() => { JObject o = new JObject(); o.Add("PropertyNameValue", new JValue(1)); o.Add("PropertyNameValue2", new JValue(2)); o.Add("PropertyNameValue3", new JValue(3)); ((ICollection>)o).CopyTo(new KeyValuePair[3], 1); }, @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array."); } [Test] public void FromObjectRaw() { PersonRaw raw = new PersonRaw { FirstName = "FirstNameValue", RawContent = new JRaw("[1,2,3,4,5]"), LastName = "LastNameValue" }; JObject o = JObject.FromObject(raw); Assert.AreEqual("FirstNameValue", (string)o["first_name"]); Assert.AreEqual(JTokenType.Raw, ((JValue)o["RawContent"]).Type); Assert.AreEqual("[1,2,3,4,5]", (string)o["RawContent"]); Assert.AreEqual("LastNameValue", (string)o["last_name"]); } [Test] public void JTokenReader() { PersonRaw raw = new PersonRaw { FirstName = "FirstNameValue", RawContent = new JRaw("[1,2,3,4,5]"), LastName = "LastNameValue" }; JObject o = JObject.FromObject(raw); JsonReader reader = new JTokenReader(o); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.StartObject, reader.TokenType); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.Raw, reader.TokenType); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndObject, reader.TokenType); Assert.IsFalse(reader.Read()); } [Test] public void DeserializeFromRaw() { PersonRaw raw = new PersonRaw { FirstName = "FirstNameValue", RawContent = new JRaw("[1,2,3,4,5]"), LastName = "LastNameValue" }; JObject o = JObject.FromObject(raw); JsonReader reader = new JTokenReader(o); JsonSerializer serializer = new JsonSerializer(); raw = (PersonRaw)serializer.Deserialize(reader, typeof(PersonRaw)); Assert.AreEqual("FirstNameValue", raw.FirstName); Assert.AreEqual("LastNameValue", raw.LastName); Assert.AreEqual("[1,2,3,4,5]", raw.RawContent.Value); } [Test] public void Parse_ShouldThrowOnUnexpectedToken() { ExceptionAssert.Throws(() => { string json = @"[""prop""]"; JObject.Parse(json); }, "Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1."); } [Test] public void ParseJavaScriptDate() { string json = @"[new Date(1207285200000)]"; JArray a = (JArray)JsonConvert.DeserializeObject(json); JValue v = (JValue)a[0]; Assert.AreEqual(DateTimeUtils.ConvertJavaScriptTicksToDateTime(1207285200000), (DateTime)v); } [Test] public void GenericValueCast() { string json = @"{""foo"":true}"; JObject o = (JObject)JsonConvert.DeserializeObject(json); bool? value = o.Value("foo"); Assert.AreEqual(true, value); json = @"{""foo"":null}"; o = (JObject)JsonConvert.DeserializeObject(json); value = o.Value("foo"); Assert.AreEqual(null, value); } [Test] public void Blog() { ExceptionAssert.Throws(() => { JObject.Parse(@"{ ""name"": ""James"", ]!#$THIS IS: BAD JSON![{}}}}] }"); }, "Invalid property identifier character: ]. Path 'name', line 3, position 4."); } [Test] public void RawChildValues() { JObject o = new JObject(); o["val1"] = new JRaw("1"); o["val2"] = new JRaw("1"); string json = o.ToString(); StringAssert.AreEqual(@"{ ""val1"": 1, ""val2"": 1 }", json); } [Test] public void Iterate() { JObject o = new JObject(); o.Add("PropertyNameValue1", new JValue(1)); o.Add("PropertyNameValue2", new JValue(2)); JToken t = o; int i = 1; foreach (JProperty property in t) { Assert.AreEqual("PropertyNameValue" + i, property.Name); Assert.AreEqual(i, (int)property.Value); i++; } } [Test] public void KeyValuePairIterate() { JObject o = new JObject(); o.Add("PropertyNameValue1", new JValue(1)); o.Add("PropertyNameValue2", new JValue(2)); int i = 1; foreach (KeyValuePair pair in o) { Assert.AreEqual("PropertyNameValue" + i, pair.Key); Assert.AreEqual(i, (int)pair.Value); i++; } } [Test] public void WriteObjectNullStringValue() { string s = null; JValue v = new JValue(s); Assert.AreEqual(null, v.Value); Assert.AreEqual(JTokenType.String, v.Type); JObject o = new JObject(); o["title"] = v; string output = o.ToString(); StringAssert.AreEqual(@"{ ""title"": null }", output); } [Test] public void Example() { string json = @"{ ""Name"": ""Apple"", ""Expiry"": new Date(1230422400000), ""Price"": 3.99, ""Sizes"": [ ""Small"", ""Medium"", ""Large"" ] }"; JObject o = JObject.Parse(json); string name = (string)o["Name"]; // Apple JArray sizes = (JArray)o["Sizes"]; string smallest = (string)sizes[0]; // Small Assert.AreEqual("Apple", name); Assert.AreEqual("Small", smallest); } [Test] public void DeserializeClassManually() { string jsonText = @"{ ""short"": { ""original"":""http://www.foo.com/"", ""short"":""krehqk"", ""error"": { ""code"":0, ""msg"":""No action taken"" } } }"; JObject json = JObject.Parse(jsonText); Shortie shortie = new Shortie { Original = (string)json["short"]["original"], Short = (string)json["short"]["short"], Error = new ShortieException { Code = (int)json["short"]["error"]["code"], ErrorMessage = (string)json["short"]["error"]["msg"] } }; Assert.AreEqual("http://www.foo.com/", shortie.Original); Assert.AreEqual("krehqk", shortie.Short); Assert.AreEqual(null, shortie.Shortened); Assert.AreEqual(0, shortie.Error.Code); Assert.AreEqual("No action taken", shortie.Error.ErrorMessage); } [Test] public void JObjectContainingHtml() { JObject o = new JObject(); o["rc"] = new JValue(200); o["m"] = new JValue(""); o["o"] = new JValue(@"
" + StringUtils.CarriageReturnLineFeed + @"
"); StringAssert.AreEqual(@"{ ""rc"": 200, ""m"": """", ""o"": ""
\r\n
"" }", o.ToString()); } [Test] public void ImplicitValueConversions() { JObject moss = new JObject(); moss["FirstName"] = new JValue("Maurice"); moss["LastName"] = new JValue("Moss"); moss["BirthDate"] = new JValue(new DateTime(1977, 12, 30)); moss["Department"] = new JValue("IT"); moss["JobTitle"] = new JValue("Support"); StringAssert.AreEqual(@"{ ""FirstName"": ""Maurice"", ""LastName"": ""Moss"", ""BirthDate"": ""1977-12-30T00:00:00"", ""Department"": ""IT"", ""JobTitle"": ""Support"" }", moss.ToString()); JObject jen = new JObject(); jen["FirstName"] = "Jen"; jen["LastName"] = "Barber"; jen["BirthDate"] = new DateTime(1978, 3, 15); jen["Department"] = "IT"; jen["JobTitle"] = "Manager"; StringAssert.AreEqual(@"{ ""FirstName"": ""Jen"", ""LastName"": ""Barber"", ""BirthDate"": ""1978-03-15T00:00:00"", ""Department"": ""IT"", ""JobTitle"": ""Manager"" }", jen.ToString()); } [Test] public void ReplaceJPropertyWithJPropertyWithSameName() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); JObject o = new JObject(p1, p2); IList l = o; Assert.AreEqual(p1, l[0]); Assert.AreEqual(p2, l[1]); JProperty p3 = new JProperty("Test1", "III"); p1.Replace(p3); Assert.AreEqual(null, p1.Parent); Assert.AreEqual(l, p3.Parent); Assert.AreEqual(p3, l[0]); Assert.AreEqual(p2, l[1]); Assert.AreEqual(2, l.Count); Assert.AreEqual(2, o.Properties().Count()); JProperty p4 = new JProperty("Test4", "IV"); p2.Replace(p4); Assert.AreEqual(null, p2.Parent); Assert.AreEqual(l, p4.Parent); Assert.AreEqual(p3, l[0]); Assert.AreEqual(p4, l[1]); } #if !(NET20 || PORTABLE || PORTABLE40) || NETSTANDARD1_3 [Test] public void PropertyChanging() { object changing = null; object changed = null; int changingCount = 0; int changedCount = 0; JObject o = new JObject(); o.PropertyChanging += (sender, args) => { JObject s = (JObject)sender; changing = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; changingCount++; }; o.PropertyChanged += (sender, args) => { JObject s = (JObject)sender; changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; changedCount++; }; o["StringValue"] = "value1"; Assert.AreEqual(null, changing); Assert.AreEqual("value1", changed); Assert.AreEqual("value1", (string)o["StringValue"]); Assert.AreEqual(1, changingCount); Assert.AreEqual(1, changedCount); o["StringValue"] = "value1"; Assert.AreEqual(1, changingCount); Assert.AreEqual(1, changedCount); o["StringValue"] = "value2"; Assert.AreEqual("value1", changing); Assert.AreEqual("value2", changed); Assert.AreEqual("value2", (string)o["StringValue"]); Assert.AreEqual(2, changingCount); Assert.AreEqual(2, changedCount); o["StringValue"] = null; Assert.AreEqual("value2", changing); Assert.AreEqual(null, changed); Assert.AreEqual(null, (string)o["StringValue"]); Assert.AreEqual(3, changingCount); Assert.AreEqual(3, changedCount); o["NullValue"] = null; Assert.AreEqual(null, changing); Assert.AreEqual(null, changed); Assert.AreEqual(JValue.CreateNull(), o["NullValue"]); Assert.AreEqual(4, changingCount); Assert.AreEqual(4, changedCount); o["NullValue"] = null; Assert.AreEqual(4, changingCount); Assert.AreEqual(4, changedCount); } #endif [Test] public void PropertyChanged() { object changed = null; int changedCount = 0; JObject o = new JObject(); o.PropertyChanged += (sender, args) => { JObject s = (JObject)sender; changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; changedCount++; }; o["StringValue"] = "value1"; Assert.AreEqual("value1", changed); Assert.AreEqual("value1", (string)o["StringValue"]); Assert.AreEqual(1, changedCount); o["StringValue"] = "value1"; Assert.AreEqual(1, changedCount); o["StringValue"] = "value2"; Assert.AreEqual("value2", changed); Assert.AreEqual("value2", (string)o["StringValue"]); Assert.AreEqual(2, changedCount); o["StringValue"] = null; Assert.AreEqual(null, changed); Assert.AreEqual(null, (string)o["StringValue"]); Assert.AreEqual(3, changedCount); o["NullValue"] = null; Assert.AreEqual(null, changed); Assert.AreEqual(JValue.CreateNull(), o["NullValue"]); Assert.AreEqual(4, changedCount); o["NullValue"] = null; Assert.AreEqual(4, changedCount); } [Test] public void IListContains() { JProperty p = new JProperty("Test", 1); IList l = new JObject(p); Assert.IsTrue(l.Contains(p)); Assert.IsFalse(l.Contains(new JProperty("Test", 1))); } [Test] public void IListIndexOf() { JProperty p = new JProperty("Test", 1); IList l = new JObject(p); Assert.AreEqual(0, l.IndexOf(p)); Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1))); } [Test] public void IListClear() { JProperty p = new JProperty("Test", 1); IList l = new JObject(p); Assert.AreEqual(1, l.Count); l.Clear(); Assert.AreEqual(0, l.Count); } [Test] public void IListCopyTo() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); object[] a = new object[l.Count]; l.CopyTo(a, 0); Assert.AreEqual(p1, a[0]); Assert.AreEqual(p2, a[1]); } [Test] public void IListAdd() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); l.Add(p3); Assert.AreEqual(3, l.Count); Assert.AreEqual(p3, l[2]); } [Test] public void IListAddBadToken() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); l.Add(new JValue("Bad!")); }, "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject."); } [Test] public void IListAddBadValue() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); l.Add("Bad!"); }, "Argument is not a JToken."); } [Test] public void IListAddPropertyWithExistingName() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test2", "II"); l.Add(p3); }, "Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object."); } [Test] public void IListRemove() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); // won't do anything l.Remove(p3); Assert.AreEqual(2, l.Count); l.Remove(p1); Assert.AreEqual(1, l.Count); Assert.IsFalse(l.Contains(p1)); Assert.IsTrue(l.Contains(p2)); l.Remove(p2); Assert.AreEqual(0, l.Count); Assert.IsFalse(l.Contains(p2)); Assert.AreEqual(null, p2.Parent); } [Test] public void IListRemoveAt() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); // won't do anything l.RemoveAt(0); l.Remove(p1); Assert.AreEqual(1, l.Count); l.Remove(p2); Assert.AreEqual(0, l.Count); } [Test] public void IListInsert() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); l.Insert(1, p3); Assert.AreEqual(l, p3.Parent); Assert.AreEqual(p1, l[0]); Assert.AreEqual(p3, l[1]); Assert.AreEqual(p2, l[2]); } [Test] public void IListIsReadOnly() { IList l = new JObject(); Assert.IsFalse(l.IsReadOnly); } [Test] public void IListIsFixedSize() { IList l = new JObject(); Assert.IsFalse(l.IsFixedSize); } [Test] public void IListSetItem() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); l[0] = p3; Assert.AreEqual(p3, l[0]); Assert.AreEqual(p2, l[1]); } [Test] public void IListSetItemAlreadyExists() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); l[0] = p3; l[1] = p3; }, "Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object."); } [Test] public void IListSetItemInvalid() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); l[0] = new JValue(true); }, @"Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject."); } [Test] public void IListSyncRoot() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); Assert.IsNotNull(l.SyncRoot); } [Test] public void IListIsSynchronized() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); Assert.IsFalse(l.IsSynchronized); } [Test] public void GenericListJTokenContains() { JProperty p = new JProperty("Test", 1); IList l = new JObject(p); Assert.IsTrue(l.Contains(p)); Assert.IsFalse(l.Contains(new JProperty("Test", 1))); } [Test] public void GenericListJTokenIndexOf() { JProperty p = new JProperty("Test", 1); IList l = new JObject(p); Assert.AreEqual(0, l.IndexOf(p)); Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1))); } [Test] public void GenericListJTokenClear() { JProperty p = new JProperty("Test", 1); IList l = new JObject(p); Assert.AreEqual(1, l.Count); l.Clear(); Assert.AreEqual(0, l.Count); } [Test] public void GenericListJTokenCopyTo() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JToken[] a = new JToken[l.Count]; l.CopyTo(a, 0); Assert.AreEqual(p1, a[0]); Assert.AreEqual(p2, a[1]); } [Test] public void GenericListJTokenAdd() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); l.Add(p3); Assert.AreEqual(3, l.Count); Assert.AreEqual(p3, l[2]); } [Test] public void GenericListJTokenAddBadToken() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); l.Add(new JValue("Bad!")); }, "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject."); } [Test] public void GenericListJTokenAddBadValue() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); // string is implicitly converted to JValue l.Add("Bad!"); }, "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject."); } [Test] public void GenericListJTokenAddPropertyWithExistingName() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test2", "II"); l.Add(p3); }, "Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object."); } [Test] public void GenericListJTokenRemove() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); // won't do anything Assert.IsFalse(l.Remove(p3)); Assert.AreEqual(2, l.Count); Assert.IsTrue(l.Remove(p1)); Assert.AreEqual(1, l.Count); Assert.IsFalse(l.Contains(p1)); Assert.IsTrue(l.Contains(p2)); Assert.IsTrue(l.Remove(p2)); Assert.AreEqual(0, l.Count); Assert.IsFalse(l.Contains(p2)); Assert.AreEqual(null, p2.Parent); } [Test] public void GenericListJTokenRemoveAt() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); // won't do anything l.RemoveAt(0); l.Remove(p1); Assert.AreEqual(1, l.Count); l.Remove(p2); Assert.AreEqual(0, l.Count); } [Test] public void GenericListJTokenInsert() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); l.Insert(1, p3); Assert.AreEqual(l, p3.Parent); Assert.AreEqual(p1, l[0]); Assert.AreEqual(p3, l[1]); Assert.AreEqual(p2, l[2]); } [Test] public void GenericListJTokenIsReadOnly() { IList l = new JObject(); Assert.IsFalse(l.IsReadOnly); } [Test] public void GenericListJTokenSetItem() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); l[0] = p3; Assert.AreEqual(p3, l[0]); Assert.AreEqual(p2, l[1]); } [Test] public void GenericListJTokenSetItemAlreadyExists() { ExceptionAssert.Throws(() => { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); IList l = new JObject(p1, p2); JProperty p3 = new JProperty("Test3", "III"); l[0] = p3; l[1] = p3; }, "Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object."); } #if !(PORTABLE || DNXCORE50 || PORTABLE40) [Test] public void IBindingListSortDirection() { IBindingList l = new JObject(); Assert.AreEqual(ListSortDirection.Ascending, l.SortDirection); } [Test] public void IBindingListSortProperty() { IBindingList l = new JObject(); Assert.AreEqual(null, l.SortProperty); } [Test] public void IBindingListSupportsChangeNotification() { IBindingList l = new JObject(); Assert.AreEqual(true, l.SupportsChangeNotification); } [Test] public void IBindingListSupportsSearching() { IBindingList l = new JObject(); Assert.AreEqual(false, l.SupportsSearching); } [Test] public void IBindingListSupportsSorting() { IBindingList l = new JObject(); Assert.AreEqual(false, l.SupportsSorting); } [Test] public void IBindingListAllowEdit() { IBindingList l = new JObject(); Assert.AreEqual(true, l.AllowEdit); } [Test] public void IBindingListAllowNew() { IBindingList l = new JObject(); Assert.AreEqual(true, l.AllowNew); } [Test] public void IBindingListAllowRemove() { IBindingList l = new JObject(); Assert.AreEqual(true, l.AllowRemove); } [Test] public void IBindingListAddIndex() { IBindingList l = new JObject(); // do nothing l.AddIndex(null); } [Test] public void IBindingListApplySort() { ExceptionAssert.Throws(() => { IBindingList l = new JObject(); l.ApplySort(null, ListSortDirection.Ascending); }, "Specified method is not supported."); } [Test] public void IBindingListRemoveSort() { ExceptionAssert.Throws(() => { IBindingList l = new JObject(); l.RemoveSort(); }, "Specified method is not supported."); } [Test] public void IBindingListRemoveIndex() { IBindingList l = new JObject(); // do nothing l.RemoveIndex(null); } [Test] public void IBindingListFind() { ExceptionAssert.Throws(() => { IBindingList l = new JObject(); l.Find(null, null); }, "Specified method is not supported."); } [Test] public void IBindingListIsSorted() { IBindingList l = new JObject(); Assert.AreEqual(false, l.IsSorted); } [Test] public void IBindingListAddNew() { ExceptionAssert.Throws(() => { IBindingList l = new JObject(); l.AddNew(); }, "Could not determine new value to add to 'Newtonsoft.Json.Linq.JObject'."); } [Test] public void IBindingListAddNewWithEvent() { JObject o = new JObject(); o._addingNew += (s, e) => e.NewObject = new JProperty("Property!"); IBindingList l = o; object newObject = l.AddNew(); Assert.IsNotNull(newObject); JProperty p = (JProperty)newObject; Assert.AreEqual("Property!", p.Name); Assert.AreEqual(o, p.Parent); } [Test] public void ITypedListGetListName() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); ITypedList l = new JObject(p1, p2); Assert.AreEqual(string.Empty, l.GetListName(null)); } [Test] public void ITypedListGetItemProperties() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); ITypedList l = new JObject(p1, p2); PropertyDescriptorCollection propertyDescriptors = l.GetItemProperties(null); Assert.IsNull(propertyDescriptors); } [Test] public void ListChanged() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); JObject o = new JObject(p1, p2); ListChangedType? changedType = null; int? index = null; o.ListChanged += (s, a) => { changedType = a.ListChangedType; index = a.NewIndex; }; JProperty p3 = new JProperty("Test3", "III"); o.Add(p3); Assert.AreEqual(changedType, ListChangedType.ItemAdded); Assert.AreEqual(index, 2); Assert.AreEqual(p3, ((IList)o)[index.Value]); JProperty p4 = new JProperty("Test4", "IV"); ((IList)o)[index.Value] = p4; Assert.AreEqual(changedType, ListChangedType.ItemChanged); Assert.AreEqual(index, 2); Assert.AreEqual(p4, ((IList)o)[index.Value]); Assert.IsFalse(((IList)o).Contains(p3)); Assert.IsTrue(((IList)o).Contains(p4)); o["Test1"] = 2; Assert.AreEqual(changedType, ListChangedType.ItemChanged); Assert.AreEqual(index, 0); Assert.AreEqual(2, (int)o["Test1"]); } #endif #if !(NET20 || NET35 || PORTABLE40) [Test] public void CollectionChanged() { JProperty p1 = new JProperty("Test1", 1); JProperty p2 = new JProperty("Test2", "Two"); JObject o = new JObject(p1, p2); NotifyCollectionChangedAction? changedType = null; int? index = null; o._collectionChanged += (s, a) => { changedType = a.Action; index = a.NewStartingIndex; }; JProperty p3 = new JProperty("Test3", "III"); o.Add(p3); Assert.AreEqual(changedType, NotifyCollectionChangedAction.Add); Assert.AreEqual(index, 2); Assert.AreEqual(p3, ((IList)o)[index.Value]); JProperty p4 = new JProperty("Test4", "IV"); ((IList)o)[index.Value] = p4; Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace); Assert.AreEqual(index, 2); Assert.AreEqual(p4, ((IList)o)[index.Value]); Assert.IsFalse(((IList)o).Contains(p3)); Assert.IsTrue(((IList)o).Contains(p4)); o["Test1"] = 2; Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace); Assert.AreEqual(index, 0); Assert.AreEqual(2, (int)o["Test1"]); } #endif [Test] public void GetGeocodeAddress() { string json = @"{ ""name"": ""Address: 435 North Mulford Road Rockford, IL 61107"", ""Status"": { ""code"": 200, ""request"": ""geocode"" }, ""Placemark"": [ { ""id"": ""p1"", ""address"": ""435 N Mulford Rd, Rockford, IL 61107, USA"", ""AddressDetails"": { ""Accuracy"" : 8, ""Country"" : { ""AdministrativeArea"" : { ""AdministrativeAreaName"" : ""IL"", ""SubAdministrativeArea"" : { ""Locality"" : { ""LocalityName"" : ""Rockford"", ""PostalCode"" : { ""PostalCodeNumber"" : ""61107"" }, ""Thoroughfare"" : { ""ThoroughfareName"" : ""435 N Mulford Rd"" } }, ""SubAdministrativeAreaName"" : ""Winnebago"" } }, ""CountryName"" : ""USA"", ""CountryNameCode"" : ""US"" } }, ""ExtendedData"": { ""LatLonBox"": { ""north"": 42.2753076, ""south"": 42.2690124, ""east"": -88.9964645, ""west"": -89.0027597 } }, ""Point"": { ""coordinates"": [ -88.9995886, 42.2721596, 0 ] } } ] }"; JObject o = JObject.Parse(json); string searchAddress = (string)o["Placemark"][0]["AddressDetails"]["Country"]["AdministrativeArea"]["SubAdministrativeArea"]["Locality"]["Thoroughfare"]["ThoroughfareName"]; Assert.AreEqual("435 N Mulford Rd", searchAddress); } [Test] public void SetValueWithInvalidPropertyName() { ExceptionAssert.Throws(() => { JObject o = new JObject(); o[0] = new JValue(3); }, "Set JObject values with invalid key value: 0. Object property name expected."); } [Test] public void SetValue() { object key = "TestKey"; JObject o = new JObject(); o[key] = new JValue(3); Assert.AreEqual(3, (int)o[key]); } [Test] public void ParseMultipleProperties() { string json = @"{ ""Name"": ""Name1"", ""Name"": ""Name2"" }"; JObject o = JObject.Parse(json); string value = (string)o["Name"]; Assert.AreEqual("Name2", value); } #if !(PORTABLE || DNXCORE50 || PORTABLE40) [Test] public void WriteObjectNullDBNullValue() { DBNull dbNull = DBNull.Value; JValue v = new JValue(dbNull); Assert.AreEqual(DBNull.Value, v.Value); Assert.AreEqual(JTokenType.Null, v.Type); JObject o = new JObject(); o["title"] = v; string output = o.ToString(); StringAssert.AreEqual(@"{ ""title"": null }", output); } #endif [Test] public void InvalidValueCastExceptionMessage() { ExceptionAssert.Throws(() => { string json = @"{ ""responseData"": {}, ""responseDetails"": null, ""responseStatus"": 200 }"; JObject o = JObject.Parse(json); string name = (string)o["responseData"]; }, "Can not convert Object to String."); } [Test] public void InvalidPropertyValueCastExceptionMessage() { ExceptionAssert.Throws(() => { string json = @"{ ""responseData"": {}, ""responseDetails"": null, ""responseStatus"": 200 }"; JObject o = JObject.Parse(json); string name = (string)o.Property("responseData"); }, "Can not convert Object to String."); } [Test] public void ParseIncomplete() { ExceptionAssert.Throws(() => { JObject.Parse("{ foo:"); }, "Unexpected end of content while loading JObject. Path 'foo', line 1, position 6."); } [Test] public void LoadFromNestedObject() { string jsonText = @"{ ""short"": { ""error"": { ""code"":0, ""msg"":""No action taken"" } } }"; JsonReader reader = new JsonTextReader(new StringReader(jsonText)); reader.Read(); reader.Read(); reader.Read(); reader.Read(); reader.Read(); JObject o = (JObject)JToken.ReadFrom(reader); Assert.IsNotNull(o); StringAssert.AreEqual(@"{ ""code"": 0, ""msg"": ""No action taken"" }", o.ToString(Formatting.Indented)); } [Test] public void LoadFromNestedObjectIncomplete() { ExceptionAssert.Throws(() => { string jsonText = @"{ ""short"": { ""error"": { ""code"":0"; JsonReader reader = new JsonTextReader(new StringReader(jsonText)); reader.Read(); reader.Read(); reader.Read(); reader.Read(); reader.Read(); JToken.ReadFrom(reader); }, "Unexpected end of content while loading JObject. Path 'short.error.code', line 6, position 14."); } #if !(PORTABLE || DNXCORE50 || PORTABLE40) [Test] public void GetProperties() { JObject o = JObject.Parse("{'prop1':12,'prop2':'hi!','prop3':null,'prop4':[1,2,3]}"); ICustomTypeDescriptor descriptor = o; PropertyDescriptorCollection properties = descriptor.GetProperties(); Assert.AreEqual(4, properties.Count); PropertyDescriptor prop1 = properties[0]; Assert.AreEqual("prop1", prop1.Name); Assert.AreEqual(typeof(object), prop1.PropertyType); Assert.AreEqual(typeof(JObject), prop1.ComponentType); Assert.AreEqual(false, prop1.CanResetValue(o)); Assert.AreEqual(false, prop1.ShouldSerializeValue(o)); PropertyDescriptor prop2 = properties[1]; Assert.AreEqual("prop2", prop2.Name); Assert.AreEqual(typeof(object), prop2.PropertyType); Assert.AreEqual(typeof(JObject), prop2.ComponentType); Assert.AreEqual(false, prop2.CanResetValue(o)); Assert.AreEqual(false, prop2.ShouldSerializeValue(o)); PropertyDescriptor prop3 = properties[2]; Assert.AreEqual("prop3", prop3.Name); Assert.AreEqual(typeof(object), prop3.PropertyType); Assert.AreEqual(typeof(JObject), prop3.ComponentType); Assert.AreEqual(false, prop3.CanResetValue(o)); Assert.AreEqual(false, prop3.ShouldSerializeValue(o)); PropertyDescriptor prop4 = properties[3]; Assert.AreEqual("prop4", prop4.Name); Assert.AreEqual(typeof(object), prop4.PropertyType); Assert.AreEqual(typeof(JObject), prop4.ComponentType); Assert.AreEqual(false, prop4.CanResetValue(o)); Assert.AreEqual(false, prop4.ShouldSerializeValue(o)); } #endif [Test] public void ParseEmptyObjectWithComment() { JObject o = JObject.Parse("{ /* A Comment */ }"); Assert.AreEqual(0, o.Count); } [Test] public void FromObjectTimeSpan() { JValue v = (JValue)JToken.FromObject(TimeSpan.FromDays(1)); Assert.AreEqual(v.Value, TimeSpan.FromDays(1)); Assert.AreEqual("1.00:00:00", v.ToString()); } [Test] public void FromObjectUri() { JValue v = (JValue)JToken.FromObject(new Uri("http://www.stuff.co.nz")); Assert.AreEqual(v.Value, new Uri("http://www.stuff.co.nz")); Assert.AreEqual("http://www.stuff.co.nz/", v.ToString()); } [Test] public void FromObjectGuid() { JValue v = (JValue)JToken.FromObject(new Guid("9065ACF3-C820-467D-BE50-8D4664BEAF35")); Assert.AreEqual(v.Value, new Guid("9065ACF3-C820-467D-BE50-8D4664BEAF35")); Assert.AreEqual("9065acf3-c820-467d-be50-8d4664beaf35", v.ToString()); } [Test] public void ParseAdditionalContent() { ExceptionAssert.Throws(() => { string json = @"{ ""Name"": ""Apple"", ""Expiry"": new Date(1230422400000), ""Price"": 3.99, ""Sizes"": [ ""Small"", ""Medium"", ""Large"" ] }, 987987"; JObject o = JObject.Parse(json); }, "Additional text encountered after finished reading JSON content: ,. Path '', line 10, position 1."); } [Test] public void DeepEqualsIgnoreOrder() { JObject o1 = new JObject( new JProperty("null", null), new JProperty("integer", 1), new JProperty("string", "string!"), new JProperty("decimal", 0.5m), new JProperty("array", new JArray(1, 2))); Assert.IsTrue(o1.DeepEquals(o1)); JObject o2 = new JObject( new JProperty("null", null), new JProperty("string", "string!"), new JProperty("decimal", 0.5m), new JProperty("integer", 1), new JProperty("array", new JArray(1, 2))); Assert.IsTrue(o1.DeepEquals(o2)); JObject o3 = new JObject( new JProperty("null", null), new JProperty("string", "string!"), new JProperty("decimal", 0.5m), new JProperty("integer", 2), new JProperty("array", new JArray(1, 2))); Assert.IsFalse(o1.DeepEquals(o3)); JObject o4 = new JObject( new JProperty("null", null), new JProperty("string", "string!"), new JProperty("decimal", 0.5m), new JProperty("integer", 1), new JProperty("array", new JArray(2, 1))); Assert.IsFalse(o1.DeepEquals(o4)); JObject o5 = new JObject( new JProperty("null", null), new JProperty("string", "string!"), new JProperty("decimal", 0.5m), new JProperty("integer", 1)); Assert.IsFalse(o1.DeepEquals(o5)); Assert.IsFalse(o1.DeepEquals(null)); } [Test] public void ToListOnEmptyObject() { JObject o = JObject.Parse(@"{}"); IList l1 = o.ToList(); Assert.AreEqual(0, l1.Count); IList> l2 = o.ToList>(); Assert.AreEqual(0, l2.Count); o = JObject.Parse(@"{'hi':null}"); l1 = o.ToList(); Assert.AreEqual(1, l1.Count); l2 = o.ToList>(); Assert.AreEqual(1, l2.Count); } [Test] public void EmptyObjectDeepEquals() { Assert.IsTrue(JToken.DeepEquals(new JObject(), new JObject())); JObject a = new JObject(); JObject b = new JObject(); b.Add("hi", "bye"); b.Remove("hi"); Assert.IsTrue(JToken.DeepEquals(a, b)); Assert.IsTrue(JToken.DeepEquals(b, a)); } [Test] public void GetValueBlogExample() { JObject o = JObject.Parse(@"{ 'name': 'Lower', 'NAME': 'Upper' }"); string exactMatch = (string)o.GetValue("NAME", StringComparison.OrdinalIgnoreCase); // Upper string ignoreCase = (string)o.GetValue("Name", StringComparison.OrdinalIgnoreCase); // Lower Assert.AreEqual("Upper", exactMatch); Assert.AreEqual("Lower", ignoreCase); } [Test] public void GetValue() { JObject a = new JObject(); a["Name"] = "Name!"; a["name"] = "name!"; a["title"] = "Title!"; Assert.AreEqual(null, a.GetValue("NAME", StringComparison.Ordinal)); Assert.AreEqual(null, a.GetValue("NAME")); Assert.AreEqual(null, a.GetValue("TITLE")); Assert.AreEqual("Name!", (string)a.GetValue("NAME", StringComparison.OrdinalIgnoreCase)); Assert.AreEqual("name!", (string)a.GetValue("name", StringComparison.Ordinal)); Assert.AreEqual(null, a.GetValue(null, StringComparison.Ordinal)); Assert.AreEqual(null, a.GetValue(null)); JToken v; Assert.IsFalse(a.TryGetValue("NAME", StringComparison.Ordinal, out v)); Assert.AreEqual(null, v); Assert.IsFalse(a.TryGetValue("NAME", out v)); Assert.IsFalse(a.TryGetValue("TITLE", out v)); Assert.IsTrue(a.TryGetValue("NAME", StringComparison.OrdinalIgnoreCase, out v)); Assert.AreEqual("Name!", (string)v); Assert.IsTrue(a.TryGetValue("name", StringComparison.Ordinal, out v)); Assert.AreEqual("name!", (string)v); Assert.IsFalse(a.TryGetValue(null, StringComparison.Ordinal, out v)); } public class FooJsonConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var token = JToken.FromObject(value, new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver() }); if (token.Type == JTokenType.Object) { var o = (JObject)token; o.AddFirst(new JProperty("foo", "bar")); o.WriteTo(writer); } else { token.WriteTo(writer); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotSupportedException("This custom converter only supportes serialization and not deserialization."); } public override bool CanRead { get { return false; } } public override bool CanConvert(Type objectType) { return true; } } [Test] public void FromObjectInsideConverterWithCustomSerializer() { var p = new Person { Name = "Daniel Wertheim", }; var settings = new JsonSerializerSettings { Converters = new List { new FooJsonConverter() }, ContractResolver = new CamelCasePropertyNamesContractResolver() }; var json = JsonConvert.SerializeObject(p, settings); Assert.AreEqual(@"{""foo"":""bar"",""name"":""Daniel Wertheim"",""birthDate"":""0001-01-01T00:00:00"",""lastModified"":""0001-01-01T00:00:00""}", json); } [Test] public void Parse_NoComments() { string json = "{'prop':[1,2/*comment*/,3]}"; JObject o = JObject.Parse(json, new JsonLoadSettings { CommentHandling = CommentHandling.Ignore }); Assert.AreEqual(3, o["prop"].Count()); Assert.AreEqual(1, (int)o["prop"][0]); Assert.AreEqual(2, (int)o["prop"][1]); Assert.AreEqual(3, (int)o["prop"][2]); } [Test] public void Parse_ExcessiveContentJustComments() { string json = @"{'prop':[1,2,3]}/*comment*/ //Another comment."; JObject o = JObject.Parse(json); Assert.AreEqual(3, o["prop"].Count()); Assert.AreEqual(1, (int)o["prop"][0]); Assert.AreEqual(2, (int)o["prop"][1]); Assert.AreEqual(3, (int)o["prop"][2]); } [Test] public void Parse_ExcessiveContent() { string json = @"{'prop':[1,2,3]}/*comment*/ //Another comment. []"; ExceptionAssert.Throws(() => JObject.Parse(json), "Additional text encountered after finished reading JSON content: [. Path '', line 3, position 0."); } } }