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

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

Issue 2410583002: Test update OCMock (Closed)
Patch Set: Patch in exactly 3.1.5 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 "OCMFunctions.h"
16 - (NSString *)_recorderDescriptions:(BOOL)onlyExpectations; 28 #import "OCMVerifier.h"
17 @end 29 #import "OCMInvocationExpectation.h"
18 30 #import "OCMExpectationRecorder.h"
19 #pragma mark -
20
21 31
22 @implementation OCMockObject 32 @implementation OCMockObject
23 33
24 #pragma mark Class initialisation 34 #pragma mark Class initialisation
25 35
26 + (void)initialize 36 + (void)initialize
27 { 37 {
28 if([[NSInvocation class] instanceMethodSignatureForSelector:@selector(ge tArgumentAtIndexAsObject:)] == NULL) 38 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?"]; 39 [NSException
40 raise:NSInternalInconsistencyException
41 format:@"** Expected method not present; the method "
42 @"getArgumentAtIndexAsObject: is not implemented by "
43 @"NSInvocation. If you see this exception it is likely "
44 @"that you are using the static library version of "
45 @"OCMock and your project is not configured correctly to "
46 @"load categories from static libraries. Did you forget "
47 @"to add the -ObjC linker flag?"];
30 } 48 }
31 49
32 50
33 #pragma mark Factory methods 51 #pragma mark Factory methods
34 52
35 + (id)mockForClass:(Class)aClass 53 + (id)mockForClass:(Class)aClass
36 { 54 {
37 return [[[OCClassMockObject alloc] initWithClass:aClass] autorelease]; 55 return [[[OCClassMockObject alloc] initWithClass:aClass] autorelease];
38 } 56 }
39 57
(...skipping 25 matching lines...) Expand all
65 return mock; 83 return mock;
66 } 84 }
67 85
68 86
69 + (id)observerMock 87 + (id)observerMock
70 { 88 {
71 return [[[OCObserverMockObject alloc] init] autorelease]; 89 return [[[OCObserverMockObject alloc] init] autorelease];
72 } 90 }
73 91
74 92
75
76 #pragma mark Initialisers, description, accessors, etc. 93 #pragma mark Initialisers, description, accessors, etc.
77 94
78 - (id)init 95 - (instancetype)init {
79 { 96 // no [super init], we're inheriting from NSProxy
80 » // no [super init], we're inheriting from NSProxy 97 expectationOrderMatters = NO;
81 » expectationOrderMatters = NO; 98 stubs = [[NSMutableArray alloc] init];
82 » recorders = [[NSMutableArray alloc] init]; 99 expectations = [[NSMutableArray alloc] init];
83 » expectations = [[NSMutableArray alloc] init]; 100 exceptions = [[NSMutableArray alloc] init];
84 » rejections = [[NSMutableArray alloc] init]; 101 invocations = [[NSMutableArray alloc] init];
85 » exceptions = [[NSMutableArray alloc] init]; 102 return self;
86 » return self;
87 } 103 }
88 104
89 - (void)dealloc 105 - (void)dealloc
90 { 106 {
91 » [recorders release]; 107 [stubs release];
92 » [expectations release]; 108 [expectations release];
93 » [rejections» release]; 109 [exceptions release];
94 » [exceptions release]; 110 [invocations release];
95 » [super dealloc]; 111 [super dealloc];
96 } 112 }
97 113
98 - (NSString *)description 114 - (NSString *)description
99 { 115 {
100 return @"OCMockObject"; 116 return @"OCMockObject";
101 } 117 }
102 118
119 - (void)addStub:(OCMInvocationStub*)aStub {
120 [stubs addObject:aStub];
121 }
122
123 - (void)addExpectation:(OCMInvocationExpectation*)anExpectation {
124 [expectations addObject:anExpectation];
125 }
126
127 #pragma mark Public API
103 128
104 - (void)setExpectationOrderMatters:(BOOL)flag 129 - (void)setExpectationOrderMatters:(BOOL)flag
105 { 130 {
106 expectationOrderMatters = flag; 131 expectationOrderMatters = flag;
107 } 132 }
108 133
109 134 - (void)stopMocking {
110 #pragma mark Public API 135 // no-op for mock objects that are not class object or partial mocks
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 - (id)verify {
134 154 return [self verifyAtLocation:nil];
135 155 }
136 - (void)verify 156
137 { 157 - (id)verifyAtLocation:(OCMLocation*)location {
138 » if([expectations count] == 1) 158 NSMutableArray* unsatisfiedExpectations = [NSMutableArray array];
139 » { 159 for (OCMInvocationExpectation* e in expectations) {
140 » » [NSException raise:NSInternalInconsistencyException format:@"%@: expected method was not invoked: %@", 160 if (![e isSatisfied])
141 » » » [self description], [[expectations objectAtIndex:0] desc ription]]; 161 [unsatisfiedExpectations addObject:e];
142 » } 162 }
143 » if([expectations count] > 0) 163
144 » { 164 if ([unsatisfiedExpectations count] == 1) {
145 » » [NSException raise:NSInternalInconsistencyException format:@"%@ : %ld expected methods were not invoked: %@", 165 NSString* description = [NSString
146 » » » [self description], (unsigned long)[expectations count], [self _recorderDescriptions:YES]]; 166 stringWithFormat:@"%@: expected method was not invoked: %@",
147 » } 167 [self description], [[unsatisfiedExpectations
148 » if([exceptions count] > 0) 168 objectAtIndex:0] description]];
149 » { 169 OCMReportFailure(location, description);
150 » » [[exceptions objectAtIndex:0] raise]; 170 } else if ([unsatisfiedExpectations count] > 0) {
151 » } 171 NSString* description = [NSString
152 } 172 stringWithFormat:@"%@: %@ expected methods were not invoked: %@",
153 173 [self description], @([unsatisfiedExpectations count]),
154 174 [self _stubDescriptions:YES]];
175 OCMReportFailure(location, description);
176 }
177
178 if ([exceptions count] > 0) {
179 NSString* description = [NSString
180 stringWithFormat:@"%@: %@ (This is a strict mock failure that was "
181 @"ignored when it actually occured.)",
182 [self description],
183 [[exceptions objectAtIndex:0] description]];
184 OCMReportFailure(location, description);
185 }
186
187 return [[[OCMVerifier alloc] initWithMockObject:self] autorelease];
188 }
189
190 - (void)verifyWithDelay:(NSTimeInterval)delay {
191 [self verifyWithDelay:delay atLocation:nil];
192 }
193
194 - (void)verifyWithDelay:(NSTimeInterval)delay
195 atLocation:(OCMLocation*)location {
196 NSTimeInterval step = 0.01;
197 while (delay > 0) {
198 if ([expectations count] == 0)
199 break;
200 [[NSRunLoop currentRunLoop]
201 runUntilDate:[NSDate dateWithTimeIntervalSinceNow:step]];
202 delay -= step;
203 step *= 2;
204 }
205 [self verifyAtLocation:location];
206 }
207
208 #pragma mark Verify after running
209
210 - (void)verifyInvocation:(OCMInvocationMatcher*)matcher {
211 [self verifyInvocation:matcher atLocation:nil];
212 }
213
214 - (void)verifyInvocation:(OCMInvocationMatcher*)matcher
215 atLocation:(OCMLocation*)location {
216 for (NSInvocation* invocation in invocations) {
217 if ([matcher matchesInvocation:invocation])
218 return;
219 }
220 NSString* description =
221 [NSString stringWithFormat:@"%@: Method %@ was not invoked.",
222 [self description], [matcher description]];
223
224 OCMReportFailure(location, description);
225 }
155 226
156 #pragma mark Handling invocations 227 #pragma mark Handling invocations
157 228
229 - (id)forwardingTargetForSelector:(SEL)aSelector {
230 if ([OCMMacroState globalState] != nil) {
231 OCMRecorder* recorder = [[OCMMacroState globalState] recorder];
232 [recorder setMockObject:self];
233 return recorder;
234 }
235 return nil;
236 }
237
238 - (BOOL)handleSelector:(SEL)sel {
239 for (OCMInvocationStub* recorder in stubs)
240 if ([recorder matchesSelector:sel])
241 return YES;
242
243 return NO;
244 }
245
158 - (void)forwardInvocation:(NSInvocation *)anInvocation 246 - (void)forwardInvocation:(NSInvocation *)anInvocation
159 { 247 {
160 » if([self handleInvocation:anInvocation] == NO) 248 @try {
161 » » [self handleUnRecordedInvocation:anInvocation]; 249 if ([self handleInvocation:anInvocation] == NO)
250 [self handleUnRecordedInvocation:anInvocation];
251 } @catch (NSException* e) {
252 [exceptions addObject:e];
253 [e raise];
254 }
162 } 255 }
163 256
164 - (BOOL)handleInvocation:(NSInvocation *)anInvocation 257 - (BOOL)handleInvocation:(NSInvocation *)anInvocation
165 { 258 {
166 » OCMockRecorder *recorder = nil; 259 [invocations addObject:anInvocation];
167 » unsigned int» » » i; 260
168 » 261 OCMInvocationStub* stub = nil;
169 » for(i = 0; i < [recorders count]; i++) 262 for (stub in stubs) {
170 » { 263 // If the stub forwards its invocation to the real object, then we don't
171 » » recorder = [recorders objectAtIndex:i]; 264 // want to do handleInvocation: yet, since forwarding the invocation to the
172 » » if([recorder matchesInvocation:anInvocation]) 265 // real object could call a method that is expected to happen after this
173 » » » break; 266 // one, which is bad if expectationOrderMatters is YES
174 » } 267 if ([stub matchesInvocation:anInvocation])
175 » 268 break;
176 » if(i == [recorders count]) 269 }
177 » » return NO; 270 // Retain the stub in case it ends up being removed from stubs and
178 » 271 // expectations, since we still have to call handleInvocation on the stub at
179 » if([rejections containsObject:recorder]) 272 // the end
180 » { 273 [stub retain];
181 » » NSException *exception = [NSException exceptionWithName:NSIntern alInconsistencyException reason: 274 if (stub == nil)
182 » » » » » » » » [NSString stri ngWithFormat:@"%@: explicitly disallowed method invoked: %@", [self description] , 275 return NO;
183 » » » » » » » » [anInvocation invocationDescription]] userInfo:nil]; 276
184 » » [exceptions addObject:exception]; 277 if ([expectations containsObject:stub]) {
185 » » [exception raise]; 278 OCMInvocationExpectation* expectation = [self _nextExptectedInvocation];
186 » } 279 if (expectationOrderMatters && (expectation != stub)) {
187 280 [NSException raise:NSInternalInconsistencyException
188 » if([expectations containsObject:recorder]) 281 format:@"%@: unexpected method invoked: %@\n\texpected:\t%@",
189 » { 282 [self description], [stub description],
190 » » if(expectationOrderMatters && ([expectations objectAtIndex:0] != recorder)) 283 [[expectations objectAtIndex:0] description]];
191 » » { 284 }
192 » » » [NSException raise:NSInternalInconsistencyException» format:@"%@: unexpected method invoked: %@\n\texpected:\t%@", 285
193 » » » [self description], [recorder description], [[expectati ons objectAtIndex:0] description]]; 286 // We can't check isSatisfied yet, since the stub won't be satisfied until
194 » » » 287 // we call handleInvocation:, and we don't want to call handleInvocation:
195 » » } 288 // yes for the reason in the comment above, since we'll still have the
196 » » [[recorder retain] autorelease]; 289 // current expectation in the expectations array, which will cause an
197 » » [expectations removeObject:recorder]; 290 // exception if expectationOrderMatters is YES and we're not ready for any
198 » » [recorders removeObjectAtIndex:i]; 291 // future expected methods to be called yet
199 » } 292 if (![(OCMInvocationExpectation*)stub isMatchAndReject]) {
200 » [[recorder invocationHandlers] makeObjectsPerformSelector:@selector(hand leInvocation:) withObject:anInvocation]; 293 [expectations removeObject:stub];
201 » 294 [stubs removeObject:stub];
202 » return YES; 295 }
296 }
297 [stub handleInvocation:anInvocation];
298 [stub release];
299
300 return YES;
301 }
302
303 - (OCMInvocationExpectation*)_nextExptectedInvocation {
304 for (OCMInvocationExpectation* expectation in expectations)
305 if (![expectation isMatchAndReject])
306 return expectation;
307 return nil;
203 } 308 }
204 309
205 - (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation 310 - (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation
206 { 311 {
207 if(isNice == NO) 312 if(isNice == NO)
208 { 313 {
209 » » NSException *exception = [NSException exceptionWithName:NSIntern alInconsistencyException reason: 314 [NSException
210 » » » » » » » » [NSString stri ngWithFormat:@"%@: unexpected method invoked: %@ %@", [self description], 315 raise:NSInternalInconsistencyException
211 » » » » » » » » [anInvocation invocationDescription], [self _recorderDescriptions:NO]] userInfo:nil]; 316 format:@"%@: unexpected method invoked: %@ %@",
212 » » [exceptions addObject:exception]; 317 [self description], [anInvocation invocationDescription],
213 » » [exception raise]; 318 [self _stubDescriptions:NO]];
214 » } 319 }
215 } 320 }
216 321
217 322 - (void)doesNotRecognizeSelector:(SEL)aSelector __unused {
218 #pragma mark Helper methods 323 if ([OCMMacroState globalState] != nil) {
219 324 // we can't do anything clever with the macro state because we must raise an
220 - (id)getNewRecorder 325 // exception here
221 { 326 [NSException raise:NSInvalidArgumentException
222 » return [[[OCMockRecorder alloc] initWithSignatureResolver:self] autorele ase]; 327 format:@"%@: Cannot stub/expect/verify method '%@' because no "
223 } 328 @"such method exists in the mocked class.",
224 329 [self description], NSStringFromSelector(aSelector)];
225 330 } else {
226 - (NSString *)_recorderDescriptions:(BOOL)onlyExpectations 331 [NSException raise:NSInvalidArgumentException
227 { 332 format:@"-[%@ %@]: unrecognized selector sent to instance %p",
228 » NSMutableString *outputString = [NSMutableString string]; 333 [self description], NSStringFromSelector(aSelector),
229 » 334 (void*)self];
230 » OCMockRecorder *currentObject; 335 }
231 » NSEnumerator *recorderEnumerator = [recorders objectEnumerator]; 336 }
232 » while((currentObject = [recorderEnumerator nextObject]) != nil) 337
233 » { 338 #pragma mark Helper methods
234 » » NSString *prefix; 339
235 » » 340 - (NSString*)_stubDescriptions:(BOOL)onlyExpectations {
236 » » if(onlyExpectations) 341 NSMutableString* outputString = [NSMutableString string];
237 » » { 342 for (OCMStubRecorder* stub in stubs) {
238 » » » if(![expectations containsObject:currentObject]) 343 NSString* prefix = @"";
239 » » » » continue; 344
240 » » » prefix = @" "; 345 if (onlyExpectations) {
241 » » } 346 if ([expectations containsObject:stub] == NO)
242 » » else 347 continue;
243 » » { 348 } else {
244 » » » if ([expectations containsObject:currentObject]) 349 if ([expectations containsObject:stub])
245 » » » » prefix = @"expected: "; 350 prefix = @"expected:\t";
246 » » » else 351 else
247 » » » » prefix = @"stubbed: "; 352 prefix = @"stubbed:\t";
248 » » } 353 }
249 » » [outputString appendFormat:@"\n\t%@\t%@", prefix, [currentObject description]]; 354 [outputString appendFormat:@"\n\t%@%@", prefix, [stub description]];
250 » } 355 }
251 » 356 return outputString;
252 » return outputString; 357 }
253 } 358
254 359
255
256 @end 360 @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