-Fixed JValue.CompareTo with number and string values

This commit is contained in:
James Newton-King
2017-07-22 13:41:14 +12:00
parent bbbddf0031
commit ad1a13728a
4 changed files with 220 additions and 3 deletions
@@ -858,5 +858,117 @@ namespace Newtonsoft.Json.Tests.Linq
ValueA
}
#endif
[Test]
public void CompareTo_MismatchedTypes()
{
JValue v1 = new JValue(1);
JValue v2 = new JValue("2");
Assert.AreEqual(-1, v1.CompareTo(v2));
Assert.AreEqual(-1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(1, v2.CompareTo(v1));
Assert.AreEqual(1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(1.5);
v2 = new JValue("2");
Assert.AreEqual(-1, v1.CompareTo(v2));
Assert.AreEqual(-1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(1, v2.CompareTo(v1));
Assert.AreEqual(1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(1.5m);
v2 = new JValue("2");
Assert.AreEqual(-1, v1.CompareTo(v2));
Assert.AreEqual(-1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(1, v2.CompareTo(v1));
Assert.AreEqual(1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(1.5m);
v2 = new JValue(2);
Assert.AreEqual(-1, v1.CompareTo(v2));
Assert.AreEqual(-1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(1, v2.CompareTo(v1));
Assert.AreEqual(1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(1.5m);
v2 = new JValue(2.1);
Assert.AreEqual(-1, v1.CompareTo(v2));
Assert.AreEqual(-1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(1, v2.CompareTo(v1));
Assert.AreEqual(1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(2);
v2 = new JValue("2");
Assert.AreEqual(0, v1.CompareTo(v2));
Assert.AreEqual(0, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(0, v2.CompareTo(v1));
Assert.AreEqual(0, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(2);
v2 = new JValue(2m);
Assert.AreEqual(0, v1.CompareTo(v2));
Assert.AreEqual(0, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(0, v2.CompareTo(v1));
Assert.AreEqual(0, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(2f);
v2 = new JValue(2m);
Assert.AreEqual(0, v1.CompareTo(v2));
Assert.AreEqual(0, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(0, v2.CompareTo(v1));
Assert.AreEqual(0, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(2);
v2 = new JValue("10");
Assert.AreEqual(-1, v1.CompareTo(v2));
Assert.AreEqual(-1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(1, v2.CompareTo(v1));
Assert.AreEqual(1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue(2);
v2 = new JValue((object)null);
Assert.AreEqual(1, v1.CompareTo(v2));
Assert.AreEqual(1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(-1, v2.CompareTo(v1));
Assert.AreEqual(-1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue("2");
v2 = new JValue((object)null);
Assert.AreEqual(1, v1.CompareTo(v2));
Assert.AreEqual(1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(-1, v2.CompareTo(v1));
Assert.AreEqual(-1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue((object)null);
v2 = new JValue("2");
Assert.AreEqual(-1, v1.CompareTo(v2));
Assert.AreEqual(-1, ((IComparable)v1).CompareTo(v2));
Assert.AreEqual(1, v2.CompareTo(v1));
Assert.AreEqual(1, ((IComparable)v2).CompareTo(v1));
v1 = new JValue("2");
v2 = null;
Assert.AreEqual(1, v1.CompareTo(v2));
Assert.AreEqual(1, ((IComparable)v1).CompareTo(v2));
v1 = new JValue((object)null);
v2 = null;
Assert.AreEqual(1, v1.CompareTo(v2));
Assert.AreEqual(1, ((IComparable)v1).CompareTo(v2));
}
}
}
@@ -51,6 +51,52 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
[TestFixture]
public class JPathExecuteTests : TestFixtureBase
{
[Test]
public void GreaterThanWithIntegerParameterAndStringValue()
{
string json = @"{
""persons"": [
{
""name"" : ""John"",
""age"": ""26""
},
{
""name"" : ""Jane"",
""age"": ""2""
}
]
}";
JObject models = JObject.Parse(json);
var results = models.SelectTokens("$.persons[?(@.age > 3)]").ToList();
Assert.AreEqual(1, results.Count);
}
[Test]
public void GreaterThanWithStringParameterAndIntegerValue()
{
string json = @"{
""persons"": [
{
""name"" : ""John"",
""age"": 26
},
{
""name"" : ""Jane"",
""age"": 2
}
]
}";
JObject models = JObject.Parse(json);
var results = models.SelectTokens("$.persons[?(@.age > '3')]").ToList();
Assert.AreEqual(1, results.Count);
}
[Test]
public void RecursiveWildcard()
{
@@ -175,6 +175,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.IsTrue(e1.IsMatch(null, new JArray(2, 3, 4, 5)));
Assert.IsFalse(e1.IsMatch(null, new JArray(3, 4, 5)));
Assert.IsFalse(e1.IsMatch(null, new JArray(4, 5)));
Assert.IsFalse(e1.IsMatch(null, new JArray("11", 5)));
BooleanQueryExpression e2 = new BooleanQueryExpression
{
@@ -190,6 +191,47 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.IsTrue(e2.IsMatch(null, new JArray(2, 3, 4, 5)));
Assert.IsTrue(e2.IsMatch(null, new JArray(3, 4, 5)));
Assert.IsFalse(e2.IsMatch(null, new JArray(4, 5)));
Assert.IsFalse(e1.IsMatch(null, new JArray("11", 5)));
}
[Test]
public void BooleanExpressionTest_GreaterThanOperator()
{
BooleanQueryExpression e1 = new BooleanQueryExpression
{
Operator = QueryOperator.GreaterThan,
Right = new JValue(3),
Left = new List<PathFilter>
{
new ArrayIndexFilter()
}
};
Assert.IsTrue(e1.IsMatch(null, new JArray("2", "26")));
Assert.IsTrue(e1.IsMatch(null, new JArray(2, 26)));
Assert.IsFalse(e1.IsMatch(null, new JArray(2, 3)));
Assert.IsFalse(e1.IsMatch(null, new JArray("2", "3")));
}
[Test]
public void BooleanExpressionTest_GreaterThanOrEqualsOperator()
{
BooleanQueryExpression e1 = new BooleanQueryExpression
{
Operator = QueryOperator.GreaterThanOrEquals,
Right = new JValue(3),
Left = new List<PathFilter>
{
new ArrayIndexFilter()
}
};
Assert.IsTrue(e1.IsMatch(null, new JArray("2", "26")));
Assert.IsTrue(e1.IsMatch(null, new JArray(2, 26)));
Assert.IsTrue(e1.IsMatch(null, new JArray(2, 3)));
Assert.IsTrue(e1.IsMatch(null, new JArray("2", "3")));
Assert.IsFalse(e1.IsMatch(null, new JArray(2, 1)));
Assert.IsFalse(e1.IsMatch(null, new JArray("2", "1")));
}
}
}
+20 -3
View File
@@ -1043,9 +1043,22 @@ namespace Newtonsoft.Json.Linq
}
JValue value = obj as JValue;
object otherValue = value != null ? value.Value : obj;
JTokenType comparisonType;
object otherValue;
if (value != null)
{
otherValue = value.Value;
comparisonType = (_valueType == JTokenType.String && _valueType != value._valueType)
? value._valueType
: _valueType;
}
else
{
otherValue = obj;
comparisonType = _valueType;
}
return Compare(_valueType, _value, otherValue);
return Compare(comparisonType, _value, otherValue);
}
/// <summary>
@@ -1073,7 +1086,11 @@ namespace Newtonsoft.Json.Linq
return 1;
}
return Compare(_valueType, _value, obj._value);
JTokenType comparisonType = (_valueType == JTokenType.String && _valueType != obj._valueType)
? obj._valueType
: _valueType;
return Compare(comparisonType, _value, obj._value);
}
#if HAVE_ICONVERTIBLE