//
// Authors:
// Federico Di Gregorio <fog@initd.org>
+// Jb Evain <jbevain@novell.com>
using System;
using System.Reflection;
[ExpectedException (typeof (InvalidOperationException))]
public void NonNullLeftParameter ()
{
- // This throws because they are both doubles, which are never
+ // This throws because they are both doubles, which are never
Expression.Coalesce (Expression.Constant (1.0), Expression.Constant (2.0));
}
}
[Test]
- public void Coalesce_1 ()
+ public void IsCoalesceStringLifted ()
{
- // Build the expression by hand for now:
- ParameterExpression pa = Expression.Parameter (typeof (int?), "a");
- ParameterExpression pb = Expression.Parameter (typeof (int?), "b");
- BinaryExpression c = Expression.Coalesce (pa, pb);
-
- Expression<Func<int?, int?, int?>> e = Expression.Lambda<Func<int?,int?,int?>>(
- c, new ParameterExpression [] { pa, pb });
+ var coalesce = Expression.Coalesce (
+ Expression.Parameter (typeof (string), "a"),
+ Expression.Parameter (typeof (string), "b"));
- Func<int?,int?,int?> comp = e.Compile ();
+ Assert.AreEqual ("(a ?? b)", coalesce.ToString ());
- Assert.AreEqual (10, comp (10, 20));
+ Assert.IsFalse (coalesce.IsLifted);
+ Assert.IsFalse (coalesce.IsLiftedToNull);
+ }
+
+ [Test]
+ public void IsCoalesceNullableIntLifted ()
+ {
+ var coalesce = Expression.Coalesce (
+ Expression.Parameter (typeof (int?), "a"),
+ Expression.Parameter (typeof (int?), "b"));
+
+ Assert.IsFalse (coalesce.IsLifted);
+ Assert.IsFalse (coalesce.IsLiftedToNull);
+ }
+
+ [Test]
+ [Category ("NotWorkingInterpreter")]
+ public void CoalesceNullableInt ()
+ {
+ var a = Expression.Parameter (typeof (int?), "a");
+ var b = Expression.Parameter (typeof (int?), "b");
+ var coalesce = Expression.Lambda<Func<int?, int?, int?>> (
+ Expression.Coalesce (a, b), a, b).Compile ();
+
+ Assert.AreEqual ((int?) 1, coalesce (1, 2));
+ Assert.AreEqual ((int?) null, coalesce (null, null));
+ Assert.AreEqual ((int?) 2, coalesce (null, 2));
+ Assert.AreEqual ((int?) 2, coalesce (2, null));
+ }
+
+ [Test]
+ public void CoalesceString ()
+ {
+ var a = Expression.Parameter (typeof (string), "a");
+ var b = Expression.Parameter (typeof (string), "b");
+ var coalesce = Expression.Lambda<Func<string, string, string>> (
+ Expression.Coalesce (a, b), a, b).Compile ();
+
+ Assert.AreEqual ("foo", coalesce ("foo", "bar"));
+ Assert.AreEqual (null, coalesce (null, null));
+ Assert.AreEqual ("bar", coalesce (null, "bar"));
+ Assert.AreEqual ("foo", coalesce ("foo", null));
+ }
+
+ [Test]
+ [Category ("NotWorkingInterpreter")]
+ public void CoalesceNullableToNonNullable ()
+ {
+ var a = Expression.Parameter (typeof (int?), "a");
+
+ var node = Expression.Coalesce (a, Expression.Constant (99, typeof (int)));
+
+ Assert.AreEqual (typeof (int), node.Type);
+ Assert.IsFalse (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+
+ var coalesce = Expression.Lambda<Func<int?, int>> (node, a).Compile ();
+
+ Assert.AreEqual (5, coalesce (5));
+ Assert.AreEqual (99, coalesce (null));
+ }
+
+ [Test]
+ [Category ("NotWorkingInterpreter")]
+ [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=349822
+ public void CoalesceUserDefinedConversion ()
+ {
+ var s = Expression.Parameter (typeof (string), "s");
+
+ var coalesce = Expression.Lambda<Func<string, int>> (
+ Expression.Coalesce (
+ s,
+ Expression.Constant (42),
+ Expression.Lambda<Func<string, int>> (
+ Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s)), s).Compile ();
+
+ Assert.AreEqual (12, coalesce ("12"));
+ Assert.AreEqual (42, coalesce (null));
+ }
+
+ struct Slot {
+ int Value;
+
+ public Slot (int v)
+ {
+ Value = v;
+ }
+
+ public static implicit operator int (Slot s)
+ {
+ return s.Value;
+ }
+ }
+
+ [Test]
+ // #12987
+ [Category ("MobileNotWorking")]
+ [Category ("NotWorkingInterpreter")]
+ public void CoalesceNullableSlotIntoInteger ()
+ {
+ var s = Expression.Parameter (typeof (Slot?), "s");
+
+ var method = typeof (Slot).GetMethod ("op_Implicit");
+
+ var coalesce = Expression.Lambda<Func<Slot?, int>> (
+ Expression.Coalesce (
+ s,
+ Expression.Constant (-3),
+ Expression.Lambda (
+ Expression.Convert (s, typeof (int), method),
+ s)), s).Compile ();
+
+ Assert.AreEqual (-3, coalesce (null));
+ Assert.AreEqual (42, coalesce (new Slot (42)));
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void WrongCoalesceConversionParameterCount ()
+ {
+ var s = Expression.Parameter (typeof (string), "s");
+ var p = Expression.Parameter (typeof (string), "foo");
+
+ Expression.Coalesce (
+ s,
+ 42.ToConstant (),
+ Expression.Lambda<Func<string, string, int>> (
+ Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s, p));
+
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void WrongCoalesceConversionParameterType ()
+ {
+ var s = Expression.Parameter (typeof (string), "s");
+ var i = Expression.Parameter (typeof (int), "i");
+
+ Expression.Coalesce (
+ s,
+ 42.ToConstant (),
+ Expression.Lambda<Func<int, int>> (
+ i, i));
+
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void WrongCoalesceConversionReturnType ()
+ {
+ var s = Expression.Parameter (typeof (string), "s");
+
+ Expression.Coalesce (
+ s,
+ 42.ToConstant (),
+ Expression.Lambda<Func<string, string>> (
+ s, s));
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void CoalesceVoidUserDefinedConversion ()
+ {
+ var s = Expression.Parameter (typeof (string), "s");
+
+ Expression.Coalesce (
+ s,
+ 42.ToConstant (),
+ Expression.Lambda<Action<string>> (
+ Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s));
}
}
}