3a4c66188fd4315a9bedf61c2bc58e8e8912d828
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / ConstructorBuilderTest.cs
1 //
2 // ConstructorBuilderTest.cs - NUnit Test Cases for the ConstructorBuilder class
3 //
4 // Zoltan Varga (vargaz@freemail.hu)
5 //
6 // (C) Ximian, Inc.  http://www.ximian.com
7
8 // TODO:
9 //  - implement 'Signature' (what the hell it does???) and test it
10 //  - implement Equals and test it
11
12 using System;
13 using System.Threading;
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Security;
17 using System.Security.Permissions;
18
19 using NUnit.Framework;
20
21 namespace MonoTests.System.Reflection.Emit
22 {
23 [TestFixture]
24 public class ConstructorBuilderTest
25 {
26         private TypeBuilder genClass;
27         private ModuleBuilder module;
28
29         private static int typeIndexer = 0;
30
31         [SetUp]
32         public void SetUp ()
33         {
34                 AssemblyName assemblyName = new AssemblyName();
35                 assemblyName.Name = "MonoTests.System.Reflection.Emit.ConstructorBuilderTest";
36
37                 AssemblyBuilder assembly 
38                         = Thread.GetDomain().DefineDynamicAssembly(
39                                 assemblyName, AssemblyBuilderAccess.Run);
40
41                 module = assembly.DefineDynamicModule("module1");
42                 genClass = module.DefineType(genTypeName (), TypeAttributes.Public);
43         }
44
45         // Return a unique type name
46         private string genTypeName ()
47         {
48                 return "class" + (typeIndexer ++);
49         }
50
51         [Test]
52         public void Attributes ()
53         {
54                 ConstructorBuilder cb = genClass.DefineConstructor (
55                         MethodAttributes.Public, 0, new Type [0]);
56
57                 Assert.IsTrue ((cb.Attributes & MethodAttributes.Public) != 0, "#1");
58                 Assert.IsTrue ((cb.Attributes & MethodAttributes.SpecialName) != 0, "#2");
59         }
60
61         [Test]
62         public void CallingConvention ()
63         {
64                 /* This does not work under MS.NET
65                 ConstructorBuilder cb3 = genClass.DefineConstructor (
66                         0, CallingConventions.VarArgs, new Type [0]);
67                 Assert.AreEqual (CallingConventions.VarArgs | CallingConventions.HasThis,
68                         cb3.CallingConvention, "#1");
69                 */
70
71                 ConstructorBuilder cb4 = genClass.DefineConstructor (
72                          MethodAttributes.Static, CallingConventions.Standard, new Type [0]);
73                 Assert.AreEqual (CallingConventions.Standard,
74                         cb4.CallingConvention, "#2");
75         }
76
77         [Test]
78         public void DeclaringType ()
79         {
80                 ConstructorBuilder cb = genClass.DefineConstructor (
81                         0, 0, new Type[0]);
82
83                 Assert.AreSame (genClass, cb.DeclaringType);
84         }
85
86         [Test]
87         public void InitLocals ()
88         {
89                 ConstructorBuilder cb = genClass.DefineConstructor (
90                         0, 0, new Type[0]);
91
92                 Assert.IsTrue (cb.InitLocals, "#1");
93                 cb.InitLocals = false;
94                 Assert.IsFalse (cb.InitLocals, "#2");
95         }
96         
97         [Test]
98         public void MethodHandle ()
99         {
100                 ConstructorBuilder cb = genClass.DefineConstructor (
101                         0, 0, new Type [0]);
102                 cb.GetILGenerator ().Emit (OpCodes.Ret);
103
104                 try {
105                         RuntimeMethodHandle handle = cb.MethodHandle;
106                         Assert.Fail ("#A1:" + handle);
107                 } catch (NotSupportedException ex) {
108                         // The invoked member is not supported in a dynamic
109                         // module
110                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
111                         Assert.IsNull (ex.InnerException, "#A3");
112                         Assert.IsNotNull (ex.Message, "#A4");
113                 }
114
115                 genClass.CreateType ();
116
117                 try {
118                         RuntimeMethodHandle handle = cb.MethodHandle;
119                         Assert.Fail ("#B1:" + handle);
120                 } catch (NotSupportedException ex) {
121                         // The invoked member is not supported in a dynamic
122                         // module
123                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
124                         Assert.IsNull (ex.InnerException, "#B3");
125                         Assert.IsNotNull (ex.Message, "#B4");
126                 }
127         }
128
129         [Test]
130         public void Name ()
131         {
132                 ConstructorBuilder cb;
133                 
134                 cb = genClass.DefineConstructor (0, 0, new Type [0]);
135                 Assert.AreEqual (".ctor", cb.Name, "#1");
136                 cb = genClass.DefineConstructor (MethodAttributes.Static, 0, new Type [0]);
137                 Assert.AreEqual (".cctor", cb.Name, "#2");
138         }
139
140         [Test]
141         public void TestReflectedType ()
142         {
143                 ConstructorBuilder cb = genClass.DefineConstructor (0, 0, new Type [0]);
144
145                 Assert.AreSame (genClass, cb.ReflectedType);
146         }
147
148         [Test]
149         public void ReturnType ()
150         {
151                 ConstructorBuilder cb;
152                 
153                 cb = genClass.DefineConstructor (0, 0, new Type [] { typeof (string) });
154                 Assert.IsNull (cb.ReturnType, "#1");
155                 cb = genClass.DefineConstructor (MethodAttributes.Static, 0, new Type [0]);
156                 Assert.IsNull (cb.ReturnType, "#2");
157         }
158
159         [Test]
160         public void DefineParameter_Position_Negative ()
161         {
162                 ConstructorBuilder cb = genClass.DefineConstructor (
163                         0, 0, new Type [2] { typeof (int), typeof (int) });
164
165                 try {
166                         cb.DefineParameter (-1, ParameterAttributes.None, "param1");
167                         Assert.Fail ("#1");
168                 } catch (ArgumentOutOfRangeException ex) {
169                         // Specified argument was out of the range of valid values
170                         Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
171                         Assert.IsNull (ex.ActualValue, "#3");
172                         Assert.IsNull (ex.InnerException, "#4");
173                         Assert.IsNotNull (ex.Message, "#5");
174                         Assert.IsNotNull (ex.ParamName, "#6");
175                 }
176         }
177
178         [Test]
179         public void DefineParameter_Position_Max ()
180         {
181                 ConstructorBuilder cb = genClass.DefineConstructor (
182                          0, 0, new Type [2] { typeof (int), typeof (int) });
183
184                 try {
185                         cb.DefineParameter (3, 0, "param1");
186                         Assert.Fail ("#1");
187                 } catch (ArgumentOutOfRangeException ex) {
188                         // Specified argument was out of the range of valid values
189                         Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
190                         Assert.IsNull (ex.ActualValue, "#3");
191                         Assert.IsNull (ex.InnerException, "#4");
192                         Assert.IsNotNull (ex.Message, "#5");
193                         Assert.IsNotNull (ex.ParamName, "#6");
194                 }
195         }
196
197         [Test]
198         [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=341439
199         public void DefineParameter_Position_Zero ()
200         {
201                 ConstructorBuilder cb = genClass.DefineConstructor (
202                         0, 0, new Type [2] { typeof (int), typeof (int) });
203
204                 try {
205                         cb.DefineParameter (0, ParameterAttributes.In, "param1");
206                         Assert.Fail ("#1");
207                 } catch (ArgumentOutOfRangeException ex) {
208                         // Specified argument was out of the range of valid values
209                         Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
210                         Assert.IsNull (ex.ActualValue, "#3");
211                         Assert.IsNull (ex.InnerException, "#4");
212                         Assert.IsNotNull (ex.Message, "#5");
213                         Assert.IsNotNull (ex.ParamName, "#6");
214                 }
215         }
216
217         [Test]
218         public void DefineParameter ()
219         {
220                 ConstructorBuilder cb = genClass.DefineConstructor (
221                          0, 0, new Type [2] { typeof(int), typeof(int) });
222
223                 cb.DefineParameter (1, 0, "param1");
224                 cb.DefineParameter (1, 0, "param1");
225                 cb.DefineParameter (2, 0, null);
226
227                 cb.GetILGenerator ().Emit (OpCodes.Ret);
228                 genClass.CreateType ();
229
230                 try {
231                         cb.DefineParameter (1, 0, "param1");
232                         Assert.Fail ("#1");
233                 } catch (InvalidOperationException ex) {
234                         // Unable to change after type has been created
235                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
236                         Assert.IsNull (ex.InnerException, "#3");
237                         Assert.IsNotNull (ex.Message, "#4");
238                 }
239         }
240
241         [Test] // GetCustomAttributes (Boolean)
242         public void GetCustomAttributes1 ()
243         {
244                 ConstructorBuilder cb = genClass.DefineConstructor (
245                         0, 0, new Type [1] {typeof(int)});
246                 cb.GetILGenerator ().Emit (OpCodes.Ret);
247
248                 try {
249                         cb.GetCustomAttributes (true);
250                         Assert.Fail ("#A1");
251                 } catch (NotSupportedException ex) {
252                         // The invoked member is not supported in a dynamic
253                         // module
254                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
255                         Assert.IsNull (ex.InnerException, "#A3");
256                         Assert.IsNotNull (ex.Message, "#A4");
257                 }
258
259                 genClass.CreateType ();
260
261                 try {
262                         cb.GetCustomAttributes (true);
263                         Assert.Fail ("#B1");
264                 } catch (NotSupportedException ex) {
265                         // The invoked member is not supported in a dynamic
266                         // module
267                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
268                         Assert.IsNull (ex.InnerException, "#B3");
269                         Assert.IsNotNull (ex.Message, "#B4");
270                 }
271         }
272
273         [Test] // GetCustomAttributes (Type, Boolean)
274         public void GetCustomAttributes2 ()
275         {
276                 ConstructorBuilder cb = genClass.DefineConstructor (
277                         0, 0, new Type [1] { typeof (int) });
278                 cb.GetILGenerator ().Emit (OpCodes.Ret);
279
280                 try {
281                         cb.GetCustomAttributes (null, true);
282                         Assert.Fail ("#A1");
283                 } catch (NotSupportedException ex) {
284                         // The invoked member is not supported in a dynamic
285                         // module
286                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
287                         Assert.IsNull (ex.InnerException, "#A3");
288                         Assert.IsNotNull (ex.Message, "#A4");
289                 }
290
291                 genClass.CreateType ();
292
293                 try {
294                         cb.GetCustomAttributes (null, true);
295                         Assert.Fail ("#B1");
296                 } catch (NotSupportedException ex) {
297                         // The invoked member is not supported in a dynamic
298                         // module
299                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
300                         Assert.IsNull (ex.InnerException, "#B3");
301                         Assert.IsNotNull (ex.Message, "#B4");
302                 }
303         }
304
305         [Test]
306         public void TestMethodImplementationFlags ()
307         {
308                 ConstructorBuilder cb = genClass.DefineConstructor (
309                         0, 0, new Type [0]);
310
311                 Assert.AreEqual (MethodImplAttributes.Managed | MethodImplAttributes.IL,
312                         cb.GetMethodImplementationFlags (), "#A1");
313                 cb.SetImplementationFlags (MethodImplAttributes.OPTIL);
314                 Assert.AreEqual (MethodImplAttributes.OPTIL,
315                         cb.GetMethodImplementationFlags (), "#A2");
316
317                 // Can not be called on a created type
318                 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
319                 ConstructorBuilder cb2 = tb.DefineConstructor (
320                          0, 0, new Type [0]);
321
322                 cb2.GetILGenerator ().Emit (OpCodes.Ret);
323                 cb2.SetImplementationFlags (MethodImplAttributes.Managed);
324                 tb.CreateType ();
325                 try {
326                         cb2.SetImplementationFlags (MethodImplAttributes.OPTIL);
327                         Assert.Fail ("#B1");
328                 } catch (InvalidOperationException ex) {
329                         // Unable to change after type has been created
330                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
331                         Assert.IsNull (ex.InnerException, "#B3");
332                         Assert.IsNotNull (ex.Message, "#B4");
333                 }
334         }
335
336         [Test]
337         public void GetModule ()
338         {
339                 ConstructorBuilder cb = genClass.DefineConstructor (
340                         0, 0, new Type [0]);
341
342                 Assert.AreSame (module, cb.GetModule ());
343         }
344
345         [Test]
346         public void GetParameters_Complete1 ()
347         {
348                 ConstructorBuilder cb;
349                 ParameterInfo [] parameters;
350
351                 cb = genClass.DefineConstructor (MethodAttributes.Public,
352                         CallingConventions.Standard,
353                         new Type [] { typeof (int), typeof (string), typeof (bool) });
354                 cb.DefineParameter (3, ParameterAttributes.In, "param3a");
355                 cb.DefineParameter (3, ParameterAttributes.In, "param3b");
356                 cb.DefineParameter (2, ParameterAttributes.Out, "param2");
357                 cb.GetILGenerator ().Emit (OpCodes.Ret);
358                 genClass.CreateType ();
359
360                 parameters = cb.GetParameters ();
361                 Assert.IsNotNull (parameters, "#A1");
362                 Assert.AreEqual (3, parameters.Length, "#A2");
363
364                 Assert.AreEqual (ParameterAttributes.None, parameters [0].Attributes, "#B1");
365                 Assert.IsNull (parameters [0].Name, "#B2");
366                 Assert.AreEqual (typeof (int), parameters [0].ParameterType, "#B3");
367                 Assert.AreEqual (0, parameters [0].Position, "#B4");
368
369                 Assert.AreEqual (ParameterAttributes.Out, parameters [1].Attributes, "#C1");
370                 Assert.AreEqual ("param2", parameters [1].Name, "#C2");
371                 Assert.AreEqual (typeof (string), parameters [1].ParameterType, "#C3");
372                 Assert.AreEqual (1, parameters [1].Position, "#C4");
373
374                 Assert.AreEqual (ParameterAttributes.In, parameters [2].Attributes, "#D1");
375                 Assert.AreEqual ("param3b", parameters [2].Name, "#D2");
376                 Assert.AreEqual (typeof (bool), parameters [2].ParameterType, "#D3");
377                 Assert.AreEqual (2, parameters [2].Position, "#D4");
378         }
379
380         [Test]
381         public void GetParameters_Complete2 ()
382         {
383                 ConstructorBuilder cb = genClass.DefineConstructor (
384                         MethodAttributes.Public,
385                         CallingConventions.Standard, null);
386                 cb.GetILGenerator ().Emit (OpCodes.Ret);
387                 genClass.CreateType ();
388
389                 ParameterInfo [] parameters = cb.GetParameters ();
390                 Assert.IsNotNull (parameters, "#1");
391                 Assert.AreEqual (0, parameters.Length, "#2");
392         }
393
394         [Test]
395         public void GetParameters_Incomplete ()
396         {
397                 ConstructorBuilder cb = genClass.DefineConstructor (
398                         0, 0, new Type [2] { typeof (int), typeof (string) });
399                 cb.DefineParameter (1, ParameterAttributes.In, "param1");
400                 cb.DefineParameter (2, ParameterAttributes.In, "param2");
401                 cb.GetILGenerator ().Emit (OpCodes.Ret);
402
403                 try {
404                         cb.GetParameters ();
405                         Assert.Fail ("#1");
406                 } catch (NotSupportedException ex) {
407                         // Type has not been created
408                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
409                         Assert.IsNull (ex.InnerException, "#3");
410                         Assert.IsNotNull (ex.Message, "#4");
411                 }
412         }
413
414         [Test]
415         public void GetToken ()
416         {
417                 ConstructorBuilder cb = genClass.DefineConstructor (
418                         0, 0, new Type [1] { typeof(int) });
419                 cb.GetILGenerator ().Emit (OpCodes.Ret);
420
421                 MethodToken tokenA = cb.GetToken ();
422                 Assert.IsFalse (tokenA == MethodToken.Empty, "#1");
423
424                 genClass.CreateType ();
425
426                 MethodToken tokenB = cb.GetToken ();
427                 Assert.AreEqual (tokenA, tokenB, "#2");
428         }
429
430         [Test] // Invoke (Object [])
431         public void Invoke1 ()
432         {
433                 ConstructorBuilder cb = genClass.DefineConstructor (
434                         0, 0, new Type [1] { typeof(int) });
435                 cb.GetILGenerator ().Emit (OpCodes.Ret);
436
437                 try {
438                         cb.Invoke (new object [1] { 42 });
439                         Assert.Fail ("#A1");
440                 } catch (NotSupportedException ex) {
441                         // The invoked member is not supported in a dynamic
442                         // module
443                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
444                         Assert.IsNull (ex.InnerException, "#A3");
445                         Assert.IsNotNull (ex.Message, "#A4");
446                 }
447
448                 genClass.CreateType ();
449
450                 try {
451                         cb.Invoke (new object [1] { 42 });
452                         Assert.Fail ("#B1");
453                 } catch (NotSupportedException ex) {
454                         // The invoked member is not supported in a dynamic
455                         // module
456                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
457                         Assert.IsNull (ex.InnerException, "#B3");
458                         Assert.IsNotNull (ex.Message, "#B4");
459                 }
460         }
461
462         [Test] // Invoke (Object, Object [])
463         public void Invoke2 ()
464         {
465                 ConstructorBuilder cb = genClass.DefineConstructor (
466                          0, 0, new Type [1] { typeof (int) });
467                 cb.GetILGenerator ().Emit (OpCodes.Ret);
468
469                 try {
470                         cb.Invoke (null, new object [1] { 42 });
471                         Assert.Fail ("#A1");
472                 } catch (NotSupportedException ex) {
473                         // The invoked member is not supported in a dynamic
474                         // module
475                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
476                         Assert.IsNull (ex.InnerException, "#A3");
477                         Assert.IsNotNull (ex.Message, "#A4");
478                 }
479
480                 genClass.CreateType ();
481
482                 try {
483                         cb.Invoke (null, new object [1] { 42 });
484                         Assert.Fail ("#B1");
485                 } catch (NotSupportedException ex) {
486                         // The invoked member is not supported in a dynamic
487                         // module
488                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
489                         Assert.IsNull (ex.InnerException, "#B3");
490                         Assert.IsNotNull (ex.Message, "#B4");
491                 }
492         }
493
494         [Test] // Invoke (BindingFlags, Binder, Object [], CultureInfo)
495         public void Invoke3 ()
496         {
497                 ConstructorBuilder cb = genClass.DefineConstructor (
498                          0, 0, new Type [1] { typeof (int) });
499                 cb.GetILGenerator ().Emit (OpCodes.Ret);
500
501                 try {
502                         cb.Invoke (0, null, new object [1] { 42 }, null);
503                         Assert.Fail ("#A1");
504                 } catch (NotSupportedException ex) {
505                         // The invoked member is not supported in a dynamic
506                         // module
507                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
508                         Assert.IsNull (ex.InnerException, "#A3");
509                         Assert.IsNotNull (ex.Message, "#A4");
510                 }
511
512                 genClass.CreateType ();
513
514                 try {
515                         cb.Invoke (0, null, new object [1] { 42 }, null);
516                         Assert.Fail ("#B1");
517                 } catch (NotSupportedException ex) {
518                         // The invoked member is not supported in a dynamic
519                         // module
520                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
521                         Assert.IsNull (ex.InnerException, "#B3");
522                         Assert.IsNotNull (ex.Message, "#B4");
523                 }
524         }
525
526         [Test] // Invoke (Object, BindingFlags, Binder, Object [], CultureInfo)
527         public void Invoke4 ()
528         {
529                 ConstructorBuilder cb = genClass.DefineConstructor (
530                          0, 0, new Type [1] { typeof (int) });
531                 cb.GetILGenerator ().Emit (OpCodes.Ret);
532
533                 try {
534                         cb.Invoke (null, 0, null, new object [1] { 42 }, null);
535                         Assert.Fail ("#A1");
536                 } catch (NotSupportedException ex) {
537                         // The invoked member is not supported in a dynamic
538                         // module
539                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
540                         Assert.IsNull (ex.InnerException, "#A3");
541                         Assert.IsNotNull (ex.Message, "#A4");
542                 }
543
544                 genClass.CreateType ();
545
546                 try {
547                         cb.Invoke (null, 0, null, new object [1] { 42 }, null);
548                         Assert.Fail ("#B1");
549                 } catch (NotSupportedException ex) {
550                         // The invoked member is not supported in a dynamic
551                         // module
552                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
553                         Assert.IsNull (ex.InnerException, "#B3");
554                         Assert.IsNotNull (ex.Message, "#B4");
555                 }
556         }
557
558         [Test]
559         public void IsDefined ()
560         {
561                 ConstructorBuilder cb = genClass.DefineConstructor (
562                          0, 0, 
563                         new Type [1] {typeof(int)});
564                 cb.GetILGenerator ().Emit (OpCodes.Ret);
565
566                 try {
567                         cb.IsDefined (null, true);
568                         Assert.Fail ("#A1");
569                 } catch (NotSupportedException ex) {
570                         // The invoked member is not supported in a dynamic
571                         // module
572                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
573                         Assert.IsNull (ex.InnerException, "#A3");
574                         Assert.IsNotNull (ex.Message, "#A4");
575                 }
576
577                 genClass.CreateType ();
578
579                 try {
580                         cb.IsDefined (null, true);
581                         Assert.Fail ("#B1");
582                 } catch (NotSupportedException ex) {
583                         // The invoked member is not supported in a dynamic
584                         // module
585                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
586                         Assert.IsNull (ex.InnerException, "#B3");
587                         Assert.IsNotNull (ex.Message, "#B4");
588                 }
589         }
590
591         [Test] // SetCustomAttribute (ConstructorInfo, Byte [])
592         public void SetCustomAttribute1 ()
593         {
594                 ConstructorBuilder cb = genClass.DefineConstructor (
595                          0, 0, new Type [1] {typeof(int)});
596                 cb.GetILGenerator ().Emit (OpCodes.Ret);
597
598                 byte[] custAttrData = { 1, 0, 0, 0, 0};
599                 Type attrType = Type.GetType
600                         ("System.Reflection.AssemblyKeyNameAttribute");
601                 Type[] paramTypes = new Type[1];
602                 paramTypes[0] = typeof(String);
603                 ConstructorInfo ctorInfo =
604                         attrType.GetConstructor(paramTypes);
605
606                 cb.SetCustomAttribute (ctorInfo, custAttrData);
607
608                 // Null arguments again
609                 try {
610                         cb.SetCustomAttribute (null, new byte [2]);
611                         Assert.Fail ("#B1");
612                 } catch (ArgumentNullException ex) {
613                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
614                         Assert.IsNull (ex.InnerException, "#B3");
615                         Assert.IsNotNull (ex.Message, "#B4");
616                         Assert.AreEqual ("con", ex.ParamName, "#B5");
617                 }
618
619                 try {
620                         cb.SetCustomAttribute (ctorInfo, null);
621                         Assert.Fail ("#C1");
622                 } catch (ArgumentNullException ex) {
623                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
624                         Assert.IsNull (ex.InnerException, "#C3");
625                         Assert.IsNotNull (ex.Message, "#C4");
626                         Assert.AreEqual ("binaryAttribute", ex.ParamName, "#C5");
627                 }
628         }
629
630         [Test] // SetCustomAttribute (CustomAttributeBuilder)
631         public void SetCustomAttribute2 ()
632         {
633                 ConstructorBuilder cb = genClass.DefineConstructor (
634                         MethodAttributes.Public, CallingConventions.Standard,
635                         new Type [1] { typeof (int) });
636                 cb.GetILGenerator ().Emit (OpCodes.Ret);
637
638                 TypeBuilder attrTb = module.DefineType ("TestAttribute",
639                         TypeAttributes.Public, typeof (Attribute));
640                 ConstructorBuilder attrCb = attrTb.DefineDefaultConstructor (
641                         MethodAttributes.Public);
642
643                 CustomAttributeBuilder cab = new CustomAttributeBuilder (
644                         attrCb, new object [0]);
645                 cb.SetCustomAttribute (cab);
646                 attrTb.CreateType ();
647                 
648                 Type emittedType  = genClass.CreateType ();
649                 ConstructorInfo ci = emittedType.GetConstructor (
650                         new Type [1] { typeof (int) });
651
652                 Assert.IsNotNull (ci, "#1");
653                 object [] cas = ci.GetCustomAttributes (false);
654                 Assert.IsNotNull (cas, "#2");
655                 Assert.AreEqual (1, cas.Length, "#3");
656                 Assert.AreEqual ("TestAttribute", cas [0].GetType ().FullName, "#4");
657         }
658
659         [Test]
660         public void SetCustomAttribute2_CustomBuilder_Null ()
661         {
662                 ConstructorBuilder cb = genClass.DefineConstructor (
663                         MethodAttributes.Public, CallingConventions.Standard,
664                         new Type [1] { typeof (int) });
665                 cb.GetILGenerator ().Emit (OpCodes.Ret);
666
667                 try {
668                         cb.SetCustomAttribute ((CustomAttributeBuilder) null);
669                         Assert.Fail ("#A1");
670                 } catch (ArgumentNullException ex) {
671                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
672                         Assert.IsNull (ex.InnerException, "#A3");
673                         Assert.IsNotNull (ex.Message, "#A4");
674                         Assert.AreEqual ("customBuilder", ex.ParamName, "#A5");
675                 }
676
677                 genClass.CreateType ();
678
679                 try {
680                         cb.SetCustomAttribute ((CustomAttributeBuilder) null);
681                         Assert.Fail ("#B1");
682                 } catch (ArgumentNullException ex) {
683                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
684                         Assert.IsNull (ex.InnerException, "#B3");
685                         Assert.IsNotNull (ex.Message, "#B4");
686                         Assert.AreEqual ("customBuilder", ex.ParamName, "#B5");
687                 }
688         }
689
690         [Test]
691         public void GetCustomAttributes_Emitted ()
692         {
693                 ConstructorBuilder cb = genClass.DefineConstructor (
694                          MethodAttributes.Public, 0, 
695                         new Type [1] {typeof(int)});
696                 cb.GetILGenerator ().Emit (OpCodes.Ret);
697
698                 Type attrType = typeof (ObsoleteAttribute);
699                 ConstructorInfo ctorInfo =
700                         attrType.GetConstructor (new Type [] { typeof (String) });
701
702                 cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
703
704                 Type t = genClass.CreateType ();
705
706                 // Try the created type
707                 {
708                         ConstructorInfo ci = t.GetConstructors () [0];
709                         object[] attrs = ci.GetCustomAttributes (true);
710
711                         Assert.AreEqual (1, attrs.Length, "#A1");
712                         Assert.IsTrue (attrs [0] is ObsoleteAttribute, "#A2");
713                         Assert.AreEqual ("FOO", ((ObsoleteAttribute)attrs [0]).Message, "#A3");
714                 }
715
716                 // Try the type builder
717                 {
718                         ConstructorInfo ci = genClass.GetConstructors () [0];
719                         object[] attrs = ci.GetCustomAttributes (true);
720
721                         Assert.AreEqual (1, attrs.Length, "#B1");
722                         Assert.IsTrue (attrs [0] is ObsoleteAttribute, "#B2");
723                         Assert.AreEqual ("FOO", ((ObsoleteAttribute)attrs [0]).Message, "#B3");
724                 }
725         }
726
727         [Test] // GetCustomAttributes (Boolean)
728         public void GetCustomAttributes1_Complete ()
729         {
730                 ConstructorBuilder cb = genClass.DefineConstructor (
731                          MethodAttributes.Public, 0,
732                         new Type [1] { typeof (int) });
733                 cb.GetILGenerator ().Emit (OpCodes.Ret);
734
735                 Type attrType = typeof (ObsoleteAttribute);
736                 ConstructorInfo ctorInfo =
737                         attrType.GetConstructor (new Type [] { typeof (String) });
738                 cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
739
740                 genClass.CreateType ();
741
742                 try {
743                         cb.GetCustomAttributes (false);
744                         Assert.Fail ("#1");
745                 } catch (NotSupportedException ex) {
746                         // The invoked member is not supported in a dynamic
747                         // module
748                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
749                         Assert.IsNull (ex.InnerException, "#3");
750                         Assert.IsNotNull (ex.Message, "#4");
751                 }
752         }
753
754         [Test] // GetCustomAttributes (Boolean)
755         public void GetCustomAttributes1_Incomplete ()
756         {
757                 ConstructorBuilder cb = genClass.DefineConstructor (
758                          MethodAttributes.Public, 0,
759                         new Type [1] { typeof (int) });
760                 cb.GetILGenerator ().Emit (OpCodes.Ret);
761
762                 Type attrType = typeof (ObsoleteAttribute);
763                 ConstructorInfo ctorInfo =
764                         attrType.GetConstructor (new Type [] { typeof (String) });
765                 cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
766
767                 try {
768                         cb.GetCustomAttributes (false);
769                         Assert.Fail ("#1");
770                 } catch (NotSupportedException ex) {
771                         // The invoked member is not supported in a dynamic
772                         // module
773                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
774                         Assert.IsNull (ex.InnerException, "#3");
775                         Assert.IsNotNull (ex.Message, "#4");
776                 }
777         }
778
779         [Test] // GetCustomAttributes (Type, Boolean)
780         public void GetCustomAttributes2_Complete ()
781         {
782                 ConstructorBuilder cb = genClass.DefineConstructor (
783                          MethodAttributes.Public, 0,
784                         new Type [1] { typeof (int) });
785                 cb.GetILGenerator ().Emit (OpCodes.Ret);
786
787                 Type attrType = typeof (ObsoleteAttribute);
788                 ConstructorInfo ctorInfo =
789                         attrType.GetConstructor (new Type [] { typeof (String) });
790                 cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
791
792                 genClass.CreateType ();
793
794                 try {
795                         cb.GetCustomAttributes (attrType, false);
796                         Assert.Fail ("#1");
797                 } catch (NotSupportedException ex) {
798                         // The invoked member is not supported in a dynamic
799                         // module
800                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
801                         Assert.IsNull (ex.InnerException, "#3");
802                         Assert.IsNotNull (ex.Message, "#4");
803                 }
804         }
805
806         [Test] // GetCustomAttributes (Type, Boolean)
807         public void GetCustomAttributes2_Incomplete ()
808         {
809                 ConstructorBuilder cb = genClass.DefineConstructor (
810                          MethodAttributes.Public, 0,
811                         new Type [1] { typeof (int) });
812                 cb.GetILGenerator ().Emit (OpCodes.Ret);
813
814                 Type attrType = typeof (ObsoleteAttribute);
815                 ConstructorInfo ctorInfo =
816                         attrType.GetConstructor (new Type [] { typeof (String) });
817                 cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
818
819                 try {
820                         cb.GetCustomAttributes (attrType, false);
821                         Assert.Fail ("#1");
822                 } catch (NotSupportedException ex) {
823                         // The invoked member is not supported in a dynamic
824                         // module
825                         Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
826                         Assert.IsNull (ex.InnerException, "#3");
827                         Assert.IsNotNull (ex.Message, "#4");
828                 }
829         }
830
831         // Same as in MethodBuilderTest
832         [Test]
833         public void AddDeclarativeSecurity_Complete ()
834         {
835                 ConstructorBuilder cb = genClass.DefineConstructor (
836                          MethodAttributes.Public, 0, new Type [0]);
837                 ILGenerator ilgen = cb.GetILGenerator ();
838                 ilgen.Emit (OpCodes.Ret);
839                 genClass.CreateType ();
840
841                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
842                 try {
843                         cb.AddDeclarativeSecurity (SecurityAction.Demand, set);
844                         Assert.Fail ("#1");
845                 } catch (InvalidOperationException ex) {
846                         // Type has not been created
847                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
848                         Assert.IsNull (ex.InnerException, "#3");
849                         Assert.IsNotNull (ex.Message, "#4");
850                 }
851         }
852
853         [Test]
854         public void AddDeclarativeSecurity_PSet_Null ()
855         {
856                 ConstructorBuilder cb = genClass.DefineConstructor (
857                          MethodAttributes.Public, 0, new Type [0]);
858                 try {
859                         cb.AddDeclarativeSecurity (SecurityAction.Demand, null);
860                         Assert.Fail ("#1");
861                 } catch (ArgumentNullException ex) {
862                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
863                         Assert.IsNull (ex.InnerException, "#3");
864                         Assert.IsNotNull (ex.Message, "#4");
865                         Assert.AreEqual ("pset", ex.ParamName, "#5");
866                 }
867         }
868
869         [Test]
870         public void AddDeclarativeSecurity_Action_Invalid ()
871         {
872                 ConstructorBuilder cb = genClass.DefineConstructor (
873                          MethodAttributes.Public, 0, new Type [0]);
874
875                 SecurityAction[] actions = new SecurityAction [] { 
876                         SecurityAction.RequestMinimum,
877                         SecurityAction.RequestOptional,
878                         SecurityAction.RequestRefuse };
879                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
880
881                 foreach (SecurityAction action in actions) {
882                         try {
883                                 cb.AddDeclarativeSecurity (action, set);
884                                 Assert.Fail ("#1");
885                         } catch (ArgumentOutOfRangeException ex) {
886                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
887                                 Assert.IsNull (ex.ActualValue, "#3");
888                                 Assert.IsNotNull (ex.Message, "#4");
889                                 Assert.AreEqual ("action", ex.ParamName, "#5");
890                         }
891                 }
892         }
893
894         [Test]
895         public void AddDeclarativeSecurity_Action_Duplicate ()
896         {
897                 ConstructorBuilder cb = genClass.DefineConstructor (
898                          MethodAttributes.Public, 0, new Type [0]);
899                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
900                 cb.AddDeclarativeSecurity (SecurityAction.Demand, set);
901                 try {
902                         cb.AddDeclarativeSecurity (SecurityAction.Demand, set);
903                         Assert.Fail ("#1");
904                 } catch (InvalidOperationException ex) {
905                         // Type has not been created
906                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
907                         Assert.IsNull (ex.InnerException, "#3");
908                         Assert.IsNotNull (ex.Message, "#4");
909                 }
910         }
911 }
912 }