-Added add/subtract/multiply/divide to dynamic JValue
This commit is contained in:
@@ -168,6 +168,282 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.IsTrue(d.Bytes == new JValue(Encoding.UTF8.GetBytes("A string lol!")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JValueAddition()
|
||||
{
|
||||
JObject o = new JObject(
|
||||
new JProperty("Null", new JValue(null, JTokenType.Null)),
|
||||
new JProperty("Integer", new JValue(1)),
|
||||
new JProperty("Float", new JValue(1.1d)),
|
||||
new JProperty("Decimal", new JValue(1.1m)),
|
||||
new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))),
|
||||
new JProperty("Boolean", new JValue(true)),
|
||||
new JProperty("String", new JValue("A string lol!")),
|
||||
new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!")))
|
||||
);
|
||||
|
||||
dynamic d = o;
|
||||
dynamic r;
|
||||
|
||||
#region Add
|
||||
r = d.String + " LAMO!";
|
||||
Assert.AreEqual("A string lol! LAMO!", (string)r);
|
||||
r += " gg";
|
||||
Assert.AreEqual("A string lol! LAMO! gg", (string)r);
|
||||
|
||||
r = d.String + null;
|
||||
Assert.AreEqual("A string lol!", (string)r);
|
||||
r += null;
|
||||
Assert.AreEqual("A string lol!", (string)r);
|
||||
|
||||
r = d.Integer + 1;
|
||||
Assert.AreEqual(2, (int)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4, (int)r);
|
||||
|
||||
r = d.Integer + 1.1;
|
||||
Assert.AreEqual(2.1, (double)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4.1, (double)r);
|
||||
|
||||
r = d.Integer + 1.1d;
|
||||
Assert.AreEqual(2.1, (decimal)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4.1, (decimal)r);
|
||||
|
||||
r = d.Integer + null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r += 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
|
||||
r = d.Float + 1;
|
||||
Assert.AreEqual(2.1, (double)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4.1, (double)r);
|
||||
|
||||
r = d.Float + 1.1;
|
||||
Assert.AreEqual(2.2, (double)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4.2, (double)r);
|
||||
|
||||
r = d.Float + 1.1d;
|
||||
Assert.AreEqual(2.2, (decimal)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4.2, (decimal)r);
|
||||
|
||||
r = d.Float + null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r += 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
|
||||
r = d.Decimal + 1;
|
||||
Assert.AreEqual(2.1, (decimal)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4.1, (decimal)r);
|
||||
|
||||
r = d.Decimal + 1.1;
|
||||
Assert.AreEqual(2.2, (decimal)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4.2, (decimal)r);
|
||||
|
||||
r = d.Decimal + 1.1d;
|
||||
Assert.AreEqual(2.2, (decimal)r);
|
||||
r += 2;
|
||||
Assert.AreEqual(4.2, (decimal)r);
|
||||
|
||||
r = d.Decimal + null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r += 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
#endregion
|
||||
|
||||
#region Subtract
|
||||
r = d.Integer - 1;
|
||||
Assert.AreEqual(0, (int)r);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-2, (int)r);
|
||||
|
||||
r = d.Integer - 1.1;
|
||||
Assert.AreEqual(-0.1, (double)r, 0.00001);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-2.1, (double)r);
|
||||
|
||||
r = d.Integer - 1.1d;
|
||||
Assert.AreEqual(-0.1, (decimal)r);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-2.1, (decimal)r);
|
||||
|
||||
r = d.Integer - null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r -= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
|
||||
r = d.Float - 1;
|
||||
Assert.AreEqual(0.1, (double)r, 0.00001);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-1.9, (double)r);
|
||||
|
||||
r = d.Float - 1.1;
|
||||
Assert.AreEqual(0, (double)r);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-2, (double)r);
|
||||
|
||||
r = d.Float - 1.1d;
|
||||
Assert.AreEqual(0, (decimal)r);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-2, (decimal)r);
|
||||
|
||||
r = d.Float - null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r -= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
|
||||
r = d.Decimal - 1;
|
||||
Assert.AreEqual(0.1, (decimal)r);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-1.9, (decimal)r);
|
||||
|
||||
r = d.Decimal - 1.1;
|
||||
Assert.AreEqual(0, (decimal)r);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-2, (decimal)r);
|
||||
|
||||
r = d.Decimal - 1.1d;
|
||||
Assert.AreEqual(0, (decimal)r);
|
||||
r -= 2;
|
||||
Assert.AreEqual(-2, (decimal)r);
|
||||
|
||||
r = d.Decimal - null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r -= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
#endregion
|
||||
|
||||
#region Multiply
|
||||
r = d.Integer * 1;
|
||||
Assert.AreEqual(1, (int)r);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2, (int)r);
|
||||
|
||||
r = d.Integer * 1.1;
|
||||
Assert.AreEqual(1.1, (double)r);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2.2, (double)r);
|
||||
|
||||
r = d.Integer * 1.1d;
|
||||
Assert.AreEqual(1.1, (decimal)r);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2.2, (decimal)r);
|
||||
|
||||
r = d.Integer * null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r *= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
|
||||
r = d.Float * 1;
|
||||
Assert.AreEqual(1.1, (double)r);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2.2, (double)r);
|
||||
|
||||
r = d.Float * 1.1;
|
||||
Assert.AreEqual(1.21, (double)r, 0.00001);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2.42, (double)r, 0.00001);
|
||||
|
||||
r = d.Float * 1.1d;
|
||||
Assert.AreEqual(1.21, (decimal)r);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2.42, (decimal)r);
|
||||
|
||||
r = d.Float * null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r *= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
|
||||
r = d.Decimal * 1;
|
||||
Assert.AreEqual(1.1, (decimal)r);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2.2, (decimal)r);
|
||||
|
||||
r = d.Decimal * 1.1;
|
||||
Assert.AreEqual(1.21, (decimal)r);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2.42, (decimal)r);
|
||||
|
||||
r = d.Decimal * 1.1d;
|
||||
Assert.AreEqual(1.21, (decimal)r);
|
||||
r *= 2;
|
||||
Assert.AreEqual(2.42, (decimal)r);
|
||||
|
||||
r = d.Decimal * null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r *= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
#endregion
|
||||
|
||||
#region Divide
|
||||
r = d.Integer / 1;
|
||||
Assert.AreEqual(1, (int)r);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0, (int)r);
|
||||
|
||||
r = d.Integer / 1.1;
|
||||
Assert.AreEqual(0.9090909090909091, (double)r);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0.454545454545455, (double)r, 0.00001);
|
||||
|
||||
r = d.Integer / 1.1d;
|
||||
Assert.AreEqual(0.909090909090909m, (decimal)r);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0.454545454545454m, (decimal)r);
|
||||
|
||||
r = d.Integer / null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r /= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
|
||||
r = d.Float / 1;
|
||||
Assert.AreEqual(1.1, (double)r);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0.55, (double)r);
|
||||
|
||||
r = d.Float / 1.1;
|
||||
Assert.AreEqual(1, (double)r, 0.00001);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0.5, (double)r, 0.00001);
|
||||
|
||||
r = d.Float / 1.1d;
|
||||
Assert.AreEqual(1m, (decimal)r);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0.5m, (decimal)r);
|
||||
|
||||
r = d.Float / null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r /= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
|
||||
r = d.Decimal / 1;
|
||||
Assert.AreEqual(1.1d, (decimal)r);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0.55d, (decimal)r);
|
||||
|
||||
r = d.Decimal / 1.1;
|
||||
Assert.AreEqual(1d, (decimal)r);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0.5d, (decimal)r);
|
||||
|
||||
r = d.Decimal / 1.1d;
|
||||
Assert.AreEqual(1d, (decimal)r);
|
||||
r /= 2;
|
||||
Assert.AreEqual(0.5d, (decimal)r);
|
||||
|
||||
r = d.Decimal / null;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
r /= 2;
|
||||
Assert.AreEqual(null, r.Value);
|
||||
#endregion
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JValueToString()
|
||||
{
|
||||
|
||||
@@ -227,6 +227,118 @@ namespace Newtonsoft.Json.Linq
|
||||
return d1.CompareTo(d2);
|
||||
}
|
||||
|
||||
#if !(NET35 || NET20 || WINDOWS_PHONE)
|
||||
private static bool Operation(ExpressionType operation, object objA, object objB, out object result)
|
||||
{
|
||||
if (objA is string || objB is string)
|
||||
{
|
||||
if (operation == ExpressionType.Add || operation == ExpressionType.AddAssign)
|
||||
{
|
||||
result = ((objA != null) ? objA.ToString() : null) + ((objB != null) ? objB.ToString() : null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
|
||||
{
|
||||
if (objA == null || objB == null)
|
||||
{
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
decimal d1 = Convert.ToDecimal(objA, CultureInfo.InvariantCulture);
|
||||
decimal d2 = Convert.ToDecimal(objB, CultureInfo.InvariantCulture);
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case ExpressionType.Add:
|
||||
case ExpressionType.AddAssign:
|
||||
result = d1 + d2;
|
||||
return true;
|
||||
case ExpressionType.Subtract:
|
||||
case ExpressionType.SubtractAssign:
|
||||
result = d1 - d2;
|
||||
return true;
|
||||
case ExpressionType.Multiply:
|
||||
case ExpressionType.MultiplyAssign:
|
||||
result = d1 * d2;
|
||||
return true;
|
||||
case ExpressionType.Divide:
|
||||
case ExpressionType.DivideAssign:
|
||||
result = d1 / d2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (objA is float || objB is float || objA is double || objB is double)
|
||||
{
|
||||
if (objA == null || objB == null)
|
||||
{
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture);
|
||||
double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture);
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case ExpressionType.Add:
|
||||
case ExpressionType.AddAssign:
|
||||
result = d1 + d2;
|
||||
return true;
|
||||
case ExpressionType.Subtract:
|
||||
case ExpressionType.SubtractAssign:
|
||||
result = d1 - d2;
|
||||
return true;
|
||||
case ExpressionType.Multiply:
|
||||
case ExpressionType.MultiplyAssign:
|
||||
result = d1 * d2;
|
||||
return true;
|
||||
case ExpressionType.Divide:
|
||||
case ExpressionType.DivideAssign:
|
||||
result = d1 / d2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (objA is int || objA is uint || objA is long || objA is short || objA is ushort || objA is sbyte || objA is byte ||
|
||||
objB is int || objB is uint || objB is long || objB is short || objB is ushort || objB is sbyte || objB is byte)
|
||||
{
|
||||
if (objA == null || objB == null)
|
||||
{
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
long l1 = Convert.ToInt64(objA, CultureInfo.InvariantCulture);
|
||||
long l2 = Convert.ToInt64(objB, CultureInfo.InvariantCulture);
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case ExpressionType.Add:
|
||||
case ExpressionType.AddAssign:
|
||||
result = l1 + l2;
|
||||
return true;
|
||||
case ExpressionType.Subtract:
|
||||
case ExpressionType.SubtractAssign:
|
||||
result = l1 - l2;
|
||||
return true;
|
||||
case ExpressionType.Multiply:
|
||||
case ExpressionType.MultiplyAssign:
|
||||
result = l1 * l2;
|
||||
return true;
|
||||
case ExpressionType.Divide:
|
||||
case ExpressionType.DivideAssign:
|
||||
result = l1 / l2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
internal override JToken CloneToken()
|
||||
{
|
||||
return new JValue(this);
|
||||
@@ -565,6 +677,20 @@ namespace Newtonsoft.Json.Linq
|
||||
case ExpressionType.LessThanOrEqual:
|
||||
result = (Compare(instance.Type, instance.Value, compareValue) <= 0);
|
||||
return true;
|
||||
case ExpressionType.Add:
|
||||
case ExpressionType.AddAssign:
|
||||
case ExpressionType.Subtract:
|
||||
case ExpressionType.SubtractAssign:
|
||||
case ExpressionType.Multiply:
|
||||
case ExpressionType.MultiplyAssign:
|
||||
case ExpressionType.Divide:
|
||||
case ExpressionType.DivideAssign:
|
||||
if (Operation(binder.Operation, instance.Value, compareValue, out result))
|
||||
{
|
||||
result = new JValue(result);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
result = null;
|
||||
|
||||
Reference in New Issue
Block a user