Disable some tests failing on mt due to #10539/#10552.
[mono.git] / mcs / class / corlib / Test / System.Reflection / MethodBaseTest.cs
1 //
2 // System.Reflection.MethodBase Test Cases
3 //
4 // Authors:
5 //  Gert Driesen (drieseng@users.sourceforge.net)
6 //
7 // Copyright (C) 2008 Gert Driesen
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Reflection;
31
32 using NUnit.Framework;
33
34 namespace MonoTests.System.Reflection
35 {
36         public class Generic<T> {
37                 public void Foo () {
38                 }
39
40                 public void GenericFoo<K> () {
41
42                 }
43         }
44
45         public class AnotherGeneric<T> {
46                 public void Foo () {
47                 }       
48         }
49
50         public class SimpleClass {
51                 public void GenericFoo<K> () {
52
53                 }
54         }
55
56         class MethodBaseOverloadTestDoesNotCauseCompilerError : MethodBase
57         {
58                 public override MethodAttributes Attributes
59                 {
60                         get { throw new NotImplementedException (); }
61                 }
62
63                 public override MethodImplAttributes GetMethodImplementationFlags ()
64                 {
65                         throw new NotImplementedException ();
66                 }
67
68                 public override ParameterInfo[] GetParameters ()
69                 {
70                         throw new NotImplementedException ();
71                 }
72
73                 public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, global::System.Globalization.CultureInfo culture)
74                 {
75                         throw new NotImplementedException ();
76                 }
77
78                 public override RuntimeMethodHandle MethodHandle
79                 {
80                         get { throw new NotImplementedException (); }
81                 }
82
83                 public override Type DeclaringType
84                 {
85                         get { throw new NotImplementedException (); }
86                 }
87
88                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
89                 {
90                         throw new NotImplementedException ();
91                 }
92
93                 public override object[] GetCustomAttributes (bool inherit)
94                 {
95                         throw new NotImplementedException ();
96                 }
97
98                 public override bool IsDefined (Type attributeType, bool inherit)
99                 {
100                         throw new NotImplementedException ();
101                 }
102
103                 public override MemberTypes MemberType
104                 {
105                         get { throw new NotImplementedException (); }
106                 }
107
108                 public override string Name
109                 {
110                         get { throw new NotImplementedException (); }
111                 }
112
113                 public override Type ReflectedType
114                 {
115                         get { throw new NotImplementedException (); }
116                 }
117         }
118
119         [TestFixture]
120         public class MethodBaseTest
121         {
122                 public static MethodInfo Where<T> (T a) {
123                         return (MethodInfo) MethodBase.GetCurrentMethod ();
124                 }
125
126                 public class Foo<K>
127                 {
128                         public static MethodInfo Where<T> (T a, K b) {
129                                 return (MethodInfo) MethodBase.GetCurrentMethod ();
130                         }
131                 }
132
133                 [Test]
134                 public void GetCurrentMethodDropsAllGenericArguments ()
135                 {
136                         MethodInfo a = Where<int> (10);
137                         MethodInfo b = Foo<int>.Where <double> (10, 10);
138
139                         Assert.IsTrue (a.IsGenericMethodDefinition, "#1");
140                         Assert.IsTrue (b.IsGenericMethodDefinition, "#2");
141
142                         Assert.IsTrue (b.DeclaringType.IsGenericTypeDefinition, "#3");
143
144                         Assert.AreSame (a, typeof (MethodBaseTest).GetMethod ("Where"), "#4");
145                         Assert.AreSame (b, typeof (Foo<>).GetMethod ("Where"), "#5");
146                 }
147
148                 [Test] // GetMethodFromHandle (RuntimeMethodHandle)
149                 public void GetMethodFromHandle1_Handle_Generic ()
150                 {
151                         G<string> instance = new G<string> ();
152                         Type t = instance.GetType ();
153                         MethodBase mb1 = t.GetMethod ("M");
154                         RuntimeMethodHandle mh = mb1.MethodHandle;
155                         RuntimeTypeHandle th = t.TypeHandle;
156
157                         try {
158                                 MethodBase.GetMethodFromHandle (mh);
159                                 Assert.Fail ("#1");
160                         } catch (ArgumentException ex) {
161                                 // Cannot resolve method Void M(System.__Canon)
162                                 // because the declaring type of the method
163                                 // handle MonoTests.System.Reflection.MethodBaseTest+G`1[T]
164                                 // is generic. Explicitly provide the declaring type to
165                                 // GetMethodFromHandle
166                         }
167                 }
168
169                 [Test] // GetMethodFromHandle (RuntimeMethodHandle)
170                 public void GetMethodFromHandle1_Handle_Zero ()
171                 {
172                         RuntimeMethodHandle mh = new RuntimeMethodHandle ();
173
174                         try {
175                                 MethodBase.GetMethodFromHandle (mh);
176                                 Assert.Fail ("#1");
177                         } catch (ArgumentException ex) {
178                                 // Handle is not initialized
179                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
180                                 Assert.IsNull (ex.InnerException, "#3");
181                                 Assert.IsNotNull (ex.Message, "#4");
182                                 Assert.IsNull (ex.ParamName, "#5");
183                         }
184                 }
185
186                 [Test]
187                 public void GetMethodFromHandle ()
188                 {
189                         Type t = typeof (object);
190                         RuntimeMethodHandle rmh = t.GetConstructor (Type.EmptyTypes).MethodHandle;
191                         MethodBase mb = MethodBase.GetMethodFromHandle (rmh);
192                         Assert.IsNotNull (mb, "#1");
193                         Assert.AreEqual (t, mb.DeclaringType, "#2");
194                         Assert.AreEqual (".ctor", mb.Name, "#3");
195                         ParameterInfo [] parameters = mb.GetParameters ();
196                         Assert.IsNotNull (parameters, "#4");
197                         Assert.AreEqual (0, parameters.Length, "#5");
198                 }
199
200                 [Test]
201                 public void GetMethodFromHandle_NonGenericType_DeclaringTypeZero ()
202                 {
203                         Type t = typeof (object);
204                         RuntimeMethodHandle rmh = t.GetConstructor (Type.EmptyTypes).MethodHandle;
205                         MethodBase mb = MethodBase.GetMethodFromHandle (rmh, new RuntimeTypeHandle ());
206                         Assert.IsNotNull (mb, "#1");
207                         Assert.AreEqual (t, mb.DeclaringType, "#2");
208                         Assert.AreEqual (".ctor", mb.Name, "#3");
209                         ParameterInfo [] parameters = mb.GetParameters ();
210                         Assert.IsNotNull (parameters, "#4");
211                         Assert.AreEqual (0, parameters.Length, "#5");
212                 }
213
214                 [Test] // GetMethodFromHandle (RuntimeMethodHandle, RuntimeTypeHandle)
215                 public void GetMethodFromHandle2_DeclaringType_Zero ()
216                 {
217                         RuntimeTypeHandle th = new RuntimeTypeHandle ();
218                         Type t = typeof (G<>);
219                         RuntimeMethodHandle mh = t.GetMethod ("M").MethodHandle;
220
221                         MethodBase mb = MethodBase.GetMethodFromHandle (mh, th);
222                         Assert.IsNotNull (mb, "#1");
223                         Assert.AreEqual (t, mb.DeclaringType, "#2");
224                         Assert.AreEqual ("M", mb.Name, "#3");
225                         ParameterInfo [] parameters = mb.GetParameters ();
226                         Assert.IsNotNull (parameters, "#4");
227                         Assert.AreEqual (1, parameters.Length, "#5");
228                         Assert.AreEqual (t.GetGenericArguments () [0] , parameters [0].ParameterType, "#6");
229                 }
230
231                 [Test] // GetMethodFromHandle (RuntimeMethodHandle, RuntimeTypeHandle)
232                 public void GetMethodFromHandle2_Handle_Generic ()
233                 {
234                         G<string> instance = new G<string> ();
235                         Type t = instance.GetType ();
236                         MethodBase mb1 = t.GetMethod ("M");
237                         RuntimeMethodHandle mh = mb1.MethodHandle;
238                         RuntimeTypeHandle th = t.TypeHandle;
239
240                         MethodBase mb2 = MethodBase.GetMethodFromHandle (mh, th);
241                         Assert.IsNotNull (mb2, "#1");
242                         Assert.AreEqual (t, mb2.DeclaringType, "#2");
243                         Assert.AreEqual ("M", mb2.Name, "#3");
244                         ParameterInfo [] parameters = mb2.GetParameters ();
245                         Assert.IsNotNull (parameters, "#4");
246                         Assert.AreEqual (1, parameters.Length, "#5");
247                         Assert.AreEqual (typeof (string), parameters [0].ParameterType, "#6");
248                 }
249
250                 [Test] // GetMethodFromHandle (RuntimeMethodHandle, RuntimeTypeHandle)
251                 public void GetMethodFromHandle2_Handle_Zero ()
252                 {
253                         RuntimeTypeHandle th = typeof (G<>).TypeHandle;
254                         RuntimeMethodHandle mh = new RuntimeMethodHandle ();
255
256                         try {
257                                 MethodBase.GetMethodFromHandle (mh, th);
258                                 Assert.Fail ("#1");
259                         } catch (ArgumentException ex) {
260                                 // Handle is not initialized
261                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
262                                 Assert.IsNull (ex.InnerException, "#3");
263                                 Assert.IsNotNull (ex.Message, "#4");
264                                 Assert.IsNull (ex.ParamName, "#5");
265                         }
266                 }
267
268                 public class G<T>
269                 {
270                         public void M (T t)
271                         {
272                         }
273                 }
274
275                 [Test]
276                 public void GetMethodFromHandle_Handle_Generic_Method ()
277                 {
278                         MethodInfo mi = typeof (SimpleClass).GetMethod ("GenericFoo");
279                         RuntimeMethodHandle handle = mi.MethodHandle;
280
281                         MethodBase res = MethodBase.GetMethodFromHandle (handle);
282                         Assert.AreEqual (mi, res, "#1");
283
284                         res = MethodBase.GetMethodFromHandle (handle, typeof (SimpleClass).TypeHandle);
285                         Assert.AreEqual (mi, res, "#2");
286                 }
287
288
289                 [Test]
290                 public void GetMethodFromHandle_Handle_Generic_Method_Instance ()
291                 {
292                         MethodInfo mi = typeof (SimpleClass).GetMethod ("GenericFoo").MakeGenericMethod (typeof (int));
293                         RuntimeMethodHandle handle = mi.MethodHandle;
294
295                         MethodBase res = MethodBase.GetMethodFromHandle (handle);
296                         Assert.AreEqual (mi, res, "#1");
297
298                         res = MethodBase.GetMethodFromHandle (handle, typeof (SimpleClass).TypeHandle);
299                         Assert.AreEqual (mi, res, "#2");
300                 }
301
302                 [Test]
303                 public void GetMethodFromHandle_Handle_Generic_Method_On_Generic_Class ()
304                 {
305                         MethodInfo mi = typeof (Generic<>).GetMethod ("GenericFoo");
306                         RuntimeMethodHandle handle = mi.MethodHandle;
307                         MethodBase res;
308
309                         try {
310                                 MethodBase.GetMethodFromHandle (handle);
311                                 Assert.Fail ("#1");
312                         } catch (ArgumentException) {
313                         }
314
315                         mi = typeof (Generic<int>).GetMethod ("GenericFoo").MakeGenericMethod (typeof (int));
316                         handle = mi.MethodHandle;
317
318                         try {
319                                 MethodBase.GetMethodFromHandle (handle);
320                                 Assert.Fail ("#2");
321                         } catch (ArgumentException) {
322                         }
323
324
325                         mi = typeof (Generic<>).GetMethod ("GenericFoo").MakeGenericMethod (typeof (int));
326                         handle = mi.MethodHandle;
327
328                         try {
329                                 MethodBase.GetMethodFromHandle (handle);
330                                 Assert.Fail ("#3");
331                         } catch (ArgumentException) {
332                         }
333
334
335                         res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<int>).TypeHandle);
336                         Assert.AreEqual (typeof (Generic<int>), res.DeclaringType, "#4");
337
338                         res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<double>).TypeHandle);
339                         Assert.AreEqual (typeof (Generic<double>), res.DeclaringType, "#5");
340
341                         res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<>).TypeHandle);
342                         Assert.AreEqual (typeof (Generic<>), res.DeclaringType, "#6");
343
344                         try {
345                                 MethodBase.GetMethodFromHandle(handle, typeof (AnotherGeneric<double>).TypeHandle);
346                                 Assert.Fail ("#7");
347                         } catch (ArgumentException) {
348                         }
349                 }
350
351                 [Test]
352                 public void GetMethodFromHandle_Handle_Method_On_Generic_Class ()
353                 {
354                         MethodInfo mi = typeof (Generic<>).GetMethod ("Foo");
355                         RuntimeMethodHandle handle = mi.MethodHandle;
356                         MethodBase res;
357
358                         try {
359                                 MethodBase.GetMethodFromHandle(handle);
360                                 Assert.Fail ("#1");
361                         } catch (ArgumentException) {
362                         }
363
364                         res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<>).TypeHandle);
365                         Assert.AreEqual (res, mi, "#2");
366
367                         mi = typeof (Generic<int>).GetMethod ("Foo");
368                         handle = mi.MethodHandle;
369
370                         try {
371                                 MethodBase.GetMethodFromHandle(handle);
372                                 Assert.Fail ("#3");
373                         } catch (ArgumentException) {
374                         }
375
376                         res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<int>).TypeHandle);
377                         Assert.AreEqual (typeof (Generic<int>), res.DeclaringType, "#4");
378
379                         res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<double>).TypeHandle);
380                         Assert.AreEqual (typeof (Generic<double>), res.DeclaringType, "#5");
381
382                         res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<>).TypeHandle);
383                         Assert.AreEqual (typeof (Generic<>), res.DeclaringType, "#6");
384
385                         try {
386                                 MethodBase.GetMethodFromHandle(handle, typeof (AnotherGeneric<double>).TypeHandle);
387                                 Assert.Fail ("#7");
388                         } catch (ArgumentException) {
389                         }
390                 }
391
392                 // test case adapted from http://www.chrishowie.com/2010/11/24/mutable-strings-in-mono/
393                 public class FakeString {
394                         public int length;
395                         public char start_char;
396                 }
397
398                 private static FakeString UnsafeConversion<T> (T thing) where T : FakeString
399                 {
400                         return thing;
401                 }
402
403                 [Test]
404 #if MOBILE
405                 [Category ("NotWorking")] // #10552
406 #endif
407                 public void MutableString ()
408                 {
409                         var m = typeof (MethodBaseTest).GetMethod ("UnsafeConversion", BindingFlags.NonPublic | BindingFlags.Static);
410                         try {
411                                 var m2 = m.MakeGenericMethod (typeof (string));
412                                 Assert.Fail ("MakeGenericMethod");
413                         }
414                         catch (ArgumentException) {
415                         }
416                 }
417         }
418 }