-Added add/subtract/multiply/divide to dynamic JValue

This commit is contained in:
JamesNK
2011-04-10 01:25:09 +00:00
parent b476a8d0fc
commit 1ab8f8b686
2 changed files with 402 additions and 0 deletions
@@ -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()
{
+126
View File
@@ -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;