Merge pull request #4381 from BrzVlad/feature-generational-hash
[mono.git] / mcs / tests / dtest-007.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5 using Microsoft.CSharp.RuntimeBinder;
6
7 // Dynamic member lookup tests
8
9 delegate void D ();
10 delegate void D2 (decimal d);
11
12 class Class
13 {
14         internal int IntValue = 5;
15         internal string StringStatic = "hi";
16
17         public const decimal Decimal = -0.3m;
18
19         public Class ()
20         {
21         }
22
23         public Class (sbyte extra)
24         {
25                 IntValue = extra;
26         }
27
28         uint s = 77;
29         protected internal uint this[byte i] {
30                 get {
31                         return s * i;
32                 }
33                 set {
34                         s = value;
35                 }
36         }
37
38         byte b = 180;
39         internal byte Prop {
40                 get {
41                         return b;
42                 }
43                 set {
44                         b = value;
45                 }
46         }
47
48         public int FixedValue
49         {
50                 set { }
51                 get { return 823; }
52         }
53
54         internal string Method (string value)
55         {
56                 return value;
57         }
58         
59         public int Method (int a, byte b)
60         {
61                 return a * b;
62         }
63
64         public void MethodInOut (ref int refValue, out string outValue)
65         {
66                 refValue = 3;
67                 outValue = "4";
68         }
69
70         public static void GenericVoid<T> (T i)
71         {
72         }
73
74         public static int StaticMethod (params int[] i)
75         {
76                 return i [0] * i.Length;
77         }
78         
79         public static void ArglistMethod (__arglist)
80         {
81         }
82 }
83
84 class EventClass
85 {
86         internal event Func<int> OutEvent;
87         
88         public int CallEvent ()
89         {
90                 return OutEvent ();
91         }
92 }
93
94 class Tester
95 {
96         static void Assert<T> (T expected, T value, string name)
97         {
98                 if (!EqualityComparer<T>.Default.Equals (expected, value)) {
99                         name += ": ";
100                         throw new ApplicationException (name + expected + " != " + value);
101                 }
102         }
103
104         static void AssertError (Action expected, string name)
105         {
106                 try {
107                         expected ();
108                         throw new ApplicationException (name + ": RuntimeBinderException expected");
109                 } catch (RuntimeBinderException) {
110                         // passed
111                 }
112         }
113         
114         event Func<int> e;
115         int field;
116
117
118 #pragma warning disable 169
119
120         void GetIndexTest ()
121         {
122                 dynamic d = new[] { 5, 8, 2 };
123                 Assert (8, d[1], "#1");
124
125                 d = new int[,] { { 1, 2 }, { 3, 4 } };
126                 Assert (3, d[1, 0], "#2");
127
128                 dynamic d2 = new Class ();
129                 Assert<uint> (154, d2[2], "#3");
130                 Assert<uint> (154, d2[i:2], "#3a");
131         }
132
133         void GetIndexError_Null ()
134         {
135                 dynamic d = null;
136                 AssertError (() => { var v = d[1]; }, "#1");
137         }
138
139         void InvokeTest ()
140         {
141                 Func<string, string> f = new Class().Method;
142                 dynamic d = f;
143                 Assert ("bar", d ("bar"), "#1");
144
145                 Action<bool> f2 = Class.GenericVoid;
146                 d = f2;
147                 d (true);
148                 
149                 Func<string, int> f3 = (s) => 3;
150                 d = f3;
151                 d ("go");
152         }
153
154         void InvokeMember ()
155         {
156                 dynamic d = new Class ();
157                 Assert ("vv", d.Method ("vv"), "#1");
158                 
159                 byte b = 2;
160                 Assert (6, d.Method (b: b++, a: b), "#1a");
161
162                 var arg1 = 1;
163                 var arg2 = "a";
164                 d.MethodInOut (ref arg1, out arg2);
165
166                 d = 2;
167                 Assert (2, Class.StaticMethod (d), "#2");
168                 Class.StaticMethod (d); 
169         }
170         
171         void InvokeMember_Error ()
172         {
173                 AssertError (() => {
174                                 dynamic d_arg = "a";
175                                 Class.ArglistMethod (d_arg);
176                         }, "#1");
177         }
178
179         void InvokeConstructor ()
180         {
181                 dynamic d = (sbyte) 8;
182                 var r = new Class (d);
183                 Assert (8, r.IntValue, "#1");
184
185                 D2 method = (decimal e) => { };
186                 d = method;
187                 var r2 = new D2 (d);
188         }
189
190         void IsEvent ()
191         {
192                 dynamic d = this;
193                 d.e += new Func<int> (() => 3);
194                 Assert (3, d.e (), "#1");
195                 
196                 d.field += 5;
197                 Assert (5, d.field, "#2");
198                 
199                 int r = d.field += 7;
200                 Assert (12, r, "#2a");
201                 Assert (12, d.field, "#2b");
202                 
203                 d = new EventClass ();
204                 d.OutEvent += new Func<int> (() => 100);
205                 Assert (100, d.CallEvent (), "#3");
206         }
207
208         void MemberGetTest ()
209         {
210                 dynamic d = new Class ();
211                 Assert (5, d.IntValue, "#1");
212                 Assert (180, d.Prop, "#1a");
213
214                 Assert ("hi", d.StringStatic, "#2");
215
216                 d = new int[4];
217                 Assert (4, d.Length, "#3");
218         }
219
220         void MemberGetError_Null ()
221         {
222                 dynamic d = null;
223                 AssertError (() => { var v = d.Foo; }, "#1");
224         }
225
226         void MemberSetTest ()
227         {
228                 dynamic d = new Class ();
229
230                 d.IntValue = 22;
231                 Assert (22, d.IntValue, "#1");
232                 d.Prop = 19;
233                 Assert (19, d.Prop, "#1a");
234
235                 d.Prop = byte.MaxValue;
236                 Assert (byte.MaxValue, d.Prop++, "#1b");
237                 Assert (1, ++d.Prop, "#1c");
238                 d.Prop++;
239                 Assert (2, d.Prop, "#1d");
240                 
241                 d.Prop += 5;
242                 Assert (7, d.Prop, "#1e");
243
244                 d.StringStatic = "no";
245                 Assert ("no", d.StringStatic, "#2");
246
247                 var r = d.FixedValue = 44;
248                 Assert (44, r, "#3");
249         }
250
251         void MemberSetError_Null ()
252         {
253                 dynamic d = null;
254                 AssertError (() => { d.Fo1 = 1; }, "#1");
255         }
256
257         void SetIndexTest ()
258         {
259                 dynamic d = new[] { "b", "v" };
260                 d[1] = "c";
261                 Assert ("c", d[1], "#1");
262
263                 d = new int[,] { { 1, 2 }, { 3, 4 } };
264                 d[1, 0] = 100;
265                 Assert (100, d[1, 0], "#2");
266                 d[1, 0]++;
267                 Assert (101, d[1, 0], "#2a");
268
269                 d [0, 0] = d [1, 0] = 55;
270                 Assert (55, d [0, 0], "#2a");
271
272                 dynamic d2 = new Class ();
273                 d2[2] = 500;
274                 Assert<uint> (1000, d2[2], "#3");
275                 d2[2]++;
276                 Assert<uint> (2002, d2[2], "#3a");
277                 d2[i:1] = 3;
278                 Assert<uint> (3, d2[1], "#3b");
279                 
280                 uint r = d2 [1] = 200;
281                 Assert<uint> (200, r, "#4");
282         }
283
284         void SetIndexError_Null ()
285         {
286                 dynamic d = null;
287                 AssertError (() => { d [1] = 0; }, "#1");
288         }
289
290 #pragma warning restore 169
291
292         static bool RunTest (MethodInfo test)
293         {
294                 Console.Write ("Running test {0, -25}", test.Name);
295                 try {
296                         test.Invoke (new Tester (), null);
297                         Console.WriteLine ("OK");
298                         return true;
299                 } catch (Exception e) {
300                         Console.WriteLine ("FAILED");
301                         Console.WriteLine (e.ToString ());
302                         //                      Console.WriteLine (e.InnerException.Message);
303                         return false;
304                 }
305         }
306
307         public static int Main ()
308         {
309                 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
310                                         where test.GetParameters ().Length == 0
311                                         orderby test.Name
312                                         select RunTest (test);
313
314                 int failures = tests.Count (a => !a);
315                 Console.WriteLine (failures + " tests failed");
316                 return failures;
317         }
318 }
319