Permalink
Browse files

Added support for any() argument matcher (for pointers and scalars)

  • Loading branch information...
MattesGroeger committed Mar 14, 2012
1 parent fd71c23 commit b96e05d8ff1b43cf7b697d9a1b2ac3cdffed4909
@@ -156,6 +156,14 @@ - (void)itShouldVerifyReceivedMessages {
[[theValue(energyLevel) should] equal:theValue(1.01f)];
}
+- (void)itShouldVerifyReceivedMessagesWithAnyArgument {
+ id subject = [Cruiser cruiser];
+ [[subject should] receive:@selector(energyLevelInWarpCore:) andReturn:theValue(1.01f) withCount:2 arguments:any()];
+ [subject energyLevelInWarpCore:2];
+ float energyLevel = [subject energyLevelInWarpCore:2];
+ [[theValue(energyLevel) should] equal:theValue(1.01f)];
+}
+
- (void)itShouldAllowExpectationsArgumentsToBeHamcrestMatchersForFuzzyMatching
{
id subject = [Robot robot];
@@ -218,6 +218,8 @@
F5F7471011B328F1000CA15C /* TestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = F5F7470F11B328F1000CA15C /* TestReporter.m */; };
F5FC83A811B1000500BF98A2 /* KWStringUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FC83A611B1000500BF98A2 /* KWStringUtilities.m */; };
F5FC83B611B100B100BF98A2 /* KWStringUtilitiesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FC83B511B100B100BF98A2 /* KWStringUtilitiesTest.m */; };
+ F5FC83B611B100B100BF98A4 /* KWAny.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FC83B611B100B100BF98A3 /* KWAny.m */; };
+ F5FC83B611B100B100BF98A8 /* KWAny.h in Headers */ = {isa = PBXBuildFile; fileRef = F5FC83B611B100B100BF98A7 /* KWAny.h */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -471,6 +473,8 @@
F5FC83A511B1000500BF98A2 /* KWStringUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KWStringUtilities.h; sourceTree = "<group>"; };
F5FC83A611B1000500BF98A2 /* KWStringUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KWStringUtilities.m; sourceTree = "<group>"; };
F5FC83B511B100B100BF98A2 /* KWStringUtilitiesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KWStringUtilitiesTest.m; sourceTree = "<group>"; };
+ F5FC83B611B100B100BF98A3 /* KWAny.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KWAny.m; sourceTree = "<group>"; };
+ F5FC83B611B100B100BF98A7 /* KWAny.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KWAny.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -726,6 +730,8 @@
F57A6868115A3A1D00591C2A /* Support */ = {
isa = PBXGroup;
children = (
+ F5FC83B611B100B100BF98A3 /* KWAny.m */,
+ F5FC83B611B100B100BF98A7 /* KWAny.h */,
F5E9FC2F11AE6A0F0089BACE /* KWBlock.h */,
F5E9FC3011AE6A0F0089BACE /* KWBlock.m */,
F5015B571158398E002E9A98 /* KWCallSite.h */,
@@ -994,6 +1000,7 @@
A3FABFAF13CBB187002003F7 /* KiwiBlockMacros.h in Headers */,
A3CB75E2144C3479002D1F7A /* KWExampleSuite.h in Headers */,
4B9D040814D3EE7300707E83 /* KWExampleGroupDelegate.h in Headers */,
+ F5FC83B611B100B100BF98A8 /* KWAny.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1228,6 +1235,7 @@
A385CAEC13AA7EDD00DCA951 /* KWUserDefinedMatcher.m in Sources */,
A385CAF013AAC9B800DCA951 /* KWMatchers.m in Sources */,
A3CB75E3144C3479002D1F7A /* KWExampleSuite.m in Sources */,
+ F5FC83B611B100B100BF98A4 /* KWAny.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
@@ -0,0 +1,18 @@
+//
+// Licensed under the terms in License.txt
+//
+// Copyright 2010 Allen Ding. All rights reserved.
+//
+
+#import "KiwiConfiguration.h"
+
+// KWAny exists to determine arguments in a message pattern that should
+// match any value. Used for pointers as well as for scalar values.
+@interface KWAny : NSObject
+
+#pragma mark -
+#pragma mark Initializing
+
++ (id)any;
+
+@end
View
@@ -0,0 +1,47 @@
+//
+// Licensed under the terms in License.txt
+//
+// Copyright 2010 Allen Ding. All rights reserved.
+//
+
+#import "KWAny.h"
+
+@implementation KWAny
+
+#pragma mark -
+#pragma mark Initializing
+
+static KWAny *sharedAny = nil;
+
++ (id)any {
+ if (sharedAny == nil) {
+ sharedAny = [[super allocWithZone:nil] init];
+ }
+
+ return sharedAny;
+}
+
++ (id)allocWithZone:(NSZone *)zone {
+ return [[self any] retain];
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+ return self;
+}
+
+- (id)retain {
+ return self;
+}
+
+- (NSUInteger)retainCount {
+ return NSUIntegerMax;
+}
+
+- (oneway void)release {
+}
+
+- (id)autorelease {
+ return self;
+}
+
+@end
View
@@ -12,6 +12,7 @@
#import "NSInvocation+KiwiAdditions.h"
#import "NSMethodSignature+KiwiAdditions.h"
#import "KWHCMatcher.h"
+#import "Kiwi.h"
@implementation KWMessagePattern
@@ -130,6 +131,10 @@ - (BOOL)argumentFiltersMatchInvocationArguments:(NSInvocation *)anInvocation {
// Match argument filter to object
id argumentFilter = [self.argumentFilters objectAtIndex:i];
+ if ([argumentFilter isEqual:[KWAny any]]) {
+ continue;
+ }
+
if (KWObjCTypeIsObject(objCType)) {
if ([argumentFilter isEqual:[KWNull null]]) {
if (object != nil)
View
@@ -14,6 +14,7 @@ extern "C" {
#import "KWAfterAllNode.h"
#import "KWAfterEachNode.h"
+#import "KWAny.h"
#import "KWAsyncVerifier.h"
#import "KWBeBetweenMatcher.h"
#import "KWBeEmptyMatcher.h"
View
@@ -33,6 +33,9 @@
#define theReturnValueOfBlock(block) [KWFutureObject futureObjectWithBlock:block] // DEPRECATED
#define expectFutureValue(futureValue) [KWFutureObject futureObjectWithBlock:^{ return futureValue; }]
+// used for message patterns to allow matching any value
+#define any() [KWAny any]
+
// If a gcc compatible compiler is available, use the statement and
// declarations in expression extension to provide a convenient catch-all macro
// to create KWValues.
@@ -7,7 +7,6 @@
#import "Kiwi.h"
#import "KiwiTestConfiguration.h"
#import "NSInvocation+KiwiAdditions.h"
-#import "TestClasses.h"
#if KW_TESTS_ENABLED
@@ -48,6 +47,38 @@ - (void)testItShouldMatchInvocationsWithNilArguments {
STAssertTrue([messagePattern matchesInvocation:invocation], @"expected matching invocation");
}
+- (void)testItShouldMatchInvocationsWithAnyArguments {
+ KWMessagePattern *messagePattern = [self messagePatternWithSelector:@selector(addObserver:forKeyPath:options:context:) arguments:@"foo",
+ [KWAny any],
+ [KWAny any],
+ nil];
+ NSMethodSignature *signature = [NSObject instanceMethodSignatureForSelector:@selector(addObserver:forKeyPath:options:context:)];
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
+ [invocation setSelector:@selector(addObserver:forKeyPath:options:context:)];
+ id observer = @"foo";
+ id keyPath = @"bar";
+ NSKeyValueObservingOptions options = 1;
+ void *context = nil;
+ [invocation setMessageArguments:&observer, &keyPath, &options, &context];
+ STAssertTrue([messagePattern matchesInvocation:invocation], @"expected matching invocation");
+}
+
+- (void)testItShouldNotMatchInvocationsWithAnyArguments {
+ KWMessagePattern *messagePattern = [self messagePatternWithSelector:@selector(addObserver:forKeyPath:options:context:) arguments:@"foo",
+ [KWAny any],
+ [KWValue valueWithUnsignedInt:0],
+ nil];
+ NSMethodSignature *signature = [NSObject instanceMethodSignatureForSelector:@selector(addObserver:forKeyPath:options:context:)];
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
+ [invocation setSelector:@selector(addObserver:forKeyPath:options:context:)];
+ id observer = @"foo";
+ id keyPath = @"bar";
+ NSKeyValueObservingOptions options = 1;
+ void *context = nil;
+ [invocation setMessageArguments:&observer, &keyPath, &options, &context];
+ STAssertTrue(![messagePattern matchesInvocation:invocation], @"expected non-matching invocation");
+}
+
- (void)testItShouldNotMatchInvocationsWithDifferentArguments {
KWMessagePattern *messagePattern = [self messagePatternWithSelector:@selector(addObserver:forKeyPath:options:context:) arguments:@"foo",
nil,
View
@@ -70,6 +70,13 @@ - (void)testItShouldStubWithASelectorReturnValueAndArguments {
STAssertTrue([mock energyLevelInWarpCore:2] != 30.0f, @"expected method with arguments not to be stubbed");
}
+- (void)testItShouldStubWithASelectorReturnValueAndAnyArguments {
+ id mock = [Cruiser nullMock];
+ [mock stub:@selector(energyLevelInWarpCore:) andReturn:theValue(30.0f) withArguments:any()];
+ STAssertEquals([mock energyLevelInWarpCore:3], 30.0f, @"expected method with any() arguments to be stubbed");
+ STAssertEquals([mock energyLevelInWarpCore:2], 30.0f, @"expected method with any() arguments to be stubbed");
+}
+
- (void)testItShouldStubWithAMessage {
id mock = [Cruiser mock];
STAssertNoThrow([[mock stub] energyLevelInWarpCore:3], @"expected mock to stub message");
@@ -47,6 +47,13 @@ - (void)testItShouldStubInstanceMethodsReturningObjects {
STAssertEquals(fighter, [cruiser fighterWithCallsign:fighterCallsign], @"expected method to be stubbed");
}
+- (void)testItShouldStubInstanceMethodsReturningObjectsWithAnyArguments {
+ Cruiser *cruiser = [Cruiser cruiserWithCallsign:@"Galactica"];
+ Fighter *fighter = [Fighter fighterWithCallsign:@"Viper 1"];
+ [cruiser stub:@selector(fighterWithCallsign:) andReturn:fighter withArguments:any()];
+ STAssertEquals(fighter, [cruiser fighterWithCallsign:@"Foo"], @"expected method to be stubbed");
+}
+
- (void)testItShouldClearStubbedRecursiveMethods {
NSUInteger starHash = 8 + 4 + 2 + 1;
Cruiser *cruiser = [Cruiser cruiserWithCallsign:@"Galactica"];

0 comments on commit b96e05d

Please sign in to comment.