Switch to compiler-tester
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / ConstructorBuilderTest.cs
1 //\r
2 // ConstructorBuilderTest.cs - NUnit Test Cases for the ConstructorBuilder class\r
3 //\r
4 // Zoltan Varga (vargaz@freemail.hu)\r
5 //\r
6 // (C) Ximian, Inc.  http://www.ximian.com\r
7 \r
8 // TODO:\r
9 //  - implement 'Signature' (what the hell it does???) and test it\r
10 //  - implement Equals and test it\r
11 \r
12 using System;\r
13 using System.Threading;\r
14 using System.Reflection;\r
15 using System.Reflection.Emit;\r
16 using System.Security;\r
17 using System.Security.Permissions;\r
18 \r
19 using NUnit.Framework;\r
20 \r
21 namespace MonoTests.System.Reflection.Emit\r
22 {\r
23 \r
24 [TestFixture]\r
25 public class ConstructorBuilderTest : Assertion\r
26 {       \r
27     private TypeBuilder genClass;\r
28 \r
29         private ModuleBuilder module;\r
30 \r
31         private static int typeIndexer = 0;\r
32 \r
33         [SetUp]\r
34         protected void SetUp () {\r
35                 AssemblyName assemblyName = new AssemblyName();\r
36                 assemblyName.Name = "MonoTests.System.Reflection.Emit.ConstructorBuilderTest";\r
37 \r
38                 AssemblyBuilder assembly \r
39                         = Thread.GetDomain().DefineDynamicAssembly(\r
40                                 assemblyName, AssemblyBuilderAccess.Run);\r
41 \r
42                 module = assembly.DefineDynamicModule("module1");\r
43                 \r
44                 genClass = module.DefineType(genTypeName (), \r
45                                                                          TypeAttributes.Public);\r
46         }\r
47 \r
48         // Return a unique type name\r
49         private string genTypeName () {\r
50                 return "class" + (typeIndexer ++);\r
51         }\r
52 \r
53         public void TestAttributes () {\r
54                 ConstructorBuilder cb = genClass.DefineConstructor (\r
55                          MethodAttributes.Public, 0, new Type [0]);\r
56 \r
57                 Assert ("Attributes works", \r
58                                 (cb.Attributes & MethodAttributes.Public) != 0);\r
59                 Assert ("Attributes works", \r
60                                 (cb.Attributes & MethodAttributes.SpecialName) != 0);\r
61         }\r
62 \r
63         public void TestCallingConvention () {\r
64                 /* This does not work under MS.NET\r
65                 ConstructorBuilder cb3 = genClass.DefineConstructor (\r
66                         0, CallingConventions.VarArgs, new Type [0]);\r
67                 AssertEquals ("CallingConvetion works",\r
68                                           CallingConventions.VarArgs | CallingConventions.HasThis,\r
69                                           cb3.CallingConvention);\r
70                 */\r
71 \r
72                 ConstructorBuilder cb4 = genClass.DefineConstructor (\r
73                          MethodAttributes.Static, CallingConventions.Standard, new Type [0]);\r
74                 AssertEquals ("Static implies !HasThis",\r
75                                           cb4.CallingConvention,\r
76                                           CallingConventions.Standard);\r
77         }\r
78 \r
79         public void TestDeclaringType () {\r
80                 ConstructorBuilder cb = genClass.DefineConstructor (\r
81                          0, 0, new Type[0]);\r
82 \r
83                 AssertEquals ("DeclaringType works",\r
84                                           cb.DeclaringType, genClass);\r
85         }\r
86 \r
87         public void TestInitLocals () {\r
88                 ConstructorBuilder cb = genClass.DefineConstructor (\r
89                          0, 0, new Type[0]);\r
90 \r
91                 AssertEquals ("InitLocals defaults to true", cb.InitLocals, true);\r
92                 cb.InitLocals = false;\r
93                 AssertEquals ("InitLocals is settable", cb.InitLocals, false);\r
94         }
95         \r
96         [Test]
97         public void TestMethodHandle () {\r
98                 ConstructorBuilder cb = genClass.DefineConstructor (\r
99                          0, 0, new Type [0]);\r
100 \r
101                 RuntimeMethodHandle handle = cb.MethodHandle;\r
102         }\r
103 \r
104         public void TestName () {\r
105                 ConstructorBuilder cb = genClass.DefineConstructor (0, 0, new Type [0]);\r
106 \r
107                 AssertEquals ("Name works", ".ctor", cb.Name);\r
108 \r
109                 ConstructorBuilder cb2 = genClass.DefineConstructor (MethodAttributes.Static, 0, new Type [0]);\r
110                 AssertEquals ("Static constructors have the right name", ".cctor", cb2.Name);\r
111         }\r
112 \r
113         public void TestReflectedType () {\r
114                 ConstructorBuilder cb = genClass.DefineConstructor (0, 0, new Type [0]);\r
115 \r
116                 AssertEquals ("ReflectedType works", \r
117                                           genClass, cb.ReflectedType);\r
118         }\r
119 \r
120         public void TestReturnType () {\r
121                 ConstructorBuilder cb = genClass.DefineConstructor (0, 0, new Type [0]);\r
122 \r
123                 AssertEquals ("ReturnType works", \r
124                                           null, cb.ReturnType);\r
125         }\r
126 \r
127         public void TestDefineParameter () {\r
128                 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
129                 ConstructorBuilder cb = tb.DefineConstructor (\r
130                          0, 0, new Type [2] { typeof(int), typeof(int) });\r
131 \r
132                 // index out of range\r
133                 try {\r
134                         cb.DefineParameter (0, 0, "param1");\r
135                         Fail ();\r
136                 } catch (ArgumentOutOfRangeException) {\r
137                 }\r
138                 try {\r
139                         cb.DefineParameter (3, 0, "param1");\r
140                         Fail ();\r
141                 } catch (ArgumentOutOfRangeException) {\r
142                 }\r
143 \r
144                 // Normal usage\r
145                 cb.DefineParameter (1, 0, "param1");\r
146                 cb.DefineParameter (1, 0, "param1");\r
147                 cb.DefineParameter (2, 0, null);\r
148 \r
149                 // Can not be called on a created type\r
150                 cb.GetILGenerator ().Emit (OpCodes.Ret);\r
151                 tb.CreateType ();\r
152                 try {\r
153                         cb.DefineParameter (1, 0, "param1");\r
154                         Fail ();\r
155                 }\r
156                 catch (InvalidOperationException) {\r
157                 }\r
158         }\r
159 \r
160         public void TestGetCustomAttributes () {\r
161                 ConstructorBuilder cb = genClass.DefineConstructor (\r
162                         0, 0, new Type [1] {typeof(int)});\r
163 \r
164                 try {\r
165                         cb.GetCustomAttributes (true);\r
166                         Fail ();\r
167                 } catch (NotSupportedException) {\r
168                 }\r
169 \r
170                 try {\r
171                         cb.GetCustomAttributes (null, true);\r
172                         Fail ();\r
173                 } catch (NotSupportedException) {\r
174                 }\r
175         }\r
176 \r
177         public void TestMethodImplementationFlags () {\r
178                 ConstructorBuilder cb = genClass.DefineConstructor (\r
179                          0, 0, new Type [0]);\r
180 \r
181                 AssertEquals ("MethodImplementationFlags defaults to Managed+IL",\r
182                                           cb.GetMethodImplementationFlags (),\r
183                                           MethodImplAttributes.Managed | MethodImplAttributes.IL);\r
184 \r
185                 cb.SetImplementationFlags (MethodImplAttributes.OPTIL);\r
186 \r
187                 AssertEquals ("SetImplementationFlags works",\r
188                                           cb.GetMethodImplementationFlags (),\r
189                                           MethodImplAttributes.OPTIL);\r
190 \r
191                 // Can not be called on a created type\r
192                 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
193                 ConstructorBuilder cb2 = tb.DefineConstructor (\r
194                          0, 0, new Type [0]);\r
195 \r
196                 cb2.GetILGenerator ().Emit (OpCodes.Ret);\r
197                 cb2.SetImplementationFlags (MethodImplAttributes.Managed);\r
198                 tb.CreateType ();\r
199                 try {\r
200                         cb2.SetImplementationFlags (MethodImplAttributes.OPTIL);\r
201                         Fail ();\r
202                 }\r
203                 catch (InvalidOperationException) {\r
204                 }\r
205         }\r
206 \r
207         public void TestGetModule () {\r
208                 ConstructorBuilder cb = genClass.DefineConstructor (\r
209                          0, 0, new Type [0]);\r
210 \r
211                 AssertEquals ("GetModule works",\r
212                                           module, cb.GetModule ());\r
213         }\r
214 \r
215         public void TestGetParameters () {\r
216                 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
217                 ConstructorBuilder cb = tb.DefineConstructor (\r
218                          0, 0, new Type [1] {typeof(int)});\r
219                 cb.GetILGenerator ().Emit (OpCodes.Ret);\r
220 \r
221                 // Can't be called before CreateType ()\r
222                 /* This does not work under mono\r
223                 try {\r
224                         cb.GetParameters ();\r
225                         Fail ();\r
226                 } catch (InvalidOperationException) {\r
227                 }\r
228                 */\r
229 \r
230                 tb.CreateType ();\r
231 \r
232                 /* This does not work under MS.NET !\r
233                 cb.GetParameters ();\r
234                 */\r
235         }\r
236 \r
237         public void TestGetToken () {\r
238                 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
239                 ConstructorBuilder cb = tb.DefineConstructor (\r
240                          0, 0, new Type [1] {typeof(void)});\r
241 \r
242                 cb.GetToken ();\r
243         }\r
244 \r
245         public void TestInvoke () {\r
246                 ConstructorBuilder cb = genClass.DefineConstructor (\r
247                          0, 0, \r
248                         new Type [1] {typeof(int)});\r
249 \r
250                 try {\r
251                         cb.Invoke (null, new object [1] { 42 });\r
252                         Fail ();\r
253                 } catch (NotSupportedException) {\r
254                 }\r
255 \r
256                 try {\r
257                         cb.Invoke (null, 0, null, new object [1] { 42 }, null);\r
258                         Fail ();\r
259                 } catch (NotSupportedException) {\r
260                 }\r
261         }\r
262 \r
263         public void TestIsDefined () {\r
264                 ConstructorBuilder cb = genClass.DefineConstructor (\r
265                          0, 0, \r
266                         new Type [1] {typeof(int)});\r
267 \r
268                 try {\r
269                         cb.IsDefined (null, true);\r
270                         Fail ();\r
271                 } catch (NotSupportedException) {\r
272                 }\r
273         }\r
274 \r
275         public void TestSetCustomAttribute () {\r
276                 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
277                 ConstructorBuilder cb = tb.DefineConstructor (\r
278                          0, 0, \r
279                         new Type [1] {typeof(int)});\r
280                 cb.GetILGenerator ().Emit (OpCodes.Ret);\r
281 \r
282                 // Null argument\r
283                 try {\r
284                         cb.SetCustomAttribute (null);\r
285                         Fail ();\r
286                 } catch (ArgumentNullException) {\r
287                 }\r
288 \r
289                 byte[] custAttrData = { 1, 0, 0, 0, 0};\r
290                 Type attrType = Type.GetType\r
291                         ("System.Reflection.AssemblyKeyNameAttribute");\r
292                 Type[] paramTypes = new Type[1];\r
293                 paramTypes[0] = typeof(String);\r
294                 ConstructorInfo ctorInfo =\r
295                         attrType.GetConstructor(paramTypes);\r
296 \r
297                 cb.SetCustomAttribute (ctorInfo, custAttrData);\r
298 \r
299                 // Null arguments again\r
300                 try {\r
301                         cb.SetCustomAttribute (null, new byte[2]);\r
302                         Fail ();\r
303                 } catch (ArgumentNullException) {\r
304                 }\r
305 \r
306                 try {\r
307                         cb.SetCustomAttribute (ctorInfo, null);\r
308                         Fail ();\r
309                 } catch (ArgumentNullException) {\r
310                 }\r
311         }\r
312 \r
313         // Same as in MethodBuilderTest\r
314         [Test]\r
315         [ExpectedException (typeof (InvalidOperationException))]\r
316         public void TestAddDeclarativeSecurityAlreadyCreated () {\r
317                 ConstructorBuilder cb = genClass.DefineConstructor (\r
318                          MethodAttributes.Public, 0, new Type [0]);\r
319                 ILGenerator ilgen = cb.GetILGenerator ();\r
320                 ilgen.Emit (OpCodes.Ret);\r
321                 genClass.CreateType ();\r
322 \r
323                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);\r
324                 cb.AddDeclarativeSecurity (SecurityAction.Demand, set);\r
325         }\r
326 \r
327         [Test]\r
328         [ExpectedException (typeof (ArgumentNullException))]\r
329         public void TestAddDeclarativeSecurityNullPermissionSet () {\r
330                 ConstructorBuilder cb = genClass.DefineConstructor (\r
331                          MethodAttributes.Public, 0, new Type [0]);\r
332                 cb.AddDeclarativeSecurity (SecurityAction.Demand, null);\r
333         }\r
334 \r
335         [Test]\r
336         public void TestAddDeclarativeSecurityInvalidAction () {\r
337                 ConstructorBuilder cb = genClass.DefineConstructor (\r
338                          MethodAttributes.Public, 0, new Type [0]);\r
339 \r
340                 SecurityAction[] actions = new SecurityAction [] { \r
341                         SecurityAction.RequestMinimum,\r
342                         SecurityAction.RequestOptional,\r
343                         SecurityAction.RequestRefuse };\r
344                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);\r
345 \r
346                 foreach (SecurityAction action in actions) {\r
347                         try {\r
348                                 cb.AddDeclarativeSecurity (action, set);\r
349                                 Fail ();\r
350                         }\r
351                         catch (ArgumentException) {\r
352                         }\r
353                 }\r
354         }\r
355 \r
356         [Test]\r
357         [ExpectedException (typeof (InvalidOperationException))]\r
358         public void TestAddDeclarativeSecurityDuplicateAction () {\r
359                 ConstructorBuilder cb = genClass.DefineConstructor (\r
360                          MethodAttributes.Public, 0, new Type [0]);\r
361                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);\r
362                 cb.AddDeclarativeSecurity (SecurityAction.Demand, set);\r
363                 cb.AddDeclarativeSecurity (SecurityAction.Demand, set);\r
364         }\r
365 }\r
366 }\r