Skip to content

Commit

Permalink
Added block constraints and invocation handler
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.mulle-kybernetik.com/OCMock/trunk@56 12620d81-68e2-0310-ae40-e3f550779089
  • Loading branch information
erik committed Apr 18, 2010
1 parent ba5ff76 commit 088f2e1
Show file tree
Hide file tree
Showing 12 changed files with 207 additions and 13 deletions.
5 changes: 5 additions & 0 deletions Source/Changes.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Chronological listing of changes. If a particular SVN revision has no entry, that
check-in did not involve any code or feature changes.

2010-04-18 (r56)

* Added block constraints and invocation handler (thanks to Justin DeWind)


2009-10-16 (r55)

* Fixed broken test for array argument descciptions (Craig Beck)
Expand Down
7 changes: 5 additions & 2 deletions Source/OCMArg.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------
// $Id: $
// Copyright (c) 2009 by Mulle Kybernetik. See License file for details.
// $Id$
// Copyright (c) 2009-2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import <Foundation/Foundation.h>
Expand All @@ -15,6 +15,9 @@
+ (id)isNotNil;
+ (id)isNotEqual:(id)value;
+ (id)checkWithSelector:(SEL)selector onObject:(id)anObject;
#ifdef MAC_OS_X_VERSION_10_6
+ (id)checkWithBlock:(BOOL (^)(id))block;
#endif

// manipulating arguments

Expand Down
14 changes: 12 additions & 2 deletions Source/OCMArg.m
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//---------------------------------------------------------------------------------------
// $Id: $
// Copyright (c) 2009 by Mulle Kybernetik. See License file for details.
// $Id$
// Copyright (c) 2009-2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import <OCMock/OCMArg.h>
#import <OCMock/OCMConstraint.h>
#import "OCMPassByRefSetter.h"
#import "OCMConstraint.h"

@implementation OCMArg

Expand Down Expand Up @@ -41,6 +42,15 @@ + (id)checkWithSelector:(SEL)selector onObject:(id)anObject
return [OCMConstraint constraintWithSelector:selector onObject:anObject];
}

#ifdef MAC_OS_X_VERSION_10_6

+ (id)checkWithBlock:(BOOL (^)(id))block
{
return [[[OCMBlockConstraint alloc] initWithConstraintBlock:block] autorelease];
}

#endif

+ (id *)setTo:(id)value;
{
return (id *)[[OCMPassByRefSetter alloc] initWithValue:value];
Expand Down
19 changes: 19 additions & 0 deletions Source/OCMBlockCaller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//---------------------------------------------------------------------------------------
// $Id$
// Copyright (c) 2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import <Foundation/Foundation.h>

#ifdef MAC_OS_X_VERSION_10_6

@interface OCMBlockCaller : NSObject
{
void (^block)(NSInvocation *);
}

-(id)initWithCallBlock:(void (^)(NSInvocation *))theBlock;

@end

#endif
32 changes: 32 additions & 0 deletions Source/OCMBlockCaller.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//---------------------------------------------------------------------------------------
// $Id$
// Copyright (c) 2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import "OCMBlockCaller.h"

#ifdef MAC_OS_X_VERSION_10_6

@implementation OCMBlockCaller

-(id)initWithCallBlock:(void (^)(NSInvocation *))theBlock
{
[super init];
block = [theBlock copy];
return self;
}

-(void)dealloc
{
[block release];
[super dealloc];
}

- (void)handleInvocation:(NSInvocation *)anInvocation
{
block(anInvocation);
}

@end

#endif
22 changes: 19 additions & 3 deletions Source/OCMConstraint.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
//---------------------------------------------------------------------------------------
// $Id: $
// Copyright (c) 2007-2009 by Mulle Kybernetik. See License file for details.
// $Id$
// Copyright (c) 2007-2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import <Foundation/Foundation.h>


@interface OCMConstraint : NSObject

+ (id)constraint;
- (BOOL)evaluate:(id)value;

// if you are looking for any, isNil, etc, they have moved to OCMArg

// try to use [OCMArg checkWith...] instead of the constraintWith... methods below

+ (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject;
+ (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject withValue:(id)aValue;

// try to use [OCMArg checkWith...] instead of constraintWithSelector in here

@end

Expand Down Expand Up @@ -44,5 +46,19 @@

@end

#ifdef MAC_OS_X_VERSION_10_6

@interface OCMBlockConstraint : OCMConstraint
{
BOOL (^block)(id);
}

- (id)initWithConstraintBlock:(BOOL (^)(id))block;

@end

#endif


#define CONSTRAINT(aSelector) [OCMConstraint constraintWithSelector:aSelector onObject:self]
#define CONSTRAINTV(aSelector, aValue) [OCMConstraint constraintWithSelector:aSelector onObject:self withValue:(aValue)]
26 changes: 24 additions & 2 deletions Source/OCMConstraint.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------
// $Id: $
// Copyright (c) 2007-2008 by Mulle Kybernetik. See License file for details.
// $Id$
// Copyright (c) 2007-2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import <OCMock/OCMConstraint.h>
Expand Down Expand Up @@ -41,6 +41,7 @@ + (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject withValue:(id)
return constraint;
}


@end


Expand Down Expand Up @@ -112,3 +113,24 @@ - (BOOL)evaluate:(id)value

@end

#pragma mark -

#ifdef MAC_OS_X_VERSION_10_6

@implementation OCMBlockConstraint

- (id)initWithConstraintBlock:(BOOL (^)(id))aBlock;
{
[super init];
block = aBlock;
return self;
}

- (BOOL)evaluate:(id)value
{
return block(value);
}

@end

#endif
36 changes: 35 additions & 1 deletion Source/OCMConstraintTests.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------
// $Id: OCMockRecorderTests.m 12 2006-06-11 02:41:31Z erik $
// Copyright (c) 2004-2008 by Mulle Kybernetik. See License file for details.
// Copyright (c) 2004-2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import "OCMConstraintTests.h"
Expand Down Expand Up @@ -94,4 +94,38 @@ - (void)testRaisesExceptionOnUnknownSelector
}


#ifdef MAC_OS_X_VERSION_10_6

-(void)testUsesBlock
{
BOOL (^checkForFooBlock)(id) = ^(id value)
{
return [value isEqualToString:@"foo"];
};

OCMBlockConstraint *constraint = [[[OCMBlockConstraint alloc] initWithConstraintBlock:checkForFooBlock] autorelease];

STAssertTrue([constraint evaluate:@"foo"], @"Should have accepted foo.");
STAssertFalse([constraint evaluate:@"bar"], @"Should not have accepted bar.");
}

-(void)testBlockConstraintCanCaptureArgument
{
__block NSString *captured;
BOOL (^captureArgBlock)(id) = ^(id value)
{
captured = value;
return YES;
};

OCMBlockConstraint *constraint = [[[OCMBlockConstraint alloc] initWithConstraintBlock:captureArgBlock] autorelease];

[constraint evaluate:@"foo"];
STAssertEqualObjects(@"foo", captured, @"Should have captured value from last invocation.");
[constraint evaluate:@"bar"];
STAssertEqualObjects(@"bar", captured, @"Should have captured value from last invocation.");
}

#endif

@end
8 changes: 8 additions & 0 deletions Source/OCMock.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
03C3672F100D6D0F00BE9731 /* OCMIndirectReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 03C3672D100D6D0F00BE9731 /* OCMIndirectReturnValueProvider.m */; };
03C36775100D744700BE9731 /* OCMNotificationPoster.h in Headers */ = {isa = PBXBuildFile; fileRef = 03C36773100D744700BE9731 /* OCMNotificationPoster.h */; };
03C36776100D744700BE9731 /* OCMNotificationPoster.m in Sources */ = {isa = PBXBuildFile; fileRef = 03C36774100D744700BE9731 /* OCMNotificationPoster.m */; };
03CFB08C117B308C00935C1E /* OCMBlockCaller.h in Headers */ = {isa = PBXBuildFile; fileRef = 03CFB089117B308C00935C1E /* OCMBlockCaller.h */; };
03CFB08D117B308C00935C1E /* OCMBlockCaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 03CFB08A117B308C00935C1E /* OCMBlockCaller.m */; };
03D880550F8C75980087D071 /* OCObserverMockObjectTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 03D880540F8C75980087D071 /* OCObserverMockObjectTest.m */; };
03D880610F8C81DE0087D071 /* OCObserverMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 03D8805E0F8C81DE0087D071 /* OCObserverMockObject.h */; };
03D880620F8C81DE0087D071 /* OCObserverMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 03D8805F0F8C81DE0087D071 /* OCObserverMockObject.m */; };
Expand Down Expand Up @@ -106,6 +108,8 @@
03C3672D100D6D0F00BE9731 /* OCMIndirectReturnValueProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMIndirectReturnValueProvider.m; sourceTree = "<group>"; };
03C36773100D744700BE9731 /* OCMNotificationPoster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMNotificationPoster.h; sourceTree = "<group>"; };
03C36774100D744700BE9731 /* OCMNotificationPoster.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMNotificationPoster.m; sourceTree = "<group>"; };
03CFB089117B308C00935C1E /* OCMBlockCaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMBlockCaller.h; sourceTree = "<group>"; };
03CFB08A117B308C00935C1E /* OCMBlockCaller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMBlockCaller.m; sourceTree = "<group>"; };
03D65B47094CA23B00DF6687 /* Changes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Changes.txt; sourceTree = "<group>"; };
03D880530F8C75980087D071 /* OCObserverMockObjectTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCObserverMockObjectTest.h; sourceTree = "<group>"; };
03D880540F8C75980087D071 /* OCObserverMockObjectTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCObserverMockObjectTest.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -244,6 +248,8 @@
03C3672D100D6D0F00BE9731 /* OCMIndirectReturnValueProvider.m */,
03C36773100D744700BE9731 /* OCMNotificationPoster.h */,
03C36774100D744700BE9731 /* OCMNotificationPoster.m */,
03CFB089117B308C00935C1E /* OCMBlockCaller.h */,
03CFB08A117B308C00935C1E /* OCMBlockCaller.m */,
);
name = "Invocation Handler";
sourceTree = "<group>";
Expand Down Expand Up @@ -374,6 +380,7 @@
03C3672E100D6D0F00BE9731 /* OCMIndirectReturnValueProvider.h in Headers */,
03C36775100D744700BE9731 /* OCMNotificationPoster.h in Headers */,
03F1FE8A10353A5F00E4962C /* NSMethodSignature+OCMAdditions.h in Headers */,
03CFB08C117B308C00935C1E /* OCMBlockCaller.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -533,6 +540,7 @@
03C3672F100D6D0F00BE9731 /* OCMIndirectReturnValueProvider.m in Sources */,
03C36776100D744700BE9731 /* OCMNotificationPoster.m in Sources */,
03F1FE8B10353A5F00E4962C /* NSMethodSignature+OCMAdditions.m in Sources */,
03CFB08D117B308C00935C1E /* OCMBlockCaller.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
32 changes: 31 additions & 1 deletion Source/OCMockObjectTests.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------
// $Id$
// Copyright (c) 2004-2008 by Mulle Kybernetik. See License file for details.
// Copyright (c) 2004-2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import <OCMock/OCMock.h>
Expand Down Expand Up @@ -111,6 +111,17 @@ - (void)testAcceptsStubbedMethodWithConstraint
[mock hasSuffix:@"bar"];
}

#ifdef MAC_OS_X_VERSION_10_6

- (void)testAcceptsStubbedMethodWithBlockConstraint
{
[[mock stub] hasSuffix:[OCMArg checkWithBlock:^(id value) { return [value isEqualToString:@"foo"]; }]];

STAssertNoThrow([mock hasSuffix:@"foo"], @"Should not have thrown a exception");
STAssertThrows([mock hasSuffix:@"bar"], @"Should have thrown a exception");
}

#endif

- (void)testAcceptsStubbedMethodWithNilArgument
{
Expand Down Expand Up @@ -343,6 +354,25 @@ - (void)testCallsAlternativeMethodAndPassesOriginalArgumentsAndReturnsValue
STAssertEqualObjects(@"[FOO, 1]", returnValue, @"Should have passed and returned invocation.");
}

#ifdef MAC_OS_X_VERSION_10_6

- (void)testCallsBlockWhichCanSetUpReturnValue
{
void (^theBlock)(NSInvocation *) = ^(NSInvocation *invocation)
{
NSString *value;
[invocation getArgument:&value atIndex:2];
value = [NSString stringWithFormat:@"MOCK %@", value];
[invocation setReturnValue:&value];
};

[[[mock stub] andDo:theBlock] stringByAppendingString:[OCMArg any]];

STAssertEqualObjects(@"MOCK foo", [mock stringByAppendingString:@"foo"], @"Should have called block.");
STAssertEqualObjects(@"MOCK bar", [mock stringByAppendingString:@"bar"], @"Should have called block.");
}

#endif

// --------------------------------------------------------------------------------------
// returning values in pass-by-reference arguments
Expand Down
5 changes: 4 additions & 1 deletion Source/OCMockRecorder.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------
// $Id$
// Copyright (c) 2004-2009 by Mulle Kybernetik. See License file for details.
// Copyright (c) 2004-2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import <Foundation/Foundation.h>
Expand All @@ -22,6 +22,9 @@
- (id)andThrow:(NSException *)anException;
- (id)andPost:(NSNotification *)aNotification;
- (id)andCall:(SEL)selector onObject:(id)anObject;
#ifdef MAC_OS_X_VERSION_10_6
- (id)andDo:(void (^)(NSInvocation *))block;
#endif

- (NSArray *)invocationHandlers;

Expand Down
14 changes: 13 additions & 1 deletion Source/OCMockRecorder.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------
// $Id$
// Copyright (c) 2004-2009 by Mulle Kybernetik. See License file for details.
// Copyright (c) 2004-2010 by Mulle Kybernetik. See License file for details.
//---------------------------------------------------------------------------------------

#import <objc/runtime.h>
Expand All @@ -13,6 +13,7 @@
#import "OCMExceptionReturnValueProvider.h"
#import "OCMIndirectReturnValueProvider.h"
#import "OCMNotificationPoster.h"
#import "OCMBlockCaller.h"
#import "NSInvocation+OCMAdditions.h"

@interface NSObject(HCMatcherDummy)
Expand Down Expand Up @@ -84,6 +85,17 @@ - (id)andCall:(SEL)selector onObject:(id)anObject
return self;
}

#ifdef MAC_OS_X_VERSION_10_6

- (id)andDo:(void (^)(NSInvocation *))aBlock
{
[invocationHandlers addObject:[[[OCMBlockCaller alloc] initWithCallBlock:aBlock] autorelease]];
return self;
}

#endif


- (NSArray *)invocationHandlers
{
return invocationHandlers;
Expand Down

0 comments on commit 088f2e1

Please sign in to comment.