2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
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
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.
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
23 #include "JSBridgeTests.h"
28 //#import <Foundation/Foundation.h>
29 #import <NGJavaScript/NGJavaScript.h>
30 #import <NGScripting/NGScriptLanguage.h>
31 #import <NGExtensions/NGExtensions.h>
33 #define SLANG @"javascript"
35 @implementation JSBridgeTests
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"
46 NSString *testScript2 =
47 @"print('blah: ' + this);\n"
48 @"print(' s1: ' + this.sequence);\n"
49 @"print(' s2: ' + this.sequence);\n"
52 #define infoobj(__X__) [self printJavaScriptObjectInfo:__X__]
54 - (void)testCreation {
55 NSAutoreleasePool *pool;
60 pool = [[NSAutoreleasePool alloc] init];
62 global = [mapCtx globalObject];
63 [self print:@"global is 0x%08X %@", global, global];
65 jobj = [[Blah alloc] init];
66 [self print:@" blah: %@ -> j0x%08X", jobj, [mapCtx handleForObject:jobj]];
68 [self print:@" do: MyType()"];
69 result = [jobj evaluateScript:@"MyType()" language:SLANG];
70 [self print:@" => %@", result];
72 [self print:@" do: new MyType()"];
73 result = [jobj evaluateScript:@"new MyType()" language:SLANG];
74 [self print:@" => %@", result];
80 - (void)testKeyValueCoding {
81 NSString *testScript_KVC =
82 @"print('jso: ' + this);\n"
85 @"print('jso.a: ' + this.a);\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"
94 jobj = [[NGJavaScriptObject alloc] init];
96 [jobj setObject:@"202" forKey:@"c"];
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"]];
105 //[c evaluateScript:testScript language:SLANG];
110 - (void)testJSStructure {
111 static NSString *testScript_struct =
113 @" { 'a': 5, 'b': 10 },\n"
114 @" { 'a': 55, 'b': 105 },\n"
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"]];
128 - (void)testDictionary {
129 static NSString *testScript_dict =
134 NSAutoreleasePool *pool;
136 pool = [NSAutoreleasePool new];
138 jobj = [[NSMutableDictionary alloc] init];
140 [jobj setObject:@"202" forKey:@"c"];
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"]];
147 [[mapCtx jsContext] collectGarbage];
150 //[jobj evaluateScript:testScript language:SLANG];
152 [jobj release]; // Note: the dict may contain JS objects !
155 - (void)testSequence {
161 global = [mapCtx globalObject];
162 NSLog(@"global is 0x%08X %@", global, global);
164 blah = [[Blah alloc] init];
165 [global setObject:blah forKey:@"blah"];
167 jso = NGObjectMapping_GetHandleForObject(blah);
168 NSLog(@"obj o0x%08X j0x%08X", blah, jso);
170 for (i = 0; i < 3; i++) {
171 NSAutoreleasePool *pool;
173 pool = [[NSAutoreleasePool alloc] init];
175 [blah evaluateScript:testScript2 language:SLANG];
177 NSLog(@"release pool %i", i);
181 [[mapCtx jsContext] collectGarbage];
182 [[mapCtx jsContext] collectGarbage];
185 [global removeObjectForKey:@"blah"];
193 id obj = nil, jobj = nil;
196 c = [[Combined alloc] init];
197 [[NGObjectMappingContext activeObjectMappingContext] makeObjectCombined:c];
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];
205 jobj = [[NGJavaScriptObject alloc] init];
206 jso = NGObjectMapping_GetHandleForObject(jobj);
207 //NSLog(@"obj o0x%08X j0x%08X", jobj, jso);
210 [[NGObjectMappingContext activeObjectMappingContext]
211 setGlobalObject:jobj];
216 //[c setObject:obj forKey:@"blah2"];
218 //[c evaluateScript:testScript language:SLANG];
225 - (void)testStringPropAvailability {
227 if evaluation doesn't run against a NGJavaScriptObject, string objects
228 do not find their properties and functions (eg .length in this case)
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 ?
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
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 ?
252 base = [[Blah alloc] init];
253 NSLog(@"base: %@", base);
255 // this makes it dump core in getprivate
256 // NSLog(@"global: %@", [[self->mapCtx jsContext] globalObject]);
258 NSLog(@"this: %@", [base evaluateScript:@"this" language:SLANG]);
259 NSLog(@"typeof this: %@",
260 [base evaluateScript:@"typeof this" language:SLANG]);
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]);
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]);
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]);
287 [self runTest:@"IncTx"];
288 [self runTest:@"KeyValueCoding"];
289 [self runTest:@"Sequence"];
290 [self runTest:@"Creation"];
291 [self runTest:@"JSStructure"];
293 [self runTest:@"StringPropAvailability"];
295 // currently the Dictionary test makes it dump core
296 //[self runTest:@"Dictionary"];
299 @end /* JSBridgeTests */