Merge pull request #225 from mistoll/master
[mono.git] / mcs / class / corlib / Test / System.Reflection / MonoGenericClassTest.cs
1 //
2 // MonoGenericClassTest.cs - NUnit Test Cases for MonoGenericClassTest
3 //
4 // Rodrigo Kumpera <rkumpera@novell.com>
5 //
6 // Copyright (C) 2009 Novell, Inc (http://www.novell.com)
7 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
8 //
9
10 using System;
11 using System.Collections;
12 using System.Collections.Generic;
13 using System.Collections.ObjectModel;
14 using System.Threading;
15 using System.Reflection;
16 using System.Reflection.Emit;
17 using System.IO;
18 using System.Security;
19 using System.Security.Permissions;
20 using System.Runtime.InteropServices;
21 using NUnit.Framework;
22 using System.Runtime.CompilerServices;
23
24 namespace MonoTests.System.Reflection.Emit
25 {
26 #if NET_2_0
27         [TestFixture]
28         public class MonoGenericClassTest
29         {
30                 AssemblyBuilder assembly;
31                 ModuleBuilder module;
32                 int typeCount;
33                 static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.MonoGenericClassTest";
34
35                 string MakeName ()
36                 {
37                         return "internal__type"+ typeCount++;
38                 }
39
40                 [SetUp]
41                 public void SetUp ()
42                 {
43                         SetUp (AssemblyBuilderAccess.RunAndSave);
44                 }
45                 
46                 void SetUp (AssemblyBuilderAccess access)
47                 {
48                         AssemblyName assemblyName = new AssemblyName ();
49                         assemblyName.Name = ASSEMBLY_NAME;
50
51                         assembly =
52                                 Thread.GetDomain ().DefineDynamicAssembly (
53                                         assemblyName, access, Path.GetTempPath ());
54
55                         module = assembly.DefineDynamicModule ("module1");
56                         typeCount = 0;
57                 }
58
59
60                 [Test]
61                 public void TestNameMethods ()
62                 {
63                         TypeBuilder tb = module.DefineType ("foo.type");
64                         tb.DefineGenericParameters ("T", "K");
65
66                         Type inst = tb.MakeGenericType (typeof (double), typeof (string));
67
68                         Assert.AreEqual ("type", inst.Name, "#1");
69                         Assert.AreEqual ("foo", inst.Namespace, "#2");
70 #if NET_4_0
71                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", inst.FullName, "#3");
72                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], MonoTests.System.Reflection.Emit.MonoGenericClassTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", inst.AssemblyQualifiedName, "#4");
73 #elif NET_2_1
74                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]", inst.FullName, "#3");
75                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], MonoTests.System.Reflection.Emit.MonoGenericClassTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", inst.AssemblyQualifiedName, "#4");
76 #else
77                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", inst.FullName, "#3");
78                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], MonoTests.System.Reflection.Emit.MonoGenericClassTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", inst.AssemblyQualifiedName, "#4");
79 #endif
80                         Assert.AreEqual ("foo.type[System.Double,System.String]", inst.ToString (), "#5");
81                 }
82
83                 static void CheckInst (string prefix, Type inst, int a, int b)
84                 {
85                         var resA = inst.GetMethods (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
86                         var resB = inst.GetMethods (BindingFlags.Public | BindingFlags.Instance);
87
88                         Assert.AreEqual (a, resA.Length, prefix + 1);
89                         Assert.AreEqual (b, resB.Length, prefix + 2);
90                 }
91
92                 [Test]
93                 [Category ("NotDotNet")]
94                 // CompilerContext no longer supported
95                 [Category ("NotWorking")]
96                 public void GetMethodsWorkWithFunkyInstantiations ()
97                 {
98                         SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
99                         TypeBuilder tb = module.DefineType ("Base", TypeAttributes.Public, typeof (object));
100
101                         var a = typeof (IList<>).GetGenericArguments () [0];
102                         var b = tb.DefineGenericParameters ("T") [0];
103
104                         CheckInst ("#A", typeof (Collection<>).MakeGenericType (new Type [] {a}), 12, 16);
105                         CheckInst ("#B", typeof (Collection<>).MakeGenericType (new Type[] { b }), 12, 16);
106
107                         var tb2 = module.DefineType ("Child", TypeAttributes.Public, typeof (Collection<>).MakeGenericType (tb.MakeGenericType (typeof (int))));
108                         tb2.DefineGenericParameters ("K");
109
110                         CheckInst ("#C", tb2.MakeGenericType (typeof (double)), 0, 16);
111                         
112                 }
113
114                 [Test]
115                 [Category ("NotDotNet")]
116                 // CompilerContext no longer supported
117                 [Category ("NotWorking")]
118                 public void GetEventMustWorkUnderCompilerContext ()
119                 {
120                         SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
121                         var tb = module.DefineType ("foo.type");
122                         tb.DefineGenericParameters ("T");
123
124                         var ginst = tb.MakeGenericType (typeof (double));
125                         
126                         try {
127                                 ginst.GetEvent ("foo", BindingFlags.Public | BindingFlags.Instance);
128                         } catch (NotSupportedException) {
129                                 Assert.Fail ("#1");
130                         }
131                 }
132
133                 [Test]
134                 public void MethodsThatRaiseNotSupported ()
135                 {
136                         var tb = module.DefineType ("foo.type");
137                         tb.DefineGenericParameters ("T");
138
139                         var ginst = tb.MakeGenericType (typeof (double));
140
141                         /*try { //FIXME this doesn't work yet
142                                 ginst.GetElementType ();
143                                 Assert.Fail ("#1");
144                         } catch (NotSupportedException) {  }*/
145                         try {
146                                 ginst.GetInterface ("foo", true);
147                                 Assert.Fail ("#2");
148                         } catch (NotSupportedException) {  }
149                         try {
150                                 ginst.GetEvent ("foo", BindingFlags.Public | BindingFlags.Instance);
151                                 Assert.Fail ("#3");
152                         } catch (NotSupportedException) {  }
153                         try {
154                                 ginst.GetField ("foo", BindingFlags.Public | BindingFlags.Instance);
155                                 Assert.Fail ("#4");
156                         } catch (NotSupportedException) {  }
157                         try {
158                                 ginst.GetMembers (BindingFlags.Public | BindingFlags.Instance);
159                                 Assert.Fail ("#5");
160                         } catch (NotSupportedException) {  }
161                         try {
162                                 ginst.GetMethod ("Foo");
163                                 Assert.Fail ("#6");
164                         } catch (NotSupportedException) {  }
165                         try {
166                                 ginst.GetNestedType ("foo", BindingFlags.Public | BindingFlags.Instance);
167                                 Assert.Fail ("#7");
168                         } catch (NotSupportedException) {  }
169                         try {
170                                 ginst.GetProperty ("foo");
171                                 Assert.Fail ("#8");
172                         } catch (NotSupportedException) {  }
173                         try {
174                                 var x = ginst.TypeInitializer;
175                                 Assert.Fail ("#9");
176                         } catch (NotSupportedException) {  }
177                         try {
178                                 var x = ginst.InvokeMember ("foo", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, null, null);
179                                 Assert.Fail ("#10");
180                         } catch (NotSupportedException) {  }
181                         try {
182                                 ginst.IsDefined (typeof (int), true);
183                                 Assert.Fail ("#11");
184                         } catch (NotSupportedException) {  }
185                         try {
186                                 ginst.GetCustomAttributes (true);
187                                 Assert.Fail ("#12");
188                         } catch (NotSupportedException) {  }
189                         try {
190                                 ginst.GetCustomAttributes (typeof (int), true);
191                                 Assert.Fail ("#13");
192                         } catch (NotSupportedException) {  }
193                 }
194
195                 [Test]
196                 public void ClassMustNotBeRegisteredAfterTypeBuilderIsFinished ()
197                 {
198                         TypeBuilder tb = module.DefineType ("foo.type");
199                         tb.DefineGenericParameters ("T");
200
201                         var c = tb.CreateType ();
202
203                         var sreInst = tb.MakeGenericType (typeof (int));
204                         var rtInst = c.MakeGenericType (typeof (int));
205
206                         Assert.AreNotSame (sreInst, rtInst, "#1");
207
208                         /*This must not throw*/
209                         rtInst.IsDefined (typeof (int), true);
210                 }
211         }
212
213 #endif
214 }