Merge pull request #901 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / Test / System.Reflection / PropertyInfoTest.cs
index 4b1e4a0d9045d430c76e79c83267611e4fa78d4d..f461e8be636edf1285b2cf22e5f17ac6b6fb5e60 100644 (file)
 using System;
 using System.Reflection;
 using System.Runtime.InteropServices;
+using System.Threading;
+#if !MONOTOUCH
+using System.Reflection.Emit;
+#endif
+using System.IO;
 
 using NUnit.Framework;
 
@@ -276,7 +281,7 @@ namespace MonoTests.System.Reflection
                }
 
                [Test]
-               public void GetIndexerReturnsObjectsBoundToTheProperty ()
+               public void GetIndexParameterReturnsObjectsBoundToTheProperty ()
                {
                        RunTest (typeof (TestA), false);
                        RunTest (typeof (TestB), true);
@@ -295,8 +300,109 @@ namespace MonoTests.System.Reflection
                        }
                }
 
+               [Test]
+               public void GetIndexParameterReturnedObjectsCustomAttributes () {
+                       var pa = typeof (TestC).GetProperty ("Item").GetIndexParameters () [0];
+                       Assert.IsTrue (pa.IsDefined (typeof (ParamArrayAttribute), false), "#1");
+
+                       var pb = typeof (TestD).GetProperty ("Item").GetIndexParameters () [0];
+                       Assert.IsTrue (pb.IsDefined (typeof (ParamArrayAttribute), false), "#2");
+
+                       Assert.AreEqual (1, Attribute.GetCustomAttributes (pa).Length, "#3");
+                       Assert.AreEqual (1, Attribute.GetCustomAttributes (pb).Length, "#4");
+
+                       Assert.AreEqual (0, pa.GetOptionalCustomModifiers ().Length, "#5");
+                       Assert.AreEqual (0, pb.GetRequiredCustomModifiers ().Length, "#6");
+               }
+
+               public class TestC {
+                       public int this[params double[] a] {
+                               get { return 99; }
+                       }
+               }
+
+               public class TestD {
+                       public int this[params double[] a] {
+                               set { }
+                       }
+               }
+
+               static string CreateTempAssembly ()
+               {
+                       FileStream f = null;
+                       string path;
+                       Random rnd;
+                       int num = 0;
+
+                       rnd = new Random ();
+                       do {
+                               num = rnd.Next ();
+                               num++;
+                               path = Path.Combine (Path.GetTempPath (), "tmp" + num.ToString ("x") + ".dll");
+
+                               try {
+                                       f = new FileStream (path, FileMode.CreateNew);
+                               } catch { }
+                       } while (f == null);
+
+                       f.Close ();
+
+
+                       return "tmp" + num.ToString ("x") + ".dll";
+               }
+
+               public class TestE {
+                       public int PropE {
+                               get { return 99; }
+                       }
+               }
+#if !MONOTOUCH
+               [Test]
+               public void ConstantValue () {
+                       /*This test looks scary because we can't generate a default value with C# */
+                       var assemblyName = new AssemblyName ();
+                       assemblyName.Name = "MonoTests.System.Reflection.Emit.PropertyInfoTest";
+                       string an = CreateTempAssembly ();
+
+                       var assembly = Thread.GetDomain ().DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.RunAndSave, Path.GetTempPath ());
+                       var module = assembly.DefineDynamicModule ("module1", an);
+
+                       var tb = module.DefineType ("Test", TypeAttributes.Public);
+                       var prop = tb.DefineProperty ("Prop", PropertyAttributes.HasDefault, typeof (string), new Type [0]);
+
+                       var getter = tb.DefineMethod ("get_Prop", MethodAttributes.Public, typeof (string), new Type [0]);
+                       var ilgen = getter.GetILGenerator ();
+                       ilgen.Emit (OpCodes.Ldnull);
+                       ilgen.Emit (OpCodes.Ret);
+
+                       var setter = tb.DefineMethod ("set_Prop", MethodAttributes.Public, null, new Type [1] { typeof (string) });
+                       setter.GetILGenerator ().Emit (OpCodes.Ret);
+
+                       prop.SetConstant ("test");
+                       prop.SetGetMethod (getter);
+                       prop.SetSetMethod (setter);
+
+                       tb.CreateType ();
+
+                       File.Delete (Path.Combine (Path.GetTempPath (), an));
+                       assembly.Save (an);
+
+                       var asm = Assembly.LoadFrom (Path.Combine (Path.GetTempPath (), an));
+                       var t = asm.GetType ("Test");
+                       var p = t.GetProperty ("Prop");
+                       Assert.AreEqual ("test", p.GetConstantValue (), "#1");
+
+                       File.Delete (Path.Combine (Path.GetTempPath (), an));
+
+                       var pa = typeof (TestE).GetProperty ("PropE");
+                       try {
+                               pa.GetConstantValue ();
+                               Assert.Fail ("#2");
+                       } catch (InvalidOperationException) {
+                       }
+               }
+#endif
 
-#if NET_2_0
                public class A<T>
                {
                        public string Property {
@@ -332,8 +438,13 @@ namespace MonoTests.System.Reflection
                        PropertyInfo property = type.GetProperty ("Property");
                        Assert.AreEqual (typeof (string).FullName, property.GetValue (instance, null));
                }
-#endif
 
+               [Test]
+               public void ToStringTest ()
+               {
+                       var pa = typeof (TestC).GetProperty ("Item");
+                       Assert.AreEqual ("Int32 Item [Double[]]", pa.ToString ());
+               }
 
                static bool HasAttribute (object [] attrs, Type attributeType)
                {
@@ -376,5 +487,64 @@ namespace MonoTests.System.Reflection
                        }
 #endif
                }
+
+               [Test] // bug #633671
+               public void DeclaringTypeOfPropertyFromInheritedTypePointsToBase ()
+               {
+                       var inherit1 = typeof(InheritsFromClassWithNullableDateTime);
+                       var siblingProperty = inherit1.GetProperty("Property1");
+
+                       Assert.AreEqual (typeof (ClassWithNullableDateTime), siblingProperty.DeclaringType, "#1");
+                       Assert.AreEqual (typeof (InheritsFromClassWithNullableDateTime), siblingProperty.ReflectedType, "#2");
+
+                       //The check is done twice since the bug is related to getting those 2 properties multiple times.
+                       Assert.AreEqual (typeof (ClassWithNullableDateTime), siblingProperty.DeclaringType, "#3");
+                       Assert.AreEqual (typeof (InheritsFromClassWithNullableDateTime), siblingProperty.ReflectedType, "#4");
+               }
+               
+       
+               public class ClassWithNullableDateTime
+               {
+                       public DateTime? Property1 { get; set; }
+               }
+       
+               public class InheritsFromClassWithNullableDateTime : ClassWithNullableDateTime
+               {
+               }
+
+               public static int ThrowingProperty {
+                       get {
+                               throw new ObjectDisposedException("TestClass");
+                       }
+               }
+
+               [Test]
+               public void GetException () {
+                       var prop = typeof(PropertyInfoTest).GetProperty("ThrowingProperty");
+                       try {
+                               prop.GetValue (null, null);
+                               Assert.Fail ();
+                       } catch (TargetInvocationException ex) {
+                               Assert.IsTrue (ex.InnerException is ObjectDisposedException);
+                       }
+               }
+
+               public class DefaultValueTest
+               {
+                       public string this[int val, string param = "test"]
+                       {
+                               get{ return val + param; }
+                       }
+               }
+
+
+               [Test]
+               public void PropertyWithDefaultValue ()
+               {
+                       var parameters = typeof (DefaultValueTest).GetProperty ("Item").GetIndexParameters ();
+                       var defaultParam = parameters[parameters.Length - 1];
+                       Assert.AreEqual ("param", defaultParam.Name, "#1");
+                       Assert.AreEqual ("test", defaultParam.DefaultValue, "#2");
+               }
        }
 }