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); }
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()); }