123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- //
- // Licensed under the terms in License.txt
- //
- // Copyright 2010 Allen Ding. All rights reserved.
- //
- #import "NSObject+KiwiStubAdditions.h"
- #import "KWCaptureSpy.h"
- #import "KWIntercept.h"
- #import "KWInvocationCapturer.h"
- #import "KWMessagePattern.h"
- #import "KWObjCUtilities.h"
- #import "KWStringUtilities.h"
- #import "KWStub.h"
- static NSString * const StubValueKey = @"StubValueKey";
- static NSString * const StubSecondValueKey = @"StubSecondValueKey";
- static NSString * const ChangeStubValueAfterTimesKey = @"ChangeStubValueAfterTimesKey";
- @implementation NSObject(KiwiStubAdditions)
- #pragma mark - Capturing Invocations
- - (NSMethodSignature *)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer methodSignatureForSelector:(SEL)aSelector {
- NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];
- if (signature != nil)
- return signature;
- NSString *encoding = KWEncodingForDefaultMethod();
- return [NSMethodSignature signatureWithObjCTypes:[encoding UTF8String]];
- }
- - (void)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer didCaptureInvocation:(NSInvocation *)anInvocation {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternFromInvocation:anInvocation];
- id value = (anInvocationCapturer.userInfo)[StubValueKey];
- if (!(anInvocationCapturer.userInfo)[StubSecondValueKey]) {
- [self stubMessagePattern:messagePattern andReturn:value];
- } else {
- id times = (anInvocationCapturer.userInfo)[ChangeStubValueAfterTimesKey];
- id secondValue = (anInvocationCapturer.userInfo)[StubSecondValueKey];
- [self stubMessagePattern:messagePattern andReturn:value times:times afterThatReturn:secondValue];
- }
- }
- #pragma mark - Stubbing Methods
- - (void)stub:(SEL)aSelector {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
- [self stubMessagePattern:messagePattern andReturn:nil];
- }
- - (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
- [self stubMessagePattern:messagePattern withBlock:block];
- }
- - (void)stub:(SEL)aSelector withArguments:(id)firstArgument, ... {
- va_list argumentList;
- va_start(argumentList, firstArgument);
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList];
- [self stubMessagePattern:messagePattern andReturn:nil];
- }
- - (void)stub:(SEL)aSelector andReturn:(id)aValue {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
- [self stubMessagePattern:messagePattern andReturn:aValue];
- }
- - (void)stub:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ... {
- va_list argumentList;
- va_start(argumentList, firstArgument);
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList];
- [self stubMessagePattern:messagePattern andReturn:aValue];
- }
- - (void)stub:(SEL)aSelector andReturn:(id)aValue times:(NSNumber *)times afterThatReturn:(id)aSecondValue {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
- [self stubMessagePattern:messagePattern andReturn:aValue times:times afterThatReturn:aSecondValue];
- }
- + (void)stub:(SEL)aSelector {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
- [self stubMessagePattern:messagePattern andReturn:nil];
- }
- + (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
- [self stubMessagePattern:messagePattern withBlock:block];
- }
- + (void)stub:(SEL)aSelector withArguments:(id)firstArgument, ... {
- va_list argumentList;
- va_start(argumentList, firstArgument);
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList];
- [self stubMessagePattern:messagePattern andReturn:nil];
- }
- + (void)stub:(SEL)aSelector andReturn:(id)aValue {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
- [self stubMessagePattern:messagePattern andReturn:aValue];
- }
- + (void)stub:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ... {
- va_list argumentList;
- va_start(argumentList, firstArgument);
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList];
- [self stubMessagePattern:messagePattern andReturn:aValue];
- }
- + (void)stub:(SEL)aSelector andReturn:(id)aValue times:(NSNumber *)times afterThatReturn:(id)aSecondValue {
- KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
- [self stubMessagePattern:messagePattern andReturn:aValue times:times afterThatReturn:aSecondValue];
- }
- - (id)stub {
- return [KWInvocationCapturer invocationCapturerWithDelegate:self];
- }
- - (id)stubAndReturn:(id)aValue {
- NSDictionary *userInfo = @{StubValueKey: aValue};
- return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo];
- }
- - (id)stubAndReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue {
- NSDictionary *userInfo = @{StubValueKey: aValue, ChangeStubValueAfterTimesKey: times, StubSecondValueKey: aSecondValue};
- return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo];
- }
- - (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue {
- [self stubMessagePattern:aMessagePattern andReturn:aValue overrideExisting:YES];
- }
- - (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue overrideExisting:(BOOL)overrideExisting {
- if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) {
- [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists",
- NSStringFromSelector(aMessagePattern.selector)];
- }
-
- Class interceptClass = KWSetupObjectInterceptSupport(self);
- KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector);
- KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue];
- KWAssociateObjectStub(self, stub, overrideExisting);
- }
- - (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue {
- if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) {
- [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists",
- NSStringFromSelector(aMessagePattern.selector)];
- }
- Class interceptClass = KWSetupObjectInterceptSupport(self);
- KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector);
- KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue times:times afterThatReturn:aSecondValue];
- KWAssociateObjectStub(self, stub, YES);
- }
- - (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block {
- if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) {
- [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists",
- NSStringFromSelector(aMessagePattern.selector)];
- }
-
- Class interceptClass = KWSetupObjectInterceptSupport(self);
- KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector);
- KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern block:block];
- KWAssociateObjectStub(self, stub, YES);
- }
- + (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue {
- [self stubMessagePattern:aMessagePattern andReturn:aValue overrideExisting:YES];
- }
- + (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue overrideExisting:(BOOL)override {
- if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) {
- [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists",
- NSStringFromSelector(aMessagePattern.selector)];
- }
-
- Class interceptClass = KWSetupObjectInterceptSupport(self);
- KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector);
- KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue];
- KWAssociateObjectStub(self, stub, override);
- }
- + (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue {
- [self stubMessagePattern:aMessagePattern andReturn:aValue times:times afterThatReturn:aSecondValue overrideExisting:YES];
- }
- + (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue overrideExisting:(BOOL)override {
- if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) {
- [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists",
- NSStringFromSelector(aMessagePattern.selector)];
- }
-
- Class interceptClass = KWSetupObjectInterceptSupport(self);
- KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector);
- KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue times:times afterThatReturn:aSecondValue];
- KWAssociateObjectStub(self, stub, override);
- }
- + (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block {
- [self stubMessagePattern:aMessagePattern withBlock:block overrideExisting:YES];
- }
- + (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block overrideExisting:(BOOL)override {
- if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) {
- [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists",
- NSStringFromSelector(aMessagePattern.selector)];
- }
-
- Class interceptClass = KWSetupObjectInterceptSupport(self);
- KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector);
- KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern block:block];
- KWAssociateObjectStub(self, stub, override);
- }
- - (void)clearStubs {
- KWClearObjectStubs(self);
- }
- #pragma mark - Spying on Messages
- - (void)addMessageSpy:(id<KWMessageSpying>)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern {
- if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) {
- [NSException raise:@"KWSpyException" format:@"cannot add spy for -%@ because no such method exists",
- NSStringFromSelector(aMessagePattern.selector)];
- }
- Class interceptClass = KWSetupObjectInterceptSupport(self);
- KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector);
- KWAssociateMessageSpy(self, aSpy, aMessagePattern);
- }
- - (void)removeMessageSpy:(id<KWMessageSpying>)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern {
- KWClearObjectSpy(self, aSpy, aMessagePattern);
- }
- - (KWCaptureSpy *)captureArgument:(SEL)selector atIndex:(NSUInteger)index {
- KWCaptureSpy *spy = [[KWCaptureSpy alloc] initWithArgumentIndex:index];
- [self addMessageSpy:spy forMessagePattern:[KWMessagePattern messagePatternWithSelector:selector]];
- return spy;
- }
- + (void)addMessageSpy:(id<KWMessageSpying>)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern {
- if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) {
- [NSException raise:@"KWSpyException" format:@"cannot add spy for -%@ because no such method exists",
- NSStringFromSelector(aMessagePattern.selector)];
- }
-
- Class interceptClass = KWSetupObjectInterceptSupport(self);
- KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector);
- KWAssociateMessageSpy(self, aSpy, aMessagePattern);
- }
- + (void)removeMessageSpy:(id<KWMessageSpying>)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern {
- KWClearObjectSpy(self, aSpy, aMessagePattern);
- }
- + (KWCaptureSpy *)captureArgument:(SEL)selector atIndex:(NSUInteger)index {
- KWCaptureSpy *spy = [[KWCaptureSpy alloc] initWithArgumentIndex:index];
- [self addMessageSpy:spy forMessagePattern:[KWMessagePattern messagePatternWithSelector:selector]];
- return spy;
- }
- @end
|