main
1//
2// Licensed under the terms in License.txt
3//
4// Copyright 2010 Allen Ding. All rights reserved.
5//
6
7#import "KWMessageTracker.h"
8#import "KWMessagePattern.h"
9#import "NSObject+KiwiStubAdditions.h"
10
11@interface KWMessageTracker()
12
13#pragma mark -
14#pragma mark Properties
15
16@property (nonatomic, readwrite) NSUInteger receivedCount;
17
18@end
19
20@implementation KWMessageTracker
21
22#pragma mark -
23#pragma mark Initializing
24
25- (id)initWithSubject:(id)anObject messagePattern:(KWMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount {
26 if ((self = [super init])) {
27 subject = [anObject retain];
28 messagePattern = [aMessagePattern retain];
29 countType = aCountType;
30 count = aCount;
31 [anObject addMessageSpy:self forMessagePattern:messagePattern];
32 }
33
34 return self;
35}
36
37+ (id)messageTrackerWithSubject:(id)anObject messagePattern:(KWMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount {
38 return [[[self alloc] initWithSubject:anObject messagePattern:aMessagePattern countType:aCountType count:aCount] autorelease];
39}
40
41- (void)dealloc {
42 [subject release];
43 [messagePattern release];
44 [super dealloc];
45}
46
47#pragma mark -
48#pragma mark Properties
49
50@synthesize subject;
51@synthesize messagePattern;
52@synthesize countType;
53@synthesize count;
54@synthesize receivedCount;
55
56#pragma mark -
57#pragma mark Spying on Messages
58
59- (void)object:(id)anObject didReceiveInvocation:(NSInvocation *)anInvocation {
60 if (![self.messagePattern matchesInvocation:anInvocation])
61 return;
62
63 ++self.receivedCount;
64}
65
66#pragma mark -
67#pragma mark Stopping Tracking
68
69- (void)stopTracking {
70 [self.subject removeMessageSpy:self forMessagePattern:self.messagePattern];
71}
72
73#pragma mark -
74#pragma mark Getting Message Tracker Status
75
76- (BOOL)succeeded {
77 switch (self.countType) {
78 case KWCountTypeExact:
79 return self.receivedCount == self.count;
80 case KWCountTypeAtLeast:
81 return self.receivedCount >= self.count;
82 case KWCountTypeAtMost:
83 return self.receivedCount <= self.count;
84 default:
85 break;
86 }
87
88 assert(0 && "should never reach here");
89 return NO;
90}
91
92#pragma mark -
93#pragma mark Getting Phrases
94
95- (NSString *)phraseForCount:(NSUInteger)aCount {
96 if (aCount == 1)
97 return @"1 time";
98
99 return [NSString stringWithFormat:@"%d times", (int)aCount];
100}
101
102- (NSString *)expectedCountPhrase {
103 NSString *countPhrase = [self phraseForCount:self.count];
104
105 switch (self.countType) {
106 case KWCountTypeExact:
107 return [NSString stringWithFormat:@"exactly %@", countPhrase];
108 case KWCountTypeAtLeast:
109 return [NSString stringWithFormat:@"at least %@", countPhrase];
110 case KWCountTypeAtMost:
111 return [NSString stringWithFormat:@"at most %@", countPhrase];
112 default:
113 break;
114 }
115
116 assert(0 && "should never reach here");
117 return nil;
118}
119
120- (NSString *)receivedCountPhrase {
121 return [self phraseForCount:self.receivedCount];
122}
123
124#pragma mark -
125#pragma mark Debugging
126
127- (NSString *)modeString {
128 switch (self.countType) {
129 case KWCountTypeExact:
130 return @"KWCountTypeExact";
131 case KWCountTypeAtLeast:
132 return @"KWCountTypeAtLeast";
133 case KWCountTypeAtMost:
134 return @"KWCountTypeAtMost";
135 default:
136 break;
137 }
138
139 assert(0 && "should never reach here");
140 return nil;
141}
142
143- (NSString *)description {
144 return [NSString stringWithFormat:@"messagePattern: %@\nmode: %@\ncount: %d\nreceiveCount: %d",
145 self.messagePattern,
146 self.modeString,
147 (int)self.count,
148 (int)self.receivedCount];
149}
150
151@end