Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARC compliance and some fixes #491

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Classes/Core/KWFailure.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#pragma mark - Initializing

- (id)initWithCallSite:(KWCallSite *)aCallSite message:(NSString *)aMessage;
- (id)initWithCallSite:(KWCallSite *)aCallSite format:(NSString *)format, ...;

+ (id)failureWithCallSite:(KWCallSite *)aCallSite message:(NSString *)aMessage;
+ (id)failureWithCallSite:(KWCallSite *)aCallSite format:(NSString *)format, ...;
Expand Down
9 changes: 1 addition & 8 deletions Classes/Core/KWFailure.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@ - (id)initWithCallSite:(KWCallSite *)aCallSite message:(NSString *)aMessage {
return self;
}

- (id)initWithCallSite:(KWCallSite *)aCallSite format:(NSString *)format, ... {
va_list argumentList;
va_start(argumentList, format);
NSString *aMessage = [[NSString alloc] initWithFormat:format arguments:argumentList];
return [self initWithCallSite:aCallSite message:aMessage];
}

+ (id)failureWithCallSite:(KWCallSite *)aCallSite message:(NSString *)aMessage {
return [[self alloc] initWithCallSite:aCallSite message:aMessage];
}
Expand All @@ -37,7 +30,7 @@ + (id)failureWithCallSite:(KWCallSite *)aCallSite format:(NSString *)format, ...
va_list argumentList;
va_start(argumentList, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:argumentList];
return [self failureWithCallSite:aCallSite message:message];
return [[self alloc] initWithCallSite:aCallSite message:message];
}

#pragma mark - Getting Exception Representations
Expand Down
1 change: 0 additions & 1 deletion Classes/Core/KWInvocationCapturer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

#pragma mark - Initializing

- (id)initWithDelegate:(id)aDelegate;
- (id)initWithDelegate:(id)aDelegate userInfo:(NSDictionary *)aUserInfo;

+ (id)invocationCapturerWithDelegate:(id)aDelegate;
Expand Down
6 changes: 1 addition & 5 deletions Classes/Core/KWInvocationCapturer.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,14 @@ @implementation KWInvocationCapturer

#pragma mark - Initializing

- (id)initWithDelegate:(id)aDelegate {
return [self initWithDelegate:aDelegate userInfo:nil];
}

- (id)initWithDelegate:(id)aDelegate userInfo:(NSDictionary *)aUserInfo {
delegate = aDelegate;
userInfo = aUserInfo;
return self;
}

+ (id)invocationCapturerWithDelegate:(id)aDelegate {
return [self invocationCapturerWithDelegate:aDelegate userInfo:nil];
return [[self alloc] initWithDelegate:aDelegate userInfo:nil];
}

+ (id)invocationCapturerWithDelegate:(id)aDelegate userInfo:(NSDictionary *)aUserInfo {
Expand Down
4 changes: 2 additions & 2 deletions Classes/Core/NSObject+KiwiSpyAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ @implementation NSObject (KiwiSpyAdditions)

- (KWCaptureSpy *)captureArgument:(SEL)selector atIndex:(NSUInteger)index {
KWCaptureSpy *spy = [[KWCaptureSpy alloc] initWithArgumentIndex:index];
KWMessagePattern *pattern = [[KWMessagePattern alloc] initWithSelector:selector];
KWMessagePattern *pattern = [KWMessagePattern messagePatternWithSelector:selector];
[self addMessageSpy:spy forMessagePattern:pattern];
return spy;
}

+ (KWCaptureSpy *)captureArgument:(SEL)selector atIndex:(NSUInteger)index {
KWCaptureSpy *spy = [[KWCaptureSpy alloc] initWithArgumentIndex:index];
KWMessagePattern *pattern = [[KWMessagePattern alloc] initWithSelector:selector];
KWMessagePattern *pattern = [KWMessagePattern messagePatternWithSelector:selector];
[self addMessageSpy:spy forMessagePattern:pattern];
return spy;
}
Expand Down
16 changes: 16 additions & 0 deletions Classes/Core/NSString+KiwiAdditions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// NSString+KiwiAdditions.h
// Kiwi
//
// Created by Cristian Kocza on 02/04/14.
// Copyright (c) 2014 Allen Ding. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSString (KiwiAdditions)

//returns true if the selector name represented by the string belongs to the given family
- (BOOL)belongsToMethodFamily:(NSString*)family;

@end
33 changes: 33 additions & 0 deletions Classes/Core/NSString+KiwiAdditions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// NSString+KiwiAdditions.m
// Kiwi
//
// Created by Cristian Kocza on 02/04/14.
// Copyright (c) 2014 Allen Ding. All rights reserved.
//

#import "NSString+KiwiAdditions.h"

@implementation NSString (KiwiAdditions)

// Per http://clang.llvm.org/docs/AutomaticReferenceCounting.html#method-families
// A selector is in a certain selector family if, ignoring any leading underscores, the first component
// of the selector either consists entirely of the name of the method family or it begins with that name
// followed by a character other than a lowercase letter. For example, _perform:with: and performWith:
// would fall into the perform family (if we recognized one), but performing:with would not.
- (BOOL)belongsToMethodFamily:(NSString*)family{
NSUInteger pos = 0;
NSUInteger selfLen = self.length;
NSUInteger familyLen = family.length;
while([self characterAtIndex:pos] == '_' && pos < selfLen) pos++;
if(selfLen >= pos+familyLen && [[self substringWithRange:NSMakeRange(pos, familyLen)] isEqualToString:family]){
pos += familyLen;
if(pos == selfLen) return YES;
unichar c = [self characterAtIndex:pos];
return c < 'a' || c > 'z';
}else{
return NO;
}
}

@end
13 changes: 0 additions & 13 deletions Classes/Mocking/KWMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,6 @@

#pragma mark - Initializing

- (id)initForClass:(Class)aClass;
- (id)initForProtocol:(Protocol *)aProtocol;
- (id)initWithName:(NSString *)aName forClass:(Class)aClass;
- (id)initWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol;

- (id)initAsNullMockForClass:(Class)aClass;
- (id)initAsNullMockForProtocol:(Protocol *)aProtocol;
- (id)initAsNullMockWithName:(NSString *)aName forClass:(Class)aClass;
- (id)initAsNullMockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol;

- (id)initAsPartialMockForObject:(id)object;
- (id)initAsPartialMockWithName:(NSString *)aName forObject:(id)object;

+ (id)mockForClass:(Class)aClass;
+ (id)mockForProtocol:(Protocol *)aProtocol;
+ (id)mockWithName:(NSString *)aName forClass:(Class)aClass;
Expand Down
92 changes: 28 additions & 64 deletions Classes/Mocking/KWMock.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ @implementation KWMock
#pragma mark - Initializing

- (id)init {
self = [super init];
// May already have been initialized since stubbing -init is allowed!
if (self.stubs != nil) {
if (self && self.stubs != nil) {
KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd];
[self expectMessagePattern:messagePattern];
NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd];
Expand All @@ -49,108 +50,71 @@ - (id)init {
return self;
}
}

return [self initAsNullMock:NO withName:nil forClass:nil protocol:nil];
}

- (id)initForClass:(Class)aClass {
return [self initAsNullMock:NO withName:nil forClass:aClass protocol:nil];
}

- (id)initForProtocol:(Protocol *)aProtocol {
return [self initAsNullMock:NO withName:nil forClass:nil protocol:aProtocol];
}

- (id)initWithName:(NSString *)aName forClass:(Class)aClass {
return [self initAsNullMock:NO withName:aName forClass:aClass protocol:nil];
}

- (id)initWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol {
return [self initAsNullMock:NO withName:aName forClass:nil protocol:aProtocol];
}

- (id)initAsNullMockForClass:(Class)aClass {
return [self initAsNullMock:YES withName:nil forClass:aClass protocol:nil];
}

- (id)initAsNullMockForProtocol:(Protocol *)aProtocol {
return [self initAsNullMock:YES withName:nil forClass:nil protocol:aProtocol];
}

- (id)initAsNullMockWithName:(NSString *)aName forClass:(Class)aClass {
return [self initAsNullMock:YES withName:aName forClass:aClass protocol:nil];
}

- (id)initAsNullMockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol {
return [self initAsNullMock:YES withName:aName forClass:nil protocol:aProtocol];
[self setupAsNullMock:NO withName:nil forClass:nil protocol:nil];
return self;
}

- (id)initAsNullMock:(BOOL)nullMockFlag withName:(NSString *)aName forClass:(Class)aClass protocol:(Protocol *)aProtocol {
self = [super init];
if (self) {
_isNullMock = nullMockFlag;
_mockName = [aName copy];
_mockedClass = aClass;
_mockedProtocol = aProtocol;
_stubs = [[NSMutableArray alloc] init];
_expectedMessagePatterns = [[NSMutableArray alloc] init];
_messageSpies = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory valueOptions:NSMapTableStrongMemory];
[self setupAsNullMock:nullMockFlag withName:aName forClass:aClass protocol:aProtocol];
}

return self;
}

- (id)initAsPartialMockForObject:(id)object {
return [self initAsPartialMockWithName:nil forObject:object];
}

- (id)initAsPartialMockWithName:(NSString *)aName forObject:(id)object {
self = [self initAsNullMock:YES withName:aName forClass:[object class] protocol:nil];
if (self) {
_isPartialMock = YES;
_mockedObject = object;
}
return self;
- (void)setupAsNullMock:(BOOL)nullMockFlag withName:(NSString *)aName forClass:(Class)aClass protocol:(Protocol *)aProtocol {
_isNullMock = nullMockFlag;
_mockName = [aName copy];
_mockedClass = aClass;
_mockedProtocol = aProtocol;
_stubs = [[NSMutableArray alloc] init];
_expectedMessagePatterns = [[NSMutableArray alloc] init];
_messageSpies = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory valueOptions:NSMapTableStrongMemory];
}

+ (id)mockForClass:(Class)aClass {
return [[self alloc] initForClass:aClass];
return [[self alloc] initAsNullMock:NO withName:nil forClass:aClass protocol:nil];
}

+ (id)mockForProtocol:(Protocol *)aProtocol {
return [[self alloc] initForProtocol:aProtocol];
return [[self alloc] initAsNullMock:NO withName:nil forClass:nil protocol:aProtocol];
}

+ (id)mockWithName:(NSString *)aName forClass:(Class)aClass {
return [[self alloc] initWithName:aName forClass:aClass];
return [[self alloc] initAsNullMock:NO withName:aName forClass:aClass protocol:nil];
}

+ (id)mockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol {
return [[self alloc] initWithName:aName forProtocol:aProtocol];
return [[self alloc] initAsNullMock:NO withName:aName forClass:nil protocol:aProtocol];
}

+ (id)nullMockForClass:(Class)aClass {
return [[self alloc] initAsNullMockForClass:aClass];
return [[self alloc] initAsNullMock:YES withName:nil forClass:aClass protocol:nil];
}

+ (id)nullMockForProtocol:(Protocol *)aProtocol {
return [[self alloc] initAsNullMockForProtocol:aProtocol];
return [[self alloc] initAsNullMock:YES withName:nil forClass:nil protocol:aProtocol];
}

+ (id)nullMockWithName:(NSString *)aName forClass:(Class)aClass {
return [[self alloc] initAsNullMockWithName:aName forClass:aClass];
return [[self alloc] initAsNullMock:YES withName:aName forClass:aClass protocol:nil];
}

+ (id)nullMockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol {
return [[self alloc] initAsNullMockWithName:aName forProtocol:aProtocol];
return [[self alloc] initAsNullMock:YES withName:aName forClass:nil protocol:aProtocol];
}

+ (id)partialMockWithName:(NSString *)aName forObject:(id)object {
return [[self alloc] initAsPartialMockWithName:aName forObject:object];
KWMock *result = [[self alloc ] initAsNullMock:YES withName:aName forClass:[object class] protocol:nil];
if (result) {
result->_isPartialMock = YES;
result->_mockedObject = object;
}
return result;
}

+ (id)partialMockForObject:(id)object {
return [[self alloc] initAsPartialMockForObject:object];
return [self partialMockWithName:nil forObject:object];
}

#pragma mark - Getting Transitive Closure For Mocked Protocols
Expand Down
1 change: 0 additions & 1 deletion Classes/Stubbing/KWStub.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

#pragma mark - Initializing

- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern;
- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue;
- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern block:(id (^)(NSArray *params))aBlock;
- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue;
Expand Down
17 changes: 7 additions & 10 deletions Classes/Stubbing/KWStub.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "KWValue.h"

#import "NSInvocation+OCMAdditions.h"
#import "NSString+KiwiAdditions.h"

@interface KWStub(){}
@property (nonatomic, copy) id (^block)(NSArray *params);
Expand All @@ -20,10 +21,6 @@ @implementation KWStub

#pragma mark - Initializing

- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern {
return [self initWithMessagePattern:aMessagePattern value:nil];
}

- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue {
self = [super init];
if (self) {
Expand All @@ -37,7 +34,7 @@ - (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern block:(id (^)(N
self = [super init];
if (self) {
messagePattern = aMessagePattern;
_block = aBlock;
_block = [aBlock copy];
}
return self;
}
Expand All @@ -54,7 +51,7 @@ - (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValu
}

+ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern {
return [self stubWithMessagePattern:aMessagePattern value:nil];
return [[self alloc] initWithMessagePattern:aMessagePattern value:nil];
}

+ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue {
Expand Down Expand Up @@ -156,10 +153,10 @@ - (void)writeObjectValueToInvocationReturnValue:(NSInvocation *)anInvocation {
// To conform to memory management conventions, retain if writing a result
// that begins with alloc, new or contains copy. This shows up as a false
// positive in clang due to the runtime conditional, so ignore it.
if (KWStringHasWordPrefix(selectorString, @"alloc") ||
KWStringHasWordPrefix(selectorString, @"new") ||
KWStringHasWord(selectorString, @"copy") ||
KWStringHasWord(selectorString, @"Copy")) {
if ([selectorString belongsToMethodFamily:@"alloc"] ||
[selectorString belongsToMethodFamily:@"new"] ||
[selectorString belongsToMethodFamily:@"copy"] ||
[selectorString belongsToMethodFamily:@"mutableCopy"]) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also replaced the references to "Copy" by "mutableCopy".


// NOTE: this should be done in a better way.
// If you don't understand it, it's basically just a -performSelector: call
Expand Down
4 changes: 2 additions & 2 deletions Classes/Verifiers/KWMatchVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@

#pragma mark - Initializing

- (id)initForShouldWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter;
- (id)initForShouldNotWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter;
- (id)initWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter;

+ (id<KWVerifying>)matchVerifierForShouldWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter;
+ (id<KWVerifying>)matchVerifierForShouldNotWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter;
+ (id<KWVerifying>)matchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter;

- (void)verifyWithMatcher:(id<KWMatching>)aMatcher;
Expand Down
16 changes: 8 additions & 8 deletions Classes/Verifiers/KWMatchVerifier.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ @implementation KWMatchVerifier

#pragma mark - Initializing

- (id)initForShouldWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter {
return [self initWithExpectationType:KWExpectationTypeShould callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter];
}

- (id)initForShouldNotWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter {
return [self initWithExpectationType:KWExpectationTypeShouldNot callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter];
}

- (id)initWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter {
self = [super init];
if (self) {
Expand All @@ -55,6 +47,14 @@ - (id)initWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWC
return self;
}

+ (id<KWVerifying>)matchVerifierForShouldWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter {
return [[self alloc ] initWithExpectationType:KWExpectationTypeShould callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter];
}

+ (id<KWVerifying>)matchVerifierForShouldNotWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter {
return [[self alloc] initWithExpectationType:KWExpectationTypeShouldNot callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter];
}

+ (id<KWVerifying>)matchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id<KWReporting>)aReporter {
return [[self alloc] initWithExpectationType:anExpectationType callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter];
}
Expand Down
Loading