2 using System.Collections.Generic;
4 using System.Reflection;
6 using System.Linq.Expressions;
7 using Microsoft.CSharp.RuntimeBinder;
8 using System.Runtime.CompilerServices;
15 class AssertDynamicObject : DynamicMetaObject
17 DynamicObjectMock mock;
19 public AssertDynamicObject (DynamicObjectMock mock, Expression parameter)
20 : base (parameter, BindingRestrictions.Empty, mock)
25 DynamicMetaObject GetFakeMetaObject (object value)
27 Type t = value == null ? typeof (object) : value.GetType ();
28 Expression<Func<object>> et = () => value;
30 Expression restr = Expression.Constant (true);
31 return new DynamicMetaObject (Expression.Convert (et.Body, t), BindingRestrictions.GetExpressionRestriction (restr));
34 public override DynamicMetaObject BindBinaryOperation (BinaryOperationBinder binder, DynamicMetaObject arg)
36 if (mock.BinaryOperation == null)
37 throw new ApplicationException ("Unexpected BindBinaryOperation");
39 mock.BinaryOperation (binder, arg.Value);
41 return GetFakeMetaObject (new object ());
44 public override DynamicMetaObject BindConvert (ConvertBinder binder)
46 if (mock.ConvertOperation == null)
47 throw new ApplicationException ("Unexpected BindConvert");
49 var r = mock.ConvertOperation (binder);
51 return GetFakeMetaObject (r);
54 public override DynamicMetaObject BindGetIndex (GetIndexBinder binder, DynamicMetaObject[] indexes)
56 if (mock.GetIndexOperation == null)
57 throw new ApplicationException ("Unexpected TryGetIndex");
59 mock.GetIndexOperation (binder, indexes.Select (l => l.Value).ToArray ());
61 return GetFakeMetaObject (new object ());
64 public override DynamicMetaObject BindGetMember (GetMemberBinder binder)
66 if (mock.GetMemberOperation == null)
67 throw new ApplicationException ("Unexpected BindGetMember");
69 var r = mock.GetMemberOperation (binder);
71 return GetFakeMetaObject (r);
74 public override DynamicMetaObject BindInvoke (InvokeBinder binder, DynamicMetaObject[] args)
76 if (mock.InvokeOperation == null)
77 throw new ApplicationException ("Unexpected BindInvoke");
79 mock.InvokeOperation (binder, args.Select (l => l.Value).ToArray ());
81 return GetFakeMetaObject (new object ());
84 public override DynamicMetaObject BindInvokeMember (InvokeMemberBinder binder, DynamicMetaObject[] args)
86 if (mock.InvokeMemberOperation == null)
87 throw new ApplicationException ("Unexpected BindInvokeMember");
89 mock.InvokeMemberOperation (binder, args.Select (l => l.Value).ToArray ());
91 return GetFakeMetaObject (new object ());
94 public override DynamicMetaObject BindSetIndex (SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
96 if (mock.SetIndexOperation == null)
97 throw new ApplicationException ("Unexpected TrySetIndex");
99 mock.SetIndexOperation (binder, indexes.Select (l => l.Value).ToArray (), value.Value);
101 return GetFakeMetaObject (new object ());
104 public override DynamicMetaObject BindSetMember (SetMemberBinder binder, DynamicMetaObject value)
106 if (mock.SetMemberOperation == null)
107 throw new ApplicationException ("Unexpected BindSetMember");
109 mock.SetMemberOperation (binder, value.Value);
111 return GetFakeMetaObject (new object ());
114 public override DynamicMetaObject BindUnaryOperation (UnaryOperationBinder binder)
116 if (mock.UnaryOperation == null)
117 throw new ApplicationException ("Unexpected BindUnaryOperation");
119 var r = mock.UnaryOperation (binder);
121 return GetFakeMetaObject (r);
126 class DynamicObjectMock : DynamicObject
128 public int HitCounter;
130 public DynamicObjectMock ()
134 public override DynamicMetaObject GetMetaObject (System.Linq.Expressions.Expression parameter)
137 return new AssertDynamicObject (this, parameter);
140 public Action<BinaryOperationBinder, object> BinaryOperation;
141 public Func<ConvertBinder, object> ConvertOperation;
142 public Action<GetIndexBinder, object[]> GetIndexOperation;
143 public Func<GetMemberBinder, object> GetMemberOperation;
144 public Action<InvokeBinder, object[]> InvokeOperation;
145 public Action<InvokeMemberBinder, object[]> InvokeMemberOperation;
146 public Action<SetIndexBinder, object[], object> SetIndexOperation;
147 public Action<SetMemberBinder, object> SetMemberOperation;
148 public Func<UnaryOperationBinder, object> UnaryOperation;
150 // Dynamic arguments methods
151 public DynamicObjectMock (int i)
155 public void DMethod (int a)
159 public static void DStaticMethod (object t)
163 public int this[int i] {
172 class Tester : DynamicObjectMock
174 static readonly int field = 7;
180 public Tester (dynamic d)
184 static void Assert<T> (T expected, T value, string name)
186 if (!EqualityComparer<T>.Default.Equals (expected, value)) {
187 if (!string.IsNullOrEmpty (name))
189 throw new ApplicationException (name + "Expected " + expected + " != " + value);
193 static void Assert<T> (IList<T> expected, IList<T> value, string name)
195 if (expected == null) {
197 throw new ApplicationException (name + ": Both arrays expected to be null");
201 if (expected.Count != value.Count)
202 throw new ApplicationException (name + ": Array length does not match " + expected.Count + " != " + value.Count);
204 for (int i = 0; i < expected.Count; ++i) {
205 if (!EqualityComparer<T>.Default.Equals (expected[i], value[i]))
206 throw new ApplicationException (name + ": Index " + i + ": " + expected[i] + " != " + value[i]);
210 static FieldInfo flags = typeof (CSharpArgumentInfo).GetField ("flags", BindingFlags.NonPublic | BindingFlags.Instance);
212 static void AssertArgument (CallSiteBinder obj, CSharpArgumentInfo[] expected, string name)
214 var ai = obj.GetType ().GetField ("argumentInfo", BindingFlags.NonPublic | BindingFlags.Instance);
215 IList<CSharpArgumentInfo> values = (IList<CSharpArgumentInfo>) ai.GetValue (obj);
216 if (values.Count != expected.Length)
217 throw new ApplicationException (name + ": Array length does not match " + values.Count + " != " + expected.Length);
219 for (int i = 0; i < expected.Length; i++) {
220 Assert (flags.GetValue (expected[i]), flags.GetValue (values[i]), "flags");
224 #pragma warning disable 168, 169, 219
226 void BinaryAdd_1 (dynamic d, DynamicObjectMock mock)
228 mock.BinaryOperation = (binder, arg) => {
229 Assert (binder.Operation, ExpressionType.Add, "Operation");
230 AssertArgument (binder, new[] {
231 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
232 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
235 Assert (arg, 1, "arg");
241 void BinaryAdd_2 (dynamic d, DynamicObjectMock mock)
243 mock.BinaryOperation = (binder, arg) => {
244 Assert (binder.Operation, ExpressionType.Add, "Operation");
245 AssertArgument (binder, new[] {
246 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
247 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null) },
250 Assert (arg, null, "arg");
257 void BinaryAdd_3 (dynamic d, DynamicObjectMock mock)
259 mock.BinaryOperation = (binder, arg) => {
260 Assert (binder.Operation, ExpressionType.Add, "Operation");
261 AssertArgument (binder, new[] {
262 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
263 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null)
266 Assert (arg, Enum.A, "arg");
272 void BinaryAdd_4 (dynamic d, DynamicObjectMock mock)
274 mock.BinaryOperation = (binder, arg) => {
275 Assert (binder.Operation, ExpressionType.Add, "Operation");
276 AssertArgument (binder, new[] {
277 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
278 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null) },
281 Assert (arg, 7, "arg");
284 d = d + Tester.field;
287 void BinaryAddChecked_1 (dynamic d, DynamicObjectMock mock)
289 mock.BinaryOperation = (binder, arg) => {
290 Assert (binder.Operation, ExpressionType.Add, "Operation");
291 AssertArgument (binder, new[] {
292 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
293 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null) },
296 Assert (arg, 3, "arg");
302 void BinaryAddChecked_2 (dynamic d, DynamicObjectMock mock)
304 mock.BinaryOperation = (binder, arg) => {
305 Assert (binder.Operation, ExpressionType.Add, "Operation");
306 AssertArgument (binder, new[] {
307 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
308 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null) },
311 Assert (arg, 3, "arg");
322 void BinaryAddAssign_1 (dynamic d, DynamicObjectMock mock)
324 mock.BinaryOperation = (binder, arg) => {
325 Assert (binder.Operation, ExpressionType.AddAssign, "Operation");
326 AssertArgument (binder, new[] {
327 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
328 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
331 Assert (arg, 1, "arg");
337 void BinaryAddAssignChecked_1 (dynamic d, DynamicObjectMock mock)
339 mock.BinaryOperation = (binder, arg) => {
340 Assert (binder.Operation, ExpressionType.AddAssign, "Operation");
341 AssertArgument (binder, new[] {
342 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
343 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
346 Assert (arg, 1, "arg");
354 void BinaryAnd_1 (dynamic d, DynamicObjectMock mock)
356 mock.BinaryOperation = (binder, arg) => {
357 Assert (binder.Operation, ExpressionType.And, "Operation");
358 AssertArgument (binder, new[] {
359 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
360 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
363 Assert (arg, 1, "arg");
369 void BinaryAndAssign_1 (dynamic d, DynamicObjectMock mock)
371 mock.BinaryOperation = (binder, arg) => {
372 Assert (binder.Operation, ExpressionType.AndAssign, "Operation");
373 AssertArgument (binder, new[] {
374 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
375 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
378 Assert (arg, 1, "arg");
384 void BinaryDivide_1 (dynamic d, DynamicObjectMock mock)
386 mock.BinaryOperation = (binder, arg) => {
387 Assert (binder.Operation, ExpressionType.Divide, "Operation");
388 AssertArgument (binder, new[] {
389 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
390 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
393 Assert (arg, 1, "arg");
399 void BinaryDivideAssign_1 (dynamic d, DynamicObjectMock mock)
401 mock.BinaryOperation = (binder, arg) => {
402 Assert (binder.Operation, ExpressionType.DivideAssign, "Operation");
403 AssertArgument (binder, new[] {
404 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
405 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
408 Assert (arg, 1, "arg");
414 void BinaryEqual_1 (dynamic d, DynamicObjectMock mock)
416 mock.BinaryOperation = (binder, arg) => {
417 Assert (binder.Operation, ExpressionType.Equal, "Operation");
418 AssertArgument (binder, new[] {
419 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
420 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
423 Assert (arg, 1, "arg");
429 void BinaryExclusiveOr_1 (dynamic d, DynamicObjectMock mock)
431 mock.BinaryOperation = (binder, arg) => {
432 Assert (binder.Operation, ExpressionType.ExclusiveOr, "Operation");
433 AssertArgument (binder, new[] {
434 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
435 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
438 Assert (arg, 1, "arg");
444 void BinaryExclusiveOrAssign_1 (dynamic d, DynamicObjectMock mock)
446 mock.BinaryOperation = (binder, arg) => {
447 Assert (binder.Operation, ExpressionType.ExclusiveOrAssign, "Operation");
448 AssertArgument (binder, new[] {
449 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
450 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
453 Assert (arg, 1, "arg");
459 void BinaryGreaterThan_1 (dynamic d, DynamicObjectMock mock)
461 mock.BinaryOperation = (binder, arg) => {
462 Assert (binder.Operation, ExpressionType.GreaterThan, "Operation");
463 AssertArgument (binder, new[] {
464 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
465 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
468 Assert (arg, 1, "arg");
474 void BinaryGreaterThanOrEqual_1 (dynamic d, DynamicObjectMock mock)
476 mock.BinaryOperation = (binder, arg) => {
477 Assert (binder.Operation, ExpressionType.GreaterThanOrEqual, "Operation");
478 AssertArgument (binder, new[] {
479 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
480 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
483 Assert (arg, 1, "arg");
489 void BinaryLeftShift_1 (dynamic d, DynamicObjectMock mock)
491 mock.BinaryOperation = (binder, arg) => {
492 Assert (binder.Operation, ExpressionType.LeftShift, "Operation");
493 AssertArgument (binder, new[] {
494 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
495 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
498 Assert (arg, 1, "arg");
504 void BinaryLeftShiftAssign_1 (dynamic d, DynamicObjectMock mock)
506 mock.BinaryOperation = (binder, arg) => {
507 Assert (binder.Operation, ExpressionType.LeftShiftAssign, "Operation");
508 AssertArgument (binder, new[] {
509 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
510 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
513 Assert (arg, 1, "arg");
519 void BinaryLessThan_1 (dynamic d, DynamicObjectMock mock)
521 mock.BinaryOperation = (binder, arg) => {
522 Assert (binder.Operation, ExpressionType.LessThan, "Operation");
523 AssertArgument (binder, new[] {
524 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
525 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
528 Assert (arg, 1, "arg");
534 void BinaryLessThanOrEqual_1 (dynamic d, DynamicObjectMock mock)
536 mock.BinaryOperation = (binder, arg) => {
537 Assert (binder.Operation, ExpressionType.LessThanOrEqual, "Operation");
538 AssertArgument (binder, new[] {
539 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
540 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
543 Assert (arg, 1, "arg");
549 void BinaryModulo_1 (dynamic d, DynamicObjectMock mock)
551 mock.BinaryOperation = (binder, arg) => {
552 Assert (binder.Operation, ExpressionType.Modulo, "Operation");
553 AssertArgument (binder, new[] {
554 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
555 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
558 Assert (arg, 1, "arg");
564 void BinaryModuloAssign_1 (dynamic d, DynamicObjectMock mock)
566 mock.BinaryOperation = (binder, arg) => {
567 Assert (binder.Operation, ExpressionType.ModuloAssign, "Operation");
568 AssertArgument (binder, new[] {
569 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
570 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
573 Assert (arg, 1, "arg");
579 void BinaryMultiply_1 (dynamic d, DynamicObjectMock mock)
581 mock.BinaryOperation = (binder, arg) => {
582 Assert (binder.Operation, ExpressionType.Multiply, "Operation");
583 AssertArgument (binder, new[] {
584 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
585 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
588 Assert (arg, 1, "arg");
594 void BinaryMultiplyAssign_1 (dynamic d, DynamicObjectMock mock)
596 mock.BinaryOperation = (binder, arg) => {
597 Assert (binder.Operation, ExpressionType.MultiplyAssign, "Operation");
598 AssertArgument (binder, new[] {
599 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
600 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
603 Assert (arg, 1, "arg");
609 void BinaryNotEqual_1 (dynamic d, DynamicObjectMock mock)
611 mock.BinaryOperation = (binder, arg) => {
612 Assert (binder.Operation, ExpressionType.NotEqual, "Operation");
613 AssertArgument (binder, new[] {
614 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
615 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
618 Assert (arg, 4, "arg");
624 void BinaryOr_1 (dynamic d, DynamicObjectMock mock)
626 mock.BinaryOperation = (binder, arg) => {
627 Assert (binder.Operation, ExpressionType.Or, "Operation");
628 AssertArgument (binder, new[] {
629 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
630 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
633 Assert (arg, 2, "arg");
639 void BinaryOrAssign_1 (dynamic d, DynamicObjectMock mock)
641 mock.BinaryOperation = (binder, arg) => {
642 Assert (binder.Operation, ExpressionType.OrAssign, "Operation");
643 AssertArgument (binder, new[] {
644 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
645 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
648 Assert (arg, 2, "arg");
654 void BinaryRightShift_1 (dynamic d, DynamicObjectMock mock)
656 mock.BinaryOperation = (binder, arg) => {
657 Assert (binder.Operation, ExpressionType.RightShift, "Operation");
658 AssertArgument (binder, new[] {
659 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
660 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
663 Assert (arg, 1, "arg");
669 void BinaryRightShiftAssign_1 (dynamic d, DynamicObjectMock mock)
671 mock.BinaryOperation = (binder, arg) => {
672 Assert (binder.Operation, ExpressionType.RightShiftAssign, "Operation");
673 AssertArgument (binder, new[] {
674 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
675 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
678 Assert (arg, 1, "arg");
684 void BinarySubtract_1 (dynamic d, DynamicObjectMock mock)
686 mock.BinaryOperation = (binder, arg) => {
687 Assert (binder.Operation, ExpressionType.Subtract, "Operation");
688 AssertArgument (binder, new[] {
689 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
690 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
693 Assert (arg, 1, "arg");
699 void BinarySubtractAssign_1 (dynamic d, DynamicObjectMock mock)
701 mock.BinaryOperation = (binder, arg) => {
702 Assert (binder.Operation, ExpressionType.SubtractAssign, "Operation");
703 AssertArgument (binder, new[] {
704 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
705 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
708 Assert (arg, 1, "arg");
714 void Convert_1 (dynamic d, DynamicObjectMock mock)
716 mock.ConvertOperation = (binder) => {
717 Assert (binder.Explicit, true, "Explicit");
718 Assert (binder.Type, typeof (byte), "Type");
725 void Convert_2 (dynamic d, DynamicObjectMock mock)
727 mock.ConvertOperation = (binder) => {
728 Assert (binder.Explicit, false, "Explicit");
729 Assert (binder.Type, typeof (int), "Type");
733 object[] o = new object[2];
737 void Convert_3 (dynamic d, DynamicObjectMock mock)
739 mock.ConvertOperation = (binder) => {
740 Assert (binder.Explicit, true, "Explicit");
741 // Assert (binder.IsChecked, true, "IsChecked");
742 Assert (binder.Type, typeof (byte), "Type");
746 object b = checked ((byte) d);
749 void Convert_4 (dynamic d, DynamicObjectMock mock)
751 mock.ConvertOperation = (binder) => {
752 Assert (binder.Explicit, false, "Explicit");
753 Assert (binder.Type, typeof (int), "Type");
760 void Convert_5 (dynamic d, DynamicObjectMock mock)
763 mock.ConvertOperation = (binder) => {
764 Assert (binder.Explicit, false, "Explicit");
765 Assert (binder.Type, typeof (System.Collections.IEnumerable), "Type");
766 return new object[] { 1 };
769 foreach (int v in d) {
770 // Console.WriteLine (v);
774 void GetIndex_1 (dynamic d, DynamicObjectMock mock)
776 mock.GetIndexOperation = (binder, args) => {
777 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
778 AssertArgument (binder, new[] {
779 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
780 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
783 Assert ((IList<object>) args, new object[] { 0 }, "args");
789 void GetIndex_2 (dynamic d, DynamicObjectMock mock)
791 mock.GetIndexOperation = (binder, args) => {
792 Assert (binder.CallInfo, new CallInfo (2, new string[0]), "CallInfo");
793 AssertArgument (binder, new[] {
794 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
795 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null),
796 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null) },
799 Assert ((IList<object>) args, new object[] { 2, 3 }, "args");
806 void GetIndex_3 (dynamic d, DynamicObjectMock mock)
808 mock.GetIndexOperation = (binder, args) => {
809 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
810 AssertArgument (binder, new[] {
811 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
812 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) },
815 Assert ((IList<object>) args, new object[] { d }, "args");
821 void GetMember_1 (dynamic d, DynamicObjectMock mock)
823 mock.GetMemberOperation = (binder) => {
824 Assert (binder.Name, "Foo", "Name");
825 Assert (binder.IgnoreCase, false, "IgnoreCase");
826 AssertArgument (binder, new[] {
827 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) },
836 void Invoke_1 (dynamic d, DynamicObjectMock mock)
838 mock.InvokeOperation = (binder, args) => {
839 Assert (binder.CallInfo, new CallInfo (2, new string[0]), "CallInfo");
840 AssertArgument (binder, new[] {
841 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
842 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null),
843 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant, null)
846 Assert ((IList<object>) args, new object[] { "foo", null }, "args");
852 void Invoke_2 (dynamic d, DynamicObjectMock mock)
854 mock.InvokeOperation = (binder, args) => {
855 Assert (binder.CallInfo, new CallInfo (0, new string[0]), "CallInfo");
856 AssertArgument (binder, new[] {
857 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) },
860 Assert ((IList<object>) args, new object[0], "args");
866 void Invoke_3 (dynamic d, DynamicObjectMock mock)
870 Assert (true, false, "No hook expected to be hit");
871 } catch (RuntimeBinderException) {
875 void Invoke_4 (dynamic d, DynamicObjectMock mock)
877 mock.InvokeOperation = (binder, args) => {
878 Assert (binder.CallInfo, new CallInfo (2, new string[] { "name" }), "CallInfo");
879 AssertArgument (binder, new[] {
880 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
881 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
882 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.NamedArgument | CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, "name")
885 Assert ((IList<object>) args, new object[] { typeof (bool), -1 }, "args");
888 d (typeof (bool), name: -1);
891 void Invoke_5 (dynamic d, DynamicObjectMock mock)
893 mock.InvokeOperation = (binder, args) => {
894 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
895 AssertArgument (binder, new[] {
896 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
897 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null)
900 Assert ((IList<object>) args, new object[] { "a" }, "args");
903 Action<dynamic> a = (i) => { i ("a"); };
907 void Invoke_6 (dynamic d, DynamicObjectMock mock)
909 mock.InvokeOperation = (binder, args) => {
910 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
911 AssertArgument (binder, new[] {
912 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
913 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null)
916 Assert ((IList<object>) args, new object[] { 3 }, "args");
922 void InvokeMember_1 (dynamic d, DynamicObjectMock mock)
924 mock.InvokeMemberOperation = (binder, args) => {
925 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
926 AssertArgument (binder, new[] {
927 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
928 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)},
931 Assert (binder.IgnoreCase, false, "IgnoreCase");
932 Assert ((IList<object>) args, new object[] { 'a' }, "args");
938 void InvokeMember_2 (dynamic d, DynamicObjectMock mock)
940 mock.InvokeMemberOperation = (binder, args) => {
941 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
942 AssertArgument (binder, new[] {
943 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
944 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)},
947 Assert (binder.IgnoreCase, false, "IgnoreCase");
948 Assert ((IList<object>) args, new object[] { mock }, "args");
954 void InvokeMember_3 (dynamic d, DynamicObjectMock mock)
956 mock.InvokeMemberOperation = (binder, args) => {
957 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
958 AssertArgument (binder, new[] {
959 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
960 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.IsRef | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
963 Assert (binder.IgnoreCase, false, "IgnoreCase");
964 Assert ((IList<object>) args, new object[] { 9 }, "args");
971 void InvokeMember_4 (dynamic d, DynamicObjectMock mock)
973 mock.InvokeMemberOperation = (binder, args) => {
974 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
975 AssertArgument (binder, new[] {
976 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
977 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.IsOut | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
980 Assert (binder.IgnoreCase, false, "IgnoreCase");
981 Assert ((IList<object>) args, new object[] { 0 }, "args");
988 void InvokeMember_5 (dynamic d, DynamicObjectMock mock)
990 DynamicObjectMock.DStaticMethod (d);
993 void InvokeMember_6 (dynamic d, DynamicObjectMock mock)
995 InvokeMemberOperation = (binder, args) => {
996 Assert (binder.CallInfo, new CallInfo (2, new string[0]), "CallInfo");
997 AssertArgument (binder, new[] {
998 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
999 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1000 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant, null),
1003 Assert (binder.IgnoreCase, false, "IgnoreCase");
1004 Assert ((IList<object>) args, new object[] { d, null }, "args");
1007 InvokeMember_5 (d, null);
1010 void InvokeMember_7 (dynamic d, DynamicObjectMock mock)
1012 mock.InvokeMemberOperation = (binder, args) => {
1013 Assert (binder.CallInfo, new CallInfo (0, new string[0]), "CallInfo");
1014 AssertArgument (binder, new[] {
1015 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1018 Assert (binder.IgnoreCase, false, "IgnoreCase");
1019 Assert ((IList<object>) args, new object[0], "args");
1025 void InvokeMember_8 (dynamic d, DynamicObjectMock mock)
1027 mock.InvokeMemberOperation = (binder, args) => {
1028 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
1029 AssertArgument (binder, new[] {
1030 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1031 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.IsRef | CSharpArgumentInfoFlags.UseCompileTimeType, null) },
1034 Assert (binder.IgnoreCase, false, "IgnoreCase");
1035 Assert ((IList<object>) args, new object[] { 9 }, "args");
1042 void SetIndex_1 (dynamic d, DynamicObjectMock mock)
1044 mock.SetIndexOperation = (binder, args, value) => {
1045 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
1046 AssertArgument (binder, new[] {
1047 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1048 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null),
1049 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)},
1052 Assert ((IList<object>) args, new object[] { 0 }, "args");
1053 Assert (value, 2m, "value");
1059 void SetIndex_2 (dynamic d, DynamicObjectMock mock)
1061 mock.SetIndexOperation = (binder, args, value) => {
1062 Assert (binder.CallInfo, new CallInfo (2, new string[0]), "CallInfo");
1063 AssertArgument (binder, new[] {
1064 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1065 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null),
1066 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
1067 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)
1070 Assert ((IList<object>) args, new object[] { 2, 3 }, "args");
1071 Assert (value, -8, "value");
1078 void SetIndex_3 (dynamic d, DynamicObjectMock mock)
1080 mock.SetIndexOperation = (binder, args, value) => {
1081 Assert (binder.CallInfo, new CallInfo (1, new string[0]), "CallInfo");
1082 AssertArgument (binder, new[] {
1083 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null),
1084 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1085 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType, null)
1088 Assert ((IList<object>) args, new object[] { d }, "args");
1089 Assert (value, this, "value");
1095 void SetMember_1 (dynamic d, DynamicObjectMock mock)
1097 const double d_const = 2.4;
1099 mock.SetMemberOperation = (binder, value) => {
1100 Assert (binder.Name, "Foo", "Name");
1101 Assert (binder.IgnoreCase, false, "IgnoreCase");
1102 AssertArgument (binder, new[] {
1103 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1104 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null)
1107 Assert (value, d_const, "value");
1113 void SetMember_2 (dynamic d, DynamicObjectMock mock)
1115 mock.GetMemberOperation = (binder) => {
1116 Assert (binder.Name, "Foo", "Name");
1117 Assert (binder.IgnoreCase, false, "IgnoreCase");
1118 AssertArgument (binder, new[] {
1119 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) },
1125 mock.BinaryOperation = (binder, arg) => {
1126 Assert (binder.Operation, ExpressionType.MultiplyAssign, "Operation");
1127 AssertArgument (binder, new[] {
1128 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1129 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant, null) },
1132 Assert (arg, null, "arg");
1135 mock.SetMemberOperation = (binder, value) => {
1136 Assert (binder.Name, "Foo", "Name");
1137 Assert (binder.IgnoreCase, false, "IgnoreCase");
1138 AssertArgument (binder, new[] {
1139 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1140 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1147 void UnaryPlus_1 (dynamic d, DynamicObjectMock mock)
1149 mock.UnaryOperation = (binder) => {
1150 Assert (binder.Operation, ExpressionType.UnaryPlus, "Operation");
1151 AssertArgument (binder, new[] {
1152 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1161 void UnaryMinus_1 (dynamic d, DynamicObjectMock mock)
1163 mock.UnaryOperation = (binder) => {
1164 Assert (binder.Operation, ExpressionType.Negate, "Operation");
1165 AssertArgument (binder, new[] {
1166 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1175 void UnaryNot_1 (dynamic d, DynamicObjectMock mock)
1177 mock.UnaryOperation = (binder) => {
1178 Assert (binder.Operation, ExpressionType.Not, "Operation");
1179 AssertArgument (binder, new[] {
1180 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1189 void UnaryOnesComplement_1 (dynamic d, DynamicObjectMock mock)
1191 mock.UnaryOperation = (binder) => {
1192 Assert (binder.Operation, ExpressionType.OnesComplement, "Operation");
1193 AssertArgument (binder, new[] {
1194 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1203 void UnaryDecrement_1 (dynamic d, DynamicObjectMock mock)
1205 mock.UnaryOperation = (binder) => {
1206 Assert (binder.Operation, ExpressionType.Decrement, "Operation");
1207 AssertArgument (binder, new[] {
1208 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1217 void UnaryDecrement_2 (dynamic d, DynamicObjectMock mock)
1219 mock.UnaryOperation = (binder) => {
1220 Assert (binder.Operation, ExpressionType.Decrement, "Operation");
1221 AssertArgument (binder, new[] {
1222 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1225 return new object ();
1231 void UnaryIncrement_1 (dynamic d, DynamicObjectMock mock)
1233 mock.UnaryOperation = (binder) => {
1234 Assert (binder.Operation, ExpressionType.Increment, "Operation");
1235 AssertArgument (binder, new[] {
1236 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1245 void UnaryIncrement_2 (dynamic d, DynamicObjectMock mock)
1247 mock.UnaryOperation = (binder) => {
1248 Assert (binder.Operation, ExpressionType.Increment, "Operation");
1249 AssertArgument (binder, new[] {
1250 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1253 return new object ();
1259 void UnaryIsFalse_1 (dynamic d, DynamicObjectMock mock)
1261 mock.UnaryOperation = (binder) => {
1262 Assert (binder.Operation, ExpressionType.IsFalse, "Operation");
1263 AssertArgument (binder, new[] {
1264 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1270 mock.BinaryOperation = (binder, arg) => {
1271 Assert (binder.Operation, ExpressionType.Equal, "Operation");
1272 AssertArgument (binder, new[] {
1273 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1274 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant, null) },
1277 Assert (arg, null, "arg");
1280 object x = d == null;
1283 void UnaryIsFalse_2 (dynamic d, DynamicObjectMock mock)
1285 mock.UnaryOperation = (binder) => {
1286 Assert (binder.Operation, ExpressionType.IsFalse, "Operation");
1287 AssertArgument (binder, new[] {
1288 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1294 mock.BinaryOperation = (binder, arg) => {
1295 Assert (binder.Operation, ExpressionType.NotEqual, "Operation");
1296 AssertArgument (binder, new[] {
1297 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1298 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant, null) },
1301 Assert (arg, null, "arg");
1304 object x = d != null;
1307 void UnaryIsFalse_3 (dynamic d, DynamicObjectMock mock)
1309 mock.UnaryOperation = (binder) => {
1310 Assert (binder.Operation, ExpressionType.IsFalse, "Operation");
1311 AssertArgument (binder, new[] {
1312 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1318 mock.BinaryOperation = (binder, arg) => {
1319 Assert (binder.Operation, ExpressionType.And, "Operation");
1320 AssertArgument (binder, new[] {
1321 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1322 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant, null) },
1325 Assert (arg, null, "arg");
1328 object x = d && null;
1331 void UnaryIsTrue_1 (dynamic d, DynamicObjectMock mock)
1333 mock.UnaryOperation = (binder) => {
1334 Assert (binder.Operation, ExpressionType.IsTrue, "Operation");
1335 AssertArgument (binder, new[] {
1336 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1342 object g = d ? 1 : 4;
1345 void UnaryIsTrue_2 (dynamic d, DynamicObjectMock mock)
1347 mock.UnaryOperation = (binder) => {
1348 Assert (binder.Operation, ExpressionType.IsTrue, "Operation");
1349 AssertArgument (binder, new[] {
1350 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)
1356 mock.BinaryOperation = (binder, arg) => {
1357 Assert (binder.Operation, ExpressionType.Or, "Operation");
1358 AssertArgument (binder, new[] {
1359 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null),
1360 CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant, null) },
1363 Assert (arg, null, "arg");
1366 object x = d || null;
1369 #pragma warning restore 168, 169, 219
1371 static bool RunTest (MethodInfo test)
1373 Console.Write ("Running test {0, -25}", test.Name);
1375 var d = new DynamicObjectMock ();
1376 test.Invoke (new Tester (), new[] { d, d });
1377 if (d.HitCounter < 1)
1378 Assert (true, false, "HitCounter");
1380 Console.WriteLine ("OK");
1382 } catch (Exception e) {
1383 Console.WriteLine ("FAILED");
1384 Console.WriteLine (e.ToString ());
1389 public static int Main ()
1391 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
1392 where test.GetParameters ().Length == 2
1394 select RunTest (test);
1396 int failures = tests.Count (a => !a);
1397 Console.WriteLine (failures + " tests failed");