Explorar el Código

tests for not lifted/lifted/lifted to null user defined binary operators

svn path=/trunk/mcs/; revision=104749
Jb Evain hace 17 años
padre
commit
5ba12ef578

+ 122 - 24
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Add.cs

@@ -18,6 +18,7 @@
 //
 // Authors:
 //		Federico Di Gregorio <[email protected]>
+//		Jb Evain <[email protected]>
 
 using System;
 using System.Reflection;
@@ -139,7 +140,8 @@ namespace MonoTests.System.Linq.Expressions
 		[Test]
 		public void CompileAdd ()
 		{
-			ParameterExpression left = Expression.Parameter (typeof (int), "l"), right = Expression.Parameter (typeof (int), "r");
+			var left = Expression.Parameter (typeof (int), "l");
+			var right = Expression.Parameter (typeof (int), "r");
 			var l = Expression.Lambda<Func<int, int, int>> (
 				Expression.Add (left, right), left, right);
 
@@ -183,7 +185,8 @@ namespace MonoTests.System.Linq.Expressions
 		[Test]
 		public void AddTestNullable ()
 		{
-			ParameterExpression a = Expression.Parameter (typeof (int?), "a"), b = Expression.Parameter (typeof (int?), "b");
+			var a = Expression.Parameter (typeof (int?), "a");
+			var b = Expression.Parameter (typeof (int?), "b");
 			var l = Expression.Lambda<Func<int?, int?, int?>> (
 				Expression.Add (a, b), a, b);
 
@@ -201,46 +204,141 @@ namespace MonoTests.System.Linq.Expressions
 			Assert.AreEqual (3,    c (1, 2), "a4");
 		}
 
-		struct EineStrukt {
-			int i;
+		struct Slot {
+			public int Value;
 
-			public int I {
-				get { return i; }
+			public Slot (int value)
+			{
+				this.Value = value;
+			}
+
+			public static Slot operator + (Slot a, Slot b)
+			{
+				return new Slot (a.Value + b.Value);
 			}
+		}
+
+		[Test]
+		[Category ("NotWorking")]
+		public void UserDefinedAdd ()
+		{
+			var l = Expression.Parameter (typeof (Slot), "l");
+			var r = Expression.Parameter (typeof (Slot), "r");
+
+			var node = Expression.Add (l, r);
+
+			Assert.IsFalse (node.IsLifted);
+			Assert.IsFalse (node.IsLiftedToNull);
+			Assert.AreEqual (typeof (Slot), node.Type);
+
+			var add = Expression.Lambda<Func<Slot, Slot, Slot>> (node, l, r).Compile ();
+
+			Assert.AreEqual (new Slot (42), add (new Slot (21), new Slot (21)));
+			Assert.AreEqual (new Slot (0), add (new Slot (1), new Slot (-1)));
+		}
+
+		[Test]
+		[Category ("NotWorking")]
+		public void UserDefinedAddLifted ()
+		{
+			var l = Expression.Parameter (typeof (Slot?), "l");
+			var r = Expression.Parameter (typeof (Slot?), "r");
+
+			var node = Expression.Add (l, r);
+
+			Assert.IsTrue (node.IsLifted);
+			Assert.IsTrue (node.IsLiftedToNull);
+			Assert.AreEqual (typeof (Slot?), node.Type);
+
+			var add = Expression.Lambda<Func<Slot?, Slot?, Slot?>> (node, l, r).Compile ();
+
+			Assert.AreEqual (null, add (null, null));
+			Assert.AreEqual ((Slot?) new Slot (42), add ((Slot?) new Slot (21), (Slot?) new Slot (21)));
+		}
 
-			public EineStrukt (int i)
+		struct SlotToNullable {
+			public int Value;
+
+			public SlotToNullable (int value)
 			{
-				this.i = i;
+				this.Value = value;
 			}
 
-			public static EineStrukt operator + (EineStrukt a, EineStrukt b)
+			public static SlotToNullable? operator + (SlotToNullable a, SlotToNullable b)
 			{
-				return new EineStrukt (a.i + b.i);
+				return new SlotToNullable (a.Value + b.Value);
 			}
 		}
 
 		[Test]
 		[Category ("NotWorking")]
-		public void AddNullableStruct ()
+		[ExpectedException (typeof (InvalidOperationException))]
+		public void UserDefinedToNullableAddFromNullable ()
+		{
+			Expression.Add (
+				Expression.Parameter (typeof (SlotToNullable?), "l"),
+				Expression.Parameter (typeof (SlotToNullable?), "r"));
+		}
+
+		[Test]
+		[Category ("NotWorking")]
+		public void UserDefinedToNullableAdd ()
 		{
-			var a = Expression.Parameter (typeof (EineStrukt?), "a");
-			var b = Expression.Parameter (typeof (EineStrukt?), "b");
+			var l = Expression.Parameter (typeof (SlotToNullable), "l");
+			var r = Expression.Parameter (typeof (SlotToNullable), "r");
+
+			var node = Expression.Add (l, r);
+
+			Assert.IsFalse (node.IsLifted);
+			Assert.IsFalse (node.IsLiftedToNull);
+			Assert.AreEqual (typeof (SlotToNullable?), node.Type);
+			Assert.IsNotNull (node.Method);
+
+			var add = Expression.Lambda<Func<SlotToNullable, SlotToNullable, SlotToNullable?>> (node, l, r).Compile ();
+
+			Assert.AreEqual ((SlotToNullable?) new SlotToNullable (4), add (new SlotToNullable (2), new SlotToNullable (2)));
+			Assert.AreEqual ((SlotToNullable?) new SlotToNullable (0), add (new SlotToNullable (2), new SlotToNullable (-2)));
+		}
 
-			var body = Expression.Add (a, b);
-			var lambda = Expression.Lambda<Func<EineStrukt?, EineStrukt?, EineStrukt?>> (body, a, b);
+		struct SlotFromNullableToNullable {
+			public int Value;
+
+			public SlotFromNullableToNullable (int value)
+			{
+				this.Value = value;
+			}
+
+			public static SlotFromNullableToNullable? operator + (SlotFromNullableToNullable? a, SlotFromNullableToNullable? b)
+			{
+				if (a.HasValue && b.HasValue)
+					return (SlotFromNullableToNullable?) new SlotFromNullableToNullable (
+						a.Value.Value + b.Value.Value);
+				else
+					return null;
+			}
+		}
+
+		[Test]
+		[Category ("NotWorking")]
+		public void UserDefinedFromNullableToNullableAdd ()
+		{
+			var l = Expression.Parameter (typeof (SlotFromNullableToNullable?), "l");
+			var r = Expression.Parameter (typeof (SlotFromNullableToNullable?), "r");
 
-			Assert.AreEqual (typeof (EineStrukt?), body.Type);
-			Assert.IsTrue (body.IsLifted);
-			Assert.IsTrue (body.IsLiftedToNull);
+			var node = Expression.Add (l, r);
 
-			var add = lambda.Compile ();
+			Assert.IsFalse (node.IsLifted);
+			Assert.IsFalse (node.IsLiftedToNull);
+			Assert.AreEqual (typeof (SlotFromNullableToNullable?), node.Type);
+			Assert.IsNotNull (node.Method);
 
-			var res = add (new EineStrukt (2), new EineStrukt (3));
-			Assert.IsTrue (res.HasValue);
-			Assert.AreEqual (5, res.Value.I);
+			var add = Expression.Lambda<Func<SlotFromNullableToNullable?, SlotFromNullableToNullable?, SlotFromNullableToNullable?>> (node, l, r).Compile ();
 
-			res = add (null, null);
-			Assert.IsFalse (res.HasValue);
+			Assert.AreEqual ((SlotFromNullableToNullable?) null, add (null, null));
+			Assert.AreEqual ((SlotFromNullableToNullable?) null, add (new SlotFromNullableToNullable (2), null));
+			Assert.AreEqual ((SlotFromNullableToNullable?) null, add (null, new SlotFromNullableToNullable (2)));
+			Assert.AreEqual ((SlotFromNullableToNullable?) new SlotFromNullableToNullable (4), add (new SlotFromNullableToNullable (2), new SlotFromNullableToNullable (2)));
+			Assert.AreEqual ((SlotFromNullableToNullable?) new SlotFromNullableToNullable (0), add (new SlotFromNullableToNullable (2), new SlotFromNullableToNullable (-2)));
 		}
 	}
 }

+ 220 - 10
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs

@@ -139,16 +139,6 @@ namespace MonoTests.System.Linq.Expressions
 			Assert.AreEqual ("(value(MonoTests.System.Linq.Expressions.OpClass) = value(MonoTests.System.Linq.Expressions.OpClass))", expr.ToString ());
 		}
 
-		//
-		// Checks for the behavior when the return type for Equal is not
-		// bool, and its coping with nullable values.
-		//
-		[Test]
-		public void UserDefinedEqual ()
-		{
-
-		}
-
 		[Test]
 		public void NullableInt32Equal ()
 		{
@@ -184,5 +174,225 @@ namespace MonoTests.System.Linq.Expressions
 			Assert.AreEqual ((bool?) null, eq (null, 0));
 			Assert.AreEqual ((bool?) null, eq (0, null));
 		}
+
+		struct Slot {
+			public int Value;
+
+			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;
+			}
+		}
+
+		[Test]
+		[Category ("NotWorking")]
+		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 ("NotWorking")]
+		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 ("NotWorking")]
+		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]
+		[Category ("NotWorking")]
+		[ExpectedException (typeof (InvalidOperationException))]
+		public void UserDefinedToNullableEqualFromNullable ()
+		{
+			Expression.Equal (
+				Expression.Parameter (typeof (SlotToNullable?), "l"),
+				Expression.Parameter (typeof (SlotToNullable?), "r"));
+		}
+
+		[Test]
+		[Category ("NotWorking")]
+		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]
+		[Category ("NotWorking")]
+		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)));
+		}
 	}
 }