/
SubstitutionContext.cs
171 lines (146 loc) · 10.1 KB
/
SubstitutionContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
using System;
using System.Collections.Generic;
using NSubstitute.Core.Arguments;
using NSubstitute.Core.DependencyInjection;
using NSubstitute.Routing;
namespace NSubstitute.Core
{
public class SubstitutionContext : ISubstitutionContext
{
public static ISubstitutionContext Current { get; set; }
private readonly ICallRouterResolver _callRouterResolver;
public ISubstituteFactory SubstituteFactory { get; }
public IRouteFactory RouteFactory { get; }
public IThreadLocalContext ThreadContext { get; }
public ICallSpecificationFactory CallSpecificationFactory { get; }
static SubstitutionContext()
{
Current = NSubstituteDefaultFactory.CreateSubstitutionContext();
}
public SubstitutionContext(ISubstituteFactory substituteFactory,
IRouteFactory routeFactory,
ICallSpecificationFactory callSpecificationFactory,
IThreadLocalContext threadLocalContext,
ICallRouterResolver callRouterResolver,
SequenceNumberGenerator sequenceNumberGenerator)
{
SubstituteFactory = substituteFactory ?? throw new ArgumentNullException(nameof(substituteFactory));
RouteFactory = routeFactory ?? throw new ArgumentNullException(nameof(routeFactory));
CallSpecificationFactory = callSpecificationFactory ?? throw new ArgumentNullException(nameof(callSpecificationFactory));
ThreadContext = threadLocalContext ?? throw new ArgumentNullException(nameof(threadLocalContext));
_callRouterResolver = callRouterResolver ?? throw new ArgumentNullException(nameof(callRouterResolver));
#pragma warning disable 618 // Obsolete
SequenceNumberGenerator = sequenceNumberGenerator;
#pragma warning restore 618 // Obsolete
}
public ICallRouter GetCallRouterFor(object substitute) =>
_callRouterResolver.ResolveFor(substitute);
// ***********************************************************
// ********************** OBSOLETE API **********************
// API below is obsolete and present for the binary compatibility with the previous versions.
// All implementations are relaying to the non-obsolete members.
[Obsolete("This property is obsolete and will be removed in a future version of the product.")]
public SequenceNumberGenerator SequenceNumberGenerator { get; }
[Obsolete("This property is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.IsQuerying) + " property instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.IsQuerying) + ".")]
public bool IsQuerying => ThreadContext.IsQuerying;
[Obsolete("This property is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.PendingSpecification) + " property instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.PendingSpecification) + ".")]
public PendingSpecificationInfo PendingSpecificationInfo
{
get
{
if (!ThreadContext.PendingSpecification.HasPendingCallSpecInfo())
return null;
// This removes the pending specification, so we need to restore it back.
var consumedSpecInfo = ThreadContext.PendingSpecification.UseCallSpecInfo();
PendingSpecificationInfo = consumedSpecInfo;
return consumedSpecInfo;
}
set
{
if (value == null)
{
ThreadContext.PendingSpecification.Clear();
return;
}
// Emulate the old API. A bit clumsy, however it's here for the backward compatibility only
// and is not expected to be used frequently.
var unwrappedValue = value.Handle(
spec => Tuple.Create(spec, (ICall) null),
call => Tuple.Create((ICallSpecification) null, call));
if (unwrappedValue.Item1 != null)
{
ThreadContext.PendingSpecification.SetCallSpecification(unwrappedValue.Item1);
}
else
{
ThreadContext.PendingSpecification.SetLastCall(unwrappedValue.Item2);
}
}
}
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.LastCallShouldReturn) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.LastCallShouldReturn) + "(...).")]
public ConfiguredCall LastCallShouldReturn(IReturn value, MatchArgs matchArgs) =>
ThreadContext.LastCallShouldReturn(value, matchArgs);
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.ClearLastCallRouter) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.ClearLastCallRouter) + "().")]
public void ClearLastCallRouter() =>
ThreadContext.ClearLastCallRouter();
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(RouteFactory) + " property instead.")]
public IRouteFactory GetRouteFactory() =>
RouteFactory;
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.SetLastCallRouter) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.SetLastCallRouter) + "(...).")]
public void LastCallRouter(ICallRouter callRouter) =>
ThreadContext.SetLastCallRouter(callRouter);
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.EnqueueArgumentSpecification) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.EnqueueArgumentSpecification) + "(...).")]
public void EnqueueArgumentSpecification(IArgumentSpecification spec) =>
ThreadContext.EnqueueArgumentSpecification(spec);
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.DequeueAllArgumentSpecifications) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.DequeueAllArgumentSpecifications) + "().")]
public IList<IArgumentSpecification> DequeueAllArgumentSpecifications() =>
ThreadContext.DequeueAllArgumentSpecifications();
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.SetPendingRaisingEventArgumentsFactory) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.SetPendingRaisingEventArgumentsFactory) + "(...).")]
public void RaiseEventForNextCall(Func<ICall, object[]> getArguments) =>
ThreadContext.SetPendingRaisingEventArgumentsFactory(getArguments);
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.UsePendingRaisingEventArgumentsFactory) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.UsePendingRaisingEventArgumentsFactory) + "().")]
public Func<ICall, object[]> DequeuePendingRaisingEventArguments() =>
ThreadContext.UsePendingRaisingEventArgumentsFactory();
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.RegisterInContextQuery) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.RegisterInContextQuery) + "().",
error: true)]
public void AddToQuery(object target, ICallSpecification callSpecification)
{
// We cannot simulate the API anymore as it changed drastically.
// That should be fine, as this method was expected to be called from the NSubstitute core only.
throw new NotSupportedException(
"This API was obsolete and is not supported anymore. " +
"Please use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.RegisterInContextQuery) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.RegisterInContextQuery) + "().");
}
[Obsolete("This method is obsolete and will be removed in a future version of the product. " +
"Use the " + nameof(ThreadContext) + "." + nameof(IThreadLocalContext.RunInQueryContext) + "() method instead. " +
"For example: SubstitutionContext.Current.ThreadContext." + nameof(IThreadLocalContext.RunInQueryContext) + "(...).")]
public IQueryResults RunQuery(Action calls)
{
var query = new Query(CallSpecificationFactory);
ThreadContext.RunInQueryContext(calls, query);
return query.Result();
}
}
}