1#import "Testing.h"
2#import <Foundation/NSAutoreleasePool.h>
3#import <Foundation/NSBundle.h>
4#import <Foundation/NSException.h>
5#import <Foundation/NSFileManager.h>
6#import <Foundation/NSInvocation.h>
7#import <Foundation/NSMethodSignature.h>
8#import <Foundation/NSObject.h>
9#import <Foundation/NSProxy.h>
10#import <Foundation/NSString.h>
11#import <Foundation/NSGeometry.h>
12#import "InvokeProxyProtocol.h"
13
14/* these macros should only be used in the scope of main */
15#define TEST_INVOKE(selx) \
16  { \
17    NS_DURING \
18      NSMethodSignature *sig = nil; \
19      sig = [tar methodSignatureForSelector:selx]; \
20      inv = [NSInvocation invocationWithMethodSignature:sig]; \
21      [inv setSelector:selx]; \
22      [inv invokeWithTarget:tar]; \
23      PASS(1,"Invoke %s",[NSStringFromSelector(selx) UTF8String]); \
24    NS_HANDLER \
25      PASS(0,"Invoke %s",[NSStringFromSelector(selx) UTF8String]); \
26      [localException raise]; \
27    NS_ENDHANDLER \
28  }
29
30#define TEST_INVOKE_ARG(selx,argp) \
31  { \
32    NS_DURING \
33      NSMethodSignature *sig = nil; \
34      sig = [tar methodSignatureForSelector:selx]; \
35      inv = [NSInvocation invocationWithMethodSignature:sig]; \
36      [inv setSelector:selx]; \
37      [inv setArgument:argp atIndex:2]; \
38      [inv invokeWithTarget:tar]; \
39      PASS(1,"Invoke %s",[NSStringFromSelector(selx) UTF8String]); \
40    NS_HANDLER \
41      PASS(0,"Invoke %s",[NSStringFromSelector(selx) UTF8String]); \
42      [localException raise]; \
43    NS_ENDHANDLER \
44  }
45
46int main()
47{
48  NSAutoreleasePool   *arp = [NSAutoreleasePool new];
49  NSInvocation *inv = nil;
50  NSObject <InvokeTarget>*tar;
51  NSObject <InvokeProxy,InvokeTarget>*pxy;
52  char cret,carg;
53  short sret,sarg;
54  int iret,iarg;
55  long lret,larg;
56  float fret,farg;
57  double dret,darg;
58  NSRect rret, rarg, rprx;
59  id oret,oarg;
60  char *cpret,*cparg,*cparg2;
61  smallStruct ssret,ssarg;
62  largeStruct lsret,lsarg;
63  Class tClass = Nil;
64  Class pClass = Nil;
65  NSString *bundlePath;
66  NSBundle *bundle;
67
68  bundlePath = [[[NSFileManager defaultManager]
69                              currentDirectoryPath]
70			       stringByAppendingPathComponent:@"Resources"];
71  bundlePath = [[NSBundle bundleWithPath:bundlePath]
72                  pathForResource:@"InvokeProxy"
73	                   ofType:@"bundle"];
74  bundle = [NSBundle bundleWithPath:bundlePath];
75  PASS([bundle load],
76       "loading resources from bundle");
77  tClass = NSClassFromString(@"InvokeTarget");
78  pClass = NSClassFromString(@"InvokeProxy");
79
80
81  tar = [tClass new];
82  pxy = [[pClass alloc] initWithTarget:tar];
83  TEST_INVOKE(@selector(retChar));
84  [inv getReturnValue:&cret];
85  PASS(cret == 99 &&
86       [pxy retChar] == 99,
87       "Can return chars");
88
89  TEST_INVOKE(@selector(retShort));
90  [inv getReturnValue:&sret];
91  PASS(sret == 12345 &&
92       [pxy retShort] == 12345,
93       "Can return short");
94
95  TEST_INVOKE(@selector(retInt));
96  [inv getReturnValue:&iret];
97  PASS(iret == 123456 &&
98       [pxy retInt] == 123456,
99       "Can return int");
100
101  TEST_INVOKE(@selector(retLong));
102  [inv getReturnValue:&lret];
103  PASS(lret == 123456 &&
104       [pxy retLong] == 123456,
105       "Can return long");
106
107  TEST_INVOKE(@selector(retFloat));
108  [inv getReturnValue:&fret];
109  PASS(fabs(123.456 - fret) <= 0.001 &&
110       fabs(123.456 - [pxy retFloat]) <= 0.001,
111       "Can return float");
112
113  TEST_INVOKE(@selector(retDouble));
114  [inv getReturnValue:&dret];
115  PASS(fabs(123.456 - dret) <= 0.001 &&
116       fabs(123.456 - [pxy retDouble]) <= 0.001,
117       "Can return double");
118
119  TEST_INVOKE(@selector(retObject));
120  [inv getReturnValue:&oret];
121  PASS(oret == tar &&
122       tar == [pxy retObject],
123       "Can return object");
124
125  carg = 1;
126  TEST_INVOKE_ARG(@selector(loopChar:),&carg);
127  [inv getReturnValue:&cret];
128  PASS(cret == 2 &&
129       2 == [pxy loopChar:carg],
130       "Can send/return chars");
131
132  sarg = 1;
133  TEST_INVOKE_ARG(@selector(loopShort:),&sarg);
134  [inv getReturnValue:&sret];
135  PASS(sret == 2 &&
136       [pxy loopShort:sarg] == 2,
137       "Can send/return shorts");
138
139  iarg = 1;
140  TEST_INVOKE_ARG(@selector(loopInt:),&iarg);
141  [inv getReturnValue:&iret];
142  PASS(iret == 2 &&
143       [pxy loopInt:iarg] == 2,
144       "Can send/return ints");
145
146  larg = 1;
147  TEST_INVOKE_ARG(@selector(loopLong:),&larg);
148  [inv getReturnValue:&lret];
149  PASS(lret == 2 &&
150       [pxy loopLong:larg] == 2,
151       "Can send/return longs");
152
153  farg = 1;
154  TEST_INVOKE_ARG(@selector(loopFloat:),&farg);
155  [inv getReturnValue:&fret];
156  PASS(fabs(2 - fret) <= 0.001 &&
157       fabs(2 - [pxy loopFloat:farg]) <= 0.001,
158       "Can send/return floats");
159
160  darg = 1;
161  TEST_INVOKE_ARG(@selector(loopDouble:),&darg);
162  [inv getReturnValue:&dret];
163  PASS(fabs(2 - dret) <= 0.001 &&
164       fabs(2 - [pxy loopFloat:darg]) <= 0.001,
165       "Can send/return double");
166
167  oarg = pxy;
168  TEST_INVOKE_ARG(@selector(loopObject:),&oarg);
169  [inv getReturnValue:&oret];
170  PASS(oret == pxy &&
171       [pxy loopObject:oarg] == pxy,
172       "Can send/return objects");
173
174  /* unlinke the rest of these loopString: modifies its arg */
175  cparg = malloc(sizeof("Hello There"));
176  strcpy(cparg,"Hello There");
177  cparg2 = malloc(sizeof("Hello There"));
178  strcpy(cparg2,"Hello There");
179
180  TEST_INVOKE_ARG(@selector(loopString:),&cparg);
181  [inv getReturnValue:&cpret];
182  PASS(strcmp(cpret,"Iello There") == 0 &&
183       strcmp([pxy loopString:cparg2],"Iello There") == 0,
184       "Can send/return char *");
185
186  ssarg.c = 7;
187  ssarg.i = 9;
188  TEST_INVOKE_ARG(@selector(loopSmall:),&ssarg);
189  [inv getReturnValue:&ssret];
190  PASS(ssret.c == 7 && ssret.i == 10,
191       "Can send/return small structs");
192
193  lsarg.i = 8;
194  lsarg.s = "Hello";
195  lsarg.f = 11.0;
196  TEST_INVOKE_ARG(@selector(loopLarge:),&lsarg);
197  [inv getReturnValue:&lsret];
198  PASS(lsret.i == 9 &&
199       strcmp(lsret.s, "Hello") == 0 &&
200       lsret.f == 11.0,
201       "Can send/return large structs");
202
203  rarg = NSMakeRect(1,2,3,4);
204  TEST_INVOKE_ARG(@selector(loopRect:),&rarg);
205  [inv getReturnValue:&rret];
206  rprx = [pxy loopRect:rarg];
207  PASS(NSEqualRects(rret, rarg) && NSEqualRects(rprx, rarg),
208       "Can send/return NSRect");
209
210  [arp release]; arp = nil;
211  return 0;
212}
213