-Fixed comparing JObjects to ignore property order

This commit is contained in:
James Newton-King
2012-04-09 16:20:42 +12:00
parent 13fe57bd44
commit 2e1211f689
8 changed files with 102 additions and 20 deletions
@@ -1746,5 +1746,55 @@ Parameter name: arrayIndex"
JObject o = JObject.Parse(json);
});
}
[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));
}
}
}
@@ -72,5 +72,5 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.1.14808")]
[assembly: AssemblyFileVersion("4.5.1.14809")]
#endif
+11 -17
View File
@@ -170,28 +170,22 @@ namespace Newtonsoft.Json.Linq
internal bool ContentsEqual(JContainer container)
{
JToken t1 = First;
JToken t2 = container.First;
if (t1 == t2)
if (container == this)
return true;
do
{
if (t1 == null && t2 == null)
return true;
IList<JToken> t1 = ChildrenTokens;
IList<JToken> t2 = container.ChildrenTokens;
if (t1 != null && t2 != null && t1.DeepEquals(t2))
{
t1 = (t1 != Last) ? t1.Next : null;
t2 = (t2 != container.Last) ? t2.Next : null;
}
else
{
if (t1.Count != t2.Count)
return false;
for (int i = 0; i < t1.Count; i++)
{
if (!t1[i].DeepEquals(t2[i]))
return false;
}
}
while (true);
return true;
}
/// <summary>
+4 -1
View File
@@ -114,7 +114,10 @@ namespace Newtonsoft.Json.Linq
internal override bool DeepEquals(JToken node)
{
JObject t = node as JObject;
return (t != null && ContentsEqual(t));
if (t == null)
return false;
return _properties.Compare(t._properties);
}
internal override void InsertItem(int index, JToken item, bool skipParentCheck)
@@ -164,5 +164,34 @@ namespace Newtonsoft.Json.Linq
return _dictionary.Values;
}
}
public bool Compare(JPropertyKeyedCollection other)
{
if (this == other)
return true;
// dictionaries in JavaScript aren't ordered
// ignore order when comparing properties
Dictionary<string, JToken> d1 = _dictionary;
Dictionary<string, JToken> d2 = other._dictionary;
if (d1.Count != d2.Count)
return false;
foreach (KeyValuePair<string, JToken> keyAndProperty in d1)
{
JToken secondValue;
if (!d2.TryGetValue(keyAndProperty.Key, out secondValue))
return false;
JProperty p1 = (JProperty)keyAndProperty.Value;
JProperty p2 = (JProperty)secondValue;
if (!p1.Value.DeepEquals(p2.Value))
return false;
}
return true;
}
}
}
+4
View File
@@ -208,7 +208,9 @@ namespace Newtonsoft.Json.Linq
yield break;
for (JToken o = Next; o != null; o = o.Next)
{
yield return o;
}
}
/// <summary>
@@ -218,7 +220,9 @@ namespace Newtonsoft.Json.Linq
public IEnumerable<JToken> BeforeSelf()
{
for (JToken o = Parent.First; o != this; o = o.Next)
{
yield return o;
}
}
/// <summary>
+2
View File
@@ -153,6 +153,8 @@ namespace Newtonsoft.Json.Linq
JValue other = node as JValue;
if (other == null)
return false;
if (other == this)
return true;
return ValuesEquals(this, other);
}
@@ -88,7 +88,7 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.1.14808")]
[assembly: AssemblyFileVersion("4.5.1.14809")]
#endif
[assembly: CLSCompliant(true)]