Merge pull request #5198 from BrzVlad/fix-binprot-stats
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / EnumBuilderTest.cs
1 //
2 // EnumBuiderTest - NUnit Test Cases for the EnumBuider class
3 //
4 // Keerti Narayan (keertiln@rediffmail.com)
5 // Gert Driesen (drieseng@users.sourceforge.net)
6 //
7 // (C) Ximian, Inc.  http://www.ximian.com
8 //
9 //
10
11 using System;
12 using System.IO;
13 using System.Reflection;
14 using System.Reflection.Emit;
15 using System.Collections;
16 using System.Threading;
17
18 using NUnit.Framework;
19
20 namespace MonoTests.System.Reflection.Emit
21 {
22         [TestFixture]
23         public class EnumBuilderTest
24         {
25                 private static string _assemblyName = "MonoTests.System.Reflection.Emit.EnumBuilder";
26                 private static string _moduleName = "EmittedModule";
27                 private static string _enumNamespace = "MyNameSpace";
28                 private static string _enumName = "MyEnum";
29                 private static Type _enumType = typeof (Int32);
30                 private static string _fieldName = "MyField";
31                 private static object _fieldValue = 1;
32
33                 [Test]
34                 public void TestEnumBuilder ()
35                 {
36                         EnumBuilder enumBuilder = GenerateEnum ();
37                         VerifyType (enumBuilder);
38
39                         Assert.IsNotNull (enumBuilder.TypeToken, "#1");
40                         Assert.IsNotNull (enumBuilder.UnderlyingField, "#2");
41                         Assert.IsNull (enumBuilder.DeclaringType, "#3");
42                         Assert.IsNull (enumBuilder.ReflectedType, "#4");
43                         Assert.AreEqual (_enumType, enumBuilder.UnderlyingSystemType, "#5");
44                         Assert.IsFalse (enumBuilder.IsSerializable);
45                 }
46
47                 [Test]
48                 [Category ("NotWorking")]
49                 public void TestHasElementTypeEnumBuilderIncomplete ()
50                 {
51                         EnumBuilder enumBuilder = GenerateEnum ();
52                         bool hasElementType = enumBuilder.HasElementType;
53                         Assert.IsFalse (hasElementType);
54                 }
55
56                 [Test]
57                 public void TestHasElementTypeEnumBuilderComplete ()
58                 {
59                         EnumBuilder enumBuilder = GenerateEnum ();
60                         enumBuilder.CreateType ();
61                         bool hasElementType = enumBuilder.HasElementType;
62                         Assert.IsFalse (hasElementType);
63                 }
64
65                 [Test]
66                 [ExpectedException (typeof (InvalidOperationException))]
67                 public void TestDefineLiteralTypeComplete ()
68                 {
69                         EnumBuilder enumBuilder = GenerateEnum ();
70                         Type enumType = enumBuilder.CreateType ();
71                         // you should not be able to define literal after type 
72                         // has been created
73                         enumBuilder.DefineLiteral (_fieldName, _fieldValue);
74                 }
75
76                 [Test]
77                 public void TestDefineLiteralTypeIncomplete ()
78                 {
79                         EnumBuilder enumBuilder = GenerateEnum ();
80                         FieldBuilder fieldBuilder = enumBuilder.DefineLiteral (_fieldName, _fieldValue);
81                         Type enumType = enumBuilder.CreateType ();
82
83                         Assert.IsTrue (fieldBuilder.IsPublic, "#1");
84                         Assert.IsTrue (fieldBuilder.IsStatic, "#2");
85                         Assert.IsTrue (fieldBuilder.IsLiteral, "#3");
86                         Assert.AreEqual (_fieldName, fieldBuilder.Name, "#4");
87                         Assert.IsFalse (enumType == fieldBuilder.DeclaringType, "#5");
88                         Assert.IsFalse (enumBuilder == fieldBuilder.DeclaringType, "#6");
89                         Assert.AreEqual (enumType.FullName, fieldBuilder.DeclaringType.FullName, "#7");
90                         Assert.IsFalse (enumType == fieldBuilder.FieldType, "#8");
91                         Assert.AreEqual (enumBuilder, fieldBuilder.FieldType, "#9");
92                 }
93
94                 [Test]
95                 public void TestEnumType ()
96                 {
97                         AssemblyBuilder assemblyBuilder = GenerateAssembly ();
98
99                         ModuleBuilder modBuilder = GenerateModule (assemblyBuilder);
100                         EnumBuilder enumBuilder = GenerateEnum (modBuilder);
101                         enumBuilder.CreateType ();
102
103                         Type enumType = assemblyBuilder.GetType (_enumNamespace + "." + _enumName, true);
104
105                         VerifyType (enumType);
106                 }
107
108                 [Test]
109                 [ExpectedException (typeof (NotSupportedException))]
110                 public void TestEnumBuilderGUIDIncomplete ()
111                 {
112                         EnumBuilder enumBuilder = GenerateEnum ();
113                         Guid guid = enumBuilder.GUID;
114                 }
115
116                 [Test]
117                 [Category ("NotWorking")] // Bug:71299
118                 public void TestEnumBuilderGUIDComplete ()
119                 {
120                         EnumBuilder enumBuilder = GenerateEnum ();
121                         enumBuilder.CreateType ();
122                         Assert.IsTrue (enumBuilder.GUID != Guid.Empty);
123                 }
124
125                 [Test]
126                 public void TestEnumTypeGUID ()
127                 {
128                         AssemblyBuilder assemblyBuilder = GenerateAssembly ();
129                         ModuleBuilder modBuilder = GenerateModule (assemblyBuilder);
130                         EnumBuilder enumBuilder = GenerateEnum (modBuilder);
131                         enumBuilder.CreateType ();
132
133                         Type enumType = assemblyBuilder.GetType (_enumNamespace + "." + _enumName, true);
134
135                         // Tested in above test: Assert (enumType.GUID != Guid.Empty);
136                         Assert.IsNull (enumType.DeclaringType);
137                 }
138
139                 [Test]
140                 public void TestFieldProperties ()
141                 {
142                         AssemblyBuilder assemblyBuilder = GenerateAssembly ();
143                         ModuleBuilder modBuilder = GenerateModule (assemblyBuilder);
144                         EnumBuilder enumBuilder = GenerateEnum (modBuilder);
145                         FieldBuilder fieldBuilder = GenerateField (enumBuilder);
146                         enumBuilder.CreateType ();
147
148                         Type enumType = assemblyBuilder.GetType (_enumNamespace + "." + _enumName, true);
149                         FieldInfo fi = enumType.GetField (_fieldName);
150                         Object o = fi.GetValue (enumType);
151
152                         Assert.IsTrue (fi.IsLiteral, "#1");
153                         Assert.IsTrue (fi.IsPublic, "#2");
154                         Assert.IsTrue (fi.IsStatic, "#3");
155                         Assert.AreEqual (enumBuilder, fieldBuilder.FieldType, "#4");
156                         Assert.IsFalse (enumType == fieldBuilder.FieldType, "#5");
157                         Assert.AreEqual (enumType.FullName, fieldBuilder.FieldType.FullName, "#6");
158                         Assert.IsFalse (_enumType == fieldBuilder.FieldType, "#7");
159
160                         object fieldValue = fi.GetValue (enumType);
161                         Assert.IsFalse (_fieldValue == fieldValue, "#8");
162                         Assert.IsTrue (fieldValue.GetType ().IsEnum, "#9");
163                         Assert.AreEqual (enumType, fieldValue.GetType (), "#10");
164                         Assert.AreEqual (_fieldValue, (int) fieldValue, "#11");
165                 }
166
167                 [Test]
168                 public void TestFindInterfaces ()
169                 {
170                         EnumBuilder enumBuilder = GenerateEnum ();
171
172                         Type [] interfaces = enumBuilder.FindInterfaces (
173                                 new TypeFilter (MyInterfaceFilter),
174                                 "System.Collections.IEnumerable");
175                         Assert.AreEqual (0, interfaces.Length);
176                 }
177
178                 [Test]
179                 [ExpectedException (typeof (NotSupportedException))]
180                 public void TestFindMembersIncomplete ()
181                 {
182                         EnumBuilder enumBuilder = GenerateEnum ();
183                         GenerateField (enumBuilder);
184
185                         MemberInfo [] members = enumBuilder.FindMembers (
186                                 MemberTypes.All, BindingFlags.Static |
187                                 BindingFlags.Public, new MemberFilter (MemberNameFilter),
188                                 _fieldName);
189                 }
190
191                 [Test]
192                 public void GetEnumUnderlyingType ()
193                 {
194                         var @enum = GenerateEnum ();
195
196                         Assert.AreEqual (_enumType, @enum.GetEnumUnderlyingType ());
197                 }
198
199                 [Test]
200                 public void TestFindMembersComplete ()
201                 {
202                         EnumBuilder enumBuilder = GenerateEnum ();
203                         GenerateField (enumBuilder);
204                         enumBuilder.CreateType ();
205
206                         MemberInfo [] members = enumBuilder.FindMembers (
207                                 MemberTypes.Field, BindingFlags.Static |
208                                 BindingFlags.Public, new MemberFilter (MemberNameFilter),
209                                 _fieldName);
210                         Assert.AreEqual (1, members.Length, "#1");
211
212                         members = enumBuilder.FindMembers (
213                                 MemberTypes.Field, BindingFlags.Static |
214                                 BindingFlags.Public, new MemberFilter (MemberNameFilter),
215                                 "doesntmatter");
216                         Assert.AreEqual (0, members.Length, "#2");
217                 }
218
219                 [Test]
220                 [ExpectedException (typeof (NotSupportedException))]
221                 public void TestGetConstructorIncomplete ()
222                 {
223                         EnumBuilder enumBuilder = GenerateEnum ();
224                         enumBuilder.GetConstructor (BindingFlags.Public, null,
225                                 CallingConventions.Any, Type.EmptyTypes, new ParameterModifier [0]);
226                 }
227
228                 [Test]
229                 public void TestGetConstructorComplete ()
230                 {
231                         EnumBuilder enumBuilder = GenerateEnum ();
232                         enumBuilder.CreateType ();
233                         ConstructorInfo ctor = enumBuilder.GetConstructor (
234                                 BindingFlags.Public, null, CallingConventions.Any,
235                                 Type.EmptyTypes, new ParameterModifier [0]);
236                         Assert.IsNull (ctor);
237                 }
238
239                 [Test]
240                 [ExpectedException (typeof (ArgumentNullException))]
241                 public void TestGetConstructorNullTypes ()
242                 {
243                         EnumBuilder enumBuilder = GenerateEnum ();
244                         enumBuilder.CreateType ();
245                         ConstructorInfo ctor = enumBuilder.GetConstructor (
246                                 BindingFlags.Public, null, CallingConventions.Any,
247                                 null, new ParameterModifier [0]);
248                 }
249
250                 [Test]
251                 [Category ("NotWorking")]
252                 [ExpectedException (typeof (ArgumentNullException))]
253                 public void TestGetConstructorNullElementType ()
254                 {
255                         EnumBuilder enumBuilder = GenerateEnum ();
256                         enumBuilder.CreateType ();
257                         ConstructorInfo ctor = enumBuilder.GetConstructor (
258                                 BindingFlags.Public, null, CallingConventions.Any,
259                                 new Type [] { null }, new ParameterModifier [0]);
260                 }
261
262                 [Test]
263                 [ExpectedException (typeof (NotSupportedException))]
264                 [Category ("NotWorking")]
265                 public void TestGetConstructorsIncomplete ()
266                 {
267                         EnumBuilder enumBuilder = GenerateEnum ();
268
269                         ConstructorInfo [] ctors = enumBuilder.GetConstructors (
270                                 BindingFlags.Instance | BindingFlags.Public);
271                         Assert.AreEqual (0, ctors.Length);
272                 }
273
274                 [Test]
275                 public void TestGetConstructorsComplete ()
276                 {
277                         EnumBuilder enumBuilder = GenerateEnum ();
278                         enumBuilder.CreateType ();
279
280                         ConstructorInfo [] ctors = enumBuilder.GetConstructors (
281                                 BindingFlags.Instance | BindingFlags.Public);
282                         Assert.AreEqual (0, ctors.Length);
283                 }
284
285                 [Test]
286                 public void TestIsValue__SpecialName ()
287                 {
288                         EnumBuilder enumBuilder = GenerateEnum ();
289                         Type enumType = enumBuilder.CreateType ();
290                         FieldInfo value = enumType.GetField ("value__", BindingFlags.Instance | BindingFlags.NonPublic);
291                         Assert.AreEqual (FieldAttributes.RTSpecialName, value.Attributes & FieldAttributes.RTSpecialName);
292                 }
293
294                 [Test]
295                 public void TestCreateTypeIncompleteEnumStaticField ()
296                 {
297                         ModuleBuilder modBuilder = GenerateModule ();
298                         EnumBuilder enumBuilder = GenerateEnum (modBuilder);
299                         GenerateField (enumBuilder);
300
301                         var tb = modBuilder.DefineType ("T", TypeAttributes.Public);
302
303                         tb.DefineDefaultConstructor (MethodAttributes.Public);
304                         tb.DefineField ("e", enumBuilder, FieldAttributes.Static | FieldAttributes.Public);
305
306                         var t = tb.CreateType ();
307                         Assert.IsNotNull (t);
308                         bool caught = false;
309                         try {
310                                 object x = Activator.CreateInstance (t);
311                         } catch (TypeLoadException exn) {
312                                 Assert.AreEqual (t.Name, exn.TypeName);
313                                 caught = true;
314                         }
315                         if (!caught)
316                                 Assert.Fail ("Expected CreateInstance of a broken type to throw TLE");
317                 }
318
319                 private static void VerifyType (Type type)
320                 {
321                         Assert.IsNotNull (type.Assembly, "#V1");
322                         Assert.IsNotNull (type.AssemblyQualifiedName, "#V2");
323                         Assert.IsNotNull (type.BaseType, "#V3");
324                         Assert.IsNotNull (type.FullName, "#V4");
325                         Assert.IsNotNull (type.Module, "#V5");
326                         Assert.IsNotNull (type.Name, "#V6");
327                         Assert.IsNotNull (type.Namespace, "#V7");
328                         Assert.IsNotNull (type.UnderlyingSystemType, "#V8");
329
330                         Assert.AreEqual (_enumNamespace, type.Namespace, "#V10");
331                         Assert.AreEqual (_enumName, type.Name, "#V11");
332                         Assert.AreEqual (typeof (Enum), type.BaseType, "#V12");
333                         Assert.AreEqual (MemberTypes.TypeInfo, type.MemberType, "#V13");
334                         Assert.AreEqual (typeof (int), Enum.GetUnderlyingType (type), "#V14");
335
336                         Assert.IsFalse (type.IsArray, "#V15");
337                         Assert.IsFalse (type.IsAutoClass, "#V16");
338                         Assert.IsTrue (type.IsAutoLayout, "#V17");
339                         Assert.IsFalse (type.IsByRef, "#V18");
340                         Assert.IsFalse (type.IsClass, "#V19");
341                         Assert.IsFalse (type.IsCOMObject, "#V20");
342                         Assert.IsFalse (type.IsContextful, "#V21");
343                         Assert.IsTrue (type.IsEnum, "#V22");
344                         Assert.IsFalse (type.IsExplicitLayout, "#V23");
345                         Assert.IsFalse (type.IsImport, "#V24");
346                         Assert.IsFalse (type.IsInterface, "#V25");
347                         Assert.IsFalse (type.IsLayoutSequential, "#V26");
348                         Assert.IsFalse (type.IsMarshalByRef, "#V27");
349                         Assert.IsFalse (type.IsNestedAssembly, "#V28");
350                         Assert.IsFalse (type.IsNestedFamily, "#V29");
351                         Assert.IsFalse (type.IsNestedPublic, "#V30");
352                         Assert.IsFalse (type.IsNestedPrivate, "#V31");
353                         Assert.IsFalse (type.IsNotPublic, "#V32");
354                         Assert.IsFalse (type.IsPrimitive, "#V33");
355                         Assert.IsFalse (type.IsPointer, "#V34");
356                         Assert.IsTrue (type.IsPublic, "#V35");
357                         Assert.IsTrue (type.IsSealed, "#V36");
358                         Assert.IsFalse (type.IsUnicodeClass, "#V37");
359                         Assert.IsFalse (type.IsSpecialName, "#V38");
360                         Assert.IsTrue (type.IsValueType, "#V39");
361                 }
362
363                 public static bool MyInterfaceFilter (Type t, object filterCriteria)
364                 {
365                         if (t.ToString () == filterCriteria.ToString ())
366                                 return true;
367                         else
368                                 return false;
369                 }
370
371                 public static bool MemberNameFilter (MemberInfo m, object filterCriteria)
372                 {
373                         if (m.Name == filterCriteria.ToString ())
374                                 return true;
375                         else
376                                 return false;
377                 }
378
379                 private static AssemblyName GetAssemblyName ()
380                 {
381                         AssemblyName assemblyName = new AssemblyName ();
382                         assemblyName.Name = _assemblyName;
383                         return assemblyName;
384                 }
385
386                 private static AssemblyBuilder GenerateAssembly ()
387                 {
388                         return AppDomain.CurrentDomain.DefineDynamicAssembly (
389                                 GetAssemblyName (), AssemblyBuilderAccess.RunAndSave);
390                 }
391
392                 private static ModuleBuilder GenerateModule ()
393                 {
394                         AssemblyBuilder assemblyBuilder = GenerateAssembly ();
395                         return assemblyBuilder.DefineDynamicModule (_moduleName);
396                 }
397
398                 private static ModuleBuilder GenerateModule (AssemblyBuilder assemblyBuilder)
399                 {
400                         return assemblyBuilder.DefineDynamicModule (_moduleName);
401                 }
402
403                 private static EnumBuilder GenerateEnum ()
404                 {
405                         ModuleBuilder modBuilder = GenerateModule ();
406                         return modBuilder.DefineEnum (_enumNamespace + "."
407                                 + _enumName, TypeAttributes.Public, _enumType);
408                 }
409
410                 private static EnumBuilder GenerateEnum (ModuleBuilder modBuilder)
411                 {
412                         return modBuilder.DefineEnum (_enumNamespace + "."
413                                 + _enumName, TypeAttributes.Public, _enumType);
414                 }
415
416                 private static FieldBuilder GenerateField ()
417                 {
418                         EnumBuilder enumBuilder = GenerateEnum ();
419                         return enumBuilder.DefineLiteral (_fieldName, _fieldValue);
420                 }
421
422                 private static FieldBuilder GenerateField (EnumBuilder enumBuilder)
423                 {
424                         return enumBuilder.DefineLiteral (_fieldName, _fieldValue);
425                 }
426         }
427 }