2  * Copyright (C) 2014 Apple Inc. All rights reserved. 
   4  * Redistribution and use in source and binary forms, with or without 
   5  * modification, are permitted provided that the following conditions 
   7  * 1. Redistributions of source code must retain the above copyright 
   8  *    notice, this list of conditions and the following disclaimer. 
   9  * 2. Redistributions in binary form must reproduce the above copyright 
  10  *    notice, this list of conditions and the following disclaimer in the 
  11  *    documentation and/or other materials provided with the distribution. 
  13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 
  14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR 
  17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
  20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
  21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  26 #include "CustomGlobalObjectClassTest.h" 
  28 #include <JavaScriptCore/JSObjectRefPrivate.h> 
  29 #include <JavaScriptCore/JavaScriptCore.h> 
  32 extern bool assertTrue(bool value
, const char* message
); 
  34 static bool executedCallback 
= false; 
  36 static JSValueRef 
jsDoSomething(JSContextRef ctx
, JSObjectRef function
, JSObjectRef thisObject
, size_t argc
, const JSValueRef args
[], JSValueRef
* exception
) 
  43     executedCallback 
= true; 
  44     return JSValueMakeNull(ctx
); 
  47 static JSStaticFunction bridgedFunctions
[] = { 
  48     {"doSomething", jsDoSomething
, kJSPropertyAttributeDontDelete
}, 
  52 static JSClassRef bridgedObjectClass 
= NULL
; 
  53 static JSClassDefinition bridgedClassDef
; 
  55 static JSClassRef 
jsClassRef() 
  57     if (!bridgedObjectClass
) { 
  58         bridgedClassDef 
= kJSClassDefinitionEmpty
; 
  59         bridgedClassDef
.className 
= "BridgedObject"; 
  60         bridgedClassDef
.staticFunctions 
= bridgedFunctions
; 
  61         bridgedObjectClass 
= JSClassCreate(&bridgedClassDef
); 
  63     return bridgedObjectClass
; 
  66 void customGlobalObjectClassTest() 
  68     JSClassRef bridgedObjectJsClassRef 
= jsClassRef(); 
  69     JSGlobalContextRef globalContext 
= JSGlobalContextCreate(bridgedObjectJsClassRef
); 
  71     JSObjectRef globalObj 
= JSContextGetGlobalObject(globalContext
); 
  73     JSPropertyNameArrayRef propertyNames 
= JSObjectCopyPropertyNames(globalContext
, globalObj
); 
  74     size_t propertyCount 
= JSPropertyNameArrayGetCount(propertyNames
); 
  75     assertTrue(propertyCount 
== 1, "Property count == 1"); 
  77     JSStringRef propertyNameRef 
= JSPropertyNameArrayGetNameAtIndex(propertyNames
, 0); 
  78     size_t propertyNameLength 
= JSStringGetLength(propertyNameRef
); 
  79     size_t bufferSize 
= sizeof(char) * (propertyNameLength 
+ 1); 
  80     char* buffer 
= (char*)malloc(bufferSize
); 
  81     JSStringGetUTF8CString(propertyNameRef
, buffer
, bufferSize
); 
  82     buffer
[propertyNameLength
] = '\0'; 
  83     assertTrue(!strncmp(buffer
, "doSomething", propertyNameLength
), "First property name is doSomething"); 
  86     bool hasMethod 
= JSObjectHasProperty(globalContext
, globalObj
, propertyNameRef
); 
  87     assertTrue(hasMethod
, "Property found by name"); 
  89     JSValueRef doSomethingProperty 
= 
  90     JSObjectGetProperty(globalContext
, globalObj
, propertyNameRef
, NULL
); 
  91     assertTrue(!JSValueIsUndefined(globalContext
, doSomethingProperty
), "Property is defined"); 
  93     bool globalObjectClassMatchesClassRef 
= JSValueIsObjectOfClass(globalContext
, globalObj
, bridgedObjectJsClassRef
); 
  94     assertTrue(globalObjectClassMatchesClassRef
, "Global object is the right class"); 
  96     JSStringRef script 
= JSStringCreateWithUTF8CString("doSomething();"); 
  97     JSEvaluateScript(globalContext
, script
, NULL
, NULL
, 1, NULL
); 
  98     JSStringRelease(script
); 
 100     assertTrue(executedCallback
, "Executed custom global object callback"); 
 103 void globalObjectSetPrototypeTest() 
 105     JSClassDefinition definition 
= kJSClassDefinitionEmpty
; 
 106     definition
.className 
= "Global"; 
 107     JSClassRef global 
= JSClassCreate(&definition
); 
 108     JSGlobalContextRef context 
= JSGlobalContextCreate(global
); 
 109     JSObjectRef object 
= JSContextGetGlobalObject(context
); 
 111     JSObjectRef above 
= JSObjectMake(context
, 0, 0); 
 112     JSStringRef test 
= JSStringCreateWithUTF8CString("test"); 
 113     JSValueRef value 
= JSValueMakeString(context
, test
); 
 114     JSObjectSetProperty(context
, above
, test
, value
, kJSPropertyAttributeDontEnum
, 0); 
 116     JSObjectSetPrototype(context
, object
, above
); 
 117     JSStringRef script 
= JSStringCreateWithUTF8CString("test === \"test\""); 
 118     JSValueRef result 
= JSEvaluateScript(context
, script
, 0, 0, 0, 0); 
 120     assertTrue(JSValueToBoolean(context
, result
), "test === \"test\""); 
 122     JSStringRelease(test
); 
 123     JSStringRelease(script
); 
 126 void globalObjectPrivatePropertyTest() 
 128     JSClassDefinition definition 
= kJSClassDefinitionEmpty
; 
 129     definition
.className 
= "Global"; 
 130     JSClassRef global 
= JSClassCreate(&definition
); 
 131     JSGlobalContextRef context 
= JSGlobalContextCreate(global
); 
 132     JSObjectRef globalObject 
= JSContextGetGlobalObject(context
); 
 134     JSStringRef privateName 
= JSStringCreateWithUTF8CString("private"); 
 135     JSValueRef privateValue 
= JSValueMakeString(context
, privateName
); 
 136     assertTrue(JSObjectSetPrivateProperty(context
, globalObject
, privateName
, privateValue
), "JSObjectSetPrivateProperty succeeded"); 
 137     JSValueRef result 
= JSObjectGetPrivateProperty(context
, globalObject
, privateName
); 
 138     assertTrue(JSValueIsStrictEqual(context
, privateValue
, result
), "privateValue === \"private\""); 
 140     assertTrue(JSObjectDeletePrivateProperty(context
, globalObject
, privateName
), "JSObjectDeletePrivateProperty succeeded"); 
 141     result 
= JSObjectGetPrivateProperty(context
, globalObject
, privateName
); 
 142     assertTrue(JSValueIsNull(context
, result
), "Deleted private property is indeed no longer present"); 
 144     JSStringRelease(privateName
);