From 9bb30db19f49134059c229ca958fbc22bde1a3d3 Mon Sep 17 00:00:00 2001 From: Daniel Cazzulino Date: Wed, 2 Aug 2023 21:03:56 -0300 Subject: [PATCH] Remove unnecessary accessibility modifiers --- src/Moq/Moq.csproj | 2 +- src/Moq/Obsolete/MockFactory.cs | 9 +- src/Moq/Protected/ProtectedMock.cs | 2298 +--------------------------- 3 files changed, 9 insertions(+), 2300 deletions(-) diff --git a/src/Moq/Moq.csproj b/src/Moq/Moq.csproj index 870e7b6e0..c0a2c3550 100644 --- a/src/Moq/Moq.csproj +++ b/src/Moq/Moq.csproj @@ -41,7 +41,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/src/Moq/Obsolete/MockFactory.cs b/src/Moq/Obsolete/MockFactory.cs index f1e1dda3e..7e3cec48d 100644 --- a/src/Moq/Obsolete/MockFactory.cs +++ b/src/Moq/Obsolete/MockFactory.cs @@ -248,12 +248,9 @@ public Mock Create(params object[] args) { // "fix" compiler picking this overload instead of // the one receiving the mock behavior. - if (args != null && args.Length > 0 && args[0] is MockBehavior) - { - return CreateMock((MockBehavior)args[0], args.Skip(1).ToArray()); - } - - return CreateMock(defaultBehavior, args); + return args != null && args.Length > 0 && args[0] is MockBehavior behavior + ? CreateMock(behavior, args.Skip(1).ToArray()) + : CreateMock(defaultBehavior, args); } /// diff --git a/src/Moq/Protected/ProtectedMock.cs b/src/Moq/Protected/ProtectedMock.cs index d753eae31..53f76bfe6 100644 --- a/src/Moq/Protected/ProtectedMock.cs +++ b/src/Moq/Protected/ProtectedMock.cs @@ -16,50 +16,8 @@ namespace Moq.Protected { - - /* Unmerged change from project 'Moq(netstandard2.0)' - Before: - internal class ProtectedMock : IProtectedMock - After: - class ProtectedMock : IProtectedMock - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Before: - internal class ProtectedMock : IProtectedMock - After: - class ProtectedMock : IProtectedMock - */ - - /* Unmerged change from project 'Moq(net6.0)' - Before: - internal class ProtectedMock : IProtectedMock - After: - class ProtectedMock : IProtectedMock - */ class ProtectedMock : IProtectedMock where T : class - - /* Unmerged change from project 'Moq(netstandard2.0)' - Before: - private Mock mock; - After: - Mock mock; - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Before: - private Mock mock; - After: - Mock mock; - */ - - /* Unmerged change from project 'Moq(net6.0)' - Before: - private Mock mock; - After: - Mock mock; - */ { Mock mock; @@ -91,27 +49,6 @@ public ISetup Setup(string methodName, Type[] genericTypeArguments, bool exac Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); return this.InternalSetup(methodName, genericTypeArguments, exactParameterMatch, args); - - /* Unmerged change from project 'Moq(netstandard2.0)' - Before: - private ISetup InternalSetup(string methodName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - ISetup InternalSetup(string methodName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Before: - private ISetup InternalSetup(string methodName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - ISetup InternalSetup(string methodName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ - - /* Unmerged change from project 'Moq(net6.0)' - Before: - private ISetup InternalSetup(string methodName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - ISetup InternalSetup(string methodName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ } ISetup InternalSetup(string methodName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) @@ -141,27 +78,6 @@ public ISetup Setup(string methodName, Type[] genericTypeAr Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); return this.InternalSetup(methodName, genericTypeArguments, exactParameterMatch, args); - - /* Unmerged change from project 'Moq(netstandard2.0)' - Before: - private ISetup InternalSetup(string methodName, Type[] genericTypeArguments, - After: - ISetup InternalSetup(string methodName, Type[] genericTypeArguments, - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Before: - private ISetup InternalSetup(string methodName, Type[] genericTypeArguments, - After: - ISetup InternalSetup(string methodName, Type[] genericTypeArguments, - */ - - /* Unmerged change from project 'Moq(net6.0)' - Before: - private ISetup InternalSetup(string methodName, Type[] genericTypeArguments, - After: - ISetup InternalSetup(string methodName, Type[] genericTypeArguments, - */ } ISetup InternalSetup(string methodName, Type[] genericTypeArguments, @@ -229,27 +145,6 @@ public ISetupSequentialAction SetupSequence(string methodOrPropertyName, Type[] { Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - - /* Unmerged change from project 'Moq(netstandard2.0)' - Before: - private ISetupSequentialAction InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - ISetupSequentialAction InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Before: - private ISetupSequentialAction InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - ISetupSequentialAction InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ - - /* Unmerged change from project 'Moq(net6.0)' - Before: - private ISetupSequentialAction InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - ISetupSequentialAction InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ } ISetupSequentialAction InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) @@ -267,30 +162,6 @@ ISetupSequentialAction InternalSetupSequence(string methodOrPropertyName, Type[] public ISetupSequentialResult SetupSequence(string methodOrPropertyName, params object[] args) { return this.InternalSetupSequence(methodOrPropertyName, null, false, args); - - /* Unmerged change from project 'Moq(netstandard2.0)' - Removed: - public ISetupSequentialResult SetupSequence(string methodOrPropertyName, bool exactParameterMatch, params object[] args) - { - return this.InternalSetupSequence(methodOrPropertyName, null, exactParameterMatch, args); - } - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Removed: - public ISetupSequentialResult SetupSequence(string methodOrPropertyName, bool exactParameterMatch, params object[] args) - { - return this.InternalSetupSequence(methodOrPropertyName, null, exactParameterMatch, args); - } - */ - - /* Unmerged change from project 'Moq(net6.0)' - Removed: - public ISetupSequentialResult SetupSequence(string methodOrPropertyName, bool exactParameterMatch, params object[] args) - { - return this.InternalSetupSequence(methodOrPropertyName, null, exactParameterMatch, args); - } - */ } public ISetupSequentialResult SetupSequence(string methodOrPropertyName, bool exactParameterMatch, params object[] args) @@ -298,73 +169,10 @@ public ISetupSequentialResult SetupSequence(string methodOrPro return this.InternalSetupSequence(methodOrPropertyName, null, exactParameterMatch, args); } - public ISetupSequentialResult SetupSequence(string methodOrPropertyName, bool exactParameterMatch, params object[] args) - - /* Unmerged change from project 'Moq(netstandard2.0)' - Before: - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - After: - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Before: - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - After: - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - */ - - /* Unmerged change from project 'Moq(net6.0)' - Before: - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - After: - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - */ + public ISetupSequentialResult SetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) { Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - return this.InternalSetupSequence(methodOrPropertyName, null, exactParameterMatch, args); - - /* Unmerged change from project 'Moq(netstandard2.0)' - Before: - private ISetupSequentialResult InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - public ISetupSequentialResult SetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - } - - ISetupSequentialResult InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Before: - private ISetupSequentialResult InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - public ISetupSequentialResult SetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - } - - ISetupSequentialResult InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ - - /* Unmerged change from project 'Moq(net6.0)' - Before: - private ISetupSequentialResult InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - After: - public ISetupSequentialResult SetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); - } - - ISetupSequentialResult InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) - */ + return this.InternalSetupSequence(methodOrPropertyName, genericTypeArguments, exactParameterMatch, args); } ISetupSequentialResult InternalSetupSequence(string methodOrPropertyName, Type[] genericTypeArguments, bool exactParameterMatch, params object[] args) @@ -402,129 +210,6 @@ public void Verify(string methodName, Type[] genericTypeArguments, Times times, { Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); this.InternalVerify(methodName, genericTypeArguments, times, false, args); - - /* Unmerged change from project 'Moq(netstandard2.0)' - Removed: - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - private void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - public void Verify(string methodName, Times times, object[] args) - { - this.InternalVerify(methodName, null, times, false, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, false, args); - } - - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Removed: - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - private void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - public void Verify(string methodName, Times times, object[] args) - { - this.InternalVerify(methodName, null, times, false, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, false, args); - } - - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - */ - - /* Unmerged change from project 'Moq(net6.0)' - Removed: - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - private void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - public void Verify(string methodName, Times times, object[] args) - { - this.InternalVerify(methodName, null, times, false, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, false, args); - } - - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - */ } public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) @@ -565,1981 +250,7 @@ public void Verify(string methodName, Times times, bool exactParameterM this.InternalVerify(methodName, null, times, exactParameterMatch, args); } - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - - /* Unmerged change from project 'Moq(netstandard2.0)' - Before: - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - private void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var property = GetProperty(methodName); - if (property != null) - { - ThrowIfPublicGetter(property, typeof(T).Name); - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - return; - } - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - // TODO should receive args to support indexers - public void VerifyGet(string propertyName, Times times) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicGetter(property, typeof(T).Name); - Guard.CanRead(property); - - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - } - - // TODO should receive args to support indexers - public void VerifySet(string propertyName, Times times, object value) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicSetter(property, typeof(T).Name); - Guard.CanWrite(property); - - var expression = GetSetterExpression(property, ToExpressionArg(property.PropertyType, value)); - // TODO should consider property indexers - // TODO should receive the parameter here - Mock.VerifySet(mock, expression, times, null); - } - - #endregion - - private static Expression> GetMemberAccess(PropertyInfo property) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.MakeMemberAccess(param, property), param); - } - - private static MethodInfo GetMethod(string methodName, Type[] genericTypeArguments, bool exact, params object[] args) - { - var argTypes = ToArgTypes(args); - var methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - .Where(m => m.Name == methodName); - if (genericTypeArguments != null && genericTypeArguments.Length > 0) - { - methods = methods - .Where(m => m.IsGenericMethod && m.GetGenericArguments().Length == genericTypeArguments.Length) - .Select(m => m.MakeGenericMethod(genericTypeArguments)); - } - - return methods - .SingleOrDefault(m => m.GetParameterTypes().CompareTo(argTypes, exact, considerTypeMatchers: false)); - } - - private static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - private static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - // TODO should support arguments for property indexers - private static PropertyInfo GetProperty(string propertyName) - { - return typeof(T).GetProperty( - propertyName, - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - } - - private static Expression> GetSetterExpression(PropertyInfo property, Expression value) - { - var param = Expression.Parameter(typeof(T), "mock"); - - return Expression.Lambda>( - Expression.Call(param, property.GetSetMethod(true), value), - param); - } - - private static void ThrowIfMemberMissing(string memberName, MemberInfo member) - { - if (member == null) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MemberMissing, - typeof(T).Name, - memberName)); - } - } - - private static void ThrowIfMethodMissing(string methodName, MethodInfo method, object[] args) - { - if (method == null) - { - List extractedTypeNames = new List(); - foreach (object o in args) - { - if (o is Expression expr) - { - extractedTypeNames.Add(expr.Type.GetFormattedName()); - } - else - { - extractedTypeNames.Add(o.GetType().GetFormattedName()); - } - } - - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodMissing, - typeof(T).Name, - methodName, - string.Join( - ", ", - extractedTypeNames.ToArray()))); - } - } - - private static void ThrowIfPublicMethod(MethodInfo method, string reflectedTypeName) - { - if (method.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodIsPublic, - reflectedTypeName, - method.Name)); - } - } - - private static void ThrowIfPublicGetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanRead(out var getter) && getter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - private static void ThrowIfPublicSetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanWrite(out var setter) && setter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - private static void ThrowIfVoidMethod(MethodInfo method) - { - if (method.ReturnType == typeof(void)) - { - throw new ArgumentException(Resources.CantSetReturnValueForVoid); - } - } - - private static Type[] ToArgTypes(object[] args) - { - if (args == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var types = new Type[args.Length]; - for (int index = 0; index < args.Length; index++) - { - if (args[index] == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var expr = args[index] as Expression; - if (expr == null) - { - types[index] = args[index].GetType(); - } - else if (expr.NodeType == ExpressionType.Call) - { - types[index] = ((MethodCallExpression)expr).Method.ReturnType; - } - else if (ItRefAnyField(expr) is FieldInfo itRefAnyField) - { - types[index] = itRefAnyField.FieldType.MakeByRefType(); - } - else if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - types[index] = field.FieldType; - } - else if (member.Member is PropertyInfo property) - { - types[index] = property.PropertyType; - } - else - { - throw new NotSupportedException(string.Format( - Resources.Culture, - Resources.UnsupportedMember, - member.Member.Name)); - } - } - else - { - types[index] = (expr.PartialEval() as ConstantExpression)?.Type; - } - } - - return types; - } - - private static bool IsItRefAny(Expression expression) - { - return ItRefAnyField(expression) != null; - } - - private static FieldInfo ItRefAnyField(Expression expr) - { - FieldInfo itRefAnyField = null; - - if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - if (field.Name == nameof(It.Ref.IsAny)) - { - var fieldDeclaringType = field.DeclaringType; - if (fieldDeclaringType.IsGenericType) - { - var fieldDeclaringTypeDefinition = fieldDeclaringType.GetGenericTypeDefinition(); - if (fieldDeclaringTypeDefinition == typeof(It.Ref<>)) - { - itRefAnyField = field; - } - } - } - } - } - - return itRefAnyField; - } - - private static Expression ToExpressionArg(Type type, object arg) - { - if (arg is Expression expression) - { - if (!type.IsAssignableFrom(expression.GetType())) - { - if(arg is LambdaExpression lambda) - { - expression = lambda.Body; - } - return expression; - } - - if (IsItRefAny(expression)) - { - return expression; - } - - if (expression.IsMatch(out _)) - { - return expression; - } - - } - - return Expression.Constant(arg, type); - } - - private static IEnumerable ToExpressionArgs(MethodInfo method, object[] args) - After: - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - public void Verify(string methodName, Times times, object[] args) - { - this.InternalVerify(methodName, null, times, false, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, false, args); - } - - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var property = GetProperty(methodName); - if (property != null) - { - ThrowIfPublicGetter(property, typeof(T).Name); - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - return; - } - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - // TODO should receive args to support indexers - public void VerifyGet(string propertyName, Times times) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicGetter(property, typeof(T).Name); - Guard.CanRead(property); - - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - } - - // TODO should receive args to support indexers - public void VerifySet(string propertyName, Times times, object value) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicSetter(property, typeof(T).Name); - Guard.CanWrite(property); - - var expression = GetSetterExpression(property, ToExpressionArg(property.PropertyType, value)); - // TODO should consider property indexers - // TODO should receive the parameter here - Mock.VerifySet(mock, expression, times, null); - } - - #endregion - - static Expression> GetMemberAccess(PropertyInfo property) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.MakeMemberAccess(param, property), param); - } - - static MethodInfo GetMethod(string methodName, Type[] genericTypeArguments, bool exact, params object[] args) - { - var argTypes = ToArgTypes(args); - var methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - .Where(m => m.Name == methodName); - if (genericTypeArguments != null && genericTypeArguments.Length > 0) - { - methods = methods - .Where(m => m.IsGenericMethod && m.GetGenericArguments().Length == genericTypeArguments.Length) - .Select(m => m.MakeGenericMethod(genericTypeArguments)); - } - - return methods - .SingleOrDefault(m => m.GetParameterTypes().CompareTo(argTypes, exact, considerTypeMatchers: false)); - } - - static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - // TODO should support arguments for property indexers - static PropertyInfo GetProperty(string propertyName) - { - return typeof(T).GetProperty( - propertyName, - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - } - - static Expression> GetSetterExpression(PropertyInfo property, Expression value) - { - var param = Expression.Parameter(typeof(T), "mock"); - - return Expression.Lambda>( - Expression.Call(param, property.GetSetMethod(true), value), - param); - } - - static void ThrowIfMemberMissing(string memberName, MemberInfo member) - { - if (member == null) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MemberMissing, - typeof(T).Name, - memberName)); - } - } - - static void ThrowIfMethodMissing(string methodName, MethodInfo method, object[] args) - { - if (method == null) - { - List extractedTypeNames = new List(); - foreach (object o in args) - { - if (o is Expression expr) - { - extractedTypeNames.Add(expr.Type.GetFormattedName()); - } - else - { - extractedTypeNames.Add(o.GetType().GetFormattedName()); - } - } - - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodMissing, - typeof(T).Name, - methodName, - string.Join( - ", ", - extractedTypeNames.ToArray()))); - } - } - - static void ThrowIfPublicMethod(MethodInfo method, string reflectedTypeName) - { - if (method.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodIsPublic, - reflectedTypeName, - method.Name)); - } - } - - static void ThrowIfPublicGetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanRead(out var getter) && getter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - static void ThrowIfPublicSetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanWrite(out var setter) && setter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - static void ThrowIfVoidMethod(MethodInfo method) - { - if (method.ReturnType == typeof(void)) - { - throw new ArgumentException(Resources.CantSetReturnValueForVoid); - } - } - - static Type[] ToArgTypes(object[] args) - { - if (args == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var types = new Type[args.Length]; - for (int index = 0; index < args.Length; index++) - { - if (args[index] == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - if (args[index] is not Expression expr) - { - types[index] = args[index].GetType(); - } - else if (expr.NodeType == ExpressionType.Call) - { - types[index] = ((MethodCallExpression)expr).Method.ReturnType; - } - else if (ItRefAnyField(expr) is FieldInfo itRefAnyField) - { - types[index] = itRefAnyField.FieldType.MakeByRefType(); - } - else if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - types[index] = field.FieldType; - } - else if (member.Member is PropertyInfo property) - { - types[index] = property.PropertyType; - } - else - { - throw new NotSupportedException(string.Format( - Resources.Culture, - Resources.UnsupportedMember, - member.Member.Name)); - } - } - else - { - types[index] = (expr.PartialEval() as ConstantExpression)?.Type; - } - } - - return types; - } - - static bool IsItRefAny(Expression expression) - { - return ItRefAnyField(expression) != null; - } - - static FieldInfo ItRefAnyField(Expression expr) - { - FieldInfo itRefAnyField = null; - - if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - if (field.Name == nameof(It.Ref.IsAny)) - { - var fieldDeclaringType = field.DeclaringType; - if (fieldDeclaringType.IsGenericType) - { - var fieldDeclaringTypeDefinition = fieldDeclaringType.GetGenericTypeDefinition(); - if (fieldDeclaringTypeDefinition == typeof(It.Ref<>)) - { - itRefAnyField = field; - } - } - } - } - } - - return itRefAnyField; - } - - static Expression ToExpressionArg(Type type, object arg) - { - if (arg is Expression expression) - { - if (!type.IsAssignableFrom(expression.GetType())) - { - if(arg is LambdaExpression lambda) - { - expression = lambda.Body; - } - return expression; - } - - if (IsItRefAny(expression)) - { - return expression; - } - - if (expression.IsMatch(out _)) - { - return expression; - } - - } - - return Expression.Constant(arg, type); - } - - static IEnumerable ToExpressionArgs(MethodInfo method, object[] args) - */ - - /* Unmerged change from project 'Moq(netstandard2.1)' - Before: - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - private void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var property = GetProperty(methodName); - if (property != null) - { - ThrowIfPublicGetter(property, typeof(T).Name); - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - return; - } - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - // TODO should receive args to support indexers - public void VerifyGet(string propertyName, Times times) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicGetter(property, typeof(T).Name); - Guard.CanRead(property); - - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - } - - // TODO should receive args to support indexers - public void VerifySet(string propertyName, Times times, object value) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicSetter(property, typeof(T).Name); - Guard.CanWrite(property); - - var expression = GetSetterExpression(property, ToExpressionArg(property.PropertyType, value)); - // TODO should consider property indexers - // TODO should receive the parameter here - Mock.VerifySet(mock, expression, times, null); - } - - #endregion - - private static Expression> GetMemberAccess(PropertyInfo property) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.MakeMemberAccess(param, property), param); - } - - private static MethodInfo GetMethod(string methodName, Type[] genericTypeArguments, bool exact, params object[] args) - { - var argTypes = ToArgTypes(args); - var methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - .Where(m => m.Name == methodName); - if (genericTypeArguments != null && genericTypeArguments.Length > 0) - { - methods = methods - .Where(m => m.IsGenericMethod && m.GetGenericArguments().Length == genericTypeArguments.Length) - .Select(m => m.MakeGenericMethod(genericTypeArguments)); - } - - return methods - .SingleOrDefault(m => m.GetParameterTypes().CompareTo(argTypes, exact, considerTypeMatchers: false)); - } - - private static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - private static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - // TODO should support arguments for property indexers - private static PropertyInfo GetProperty(string propertyName) - { - return typeof(T).GetProperty( - propertyName, - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - } - - private static Expression> GetSetterExpression(PropertyInfo property, Expression value) - { - var param = Expression.Parameter(typeof(T), "mock"); - - return Expression.Lambda>( - Expression.Call(param, property.GetSetMethod(true), value), - param); - } - - private static void ThrowIfMemberMissing(string memberName, MemberInfo member) - { - if (member == null) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MemberMissing, - typeof(T).Name, - memberName)); - } - } - - private static void ThrowIfMethodMissing(string methodName, MethodInfo method, object[] args) - { - if (method == null) - { - List extractedTypeNames = new List(); - foreach (object o in args) - { - if (o is Expression expr) - { - extractedTypeNames.Add(expr.Type.GetFormattedName()); - } - else - { - extractedTypeNames.Add(o.GetType().GetFormattedName()); - } - } - - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodMissing, - typeof(T).Name, - methodName, - string.Join( - ", ", - extractedTypeNames.ToArray()))); - } - } - - private static void ThrowIfPublicMethod(MethodInfo method, string reflectedTypeName) - { - if (method.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodIsPublic, - reflectedTypeName, - method.Name)); - } - } - - private static void ThrowIfPublicGetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanRead(out var getter) && getter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - private static void ThrowIfPublicSetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanWrite(out var setter) && setter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - private static void ThrowIfVoidMethod(MethodInfo method) - { - if (method.ReturnType == typeof(void)) - { - throw new ArgumentException(Resources.CantSetReturnValueForVoid); - } - } - - private static Type[] ToArgTypes(object[] args) - { - if (args == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var types = new Type[args.Length]; - for (int index = 0; index < args.Length; index++) - { - if (args[index] == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var expr = args[index] as Expression; - if (expr == null) - { - types[index] = args[index].GetType(); - } - else if (expr.NodeType == ExpressionType.Call) - { - types[index] = ((MethodCallExpression)expr).Method.ReturnType; - } - else if (ItRefAnyField(expr) is FieldInfo itRefAnyField) - { - types[index] = itRefAnyField.FieldType.MakeByRefType(); - } - else if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - types[index] = field.FieldType; - } - else if (member.Member is PropertyInfo property) - { - types[index] = property.PropertyType; - } - else - { - throw new NotSupportedException(string.Format( - Resources.Culture, - Resources.UnsupportedMember, - member.Member.Name)); - } - } - else - { - types[index] = (expr.PartialEval() as ConstantExpression)?.Type; - } - } - - return types; - } - - private static bool IsItRefAny(Expression expression) - { - return ItRefAnyField(expression) != null; - } - - private static FieldInfo ItRefAnyField(Expression expr) - { - FieldInfo itRefAnyField = null; - - if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - if (field.Name == nameof(It.Ref.IsAny)) - { - var fieldDeclaringType = field.DeclaringType; - if (fieldDeclaringType.IsGenericType) - { - var fieldDeclaringTypeDefinition = fieldDeclaringType.GetGenericTypeDefinition(); - if (fieldDeclaringTypeDefinition == typeof(It.Ref<>)) - { - itRefAnyField = field; - } - } - } - } - } - - return itRefAnyField; - } - - private static Expression ToExpressionArg(Type type, object arg) - { - if (arg is Expression expression) - { - if (!type.IsAssignableFrom(expression.GetType())) - { - if(arg is LambdaExpression lambda) - { - expression = lambda.Body; - } - return expression; - } - - if (IsItRefAny(expression)) - { - return expression; - } - - if (expression.IsMatch(out _)) - { - return expression; - } - - } - - return Expression.Constant(arg, type); - } - - private static IEnumerable ToExpressionArgs(MethodInfo method, object[] args) - After: - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - public void Verify(string methodName, Times times, object[] args) - { - this.InternalVerify(methodName, null, times, false, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, false, args); - } - - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var property = GetProperty(methodName); - if (property != null) - { - ThrowIfPublicGetter(property, typeof(T).Name); - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - return; - } - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - // TODO should receive args to support indexers - public void VerifyGet(string propertyName, Times times) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicGetter(property, typeof(T).Name); - Guard.CanRead(property); - - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - } - - // TODO should receive args to support indexers - public void VerifySet(string propertyName, Times times, object value) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicSetter(property, typeof(T).Name); - Guard.CanWrite(property); - - var expression = GetSetterExpression(property, ToExpressionArg(property.PropertyType, value)); - // TODO should consider property indexers - // TODO should receive the parameter here - Mock.VerifySet(mock, expression, times, null); - } - - #endregion - - static Expression> GetMemberAccess(PropertyInfo property) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.MakeMemberAccess(param, property), param); - } - - static MethodInfo GetMethod(string methodName, Type[] genericTypeArguments, bool exact, params object[] args) - { - var argTypes = ToArgTypes(args); - var methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - .Where(m => m.Name == methodName); - if (genericTypeArguments != null && genericTypeArguments.Length > 0) - { - methods = methods - .Where(m => m.IsGenericMethod && m.GetGenericArguments().Length == genericTypeArguments.Length) - .Select(m => m.MakeGenericMethod(genericTypeArguments)); - } - - return methods - .SingleOrDefault(m => m.GetParameterTypes().CompareTo(argTypes, exact, considerTypeMatchers: false)); - } - - static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - // TODO should support arguments for property indexers - static PropertyInfo GetProperty(string propertyName) - { - return typeof(T).GetProperty( - propertyName, - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - } - - static Expression> GetSetterExpression(PropertyInfo property, Expression value) - { - var param = Expression.Parameter(typeof(T), "mock"); - - return Expression.Lambda>( - Expression.Call(param, property.GetSetMethod(true), value), - param); - } - - static void ThrowIfMemberMissing(string memberName, MemberInfo member) - { - if (member == null) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MemberMissing, - typeof(T).Name, - memberName)); - } - } - - static void ThrowIfMethodMissing(string methodName, MethodInfo method, object[] args) - { - if (method == null) - { - List extractedTypeNames = new List(); - foreach (object o in args) - { - if (o is Expression expr) - { - extractedTypeNames.Add(expr.Type.GetFormattedName()); - } - else - { - extractedTypeNames.Add(o.GetType().GetFormattedName()); - } - } - - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodMissing, - typeof(T).Name, - methodName, - string.Join( - ", ", - extractedTypeNames.ToArray()))); - } - } - - static void ThrowIfPublicMethod(MethodInfo method, string reflectedTypeName) - { - if (method.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodIsPublic, - reflectedTypeName, - method.Name)); - } - } - - static void ThrowIfPublicGetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanRead(out var getter) && getter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - static void ThrowIfPublicSetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanWrite(out var setter) && setter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - static void ThrowIfVoidMethod(MethodInfo method) - { - if (method.ReturnType == typeof(void)) - { - throw new ArgumentException(Resources.CantSetReturnValueForVoid); - } - } - - static Type[] ToArgTypes(object[] args) - { - if (args == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var types = new Type[args.Length]; - for (int index = 0; index < args.Length; index++) - { - if (args[index] == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - if (args[index] is not Expression expr) - { - types[index] = args[index].GetType(); - } - else if (expr.NodeType == ExpressionType.Call) - { - types[index] = ((MethodCallExpression)expr).Method.ReturnType; - } - else if (ItRefAnyField(expr) is FieldInfo itRefAnyField) - { - types[index] = itRefAnyField.FieldType.MakeByRefType(); - } - else if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - types[index] = field.FieldType; - } - else if (member.Member is PropertyInfo property) - { - types[index] = property.PropertyType; - } - else - { - throw new NotSupportedException(string.Format( - Resources.Culture, - Resources.UnsupportedMember, - member.Member.Name)); - } - } - else - { - types[index] = (expr.PartialEval() as ConstantExpression)?.Type; - } - } - - return types; - } - - static bool IsItRefAny(Expression expression) - { - return ItRefAnyField(expression) != null; - } - - static FieldInfo ItRefAnyField(Expression expr) - { - FieldInfo itRefAnyField = null; - - if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - if (field.Name == nameof(It.Ref.IsAny)) - { - var fieldDeclaringType = field.DeclaringType; - if (fieldDeclaringType.IsGenericType) - { - var fieldDeclaringTypeDefinition = fieldDeclaringType.GetGenericTypeDefinition(); - if (fieldDeclaringTypeDefinition == typeof(It.Ref<>)) - { - itRefAnyField = field; - } - } - } - } - } - - return itRefAnyField; - } - - static Expression ToExpressionArg(Type type, object arg) - { - if (arg is Expression expression) - { - if (!type.IsAssignableFrom(expression.GetType())) - { - if(arg is LambdaExpression lambda) - { - expression = lambda.Body; - } - return expression; - } - - if (IsItRefAny(expression)) - { - return expression; - } - - if (expression.IsMatch(out _)) - { - return expression; - } - - } - - return Expression.Constant(arg, type); - } - - static IEnumerable ToExpressionArgs(MethodInfo method, object[] args) - */ - - /* Unmerged change from project 'Moq(net6.0)' - Before: - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - private void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var property = GetProperty(methodName); - if (property != null) - { - ThrowIfPublicGetter(property, typeof(T).Name); - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - return; - } - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - // TODO should receive args to support indexers - public void VerifyGet(string propertyName, Times times) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicGetter(property, typeof(T).Name); - Guard.CanRead(property); - - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - } - - // TODO should receive args to support indexers - public void VerifySet(string propertyName, Times times, object value) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicSetter(property, typeof(T).Name); - Guard.CanWrite(property); - - var expression = GetSetterExpression(property, ToExpressionArg(property.PropertyType, value)); - // TODO should consider property indexers - // TODO should receive the parameter here - Mock.VerifySet(mock, expression, times, null); - } - - #endregion - - private static Expression> GetMemberAccess(PropertyInfo property) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.MakeMemberAccess(param, property), param); - } - - private static MethodInfo GetMethod(string methodName, Type[] genericTypeArguments, bool exact, params object[] args) - { - var argTypes = ToArgTypes(args); - var methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - .Where(m => m.Name == methodName); - if (genericTypeArguments != null && genericTypeArguments.Length > 0) - { - methods = methods - .Where(m => m.IsGenericMethod && m.GetGenericArguments().Length == genericTypeArguments.Length) - .Select(m => m.MakeGenericMethod(genericTypeArguments)); - } - - return methods - .SingleOrDefault(m => m.GetParameterTypes().CompareTo(argTypes, exact, considerTypeMatchers: false)); - } - - private static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - private static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - // TODO should support arguments for property indexers - private static PropertyInfo GetProperty(string propertyName) - { - return typeof(T).GetProperty( - propertyName, - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - } - - private static Expression> GetSetterExpression(PropertyInfo property, Expression value) - { - var param = Expression.Parameter(typeof(T), "mock"); - - return Expression.Lambda>( - Expression.Call(param, property.GetSetMethod(true), value), - param); - } - - private static void ThrowIfMemberMissing(string memberName, MemberInfo member) - { - if (member == null) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MemberMissing, - typeof(T).Name, - memberName)); - } - } - - private static void ThrowIfMethodMissing(string methodName, MethodInfo method, object[] args) - { - if (method == null) - { - List extractedTypeNames = new List(); - foreach (object o in args) - { - if (o is Expression expr) - { - extractedTypeNames.Add(expr.Type.GetFormattedName()); - } - else - { - extractedTypeNames.Add(o.GetType().GetFormattedName()); - } - } - - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodMissing, - typeof(T).Name, - methodName, - string.Join( - ", ", - extractedTypeNames.ToArray()))); - } - } - - private static void ThrowIfPublicMethod(MethodInfo method, string reflectedTypeName) - { - if (method.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodIsPublic, - reflectedTypeName, - method.Name)); - } - } - - private static void ThrowIfPublicGetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanRead(out var getter) && getter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - private static void ThrowIfPublicSetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanWrite(out var setter) && setter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - private static void ThrowIfVoidMethod(MethodInfo method) - { - if (method.ReturnType == typeof(void)) - { - throw new ArgumentException(Resources.CantSetReturnValueForVoid); - } - } - - private static Type[] ToArgTypes(object[] args) - { - if (args == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var types = new Type[args.Length]; - for (int index = 0; index < args.Length; index++) - { - if (args[index] == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var expr = args[index] as Expression; - if (expr == null) - { - types[index] = args[index].GetType(); - } - else if (expr.NodeType == ExpressionType.Call) - { - types[index] = ((MethodCallExpression)expr).Method.ReturnType; - } - else if (ItRefAnyField(expr) is FieldInfo itRefAnyField) - { - types[index] = itRefAnyField.FieldType.MakeByRefType(); - } - else if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - types[index] = field.FieldType; - } - else if (member.Member is PropertyInfo property) - { - types[index] = property.PropertyType; - } - else - { - throw new NotSupportedException(string.Format( - Resources.Culture, - Resources.UnsupportedMember, - member.Member.Name)); - } - } - else - { - types[index] = (expr.PartialEval() as ConstantExpression)?.Type; - } - } - - return types; - } - - private static bool IsItRefAny(Expression expression) - { - return ItRefAnyField(expression) != null; - } - - private static FieldInfo ItRefAnyField(Expression expr) - { - FieldInfo itRefAnyField = null; - - if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - if (field.Name == nameof(It.Ref.IsAny)) - { - var fieldDeclaringType = field.DeclaringType; - if (fieldDeclaringType.IsGenericType) - { - var fieldDeclaringTypeDefinition = fieldDeclaringType.GetGenericTypeDefinition(); - if (fieldDeclaringTypeDefinition == typeof(It.Ref<>)) - { - itRefAnyField = field; - } - } - } - } - } - - return itRefAnyField; - } - - private static Expression ToExpressionArg(Type type, object arg) - { - if (arg is Expression expression) - { - if (!type.IsAssignableFrom(expression.GetType())) - { - if(arg is LambdaExpression lambda) - { - expression = lambda.Body; - } - return expression; - } - - if (IsItRefAny(expression)) - { - return expression; - } - - if (expression.IsMatch(out _)) - { - return expression; - } - - } - - return Expression.Constant(arg, type); - } - - private static IEnumerable ToExpressionArgs(MethodInfo method, object[] args) - After: - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - public void Verify(string methodName, Times times, object[] args) - { - this.InternalVerify(methodName, null, times, false, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, false, args); - } - - public void Verify(string methodName, Times times, bool exactParameterMatch, object[] args) - { - this.InternalVerify(methodName, null, times, exactParameterMatch, args); - } - - public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); - this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); - } - - void InternalVerify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) - { - Guard.NotNullOrEmpty(methodName, nameof(methodName)); - - var property = GetProperty(methodName); - if (property != null) - { - ThrowIfPublicGetter(property, typeof(T).Name); - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - return; - } - - var method = GetMethod(methodName, genericTypeArguments, exactParameterMatch, args); - ThrowIfMethodMissing(methodName, method, args); - ThrowIfPublicMethod(method, typeof(T).Name); - - Mock.Verify(mock, GetMethodCall(method, args), times, null); - } - - // TODO should receive args to support indexers - public void VerifyGet(string propertyName, Times times) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicGetter(property, typeof(T).Name); - Guard.CanRead(property); - - // TODO should consider property indexers - Mock.VerifyGet(mock, GetMemberAccess(property), times, null); - } - - // TODO should receive args to support indexers - public void VerifySet(string propertyName, Times times, object value) - { - Guard.NotNullOrEmpty(propertyName, nameof(propertyName)); - - var property = GetProperty(propertyName); - ThrowIfMemberMissing(propertyName, property); - ThrowIfPublicSetter(property, typeof(T).Name); - Guard.CanWrite(property); - - var expression = GetSetterExpression(property, ToExpressionArg(property.PropertyType, value)); - // TODO should consider property indexers - // TODO should receive the parameter here - Mock.VerifySet(mock, expression, times, null); - } - - #endregion - - static Expression> GetMemberAccess(PropertyInfo property) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.MakeMemberAccess(param, property), param); - } - - static MethodInfo GetMethod(string methodName, Type[] genericTypeArguments, bool exact, params object[] args) - { - var argTypes = ToArgTypes(args); - var methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - .Where(m => m.Name == methodName); - if (genericTypeArguments != null && genericTypeArguments.Length > 0) - { - methods = methods - .Where(m => m.IsGenericMethod && m.GetGenericArguments().Length == genericTypeArguments.Length) - .Select(m => m.MakeGenericMethod(genericTypeArguments)); - } - - return methods - .SingleOrDefault(m => m.GetParameterTypes().CompareTo(argTypes, exact, considerTypeMatchers: false)); - } - - static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - static Expression> GetMethodCall(MethodInfo method, object[] args) - { - var param = Expression.Parameter(typeof(T), "mock"); - return Expression.Lambda>(Expression.Call(param, method, ToExpressionArgs(method, args)), param); - } - - // TODO should support arguments for property indexers - static PropertyInfo GetProperty(string propertyName) - { - return typeof(T).GetProperty( - propertyName, - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - } - - static Expression> GetSetterExpression(PropertyInfo property, Expression value) - { - var param = Expression.Parameter(typeof(T), "mock"); - - return Expression.Lambda>( - Expression.Call(param, property.GetSetMethod(true), value), - param); - } - - static void ThrowIfMemberMissing(string memberName, MemberInfo member) - { - if (member == null) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MemberMissing, - typeof(T).Name, - memberName)); - } - } - - static void ThrowIfMethodMissing(string methodName, MethodInfo method, object[] args) - { - if (method == null) - { - List extractedTypeNames = new List(); - foreach (object o in args) - { - if (o is Expression expr) - { - extractedTypeNames.Add(expr.Type.GetFormattedName()); - } - else - { - extractedTypeNames.Add(o.GetType().GetFormattedName()); - } - } - - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodMissing, - typeof(T).Name, - methodName, - string.Join( - ", ", - extractedTypeNames.ToArray()))); - } - } - - static void ThrowIfPublicMethod(MethodInfo method, string reflectedTypeName) - { - if (method.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.MethodIsPublic, - reflectedTypeName, - method.Name)); - } - } - - static void ThrowIfPublicGetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanRead(out var getter) && getter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - static void ThrowIfPublicSetter(PropertyInfo property, string reflectedTypeName) - { - if (property.CanWrite(out var setter) && setter.IsPublic) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Resources.UnexpectedPublicProperty, - reflectedTypeName, - property.Name)); - } - } - - static void ThrowIfVoidMethod(MethodInfo method) - { - if (method.ReturnType == typeof(void)) - { - throw new ArgumentException(Resources.CantSetReturnValueForVoid); - } - } - - static Type[] ToArgTypes(object[] args) - { - if (args == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - var types = new Type[args.Length]; - for (int index = 0; index < args.Length; index++) - { - if (args[index] == null) - { - throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); - } - - if (args[index] is not Expression expr) - { - types[index] = args[index].GetType(); - } - else if (expr.NodeType == ExpressionType.Call) - { - types[index] = ((MethodCallExpression)expr).Method.ReturnType; - } - else if (ItRefAnyField(expr) is FieldInfo itRefAnyField) - { - types[index] = itRefAnyField.FieldType.MakeByRefType(); - } - else if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - types[index] = field.FieldType; - } - else if (member.Member is PropertyInfo property) - { - types[index] = property.PropertyType; - } - else - { - throw new NotSupportedException(string.Format( - Resources.Culture, - Resources.UnsupportedMember, - member.Member.Name)); - } - } - else - { - types[index] = (expr.PartialEval() as ConstantExpression)?.Type; - } - } - - return types; - } - - static bool IsItRefAny(Expression expression) - { - return ItRefAnyField(expression) != null; - } - - static FieldInfo ItRefAnyField(Expression expr) - { - FieldInfo itRefAnyField = null; - - if (expr.NodeType == ExpressionType.MemberAccess) - { - var member = (MemberExpression)expr; - if (member.Member is FieldInfo field) - { - if (field.Name == nameof(It.Ref.IsAny)) - { - var fieldDeclaringType = field.DeclaringType; - if (fieldDeclaringType.IsGenericType) - { - var fieldDeclaringTypeDefinition = fieldDeclaringType.GetGenericTypeDefinition(); - if (fieldDeclaringTypeDefinition == typeof(It.Ref<>)) - { - itRefAnyField = field; - } - } - } - } - } - - return itRefAnyField; - } - - static Expression ToExpressionArg(Type type, object arg) - { - if (arg is Expression expression) - { - if (!type.IsAssignableFrom(expression.GetType())) - { - if(arg is LambdaExpression lambda) - { - expression = lambda.Body; - } - return expression; - } - - if (IsItRefAny(expression)) - { - return expression; - } - - if (expression.IsMatch(out _)) - { - return expression; - } - - } - - return Expression.Constant(arg, type); - } - - static IEnumerable ToExpressionArgs(MethodInfo method, object[] args) - */ + public void Verify(string methodName, Type[] genericTypeArguments, Times times, bool exactParameterMatch, params object[] args) { Guard.NotNull(genericTypeArguments, nameof(genericTypeArguments)); this.InternalVerify(methodName, genericTypeArguments, times, exactParameterMatch, args); @@ -2747,7 +458,8 @@ static Type[] ToArgTypes(object[] args) throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue); } - if (args[index] is not Expression expr) + var expr = args[index] as Expression; + if (expr == null) { types[index] = args[index].GetType(); }