Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: third_party/ocmock/OCMock/OCMockObject.m

Issue 2626723004: Update OCMock to 3e193f3c2d4ea4ada63df54c8ce98e7ea4cf768f (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/ocmock/OCMock/OCMockObject.h ('k') | third_party/ocmock/OCMock/OCMockRecorder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //------------------------------------------------------------------------------ --------- 1 /*
2 // $Id$ 2 * Copyright (c) 2004-2015 Erik Doernenburg and contributors
3 // Copyright (c) 2004-2009 by Mulle Kybernetik. See License file for details. 3 *
4 //------------------------------------------------------------------------------ --------- 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 * not use these files except in compliance with the License. You may obtain
6 * a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
5 16
6 #import <OCMock/OCMockObject.h> 17 #import <OCMock/OCMockObject.h>
7 #import "OCClassMockObject.h" 18 #import "OCClassMockObject.h"
8 #import "OCProtocolMockObject.h" 19 #import "OCProtocolMockObject.h"
9 #import "OCPartialMockObject.h" 20 #import "OCPartialMockObject.h"
10 #import "OCObserverMockObject.h" 21 #import "OCObserverMockObject.h"
11 #import <OCMock/OCMockRecorder.h> 22 #import "OCMStubRecorder.h"
23 #import <OCMock/OCMLocation.h>
12 #import "NSInvocation+OCMAdditions.h" 24 #import "NSInvocation+OCMAdditions.h"
13 25 #import "OCMInvocationMatcher.h"
14 @interface OCMockObject(Private) 26 #import "OCMMacroState.h"
15 + (id)_makeNice:(OCMockObject *)mock; 27 #import "OCMFunctionsPrivate.h"
16 - (NSString *)_recorderDescriptions:(BOOL)onlyExpectations; 28 #import "OCMVerifier.h"
17 @end 29 #import "OCMInvocationExpectation.h"
18 30 #import "OCMExceptionReturnValueProvider.h"
19 #pragma mark - 31 #import "OCMExpectationRecorder.h"
20 32
21 33
22 @implementation OCMockObject 34 @implementation OCMockObject
23 35
24 #pragma mark Class initialisation 36 #pragma mark Class initialisation
25 37
26 + (void)initialize 38 + (void)initialize
27 { 39 {
28 if([[NSInvocation class] instanceMethodSignatureForSelector:@selector(ge tArgumentAtIndexAsObject:)] == NULL) 40 if([[NSInvocation class] instanceMethodSignatureForSelector:@selector(ge tArgumentAtIndexAsObject:)] == NULL)
29 » » [NSException raise:NSInternalInconsistencyException format:@"** Expected method not present; the method getArgumentAtIndexAsObject: is not imple mented by NSInvocation. If you see this exception it is likely that you are usin g the static library version of OCMock and your project is not configured correc tly to load categories from static libraries. Did you forget to add the -force_l oad linker flag?"]; 41 » » [NSException raise:NSInternalInconsistencyException format:@"** Expected method not present; the method getArgumentAtIndexAsObject: is not imple mented by NSInvocation. If you see this exception it is likely that you are usin g the static library version of OCMock and your project is not configured correc tly to load categories from static libraries. Did you forget to add the -ObjC li nker flag?"];
30 } 42 }
31 43
32 44
33 #pragma mark Factory methods 45 #pragma mark Factory methods
34 46
35 + (id)mockForClass:(Class)aClass 47 + (id)mockForClass:(Class)aClass
36 { 48 {
37 return [[[OCClassMockObject alloc] initWithClass:aClass] autorelease]; 49 return [[[OCClassMockObject alloc] initWithClass:aClass] autorelease];
38 } 50 }
39 51
(...skipping 25 matching lines...) Expand all
65 return mock; 77 return mock;
66 } 78 }
67 79
68 80
69 + (id)observerMock 81 + (id)observerMock
70 { 82 {
71 return [[[OCObserverMockObject alloc] init] autorelease]; 83 return [[[OCObserverMockObject alloc] init] autorelease];
72 } 84 }
73 85
74 86
75
76 #pragma mark Initialisers, description, accessors, etc. 87 #pragma mark Initialisers, description, accessors, etc.
77 88
78 - (id)init 89 - (instancetype)init
79 { 90 {
80 // no [super init], we're inheriting from NSProxy 91 // no [super init], we're inheriting from NSProxy
81 expectationOrderMatters = NO; 92 expectationOrderMatters = NO;
82 » recorders = [[NSMutableArray alloc] init]; 93 » stubs = [[NSMutableArray alloc] init];
83 expectations = [[NSMutableArray alloc] init]; 94 expectations = [[NSMutableArray alloc] init];
84 rejections = [[NSMutableArray alloc] init];
85 exceptions = [[NSMutableArray alloc] init]; 95 exceptions = [[NSMutableArray alloc] init];
86 » return self; 96 invocations = [[NSMutableArray alloc] init];
97 return self;
87 } 98 }
88 99
89 - (void)dealloc 100 - (void)dealloc
90 { 101 {
91 » [recorders release]; 102 » [stubs release];
92 [expectations release]; 103 [expectations release];
93 [rejections release];
94 [exceptions release]; 104 [exceptions release];
105 [invocations release];
95 [super dealloc]; 106 [super dealloc];
96 } 107 }
97 108
98 - (NSString *)description 109 - (NSString *)description
99 { 110 {
100 return @"OCMockObject"; 111 return @"OCMockObject";
101 } 112 }
102 113
114 - (void)addStub:(OCMInvocationStub *)aStub
115 {
116 [stubs addObject:aStub];
117 }
118
119 - (void)addExpectation:(OCMInvocationExpectation *)anExpectation
120 {
121 [expectations addObject:anExpectation];
122 }
123
124
125 #pragma mark Public API
103 126
104 - (void)setExpectationOrderMatters:(BOOL)flag 127 - (void)setExpectationOrderMatters:(BOOL)flag
105 { 128 {
106 expectationOrderMatters = flag; 129 expectationOrderMatters = flag;
107 } 130 }
108 131
109 132 - (void)stopMocking
110 #pragma mark Public API 133 {
134 // no-op for mock objects that are not class object or partial mocks
135 }
136
111 137
112 - (id)stub 138 - (id)stub
113 { 139 {
114 » OCMockRecorder *recorder = [self getNewRecorder]; 140 » return [[[OCMStubRecorder alloc] initWithMockObject:self] autorelease];
115 » [recorders addObject:recorder]; 141 }
116 » return recorder;
117 }
118
119 142
120 - (id)expect 143 - (id)expect
121 { 144 {
122 » OCMockRecorder *recorder = [self stub]; 145 return [[[OCMExpectationRecorder alloc] initWithMockObject:self] autorelease ];
123 » [expectations addObject:recorder]; 146 }
124 » return recorder;
125 }
126
127 147
128 - (id)reject 148 - (id)reject
129 { 149 {
130 » OCMockRecorder *recorder = [self stub]; 150 » return [[self expect] never];
131 » [rejections addObject:recorder]; 151 }
132 » return recorder; 152
133 } 153
134 154 - (id)verify
135 155 {
136 - (void)verify 156 return [self verifyAtLocation:nil];
137 { 157 }
138 » if([expectations count] == 1) 158
139 » { 159 - (id)verifyAtLocation:(OCMLocation *)location
140 » » [NSException raise:NSInternalInconsistencyException format:@"%@: expected method was not invoked: %@", 160 {
141 » » » [self description], [[expectations objectAtIndex:0] desc ription]]; 161 NSMutableArray *unsatisfiedExpectations = [NSMutableArray array];
142 » } 162 for(OCMInvocationExpectation *e in expectations)
143 » if([expectations count] > 0) 163 {
144 » { 164 if(![e isSatisfied])
145 » » [NSException raise:NSInternalInconsistencyException format:@"%@ : %ld expected methods were not invoked: %@", 165 [unsatisfiedExpectations addObject:e];
146 » » » [self description], (unsigned long)[expectations count], [self _recorderDescriptions:YES]]; 166 }
147 » } 167
168 » if([unsatisfiedExpectations count] == 1)
169 » {
170 NSString *description = [NSString stringWithFormat:@"%@: expected method was not invoked: %@",
171 [self description], [[unsatisfiedExpectations objectAtIndex:0] descript ion]];
172 OCMReportFailure(location, description);
173 » }
174 » else if([unsatisfiedExpectations count] > 0)
175 » {
176 » » NSString *description = [NSString stringWithFormat:@"%@: %@ expe cted methods were not invoked: %@",
177 [self description], @([unsatisfiedExpectations count]), [self _stubDesc riptions:YES]];
178 OCMReportFailure(location, description);
179 » }
180
148 if([exceptions count] > 0) 181 if([exceptions count] > 0)
149 { 182 {
150 » » [[exceptions objectAtIndex:0] raise]; 183 NSString *description = [NSString stringWithFormat:@"%@: %@ (This is a s trict mock failure that was ignored when it actually occured.)",
151 » } 184 [self description], [[exceptions objectAtIndex:0] description]];
152 } 185 OCMReportFailure(location, description);
153 186 » }
187
188 return [[[OCMVerifier alloc] initWithMockObject:self] autorelease];
189 }
190
191
192 - (void)verifyWithDelay:(NSTimeInterval)delay
193 {
194 [self verifyWithDelay:delay atLocation:nil];
195 }
196
197 - (void)verifyWithDelay:(NSTimeInterval)delay atLocation:(OCMLocation *)location
198 {
199 NSTimeInterval step = 0.01;
200 while(delay > 0)
201 {
202 if([expectations count] == 0)
203 break;
204 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSin ceNow:step]];
205 delay -= step;
206 step *= 2;
207 }
208 [self verifyAtLocation:location];
209 }
210
211
212 #pragma mark Verify after running
213
214 - (void)verifyInvocation:(OCMInvocationMatcher *)matcher
215 {
216 [self verifyInvocation:matcher atLocation:nil];
217 }
218
219 - (void)verifyInvocation:(OCMInvocationMatcher *)matcher atLocation:(OCMLocation *)location
220 {
221 for(NSInvocation *invocation in invocations)
222 {
223 if([matcher matchesInvocation:invocation])
224 return;
225 }
226 NSString *description = [NSString stringWithFormat:@"%@: Method %@ was not i nvoked.",
227 [self description], [matcher description]];
228
229 OCMReportFailure(location, description);
230 }
154 231
155 232
156 #pragma mark Handling invocations 233 #pragma mark Handling invocations
157 234
235 - (id)forwardingTargetForSelector:(SEL)aSelector
236 {
237 if([OCMMacroState globalState] != nil)
238 {
239 OCMRecorder *recorder = [[OCMMacroState globalState] recorder];
240 [recorder setMockObject:self];
241 return recorder;
242 }
243 return nil;
244 }
245
246
247 - (BOOL)handleSelector:(SEL)sel
248 {
249 for(OCMInvocationStub *recorder in stubs)
250 if([recorder matchesSelector:sel])
251 return YES;
252
253 return NO;
254 }
255
158 - (void)forwardInvocation:(NSInvocation *)anInvocation 256 - (void)forwardInvocation:(NSInvocation *)anInvocation
159 { 257 {
160 » if([self handleInvocation:anInvocation] == NO) 258 @try
161 » » [self handleUnRecordedInvocation:anInvocation]; 259 {
260 if([self handleInvocation:anInvocation] == NO)
261 [self handleUnRecordedInvocation:anInvocation];
262 }
263 @catch(NSException *e)
264 {
265 if([[e name] isEqualToString:OCMStubbedException])
266 {
267 e = [[e userInfo] objectForKey:@"exception"];
268 }
269 else
270 {
271 // add non-stubbed method to list of exceptions to be re-raised in v erify
272 [exceptions addObject:e];
273 }
274 [e raise];
275 }
162 } 276 }
163 277
164 - (BOOL)handleInvocation:(NSInvocation *)anInvocation 278 - (BOOL)handleInvocation:(NSInvocation *)anInvocation
165 { 279 {
166 » OCMockRecorder *recorder = nil; 280 [invocations addObject:anInvocation];
167 » unsigned int» » » i; 281
168 » 282 OCMInvocationStub *stub = nil;
169 » for(i = 0; i < [recorders count]; i++) 283 for(stub in stubs)
170 » { 284 {
171 » » recorder = [recorders objectAtIndex:i]; 285 // If the stub forwards its invocation to the real object, then we don't want to do handleInvocation: yet, since forwarding the invocation to the real o bject could call a method that is expected to happen after this one, which is ba d if expectationOrderMatters is YES
172 » » if([recorder matchesInvocation:anInvocation]) 286 if([stub matchesInvocation:anInvocation])
173 » » » break; 287 break;
174 » } 288 }
175 » 289 // Retain the stub in case it ends up being removed from stubs and expectati ons, since we still have to call handleInvocation on the stub at the end
176 » if(i == [recorders count]) 290 [stub retain];
177 » » return NO; 291 if(stub == nil)
178 » 292 return NO;
179 » if([rejections containsObject:recorder]) 293
180 » { 294 if([expectations containsObject:stub])
181 » » NSException *exception = [NSException exceptionWithName:NSIntern alInconsistencyException reason: 295 {
182 » » » » » » » » [NSString stri ngWithFormat:@"%@: explicitly disallowed method invoked: %@", [self description] , 296 OCMInvocationExpectation *expectation = [self _nextExpectedInvocation] ;
183 » » » » » » » » [anInvocation invocationDescription]] userInfo:nil]; 297 if(expectationOrderMatters && (expectation != stub))
184 » » [exceptions addObject:exception]; 298 {
185 » » [exception raise]; 299 [NSException raise:NSInternalInconsistencyException format:@"%@: unexpected method invoked: %@\n\texpected:\t%@",
186 » } 300 [self description], [stub description], [[expectatio ns objectAtIndex:0] description]];
187 301 }
188 » if([expectations containsObject:recorder]) 302
189 » { 303 // We can't check isSatisfied yet, since the stub won't be satisfied u ntil we call handleInvocation:, and we don't want to call handleInvocation: yes for the reason in the comment above, since we'll still have the current expectat ion in the expectations array, which will cause an exception if expectationOrder Matters is YES and we're not ready for any future expected methods to be called yet
190 » » if(expectationOrderMatters && ([expectations objectAtIndex:0] != recorder)) 304 if(![(OCMInvocationExpectation *)stub isMatchAndReject])
191 » » { 305 {
192 » » » [NSException raise:NSInternalInconsistencyException» format:@"%@: unexpected method invoked: %@\n\texpected:\t%@", 306 [expectations removeObject:stub];
193 » » » [self description], [recorder description], [[expectati ons objectAtIndex:0] description]]; 307 [stubs removeObject:stub];
194 » » » 308 }
195 » » } 309 }
196 » » [[recorder retain] autorelease]; 310 [stub handleInvocation:anInvocation];
197 » » [expectations removeObject:recorder]; 311 [stub release];
198 » » [recorders removeObjectAtIndex:i]; 312
199 » } 313 return YES;
200 » [[recorder invocationHandlers] makeObjectsPerformSelector:@selector(hand leInvocation:) withObject:anInvocation]; 314 }
201 » 315
202 » return YES; 316
317 - (OCMInvocationExpectation *)_nextExpectedInvocation
318 {
319 for(OCMInvocationExpectation *expectation in expectations)
320 if(![expectation isMatchAndReject])
321 return expectation;
322 return nil;
203 } 323 }
204 324
205 - (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation 325 - (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation
206 { 326 {
207 if(isNice == NO) 327 if(isNice == NO)
208 { 328 {
209 » » NSException *exception = [NSException exceptionWithName:NSIntern alInconsistencyException reason: 329 » » [NSException raise:NSInternalInconsistencyException format:@"%@: unexpected method invoked: %@ %@",
210 » » » » » » » » [NSString stri ngWithFormat:@"%@: unexpected method invoked: %@ %@", [self description], 330 [self description], [anInvocation invocationDescription] , [self _stubDescriptions:NO]];
211 » » » » » » » » [anInvocation invocationDescription], [self _recorderDescriptions:NO]] userInfo:nil]; 331 » }
212 » » [exceptions addObject:exception]; 332 }
213 » » [exception raise]; 333
214 » } 334 - (void)doesNotRecognizeSelector:(SEL)aSelector __unused
335 {
336 if([OCMMacroState globalState] != nil)
337 {
338 // we can't do anything clever with the macro state because we must rais e an exception here
339 [NSException raise:NSInvalidArgumentException format:@"%@: Cannot stub/e xpect/verify method '%@' because no such method exists in the mocked class.",
340 [self description], NSStringFromSelector(aSelector)];
341 }
342 else
343 {
344 [NSException raise:NSInvalidArgumentException format:@"-[%@ %@]: unrecog nized selector sent to instance %p",
345 [self description], NSStringFromSelector(aSelector), (vo id *)self];
346 }
215 } 347 }
216 348
217 349
218 #pragma mark Helper methods 350 #pragma mark Helper methods
219 351
220 - (id)getNewRecorder 352 - (NSString *)_stubDescriptions:(BOOL)onlyExpectations
221 {
222 » return [[[OCMockRecorder alloc] initWithSignatureResolver:self] autorele ase];
223 }
224
225
226 - (NSString *)_recorderDescriptions:(BOOL)onlyExpectations
227 { 353 {
228 NSMutableString *outputString = [NSMutableString string]; 354 NSMutableString *outputString = [NSMutableString string];
229 » 355 for(OCMStubRecorder *stub in stubs)
230 » OCMockRecorder *currentObject; 356 {
231 » NSEnumerator *recorderEnumerator = [recorders objectEnumerator]; 357 » » NSString *prefix = @"";
232 » while((currentObject = [recorderEnumerator nextObject]) != nil)
233 » {
234 » » NSString *prefix;
235 358
236 if(onlyExpectations) 359 if(onlyExpectations)
237 { 360 {
238 » » » if(![expectations containsObject:currentObject]) 361 » » » if([expectations containsObject:stub] == NO)
239 continue; 362 continue;
240 prefix = @" ";
241 } 363 }
242 else 364 else
243 { 365 {
244 » » » if ([expectations containsObject:currentObject]) 366 » » » if([expectations containsObject:stub])
245 » » » » prefix = @"expected: "; 367 » » » » prefix = @"expected:\t";
246 else 368 else
247 » » » » prefix = @"stubbed: "; 369 » » » » prefix = @"stubbed:\t";
248 } 370 }
249 » » [outputString appendFormat:@"\n\t%@\t%@", prefix, [currentObject description]]; 371 » » [outputString appendFormat:@"\n\t%@%@", prefix, [stub descriptio n]];
250 » } 372 » }
251 »
252 return outputString; 373 return outputString;
253 } 374 }
254 375
255 376
256 @end 377 @end
OLDNEW
« no previous file with comments | « third_party/ocmock/OCMock/OCMockObject.h ('k') | third_party/ocmock/OCMock/OCMockRecorder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698