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