1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
46 #define BEGINTEST() bool _testPassed = true;
47 #define ENDTEST() return _testPassed;
49 #define VERIFY(expr) { \
51 fprintf(stderr, "FAIL: %s:%d %s\n", __FILE__, __LINE__, # expr); \
52 _testPassed = false; \
57 struct MyStringResource : public String::ExternalAsciiStringResource
59 static bool wasDestroyed;
60 virtual ~MyStringResource() { wasDestroyed = true; }
61 virtual const char* data() const { return "v8test"; }
62 virtual size_t length() const { return 6; }
64 bool MyStringResource::wasDestroyed = false;
66 struct MyResource : public Object::ExternalResource
68 static bool wasDestroyed;
69 virtual ~MyResource() { wasDestroyed = true; }
71 bool MyResource::wasDestroyed = false;
73 bool v8test_externalteardown()
77 Isolate *isolate = v8::Isolate::New();
81 HandleScope handle_scope;
82 Persistent<Context> context = Context::New();
83 Context::Scope context_scope(context);
85 Local<String> str = String::NewExternal(new MyStringResource);
87 Local<FunctionTemplate> ft = FunctionTemplate::New();
88 ft->InstanceTemplate()->SetHasExternalResource(true);
90 Local<Object> obj = ft->GetFunction()->NewInstance();
91 obj->SetExternalResource(new MyResource);
96 // while (!v8::V8::IdleNotification()) ;
100 // ExternalString resources aren't guaranteed to be freed by v8 at this
101 // point. Uncommenting the IdleNotification() line above helps.
102 // VERIFY(MyStringResource::wasDestroyed);
104 VERIFY(MyResource::wasDestroyed);
115 HandleScope handle_scope;
116 Persistent<Context> context = Context::New();
117 Context::Scope context_scope(context);
119 Local<Object> qmlglobal = Object::New();
120 qmlglobal->Set(String::New("a"), Integer::New(1922));
122 Local<Script> script = Script::Compile(String::New("eval(\"a\")"), NULL, NULL,
123 Handle<String>(), Script::QmlMode);
126 Local<Value> result = script->Run(qmlglobal);
128 VERIFY(!tc.HasCaught());
129 VERIFY(result->Int32Value() == 1922);
137 bool v8test_globalcall()
141 HandleScope handle_scope;
142 Persistent<Context> context = Context::New();
143 Context::Scope context_scope(context);
145 Local<Object> qmlglobal = Object::New();
147 #define SOURCE "function func1() { return 1; }\n" \
148 "function func2() { var sum = 0; for (var ii = 0; ii < 10000000; ++ii) { sum += func1(); } return sum; }\n" \
151 Local<Script> script = Script::Compile(String::New(SOURCE), NULL, NULL,
152 Handle<String>(), Script::QmlMode);
153 Local<Value> result = script->Run(qmlglobal);
154 VERIFY(!result.IsEmpty());
155 VERIFY(result->IsInt32());
156 VERIFY(result->Int32Value() == 10000000);
166 bool v8test_evalwithinwith()
170 HandleScope handle_scope;
171 Persistent<Context> context = Context::New();
172 Context::Scope context_scope(context);
174 Local<Object> qmlglobal = Object::New();
175 qmlglobal->Set(String::New("a"), Integer::New(1922));
176 // There was a bug that the "eval" lookup would incorrectly resolve
177 // to the QML global object
178 qmlglobal->Set(String::New("eval"), Integer::New(1922));
182 " var b = { c: 10 }; " \
184 " return eval(\"a\"); " \
187 Local<Script> script = Script::Compile(String::New(SOURCE), NULL, NULL,
188 Handle<String>(), Script::QmlMode);
192 Local<Value> result = script->Run(qmlglobal);
194 VERIFY(!tc.HasCaught());
195 VERIFY(result->IsFunction());
198 Local<Value> fresult = Handle<Function>::Cast(result)->Call(context->Global(), 0, 0);
199 VERIFY(!tc.HasCaught());
200 VERIFY(fresult->Int32Value() == 1922);
209 static int userObjectComparisonCalled = 0;
210 static bool userObjectComparisonReturn = false;
211 static Local<Object> expectedLhs;
212 static Local<Object> expectedRhs;
213 static bool expectedObjectsCompared = false;
215 #define SET_EXPECTED(lhs, rhs) { \
216 expectedObjectsCompared = false; \
221 static bool UserObjectComparison(Local<Object> lhs, Local<Object> rhs)
223 userObjectComparisonCalled++;
225 expectedObjectsCompared = (lhs == expectedLhs && rhs == expectedRhs);
227 return userObjectComparisonReturn;
230 inline bool runscript(const char *source) {
231 Local<Script> script = Script::Compile(String::New(source));
232 Local<Value> result = script->Run();
233 return result->BooleanValue();
236 bool v8test_userobjectcompare()
240 HandleScope handle_scope;
241 Persistent<Context> context = Context::New();
242 Context::Scope context_scope(context);
244 V8::SetUserObjectComparisonCallbackFunction(UserObjectComparison);
246 Local<ObjectTemplate> ot = ObjectTemplate::New();
247 ot->MarkAsUseUserObjectComparison();
249 Local<Object> uoc1 = ot->NewInstance();
250 Local<Object> uoc2 = ot->NewInstance();
251 context->Global()->Set(String::New("uoc1a"), uoc1);
252 context->Global()->Set(String::New("uoc1b"), uoc1);
253 context->Global()->Set(String::New("uoc2"), uoc2);
254 Local<Object> obj1 = Object::New();
255 context->Global()->Set(String::New("obj1a"), obj1);
256 context->Global()->Set(String::New("obj1b"), obj1);
257 context->Global()->Set(String::New("obj2"), Object::New());
258 Local<String> string1 = String::New("Hello World");
259 context->Global()->Set(String::New("string1a"), string1);
260 context->Global()->Set(String::New("string1b"), string1);
261 context->Global()->Set(String::New("string2"), v8::String::New("Goodbye World"));
263 // XXX Opportunity for optimization - don't invoke user callback if objects are
266 userObjectComparisonCalled = 0; userObjectComparisonReturn = false;
267 VERIFY(true == runscript("uoc1a == uoc1b"));
268 VERIFY(userObjectComparisonCalled == 0);
271 // Comparing two uoc objects invokes uoc
272 userObjectComparisonCalled = 0;
273 userObjectComparisonReturn = false;
274 VERIFY(false == runscript("uoc1a == uoc2"));
275 VERIFY(userObjectComparisonCalled == 1);
277 VERIFY(false == runscript("uoc2 == uoc1a"));
278 VERIFY(userObjectComparisonCalled == 2);
279 userObjectComparisonReturn = true;
280 VERIFY(true == runscript("uoc1a == uoc2"));
281 VERIFY(userObjectComparisonCalled == 3);
282 VERIFY(true == runscript("uoc2 == uoc1a"));
283 VERIFY(userObjectComparisonCalled == 4);
285 // != on two uoc object invokes uoc
286 userObjectComparisonCalled = 0;
287 userObjectComparisonReturn = false;
288 VERIFY(true == runscript("uoc1a != uoc2"));
289 VERIFY(userObjectComparisonCalled == 1);
290 VERIFY(true == runscript("uoc2 != uoc1a"));
291 VERIFY(userObjectComparisonCalled == 2);
292 userObjectComparisonReturn = true;
293 VERIFY(false == runscript("uoc1a != uoc2"));
294 VERIFY(userObjectComparisonCalled == 3);
295 VERIFY(false == runscript("uoc2 != uoc1a"));
296 VERIFY(userObjectComparisonCalled == 4);
298 // Comparison against a non-object doesn't invoke uoc
299 userObjectComparisonCalled = 0;
300 userObjectComparisonReturn = false;
301 VERIFY(false == runscript("uoc1a == string1a"));
302 VERIFY(userObjectComparisonCalled == 0);
303 VERIFY(false == runscript("string1a == uoc1a"));
304 VERIFY(userObjectComparisonCalled == 0);
305 VERIFY(false == runscript("2 == uoc1a"));
306 VERIFY(userObjectComparisonCalled == 0);
307 VERIFY(true == runscript("uoc1a != string1a"));
308 VERIFY(userObjectComparisonCalled == 0);
309 VERIFY(true == runscript("string1a != uoc1a"));
310 VERIFY(userObjectComparisonCalled == 0);
311 VERIFY(true == runscript("2 != uoc1a"));
312 VERIFY(userObjectComparisonCalled == 0);
314 // Comparison against a non-uoc-object still invokes uoc
315 userObjectComparisonCalled = 0;
316 userObjectComparisonReturn = false;
317 VERIFY(false == runscript("uoc1a == obj1a"));
318 VERIFY(userObjectComparisonCalled == 1);
319 VERIFY(false == runscript("obj1a == uoc1a"));
320 VERIFY(userObjectComparisonCalled == 2);
321 userObjectComparisonReturn = true;
322 VERIFY(true == runscript("uoc1a == obj1a"));
323 VERIFY(userObjectComparisonCalled == 3);
324 VERIFY(true == runscript("obj1a == uoc1a"));
325 VERIFY(userObjectComparisonCalled == 4);
327 // != comparison against a non-uoc-object still invokes uoc
328 userObjectComparisonCalled = 0;
329 userObjectComparisonReturn = false;
330 VERIFY(true == runscript("uoc1a != obj1a"));
331 VERIFY(userObjectComparisonCalled == 1);
332 VERIFY(true == runscript("obj1a != uoc1a"));
333 VERIFY(userObjectComparisonCalled == 2);
334 userObjectComparisonReturn = true;
335 VERIFY(false == runscript("uoc1a != obj1a"));
336 VERIFY(userObjectComparisonCalled == 3);
337 VERIFY(false == runscript("obj1a != uoc1a"));
338 VERIFY(userObjectComparisonCalled == 4);
340 // Comparing two non-uoc objects does not invoke uoc
341 userObjectComparisonCalled = 0;
342 userObjectComparisonReturn = false;
343 VERIFY(true == runscript("obj1a == obj1a"));
344 VERIFY(true == runscript("obj1a == obj1b"));
345 VERIFY(false == runscript("obj1a == obj2"));
346 VERIFY(false == runscript("obj1a == string1a"));
347 VERIFY(true == runscript("string1a == string1a"));
348 VERIFY(true == runscript("string1a == string1b"));
349 VERIFY(false == runscript("string1a == string2"));
350 VERIFY(userObjectComparisonCalled == 0);
352 // Correct lhs and rhs passed to uoc
353 userObjectComparisonCalled = 0;
354 userObjectComparisonReturn = false;
355 SET_EXPECTED(uoc1, uoc2);
356 VERIFY(false == runscript("uoc1a == uoc2"));
357 VERIFY(true == expectedObjectsCompared);
358 SET_EXPECTED(uoc2, uoc1);
359 VERIFY(false == runscript("uoc2 == uoc1a"));
360 VERIFY(true == expectedObjectsCompared);
361 SET_EXPECTED(uoc1, uoc2);
362 VERIFY(true == runscript("uoc1a != uoc2"));
363 VERIFY(true == expectedObjectsCompared);
364 SET_EXPECTED(uoc2, uoc1);
365 VERIFY(true == runscript("uoc2 != uoc1a"));
366 VERIFY(true == expectedObjectsCompared);
367 SET_EXPECTED(uoc1, obj1);
368 VERIFY(false == runscript("uoc1a == obj1a"));
369 VERIFY(true == expectedObjectsCompared);
370 SET_EXPECTED(obj1, uoc1);
371 VERIFY(false == runscript("obj1a == uoc1a"));
372 VERIFY(true == expectedObjectsCompared);
375 V8::SetUserObjectComparisonCallbackFunction(0);