//
// Authors:
// Federico Di Gregorio <fog@initd.org>
+// Jb Evain <jbevain@novell.com>
using System;
using System.Reflection;
Assert.AreEqual (ExpressionType.AndAlso, expr.NodeType, "AndAlso#01");
Assert.AreEqual (typeof (bool), expr.Type, "AndAlso#02");
Assert.IsNull (expr.Method, "AndAlso#03");
+#if !NET_4_0
Assert.AreEqual ("(True && False)", expr.ToString(), "AndAlso#04");
+#endif
}
[Test]
Assert.AreEqual (typeof (OpClass), expr.Type, "AndAlso#06");
Assert.AreEqual (mi, expr.Method, "AndAlso#07");
Assert.AreEqual ("op_BitwiseAnd", expr.Method.Name, "AndAlso#08");
+#if !NET_4_0
Assert.AreEqual ("(value(MonoTests.System.Linq.Expressions.OpClass) && value(MonoTests.System.Linq.Expressions.OpClass))",
expr.ToString(), "AndAlso#09");
+#endif
}
[Test]
public void AndAlsoTest ()
{
- ParameterExpression a = Expression.Parameter (typeof (bool), "a"), b = Expression.Parameter (typeof (bool), "b");
+ var a = Expression.Parameter (typeof (bool), "a");
+ var b = Expression.Parameter (typeof (bool), "b");
var l = Expression.Lambda<Func<bool, bool, bool>> (
Expression.AndAlso (a, b), a, b);
}
[Test]
- [Category ("NotWorking")]
public void AndAlsoTestNullable ()
{
- ParameterExpression a = Expression.Parameter (typeof (bool?), "a"), b = Expression.Parameter (typeof (bool?), "b");
+ var a = Expression.Parameter (typeof (bool?), "a");
+ var b = Expression.Parameter (typeof (bool?), "b");
var l = Expression.Lambda<Func<bool?, bool?, bool?>> (
Expression.AndAlso (a, b), a, b);
Assert.AreEqual (null, c (true, null), "a8");
Assert.AreEqual (null, c (null, null), "a9");
}
+
+ [Test]
+ public void AndAlsoBoolItem ()
+ {
+ var i = Expression.Parameter (typeof (Item<bool>), "i");
+ var and = Expression.Lambda<Func<Item<bool>, bool>> (
+ Expression.AndAlso (
+ Expression.Property (i, "Left"),
+ Expression.Property (i, "Right")), i).Compile ();
+
+ var item = new Item<bool> (false, true);
+ Assert.AreEqual (false, and (item));
+ Assert.IsTrue (item.LeftCalled);
+ Assert.IsFalse (item.RightCalled);
+ }
+
+ [Test]
+ public void AndAlsoNullableBoolItem ()
+ {
+ var i = Expression.Parameter (typeof (Item<bool?>), "i");
+ var and = Expression.Lambda<Func<Item<bool?>, bool?>> (
+ Expression.AndAlso (
+ Expression.Property (i, "Left"),
+ Expression.Property (i, "Right")), i).Compile ();
+
+ var item = new Item<bool?> (false, true);
+ Assert.AreEqual ((bool?) false, and (item));
+ Assert.IsTrue (item.LeftCalled);
+ Assert.IsFalse (item.RightCalled);
+ }
+
+ struct Slot {
+
+ public int Value;
+
+ public Slot (int val)
+ {
+ this.Value = val;
+ }
+
+ public static Slot operator & (Slot a, Slot b)
+ {
+ return new Slot (a.Value & b.Value);
+ }
+
+ public static bool operator true (Slot a)
+ {
+ return a.Value != 0;
+ }
+
+ public static bool operator false (Slot a)
+ {
+ return a.Value == 0;
+ }
+
+ public override string ToString ()
+ {
+ return Value.ToString ();
+ }
+ }
+
+ [Test]
+ public void UserDefinedAndAlso ()
+ {
+ var l = Expression.Parameter (typeof (Slot), "l");
+ var r = Expression.Parameter (typeof (Slot), "r");
+
+ var method = typeof (Slot).GetMethod ("op_BitwiseAnd");
+
+ var node = Expression.AndAlso (l, r, method);
+ Assert.IsFalse (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (method, node.Method);
+
+ var andalso = Expression.Lambda<Func<Slot, Slot, Slot>> (node, l, r).Compile ();
+
+ Assert.AreEqual (new Slot (64), andalso (new Slot (64), new Slot (64)));
+ Assert.AreEqual (new Slot (0), andalso (new Slot (32), new Slot (64)));
+ Assert.AreEqual (new Slot (0), andalso (new Slot (64), new Slot (32)));
+ }
+
+ [Test]
+ public void UserDefinedAndAlsoShortCircuit ()
+ {
+ var i = Expression.Parameter (typeof (Item<Slot>), "i");
+ var and = Expression.Lambda<Func<Item<Slot>, Slot>> (
+ Expression.AndAlso (
+ Expression.Property (i, "Left"),
+ Expression.Property (i, "Right")), i).Compile ();
+
+ var item = new Item<Slot> (new Slot (0), new Slot (1));
+ Assert.AreEqual (new Slot (0), and (item));
+ Assert.IsTrue (item.LeftCalled);
+ Assert.IsFalse (item.RightCalled);
+ }
+
+ [Test]
+ [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=350228
+ public void UserDefinedLiftedAndAlsoShortCircuit ()
+ {
+ var i = Expression.Parameter (typeof (Item<Slot?>), "i");
+ var and = Expression.Lambda<Func<Item<Slot?>, Slot?>> (
+ Expression.AndAlso (
+ Expression.Property (i, "Left"),
+ Expression.Property (i, "Right")), i).Compile ();
+
+ var item = new Item<Slot?> (null, new Slot (1));
+ Assert.AreEqual ((Slot?) null, and (item));
+ Assert.IsTrue (item.LeftCalled);
+ Assert.IsFalse (item.RightCalled);
+ }
+
+ [Test]
+ public void UserDefinedAndAlsoLiftedToNull ()
+ {
+ var l = Expression.Parameter (typeof (Slot?), "l");
+ var r = Expression.Parameter (typeof (Slot?), "r");
+
+ var method = typeof (Slot).GetMethod ("op_BitwiseAnd");
+
+ var node = Expression.AndAlso (l, r, method);
+ Assert.IsTrue (node.IsLifted);
+ Assert.IsTrue (node.IsLiftedToNull);
+ Assert.AreEqual (method, node.Method);
+
+ var andalso = Expression.Lambda<Func<Slot?, Slot?, Slot?>> (node, l, r).Compile ();
+
+ Assert.AreEqual (new Slot (64), andalso (new Slot (64), new Slot (64)));
+ Assert.AreEqual (new Slot (0), andalso (new Slot (32), new Slot (64)));
+ Assert.AreEqual (new Slot (0), andalso (new Slot (64), new Slot (32)));
+ Assert.AreEqual (null, andalso (null, new Slot (32)));
+ Assert.AreEqual (null, andalso (new Slot (64), null));
+ Assert.AreEqual (null, andalso (null, null));
+ }
+
+ struct Incomplete {
+ public int Value;
+
+ public Incomplete (int val)
+ {
+ Value = val;
+ }
+
+ public static Incomplete operator & (Incomplete a, Incomplete b)
+ {
+ return new Incomplete (a.Value & b.Value);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void IncompleteUserDefinedAndAlso ()
+ {
+ var l = Expression.Parameter (typeof (Incomplete), "l");
+ var r = Expression.Parameter (typeof (Incomplete), "r");
+
+ var method = typeof (Incomplete).GetMethod ("op_BitwiseAnd");
+
+ Expression.AndAlso (l, r, method);
+ }
+
+ class A {
+ public static bool operator true (A x)
+ {
+ return true;
+ }
+
+ public static bool operator false (A x)
+ {
+ return false;
+ }
+ }
+
+ class B : A {
+ public static B operator & (B x, B y)
+ {
+ return new B ();
+ }
+
+ public static bool op_True<T> (B x)
+ {
+ return true;
+ }
+
+ public static bool op_False (B x)
+ {
+ return false;
+ }
+ }
+
+ [Test] // from https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=350487
+ public void Connect350487 ()
+ {
+ var p = Expression.Parameter (typeof (B), "b");
+ var l = Expression.Lambda<Func<B, A>> (
+ Expression.AndAlso (p, p), p).Compile ();
+
+ Assert.IsNotNull (l (null));
+ }
}
}