forked from kiwi-bdd/Kiwi
/
NSObject+KiwiStubAdditions.m
133 lines (107 loc) · 5.61 KB
/
NSObject+KiwiStubAdditions.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// Licensed under the terms in License.txt
//
// Copyright 2010 Allen Ding. All rights reserved.
//
#import "NSObject+KiwiStubAdditions.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 -
#pragma mark Capturing Invocations
- (NSMethodSignature *)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];
if (signature != nil)
return signature;
NSString *encoding = KWEncodingForVoidMethod();
return [NSMethodSignature signatureWithObjCTypes:[encoding UTF8String]];
}
- (void)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer didCaptureInvocation:(NSInvocation *)anInvocation {
KWMessagePattern *messagePattern = [KWMessagePattern messagePatternFromInvocation:anInvocation];
id value = [anInvocationCapturer.userInfo objectForKey:StubValueKey];
if (![anInvocationCapturer.userInfo objectForKey:StubSecondValueKey]) {
[self stubMessagePattern:messagePattern andReturn:value];
} else {
id times = [anInvocationCapturer.userInfo objectForKey:ChangeStubValueAfterTimesKey];
id secondValue = [anInvocationCapturer.userInfo objectForKey:StubSecondValueKey];
[self stubMessagePattern:messagePattern andReturn:value times:times afterThatReturn:secondValue];
}
}
#pragma mark -
#pragma mark Stubbing Methods
- (void)stub:(SEL)aSelector {
KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector];
[self stubMessagePattern:messagePattern andReturn:nil];
}
- (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];
}
- (id)stub {
return [KWInvocationCapturer invocationCapturerWithDelegate:self];
}
- (id)stubAndReturn:(id)aValue {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:aValue forKey:StubValueKey];
return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo];
}
- (id)stubAndReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: aValue, StubValueKey, times, ChangeStubValueAfterTimesKey, aSecondValue, StubSecondValueKey, nil];
return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo];
}
- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue {
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);
}
- (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);
}
- (void)clearStubs {
KWClearObjectStubs(self);
}
#pragma mark -
#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);
}
@end