Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to specify proxy generator or invalidate it #925 #1227

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Moq/ActionObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public override Expression<Action<T>> ReconstructExpression<T>(Action<T> action,
}
}

Expression[] GetArgumentExpressions(Invocation invocation, Match[] matches)
Expression[] GetArgumentExpressions(IInvocation invocation, Match[] matches)
{
// First, let's pretend that all arguments are constant values:
var parameterTypes = invocation.Method.GetParameterTypes();
Expand Down Expand Up @@ -239,7 +239,7 @@ private sealed class Recorder : IInterceptor
{
private readonly MatcherObserver matcherObserver;
private int creationTimestamp;
private Invocation invocation;
private IInvocation invocation;
private int invocationTimestamp;
private object returnValue;

Expand All @@ -251,7 +251,7 @@ public Recorder(MatcherObserver matcherObserver)
this.creationTimestamp = this.matcherObserver.GetNextTimestamp();
}

public Invocation Invocation => this.invocation;
public IInvocation Invocation => this.invocation;

public IEnumerable<Match> Matches
{
Expand All @@ -264,7 +264,7 @@ public IEnumerable<Match> Matches

public Recorder Next => (Awaitable.TryGetResultRecursive(this.returnValue) as IProxy)?.Interceptor as Recorder;

public void Intercept(Invocation invocation)
public void Intercept(IInvocation invocation)
{
var returnType = invocation.Method.ReturnType;

Expand Down
16 changes: 15 additions & 1 deletion src/Moq/Async/IAwaitableFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,32 @@

namespace Moq.Async
{
internal interface IAwaitableFactory
/// <summary>
/// </summary>
public interface IAwaitableFactory
{
/// <summary>
/// </summary>
Type ResultType { get; }

/// <summary>
/// </summary>
object CreateCompleted(object result = null);

/// <summary>
/// </summary>
object CreateFaulted(Exception exception);

/// <summary>
/// </summary>
object CreateFaulted(IEnumerable<Exception> exceptions);

/// <summary>
/// </summary>
Expression CreateResultExpression(Expression awaitableExpression);

/// <summary>
/// </summary>
bool TryGetResult(object awaitable, out object result);
}
}
2 changes: 1 addition & 1 deletion src/Moq/AutoImplementedPropertyGetterSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public AutoImplementedPropertyGetterSetup(Mock mock, LambdaExpression originalEx
this.MarkAsVerifiable();
}

protected override void ExecuteCore(Invocation invocation)
protected override void ExecuteCore(IInvocation invocation)
{
invocation.ReturnValue = this.getter.Invoke();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/AutoImplementedPropertySetterSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public AutoImplementedPropertySetterSetup(Mock mock, LambdaExpression originalEx
this.MarkAsVerifiable();
}

protected override void ExecuteCore(Invocation invocation)
protected override void ExecuteCore(IInvocation invocation)
{
this.setter.Invoke(invocation.Arguments[0]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ protected Behavior()
{
}

public abstract void Execute(Invocation invocation);
public abstract void Execute(IInvocation invocation);
}
}
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/Callback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public Callback(Action<IInvocation> callback)
this.callback = callback;
}

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
this.callback.Invoke(invocation);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/LimitInvocationCount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void Reset()
this.count = 0;
}

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
++this.count;

Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/NoOp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ private NoOp()
{
}

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/RaiseEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public RaiseEvent(Mock mock, LambdaExpression expression, Delegate eventArgsFunc
this.eventArgsParams = eventArgsParams;
}

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
object[] args;

Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/ReturnBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ private ReturnBase()
{
}

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
invocation.ReturnValue = invocation.CallBase();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/ReturnBaseOrDefaultValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public ReturnBaseOrDefaultValue(Mock mock)
this.mock = mock;
}

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
Debug.Assert(invocation.Method != null);
Debug.Assert(invocation.Method.ReturnType != null);
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/ReturnComputedValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public ReturnComputedValue(Func<IInvocation, object> valueFactory)
this.valueFactory = valueFactory;
}

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
invocation.ReturnValue = this.valueFactory.Invoke(invocation);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/ReturnValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public ReturnValue(object value)

public object Value => this.value;

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
invocation.ReturnValue = this.value;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Behaviors/ThrowException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public ThrowException(Exception exception)
this.exception = exception;
}

public override void Execute(Invocation invocation)
public override void Execute(IInvocation invocation)
{
throw this.exception;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ public static Setup TryFind(this IEnumerable<Setup> setups, InvocationShape expe
return setups.FirstOrDefault(setup => setup.Expectation.Equals(expectation));
}

public static Setup TryFind(this IEnumerable<Setup> setups, Invocation invocation)
public static Setup TryFind(this IEnumerable<Setup> setups, IInvocation invocation)
{
return setups.FirstOrDefault(setup => setup.Matches(invocation));
}
Expand Down
27 changes: 24 additions & 3 deletions src/Moq/IInvocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Moq.Async;

namespace Moq
{
Expand All @@ -17,16 +18,24 @@ public interface IInvocation
/// </summary>
MethodInfo Method { get; }

/// <summary>
/// </summary>
MethodInfo MethodImplementation { get; }

/// <summary>
/// Gets the arguments of the invocation.
/// </summary>
IReadOnlyList<object> Arguments { get; }
object[] Arguments { get; }

/// <summary>
/// Gets the setup that matched this invocation (or <see langword="null"/> if there was no matching setup).
/// </summary>
ISetup MatchingSetup { get; }

/// <summary>
/// </summary>
Type ProxyType { get; }

/// <summary>
/// Gets whether this invocation was successfully verified by any of the various <c>`Verify`</c> methods.
/// </summary>
Expand All @@ -35,11 +44,23 @@ public interface IInvocation
/// <summary>
/// The value being returned for a non-void method if no exception was thrown.
/// </summary>
object ReturnValue { get; }
object ReturnValue { get; set; }

/// <summary>
/// Optional exception if the method invocation results in an exception being thrown.
/// </summary>
Exception Exception { get; }
Exception Exception { get; set; }

/// <summary>
/// </summary>
void MarkAsMatchedBy(ISetup setup);

/// <summary>
/// </summary>
void ConvertResultToAwaitable(IAwaitableFactory awaitableFactory);

/// <summary>
/// </summary>
object CallBase();
}
}
2 changes: 1 addition & 1 deletion src/Moq/InnerMockSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public InnerMockSetup(Expression originalExpression, Mock mock, InvocationShape
this.MarkAsVerifiable();
}

protected override void ExecuteCore(Invocation invocation)
protected override void ExecuteCore(IInvocation invocation)
{
invocation.ReturnValue = this.returnValue;
}
Expand Down
6 changes: 4 additions & 2 deletions src/Moq/Interception/IInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ namespace Moq
/// This role interface represents a <see cref="Mock"/>'s ability to intercept method invocations for its <see cref="Mock.Object"/>.
/// It is meant for use by <see cref="ProxyFactory"/>.
/// </summary>
internal interface IInterceptor
public interface IInterceptor
{
void Intercept(Invocation invocation);
/// <summary>
/// </summary>
void Intercept(IInvocation invocation);
}
}
26 changes: 13 additions & 13 deletions src/Moq/Interception/InterceptionAspects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Moq
{
internal static class HandleWellKnownMethods
{
private static Dictionary<string, Func<Invocation, Mock, bool>> specialMethods = new Dictionary<string, Func<Invocation, Mock, bool>>()
private static Dictionary<string, Func<IInvocation, Mock, bool>> specialMethods = new Dictionary<string, Func<IInvocation, Mock, bool>>()
{
["Equals"] = HandleEquals,
["Finalize"] = HandleFinalize,
Expand All @@ -22,13 +22,13 @@ internal static class HandleWellKnownMethods
["ToString"] = HandleToString,
};

public static bool Handle(Invocation invocation, Mock mock)
public static bool Handle(IInvocation invocation, Mock mock)
{
return specialMethods.TryGetValue(invocation.Method.Name, out var handler)
&& handler.Invoke(invocation, mock);
}

private static bool HandleEquals(Invocation invocation, Mock mock)
private static bool HandleEquals(IInvocation invocation, Mock mock)
{
if (IsObjectMethod(invocation.Method) && !mock.MutableSetups.Any(c => IsObjectMethod(c.Method, "Equals")))
{
Expand All @@ -41,12 +41,12 @@ private static bool HandleEquals(Invocation invocation, Mock mock)
}
}

private static bool HandleFinalize(Invocation invocation, Mock mock)
private static bool HandleFinalize(IInvocation invocation, Mock mock)
{
return IsFinalizer(invocation.Method);
}

private static bool HandleGetHashCode(Invocation invocation, Mock mock)
private static bool HandleGetHashCode(IInvocation invocation, Mock mock)
{
// Only if there is no corresponding setup for `GetHashCode()`
if (IsObjectMethod(invocation.Method) && !mock.MutableSetups.Any(c => IsObjectMethod(c.Method, "GetHashCode")))
Expand All @@ -60,7 +60,7 @@ private static bool HandleGetHashCode(Invocation invocation, Mock mock)
}
}

private static bool HandleToString(Invocation invocation, Mock mock)
private static bool HandleToString(IInvocation invocation, Mock mock)
{
// Only if there is no corresponding setup for `ToString()`
if (IsObjectMethod(invocation.Method) && !mock.MutableSetups.Any(c => IsObjectMethod(c.Method, "ToString")))
Expand All @@ -74,7 +74,7 @@ private static bool HandleToString(Invocation invocation, Mock mock)
}
}

private static bool HandleMockGetter(Invocation invocation, Mock mock)
private static bool HandleMockGetter(IInvocation invocation, Mock mock)
{
if (typeof(IMocked).IsAssignableFrom(invocation.Method.DeclaringType))
{
Expand All @@ -99,7 +99,7 @@ private static bool IsFinalizer(MethodInfo method)

internal static class FindAndExecuteMatchingSetup
{
public static bool Handle(Invocation invocation, Mock mock)
public static bool Handle(IInvocation invocation, Mock mock)
{
var matchingSetup = mock.MutableSetups.FindMatchFor(invocation);
if (matchingSetup != null)
Expand All @@ -116,7 +116,7 @@ public static bool Handle(Invocation invocation, Mock mock)

internal static class HandleEventSubscription
{
public static bool Handle(Invocation invocation, Mock mock)
public static bool Handle(IInvocation invocation, Mock mock)
{
const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;

Expand Down Expand Up @@ -170,7 +170,7 @@ public static bool Handle(Invocation invocation, Mock mock)

internal static class RecordInvocation
{
public static void Handle(Invocation invocation, Mock mock)
public static void Handle(IInvocation invocation, Mock mock)
{
// Save to support Verify[expression] pattern.
mock.MutableInvocations.Add(invocation);
Expand All @@ -179,7 +179,7 @@ public static void Handle(Invocation invocation, Mock mock)

internal static class Return
{
public static void Handle(Invocation invocation, Mock mock)
public static void Handle(IInvocation invocation, Mock mock)
{
new ReturnBaseOrDefaultValue(mock).Execute(invocation);
}
Expand All @@ -189,7 +189,7 @@ internal static class HandleAutoSetupProperties
{
private static readonly int AccessorPrefixLength = "?et_".Length; // get_ or set_

public static bool Handle(Invocation invocation, Mock mock)
public static bool Handle(IInvocation invocation, Mock mock)
{
if (mock.AutoSetupPropertiesDefaultValueProvider == null)
{
Expand Down Expand Up @@ -278,7 +278,7 @@ private static LambdaExpression GetPropertyExpression(Type mockType, PropertyInf

internal static class FailForStrictMock
{
public static void Handle(Invocation invocation, Mock mock)
public static void Handle(IInvocation invocation, Mock mock)
{
if (mock.Behavior == MockBehavior.Strict)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Interception/Mock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Moq
{
partial class Mock : IInterceptor
{
void IInterceptor.Intercept(Invocation invocation)
void IInterceptor.Intercept(IInvocation invocation)
{
if (HandleWellKnownMethods.Handle(invocation, this))
{
Expand Down