ExpressionTest_MakeBinary.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. //
  19. // Authors:
  20. // Miguel de Icaza <[email protected]>
  21. //
  22. using System;
  23. using System.Reflection;
  24. using System.Linq;
  25. using System.Linq.Expressions;
  26. using System.Reflection;
  27. using NUnit.Framework;
  28. namespace MonoTests.System.Linq.Expressions
  29. {
  30. [TestFixture]
  31. public class ExpressionTest_MakeBinary {
  32. public static int GoodMethod (string a, double d)
  33. {
  34. return 1;
  35. }
  36. public static int BadMethodSig_1 ()
  37. {
  38. return 1;
  39. }
  40. public static int BadMethodSig_2 (int a)
  41. {
  42. return 1;
  43. }
  44. public static int BadMethodSig_3 (int a, int b, int c)
  45. {
  46. return 1;
  47. }
  48. static MethodInfo GM (string n)
  49. {
  50. MethodInfo [] methods = typeof (ExpressionTest_MakeBinary).GetMethods (
  51. BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
  52. foreach (MethodInfo m in methods)
  53. if (m.Name == n)
  54. return m;
  55. throw new Exception (String.Format ("Method {0} not found", n));
  56. }
  57. [Test]
  58. public void MethodChecks ()
  59. {
  60. Expression left = Expression.Constant ("");
  61. Expression right = Expression.Constant (1.0);
  62. BinaryExpression r = Expression.Add (left, right, GM ("GoodMethod"));
  63. Assert.AreEqual (r.Type, typeof (int));
  64. }
  65. [Test]
  66. [ExpectedException(typeof (ArgumentException))]
  67. public void MethodCheck_BadArgs ()
  68. {
  69. Expression left = Expression.Constant ("");
  70. Expression right = Expression.Constant (1.0);
  71. BinaryExpression r = Expression.Add (left, right, GM ("BadMethodSig_1"));
  72. }
  73. [Test]
  74. [ExpectedException(typeof (ArgumentException))]
  75. public void MethodCheck_BadArgs2 ()
  76. {
  77. Expression left = Expression.Constant ("");
  78. Expression right = Expression.Constant (1.0);
  79. BinaryExpression r = Expression.Add (left, right, GM ("BadMethodSig_2"));
  80. }
  81. [Test]
  82. [ExpectedException(typeof (ArgumentException))]
  83. public void MethodCheck_BadArgs3 ()
  84. {
  85. Expression left = Expression.Constant ("");
  86. Expression right = Expression.Constant (1.0);
  87. BinaryExpression r = Expression.Add (left, right, GM ("BadMethodSig_3"));
  88. }
  89. static void PassInt (ExpressionType nt)
  90. {
  91. Expression left = Expression.Constant (1);
  92. Expression right = Expression.Constant (1);
  93. Expression.MakeBinary (nt, left, right);
  94. }
  95. static void FailInt (ExpressionType nt)
  96. {
  97. Expression left = Expression.Constant (1);
  98. Expression right = Expression.Constant (1);
  99. try {
  100. Expression.MakeBinary (nt, left, right);
  101. } catch (ArgumentException){
  102. return;
  103. }
  104. // If we get here, there was an error
  105. Assert.Fail ("FailInt failed while creating an {0}", nt);
  106. }
  107. //
  108. // Checks that we complain on the proper ExpressionTypes
  109. //
  110. [Test]
  111. public void TestBinaryCtor ()
  112. {
  113. PassInt (ExpressionType.Add);
  114. PassInt (ExpressionType.AddChecked);
  115. PassInt (ExpressionType.And);
  116. PassInt (ExpressionType.Divide);
  117. PassInt (ExpressionType.Equal);
  118. PassInt (ExpressionType.ExclusiveOr);
  119. PassInt (ExpressionType.GreaterThan);
  120. PassInt (ExpressionType.GreaterThanOrEqual);
  121. PassInt (ExpressionType.LeftShift);
  122. PassInt (ExpressionType.LessThan);
  123. PassInt (ExpressionType.LessThanOrEqual);
  124. PassInt (ExpressionType.Multiply);
  125. PassInt (ExpressionType.MultiplyChecked);
  126. PassInt (ExpressionType.NotEqual);
  127. PassInt (ExpressionType.Or);
  128. PassInt (ExpressionType.Modulo);
  129. PassInt (ExpressionType.RightShift);
  130. PassInt (ExpressionType.Subtract);
  131. PassInt (ExpressionType.SubtractChecked);
  132. // Remove comment when the code is implemented:
  133. //FailInt (ExpressionType.AndAlso);
  134. //FailInt (ExpressionType.OrElse);
  135. //This should test for types, not operation: FailInt (ExpressionType.Power);
  136. #if false
  137. // These currently fail, because it now goes directly to the nodes, instead of doing
  138. // a first-pass check; REmove when its all done.
  139. FailInt (ExpressionType.ArrayLength);
  140. FailInt (ExpressionType.ArrayIndex);
  141. FailInt (ExpressionType.Call);
  142. FailInt (ExpressionType.Coalesce);
  143. FailInt (ExpressionType.Conditional);
  144. FailInt (ExpressionType.Constant);
  145. FailInt (ExpressionType.Convert);
  146. FailInt (ExpressionType.ConvertChecked);
  147. FailInt (ExpressionType.Invoke);
  148. FailInt (ExpressionType.Lambda);
  149. FailInt (ExpressionType.ListInit);
  150. FailInt (ExpressionType.MemberAccess);
  151. FailInt (ExpressionType.MemberInit);
  152. FailInt (ExpressionType.Negate);
  153. FailInt (ExpressionType.UnaryPlus);
  154. FailInt (ExpressionType.NegateChecked);
  155. FailInt (ExpressionType.New);
  156. FailInt (ExpressionType.NewArrayInit);
  157. FailInt (ExpressionType.NewArrayBounds);
  158. FailInt (ExpressionType.Not);
  159. FailInt (ExpressionType.Parameter);
  160. FailInt (ExpressionType.Quote);
  161. FailInt (ExpressionType.TypeAs);
  162. FailInt (ExpressionType.TypeIs);
  163. #endif
  164. }
  165. public delegate Expression BinaryExpr (Expression a, Expression b);
  166. public T CodeGen<T> (BinaryExpr bin, T v1, T v2)
  167. {
  168. Expression<Func<T>> l = Expression.Lambda<Func<T>> (
  169. bin (Expression.Constant(v1), Expression.Constant(v2)),
  170. new ParameterExpression [0]);
  171. Func<T> fi = l.Compile ();
  172. return fi ();
  173. }
  174. [Test]
  175. public void TestOperations ()
  176. {
  177. Assert.AreEqual (30, CodeGen<int> ((a, b) => Expression.Add (a, b), 10, 20));
  178. Assert.AreEqual (-12, CodeGen<int> ((a, b) => Expression.Subtract (a, b), 11, 23));
  179. Assert.AreEqual (253, CodeGen<int> ((a, b) => Expression.Multiply (a, b), 11, 23));
  180. Assert.AreEqual (33, CodeGen<int> ((a, b) => Expression.Divide (a, b), 100, 3));
  181. Assert.AreEqual (100.0/3, CodeGen<double> ((a, b) => Expression.Divide (a, b), 100, 3));
  182. }
  183. }
  184. }