2008-01-30 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / corlib / Test / System.Reflection / ModuleTest.cs
1 //
2 // ModuleTest - NUnit Test Cases for the Module class
3 //
4 // Zoltan Varga (vargaz@freemail.hu)
5 //
6 // (C) Ximian, Inc.  http://www.ximian.com
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9
10 using System;
11 using System.Threading;
12 using System.Reflection;
13 using System.Reflection.Emit;
14 using System.Runtime.Serialization;
15 using System.IO;
16 using System.Collections;
17
18 using NUnit.Framework;
19
20 namespace MonoTests.System.Reflection
21 {
22 [TestFixture]
23 public class ModuleTest
24 {
25         static string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.Reflection.ModuleTest");
26
27         [SetUp]
28         public void SetUp ()
29         {
30                 while (Directory.Exists (TempFolder))
31                         TempFolder = Path.Combine (TempFolder, "2");
32                 Directory.CreateDirectory (TempFolder);
33         }
34
35         [TearDown]
36         public void TearDown ()
37         {
38                 try {
39                         // This throws an exception under MS.NET, since the directory contains loaded
40                         // assemblies.
41                         Directory.Delete (TempFolder, true);
42                 } catch (Exception) {
43                 }
44         }
45
46         [Test]
47         public void IsDefined_AttributeType_Null ()
48         {
49                 Type t = typeof (ModuleTest);
50                 Module module = t.Module;
51
52                 try {
53                         module.IsDefined ((Type) null, false);
54                         Assert.Fail ("#1");
55                 } catch (ArgumentNullException ex) {
56                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
57                         Assert.IsNull (ex.InnerException, "#3");
58                         Assert.IsNotNull (ex.Message, "#4");
59                         Assert.IsNotNull (ex.ParamName, "#5");
60                         Assert.AreEqual ("attributeType", ex.ParamName, "#6");
61                 }
62         }
63
64         [Test]
65         public void GetField_Name_Null ()
66         {
67                 Type t = typeof (ModuleTest);
68                 Module module = t.Module;
69
70                 try {
71                         module.GetField (null);
72                         Assert.Fail ("#A1");
73                 } catch (ArgumentNullException ex) {
74                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
75                         Assert.IsNull (ex.InnerException, "#A3");
76                         Assert.IsNotNull (ex.Message, "#A4");
77                         Assert.IsNotNull (ex.ParamName, "#A5");
78                         Assert.AreEqual ("name", ex.ParamName, "#A6");
79                 }
80
81                 try {
82                         module.GetField (null, 0);
83                         Assert.Fail ("#B1");
84                 } catch (ArgumentNullException ex) {
85                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
86                         Assert.IsNull (ex.InnerException, "#B3");
87                         Assert.IsNotNull (ex.Message, "#B4");
88                         Assert.IsNotNull (ex.ParamName, "#B5");
89                         Assert.AreEqual ("name", ex.ParamName, "#B6");
90                 }
91         }
92
93         // Some of these tests overlap with the tests for ModuleBuilder
94
95         [Test]
96         [Category("NotDotNet")] // path length can cause suprious failures
97         public void TestGlobalData () {
98
99                 string name = "moduletest-assembly";
100                 string fileName = name + ".dll";
101
102                 AssemblyName assemblyName = new AssemblyName();
103                 assemblyName.Name = name;
104
105                 AssemblyBuilder ab
106                         = Thread.GetDomain().DefineDynamicAssembly(
107                                 assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder);
108
109                 string resfile = Path.Combine (TempFolder, "res");
110                 using (StreamWriter sw = new StreamWriter (resfile)) {
111                         sw.WriteLine ("FOO");
112                 }
113
114                 ab.AddResourceFile ("res", "res");
115
116                 ModuleBuilder mb = ab.DefineDynamicModule(fileName, fileName);
117
118                 mb.DefineInitializedData ("DATA", new byte [100], FieldAttributes.Public);
119                 mb.DefineInitializedData ("DATA2", new byte [100], FieldAttributes.Public);
120                 mb.DefineInitializedData ("DATA3", new byte [99], FieldAttributes.Public);
121                 mb.DefineUninitializedData ("DATA4", 101, FieldAttributes.Public);
122                 mb.DefineInitializedData ("DATA_PRIVATE", new byte [100], 0);
123                 mb.CreateGlobalFunctions ();
124
125                 ab.Save (fileName);
126
127                 Assembly assembly = Assembly.LoadFrom (Path.Combine (TempFolder, fileName));
128
129                 Module module = assembly.GetLoadedModules ()[0];
130
131                 string[] expectedFieldNames = new string [] {
132                         "DATA", "DATA2", "DATA3", "DATA4"
133                 };
134                 ArrayList fieldNames = new ArrayList ();
135                 foreach (FieldInfo fi in module.GetFields ()) {
136                         fieldNames.Add (fi.Name);
137                 }
138                 AssertArrayEqualsSorted (expectedFieldNames, fieldNames.ToArray (typeof (string)));
139
140                 Assert.IsNotNull (module.GetField ("DATA"), "#A1");
141                 Assert.IsNotNull (module.GetField ("DATA2"), "#A2");
142                 Assert.IsNotNull (module.GetField ("DATA3"), "#A3");
143                 Assert.IsNotNull (module.GetField ("DATA4"), "#A4");
144                 Assert.IsNull (module.GetField ("DATA_PRIVATE"), "#A5");
145                 Assert.IsNotNull (module.GetField ("DATA_PRIVATE", BindingFlags.NonPublic | BindingFlags.Static), "#A6");
146
147                 // Check that these methods work correctly on resource modules
148                 Module m2 = assembly.GetModule ("res");
149                 Assert.IsNotNull (m2, "#B1");
150                 Assert.AreEqual (0, m2.GetFields ().Length, "#B2");
151                 Assert.IsNull (m2.GetField ("DATA"), "#B3");
152                 Assert.IsNull (m2.GetField ("DATA", BindingFlags.Public), "#B4");
153         }
154
155 #if NET_2_0
156         [Test]
157         public void ResolveType ()
158         {
159                 Type t = typeof (ModuleTest);
160                 Module module = t.Module;
161
162                 Assert.AreEqual (t, module.ResolveType (t.MetadataToken), "#1");
163
164                 /* We currently throw ArgumentException for this one */
165                 try {
166                         module.ResolveType (1234);
167                         Assert.Fail ("#2");
168                 } catch (ArgumentException) {
169                 }
170
171                 try {
172                         module.ResolveType (t.GetMethod ("ResolveType").MetadataToken);
173                         Assert.Fail ("#3");
174                 } catch (ArgumentException) {
175                 }
176
177                 try {
178                         module.ResolveType (t.MetadataToken + 10000);
179                         Assert.Fail ("#4");
180                 } catch (ArgumentOutOfRangeException) {
181                 }
182         }
183
184         [Test]
185         public void ResolveMethod ()
186         {
187                 Type t = typeof (ModuleTest);
188                 Module module = t.Module;
189
190                 Assert.AreEqual (t.GetMethod ("ResolveMethod"), module.ResolveMethod (t.GetMethod ("ResolveMethod").MetadataToken));
191
192                 try {
193                         module.ResolveMethod (1234);
194                         Assert.Fail ();
195                 } catch (ArgumentException) {
196                 }
197
198                 try {
199                         module.ResolveMethod (t.MetadataToken);
200                         Assert.Fail ();
201                 } catch (ArgumentException) {
202                 }
203
204                 try {
205                         module.ResolveMethod (t.GetMethod ("ResolveMethod").MetadataToken + 10000);
206                         Assert.Fail ();
207                 } catch (ArgumentOutOfRangeException) {
208                 }
209         }
210
211         public int aField;
212
213         [Test]
214         public void ResolveField ()
215         {
216                 Type t = typeof (ModuleTest);
217                 Module module = t.Module;
218
219                 Assert.AreEqual (t.GetField ("aField"), module.ResolveField (t.GetField ("aField").MetadataToken));
220
221                 try {
222                         module.ResolveField (1234);
223                         Assert.Fail ();
224                 } catch (ArgumentException) {
225                 }
226
227                 try {
228                         module.ResolveField (t.MetadataToken);
229                         Assert.Fail ();
230                 } catch (ArgumentException) {
231                 }
232
233                 try {
234                         module.ResolveField (t.GetField ("aField").MetadataToken + 10000);
235                         Assert.Fail ();
236                 } catch (ArgumentOutOfRangeException) {
237                 }
238         }
239
240         [Ignore ("it breaks nunit-console.exe execution under .NET 2.0")]
241         [Test]
242         public void ResolveString ()
243         {
244                 Type t = typeof (ModuleTest);
245                 Module module = t.Module;
246
247                 for (int i = 1; i < 10000; ++i) {
248                         try {
249                                 module.ResolveString (0x70000000 + i);
250                         } catch (Exception) {
251                         }
252                 }
253
254                 try {
255                         module.ResolveString (1234);
256                         Assert.Fail ();
257                 } catch (ArgumentException) {
258                 }
259
260                 try {
261                         module.ResolveString (t.MetadataToken);
262                         Assert.Fail ();
263                 } catch (ArgumentException) {
264                 }
265
266                 try {
267                         module.ResolveString (0x70000000 | 10000);
268                         Assert.Fail ();
269                 } catch (ArgumentOutOfRangeException) {
270                 }
271         }
272
273
274         [Test]
275         public void ResolveMember ()
276         {
277                 Type t = typeof (ModuleTest);
278                 Module module = t.Module;
279
280                 Assert.AreEqual (t, module.ResolveMember (t.MetadataToken), "#1");
281                 Assert.AreEqual (t.GetField ("aField"), module.ResolveMember (t.GetField ("aField").MetadataToken), "#2");
282                 Assert.AreEqual (t.GetMethod ("ResolveMember"), module.ResolveMember (t.GetMethod ("ResolveMember").MetadataToken), "#3");
283
284                 try {
285                         module.ResolveMember (module.MetadataToken);
286                         Assert.Fail ("#4");
287                 } catch (ArgumentException) {
288                 }
289         }
290 #endif
291
292         [Test]
293         public void FindTypes ()
294         {
295                 Module m = typeof (ModuleTest).Module;
296
297                 Type[] t;
298
299                 t = m.FindTypes (Module.FilterTypeName, "FindTypesTest*");
300                 Assert.AreEqual (2, t.Length, "#A1");
301                 Assert.AreEqual ("FindTypesTestFirstClass", t [0].Name, "#A2");
302                 Assert.AreEqual ("FindTypesTestSecondClass", t [1].Name, "#A3");
303                 t = m.FindTypes (Module.FilterTypeNameIgnoreCase, "findtypestest*");
304                 Assert.AreEqual (2, t.Length, "#B1");
305                 Assert.AreEqual ("FindTypesTestFirstClass", t [0].Name, "#B2");
306                 Assert.AreEqual ("FindTypesTestSecondClass", t [1].Name, "#B3");
307         }
308
309         [Test]
310         [ExpectedException (typeof (ArgumentNullException))]
311         public void GetObjectData_Null ()
312         {
313                 Module m = typeof (ModuleTest).Module;
314                 m.GetObjectData (null, new StreamingContext (StreamingContextStates.All));
315         }
316
317         [Test]
318         public void GetTypes ()
319         {
320                 AssemblyName newName = new AssemblyName ();
321                 newName.Name = "ModuleTest";
322
323                 AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly (newName, AssemblyBuilderAccess.RunAndSave, TempFolder);
324
325                 ModuleBuilder mb = ab.DefineDynamicModule ("myDynamicModule1", "myDynamicModule" + ".dll", true);
326
327                 TypeBuilder tb = mb.DefineType ("Foo", TypeAttributes.Public);
328                 tb.CreateType ();
329
330                 ab.Save ("test_assembly.dll");
331
332                 Assembly ass = Assembly.LoadFrom (Path.Combine (TempFolder, "test_assembly.dll"));
333                 ArrayList types = new ArrayList ();
334                 // The order of the modules is different between MS.NET and mono
335                 foreach (Module m in ass.GetModules ()) {
336                         Type[] t = m.GetTypes ();
337                         types.AddRange (t);
338                 }
339                 Assert.AreEqual (1, types.Count);
340                 Assert.AreEqual ("Foo", ((Type)(types [0])).Name);
341         }
342
343         class FindTypesTestFirstClass {
344         }
345
346         class FindTypesTestSecondClass {
347         }
348
349         private static void AssertArrayEqualsSorted (Array o1, Array o2) {
350                 Array s1 = (Array)o1.Clone ();
351                 Array s2 = (Array)o2.Clone ();
352
353                 Array.Sort (s1);
354                 Array.Sort (s2);
355
356                 Assert.AreEqual (s1.Length, s2.Length);
357                 for (int i = 0; i < s1.Length; ++i)
358                         Assert.AreEqual (s1.GetValue (i), s2.GetValue (i));
359         }
360 }
361 }
362