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

Add unit tests for GSFFIInvocation #466

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
Empty file.
117 changes: 117 additions & 0 deletions Tests/base/GSFFIInvocation/basic.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#import <Foundation/Foundation.h>
#import "Testing.h"
#import "ObjectTesting.h"

@protocol NSMenuItem <NSObject>
- (NSString*) keyEquivalent;
- (void) setKeyEquivalent: (NSString*)aKeyEquivalent;
@end

@interface NSMenuItem : NSObject <NSMenuItem>
{
NSString *_keyEquivalent;
}
@end

@implementation NSMenuItem
- (void) setKeyEquivalent: (NSString*)aKeyEquivalent
{
ASSIGNCOPY(_keyEquivalent, aKeyEquivalent);
}

- (NSString*) keyEquivalent
{
return _keyEquivalent;
}
@end

@interface GSFakeNSMenuItem : NSObject
{
NSMenuItem* _originalItem;
}

- (id) initWithItem: (NSMenuItem*)item;
- (NSMenuItem*) originalItem;
- (id) target;
- (SEL)action;
- (void) action: (id)sender;
@end

@implementation GSFakeNSMenuItem
- (id) initWithItem: (NSMenuItem*)item
{
self = [super init];
if (self)
{
_originalItem = item;
}
return self;
}

- (NSMenuItem*) originalItem
{
return _originalItem;
}

- (id)target
{
return self;
}

- (SEL)action
{
return @selector(action:);
}

- (id)forwardingTargetForSelector:(SEL)selector
{
if ([_originalItem respondsToSelector:selector])
return _originalItem;
return nil;
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
SEL selector = [invocation selector];

// Forward any invocation to the original item if it supports it...
if ([_originalItem respondsToSelector:selector])
[invocation invokeWithTarget:_originalItem];
else
[super forwardInvocation:invocation];
}
Copy link
Member

Choose a reason for hiding this comment

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

In the else case you should call the super implementation, to make sure we end up in -doesNotRecognizeSelector:. This won't change the problem, just document the correct way to implement this method.


-(NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature *signature = [[_originalItem class] instanceMethodSignatureForSelector:selector];
if(signature == nil)
{
signature = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
}
return(signature);
}

- (void)doesNotRecognizeSelector:(SEL)selector
{
NSLog(@"%s:selector not recognized: %@", __PRETTY_FUNCTION__, NSStringFromSelector(selector));
}
@end

int main(int argc,char **argv)
{
START_SET("GSFFIInvocation")

NSMenuItem *item = [NSMenuItem alloc];
[item setKeyEquivalent:@"Hello, World!"];

GSFakeNSMenuItem *fakeItem = [[GSFakeNSMenuItem alloc] initWithItem:item];

NSString *itemKeyEquivalent = [item keyEquivalent];
NSString *fakeItemKeyEquivalent = [fakeItem keyEquivalent];

PASS_EQUAL(itemKeyEquivalent, fakeItemKeyEquivalent, "keyEquivalent selector is forwarded from the fake item to the actual item");
NSLog(@"Item key equivalent: %@, fake item key equivalent: %@", itemKeyEquivalent, fakeItemKeyEquivalent);

END_SET("GSFFIInvocation")
return 0;
}
68 changes: 68 additions & 0 deletions Tests/base/GSFFIInvocation/forwardInvocation.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#import <Foundation/Foundation.h>
#import "Testing.h"
#import "ObjectTesting.h"

@interface GSFakeNSString : NSObject
{
NSString* _originalItem;
}

- (id) initWithItem: (NSString*)item;
- (NSString*) originalItem;
@end

@implementation GSFakeNSString
- (id) initWithItem: (NSString*)item
{
self = [super init];
if (self)
{
_originalItem = item;
}
return self;
}

- (NSString*) originalItem
{
return _originalItem;
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
SEL selector = [invocation selector];

// Forward any invocation to the original item if it supports it...
if ([_originalItem respondsToSelector:selector])
[invocation invokeWithTarget:_originalItem];
else
[super forwardInvocation:invocation];
}

-(NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature *signature = [[_originalItem class] instanceMethodSignatureForSelector:selector];
if(signature == nil)
{
signature = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
}
return(signature);
}
@end

int main(int argc,char **argv)
{
START_SET("GSFFIInvocation")

NSString *string = @"Hello, World!";

GSFakeNSString *fakeString = [[GSFakeNSString alloc] initWithItem:string];

NSString *upperCaseString = [string uppercaseString];
NSString *fakeUpperCaseString = [fakeString uppercaseString];

NSLog(@"Upper case string: %@, fake upper case string: %@", upperCaseString, fakeUpperCaseString);
PASS_EQUAL(upperCaseString, fakeUpperCaseString, "uppercaseString selector is forwarded from the fake string to the actual NSString object");

END_SET("GSFFIInvocation")
return 0;
}
55 changes: 55 additions & 0 deletions Tests/base/GSFFIInvocation/forwardingTargetForSelector.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#import <Foundation/Foundation.h>
#import "Testing.h"
#import "ObjectTesting.h"

@interface GSFakeNSString : NSObject
{
NSString* _originalItem;
}

- (id) initWithItem: (NSString*)item;
- (NSString*) originalItem;
@end

@implementation GSFakeNSString
- (id) initWithItem: (NSString*)item
{
self = [super init];
if (self)
{
_originalItem = item;
}
return self;
}

- (NSString*) originalItem
{
return _originalItem;
}

- (id)forwardingTargetForSelector:(SEL)selector
{
if ([_originalItem respondsToSelector:selector])
return _originalItem;
return nil;
}

@end

int main(int argc,char **argv)
{
START_SET("GSFFIInvocation")

NSString *string = @"Hello, World!";

GSFakeNSString *fakeString = [[GSFakeNSString alloc] initWithItem:string];

NSString *upperCaseString = [string uppercaseString];
NSString *fakeUpperCaseString = [fakeString uppercaseString];

NSLog(@"Upper case string: %@, fake upper case string: %@", upperCaseString, fakeUpperCaseString);
PASS_EQUAL(upperCaseString, fakeUpperCaseString, "uppercaseString selector is forwarded from the fake string to the actual NSString object");

END_SET("GSFFIInvocation")
return 0;
}
Loading