public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint)
        {
            var methE = expression as MethodCallExpression;
            if (methE != null)
            {
                if (methE.Method == ObjectEqualsMethodInfo)
                {
                    var left = parser.DynamicInvoke(methE.Arguments[0]);
                    var right = parser.DynamicInvoke(methE.Arguments[1]);

                    if (left is Delegate || right is Delegate)
                    {
                        if (CheckArgument(parser, methE, true, out hint))
                        {
                            return true;
                        }

                        if (CheckArgument(parser, methE, false, out hint))
                        {
                            return true;
                        }

                        hint = ", this is a suspicious comparison";
                        return true;
                    }
                }
            }

            hint = null;
            return false;
        }
 public void ParseStringConstant()
 {
     Expression<Func<string>> f = () => "foo";
     var p = new ExpressionParser(f.Body);
     ConstantNode constantNode = p.Parse() as ConstantNode;
     Assert.AreEqual("\"foo\"", constantNode.Text);
 }
        static bool CheckArgument(ExpressionParser parser, MethodCallExpression methE, bool left, out string hint)
        {
            int ix1 = left ? 0 : 1;
            int ix2 = left ? 1 : 0;

            if (typeof (Delegate).IsAssignableFrom(methE.Arguments[ix1].Type))
            {
                object leftR;
                try
                {
                    leftR = parser.DynamicInvoke(Expression.Invoke(methE.Arguments[ix1]));
                }
                catch (InvalidOperationException) // delegate needs arguments
                {
                    hint = null;
                    return false;
                }

                if (Equals(leftR, parser.DynamicInvoke(methE.Arguments[ix2])))
                {
                    hint = string.Format(", but would have been True if you had invoked '{0}'",
                        NodeFormatter.PrettyPrint(parser.Parse(methE.Arguments[ix1])));
                    return true;
                }
            }

            hint = null;
            return false;
        }
 public void ParsePrimitiveConstant()
 {
     Expression<Func<int>> f = () => 5;
     var p = new ExpressionParser(f.Body);
     ConstantNode constantNode = p.Parse() as ConstantNode;
     Assert.AreEqual("5", constantNode.Text);
 }
 public void ParsePrimitiveStaticField()
 {
     Expression<Func<int>> f = () => field;
     var p = new ExpressionParser(f.Body);
     ConstantNode constantNode = p.Parse() as ConstantNode;
     Assert.AreEqual("field", constantNode.Text);
     Assert.AreEqual("5", constantNode.Value);
 }
 public void ParseMember()
 {
     int x = 5;
     Expression<Func<int>> f = () => x;
     var p = new ExpressionParser(f.Body);
     Node constantNode = p.Parse();
     Assert.AreEqual(new ConstantNode {Text = "x", Value = "5"}, constantNode);
 }
        public void ShouldTriggerOnTotalMisusageWithObjectEquals_Right()
        {
            var hint = new TimeSpanTotalMistakesHint();

            Expression<Func<bool>> x = () => Equals(63, TimeSpan.FromMinutes(63).Minutes);
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNotNull(description);
        }
        public void DoesntTriggerIfNotComparesEqual()
        {
            var hint = new MethodEqualsInsteadOfOperatorEqualsHint();

            Expression<Func<bool>> exp = () => new NeverEqual() == new NeverEqual();
            var p = new ExpressionParser(exp.Body);

            string description;
            Assert.IsFalse(hint.TryGetHint(p, exp.Body, out description));
            Assert.IsNull(description);
        }
        public void TriggersIfComparesEqual()
        {
            var hint = new MethodEqualsInsteadOfOperatorEqualsHint();

            Expression<Func<bool>> exp = () => new AlwaysEqual() == new AlwaysEqual();
            var p = new ExpressionParser(exp.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, exp.Body, out description));
            Assert.IsNotNull(description);
        }
        public void DoesTriggerOnDifferentStrings()
        {
            var hint = new StringOperatorEqualsHint();

            Expression<Func<bool>> x = () => new string('x', 1) == "X"; // prevent inlining the constant
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNotNull(description);
        }
        public void HintPicksUpDiff()
        {
            var hint = new StringEqualsHint();

            Expression<Func<bool>> x = () => "x".Equals("X");
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNotNull(description);
        }
        public void HintObeysComparer()
        {
            var hint = new StringEqualsHint();

            Expression<Func<bool>> x = () => "x".Equals("X", StringComparison.OrdinalIgnoreCase);
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsFalse(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNull(description);
        }
        public void ShouldNotTriggerOnSequencesComparedWithEquals()
        {
            var hint = new SequenceEqualHint();

            Expression<Func<bool>> exp = () => new List<int> {1}.Equals(new[] {2});
            var p = new ExpressionParser(exp.Body);

            string description;
            Assert.IsFalse(hint.TryGetHint(p, exp.Body, out description));
            Assert.IsNull(description);
        }
        protected override bool TryGetHint(ExpressionParser parser, object left, object right, out string hint)
        {
            if (Equals(left, right))
            {
                hint = ", but would have been True with Equals()";
                return true;
            }

            hint = null;
            return false;
        }
        public void ShouldBeTriggeredWithoutClosure_Right()
        {
            var hint = new DelegateShouldHaveBeenInvokedEqualsHint();

            Func<int> f = () => 3;

            Expression<Func<bool>> ex = () => Equals(3, f);
            var p = new ExpressionParser(ex.Body);

            string ignored;
            Assert.IsTrue(hint.TryGetHint(p, ex.Body, out ignored));
            Assert.IsNotNull(ignored);
        }
        public void ShouldPickUpTabVsSpace()
        {
            var hint = new StringOperatorEqualsHint();

            Expression<Func<bool>> x = () => new string(' ', 1) == "\t"; // prevent inlining the constant
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNotNull(description);

            Assert.IsTrue(description.Contains("tab"));
        }
        public void ShouldPickUpMismatchedNewlines()
        {
            var hint = new StringEqualsHint();

            Expression<Func<bool>> x = () => new string('\n', 1).Equals("\r\n");
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNotNull(description);

            Assert.IsTrue(description.Contains("carriage-return"));
        }
        public void ShouldPickUpControlCharacters()
        {
            var hint = new StringOperatorEqualsHint();

            Expression<Func<bool>> x = () => new string('\0', 1) + "Hello" == "Hello"; // prevent inlining the constant
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNotNull(description);

            Assert.IsTrue(description.Contains("control"));
        }
        public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint)
        {
            foreach (var hinter in _hints)
            {
                if (hinter.TryGetHint(parser, expression, out hint))
                {
                    return true;
                }
            }

            hint = null;
            return false;
        }
        public void ShouldPickUpTabVsSpace()
        {
            var hint = new StringEqualsHint();

            Expression<Func<bool>> x = () => " ".Equals("\t");
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNotNull(description);

            Assert.IsTrue(description.Contains("tab"));
        }
        public void ShouldPickUpDecomposedCharacters()
        {
            var hint = new StringEqualsHint();

            Expression<Func<bool>> x = () => ConstantStrings.AcuteEComposed.Equals(ConstantStrings.AcuteEDecomposed);
            var p = new ExpressionParser(x.Body);

            string description;
            Assert.IsTrue(hint.TryGetHint(p, x.Body, out description));
            Assert.IsNotNull(description);

            Assert.IsTrue(description.Contains("decomposed"));
        }
        public void ShouldTriggerOnSequenceEqualEnumerables()
        {
            var hint = new EnumerableOperatorEqualsHint();

            var x = new[] {3};
            var y = new[] {3};

            Expression<Func<bool>> assertion = () => x == y;
            var p = new ExpressionParser(assertion.Body);

            string message;
            Assert.IsTrue(hint.TryGetHint(p, assertion.Body, out message));
            Assert.IsNotNull(message);
        }
        protected override bool TryGetHint(ExpressionParser parser, object left, object right, out string hint)
        {
            if (left is IEnumerable && right is IEnumerable)
            {
                if (((IEnumerable) left).Cast<object>().SequenceEqual(((IEnumerable) right).Cast<object>()))
                {
                    hint = ", but would have been True with .SequenceEqual()";
                    return true;
                }
            }

            hint = null;
            return false;
        }
        public void ShouldTriggerForDifferentEnumerables()
        {
            var hint = new EnumerableOperatorEqualsHint();

            object x = new[] {3};
            object y = new List<int> {3};

            Expression<Func<bool>> assertion = () => x == y;
            var p = new ExpressionParser(assertion.Body);

            string message;
            Assert.IsTrue(hint.TryGetHint(p, assertion.Body, out message));
            Assert.IsNotNull(message);
        }
        public void ShouldntTriggerOnEqualsMethod()
        {
            var hint = new EnumerableOperatorEqualsHint();

            var x = new[] {3};
            var y = new[] {3};

            Expression<Func<bool>> assertion = () => x.Equals(y);
            var p = new ExpressionParser(assertion.Body);

            string message;
            Assert.IsFalse(hint.TryGetHint(p, assertion.Body, out message));
            Assert.IsNull(message);
        }
        public void ShouldBeTriggeredWithClosure_Left()
        {
            var hint = new DelegateShouldHaveBeenInvokedEqualsHint();

            int n = 3;
            Func<int> f = () => n; // now this func requires a closure

            Expression<Func<bool>> ex = () => Equals(f, 3);
            var p = new ExpressionParser(ex.Body);

            string ignored;
            Assert.IsTrue(hint.TryGetHint(p, ex.Body, out ignored));
            Assert.IsNotNull(ignored);
        }
        public void ShouldNotBeTriggeredIfBothAreDelegates()
        {
            var hint = new DelegateShouldHaveBeenInvokedEqualsHint();

            Func<int> f = () => 3;

            Expression<Func<bool>> ex = () => Equals(f, f);
            var p = new ExpressionParser(ex.Body);

            string ignored;
            Assert.IsTrue(hint.TryGetHint(p, ex.Body, out ignored));

            Assert.IsTrue(ignored.Contains("suspicious"));
        }
        public void TestFloatFloatComparison()
        {
            float d = 0.1f;
            float f = d*100;
            f /= 100;

            var floatHint = new FloatEqualityHint();

            Expression<Func<bool>> exp = () => d == f;
            var p = new ExpressionParser(exp.Body);

            string description;
            Assert.IsTrue(floatHint.TryGetHint(p, exp.Body, out description));
            Assert.IsNotNull(description);
        }
        public void ParseMemberAccess()
        {
            DateTime d = new DateTime(2010, 12, 25);
            Expression<Func<int>> f = () => d.Day;
            var p = new ExpressionParser(f.Body);
            MemberAccessNode node = (MemberAccessNode) p.Parse();

            MemberAccessNode expected = new MemberAccessNode
            {
                Container = new ConstantNode {Text = "d", Value = d.ToString()},
                MemberName = "Day",
                MemberValue = "25"
            };

            Assert.AreEqual(expected, node);
        }
        public void ParseMethodAccess()
        {
            string s = "hello";
            Expression<Func<string>> f = () => s.Substring(1);
            var p = new ExpressionParser(f.Body);
            var node = p.Parse();

            var expected = new MethodCallNode
            {
                Container = new ConstantNode {Text = "s", Value = @"""hello"""},
                MemberName = "Substring",
                MemberValue = @"""ello""",
                Parameters = new List<Node>() {new ConstantNode {Text = "1"}}
            };

            Assert.AreEqual(expected, node);
        }
Exemple #31
0
        internal static string FormatObject(object value)
        {
            if (value == null)
            {
                return("null");
            }
            if (value is string)
            {
                return("\"" + value + "\"");
            }
            if (value is char)
            {
                return("'" + value + "'");
            }

            var exception = value as Exception;

            if (exception != null)
            {
                return("{" + exception.GetType().Name + "}");
            }

            var type = value.GetType();

            if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))
            {
                var k = type.GetRuntimeProperty("Key").GetValue(value, null);
                var v = type.GetRuntimeProperty("Value").GetValue(value, null);
                return(String.Format("{{{0}:{1}}}", FormatObject(k), FormatObject(v)));
            }
            if (type.GetTypeInfo().ImplementedInterfaces
                .Where(i => i.IsConstructedGenericType)
                .Any(i => i.GetGenericTypeDefinition() == typeof(IGrouping <,>)))
            {
                var k = type.GetRuntimeProperty("Key").GetValue(value, null);
                return(String.Format("{{{0}:{1}}}", FormatObject(k), FormatEnumerable(value)));
            }
            if (value is Type)
            {
                return("typeof(" + ExpressionParser.NameOfType((Type)value) + ")");
            }
            if (value is Delegate)
            {
                var del = (Delegate)value;


                return(String.Format("delegate {0}, type: {2} ({1})", ExpressionParser.NameOfType(del.GetType()), String.Join(", ", del.GetMethodInfo().GetParameters().Select(x => ExpressionParser.NameOfType(x.ParameterType))), ExpressionParser.NameOfType(del.GetMethodInfo().ReturnType)));
            }
            if (value is IEnumerable)
            {
                return(FormatEnumerable(value));
            }
            return(value.ToString());
        }
        internal static string FormatObject(object value)
        {
            if (value == null)
            {
                return("null");
            }
            if (value is string)
            {
                return("\"" + value + "\"");
            }
            if (value is char)
            {
                return("'" + value + "'");
            }

            var exception = value as Exception;

            if (exception != null)
            {
                return("{" + exception.GetType().Name + "}");
            }

            var type = value.GetType();

#if NETCOREAPP1_1
            var isGenericType = new Func <Type, bool>(t => t.GetTypeInfo().IsGenericType);
#else
            var isGenericType = new Func <Type, bool>(t => t.IsGenericType);
#endif
            if (isGenericType(type) && type.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))
            {
                var k = type.GetProperty("Key").GetValue(value, null);
                var v = type.GetProperty("Value").GetValue(value, null);
                return(String.Format("{{{0}:{1}}}", FormatObject(k), FormatObject(v)));
            }
            if (type.GetInterfaces()
                .Where(isGenericType)
                .Any(i => i.GetGenericTypeDefinition() == typeof(IGrouping <,>)))
            {
                var k = type.GetProperty("Key").GetValue(value, null);
                return(String.Format("{{{0}:{1}}}", FormatObject(k), FormatEnumerable(value)));
            }
            if (value is Type)
            {
                return("typeof(" + ExpressionParser.NameOfType((Type)value) + ")");
            }
            if (value is Delegate)
            {
                var del = (Delegate)value;

#if NETCOREAPP1_1
                var method = RuntimeReflectionExtensions.GetMethodInfo(del);
#else
                var method = del.Method;
#endif

                return(String.Format("delegate {0}, type: {2} ({1})", ExpressionParser.NameOfType(del.GetType()), String.Join(", ", method.GetParameters().Select(x => ExpressionParser.NameOfType(x.ParameterType))), ExpressionParser.NameOfType(method.ReturnType)));
            }
            if (value is IEnumerable)
            {
                return(FormatEnumerable(value));
            }
            return(value.ToString());
        }