| OLD | NEW |
| (Empty) |
| 1 //------------------------------------------------------------------------------
--------- | |
| 2 // $Id$ | |
| 3 // Copyright (c) 2004-2011 by Mulle Kybernetik. See License file for details. | |
| 4 //------------------------------------------------------------------------------
--------- | |
| 5 | |
| 6 #import <objc/runtime.h> | |
| 7 #import <OCMock/OCMockRecorder.h> | |
| 8 #import <OCMock/OCMArg.h> | |
| 9 #import <OCMock/OCMConstraint.h> | |
| 10 #import "OCMPassByRefSetter.h" | |
| 11 #import "OCMReturnValueProvider.h" | |
| 12 #import "OCMBoxedReturnValueProvider.h" | |
| 13 #import "OCMExceptionReturnValueProvider.h" | |
| 14 #import "OCMIndirectReturnValueProvider.h" | |
| 15 #import "OCMNotificationPoster.h" | |
| 16 #import "OCMBlockCaller.h" | |
| 17 #import "NSInvocation+OCMAdditions.h" | |
| 18 | |
| 19 @interface NSObject(HCMatcherDummy) | |
| 20 - (BOOL)matches:(id)item; | |
| 21 @end | |
| 22 | |
| 23 #pragma mark - | |
| 24 | |
| 25 | |
| 26 @implementation OCMockRecorder | |
| 27 | |
| 28 #pragma mark Initialisers, description, accessors, etc. | |
| 29 | |
| 30 - (id)initWithSignatureResolver:(id)anObject | |
| 31 { | |
| 32 signatureResolver = anObject; | |
| 33 invocationHandlers = [[NSMutableArray alloc] init]; | |
| 34 return self; | |
| 35 } | |
| 36 | |
| 37 - (void)dealloc | |
| 38 { | |
| 39 [recordedInvocation release]; | |
| 40 [invocationHandlers release]; | |
| 41 [super dealloc]; | |
| 42 } | |
| 43 | |
| 44 - (NSString *)description | |
| 45 { | |
| 46 return [recordedInvocation invocationDescription]; | |
| 47 } | |
| 48 | |
| 49 - (void)releaseInvocation | |
| 50 { | |
| 51 [recordedInvocation release]; | |
| 52 recordedInvocation = nil; | |
| 53 } | |
| 54 | |
| 55 | |
| 56 #pragma mark Recording invocation handlers | |
| 57 | |
| 58 - (id)andReturn:(id)anObject | |
| 59 { | |
| 60 [invocationHandlers addObject:[[[OCMReturnValueProvider alloc] initWithV
alue:anObject] autorelease]]; | |
| 61 return self; | |
| 62 } | |
| 63 | |
| 64 - (id)andReturnValue:(NSValue *)aValue | |
| 65 { | |
| 66 [invocationHandlers addObject:[[[OCMBoxedReturnValueProvider alloc] init
WithValue:aValue] autorelease]]; | |
| 67 return self; | |
| 68 } | |
| 69 | |
| 70 - (id)andThrow:(NSException *)anException | |
| 71 { | |
| 72 [invocationHandlers addObject:[[[OCMExceptionReturnValueProvider alloc]
initWithValue:anException] autorelease]]; | |
| 73 return self; | |
| 74 } | |
| 75 | |
| 76 - (id)andPost:(NSNotification *)aNotification | |
| 77 { | |
| 78 [invocationHandlers addObject:[[[OCMNotificationPoster alloc] initWithNo
tification:aNotification] autorelease]]; | |
| 79 return self; | |
| 80 } | |
| 81 | |
| 82 - (id)andCall:(SEL)selector onObject:(id)anObject | |
| 83 { | |
| 84 [invocationHandlers addObject:[[[OCMIndirectReturnValueProvider alloc] i
nitWithProvider:anObject andSelector:selector] autorelease]]; | |
| 85 return self; | |
| 86 } | |
| 87 | |
| 88 #if NS_BLOCKS_AVAILABLE | |
| 89 | |
| 90 - (id)andDo:(void (^)(NSInvocation *))aBlock | |
| 91 { | |
| 92 [invocationHandlers addObject:[[[OCMBlockCaller alloc] initWithCallBlock
:aBlock] autorelease]]; | |
| 93 return self; | |
| 94 } | |
| 95 | |
| 96 #endif | |
| 97 | |
| 98 - (id)andForwardToRealObject | |
| 99 { | |
| 100 [NSException raise:NSInternalInconsistencyException format:@"Method %@ c
an only be used with partial mocks.", | |
| 101 NSStringFromSelector(_cmd)]; | |
| 102 return self; // keep compiler happy | |
| 103 } | |
| 104 | |
| 105 | |
| 106 - (NSArray *)invocationHandlers | |
| 107 { | |
| 108 return invocationHandlers; | |
| 109 } | |
| 110 | |
| 111 | |
| 112 #pragma mark Recording the actual invocation | |
| 113 | |
| 114 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector | |
| 115 { | |
| 116 return [signatureResolver methodSignatureForSelector:aSelector]; | |
| 117 } | |
| 118 | |
| 119 - (void)forwardInvocation:(NSInvocation *)anInvocation | |
| 120 { | |
| 121 if(recordedInvocation != nil) | |
| 122 [NSException raise:NSInternalInconsistencyException format:@"Rec
order received two methods to record."]; | |
| 123 [anInvocation setTarget:nil]; | |
| 124 [anInvocation retainArguments]; | |
| 125 recordedInvocation = [anInvocation retain]; | |
| 126 } | |
| 127 | |
| 128 | |
| 129 | |
| 130 #pragma mark Checking the invocation | |
| 131 | |
| 132 - (BOOL)matchesInvocation:(NSInvocation *)anInvocation | |
| 133 { | |
| 134 id recordedArg, passedArg; | |
| 135 int i, n; | |
| 136 | |
| 137 if([anInvocation selector] != [recordedInvocation selector]) | |
| 138 return NO; | |
| 139 | |
| 140 n = (int)[[recordedInvocation methodSignature] numberOfArguments]; | |
| 141 for(i = 2; i < n; i++) | |
| 142 { | |
| 143 recordedArg = [recordedInvocation getArgumentAtIndexAsObject:i]; | |
| 144 passedArg = [anInvocation getArgumentAtIndexAsObject:i]; | |
| 145 | |
| 146 if([recordedArg isProxy]) | |
| 147 { | |
| 148 if(![recordedArg isEqual:passedArg]) | |
| 149 return NO; | |
| 150 continue; | |
| 151 } | |
| 152 | |
| 153 if([recordedArg isKindOfClass:[NSValue class]]) | |
| 154 recordedArg = [OCMArg resolveSpecialValues:recordedArg]; | |
| 155 | |
| 156 if([recordedArg isKindOfClass:[OCMConstraint class]]) | |
| 157 { | |
| 158 if([recordedArg evaluate:passedArg] == NO) | |
| 159 return NO; | |
| 160 } | |
| 161 else if([recordedArg isKindOfClass:[OCMPassByRefSetter class]]) | |
| 162 { | |
| 163 // side effect but easier to do here than in handleInvoc
ation | |
| 164 *(id *)[passedArg pointerValue] = [(OCMPassByRefSetter *
)recordedArg value]; | |
| 165 } | |
| 166 else if([recordedArg conformsToProtocol:objc_getProtocol("HCMatc
her")]) | |
| 167 { | |
| 168 if([recordedArg matches:passedArg] == NO) | |
| 169 return NO; | |
| 170 } | |
| 171 else | |
| 172 { | |
| 173 if(([recordedArg class] == [NSNumber class]) && | |
| 174 ([(NSNumber*)recordedArg compare:(NSNumber*)pass
edArg] != NSOrderedSame)) | |
| 175 return NO; | |
| 176 if(([recordedArg isEqual:passedArg] == NO) && | |
| 177 !((recordedArg == nil) && (passedArg == nil))) | |
| 178 return NO; | |
| 179 } | |
| 180 } | |
| 181 return YES; | |
| 182 } | |
| 183 | |
| 184 | |
| 185 | |
| 186 | |
| 187 @end | |
| OLD | NEW |