New tests.
[mono.git] / mcs / class / corlib / Test / System / TypeTest.cs
index b22cef63b659ac26dd75b636a9eedde0e9c804cf..dc3b50836dc05f82d837c57f9a08b3dc053d07ba 100644 (file)
@@ -3219,6 +3219,108 @@ PublicKeyToken=b77a5c561934e089"));
                        }
                }
 
+               [Test] // Bug #574696
+               public void GetMember_DoesntReturnPrivatePropOfParent ()
+               {
+                       BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
+                       Assert.AreEqual (1, typeof (Bar).GetMember ("PrivInst", flags).Length);
+                       Assert.AreEqual (0, typeof (Bar).GetMember ("PrivInstBase", flags).Length);
+                       Assert.AreEqual (1, typeof (Foo).GetMember ("PrivInstBase", flags).Length);
+               }
+
+               [Test] // Bug #484246
+               public void GetInterfaceCompareAgainstGTDNames ()
+               {
+                       var t = typeof (Dictionary<string,string>);
+                       var iface = typeof (IDictionary<string,string>);
+
+                       Assert.AreSame (iface, t.GetInterface ("System.Collections.Generic.IDictionary`2"), "#1");
+
+                       string name = "System.Collections.Generic.IDictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]";
+
+                       Assert.IsNull (t.GetInterface (name), "#2");
+               } 
+
+               [Test]
+               public void RuntimeCorrectlyNormalizeGenericTypes ()
+               {
+                       Type lst = typeof (MList<>);
+                       Type arg = lst.GetGenericArguments ()[0];
+
+                       Type sup = lst.BaseType;
+                       Type sa0 = sup.GetGenericArguments ()[0];
+                       Type sa1 = sup.GetGenericArguments ()[1];
+
+                       Assert.IsTrue (sa1 == lst, "#1");
+                       Assert.IsTrue (sa0 == arg, "#2");
+
+                       Type inst = typeof (Cons<,>).MakeGenericType (arg, lst.MakeGenericType (arg));
+                       Assert.IsTrue (inst == sup, "#3");
+               }
+
+               class Cons<T,U>
+               {
+
+               }
+
+               class MList<A> : Cons<A, MList<A>>
+               {
+
+               }
+
+               [Test] // Bug #331126
+               public void IsAssignableFromWorksCorrectlyWithByRefs ()
+               {
+                       Type int_byref = typeof (int).MakeByRefType ();
+                       Type obj_byref = typeof (object).MakeByRefType ();
+                       Type long_byref = typeof (long).MakeByRefType ();
+                       Type enum1_byref = typeof (AttributeTargets).MakeByRefType ();
+                       Type enum2_byref = typeof (PlatformID).MakeByRefType ();
+                       Type uint_byref = typeof (uint).MakeByRefType ();
+                       Type string_byref = typeof (object).MakeByRefType ();
+                       Type struct0_byref = typeof (Size4).MakeByRefType ();
+                       Type struct1_byref = typeof (Size4b).MakeByRefType ();
+                       Type mvar0_byref = typeof (TypeTest).GetMethod ("Bug331126").GetGenericArguments ()[0].MakeByRefType ();
+                       Type mvar1_byref = typeof (TypeTest).GetMethod ("Bug331126").GetGenericArguments ()[1].MakeByRefType ();
+
+                       Assert.IsFalse (typeof (int).IsAssignableFrom (int_byref), "#1");
+                       Assert.IsFalse (int_byref.IsAssignableFrom (typeof (int)), "#2");
+                       Assert.IsFalse (obj_byref.IsAssignableFrom (long_byref), "#3");
+                       Assert.IsFalse (long_byref.IsAssignableFrom (obj_byref), "#4");
+                       Assert.IsTrue (enum1_byref.IsAssignableFrom (enum2_byref), "#5");
+                       Assert.IsTrue (enum2_byref.IsAssignableFrom (enum1_byref), "#6");
+                       Assert.IsTrue (int_byref.IsAssignableFrom (enum2_byref), "#7");
+                       Assert.IsTrue (enum2_byref.IsAssignableFrom (int_byref), "#8");
+                       Assert.IsTrue (enum2_byref.IsAssignableFrom (uint_byref), "#9");
+                       Assert.IsTrue (uint_byref.IsAssignableFrom (enum2_byref), "#10");
+                       Assert.IsTrue (int_byref.IsAssignableFrom (uint_byref), "#11");
+                       Assert.IsTrue (uint_byref.IsAssignableFrom (int_byref), "#12");
+
+                       Assert.IsTrue (typeof (object).IsAssignableFrom (typeof (long)), "#13");
+
+                       Assert.IsTrue (obj_byref.IsAssignableFrom (string_byref), "#14");
+                       Assert.IsTrue (string_byref.IsAssignableFrom (obj_byref), "#15");
+
+                       Assert.IsFalse (uint_byref.IsAssignableFrom (struct0_byref), "#16");
+                       Assert.IsFalse (struct0_byref.IsAssignableFrom (int_byref), "#17");
+                       Assert.IsFalse (struct0_byref.IsAssignableFrom (struct1_byref), "#18");
+
+                       Assert.IsFalse (obj_byref.IsAssignableFrom (mvar0_byref), "#19");
+                       Assert.IsFalse (mvar0_byref.IsAssignableFrom (mvar1_byref), "#20");
+                       Assert.IsTrue (mvar0_byref.IsAssignableFrom (mvar0_byref), "#21");
+                       Assert.IsFalse (mvar0_byref.IsAssignableFrom (obj_byref), "#22");
+               }
+
+               public void Bug331126<T,K> () {}
+
+               public struct Size4 {
+                       public int field;
+               }
+
+               public struct Size4b {
+                       public int field;
+               }
+
 #if NET_4_0
                interface IGetInterfaceMap<in T>
                {
@@ -3271,10 +3373,10 @@ PublicKeyToken=b77a5c561934e089"));
 
                        a.Equals (a);
                        Assert.AreEqual (1, ta.eq, "#1");
-                       Assert.AreEqual (2, ta.ust, "#2");
+                       Assert.AreEqual (0, ta.ust, "#2");
                        a.Equals (b);
                        Assert.AreEqual (2, ta.eq, "#3");
-                       Assert.AreEqual (3, ta.ust, "#4");
+                       Assert.AreEqual (1, ta.ust, "#4");
                        Assert.AreEqual (0, tb.eq, "#5");
                        Assert.AreEqual (1, tb.ust, "#6");
                }
@@ -3287,6 +3389,11 @@ PublicKeyToken=b77a5c561934e089"));
                public enum MyRealEnum2 : byte {
                        A,B,C
                }
+
+               public enum MyRealEnum3 : short {
+                       A,B,C
+               }
+
                public class MyEnum : TypeDelegator {
                        public bool is_enum { get; set; }
                        public int fields { get; set; }
@@ -3455,6 +3562,304 @@ PublicKeyToken=b77a5c561934e089"));
 
                        Assert.IsNull (typeof (MyRealEnum2).GetEnumName (12345), "#35");
                }
+
+               [Test]
+               public void IsEnumDefined () {
+                       try {
+                               typeof (MyRealEnum).IsEnumDefined (null);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException) { }
+
+                       try {
+                               new MyEnum () { is_enum = false }.IsEnumDefined (99);
+                               Assert.Fail ("#2");
+                       } catch (ArgumentException) { }
+
+                       try {
+                               typeof (MyRealEnum).IsEnumDefined (0);
+                               Assert.Fail ("#3");
+                       } catch (ArgumentException) { }
+
+                       try {
+                               typeof (MyRealEnum).IsEnumDefined ((ushort)0);
+                               Assert.Fail ("#4");
+                       } catch (ArgumentException) { }
+
+                       try {
+                               typeof (MyRealEnum).IsEnumDefined (MyRealEnum3.A);
+                               Assert.Fail ("#5");
+                       } catch (ArgumentException) { }
+
+                       try {
+                               typeof (MyRealEnum).IsEnumDefined (true);
+                               Assert.Fail ("#6");
+                       } catch (InvalidOperationException) { }
+
+                       try {
+                               typeof (MyRealEnum).IsEnumDefined (MyRealEnum2.A);
+                               Assert.Fail ("#7");
+                       } catch (ArgumentException) { }
+
+                       try {
+                               typeof (MyRealEnum).IsEnumDefined (typeof (MyRealEnum));
+                               Assert.Fail ("#8");
+                       } catch (InvalidOperationException) { }
+
+                       Assert.IsTrue (typeof (MyRealEnum).IsEnumDefined ((short)0), "#9");
+                       Assert.IsFalse (typeof (MyRealEnum).IsEnumDefined ((short)88), "#10");
+                       Assert.IsTrue (typeof (MyRealEnum).IsEnumDefined (MyRealEnum.A), "#11");
+                       Assert.IsFalse (typeof (MyRealEnum).IsEnumDefined ("d"), "#12");
+                       Assert.IsTrue  (typeof (MyRealEnum).IsEnumDefined ("A"), "#13");
+                       Assert.IsFalse  (new MyEnum () { is_enum = true, fields = 1 }.IsEnumDefined ((short)99), "#14");
+               }
+
+
+
+               public class Outer {
+                       public class Inner {}
+               }
+
+
+               public class Outer<T> {
+                       public class Inner {}
+               }
+
+               [Test]
+               public void GetTypeWithDelegates () {
+                       var tname = typeof (MyRealEnum).AssemblyQualifiedName;
+                       var res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (MyRealEnum), res, "#1");
+
+
+                       tname = typeof (Dictionary<int, string>).AssemblyQualifiedName;
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (Dictionary<int, string>), res, "#2");
+
+
+                       tname = typeof (Foo<int>).AssemblyQualifiedName;
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (Foo<int>), res, "#3");
+
+
+                       tname = typeof (Outer.Inner).AssemblyQualifiedName;
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (Outer.Inner), res, "#4");
+
+
+                       tname = typeof (Outer<double>.Inner).AssemblyQualifiedName;
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (Outer<double>.Inner), res, "#5");
+
+
+                       tname = "System.Collections.Generic.List`1[System.Int32]";
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (List<int>), res, "#6");
+
+
+                       tname = typeof (Foo<>).FullName + "[,][]";
+                       res = Type.GetType (tname, name => {
+                                       Console.WriteLine ("resolve-asm name {0}", name);
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (Foo<>).MakeArrayType (2).MakeArrayType (), res, "#7");
+
+                       tname = string.Format("{0}[{1}][]*&", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName);
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (Foo<MyRealEnum>[]).MakePointerType ().MakeByRefType (), res, "#8");
+
+
+                       tname = typeof (MyRealEnum).FullName + "[][]";
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (MyRealEnum[][]), res, "#9");
+
+
+                       tname = typeof (MyRealEnum).FullName + "[*]";
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (MyRealEnum).MakeArrayType (1), res, "#10");
+
+
+                       tname = typeof (MyRealEnum).FullName + "&";
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (MyRealEnum).MakeByRefType (), res, "#11");
+
+
+                       tname = typeof (MyRealEnum).FullName + "*";
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual (typeof (MyRealEnum).MakePointerType (), res, "#12");
+               }
+
+
+               public class CustomGetType : TypeDelegator {
+                       string name;
+
+                       public CustomGetType (string name) { this.name = name; }
+
+                       public override Type MakeGenericType (Type[] args) {
+                               return new CustomGetType ("GINST");
+                       }
+
+                       public override Type GetNestedType(String name, BindingFlags bidingAttr) {
+                               return new CustomGetType ("NESTED");
+                       }
+
+                       public override string ToString () { return "UT_" + name; }
+
+                       public override string Name {
+                               get { return  "UT_" + name; }
+                       }
+               }
+
+               [Test]
+               public void GetTypeWithDelegatesAndUserTypes ()
+               {
+                       var tname = "Magic[System.Int32]";
+                       var res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       if (name == "Magic") return new CustomGetType ("MAGIC");
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual ("UT_GINST", res.Name, "#1");
+
+
+                       tname = "Magic+MyRealEnum";
+                       res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       if (name == "Magic") return new CustomGetType ("MAGIC");
+                                       return asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, false, false);
+                       Assert.AreEqual ("UT_NESTED", res.Name, "#2");
+               }
+
+               void MustTLE (string tname) {
+                       try {
+                               var res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return (object)asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, true, false);
+                               Assert.Fail (tname);
+                       } catch (TypeLoadException) {}
+               }
+
+               void MustANE (string tname) {
+                       try {
+                               var res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return (object)asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, true, false);
+                               Assert.Fail (tname);
+                       } catch (ArgumentNullException) {}
+               }
+
+               void MustAE (string tname) {
+                       try {
+                               var res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return (object)asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, true, false);
+                               Assert.Fail (tname);
+                       } catch (ArgumentException) {}
+               }
+
+               void MustFNFE (string tname) {
+                       try {
+                               var res = Type.GetType (tname, name => {
+                                       return Assembly.Load (name);
+                               },(asm,name,ignore) => {
+                                       return (object)asm == null ? Type.GetType (name, false, ignore) : asm.GetType (name, false, ignore);
+                               }, true, false);
+                               Assert.Fail (tname);
+                       } catch (FileNotFoundException) {}
+               }
+
+               [Test]
+               public void NewGetTypeErrors () {
+                       MustANE (null);
+                       MustAE (string.Format ("{0}[{1}&]", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[{1}*]", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}&&", typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}&*", typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}&[{1}]", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+
+
+                       MustAE (string.Format ("{0}[[{1},", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[[{1}]", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[[{1}],", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[[{1}]_", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+
+                       MustAE (string.Format ("{0}[{1}", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[{1},", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[{1},,", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[{1} (", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[", typeof (Foo<>).FullName));
+
+                       MustAE (string.Format ("{0}[**]", typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[*,*]", typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[*,]", typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[,*]", typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[,-]", typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[,{0}]", typeof (MyRealEnum).FullName));
+
+                       MustAE (string.Format ("{0}[{1}]]", typeof (Foo<>).FullName, typeof (MyRealEnum).FullName));
+                       MustAE (string.Format ("{0}[,]]", typeof (MyRealEnum).FullName));
+
+
+                       string aqn = typeof (MyRealEnum).Assembly.FullName;
+                       MustFNFE (string.Format ("{0}, ZZZ{1}", typeof (MyRealEnum).FullName, aqn));
+                       MustTLE (string.Format ("{0}ZZZZ", typeof (MyRealEnum).FullName));
+                       MustTLE (string.Format ("{0}ZZZZ,{1}", typeof (MyRealEnum).FullName, aqn));
+               }
+
 #endif
 
                public abstract class Stream : IDisposable