~ubuntu-branches/ubuntu/karmic/gnustep-base/karmic

« back to all changes in this revision

Viewing changes to Testing/gsbehavior.m

  • Committer: Bazaar Package Importer
  • Author(s): Eric Heintzmann
  • Date: 2005-04-17 00:14:38 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050417001438-enf0y07c9tku85z1
Tags: 1.10.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** gsbehavior - Program to test GSObjCAddClassBehavior.
 
2
   Copyright (C) 2003 Free Software Foundation, Inc.
 
3
 
 
4
   Written by:  David Ayers  <d.ayers@inode.at>
 
5
 
 
6
   This file is part of the GNUstep Base Library.
 
7
 
 
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.
 
12
 
 
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.
 
17
 
 
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.
 
21
*/
 
22
 
 
23
 
 
24
#include <Foundation/NSAutoreleasePool.h>
 
25
#include <Foundation/NSNotification.h>
 
26
#include <Foundation/NSException.h>
 
27
#include <Foundation/NSDebug.h>
 
28
 
 
29
#include <GNUstepBase/GSObjCRuntime.h>
 
30
 
 
31
/*------------------------------------*/
 
32
@interface MyClass : NSObject
 
33
-(const char *)text;
 
34
-(const char *)textBase;
 
35
@end
 
36
@implementation MyClass
 
37
-(void)myClassMain {};
 
38
-(const char *)text
 
39
{
 
40
  return "class_main";
 
41
}
 
42
-(const char *)textBase
 
43
{
 
44
  return "class_main_base";
 
45
}
 
46
@end
 
47
 
 
48
@interface  MyClass (Category1)
 
49
-(void)myClassCategory1;
 
50
@end
 
51
@implementation MyClass (Category1)
 
52
-(void)myClassCategory1 {};
 
53
-(const char *)text
 
54
{
 
55
  return "class_category_1";
 
56
}
 
57
@end
 
58
 
 
59
@interface  MyClass (Category2)
 
60
-(void)myClassCategory2;
 
61
@end
 
62
@implementation MyClass (Category2)
 
63
-(void)myClassCategory2 {};
 
64
-(const char *)text
 
65
{
 
66
  return "class_category_2";
 
67
}
 
68
@end
 
69
 
 
70
/*------------------------------------*/
 
71
 
 
72
@interface MyTemplate1 : NSObject
 
73
@end
 
74
@implementation MyTemplate1
 
75
@end
 
76
 
 
77
/*------------------------------------*/
 
78
/*------------------------------------*/
 
79
 
 
80
@interface MyTemplate2 : NSObject
 
81
-(const char *)text;
 
82
@end
 
83
@implementation MyTemplate2
 
84
-(const char *)text
 
85
{
 
86
  return "template_main";
 
87
}
 
88
@end
 
89
 
 
90
/*------------------------------------*/
 
91
 
 
92
@interface MyBehavior : NSObject
 
93
-(const char *)text;
 
94
-(const char *)textBase;
 
95
@end
 
96
@implementation MyBehavior
 
97
-(void)myBehaviorMain {};
 
98
-(const char *)text
 
99
{
 
100
  return "behavior_main";
 
101
}
 
102
-(const char *)textBase
 
103
{
 
104
  return "behavior_main_base";
 
105
}
 
106
@end
 
107
@interface  MyBehavior (Category1)
 
108
-(void)myBehaviorCategory1;
 
109
@end
 
110
@implementation MyBehavior (Category1)
 
111
-(void)myBehaviorCategory1 {};
 
112
-(const char *)text
 
113
{
 
114
  return "behavior_category_1";
 
115
}
 
116
@end
 
117
 
 
118
@interface  MyBehavior (Category2)
 
119
-(void)myBehaviorCategory2;
 
120
@end
 
121
@implementation MyBehavior (Category2)
 
122
-(void)myBehaviorCategory2 {};
 
123
-(const char *)text
 
124
{
 
125
  return "behavior_category_2";
 
126
}
 
127
@end
 
128
 
 
129
/*------------------------------------*/
 
130
 
 
131
void
 
132
test_basic(void)
 
133
{
 
134
  id myClass;
 
135
  id myBehavior;
 
136
 
 
137
  myClass = [MyClass new];
 
138
  myBehavior = [MyBehavior new];
 
139
 
 
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!");
 
144
 
 
145
  RELEASE(myClass);
 
146
  RELEASE(myBehavior);
 
147
}
 
148
 
 
149
void
 
150
test_create_list(void)
 
151
{
 
152
  GSMethodList myList;
 
153
  GSMethod myMethod;
 
154
  Class myClass;
 
155
  void *it;
 
156
  IMP imp_main;
 
157
  IMP imp_1;
 
158
  IMP imp_2;
 
159
  const char *types;
 
160
  id myObj;
 
161
 
 
162
  it = 0;
 
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;
 
170
 
 
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;
 
176
 
 
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;
 
182
 
 
183
  types = myMethod->method_types;
 
184
 
 
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);
 
189
 
 
190
  GSAddMethodList(myClass, myList, YES);
 
191
  GSFlushMethodCacheForClass(myClass);
 
192
  NSCAssert([myObj respondsToSelector:@selector(text_main)] == YES,
 
193
            @"Add failed.");
 
194
  NSCAssert([myObj respondsToSelector:@selector(text_1)] == YES,
 
195
            @"Add failed.");
 
196
  NSCAssert([myObj respondsToSelector:@selector(text_2)] == YES,
 
197
            @"Add failed.");
 
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!");
 
204
 
 
205
}
 
206
 
 
207
void
 
208
test_reorder_list(void)
 
209
{
 
210
  Class myClass;
 
211
  id    myObj;
 
212
  GSMethodList list;
 
213
 
 
214
  myClass = [MyClass class];
 
215
  myObj = [MyClass new];
 
216
 
 
217
  list = GSMethodListForSelector(myClass, @selector(myClassMain), 0, YES);
 
218
 
 
219
  /* Remove */
 
220
  GSRemoveMethodList(myClass, list, YES);
 
221
  GSFlushMethodCacheForClass(myClass);
 
222
  NSCAssert([myObj respondsToSelector:@selector(myClassMain)] == NO,
 
223
            @"Remove failed.");
 
224
 
 
225
  /* Add */
 
226
  GSAddMethodList(myClass, list, YES);
 
227
  GSFlushMethodCacheForClass(myClass);
 
228
 
 
229
  NSCAssert([myObj respondsToSelector:@selector(myClassMain)] == YES,
 
230
            @"Add failed.");
 
231
  NSCAssert(strcmp([myObj text], "class_main") == 0,
 
232
            @"Add failed to add correct implementation!");
 
233
 
 
234
  RELEASE(myClass);
 
235
}
 
236
 
 
237
void
 
238
test_exchange_method(void)
 
239
{
 
240
  Class myClass;
 
241
  Class myBehavior;
 
242
  id myClsObj;
 
243
  id myBhvObj;
 
244
  GSMethodList myListC;
 
245
  GSMethodList myListB;
 
246
  GSMethod myMethodC;
 
247
  GSMethod myMethodB;
 
248
  struct objc_method myMethodStructC;
 
249
  struct objc_method myMethodStructB;
 
250
 
 
251
  myClass = [MyClass class];
 
252
  myBehavior = [MyBehavior class];
 
253
 
 
254
  myClsObj = [myClass new];
 
255
  myBhvObj = [myBehavior new];
 
256
 
 
257
  NSCAssert(strcmp([myClsObj textBase], "class_main_base") == 0,
 
258
            @"Wrong precondition!");
 
259
  NSCAssert(strcmp([myBhvObj textBase], "behavior_main_base") == 0,
 
260
            @"Wrong precondition!");
 
261
 
 
262
  myListC = GSMethodListForSelector(myClass, @selector(textBase), 0, YES);
 
263
  myListB = GSMethodListForSelector(myBehavior, @selector(textBase), 0, YES);
 
264
 
 
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;
 
271
 
 
272
  GSRemoveMethodFromList(myListC, @selector(textBase), NO);
 
273
  GSRemoveMethodFromList(myListB, @selector(textBase), NO);
 
274
 
 
275
  GSAppendMethodToList(myListC,
 
276
                       myMethodB->method_name,
 
277
                       myMethodB->method_types,
 
278
                       myMethodB->method_imp,
 
279
                       NO);
 
280
  GSAppendMethodToList(myListB,
 
281
                       myMethodC->method_name,
 
282
                       myMethodC->method_types,
 
283
                       myMethodC->method_imp,
 
284
                       NO);
 
285
 
 
286
  GSFlushMethodCacheForClass(myClass);
 
287
  GSFlushMethodCacheForClass(myBehavior);
 
288
 
 
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!");
 
293
 
 
294
}
 
295
 
 
296
void
 
297
test_behavior1(void)
 
298
{
 
299
  Class myTmplClass;
 
300
  id myTmplObj;
 
301
 
 
302
  myTmplClass = [MyTemplate1 class];
 
303
  myTmplObj = [MyTemplate1 new];
 
304
 
 
305
  NSCAssert([myTmplObj respondsToSelector:@selector(text)] == NO,
 
306
            @"Initial state invalid");
 
307
  GSObjCAddClassBehavior(myTmplClass, [MyClass class]);
 
308
  NSCAssert([myTmplObj respondsToSelector:@selector(text)] == YES,
 
309
            @"Behavior failed");
 
310
 
 
311
}
 
312
 
 
313
 
 
314
void
 
315
test_behavior2(void)
 
316
{
 
317
  Class myTmplClass;
 
318
  id myTmplObj;
 
319
 
 
320
  myTmplClass = [MyTemplate2 class];
 
321
  myTmplObj = [MyTemplate2 new];
 
322
 
 
323
  NSCAssert([myTmplObj respondsToSelector:@selector(myClassCategory1)] == NO,
 
324
            @"Initial state invalid");
 
325
  GSObjCAddClassBehavior(myTmplClass, [MyClass class]);
 
326
  NSCAssert([myTmplObj respondsToSelector:@selector(myClassCategory1)] == YES,
 
327
            @"Behavior failed");
 
328
 
 
329
  NSCAssert(strcmp([myTmplObj text], "template_main") == 0,
 
330
            @"Overwritten existing implementation!");
 
331
}
 
332
 
 
333
void
 
334
test_methodnames(void)
 
335
{
 
336
  id obj = [NSNotificationCenter defaultCenter];
 
337
  NSArray *names;
 
338
 
 
339
  names = GSObjCMethodNames(obj);
 
340
  NSDebugLog(@"obj:%@", names);
 
341
  names = GSObjCMethodNames([obj class]);
 
342
  NSDebugLog(@"class:%@", names);
 
343
}
 
344
 
 
345
int
 
346
main(int argc, char *argv[])
 
347
{
 
348
  NSAutoreleasePool *pool;
 
349
  //  [NSAutoreleasePool enableDoubleReleaseCheck:YES];
 
350
  pool = [[NSAutoreleasePool alloc] init];
 
351
 
 
352
  NS_DURING
 
353
    {
 
354
      test_methodnames();
 
355
      test_basic();
 
356
      test_create_list();
 
357
      test_reorder_list();
 
358
      test_exchange_method();
 
359
 
 
360
      NSLog(@"Behavior Test Succeeded.");
 
361
    }
 
362
  NS_HANDLER
 
363
    {
 
364
      NSLog(@"Behavior Test Failed:");
 
365
      NSLog(@"%@ %@ %@",
 
366
            [localException name],
 
367
            [localException reason],
 
368
            [localException userInfo]);
 
369
      [localException raise];
 
370
    }
 
371
  NS_ENDHANDLER
 
372
 
 
373
  [pool release];
 
374
 
 
375
  exit(0);
 
376
}
 
377