Merge pull request #901 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / System.Core / Test / System.Linq.Expressions / ExpressionTest_Negate.cs
index fdd70df321e41edf4227b2f92a426a0beb987152..8c0149821b9a3be1b10a4fbc01577381dec0735f 100644 (file)
@@ -65,6 +65,13 @@ namespace MonoTests.System.Linq.Expressions
                        Expression.Negate (Expression.Constant (new object ()), typeof (OpClass).GetMethod ("WrongUnaryReturnVoid"));
                }
 
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void NegateBool ()
+               {
+                       Expression.Negate (true.ToConstant ());
+               }
+
                [Test]
                public void Number ()
                {
@@ -105,5 +112,204 @@ namespace MonoTests.System.Linq.Expressions
                        Assert.AreEqual (0, negate (0));
                        Assert.AreEqual (3, negate (-3));
                }
+
+               [Test]
+               public void CompiledNegateNullableInt32 ()
+               {
+                       var p = Expression.Parameter (typeof (int?), "i");
+                       var negate = Expression.Lambda<Func<int?, int?>> (Expression.Negate (p), p).Compile ();
+
+                       Assert.AreEqual (null, negate (null));
+                       Assert.AreEqual ((int?) -2, negate (2));
+                       Assert.AreEqual ((int?) 0, negate (0));
+                       Assert.AreEqual ((int?) 3, negate (-3));
+               }
+
+               struct Slot {
+                       public int Value;
+
+                       public Slot (int value)
+                       {
+                               this.Value = value;
+                       }
+
+                       public static Slot operator - (Slot s)
+                       {
+                               return new Slot (-s.Value);
+                       }
+               }
+
+               [Test]
+               public void UserDefinedNegate ()
+               {
+                       var s = Expression.Parameter (typeof (Slot), "s");
+                       var node = Expression.Negate (s);
+                       Assert.IsFalse (node.IsLifted);
+                       Assert.IsFalse (node.IsLiftedToNull);
+                       Assert.AreEqual (typeof (Slot), node.Type);
+
+                       var negate = Expression.Lambda<Func<Slot, Slot>> (node, s).Compile ();
+
+                       Assert.AreEqual (new Slot (-2), negate (new Slot (2)));
+                       Assert.AreEqual (new Slot (42), negate (new Slot (-42)));
+               }
+
+               [Test]
+               [Category ("NotWorkingInterpreter")]
+               public void UserDefinedNotNullableNegateNullable ()
+               {
+                       var s = Expression.Parameter (typeof (Slot?), "s");
+                       var node = Expression.Negate (s);
+                       Assert.IsTrue (node.IsLifted);
+                       Assert.IsTrue (node.IsLiftedToNull);
+                       Assert.AreEqual (typeof (Slot?), node.Type);
+
+                       var negate = Expression.Lambda<Func<Slot?, Slot?>> (node, s).Compile ();
+
+                       Assert.AreEqual (null, negate (null));
+                       Assert.AreEqual (new Slot (42), negate (new Slot (-42)));
+                       Assert.AreEqual (new Slot (-2), negate (new Slot (2)));
+               }
+
+               struct SlotToNullable {
+                       public int Value;
+
+                       public SlotToNullable (int value)
+                       {
+                               this.Value = value;
+                       }
+
+                       public static SlotToNullable? operator - (SlotToNullable s)
+                       {
+                               return new SlotToNullable (-s.Value);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void UserDefinedToNullableNegateFromNullable ()
+               {
+                       Expression.Negate (Expression.Parameter (typeof (SlotToNullable?), "s"));
+               }
+
+               [Test]
+               public void UserDefinedToNullableNegateNullable ()
+               {
+                       var s = Expression.Parameter (typeof (SlotToNullable), "s");
+                       var node = Expression.Negate (s);
+                       Assert.IsFalse (node.IsLifted);
+                       Assert.IsFalse (node.IsLiftedToNull);
+                       Assert.AreEqual (typeof (SlotToNullable?), node.Type);
+
+                       var negate = Expression.Lambda<Func<SlotToNullable, SlotToNullable?>> (node, s).Compile ();
+
+                       Assert.AreEqual ((SlotToNullable?) new SlotToNullable (42), negate (new SlotToNullable (-42)));
+                       Assert.AreEqual ((SlotToNullable?) new SlotToNullable (-2), negate (new SlotToNullable (2)));
+               }
+
+               struct SlotFromNullable {
+                       public int Value;
+
+                       public SlotFromNullable (int value)
+                       {
+                               this.Value = value;
+                       }
+
+                       public static SlotFromNullable operator - (SlotFromNullable? s)
+                       {
+                               if (s.HasValue)
+                                       return new SlotFromNullable (-s.Value.Value);
+                               else
+                                       return new SlotFromNullable (-1);
+                       }
+               }
+
+               [Test]
+               public void UserDefinedNegateFromNullable ()
+               {
+                       var s = Expression.Parameter (typeof (SlotFromNullable?), "s");
+                       var node = Expression.Negate (s);
+                       Assert.IsFalse (node.IsLifted);
+                       Assert.IsFalse (node.IsLiftedToNull);
+                       Assert.AreEqual (typeof (SlotFromNullable), node.Type);
+
+                       var negate = Expression.Lambda<Func<SlotFromNullable?, SlotFromNullable>> (node, s).Compile ();
+
+                       Assert.AreEqual (new SlotFromNullable (-2), negate (new SlotFromNullable (2)));
+                       Assert.AreEqual (new SlotFromNullable (42), negate (new SlotFromNullable (-42)));
+                       Assert.AreEqual (new SlotFromNullable (-1), negate (null));
+               }
+
+               struct SlotFromNullableToNullable {
+                       public int Value;
+
+                       public SlotFromNullableToNullable (int value)
+                       {
+                               this.Value = value;
+                       }
+
+                       public static SlotFromNullableToNullable? operator - (SlotFromNullableToNullable? s)
+                       {
+                               if (s.HasValue)
+                                       return new SlotFromNullableToNullable (-s.Value.Value);
+                               else
+                                       return s;
+                       }
+               }
+
+               [Test]
+               public void UserDefinedNegateFromNullableNotNullable ()
+               {
+                       var s = Expression.Parameter (typeof (SlotFromNullableToNullable?), "s");
+                       var node = Expression.Negate (s);
+                       Assert.IsFalse (node.IsLifted);
+                       Assert.IsFalse (node.IsLiftedToNull);
+                       Assert.AreEqual (typeof (SlotFromNullableToNullable?), node.Type);
+
+                       var negate = Expression.Lambda<Func<SlotFromNullableToNullable?, SlotFromNullableToNullable?>> (
+                               node, s).Compile ();
+
+                       Assert.AreEqual (new SlotFromNullableToNullable (-2), negate (new SlotFromNullableToNullable (2)));
+                       Assert.AreEqual (new SlotFromNullableToNullable (42), negate (new SlotFromNullableToNullable (-42)));
+                       Assert.AreEqual (null, negate (null));
+               }
+
+               [Test]
+               public void NegateDecimal ()
+               {
+                       var d = Expression.Parameter (typeof (decimal), "l");
+
+                       var meth = typeof (decimal).GetMethod ("op_UnaryNegation", new [] { typeof (decimal) });
+
+                       var node = Expression.Negate (d);
+                       Assert.IsFalse (node.IsLifted);
+                       Assert.IsFalse (node.IsLiftedToNull);
+                       Assert.AreEqual (typeof (decimal), node.Type);
+                       Assert.AreEqual (meth, node.Method);
+
+                       var neg = Expression.Lambda<Func<decimal, decimal>> (node, d).Compile ();
+
+                       Assert.AreEqual (-2m, neg (2m));
+               }
+
+               [Test]
+               [Category ("NotWorkingInterpreter")]
+               public void NegateLiftedDecimal ()
+               {
+                       var d = Expression.Parameter (typeof (decimal?), "l");
+
+                       var meth = typeof (decimal).GetMethod ("op_UnaryNegation", new [] { typeof (decimal) });
+
+                       var node = Expression.Negate (d);
+                       Assert.IsTrue (node.IsLifted);
+                       Assert.IsTrue (node.IsLiftedToNull);
+                       Assert.AreEqual (typeof (decimal?), node.Type);
+                       Assert.AreEqual (meth, node.Method);
+
+                       var neg = Expression.Lambda<Func<decimal?, decimal?>> (node, d).Compile ();
+
+                       Assert.AreEqual (-2m, neg (2m));
+                       Assert.AreEqual (null, neg (null));
+               }
        }
 }