PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs

https://bitbucket.org/steenlund/mono-2.6.7-for-amiga
C# | 475 lines | 358 code | 86 blank | 31 comment | 0 complexity | 4e69555ce161c8111b6d6def95b98f75 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0, LGPL-2.1
  1. //
  2. // ExpressionTest_Call.cs
  3. //
  4. // Author:
  5. // Federico Di Gregorio <fog@initd.org>
  6. // Jb Evain (jbevain@novell.com)
  7. //
  8. // (C) 2008 Novell, Inc. (http://www.novell.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. using System;
  30. using System.Reflection;
  31. using System.Collections.Generic;
  32. using System.Linq;
  33. using System.Linq.Expressions;
  34. using NUnit.Framework;
  35. namespace MonoTests.System.Linq.Expressions {
  36. [TestFixture]
  37. public class ExpressionTest_Call {
  38. [Test]
  39. [ExpectedException (typeof (ArgumentNullException))]
  40. public void Arg1Null ()
  41. {
  42. Expression.Call ((Type)null, "TestMethod", null, Expression.Constant (1));
  43. }
  44. [Test]
  45. [ExpectedException (typeof (ArgumentNullException))]
  46. public void Arg2Null ()
  47. {
  48. Expression.Call (typeof (MemberClass), null, null, Expression.Constant (1));
  49. }
  50. [Test]
  51. [ExpectedException (typeof (InvalidOperationException))]
  52. public void Arg4WrongType ()
  53. {
  54. Expression.Call (typeof (MemberClass), "StaticMethod", null, Expression.Constant (true));
  55. }
  56. [Test]
  57. [ExpectedException (typeof (InvalidOperationException))]
  58. public void InstanceMethod ()
  59. {
  60. Expression.Call (typeof (MemberClass), "TestMethod", null, Expression.Constant (1));
  61. }
  62. [Test]
  63. public void StaticMethod ()
  64. {
  65. Expression.Call (typeof (MemberClass), "StaticMethod", null, Expression.Constant (1));
  66. }
  67. [Test]
  68. public void StaticGenericMethod ()
  69. {
  70. Expression.Call (typeof (MemberClass), "StaticGenericMethod", new [] { typeof (int) }, Expression.Constant (1));
  71. }
  72. [Test]
  73. [ExpectedException (typeof (ArgumentNullException))]
  74. public void ArgMethodNull ()
  75. {
  76. Expression.Call (Expression.Constant (new object ()), null);
  77. }
  78. [Test]
  79. [ExpectedException (typeof (ArgumentNullException))]
  80. public void ArgInstanceNullForNonStaticMethod ()
  81. {
  82. Expression.Call (null, typeof (object).GetMethod ("ToString"));
  83. }
  84. [Test]
  85. [ExpectedException (typeof (ArgumentException))]
  86. public void InstanceTypeDoesntMatchMethodDeclaringType ()
  87. {
  88. Expression.Call (Expression.Constant (1), typeof (string).GetMethod ("Intern"));
  89. }
  90. [Test]
  91. [ExpectedException (typeof (ArgumentException))]
  92. public void MethodArgumentCountDoesnMatchParameterLength ()
  93. {
  94. Expression.Call (Expression.Constant (new object ()), typeof (object).GetMethod ("ToString"), Expression.Constant (new object ()));
  95. }
  96. public class Foo {
  97. public void Bar (string s)
  98. {
  99. }
  100. }
  101. [Test]
  102. [ExpectedException (typeof (ArgumentNullException))]
  103. public void MethodHasNullArgument ()
  104. {
  105. Expression.Call (Expression.New (typeof (Foo)), typeof (Foo).GetMethod ("Bar"), null as Expression);
  106. }
  107. [Test]
  108. [ExpectedException (typeof (ArgumentException))]
  109. public void MethodArgumentDoesntMatchParameterType ()
  110. {
  111. Expression.Call (Expression.New (typeof (Foo)), typeof (Foo).GetMethod ("Bar"), Expression.Constant (42));
  112. }
  113. [Test]
  114. public void CallToString ()
  115. {
  116. var call = Expression.Call (Expression.Constant (new object ()), typeof (object).GetMethod ("ToString"));
  117. Assert.AreEqual ("value(System.Object).ToString()", call.ToString ());
  118. }
  119. [Test]
  120. public void CallStringIsNullOrEmpty ()
  121. {
  122. var call = Expression.Call (null, typeof (string).GetMethod ("IsNullOrEmpty"), Expression.Constant (""));
  123. Assert.AreEqual ("IsNullOrEmpty(\"\")", call.ToString ());
  124. }
  125. [Test]
  126. [Category ("NotDotNet")] // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=339351
  127. [ExpectedException (typeof (ArgumentException))]
  128. public void CallStaticMethodWithInstanceArgument ()
  129. {
  130. Expression.Call (
  131. Expression.Parameter (GetType (), "t"),
  132. GetType ().GetMethod ("Identity"),
  133. Expression.Constant (null));
  134. }
  135. public static object Identity (object o)
  136. {
  137. return o;
  138. }
  139. [Test]
  140. public void CompileSimpleStaticCall ()
  141. {
  142. var p = Expression.Parameter (typeof (object), "o");
  143. var lambda = Expression.Lambda<Func<object, object>> (Expression.Call (GetType ().GetMethod ("Identity"), p), p);
  144. var i = lambda.Compile ();
  145. Assert.AreEqual (2, i (2));
  146. Assert.AreEqual ("Foo", i ("Foo"));
  147. }
  148. [Test]
  149. public void CompileSimpleInstanceCall ()
  150. {
  151. var p = Expression.Parameter (typeof (string), "p");
  152. var lambda = Expression.Lambda<Func<string, string>> (
  153. Expression.Call (
  154. p, typeof (string).GetMethod ("ToString", Type.EmptyTypes)),
  155. p);
  156. var ts = lambda.Compile ();
  157. Assert.AreEqual ("foo", ts ("foo"));
  158. Assert.AreEqual ("bar", ts ("bar"));
  159. }
  160. [Test]
  161. [ExpectedException (typeof (InvalidOperationException))]
  162. public void CheckTypeArgsIsNotUsedForParameterLookup ()
  163. {
  164. Expression.Call (GetType (), "EineMethod", new [] { typeof (string), typeof (int) }, "foo".ToConstant (), 2.ToConstant ());
  165. }
  166. public static void EineGenericMethod<X, Y> (string foo, int bar)
  167. {
  168. }
  169. [Test]
  170. public void CheckTypeArgsIsUsedForGenericArguments ()
  171. {
  172. var m = Expression.Call (GetType (), "EineGenericMethod", new [] { typeof (string), typeof (int) }, "foo".ToConstant (), 2.ToConstant ());
  173. Assert.IsNotNull (m.Method);
  174. Assert.AreEqual ("Void EineGenericMethod[String,Int32](System.String, Int32)", m.Method.ToString ());
  175. }
  176. public struct EineStrukt {
  177. public string Foo;
  178. public EineStrukt (string foo)
  179. {
  180. Foo = foo;
  181. }
  182. public string GimmeFoo ()
  183. {
  184. return Foo;
  185. }
  186. }
  187. [Test]
  188. public void CallMethodOnStruct ()
  189. {
  190. var param = Expression.Parameter (typeof (EineStrukt), "s");
  191. var foo = Expression.Lambda<Func<EineStrukt, string>> (
  192. Expression.Call (param, typeof (EineStrukt).GetMethod ("GimmeFoo")), param).Compile ();
  193. var s = new EineStrukt ("foo");
  194. Assert.AreEqual ("foo", foo (s));
  195. }
  196. public static int OneStaticMethod ()
  197. {
  198. return 42;
  199. }
  200. [Test]
  201. [Category ("NotDotNet")] // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=339351
  202. [ExpectedException (typeof (ArgumentException))]
  203. public void CallStaticMethodOnNonSenseInstanceExpression ()
  204. {
  205. Expression.Call (
  206. Expression.Constant ("la la la"),
  207. this.GetType ().GetMethod ("OneStaticMethod"));
  208. }
  209. public static int DoSomethingWith (ref int a)
  210. {
  211. return a + 4;
  212. }
  213. public static string DoAnotherThing (ref int a, string s)
  214. {
  215. return s + a;
  216. }
  217. [Test]
  218. public void CallStaticMethodWithRefParameter ()
  219. {
  220. var p = Expression.Parameter (typeof (int), "i");
  221. var c = Expression.Lambda<Func<int, int>> (
  222. Expression.Call (GetType ().GetMethod ("DoSomethingWith"), p), p).Compile ();
  223. Assert.AreEqual (42, c (38));
  224. }
  225. [Test]
  226. public void CallStaticMethodWithRefParameterAndOtherParameter ()
  227. {
  228. var i = Expression.Parameter (typeof (int), "i");
  229. var s = Expression.Parameter (typeof (string), "s");
  230. var lamda = Expression.Lambda<Func<int, string, string>> (
  231. Expression.Call (GetType ().GetMethod ("DoAnotherThing"), i, s), i, s).Compile ();
  232. Assert.AreEqual ("foo42", lamda (42, "foo"));
  233. }
  234. public static int Bang (Expression i)
  235. {
  236. return (int) (i as ConstantExpression).Value;
  237. }
  238. [Test]
  239. public void CallMethodWithExpressionParameter ()
  240. {
  241. var call = Expression.Call (GetType ().GetMethod ("Bang"), Expression.Constant (42));
  242. Assert.AreEqual (ExpressionType.Quote, call.Arguments [0].NodeType);
  243. var l = Expression.Lambda<Func<int>> (call).Compile ();
  244. Assert.AreEqual (42, l ());
  245. }
  246. static bool fout_called = false;
  247. public static int FooOut (out int x)
  248. {
  249. fout_called = true;
  250. return x = 0;
  251. }
  252. [Test]
  253. public void Connect282729 ()
  254. {
  255. // test from https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=282729
  256. var p = Expression.Parameter (typeof (int), "p");
  257. var lambda = Expression.Lambda<Func<int, int>> (
  258. Expression.Call (
  259. GetType ().GetMethod ("FooOut"),
  260. Expression.ArrayIndex(
  261. Expression.NewArrayBounds (
  262. typeof(int),
  263. 1.ToConstant ()),
  264. 0.ToConstant ())),
  265. p).Compile ();
  266. Assert.AreEqual (0, lambda (0));
  267. Assert.IsTrue (fout_called);
  268. }
  269. public static int FooOut2 (out int x)
  270. {
  271. x = 2;
  272. return 3;
  273. }
  274. [Test]
  275. [Category ("NotWorking")]
  276. public void Connect290278 ()
  277. {
  278. // test from https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=290278
  279. var p = Expression.Parameter (typeof (int [,]), "p");
  280. var lambda = Expression.Lambda<Func<int [,], int>> (
  281. Expression.Call (
  282. GetType ().GetMethod ("FooOut2"),
  283. Expression.ArrayIndex (p, 0.ToConstant (), 0.ToConstant ())),
  284. p).Compile ();
  285. int [,] data = { { 1 } };
  286. Assert.AreEqual (3, lambda (data));
  287. Assert.AreEqual (2, data [0, 0]);
  288. }
  289. public static void FooRef (ref string s)
  290. {
  291. }
  292. [Test]
  293. public void Connect297597 ()
  294. {
  295. // test from https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=297597
  296. var strings = new string [1];
  297. var lambda = Expression.Lambda<Action> (
  298. Expression.Call (
  299. GetType ().GetMethod ("FooRef"),
  300. Expression.ArrayIndex (
  301. Expression.Constant (strings), 0.ToConstant ()))).Compile ();
  302. lambda ();
  303. }
  304. [Test]
  305. [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=319190
  306. public void Connect319190 ()
  307. {
  308. var lambda = Expression.Lambda<Func<bool>> (
  309. Expression.TypeIs (
  310. Expression.New (typeof (TypedReference)),
  311. typeof (object))).Compile ();
  312. Assert.IsTrue (lambda ());
  313. }
  314. public static int Truc ()
  315. {
  316. return 42;
  317. }
  318. [Test]
  319. public void Connect282702 ()
  320. {
  321. var lambda = Expression.Lambda<Func<Func<int>>> (
  322. Expression.Convert (
  323. Expression.Call (
  324. typeof (Delegate).GetMethod ("CreateDelegate", new [] { typeof (Type), typeof (object), typeof (MethodInfo) }),
  325. Expression.Constant (typeof (Func<int>), typeof (Type)),
  326. Expression.Constant (null, typeof (object)),
  327. Expression.Constant (GetType ().GetMethod ("Truc"))),
  328. typeof (Func<int>))).Compile ();
  329. Assert.AreEqual (42, lambda ().Invoke ());
  330. }
  331. [Test]
  332. public void CallQueryableWhere ()
  333. {
  334. var queryable = new [] { 1, 2, 3 }.AsQueryable ();
  335. var parameter = Expression.Parameter (typeof (int), "i");
  336. var lambda = Expression.Lambda<Func<int, bool>> (
  337. Expression.LessThan (parameter, Expression.Constant (2)),
  338. parameter);
  339. var selector = Expression.Quote (lambda);
  340. var call = Expression.Call (
  341. typeof (Queryable),
  342. "Where",
  343. new [] { typeof (int) },
  344. queryable.Expression,
  345. selector);
  346. Assert.IsNotNull (call);
  347. Assert.IsNotNull (call.Method);
  348. }
  349. [Test]
  350. public void CallAsQueryable () // #537768
  351. {
  352. var constant = Expression.Constant (
  353. new List<string> (),
  354. typeof (IEnumerable<string>));
  355. var call = Expression.Call (
  356. typeof (Queryable),
  357. "AsQueryable",
  358. new [] { typeof (string) },
  359. constant);
  360. Assert.IsNotNull (call);
  361. Assert.AreEqual (1, call.Arguments.Count);
  362. Assert.AreEqual (constant, call.Arguments [0]);
  363. var method = call.Method;
  364. Assert.AreEqual ("AsQueryable", method.Name);
  365. Assert.IsTrue (method.IsGenericMethod);
  366. Assert.AreEqual (typeof (string), method.GetGenericArguments () [0]);
  367. }
  368. [Test]
  369. public void CallQueryableSelect () // #536637
  370. {
  371. var parameter = Expression.Parameter (typeof (string), "s");
  372. var string_length = Expression.Property (parameter, typeof (string).GetProperty ("Length"));
  373. var lambda = Expression.Lambda (string_length, parameter);
  374. var strings = new [] { "1", "22", "333" };
  375. var call = Expression.Call (
  376. typeof (Queryable),
  377. "Select",
  378. new [] { typeof (string), typeof (int) },
  379. Expression.Constant (strings.AsQueryable ()),
  380. lambda);
  381. Assert.IsNotNull (call);
  382. var method = call.Method;
  383. Assert.AreEqual ("Select", method.Name);
  384. Assert.IsTrue (method.IsGenericMethod);
  385. Assert.AreEqual (typeof (string), method.GetGenericArguments () [0]);
  386. Assert.AreEqual (typeof (int), method.GetGenericArguments () [1]);
  387. }
  388. }
  389. }