]> err.no Git - sope/blob - Recycler/NGJavaScript/tests/JSBridgeTests.m
added Kolab sample data
[sope] / Recycler / NGJavaScript / tests / JSBridgeTests.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include "JSBridgeTests.h"
24 #include "Combined.h"
25 #include "Blah.h"
26 #include "MyNum.h"
27 #include "common.h"
28 //#import <Foundation/Foundation.h>
29 #import <NGJavaScript/NGJavaScript.h>
30 #import <NGScripting/NGScriptLanguage.h>
31 #import <NGExtensions/NGExtensions.h>
32
33 #define SLANG @"javascript"
34
35 @implementation JSBridgeTests
36
37 NSString *testScript =
38 @"print('blah: ' + this.blah);\n"
39 @"print('blah: ' + this.blah);\n"
40 @"print('  s1: ' + this.blah.sequence);\n"
41 @"print('  s2: ' + this.blah.sequence);\n"
42 @"print('  s3: ' + this.blah.sequence);\n"
43 @"print('blah2:' + this.blah2);\n"
44 ;
45
46 NSString *testScript2 =
47 @"print('blah: ' + this);\n"
48 @"print('  s1: ' + this.sequence);\n"
49 @"print('  s2: ' + this.sequence);\n"
50 ;
51
52 #define infoobj(__X__) [self printJavaScriptObjectInfo:__X__]
53
54 - (void)testCreation {
55   NSAutoreleasePool *pool;
56   id jobj;
57   id result;
58   id global;
59   
60   pool = [[NSAutoreleasePool alloc] init];
61   
62   global = [mapCtx globalObject];
63   [self print:@"global is 0x%08X %@", global, global];
64   
65   jobj = [[Blah alloc] init];
66   [self print:@"  blah: %@ -> j0x%08X", jobj, [mapCtx handleForObject:jobj]];
67
68   [self print:@"  do: MyType()"];
69   result = [jobj evaluateScript:@"MyType()" language:SLANG];
70   [self print:@"  => %@", result];
71   
72   [self print:@"  do: new MyType()"];
73   result = [jobj evaluateScript:@"new MyType()" language:SLANG];
74   [self print:@"  => %@", result];
75   
76   [jobj release];
77   [pool release];
78 }
79
80 - (void)testKeyValueCoding {
81   NSString *testScript_KVC =
82   @"print('jso:  ' + this);\n"
83   @"var b = 10;\n"
84   @"this.a = 100;\n"
85   @"print('jso.a: ' + this.a);\n"
86   @"this['a'] = 101;\n"
87   @"print('jso.a: ' + this.a);\n"
88   @"print('jso.b: ' + this.b);\n"
89   @"print('jso.c: ' + this.c);\n"
90   @"for (var i in this.a) { print('  ' + i); };\n"
91   ;
92   id jobj = nil;
93   
94   jobj = [[NGJavaScriptObject alloc] init];
95   
96   [jobj setObject:@"202" forKey:@"c"];
97   
98   [jobj evaluateScript:testScript_KVC language:SLANG];
99   [self print:@"  obj.a=%@", [jobj objectForKey:@"a"]];
100   [self print:@"  obj.b=%@", [jobj objectForKey:@"b"]];
101   [self print:@"  obj.c=%@", [jobj objectForKey:@"c"]];
102   
103   infoobj(jobj);
104   
105   //[c evaluateScript:testScript language:SLANG];
106   
107   [jobj release];
108 }
109
110 - (void)testJSStructure {
111   static NSString *testScript_struct =
112     @"var dataRec = [\n"
113     @" { 'a': 5,  'b': 10  },\n"
114     @" { 'a': 55, 'b': 105 },\n"
115     @"];\n"
116   ;
117   id jobj;
118   jobj = [[NGJavaScriptObject alloc] init];
119   [jobj evaluateScript:testScript_struct language:SLANG];
120   [self print:@"  obj: %@", jobj];
121   [self print:@"  obj.dataRec: %@", [jobj objectForKey:@"dataRec"]];
122   [self print:@"  obj.dataRec[0]: %@", [[jobj objectForKey:@"dataRec"] objectAtIndex:0]];
123   [self print:@"  obj.dataRec[0].a: %@", 
124           [[[jobj objectForKey:@"dataRec"] objectAtIndex:0] objectForKey:@"a"]];
125   [jobj release];
126 }
127
128 - (void)testDictionary {
129   static NSString *testScript_dict =
130     @"this.a=10;"
131     @"this.b=101;"
132   ;
133   id jobj = nil;
134   NSAutoreleasePool *pool;
135   
136   pool = [NSAutoreleasePool new];
137
138   jobj = [[NSMutableDictionary alloc] init];
139   
140   [jobj setObject:@"202" forKey:@"c"];
141   
142   [jobj evaluateScript:testScript_dict language:SLANG];
143   [self print:@"  obj.a=%@", [jobj objectForKey:@"a"]];
144   [self print:@"  obj.b=%@", [jobj objectForKey:@"b"]];
145   [self print:@"  obj.c=%@", [jobj objectForKey:@"c"]];
146   
147   [[mapCtx jsContext] collectGarbage];
148   [pool release];
149   
150   //[jobj evaluateScript:testScript language:SLANG];
151   
152   [jobj release]; // Note: the dict may contain JS objects !
153 }
154
155 - (void)testSequence {
156   id   blah;
157   void *jso;
158   int  i;
159   id   global;
160   
161   global = [mapCtx globalObject];
162   NSLog(@"global is 0x%08X %@", global, global);
163   
164   blah = [[Blah alloc] init];
165   [global setObject:blah forKey:@"blah"];
166   
167   jso = NGObjectMapping_GetHandleForObject(blah);
168   NSLog(@"obj o0x%08X j0x%08X", blah, jso);
169
170   for (i = 0; i < 3; i++) {
171     NSAutoreleasePool *pool;
172
173     pool = [[NSAutoreleasePool alloc] init];
174     
175     [blah evaluateScript:testScript2 language:SLANG];
176
177     NSLog(@"release pool %i", i);
178     [pool release];
179     
180     NSLog(@"GC %i", i);
181     [[mapCtx jsContext] collectGarbage];
182     [[mapCtx jsContext] collectGarbage];
183   }
184   
185   [global removeObjectForKey:@"blah"];
186   
187   [blah release];
188 }
189
190 - (void)testIncTx {
191   Combined *c = nil;
192   void *jso;
193   id   obj = nil, jobj = nil;
194
195 #if 0
196   c = [[Combined alloc] init];
197   [[NGObjectMappingContext activeObjectMappingContext] makeObjectCombined:c];
198   
199   obj = [[Blah alloc] init];
200   jso = NGObjectMapping_GetHandleForObject(obj);
201   NSLog(@"obj o0x%08X j0x%08X", obj, jso);
202   [obj evaluateScript:testScript2 language:SLANG];
203 #endif
204   
205   jobj = [[NGJavaScriptObject alloc] init];
206   jso = NGObjectMapping_GetHandleForObject(jobj);
207   //NSLog(@"obj o0x%08X j0x%08X", jobj, jso);
208
209 #if 0
210   [[NGObjectMappingContext activeObjectMappingContext]
211                            setGlobalObject:jobj];
212 #endif
213   
214   infoobj(jobj);
215   
216   //[c setObject:obj forKey:@"blah2"];
217   
218   //[c evaluateScript:testScript language:SLANG];
219   
220   [jobj release];
221   [c    release];
222   [obj  release];
223 }
224
225 - (void)testStringPropAvailability {
226   /* 
227      if evaluation doesn't run against a NGJavaScriptObject, string objects
228      do not find their properties and functions (eg .length in this case)
229      why-o-why ? :-(
230      
231      - the NSString seems to be propertly converted into a JSString
232      - maybe the object doesn't have a proper parent pointer ?
233      - or the prototype of the string is broken ?
234      - or the standard classes are not loaded ?
235
236      - if I uncomment _jsGetValue in NSString+JS, I get a proper call to it's
237        length property, but the typeof (obviously) is 'object' instead of
238        'string' and certainly can't be used in a string context
239      
240      what sequence actually happens when we call "title.length" ?
241      - we map 'self' to a JS object (create a JS proxy, add statics)
242      - we call JS_EvaluateScript with that JS Object => makes self to this
243      - control goes to SpiderMoneky
244      - SpiderMonkey needs to resolve "title", which is a static
245        property we defined when creating the JS proxy
246      - this calls the _jsprop_title method which returns an NSString object
247      - the NSString object is converted to a value using it's own method
248      - SpiderMonkey should have a JS String with all methods ?
249   */
250   id base;
251   
252   base = [[Blah alloc] init];
253   NSLog(@"base: %@", base);
254
255   // this makes it dump core in getprivate
256   // NSLog(@"global: %@", [[self->mapCtx jsContext] globalObject]);
257   
258   NSLog(@"this: %@", [base evaluateScript:@"this" language:SLANG]);
259   NSLog(@"typeof this: %@", 
260         [base evaluateScript:@"typeof this" language:SLANG]);
261   
262   NSLog(@"title: %@",        
263         [base evaluateScript:@"title" language:SLANG]);
264   NSLog(@"typeof title: %@",        
265         [base evaluateScript:@"typeof title" language:SLANG]);
266   NSLog(@"title.length: %@ (should be %i)",        
267         [base evaluateScript:@"title.length" language:SLANG],
268         [[base _jsprop_title] length]);
269   
270   NSLog(@"getContent(): %@",        
271         [base evaluateScript:@"getContent()" language:SLANG]);
272   NSLog(@"getContent().length: %@ (should be %i)", 
273         [base evaluateScript:@"getContent().length" language:SLANG],
274         [[base _jsfunc_getContent:nil] length]);
275   
276   NSLog(@"'hello': %@",        
277         [base evaluateScript:@"'hello'" language:SLANG]);
278   NSLog(@"typeof 'hello': %@",        
279         [base evaluateScript:@"typeof 'hello'" language:SLANG]);
280   NSLog(@"'hello'.length: %@",        
281         [base evaluateScript:@"'hello'.length" language:SLANG]);
282   NSLog(@"'hello'.length == null: %@",        
283         [base evaluateScript:@"'hello'.length==null" language:SLANG]);
284 }
285
286 + (void)runSuite {
287   [self runTest:@"IncTx"];
288   [self runTest:@"KeyValueCoding"];
289   [self runTest:@"Sequence"];
290   [self runTest:@"Creation"];
291   [self runTest:@"JSStructure"];
292   
293   [self runTest:@"StringPropAvailability"];
294   
295   // currently the Dictionary test makes it dump core
296   //[self runTest:@"Dictionary"];
297 }
298
299 @end /* JSBridgeTests */