//
// Authors:
// Miguel de Icaza (miguel@novell.com)
+// Jb Evain (jbevain@novell.com)
//
using System;
Assert.AreEqual (ExpressionType.Equal, expr.NodeType);
Assert.AreEqual (typeof (bool), expr.Type);
Assert.IsNull (expr.Method);
- Assert.AreEqual ("(1 = 2)", expr.ToString ());
+ }
+
+ [Test]
+ public void PrimitiveNonNumeric ()
+ {
+ BinaryExpression expr = Expression.Equal (Expression.Constant ('a'), Expression.Constant ('b'));
+ Assert.AreEqual (ExpressionType.Equal, expr.NodeType);
+ Assert.AreEqual (typeof (bool), expr.Type);
+ Assert.IsNull (expr.Method);
+
+ var eq = Expression.Lambda<Func<bool>> (expr).Compile ();
+ Assert.IsFalse (eq ());
+ }
+
+ [Test]
+ public void StringWithNull ()
+ {
+ BinaryExpression expr = Expression.Equal (Expression.Constant ("a"), Expression.Constant (null));
+ Assert.AreEqual (ExpressionType.Equal, expr.NodeType);
+ Assert.AreEqual (typeof (bool), expr.Type);
+ Assert.IsNull (expr.Method);
+
+ var eq = Expression.Lambda<Func<bool>> (expr).Compile ();
+ Assert.IsFalse (eq ());
}
[Test]
Assert.AreEqual (true, expr.IsLifted);
Assert.AreEqual (false, expr.IsLiftedToNull);
Assert.IsNull (expr.Method);
- Assert.AreEqual ("(1 = 2)", expr.ToString ());
}
[Test]
Assert.AreEqual (true, expr.IsLifted);
Assert.AreEqual (true, expr.IsLiftedToNull);
Assert.IsNull (expr.Method);
- Assert.AreEqual ("(1 = 2)", expr.ToString ());
}
[Test]
int? a = 1;
int b = 2;
- BinaryExpression expr = Expression.Equal (Expression.Constant (a, typeof (int?)),
- Expression.Constant (b, typeof (int)));
+ Expression.Equal (Expression.Constant (a, typeof (int?)),
+ Expression.Constant (b, typeof (int)));
}
[Test]
Assert.AreEqual (typeof (bool), expr.Type);
Assert.AreEqual (mi, expr.Method);
Assert.AreEqual ("op_Equality", expr.Method.Name);
+ }
+
+ [Test]
+ public void NullableInt32Equal ()
+ {
+ var l = Expression.Parameter (typeof (int?), "l");
+ var r = Expression.Parameter (typeof (int?), "r");
+
+ var eq = Expression.Lambda<Func<int?, int?, bool>> (
+ Expression.Equal (l, r), l, r).Compile ();
+
+ Assert.IsTrue (eq (null, null));
+ Assert.IsFalse (eq (null, 1));
+ Assert.IsFalse (eq (1, null));
+ Assert.IsFalse (eq (1, 2));
+ Assert.IsTrue (eq (1, 1));
+ Assert.IsFalse (eq (null, 0));
+ Assert.IsFalse (eq (0, null));
+ }
+
+ [Test]
+ public void NullableInt32EqualLiftedToNull ()
+ {
+ var l = Expression.Parameter (typeof (int?), "l");
+ var r = Expression.Parameter (typeof (int?), "r");
+
+ var eq = Expression.Lambda<Func<int?, int?, bool?>> (
+ Expression.Equal (l, r, true, null), l, r).Compile ();
+
+ Assert.AreEqual ((bool?) null, eq (null, null));
+ Assert.AreEqual ((bool?) null, eq (null, 1));
+ Assert.AreEqual ((bool?) null, eq (1, null));
+ Assert.AreEqual ((bool?) false, eq (1, 2));
+ Assert.AreEqual ((bool?) true, eq (1, 1));
+ Assert.AreEqual ((bool?) null, eq (null, 0));
+ Assert.AreEqual ((bool?) null, eq (0, null));
+ }
+
+ struct Slot {
+ public int Value;
- Assert.AreEqual ("(value(MonoTests.System.Linq.Expressions.OpClass) = value(MonoTests.System.Linq.Expressions.OpClass))", expr.ToString ());
+ public Slot (int value)
+ {
+ this.Value = value;
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (!(obj is Slot))
+ return false;
+
+ var other = (Slot) obj;
+ return other.Value == this.Value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return Value;
+ }
+
+ public static bool operator == (Slot a, Slot b)
+ {
+ return a.Value == b.Value;
+ }
+
+ public static bool operator != (Slot a, Slot b)
+ {
+ return a.Value != b.Value;
+ }
}
- //
- // Checks for the behavior when the return type for Equal is not
- // bool, and its coping with nullable values.
- //
[Test]
public void UserDefinedEqual ()
{
+ var l = Expression.Parameter (typeof (Slot), "l");
+ var r = Expression.Parameter (typeof (Slot), "r");
+
+ var node = Expression.Equal (l, r);
+
+ Assert.IsFalse (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool), node.Type);
+ Assert.IsNotNull (node.Method);
+
+ var eq = Expression.Lambda<Func<Slot, Slot, bool>> (node, l, r).Compile ();
+
+ Assert.AreEqual (true, eq (new Slot (21), new Slot (21)));
+ Assert.AreEqual (false, eq (new Slot (1), new Slot (-1)));
+ }
+
+ [Test]
+ [Category ("NotWorkingInterpreter")]
+ public void UserDefinedEqualLifted ()
+ {
+ var l = Expression.Parameter (typeof (Slot?), "l");
+ var r = Expression.Parameter (typeof (Slot?), "r");
+
+ var node = Expression.Equal (l, r);
+
+ Assert.IsTrue (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool), node.Type);
+ Assert.IsNotNull (node.Method);
+
+ var eq = Expression.Lambda<Func<Slot?, Slot?, bool>> (node, l, r).Compile ();
+
+ Assert.AreEqual (true, eq (null, null));
+ Assert.AreEqual (false, eq ((Slot?) new Slot (2), null));
+ Assert.AreEqual (false, eq (null, (Slot?) new Slot (2)));
+ Assert.AreEqual (true, eq ((Slot?) new Slot (21), (Slot?) new Slot (21)));
+ }
+
+ [Test]
+ [Category ("NotWorkingInterpreter")]
+ public void UserDefinedEqualLiftedToNull ()
+ {
+ var l = Expression.Parameter (typeof (Slot?), "l");
+ var r = Expression.Parameter (typeof (Slot?), "r");
+
+ var node = Expression.Equal (l, r, true, null);
+
+ Assert.IsTrue (node.IsLifted);
+ Assert.IsTrue (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool?), node.Type);
+ Assert.IsNotNull (node.Method);
+
+ var eq = Expression.Lambda<Func<Slot?, Slot?, bool?>> (node, l, r).Compile ();
+
+ Assert.AreEqual ((bool?) null, eq (null, null));
+ Assert.AreEqual ((bool?) null, eq ((Slot?) new Slot (2), null));
+ Assert.AreEqual ((bool?) null, eq (null, (Slot?) new Slot (2)));
+ Assert.AreEqual ((bool?) true, eq ((Slot?) new Slot (21), (Slot?) new Slot (21)));
+ Assert.AreEqual ((bool?) false, eq ((Slot?) new Slot (21), (Slot?) new Slot (-21)));
+ }
+
+ struct SlotToNullable {
+ public int Value;
+
+ public SlotToNullable (int value)
+ {
+ this.Value = value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return Value;
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (!(obj is SlotToNullable))
+ return false;
+
+ var other = (SlotToNullable) obj;
+ return other.Value == this.Value;
+ }
+
+ public static bool? operator == (SlotToNullable a, SlotToNullable b)
+ {
+ return (bool?) (a.Value == b.Value);
+ }
+
+ public static bool? operator != (SlotToNullable a, SlotToNullable b)
+ {
+ return (bool?) (a.Value != b.Value);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void UserDefinedToNullableEqualFromNullable ()
+ {
+ Expression.Equal (
+ Expression.Parameter (typeof (SlotToNullable?), "l"),
+ Expression.Parameter (typeof (SlotToNullable?), "r"));
+ }
+
+ [Test]
+ public void UserDefinedToNullableEqual ()
+ {
+ var l = Expression.Parameter (typeof (SlotToNullable), "l");
+ var r = Expression.Parameter (typeof (SlotToNullable), "r");
+
+ var node = Expression.Equal (l, r, false, null);
+
+ Assert.IsFalse (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool?), node.Type);
+ Assert.IsNotNull (node.Method);
+
+ var eq = Expression.Lambda<Func<SlotToNullable, SlotToNullable, bool?>> (node, l, r).Compile ();
+
+ Assert.AreEqual ((bool?) true, eq (new SlotToNullable (2), new SlotToNullable (2)));
+ Assert.AreEqual ((bool?) false, eq (new SlotToNullable (2), new SlotToNullable (-2)));
+ }
+
+ /*struct SlotFromNullableToNullable {
+ public int Value;
+
+ public SlotFromNullableToNullable (int value)
+ {
+ this.Value = value;
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (!(obj is SlotFromNullableToNullable))
+ return false;
+
+ var other = (SlotFromNullableToNullable) obj;
+ return other.Value == this.Value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return Value;
+ }
+
+ public static bool? operator == (SlotFromNullableToNullable? a, SlotFromNullableToNullable? b)
+ {
+ if (a.HasValue && b.HasValue)
+ return (bool?) (a.Value.Value == b.Value.Value);
+ else
+ return null;
+ }
+
+ public static bool? operator != (SlotFromNullableToNullable? a, SlotFromNullableToNullable? b)
+ {
+ return !(a == b);
+ }
+ }
+
+ [Test]
+ public void UserDefinedFromNullableToNullableEqual ()
+ {
+ var l = Expression.Parameter (typeof (SlotFromNullableToNullable?), "l");
+ var r = Expression.Parameter (typeof (SlotFromNullableToNullable?), "r");
+
+ var node = Expression.Equal (l, r);
+
+ Assert.IsFalse (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool?), node.Type);
+ Assert.IsNotNull (node.Method);
+
+ var eq = Expression.Lambda<Func<SlotFromNullableToNullable?, SlotFromNullableToNullable?, bool?>> (node, l, r).Compile ();
+
+ Assert.AreEqual ((bool?) null, eq (null, null));
+ Assert.AreEqual ((bool?) null, eq (new SlotFromNullableToNullable (2), null));
+ Assert.AreEqual ((bool?) null, eq (null, new SlotFromNullableToNullable (2)));
+ Assert.AreEqual ((bool?) true, eq (new SlotFromNullableToNullable (2), new SlotFromNullableToNullable (2)));
+ Assert.AreEqual ((bool?) false, eq (new SlotFromNullableToNullable (2), new SlotFromNullableToNullable (-2)));
+ }*/
+
+ [Test]
+ public void NullableBoolEqualToBool ()
+ {
+ var l = Expression.Parameter (typeof (bool?), "l");
+ var r = Expression.Parameter (typeof (bool?), "r");
+
+ var node = Expression.Equal (l, r);
+ Assert.IsTrue (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool), node.Type);
+ Assert.IsNull (node.Method);
+
+ var eq = Expression.Lambda<Func<bool?, bool?, bool>> (node, l, r).Compile ();
+
+ Assert.AreEqual (false, eq (true, null));
+ Assert.AreEqual (true, eq (null, null));
+ Assert.AreEqual (true, eq (false, false));
+ }
+
+ public enum Foo {
+ Bar,
+ Baz,
+ }
+
+ [Test]
+ public void EnumEqual ()
+ {
+ var l = Expression.Parameter (typeof (Foo), "l");
+ var r = Expression.Parameter (typeof (Foo), "r");
+
+ var node = Expression.Equal (l, r);
+ Assert.IsFalse (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool), node.Type);
+ Assert.IsNull (node.Method);
+
+ var eq = Expression.Lambda<Func<Foo, Foo, bool>> (node, l, r).Compile ();
+
+ Assert.AreEqual (true, eq (Foo.Bar, Foo.Bar));
+ Assert.AreEqual (false, eq (Foo.Bar, Foo.Baz));
+ }
+
+ [Test]
+ public void LiftedEnumEqual ()
+ {
+ var l = Expression.Parameter (typeof (Foo?), "l");
+ var r = Expression.Parameter (typeof (Foo?), "r");
+
+ var node = Expression.Equal (l, r);
+ Assert.IsTrue (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool), node.Type);
+ Assert.IsNull (node.Method);
+
+ var eq = Expression.Lambda<Func<Foo?, Foo?, bool>> (node, l, r).Compile ();
+ Assert.AreEqual (true, eq (Foo.Bar, Foo.Bar));
+ Assert.AreEqual (false, eq (Foo.Bar, Foo.Baz));
+ Assert.AreEqual (false, eq (Foo.Bar, null));
+ Assert.AreEqual (true, eq (null, null));
}
+ [Test]
+ [Category ("NotWorkingInterpreter")]
+ public void NullableNullEqual ()
+ {
+ var param = Expression.Parameter (typeof (DateTime?), "x");
+
+ var node = Expression.Equal (param, Expression.Constant (null));
+
+ Assert.IsTrue (node.IsLifted);
+ Assert.IsFalse (node.IsLiftedToNull);
+ Assert.AreEqual (typeof (bool), node.Type);
+ Assert.IsNull (node.Method);
+
+ var eq = Expression.Lambda<Func<DateTime?, bool>> (node, new [] { param }).Compile ();
+
+ Assert.AreEqual (true, eq (null));
+ Assert.AreEqual (false, eq (DateTime.Now));
+ }
}
}