1 // TypeTest.cs - NUnit Test Cases for the System.Type class
4 // Zoltan Varga (vargaz@freemail.hu)
7 // (C) 2003 Ximian, Inc. http://www.ximian.com
10 using NUnit.Framework;
13 using System.Reflection;
14 using System.Runtime.InteropServices;
16 class NoNamespaceClass {
19 namespace MonoTests.System
21 class Super : ICloneable {
22 public virtual object Clone () {
33 interface IFace2 : IFace1 {
37 interface IFace3 : IFace2 {
40 enum TheEnum { A, B, C };
45 public abstract int this [byte i] { get; }
46 public abstract int this [int i] { get; }
47 public abstract void TestVoid();
48 public abstract void TestInt(int i);
51 class DeriveVTable : Base {
52 public override int this [byte i] { get { return 1; } }
53 public override int this [int i] { get { return 1; } }
54 public override void TestVoid() { level = 1; }
55 public override void TestInt(int i) { level = 1; }
58 class NewVTable : DeriveVTable {
59 public new int this [byte i] { get { return 2; } }
60 public new int this [int i] { get { return 2; } }
61 public new void TestVoid() { level = 2; }
62 public new void TestInt(int i) { level = 2; }
64 public void Overload () { }
65 public void Overload (int i) { }
67 public NewVTable (out int i) {
71 public void byref_method (out int i) {
78 public virtual int Foo {
87 class Derived1 : Base1 {
88 public override int Foo {
99 get { throw new NotImplementedException (); }
102 public T Execute(T a) {
107 public interface IBar<T> { }
108 public class Baz<T> : IBar<T> { }
112 public class TypeTest
114 private void ByrefMethod (ref int i, ref Derived1 j, ref Base1 k) {
118 public void TestIsAssignableFrom () {
119 // Simple tests for inheritance
120 Assert.AreEqual (typeof (Super).IsAssignableFrom (typeof (Duper)) , true, "#01");
121 Assert.AreEqual (typeof (Duper).IsAssignableFrom (typeof (Duper)), true, "#02");
122 Assert.AreEqual (typeof (Object).IsAssignableFrom (typeof (Duper)), true, "#03");
123 Assert.AreEqual (typeof (ICloneable).IsAssignableFrom (typeof (Duper)), true, "#04");
126 Assert.AreEqual (typeof (Super[]).IsAssignableFrom (typeof (Duper[])), true, "#05");
127 Assert.AreEqual (typeof (Duper[]).IsAssignableFrom (typeof (Super[])), false, "#06");
128 Assert.AreEqual (typeof (Object[]).IsAssignableFrom (typeof (Duper[])), true, "#07");
129 Assert.AreEqual (typeof (ICloneable[]).IsAssignableFrom (typeof (Duper[])), true, "#08");
131 // Tests for multiple dimensional arrays
132 Assert.AreEqual (typeof (Super[][]).IsAssignableFrom (typeof (Duper[][])), true, "#09");
133 Assert.AreEqual (typeof (Duper[][]).IsAssignableFrom (typeof (Super[][])), false, "#10");
134 Assert.AreEqual (typeof (Object[][]).IsAssignableFrom (typeof (Duper[][])), true, "#11");
135 Assert.AreEqual (typeof (ICloneable[][]).IsAssignableFrom (typeof (Duper[][])), true, "#12");
137 // Tests for vectors<->one dimensional arrays */
138 Array arr1 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {0});
139 Array arr2 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {10});
141 Assert.AreEqual (typeof (int[]).IsAssignableFrom (arr1.GetType ()), true, "#13");
142 Assert.AreEqual (typeof (int[]).IsAssignableFrom (arr2.GetType ()), false, "#14");
144 // Test that arrays of enums can be cast to their base types
145 Assert.AreEqual (typeof (int[]).IsAssignableFrom (typeof (TypeCode[])), true, "#15");
147 // Test that arrays of valuetypes can't be cast to arrays of
149 Assert.AreEqual (typeof (object[]).IsAssignableFrom (typeof (TypeCode[])), false, "#16");
150 Assert.AreEqual (typeof (ValueType[]).IsAssignableFrom (typeof (TypeCode[])), false, "#17");
151 Assert.AreEqual (typeof (Enum[]).IsAssignableFrom (typeof (TypeCode[])), false, "#18");
153 // Test that arrays of enums can't be cast to arrays of references
154 Assert.AreEqual (typeof (object[]).IsAssignableFrom (typeof (TheEnum[])), false, "#19");
155 Assert.AreEqual (typeof (ValueType[]).IsAssignableFrom (typeof (TheEnum[])), false, "#20");
156 Assert.AreEqual (typeof (Enum[]).IsAssignableFrom (typeof (TheEnum[])), false, "#21");
158 // Check that ValueType and Enum are recognized as reference types
159 Assert.AreEqual (typeof (object).IsAssignableFrom (typeof (ValueType)), true, "#22");
160 Assert.AreEqual (typeof (object).IsAssignableFrom (typeof (Enum)), true, "#23");
161 Assert.AreEqual (typeof (ValueType).IsAssignableFrom (typeof (Enum)), true, "#24");
163 Assert.AreEqual (typeof (object[]).IsAssignableFrom (typeof (ValueType[])), true, "#25");
164 Assert.AreEqual (typeof (ValueType[]).IsAssignableFrom (typeof (ValueType[])), true, "#26");
165 Assert.AreEqual (typeof (Enum[]).IsAssignableFrom (typeof (ValueType[])), false, "#27");
167 Assert.AreEqual (typeof (object[]).IsAssignableFrom (typeof (Enum[])), true, "#28");
168 Assert.AreEqual (typeof (ValueType[]).IsAssignableFrom (typeof (Enum[])), true, "#29");
169 Assert.AreEqual (typeof (Enum[]).IsAssignableFrom (typeof (Enum[])), true, "#30");
171 // Tests for byref types
172 MethodInfo mi = typeof (TypeTest).GetMethod ("ByrefMethod", BindingFlags.Instance|BindingFlags.NonPublic);
173 Assert.IsTrue (mi.GetParameters ()[2].ParameterType.IsAssignableFrom (mi.GetParameters ()[1].ParameterType));
174 Assert.IsTrue (mi.GetParameters ()[1].ParameterType.IsAssignableFrom (mi.GetParameters ()[1].ParameterType));
178 public void TestIsSubclassOf () {
179 Assert.IsTrue (typeof (ICloneable).IsSubclassOf (typeof (object)), "#01");
181 // Tests for byref types
182 Type paramType = typeof (TypeTest).GetMethod ("ByrefMethod", BindingFlags.Instance|BindingFlags.NonPublic).GetParameters () [0].ParameterType;
183 Assert.IsTrue (!paramType.IsSubclassOf (typeof (ValueType)), "#02");
184 //Assert.IsTrue (paramType.IsSubclassOf (typeof (Object)), "#03");
185 Assert.IsTrue (!paramType.IsSubclassOf (paramType), "#04");
189 public void TestGetMethodImpl() {
190 // Test binding of new slot methods (using no types)
191 Assert.AreEqual (typeof (Base), typeof (Base).GetMethod("TestVoid").DeclaringType, "#01");
192 Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetMethod ("TestVoid").DeclaringType, "#02");
194 // Test binding of new slot methods (using types)
195 Assert.AreEqual (typeof (Base), typeof (Base).GetMethod ("TestInt", new Type[] { typeof (int) }).DeclaringType, "#03");
196 Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetMethod ("TestInt", new Type[] { typeof (int) }).DeclaringType, "#04");
198 // Test overload resolution
199 Assert.AreEqual (0, typeof (NewVTable).GetMethod ("Overload", new Type[0]).GetParameters ().Length, "#05");
201 // Test byref parameters
202 Assert.AreEqual (null, typeof (NewVTable).GetMethod ("byref_method", new Type[] { typeof (int) }), "#06");
203 Type byrefInt = typeof (NewVTable).GetMethod ("byref_method").GetParameters ()[0].ParameterType;
204 Assert.IsNotNull (typeof (NewVTable).GetMethod ("byref_method", new Type[] { byrefInt }), "#07");
208 public void TestGetPropertyImpl() {
209 // Test getting property that is exact
210 Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetProperty ("Item", new Type[1] { typeof (Int32) }).DeclaringType, "#01");
212 // Test getting property that is not exact
213 Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetProperty ("Item", new Type[1] { typeof (Int16) }).DeclaringType, "#02");
215 // Test overriding of properties when only the set accessor is overriden
216 Assert.AreEqual (1, typeof (Derived1).GetProperties ().Length, "#03");
219 [StructLayout(LayoutKind.Explicit, Pack = 4, Size = 64)]
220 public class Class1 {
223 [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
224 public class Class2 {
229 public void StructLayoutAttribute () {
230 StructLayoutAttribute attr1 = typeof (TypeTest).StructLayoutAttribute;
231 Assert.AreEqual (LayoutKind.Auto, attr1.Value);
233 StructLayoutAttribute attr2 = typeof (Class1).StructLayoutAttribute;
234 Assert.AreEqual (LayoutKind.Explicit, attr2.Value);
235 Assert.AreEqual (4, attr2.Pack);
236 Assert.AreEqual (64, attr2.Size);
238 StructLayoutAttribute attr3 = typeof (Class2).StructLayoutAttribute;
239 Assert.AreEqual (LayoutKind.Explicit, attr3.Value);
240 Assert.AreEqual (CharSet.Unicode, attr3.CharSet);
245 public void Namespace () {
246 Assert.AreEqual (null, typeof (NoNamespaceClass).Namespace);
250 public void GetInterfaces () {
251 Type[] t = typeof (Duper).GetInterfaces ();
252 Assert.AreEqual (1, t.Length);
253 Assert.AreEqual (typeof (ICloneable), t[0]);
255 Type[] t2 = typeof (IFace3).GetInterfaces ();
256 Assert.AreEqual (2, t2.Length);
262 public void GetFieldIgnoreCase () {
263 Assert.IsNotNull (typeof (TypeTest).GetField ("afield", BindingFlags.Instance|BindingFlags.Public|BindingFlags.IgnoreCase));
277 public void GetPropertyAccessorModifiers () {
278 Assert.IsNotNull (typeof (TypeTest).GetProperty ("Count", BindingFlags.Instance | BindingFlags.Public));
279 Assert.IsNull (typeof (TypeTest).GetProperty ("Count", BindingFlags.Instance | BindingFlags.NonPublic));
284 public void IsPrimitive () {
285 Assert.IsTrue (typeof (IntPtr).IsPrimitive);
289 [Category("NotDotNet")]
290 // Depends on the GAC working, which it doesn't durring make distcheck.
291 [Category ("NotWorking")]
292 public void GetTypeWithWhitespace () {
293 Assert.IsNotNull (Type.GetType
294 (@"System.Configuration.NameValueSectionHandler,
299 PublicKeyToken=b77a5c561934e089"));
303 public void ExerciseFilterName() {
304 MemberInfo[] mi = typeof(Base).FindMembers(
306 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
307 BindingFlags.Instance | BindingFlags.DeclaredOnly,
308 Type.FilterName, "*");
309 Assert.AreEqual (4, mi.Length);
310 mi = typeof(Base).FindMembers(
312 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
313 BindingFlags.Instance | BindingFlags.DeclaredOnly,
314 Type.FilterName, "Test*");
315 Assert.AreEqual (2, mi.Length);
316 mi = typeof(Base).FindMembers(
318 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
319 BindingFlags.Instance | BindingFlags.DeclaredOnly,
320 Type.FilterName, "TestVoid");
321 Assert.AreEqual (1, mi.Length);
322 mi = typeof(Base).FindMembers(
324 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
325 BindingFlags.Instance | BindingFlags.DeclaredOnly,
326 Type.FilterName, "NonExistingMethod");
327 Assert.AreEqual (0, mi.Length);
331 public void ExerciseFilterNameIgnoreCase() {
332 MemberInfo[] mi = typeof(Base).FindMembers(
334 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
335 BindingFlags.Instance | BindingFlags.DeclaredOnly,
336 Type.FilterNameIgnoreCase, "*");
337 Assert.AreEqual (4, mi.Length);
338 mi = typeof(Base).FindMembers(
340 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
341 BindingFlags.Instance | BindingFlags.DeclaredOnly,
342 Type.FilterNameIgnoreCase, "test*");
343 Assert.AreEqual (2, mi.Length);
344 mi = typeof(Base).FindMembers(
346 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
347 BindingFlags.Instance | BindingFlags.DeclaredOnly,
348 Type.FilterNameIgnoreCase, "TESTVOID");
349 Assert.AreEqual (1, mi.Length);
350 mi = typeof(Base).FindMembers(
352 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
353 BindingFlags.Instance | BindingFlags.DeclaredOnly,
354 Type.FilterNameIgnoreCase, "NonExistingMethod");
355 Assert.AreEqual (0, mi.Length);
358 public int byref_field;
360 public int byref_property {
367 public void ByrefTypes ()
369 Type t = Type.GetType ("MonoTests.System.TypeTest&");
370 Assert.AreEqual (0, t.GetMethods (BindingFlags.Public | BindingFlags.Instance).Length);
371 Assert.AreEqual (0, t.GetConstructors (BindingFlags.Public | BindingFlags.Instance).Length);
372 Assert.AreEqual (0, t.GetEvents (BindingFlags.Public | BindingFlags.Instance).Length);
373 Assert.AreEqual (0, t.GetProperties (BindingFlags.Public | BindingFlags.Instance).Length);
375 Assert.IsNull (t.GetMethod ("ByrefTypes"));
376 Assert.IsNull (t.GetField ("byref_field"));
377 Assert.IsNull (t.GetProperty ("byref_property"));
386 public void CreateValueTypeNoCtor () {
387 typeof(B).InvokeMember ("", BindingFlags.CreateInstance, null, null, null);
391 [ExpectedException (typeof (MissingMethodException))]
392 public void CreateValueTypeNoCtorArgs () {
393 typeof(B).InvokeMember ("", BindingFlags.CreateInstance, null, null, new object [] { 1 });
398 public static int Value;
406 public void InvokeMemberGetSetField () {
407 typeof (X).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.SetField, null, null, new object [] { 5 });
409 Assert.AreEqual (5, X.Value);
410 Assert.AreEqual (5, typeof (X).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.GetField, null, null, new object [0]));
411 Assert.AreEqual (5, Y.Value);
412 Assert.AreEqual (5, typeof (Y).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.GetField, null, null, new object [0]));
418 public TakesInt (int x)
429 public TakesObject (object x) {}
432 // Filed as bug #75241
434 public void GetConstructorNullInTypes ()
436 // This ends up calling type.GetConstructor ()
437 Activator.CreateInstance (typeof (TakesInt), new object [] { null });
438 Activator.CreateInstance (typeof (TakesObject), new object [] { null });
442 [ExpectedException (typeof (ArgumentNullException))]
443 public void GetConstructorNullInTypes_Bug71300 ()
445 typeof (TakesInt).GetConstructor (new Type[1] { null });
446 // so null in types isn't valid for GetConstructor!
450 public void GetConstructor_TakeInt_Object ()
452 Assert.IsNull (typeof (TakesInt).GetConstructor (new Type[1] { typeof (object) }));
457 public void IsDefined ()
459 Assert.IsTrue (typeof (A).IsDefined (typeof (NemerleAttribute), false), "#1");
460 Assert.IsTrue (typeof (A).IsDefined (typeof (VolatileModifier), false), "#2");
464 public void GetTypeCode ()
466 Assert.AreEqual (TypeCode.Boolean, Type.GetTypeCode (typeof (bool)), "#1");
467 Assert.AreEqual (TypeCode.Byte, Type.GetTypeCode (typeof (byte)), "#2");
468 Assert.AreEqual (TypeCode.Char, Type.GetTypeCode (typeof (char)), "#3");
469 Assert.AreEqual (TypeCode.DateTime, Type.GetTypeCode (typeof (DateTime)), "#4");
470 Assert.AreEqual (TypeCode.DBNull, Type.GetTypeCode (typeof (DBNull)), "#5");
471 Assert.AreEqual (TypeCode.Decimal, Type.GetTypeCode (typeof (decimal)), "#6");
472 Assert.AreEqual (TypeCode.Double, Type.GetTypeCode (typeof (double)), "#7");
473 Assert.AreEqual (TypeCode.Empty, Type.GetTypeCode (null), "#8");
474 Assert.AreEqual (TypeCode.Int16, Type.GetTypeCode (typeof (short)), "#9");
475 Assert.AreEqual (TypeCode.Int32, Type.GetTypeCode (typeof (int)), "#10");
476 Assert.AreEqual (TypeCode.Int64, Type.GetTypeCode (typeof (long)), "#11");
477 Assert.AreEqual (TypeCode.Object, Type.GetTypeCode (typeof (TakesInt)), "#12");
478 Assert.AreEqual (TypeCode.SByte, Type.GetTypeCode (typeof (sbyte)), "#13");
479 Assert.AreEqual (TypeCode.Single, Type.GetTypeCode (typeof (float)), "#14");
480 Assert.AreEqual (TypeCode.String, Type.GetTypeCode (typeof (string)), "#15");
481 Assert.AreEqual (TypeCode.UInt16, Type.GetTypeCode (typeof (ushort)), "#16");
482 Assert.AreEqual (TypeCode.UInt32, Type.GetTypeCode (typeof (uint)), "#17");
483 Assert.AreEqual (TypeCode.UInt64, Type.GetTypeCode (typeof (ulong)), "#18");
487 [ExpectedException (typeof (ArgumentNullException))]
488 public void GetConstructor1a_Bug71300 ()
490 typeof (BindingFlags).GetConstructor (null);
494 [ExpectedException (typeof (ArgumentNullException))]
495 public void GetConstructor1b_Bug71300 ()
497 typeof (BindingFlags).GetConstructor (new Type[1] { null });
501 [ExpectedException (typeof (ArgumentNullException))]
502 public void GetConstructor4_Bug71300 ()
504 typeof (BindingFlags).GetConstructor (BindingFlags.Default, null, new Type[1] { null }, null);
508 [ExpectedException (typeof (ArgumentNullException))]
509 public void GetConstructor5_Bug71300 ()
511 typeof (BindingFlags).GetConstructor (BindingFlags.Default, null, CallingConventions.Any, new Type[1] { null }, null);
516 public void FullNameGenerics ()
518 Type fooType = typeof (Foo<>);
519 FieldInfo [] fields = fooType.GetFields ();
521 Assert.AreEqual (1, fields.Length, "#0");
523 Assert.IsNotNull (fooType.FullName, "#1");
524 Assert.IsNotNull (fooType.AssemblyQualifiedName, "#1a");
526 FieldInfo field = fooType.GetField ("Whatever");
527 Assert.IsNotNull (field, "#2");
528 Assert.AreEqual (field, fields [0], "#2a");
529 Assert.IsNull (field.FieldType.FullName, "#3");
530 Assert.IsNull (field.FieldType.AssemblyQualifiedName, "#3a");
531 Assert.IsNotNull (field.FieldType.ToString (), "#4");
533 PropertyInfo prop = fooType.GetProperty ("Test");
534 Assert.IsNotNull (prop, "#5");
535 Assert.IsNull (prop.PropertyType.FullName, "#6");
536 Assert.IsNull (prop.PropertyType.AssemblyQualifiedName, "#6a");
537 Assert.IsNotNull (prop.PropertyType.ToString (), "#7");
539 MethodInfo method = fooType.GetMethod("Execute");
540 Assert.IsNotNull (method, "#8");
541 Assert.IsNull (method.ReturnType.FullName, "#9");
542 Assert.IsNull (method.ReturnType.AssemblyQualifiedName, "#9a");
543 Assert.IsNotNull (method.ReturnType.ToString (), "#10");
545 ParameterInfo[] parameters = method.GetParameters();
546 Assert.AreEqual (1, parameters.Length, "#11");
547 Assert.IsNull (parameters[0].ParameterType.FullName, "#12");
548 Assert.IsNull (parameters[0].ParameterType.AssemblyQualifiedName, "#12a");
549 Assert.IsNotNull (parameters[0].ParameterType.ToString (), "#13");
553 public void TypeParameterIsNotGeneric ()
555 Type fooType = typeof (Foo<>);
556 Type type_param = fooType.GetGenericArguments () [0];
557 Assert.IsTrue (type_param.IsGenericParameter);
558 Assert.IsFalse (type_param.IsGenericType);
559 Assert.IsFalse (type_param.IsGenericTypeDefinition);
561 // LAMESPEC: MSDN claims that this should be false, but .NET v2.0.50727 says it's true
562 // http://msdn2.microsoft.com/en-us/library/system.type.isgenerictype.aspx
563 Assert.IsTrue (type_param.ContainsGenericParameters);
567 public void IsAssignable ()
569 Type foo_type = typeof (Foo<>);
570 Type foo_int_type = typeof (Foo<int>);
571 Assert.IsFalse (foo_type.IsAssignableFrom (foo_int_type), "Foo<int> -!-> Foo<>");
572 Assert.IsFalse (foo_int_type.IsAssignableFrom (foo_type), "Foo<> -!-> Foo<int>");
574 Type ibar_short_type = typeof (IBar<short>);
575 Type ibar_int_type = typeof (IBar<int>);
576 Type baz_short_type = typeof (Baz<short>);
577 Type baz_int_type = typeof (Baz<int>);
579 Assert.IsTrue (ibar_int_type.IsAssignableFrom (baz_int_type), "Baz<int> -> IBar<int>");
580 Assert.IsTrue (ibar_short_type.IsAssignableFrom (baz_short_type), "Baz<short> -> IBar<short>");
582 Assert.IsFalse (ibar_int_type.IsAssignableFrom (baz_short_type), "Baz<short> -!-> IBar<int>");
583 Assert.IsFalse (ibar_short_type.IsAssignableFrom (baz_int_type), "Baz<int> -!-> IBar<short>");
586 Assert.IsTrue (typeof (Nullable<int>).IsAssignableFrom (typeof (int)));
587 Assert.IsFalse (typeof (int).IsAssignableFrom (typeof (Nullable<int>)));
588 Assert.IsTrue (typeof (Nullable<FooStruct>).IsAssignableFrom (typeof (FooStruct)));
592 public void IsInstanceOf ()
594 Assert.IsTrue (typeof (Nullable<int>).IsInstanceOfType (5));
598 public class ComFoo<T> {
602 public void GetCustomAttributesGenericInstance ()
604 Assert.AreEqual (1, typeof (ComFoo<int>).GetCustomAttributes (typeof (ComVisibleAttribute), true).Length);
608 public class NemerleAttribute : Attribute
611 public class VolatileModifier : NemerleAttribute