Wed Feb 24 15:47:16 CET 2010 Paolo Molaro <lupus@ximian.com>
[mono.git] / mcs / tests / dtest-003.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5 using System.Dynamic;
6 using System.Linq.Expressions;
7 using Microsoft.CSharp.RuntimeBinder;
8 using System.Runtime.CompilerServices;
9
10 enum Enum
11 {
12         A = 3
13 }
14
15 class AssertDynamicObject : DynamicMetaObject
16 {
17         DynamicObjectMock mock;
18
19         public AssertDynamicObject (DynamicObjectMock mock, Expression parameter)
20                 : base (parameter, BindingRestrictions.Empty, mock)
21         {
22                 this.mock = mock;
23         }
24
25         DynamicMetaObject GetFakeMetaObject (object value)
26         {
27                 Type t = value == null ? typeof (object) : value.GetType ();
28                 var v = Expression.Variable (t);
29                 Expression e = Expression.Block (new[] { v }, Expression.Default (t));
30
31                 Expression restr = Expression.Constant (true);
32                 return new DynamicMetaObject (e, BindingRestrictions.GetExpressionRestriction (restr));
33         }
34
35         public override DynamicMetaObject BindBinaryOperation (BinaryOperationBinder binder, DynamicMetaObject arg)
36         {
37                 if (mock.BinaryOperation == null)
38                         throw new ApplicationException ("Unexpected BindBinaryOperation");
39
40                 mock.BinaryOperation (binder, arg.Value);
41
42                 return GetFakeMetaObject (new object ());
43         }
44
45         public override DynamicMetaObject BindConvert (ConvertBinder binder)
46         {
47                 if (mock.ConvertOperation == null)
48                         throw new ApplicationException ("Unexpected BindConvert");
49
50                 var r = mock.ConvertOperation (binder);
51
52                 return GetFakeMetaObject (r);
53         }
54
55         public override DynamicMetaObject BindGetIndex (GetIndexBinder binder, DynamicMetaObject[] indexes)
56         {
57                 if (mock.GetIndexOperation == null)
58                         throw new ApplicationException ("Unexpected TryGetIndex");
59
60                 mock.GetIndexOperation (binder, indexes.Select (l => l.Value).ToArray ());
61
62                 return GetFakeMetaObject (new object ());
63         }
64
65         public override DynamicMetaObject BindGetMember (GetMemberBinder binder)
66         {
67                 if (mock.GetMemberOperation == null)
68                         throw new ApplicationException ("Unexpected BindGetMember");
69
70                 mock.GetMemberOperation (binder);
71
72                 return GetFakeMetaObject (new object ());
73         }
74
75         public override DynamicMetaObject BindInvoke (InvokeBinder binder, DynamicMetaObject[] args)
76         {
77                 if (mock.InvokeOperation == null)
78                         throw new ApplicationException ("Unexpected BindInvoke");
79
80                 mock.InvokeOperation (binder, args.Select (l => l.Value).ToArray ());
81
82                 return GetFakeMetaObject (new object ());
83         }
84
85         public override DynamicMetaObject BindInvokeMember (InvokeMemberBinder binder, DynamicMetaObject[] args)
86         {
87                 if (mock.InvokeMemberOperation == null)
88                         throw new ApplicationException ("Unexpected BindInvokeMember");
89
90                 mock.InvokeMemberOperation (binder, args.Select (l => l.Value).ToArray ());
91
92                 return GetFakeMetaObject (new object ());
93         }
94
95         public override DynamicMetaObject BindSetIndex (SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
96         {
97                 if (mock.SetIndexOperation == null)
98                         throw new ApplicationException ("Unexpected TrySetIndex");
99
100                 mock.SetIndexOperation (binder, indexes.Select (l => l.Value).ToArray (), value.Value);
101
102                 return GetFakeMetaObject (new object ());
103         }
104
105         public override DynamicMetaObject BindSetMember (SetMemberBinder binder, DynamicMetaObject value)
106         {
107                 if (mock.SetMemberOperation == null)
108                         throw new ApplicationException ("Unexpected BindSetMember");
109
110                 mock.SetMemberOperation (binder, value.Value);
111
112                 return GetFakeMetaObject (new object ());
113         }
114
115         public override DynamicMetaObject BindUnaryOperation (UnaryOperationBinder binder)
116         {
117                 if (mock.UnaryOperation == null)
118                         throw new ApplicationException ("Unexpected BindUnaryOperation");
119
120                 var r = mock.UnaryOperation (binder);
121
122                 return GetFakeMetaObject (r);
123         }
124
125 }
126
127 class DynamicObjectMock : DynamicObject
128 {
129         public int HitCounter;
130
131         public DynamicObjectMock ()
132         {
133         }
134
135         public override DynamicMetaObject GetMetaObject (System.Linq.Expressions.Expression parameter)
136         {
137                 HitCounter++;
138                 return new AssertDynamicObject (this, parameter);
139         }
140
141         public Action<BinaryOperationBinder, object> BinaryOperation;
142         public Func<ConvertBinder, object> ConvertOperation;
143         public Action<GetIndexBinder, object[]> GetIndexOperation;
144         public Action<GetMemberBinder> GetMemberOperation;
145         public Action<InvokeBinder, object[]> InvokeOperation;
146         public Action<InvokeMemberBinder, object[]> InvokeMemberOperation;
147         public Action<SetIndexBinder, object[], object> SetIndexOperation;
148         public Action<SetMemberBinder, object> SetMemberOperation;
149         public Func<UnaryOperationBinder, object> UnaryOperation;
150
151         // Dynamic arguments methods
152         public DynamicObjectMock (int i)
153         {
154         }
155
156         public void DMethod (int a)
157         {
158         }
159
160         public static void DStaticMethod (object t)
161         {
162         }
163
164         public int this[int i] {
165                 get {
166                         return i;
167                 }
168                 set { }
169         }
170
171 }
172
173 class Tester : DynamicObjectMock
174 {
175         static readonly int field = 7;
176
177         public Tester ()
178         {
179         }
180
181         public Tester (dynamic d)
182         {
183         }
184
185         static void Assert<T> (T expected, T value, string name)
186         {
187                 if (!EqualityComparer<T>.Default.Equals (expected, value)) {
188                         if (!string.IsNullOrEmpty (name))
189                                 name += ": ";
190                         throw new ApplicationException (name + "Expected " + expected + " != " + value);
191                 }
192         }
193
194         static void Assert<T> (IList<T> expected, IList<T> value, string name)
195         {
196                 if (expected == null) {
197                         if (value != null)
198                                 throw new ApplicationException (name + ": Both arrays expected to be null");
199                         return;
200                 }
201
202                 if (expected.Count != value.Count)
203                         throw new ApplicationException (name + ": Array length does not match " + expected.Count + " != " + value.Count);
204
205                 for (int i = 0; i < expected.Count; ++i) {
206                         if (!EqualityComparer<T>.Default.Equals (expected[i], value[i]))
207                                 throw new ApplicationException (name + ": Index " + i + ": " + expected[i] + " != " + value[i]);
208                 }
209         }
210
211         static FieldInfo flags = typeof (CSharpArgumentInfo).GetField ("flags", BindingFlags.NonPublic | BindingFlags.Instance);
212
213         static void AssertArgument (CallSiteBinder obj, CSharpArgumentInfo[] expected, string name)
214         {
215                 var ai = obj.GetType ().GetField ("argumentInfo", BindingFlags.NonPublic | BindingFlags.Instance);
216                 IList<CSharpArgumentInfo> values = (IList<CSharpArgumentInfo>) ai.GetValue (obj);
217                 if (values.Count != expected.Length)
218                         throw new ApplicationException (name + ": Array length does not match " + values.Count + " != " + expected.Length);
219
220                 for (int i = 0; i < expected.Length; i++)
221                 {
222                         Assert (flags.GetValue (expected[i]), flags.GetValue (values[i]), "flags");
223                 }
224         }
225
226 #pragma warning disable 168, 169, 219
227
228         void BinaryAdd_1 (dynamic d, DynamicObjectMock mock)
229         {
230                 mock.BinaryOperation = (binder, arg) => {
231                         Assert (binder.Operation, ExpressionType.Add, "Operation");
232                         AssertArgument (binder, new[] {
233                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
234                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
235                                 "ArgumentInfo");
236
237                         Assert (arg, 1, "arg");
238                 };
239
240                 d = d + 1;
241         }
242
243         void BinaryAdd_2 (dynamic d, DynamicObjectMock mock)
244         {
245                 mock.BinaryOperation = (binder, arg) => {
246                         Assert (binder.Operation, ExpressionType.Add, "Operation");
247                         AssertArgument (binder, new[] {
248                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
249                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null) },
250                                 "ArgumentInfo");
251
252                         Assert (arg, null, "arg");
253                 };
254
255                 int? v = null;
256                 d = d + v;
257         }
258
259         void BinaryAdd_3 (dynamic d, DynamicObjectMock mock)
260         {
261                 mock.BinaryOperation = (binder, arg) => {
262                         Assert (binder.Operation, ExpressionType.Add, "Operation");
263                         AssertArgument (binder, new[] {
264                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
265                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null)
266                         }, "ArgumentInfo");
267
268                         Assert (arg, Enum.A, "arg");
269                 };
270
271                 d = d + Enum.A;
272         }
273
274         void BinaryAdd_4 (dynamic d, DynamicObjectMock mock)
275         {
276                 mock.BinaryOperation = (binder, arg) => {
277                         Assert (binder.Operation, ExpressionType.Add, "Operation");
278                         AssertArgument (binder, new[] {
279                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
280                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null) },
281                                 "ArgumentInfo");
282
283                         Assert (arg, 7, "arg");
284                 };
285
286                 d = d + Tester.field;
287         }
288
289         void BinaryAddChecked_1 (dynamic d, DynamicObjectMock mock)
290         {
291                 mock.BinaryOperation = (binder, arg) => {
292                         Assert (binder.Operation, ExpressionType.Add, "Operation");
293                         AssertArgument (binder, new[] {
294                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
295                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null) },
296                                 "ArgumentInfo");
297
298                         Assert (arg, 3, "arg");
299                 };
300
301                 d = checked (d + 3);
302         }
303         
304         void BinaryAddChecked_2 (dynamic d, DynamicObjectMock mock)
305         {
306                 mock.BinaryOperation = (binder, arg) => {
307                         Assert (binder.Operation, ExpressionType.Add, "Operation");
308                         AssertArgument (binder, new[] {
309                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
310                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null) },
311                                 "ArgumentInfo");
312
313                         Assert (arg, 3, "arg");
314                 };
315
316                 Func<dynamic> r;
317                 checked {
318                         r = () => d + 3;
319                 }
320                 
321                 r ();
322         }
323
324         void BinaryAddAssign_1 (dynamic d, DynamicObjectMock mock)
325         {
326                 mock.BinaryOperation = (binder, arg) => {
327                         Assert (binder.Operation, ExpressionType.AddAssign, "Operation");
328                         AssertArgument (binder, new[] {
329                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
330                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
331                                 "ArgumentInfo");
332
333                         Assert (arg, 1, "arg");
334                 };
335
336                 d += 1;
337         }
338
339         void BinaryAddAssignChecked_1 (dynamic d, DynamicObjectMock mock)
340         {
341                 mock.BinaryOperation = (binder, arg) => {
342                         Assert (binder.Operation, ExpressionType.AddAssign, "Operation");
343                         AssertArgument (binder, new[] {
344                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
345                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
346                                 "ArgumentInfo");
347
348                         Assert (arg, 1, "arg");
349                 };
350
351                 checked {
352                         d += 1;
353                 }
354         }
355
356         void BinaryAnd_1 (dynamic d, DynamicObjectMock mock)
357         {
358                 mock.BinaryOperation = (binder, arg) => {
359                         Assert (binder.Operation, ExpressionType.And, "Operation");
360                         AssertArgument (binder, new[] {
361                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
362                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
363                                 "ArgumentInfo");
364
365                         Assert (arg, 1, "arg");
366                 };
367
368                 d = d & 1;
369         }
370
371         void BinaryAndAssign_1 (dynamic d, DynamicObjectMock mock)
372         {
373                 mock.BinaryOperation = (binder, arg) => {
374                         Assert (binder.Operation, ExpressionType.AndAssign, "Operation");
375                         AssertArgument (binder, new[] {
376                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
377                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
378                                 "ArgumentInfo");
379
380                         Assert (arg, 1, "arg");
381                 };
382
383                 d &= 1;
384         }
385
386         void BinaryDivide_1 (dynamic d, DynamicObjectMock mock)
387         {
388                 mock.BinaryOperation = (binder, arg) => {
389                         Assert (binder.Operation, ExpressionType.Divide, "Operation");
390                         AssertArgument (binder, new[] {
391                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
392                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
393                                 "ArgumentInfo");
394
395                         Assert (arg, 1, "arg");
396                 };
397
398                 d = d / 1;
399         }
400
401         void BinaryDivideAssign_1 (dynamic d, DynamicObjectMock mock)
402         {
403                 mock.BinaryOperation = (binder, arg) => {
404                         Assert (binder.Operation, ExpressionType.DivideAssign, "Operation");
405                         AssertArgument (binder, new[] {
406                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
407                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
408                                 "ArgumentInfo");
409
410                         Assert (arg, 1, "arg");
411                 };
412
413                 d /= 1;
414         }
415
416         void BinaryEqual_1 (dynamic d, DynamicObjectMock mock)
417         {
418                 mock.BinaryOperation = (binder, arg) => {
419                         Assert (binder.Operation, ExpressionType.Equal, "Operation");
420                         AssertArgument (binder, new[] {
421                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
422                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
423                                 "ArgumentInfo");
424
425                         Assert (arg, 1, "arg");
426                 };
427
428                 d = d == 1;
429         }
430
431         void BinaryExclusiveOr_1 (dynamic d, DynamicObjectMock mock)
432         {
433                 mock.BinaryOperation = (binder, arg) => {
434                         Assert (binder.Operation, ExpressionType.ExclusiveOr, "Operation");
435                         AssertArgument (binder, new[] {
436                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
437                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
438                                 "ArgumentInfo");
439
440                         Assert (arg, 1, "arg");
441                 };
442
443                 d = d ^ 1;
444         }
445
446         void BinaryExclusiveOrAssign_1 (dynamic d, DynamicObjectMock mock)
447         {
448                 mock.BinaryOperation = (binder, arg) => {
449                         Assert (binder.Operation, ExpressionType.ExclusiveOrAssign, "Operation");
450                         AssertArgument (binder, new[] {
451                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
452                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
453                                 "ArgumentInfo");
454
455                         Assert (arg, 1, "arg");
456                 };
457
458                 d ^= 1;
459         }
460
461         void BinaryGreaterThan_1 (dynamic d, DynamicObjectMock mock)
462         {
463                 mock.BinaryOperation = (binder, arg) => {
464                         Assert (binder.Operation, ExpressionType.GreaterThan, "Operation");
465                         AssertArgument (binder, new[] {
466                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
467                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
468                                 "ArgumentInfo");
469
470                         Assert (arg, 1, "arg");
471                 };
472
473                 d = d > 1;
474         }
475
476         void BinaryGreaterThanOrEqual_1 (dynamic d, DynamicObjectMock mock)
477         {
478                 mock.BinaryOperation = (binder, arg) => {
479                         Assert (binder.Operation, ExpressionType.GreaterThanOrEqual, "Operation");
480                         AssertArgument (binder, new[] {
481                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
482                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
483                                 "ArgumentInfo");
484
485                         Assert (arg, 1, "arg");
486                 };
487
488                 d = d >= 1;
489         }
490
491         void BinaryLeftShift_1 (dynamic d, DynamicObjectMock mock)
492         {
493                 mock.BinaryOperation = (binder, arg) => {
494                         Assert (binder.Operation, ExpressionType.LeftShift, "Operation");
495                         AssertArgument (binder, new[] {
496                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
497                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
498                                 "ArgumentInfo");
499
500                         Assert (arg, 1, "arg");
501                 };
502
503                 d = d << 1;
504         }
505
506         void BinaryLeftShiftAssign_1 (dynamic d, DynamicObjectMock mock)
507         {
508                 mock.BinaryOperation = (binder, arg) => {
509                         Assert (binder.Operation, ExpressionType.LeftShiftAssign, "Operation");
510                         AssertArgument (binder, new[] {
511                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
512                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
513                                 "ArgumentInfo");
514
515                         Assert (arg, 1, "arg");
516                 };
517
518                 d <<= 1;
519         }
520
521         void BinaryLessThan_1 (dynamic d, DynamicObjectMock mock)
522         {
523                 mock.BinaryOperation = (binder, arg) => {
524                         Assert (binder.Operation, ExpressionType.LessThan, "Operation");
525                         AssertArgument (binder, new[] {
526                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
527                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
528                                 "ArgumentInfo");
529
530                         Assert (arg, 1, "arg");
531                 };
532
533                 d = d < 1;
534         }
535
536         void BinaryLessThanOrEqual_1 (dynamic d, DynamicObjectMock mock)
537         {
538                 mock.BinaryOperation = (binder, arg) => {
539                         Assert (binder.Operation, ExpressionType.LessThanOrEqual, "Operation");
540                         AssertArgument (binder, new[] {
541                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
542                             CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
543                                 "ArgumentInfo");
544
545                         Assert (arg, 1, "arg");
546                 };
547
548                 d = d <= 1;
549         }
550
551         void BinaryModulo_1 (dynamic d, DynamicObjectMock mock)
552         {
553                 mock.BinaryOperation = (binder, arg) => {
554                         Assert (binder.Operation, ExpressionType.Modulo, "Operation");
555                         AssertArgument (binder, new[] {
556                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
557                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
558                                 "ArgumentInfo");
559
560                         Assert (arg, 1, "arg");
561                 };
562
563                 d = d % 1;
564         }
565
566         void BinaryModuloAssign_1 (dynamic d, DynamicObjectMock mock)
567         {
568                 mock.BinaryOperation = (binder, arg) => {
569                         Assert (binder.Operation, ExpressionType.ModuloAssign, "Operation");
570                         AssertArgument (binder, new[] {
571                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
572                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
573                                 "ArgumentInfo");
574
575                         Assert (arg, 1, "arg");
576                 };
577
578                 d %= 1;
579         }
580
581         void BinaryMultiply_1 (dynamic d, DynamicObjectMock mock)
582         {
583                 mock.BinaryOperation = (binder, arg) => {
584                         Assert (binder.Operation, ExpressionType.Multiply, "Operation");
585                         AssertArgument (binder, new[] {
586                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
587                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
588                                 "ArgumentInfo");
589
590                         Assert (arg, 1, "arg");
591                 };
592
593                 d = d * 1;
594         }
595
596         void BinaryMultiplyAssign_1 (dynamic d, DynamicObjectMock mock)
597         {
598                 mock.BinaryOperation = (binder, arg) => {
599                         Assert (binder.Operation, ExpressionType.MultiplyAssign, "Operation");
600                         AssertArgument (binder, new[] {
601                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
602                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
603                                 "ArgumentInfo");
604
605                         Assert (arg, 1, "arg");
606                 };
607
608                 d *= 1;
609         }
610
611         void BinaryNotEqual_1 (dynamic d, DynamicObjectMock mock)
612         {
613                 mock.BinaryOperation = (binder, arg) => {
614                         Assert (binder.Operation, ExpressionType.NotEqual, "Operation");
615                         AssertArgument (binder, new[] {
616                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
617                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
618                                 "ArgumentInfo");
619
620                         Assert (arg, 4, "arg");
621                 };
622
623                 d = d != 4;
624         }
625
626         void BinaryOr_1 (dynamic d, DynamicObjectMock mock)
627         {
628                 mock.BinaryOperation = (binder, arg) => {
629                         Assert (binder.Operation, ExpressionType.Or, "Operation");
630                         AssertArgument (binder, new[] {
631                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
632                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
633                                 "ArgumentInfo");
634
635                         Assert (arg, 2, "arg");
636                 };
637
638                 d = d | 2;
639         }
640
641         void BinaryOrAssign_1 (dynamic d, DynamicObjectMock mock)
642         {
643                 mock.BinaryOperation = (binder, arg) => {
644                         Assert (binder.Operation, ExpressionType.OrAssign, "Operation");
645                         AssertArgument (binder, new[] {
646                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
647                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
648                                 "ArgumentInfo");
649
650                         Assert (arg, 2, "arg");
651                 };
652
653                 d |= 2;
654         }
655
656         void BinaryRightShift_1 (dynamic d, DynamicObjectMock mock)
657         {
658                 mock.BinaryOperation = (binder, arg) => {
659                         Assert (binder.Operation, ExpressionType.RightShift, "Operation");
660                         AssertArgument (binder, new[] {
661                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
662                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
663                                 "ArgumentInfo");
664
665                         Assert (arg, 1, "arg");
666                 };
667
668                 d = d >> 1;
669         }
670
671         void BinaryRightShiftAssign_1 (dynamic d, DynamicObjectMock mock)
672         {
673                 mock.BinaryOperation = (binder, arg) => {
674                         Assert (binder.Operation, ExpressionType.RightShiftAssign, "Operation");
675                         AssertArgument (binder, new[] {
676                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
677                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
678                                 "ArgumentInfo");
679
680                         Assert (arg, 1, "arg");
681                 };
682
683                 d >>= 1;
684         }
685
686         void BinarySubtract_1 (dynamic d, DynamicObjectMock mock)
687         {
688                 mock.BinaryOperation = (binder, arg) => {
689                         Assert (binder.Operation, ExpressionType.Subtract, "Operation");
690                         AssertArgument (binder, new[] {
691                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
692                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
693                                 "ArgumentInfo");
694
695                         Assert (arg, 1, "arg");
696                 };
697
698                 d = d - 1;
699         }
700
701         void BinarySubtractAssign_1 (dynamic d, DynamicObjectMock mock)
702         {
703                 mock.BinaryOperation = (binder, arg) => {
704                         Assert (binder.Operation, ExpressionType.SubtractAssign, "Operation");
705                         AssertArgument (binder, new[] {
706                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
707                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
708                                 "ArgumentInfo");
709
710                         Assert (arg, 1, "arg");
711                 };
712
713                 d -= 1;
714         }
715
716         void Convert_1 (dynamic d, DynamicObjectMock mock)
717         {
718                 mock.ConvertOperation = (binder) => {
719                         Assert (binder.Explicit, true, "Explicit");
720                         Assert (binder.Type, typeof (byte), "Type");
721                         return (byte) 1;
722                 };
723
724                 object b = (byte) d;
725         }
726
727         void Convert_2 (dynamic d, DynamicObjectMock mock)
728         {
729                 mock.ConvertOperation = (binder) => {
730                         Assert (binder.Explicit, false, "Explicit");
731                         Assert (binder.Type, typeof (int), "Type");
732                         return 2;
733                 };
734
735                 object[] o = new object [2];
736                 d = o[d];
737         }
738
739         void Convert_3 (dynamic d, DynamicObjectMock mock)
740         {
741                 mock.ConvertOperation = (binder) => {
742                         Assert (binder.Explicit, true, "Explicit");
743 //                      Assert (binder.IsChecked, true, "IsChecked");
744                         Assert (binder.Type, typeof (byte), "Type");
745                         return (byte) 2;
746                 };
747
748                 object b = checked((byte) d);
749         }
750
751         void Convert_4 (dynamic d, DynamicObjectMock mock)
752         {
753                 mock.ConvertOperation = (binder) => {
754                         Assert (binder.Explicit, false, "Explicit");
755                         Assert (binder.Type, typeof (int), "Type");
756                         return 5;
757                 };
758
759                 var g = new int[d];
760         }
761
762         void GetIndex_1 (dynamic d, DynamicObjectMock mock)
763         {
764                 mock.GetIndexOperation = (binder, args) => {
765                         Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
766 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
767                         AssertArgument (binder, new[] {
768                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
769                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
770                                 "ArgumentInfo");
771
772                         Assert ((IList<object>)args, new object[] { 0 }, "args");
773                 };
774
775                 var o = d [0];
776         }
777
778         void GetIndex_2 (dynamic d, DynamicObjectMock mock)
779         {
780                 mock.GetIndexOperation = (binder, args) => {
781                         Assert (binder.CallInfo, new CallInfo (2, new string[0]), "CallInfo");
782 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
783                         AssertArgument (binder, new[] {
784                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
785                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null),
786                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null) },
787                         "ArgumentInfo");
788
789                         Assert ((IList<object>) args, new object[] { 2, 3 }, "args");
790                 };
791
792                 object i = 3;
793                 var o = d[2, i];
794         }
795
796         void GetIndex_3 (dynamic d, DynamicObjectMock mock)
797         {
798                 mock.GetIndexOperation = (binder, args) => {
799                         Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
800 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
801                         AssertArgument (binder, new[] {
802                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
803                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) },
804                                 "ArgumentInfo");
805
806                         Assert ((IList<object>) args, new object[] { d }, "args");
807                 };
808
809                 var o = mock[d];
810         }
811
812         void GetMember_1 (dynamic d, DynamicObjectMock mock)
813         {
814                 mock.GetMemberOperation = (binder) => {
815                         Assert (binder.Name, "Foo", "Name");
816                         Assert (binder.IgnoreCase, false, "IgnoreCase");
817 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
818                         AssertArgument (binder, new[] {
819                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) },
820                                 "ArgumentInfo");
821                 };
822
823                 var g = d.Foo;
824         }
825
826         void Invoke_1 (dynamic d, DynamicObjectMock mock)
827         {
828                 mock.InvokeOperation = (binder, args) => {
829                         Assert (binder.CallInfo, new CallInfo (2, new string[0]), "CallInfo");
830 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
831                         AssertArgument (binder, new[] {
832                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
833                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null),
834                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)
835                         },      "ArgumentInfo");
836
837                         Assert ((IList<object>) args, new object[] { "foo", null }, "args");
838                 };
839
840                 d ("foo", null);
841         }
842
843         void Invoke_2 (dynamic d, DynamicObjectMock mock)
844         {
845                 mock.InvokeOperation = (binder, args) => {
846                         Assert (binder.CallInfo, new CallInfo (0, new string[0]), "CallInfo");
847 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
848                         AssertArgument (binder, new[] {
849                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) },
850                                 "ArgumentInfo");
851
852                         Assert ((IList<object>) args, new object[0], "args");
853                 };
854
855                 d ();
856         }
857
858         void Invoke_3 (dynamic d, DynamicObjectMock mock)
859         {
860                 try {
861                         Math.Max (d, d);
862                         Assert (true, false, "No hook expected to be hit");
863                 } catch (RuntimeBinderException) {
864                 }
865         }
866
867         void Invoke_4 (dynamic d, DynamicObjectMock mock)
868         {
869                 mock.InvokeOperation = (binder, args) => {
870                         Assert (binder.CallInfo, new CallInfo (2, new string[] { "name" }), "CallInfo");
871 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
872                         AssertArgument (binder, new[] {
873                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
874                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
875                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.NamedArgument | CSharpArgumentInfoFlags.UseCompileTimeType, "name")
876                         }, "ArgumentInfo");
877
878                         Assert ((IList<object>) args, new object[] { typeof (bool), -1 }, "args");
879                 };
880
881                 d (typeof (bool), name:-1);
882         }
883         
884         void Invoke_5 (dynamic d, DynamicObjectMock mock)
885         {
886                 mock.InvokeOperation = (binder, args) => {
887                         Assert (binder.CallInfo, new CallInfo (2, new string[] { "name" }), "CallInfo");
888                         AssertArgument (binder, new[] {
889                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
890                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
891                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.NamedArgument | CSharpArgumentInfoFlags.UseCompileTimeType, "name")
892                         }, "ArgumentInfo");
893
894                         Assert ((IList<object>) args, new object[] { typeof (bool), -1 }, "args");
895                 };
896
897                 Action<object> a = (i) => {};
898                 a (d);
899         }
900         
901         void InvokeMember_1 (dynamic d, DynamicObjectMock mock)
902         {
903                 mock.InvokeMemberOperation = (binder, args) => {
904                         Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
905 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
906                         AssertArgument (binder, new[] {
907                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
908                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)},
909                                 "ArgumentInfo");
910
911 //                      Assert (binder.Flags, CSharpCallFlags.None, "Flags");
912                         Assert (binder.IgnoreCase, false, "IgnoreCase");
913 //                      Assert (binder.TypeArguments, new Type[0], "TypeArguments");
914
915                         Assert ((IList<object>) args, new object[] { 'a' }, "args");
916                 };
917
918                 d.Max ('a');
919         }
920
921         void InvokeMember_2 (dynamic d, DynamicObjectMock mock)
922         {
923                 mock.InvokeMemberOperation = (binder, args) => {
924                         Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
925 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
926                         AssertArgument (binder, new[] {
927                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
928                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)},
929                                 "ArgumentInfo");
930
931 //                      Assert (binder.Flags, CSharpCallFlags.None, "Flags");
932                         Assert (binder.IgnoreCase, false, "IgnoreCase");
933 //                      Assert (binder.TypeArguments, new Type[0], "TypeArguments");
934
935                         Assert ((IList<object>) args, new object[] { mock }, "args");
936                 };
937
938                 mock.DMethod (d);
939         }
940
941         void InvokeMember_3 (dynamic d, DynamicObjectMock mock)
942         {
943                 mock.InvokeMemberOperation = (binder, args) => {
944                         Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
945 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
946                         AssertArgument (binder, new[] {
947                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
948                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.IsRef | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
949                                 "ArgumentInfo");
950
951 //                      Assert (binder.Flags, CSharpCallFlags.None, "Flags");
952                         Assert (binder.IgnoreCase, false, "IgnoreCase");
953 //                      Assert (binder.TypeArguments, new Type[0], "TypeArguments");
954
955                         Assert ((IList<object>) args, new object[] { 9 }, "args");
956                 };
957
958                 int i = 9;
959                 d.Max (ref i);
960         }
961
962         void InvokeMember_4 (dynamic d, DynamicObjectMock mock)
963         {
964                 mock.InvokeMemberOperation = (binder, args) => {
965                         Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
966 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
967                         AssertArgument (binder, new[] {
968                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
969                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.IsOut | CSharpArgumentInfoFlags.UseCompileTimeType, null)    },
970                                 "ArgumentInfo");
971
972 //                      Assert (binder.Flags, CSharpCallFlags.None, "Flags");
973                         Assert (binder.IgnoreCase, false, "IgnoreCase");
974 //                      Assert (binder.TypeArguments, new Type[0], "TypeArguments");
975
976                         Assert ((IList<object>) args, new object[] { 0 }, "args");
977                 };
978
979                 int i;
980                 d.Max (out i);
981         }
982
983         void InvokeMember_5 (dynamic d, DynamicObjectMock mock)
984         {
985                 DynamicObjectMock.DStaticMethod (d);
986         }
987
988         void InvokeMember_6 (dynamic d, DynamicObjectMock mock)
989         {
990                 InvokeMemberOperation = (binder, args) => {
991                         Assert (binder.CallInfo, new CallInfo (2, new string[0]), "CallInfo");
992 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
993                         AssertArgument (binder, new[] {
994                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
995                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
996                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null),
997                         }, "ArgumentInfo");
998 //                      Assert (binder.Flags, CSharpCallFlags.SimpleNameCall, "Flags");
999                         Assert (binder.IgnoreCase, false, "IgnoreCase");
1000 //                      Assert (binder.TypeArguments, Type.EmptyTypes, "TypeArguments");
1001
1002                         Assert ((IList<object>) args, new object[] { d, null }, "args");
1003                 };
1004
1005                 InvokeMember_5 (d, null);
1006         }
1007
1008         void InvokeMember_7 (dynamic d, DynamicObjectMock mock)
1009         {
1010                 mock.InvokeMemberOperation = (binder, args) => {
1011                         Assert (binder.CallInfo, new CallInfo (0, new string[0]), "CallInfo");
1012 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
1013                         AssertArgument (binder, new[] {
1014                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1015                         }, "ArgumentInfo");
1016 //                      Assert (binder.Flags, CSharpCallFlags.None, "Flags");
1017                         Assert (binder.IgnoreCase, false, "IgnoreCase");
1018 //                      Assert (binder.TypeArguments, new Type[] { typeof (object) }, "TypeArguments");
1019
1020                         Assert ((IList<object>) args, new object[0], "args");
1021                 };
1022
1023                 d.Max<dynamic> ();
1024         }
1025
1026         void SetIndex_1 (dynamic d, DynamicObjectMock mock)
1027         {
1028                 mock.SetIndexOperation = (binder, args, value) => {
1029                         Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
1030 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
1031                         AssertArgument (binder, new[] {
1032                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1033                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null),
1034                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)},
1035                                 "ArgumentInfo");
1036
1037                         Assert ((IList<object>) args, new object[] { 0 }, "args");
1038                         Assert (value, 2m, "value");
1039                 };
1040
1041                 d[0] = 2m;
1042         }
1043
1044         void SetIndex_2 (dynamic d, DynamicObjectMock mock)
1045         {
1046                 mock.SetIndexOperation = (binder, args, value) => {
1047                         Assert (binder.CallInfo, new CallInfo (2, new string[0]), "CallInfo");
1048 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
1049                         AssertArgument (binder, new[] {
1050                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1051                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null),
1052                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
1053                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null)
1054                         }, "ArgumentInfo");
1055
1056                         Assert ((IList<object>) args, new object[] { 2, 3 }, "args");
1057                         Assert (value, -8, "value");
1058                 };
1059
1060                 object i = 3;
1061                 d[2, i] = -8;
1062         }
1063
1064         void SetIndex_3 (dynamic d, DynamicObjectMock mock)
1065         {
1066                 mock.SetIndexOperation = (binder, args, value) => {
1067                         Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
1068 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
1069                         AssertArgument (binder, new[] {
1070                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
1071                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1072                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null)
1073                         }, "ArgumentInfo");
1074
1075                         Assert ((IList<object>) args, new object[] { d }, "args");
1076                         Assert (value, this, "value");
1077                 };
1078
1079                 mock[d] = this;
1080         }
1081
1082         void SetMember_1 (dynamic d, DynamicObjectMock mock)
1083         {
1084                 const double d_const = 2.4;
1085
1086                 mock.SetMemberOperation = (binder, value) => {
1087                         Assert (binder.Name, "Foo", "Name");
1088                         Assert (binder.IgnoreCase, false, "IgnoreCase");
1089 //                      Assert (binder.CallingContext, typeof (Tester), "CallingContext");
1090                         AssertArgument (binder, new[] {
1091                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1092                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null) // CSC bug?
1093                         },      "ArgumentInfo");
1094
1095                         Assert (value, d_const, "value");
1096                 };
1097
1098                 d.Foo = d_const;
1099         }
1100
1101         void UnaryPlus_1 (dynamic d, DynamicObjectMock mock)
1102         {
1103                 mock.UnaryOperation = (binder) => {
1104                         Assert (binder.Operation, ExpressionType.UnaryPlus, "Operation");
1105                         AssertArgument (binder, new[] {
1106                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1107                         }, "ArgumentInfo");
1108
1109                         return null;
1110                 };
1111
1112                 d = +d;
1113         }
1114
1115         void UnaryMinus_1 (dynamic d, DynamicObjectMock mock)
1116         {
1117                 mock.UnaryOperation = (binder) => {
1118                         Assert (binder.Operation, ExpressionType.Negate, "Operation");
1119                         AssertArgument (binder, new[] {
1120                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1121                         }, "ArgumentInfo");
1122
1123                         return null;
1124                 };
1125
1126                 d = -d;
1127         }
1128
1129         void UnaryNot_1 (dynamic d, DynamicObjectMock mock)
1130         {
1131                 mock.UnaryOperation = (binder) => {
1132                         Assert (binder.Operation, ExpressionType.Not, "Operation");
1133                         AssertArgument (binder, new[] {
1134                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1135                         }, "ArgumentInfo");
1136
1137                         return null;
1138                 };
1139
1140                 d = !d;
1141         }
1142
1143         void UnaryOnesComplement_1 (dynamic d, DynamicObjectMock mock)
1144         {
1145                 mock.UnaryOperation = (binder) => {
1146                         Assert (binder.Operation, ExpressionType.OnesComplement, "Operation");
1147                         AssertArgument (binder, new[] {
1148                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1149                         }, "ArgumentInfo");
1150
1151                         return null;
1152                 };
1153
1154                 d = ~d;
1155         }
1156
1157         void UnaryDecrement_1 (dynamic d, DynamicObjectMock mock)
1158         {
1159                 mock.UnaryOperation = (binder) => {
1160                         Assert (binder.Operation, ExpressionType.Decrement, "Operation");
1161                         AssertArgument (binder, new[] {
1162                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1163                         }, "ArgumentInfo");
1164
1165                         return null;
1166                 };
1167
1168                 d = --d;
1169         }
1170
1171         void UnaryDecrement_2 (dynamic d, DynamicObjectMock mock)
1172         {
1173                 mock.UnaryOperation = (binder) => {
1174                         Assert (binder.Operation, ExpressionType.Decrement, "Operation");
1175                         AssertArgument (binder, new[] {
1176                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1177                         }, "ArgumentInfo");
1178
1179                         return new object ();
1180                 };
1181
1182                 d = d--;
1183         }
1184
1185         void UnaryIncrement_1 (dynamic d, DynamicObjectMock mock)
1186         {
1187                 mock.UnaryOperation = (binder) => {
1188                         Assert (binder.Operation, ExpressionType.Increment, "Operation");
1189                         AssertArgument (binder, new[] {
1190                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1191                         }, "ArgumentInfo");
1192
1193                         return null;
1194                 };
1195
1196                 d = ++d;
1197         }
1198
1199         void UnaryIncrement_2 (dynamic d, DynamicObjectMock mock)
1200         {
1201                 mock.UnaryOperation = (binder) => {
1202                         Assert (binder.Operation, ExpressionType.Increment, "Operation");
1203                         AssertArgument (binder, new[] {
1204                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1205                         }, "ArgumentInfo");
1206
1207                         return new object ();
1208                 };
1209
1210                 d = d++;
1211         }
1212
1213         void UnaryIsFalse_1 (dynamic d, DynamicObjectMock mock)
1214         {
1215                 mock.UnaryOperation = (binder) => {
1216                         Assert (binder.Operation, ExpressionType.IsFalse, "Operation");
1217                         AssertArgument (binder, new[] {
1218                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1219                         }, "ArgumentInfo");
1220
1221                         return true;
1222                 };
1223
1224                 mock.BinaryOperation = (binder, arg) => {
1225                         Assert (binder.Operation, ExpressionType.Equal, "Operation");
1226                         AssertArgument (binder, new[] {
1227                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1228                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
1229                                 "ArgumentInfo");
1230
1231                         Assert (arg, null, "arg");
1232                 };
1233
1234                 object x = d == null;
1235         }
1236
1237         void UnaryIsFalse_2 (dynamic d, DynamicObjectMock mock)
1238         {
1239                 mock.UnaryOperation = (binder) => {
1240                         Assert (binder.Operation, ExpressionType.IsFalse, "Operation");
1241                         AssertArgument (binder, new[] {
1242                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1243                         }, "ArgumentInfo");
1244
1245                         return true;
1246                 };
1247
1248                 mock.BinaryOperation = (binder, arg) => {
1249                         Assert (binder.Operation, ExpressionType.NotEqual, "Operation");
1250                         AssertArgument (binder, new[] {
1251                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1252                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
1253                                 "ArgumentInfo");
1254
1255                         Assert (arg, null, "arg");
1256                 };
1257
1258                 object x = d != null;
1259         }
1260
1261         void UnaryIsFalse_3 (dynamic d, DynamicObjectMock mock)
1262         {
1263                 mock.UnaryOperation = (binder) => {
1264                         Assert (binder.Operation, ExpressionType.IsFalse, "Operation");
1265                         AssertArgument (binder, new[] {
1266                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1267                         }, "ArgumentInfo");
1268
1269                         return true;
1270                 };
1271
1272                 mock.BinaryOperation = (binder, arg) => {
1273                         Assert (binder.Operation, ExpressionType.And, "Operation");
1274                         AssertArgument (binder, new[] {
1275                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1276                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
1277                                 "ArgumentInfo");
1278
1279                         Assert (arg, null, "arg");
1280                 };
1281
1282                 object x = d && null;
1283         }
1284
1285         void UnaryIsTrue_1 (dynamic d, DynamicObjectMock mock)
1286         {
1287                 mock.UnaryOperation = (binder) => {
1288                         Assert (binder.Operation, ExpressionType.IsTrue, "Operation");
1289                         AssertArgument (binder, new[] {
1290                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1291                         }, "ArgumentInfo");
1292
1293                         return true;
1294                 };
1295
1296                 object g = d ? 1 :4;
1297         }
1298
1299         void UnaryIsTrue_2 (dynamic d, DynamicObjectMock mock)
1300         {
1301                 mock.UnaryOperation = (binder) => {
1302                         Assert (binder.Operation, ExpressionType.IsTrue, "Operation");
1303                         AssertArgument (binder, new[] {
1304                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1305                         }, "ArgumentInfo");
1306
1307                         return false;
1308                 };
1309
1310                 mock.BinaryOperation = (binder, arg) => {
1311                         Assert (binder.Operation, ExpressionType.Or, "Operation");
1312                         AssertArgument (binder, new[] {
1313                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1314                                 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
1315                                 "ArgumentInfo");
1316
1317                         Assert (arg, null, "arg");
1318                 };
1319
1320                 object x = d || null;
1321         }
1322         
1323 #pragma warning restore 168, 169, 219
1324
1325         static bool RunTest (MethodInfo test)
1326         {
1327                 Console.Write ("Running test {0, -25}", test.Name);
1328                 try {
1329                         var d = new DynamicObjectMock ();
1330                         test.Invoke (new Tester (), new [] { d, d });
1331                         if (d.HitCounter < 1)
1332                                 Assert (true, false, "HitCounter");
1333
1334                         Console.WriteLine ("OK");
1335                         return true;
1336                 } catch (Exception e) {
1337                         Console.WriteLine ("FAILED");
1338                         Console.WriteLine (e.ToString ());
1339                         return false;
1340                 }
1341         }
1342
1343         public static int Main ()
1344         {
1345                 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
1346                                         where test.GetParameters ().Length == 2
1347                                         orderby test.Name
1348                                         select RunTest (test);
1349
1350                 int failures = tests.Count (a => !a);
1351                 Console.WriteLine (failures + " tests failed");
1352                 return failures;
1353         }
1354 }