public static void TestMetaObject(DynamicMetaObject target, string methodName, object[] arguments, bool isExtension = false)
            {
                InvokeMemberBinder binder = new TestInvokeMemberBinder(methodName, arguments.Length);

                DynamicMetaObject[] args = new DynamicMetaObject[arguments.Length];

                for (int idx = 0; idx < args.Length; idx++)
                {
                    object value     = arguments[idx];
                    Type   valueType = value != null?value.GetType() : typeof(object);

                    args[idx] = new DynamicMetaObject(Expression.Parameter(valueType), BindingRestrictions.Empty, value);
                }

                DynamicMetaObject result = target.BindInvokeMember(binder, args);

                Assert.IsNotNull(result);

                if (isExtension)
                {
                    UnaryExpression expression = result.Expression as UnaryExpression;
                    Assert.IsNotNull(expression);

                    MethodCallExpression callExpression = expression.Operand as MethodCallExpression;
                    Assert.IsNotNull(callExpression);

                    Assert.IsTrue(callExpression.Method.ToString().Contains(methodName));
                }
                else
                {
                    Assert.AreSame(target, result.Value);
                }
            }
            public static void TestBindParams(DynamicMetaObject target)
            {
                string methodName = "ToString";

                object[] arguments = new object[] { };

                InvokeMemberBinder binder = new TestInvokeMemberBinder(methodName, arguments.Length);

                DynamicMetaObject[] args = new DynamicMetaObject[arguments.Length];

                ExceptionTestHelper.ExpectException <ArgumentNullException>(() => { var result = target.BindInvokeMember(null, args); });
                ExceptionTestHelper.ExpectException <ArgumentNullException>(() => { var result = target.BindInvokeMember(binder, null); });
            }
        public void BindInvokeMemberTest()
        {
            JsonValue         value  = AnyInstance.AnyJsonValue1;
            DynamicMetaObject target = GetJsonValueDynamicMetaObject(value);

            TestInvokeMemberBinder.TestBindParams(target);

            string methodName;

            object[] arguments;
            object   result = null;

            methodName = "ToString";
            arguments  = new object[] { };
            TestInvokeMemberBinder.TestMetaObject(target, methodName, arguments);

            methodName = "TryReadAs";
            arguments  = new object[] { typeof(int), result };
            TestInvokeMemberBinder.TestMetaObject(target, methodName, arguments);

            methodName = "TryReadAsType";
            arguments  = new object[] { typeof(Person), result };
            TestInvokeMemberBinder.TestMetaObject(target, methodName, arguments, true);
        }
            public static void TestMetaObject(DynamicMetaObject target, string methodName, object[] arguments, bool isExtension = false)
            {
                InvokeMemberBinder binder = new TestInvokeMemberBinder(methodName, arguments.Length);
                DynamicMetaObject[] args = new DynamicMetaObject[arguments.Length];

                for (int idx = 0; idx < args.Length; idx++)
                {
                    object value = arguments[idx];
                    Type valueType = value != null ? value.GetType() : typeof(object);
                    args[idx] = new DynamicMetaObject(Expression.Parameter(valueType), BindingRestrictions.Empty, value);
                }

                DynamicMetaObject result = target.BindInvokeMember(binder, args);
                Assert.IsNotNull(result);

                if (isExtension)
                {
                    UnaryExpression expression = result.Expression as UnaryExpression;
                    Assert.IsNotNull(expression);

                    MethodCallExpression callExpression = expression.Operand as MethodCallExpression;
                    Assert.IsNotNull(callExpression);

                    Assert.IsTrue(callExpression.Method.ToString().Contains(methodName));
                }
                else
                {
                    Assert.AreSame(target, result.Value);
                }
            }
            public static void TestBindParams(DynamicMetaObject target)
            {
                string methodName = "ToString";
                object[] arguments = new object[] { };

                InvokeMemberBinder binder = new TestInvokeMemberBinder(methodName, arguments.Length);
                DynamicMetaObject[] args = new DynamicMetaObject[arguments.Length];

                ExceptionTestHelper.ExpectException<ArgumentNullException>(() => { var result = target.BindInvokeMember(null, args); });
                ExceptionTestHelper.ExpectException<ArgumentNullException>(() => { var result = target.BindInvokeMember(binder, null); });
            }