2003-02-08 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / TypeBuilderTest.cs
1 //\r
2 // TypeBuilderTest.cs - NUnit Test Cases for the TypeBuilder 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 using System;\r
9 using System.Threading;\r
10 using System.Reflection;\r
11 using System.Reflection.Emit;\r
12 \r
13 using NUnit.Framework;\r
14 \r
15 namespace MonoTests.System.Reflection.Emit\r
16 {\r
17 \r
18 public class TypeBuilderTest : TestCase\r
19 {       \r
20         private AssemblyBuilder assembly;\r
21 \r
22         private ModuleBuilder module;\r
23 \r
24         static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.TypeBuilderTest";\r
25 \r
26         protected override void SetUp () {\r
27                 AssemblyName assemblyName = new AssemblyName();\r
28                 assemblyName.Name = ASSEMBLY_NAME;\r
29 \r
30                 assembly = \r
31                         Thread.GetDomain().DefineDynamicAssembly(\r
32                                 assemblyName, AssemblyBuilderAccess.Run);\r
33 \r
34                 module = assembly.DefineDynamicModule("module1");\r
35         }\r
36 \r
37         static int typeIndexer = 0;\r
38 \r
39         // Return a unique type name\r
40         private string genTypeName () {\r
41                 return "t" + (typeIndexer ++);\r
42         }\r
43 \r
44         public void TestAssembly () {\r
45                 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
46                 AssertEquals ("Assembly works",\r
47                                           tb.Assembly, assembly);\r
48         }\r
49 \r
50         public void TestAssemblyQualifiedName () {\r
51                 TypeBuilder tb = module.DefineType ("A.B.C.D", TypeAttributes.Public);\r
52 \r
53                 AssertEquals ("AssemblyQualifiedName works",\r
54                                           tb.AssemblyQualifiedName, "A.B.C.D, " + assembly.GetName ().FullName);\r
55         }\r
56 \r
57         public void TestAttributes () {\r
58                 TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.BeforeFieldInit;\r
59                 TypeBuilder tb = module.DefineType (genTypeName (), attrs);\r
60 \r
61                 AssertEquals ("Attributes works",\r
62                                           tb.Attributes, attrs);\r
63         }\r
64 \r
65         public void TestBaseType () {\r
66                 TypeAttributes attrs = TypeAttributes.Public;\r
67                 TypeBuilder tb = module.DefineType (genTypeName (), attrs);\r
68                 AssertEquals ("BaseType defaults to Object",\r
69                                           tb.BaseType, typeof (object));\r
70 \r
71                 TypeBuilder tb2 = module.DefineType (genTypeName (), attrs, tb);\r
72                 AssertEquals ("BaseType works",\r
73                                           tb2.BaseType, tb);\r
74 \r
75                 /* This does not run under mono\r
76                 TypeBuilder tb3 = module.DefineType (genTypeName (),\r
77                                                                                          TypeAttributes.Interface |\r
78                                                                                          TypeAttributes.Abstract);\r
79                 AssertEquals ("Interfaces default to no base type",\r
80                                           null, tb3.BaseType);\r
81                 */\r
82         }\r
83 \r
84         public void TestDeclaringType () {\r
85                 TypeAttributes attrs = 0;\r
86                 TypeBuilder tb = module.DefineType (genTypeName (), attrs);\r
87 \r
88                 AssertEquals ("Has no declaring type",\r
89                                           null, tb.DeclaringType);\r
90 \r
91                 attrs = TypeAttributes.NestedPublic;\r
92                 TypeBuilder tb2 = tb.DefineNestedType (genTypeName (), attrs);\r
93                 TypeBuilder tb3 = tb2.DefineNestedType (genTypeName (), attrs);\r
94                 AssertEquals ("DeclaringType works",\r
95                                           tb, tb3.DeclaringType.DeclaringType);\r
96         }\r
97 \r
98         public void TestFullName () {\r
99                 string name = genTypeName ();\r
100                 TypeAttributes attrs = 0;\r
101                 TypeBuilder tb = module.DefineType (name, attrs);\r
102                 AssertEquals ("FullName works",\r
103                                           name, tb.FullName);\r
104 \r
105                 string name2 = genTypeName ();\r
106                 attrs = TypeAttributes.NestedPublic;\r
107                 TypeBuilder tb2 = tb.DefineNestedType (name2, attrs);\r
108 \r
109                 string name3 = genTypeName ();\r
110                 attrs = TypeAttributes.NestedPublic;\r
111                 TypeBuilder tb3 = tb2.DefineNestedType (name3, attrs);\r
112 \r
113                 AssertEquals ("FullName works on nested types",\r
114                                           name + "+" + name2 + "+" + name3, tb3.FullName);\r
115         }\r
116 \r
117         public void TestGUID () {\r
118                 TypeBuilder tb = module.DefineType (genTypeName ());\r
119                 try {\r
120                         Guid g = tb.GUID;\r
121                         Fail ();\r
122                 }\r
123                 catch (NotSupportedException) {\r
124                 }\r
125         }\r
126 \r
127         public void TestHasElementType () {\r
128                 // According to the MSDN docs, this member works, but in reality, it\r
129                 // returns a NotSupportedException\r
130                 TypeBuilder tb = module.DefineType (genTypeName ());\r
131                 try {\r
132                         bool b = tb.HasElementType;\r
133                         Fail ();\r
134                 }\r
135                 catch (NotSupportedException) {\r
136                 }\r
137         }\r
138 \r
139         public void TestIsAbstract () {\r
140                 TypeBuilder tb = module.DefineType (genTypeName ());\r
141                 AssertEquals ("",\r
142                                           false, tb.IsAbstract);\r
143 \r
144                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Abstract);\r
145                 AssertEquals ("",\r
146                                           true, tb2.IsAbstract);\r
147         }\r
148 \r
149         public void TestIsAnsiClass () {\r
150                 TypeBuilder tb = module.DefineType (genTypeName ());\r
151                 AssertEquals ("",\r
152                                           true, tb.IsAnsiClass);\r
153 \r
154                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.UnicodeClass);\r
155                 AssertEquals ("",\r
156                                           false, tb2.IsAnsiClass);\r
157         }\r
158 \r
159         public void TestIsArray () {\r
160                 // How can a TypeBuilder be an array ?\r
161                 string name = genTypeName ();\r
162                 TypeBuilder tb = module.DefineType (name);\r
163                 AssertEquals ("IsArray works",\r
164                                           false, tb.IsArray);\r
165         }\r
166 \r
167         public void TestIsAutoClass () {\r
168                 TypeBuilder tb = module.DefineType (genTypeName ());\r
169                 AssertEquals ("",\r
170                                           false, tb.IsAutoClass);\r
171 \r
172                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.AutoClass);\r
173                 AssertEquals ("",\r
174                                           true, tb2.IsAutoClass);\r
175         }       \r
176 \r
177         public void TestIsAutoLayout () {\r
178                 TypeBuilder tb = module.DefineType (genTypeName ());\r
179                 AssertEquals ("AutoLayout defaults to true",\r
180                                           true, tb.IsAutoLayout);\r
181 \r
182                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.ExplicitLayout);\r
183                 AssertEquals ("",\r
184                                           false, tb2.IsAutoLayout);\r
185         }\r
186 \r
187         public void TestIsByRef () {\r
188                 // How can a TypeBuilder be ByRef ?\r
189                 TypeBuilder tb = module.DefineType (genTypeName ());\r
190                 AssertEquals ("IsByRef works",\r
191                                           false, tb.IsByRef);\r
192         }\r
193 \r
194         public void TestIsClass () {\r
195                 TypeBuilder tb = module.DefineType (genTypeName ());\r
196                 AssertEquals ("Most types are classes",\r
197                                           true, tb.IsClass);\r
198 \r
199                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);\r
200                 AssertEquals ("Interfaces are not classes",\r
201                                           false, tb2.IsClass);\r
202 \r
203                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));\r
204                 AssertEquals ("value types are not classes",\r
205                                           false, tb3.IsClass);\r
206 \r
207                 TypeBuilder tb4 = module.DefineType (genTypeName (), 0, typeof (Enum));\r
208                 AssertEquals ("enums are not classes",\r
209                                           false, tb4.IsClass);\r
210         }\r
211 \r
212         public void TestIsCOMObject () {\r
213                 TypeBuilder tb = module.DefineType (genTypeName ());\r
214                 AssertEquals ("Probably not",\r
215                                           false, tb.IsCOMObject);\r
216         }\r
217 \r
218         public void TestIsContextful () {\r
219                 TypeBuilder tb = module.DefineType (genTypeName ());\r
220                 AssertEquals ("",\r
221                                           false, tb.IsContextful);\r
222 \r
223                 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (ContextBoundObject));\r
224                 AssertEquals ("",\r
225                                           true, tb2.IsContextful);\r
226         }\r
227 \r
228         public void TestIsEnum () {\r
229                 TypeBuilder tb = module.DefineType (genTypeName ());\r
230                 AssertEquals ("",\r
231                                           false, tb.IsEnum);\r
232 \r
233                 // This returns true under both mono and MS .NET ???\r
234                 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (ValueType));\r
235                 AssertEquals ("value types are not necessary enums",\r
236                                           false, tb2.IsEnum);\r
237 \r
238                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (Enum));\r
239                 AssertEquals ("enums are enums",\r
240                                           true, tb3.IsEnum);\r
241         }\r
242 \r
243         public void TestIsExplicitLayout () {\r
244                 TypeBuilder tb = module.DefineType (genTypeName ());\r
245                 AssertEquals ("ExplicitLayout defaults to false",\r
246                                           false, tb.IsExplicitLayout);\r
247 \r
248                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.ExplicitLayout);\r
249                 AssertEquals ("",\r
250                                           true, tb2.IsExplicitLayout);\r
251         }\r
252 \r
253         public void TestIsImport () {\r
254                 // How can this be true ?\r
255                 TypeBuilder tb = module.DefineType (genTypeName ());\r
256                 AssertEquals ("",\r
257                                           false, tb.IsImport);\r
258         }\r
259 \r
260         public void TestIsInterface () {\r
261                 TypeBuilder tb = module.DefineType (genTypeName ());\r
262                 AssertEquals ("Most types are not interfaces",\r
263                                           false, tb.IsInterface);\r
264 \r
265                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);\r
266                 AssertEquals ("Interfaces are interfaces",\r
267                                           true, tb2.IsInterface);\r
268 \r
269                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));\r
270                 AssertEquals ("value types are not interfaces",\r
271                                           false, tb3.IsInterface);\r
272         }\r
273 \r
274         public void TestIsLayoutSequential () {\r
275                 TypeBuilder tb = module.DefineType (genTypeName ());\r
276                 AssertEquals ("SequentialLayout defaults to false",\r
277                                           false, tb.IsLayoutSequential);\r
278 \r
279                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.SequentialLayout);\r
280                 AssertEquals ("",\r
281                                           true, tb2.IsLayoutSequential);\r
282         }\r
283 \r
284         public void TestIsMarshalByRef () {\r
285                 TypeBuilder tb = module.DefineType (genTypeName ());\r
286                 AssertEquals ("",\r
287                                           false, tb.IsMarshalByRef);\r
288 \r
289                 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (MarshalByRefObject));\r
290                 AssertEquals ("",\r
291                                           true, tb2.IsMarshalByRef);\r
292 \r
293                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ContextBoundObject));\r
294                 AssertEquals ("",\r
295                                           true, tb3.IsMarshalByRef);\r
296         }\r
297 \r
298         // TODO: Visibility properties\r
299 \r
300         public void TestIsPointer () {\r
301                 // How can this be true?\r
302                 TypeBuilder tb = module.DefineType (genTypeName ());\r
303                 AssertEquals ("",\r
304                                           false, tb.IsPointer);\r
305         }\r
306 \r
307         public void TestIsPrimitive () {\r
308                 TypeBuilder tb = module.DefineType ("int");\r
309                 AssertEquals ("",\r
310                                           false, tb.IsPrimitive);\r
311         }\r
312 \r
313         public void IsSealed () {\r
314                 TypeBuilder tb = module.DefineType (genTypeName ());\r
315                 AssertEquals ("Sealed defaults to false",\r
316                                           false, tb.IsSealed);\r
317 \r
318                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Sealed);\r
319                 AssertEquals ("IsSealed works",\r
320                                           true, tb2.IsSealed);\r
321         }\r
322 \r
323         public void IsSerializable () {\r
324                 TypeBuilder tb = module.DefineType (genTypeName ());\r
325                 AssertEquals ("",\r
326                                           false, tb.IsSerializable);\r
327 \r
328                 tb.SetCustomAttribute (new CustomAttributeBuilder (typeof (SerializableAttribute).GetConstructors (BindingFlags.Public)[0], null));\r
329                 AssertEquals ("",\r
330                                           true, tb.IsSerializable);\r
331         }\r
332 \r
333         public void TestIsSpecialName () {\r
334                 TypeBuilder tb = module.DefineType (genTypeName ());\r
335                 AssertEquals ("SpecialName defaults to false",\r
336                                           false, tb.IsSpecialName);\r
337 \r
338                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.SpecialName);\r
339                 AssertEquals ("IsSpecialName works",\r
340                                           true, tb2.IsSpecialName);\r
341         }\r
342 \r
343         public void TestIsUnicodeClass () {\r
344                 TypeBuilder tb = module.DefineType (genTypeName ());\r
345                 AssertEquals ("",\r
346                                           false, tb.IsUnicodeClass);\r
347 \r
348                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.UnicodeClass);\r
349                 AssertEquals ("",\r
350                                           true, tb2.IsUnicodeClass);\r
351         }\r
352 \r
353         public void TestIsValueType () {\r
354                 TypeBuilder tb = module.DefineType (genTypeName ());\r
355                 AssertEquals ("Most types are not value types",\r
356                                           false, tb.IsValueType);\r
357 \r
358                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);\r
359                 AssertEquals ("Interfaces are not value types",\r
360                                           false, tb2.IsValueType);\r
361 \r
362                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));\r
363                 AssertEquals ("value types are value types",\r
364                                           true, tb3.IsValueType);\r
365 \r
366                 TypeBuilder tb4 = module.DefineType (genTypeName (), 0, typeof (Enum));\r
367                 AssertEquals ("enums are value types",\r
368                                           true, tb4.IsValueType);\r
369         }\r
370 \r
371         public void TestMemberType () {\r
372                 TypeBuilder tb = module.DefineType (genTypeName ());\r
373                 AssertEquals ("A type is a type",\r
374                                           MemberTypes.TypeInfo, tb.MemberType);\r
375         }\r
376 \r
377         public void TestModule () {\r
378                 TypeBuilder tb = module.DefineType (genTypeName ());\r
379                 AssertEquals ("Module works",\r
380                                           module, tb.Module);\r
381         }\r
382 \r
383         public void TestName () {\r
384                 TypeBuilder tb = module.DefineType ("A");\r
385                 AssertEquals ("",\r
386                                           "A", tb.Name);\r
387 \r
388                 TypeBuilder tb2 = module.DefineType ("A.B.C.D.E");\r
389                 AssertEquals ("",\r
390                                           "E", tb2.Name);\r
391 \r
392                 TypeBuilder tb3 = tb2.DefineNestedType ("A");\r
393                 AssertEquals ("",\r
394                                           "A", tb3.Name);\r
395 \r
396                 /* Is .E a valid name ?\r
397                 TypeBuilder tb4 = module.DefineType (".E");\r
398                 AssertEquals ("",\r
399                                           "E", tb4.Name);\r
400                 */\r
401         }\r
402 \r
403         public void TestNamespace () {\r
404                 TypeBuilder tb = module.DefineType ("A");\r
405                 AssertEquals ("",\r
406                                           "", tb.Namespace);\r
407 \r
408                 TypeBuilder tb2 = module.DefineType ("A.B.C.D.E");\r
409                 AssertEquals ("",\r
410                                           "A.B.C.D", tb2.Namespace);\r
411 \r
412                 TypeBuilder tb3 = tb2.DefineNestedType ("A");\r
413                 AssertEquals ("",\r
414                                           "", tb3.Namespace);\r
415 \r
416                 /* Is .E a valid name ?\r
417                 TypeBuilder tb4 = module.DefineType (".E");\r
418                 AssertEquals ("",\r
419                                           "E", tb4.Name);\r
420                 */              \r
421         }\r
422 \r
423         public void TestPackingSize () {\r
424                 TypeBuilder tb = module.DefineType (genTypeName ());\r
425                 AssertEquals ("",\r
426                                           PackingSize.Unspecified, tb.PackingSize);\r
427 \r
428                 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (object),\r
429                                                                                          PackingSize.Size16, 16);\r
430                 AssertEquals ("",\r
431                                           PackingSize.Size16, tb2.PackingSize);\r
432         }\r
433 \r
434         public void TestReflectedType () {\r
435                 // It is the same as DeclaringType, but why?\r
436                 TypeBuilder tb = module.DefineType (genTypeName ());\r
437                 AssertEquals ("",\r
438                                           null, tb.ReflectedType);\r
439 \r
440                 TypeBuilder tb2 = tb.DefineNestedType (genTypeName ());\r
441                 AssertEquals ("",\r
442                                           tb, tb2.ReflectedType);\r
443         }\r
444 \r
445         public void TestSize () {\r
446                 {\r
447                         TypeBuilder tb = module.DefineType (genTypeName ());\r
448                         AssertEquals ("",\r
449                                                   0, tb.Size);\r
450                         tb.CreateType ();\r
451                         AssertEquals ("",\r
452                                                   0, tb.Size);\r
453                 }\r
454 \r
455                 {\r
456                         TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (object),\r
457                                                                                                 PackingSize.Size16, 32);\r
458                         AssertEquals ("",\r
459                                                   32, tb.Size);\r
460                 }\r
461         }\r
462 \r
463         public void TestTypeHandle () {\r
464                 TypeBuilder tb = module.DefineType (genTypeName ());\r
465                 try {\r
466                         RuntimeTypeHandle handle = tb.TypeHandle;\r
467                         Fail ();\r
468                 }\r
469                 catch (NotSupportedException) {\r
470                 }\r
471         }\r
472 \r
473         public void TestTypeInitializer () {\r
474                 // According to the MSDN docs, this works, but it doesn't\r
475                 /* TODO:\r
476                 TypeBuilder tb = module.DefineType (genTypeName ());\r
477                 try {\r
478                         ConstructorInfo cb = tb.TypeInitializer;\r
479                         Fail ();\r
480                 }\r
481                 catch (NotSupportedException) {\r
482                 }\r
483                 */\r
484         }\r
485 \r
486         public void TestTypeToken () {\r
487                 TypeBuilder tb = module.DefineType (genTypeName ());\r
488                 TypeToken token = tb.TypeToken;\r
489         }\r
490 \r
491         public void TestUnderlyingSystemType () {\r
492                 //\r
493                 // For non-enum types, UnderlyingSystemType should return itself.\r
494                 // But if I modify the code to do this, I get an exception in mcs.\r
495                 // Reason: the enums created during corlib compilation do not seem\r
496                 // to be an enum according to IsEnum.\r
497                 //\r
498                 /*\r
499                 {\r
500                         TypeBuilder tb = module.DefineType (genTypeName ());\r
501                         AssertEquals ("For non-enums this equals itself",\r
502                                                   tb, tb.UnderlyingSystemType);\r
503                 }\r
504                 {\r
505                         TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);\r
506                         AssertEquals ("",\r
507                                                   tb, tb.UnderlyingSystemType);\r
508                 }\r
509                 {\r
510                         TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (ValueType));\r
511                         AssertEquals ("",\r
512                                                   tb, tb.UnderlyingSystemType);\r
513                 }\r
514                 */\r
515                 {\r
516                         TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (Enum));\r
517                         try {\r
518                                 Type t = tb.UnderlyingSystemType;\r
519                                 Fail ();\r
520                         }\r
521                         catch (InvalidOperationException) {\r
522                         }\r
523 \r
524                         tb.DefineField ("val", typeof (int), 0);\r
525                         AssertEquals ("",\r
526                                                   typeof (int), tb.UnderlyingSystemType);\r
527                 }\r
528         }\r
529 }\r
530 }\r