ParameterInfoTest.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. //
  2. // ParameterInfoTest - NUnit Test Cases for the ParameterInfo class
  3. //
  4. // Zoltan Varga ([email protected])
  5. //
  6. // (C) Ximian, Inc. http://www.ximian.com
  7. // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
  8. //
  9. //
  10. using System;
  11. using System.Threading;
  12. using System.Reflection;
  13. using System.Runtime.InteropServices;
  14. using System.Runtime.CompilerServices;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Text;
  18. using NUnit.Framework;
  19. namespace MonoTests.System.Reflection
  20. {
  21. public class Marshal1 : ICustomMarshaler
  22. {
  23. public static ICustomMarshaler GetInstance (string s)
  24. {
  25. return new Marshal1 ();
  26. }
  27. public void CleanUpManagedData (object managedObj)
  28. {
  29. }
  30. public void CleanUpNativeData (IntPtr pNativeData)
  31. {
  32. }
  33. public int GetNativeDataSize ()
  34. {
  35. return 4;
  36. }
  37. public IntPtr MarshalManagedToNative (object managedObj)
  38. {
  39. return IntPtr.Zero;
  40. }
  41. public object MarshalNativeToManaged (IntPtr pNativeData)
  42. {
  43. return null;
  44. }
  45. }
  46. [TestFixture]
  47. public class ParameterInfoTest
  48. {
  49. [Test]
  50. public void IsDefined_AttributeType_Null ()
  51. {
  52. MethodInfo mi = typeof (object).GetMethod ("Equals",
  53. new Type [1] { typeof (object) });
  54. ParameterInfo pi = mi.GetParameters () [0];
  55. try {
  56. pi.IsDefined ((Type) null, false);
  57. Assert.Fail ("#1");
  58. } catch (ArgumentNullException ex) {
  59. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  60. Assert.IsNull (ex.InnerException, "#3");
  61. Assert.IsNotNull (ex.Message, "#4");
  62. Assert.IsNotNull (ex.ParamName, "#5");
  63. Assert.AreEqual ("attributeType", ex.ParamName, "#6");
  64. }
  65. }
  66. #if !MOBILE
  67. public enum ParamEnum {
  68. None = 0,
  69. Foo = 1,
  70. Bar = 2
  71. };
  72. public static void paramMethod (int i, [In] int j, [Out] int k, [Optional] int l, [In,Out] int m, ParamEnum n = ParamEnum.Foo)
  73. {
  74. }
  75. [DllImport ("foo")]
  76. public extern static void marshalAsMethod (
  77. [MarshalAs(UnmanagedType.Bool)]int p0,
  78. [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] string [] p1,
  79. [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5")] object p2);
  80. [Test]
  81. public void DefaultValueEnum () {
  82. ParameterInfo[] info = typeof (ParameterInfoTest).GetMethod ("paramMethod").GetParameters ();
  83. Assert.AreEqual (typeof (ParamEnum), info [5].DefaultValue.GetType (), "#1");
  84. Assert.AreEqual (ParamEnum.Foo, info [5].DefaultValue, "#2");
  85. }
  86. [Test]
  87. public void HasDefaultValueEnum () {
  88. ParameterInfo[] info = typeof (ParameterInfoTest).GetMethod ("paramMethod").GetParameters ();
  89. Assert.IsTrue (info [5].HasDefaultValue);
  90. }
  91. public static void Sample2 ([DecimalConstantAttribute(2,2,2,2,2)] decimal a, [DateTimeConstantAttribute(123456)] DateTime b) {}
  92. [Test]
  93. public void DefaultValuesFromCustomAttr () {
  94. ParameterInfo[] info = typeof (ParameterInfoTest).GetMethod ("Sample2").GetParameters ();
  95. Assert.AreEqual (typeof (Decimal), info [0].DefaultValue.GetType (), "#1");
  96. Assert.AreEqual (typeof (DateTime), info [1].DefaultValue.GetType (), "#2");
  97. }
  98. [Test] // bug #339013
  99. public void TestDefaultValues ()
  100. {
  101. ParameterInfo [] pi = typeof (ParameterInfoTest).GetMethod ("Sample").GetParameters ();
  102. Assert.AreEqual (pi [0].DefaultValue.GetType (), typeof (DBNull), "#1");
  103. Assert.AreEqual (pi [1].DefaultValue.GetType (), typeof (Missing), "#2");
  104. }
  105. [Test]
  106. public void TestHasDefaultValues ()
  107. {
  108. ParameterInfo [] pi = typeof (ParameterInfoTest).GetMethod ("Sample").GetParameters ();
  109. Assert.IsFalse (pi [0].HasDefaultValue, "#1");
  110. Assert.IsFalse (pi [1].HasDefaultValue, "#2");
  111. Assert.IsTrue (pi [2].HasDefaultValue, "#3");
  112. }
  113. public void Sample (int a, [Optional] int b, object c = null)
  114. {
  115. }
  116. [Test]
  117. public void PseudoCustomAttributes () {
  118. ParameterInfo[] info = typeof (ParameterInfoTest).GetMethod ("paramMethod").GetParameters ();
  119. Assert.AreEqual (0, info[0].GetCustomAttributes (true).Length, "#A1");
  120. Assert.AreEqual (1, info[1].GetCustomAttributes (typeof (InAttribute), true).Length, "#A2");
  121. Assert.AreEqual (1, info[2].GetCustomAttributes (typeof (OutAttribute), true).Length, "#A3");
  122. Assert.AreEqual (1, info[3].GetCustomAttributes (typeof (OptionalAttribute), true).Length, "#A4");
  123. Assert.AreEqual (2, info[4].GetCustomAttributes (true).Length, "#A5");
  124. ParameterInfo[] pi = typeof (ParameterInfoTest).GetMethod ("marshalAsMethod").GetParameters ();
  125. MarshalAsAttribute attr;
  126. attr = (MarshalAsAttribute)(pi [0].GetCustomAttributes (true) [0]);
  127. Assert.AreEqual (UnmanagedType.Bool, attr.Value, "#B");
  128. attr = (MarshalAsAttribute)(pi [1].GetCustomAttributes (true) [0]);
  129. Assert.AreEqual (UnmanagedType.LPArray, attr.Value, "#C1");
  130. Assert.AreEqual (UnmanagedType.LPStr, attr.ArraySubType, "#C2");
  131. attr = (MarshalAsAttribute)(pi [2].GetCustomAttributes (true) [0]);
  132. Assert.AreEqual (UnmanagedType.CustomMarshaler, attr.Value, "#D1");
  133. Assert.AreEqual ("5", attr.MarshalCookie, "#D2");
  134. Assert.AreEqual (typeof (Marshal1), Type.GetType (attr.MarshalType), "#D3");
  135. }
  136. [Test] // bug #342536
  137. public void Generics_Name ()
  138. {
  139. MethodInfo mi;
  140. Type type;
  141. ParameterInfo [] info;
  142. type = typeof (BaseType<string>);
  143. mi = type.GetMethod ("GetItems");
  144. Assert.IsNotNull (mi, "#A1");
  145. info = mi.GetParameters ();
  146. Assert.AreEqual (1, info.Length, "#A2");
  147. Assert.AreEqual ("count", info [0].Name, "#A3");
  148. mi = type.GetMethod ("Add");
  149. Assert.IsNotNull (mi, "#B1");
  150. info = mi.GetParameters ();
  151. Assert.AreEqual (2, info.Length, "#B2");
  152. Assert.AreEqual ("item", info [0].Name, "#B3");
  153. Assert.AreEqual ("index", info [1].Name, "#B4");
  154. mi = type.GetMethod ("Create");
  155. Assert.IsNotNull (mi, "#C1");
  156. info = mi.GetParameters ();
  157. Assert.AreEqual (2, info.Length, "#C2");
  158. Assert.AreEqual ("x", info [0].Name, "#C3");
  159. Assert.AreEqual ("item", info [1].Name, "#C4");
  160. }
  161. public class BaseType <T>
  162. {
  163. public void GetItems (int count)
  164. {
  165. }
  166. public void Add (T item, int index)
  167. {
  168. }
  169. public V Create <V> (int x, T item)
  170. {
  171. return default (V);
  172. }
  173. }
  174. #endif
  175. [Test]
  176. public void Member () {
  177. ParameterInfo parm = typeof (Derived).GetMethod ("SomeMethod").GetParameters()[0];
  178. Assert.AreEqual (typeof (Derived), parm.Member.ReflectedType);
  179. Assert.AreEqual (typeof (Base), parm.Member.DeclaringType);
  180. }
  181. [Test]
  182. public void ArrayMethodParameters ()
  183. {
  184. var matrix_int_get = typeof (int[,,]).GetMethod ("Get");
  185. var parameters = matrix_int_get.GetParameters ();
  186. Assert.AreEqual (3, parameters.Length);
  187. Assert.AreEqual (0, parameters [0].GetCustomAttributes (false).Length);
  188. Assert.AreEqual (0, parameters [1].GetCustomAttributes (false).Length);
  189. Assert.AreEqual (0, parameters [2].GetCustomAttributes (false).Length);
  190. }
  191. class Base
  192. {
  193. public void SomeMethod( int x )
  194. {
  195. }
  196. }
  197. class Derived : Base
  198. {
  199. }
  200. public static void TestC (decimal u = decimal.MaxValue) {
  201. }
  202. [Test]
  203. public void DefaultValueDecimal () {
  204. var info = typeof (ParameterInfoTest).GetMethod ("TestC").GetParameters ();
  205. Assert.AreEqual (decimal.MaxValue, info [0].DefaultValue);
  206. }
  207. [Test]
  208. public void HasDefaultValueDecimal () {
  209. var info = typeof (ParameterInfoTest).GetMethod ("TestC").GetParameters ();
  210. Assert.IsTrue (info [0].HasDefaultValue);
  211. }
  212. class TestParamAttribute : Attribute
  213. {
  214. }
  215. public static int TestCustomAttribute_Method ([TestParamAttribute] string arg)
  216. {
  217. return arg.Length;
  218. }
  219. [Test]
  220. public void TestCustomAttribute ()
  221. {
  222. var metInfo = GetType ().GetMethod ("TestCustomAttribute_Method", new Type[] { typeof(string) });
  223. var paramInfos = metInfo.GetParameters ();
  224. var argParamInfo = paramInfos[0];
  225. var custAttrs = argParamInfo.GetCustomAttributes ();
  226. Assert.AreEqual (1, custAttrs.Count ());
  227. }
  228. class MyParameterInfo2 : ParameterInfo
  229. {
  230. public ParameterAttributes MyAttrsImpl;
  231. public override ParameterAttributes Attributes {
  232. get {return MyAttrsImpl;}
  233. }
  234. public IList<CustomAttributeData> myList = new List<CustomAttributeData> ();
  235. public override IList<CustomAttributeData> GetCustomAttributesData () {
  236. return myList;
  237. }
  238. }
  239. class MyParameterInfo : ParameterInfo
  240. {
  241. public void SetClassImpl (Type t)
  242. {
  243. ClassImpl = t;
  244. }
  245. public void SetDefaultValueImpl (object o)
  246. {
  247. DefaultValueImpl = o;
  248. }
  249. public void SetMemberImpl (MemberInfo o)
  250. {
  251. MemberImpl = o;
  252. }
  253. public void SetNameImpl (string s)
  254. {
  255. NameImpl = s;
  256. }
  257. public void SetPositionImpl (int i)
  258. {
  259. PositionImpl = i;
  260. }
  261. public void SetAttrsImpl (ParameterAttributes a)
  262. {
  263. AttrsImpl = a;
  264. }
  265. public void TestMethod (int a) {}
  266. public int this[int x, int y] {
  267. get { return 0; }
  268. set { }
  269. }
  270. }
  271. [Test]
  272. public void SubClassWithNoOverrides ()
  273. {
  274. var p = new MyParameterInfo ();
  275. Assert.IsFalse (p.IsDefined (typeof (FlagsAttribute), false), "#1");
  276. Assert.AreEqual (0, p.GetCustomAttributes (false).Length, "#2");
  277. Assert.AreEqual (0, p.GetCustomAttributes (typeof (FlagsAttribute), false).Length, "#3");
  278. Assert.AreEqual (0, p.GetOptionalCustomModifiers ().Length, "#4");
  279. Assert.AreEqual (0, p.GetRequiredCustomModifiers ().Length, "#5");
  280. try {
  281. var ign = p.HasDefaultValue;
  282. Assert.Fail ("#6");
  283. } catch (NotImplementedException) {
  284. }
  285. Assert.IsFalse (p.IsIn, "#7");
  286. #if FEATURE_USE_LCID
  287. Assert.IsFalse (p.IsLcid, "#8");
  288. #endif
  289. Assert.IsFalse (p.IsOptional, "#9");
  290. Assert.IsFalse (p.IsOut, "#10");
  291. Assert.IsFalse (p.IsRetval, "#10");
  292. try {
  293. var ign = p.CustomAttributes;
  294. Assert.Fail ("#11");
  295. } catch (NotImplementedException) {
  296. }
  297. try {
  298. p.GetCustomAttributesData ();
  299. Assert.Fail ("#12");
  300. } catch (NotImplementedException) {
  301. }
  302. Assert.AreEqual (0x8000000, p.MetadataToken, "#13");
  303. Assert.AreEqual (0, p.Position, "#14");
  304. try {
  305. var ign = p.DefaultValue;
  306. Assert.Fail ("#15");
  307. } catch (NotImplementedException) {
  308. }
  309. try {
  310. var ign = p.RawDefaultValue;
  311. Assert.Fail ("#16");
  312. } catch (NotImplementedException) {
  313. }
  314. Assert.IsNull (p.Member, "#17");
  315. Assert.AreEqual (ParameterAttributes.None, p.Attributes, "#18");
  316. Assert.IsNull (p.Name, "#19");
  317. Assert.IsNull (p.ParameterType, "#20");
  318. }
  319. [Test]
  320. public void SubClassWithValuesSet ()
  321. {
  322. var p = new MyParameterInfo ();
  323. p.SetClassImpl (typeof (Decimal));
  324. Assert.AreEqual (typeof (Decimal), p.ParameterType, "#1");
  325. p.SetClassImpl (null);
  326. p.SetDefaultValueImpl ("foo");
  327. try {
  328. var ign = p.DefaultValue;
  329. Assert.Fail ("#2");
  330. } catch (NotImplementedException) {
  331. }
  332. p.SetDefaultValueImpl (null);
  333. var obj = typeof (object);
  334. p.SetMemberImpl (obj);
  335. Assert.AreEqual (obj, p.Member, "#3");
  336. Assert.AreEqual (0x8000000, p.MetadataToken, "#4");
  337. p.SetMemberImpl (null);
  338. var method = typeof (MyParameterInfo).GetMethod ("TestMethod");
  339. p.SetMemberImpl (method);
  340. Assert.IsNotNull (method, "#5");
  341. Assert.AreEqual (method, p.Member, "#6");
  342. Assert.AreEqual (0x8000000, p.MetadataToken, "#7");
  343. p.SetMemberImpl (null);
  344. var property = typeof (MyParameterInfo).GetProperty ("Item");
  345. p.SetMemberImpl (property);
  346. Assert.IsNotNull (property, "#8");
  347. Assert.AreEqual (property, p.Member, "#9");
  348. Assert.AreEqual (0x8000000, p.MetadataToken, "#10");
  349. p.SetMemberImpl (null);
  350. p.SetNameImpl ("foo");
  351. Assert.AreEqual ("foo", p.Name, "#11");
  352. p.SetNameImpl (null);
  353. p.SetPositionImpl (99);
  354. Assert.AreEqual (p.Position, 99, "#12");
  355. Assert.AreEqual (p.MetadataToken, 0x8000000, "#13");
  356. p.SetPositionImpl (0);
  357. Assert.IsFalse (p.IsIn, "#14");
  358. p.SetAttrsImpl (ParameterAttributes.In);
  359. Assert.IsTrue (p.IsIn, "#15");
  360. }
  361. [Test]
  362. public void SubClassWithOverrides ()
  363. {
  364. var p2 = new MyParameterInfo2 ();
  365. Assert.IsFalse (p2.IsIn, "#1");
  366. p2.MyAttrsImpl = ParameterAttributes.In;
  367. Assert.IsTrue (p2.IsIn, "#2");
  368. Assert.AreEqual (p2.myList, p2.CustomAttributes, "#3");
  369. }
  370. [Test]
  371. public void ParameterInfoToString ()
  372. {
  373. var method = typeof (TestNestedClass).GetTypeInfo ().GetMethod ("TestMethod");
  374. var sb = new StringBuilder ();
  375. foreach (var parameter in method.GetParameters ())
  376. {
  377. sb.Append (parameter + "\n");
  378. }
  379. string actual = sb.ToString ();
  380. string expected = "Int32 a0\n" +
  381. "System.String a1\n" +
  382. "TestNestedClass a2\n" +
  383. "System.Collections.Generic.List`1[System.Int32] a3\n" +
  384. "System.Collections.Generic.List`1[System.Text.StringBuilder] a4\n" +
  385. "System.Collections.Generic.List`1[MonoTests.System.Reflection.ParameterInfoTest+TestNestedClass] a5\n" +
  386. "System.Text.StringBuilder a6\n" +
  387. "System.Collections.Generic.Dictionary`2[System.Int32,System.String] a7\n" +
  388. "Int32& a8\n" +
  389. "Int32& a9\n" +
  390. "TestNestedClass& a10\n" +
  391. "System.Collections.Generic.List`1[System.Int32]& a11\n";
  392. Assert.AreEqual (expected, actual, "#1");
  393. }
  394. public class TestNestedClass
  395. {
  396. public static void TestMethod (int a0, string a1,
  397. TestNestedClass a2, List<int> a3,
  398. List<StringBuilder> a4, List<TestNestedClass> a5,
  399. StringBuilder a6, Dictionary<int, string> a7,
  400. out int a8, ref int a9, out TestNestedClass a10, out List<int> a11)
  401. {
  402. a8 = 0;
  403. a9 = 0;
  404. a10 = null;
  405. a11 = null;
  406. }
  407. }
  408. [Test] // https://github.com/mono/mono/issues/8312
  409. // The linker removes the SkipWhile methods
  410. [Category ("MobileNotWorking")]
  411. public void ParameterInfoToStringForQueryableSkipWhile ()
  412. {
  413. var sb = new StringBuilder ();
  414. var methods = typeof (Queryable).GetTypeInfo ().GetMethods ().Where (m => m.Name == "SkipWhile");
  415. foreach (var methodInfo in methods)
  416. {
  417. foreach (var parameter in methodInfo.GetParameters ())
  418. {
  419. sb.Append (parameter + "\n");
  420. }
  421. }
  422. string actual = sb.ToString ();
  423. string expected = "System.Linq.IQueryable`1[TSource] source\n" +
  424. "System.Linq.Expressions.Expression`1[System.Func`2[TSource,System.Boolean]] predicate\n" +
  425. "System.Linq.IQueryable`1[TSource] source\n" +
  426. "System.Linq.Expressions.Expression`1[System.Func`3[TSource,System.Int32,System.Boolean]] predicate\n";
  427. Assert.AreEqual (expected, actual, "#1");
  428. }
  429. }
  430. }