Skip to content

Commit 10101d6

Browse files
committed
Split SubstituteExtensions into multiple files
1 parent 603645d commit 10101d6

8 files changed

+474
-422
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Disable nullability for client API, so it does not affect clients.
2+
3+
using System.Collections.Generic;
4+
using NSubstitute.ClearExtensions;
5+
using NSubstitute.Core;
6+
using NSubstitute.Exceptions;
7+
using NSubstitute.ReceivedExtensions;
8+
9+
#nullable disable annotations
10+
11+
namespace NSubstitute
12+
{
13+
public static partial class SubstituteExtensions
14+
{
15+
/// <summary>
16+
/// Checks this substitute has received the following call.
17+
/// </summary>
18+
public static T Received<T>(this T substitute) where T : class
19+
{
20+
if (substitute == null) throw new NullSubstituteReferenceException();
21+
22+
return substitute.Received(Quantity.AtLeastOne());
23+
}
24+
25+
/// <summary>
26+
/// Checks this substitute has received the following call the required number of times.
27+
/// </summary>
28+
public static T Received<T>(this T substitute, int requiredNumberOfCalls) where T : class
29+
{
30+
if (substitute == null) throw new NullSubstituteReferenceException();
31+
32+
return substitute.Received(Quantity.Exactly(requiredNumberOfCalls));
33+
}
34+
35+
/// <summary>
36+
/// Checks this substitute has not received the following call.
37+
/// </summary>
38+
public static T DidNotReceive<T>(this T substitute) where T : class
39+
{
40+
if (substitute == null) throw new NullSubstituteReferenceException();
41+
42+
return substitute.Received(Quantity.None());
43+
}
44+
45+
/// <summary>
46+
/// Checks this substitute has received the following call with any arguments.
47+
/// </summary>
48+
public static T ReceivedWithAnyArgs<T>(this T substitute) where T : class
49+
{
50+
if (substitute == null) throw new NullSubstituteReferenceException();
51+
52+
return substitute.ReceivedWithAnyArgs(Quantity.AtLeastOne());
53+
}
54+
55+
/// <summary>
56+
/// Checks this substitute has received the following call with any arguments the required number of times.
57+
/// </summary>
58+
public static T ReceivedWithAnyArgs<T>(this T substitute, int requiredNumberOfCalls) where T : class
59+
{
60+
if (substitute == null) throw new NullSubstituteReferenceException();
61+
62+
return substitute.ReceivedWithAnyArgs(Quantity.Exactly(requiredNumberOfCalls));
63+
}
64+
65+
/// <summary>
66+
/// Checks this substitute has not received the following call with any arguments.
67+
/// </summary>
68+
public static T DidNotReceiveWithAnyArgs<T>(this T substitute) where T : class
69+
{
70+
if (substitute == null) throw new NullSubstituteReferenceException();
71+
72+
return substitute.ReceivedWithAnyArgs(Quantity.None());
73+
}
74+
75+
/// <summary>
76+
/// Returns the calls received by this substitute.
77+
/// </summary>
78+
public static IEnumerable<ICall> ReceivedCalls<T>(this T substitute) where T : class
79+
{
80+
if (substitute == null) throw new NullSubstituteReferenceException();
81+
82+
return SubstitutionContext
83+
.Current
84+
.GetCallRouterFor(substitute!)
85+
.ReceivedCalls();
86+
}
87+
88+
/// <summary>
89+
/// Forget all the calls this substitute has received.
90+
/// </summary>
91+
/// <remarks>
92+
/// Note that this will not clear any results set up for the substitute using Returns().
93+
/// See <see cref="NSubstitute.ClearExtensions.ClearExtensions.ClearSubstitute{T}"/> for more options with resetting
94+
/// a substitute.
95+
/// </remarks>
96+
public static void ClearReceivedCalls<T>(this T substitute) where T : class
97+
{
98+
if (substitute == null) throw new NullSubstituteReferenceException();
99+
100+
substitute.ClearSubstitute(ClearOptions.ReceivedCalls);
101+
}
102+
}
103+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using System;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using NSubstitute.Core;
5+
using NSubstitute.Exceptions;
6+
7+
// Disable nullability for client API, so it does not affect clients.
8+
#nullable disable annotations
9+
10+
namespace NSubstitute
11+
{
12+
public static partial class SubstituteExtensions
13+
{
14+
/// <summary>
15+
/// Set a return value for this call. The value(s) to be returned will be wrapped in Tasks.
16+
/// </summary>
17+
/// <param name="value"></param>
18+
/// <param name="returnThis">Value to return. Will be wrapped in a Task</param>
19+
/// <param name="returnThese">Optionally use these values next</param>
20+
public static ConfiguredCall Returns<T>(this Task<T> value, T returnThis, params T[] returnThese)
21+
{
22+
ReThrowOnNSubstituteFault(value);
23+
24+
var wrappedReturnValue = CompletedTask(returnThis);
25+
var wrappedReturnThese = returnThese.Length > 0 ? returnThese.Select(CompletedTask).ToArray() : null;
26+
27+
return ConfigureReturn(MatchArgs.AsSpecifiedInCall, wrappedReturnValue, wrappedReturnThese);
28+
}
29+
30+
/// <summary>
31+
/// Set a return value for this call, calculated by the provided function. The value(s) to be returned will be wrapped in Tasks.
32+
/// </summary>
33+
/// <param name="value"></param>
34+
/// <param name="returnThis">Function to calculate the return value</param>
35+
/// <param name="returnThese">Optionally use these functions next</param>
36+
public static ConfiguredCall Returns<T>(this Task<T> value, Func<CallInfo, T> returnThis, params Func<CallInfo, T>[] returnThese)
37+
{
38+
ReThrowOnNSubstituteFault(value);
39+
40+
var wrappedFunc = WrapFuncInTask(returnThis);
41+
var wrappedReturnThese = returnThese.Length > 0 ? returnThese.Select(WrapFuncInTask).ToArray() : null;
42+
43+
return ConfigureReturn(MatchArgs.AsSpecifiedInCall, wrappedFunc, wrappedReturnThese);
44+
}
45+
46+
/// <summary>
47+
/// Set a return value for this call made with any arguments. The value(s) to be returned will be wrapped in Tasks.
48+
/// </summary>
49+
/// <param name="value"></param>
50+
/// <param name="returnThis">Value to return</param>
51+
/// <param name="returnThese">Optionally return these values next</param>
52+
public static ConfiguredCall ReturnsForAnyArgs<T>(this Task<T> value, T returnThis, params T[] returnThese)
53+
{
54+
ReThrowOnNSubstituteFault(value);
55+
56+
var wrappedReturnValue = CompletedTask(returnThis);
57+
var wrappedReturnThese = returnThese.Length > 0 ? returnThese.Select(CompletedTask).ToArray() : null;
58+
59+
return ConfigureReturn(MatchArgs.Any, wrappedReturnValue, wrappedReturnThese);
60+
}
61+
62+
/// <summary>
63+
/// Set a return value for this call made with any arguments, calculated by the provided function. The value(s) to be returned will be wrapped in Tasks.
64+
/// </summary>
65+
/// <param name="value"></param>
66+
/// <param name="returnThis">Function to calculate the return value</param>
67+
/// <param name="returnThese">Optionally use these functions next</param>
68+
public static ConfiguredCall ReturnsForAnyArgs<T>(this Task<T> value, Func<CallInfo, T> returnThis, params Func<CallInfo, T>[] returnThese)
69+
{
70+
ReThrowOnNSubstituteFault(value);
71+
72+
var wrappedFunc = WrapFuncInTask(returnThis);
73+
var wrappedReturnThese = returnThese.Length > 0 ? returnThese.Select(WrapFuncInTask).ToArray() : null;
74+
75+
return ConfigureReturn(MatchArgs.Any, wrappedFunc, wrappedReturnThese);
76+
}
77+
78+
#nullable restore
79+
private static void ReThrowOnNSubstituteFault<T>(Task<T?> task)
80+
{
81+
if (task.IsFaulted && task.Exception!.InnerExceptions.FirstOrDefault() is SubstituteException)
82+
{
83+
task.GetAwaiter().GetResult();
84+
}
85+
}
86+
87+
private static Task<T?> CompletedTask<T>(T? result) => Task.FromResult(result);
88+
89+
private static Func<CallInfo, Task<T?>> WrapFuncInTask<T>(Func<CallInfo, T> returnThis) =>
90+
x => CompletedTask(returnThis(x));
91+
}
92+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using System;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using NSubstitute.Core;
5+
using NSubstitute.Exceptions;
6+
7+
// Disable nullability for client API, so it does not affect clients.
8+
#nullable disable annotations
9+
10+
namespace NSubstitute
11+
{
12+
public static partial class SubstituteExtensions
13+
{
14+
/// <summary>
15+
/// Set a return value for this call. The value(s) to be returned will be wrapped in ValueTasks.
16+
/// </summary>
17+
/// <param name="value"></param>
18+
/// <param name="returnThis">Value to return. Will be wrapped in a ValueTask</param>
19+
/// <param name="returnThese">Optionally use these values next</param>
20+
public static ConfiguredCall Returns<T>(this ValueTask<T> value, T returnThis, params T[] returnThese)
21+
{
22+
ReThrowOnNSubstituteFault(value);
23+
24+
var wrappedReturnValue = CompletedValueTask(returnThis);
25+
var wrappedReturnThese = returnThese.Length > 0 ? returnThese.Select(CompletedValueTask).ToArray() : null;
26+
27+
return ConfigureReturn(MatchArgs.AsSpecifiedInCall, wrappedReturnValue, wrappedReturnThese);
28+
}
29+
30+
/// <summary>
31+
/// Set a return value for this call, calculated by the provided function. The value(s) to be returned will be wrapped in ValueTasks.
32+
/// </summary>
33+
/// <param name="value"></param>
34+
/// <param name="returnThis">Function to calculate the return value</param>
35+
/// <param name="returnThese">Optionally use these functions next</param>
36+
public static ConfiguredCall Returns<T>(this ValueTask<T> value, Func<CallInfo, T> returnThis, params Func<CallInfo, T>[] returnThese)
37+
{
38+
ReThrowOnNSubstituteFault(value);
39+
40+
var wrappedFunc = WrapFuncInValueTask(returnThis);
41+
var wrappedReturnThese = returnThese.Length > 0 ? returnThese.Select(WrapFuncInValueTask).ToArray() : null;
42+
43+
return ConfigureReturn(MatchArgs.AsSpecifiedInCall, wrappedFunc, wrappedReturnThese);
44+
}
45+
46+
/// <summary>
47+
/// Set a return value for this call made with any arguments. The value(s) to be returned will be wrapped in ValueTasks.
48+
/// </summary>
49+
/// <param name="value"></param>
50+
/// <param name="returnThis">Value to return</param>
51+
/// <param name="returnThese">Optionally return these values next</param>
52+
public static ConfiguredCall ReturnsForAnyArgs<T>(this ValueTask<T> value, T returnThis, params T[] returnThese)
53+
{
54+
ReThrowOnNSubstituteFault(value);
55+
56+
var wrappedReturnValue = CompletedValueTask(returnThis);
57+
var wrappedReturnThese = returnThese.Length > 0 ? returnThese.Select(CompletedValueTask).ToArray() : null;
58+
59+
return ConfigureReturn(MatchArgs.Any, wrappedReturnValue, wrappedReturnThese);
60+
}
61+
62+
/// <summary>
63+
/// Set a return value for this call made with any arguments, calculated by the provided function. The value(s) to be returned will be wrapped in ValueTasks.
64+
/// </summary>
65+
/// <param name="value"></param>
66+
/// <param name="returnThis">Function to calculate the return value</param>
67+
/// <param name="returnThese">Optionally use these functions next</param>
68+
public static ConfiguredCall ReturnsForAnyArgs<T>(this ValueTask<T> value, Func<CallInfo, T> returnThis, params Func<CallInfo, T>[] returnThese)
69+
{
70+
ReThrowOnNSubstituteFault(value);
71+
72+
var wrappedFunc = WrapFuncInValueTask(returnThis);
73+
var wrappedReturnThese = returnThese.Length > 0 ? returnThese.Select(WrapFuncInValueTask).ToArray() : null;
74+
75+
return ConfigureReturn(MatchArgs.Any, wrappedFunc, wrappedReturnThese);
76+
}
77+
78+
#nullable restore
79+
private static void ReThrowOnNSubstituteFault<T>(ValueTask<T?> task)
80+
{
81+
if (task.IsFaulted && task.AsTask().Exception!.InnerExceptions.FirstOrDefault() is SubstituteException)
82+
{
83+
task.GetAwaiter().GetResult();
84+
}
85+
}
86+
87+
private static ValueTask<T?> CompletedValueTask<T>(T? result) => new(result);
88+
89+
private static Func<CallInfo, ValueTask<T?>> WrapFuncInValueTask<T>(Func<CallInfo, T> returnThis) =>
90+
x => CompletedValueTask(returnThis(x));
91+
}
92+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System;
2+
using System.Linq;
3+
using NSubstitute.Core;
4+
5+
// Disable nullability for client API, so it does not affect clients.
6+
#nullable disable annotations
7+
8+
namespace NSubstitute
9+
{
10+
public static partial class SubstituteExtensions
11+
{
12+
/// <summary>
13+
/// Set a return value for this call.
14+
/// </summary>
15+
/// <param name="value"></param>
16+
/// <param name="returnThis">Value to return</param>
17+
/// <param name="returnThese">Optionally return these values next</param>
18+
public static ConfiguredCall Returns<T>(this T value, T returnThis, params T[] returnThese) =>
19+
ConfigureReturn(MatchArgs.AsSpecifiedInCall, returnThis, returnThese);
20+
21+
/// <summary>
22+
/// Set a return value for this call, calculated by the provided function.
23+
/// </summary>
24+
/// <param name="value"></param>
25+
/// <param name="returnThis">Function to calculate the return value</param>
26+
/// <param name="returnThese">Optionally use these functions next</param>
27+
public static ConfiguredCall Returns<T>(this T value, Func<CallInfo, T> returnThis, params Func<CallInfo, T>[] returnThese) =>
28+
ConfigureReturn(MatchArgs.AsSpecifiedInCall, returnThis, returnThese);
29+
30+
/// <summary>
31+
/// Set a return value for this call made with any arguments.
32+
/// </summary>
33+
/// <param name="value"></param>
34+
/// <param name="returnThis">Value to return</param>
35+
/// <param name="returnThese">Optionally return these values next</param>
36+
public static ConfiguredCall ReturnsForAnyArgs<T>(this T value, T returnThis, params T[] returnThese) =>
37+
ConfigureReturn(MatchArgs.Any, returnThis, returnThese);
38+
39+
/// <summary>
40+
/// Set a return value for this call made with any arguments, calculated by the provided function.
41+
/// </summary>
42+
/// <param name="value"></param>
43+
/// <param name="returnThis">Function to calculate the return value</param>
44+
/// <param name="returnThese">Optionally use these functions next</param>
45+
/// <returns></returns>
46+
public static ConfiguredCall ReturnsForAnyArgs<T>(this T value, Func<CallInfo, T> returnThis, params Func<CallInfo, T>[] returnThese) =>
47+
ConfigureReturn(MatchArgs.Any, returnThis, returnThese);
48+
49+
#nullable restore
50+
private static ConfiguredCall ConfigureReturn<T>(MatchArgs matchArgs, T? returnThis, T?[]? returnThese)
51+
{
52+
IReturn returnValue;
53+
if (returnThese == null || returnThese.Length == 0)
54+
{
55+
returnValue = new ReturnValue(returnThis);
56+
}
57+
else
58+
{
59+
returnValue = new ReturnMultipleValues<T>(new[] { returnThis }.Concat(returnThese).ToArray());
60+
}
61+
return SubstitutionContext
62+
.Current
63+
.ThreadContext
64+
.LastCallShouldReturn(returnValue, matchArgs);
65+
}
66+
67+
private static ConfiguredCall ConfigureReturn<T>(MatchArgs matchArgs, Func<CallInfo, T?> returnThis, Func<CallInfo, T?>[]? returnThese)
68+
{
69+
IReturn returnValue;
70+
if (returnThese == null || returnThese.Length == 0)
71+
{
72+
returnValue = new ReturnValueFromFunc<T>(returnThis);
73+
}
74+
else
75+
{
76+
returnValue = new ReturnMultipleFuncsValues<T>(new[] { returnThis }.Concat(returnThese).ToArray());
77+
}
78+
79+
return SubstitutionContext
80+
.Current
81+
.ThreadContext
82+
.LastCallShouldReturn(returnValue, matchArgs);
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)