diff --git a/Classes/Core/KWMessagePattern.m b/Classes/Core/KWMessagePattern.m index 58012f9a..317cd74b 100644 --- a/Classes/Core/KWMessagePattern.m +++ b/Classes/Core/KWMessagePattern.m @@ -181,8 +181,7 @@ - (NSArray *)argumentFiltersWithFirstArgumentFilter:(id)firstArgumentFilter NSMutableArray *array = [NSMutableArray arrayWithCapacity:count]; [array addObject:(firstArgumentFilter != nil) ? firstArgumentFilter : [KWNull null]]; - for (NSUInteger i = 1; i < count; ++i) - { + for (NSUInteger i = 1; i < count; ++i) { id object = va_arg(argumentList, id); [array addObject:(object != nil) ? object : [KWNull null]]; } diff --git a/Classes/Matchers/KWBeEvaluatedMatcher.h b/Classes/Matchers/KWBeEvaluatedMatcher.h index 7ad8ffcb..2b2f4cef 100644 --- a/Classes/Matchers/KWBeEvaluatedMatcher.h +++ b/Classes/Matchers/KWBeEvaluatedMatcher.h @@ -7,6 +7,7 @@ // #import "KWMessageTrackerMatcher.h" +#import "KWMatchVerifier.h" @interface KWBeEvaluatedMatcher : KWMessageTrackerMatcher @@ -21,3 +22,13 @@ - (void)beEvaluatedWithCountAtMost:(NSUInteger)aCount arguments:(id)firstArgument, ...; @end + +@interface KWMatchVerifier (KWBeEvaluatedMatcherAdditions) + +// NSInvocation doesn't work with va_arg, so we have to implement it directly in match verifier +- (void)beEvaluatedWithArguments:(id)firstArgument, ...; +- (void)beEvaluatedWithCount:(NSUInteger)aCount arguments:(id)firstArgument, ...; +- (void)beEvaluatedWithCountAtLeast:(NSUInteger)aCount arguments:(id)firstArgument, ...; +- (void)beEvaluatedWithCountAtMost:(NSUInteger)aCount arguments:(id)firstArgument, ...; + +@end diff --git a/Classes/Matchers/KWBeEvaluatedMatcher.m b/Classes/Matchers/KWBeEvaluatedMatcher.m index 2b50d07b..5a7ce427 100644 --- a/Classes/Matchers/KWBeEvaluatedMatcher.m +++ b/Classes/Matchers/KWBeEvaluatedMatcher.m @@ -26,7 +26,9 @@ + (NSArray *)matcherStrings { @"beEvaluatedWithArguments:", @"beEvaluatedWithCount:arguments:", @"beEvaluatedWithCountAtLeast:arguments:", - @"beEvaluatedWithCountAtMost:arguments:"]; + @"beEvaluatedWithCountAtMost:arguments:", + @"beEvaluatedWithUnspecifiedCountOfMessagePattern:", + @"beEvaluatedWithMessagePattern:countType:count:"]; } #pragma mark - Configuring Matchers @@ -51,7 +53,7 @@ - (void)beEvaluatedWithCountAtMost:(NSUInteger)aCount { - (void)beEvaluatedWithCountType:(KWCountType)aCountType count:(NSUInteger)aCount { id pattern = [KWBlockMessagePattern messagePatternWithSignature:[self subjectSignature]]; - [self receiveMessagePattern:pattern countType:aCountType count:aCount]; + [self beEvaluatedWithMessagePattern:pattern countType:aCountType count:aCount]; } - (void)beEvaluatedWithUnspecifiedCountOfMessagePattern:(KWBlockMessagePattern *)messagePattern { @@ -65,7 +67,8 @@ - (void)beEvaluatedWithUnspecifiedCountOfMessagePattern:(KWBlockMessagePattern * va_start(listName, firstArgument); - (void)beEvaluatedWithArguments:(id)firstArgument, ... { - KWStartVAListWithVariableName(argumentList); + va_list argumentList; + va_start(argumentList, firstArgument); id pattern = [KWBlockMessagePattern messagePatternWithSignature:[self subjectSignature] firstArgumentFilter:firstArgument @@ -80,7 +83,7 @@ - (void)beEvaluatedWithArguments:(id)firstArgument, ... { id pattern = [KWBlockMessagePattern messagePatternWithSignature:[self subjectSignature] \ firstArgumentFilter:firstArgument \ argumentList:argumentList]; \ - [self receiveMessagePattern:pattern countType:aCountType count:aCount]; \ + [self beEvaluatedWithMessagePattern:pattern countType:aCountType count:aCount]; \ } while(0) - (void)beEvaluatedWithCount:(NSUInteger)aCount arguments:(id)firstArgument, ... { @@ -100,7 +103,7 @@ - (void)beEvaluatedWithCountAtMost:(NSUInteger)aCount arguments:(id)firstArgumen #pragma mark - Message Pattern Receiving -- (void)receiveMessagePattern:(KWBlockMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount { +- (void)beEvaluatedWithMessagePattern:(KWBlockMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount { #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG @try { #endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG @@ -132,3 +135,52 @@ - (NSMethodSignature *)subjectSignature { } @end + +@implementation KWMatchVerifier (KWBeEvaluatedMatcherAdditions) + +#pragma mark - Verifying + +#define KWStartVAListWithVariableName(listName) \ + va_list listName; \ + va_start(listName, firstArgument); + +- (void)beEvaluatedWithArguments:(id)firstArgument, ... { + KWStartVAListWithVariableName(argumentList) + + id pattern = [KWBlockMessagePattern messagePatternWithSignature:[self beEvaluated_subjectSignature] + firstArgumentFilter:firstArgument + argumentList:argumentList]; + + [(id)self beEvaluatedWithUnspecifiedCountOfMessagePattern:pattern]; +} + +#define KWReceiveVAListMessagePatternWithCountType(aCountType) \ + do { \ + KWStartVAListWithVariableName(argumentList); \ + id pattern = [KWBlockMessagePattern messagePatternWithSignature:[self beEvaluated_subjectSignature] \ + firstArgumentFilter:firstArgument \ + argumentList:argumentList]; \ + [(id)self beEvaluatedWithMessagePattern:pattern countType:aCountType count:aCount]; \ + } while(0) + +- (void)beEvaluatedWithCount:(NSUInteger)aCount arguments:(id)firstArgument, ... { + KWReceiveVAListMessagePatternWithCountType(KWCountTypeExact); +} + +- (void)beEvaluatedWithCountAtLeast:(NSUInteger)aCount arguments:(id)firstArgument, ... { + KWReceiveVAListMessagePatternWithCountType(KWCountTypeAtLeast); +} + +- (void)beEvaluatedWithCountAtMost:(NSUInteger)aCount arguments:(id)firstArgument, ... { + KWReceiveVAListMessagePatternWithCountType(KWCountTypeAtMost); +} + +#undef KWReceiveVAListMessagePatternWithCountType +#undef KWArgumentList + +- (NSMethodSignature *)beEvaluated_subjectSignature { + return [self.subject methodSignature]; +} + +@end + diff --git a/Tests/KWBeEvaluatedMatcherTest.m b/Tests/KWBeEvaluatedMatcherTest.m index 2fdd2f06..9133a67f 100644 --- a/Tests/KWBeEvaluatedMatcherTest.m +++ b/Tests/KWBeEvaluatedMatcherTest.m @@ -71,7 +71,9 @@ - (void)testItShouldHaveTheRightMatcherStrings { @"beEvaluatedWithArguments:", @"beEvaluatedWithCount:arguments:", @"beEvaluatedWithCountAtLeast:arguments:", - @"beEvaluatedWithCountAtMost:arguments:"]; + @"beEvaluatedWithCountAtMost:arguments:", + @"beEvaluatedWithUnspecifiedCountOfMessagePattern:", + @"beEvaluatedWithMessagePattern:countType:count:"]; XCTAssertEqualObjects([matcherStrings sortedArrayUsingSelector:@selector(compare:)], [expectedStrings sortedArrayUsingSelector:@selector(compare:)], diff --git a/Tests/KWMessagePatternFunctionalTests.m b/Tests/KWMessagePatternFunctionalTests.m index af9ffd7c..641d3b94 100644 --- a/Tests/KWMessagePatternFunctionalTests.m +++ b/Tests/KWMessagePatternFunctionalTests.m @@ -2,32 +2,80 @@ #import "KiwiTestConfiguration.h" #import "TestClasses.h" -typedef void(^KWTestBlock)(id); +typedef void(^KWVoidTestBlock)(); +typedef void(^KWArgumentTestBlock)(id); +typedef void(^KWMultiArgumentTestBlock)(id, id, id); SPEC_BEGIN(KWMessagePatternFunctionalTests) describe(@"message patterns", ^{ + NSString *description = @"description"; + NSString *format = nil; + Cruiser *cruiser = [Cruiser new]; + + it(@"can match a selector with no arguments", ^{ + [[cruiser should] receive:@selector(computeParsecs)]; + + [cruiser computeParsecs]; + }); + it(@"can match a selector with a specific single argument", ^{ - Cruiser *cruiser = [Cruiser new]; Fighter *fighter = [Fighter mock]; + [[cruiser should] receive:@selector(loadFighter:) withArguments:fighter]; + [cruiser loadFighter:fighter]; }); + + it(@"can match a selector with specific multiple arguments", ^{ + [[cruiser should] receive:@selector(raiseWithName:description:) withArguments:description, format]; + + [cruiser raiseWithName:description description:format]; + }); + it(@"can match a selector with multiple arguments", ^{ + [[cruiser should] receive:@selector(raiseWithName:description:)]; + + [cruiser raiseWithName:description description:format]; + }); }); describe(@"block message patterns", ^{ + id argument1 = [NSObject new]; + id argument2 = [NSObject new]; + + it(@"can match a call with a call without arguments", ^{ + id block = theBlockProxy(^{ }); + + [[block should] beEvaluated]; + + ((KWVoidTestBlock)block)(); + }); it(@"can match a call with a specific single argument", ^{ - id argument = [NSObject new]; - id block = theBlockProxy(^(id object) { [object description]; }); + id block = theBlockProxy(^(id object) { }); - [[block should] beEvaluatedWithArguments:argument]; + [[block should] beEvaluatedWithArguments:argument1]; - ((KWTestBlock)block)(argument); + ((KWArgumentTestBlock)block)(argument1); }); + it(@"can match a call with specific multiple arguments", ^{ + id block = theBlockProxy(^(id object1, id object2, id object3) { }); + + [[block should] beEvaluatedWithArguments:argument1, nil, argument2]; + + ((KWMultiArgumentTestBlock)block)(argument1, nil, argument2); + }); + + it(@"can match a call with multiple arguments", ^{ + id block = theBlockProxy(^(id object1, id object2, id object3) { }); + + [[block should] beEvaluated]; + + ((KWMultiArgumentTestBlock)block)(argument1, nil, argument2); + }); }); SPEC_END