Rename WebKitTools to Tools
[WebKit-https.git] / Tools / DumpRenderTree / mac / ObjCController.m
1 /*
2  * Copyright (C) 2007 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
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  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import "config.h"
30 #import "ObjCController.h"
31
32 // Avoid compile error in DOMPrivate.h.
33 @class NSFont;
34
35 #import <JavaScriptCore/JavaScriptCore.h>
36 #import <WebKit/DOMAbstractView.h>
37 #import <WebKit/DOMPrivate.h>
38 #import <WebKit/WebScriptObject.h>
39 #import <WebKit/WebView.h>
40 #import <pthread.h>
41 #import <wtf/Assertions.h>
42
43 // Remove this once hasWebScriptKey has been made public.
44 @interface WebScriptObject (StagedForPublic)
45 - (BOOL)hasWebScriptKey:(NSString *)name;
46 @end
47
48 static void* runJavaScriptThread(void* arg)
49 {
50     JSGlobalContextRef ctx = JSGlobalContextCreate(0);
51     JSStringRef scriptRef = JSStringCreateWithUTF8CString("'Hello World!'");
52
53     JSValueRef exception = 0;
54     JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception);
55     ASSERT(!exception);
56
57     JSGlobalContextRelease(ctx);
58     JSStringRelease(scriptRef);
59     
60     return 0;
61 }
62
63 @implementation ObjCController
64
65 + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
66 {
67     if (0
68             || aSelector == @selector(classNameOf:)
69             || aSelector == @selector(objectOfClass:)
70             || aSelector == @selector(arrayOfString)
71             || aSelector == @selector(identityIsEqual::)
72             || aSelector == @selector(longLongRoundTrip:)
73             || aSelector == @selector(unsignedLongLongRoundTrip:)
74             || aSelector == @selector(testWrapperRoundTripping:)
75             || aSelector == @selector(accessStoredWebScriptObject)
76             || aSelector == @selector(storeWebScriptObject:)
77             || aSelector == @selector(testValueForKey)
78             || aSelector == @selector(testHasWebScriptKey:)
79             || aSelector == @selector(testArray)
80             || aSelector == @selector(setSelectElement:selectedIndex:allowingMultiple:)
81         )
82         return NO;
83     return YES;
84 }
85
86 + (NSString *)webScriptNameForSelector:(SEL)aSelector
87 {
88     if (aSelector == @selector(classNameOf:))
89         return @"className";
90     if (aSelector == @selector(objectOfClass:))
91         return @"objectOfClass";
92     if (aSelector == @selector(arrayOfString))
93         return @"arrayOfString";
94     if (aSelector == @selector(identityIsEqual::))
95         return @"identityIsEqual";
96     if (aSelector == @selector(longLongRoundTrip:))
97         return @"longLongRoundTrip";
98     if (aSelector == @selector(unsignedLongLongRoundTrip:))
99         return @"unsignedLongLongRoundTrip";
100     if (aSelector == @selector(testWrapperRoundTripping:))
101         return @"testWrapperRoundTripping";
102     if (aSelector == @selector(storeWebScriptObject:))
103         return @"storeWebScriptObject";
104     if (aSelector == @selector(testValueForKey))
105         return @"testValueForKey";
106     if (aSelector == @selector(testHasWebScriptKey:))
107         return @"testHasWebScriptKey";
108     if (aSelector == @selector(testArray))
109         return @"testArray";
110     if (aSelector == @selector(setSelectElement:selectedIndex:allowingMultiple:))
111         return @"setSelectElementSelectedIndexAllowingMultiple";
112
113     return nil;
114 }
115
116 - (NSString *)classNameOf:(id)object
117 {
118     if (!object)
119         return @"nil";
120     return NSStringFromClass([object class]);
121 }
122
123 - (id)objectOfClass:(NSString *)aClass
124 {
125     if ([aClass isEqualToString:@"NSNull"])
126         return [NSNull null];
127     if ([aClass isEqualToString:@"WebUndefined"])
128         return [WebUndefined undefined];
129     if ([aClass isEqualToString:@"NSCFBoolean"])
130         return [NSNumber numberWithBool:true];
131     if ([aClass isEqualToString:@"NSCFNumber"])
132         return [NSNumber numberWithInt:1];
133     if ([aClass isEqualToString:@"NSCFString"])
134         return @"";
135     if ([aClass isEqualToString:@"WebScriptObject"])
136         return self;
137     if ([aClass isEqualToString:@"NSArray"])
138         return [NSArray array];
139
140     return nil;
141 }
142
143 - (NSArray *)arrayOfString
144 {
145     NSString *strings[3];
146     strings[0] = @"one";
147     strings[1] = @"two";
148     strings[2] = @"three";
149     NSArray *array = [NSArray arrayWithObjects:strings count:3];
150     return array;
151 }
152
153 - (BOOL)identityIsEqual:(WebScriptObject *)a :(WebScriptObject *)b
154 {
155     if ([a isKindOfClass:[NSString class]] && [b isKindOfClass:[NSString class]])
156         return [(NSString *)a isEqualToString:(NSString *)b];
157     return a == b;
158 }
159
160 - (long long)longLongRoundTrip:(long long)num
161 {
162     return num;
163 }
164
165 - (unsigned long long)unsignedLongLongRoundTrip:(unsigned long long)num
166 {
167     return num;
168 }
169
170 - (void)testValueForKey
171 {
172     ASSERT(storedWebScriptObject);
173     
174     @try {
175         [storedWebScriptObject valueForKey:@"ThisKeyDoesNotExist"];
176     } @catch (NSException *e) {
177     }
178
179     pthread_t pthread;
180     pthread_create(&pthread, 0, &runJavaScriptThread, 0);
181     pthread_join(pthread, 0);
182 }
183
184 - (BOOL)testHasWebScriptKey:(NSString *)key
185 {
186     ASSERT(storedWebScriptObject);
187     return [storedWebScriptObject hasWebScriptKey:key];
188 }
189
190 - (BOOL)testWrapperRoundTripping:(WebScriptObject *)webScriptObject
191 {
192     JSObjectRef jsObject = [webScriptObject JSObject];
193
194     if (!jsObject)
195         return false;
196
197     if (!webScriptObject)
198         return false;
199
200     if ([[webScriptObject evaluateWebScript:@"({ })"] class] != [webScriptObject class])
201         return false;
202
203     [webScriptObject setValue:[NSNumber numberWithInt:666] forKey:@"key"];
204     if (![[webScriptObject valueForKey:@"key"] isKindOfClass:[NSNumber class]] ||
205         ![[webScriptObject valueForKey:@"key"] isEqualToNumber:[NSNumber numberWithInt:666]])
206         return false;
207
208     [webScriptObject removeWebScriptKey:@"key"];
209     @try {
210         if ([webScriptObject valueForKey:@"key"])
211             return false;
212     } @catch(NSException *exception) {
213         // NSObject throws an exception if the key doesn't exist.
214     }
215
216     [webScriptObject setWebScriptValueAtIndex:0 value:webScriptObject];
217     if ([webScriptObject webScriptValueAtIndex:0] != webScriptObject)
218         return false;
219
220     if ([[webScriptObject stringRepresentation] isEqualToString:@"[Object object]"])
221         return false;
222
223     if ([webScriptObject callWebScriptMethod:@"returnThis" withArguments:nil] != webScriptObject)
224         return false;
225
226     return true;
227 }
228
229 - (void)accessStoredWebScriptObject
230 {
231 #if !ASSERT_DISABLED
232     BOOL isWindowObject = [storedWebScriptObject isKindOfClass:[DOMAbstractView class]];
233     JSObjectRef jsObject = [storedWebScriptObject JSObject];
234     ASSERT((jsObject && isWindowObject) || (!jsObject && !isWindowObject));
235 #endif
236     [storedWebScriptObject callWebScriptMethod:@"" withArguments:nil];
237     [storedWebScriptObject evaluateWebScript:@""];
238     [storedWebScriptObject setValue:[WebUndefined undefined] forKey:@"key"];
239     [storedWebScriptObject valueForKey:@"key"];
240     [storedWebScriptObject removeWebScriptKey:@"key"];
241     [storedWebScriptObject stringRepresentation];
242     [storedWebScriptObject webScriptValueAtIndex:0];
243     [storedWebScriptObject setWebScriptValueAtIndex:0 value:[WebUndefined undefined]];
244     [storedWebScriptObject setException:@"exception"];
245 }
246
247 - (void)storeWebScriptObject:(WebScriptObject *)webScriptObject
248 {
249     if (webScriptObject == storedWebScriptObject)
250         return;
251
252     [storedWebScriptObject release];
253     storedWebScriptObject = [webScriptObject retain];
254 }
255
256 - (NSArray *)testArray
257 {
258     return [NSArray array];
259 }
260
261 - (void)dealloc
262 {
263     [storedWebScriptObject release];
264     [super dealloc];
265 }
266
267 - (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args
268 {
269     // FIXME: Perhaps we should log that this has been called.
270     return nil;
271 }
272
273 #pragma mark -
274 #pragma mark Testing Objective-C DOM HTML Bindings
275
276 - (void)setSelectElement:(WebScriptObject *)element selectedIndex:(int)index allowingMultiple:(BOOL)allowingMultiple
277 {
278     if (![element isKindOfClass:[DOMHTMLSelectElement class]])
279         return;
280
281     DOMHTMLSelectElement *select = (DOMHTMLSelectElement*)element;
282     [select _activateItemAtIndex:index allowMultipleSelection:allowingMultiple];
283 }
284
285 @end