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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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
20 // Miguel de Icaza <miguel@novell.com>
23 using System.Reflection;
25 using System.Linq.Expressions;
26 using NUnit.Framework;
28 namespace MonoTests.System.Linq.Expressions
31 public class ExpressionTest_MakeBinary {
33 public static int GoodMethod (string a, double d)
38 public static int BadMethodSig_1 ()
43 public static int BadMethodSig_2 (int a)
48 public static int BadMethodSig_3 (int a, int b, int c)
53 static MethodInfo GM (string n)
55 MethodInfo [] methods = typeof (ExpressionTest_MakeBinary).GetMethods (
56 BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
58 foreach (MethodInfo m in methods)
62 throw new Exception (String.Format ("Method {0} not found", n));
66 public void MethodChecks ()
68 Expression left = Expression.Constant ("");
69 Expression right = Expression.Constant (1.0);
71 BinaryExpression r = Expression.Add (left, right, GM ("GoodMethod"));
72 Assert.AreEqual (r.Type, typeof (int));
76 [ExpectedException(typeof (ArgumentException))]
77 public void MethodCheck_BadArgs ()
79 Expression left = Expression.Constant ("");
80 Expression right = Expression.Constant (1.0);
82 Expression.Add (left, right, GM ("BadMethodSig_1"));
86 [ExpectedException(typeof (ArgumentException))]
87 public void MethodCheck_BadArgs2 ()
89 Expression left = Expression.Constant ("");
90 Expression right = Expression.Constant (1.0);
92 Expression.Add (left, right, GM ("BadMethodSig_2"));
96 [ExpectedException(typeof (ArgumentException))]
97 public void MethodCheck_BadArgs3 ()
99 Expression left = Expression.Constant ("");
100 Expression right = Expression.Constant (1.0);
102 Expression.Add (left, right, GM ("BadMethodSig_3"));
105 static void PassInt (ExpressionType nt)
107 Expression left = Expression.Constant (1);
108 Expression right = Expression.Constant (1);
110 Expression.MakeBinary (nt, left, right);
113 static void FailInt (ExpressionType nt)
115 Expression left = Expression.Constant (1);
116 Expression right = Expression.Constant (1);
119 Expression.MakeBinary (nt, left, right);
120 } catch (ArgumentException) {
122 } catch (InvalidOperationException) {
125 // If we get here, there was an error
126 Assert.Fail ("FailInt failed while creating an {0}", nt);
130 // Checks that we complain on the proper ExpressionTypes
133 public void TestBinaryCtor ()
135 PassInt (ExpressionType.Add);
136 PassInt (ExpressionType.AddChecked);
137 PassInt (ExpressionType.And);
138 PassInt (ExpressionType.Divide);
139 PassInt (ExpressionType.Equal);
140 PassInt (ExpressionType.ExclusiveOr);
141 PassInt (ExpressionType.GreaterThan);
142 PassInt (ExpressionType.GreaterThanOrEqual);
143 PassInt (ExpressionType.LeftShift);
144 PassInt (ExpressionType.LessThan);
145 PassInt (ExpressionType.LessThanOrEqual);
146 PassInt (ExpressionType.Multiply);
147 PassInt (ExpressionType.MultiplyChecked);
148 PassInt (ExpressionType.NotEqual);
149 PassInt (ExpressionType.Or);
150 PassInt (ExpressionType.Modulo);
151 PassInt (ExpressionType.RightShift);
152 PassInt (ExpressionType.Subtract);
153 PassInt (ExpressionType.SubtractChecked);
155 FailInt (ExpressionType.AndAlso);
156 FailInt (ExpressionType.OrElse);
157 FailInt (ExpressionType.Power);
158 FailInt (ExpressionType.ArrayLength);
159 FailInt (ExpressionType.ArrayIndex);
160 FailInt (ExpressionType.Call);
161 FailInt (ExpressionType.Coalesce);
162 FailInt (ExpressionType.Conditional);
163 FailInt (ExpressionType.Constant);
164 FailInt (ExpressionType.Convert);
165 FailInt (ExpressionType.ConvertChecked);
166 FailInt (ExpressionType.Invoke);
167 FailInt (ExpressionType.Lambda);
168 FailInt (ExpressionType.ListInit);
169 FailInt (ExpressionType.MemberAccess);
170 FailInt (ExpressionType.MemberInit);
171 FailInt (ExpressionType.Negate);
172 FailInt (ExpressionType.UnaryPlus);
173 FailInt (ExpressionType.NegateChecked);
174 FailInt (ExpressionType.New);
175 FailInt (ExpressionType.NewArrayInit);
176 FailInt (ExpressionType.NewArrayBounds);
177 FailInt (ExpressionType.Not);
178 FailInt (ExpressionType.Parameter);
179 FailInt (ExpressionType.Quote);
180 FailInt (ExpressionType.TypeAs);
181 FailInt (ExpressionType.TypeIs);
184 public T CodeGen<T> (Func<Expression, Expression, Expression> bin, T v1, T v2)
186 var lambda = Expression.Lambda<Func<T>> (bin (v1.ToConstant (), v2.ToConstant ())).Compile ();
191 public void TestOperations ()
193 Assert.AreEqual (30, CodeGen<int> ((a, b) => Expression.Add (a, b), 10, 20));
194 Assert.AreEqual (-12, CodeGen<int> ((a, b) => Expression.Subtract (a, b), 11, 23));
195 Assert.AreEqual (253, CodeGen<int> ((a, b) => Expression.Multiply (a, b), 11, 23));
196 Assert.AreEqual (33, CodeGen<int> ((a, b) => Expression.Divide (a, b), 100, 3));
197 Assert.AreEqual (100.0/3, CodeGen<double> ((a, b) => Expression.Divide (a, b), 100, 3));
200 void CTest<T> (ExpressionType node, bool r, T a, T b)
202 ParameterExpression pa = Expression.Parameter(typeof(T), "a");
203 ParameterExpression pb = Expression.Parameter(typeof(T), "b");
205 BinaryExpression p = Expression.MakeBinary (node, Expression.Constant (a), Expression.Constant(b));
206 Expression<Func<T,T,bool>> pexpr = Expression.Lambda<Func<T,T,bool>> (
207 p, new ParameterExpression [] { pa, pb });
209 Func<T,T,bool> compiled = pexpr.Compile ();
210 Assert.AreEqual (r, compiled (a, b), String.Format ("{0} ({1},{2}) == {3}", node, a, b, r));
214 public void ComparisonTests ()
216 ExpressionType t = ExpressionType.Equal;
218 CTest<byte> (t, true, 10, 10);
219 CTest<sbyte> (t, false, 1, 5);
220 CTest<sbyte> (t, true, 1, 1);
221 CTest<int> (t, true, 1, 1);
222 CTest<double> (t, true, 1.0, 1.0);
223 CTest<string> (t, true, "", "");
224 CTest<string> (t, true, "Hey", "Hey");
225 CTest<string> (t, false, "Hey", "There");
227 t = ExpressionType.NotEqual;
229 CTest<byte> (t, false, 10, 10);
230 CTest<sbyte> (t, true, 1, 5);
231 CTest<sbyte> (t, false, 1, 1);
232 CTest<int> (t, false, 1, 1);
233 CTest<double> (t, false, 1.0, 1.0);
234 CTest<double> (t, false, 1.0, 1.0);
235 CTest<string> (t, false, "", "");
236 CTest<string> (t, false, "Hey", "Hey");
237 CTest<string> (t, true, "Hey", "There");
239 t = ExpressionType.GreaterThan;
240 CTest<byte> (t, true, 5, 1);
241 CTest<byte> (t, false, 10, 10);
242 CTest<sbyte> (t, false, 1, 5);
243 CTest<sbyte> (t, false, 1, 1);
244 CTest<int> (t, false, 1, 1);
245 CTest<uint> (t, true, 1, 0);
246 CTest<ulong> (t, true, Int64.MaxValue, 0);
247 CTest<double> (t, false, 1.0, 1.0);
248 CTest<double> (t, false, 1.0, 1.0);
251 t = ExpressionType.LessThan;
252 CTest<byte> (t, false, 5, 1);
253 CTest<byte> (t, false, 10, 10);
254 CTest<sbyte> (t, true, 1, 5);
255 CTest<sbyte> (t, false, 1, 1);
256 CTest<int> (t, false, 1, 1);
257 CTest<uint> (t, false, 1, 0);
258 CTest<ulong> (t, false, Int64.MaxValue, 0);
259 CTest<double> (t, false, 1.0, 1.0);
260 CTest<double> (t, false, 1.0, 1.0);
262 t = ExpressionType.GreaterThanOrEqual;
263 CTest<byte> (t, true, 5, 1);
264 CTest<byte> (t, true, 10, 10);
265 CTest<sbyte> (t, false, 1, 5);
266 CTest<sbyte> (t, true, 1, 1);
267 CTest<int> (t, true, 1, 1);
268 CTest<uint> (t, true, 1, 0);
269 CTest<ulong> (t, true, Int64.MaxValue, 0);
270 CTest<double> (t, true, 1.0, 1.0);
271 CTest<double> (t, true, 1.0, 1.0);
274 t = ExpressionType.LessThanOrEqual;
275 CTest<byte> (t, false, 5, 1);
276 CTest<byte> (t, true, 10, 10);
277 CTest<sbyte> (t, true, 1, 5);
278 CTest<sbyte> (t, true, 1, 1);
279 CTest<int> (t, true, 1, 1);
280 CTest<uint> (t, false, 1, 0);
281 CTest<ulong> (t, false, Int64.MaxValue, 0);
282 CTest<double> (t, true, 1.0, 1.0);
283 CTest<double> (t, true, 1.0, 1.0);