public static void TestBindParams(DynamicMetaObject target, DynamicMetaObject arg)
            {
                BinaryOperationBinder binder = new TestBinaryOperationBinder(ExpressionType.Equal);

                ExceptionTestHelper.ExpectException <ArgumentNullException>(() => { var result = target.BindBinaryOperation(null, arg); });
                ExceptionTestHelper.ExpectException <ArgumentNullException>(() => { var result = target.BindBinaryOperation(binder, null); });
            }
        public void BindBinaryOperationInvalidTest()
        {
            DynamicMetaObject target;

            DynamicMetaObject argPrimitive    = new DynamicMetaObject(Expression.Constant(10), BindingRestrictions.Empty);
            DynamicMetaObject argNonPrimitive = new DynamicMetaObject(Expression.Constant(AnyInstance.AnyJsonObject), BindingRestrictions.Empty);

            foreach (JsonValue value in AnyInstance.AnyJsonValueArray)
            {
                target = GetJsonValueDynamicMetaObject(value);

                TestBinaryOperationBinder.TestMetaObject(target, argPrimitive, TestBinaryOperationBinder.UnsupportedOperations, false);
            }

            foreach (JsonValue value in AnyInstance.AnyJsonValueArray)
            {
                target = GetJsonValueDynamicMetaObject(value);

                if (value is JsonPrimitive)
                {
                    //// not supported on operand of type JsonValue if it isn't a primitive and not comparing JsonValue types.
                    TestBinaryOperationBinder.TestMetaObject(target, argNonPrimitive, TestBinaryOperationBinder.NumberOperations, false);
                    TestBinaryOperationBinder.TestMetaObject(target, argNonPrimitive, TestBinaryOperationBinder.BoolOperations, false);
                }
                else
                {
                    //// When value is non-primitive, it must be a compare operation and (the other operand must be null or a JsonValue)
                    TestBinaryOperationBinder.TestMetaObject(target, argPrimitive, TestBinaryOperationBinder.NumberOperations, false);
                    TestBinaryOperationBinder.TestMetaObject(target, argPrimitive, TestBinaryOperationBinder.BoolOperations, false);
                }
            }
        }
            public static void TestMetaObject(DynamicMetaObject target, DynamicMetaObject arg, ExpressionType[] testExpressions, bool isValid = true)
            {
                foreach (ExpressionType expType in testExpressions)
                {
                    BinaryOperationBinder binder = new TestBinaryOperationBinder(expType);
                    DynamicMetaObject     result = target.BindBinaryOperation(binder, arg);
                    Assert.IsNotNull(result);

                    //The resulting expression is a convert expression, that's why we are checking for unary expression here.
                    UnaryExpression expression = result.Expression as UnaryExpression;
                    Assert.IsNotNull(expression);

                    // The operand expression is supposed to be a binary expression.
                    ExpressionType expectedType = isValid ? expType : ExpressionType.Throw;
                    Assert.AreEqual <ExpressionType>(expectedType, expression.Operand.NodeType);
                }
            }
        public void BindBinaryOperationTest()
        {
            //// Binary operators: +, -, *, /, %, &, |, ^, <<, >>, ==, !=, >, <, >=, <=
            //// The '&&' and '||' operators are conditional versions of the '&' and '|' operators.

            JsonValue         value;
            DynamicMetaObject target;
            DynamicMetaObject arg;

            value  = AnyInstance.AnyInt;
            target = GetJsonValueDynamicMetaObject(value);
            arg    = new DynamicMetaObject(Expression.Constant(AnyInstance.AnyInt), BindingRestrictions.Empty, AnyInstance.AnyInt);

            TestBinaryOperationBinder.TestBindParams(target, arg);
            TestBinaryOperationBinder.TestMetaObject(target, arg, TestBinaryOperationBinder.NumberOperations);

            value  = AnyInstance.AnyBool;
            target = GetJsonValueDynamicMetaObject(value);
            arg    = new DynamicMetaObject(Expression.Constant(AnyInstance.AnyBool), BindingRestrictions.Empty, AnyInstance.AnyBool);
            TestBinaryOperationBinder.TestMetaObject(target, arg, TestBinaryOperationBinder.BoolOperations);

            arg = target;
            foreach (JsonValue otherValue in AnyInstance.AnyJsonValueArray)
            {
                if (!(otherValue is JsonPrimitive))
                {
                    target = GetJsonValueDynamicMetaObject(otherValue);
                    TestBinaryOperationBinder.TestMetaObject(target, arg, TestBinaryOperationBinder.CompareOperations);
                }
            }

            arg = new DynamicMetaObject(Expression.Constant(null), BindingRestrictions.Empty);
            foreach (JsonValue otherValue in AnyInstance.AnyJsonValueArray)
            {
                target = GetJsonValueDynamicMetaObject(otherValue);
                TestBinaryOperationBinder.TestMetaObject(target, arg, TestBinaryOperationBinder.CompareOperations);
            }
        }
            public static void TestMetaObject(DynamicMetaObject target, DynamicMetaObject arg, ExpressionType[] testExpressions, bool isValid = true)
            {
                foreach (ExpressionType expType in testExpressions)
                {
                    BinaryOperationBinder binder = new TestBinaryOperationBinder(expType);
                    DynamicMetaObject result = target.BindBinaryOperation(binder, arg);
                    Assert.IsNotNull(result);

                    //The resulting expression is a convert expression, that's why we are checking for unary expression here.
                    UnaryExpression expression = result.Expression as UnaryExpression;
                    Assert.IsNotNull(expression);

                    // The operand expression is supposed to be a binary expression.
                    ExpressionType expectedType = isValid ? expType : ExpressionType.Throw;
                    Assert.AreEqual<ExpressionType>(expectedType, expression.Operand.NodeType);
                }
            }
            public static void TestBindParams(DynamicMetaObject target, DynamicMetaObject arg)
            {
                BinaryOperationBinder binder = new TestBinaryOperationBinder(ExpressionType.Equal);

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