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