2010-02-05 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mcs / class / corlib / Test / System.Reflection / PropertyInfoTest.cs
1 //
2 // PropertyInfoTest.cs - NUnit Test Cases for PropertyInfo
3 //
4 // Author:
5 //      Gert Driesen (drieseng@users.sourceforge.net)
6 //
7 // (C) 2004-2007 Gert Driesen
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29
30 using System;
31 using System.Reflection;
32 using System.Runtime.InteropServices;
33
34 using NUnit.Framework;
35
36 namespace MonoTests.System.Reflection
37 {
38         [TestFixture]
39         public class PropertyInfoTest
40         {
41                 [Test]
42                 public void GetAccessorsTest ()
43                 {
44                         Type type = typeof (TestClass);
45                         PropertyInfo property = type.GetProperty ("ReadOnlyProperty");
46
47                         MethodInfo [] methods = property.GetAccessors (true);
48                         Assert.AreEqual (1, methods.Length, "#A1");
49                         Assert.IsNotNull (methods [0], "#A2");
50                         Assert.AreEqual ("get_ReadOnlyProperty", methods [0].Name, "#A3");
51
52                         methods = property.GetAccessors (false);
53                         Assert.AreEqual (1, methods.Length, "#B1");
54                         Assert.IsNotNull (methods [0], "#B2");
55                         Assert.AreEqual ("get_ReadOnlyProperty", methods [0].Name, "#B3");
56
57                         property = typeof (Base).GetProperty ("P");
58
59                         methods = property.GetAccessors (true);
60                         Assert.AreEqual (2, methods.Length, "#C1");
61                         Assert.IsNotNull (methods [0], "#C2");
62                         Assert.IsNotNull (methods [1], "#C3");
63                         Assert.IsTrue (HasMethod (methods, "get_P"), "#C4");
64                         Assert.IsTrue (HasMethod (methods, "set_P"), "#C5");
65
66                         methods = property.GetAccessors (false);
67                         Assert.AreEqual (2, methods.Length, "#D1");
68                         Assert.IsNotNull (methods [0], "#D2");
69                         Assert.IsNotNull (methods [1], "#D3");
70                         Assert.IsTrue (HasMethod (methods, "get_P"), "#D4");
71                         Assert.IsTrue (HasMethod (methods, "set_P"), "#D5");
72
73                         methods = property.GetAccessors ();
74                         Assert.AreEqual (2, methods.Length, "#E1");
75                         Assert.IsNotNull (methods [0], "#E2");
76                         Assert.IsNotNull (methods [1], "#E3");
77                         Assert.IsTrue (HasMethod (methods, "get_P"), "#E4");
78                         Assert.IsTrue (HasMethod (methods, "set_P"), "#E5");
79
80                         property = typeof (TestClass).GetProperty ("Private",
81                                 BindingFlags.NonPublic | BindingFlags.Instance);
82
83                         methods = property.GetAccessors (true);
84                         Assert.AreEqual (2, methods.Length, "#F1");
85                         Assert.IsNotNull (methods [0], "#F2");
86                         Assert.IsNotNull (methods [1], "#F3");
87                         Assert.IsTrue (HasMethod (methods, "get_Private"), "#F4");
88                         Assert.IsTrue (HasMethod (methods, "set_Private"), "#F5");
89
90                         methods = property.GetAccessors (false);
91                         Assert.AreEqual (0, methods.Length, "#G");
92
93                         methods = property.GetAccessors ();
94                         Assert.AreEqual (0, methods.Length, "#H");
95
96 #if NET_2_0
97                         property = typeof (TestClass).GetProperty ("PrivateSetter");
98
99                         methods = property.GetAccessors (true);
100                         Assert.AreEqual (2, methods.Length, "#H1");
101                         Assert.IsNotNull (methods [0], "#H2");
102                         Assert.IsNotNull (methods [1], "#H3");
103                         Assert.IsTrue (HasMethod (methods, "get_PrivateSetter"), "#H4");
104                         Assert.IsTrue (HasMethod (methods, "set_PrivateSetter"), "#H5");
105
106                         methods = property.GetAccessors (false);
107                         Assert.AreEqual (1, methods.Length, "#I1");
108                         Assert.IsNotNull (methods [0], "#I2");
109                         Assert.AreEqual ("get_PrivateSetter", methods [0].Name, "#I3");
110
111                         methods = property.GetAccessors ();
112                         Assert.AreEqual (1, methods.Length, "#J1");
113                         Assert.IsNotNull (methods [0], "#J2");
114                         Assert.AreEqual ("get_PrivateSetter", methods [0].Name, "#J3");
115 #endif
116                 }
117
118                 [Test]
119                 public void GetCustomAttributes ()
120                 {
121                         object [] attrs;
122                         PropertyInfo p = typeof (Base).GetProperty ("P");
123
124                         attrs = p.GetCustomAttributes (false);
125                         Assert.AreEqual (1, attrs.Length, "#A1");
126                         Assert.AreEqual (typeof (ThisAttribute), attrs [0].GetType (), "#A2");
127                         attrs = p.GetCustomAttributes (true);
128                         Assert.AreEqual (1, attrs.Length, "#A3");
129                         Assert.AreEqual (typeof (ThisAttribute), attrs [0].GetType (), "#A4");
130
131                         p = typeof (Base).GetProperty ("T");
132
133                         attrs = p.GetCustomAttributes (false);
134                         Assert.AreEqual (2, attrs.Length, "#B1");
135                         Assert.IsTrue (HasAttribute (attrs, typeof (ThisAttribute)), "#B2");
136                         Assert.IsTrue (HasAttribute (attrs, typeof (ComVisibleAttribute)), "#B3");
137                         attrs = p.GetCustomAttributes (true);
138                         Assert.AreEqual (2, attrs.Length, "#B41");
139                         Assert.IsTrue (HasAttribute (attrs, typeof (ThisAttribute)), "#B5");
140                         Assert.IsTrue (HasAttribute (attrs, typeof (ComVisibleAttribute)), "#B6");
141
142                         p = typeof (Base).GetProperty ("Z");
143
144                         attrs = p.GetCustomAttributes (false);
145                         Assert.AreEqual (0, attrs.Length, "#C1");
146                         attrs = p.GetCustomAttributes (true);
147                         Assert.AreEqual (0, attrs.Length, "#C2");
148                 }
149
150                 [Test]
151                 public void GetCustomAttributes_Inherited ()
152                 {
153                         object [] attrs;
154                         PropertyInfo p = typeof (Derived).GetProperty ("P");
155
156                         attrs = p.GetCustomAttributes (false);
157                         Assert.AreEqual (0, attrs.Length, "#A1");
158                         attrs = p.GetCustomAttributes (true);
159                         Assert.AreEqual (0, attrs.Length, "#A3");
160
161                         p = typeof (Derived).GetProperty ("T");
162
163                         attrs = p.GetCustomAttributes (false);
164                         Assert.AreEqual (2, attrs.Length, "#B1");
165                         Assert.IsTrue (HasAttribute (attrs, typeof (ThisAttribute)), "#B2");
166                         Assert.IsTrue (HasAttribute (attrs, typeof (ComVisibleAttribute)), "#B3");
167                         attrs = p.GetCustomAttributes (true);
168                         Assert.AreEqual (2, attrs.Length, "#B41");
169                         Assert.IsTrue (HasAttribute (attrs, typeof (ThisAttribute)), "#B5");
170                         Assert.IsTrue (HasAttribute (attrs, typeof (ComVisibleAttribute)), "#B6");
171
172                         p = typeof (Derived).GetProperty ("Z");
173
174                         attrs = p.GetCustomAttributes (false);
175                         Assert.AreEqual (0, attrs.Length, "#C1");
176                         attrs = p.GetCustomAttributes (true);
177                         Assert.AreEqual (0, attrs.Length, "#C2");
178                 }
179
180                 [Test]
181                 public void IsDefined_AttributeType_Null ()
182                 {
183                         Type derived = typeof (Derived);
184                         PropertyInfo pi = derived.GetProperty ("P");
185
186                         try {
187                                 pi.IsDefined ((Type) null, false);
188                                 Assert.Fail ("#1");
189                         } catch (ArgumentNullException ex) {
190                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
191                                 Assert.IsNull (ex.InnerException, "#3");
192                                 Assert.IsNotNull (ex.Message, "#4");
193                                 Assert.IsNotNull (ex.ParamName, "#5");
194                                 Assert.AreEqual ("attributeType", ex.ParamName, "#6");
195                         }
196                 }
197
198                 [Test]
199                 public void AccessorsReflectedType ()
200                 {
201                         PropertyInfo pi = typeof (Derived).GetProperty ("T");
202                         Assert.AreEqual (typeof (Derived), pi.GetGetMethod ().ReflectedType);
203                         Assert.AreEqual (typeof (Derived), pi.GetSetMethod ().ReflectedType);
204                 }
205
206                 [Test] // bug #399985
207                 public void SetValue_Enum ()
208                 {
209                         TestClass t = new TestClass ();
210                         PropertyInfo pi = t.GetType ().GetProperty ("Targets");
211                         pi.SetValue (t, AttributeTargets.Field, null);
212                         Assert.AreEqual (AttributeTargets.Field, t.Targets, "#1");
213                         pi.SetValue (t, (int) AttributeTargets.Interface, null);
214                         Assert.AreEqual (AttributeTargets.Interface, t.Targets, "#2");
215                 }
216
217                 public class ThisAttribute : Attribute
218                 {
219                 }
220
221                 class Base
222                 {
223                         [ThisAttribute]
224                         public virtual string P {
225                                 get { return null; }
226                                 set { }
227                         }
228
229                         [ThisAttribute]
230                         [ComVisible (false)]
231                         public virtual string T {
232                                 get { return null; }
233                                 set { }
234                         }
235
236                         public virtual string Z {
237                                 get { return null; }
238                                 set { }
239                         }
240                 }
241
242                 class Derived : Base
243                 {
244                         public override string P {
245                                 get { return null; }
246                                 set { }
247                         }
248                 }
249
250                 static void RunTest (Type t, bool use_getter) {
251                         var p = t.GetProperty ("Item");
252                         var idx = p.GetIndexParameters ();
253                         var m_args = t.GetMethod (use_getter ? "get_Item" : "set_Item").GetParameters ();
254
255                         Assert.AreEqual (2, idx.Length, "#1");
256
257                         Assert.AreEqual (typeof (double), idx [0].ParameterType, "#2");
258                         Assert.AreEqual (p, idx [0].Member, "#3");
259                         Assert.AreEqual ("a", idx [0].Name, "#4");
260                         Assert.AreEqual (0, idx [0].Position, "#5");
261                         Assert.AreEqual (m_args [0].MetadataToken, idx [0].MetadataToken, "#6");
262                         Assert.AreEqual (ParameterAttributes.None, idx [0].Attributes, "#7");
263
264                         Assert.AreEqual (typeof (string), idx [1].ParameterType, "#8");
265                         Assert.AreEqual (p, idx [1].Member, "#9");
266                         Assert.AreEqual ("b", idx [1].Name, "#10");
267                         Assert.AreEqual (1, idx [1].Position, "#11");
268                         Assert.AreEqual (m_args [1].MetadataToken, idx [1].MetadataToken, "#12");
269                         Assert.AreEqual (ParameterAttributes.None, idx [1].Attributes, "#13");
270
271                         var idx2 = p.GetIndexParameters ();
272
273                         //No interning exposed
274                         Assert.AreNotSame (idx, idx2, "#14");
275                         Assert.AreNotSame (idx [0], idx2 [1], "#15");
276                 }
277
278                 [Test]
279                 public void GetIndexerReturnsObjectsBoundToTheProperty ()
280                 {
281
282                 }
283
284                 public class TestA {
285                         public int this[double a, string b] {
286                                 set {}
287                         }
288                 }
289
290                 public class TestB {
291                         public int this[double a, string b] {
292                                 get { return 1; }
293                                 set {}
294                         }
295                 }
296
297
298 #if NET_2_0
299                 public class A<T>
300                 {
301                         public string Property {
302                                 get { return typeof (T).FullName; }
303                         }
304                 }
305
306                 public int? nullable_field;
307
308                 public int? NullableProperty {
309                         get { return nullable_field; }
310                         set { nullable_field = value; }
311                 }
312
313                 [Test]
314                 public void NullableTests ()
315                 {
316                         PropertyInfoTest t = new PropertyInfoTest ();
317
318                         PropertyInfo pi = typeof(PropertyInfoTest).GetProperty("NullableProperty");
319
320                         pi.SetValue (t, 100, null);
321                         Assert.AreEqual (100, pi.GetValue (t, null));
322                         pi.SetValue (t, null, null);
323                         Assert.AreEqual (null, pi.GetValue (t, null));
324                 }
325
326                 [Test]
327                 public void Bug77160 ()
328                 {
329                         object instance = new A<string> ();
330                         Type type = instance.GetType ();
331                         PropertyInfo property = type.GetProperty ("Property");
332                         Assert.AreEqual (typeof (string).FullName, property.GetValue (instance, null));
333                 }
334 #endif
335
336
337                 static bool HasAttribute (object [] attrs, Type attributeType)
338                 {
339                         foreach (object attr in attrs)
340                                 if (attr.GetType () == attributeType)
341                                         return true;
342                         return false;
343                 }
344
345                 static bool HasMethod (MethodInfo [] methods, string name)
346                 {
347                         foreach (MethodInfo method in methods)
348                                 if (method.Name == name)
349                                         return true;
350                         return false;
351                 }
352
353                 private class TestClass
354                 {
355                         private AttributeTargets _targets = AttributeTargets.Assembly;
356
357                         public AttributeTargets Targets {
358                                 get { return _targets; }
359                                 set { _targets = value; }
360                         }
361
362                         public string ReadOnlyProperty {
363                                 get { return string.Empty; }
364                         }
365
366                         private string Private {
367                                 get { return null; }
368                                 set { }
369                         }
370
371 #if NET_2_0
372                         public string PrivateSetter {
373                                 get { return null; }
374                                 private set { }
375                         }
376 #endif
377                 }
378         }
379 }