Permalink
Browse files

Allow failure messages to be customized when creating dynamic matchers.

  • Loading branch information...
Luke Redpath
Luke Redpath committed Jun 17, 2011
1 parent 924bc5a commit 8737c71a0804a4ea00f1f5bc8a0a5c837e1b7213
Showing with 100 additions and 16 deletions.
  1. +1 −1 Kiwi.xcodeproj/project.pbxproj
  2. +1 −1 Kiwi/KWMatcher.h
  3. +23 −4 Kiwi/KWUserDefinedMatcher.h
  4. +51 −10 Kiwi/KWUserDefinedMatcher.m
  5. +24 −0 Tests/KWUserDefinedMatcherTest.m
@@ -261,7 +261,7 @@
A352EA1812EDC8160049C691 /* KWHamcrestMatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KWHamcrestMatcher.m; sourceTree = "<group>"; };
A352EA1A12EDC8380049C691 /* KWHamcrestMatcherTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KWHamcrestMatcherTest.m; sourceTree = "<group>"; };
A385CAE713AA7EA200DCA951 /* KWUserDefinedMatcherTest.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = KWUserDefinedMatcherTest.m; sourceTree = "<group>"; tabWidth = 4; };
- A385CAE913AA7ED800DCA951 /* KWUserDefinedMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KWUserDefinedMatcher.h; sourceTree = "<group>"; };
+ A385CAE913AA7ED800DCA951 /* KWUserDefinedMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = KWUserDefinedMatcher.h; sourceTree = "<group>"; tabWidth = 4; };
A385CAEA13AA7ED800DCA951 /* KWUserDefinedMatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = KWUserDefinedMatcher.m; sourceTree = "<group>"; tabWidth = 4; };
A385CAED13AAC9B600DCA951 /* KWMatchers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KWMatchers.h; sourceTree = "<group>"; };
A385CAEE13AAC9B700DCA951 /* KWMatchers.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = KWMatchers.m; sourceTree = "<group>"; tabWidth = 4; };
View
@@ -8,7 +8,7 @@
#import "KWMatching.h"
@interface KWMatcher : NSObject<KWMatching> {
-@private
+@protected
id subject;
}
@@ -16,25 +16,44 @@ typedef BOOL (^KWUserDefinedMatcherBlock)();
KWUserDefinedMatcherBlock matcherBlock;
SEL selector;
NSInvocation *invocation;
+ NSString *failureMessageForShould;
+ NSString *failureMessageForShouldNot;
}
@property (nonatomic, assign) SEL selector;
+@property (nonatomic, copy) NSString *failureMessageForShould;
+@property (nonatomic, copy) NSString *failureMessageForShouldNot;
+@property (nonatomic, assign) KWUserDefinedMatcherBlock matcherBlock;
-+ (id)matcherWithSubject:(id)subject block:(KWUserDefinedMatcherBlock)aBlock;
-- (id)initWithSubject:(id)subject block:(KWUserDefinedMatcherBlock)aBlock;
++ (id)matcherWithSubject:(id)aSubject block:(KWUserDefinedMatcherBlock)aBlock;
+- (id)initWithSubject:(id)aSubject block:(KWUserDefinedMatcherBlock)aBlock;
+- (void)setSubject:(id)aSubject;
@end
#pragma mark -
+typedef NSString * (^KWUserDefinedMatcherMessageBlock)(id);
+
@interface KWUserDefinedMatcherBuilder : NSObject
{
- KWUserDefinedMatcherBlock matcherBlock;
- SEL selector;
+ KWUserDefinedMatcher *matcher;
+ KWUserDefinedMatcherMessageBlock failureMessageForShouldBlock;
+ KWUserDefinedMatcherMessageBlock failureMessageForShouldNotBlock;
}
@property (nonatomic, readonly) NSString *key;
+ (id)builder;
+ (id)builderForSelector:(SEL)aSelector;
- (id)initWithSelector:(SEL)aSelector;
+
+#pragma mark -
+#pragma mark Configuring The Matcher
+
- (void)match:(KWUserDefinedMatcherBlock)block;
+- (void)failureMessageForShould:(KWUserDefinedMatcherMessageBlock)block;
+- (void)failureMessageForShouldNot:(KWUserDefinedMatcherMessageBlock)block;
+
+#pragma mark -
+#pragma mark Buiding The Matcher
+
- (KWUserDefinedMatcher *)buildMatcherWithSubject:(id)subject;
@end
@@ -11,15 +11,18 @@
@implementation KWUserDefinedMatcher
@synthesize selector;
+@synthesize failureMessageForShould;
+@synthesize failureMessageForShouldNot;
+@synthesize matcherBlock;
-+ (id)matcherWithSubject:(id)subject block:(KWUserDefinedMatcherBlock)aBlock
++ (id)matcherWithSubject:(id)aSubject block:(KWUserDefinedMatcherBlock)aBlock
{
- return [[[self alloc] initWithSubject:subject block:aBlock] autorelease];
+ return [[[self alloc] initWithSubject:aSubject block:aBlock] autorelease];
}
-- (id)initWithSubject:(id)subject block:(KWUserDefinedMatcherBlock)aBlock
+- (id)initWithSubject:(id)aSubject block:(KWUserDefinedMatcherBlock)aBlock
{
- if ((self = [super initWithSubject:subject])) {
+ if ((self = [super initWithSubject:aSubject])) {
matcherBlock = [aBlock copy];
}
return self;
@@ -46,6 +49,13 @@ - (BOOL)evaluate
return result;
}
+- (void)setSubject:(id)aSubject {
+ if (aSubject != subject) {
+ [subject release];
+ subject = [aSubject retain];
+ }
+}
+
#pragma mark -
#pragma mark Message forwarding
@@ -102,23 +112,54 @@ + (id)builderForSelector:(SEL)aSelector {
- (id)initWithSelector:(SEL)aSelector {
if ((self = [super init])) {
- selector = aSelector;
+ matcher = [[KWUserDefinedMatcher alloc] init];
+ matcher.selector = aSelector;
}
return self;
}
+- (void)dealloc
+{
+ [matcher release];
+ [failureMessageForShouldBlock release];
+ [super dealloc];
+}
+
- (NSString *)key {
- return NSStringFromSelector(selector);
+ return NSStringFromSelector(matcher.selector);
}
+#pragma mark -
+#pragma mark Configuring The Matcher
+
- (void)match:(KWUserDefinedMatcherBlock)block {
- Block_release(matcherBlock);
- matcherBlock = Block_copy(block);
+ matcher.matcherBlock = block;
}
+- (void)failureMessageForShould:(KWUserDefinedMatcherMessageBlock)block {
+ [failureMessageForShouldBlock release];
+ failureMessageForShouldBlock = [block copy];
+}
+
+- (void)failureMessageForShouldNot:(KWUserDefinedMatcherMessageBlock)block {
+ [failureMessageForShouldNotBlock release];
+ failureMessageForShouldNotBlock = [block copy];
+}
+
+#pragma mark -
+#pragma mark Buiding The Matcher
+
- (KWUserDefinedMatcher *)buildMatcherWithSubject:(id)subject {
- KWUserDefinedMatcher *matcher = [KWUserDefinedMatcher matcherWithSubject:subject block:matcherBlock];
- matcher.selector = selector;
+ [matcher setSubject:subject];
+
+ if (failureMessageForShouldBlock) {
+ [matcher setFailureMessageForShould:failureMessageForShouldBlock(subject)];
+ }
+
+ if (failureMessageForShouldNotBlock) {
+ [matcher setFailureMessageForShouldNot:failureMessageForShouldNotBlock(subject)];
+ }
+
return matcher;
}
@@ -86,6 +86,30 @@ - (void)testShouldSetTheSelectorForTheMatcher
}
+- (void)testCanSetTheFailureMessageForShould
+{
+ KWUserDefinedMatcherBuilder *builder = [KWUserDefinedMatcherBuilder builder];
+
+ [builder failureMessageForShould:^(id subject) {
+ return [NSString stringWithFormat:@"failure message containing subject %@", subject];
+ }];
+
+ KWUserDefinedMatcher *matcher = [builder buildMatcherWithSubject:@"foo"];
+ STAssertEquals(@"failure message containing subject foo", [matcher failureMessageForShould], @"should set failure message for should");
+}
+
+- (void)testCanSetTheFailureMessageForShouldNot
+{
+ KWUserDefinedMatcherBuilder *builder = [KWUserDefinedMatcherBuilder builder];
+
+ [builder failureMessageForShouldNot:^(id subject) {
+ return [NSString stringWithFormat:@"failure message containing subject %@", subject];
+ }];
+
+ KWUserDefinedMatcher *matcher = [builder buildMatcherWithSubject:@"foo"];
+ STAssertEquals(@"failure message containing subject foo", [matcher failureMessageForShouldNot], @"should set failure message for should");
+}
+
@end
#endif

0 comments on commit 8737c71

Please sign in to comment.