-Fixed writing Uri JValues to use OriginalString to be consistant with serializer

-Fixed comparing non-string JValues with JPath queries
This commit is contained in:
James Newton-King
2015-09-05 15:24:30 +12:00
parent 30265076bb
commit 4baf2a751f
5 changed files with 132 additions and 4 deletions
@@ -701,6 +701,22 @@ namespace Newtonsoft.Json.Tests.Linq
}
#endif
[Test]
public void ToStringUri()
{
JArray a = new JArray(
new JValue(new Uri("http://james.newtonking.com")),
new JValue(new Uri("http://james.newtonking.com/install?v=7.0.1"))
);
Console.WriteLine(a.ToString());
StringAssert.AreEqual(@"[
""http://james.newtonking.com"",
""http://james.newtonking.com/install?v=7.0.1""
]", a.ToString());
}
#if !NET20
[Test]
public void ParseIsoTimeZones()
@@ -25,6 +25,7 @@
using System;
using System.Collections.Generic;
using System.Text;
#if !(PORTABLE || PORTABLE40 || NET35 || NET20)
using System.Numerics;
#endif
@@ -739,6 +740,55 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual(1L, v.Value);
}
[Test]
public void QueryAgainstNonStringValues()
{
IList<object> values = new List<object>
{
"ff2dc672-6e15-4aa2-afb0-18f4f69596ad",
Guid.Parse("ff2dc672-6e15-4aa2-afb0-18f4f69596ad"),
"http://localhost",
new Uri("http://localhost"),
"2000-12-05T05:07:59Z",
new DateTime(2000, 12, 5, 5, 7, 59, DateTimeKind.Utc),
#if !NET20
"2000-12-05T05:07:59-10:00",
new DateTimeOffset(2000, 12, 5, 5, 7, 59, -TimeSpan.FromHours(10)),
#endif
"SGVsbG8gd29ybGQ=",
Encoding.UTF8.GetBytes("Hello world"),
"365.23:59:59",
new TimeSpan(365, 23, 59, 59)
};
JObject o = new JObject(
new JProperty("prop",
new JArray(
values.Select(v => new JObject(new JProperty("childProp", v)))
)
)
);
IList<JToken> t = o.SelectTokens("$.prop[?(@.childProp =='ff2dc672-6e15-4aa2-afb0-18f4f69596ad')]").ToList();
Assert.AreEqual(2, t.Count);
t = o.SelectTokens("$.prop[?(@.childProp =='http://localhost')]").ToList();
Assert.AreEqual(2, t.Count);
t = o.SelectTokens("$.prop[?(@.childProp =='2000-12-05T05:07:59Z')]").ToList();
Assert.AreEqual(2, t.Count);
#if !NET20
t = o.SelectTokens("$.prop[?(@.childProp =='2000-12-05T05:07:59-10:00')]").ToList();
Assert.AreEqual(2, t.Count);
#endif
t = o.SelectTokens("$.prop[?(@.childProp =='SGVsbG8gd29ybGQ=')]").ToList();
Assert.AreEqual(2, t.Count);
t = o.SelectTokens("$.prop[?(@.childProp =='365.23:59:59')]").ToList();
Assert.AreEqual(2, t.Count);
}
[Test]
public void Example()
@@ -1235,7 +1235,7 @@ keyword such as type of business.""
""NullableGuid"": ""9e9f3adf-e017-4f72-91e0-617ebe85967d"",
""TimeSpan"": ""1.00:00:00"",
""NullableTimeSpan"": ""01:00:00"",
""Uri"": ""http://testuri.com/""
""Uri"": ""http://testuri.com""
}", o.ToString());
UriGuidTimeSpanTestClass c2 = o.ToObject<UriGuidTimeSpanTestClass>();
@@ -1244,6 +1244,10 @@ keyword such as type of business.""
Assert.AreEqual(c1.TimeSpan, c2.TimeSpan);
Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan);
Assert.AreEqual(c1.Uri, c2.Uri);
string j = JsonConvert.SerializeObject(c1, Formatting.Indented);
StringAssert.AreEqual(j, o.ToString());
}
[Test]
+3 -1
View File
@@ -717,10 +717,12 @@ namespace Newtonsoft.Json.Linq
writer.WriteValue((byte[])_value);
return;
case JTokenType.Guid:
case JTokenType.Uri:
case JTokenType.TimeSpan:
writer.WriteValue((_value != null) ? _value.ToString() : null);
return;
case JTokenType.Uri:
writer.WriteValue((_value != null) ? ((Uri) _value).OriginalString : null);
return;
}
throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type.");
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Linq.JsonPath
{
@@ -72,11 +75,11 @@ namespace Newtonsoft.Json.Linq.JsonPath
switch (Operator)
{
case QueryOperator.Equals:
if (v != null && v.Equals(Value))
if (v != null && EqualsWithStringCoercion(v, Value))
return true;
break;
case QueryOperator.NotEquals:
if (v != null && !v.Equals(Value))
if (v != null && !EqualsWithStringCoercion(v, Value))
return true;
break;
case QueryOperator.GreaterThan:
@@ -104,5 +107,58 @@ namespace Newtonsoft.Json.Linq.JsonPath
return false;
}
private bool EqualsWithStringCoercion(JValue value, JValue queryValue)
{
if (value.Equals(queryValue))
{
return true;
}
if (queryValue.Type != JTokenType.String)
{
return false;
}
string queryValueString = (string)queryValue.Value;
string currentValueString;
// potential performance issue with converting every value to string?
switch (value.Type)
{
case JTokenType.Date:
using (StringWriter writer = StringUtils.CreateStringWriter(64))
{
#if !NET20
if (value.Value is DateTimeOffset)
{
DateTimeUtils.WriteDateTimeOffsetString(writer, (DateTimeOffset)value.Value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
}
else
#endif
{
DateTimeUtils.WriteDateTimeString(writer, (DateTime)value.Value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
}
currentValueString = writer.ToString();
}
break;
case JTokenType.Bytes:
currentValueString = Convert.ToBase64String((byte[])value.Value);
break;
case JTokenType.Guid:
case JTokenType.TimeSpan:
currentValueString = value.Value.ToString();
break;
case JTokenType.Uri:
currentValueString = ((Uri)value.Value).OriginalString;
break;
default:
return false;
}
return string.Equals(currentValueString, queryValueString, StringComparison.Ordinal);
}
}
}