Skip to content

Commit

Permalink
Enable task.Result in delegate-based setup methods
Browse files Browse the repository at this point in the history
  • Loading branch information
stakx committed Jan 1, 2021
1 parent 42521c4 commit 66bcb21
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/Moq/ActionObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Linq.Expressions;
using System.Reflection;

using Moq.Async;
using Moq.Expressions.Visitors;
using Moq.Internals;
using Moq.Properties;
Expand Down Expand Up @@ -60,6 +61,19 @@ public override Expression<Action<T>> ReconstructExpression<T>(Action<T> action,
var invocation = recorder.Invocation;
if (invocation != null)
{
var resultType = invocation.Method.DeclaringType;
if (resultType.IsAssignableFrom(body.Type) == false)
{
if (AwaitableFactory.TryGet(body.Type) is { } awaitableHandler
&& awaitableHandler.ResultType.IsAssignableFrom(resultType))
{
// We are here because the current invocation cannot be chained onto the previous one,
// however it *can* be chained if we assume that there was a `.Result` query on the
// former invocation that we don't see because non-virtual members aren't recorded.
// In this case, we make things work by adding back the missing `.Result`:
body = awaitableHandler.CreateResultExpression(body);
}
}
body = Expression.Call(body, invocation.Method, GetArgumentExpressions(invocation, recorder.Matches.ToArray()));
}
else
Expand Down Expand Up @@ -227,7 +241,7 @@ private sealed class Recorder : IInterceptor
private int creationTimestamp;
private Invocation invocation;
private int invocationTimestamp;
private IProxy returnValue;
private object returnValue;

public Recorder(MatcherObserver matcherObserver)
{
Expand All @@ -248,7 +262,7 @@ public IEnumerable<Match> Matches
}
}

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

public void Intercept(Invocation invocation)
{
Expand Down Expand Up @@ -277,6 +291,11 @@ public void Intercept(Invocation invocation)
{
this.returnValue = null;
}
else if (AwaitableFactory.TryGet(returnType) is { } awaitableFactory)
{
var result = CreateProxy(awaitableFactory.ResultType, null, this.matcherObserver, out _);
this.returnValue = awaitableFactory.CreateCompleted(result);
}
else if (returnType.IsMockable())
{
this.returnValue = CreateProxy(returnType, null, this.matcherObserver, out _);
Expand Down

0 comments on commit 66bcb21

Please sign in to comment.