diff --git a/src/Moq/Match.cs b/src/Moq/Match.cs index adf2ffc8a..4dd855794 100644 --- a/src/Moq/Match.cs +++ b/src/Moq/Match.cs @@ -2,6 +2,7 @@ // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. using System; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; using System.Reflection; @@ -108,24 +109,28 @@ internal Match(Predicate condition, Expression> renderExpression, Act internal override bool Matches(object value) { - bool canCastValueToT; + return CanCast(value) && this.Condition((T)value); + } + + internal override void SetupEvaluatedSuccessfully(object value) + { + Debug.Assert(this.Matches(value)); + Debug.Assert(CanCast(value)); + + this.Success?.Invoke((T)value); + } + private static bool CanCast(object value) + { if (value != null) { - canCastValueToT = value is T; + return value is T; } else { var t = typeof(T); - canCastValueToT = !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)); + return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)); } - - return canCastValueToT && this.Condition((T)value); - } - - internal override void SetupEvaluatedSuccessfully(object value) - { - this.Success?.Invoke((T)value); } /// diff --git a/src/Moq/Matchers/AnyMatcher.cs b/src/Moq/Matchers/AnyMatcher.cs index 6f6c6cdba..f10c27ea7 100644 --- a/src/Moq/Matchers/AnyMatcher.cs +++ b/src/Moq/Matchers/AnyMatcher.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD. // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. +using System.Diagnostics; + namespace Moq.Matchers { internal sealed class AnyMatcher : IMatcher @@ -15,6 +17,7 @@ private AnyMatcher() public void SetupEvaluatedSuccessfully(object value) { + Debug.Assert(this.Matches(value)); } } } diff --git a/src/Moq/Matchers/ConstantMatcher.cs b/src/Moq/Matchers/ConstantMatcher.cs index 1e9d68189..b36b6928d 100644 --- a/src/Moq/Matchers/ConstantMatcher.cs +++ b/src/Moq/Matchers/ConstantMatcher.cs @@ -2,8 +2,8 @@ // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. using System.Collections; +using System.Diagnostics; using System.Linq; -using System.Linq.Expressions; namespace Moq.Matchers { @@ -37,6 +37,7 @@ public bool Matches(object value) public void SetupEvaluatedSuccessfully(object value) { + Debug.Assert(this.Matches(value)); } private bool MatchesEnumerable(IEnumerable enumerable) diff --git a/src/Moq/Matchers/ExpressionMatcher.cs b/src/Moq/Matchers/ExpressionMatcher.cs index 6c59409e2..36d2fcf92 100644 --- a/src/Moq/Matchers/ExpressionMatcher.cs +++ b/src/Moq/Matchers/ExpressionMatcher.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD. // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. -using System; +using System.Diagnostics; using System.Linq.Expressions; namespace Moq.Matchers @@ -23,6 +23,7 @@ public bool Matches(object value) public void SetupEvaluatedSuccessfully(object value) { + Debug.Assert(this.Matches(value)); } } } diff --git a/src/Moq/Matchers/LazyEvalMatcher.cs b/src/Moq/Matchers/LazyEvalMatcher.cs index 8f0b74558..7ae5130e0 100644 --- a/src/Moq/Matchers/LazyEvalMatcher.cs +++ b/src/Moq/Matchers/LazyEvalMatcher.cs @@ -2,6 +2,7 @@ // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. using System; +using System.Diagnostics; using System.Linq.Expressions; namespace Moq.Matchers @@ -28,6 +29,7 @@ public bool Matches(object value) public void SetupEvaluatedSuccessfully(object value) { + Debug.Assert(this.Matches(value)); } } } diff --git a/src/Moq/Matchers/MatcherAttributeMatcher.cs b/src/Moq/Matchers/MatcherAttributeMatcher.cs index 1aa1401d1..7e19d03e7 100644 --- a/src/Moq/Matchers/MatcherAttributeMatcher.cs +++ b/src/Moq/Matchers/MatcherAttributeMatcher.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.Linq; using System.Linq.Expressions; @@ -91,6 +92,7 @@ public bool Matches(object value) public void SetupEvaluatedSuccessfully(object value) { + Debug.Assert(this.Matches(value)); } } } diff --git a/src/Moq/Matchers/ParamArrayMatcher.cs b/src/Moq/Matchers/ParamArrayMatcher.cs index a47e09c00..59213328f 100644 --- a/src/Moq/Matchers/ParamArrayMatcher.cs +++ b/src/Moq/Matchers/ParamArrayMatcher.cs @@ -38,9 +38,13 @@ public bool Matches(object value) public void SetupEvaluatedSuccessfully(object value) { - foreach (var matcher in this.matchers) + Debug.Assert(this.Matches(value)); + Debug.Assert(value is Array array && array.Length == this.matchers.Length); + + var values = (Array)value; + for (int i = 0, n = this.matchers.Length; i < n; ++i) { - matcher.SetupEvaluatedSuccessfully(value); + this.matchers[i].SetupEvaluatedSuccessfully(values.GetValue(i)); } } } diff --git a/src/Moq/Matchers/RefMatcher.cs b/src/Moq/Matchers/RefMatcher.cs index 2eee31dbe..195074e87 100644 --- a/src/Moq/Matchers/RefMatcher.cs +++ b/src/Moq/Matchers/RefMatcher.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD. // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. +using System.Diagnostics; + namespace Moq.Matchers { internal class RefMatcher : IMatcher @@ -22,6 +24,7 @@ public bool Matches(object value) public void SetupEvaluatedSuccessfully(object value) { + Debug.Assert(this.Matches(value)); } } } diff --git a/tests/Moq.Tests/Matchers/ParamArrayMatcherFixture.cs b/tests/Moq.Tests/Matchers/ParamArrayMatcherFixture.cs new file mode 100644 index 000000000..08381e795 --- /dev/null +++ b/tests/Moq.Tests/Matchers/ParamArrayMatcherFixture.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD. +// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using Xunit; + +namespace Moq.Tests.Matchers +{ + public class ParamArrayMatcherFixture + { + [Theory] + [InlineData(42, "", true)] + [InlineData(42, null, true)] + [InlineData(3.141f, "", false)] + [InlineData(null, "", false)] + public void Matches_several_matchers_from_params_array(object first, object second, bool shouldMatch) + { + var seconds = new List(); + var methodCallExpr = (MethodCallExpression)ToExpression(x => x.Method(It.IsAny(), Capture.In(seconds))).Body; + var expr = methodCallExpr.Arguments.Single(); + var parameter = typeof(IX).GetMethod("Method").GetParameters().Single(); + + var (matcher, _) = MatcherFactory.CreateMatcher(expr, parameter); + + Assert.Equal(shouldMatch, matcher.Matches(new object[] { first, second })); + } + + [Fact] + public void SetupEvaluatedSuccessfully_succeeds_for_matching_values() + { + var seconds = new List(); + var methodCallExpr = (MethodCallExpression)ToExpression(x => x.Method(It.IsAny(), Capture.In(seconds))).Body; + var expr = methodCallExpr.Arguments.Single(); + var parameter = typeof(IX).GetMethod("Method").GetParameters().Single(); + + var (matcher, _) = MatcherFactory.CreateMatcher(expr, parameter); + + matcher.SetupEvaluatedSuccessfully(new object[] { 42, "" }); + } + + private LambdaExpression ToExpression(Expression> expr) + { + return expr; + } + + public interface IX + { + void Method(params object[] args); + } + } +}