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
);