libs-base/Testing/gsbehavior.m
Richard Frith-MacDonald 62559023b9 Update to GPL3 and LGPL3
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25482 72102866-910b-0410-8b05-ffd578937521
2007-09-14 11:36:11 +00:00

377 lines
9.2 KiB
Objective-C

/** gsbehavior - Program to test GSObjCAddClassBehavior.
Copyright (C) 2003 Free Software Foundation, Inc.
Written by: David Ayers <d.ayers@inode.at>
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
*/
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSException.h>
#include <Foundation/NSDebug.h>
#include <GNUstepBase/GSObjCRuntime.h>
/*------------------------------------*/
@interface MyClass : NSObject
-(const char *)text;
-(const char *)textBase;
@end
@implementation MyClass
-(void)myClassMain {};
-(const char *)text
{
return "class_main";
}
-(const char *)textBase
{
return "class_main_base";
}
@end
@interface MyClass (Category1)
-(void)myClassCategory1;
@end
@implementation MyClass (Category1)
-(void)myClassCategory1 {};
-(const char *)text
{
return "class_category_1";
}
@end
@interface MyClass (Category2)
-(void)myClassCategory2;
@end
@implementation MyClass (Category2)
-(void)myClassCategory2 {};
-(const char *)text
{
return "class_category_2";
}
@end
/*------------------------------------*/
@interface MyTemplate1 : NSObject
@end
@implementation MyTemplate1
@end
/*------------------------------------*/
/*------------------------------------*/
@interface MyTemplate2 : NSObject
-(const char *)text;
@end
@implementation MyTemplate2
-(const char *)text
{
return "template_main";
}
@end
/*------------------------------------*/
@interface MyBehavior : NSObject
-(const char *)text;
-(const char *)textBase;
@end
@implementation MyBehavior
-(void)myBehaviorMain {};
-(const char *)text
{
return "behavior_main";
}
-(const char *)textBase
{
return "behavior_main_base";
}
@end
@interface MyBehavior (Category1)
-(void)myBehaviorCategory1;
@end
@implementation MyBehavior (Category1)
-(void)myBehaviorCategory1 {};
-(const char *)text
{
return "behavior_category_1";
}
@end
@interface MyBehavior (Category2)
-(void)myBehaviorCategory2;
@end
@implementation MyBehavior (Category2)
-(void)myBehaviorCategory2 {};
-(const char *)text
{
return "behavior_category_2";
}
@end
/*------------------------------------*/
void
test_basic(void)
{
id myClass;
id myBehavior;
myClass = [MyClass new];
myBehavior = [MyBehavior new];
NSCAssert(strncmp([myClass text], "class_category", 14) == 0,
@"Default implementation isn't Category!");
NSCAssert(strncmp([myBehavior text], "behavior_category", 17) == 0,
@"Default implementation isn't Category!");
RELEASE(myClass);
RELEASE(myBehavior);
}
void
test_create_list(void)
{
GSMethodList myList;
GSMethod myMethod;
Class myClass;
void *it;
IMP imp_main;
IMP imp_1;
IMP imp_2;
const char *types;
id myObj;
it = 0;
myClass = [MyClass class];
myObj = [myClass new];
myList = GSMethodListForSelector(myClass, @selector(text), &it, YES);
NSCAssert(myList,@"List is NULL!");
myMethod = GSMethodFromList(myList, @selector(text), NO);
NSCAssert(myMethod,@"Method is NULL!");
imp_1 = myMethod->method_imp;
myList = GSMethodListForSelector(myClass, @selector(text), &it, YES);
NSCAssert(myList,@"List is NULL!");
myMethod = GSMethodFromList(myList, @selector(text), NO);
NSCAssert(myMethod,@"Method is NULL!");
imp_2 = myMethod->method_imp;
myList = GSMethodListForSelector(myClass, @selector(text), &it, YES);
NSCAssert(myList,@"List is NULL!");
myMethod = GSMethodFromList(myList, @selector(text), NO);
NSCAssert(myMethod,@"Method is NULL!");
imp_main = myMethod->method_imp;
types = myMethod->method_types;
myList = GSAllocMethodList(3);
GSAppendMethodToList(myList, @selector(text_main), types, imp_main, YES);
GSAppendMethodToList(myList, @selector(text_1), types, imp_1, YES);
GSAppendMethodToList(myList, @selector(text_2), types, imp_2, YES);
GSAddMethodList(myClass, myList, YES);
GSFlushMethodCacheForClass(myClass);
NSCAssert([myObj respondsToSelector:@selector(text_main)] == YES,
@"Add failed.");
NSCAssert([myObj respondsToSelector:@selector(text_1)] == YES,
@"Add failed.");
NSCAssert([myObj respondsToSelector:@selector(text_2)] == YES,
@"Add failed.");
NSCAssert(strcmp([myObj text_main], "class_main") == 0,
@"Add failed to add correct implementation!");
NSCAssert(strncmp([myObj text_1], "class_category", 14) == 0,
@"Add failed to add correct implementation!");
NSCAssert(strncmp([myObj text_2], "class_category", 14) == 0,
@"Add failed to add correct implementation!");
}
void
test_reorder_list(void)
{
Class myClass;
id myObj;
GSMethodList list;
myClass = [MyClass class];
myObj = [MyClass new];
list = GSMethodListForSelector(myClass, @selector(myClassMain), 0, YES);
/* Remove */
GSRemoveMethodList(myClass, list, YES);
GSFlushMethodCacheForClass(myClass);
NSCAssert([myObj respondsToSelector:@selector(myClassMain)] == NO,
@"Remove failed.");
/* Add */
GSAddMethodList(myClass, list, YES);
GSFlushMethodCacheForClass(myClass);
NSCAssert([myObj respondsToSelector:@selector(myClassMain)] == YES,
@"Add failed.");
NSCAssert(strcmp([myObj text], "class_main") == 0,
@"Add failed to add correct implementation!");
RELEASE(myClass);
}
void
test_exchange_method(void)
{
Class myClass;
Class myBehavior;
id myClsObj;
id myBhvObj;
GSMethodList myListC;
GSMethodList myListB;
GSMethod myMethodC;
GSMethod myMethodB;
struct objc_method myMethodStructC;
struct objc_method myMethodStructB;
myClass = [MyClass class];
myBehavior = [MyBehavior class];
myClsObj = [myClass new];
myBhvObj = [myBehavior new];
NSCAssert(strcmp([myClsObj textBase], "class_main_base") == 0,
@"Wrong precondition!");
NSCAssert(strcmp([myBhvObj textBase], "behavior_main_base") == 0,
@"Wrong precondition!");
myListC = GSMethodListForSelector(myClass, @selector(textBase), 0, YES);
myListB = GSMethodListForSelector(myBehavior, @selector(textBase), 0, YES);
myMethodC = GSMethodFromList(myListC, @selector(textBase), NO);
myMethodStructC = *myMethodC;
myMethodC = &myMethodStructC;
myMethodB = GSMethodFromList(myListB, @selector(textBase), NO);
myMethodStructB = *myMethodB;
myMethodB = &myMethodStructB;
GSRemoveMethodFromList(myListC, @selector(textBase), NO);
GSRemoveMethodFromList(myListB, @selector(textBase), NO);
GSAppendMethodToList(myListC,
myMethodB->method_name,
myMethodB->method_types,
myMethodB->method_imp,
NO);
GSAppendMethodToList(myListB,
myMethodC->method_name,
myMethodC->method_types,
myMethodC->method_imp,
NO);
GSFlushMethodCacheForClass(myClass);
GSFlushMethodCacheForClass(myBehavior);
NSCAssert(strcmp([myClsObj textBase], "behavior_main_base") == 0,
@"Couldn't replace implementation!");
NSCAssert(strcmp([myBhvObj textBase], "class_main_base") == 0,
@"Couldn't replace implementation!");
}
void
test_behavior1(void)
{
Class myTmplClass;
id myTmplObj;
myTmplClass = [MyTemplate1 class];
myTmplObj = [MyTemplate1 new];
NSCAssert([myTmplObj respondsToSelector:@selector(text)] == NO,
@"Initial state invalid");
GSObjCAddClassBehavior(myTmplClass, [MyClass class]);
NSCAssert([myTmplObj respondsToSelector:@selector(text)] == YES,
@"Behavior failed");
}
void
test_behavior2(void)
{
Class myTmplClass;
id myTmplObj;
myTmplClass = [MyTemplate2 class];
myTmplObj = [MyTemplate2 new];
NSCAssert([myTmplObj respondsToSelector:@selector(myClassCategory1)] == NO,
@"Initial state invalid");
GSObjCAddClassBehavior(myTmplClass, [MyClass class]);
NSCAssert([myTmplObj respondsToSelector:@selector(myClassCategory1)] == YES,
@"Behavior failed");
NSCAssert(strcmp([myTmplObj text], "template_main") == 0,
@"Overwritten existing implementation!");
}
void
test_methodnames(void)
{
id obj = [NSNotificationCenter defaultCenter];
NSArray *names;
names = GSObjCMethodNames(obj);
NSDebugLog(@"obj:%@", names);
names = GSObjCMethodNames([obj class]);
NSDebugLog(@"class:%@", names);
}
int
main(int argc, char *argv[])
{
NSAutoreleasePool *pool;
// [NSAutoreleasePool enableDoubleReleaseCheck:YES];
pool = [[NSAutoreleasePool alloc] init];
NS_DURING
{
test_methodnames();
test_basic();
test_create_list();
test_reorder_list();
test_exchange_method();
NSLog(@"Behavior Test Succeeded.");
}
NS_HANDLER
{
NSLog(@"Behavior Test Failed:");
NSLog(@"%@ %@ %@",
[localException name],
[localException reason],
[localException userInfo]);
[localException raise];
}
NS_ENDHANDLER
[pool release];
exit(0);
}