source: webkit/trunk/JavaScriptCore/API/testapi.c@ 15376

Last change on this file since 15376 was 15376, checked in by ggaren, 19 years ago

Reviewed by Maciej.


  • Implemented a vast number of renames and comment clarifications suggested during API review.


JSInternalString -> JSString
JS*Make -> JSValueMake*, JSObjectMake*
JSTypeCode -> JSType
JSValueIsInstanceOf -> JSValueIsInstanceOfConstructor (reads strangely well in client code)
JSGC*Protect -> JSValue*Protect
JS*Callback -> JSObject*Callback
JSGetPropertyListCallback -> JSObjectAddPropertiesToListCallback
JSPropertyEnumeratorGetNext -> JSPropertyEnumeratorGetNextName
JSString* ->

JSStringCreateWithUTF8CString, JSStringGetUTF8CString,
JSStringGetMaximumUTF8CStringSize JSStringIsEqualToUTF8CString,
JSStringCreateWithCFString, JSStringCopyCFString, JSStringCreateWithCharacters.


  • Changed functions taking a JSValue out arg and returning a bool indicating whether it was set to simply return a JSValue or NULL.


  • Removed JSStringGetCharacters because it's more documentation than code, and it's just a glorified memcpy built on existing API functionality.


  • Moved standard library includes into the headers that actually require them.


  • Standardized use of the phrase "Create Rule."


  • Removed JSLock from make functions that don't allocate.


  • Added exception handling to JSValueToBoolean, since we now allow callback objects to throw exceptions upon converting to boolean.


  • Renamed JSGCCollect to JSGarbageCollect.
File size: 23.2 KB
Line 
1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "JavaScriptCore.h"
28#include <wtf/UnusedParam.h>
29
30#if defined(__APPLE__)
31#include <CoreFoundation/CoreFoundation.h>
32#endif
33
34#include <assert.h>
35#include <math.h>
36
37static JSContextRef context = 0;
38
39static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
40{
41 if (JSValueToBoolean(context, value) != expectedValue)
42 fprintf(stderr, "assertEqualsAsBoolean failed: %p, %d\n", value, expectedValue);
43}
44
45static void assertEqualsAsNumber(JSValueRef value, double expectedValue)
46{
47 double number = JSValueToNumber(context, value);
48 if (number != expectedValue && !(isnan(number) && isnan(expectedValue)))
49 fprintf(stderr, "assertEqualsAsNumber failed: %p, %lf\n", value, expectedValue);
50}
51
52static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue)
53{
54 JSStringRef valueAsString = JSValueToStringCopy(context, value);
55
56 size_t jsSize = JSStringGetMaximumUTF8CStringSize(valueAsString);
57 char jsBuffer[jsSize];
58 JSStringGetUTF8CString(valueAsString, jsBuffer, jsSize);
59
60 if (strcmp(jsBuffer, expectedValue) != 0)
61 fprintf(stderr, "assertEqualsAsUTF8String strcmp failed: %s != %s\n", jsBuffer, expectedValue);
62
63 if (jsSize < strlen(jsBuffer) + 1)
64 fprintf(stderr, "assertEqualsAsUTF8String failed: jsSize was too small\n");
65
66 JSStringRelease(valueAsString);
67}
68
69#if defined(__APPLE__)
70static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedValue)
71{
72 JSStringRef valueAsString = JSValueToStringCopy(context, value);
73
74 size_t jsLength = JSStringGetLength(valueAsString);
75 const JSChar* jsBuffer = JSStringGetCharactersPtr(valueAsString);
76
77 CFStringRef expectedValueAsCFString = CFStringCreateWithCString(kCFAllocatorDefault,
78 expectedValue,
79 kCFStringEncodingUTF8);
80 CFIndex cfLength = CFStringGetLength(expectedValueAsCFString);
81 UniChar cfBuffer[cfLength];
82 CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
83 CFRelease(expectedValueAsCFString);
84
85 if (memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) != 0)
86 fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsBuffer != cfBuffer\n");
87
88 if (jsLength != (size_t)cfLength)
89 fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%ld) != cfLength(%ld)\n", jsLength, cfLength);
90
91 JSStringRelease(valueAsString);
92}
93
94#endif // __APPLE__
95
96static JSValueRef jsGlobalValue; // non-stack value for testing JSValueProtect()
97
98/* MyObject pseudo-class */
99
100static bool didInitialize = false;
101static void MyObject_initialize(JSContextRef context, JSObjectRef object, JSValueRef* exception)
102{
103 UNUSED_PARAM(context);
104 UNUSED_PARAM(object);
105 didInitialize = true;
106}
107
108static bool MyObject_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
109{
110 UNUSED_PARAM(context);
111 UNUSED_PARAM(object);
112
113 if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")
114 || JSStringIsEqualToUTF8CString(propertyName, "cantFind")
115 || JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")) {
116 return true;
117 }
118
119 return false;
120}
121
122static JSValueRef MyObject_getProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
123{
124 UNUSED_PARAM(context);
125 UNUSED_PARAM(object);
126
127 if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")) {
128 return JSValueMakeNumber(1);
129 }
130
131 if (JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")) {
132 return JSValueMakeNumber(1);
133 }
134
135 if (JSStringIsEqualToUTF8CString(propertyName, "cantFind")) {
136 return JSValueMakeUndefined();
137 }
138
139 return NULL;
140}
141
142static bool MyObject_setProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
143{
144 UNUSED_PARAM(context);
145 UNUSED_PARAM(object);
146 UNUSED_PARAM(value);
147
148 if (JSStringIsEqualToUTF8CString(propertyName, "cantSet"))
149 return true; // pretend we set the property in order to swallow it
150
151 return false;
152}
153
154static bool MyObject_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
155{
156 UNUSED_PARAM(context);
157 UNUSED_PARAM(object);
158
159 if (JSStringIsEqualToUTF8CString(propertyName, "cantDelete"))
160 return true;
161
162 return false;
163}
164
165static void MyObject_getPropertyList(JSContextRef context, JSObjectRef object, JSPropertyListRef propertyList, JSValueRef* exception)
166{
167 UNUSED_PARAM(context);
168
169 JSStringRef propertyName;
170
171 propertyName = JSStringCreateWithUTF8CString("alwaysOne");
172 JSPropertyListAdd(propertyList, object, propertyName);
173 JSStringRelease(propertyName);
174
175 propertyName = JSStringCreateWithUTF8CString("myPropertyName");
176 JSPropertyListAdd(propertyList, object, propertyName);
177 JSStringRelease(propertyName);
178}
179
180static JSValueRef MyObject_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argc, JSValueRef argv[], JSValueRef* exception)
181{
182 UNUSED_PARAM(context);
183 UNUSED_PARAM(object);
184 UNUSED_PARAM(thisObject);
185
186 if (argc > 0 && JSValueIsStrictEqual(context, argv[0], JSValueMakeNumber(0)))
187 return JSValueMakeNumber(1);
188
189 return JSValueMakeUndefined();
190}
191
192static JSObjectRef MyObject_callAsConstructor(JSContextRef context, JSObjectRef object, size_t argc, JSValueRef argv[], JSValueRef* exception)
193{
194 UNUSED_PARAM(context);
195 UNUSED_PARAM(object);
196
197 if (argc > 0 && JSValueIsStrictEqual(context, argv[0], JSValueMakeNumber(0)))
198 return JSValueToObject(context, JSValueMakeNumber(1));
199
200 return JSValueToObject(context, JSValueMakeNumber(0));
201}
202
203static JSValueRef MyObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
204{
205 UNUSED_PARAM(context);
206 UNUSED_PARAM(object);
207
208 switch (type) {
209 case kJSTypeBoolean:
210 return JSValueMakeBoolean(false); // default object conversion is 'true'
211 case kJSTypeNumber:
212 return JSValueMakeNumber(1);
213 default:
214 break;
215 }
216
217 // string conversion -- forward to default object class
218 return NULL;
219}
220
221static bool didFinalize = false;
222static void MyObject_finalize(JSObjectRef object)
223{
224 UNUSED_PARAM(context);
225 UNUSED_PARAM(object);
226 didFinalize = true;
227}
228
229JSObjectCallbacks MyObject_callbacks = {
230 0,
231 &MyObject_initialize,
232 &MyObject_finalize,
233 &MyObject_hasProperty,
234 &MyObject_getProperty,
235 &MyObject_setProperty,
236 &MyObject_deleteProperty,
237 &MyObject_getPropertyList,
238 &MyObject_callAsFunction,
239 &MyObject_callAsConstructor,
240 &MyObject_convertToType,
241};
242
243static JSClassRef MyObject_class(JSContextRef context)
244{
245 static JSClassRef jsClass;
246 if (!jsClass) {
247 jsClass = JSClassCreate(NULL, NULL, &MyObject_callbacks, NULL);
248 }
249
250 return jsClass;
251}
252
253static JSValueRef print_callAsFunction(JSContextRef context, JSObjectRef functionObject, JSObjectRef thisObject, size_t argc, JSValueRef argv[], JSValueRef* exception)
254{
255 UNUSED_PARAM(functionObject);
256 UNUSED_PARAM(thisObject);
257
258 if (argc > 0) {
259 JSStringRef string = JSValueToStringCopy(context, argv[0]);
260 size_t sizeUTF8 = JSStringGetMaximumUTF8CStringSize(string);
261 char stringUTF8[sizeUTF8];
262 JSStringGetUTF8CString(string, stringUTF8, sizeUTF8);
263 printf("%s\n", stringUTF8);
264 JSStringRelease(string);
265 }
266
267 return JSValueMakeUndefined();
268}
269
270static JSObjectRef myConstructor_callAsConstructor(JSContextRef context, JSObjectRef constructorObject, size_t argc, JSValueRef argv[], JSValueRef* exception)
271{
272 UNUSED_PARAM(constructorObject);
273
274 JSObjectRef result = JSObjectMake(context, NULL, 0);
275 if (argc > 0) {
276 JSStringRef value = JSStringCreateWithUTF8CString("value");
277 JSObjectSetProperty(context, result, value, argv[0], kJSPropertyAttributeNone);
278 JSStringRelease(value);
279 }
280
281 return result;
282}
283
284static char* createStringWithContentsOfFile(const char* fileName);
285
286int main(int argc, char* argv[])
287{
288 UNUSED_PARAM(argc);
289 UNUSED_PARAM(argv);
290
291 context = JSContextCreate(NULL);
292
293 JSValueRef jsUndefined = JSValueMakeUndefined();
294 JSValueRef jsNull = JSValueMakeNull();
295 JSValueRef jsTrue = JSValueMakeBoolean(true);
296 JSValueRef jsFalse = JSValueMakeBoolean(false);
297 JSValueRef jsZero = JSValueMakeNumber(0);
298 JSValueRef jsOne = JSValueMakeNumber(1);
299 JSValueRef jsOneThird = JSValueMakeNumber(1.0 / 3.0);
300 JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, JSValueMakeNull());
301
302 // FIXME: test funny utf8 characters
303 JSStringRef jsEmptyIString = JSStringCreateWithUTF8CString("");
304 JSValueRef jsEmptyString = JSValueMakeString(jsEmptyIString);
305
306 JSStringRef jsOneIString = JSStringCreateWithUTF8CString("1");
307 JSValueRef jsOneString = JSValueMakeString(jsOneIString);
308
309#if defined(__APPLE__)
310 UniChar singleUniChar = 65; // Capital A
311 CFMutableStringRef cfString =
312 CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault,
313 &singleUniChar,
314 1,
315 1,
316 kCFAllocatorNull);
317
318 JSStringRef jsCFIString = JSStringCreateWithCFString(cfString);
319 JSValueRef jsCFString = JSValueMakeString(jsCFIString);
320
321 CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8);
322
323 JSStringRef jsCFEmptyIString = JSStringCreateWithCFString(cfEmptyString);
324 JSValueRef jsCFEmptyString = JSValueMakeString(jsCFEmptyIString);
325
326 CFIndex cfStringLength = CFStringGetLength(cfString);
327 UniChar buffer[cfStringLength];
328 CFStringGetCharacters(cfString,
329 CFRangeMake(0, cfStringLength),
330 buffer);
331 JSStringRef jsCFIStringWithCharacters = JSStringCreateWithCharacters(buffer, cfStringLength);
332 JSValueRef jsCFStringWithCharacters = JSValueMakeString(jsCFIStringWithCharacters);
333
334 JSStringRef jsCFEmptyIStringWithCharacters = JSStringCreateWithCharacters(buffer, CFStringGetLength(cfEmptyString));
335 JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(jsCFEmptyIStringWithCharacters);
336#endif // __APPLE__
337
338 assert(JSValueGetType(jsUndefined) == kJSTypeUndefined);
339 assert(JSValueGetType(jsNull) == kJSTypeNull);
340 assert(JSValueGetType(jsTrue) == kJSTypeBoolean);
341 assert(JSValueGetType(jsFalse) == kJSTypeBoolean);
342 assert(JSValueGetType(jsZero) == kJSTypeNumber);
343 assert(JSValueGetType(jsOne) == kJSTypeNumber);
344 assert(JSValueGetType(jsOneThird) == kJSTypeNumber);
345 assert(JSValueGetType(jsEmptyString) == kJSTypeString);
346 assert(JSValueGetType(jsOneString) == kJSTypeString);
347#if defined(__APPLE__)
348 assert(JSValueGetType(jsCFString) == kJSTypeString);
349 assert(JSValueGetType(jsCFStringWithCharacters) == kJSTypeString);
350 assert(JSValueGetType(jsCFEmptyString) == kJSTypeString);
351 assert(JSValueGetType(jsCFEmptyStringWithCharacters) == kJSTypeString);
352#endif // __APPLE__
353
354 // Conversions that throw exceptions
355 assert(NULL == JSValueToObject(context, jsNull));
356 assert(isnan(JSValueToNumber(context, jsObjectNoProto)));
357 assertEqualsAsCharactersPtr(jsObjectNoProto, "");
358
359 assertEqualsAsBoolean(jsUndefined, false);
360 assertEqualsAsBoolean(jsNull, false);
361 assertEqualsAsBoolean(jsTrue, true);
362 assertEqualsAsBoolean(jsFalse, false);
363 assertEqualsAsBoolean(jsZero, false);
364 assertEqualsAsBoolean(jsOne, true);
365 assertEqualsAsBoolean(jsOneThird, true);
366 assertEqualsAsBoolean(jsEmptyString, false);
367 assertEqualsAsBoolean(jsOneString, true);
368#if defined(__APPLE__)
369 assertEqualsAsBoolean(jsCFString, true);
370 assertEqualsAsBoolean(jsCFStringWithCharacters, true);
371 assertEqualsAsBoolean(jsCFEmptyString, false);
372 assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false);
373#endif // __APPLE__
374
375 assertEqualsAsNumber(jsUndefined, nan(""));
376 assertEqualsAsNumber(jsNull, 0);
377 assertEqualsAsNumber(jsTrue, 1);
378 assertEqualsAsNumber(jsFalse, 0);
379 assertEqualsAsNumber(jsZero, 0);
380 assertEqualsAsNumber(jsOne, 1);
381 assertEqualsAsNumber(jsOneThird, 1.0 / 3.0);
382 assertEqualsAsNumber(jsEmptyString, 0);
383 assertEqualsAsNumber(jsOneString, 1);
384#if defined(__APPLE__)
385 assertEqualsAsNumber(jsCFString, nan(""));
386 assertEqualsAsNumber(jsCFStringWithCharacters, nan(""));
387 assertEqualsAsNumber(jsCFEmptyString, 0);
388 assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0);
389 assert(sizeof(JSChar) == sizeof(UniChar));
390#endif // __APPLE__
391
392 assertEqualsAsCharactersPtr(jsUndefined, "undefined");
393 assertEqualsAsCharactersPtr(jsNull, "null");
394 assertEqualsAsCharactersPtr(jsTrue, "true");
395 assertEqualsAsCharactersPtr(jsFalse, "false");
396 assertEqualsAsCharactersPtr(jsZero, "0");
397 assertEqualsAsCharactersPtr(jsOne, "1");
398 assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333");
399 assertEqualsAsCharactersPtr(jsEmptyString, "");
400 assertEqualsAsCharactersPtr(jsOneString, "1");
401#if defined(__APPLE__)
402 assertEqualsAsCharactersPtr(jsCFString, "A");
403 assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A");
404 assertEqualsAsCharactersPtr(jsCFEmptyString, "");
405 assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, "");
406#endif // __APPLE__
407
408 assertEqualsAsUTF8String(jsUndefined, "undefined");
409 assertEqualsAsUTF8String(jsNull, "null");
410 assertEqualsAsUTF8String(jsTrue, "true");
411 assertEqualsAsUTF8String(jsFalse, "false");
412 assertEqualsAsUTF8String(jsZero, "0");
413 assertEqualsAsUTF8String(jsOne, "1");
414 assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333");
415 assertEqualsAsUTF8String(jsEmptyString, "");
416 assertEqualsAsUTF8String(jsOneString, "1");
417#if defined(__APPLE__)
418 assertEqualsAsUTF8String(jsCFString, "A");
419 assertEqualsAsUTF8String(jsCFStringWithCharacters, "A");
420 assertEqualsAsUTF8String(jsCFEmptyString, "");
421 assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, "");
422#endif // __APPLE__
423
424 assert(JSValueIsStrictEqual(context, jsTrue, jsTrue));
425 assert(!JSValueIsStrictEqual(context, jsOne, jsOneString));
426
427 assert(JSValueIsEqual(context, jsOne, jsOneString));
428 assert(!JSValueIsEqual(context, jsTrue, jsFalse));
429
430#if defined(__APPLE__)
431 CFStringRef cfJSString = JSStringCopyCFString(kCFAllocatorDefault, jsCFIString);
432 CFStringRef cfJSEmptyString = JSStringCopyCFString(kCFAllocatorDefault, jsCFEmptyIString);
433 assert(CFEqual(cfJSString, cfString));
434 assert(CFEqual(cfJSEmptyString, cfEmptyString));
435 CFRelease(cfJSString);
436 CFRelease(cfJSEmptyString);
437
438 CFRelease(cfString);
439 CFRelease(cfEmptyString);
440#endif // __APPLE__
441
442 jsGlobalValue = JSObjectMake(context, NULL, NULL);
443 JSValueProtect(jsGlobalValue);
444 JSGarbageCollect();
445 assert(JSValueIsObject(jsGlobalValue));
446 JSValueUnprotect(jsGlobalValue);
447
448 /* JSInterpreter.h */
449
450 JSObjectRef globalObject = JSContextGetGlobalObject(context);
451 assert(JSValueIsObject(globalObject));
452
453 JSStringRef goodSyntax = JSStringCreateWithUTF8CString("x = 1;");
454 JSStringRef badSyntax = JSStringCreateWithUTF8CString("x := 1;");
455 assert(JSCheckSyntax(context, goodSyntax, NULL, 0, NULL));
456 assert(!JSCheckSyntax(context, badSyntax, NULL, 0, NULL));
457
458 JSValueRef result;
459 JSValueRef exception;
460 JSValueRef v;
461 JSObjectRef o;
462
463 result = JSEvaluate(context, goodSyntax, NULL, NULL, 1, NULL);
464 assert(result);
465 assert(JSValueIsEqual(context, result, jsOne));
466
467 exception = NULL;
468 result = JSEvaluate(context, badSyntax, NULL, NULL, 1, &exception);
469 assert(!result);
470 assert(JSValueIsObject(exception));
471
472 JSStringRef array = JSStringCreateWithUTF8CString("Array");
473 v = JSObjectGetProperty(context, globalObject, array);
474 assert(v);
475 JSObjectRef arrayConstructor = JSValueToObject(context, v);
476 JSStringRelease(array);
477 result = JSObjectCallAsConstructor(context, arrayConstructor, 0, NULL, NULL);
478 assert(result);
479 assert(JSValueIsInstanceOfConstructor(context, result, arrayConstructor));
480 assert(!JSValueIsInstanceOfConstructor(context, JSValueMakeNull(), arrayConstructor));
481
482 JSStringRef functionBody;
483
484 exception = NULL;
485 functionBody = JSStringCreateWithUTF8CString("rreturn Array;");
486 JSStringRef line = JSStringCreateWithUTF8CString("line");
487 assert(!JSObjectMakeFunctionWithBody(context, functionBody, NULL, 1, &exception));
488 assert(JSValueIsObject(exception));
489 v = JSObjectGetProperty(context, JSValueToObject(context, exception), line);
490 assert(v);
491 assertEqualsAsNumber(v, 2); // FIXME: Lexer::setCode bumps startingLineNumber by 1 -- we need to change internal callers so that it doesn't have to (saying '0' to mean '1' in the API would be really confusing -- it's really confusing internally, in fact)
492 JSStringRelease(functionBody);
493 JSStringRelease(line);
494
495 functionBody = JSStringCreateWithUTF8CString("return Array;");
496 JSObjectRef function = JSObjectMakeFunctionWithBody(context, functionBody, NULL, 1, NULL);
497 JSStringRelease(functionBody);
498
499 assert(JSObjectIsFunction(function));
500 v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
501 assert(JSValueIsEqual(context, v, arrayConstructor));
502
503 JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);
504 assert(didInitialize);
505 JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject");
506 JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone);
507 JSStringRelease(myObjectIString);
508
509 JSStringRef print = JSStringCreateWithUTF8CString("print");
510 JSObjectRef printFunction = JSObjectMakeFunction(context, print_callAsFunction);
511 JSObjectSetProperty(context, globalObject, print, printFunction, kJSPropertyAttributeNone);
512 JSStringRelease(print);
513
514 assert(JSObjectSetPrivate(printFunction, (void*)1));
515 assert(JSObjectGetPrivate(printFunction) == (void*)1);
516
517 JSStringRef myConstructorIString = JSStringCreateWithUTF8CString("MyConstructor");
518 JSObjectRef myConstructor = JSObjectMakeConstructor(context, myConstructor_callAsConstructor);
519 JSObjectSetProperty(context, globalObject, myConstructorIString, myConstructor, kJSPropertyAttributeNone);
520 JSStringRelease(myConstructorIString);
521
522 assert(JSObjectSetPrivate(myConstructor, (void*)1));
523 assert(JSObjectGetPrivate(myConstructor) == (void*)1);
524
525 o = JSObjectMake(context, NULL, NULL);
526 JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(1), kJSPropertyAttributeNone);
527 JSObjectSetProperty(context, o, jsCFIString, JSValueMakeNumber(1), kJSPropertyAttributeDontEnum);
528 JSPropertyEnumeratorRef enumerator = JSObjectCreatePropertyEnumerator(context, o);
529 int count = 0;
530 while (JSPropertyEnumeratorGetNextName(enumerator))
531 ++count;
532 JSPropertyEnumeratorRelease(enumerator);
533 assert(count == 1); // jsCFString should not be enumerated
534
535 JSClassRef nullCallbacksClass = JSClassCreate(NULL, NULL, NULL, NULL);
536 JSClassRelease(nullCallbacksClass);
537
538 functionBody = JSStringCreateWithUTF8CString("return this;");
539 function = JSObjectMakeFunctionWithBody(context, functionBody, NULL, 1, NULL);
540 JSStringRelease(functionBody);
541 v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
542 assert(JSValueIsEqual(context, v, globalObject));
543 v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
544 assert(JSValueIsEqual(context, v, o));
545
546 char* scriptUTF8 = createStringWithContentsOfFile("testapi.js");
547 JSStringRef script = JSStringCreateWithUTF8CString(scriptUTF8);
548 result = JSEvaluate(context, script, NULL, NULL, 1, &exception);
549 if (JSValueIsUndefined(result))
550 printf("PASS: Test script executed successfully.\n");
551 else {
552 printf("FAIL: Test script returned unexcpected value:\n");
553 JSStringRef exceptionIString = JSValueToStringCopy(context, exception);
554 CFStringRef exceptionCF = JSStringCopyCFString(kCFAllocatorDefault, exceptionIString);
555 CFShow(exceptionCF);
556 CFRelease(exceptionCF);
557 JSStringRelease(exceptionIString);
558 }
559 JSStringRelease(script);
560 free(scriptUTF8);
561
562 // Allocate a few dummies so that at least one will be collected
563 JSObjectMake(context, MyObject_class(context), 0);
564 JSObjectMake(context, MyObject_class(context), 0);
565 JSGarbageCollect();
566 assert(didFinalize);
567
568 JSStringRelease(jsEmptyIString);
569 JSStringRelease(jsOneIString);
570#if defined(__APPLE__)
571 JSStringRelease(jsCFIString);
572 JSStringRelease(jsCFEmptyIString);
573 JSStringRelease(jsCFIStringWithCharacters);
574 JSStringRelease(jsCFEmptyIStringWithCharacters);
575#endif // __APPLE__
576 JSStringRelease(goodSyntax);
577 JSStringRelease(badSyntax);
578
579 JSContextDestroy(context);
580 printf("PASS: Program exited normally.\n");
581 return 0;
582}
583
584static char* createStringWithContentsOfFile(const char* fileName)
585{
586 char* buffer;
587
588 int buffer_size = 0;
589 int buffer_capacity = 1024;
590 buffer = (char*)malloc(buffer_capacity);
591
592 FILE* f = fopen(fileName, "r");
593 if (!f) {
594 fprintf(stderr, "Could not open file: %s\n", fileName);
595 return 0;
596 }
597
598 while (!feof(f) && !ferror(f)) {
599 buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
600 if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
601 buffer_capacity *= 2;
602 buffer = (char*)realloc(buffer, buffer_capacity);
603 assert(buffer);
604 }
605
606 assert(buffer_size < buffer_capacity);
607 }
608 fclose(f);
609 buffer[buffer_size] = '\0';
610
611 return buffer;
612}
Note: See TracBrowser for help on using the repository browser.