1
/** gsbehavior - Program to test GSObjCAddClassBehavior.
2
Copyright (C) 2003 Free Software Foundation, Inc.
4
Written by: David Ayers <d.ayers@inode.at>
6
This file is part of the GNUstep Base Library.
8
This library is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Library General Public
10
License as published by the Free Software Foundation; either
11
version 2 of the License, or (at your option) any later version.
13
This library is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
Library General Public License for more details.
18
You should have received a copy of the GNU Library General Public
19
License along with this library; if not, write to the Free
20
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
24
#include <Foundation/NSAutoreleasePool.h>
25
#include <Foundation/NSNotification.h>
26
#include <Foundation/NSException.h>
27
#include <Foundation/NSDebug.h>
29
#include <GNUstepBase/GSObjCRuntime.h>
31
/*------------------------------------*/
32
@interface MyClass : NSObject
34
-(const char *)textBase;
36
@implementation MyClass
37
-(void)myClassMain {};
42
-(const char *)textBase
44
return "class_main_base";
48
@interface MyClass (Category1)
49
-(void)myClassCategory1;
51
@implementation MyClass (Category1)
52
-(void)myClassCategory1 {};
55
return "class_category_1";
59
@interface MyClass (Category2)
60
-(void)myClassCategory2;
62
@implementation MyClass (Category2)
63
-(void)myClassCategory2 {};
66
return "class_category_2";
70
/*------------------------------------*/
72
@interface MyTemplate1 : NSObject
74
@implementation MyTemplate1
77
/*------------------------------------*/
78
/*------------------------------------*/
80
@interface MyTemplate2 : NSObject
83
@implementation MyTemplate2
86
return "template_main";
90
/*------------------------------------*/
92
@interface MyBehavior : NSObject
94
-(const char *)textBase;
96
@implementation MyBehavior
97
-(void)myBehaviorMain {};
100
return "behavior_main";
102
-(const char *)textBase
104
return "behavior_main_base";
107
@interface MyBehavior (Category1)
108
-(void)myBehaviorCategory1;
110
@implementation MyBehavior (Category1)
111
-(void)myBehaviorCategory1 {};
114
return "behavior_category_1";
118
@interface MyBehavior (Category2)
119
-(void)myBehaviorCategory2;
121
@implementation MyBehavior (Category2)
122
-(void)myBehaviorCategory2 {};
125
return "behavior_category_2";
129
/*------------------------------------*/
137
myClass = [MyClass new];
138
myBehavior = [MyBehavior new];
140
NSCAssert(strncmp([myClass text], "class_category", 14) == 0,
141
@"Default implementation isn't Category!");
142
NSCAssert(strncmp([myBehavior text], "behavior_category", 17) == 0,
143
@"Default implementation isn't Category!");
150
test_create_list(void)
163
myClass = [MyClass class];
164
myObj = [myClass new];
165
myList = GSMethodListForSelector(myClass, @selector(text), &it, YES);
166
NSCAssert(myList,@"List is NULL!");
167
myMethod = GSMethodFromList(myList, @selector(text), NO);
168
NSCAssert(myMethod,@"Method is NULL!");
169
imp_1 = myMethod->method_imp;
171
myList = GSMethodListForSelector(myClass, @selector(text), &it, YES);
172
NSCAssert(myList,@"List is NULL!");
173
myMethod = GSMethodFromList(myList, @selector(text), NO);
174
NSCAssert(myMethod,@"Method is NULL!");
175
imp_2 = myMethod->method_imp;
177
myList = GSMethodListForSelector(myClass, @selector(text), &it, YES);
178
NSCAssert(myList,@"List is NULL!");
179
myMethod = GSMethodFromList(myList, @selector(text), NO);
180
NSCAssert(myMethod,@"Method is NULL!");
181
imp_main = myMethod->method_imp;
183
types = myMethod->method_types;
185
myList = GSAllocMethodList(3);
186
GSAppendMethodToList(myList, @selector(text_main), types, imp_main, YES);
187
GSAppendMethodToList(myList, @selector(text_1), types, imp_1, YES);
188
GSAppendMethodToList(myList, @selector(text_2), types, imp_2, YES);
190
GSAddMethodList(myClass, myList, YES);
191
GSFlushMethodCacheForClass(myClass);
192
NSCAssert([myObj respondsToSelector:@selector(text_main)] == YES,
194
NSCAssert([myObj respondsToSelector:@selector(text_1)] == YES,
196
NSCAssert([myObj respondsToSelector:@selector(text_2)] == YES,
198
NSCAssert(strcmp([myObj text_main], "class_main") == 0,
199
@"Add failed to add correct implementation!");
200
NSCAssert(strncmp([myObj text_1], "class_category", 14) == 0,
201
@"Add failed to add correct implementation!");
202
NSCAssert(strncmp([myObj text_2], "class_category", 14) == 0,
203
@"Add failed to add correct implementation!");
208
test_reorder_list(void)
214
myClass = [MyClass class];
215
myObj = [MyClass new];
217
list = GSMethodListForSelector(myClass, @selector(myClassMain), 0, YES);
220
GSRemoveMethodList(myClass, list, YES);
221
GSFlushMethodCacheForClass(myClass);
222
NSCAssert([myObj respondsToSelector:@selector(myClassMain)] == NO,
226
GSAddMethodList(myClass, list, YES);
227
GSFlushMethodCacheForClass(myClass);
229
NSCAssert([myObj respondsToSelector:@selector(myClassMain)] == YES,
231
NSCAssert(strcmp([myObj text], "class_main") == 0,
232
@"Add failed to add correct implementation!");
238
test_exchange_method(void)
244
GSMethodList myListC;
245
GSMethodList myListB;
248
struct objc_method myMethodStructC;
249
struct objc_method myMethodStructB;
251
myClass = [MyClass class];
252
myBehavior = [MyBehavior class];
254
myClsObj = [myClass new];
255
myBhvObj = [myBehavior new];
257
NSCAssert(strcmp([myClsObj textBase], "class_main_base") == 0,
258
@"Wrong precondition!");
259
NSCAssert(strcmp([myBhvObj textBase], "behavior_main_base") == 0,
260
@"Wrong precondition!");
262
myListC = GSMethodListForSelector(myClass, @selector(textBase), 0, YES);
263
myListB = GSMethodListForSelector(myBehavior, @selector(textBase), 0, YES);
265
myMethodC = GSMethodFromList(myListC, @selector(textBase), NO);
266
myMethodStructC = *myMethodC;
267
myMethodC = &myMethodStructC;
268
myMethodB = GSMethodFromList(myListB, @selector(textBase), NO);
269
myMethodStructB = *myMethodB;
270
myMethodB = &myMethodStructB;
272
GSRemoveMethodFromList(myListC, @selector(textBase), NO);
273
GSRemoveMethodFromList(myListB, @selector(textBase), NO);
275
GSAppendMethodToList(myListC,
276
myMethodB->method_name,
277
myMethodB->method_types,
278
myMethodB->method_imp,
280
GSAppendMethodToList(myListB,
281
myMethodC->method_name,
282
myMethodC->method_types,
283
myMethodC->method_imp,
286
GSFlushMethodCacheForClass(myClass);
287
GSFlushMethodCacheForClass(myBehavior);
289
NSCAssert(strcmp([myClsObj textBase], "behavior_main_base") == 0,
290
@"Couldn't replace implementation!");
291
NSCAssert(strcmp([myBhvObj textBase], "class_main_base") == 0,
292
@"Couldn't replace implementation!");
302
myTmplClass = [MyTemplate1 class];
303
myTmplObj = [MyTemplate1 new];
305
NSCAssert([myTmplObj respondsToSelector:@selector(text)] == NO,
306
@"Initial state invalid");
307
GSObjCAddClassBehavior(myTmplClass, [MyClass class]);
308
NSCAssert([myTmplObj respondsToSelector:@selector(text)] == YES,
320
myTmplClass = [MyTemplate2 class];
321
myTmplObj = [MyTemplate2 new];
323
NSCAssert([myTmplObj respondsToSelector:@selector(myClassCategory1)] == NO,
324
@"Initial state invalid");
325
GSObjCAddClassBehavior(myTmplClass, [MyClass class]);
326
NSCAssert([myTmplObj respondsToSelector:@selector(myClassCategory1)] == YES,
329
NSCAssert(strcmp([myTmplObj text], "template_main") == 0,
330
@"Overwritten existing implementation!");
334
test_methodnames(void)
336
id obj = [NSNotificationCenter defaultCenter];
339
names = GSObjCMethodNames(obj);
340
NSDebugLog(@"obj:%@", names);
341
names = GSObjCMethodNames([obj class]);
342
NSDebugLog(@"class:%@", names);
346
main(int argc, char *argv[])
348
NSAutoreleasePool *pool;
349
// [NSAutoreleasePool enableDoubleReleaseCheck:YES];
350
pool = [[NSAutoreleasePool alloc] init];
358
test_exchange_method();
360
NSLog(@"Behavior Test Succeeded.");
364
NSLog(@"Behavior Test Failed:");
366
[localException name],
367
[localException reason],
368
[localException userInfo]);
369
[localException raise];