8000 Arguments in recursive expressions should not be treated like `It.IsAny` by default by stakx · Pull Request #780 · devlooped/moq · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This release contains several **minor breaking changes**. Please review your cod
* `mock.Verify[All]` now performs a more thorough error aggregation. Error messages of inner/recursive mocks are included in the error message using indentation to show the relationship between mocks. (@stakx, #762)
* `mock.Verify` no longer creates setups, nor will it override existing setups, as a side-effect of using a recursive expression. (@stakx, #765)
* More accurate detection of argument matchers with `SetupSet` and `VerifySet`, especially when used in fluent setup expressions or with indexers (@stakx, #767)
* `mock.Verify(expression)` no longer includes setups in its error message, as they are completely irrelevant in the context of this method (@stakx, #779)
* `mock.Verify(expression)` error messages now contain a full listing of all invocations that occurred across all involved mocks. Setups are no longer listed, since they are completely irrelevant in the context of call verification. (@stakx, #779, #780)

#### Added

Expand Down
7 changes: 5 additions & 2 deletions src/Moq/AsInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;

namespace Moq
{
Expand Down Expand Up @@ -74,5 +72,10 @@ protected override object OnGetObject()
{
return this.owner.Object;
}

public override string ToString()
{
return this.owner.ToString();
}
}
}
19 changes: 17 additions & 2 deletions src/Moq/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,26 @@ private static void AddPropertiesInDepthFirstOrderTo(this Type type, List<Proper
}
}

public static bool TryFind(this IEnumerable<IDeterministicReturnValueSetup> setups, MethodInfo method, out IDeterministicReturnValueSetup setup)
public static bool TryFind(this IEnumerable<IDeterministicReturnValueSetup> setups, InvocationShape expectation, out IDeterministicReturnValueSetup setup)
{
foreach (Setup s in setups)
{
if (s.Method == method)
if (s.Expectation.Equals(expectation))
{
setup = (IDeterministicReturnValueSetup)s;
return true;
}
}

setup = default;
return false;
}

public static bool TryFind(this IEnumerable<IDeterministicReturnValueSetup> setups, Invocation invocation, out IDeterministicReturnValueSetup setup)
{
foreach (Setup s in setups)
{
if (s.Matches(invocation))
{
setup = (IDeterministicReturnValueSetup)s;
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/FluentMockVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ private static Mock<TResult> FluentMock<T, TResult>(Mock<T> mock, Expression<Fun

Mock fluentMock;
object result;
if (mock.GetInnerMockSetups().TryFind(info, out var inner))
if (mock.GetInnerMockSetups().TryFind(new InvocationShape(setup, info, arguments), out var inner))
{
fluentMock = inner.GetInnerMock();
result = inner.ReturnValue;
Expand Down
43 changes: 43 additions & 0 deletions src/Moq/ImmutablePoppableStack.cs
< 8000 td class="blob-code blob-code-addition js-file-line"> {
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD.
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Moq
{
internal readonly struct ImmutablePopOnlyStack<T>
{
private readonly T[] items;
private readonly int index;

public ImmutablePopOnlyStack(IEnumerable<T> items)
Debug.Assert(items != null);

this.items = items.ToArray();
this.index = 0;
}

private ImmutablePopOnlyStack(T[] items, int index)
{
Debug.Assert(items != null);
Debug.Assert(0 <= index && index <= items.Length);

this.items = items;
this.index = index;
}

public bool Empty => this.index == this.items.Length;

public T Pop(out ImmutablePopOnlyStack<T> stackBelowTop)
{
Debug.Assert(this.index < this.items.Length);

var top = this.items[this.index];
stackBelowTop = new ImmutablePopOnlyStack<T>(this.items, this.index + 1);
return top;
}
}
}
2 changes: 1 addition & 1 deletion src/Moq/Interception/InterceptionAspects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ public override InterceptionAction Handle(Invocation invocation, Mock mock)
var returnValue = mock.GetDefaultValue(method, out var innerMock);
if (innerMock != null)
{
mock.AddInnerMockSetup(method, returnValue);
mock.AddInnerMockSetup(invocation, returnValue);
}
invocation.Return(returnValue);
}
Expand Down
12 changes: 11 additions & 1 deletion src/Moq/Invocation.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD.
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
Expand All @@ -13,6 +12,7 @@ internal abstract class Invocation : IInvocation
{
private object[] arguments;
private MethodInfo method;
private object returnValue;
private VerificationState verificationState;

/// <summary>
Expand Down Expand Up @@ -45,6 +45,8 @@ protected Invocation(MethodInfo method, params object[] arguments)

IReadOnlyList<object> IInvocation.Arguments => this.arguments;

public object ReturnValue => this.returnValue;

internal bool Verified => this.verificationState == VerificationState.Verified;

/// <summary>
Expand Down Expand Up @@ -79,6 +81,7 @@ protected Invocation(MethodInfo method, params object[] arguments)
/// and that no more calls to any of the three <c>Return</c> methods will be made.
/// <para>
/// Implementations must ensure that any by-reference parameters are written back from <see cref="Arguments"/>.
/// Implementations must also call <see cref="SetReturnValue(object)"/>.
/// </para>
/// </remarks>
public abstract void Return(object value);
Expand Down Expand Up @@ -119,6 +122,13 @@ internal void MarkAsVerifiedIfMatchedByVerifiableSetup() // this supports the `
}
}

protected void SetReturnValue(object returnValue)
{
Debug.Assert(this.returnValue == null); // quick & dirty check against double invocations

this.returnValue = returnValue;
}

/// <inheritdoc/>
public override string ToString()
{
Expand Down
Loading
0