3636#pragma mark - Types & Constants
3737
3838@interface OHHTTPStubsProtocol : NSURLProtocol @end
39- typedef OHHTTPStubsResponse*(^OHHTTPStubsRequestHandler)(NSURLRequest * request, BOOL onlyCheck);
4039
4140static NSTimeInterval const kSlotTime = 0.25 ; // Must be >0. We will send a chunk of the data from the stream each 'slotTime' seconds
4241
4342// //////////////////////////////////////////////////////////////////////////////
44- #pragma mark - Private Interface
43+ #pragma mark - Private Interfaces
4544
4645@interface OHHTTPStubs ()
4746+ (instancetype )sharedInstance ;
48- @property (atomic , strong ) NSMutableArray * requestHandlers;
47+ @property (atomic , copy ) NSMutableArray * stubDescriptors;
48+ @property (atomic , copy ) void (^onStubActivationBlock)(NSURLRequest *, id <OHHTTPStubsDescriptor>);
4949@end
5050
51+ @interface OHHTTPStubsDescriptor : NSObject <OHHTTPStubsDescriptor>
52+ @property (atomic , copy ) OHHTTPStubsTestBlock testBlock;
53+ @property (atomic , copy ) OHHTTPStubsResponseBlock responseBlock;
54+ @end
55+
56+ // //////////////////////////////////////////////////////////////////////////////
57+ #pragma mark - OHHTTPStubsDescriptor Implementation
58+
59+ @implementation OHHTTPStubsDescriptor
60+
61+ @synthesize name = _name;
62+
63+ +(instancetype )stubDescriptorWithTestBlock : (OHHTTPStubsTestBlock)testBlock
64+ responseBlock : (OHHTTPStubsResponseBlock)responseBlock
65+ {
66+ OHHTTPStubsDescriptor* stub = [OHHTTPStubsDescriptor new ];
67+ stub.testBlock = testBlock;
68+ stub.responseBlock = responseBlock;
69+ return stub;
70+ }
71+
72+ -(NSString *)description
73+ {
74+ return [NSString stringWithFormat: @" <%@ %p : %@ >" , self .class, self , self .name];
75+ }
76+
77+ @end
78+
79+
80+
81+
5182// //////////////////////////////////////////////////////////////////////////////
52- #pragma mark - Implementation
83+ #pragma mark - OHHTTPStubs Implementation
5384
5485@implementation OHHTTPStubs
5586
@@ -76,7 +107,7 @@ - (id)init
76107 self = [super init ];
77108 if (self)
78109 {
79- _requestHandlers = [NSMutableArray array ];
110+ _stubDescriptors = [NSMutableArray array ];
80111 [self .class setEnabled: YES ];
81112 }
82113 return self;
@@ -90,34 +121,26 @@ - (void)dealloc
90121// //////////////////////////////////////////////////////////////////////////////
91122#pragma mark - Public class methods
92123
93- +(OHHTTPStubsID )stubRequestsPassingTest : (OHHTTPStubsTestBlock)testBlock
94- withStubResponse : (OHHTTPStubsResponseBlock)responseBlock
124+ +(id <OHHTTPStubsDescriptor> )stubRequestsPassingTest : (OHHTTPStubsTestBlock)testBlock
125+ withStubResponse : (OHHTTPStubsResponseBlock)responseBlock
95126{
96- return [self .sharedInstance addRequestHandler: ^OHHTTPStubsResponse *(NSURLRequest *request, BOOL onlyCheck)
97- {
98- BOOL shouldStub = testBlock ? testBlock (request) : YES ;
99- if (onlyCheck)
100- {
101- return shouldStub ? (OHHTTPStubsResponse*)@" DummyStub" : (OHHTTPStubsResponse*)nil ;
102- }
103- else
104- {
105- return (responseBlock && shouldStub) ? responseBlock (request) : nil ;
106- }
107- }];
127+ OHHTTPStubsDescriptor* stub = [OHHTTPStubsDescriptor stubDescriptorWithTestBlock: testBlock
128+ responseBlock: responseBlock];
129+ [OHHTTPStubs.sharedInstance addStub: stub];
130+ return stub;
108131}
109132
110- +(BOOL )removeStub : (OHHTTPStubsID) stubID
133+ +(BOOL )removeStub : (id <OHHTTPStubsDescriptor>) stubDesc
111134{
112- return [self .sharedInstance removeRequestHandler: stubID ];
135+ return [OHHTTPStubs .sharedInstance removeStub: stubDesc ];
113136}
114137+(void )removeLastStub
115138{
116- [self .sharedInstance removeLastRequestHandler ];
139+ [OHHTTPStubs .sharedInstance removeLastStub ];
117140}
118141+(void )removeAllStubs
119142{
120- [self .sharedInstance removeAllRequestHandlers ];
143+ [OHHTTPStubs .sharedInstance removeAllStubs ];
121144}
122145
123146+(void )setEnabled : (BOOL )enabled
@@ -130,66 +153,77 @@ +(void)setEnabled:(BOOL)enabled
130153 else if (!enabled && currentEnabledState)
131154 {
132155 // Force instanciate sharedInstance to avoid it being created later and this turning setEnabled to YES again
133- (void )self .sharedInstance ; // This way if we call [setEnabled:NO] before any call to sharedInstance it will be kept disabled
156+ (void )OHHTTPStubs .sharedInstance ; // This way if we call [setEnabled:NO] before any call to sharedInstance it will be kept disabled
134157 [NSURLProtocol unregisterClass: OHHTTPStubsProtocol.class];
135158 }
136159 currentEnabledState = enabled;
137160}
138161
162+ +(NSArray *)allStubs
163+ {
164+ return [OHHTTPStubs.sharedInstance stubDescriptors ];
165+ }
166+
167+ +(void )onStubActivation : ( void (^)(NSURLRequest * request, id <OHHTTPStubsDescriptor> stub) )block
168+ {
169+ [OHHTTPStubs.sharedInstance setOnStubActivationBlock: block];
170+ }
171+
172+
173+
139174// //////////////////////////////////////////////////////////////////////////////
140175#pragma mark - Private instance methods
141176
142- -(OHHTTPStubsID) addRequestHandler : (OHHTTPStubsRequestHandler) handler
177+ -(void ) addStub : (OHHTTPStubsDescriptor*) stubDesc
143178{
144- OHHTTPStubsRequestHandler handlerCopy = [handler copy ];
145- @synchronized (_requestHandlers)
179+ @synchronized (_stubDescriptors)
146180 {
147- [_requestHandlers addObject: handlerCopy ];
181+ [_stubDescriptors addObject: stubDesc ];
148182 }
149- return handlerCopy;
150183}
151184
152- -(BOOL )removeRequestHandler : (OHHTTPStubsID) stubID
185+ -(BOOL )removeStub : ( id <OHHTTPStubsDescriptor>) stubDesc
153186{
154187 BOOL handlerFound = NO ;
155- @synchronized (_requestHandlers )
188+ @synchronized (_stubDescriptors )
156189 {
157- handlerFound = [self .requestHandlers containsObject: stubID ];
158- [_requestHandlers removeObject: stubID ];
190+ handlerFound = [_stubDescriptors containsObject: stubDesc ];
191+ [_stubDescriptors removeObject: stubDesc ];
159192 }
160193 return handlerFound;
161194}
162- -(void )removeLastRequestHandler
195+
196+ -(void )removeLastStub
163197{
164- @synchronized (_requestHandlers )
198+ @synchronized (_stubDescriptors )
165199 {
166- [_requestHandlers removeLastObject ];
200+ [_stubDescriptors removeLastObject ];
167201 }
168202}
169203
170- -(void )removeAllRequestHandlers
204+ -(void )removeAllStubs
171205{
172- @synchronized (_requestHandlers )
206+ @synchronized (_stubDescriptors )
173207 {
174- [_requestHandlers removeAllObjects ];
208+ [_stubDescriptors removeAllObjects ];
175209 }
176210}
177211
178- // //////////////////////////////////////////////////////////////////////////////
179- #pragma mark - Private methods
180-
181- - (OHHTTPStubsResponse*)responseForRequest : (NSURLRequest *)request onlyCheck : (BOOL )onlyCheck
212+ - (OHHTTPStubsDescriptor*)firstStubPassingTestForRequest : (NSURLRequest *)request
182213{
183- OHHTTPStubsResponse* response = nil ;
184- @synchronized (_requestHandlers )
214+ OHHTTPStubsDescriptor* foundStub = nil ;
215+ @synchronized (_stubDescriptors )
185216 {
186- for (OHHTTPStubsRequestHandler handler in _requestHandlers .reverseObjectEnumerator )
217+ for (OHHTTPStubsDescriptor* stub in _stubDescriptors .reverseObjectEnumerator )
187218 {
188- response = handler (request, onlyCheck);
189- if (response) break ;
219+ if (stub.testBlock (request))
220+ {
221+ foundStub = stub;
222+ break ;
223+ }
190224 }
191225 }
192- return response ;
226+ return foundStub ;
193227}
194228
195229@end
@@ -201,11 +235,18 @@ - (OHHTTPStubsResponse*)responseForRequest:(NSURLRequest*)request onlyCheck:(BOO
201235#pragma mark - Deprecated Methods (will be removed in 3.0)
202236/* ! @name Deprecated Methods */
203237
238+ typedef OHHTTPStubsResponse*(^OHHTTPStubsRequestHandler)(NSURLRequest * request, BOOL onlyCheck) __deprecated;
239+
204240@implementation OHHTTPStubs (Deprecated)
205241
206242+(OHHTTPStubsRequestHandlerID)addRequestHandler : (OHHTTPStubsRequestHandler)handler
207243{
208- return [self .sharedInstance addRequestHandler: handler];
244+ return [OHHTTPStubsDescriptor stubDescriptorWithTestBlock: ^BOOL (NSURLRequest *request)
245+ {
246+ return (handler (request, YES ) != nil );
247+ } responseBlock: ^OHHTTPStubsResponse *(NSURLRequest *request) {
248+ return handler (request, NO );
249+ }];
209250}
210251
211252+(BOOL )removeRequestHandler : (OHHTTPStubsRequestHandlerID)handler
@@ -242,7 +283,7 @@ @implementation OHHTTPStubsProtocol
242283
243284+ (BOOL )canInitWithRequest : (NSURLRequest *)request
244285{
245- return ([OHHTTPStubs.sharedInstance responseForRequest : request onlyCheck: YES ] != nil );
286+ return ([OHHTTPStubs.sharedInstance firstStubPassingTestForRequest : request] != nil );
246287}
247288
248289- (id )initWithRequest : (NSURLRequest *)request cachedResponse : (NSCachedURLResponse *)response client : (id <NSURLProtocolClient >)client
@@ -266,7 +307,14 @@ - (void)startLoading
266307 NSURLRequest * request = self.request ;
267308 id <NSURLProtocolClient > client = self.client ;
268309
269- OHHTTPStubsResponse* responseStub = [OHHTTPStubs.sharedInstance responseForRequest: request onlyCheck: NO ];
310+ OHHTTPStubsDescriptor* stub = [OHHTTPStubs.sharedInstance firstStubPassingTestForRequest: request];
311+ NSAssert (stub, @" At the time startLoading is called, canInitRequest should have assured that stub is != nil beforehand" );
312+ OHHTTPStubsResponse* responseStub = stub.responseBlock (request);
313+
314+ if (OHHTTPStubs.sharedInstance .onStubActivationBlock )
315+ {
316+ OHHTTPStubs.sharedInstance .onStubActivationBlock (request, stub);
317+ }
270318
271319 if (responseStub.error == nil )
272320 {
@@ -456,7 +504,7 @@ - (void) streamDataForClient:(id<NSURLProtocolClient>)client
456504// Delayed execution utility methods
457505// ///////////////////////////////////////////
458506
459- void execute_after (NSTimeInterval delayInSeconds, dispatch_block_t block)
507+ static void execute_after (NSTimeInterval delayInSeconds, dispatch_block_t block)
460508{
461509 dispatch_time_t popTime = dispatch_time (DISPATCH_TIME_NOW, (int64_t )(delayInSeconds * NSEC_PER_SEC));
462510 dispatch_after (popTime, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), block);
0 commit comments