Fix Attribute.GetHashCode to match MS behavior (needed for Moonlight)
[mono.git] / mcs / class / corlib / Test / System / AttributeTest.cs
1 //
2 // AttributeTest.cs - NUnit Test Cases for the System.Attribute class
3 //
4 // Authors:
5 //      Duco Fijma (duco@lorentz.xs4all.nl)
6 //      Gonzalo Paniagua (gonzalo@ximian.com)
7 //      Gert Driesen (drieseng@users.sourceforge.net)
8 //
9 //      (C) 2002 Duco Fijma
10 //      (c) 2004 Novell, Inc. (http://www.novell.com)
11 //
12
13 using System;
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Runtime.InteropServices;
17 using System.Threading;
18
19 using NUnit.Framework;
20
21 namespace MonoTests.System
22 {
23         using MonoTests.System.AttributeTestInternals;
24
25         namespace AttributeTestInternals
26         {
27                 [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
28                 internal class MyCustomAttribute : Attribute
29                 {
30                         private string _info;
31
32                         public MyCustomAttribute (string info)
33                         {
34                                 _info = info;
35                         }
36
37                         public string Info {
38                                 get {
39                                         return _info;
40                                 }
41                         }
42                 }
43
44                 [AttributeUsage (AttributeTargets.Class)]
45                 internal class YourCustomAttribute : Attribute
46                 {
47                         private int _value;
48
49                         public YourCustomAttribute (int value)
50                         {
51                                 _value = value;
52                         }
53
54                         public int Value {
55                                 get {
56                                         return _value;
57                                 }
58                         }
59                 }
60
61                 [AttributeUsage (AttributeTargets.Class)]
62                 internal class UnusedAttribute : Attribute
63                 {
64                 }
65
66                 [MyCustomAttribute ("MyBaseClass"), YourCustomAttribute (37)]
67                 internal class MyClass
68                 {
69                         int Value {
70                                 get { return 42; }
71                         }
72
73                         public static void ParamsMethod(params object[] args)
74                         {
75                         }
76                 }
77
78                 [MyCustomAttribute ("MyDerivedClass")]
79                 internal class MyDerivedClass : MyClass
80                 {
81                         public void Do ()
82                         {
83                         }
84                 }
85         }
86
87         [TestFixture]
88         public class AttributeTest
89         {
90                 [Test]
91                 public void TestIsDefined ()
92                 {
93                         Assert.IsTrue (Attribute.IsDefined (typeof(MyDerivedClass), typeof(MyCustomAttribute)), "#1");
94                         Assert.IsTrue (Attribute.IsDefined (typeof (MyDerivedClass), typeof (YourCustomAttribute)), "#2");
95                         Assert.IsFalse (Attribute.IsDefined (typeof (MyDerivedClass), typeof (UnusedAttribute)), "#3");
96                         Assert.IsTrue (Attribute.IsDefined (typeof (MyDerivedClass), typeof (MyCustomAttribute), true), "#4");
97                         Assert.IsTrue (Attribute.IsDefined (typeof (MyDerivedClass), typeof (YourCustomAttribute), true), "#5");
98                         Assert.IsFalse (Attribute.IsDefined (typeof (MyDerivedClass), typeof (UnusedAttribute), false), "#6");
99                         Assert.IsTrue (Attribute.IsDefined (typeof (MyDerivedClass), typeof (MyCustomAttribute), false), "#7");
100                         Assert.IsFalse (Attribute.IsDefined (typeof (MyDerivedClass), typeof (YourCustomAttribute), false), "#8");
101                         Assert.IsFalse (Attribute.IsDefined (typeof (MyDerivedClass), typeof (UnusedAttribute), false), "#9");
102                         Assert.IsTrue (Attribute.IsDefined (typeof (MyClass).GetMethod ("ParamsMethod").GetParameters () [0], typeof (ParamArrayAttribute), false), "#10");
103                 }
104
105                 [Test]
106                 public void IsDefined_PropertyInfo ()
107                 {
108                         PropertyInfo pi = typeof (TestBase).GetProperty ("PropBase3");
109                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute)), "#A1");
110                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute), false), "#A2");
111                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute), true), "#A3");
112                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute)), "#A4");
113                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), false), "#A5");
114                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), true), "#A6");
115
116                         pi = typeof (TestBase).GetProperty ("PropBase2");
117                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute)), "#C1");
118                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute), false), "#C2");
119                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute), true), "#C3");
120                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (ComVisibleAttribute)), "#C4");
121                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), false), "#C5");
122                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), true), "#C6");
123
124                         pi = typeof (TestSub).GetProperty ("PropBase2");
125                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute)), "#D1");
126                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute), false), "#D2");
127                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute), true), "#D3");
128                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (ComVisibleAttribute)), "#D4");
129                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), false), "#D5");
130                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), true), "#D6");
131                 }
132
133                 [Test]
134                 public void IsDefined_PropertyInfo_Override ()
135                 {
136                         PropertyInfo pi = typeof (TestSub).GetProperty ("PropBase3");
137 #if NET_2_0
138                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute)), "#B1");
139 #else
140                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (PropTestAttribute)), "#B1");
141 #endif
142                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (PropTestAttribute), false), "#B2");
143 #if NET_2_0
144                         Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute), true), "#B3");
145 #else
146                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (PropTestAttribute), true), "#B3");
147 #endif
148                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute)), "#B4");
149                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), false), "#B5");
150                         Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), true), "#B6");
151                 }
152
153                 [Test]
154                 public void TestGetCustomAttribute ()
155                 {
156                         int i = 1;
157                         Type t = typeof(MyDerivedClass);
158                         try {
159                                 Assert.AreEqual  ("MyDerivedClass", ((MyCustomAttribute) (Attribute.GetCustomAttribute (typeof(MyDerivedClass), typeof(MyCustomAttribute), false))).Info, "#1");
160                                 i++;
161                                 Assert.IsNull (((YourCustomAttribute) (Attribute.GetCustomAttribute (typeof(MyDerivedClass), typeof(YourCustomAttribute), false))), "#2");
162                                 i++;
163                                 Assert.AreEqual ("MyDerivedClass", ((MyCustomAttribute) (Attribute.GetCustomAttribute (typeof(MyDerivedClass), typeof(MyCustomAttribute)))).Info, "#3");
164                                 i++;
165                                 Assert.IsNotNull (Attribute.GetCustomAttribute (t, typeof(YourCustomAttribute)), "#4");
166                                 i++;
167                                 Assert.AreEqual (37, ((YourCustomAttribute) (Attribute.GetCustomAttribute (t, typeof(YourCustomAttribute)))).Value, "#5");
168                         } catch (Exception e) {
169                                 Assert.Fail ("Unexpected exception thrown at i=" + i + " with t=" + t + ". e=" + e);
170                         }
171                 }
172
173                 [Test]
174                 public void GetCustomAttribute_PropertyInfo ()
175                 {
176                         PropertyInfo pi = typeof (TestBase).GetProperty ("PropBase3");
177                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
178                                 typeof (PropTestAttribute)), "#A1");
179                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
180                                 typeof (PropTestAttribute), false), "#A2");
181                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
182                                 typeof (PropTestAttribute), true), "#A3");
183                         Assert.IsNull (Attribute.GetCustomAttribute (pi,
184                                 typeof (ComVisibleAttribute)), "#A4");
185                         Assert.IsNull (Attribute.GetCustomAttribute (pi,
186                                 typeof (ComVisibleAttribute), false), "#A5");
187                         Assert.IsNull (Attribute.GetCustomAttribute (pi,
188                                 typeof (ComVisibleAttribute), true), "#A6");
189
190                         pi = typeof (TestBase).GetProperty ("PropBase2");
191                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
192                                 typeof (PropTestAttribute)), "#C1");
193                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
194                                 typeof (PropTestAttribute), false), "#C2");
195                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
196                                 typeof (PropTestAttribute), true), "#C3");
197                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
198                                 typeof (ComVisibleAttribute)), "#C4");
199                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
200                                 typeof (ComVisibleAttribute), false), "#C5");
201                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
202                                 typeof (ComVisibleAttribute), true), "#C6");
203
204                         pi = typeof (TestSub).GetProperty ("PropBase2");
205                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
206                                 typeof (PropTestAttribute)), "#D1");
207                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
208                                 typeof (PropTestAttribute), false), "#D2");
209                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
210                                 typeof (PropTestAttribute), true), "#D3");
211                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
212                                 typeof (ComVisibleAttribute)), "#D4");
213                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
214                                 typeof (ComVisibleAttribute), false), "#D5");
215                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
216                                 typeof (ComVisibleAttribute), true), "#D6");
217                 }
218
219                 [Test]
220                 public void GetCustomAttribute_PropertyInfo_Override ()
221                 {
222                         PropertyInfo pi = typeof (TestSub).GetProperty ("PropBase3");
223                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
224                                 typeof (PropTestAttribute)), "#B1");
225                         Assert.IsNull (Attribute.GetCustomAttribute (pi,
226                                 typeof (PropTestAttribute), false), "#B2");
227                         Assert.IsNotNull (Attribute.GetCustomAttribute (pi,
228                                 typeof (PropTestAttribute), true), "#B3");
229                         Assert.IsNull (Attribute.GetCustomAttribute (pi,
230                                 typeof (ComVisibleAttribute)), "#B4");
231                         Assert.IsNull (Attribute.GetCustomAttribute (pi,
232                                 typeof (ComVisibleAttribute), false), "#B5");
233                         Assert.IsNull (Attribute.GetCustomAttribute (pi,
234                                 typeof (ComVisibleAttribute), true), "#B6");
235                 }
236
237                 /* Test for bug 54518 */
238                 [AttributeUsage (AttributeTargets.Field | AttributeTargets.Property)]
239                 public class PropTestAttribute : Attribute
240                 {
241                         public PropTestAttribute ()
242                         {
243                         }
244                 }
245
246                 public class TestBase
247                 {
248                         [PropTest]
249                         public int PropBase1 {
250                                 get { return 0; }
251                                 set { }
252                         }
253
254                         [PropTest]
255                         [ComVisible (false)]
256                         public string PropBase2 {
257                                 get { return ""; }
258                                 set { }
259                         }
260
261                         [PropTest]
262                         public virtual string PropBase3 {
263                                 get { return ""; }
264                                 set { }
265                         }
266                 }
267
268                 public class TestSub : TestBase
269                 {
270                         [PropTest]
271                         public int PropSub1 {
272                                 get { return 0; }
273                                 set { }
274                         }
275
276                         [PropTest]
277                         public string PropSub2 {
278                                 get { return ""; }
279                                 set { }
280                         }
281
282                         public override string PropBase3 {
283                                 get { return ""; }
284                                 set { }
285                         }
286                 }
287
288                 [Test]
289                 public void GetCustomAttributes_Element_Null ()
290                 {
291                         // 
292                         // Assembly
293                         // 
294
295                         try {
296                                 Attribute.GetCustomAttributes ((Assembly) null);
297                                 Assert.Fail ("#A1");
298                         } catch (ArgumentNullException ex) {
299                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
300                                 Assert.IsNull (ex.InnerException, "#A3");
301                                 Assert.IsNotNull (ex.Message, "#A4");
302                                 Assert.IsNotNull (ex.ParamName, "#A5");
303                                 Assert.AreEqual ("element", ex.ParamName, "#A6");
304                         }
305
306                         try {
307                                 Attribute.GetCustomAttributes ((Assembly) null, false);
308                                 Assert.Fail ("#B1");
309                         } catch (ArgumentNullException ex) {
310                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
311                                 Assert.IsNull (ex.InnerException, "#B3");
312                                 Assert.IsNotNull (ex.Message, "#B4");
313                                 Assert.IsNotNull (ex.ParamName, "#B5");
314                                 Assert.AreEqual ("element", ex.ParamName, "#B6");
315                         }
316
317                         try {
318                                 Attribute.GetCustomAttributes ((Assembly) null, typeof (PropTestAttribute));
319                                 Assert.Fail ("#C1");
320                         } catch (ArgumentNullException ex) {
321                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
322                                 Assert.IsNull (ex.InnerException, "#C3");
323                                 Assert.IsNotNull (ex.Message, "#C4");
324                                 Assert.IsNotNull (ex.ParamName, "#C5");
325                                 Assert.AreEqual ("element", ex.ParamName, "#C6");
326                         }
327
328                         try {
329                                 Attribute.GetCustomAttributes ((Assembly) null, typeof (PropTestAttribute), false);
330                                 Assert.Fail ("#D1");
331                         } catch (ArgumentNullException ex) {
332                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#D2");
333                                 Assert.IsNull (ex.InnerException, "#D3");
334                                 Assert.IsNotNull (ex.Message, "#D4");
335                                 Assert.IsNotNull (ex.ParamName, "#D5");
336                                 Assert.AreEqual ("element", ex.ParamName, "#D6");
337                         }
338
339                         // 
340                         // MemberInfo
341                         // 
342
343                         try {
344                                 Attribute.GetCustomAttributes ((MemberInfo) null);
345                                 Assert.Fail ("#A1");
346                         } catch (ArgumentNullException ex) {
347                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
348                                 Assert.IsNull (ex.InnerException, "#A3");
349                                 Assert.IsNotNull (ex.Message, "#A4");
350                                 Assert.IsNotNull (ex.ParamName, "#A5");
351                                 Assert.AreEqual ("element", ex.ParamName, "#A6");
352                         }
353
354                         try {
355                                 Attribute.GetCustomAttributes ((MemberInfo) null, false);
356                                 Assert.Fail ("#B1");
357                         } catch (ArgumentNullException ex) {
358                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
359                                 Assert.IsNull (ex.InnerException, "#B3");
360                                 Assert.IsNotNull (ex.Message, "#B4");
361                                 Assert.IsNotNull (ex.ParamName, "#B5");
362                                 Assert.AreEqual ("element", ex.ParamName, "#B6");
363                         }
364
365                         try {
366                                 Attribute.GetCustomAttributes ((MemberInfo) null, typeof (PropTestAttribute));
367                                 Assert.Fail ("#C1");
368                         } catch (ArgumentNullException ex) {
369                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
370                                 Assert.IsNull (ex.InnerException, "#C3");
371                                 Assert.IsNotNull (ex.Message, "#C4");
372                                 Assert.IsNotNull (ex.ParamName, "#C5");
373                                 Assert.AreEqual ("element", ex.ParamName, "#C6");
374                         }
375
376                         try {
377                                 Attribute.GetCustomAttributes ((MemberInfo) null, typeof (PropTestAttribute), false);
378                                 Assert.Fail ("#D1");
379                         } catch (ArgumentNullException ex) {
380                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#D2");
381                                 Assert.IsNull (ex.InnerException, "#D3");
382                                 Assert.IsNotNull (ex.Message, "#D4");
383                                 Assert.IsNotNull (ex.ParamName, "#D5");
384                                 Assert.AreEqual ("element", ex.ParamName, "#D6");
385                         }
386
387                         // 
388                         // Module
389                         // 
390
391                         try {
392                                 Attribute.GetCustomAttributes ((Module) null);
393                                 Assert.Fail ("#A1");
394                         } catch (ArgumentNullException ex) {
395                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
396                                 Assert.IsNull (ex.InnerException, "#A3");
397                                 Assert.IsNotNull (ex.Message, "#A4");
398                                 Assert.IsNotNull (ex.ParamName, "#A5");
399                                 Assert.AreEqual ("element", ex.ParamName, "#A6");
400                         }
401
402                         try {
403                                 Attribute.GetCustomAttributes ((Module) null, false);
404                                 Assert.Fail ("#B1");
405                         } catch (ArgumentNullException ex) {
406                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
407                                 Assert.IsNull (ex.InnerException, "#B3");
408                                 Assert.IsNotNull (ex.Message, "#B4");
409                                 Assert.IsNotNull (ex.ParamName, "#B5");
410                                 Assert.AreEqual ("element", ex.ParamName, "#B6");
411                         }
412
413                         try {
414                                 Attribute.GetCustomAttributes ((Module) null, typeof (PropTestAttribute));
415                                 Assert.Fail ("#C1");
416                         } catch (ArgumentNullException ex) {
417                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
418                                 Assert.IsNull (ex.InnerException, "#C3");
419                                 Assert.IsNotNull (ex.Message, "#C4");
420                                 Assert.IsNotNull (ex.ParamName, "#C5");
421                                 Assert.AreEqual ("element", ex.ParamName, "#C6");
422                         }
423
424                         try {
425                                 Attribute.GetCustomAttributes ((Module) null, typeof (PropTestAttribute), false);
426                                 Assert.Fail ("#D1");
427                         } catch (ArgumentNullException ex) {
428                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#D2");
429                                 Assert.IsNull (ex.InnerException, "#D3");
430                                 Assert.IsNotNull (ex.Message, "#D4");
431                                 Assert.IsNotNull (ex.ParamName, "#D5");
432                                 Assert.AreEqual ("element", ex.ParamName, "#D6");
433                         }
434
435                         // 
436                         // ParameterInfo
437                         // 
438
439                         try {
440                                 Attribute.GetCustomAttributes ((ParameterInfo) null);
441                                 Assert.Fail ("#A1");
442                         } catch (ArgumentNullException ex) {
443                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
444                                 Assert.IsNull (ex.InnerException, "#A3");
445                                 Assert.IsNotNull (ex.Message, "#A4");
446                                 Assert.IsNotNull (ex.ParamName, "#A5");
447                                 Assert.AreEqual ("element", ex.ParamName, "#A6");
448                         }
449
450                         try {
451                                 Attribute.GetCustomAttributes ((ParameterInfo) null, false);
452                                 Assert.Fail ("#B1");
453                         } catch (ArgumentNullException ex) {
454                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
455                                 Assert.IsNull (ex.InnerException, "#B3");
456                                 Assert.IsNotNull (ex.Message, "#B4");
457                                 Assert.IsNotNull (ex.ParamName, "#B5");
458                                 Assert.AreEqual ("element", ex.ParamName, "#B6");
459                         }
460
461                         try {
462                                 Attribute.GetCustomAttributes ((ParameterInfo) null, typeof (PropTestAttribute));
463                                 Assert.Fail ("#C1");
464                         } catch (ArgumentNullException ex) {
465                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
466                                 Assert.IsNull (ex.InnerException, "#C3");
467                                 Assert.IsNotNull (ex.Message, "#C4");
468                                 Assert.IsNotNull (ex.ParamName, "#C5");
469                                 Assert.AreEqual ("element", ex.ParamName, "#C6");
470                         }
471
472                         try {
473                                 Attribute.GetCustomAttributes ((ParameterInfo) null, typeof (PropTestAttribute), false);
474                                 Assert.Fail ("#D1");
475                         } catch (ArgumentNullException ex) {
476                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#D2");
477                                 Assert.IsNull (ex.InnerException, "#D3");
478                                 Assert.IsNotNull (ex.Message, "#D4");
479                                 Assert.IsNotNull (ex.ParamName, "#D5");
480                                 Assert.AreEqual ("element", ex.ParamName, "#D6");
481                         }
482                 }
483
484                 [Test]
485                 public void GetCustomAttributes_PropertyInfo ()
486                 {
487                         object[] attrs;
488                         PropertyInfo pi;
489
490                         pi = typeof (TestBase).GetProperty ("PropBase3");
491                         attrs = Attribute.GetCustomAttributes (pi);
492                         Assert.AreEqual (1, attrs.Length, "#A1");
493                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#A2");
494                         attrs = Attribute.GetCustomAttributes (pi, false);
495                         Assert.AreEqual (1, attrs.Length, "#A3");
496                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#A4");
497                         attrs = Attribute.GetCustomAttributes (pi, true);
498                         Assert.AreEqual (1, attrs.Length, "#A5");
499                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#A6");
500                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute));
501                         Assert.AreEqual (1, attrs.Length, "#A7");
502                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#A8");
503                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), false);
504                         Assert.AreEqual (1, attrs.Length, "#A9");
505                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#A10");
506                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), true);
507                         Assert.AreEqual (1, attrs.Length, "#A11");
508                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#A12");
509                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute));
510                         Assert.AreEqual (0, attrs.Length, "#A13");
511                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), false);
512                         Assert.AreEqual (0, attrs.Length, "#A14");
513                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), true);
514                         Assert.AreEqual (0, attrs.Length, "#A15");
515
516                         pi = typeof (TestBase).GetProperty ("PropBase2");
517                         attrs = Attribute.GetCustomAttributes (pi);
518                         Assert.AreEqual (2, attrs.Length, "#C1");
519                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (PropTestAttribute)), "#C2");
520                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (ComVisibleAttribute)), "#C3");
521                         attrs = Attribute.GetCustomAttributes (pi, false);
522                         Assert.AreEqual (2, attrs.Length, "#C4");
523                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (PropTestAttribute)), "#C5");
524                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (ComVisibleAttribute)), "#C6");
525                         attrs = Attribute.GetCustomAttributes (pi, true);
526                         Assert.AreEqual (2, attrs.Length, "#C7");
527                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (PropTestAttribute)), "#C8");
528                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (ComVisibleAttribute)), "#C9");
529                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute));
530                         Assert.AreEqual (1, attrs.Length, "#C10");
531                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#C11");
532                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), false);
533                         Assert.AreEqual (1, attrs.Length, "#C12");
534                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#C13");
535                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), true);
536                         Assert.AreEqual (1, attrs.Length, "#C14");
537                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#C15");
538                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute));
539                         Assert.AreEqual (1, attrs.Length, "#C16");
540                         Assert.AreEqual (typeof (ComVisibleAttribute), attrs [0].GetType (), "#C17");
541                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), false);
542                         Assert.AreEqual (1, attrs.Length, "#C18");
543                         Assert.AreEqual (typeof (ComVisibleAttribute), attrs [0].GetType (), "#C19");
544                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), true);
545                         Assert.AreEqual (1, attrs.Length, "#C20");
546                         Assert.AreEqual (typeof (ComVisibleAttribute), attrs [0].GetType (), "#C21");
547
548                         pi = typeof (TestSub).GetProperty ("PropBase2");
549                         attrs = Attribute.GetCustomAttributes (pi);
550                         Assert.AreEqual (2, attrs.Length, "#D1");
551                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (PropTestAttribute)), "#D2");
552                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (ComVisibleAttribute)), "#D3");
553                         attrs = Attribute.GetCustomAttributes (pi, false);
554                         Assert.AreEqual (2, attrs.Length, "#D4");
555                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (PropTestAttribute)), "#D5");
556                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (ComVisibleAttribute)), "#D6");
557                         attrs = Attribute.GetCustomAttributes (pi, true);
558                         Assert.AreEqual (2, attrs.Length, "#D7");
559                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (PropTestAttribute)), "#D8");
560                         Assert.AreEqual (1, GetAttributeCount (attrs, typeof (ComVisibleAttribute)), "#D9");
561                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute));
562                         Assert.AreEqual (1, attrs.Length, "#D10");
563                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#D11");
564                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), false);
565                         Assert.AreEqual (1, attrs.Length, "#D12");
566                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#D13");
567                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), true);
568                         Assert.AreEqual (1, attrs.Length, "#D14");
569                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#D15");
570                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute));
571                         Assert.AreEqual (1, attrs.Length, "#D16");
572                         Assert.AreEqual (typeof (ComVisibleAttribute), attrs [0].GetType (), "#D17");
573                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), false);
574                         Assert.AreEqual (1, attrs.Length, "#D18");
575                         Assert.AreEqual (typeof (ComVisibleAttribute), attrs [0].GetType (), "#D19");
576                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), true);
577                         Assert.AreEqual (1, attrs.Length, "#D20");
578                         Assert.AreEqual (typeof (ComVisibleAttribute), attrs [0].GetType (), "#D21");
579
580                         pi = typeof (TestSub).GetProperty ("PropSub1");
581                         attrs = Attribute.GetCustomAttributes (pi);
582                         Assert.AreEqual (1, attrs.Length, "#E1");
583                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#E2");
584                         attrs = Attribute.GetCustomAttributes (pi, false);
585                         Assert.AreEqual (1, attrs.Length, "#E3");
586                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#E4");
587                         attrs = Attribute.GetCustomAttributes (pi, true);
588                         Assert.AreEqual (1, attrs.Length, "#E5");
589                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#E6");
590                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute));
591                         Assert.AreEqual (1, attrs.Length, "#E7");
592                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#E8");
593                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), false);
594                         Assert.AreEqual (1, attrs.Length, "#E9");
595                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#E10");
596                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), true);
597                         Assert.AreEqual (1, attrs.Length, "#E11");
598                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#E12");
599                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute));
600                         Assert.AreEqual (0, attrs.Length, "#E13");
601                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), false);
602                         Assert.AreEqual (0, attrs.Length, "#E14");
603                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), true);
604                         Assert.AreEqual (0, attrs.Length, "#D15");
605                 }
606
607                 [Test]
608                 public void GetCustomAttributes_PropertyInfo_Override ()
609                 {
610                         object [] attrs;
611                         PropertyInfo pi;
612
613                         pi = typeof (TestSub).GetProperty ("PropBase3");
614                         attrs = Attribute.GetCustomAttributes (pi);
615                         Assert.AreEqual (1, attrs.Length, "#B1");
616                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#B2");
617                         attrs = Attribute.GetCustomAttributes (pi, false);
618                         Assert.AreEqual (0, attrs.Length, "#B3");
619                         attrs = Attribute.GetCustomAttributes (pi, true);
620                         Assert.AreEqual (1, attrs.Length, "#B4");
621                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#B5");
622                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute));
623                         Assert.AreEqual (1, attrs.Length, "#B6");
624                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#B7");
625                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), false);
626                         Assert.AreEqual (0, attrs.Length, "#B8");
627                         attrs = Attribute.GetCustomAttributes (pi, typeof (PropTestAttribute), true);
628                         Assert.AreEqual (1, attrs.Length, "#B9");
629                         Assert.AreEqual (typeof (PropTestAttribute), attrs [0].GetType (), "#B10");
630                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute));
631                         Assert.AreEqual (0, attrs.Length, "#B11");
632                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), false);
633                         Assert.AreEqual (0, attrs.Length, "#B12");
634                         attrs = Attribute.GetCustomAttributes (pi, typeof (ComVisibleAttribute), true);
635                         Assert.AreEqual (0, attrs.Length, "#B13");
636                 }
637
638                 [Test]
639                 public void GetCustomAttributeOK ()
640                 {
641                         Attribute attribute = Attribute.GetCustomAttribute (typeof(ClassA),
642                                 typeof(DerivedTestCustomAttributeInherit));
643                         Assert.IsNotNull (attribute);
644                 }
645
646                 [Test]
647                 [ExpectedException (typeof(AmbiguousMatchException))]
648                 public void GetCustomAttributeAmbiguous ()
649                 {
650                         Attribute.GetCustomAttribute (typeof(ClassA), typeof(TestCustomAttribute));
651                 }
652
653                 [Test]
654                 public void GetCustomAttributeNull ()
655                 {
656                         Attribute attribute = Attribute.GetCustomAttribute (typeof(ClassA),
657                                 typeof(DerivedTestCustomAttributeMultipleInherit));
658                         Assert.IsNull (attribute);
659                 }
660
661                 [Test]
662                 public void GetCustomAttributesTypeNoInherit ()
663                 {
664                         object[] attributes;
665
666                         attributes = Attribute.GetCustomAttributes (typeof(ClassA), false);
667                         Assert.AreEqual (3, attributes.Length, "#A1");
668                         Assert.AreEqual (1, GetAttributeCount (attributes,
669                                 typeof(TestCustomAttribute)), "#A2");
670                         Assert.AreEqual (1, GetAttributeCount (attributes,
671                                 typeof(DerivedTestCustomAttributeMultiple)), "#A3");
672                         Assert.AreEqual (1, GetAttributeCount (attributes,
673                                 typeof(DerivedTestCustomAttributeInherit)), "#A4");
674
675                         attributes = Attribute.GetCustomAttributes (typeof(ClassB), false);
676                         Assert.AreEqual (4, attributes.Length, "#B1");
677                         Assert.AreEqual (1, GetAttributeCount (attributes,
678                                 typeof(TestCustomAttribute)), "#B2");
679                         Assert.AreEqual (2, GetAttributeCount (attributes,
680                                 typeof(DerivedTestCustomAttributeMultiple)), "#B3");
681                         Assert.AreEqual (1, GetAttributeCount (attributes,
682                                 typeof(DerivedTestCustomAttributeMultipleInherit)), "#B4");
683                 }
684
685                 [Test]
686                 public void GetCustomAttributesTypeInherit ()
687                 {
688                         object[] attributes;
689
690                         attributes = Attribute.GetCustomAttributes (typeof(ClassA), true);
691                         Assert.AreEqual (3, attributes.Length, "#A1");
692                         Assert.AreEqual (1, GetAttributeCount (attributes,
693                                 typeof(TestCustomAttribute)), "#A2");
694                         Assert.AreEqual (1, GetAttributeCount (attributes,
695                                 typeof(DerivedTestCustomAttributeMultiple)), "#A3");
696                         Assert.AreEqual (1, GetAttributeCount (attributes,
697                                 typeof(DerivedTestCustomAttributeInherit)), "#A4");
698
699                         attributes = Attribute.GetCustomAttributes (typeof(ClassB), true);
700                         Assert.AreEqual (5, attributes.Length, "#B1");
701                         Assert.AreEqual (1, GetAttributeCount (attributes,
702                                 typeof(TestCustomAttribute)), "#B2");
703                         Assert.AreEqual (2, GetAttributeCount (attributes,
704                                 typeof(DerivedTestCustomAttributeMultiple)), "#B3");
705                         Assert.AreEqual (1, GetAttributeCount (attributes,
706                                 typeof(DerivedTestCustomAttributeInherit)), "#B4");
707                         Assert.AreEqual (1, GetAttributeCount (attributes,
708                                 typeof(DerivedTestCustomAttributeMultipleInherit)), "#B5");
709                 }
710
711                 [Test]
712                 public void TestEquality ()
713                 {
714                         MyCustomAttribute a = new MyCustomAttribute ("one");
715                         MyCustomAttribute b = new MyCustomAttribute ("two");
716                         MyCustomAttribute c = new MyCustomAttribute ("one");
717                         MyCustomAttribute d = a;
718                         
719                         Assert.IsTrue (a.Equals (c), "#1");
720                         Assert.IsTrue (c.Equals (a), "#2");
721                         Assert.IsFalse (c.Equals (b), "#3");
722                         Assert.IsFalse (b.Equals (a), "#4");
723                         Assert.IsFalse (b.Equals (c), "#5");
724                         Assert.IsTrue (a.Equals (a), "#6");
725                         Assert.IsTrue (a.Equals (d), "#7");
726                         Assert.IsFalse (a.Equals (null), "#8");
727                 }
728
729                 class UserType : TypeDelegator {
730                         public int GetCattr1;
731                         public int GetCattr2;
732                         public int IsDef;
733                         public bool lastInherit;
734                         public Type lastAttrType;
735
736                         public UserType (Type type) : base (type) {}
737                         
738                         public override object [] GetCustomAttributes (bool inherit)
739                         {
740                                 ++GetCattr1;
741                                 lastInherit = inherit;
742                                 lastAttrType = null;
743                                 return base.GetCustomAttributes (inherit);
744                         }
745
746                         public override object [] GetCustomAttributes (Type attributeType, bool inherit)
747                         {
748                                 ++GetCattr2;
749                                 lastInherit = inherit;
750                                 lastAttrType = attributeType;
751                                 return base.GetCustomAttributes (attributeType, inherit);
752                         }
753
754                         public override bool IsDefined (Type attributeType, bool inherit)
755                         {
756                                 ++IsDef;
757                                 lastInherit = inherit;
758                                 lastAttrType = attributeType;
759                                 return base.IsDefined (attributeType, inherit);
760                         }
761                 }
762
763                 [Test]
764                 public void GetCustomAttributeOnUserType ()
765                 {
766                         UserType type = new UserType (typeof (AttributeTest));
767                         var res = Attribute.GetCustomAttribute (type, typeof (TestFixtureAttribute));
768                         Assert.IsNotNull (res, "#1");
769                         Assert.AreEqual (typeof (TestFixtureAttribute), res.GetType (), "#2");
770
771                         Assert.AreEqual (0, type.IsDef, "#4");
772                         Assert.AreEqual (0, type.GetCattr1, "#5");
773                         Assert.AreEqual (1, type.GetCattr2, "#6");
774                         Assert.IsTrue (type.lastInherit, "#7");
775                         Assert.AreEqual (typeof (TestFixtureAttribute), type.lastAttrType, "#8");
776                 }
777
778                 [Test]
779                 public void GetCustomAttributeOnMethodInfo ()
780                 {
781                         MemberInfo method = typeof (AttributeTest).GetMethod ("GetCustomAttributeOnMethodInfo");
782                         var res = Attribute.GetCustomAttribute (method, typeof (TestAttribute));
783
784                         Assert.IsNotNull (res, "#1");
785                         Assert.AreEqual (typeof (TestAttribute), res.GetType (), "#2");
786                 }
787
788                 [Test]
789                 public void GetCustomAttributesOnUserType ()
790                 {
791                         UserType type = new UserType (typeof (AttributeTest));
792                         var res = Attribute.GetCustomAttributes (type);
793                         Assert.IsNotNull (res, "#1");
794                         Assert.AreEqual (1, res.Length, "#2");
795                         Assert.AreEqual (typeof (TestFixtureAttribute), res [0].GetType (), "#3");
796
797                         Assert.AreEqual (0, type.IsDef, "#4");
798                         Assert.AreEqual (0, type.GetCattr1, "#5");
799                         Assert.AreEqual (1, type.GetCattr2, "#6");
800                         Assert.IsTrue (type.lastInherit, "#7");
801                         Assert.AreEqual (typeof (Attribute), type.lastAttrType, "#8");
802                 }
803
804                 [Test]
805                 public void IsDefinedOnUserType ()
806                 {
807                         UserType type = new UserType (typeof (AttributeTest));
808                         var res = Attribute.IsDefined (type, typeof (TestFixtureAttribute));
809                         Assert.IsTrue (res, "#1");
810
811                         Assert.AreEqual (1, type.IsDef, "#4");
812                         Assert.AreEqual (0, type.GetCattr1, "#5");
813                         Assert.AreEqual (0, type.GetCattr2, "#6");
814                         Assert.IsTrue (type.lastInherit, "#7");
815                         Assert.AreEqual (typeof (TestFixtureAttribute), type.lastAttrType, "#8");
816                 }
817
818                 [Test]
819                 public void GetCustomAttributeOnNewSreTypes ()
820                 {
821                         AssemblyName assemblyName = new AssemblyName ();
822                         assemblyName.Name = "MonoTests.System.Reflection.Emit.TypeBuilderTest";
823                         AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
824                                         assemblyName, AssemblyBuilderAccess.Run);
825                         ModuleBuilder module = assembly.DefineDynamicModule ("module1");
826
827                         var tb = module.DefineType ("ns.type", TypeAttributes.Public);
828                         var arr = tb.MakeArrayType ();
829                         var ptr = tb.MakePointerType ();
830                         var byref = tb.MakeByRefType ();
831
832                         try {
833                                 Attribute.GetCustomAttribute (arr, typeof (ObsoleteAttribute));
834                                 Assert.Fail ("#1");
835                         } catch (NotSupportedException) {}
836
837                         try {
838                                 Attribute.GetCustomAttribute (ptr, typeof (ObsoleteAttribute));
839                                 Assert.Fail ("#2");
840                         } catch (NotSupportedException) {}
841
842                         try {
843                                 Attribute.GetCustomAttribute (byref, typeof (ObsoleteAttribute));
844                                 Assert.Fail ("#3");
845                         } catch (NotSupportedException) {}
846                 }
847
848                 [Test]
849                 public void GetCustomAttributeOnBadSreTypes ()
850                 {
851                         AssemblyName assemblyName = new AssemblyName ();
852                         assemblyName.Name = "MonoTests.System.Reflection.Emit.TypeBuilderTest";
853                         AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
854                                         assemblyName, AssemblyBuilderAccess.Run);
855                         ModuleBuilder module = assembly.DefineDynamicModule ("module1");
856
857                         var tb = module.DefineType ("ns.type", TypeAttributes.Public);
858                         tb.DefineGenericParameters ("T");
859                         var ginst = tb.MakeGenericType (typeof (int));
860                         try {
861                                 Attribute.GetCustomAttribute (ginst, typeof (ObsoleteAttribute));
862                                 Assert.Fail ("#1");
863                         } catch (NotSupportedException) {}
864                 }
865
866                 [Test] //Regression test for #499569
867                 public void GetCattrOnPropertyAndInheritance ()
868                 {
869                         var m = typeof(Sub).GetProperty ("Name");
870                         var res = Attribute.GetCustomAttributes (m, typeof(MyAttribute), true);
871                         Assert.AreEqual (1, res.Length, "#1");
872                 }
873
874                 abstract class Abs
875                 {
876                         public abstract string Name { get; set; }
877                 }
878                 
879                 class Base: Abs
880                 {
881                         [MyAttribute]
882                         public override string Name {
883                                 get { return ""; }
884                                 set {}
885                         }
886                 }
887                 
888                 class Sub: Base
889                 {
890                         public override string Name {
891                                 get { return ""; }
892                                 set {}
893                         }
894                 }
895                 
896                 class MySubAttribute: MyAttribute
897                 {
898                 }
899                 
900                 class MyAttribute: Attribute
901                 {
902                 }
903
904                 private int GetAttributeCount (object[] attributes, Type attributeType)
905                 {
906                         int counter = 0;
907
908                         foreach (Attribute attribute in attributes) {
909                                 if (attribute.GetType () == attributeType)
910                                         counter++;
911                         }
912
913                         return counter;
914                 }
915
916                 [AttributeUsage (AttributeTargets.All, AllowMultiple = false, Inherited = true)]
917                 private class TestCustomAttribute : Attribute
918                 {
919                 }
920
921                 [AttributeUsage (AttributeTargets.All, AllowMultiple = true, Inherited = false)]
922                 private class DerivedTestCustomAttributeMultiple : TestCustomAttribute
923                 {
924                 }
925
926                 [AttributeUsage (AttributeTargets.All, AllowMultiple = false, Inherited = true)]
927                 private class DerivedTestCustomAttributeInherit : TestCustomAttribute
928                 {
929                 }
930
931                 [AttributeUsage (AttributeTargets.All, AllowMultiple = true, Inherited = true)]
932                 private class DerivedTestCustomAttributeMultipleInherit : TestCustomAttribute
933                 {
934                 }
935
936                 [TestCustomAttribute]
937                 [DerivedTestCustomAttributeMultiple]
938                 [DerivedTestCustomAttributeInherit]
939                 private class ClassA
940                 {
941                 }
942
943                 [TestCustomAttribute ()]
944                 [DerivedTestCustomAttributeMultiple ()]
945                 [DerivedTestCustomAttributeMultiple ()]
946                 [DerivedTestCustomAttributeMultipleInherit ()]
947                 private class ClassB : ClassA
948                 {
949                 }
950
951                 [TestCustomAttribute ()]
952                 [DerivedTestCustomAttributeMultiple ()]
953                 [DerivedTestCustomAttributeMultipleInherit ()]
954                 private class ClassC : ClassB
955                 {
956                 }
957
958                 [Test]
959                 public void EmptyNonOverridenGetHashCode ()
960                 {
961                         MyAttribute a1 = new MyAttribute ();
962                         MyAttribute a2 = new MyAttribute ();
963                         Assert.AreEqual (a1.GetHashCode (), a2.GetHashCode (), "identical argument-less");
964                         Assert.AreEqual (a1.GetHashCode (), a1.TypeId.GetHashCode (), "Empty/TypeId");
965
966                         MySubAttribute b1 = new MySubAttribute ();
967                         Assert.AreNotEqual (a1.GetHashCode (), b1.GetHashCode (), "non-identical-types");
968                         Assert.AreEqual (b1.GetHashCode (), b1.TypeId.GetHashCode (), "Empty/TypeId/Sub");
969                 }
970
971                 class MyOwnCustomAttribute : MyCustomAttribute {
972
973                         public MyOwnCustomAttribute (string s)
974                                 : base (s)
975                         {
976                         }
977                 }
978
979                 [Test]
980                 public void NonEmptyNonOverridenGetHashCode ()
981                 {
982                         MyCustomAttribute a1 = new MyCustomAttribute (null);
983                         MyCustomAttribute a2 = new MyCustomAttribute (null);
984                         Assert.AreEqual (a1.GetHashCode (), a2.GetHashCode (), "identical arguments");
985                         Assert.AreEqual (a1.GetHashCode (), a1.TypeId.GetHashCode (), "TypeId");
986
987                         MyCustomAttribute a3 = new MyCustomAttribute ("a");
988                         MyCustomAttribute a4 = new MyCustomAttribute ("b");
989                         Assert.AreNotEqual (a3.GetHashCode (), a4.GetHashCode (), "non-identical-arguments");
990
991                         MyOwnCustomAttribute b1 = new MyOwnCustomAttribute (null);
992                         Assert.AreNotEqual (a1.GetHashCode (), b1.GetHashCode (), "non-identical-types");
993                 }
994         }
995
996         namespace ParamNamespace {
997
998                 class FooAttribute : Attribute {}
999                 class BarAttribute : Attribute {}
1000
1001                 class DataAttribute : Attribute {
1002
1003                         public string Data { get; set; }
1004
1005                         public DataAttribute (string data)
1006                         {
1007                                 this.Data = data;
1008                         }
1009                 }
1010
1011                 class UltraBase {
1012
1013                         public virtual void Bar ([Foo] string bar, [Data ("UltraBase.baz")] string baz)
1014                         {
1015                         }
1016                 }
1017
1018                 class Base : UltraBase {
1019
1020                         public override void Bar ([Data ("Base.bar")] string bar, string baz)
1021                         {
1022                         }
1023                 }
1024
1025                 class Derived : Base {
1026
1027                         public override void Bar ([Bar] string bar, [Data ("Derived.baz")] string baz)
1028                         {
1029                         }
1030                 }
1031         }
1032
1033         [TestFixture]
1034         public class ParamAttributeTest {
1035
1036                 static ParameterInfo GetParameter (Type type, string method_name, string param_name)
1037                 {
1038                         foreach (var method in type.GetMethods ()) {
1039                                 if (method.Name != method_name)
1040                                         continue;
1041
1042                                 foreach (var parameter in method.GetParameters ())
1043                                         if (parameter.Name == param_name)
1044                                                 return parameter;
1045                         }
1046
1047                         return null;
1048                 }
1049
1050                 [Test]
1051                 public void IsDefinedTopLevel ()
1052                 {
1053                         var parameter = GetParameter (typeof (ParamNamespace.Derived), "Bar", "bar");
1054
1055                         Assert.IsNotNull (parameter);
1056                         Assert.IsTrue (Attribute.IsDefined (parameter, typeof (ParamNamespace.BarAttribute)));
1057                 }
1058
1059                 [Test]
1060                 public void IsDefinedHierarchy ()
1061                 {
1062                         var parameter = GetParameter (typeof (ParamNamespace.Derived), "Bar", "bar");
1063
1064                         Assert.IsNotNull (parameter);
1065                         Assert.IsTrue (Attribute.IsDefined (parameter, typeof (ParamNamespace.FooAttribute)));
1066                 }
1067
1068                 [Test]
1069                 public void IsDefinedHierarchyMultiple ()
1070                 {
1071                         var parameter = GetParameter (typeof (ParamNamespace.Derived), "Bar", "baz");
1072
1073                         Assert.IsNotNull (parameter);
1074                         Assert.IsTrue (Attribute.IsDefined (parameter, typeof (ParamNamespace.DataAttribute)));
1075                 }
1076
1077                 [Test]
1078                 public void GetCustomAttributeTopLevel ()
1079                 {
1080                         var parameter = GetParameter (typeof (ParamNamespace.Derived), "Bar", "bar");
1081
1082                         Assert.IsNotNull (Attribute.GetCustomAttribute (parameter, typeof (ParamNamespace.BarAttribute)));
1083                 }
1084
1085                 [Test]
1086                 public void GetCustomAttributeHierarchy ()
1087                 {
1088                         var parameter = GetParameter (typeof (ParamNamespace.Derived), "Bar", "bar");
1089                         var data = (ParamNamespace.DataAttribute) Attribute.GetCustomAttribute (parameter, typeof (ParamNamespace.DataAttribute));
1090                         Assert.IsNotNull (data);
1091                         Assert.AreEqual ("Base.bar", data.Data);
1092                 }
1093
1094                 [Test]
1095                 public void GetCustomAttributeHierarchyMultiple ()
1096                 {
1097                         var parameter = GetParameter (typeof (ParamNamespace.Derived), "Bar", "baz");
1098                         var data = (ParamNamespace.DataAttribute) Attribute.GetCustomAttribute (parameter, typeof (ParamNamespace.DataAttribute));
1099                         Assert.IsNotNull (data);
1100                         Assert.AreEqual ("Derived.baz", data.Data);
1101                 }
1102
1103                 [Test]
1104                 public void GetAllCustomAttributes ()
1105                 {
1106                         var parameter = GetParameter (typeof (ParamNamespace.Derived), "Bar", "bar");
1107                         var attributes = (Attribute []) Attribute.GetCustomAttributes (parameter, true);
1108                         Assert.AreEqual (3, attributes.Length);
1109                         Assert.AreEqual (typeof (ParamNamespace.BarAttribute), attributes [0].GetType ());
1110                         Assert.AreEqual (typeof (ParamNamespace.DataAttribute), attributes [1].GetType ());
1111                         Assert.AreEqual (typeof (ParamNamespace.FooAttribute), attributes [2].GetType ());
1112                 }
1113
1114                 [Test]
1115                 public void GetDataCustomAttributes ()
1116                 {
1117                         var parameter = GetParameter (typeof (ParamNamespace.Derived), "Bar", "baz");
1118                         var attributes = (ParamNamespace.DataAttribute []) Attribute.GetCustomAttributes (parameter, typeof (ParamNamespace.DataAttribute), true);
1119                         Assert.AreEqual (1, attributes.Length);
1120                         Assert.AreEqual ("Derived.baz", attributes [0].Data);
1121                 }
1122         }
1123 }