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 ****************************************************************************/
42 #include "tst_qjsvalue.h"
43 #include <QtWidgets/QPushButton>
46 extern bool qt_script_isJITEnabled();
49 tst_QJSValue::tst_QJSValue()
54 tst_QJSValue::~tst_QJSValue()
60 void tst_QJSValue::ctor_invalid()
65 QCOMPARE(v.isValid(), false);
66 QCOMPARE(v.engine(), (QJSEngine *)0);
70 void tst_QJSValue::ctor_undefinedWithEngine()
74 QJSValue v(&eng, QJSValue::UndefinedValue);
75 QCOMPARE(v.isValid(), true);
76 QCOMPARE(v.isUndefined(), true);
77 QCOMPARE(v.isObject(), false);
78 QCOMPARE(v.engine(), &eng);
82 void tst_QJSValue::ctor_nullWithEngine()
86 QJSValue v(&eng, QJSValue::NullValue);
87 QCOMPARE(v.isValid(), true);
88 QCOMPARE(v.isNull(), true);
89 QCOMPARE(v.isObject(), false);
90 QCOMPARE(v.engine(), &eng);
94 void tst_QJSValue::ctor_boolWithEngine()
98 QJSValue v(&eng, false);
99 QCOMPARE(v.isValid(), true);
100 QCOMPARE(v.isBoolean(), true);
101 QCOMPARE(v.isBool(), true);
102 QCOMPARE(v.isObject(), false);
103 QCOMPARE(v.toBoolean(), false);
104 QCOMPARE(v.engine(), &eng);
108 void tst_QJSValue::ctor_intWithEngine()
112 QJSValue v(&eng, int(1));
113 QCOMPARE(v.isValid(), true);
114 QCOMPARE(v.isNumber(), true);
115 QCOMPARE(v.isObject(), false);
116 QCOMPARE(v.toNumber(), 1.0);
117 QCOMPARE(v.engine(), &eng);
121 void tst_QJSValue::ctor_int()
124 QJSValue v(int(0x43211234));
125 QVERIFY(v.isNumber());
126 QCOMPARE(v.toInt32(), 0x43211234);
130 QCOMPARE(v.isValid(), true);
131 QCOMPARE(v.isNumber(), true);
132 QCOMPARE(v.isObject(), false);
133 QCOMPARE(v.toNumber(), 1.0);
134 QCOMPARE(v.engine(), (QJSEngine *)0);
138 void tst_QJSValue::ctor_uintWithEngine()
142 QJSValue v(&eng, uint(1));
143 QCOMPARE(v.isValid(), true);
144 QCOMPARE(v.isNumber(), true);
145 QCOMPARE(v.isObject(), false);
146 QCOMPARE(v.toNumber(), 1.0);
147 QCOMPARE(v.engine(), &eng);
151 void tst_QJSValue::ctor_uint()
154 QJSValue v(uint(0x43211234));
155 QVERIFY(v.isNumber());
156 QCOMPARE(v.toUInt32(), uint(0x43211234));
160 QCOMPARE(v.isValid(), true);
161 QCOMPARE(v.isNumber(), true);
162 QCOMPARE(v.isObject(), false);
163 QCOMPARE(v.toNumber(), 1.0);
164 QCOMPARE(v.engine(), (QJSEngine *)0);
168 void tst_QJSValue::ctor_floatWithEngine()
172 QJSValue v(&eng, 1.0);
173 QCOMPARE(v.isValid(), true);
174 QCOMPARE(v.isNumber(), true);
175 QCOMPARE(v.isObject(), false);
176 QCOMPARE(v.toNumber(), 1.0);
177 QCOMPARE(v.engine(), &eng);
181 void tst_QJSValue::ctor_float()
184 QJSValue v(12345678910.5);
185 QVERIFY(v.isNumber());
186 QCOMPARE(v.toNumber(), 12345678910.5);
190 QCOMPARE(v.isValid(), true);
191 QCOMPARE(v.isNumber(), true);
192 QCOMPARE(v.isObject(), false);
193 QCOMPARE(v.toNumber(), 1.0);
194 QCOMPARE(v.engine(), (QJSEngine *)0);
198 void tst_QJSValue::ctor_stringWithEngine()
202 QJSValue v(&eng, QLatin1String("ciao"));
203 QCOMPARE(v.isValid(), true);
204 QCOMPARE(v.isString(), true);
205 QCOMPARE(v.isObject(), false);
206 QCOMPARE(v.toString(), QLatin1String("ciao"));
207 QCOMPARE(v.engine(), &eng);
211 void tst_QJSValue::ctor_string()
214 QJSValue v(QString("ciao"));
215 QCOMPARE(v.isValid(), true);
216 QCOMPARE(v.isString(), true);
217 QCOMPARE(v.isObject(), false);
218 QCOMPARE(v.toString(), QLatin1String("ciao"));
219 QCOMPARE(v.engine(), (QJSEngine *)0);
223 QCOMPARE(v.isValid(), true);
224 QCOMPARE(v.isString(), true);
225 QCOMPARE(v.isObject(), false);
226 QCOMPARE(v.toString(), QLatin1String("ciao"));
227 QCOMPARE(v.engine(), (QJSEngine *)0);
231 void tst_QJSValue::ctor_copyAndAssignWithEngine()
234 // copy constructor, operator=
236 QJSValue v(&eng, 1.0);
238 QCOMPARE(v2.strictlyEquals(v), true);
239 QCOMPARE(v2.engine(), &eng);
242 QCOMPARE(v3.strictlyEquals(v), true);
243 QCOMPARE(v3.strictlyEquals(v2), true);
244 QCOMPARE(v3.engine(), &eng);
246 QJSValue v4(&eng, 2.0);
247 QCOMPARE(v4.strictlyEquals(v), false);
249 QCOMPARE(v3.strictlyEquals(v), false);
250 QCOMPARE(v3.strictlyEquals(v4), true);
253 QCOMPARE(v2.strictlyEquals(v), false);
254 QCOMPARE(v.toNumber(), 1.0);
257 QCOMPARE(v5.strictlyEquals(v), true);
259 QCOMPARE(v5.strictlyEquals(v), false);
260 QCOMPARE(v5.toNumber(), 1.0);
264 void tst_QJSValue::ctor_undefined()
266 QJSValue v(QJSValue::UndefinedValue);
267 QCOMPARE(v.isValid(), true);
268 QCOMPARE(v.isUndefined(), true);
269 QCOMPARE(v.isObject(), false);
270 QCOMPARE(v.engine(), (QJSEngine *)0);
273 void tst_QJSValue::ctor_null()
275 QJSValue v(QJSValue::NullValue);
276 QCOMPARE(v.isValid(), true);
277 QCOMPARE(v.isNull(), true);
278 QCOMPARE(v.isObject(), false);
279 QCOMPARE(v.engine(), (QJSEngine *)0);
282 void tst_QJSValue::ctor_bool()
285 QCOMPARE(v.isValid(), true);
286 QCOMPARE(v.isBoolean(), true);
287 QCOMPARE(v.isBool(), true);
288 QCOMPARE(v.isObject(), false);
289 QCOMPARE(v.toBoolean(), false);
290 QCOMPARE(v.engine(), (QJSEngine *)0);
293 void tst_QJSValue::ctor_copyAndAssign()
297 QCOMPARE(v2.strictlyEquals(v), true);
298 QCOMPARE(v2.engine(), (QJSEngine *)0);
301 QCOMPARE(v3.strictlyEquals(v), true);
302 QCOMPARE(v3.strictlyEquals(v2), true);
303 QCOMPARE(v3.engine(), (QJSEngine *)0);
306 QCOMPARE(v4.strictlyEquals(v), false);
308 QCOMPARE(v3.strictlyEquals(v), false);
309 QCOMPARE(v3.strictlyEquals(v4), true);
312 QCOMPARE(v2.strictlyEquals(v), false);
313 QCOMPARE(v.toNumber(), 1.0);
316 QCOMPARE(v5.strictlyEquals(v), true);
318 QCOMPARE(v5.strictlyEquals(v), false);
319 QCOMPARE(v5.toNumber(), 1.0);
322 void tst_QJSValue::ctor_nullEngine()
325 QVERIFY(QJSValue(0, QJSValue::UndefinedValue).isUndefined());
326 QVERIFY(QJSValue(0, QJSValue::NullValue).isNull());
327 QVERIFY(QJSValue(0, false).isBool());
328 QVERIFY(QJSValue(0, int(1)).isNumber());
329 QVERIFY(QJSValue(0, uint(1)).isNumber());
330 QVERIFY(QJSValue(0, 1.0).isNumber());
331 QVERIFY(QJSValue(0, QString("ciao")).isString());
334 #if 0 // FIXME: No c-style callbacks currently
335 static QJSValue myFunction(QScriptContext *, QScriptEngine *eng)
337 return eng->undefinedValue();
341 void tst_QJSValue::toString()
345 QJSValue undefined = eng.undefinedValue();
346 QCOMPARE(undefined.toString(), QString("undefined"));
347 QCOMPARE(qjsvalue_cast<QString>(undefined), QString());
349 QJSValue null = eng.nullValue();
350 QCOMPARE(null.toString(), QString("null"));
351 QCOMPARE(qjsvalue_cast<QString>(null), QString());
354 QJSValue falskt = QJSValue(&eng, false);
355 QCOMPARE(falskt.toString(), QString("false"));
356 QCOMPARE(qjsvalue_cast<QString>(falskt), QString("false"));
358 QJSValue sant = QJSValue(&eng, true);
359 QCOMPARE(sant.toString(), QString("true"));
360 QCOMPARE(qjsvalue_cast<QString>(sant), QString("true"));
363 QJSValue number = QJSValue(&eng, 123);
364 QCOMPARE(number.toString(), QString("123"));
365 QCOMPARE(qjsvalue_cast<QString>(number), QString("123"));
368 QJSValue number = QJSValue(&eng, 6.37e-8);
369 QCOMPARE(number.toString(), QString("6.37e-8"));
372 QJSValue number = QJSValue(&eng, -6.37e-8);
373 QCOMPARE(number.toString(), QString("-6.37e-8"));
375 QJSValue str = QJSValue(&eng, QString("ciao"));
376 QCOMPARE(str.toString(), QString("ciao"));
377 QCOMPARE(qjsvalue_cast<QString>(str), QString("ciao"));
380 QJSValue object = eng.newObject();
381 QCOMPARE(object.toString(), QString("[object Object]"));
382 QCOMPARE(qjsvalue_cast<QString>(object), QString("[object Object]"));
384 // FIXME: No c-style callbacks currently
386 QJSValue fun = eng.newFunction(myFunction);
387 QCOMPARE(fun.toString().simplified(), QString("function () { [native code] }"));
388 QCOMPARE(qscriptvalue_cast<QString>(fun).simplified(), QString("function () { [native code] }"));
391 // toString() that throws exception
393 QJSValue objectObject = eng.evaluate(
396 " o.toString = function() { throw new Error('toString'); };"
399 QCOMPARE(objectObject.toString(), QLatin1String("Error: toString"));
400 QVERIFY(eng.hasUncaughtException());
401 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: toString"));
404 eng.clearExceptions();
405 QJSValue objectObject = eng.evaluate(
407 " var f = function() {};"
408 " f.prototype = Date;"
411 QVERIFY(!eng.hasUncaughtException());
412 QVERIFY(objectObject.isObject());
413 QCOMPARE(objectObject.toString(), QString::fromLatin1("TypeError: Function.prototype.toString is not generic"));
414 QVERIFY(eng.hasUncaughtException());
415 eng.clearExceptions();
418 QJSValue inv = QJSValue();
419 QCOMPARE(inv.toString(), QString());
423 QJSValue falskt = QJSValue(false);
424 QCOMPARE(falskt.toString(), QString("false"));
425 QCOMPARE(qjsvalue_cast<QString>(falskt), QString("false"));
427 QJSValue sant = QJSValue(true);
428 QCOMPARE(sant.toString(), QString("true"));
429 QCOMPARE(qjsvalue_cast<QString>(sant), QString("true"));
431 QJSValue number = QJSValue(123);
432 QCOMPARE(number.toString(), QString("123"));
433 QCOMPARE(qjsvalue_cast<QString>(number), QString("123"));
435 QJSValue number2(int(0x43211234));
436 QCOMPARE(number2.toString(), QString("1126240820"));
438 QJSValue str = QJSValue(QString("ciao"));
439 QCOMPARE(str.toString(), QString("ciao"));
440 QCOMPARE(qjsvalue_cast<QString>(str), QString("ciao"));
443 // variant should use internal valueOf(), then fall back to QVariant::toString(),
444 // then fall back to "QVariant(typename)"
445 QJSValue variant = eng.newVariant(123);
446 QVERIFY(variant.isVariant());
447 QCOMPARE(variant.toString(), QString::fromLatin1("123"));
448 variant = eng.newVariant(QByteArray("hello"));
449 QVERIFY(variant.isVariant());
450 QCOMPARE(variant.toString(), QString::fromLatin1("hello"));
451 variant = eng.newVariant(QVariant(QPoint(10, 20)));
452 QVERIFY(variant.isVariant());
453 QCOMPARE(variant.toString(), QString::fromLatin1("QVariant(QPoint)"));
454 variant = eng.newVariant(QUrl());
455 QVERIFY(variant.toString().isEmpty());
458 void tst_QJSValue::toNumber()
462 QJSValue undefined = eng.undefinedValue();
463 QCOMPARE(qIsNaN(undefined.toNumber()), true);
464 QCOMPARE(qIsNaN(qjsvalue_cast<qreal>(undefined)), true);
466 QJSValue null = eng.nullValue();
467 QCOMPARE(null.toNumber(), 0.0);
468 QCOMPARE(qjsvalue_cast<qreal>(null), 0.0);
471 QJSValue falskt = QJSValue(&eng, false);
472 QCOMPARE(falskt.toNumber(), 0.0);
473 QCOMPARE(qjsvalue_cast<qreal>(falskt), 0.0);
475 QJSValue sant = QJSValue(&eng, true);
476 QCOMPARE(sant.toNumber(), 1.0);
477 QCOMPARE(qjsvalue_cast<qreal>(sant), 1.0);
479 QJSValue number = QJSValue(&eng, 123.0);
480 QCOMPARE(number.toNumber(), 123.0);
481 QCOMPARE(qjsvalue_cast<qreal>(number), 123.0);
483 QJSValue str = QJSValue(&eng, QString("ciao"));
484 QCOMPARE(qIsNaN(str.toNumber()), true);
485 QCOMPARE(qIsNaN(qjsvalue_cast<qreal>(str)), true);
487 QJSValue str2 = QJSValue(&eng, QString("123"));
488 QCOMPARE(str2.toNumber(), 123.0);
489 QCOMPARE(qjsvalue_cast<qreal>(str2), 123.0);
492 QJSValue object = eng.newObject();
493 QCOMPARE(qIsNaN(object.toNumber()), true);
494 QCOMPARE(qIsNaN(qjsvalue_cast<qreal>(object)), true);
496 // FIXME: No c-style callbacks currently
498 QJSValue fun = eng.newFunction(myFunction);
499 QCOMPARE(qIsNaN(fun.toNumber()), true);
500 QCOMPARE(qIsNaN(qscriptvalue_cast<qreal>(fun)), true);
503 QJSValue inv = QJSValue();
504 QCOMPARE(inv.toNumber(), 0.0);
505 QCOMPARE(qjsvalue_cast<qreal>(inv), 0.0);
509 QJSValue falskt = QJSValue(false);
510 QCOMPARE(falskt.toNumber(), 0.0);
511 QCOMPARE(qjsvalue_cast<qreal>(falskt), 0.0);
513 QJSValue sant = QJSValue(true);
514 QCOMPARE(sant.toNumber(), 1.0);
515 QCOMPARE(qjsvalue_cast<qreal>(sant), 1.0);
517 QJSValue number = QJSValue(123.0);
518 QCOMPARE(number.toNumber(), 123.0);
519 QCOMPARE(qjsvalue_cast<qreal>(number), 123.0);
521 QJSValue number2(int(0x43211234));
522 QCOMPARE(number2.toNumber(), 1126240820.0);
524 QJSValue str = QJSValue(QString("ciao"));
525 QCOMPARE(qIsNaN(str.toNumber()), true);
526 QCOMPARE(qIsNaN(qjsvalue_cast<qreal>(str)), true);
528 QJSValue str2 = QJSValue(QString("123"));
529 QCOMPARE(str2.toNumber(), 123.0);
530 QCOMPARE(qjsvalue_cast<qreal>(str2), 123.0);
534 void tst_QJSValue::toBoolean() // deprecated
538 QJSValue undefined = eng.undefinedValue();
539 QCOMPARE(undefined.toBoolean(), false);
540 QCOMPARE(qjsvalue_cast<bool>(undefined), false);
542 QJSValue null = eng.nullValue();
543 QCOMPARE(null.toBoolean(), false);
544 QCOMPARE(qjsvalue_cast<bool>(null), false);
547 QJSValue falskt = QJSValue(&eng, false);
548 QCOMPARE(falskt.toBoolean(), false);
549 QCOMPARE(qjsvalue_cast<bool>(falskt), false);
551 QJSValue sant = QJSValue(&eng, true);
552 QCOMPARE(sant.toBoolean(), true);
553 QCOMPARE(qjsvalue_cast<bool>(sant), true);
555 QJSValue number = QJSValue(&eng, 0.0);
556 QCOMPARE(number.toBoolean(), false);
557 QCOMPARE(qjsvalue_cast<bool>(number), false);
559 QJSValue number2 = QJSValue(&eng, qSNaN());
560 QCOMPARE(number2.toBoolean(), false);
561 QCOMPARE(qjsvalue_cast<bool>(number2), false);
563 QJSValue number3 = QJSValue(&eng, 123.0);
564 QCOMPARE(number3.toBoolean(), true);
565 QCOMPARE(qjsvalue_cast<bool>(number3), true);
567 QJSValue number4 = QJSValue(&eng, -456.0);
568 QCOMPARE(number4.toBoolean(), true);
569 QCOMPARE(qjsvalue_cast<bool>(number4), true);
571 QJSValue str = QJSValue(&eng, QString(""));
572 QCOMPARE(str.toBoolean(), false);
573 QCOMPARE(qjsvalue_cast<bool>(str), false);
575 QJSValue str2 = QJSValue(&eng, QString("123"));
576 QCOMPARE(str2.toBoolean(), true);
577 QCOMPARE(qjsvalue_cast<bool>(str2), true);
580 QJSValue object = eng.newObject();
581 QCOMPARE(object.toBoolean(), true);
582 QCOMPARE(qjsvalue_cast<bool>(object), true);
584 // FIXME: No c-style callbacks currently
586 QJSValue fun = eng.newFunction(myFunction);
587 QCOMPARE(fun.toBoolean(), true);
588 QCOMPARE(qscriptvalue_cast<bool>(fun), true);
591 QJSValue inv = QJSValue();
592 QCOMPARE(inv.toBoolean(), false);
593 QCOMPARE(qjsvalue_cast<bool>(inv), false);
597 QJSValue falskt = QJSValue(false);
598 QCOMPARE(falskt.toBoolean(), false);
599 QCOMPARE(qjsvalue_cast<bool>(falskt), false);
601 QJSValue sant = QJSValue(true);
602 QCOMPARE(sant.toBoolean(), true);
603 QCOMPARE(qjsvalue_cast<bool>(sant), true);
605 QJSValue number = QJSValue(0.0);
606 QCOMPARE(number.toBoolean(), false);
607 QCOMPARE(qjsvalue_cast<bool>(number), false);
609 QJSValue number2 = QJSValue(qSNaN());
610 QCOMPARE(number2.toBoolean(), false);
611 QCOMPARE(qjsvalue_cast<bool>(number2), false);
613 QJSValue number3 = QJSValue(123.0);
614 QCOMPARE(number3.toBoolean(), true);
615 QCOMPARE(qjsvalue_cast<bool>(number3), true);
617 QJSValue number4 = QJSValue(-456.0);
618 QCOMPARE(number4.toBoolean(), true);
619 QCOMPARE(qjsvalue_cast<bool>(number4), true);
621 QJSValue number5 = QJSValue(0x43211234);
622 QCOMPARE(number5.toBoolean(), true);
624 QJSValue str = QJSValue(QString(""));
625 QCOMPARE(str.toBoolean(), false);
626 QCOMPARE(qjsvalue_cast<bool>(str), false);
628 QJSValue str2 = QJSValue(QString("123"));
629 QCOMPARE(str2.toBoolean(), true);
630 QCOMPARE(qjsvalue_cast<bool>(str2), true);
634 void tst_QJSValue::toBool()
638 QJSValue undefined = eng.undefinedValue();
639 QCOMPARE(undefined.toBool(), false);
640 QCOMPARE(qjsvalue_cast<bool>(undefined), false);
642 QJSValue null = eng.nullValue();
643 QCOMPARE(null.toBool(), false);
644 QCOMPARE(qjsvalue_cast<bool>(null), false);
647 QJSValue falskt = QJSValue(&eng, false);
648 QCOMPARE(falskt.toBool(), false);
649 QCOMPARE(qjsvalue_cast<bool>(falskt), false);
651 QJSValue sant = QJSValue(&eng, true);
652 QCOMPARE(sant.toBool(), true);
653 QCOMPARE(qjsvalue_cast<bool>(sant), true);
655 QJSValue number = QJSValue(&eng, 0.0);
656 QCOMPARE(number.toBool(), false);
657 QCOMPARE(qjsvalue_cast<bool>(number), false);
659 QJSValue number2 = QJSValue(&eng, qSNaN());
660 QCOMPARE(number2.toBool(), false);
661 QCOMPARE(qjsvalue_cast<bool>(number2), false);
663 QJSValue number3 = QJSValue(&eng, 123.0);
664 QCOMPARE(number3.toBool(), true);
665 QCOMPARE(qjsvalue_cast<bool>(number3), true);
667 QJSValue number4 = QJSValue(&eng, -456.0);
668 QCOMPARE(number4.toBool(), true);
669 QCOMPARE(qjsvalue_cast<bool>(number4), true);
671 QJSValue str = QJSValue(&eng, QString(""));
672 QCOMPARE(str.toBool(), false);
673 QCOMPARE(qjsvalue_cast<bool>(str), false);
675 QJSValue str2 = QJSValue(&eng, QString("123"));
676 QCOMPARE(str2.toBool(), true);
677 QCOMPARE(qjsvalue_cast<bool>(str2), true);
680 QJSValue object = eng.newObject();
681 QCOMPARE(object.toBool(), true);
682 QCOMPARE(qjsvalue_cast<bool>(object), true);
684 // FIXME: No c-style callbacks currently
686 QJSValue fun = eng.newFunction(myFunction);
687 QCOMPARE(fun.toBool(), true);
688 QCOMPARE(qscriptvalue_cast<bool>(fun), true);
691 QJSValue inv = QJSValue();
692 QCOMPARE(inv.toBool(), false);
693 QCOMPARE(qjsvalue_cast<bool>(inv), false);
697 QJSValue falskt = QJSValue(false);
698 QCOMPARE(falskt.toBool(), false);
699 QCOMPARE(qjsvalue_cast<bool>(falskt), false);
701 QJSValue sant = QJSValue(true);
702 QCOMPARE(sant.toBool(), true);
703 QCOMPARE(qjsvalue_cast<bool>(sant), true);
705 QJSValue number = QJSValue(0.0);
706 QCOMPARE(number.toBool(), false);
707 QCOMPARE(qjsvalue_cast<bool>(number), false);
709 QJSValue number2 = QJSValue(qSNaN());
710 QCOMPARE(number2.toBool(), false);
711 QCOMPARE(qjsvalue_cast<bool>(number2), false);
713 QJSValue number3 = QJSValue(123.0);
714 QCOMPARE(number3.toBool(), true);
715 QCOMPARE(qjsvalue_cast<bool>(number3), true);
717 QJSValue number4 = QJSValue(-456.0);
718 QCOMPARE(number4.toBool(), true);
719 QCOMPARE(qjsvalue_cast<bool>(number4), true);
721 QJSValue number5 = QJSValue(0x43211234);
722 QCOMPARE(number5.toBool(), true);
724 QJSValue str = QJSValue(QString(""));
725 QCOMPARE(str.toBool(), false);
726 QCOMPARE(qjsvalue_cast<bool>(str), false);
728 QJSValue str2 = QJSValue(QString("123"));
729 QCOMPARE(str2.toBool(), true);
730 QCOMPARE(qjsvalue_cast<bool>(str2), true);
734 void tst_QJSValue::toInteger()
739 QJSValue number = QJSValue(&eng, 123.0);
740 QCOMPARE(number.toInteger(), 123.0);
742 QJSValue number2 = QJSValue(&eng, qSNaN());
743 QCOMPARE(number2.toInteger(), 0.0);
745 QJSValue number3 = QJSValue(&eng, qInf());
746 QCOMPARE(qIsInf(number3.toInteger()), true);
748 QJSValue number4 = QJSValue(&eng, 0.5);
749 QCOMPARE(number4.toInteger(), 0.0);
751 QJSValue number5 = QJSValue(&eng, 123.5);
752 QCOMPARE(number5.toInteger(), 123.0);
754 QJSValue number6 = QJSValue(&eng, -456.5);
755 QCOMPARE(number6.toInteger(), -456.0);
757 QJSValue str = QJSValue(&eng, QLatin1String("123.0"));
758 QCOMPARE(str.toInteger(), 123.0);
760 QJSValue str2 = QJSValue(&eng, QLatin1String("NaN"));
761 QCOMPARE(str2.toInteger(), 0.0);
763 QJSValue str3 = QJSValue(&eng, QLatin1String("Infinity"));
764 QCOMPARE(qIsInf(str3.toInteger()), true);
766 QJSValue str4 = QJSValue(&eng, QLatin1String("0.5"));
767 QCOMPARE(str4.toInteger(), 0.0);
769 QJSValue str5 = QJSValue(&eng, QLatin1String("123.5"));
770 QCOMPARE(str5.toInteger(), 123.0);
772 QJSValue str6 = QJSValue(&eng, QLatin1String("-456.5"));
773 QCOMPARE(str6.toInteger(), -456.0);
777 QJSValue number = QJSValue(123.0);
778 QCOMPARE(number.toInteger(), 123.0);
780 QJSValue number2 = QJSValue(qSNaN());
781 QCOMPARE(number2.toInteger(), 0.0);
783 QJSValue number3 = QJSValue(qInf());
784 QCOMPARE(qIsInf(number3.toInteger()), true);
786 QJSValue number4 = QJSValue(0.5);
787 QCOMPARE(number4.toInteger(), 0.0);
789 QJSValue number5 = QJSValue(123.5);
790 QCOMPARE(number5.toInteger(), 123.0);
792 QJSValue number6 = QJSValue(-456.5);
793 QCOMPARE(number6.toInteger(), -456.0);
795 QJSValue number7 = QJSValue(0x43211234);
796 QCOMPARE(number7.toInteger(), qreal(0x43211234));
798 QJSValue str = QJSValue("123.0");
799 QCOMPARE(str.toInteger(), 123.0);
801 QJSValue str2 = QJSValue("NaN");
802 QCOMPARE(str2.toInteger(), 0.0);
804 QJSValue str3 = QJSValue("Infinity");
805 QCOMPARE(qIsInf(str3.toInteger()), true);
807 QJSValue str4 = QJSValue("0.5");
808 QCOMPARE(str4.toInteger(), 0.0);
810 QJSValue str5 = QJSValue("123.5");
811 QCOMPARE(str5.toInteger(), 123.0);
813 QJSValue str6 = QJSValue("-456.5");
814 QCOMPARE(str6.toInteger(), -456.0);
818 QCOMPARE(inv.toInteger(), 0.0);
821 void tst_QJSValue::toInt32()
826 QJSValue zer0 = QJSValue(&eng, 0.0);
827 QCOMPARE(zer0.toInt32(), 0);
828 QCOMPARE(qjsvalue_cast<qint32>(zer0), 0);
830 QJSValue number = QJSValue(&eng, 123.0);
831 QCOMPARE(number.toInt32(), 123);
832 QCOMPARE(qjsvalue_cast<qint32>(number), 123);
834 QJSValue number2 = QJSValue(&eng, qSNaN());
835 QCOMPARE(number2.toInt32(), 0);
836 QCOMPARE(qjsvalue_cast<qint32>(number2), 0);
838 QJSValue number3 = QJSValue(&eng, +qInf());
839 QCOMPARE(number3.toInt32(), 0);
840 QCOMPARE(qjsvalue_cast<qint32>(number3), 0);
842 QJSValue number3_2 = QJSValue(&eng, -qInf());
843 QCOMPARE(number3_2.toInt32(), 0);
844 QCOMPARE(qjsvalue_cast<qint32>(number3_2), 0);
846 QJSValue number4 = QJSValue(&eng, 0.5);
847 QCOMPARE(number4.toInt32(), 0);
848 QCOMPARE(qjsvalue_cast<qint32>(number4), 0);
850 QJSValue number5 = QJSValue(&eng, 123.5);
851 QCOMPARE(number5.toInt32(), 123);
852 QCOMPARE(qjsvalue_cast<qint32>(number5), 123);
854 QJSValue number6 = QJSValue(&eng, -456.5);
855 QCOMPARE(number6.toInt32(), -456);
856 QCOMPARE(qjsvalue_cast<qint32>(number6), -456);
858 QJSValue str = QJSValue(&eng, QLatin1String("123.0"));
859 QCOMPARE(str.toInt32(), 123);
860 QCOMPARE(qjsvalue_cast<qint32>(str), 123);
862 QJSValue str2 = QJSValue(&eng, QLatin1String("NaN"));
863 QCOMPARE(str2.toInt32(), 0);
864 QCOMPARE(qjsvalue_cast<qint32>(str2), 0);
866 QJSValue str3 = QJSValue(&eng, QLatin1String("Infinity"));
867 QCOMPARE(str3.toInt32(), 0);
868 QCOMPARE(qjsvalue_cast<qint32>(str3), 0);
870 QJSValue str3_2 = QJSValue(&eng, QLatin1String("-Infinity"));
871 QCOMPARE(str3_2.toInt32(), 0);
872 QCOMPARE(qjsvalue_cast<qint32>(str3_2), 0);
874 QJSValue str4 = QJSValue(&eng, QLatin1String("0.5"));
875 QCOMPARE(str4.toInt32(), 0);
876 QCOMPARE(qjsvalue_cast<qint32>(str4), 0);
878 QJSValue str5 = QJSValue(&eng, QLatin1String("123.5"));
879 QCOMPARE(str5.toInt32(), 123);
880 QCOMPARE(qjsvalue_cast<qint32>(str5), 123);
882 QJSValue str6 = QJSValue(&eng, QLatin1String("-456.5"));
883 QCOMPARE(str6.toInt32(), -456);
884 QCOMPARE(qjsvalue_cast<qint32>(str6), -456);
888 QJSValue zer0 = QJSValue(0.0);
889 QCOMPARE(zer0.toInt32(), 0);
890 QCOMPARE(qjsvalue_cast<qint32>(zer0), 0);
892 QJSValue number = QJSValue(123.0);
893 QCOMPARE(number.toInt32(), 123);
894 QCOMPARE(qjsvalue_cast<qint32>(number), 123);
896 QJSValue number2 = QJSValue(qSNaN());
897 QCOMPARE(number2.toInt32(), 0);
898 QCOMPARE(qjsvalue_cast<qint32>(number2), 0);
900 QJSValue number3 = QJSValue(+qInf());
901 QCOMPARE(number3.toInt32(), 0);
902 QCOMPARE(qjsvalue_cast<qint32>(number3), 0);
904 QJSValue number3_2 = QJSValue(-qInf());
905 QCOMPARE(number3_2.toInt32(), 0);
906 QCOMPARE(qjsvalue_cast<qint32>(number3_2), 0);
908 QJSValue number4 = QJSValue(0.5);
909 QCOMPARE(number4.toInt32(), 0);
910 QCOMPARE(qjsvalue_cast<qint32>(number4), 0);
912 QJSValue number5 = QJSValue(123.5);
913 QCOMPARE(number5.toInt32(), 123);
914 QCOMPARE(qjsvalue_cast<qint32>(number5), 123);
916 QJSValue number6 = QJSValue(-456.5);
917 QCOMPARE(number6.toInt32(), -456);
918 QCOMPARE(qjsvalue_cast<qint32>(number6), -456);
920 QJSValue number7 = QJSValue(0x43211234);
921 QCOMPARE(number7.toInt32(), 0x43211234);
923 QJSValue str = QJSValue("123.0");
924 QCOMPARE(str.toInt32(), 123);
925 QCOMPARE(qjsvalue_cast<qint32>(str), 123);
927 QJSValue str2 = QJSValue("NaN");
928 QCOMPARE(str2.toInt32(), 0);
929 QCOMPARE(qjsvalue_cast<qint32>(str2), 0);
931 QJSValue str3 = QJSValue("Infinity");
932 QCOMPARE(str3.toInt32(), 0);
933 QCOMPARE(qjsvalue_cast<qint32>(str3), 0);
935 QJSValue str3_2 = QJSValue("-Infinity");
936 QCOMPARE(str3_2.toInt32(), 0);
937 QCOMPARE(qjsvalue_cast<qint32>(str3_2), 0);
939 QJSValue str4 = QJSValue("0.5");
940 QCOMPARE(str4.toInt32(), 0);
941 QCOMPARE(qjsvalue_cast<qint32>(str4), 0);
943 QJSValue str5 = QJSValue("123.5");
944 QCOMPARE(str5.toInt32(), 123);
945 QCOMPARE(qjsvalue_cast<qint32>(str5), 123);
947 QJSValue str6 = QJSValue("-456.5");
948 QCOMPARE(str6.toInt32(), -456);
949 QCOMPARE(qjsvalue_cast<qint32>(str6), -456);
953 QCOMPARE(inv.toInt32(), 0);
954 QCOMPARE(qjsvalue_cast<qint32>(inv), 0);
957 void tst_QJSValue::toUInt32()
962 QJSValue zer0 = QJSValue(&eng, 0.0);
963 QCOMPARE(zer0.toUInt32(), quint32(0));
964 QCOMPARE(qjsvalue_cast<quint32>(zer0), quint32(0));
966 QJSValue number = QJSValue(&eng, 123.0);
967 QCOMPARE(number.toUInt32(), quint32(123));
968 QCOMPARE(qjsvalue_cast<quint32>(number), quint32(123));
970 QJSValue number2 = QJSValue(&eng, qSNaN());
971 QCOMPARE(number2.toUInt32(), quint32(0));
972 QCOMPARE(qjsvalue_cast<quint32>(number2), quint32(0));
974 QJSValue number3 = QJSValue(&eng, +qInf());
975 QCOMPARE(number3.toUInt32(), quint32(0));
976 QCOMPARE(qjsvalue_cast<quint32>(number3), quint32(0));
978 QJSValue number3_2 = QJSValue(&eng, -qInf());
979 QCOMPARE(number3_2.toUInt32(), quint32(0));
980 QCOMPARE(qjsvalue_cast<quint32>(number3_2), quint32(0));
982 QJSValue number4 = QJSValue(&eng, 0.5);
983 QCOMPARE(number4.toUInt32(), quint32(0));
985 QJSValue number5 = QJSValue(&eng, 123.5);
986 QCOMPARE(number5.toUInt32(), quint32(123));
988 QJSValue number6 = QJSValue(&eng, -456.5);
989 QCOMPARE(number6.toUInt32(), quint32(-456));
990 QCOMPARE(qjsvalue_cast<quint32>(number6), quint32(-456));
992 QJSValue str = QJSValue(&eng, QLatin1String("123.0"));
993 QCOMPARE(str.toUInt32(), quint32(123));
994 QCOMPARE(qjsvalue_cast<quint32>(str), quint32(123));
996 QJSValue str2 = QJSValue(&eng, QLatin1String("NaN"));
997 QCOMPARE(str2.toUInt32(), quint32(0));
998 QCOMPARE(qjsvalue_cast<quint32>(str2), quint32(0));
1000 QJSValue str3 = QJSValue(&eng, QLatin1String("Infinity"));
1001 QCOMPARE(str3.toUInt32(), quint32(0));
1002 QCOMPARE(qjsvalue_cast<quint32>(str3), quint32(0));
1004 QJSValue str3_2 = QJSValue(&eng, QLatin1String("-Infinity"));
1005 QCOMPARE(str3_2.toUInt32(), quint32(0));
1006 QCOMPARE(qjsvalue_cast<quint32>(str3_2), quint32(0));
1008 QJSValue str4 = QJSValue(&eng, QLatin1String("0.5"));
1009 QCOMPARE(str4.toUInt32(), quint32(0));
1010 QCOMPARE(qjsvalue_cast<quint32>(str4), quint32(0));
1012 QJSValue str5 = QJSValue(&eng, QLatin1String("123.5"));
1013 QCOMPARE(str5.toUInt32(), quint32(123));
1014 QCOMPARE(qjsvalue_cast<quint32>(str5), quint32(123));
1016 QJSValue str6 = QJSValue(&eng, QLatin1String("-456.5"));
1017 QCOMPARE(str6.toUInt32(), quint32(-456));
1018 QCOMPARE(qjsvalue_cast<quint32>(str6), quint32(-456));
1022 QJSValue zer0 = QJSValue(0.0);
1023 QCOMPARE(zer0.toUInt32(), quint32(0));
1024 QCOMPARE(qjsvalue_cast<quint32>(zer0), quint32(0));
1026 QJSValue number = QJSValue(123.0);
1027 QCOMPARE(number.toUInt32(), quint32(123));
1028 QCOMPARE(qjsvalue_cast<quint32>(number), quint32(123));
1030 QJSValue number2 = QJSValue(qSNaN());
1031 QCOMPARE(number2.toUInt32(), quint32(0));
1032 QCOMPARE(qjsvalue_cast<quint32>(number2), quint32(0));
1034 QJSValue number3 = QJSValue(+qInf());
1035 QCOMPARE(number3.toUInt32(), quint32(0));
1036 QCOMPARE(qjsvalue_cast<quint32>(number3), quint32(0));
1038 QJSValue number3_2 = QJSValue(-qInf());
1039 QCOMPARE(number3_2.toUInt32(), quint32(0));
1040 QCOMPARE(qjsvalue_cast<quint32>(number3_2), quint32(0));
1042 QJSValue number4 = QJSValue(0.5);
1043 QCOMPARE(number4.toUInt32(), quint32(0));
1045 QJSValue number5 = QJSValue(123.5);
1046 QCOMPARE(number5.toUInt32(), quint32(123));
1048 QJSValue number6 = QJSValue(-456.5);
1049 QCOMPARE(number6.toUInt32(), quint32(-456));
1050 QCOMPARE(qjsvalue_cast<quint32>(number6), quint32(-456));
1052 QJSValue number7 = QJSValue(0x43211234);
1053 QCOMPARE(number7.toUInt32(), quint32(0x43211234));
1055 QJSValue str = QJSValue(QLatin1String("123.0"));
1056 QCOMPARE(str.toUInt32(), quint32(123));
1057 QCOMPARE(qjsvalue_cast<quint32>(str), quint32(123));
1059 QJSValue str2 = QJSValue(QLatin1String("NaN"));
1060 QCOMPARE(str2.toUInt32(), quint32(0));
1061 QCOMPARE(qjsvalue_cast<quint32>(str2), quint32(0));
1063 QJSValue str3 = QJSValue(QLatin1String("Infinity"));
1064 QCOMPARE(str3.toUInt32(), quint32(0));
1065 QCOMPARE(qjsvalue_cast<quint32>(str3), quint32(0));
1067 QJSValue str3_2 = QJSValue(QLatin1String("-Infinity"));
1068 QCOMPARE(str3_2.toUInt32(), quint32(0));
1069 QCOMPARE(qjsvalue_cast<quint32>(str3_2), quint32(0));
1071 QJSValue str4 = QJSValue(QLatin1String("0.5"));
1072 QCOMPARE(str4.toUInt32(), quint32(0));
1073 QCOMPARE(qjsvalue_cast<quint32>(str4), quint32(0));
1075 QJSValue str5 = QJSValue(QLatin1String("123.5"));
1076 QCOMPARE(str5.toUInt32(), quint32(123));
1077 QCOMPARE(qjsvalue_cast<quint32>(str5), quint32(123));
1079 QJSValue str6 = QJSValue(QLatin1String("-456.5"));
1080 QCOMPARE(str6.toUInt32(), quint32(-456));
1081 QCOMPARE(qjsvalue_cast<quint32>(str6), quint32(-456));
1085 QCOMPARE(inv.toUInt32(), quint32(0));
1086 QCOMPARE(qjsvalue_cast<quint32>(inv), quint32(0));
1089 void tst_QJSValue::toUInt16()
1094 QJSValue zer0 = QJSValue(&eng, 0.0);
1095 QCOMPARE(zer0.toUInt16(), quint16(0));
1096 QCOMPARE(qjsvalue_cast<quint16>(zer0), quint16(0));
1098 QJSValue number = QJSValue(&eng, 123.0);
1099 QCOMPARE(number.toUInt16(), quint16(123));
1100 QCOMPARE(qjsvalue_cast<quint16>(number), quint16(123));
1102 QJSValue number2 = QJSValue(&eng, qSNaN());
1103 QCOMPARE(number2.toUInt16(), quint16(0));
1104 QCOMPARE(qjsvalue_cast<quint16>(number2), quint16(0));
1106 QJSValue number3 = QJSValue(&eng, +qInf());
1107 QCOMPARE(number3.toUInt16(), quint16(0));
1108 QCOMPARE(qjsvalue_cast<quint16>(number3), quint16(0));
1110 QJSValue number3_2 = QJSValue(&eng, -qInf());
1111 QCOMPARE(number3_2.toUInt16(), quint16(0));
1112 QCOMPARE(qjsvalue_cast<quint16>(number3_2), quint16(0));
1114 QJSValue number4 = QJSValue(&eng, 0.5);
1115 QCOMPARE(number4.toUInt16(), quint16(0));
1117 QJSValue number5 = QJSValue(&eng, 123.5);
1118 QCOMPARE(number5.toUInt16(), quint16(123));
1120 QJSValue number6 = QJSValue(&eng, -456.5);
1121 QCOMPARE(number6.toUInt16(), quint16(-456));
1122 QCOMPARE(qjsvalue_cast<quint16>(number6), quint16(-456));
1124 QJSValue number7 = QJSValue(&eng, 0x10000);
1125 QCOMPARE(number7.toUInt16(), quint16(0));
1126 QCOMPARE(qjsvalue_cast<quint16>(number7), quint16(0));
1128 QJSValue number8 = QJSValue(&eng, 0x10001);
1129 QCOMPARE(number8.toUInt16(), quint16(1));
1130 QCOMPARE(qjsvalue_cast<quint16>(number8), quint16(1));
1132 QJSValue str = QJSValue(&eng, QLatin1String("123.0"));
1133 QCOMPARE(str.toUInt16(), quint16(123));
1134 QCOMPARE(qjsvalue_cast<quint16>(str), quint16(123));
1136 QJSValue str2 = QJSValue(&eng, QLatin1String("NaN"));
1137 QCOMPARE(str2.toUInt16(), quint16(0));
1138 QCOMPARE(qjsvalue_cast<quint16>(str2), quint16(0));
1140 QJSValue str3 = QJSValue(&eng, QLatin1String("Infinity"));
1141 QCOMPARE(str3.toUInt16(), quint16(0));
1142 QCOMPARE(qjsvalue_cast<quint16>(str3), quint16(0));
1144 QJSValue str3_2 = QJSValue(&eng, QLatin1String("-Infinity"));
1145 QCOMPARE(str3_2.toUInt16(), quint16(0));
1146 QCOMPARE(qjsvalue_cast<quint16>(str3_2), quint16(0));
1148 QJSValue str4 = QJSValue(&eng, QLatin1String("0.5"));
1149 QCOMPARE(str4.toUInt16(), quint16(0));
1151 QJSValue str5 = QJSValue(&eng, QLatin1String("123.5"));
1152 QCOMPARE(str5.toUInt16(), quint16(123));
1154 QJSValue str6 = QJSValue(&eng, QLatin1String("-456.5"));
1155 QCOMPARE(str6.toUInt16(), quint16(-456));
1156 QCOMPARE(qjsvalue_cast<quint16>(str6), quint16(-456));
1158 QJSValue str7 = QJSValue(&eng, QLatin1String("0x10000"));
1159 QCOMPARE(str7.toUInt16(), quint16(0));
1160 QCOMPARE(qjsvalue_cast<quint16>(str7), quint16(0));
1162 QJSValue str8 = QJSValue(&eng, QLatin1String("0x10001"));
1163 QCOMPARE(str8.toUInt16(), quint16(1));
1164 QCOMPARE(qjsvalue_cast<quint16>(str8), quint16(1));
1168 QJSValue zer0 = QJSValue(0.0);
1169 QCOMPARE(zer0.toUInt16(), quint16(0));
1170 QCOMPARE(qjsvalue_cast<quint16>(zer0), quint16(0));
1172 QJSValue number = QJSValue(123.0);
1173 QCOMPARE(number.toUInt16(), quint16(123));
1174 QCOMPARE(qjsvalue_cast<quint16>(number), quint16(123));
1176 QJSValue number2 = QJSValue(qSNaN());
1177 QCOMPARE(number2.toUInt16(), quint16(0));
1178 QCOMPARE(qjsvalue_cast<quint16>(number2), quint16(0));
1180 QJSValue number3 = QJSValue(+qInf());
1181 QCOMPARE(number3.toUInt16(), quint16(0));
1182 QCOMPARE(qjsvalue_cast<quint16>(number3), quint16(0));
1184 QJSValue number3_2 = QJSValue(-qInf());
1185 QCOMPARE(number3_2.toUInt16(), quint16(0));
1186 QCOMPARE(qjsvalue_cast<quint16>(number3_2), quint16(0));
1188 QJSValue number4 = QJSValue(0.5);
1189 QCOMPARE(number4.toUInt16(), quint16(0));
1191 QJSValue number5 = QJSValue(123.5);
1192 QCOMPARE(number5.toUInt16(), quint16(123));
1194 QJSValue number6 = QJSValue(-456.5);
1195 QCOMPARE(number6.toUInt16(), quint16(-456));
1196 QCOMPARE(qjsvalue_cast<quint16>(number6), quint16(-456));
1198 QJSValue number7 = QJSValue(0x10000);
1199 QCOMPARE(number7.toUInt16(), quint16(0));
1200 QCOMPARE(qjsvalue_cast<quint16>(number7), quint16(0));
1202 QJSValue number8 = QJSValue(0x10001);
1203 QCOMPARE(number8.toUInt16(), quint16(1));
1204 QCOMPARE(qjsvalue_cast<quint16>(number8), quint16(1));
1206 QJSValue str = QJSValue(QLatin1String("123.0"));
1207 QCOMPARE(str.toUInt16(), quint16(123));
1208 QCOMPARE(qjsvalue_cast<quint16>(str), quint16(123));
1210 QJSValue str2 = QJSValue(QLatin1String("NaN"));
1211 QCOMPARE(str2.toUInt16(), quint16(0));
1212 QCOMPARE(qjsvalue_cast<quint16>(str2), quint16(0));
1214 QJSValue str3 = QJSValue(QLatin1String("Infinity"));
1215 QCOMPARE(str3.toUInt16(), quint16(0));
1216 QCOMPARE(qjsvalue_cast<quint16>(str3), quint16(0));
1218 QJSValue str3_2 = QJSValue(QLatin1String("-Infinity"));
1219 QCOMPARE(str3_2.toUInt16(), quint16(0));
1220 QCOMPARE(qjsvalue_cast<quint16>(str3_2), quint16(0));
1222 QJSValue str4 = QJSValue("0.5");
1223 QCOMPARE(str4.toUInt16(), quint16(0));
1225 QJSValue str5 = QJSValue("123.5");
1226 QCOMPARE(str5.toUInt16(), quint16(123));
1228 QJSValue str6 = QJSValue("-456.5");
1229 QCOMPARE(str6.toUInt16(), quint16(-456));
1230 QCOMPARE(qjsvalue_cast<quint16>(str6), quint16(-456));
1232 QJSValue str7 = QJSValue("0x10000");
1233 QCOMPARE(str7.toUInt16(), quint16(0));
1234 QCOMPARE(qjsvalue_cast<quint16>(str7), quint16(0));
1236 QJSValue str8 = QJSValue("0x10001");
1237 QCOMPARE(str8.toUInt16(), quint16(1));
1238 QCOMPARE(qjsvalue_cast<quint16>(str8), quint16(1));
1242 QCOMPARE(inv.toUInt16(), quint16(0));
1243 QCOMPARE(qjsvalue_cast<quint16>(inv), quint16(0));
1246 #if defined Q_CC_MSVC && _MSC_VER < 1300
1247 Q_DECLARE_METATYPE(QVariant)
1250 void tst_QJSValue::toVariant()
1254 QJSValue undefined = eng.undefinedValue();
1255 QCOMPARE(undefined.toVariant(), QVariant());
1256 QCOMPARE(qjsvalue_cast<QVariant>(undefined), QVariant());
1258 QJSValue null = eng.nullValue();
1259 QCOMPARE(null.toVariant(), QVariant());
1260 QCOMPARE(qjsvalue_cast<QVariant>(null), QVariant());
1263 QJSValue number = QJSValue(&eng, 123.0);
1264 QCOMPARE(number.toVariant(), QVariant(123.0));
1265 QCOMPARE(qjsvalue_cast<QVariant>(number), QVariant(123.0));
1267 QJSValue intNumber = QJSValue(&eng, (qint32)123);
1268 QCOMPARE(intNumber.toVariant().type(), QVariant((qint32)123).type());
1269 QCOMPARE((qjsvalue_cast<QVariant>(number)).type(), QVariant((qint32)123).type());
1271 QJSValue falskt = QJSValue(&eng, false);
1272 QCOMPARE(falskt.toVariant(), QVariant(false));
1273 QCOMPARE(qjsvalue_cast<QVariant>(falskt), QVariant(false));
1275 QJSValue sant = QJSValue(&eng, true);
1276 QCOMPARE(sant.toVariant(), QVariant(true));
1277 QCOMPARE(qjsvalue_cast<QVariant>(sant), QVariant(true));
1279 QJSValue str = QJSValue(&eng, QString("ciao"));
1280 QCOMPARE(str.toVariant(), QVariant(QString("ciao")));
1281 QCOMPARE(qjsvalue_cast<QVariant>(str), QVariant(QString("ciao")));
1284 QVariant var(QChar(0x007A));
1285 QJSValue opaque = eng.newVariant(var);
1286 QVERIFY(opaque.isVariant());
1287 QCOMPARE(opaque.toVariant(), var);
1289 QJSValue object = eng.newObject();
1290 QCOMPARE(object.toVariant(), QVariant(QVariantMap()));
1292 QJSValue qobject = eng.newQObject(this);
1294 QVariant var = qobject.toVariant();
1295 QCOMPARE(var.userType(), int(QMetaType::QObjectStar));
1296 QCOMPARE(qVariantValue<QObject*>(var), (QObject *)this);
1300 QDateTime dateTime = QDateTime(QDate(1980, 10, 4));
1301 QJSValue dateObject = eng.newDate(dateTime);
1302 QVariant var = dateObject.toVariant();
1303 QCOMPARE(var, QVariant(dateTime));
1307 QRegExp rx = QRegExp("[0-9a-z]+", Qt::CaseSensitive, QRegExp::RegExp2);
1308 QJSValue rxObject = eng.newRegExp(rx);
1309 QVariant var = rxObject.toVariant();
1310 QCOMPARE(var, QVariant(rx));
1314 QCOMPARE(inv.toVariant(), QVariant());
1315 QCOMPARE(qjsvalue_cast<QVariant>(inv), QVariant());
1319 QJSValue number = QJSValue(123.0);
1320 QCOMPARE(number.toVariant(), QVariant(123.0));
1321 QCOMPARE(qjsvalue_cast<QVariant>(number), QVariant(123.0));
1323 QJSValue falskt = QJSValue(false);
1324 QCOMPARE(falskt.toVariant(), QVariant(false));
1325 QCOMPARE(qjsvalue_cast<QVariant>(falskt), QVariant(false));
1327 QJSValue sant = QJSValue(true);
1328 QCOMPARE(sant.toVariant(), QVariant(true));
1329 QCOMPARE(qjsvalue_cast<QVariant>(sant), QVariant(true));
1331 QJSValue str = QJSValue(QString("ciao"));
1332 QCOMPARE(str.toVariant(), QVariant(QString("ciao")));
1333 QCOMPARE(qjsvalue_cast<QVariant>(str), QVariant(QString("ciao")));
1336 #if 0 // FIXME: No automatic sequence conversion
1339 QVariantList listIn;
1340 listIn << 123 << "hello";
1341 QJSValue array = qScriptValueFromValue(&eng, listIn);
1342 QVERIFY(array.isArray());
1343 QCOMPARE(array.property("length").toInt32(), 2);
1344 QVariant ret = array.toVariant();
1345 QCOMPARE(ret.type(), QVariant::List);
1346 QVariantList listOut = ret.toList();
1347 QCOMPARE(listOut.size(), listIn.size());
1348 for (int i = 0; i < listIn.size(); ++i)
1349 QVERIFY(listOut.at(i) == listIn.at(i));
1350 // round-trip conversion
1351 QJSValue array2 = qScriptValueFromValue(&eng, ret);
1352 QVERIFY(array2.isArray());
1353 QCOMPARE(array2.property("length").toInt32(), array.property("length").toInt32());
1354 for (int i = 0; i < array.property("length").toInt32(); ++i)
1355 QVERIFY(array2.property(i).strictlyEquals(array.property(i)));
1360 void tst_QJSValue::toQObject_nonQObject_data()
1363 QTest::addColumn<QJSValue>("value");
1365 QTest::newRow("invalid") << QJSValue();
1366 QTest::newRow("bool(false)") << QJSValue(false);
1367 QTest::newRow("bool(true)") << QJSValue(true);
1368 QTest::newRow("int") << QJSValue(123);
1369 QTest::newRow("string") << QJSValue(QString::fromLatin1("ciao"));
1370 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
1371 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
1373 QTest::newRow("bool bound(false)") << QJSValue(engine, false);
1374 QTest::newRow("bool bound(true)") << QJSValue(engine, true);
1375 QTest::newRow("int bound") << QJSValue(engine, 123);
1376 QTest::newRow("string bound") << QJSValue(engine, QString::fromLatin1("ciao"));
1377 QTest::newRow("undefined bound") << engine->undefinedValue();
1378 QTest::newRow("null bound") << engine->nullValue();
1379 QTest::newRow("object") << engine->newObject();
1380 QTest::newRow("array") << engine->newArray();
1381 QTest::newRow("date") << engine->newDate(124);
1382 QTest::newRow("variant(12345)") << engine->newVariant(12345);
1383 QTest::newRow("variant((QObject*)0)") << engine->newVariant(qVariantFromValue((QObject*)0));
1384 QTest::newRow("newQObject(0)") << engine->newQObject(0);
1388 void tst_QJSValue::toQObject_nonQObject()
1390 QFETCH(QJSValue, value);
1391 QCOMPARE(value.toQObject(), (QObject *)0);
1392 QCOMPARE(qjsvalue_cast<QObject*>(value), (QObject *)0);
1395 // unfortunately, this is necessary in order to do qscriptvalue_cast<QPushButton*>(...)
1396 Q_DECLARE_METATYPE(QPushButton*);
1398 void tst_QJSValue::toQObject()
1402 QJSValue qobject = eng.newQObject(this);
1403 QCOMPARE(qobject.toQObject(), (QObject *)this);
1404 QCOMPARE(qjsvalue_cast<QObject*>(qobject), (QObject *)this);
1405 QCOMPARE(qjsvalue_cast<QWidget*>(qobject), (QWidget *)0);
1408 QJSValue qwidget = eng.newQObject(&widget);
1409 QCOMPARE(qwidget.toQObject(), (QObject *)&widget);
1410 QCOMPARE(qjsvalue_cast<QObject*>(qwidget), (QObject *)&widget);
1411 QCOMPARE(qjsvalue_cast<QWidget*>(qwidget), &widget);
1414 QJSValue qbutton = eng.newQObject(&button);
1415 QCOMPARE(qbutton.toQObject(), (QObject *)&button);
1416 QCOMPARE(qjsvalue_cast<QObject*>(qbutton), (QObject *)&button);
1417 QCOMPARE(qjsvalue_cast<QWidget*>(qbutton), (QWidget *)&button);
1418 QCOMPARE(qjsvalue_cast<QPushButton*>(qbutton), &button);
1420 // wrapping a QObject* as variant
1421 QJSValue variant = eng.newVariant(qVariantFromValue((QObject*)&button));
1422 QCOMPARE(variant.toQObject(), (QObject*)&button);
1423 QCOMPARE(qjsvalue_cast<QObject*>(variant), (QObject*)&button);
1424 QCOMPARE(qjsvalue_cast<QWidget*>(variant), (QWidget*)&button);
1425 QCOMPARE(qjsvalue_cast<QPushButton*>(variant), &button);
1427 QJSValue variant2 = eng.newVariant(qVariantFromValue((QWidget*)&button));
1428 QCOMPARE(variant2.toQObject(), (QObject*)&button);
1429 QCOMPARE(qjsvalue_cast<QObject*>(variant2), (QObject*)&button);
1430 QCOMPARE(qjsvalue_cast<QWidget*>(variant2), (QWidget*)&button);
1431 QCOMPARE(qjsvalue_cast<QPushButton*>(variant2), &button);
1433 QJSValue variant3 = eng.newVariant(qVariantFromValue(&button));
1434 QCOMPARE(variant3.toQObject(), (QObject*)0);
1435 QCOMPARE(qjsvalue_cast<QObject*>(variant3), (QObject*)0);
1436 QCOMPARE(qjsvalue_cast<QWidget*>(variant3), (QWidget*)0);
1437 QCOMPARE(qjsvalue_cast<QPushButton*>(variant3), &button);
1440 void tst_QJSValue::toObject()
1444 QJSValue undefined = eng.undefinedValue();
1445 QCOMPARE(undefined.toObject().isValid(), false);
1446 QVERIFY(undefined.isUndefined());
1448 QJSValue null = eng.nullValue();
1449 QCOMPARE(null.toObject().isValid(), false);
1450 QVERIFY(null.isNull());
1453 QJSValue falskt = QJSValue(&eng, false);
1455 QJSValue tmp = falskt.toObject();
1456 QCOMPARE(tmp.isObject(), true);
1457 QCOMPARE(tmp.toNumber(), falskt.toNumber());
1459 QVERIFY(falskt.isBool());
1461 QJSValue sant = QJSValue(&eng, true);
1463 QJSValue tmp = sant.toObject();
1464 QCOMPARE(tmp.isObject(), true);
1465 QCOMPARE(tmp.toNumber(), sant.toNumber());
1467 QVERIFY(sant.isBool());
1469 QJSValue number = QJSValue(&eng, 123.0);
1471 QJSValue tmp = number.toObject();
1472 QCOMPARE(tmp.isObject(), true);
1473 QCOMPARE(tmp.toNumber(), number.toNumber());
1475 QVERIFY(number.isNumber());
1477 QJSValue str = QJSValue(&eng, QString("ciao"));
1479 QJSValue tmp = str.toObject();
1480 QCOMPARE(tmp.isObject(), true);
1481 QCOMPARE(tmp.toString(), str.toString());
1483 QVERIFY(str.isString());
1486 QJSValue object = eng.newObject();
1488 QJSValue tmp = object.toObject();
1489 QCOMPARE(tmp.isObject(), true);
1492 QJSValue qobject = eng.newQObject(this);
1493 QCOMPARE(qobject.toObject().isValid(), true);
1496 QCOMPARE(inv.toObject().isValid(), false);
1498 // V2 constructors: in this case, you have to use QScriptEngine::toObject()
1500 QJSValue undefined = QJSValue(QJSValue::UndefinedValue);
1501 QVERIFY(!undefined.toObject().isValid());
1502 QVERIFY(!eng.toObject(undefined).isValid());
1503 QVERIFY(undefined.isUndefined());
1505 QJSValue null = QJSValue(QJSValue::NullValue);
1506 QVERIFY(!null.toObject().isValid());
1507 QVERIFY(!eng.toObject(null).isValid());
1508 QVERIFY(null.isNull());
1510 QJSValue falskt = QJSValue(false);
1511 QVERIFY(!falskt.toObject().isValid());
1513 QJSValue tmp = eng.toObject(falskt);
1514 QVERIFY(tmp.isObject());
1515 QVERIFY(tmp.toBool());
1517 QVERIFY(falskt.isBool());
1519 QJSValue sant = QJSValue(true);
1520 QVERIFY(!sant.toObject().isValid());
1522 QJSValue tmp = eng.toObject(sant);
1523 QVERIFY(tmp.isObject());
1524 QVERIFY(tmp.toBool());
1526 QVERIFY(sant.isBool());
1528 QJSValue number = QJSValue(123.0);
1529 QVERIFY(!number.toObject().isValid());
1531 QJSValue tmp = eng.toObject(number);
1532 QVERIFY(tmp.isObject());
1533 QCOMPARE(tmp.toInt32(), number.toInt32());
1535 QVERIFY(number.isNumber());
1537 QJSValue str = QJSValue(QString::fromLatin1("ciao"));
1538 QVERIFY(!str.toObject().isValid());
1540 QJSValue tmp = eng.toObject(str);
1541 QVERIFY(tmp.isObject());
1542 QCOMPARE(tmp.toString(), QString::fromLatin1("ciao"));
1544 QVERIFY(str.isString());
1548 void tst_QJSValue::toDateTime()
1551 QDateTime dt = eng.evaluate("new Date(0)").toDateTime();
1552 QVERIFY(dt.isValid());
1553 QCOMPARE(dt.timeSpec(), Qt::LocalTime);
1554 QCOMPARE(dt.toUTC(), QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::UTC));
1556 QVERIFY(!eng.evaluate("[]").toDateTime().isValid());
1557 QVERIFY(!eng.evaluate("{}").toDateTime().isValid());
1558 QVERIFY(!eng.globalObject().toDateTime().isValid());
1559 QVERIFY(!QJSValue().toDateTime().isValid());
1560 QVERIFY(!QJSValue(123).toDateTime().isValid());
1561 QVERIFY(!QJSValue(false).toDateTime().isValid());
1562 QVERIFY(!eng.nullValue().toDateTime().isValid());
1563 QVERIFY(!eng.undefinedValue().toDateTime().isValid());
1566 void tst_QJSValue::toRegExp()
1570 QRegExp rx = eng.evaluate("/foo/").toRegExp();
1571 QVERIFY(rx.isValid());
1572 QCOMPARE(rx.patternSyntax(), QRegExp::RegExp2);
1573 QCOMPARE(rx.pattern(), QString::fromLatin1("foo"));
1574 QCOMPARE(rx.caseSensitivity(), Qt::CaseSensitive);
1575 QVERIFY(!rx.isMinimal());
1578 QRegExp rx = eng.evaluate("/bar/gi").toRegExp();
1579 QVERIFY(rx.isValid());
1580 QCOMPARE(rx.patternSyntax(), QRegExp::RegExp2);
1581 QCOMPARE(rx.pattern(), QString::fromLatin1("bar"));
1582 QCOMPARE(rx.caseSensitivity(), Qt::CaseInsensitive);
1583 QVERIFY(!rx.isMinimal());
1586 QVERIFY(eng.evaluate("[]").toRegExp().isEmpty());
1587 QVERIFY(eng.evaluate("{}").toRegExp().isEmpty());
1588 QVERIFY(eng.globalObject().toRegExp().isEmpty());
1589 QVERIFY(QJSValue().toRegExp().isEmpty());
1590 QVERIFY(QJSValue(123).toRegExp().isEmpty());
1591 QVERIFY(QJSValue(false).toRegExp().isEmpty());
1592 QVERIFY(eng.nullValue().toRegExp().isEmpty());
1593 QVERIFY(eng.undefinedValue().toRegExp().isEmpty());
1596 void tst_QJSValue::instanceOf_twoEngines()
1599 QJSValue obj = eng.newObject();
1600 QJSEngine otherEngine;
1601 QTest::ignoreMessage(QtWarningMsg, "QJSValue::instanceof: cannot perform operation on a value created in a different engine");
1602 QCOMPARE(obj.instanceOf(otherEngine.globalObject().property("Object")), false);
1605 void tst_QJSValue::instanceOf()
1608 QJSValue obj = eng.newObject();
1609 QCOMPARE(obj.instanceOf(eng.evaluate("Object.prototype")), false);
1610 QCOMPARE(obj.instanceOf(eng.evaluate("Array.prototype")), false);
1611 QCOMPARE(obj.instanceOf(eng.evaluate("Function.prototype")), false);
1612 QCOMPARE(obj.instanceOf(eng.evaluate("QObject.prototype")), false);
1613 QCOMPARE(obj.instanceOf(QJSValue(&eng, 123)), false);
1614 QCOMPARE(obj.instanceOf(eng.undefinedValue()), false);
1615 QCOMPARE(obj.instanceOf(eng.nullValue()), false);
1616 QCOMPARE(obj.instanceOf(QJSValue()), false);
1618 QCOMPARE(obj.instanceOf(eng.evaluate("Object")), true);
1619 QCOMPARE(obj.instanceOf(eng.evaluate("Array")), false);
1620 QCOMPARE(obj.instanceOf(eng.evaluate("Function")), false);
1621 QCOMPARE(obj.instanceOf(eng.evaluate("QObject")), false);
1623 QJSValue arr = eng.newArray();
1624 QVERIFY(arr.isArray());
1625 QCOMPARE(arr.instanceOf(eng.evaluate("Object.prototype")), false);
1626 QCOMPARE(arr.instanceOf(eng.evaluate("Array.prototype")), false);
1627 QCOMPARE(arr.instanceOf(eng.evaluate("Function.prototype")), false);
1628 QCOMPARE(arr.instanceOf(eng.evaluate("QObject.prototype")), false);
1629 QCOMPARE(arr.instanceOf(eng.evaluate("Object")), true);
1630 QCOMPARE(arr.instanceOf(eng.evaluate("Array")), true);
1631 QCOMPARE(arr.instanceOf(eng.evaluate("Function")), false);
1632 QCOMPARE(arr.instanceOf(eng.evaluate("QObject")), false);
1634 QCOMPARE(QJSValue().instanceOf(arr), false);
1637 void tst_QJSValue::isArray_data()
1641 QTest::addColumn<QJSValue>("value");
1642 QTest::addColumn<bool>("array");
1644 QTest::newRow("[]") << engine->evaluate("[]") << true;
1645 QTest::newRow("{}") << engine->evaluate("{}") << false;
1646 QTest::newRow("globalObject") << engine->globalObject() << false;
1647 QTest::newRow("invalid") << QJSValue() << false;
1648 QTest::newRow("number") << QJSValue(123) << false;
1649 QTest::newRow("bool") << QJSValue(false) << false;
1650 QTest::newRow("null") << engine->nullValue() << false;
1651 QTest::newRow("undefined") << engine->undefinedValue() << false;
1654 void tst_QJSValue::isArray()
1656 QFETCH(QJSValue, value);
1657 QFETCH(bool, array);
1659 QCOMPARE(value.isArray(), array);
1662 void tst_QJSValue::isDate_data()
1666 QTest::addColumn<QJSValue>("value");
1667 QTest::addColumn<bool>("date");
1669 QTest::newRow("date") << engine->evaluate("new Date()") << true;
1670 QTest::newRow("[]") << engine->evaluate("[]") << false;
1671 QTest::newRow("{}") << engine->evaluate("{}") << false;
1672 QTest::newRow("globalObject") << engine->globalObject() << false;
1673 QTest::newRow("invalid") << QJSValue() << false;
1674 QTest::newRow("number") << QJSValue(123) << false;
1675 QTest::newRow("bool") << QJSValue(false) << false;
1676 QTest::newRow("null") << engine->nullValue() << false;
1677 QTest::newRow("undefined") << engine->undefinedValue() << false;
1680 void tst_QJSValue::isDate()
1682 QFETCH(QJSValue, value);
1685 QCOMPARE(value.isDate(), date);
1688 void tst_QJSValue::isError_propertiesOfGlobalObject()
1699 for (int i = 0; i < errors.size(); ++i) {
1700 QJSValue ctor = eng.globalObject().property(errors.at(i));
1701 QVERIFY(ctor.isFunction());
1702 QVERIFY(ctor.property("prototype").isError());
1706 void tst_QJSValue::isError_data()
1710 QTest::addColumn<QJSValue>("value");
1711 QTest::addColumn<bool>("error");
1713 QTest::newRow("syntax error") << engine->evaluate("%fsdg's") << true;
1714 QTest::newRow("[]") << engine->evaluate("[]") << false;
1715 QTest::newRow("{}") << engine->evaluate("{}") << false;
1716 QTest::newRow("globalObject") << engine->globalObject() << false;
1717 QTest::newRow("invalid") << QJSValue() << false;
1718 QTest::newRow("number") << QJSValue(123) << false;
1719 QTest::newRow("bool") << QJSValue(false) << false;
1720 QTest::newRow("null") << engine->nullValue() << false;
1721 QTest::newRow("undefined") << engine->undefinedValue() << false;
1722 QTest::newRow("newObject") << engine->newObject() << false;
1723 QTest::newRow("new Object") << engine->evaluate("new Object()") << false;
1726 void tst_QJSValue::isError()
1728 QFETCH(QJSValue, value);
1729 QFETCH(bool, error);
1731 QCOMPARE(value.isError(), error);
1734 void tst_QJSValue::isRegExp_data()
1738 QTest::addColumn<QJSValue>("value");
1739 QTest::addColumn<bool>("regexp");
1741 QTest::newRow("/foo/") << engine->evaluate("/foo/") << true;
1742 QTest::newRow("[]") << engine->evaluate("[]") << false;
1743 QTest::newRow("{}") << engine->evaluate("{}") << false;
1744 QTest::newRow("globalObject") << engine->globalObject() << false;
1745 QTest::newRow("invalid") << QJSValue() << false;
1746 QTest::newRow("number") << QJSValue(123) << false;
1747 QTest::newRow("bool") << QJSValue(false) << false;
1748 QTest::newRow("null") << engine->nullValue() << false;
1749 QTest::newRow("undefined") << engine->undefinedValue() << false;
1752 void tst_QJSValue::isRegExp()
1754 QFETCH(QJSValue, value);
1755 QFETCH(bool, regexp);
1757 QCOMPARE(value.isRegExp(), regexp);
1760 #if 0 // FIXME: No c-style callbacks currently
1761 static QJSValue getter(QScriptContext *ctx, QScriptEngine *)
1763 return ctx->thisObject().property("x");
1766 static QJSValue setter(QScriptContext *ctx, QScriptEngine *)
1768 ctx->thisObject().setProperty("x", ctx->argument(0));
1769 return ctx->argument(0);
1772 static QJSValue getterSetter(QScriptContext *ctx, QScriptEngine *)
1774 if (ctx->argumentCount() > 0)
1775 ctx->thisObject().setProperty("x", ctx->argument(0));
1776 return ctx->thisObject().property("x");
1779 static QJSValue getterSetterThrowingError(QScriptContext *ctx, QScriptEngine *)
1781 if (ctx->argumentCount() > 0)
1782 return ctx->throwError("set foo");
1784 return ctx->throwError("get foo");
1787 static QJSValue getSet__proto__(QScriptContext *ctx, QScriptEngine *)
1789 if (ctx->argumentCount() > 0)
1790 ctx->callee().setProperty("value", ctx->argument(0));
1791 return ctx->callee().property("value");
1795 void tst_QJSValue::getSetProperty_HooliganTask162051()
1798 // task 162051 -- detecting whether the property is an array index or not
1799 QVERIFY(eng.evaluate("a = []; a['00'] = 123; a['00']").strictlyEquals(QJSValue(&eng, 123)));
1800 QVERIFY(eng.evaluate("a.length").strictlyEquals(QJSValue(&eng, 0)));
1801 QVERIFY(eng.evaluate("a.hasOwnProperty('00')").strictlyEquals(QJSValue(&eng, true)));
1802 QVERIFY(eng.evaluate("a.hasOwnProperty('0')").strictlyEquals(QJSValue(&eng, false)));
1803 QVERIFY(eng.evaluate("a[0]").isUndefined());
1804 QVERIFY(eng.evaluate("a[0.5] = 456; a[0.5]").strictlyEquals(QJSValue(&eng, 456)));
1805 QVERIFY(eng.evaluate("a.length").strictlyEquals(QJSValue(&eng, 0)));
1806 QVERIFY(eng.evaluate("a.hasOwnProperty('0.5')").strictlyEquals(QJSValue(&eng, true)));
1807 QVERIFY(eng.evaluate("a[0]").isUndefined());
1808 QVERIFY(eng.evaluate("a[0] = 789; a[0]").strictlyEquals(QJSValue(&eng, 789)));
1809 QVERIFY(eng.evaluate("a.length").strictlyEquals(QJSValue(&eng, 1)));
1812 void tst_QJSValue::getSetProperty_HooliganTask183072()
1815 // task 183072 -- 0x800000000 is not an array index
1816 eng.evaluate("a = []; a[0x800000000] = 123");
1817 QVERIFY(eng.evaluate("a.length").strictlyEquals(QJSValue(&eng, 0)));
1818 QVERIFY(eng.evaluate("a[0]").isUndefined());
1819 QVERIFY(eng.evaluate("a[0x800000000]").strictlyEquals(QJSValue(&eng, 123)));
1822 void tst_QJSValue::getSetProperty_propertyRemoval()
1824 // test property removal (setProperty(QJSValue()))
1826 QJSValue object = eng.newObject();
1827 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
1828 QJSValue num = QJSValue(&eng, 123.0);
1830 object.setProperty("foo", num);
1831 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1832 object.setProperty("bar", str);
1833 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1834 object.setProperty("foo", QJSValue());
1835 QCOMPARE(object.property("foo").isValid(), false);
1836 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1837 object.setProperty("foo", num);
1838 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1839 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1840 object.setProperty("bar", QJSValue());
1841 QCOMPARE(object.property("bar").isValid(), false);
1842 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1843 object.setProperty("foo", QJSValue());
1844 object.setProperty("foo", QJSValue());
1846 eng.globalObject().setProperty("object3", object);
1847 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
1848 .strictlyEquals(QJSValue(&eng, false)), true);
1849 object.setProperty("foo", num);
1850 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
1851 .strictlyEquals(QJSValue(&eng, true)), true);
1852 eng.globalObject().setProperty("object3", QJSValue());
1853 QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')")
1854 .strictlyEquals(QJSValue(&eng, false)), true);
1857 void tst_QJSValue::getSetProperty_resolveMode()
1861 QJSValue object = eng.newObject();
1862 QJSValue prototype = eng.newObject();
1863 object.setPrototype(prototype);
1864 QJSValue num2 = QJSValue(&eng, 456.0);
1865 prototype.setProperty("propertyInPrototype", num2);
1866 // default is ResolvePrototype
1867 QCOMPARE(object.property("propertyInPrototype")
1868 .strictlyEquals(num2), true);
1869 #if 0 // FIXME: ResolveFlags removed from API
1870 QCOMPARE(object.property("propertyInPrototype", QJSValue::ResolvePrototype)
1871 .strictlyEquals(num2), true);
1872 QCOMPARE(object.property("propertyInPrototype", QJSValue::ResolveLocal)
1874 QCOMPARE(object.property("propertyInPrototype", QJSValue::ResolveScope)
1875 .strictlyEquals(num2), false);
1876 QCOMPARE(object.property("propertyInPrototype", QJSValue::ResolveFull)
1877 .strictlyEquals(num2), true);
1881 void tst_QJSValue::getSetProperty_twoEngines()
1884 QJSValue object = engine.newObject();
1886 QJSEngine otherEngine;
1887 QJSValue otherNum = QJSValue(&otherEngine, 123);
1888 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setProperty(oof) failed: cannot set value created in a different engine");
1889 object.setProperty("oof", otherNum);
1890 QCOMPARE(object.property("oof").isValid(), false);
1894 void tst_QJSValue::getSetProperty_gettersAndSetters()
1896 #if 0 // FIXME: No setters/getters right now
1898 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
1899 QJSValue num = QJSValue(&eng, 123.0);
1900 QJSValue object = eng.newObject();
1901 for (int x = 0; x < 2; ++x) {
1902 object.setProperty("foo", QJSValue());
1903 // getter() returns this.x
1904 object.setProperty("foo", eng.newFunction(getter),
1905 QJSValue::PropertyGetter | QJSValue::UserRange);
1906 QCOMPARE(object.propertyFlags("foo") & ~QJSValue::UserRange,
1907 QJSValue::PropertyGetter );
1909 QEXPECT_FAIL("", "QTBUG-17615: User-range flags are not retained for getter/setter properties", Continue);
1910 QCOMPARE(object.propertyFlags("foo"),
1911 QJSValue::PropertyGetter | QJSValue::UserRange);
1912 object.setProperty("x", num);
1913 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1915 // setter() sets this.x
1916 object.setProperty("foo", eng.newFunction(setter),
1917 QJSValue::PropertySetter);
1918 QCOMPARE(object.propertyFlags("foo") & ~QJSValue::UserRange,
1919 QJSValue::PropertySetter | QJSValue::PropertyGetter);
1921 QCOMPARE(object.propertyFlags("foo"),
1922 QJSValue::PropertySetter | QJSValue::PropertyGetter);
1923 object.setProperty("foo", str);
1924 QCOMPARE(object.property("x").strictlyEquals(str), true);
1925 QCOMPARE(object.property("foo").strictlyEquals(str), true);
1928 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
1929 QVERIFY(!(object.propertyFlags("foo") & QJSValue::PropertyGetter));
1930 QVERIFY(object.propertyFlags("foo") & QJSValue::PropertySetter);
1931 QCOMPARE(object.property("foo").isUndefined(), true);
1933 // setter should still work
1934 object.setProperty("foo", num);
1935 QCOMPARE(object.property("x").strictlyEquals(num), true);
1937 // kill the setter too
1938 object.setProperty("foo", QJSValue(), QJSValue::PropertySetter);
1939 QVERIFY(!(object.propertyFlags("foo") & QJSValue::PropertySetter));
1940 // now foo is just a regular property
1941 object.setProperty("foo", str);
1942 QCOMPARE(object.property("x").strictlyEquals(num), true);
1943 QCOMPARE(object.property("foo").strictlyEquals(str), true);
1946 for (int x = 0; x < 2; ++x) {
1947 object.setProperty("foo", QJSValue());
1948 // setter() sets this.x
1949 object.setProperty("foo", eng.newFunction(setter), QJSValue::PropertySetter);
1950 object.setProperty("foo", str);
1951 QCOMPARE(object.property("x").strictlyEquals(str), true);
1952 QCOMPARE(object.property("foo").isUndefined(), true);
1954 // getter() returns this.x
1955 object.setProperty("foo", eng.newFunction(getter), QJSValue::PropertyGetter);
1956 object.setProperty("x", num);
1957 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1960 object.setProperty("foo", QJSValue(), QJSValue::PropertySetter);
1961 object.setProperty("foo", str);
1963 // getter should still work
1964 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1966 // kill the getter too
1967 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
1968 // now foo is just a regular property
1969 object.setProperty("foo", str);
1970 QCOMPARE(object.property("x").strictlyEquals(num), true);
1971 QCOMPARE(object.property("foo").strictlyEquals(str), true);
1974 // use a single function as both getter and setter
1975 object.setProperty("foo", QJSValue());
1976 object.setProperty("foo", eng.newFunction(getterSetter),
1977 QJSValue::PropertyGetter | QJSValue::PropertySetter);
1978 QCOMPARE(object.propertyFlags("foo"),
1979 QJSValue::PropertyGetter | QJSValue::PropertySetter);
1980 object.setProperty("x", num);
1981 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1983 // killing the getter will preserve the setter, even though they are the same function
1984 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
1985 QVERIFY(object.propertyFlags("foo") & QJSValue::PropertySetter);
1986 QCOMPARE(object.property("foo").isUndefined(), true);
1990 void tst_QJSValue::getSetProperty_gettersAndSettersThrowErrorNative()
1992 #if 0 // FIXME: No setters/getters right now
1993 // getter/setter that throws an error
1995 QJSValue str = QJSValue(&eng, "bar");
1996 QJSValue object = eng.newObject();
1998 object.setProperty("foo", eng.newFunction(getterSetterThrowingError),
1999 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2000 QVERIFY(!eng.hasUncaughtException());
2001 QJSValue ret = object.property("foo");
2002 QVERIFY(ret.isError());
2003 QVERIFY(eng.hasUncaughtException());
2004 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
2005 QCOMPARE(ret.toString(), QLatin1String("Error: get foo"));
2006 eng.evaluate("Object"); // clear exception state...
2007 QVERIFY(!eng.hasUncaughtException());
2008 object.setProperty("foo", str);
2009 QVERIFY(eng.hasUncaughtException());
2010 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
2014 void tst_QJSValue::getSetProperty_gettersAndSettersThrowErrorJS()
2016 // getter/setter that throws an error (from js function)
2018 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
2020 eng.evaluate("o = new Object; "
2021 "o.__defineGetter__('foo', function() { throw new Error('get foo') }); "
2022 "o.__defineSetter__('foo', function() { throw new Error('set foo') }); ");
2023 QJSValue object = eng.evaluate("o");
2024 QVERIFY(!eng.hasUncaughtException());
2025 QJSValue ret = object.property("foo");
2026 QVERIFY(ret.isError());
2027 QVERIFY(eng.hasUncaughtException());
2028 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
2029 QCOMPARE(ret.toString(), QLatin1String("Error: get foo"));
2030 eng.evaluate("Object"); // clear exception state...
2031 QVERIFY(!eng.hasUncaughtException());
2032 object.setProperty("foo", str);
2033 QVERIFY(eng.hasUncaughtException());
2034 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
2037 void tst_QJSValue::getSetProperty_gettersAndSettersOnNative()
2039 #if 0 // FIXME: No c-style functions right now
2040 // attempt to install getter+setter on built-in (native) property
2042 QJSValue object = eng.newObject();
2043 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2045 QJSValue fun = eng.newFunction(getSet__proto__);
2046 fun.setProperty("value", QJSValue(&eng, "boo"));
2047 /* QTest::ignoreMessage(QtWarningMsg, "QJSValue::setProperty() failed: "
2048 "cannot set getter or setter of native property "
2050 object.setProperty("__proto__", fun,
2051 QJSValue::PropertyGetter | QJSValue::PropertySetter
2052 | QJSValue::UserRange);
2053 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2055 object.setProperty("__proto__", QJSValue(),
2056 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2057 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2061 void tst_QJSValue::getSetProperty_gettersAndSettersOnGlobalObject()
2063 #if 0 // FIXME: No c-style functions right now
2064 // global property that's a getter+setter
2066 eng.globalObject().setProperty("globalGetterSetterProperty", eng.newFunction(getterSetter),
2067 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2068 eng.evaluate("globalGetterSetterProperty = 123");
2070 QJSValue ret = eng.evaluate("globalGetterSetterProperty");
2071 QVERIFY(ret.isNumber());
2072 QVERIFY(ret.strictlyEquals(QJSValue(&eng, 123)));
2074 QCOMPARE(eng.evaluate("typeof globalGetterSetterProperty").toString(),
2075 QString::fromLatin1("number"));
2077 QJSValue ret = eng.evaluate("this.globalGetterSetterProperty()");
2078 QVERIFY(ret.isError());
2079 QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Property 'globalGetterSetterProperty' of object #<Object> is not a function"));
2082 QJSValue ret = eng.evaluate("new this.globalGetterSetterProperty()");
2083 QVERIFY(ret.isError());
2084 QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: number is not a function"));
2089 void tst_QJSValue::getSetProperty_gettersAndSettersChange()
2091 #if 0 // FIXME: No setters/getters API right now
2092 // "upgrading" an existing property to become a getter+setter
2094 QJSValue object = eng.newObject();
2095 QJSValue num(&eng, 123);
2096 object.setProperty("foo", num);
2097 object.setProperty("foo", eng.newFunction(getterSetter),
2098 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2099 QVERIFY(!object.property("x").isValid());
2100 object.setProperty("foo", num);
2101 QVERIFY(object.property("x").equals(num));
2103 eng.globalObject().setProperty("object", object);
2104 QJSValue res = eng.evaluate("object.x = 89; var a = object.foo; object.foo = 65; a");
2105 QCOMPARE(res.toInt32(), 89);
2106 QCOMPARE(object.property("x").toInt32(), 65);
2107 QCOMPARE(object.property("foo").toInt32(), 65);
2111 void tst_QJSValue::getSetProperty_array()
2114 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
2115 QJSValue num = QJSValue(&eng, 123.0);
2116 QJSValue array = eng.newArray();
2118 QVERIFY(array.isArray());
2119 array.setProperty(0, num);
2120 QCOMPARE(array.property(0).toNumber(), num.toNumber());
2121 QCOMPARE(array.property("0").toNumber(), num.toNumber());
2122 QCOMPARE(array.property("length").toUInt32(), quint32(1));
2123 array.setProperty(1, str);
2124 QCOMPARE(array.property(1).toString(), str.toString());
2125 QCOMPARE(array.property("1").toString(), str.toString());
2126 QCOMPARE(array.property("length").toUInt32(), quint32(2));
2127 array.setProperty("length", QJSValue(&eng, 1));
2128 QCOMPARE(array.property("length").toUInt32(), quint32(1));
2129 QCOMPARE(array.property(1).isValid(), false);
2132 void tst_QJSValue::getSetProperty_gettersAndSettersStupid()
2134 #if 0 // FIXME: No setters/getters API right now
2135 //removing unexisting Setter or Getter should not crash.
2137 QJSValue num = QJSValue(&eng, 123.0);
2140 QJSValue object = eng.newObject();
2141 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
2142 QVERIFY(!object.property("foo").isValid());
2143 object.setProperty("foo", num);
2144 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2148 QJSValue object = eng.newObject();
2149 object.setProperty("foo", QJSValue(), QJSValue::PropertySetter);
2150 QVERIFY(!object.property("foo").isValid());
2151 object.setProperty("foo", num);
2152 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2156 QJSValue object = eng.globalObject();
2157 object.setProperty("foo", QJSValue(), QJSValue::PropertySetter);
2158 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
2159 QVERIFY(!object.property("foo").isValid());
2160 object.setProperty("foo", num);
2161 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2166 void tst_QJSValue::getSetProperty()
2170 QJSValue object = eng.newObject();
2172 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
2173 object.setProperty("foo", str);
2174 QCOMPARE(object.property("foo").toString(), str.toString());
2176 QJSValue num = QJSValue(&eng, 123.0);
2177 object.setProperty("baz", num);
2178 QCOMPARE(object.property("baz").toNumber(), num.toNumber());
2180 QJSValue strstr = QJSValue("bar");
2181 QCOMPARE(strstr.engine(), (QJSEngine *)0);
2182 object.setProperty("foo", strstr);
2183 QCOMPARE(object.property("foo").toString(), strstr.toString());
2184 QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine
2186 QJSValue numnum = QJSValue(123.0);
2187 object.setProperty("baz", numnum);
2188 QCOMPARE(object.property("baz").toNumber(), numnum.toNumber());
2191 inv.setProperty("foo", num);
2192 QCOMPARE(inv.property("foo").isValid(), false);
2194 eng.globalObject().setProperty("object", object);
2196 #if 0 // FIXME: no setProperty API with flags
2198 object.setProperty("readOnlyProperty", num, QJSValue::ReadOnly);
2199 QCOMPARE(object.propertyFlags("readOnlyProperty"), QJSValue::ReadOnly);
2200 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
2201 eng.evaluate("object.readOnlyProperty = !object.readOnlyProperty");
2202 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
2203 // should still be part of enumeration
2205 QJSValue ret = eng.evaluate(
2207 "for (var p in object) {"
2208 " if (p == 'readOnlyProperty') {"
2209 " found = true; break;"
2212 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), true);
2214 // should still be deletable
2216 QJSValue ret = eng.evaluate("delete object.readOnlyProperty");
2217 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), true);
2218 QCOMPARE(object.property("readOnlyProperty").isValid(), false);
2222 object.setProperty("undeletableProperty", num, QJSValue::Undeletable);
2223 QCOMPARE(object.propertyFlags("undeletableProperty"), QJSValue::Undeletable);
2224 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
2226 QJSValue ret = eng.evaluate("delete object.undeletableProperty");
2227 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), false);
2228 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
2230 // should still be writable
2231 eng.evaluate("object.undeletableProperty = object.undeletableProperty + 1");
2232 QCOMPARE(object.property("undeletableProperty").toNumber(), num.toNumber() + 1);
2233 // should still be part of enumeration
2235 QJSValue ret = eng.evaluate(
2237 "for (var p in object) {"
2238 " if (p == 'undeletableProperty') {"
2239 " found = true; break;"
2242 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), true);
2244 // should still be deletable from C++
2245 object.setProperty("undeletableProperty", QJSValue());
2246 QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
2247 QVERIFY(!object.property("undeletableProperty").isValid());
2248 QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
2249 QCOMPARE(object.propertyFlags("undeletableProperty"), 0);
2251 // SkipInEnumeration
2252 object.setProperty("dontEnumProperty", num, QJSValue::SkipInEnumeration);
2253 QCOMPARE(object.propertyFlags("dontEnumProperty"), QJSValue::SkipInEnumeration);
2254 QCOMPARE(object.property("dontEnumProperty").strictlyEquals(num), true);
2255 // should not be part of enumeration
2257 QJSValue ret = eng.evaluate(
2259 "for (var p in object) {"
2260 " if (p == 'dontEnumProperty') {"
2261 " found = true; break;"
2264 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, false)), true);
2266 // should still be writable
2267 eng.evaluate("object.dontEnumProperty = object.dontEnumProperty + 1");
2268 QCOMPARE(object.property("dontEnumProperty").toNumber(), num.toNumber() + 1);
2269 // should still be deletable
2271 QJSValue ret = eng.evaluate("delete object.dontEnumProperty");
2272 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), true);
2273 QCOMPARE(object.property("dontEnumProperty").isValid(), false);
2277 object.setProperty("flagProperty", str);
2278 QCOMPARE(object.propertyFlags("flagProperty"), static_cast<QJSValue::PropertyFlags>(0));
2280 QEXPECT_FAIL("", "FIXME: v8 does not support changing flags of existing properties", Continue);
2281 //v8::i::JSObject::SetProperty(LookupResult* result, ... ) does not take in account the attributes
2282 // if the result->isFound()
2283 object.setProperty("flagProperty", str, QJSValue::ReadOnly);
2284 QCOMPARE(object.propertyFlags("flagProperty"), QJSValue::ReadOnly);
2286 QEXPECT_FAIL("", "FIXME: v8 does not support changing flags of existing properties", Continue);
2287 object.setProperty("flagProperty", str, object.propertyFlags("flagProperty") | QJSValue::SkipInEnumeration);
2288 QCOMPARE(object.propertyFlags("flagProperty"), QJSValue::ReadOnly | QJSValue::SkipInEnumeration);
2290 QEXPECT_FAIL("", "FIXME: v8 does not support changing flags of existing properties", Continue);
2291 object.setProperty("flagProperty", str, QJSValue::KeepExistingFlags);
2292 QCOMPARE(object.propertyFlags("flagProperty"), QJSValue::ReadOnly | QJSValue::SkipInEnumeration);
2294 QEXPECT_FAIL("", "FIXME: v8 does not support UserRange", Continue);
2295 object.setProperty("flagProperty", str, QJSValue::UserRange);
2296 QCOMPARE(object.propertyFlags("flagProperty"), QJSValue::UserRange);
2298 // flags of property in the prototype
2300 QJSValue object2 = eng.newObject();
2301 object2.setPrototype(object);
2302 QCOMPARE(object2.propertyFlags("flagProperty", QJSValue::ResolveLocal), 0);
2303 QEXPECT_FAIL("", "FIXME: v8 does not support UserRange", Continue);
2304 QCOMPARE(object2.propertyFlags("flagProperty"), QJSValue::UserRange);
2307 // using interned strings
2308 QScriptString foo = eng.toStringHandle("foo");
2310 object.setProperty(foo, QJSValue());
2311 QVERIFY(!object.property(foo).isValid());
2313 object.setProperty(foo, num);
2314 QVERIFY(object.property(foo).strictlyEquals(num));
2315 QVERIFY(object.property("foo").strictlyEquals(num));
2316 QVERIFY(object.propertyFlags(foo) == 0);
2319 // Setting index property on non-Array
2320 object.setProperty(13, num);
2321 QVERIFY(object.property(13).equals(num));
2324 void tst_QJSValue::arrayElementGetterSetter()
2326 #if 0 // FIXME: No c-style functions
2328 QJSValue obj = eng.newObject();
2329 obj.setProperty(1, eng.newFunction(getterSetter), QJSValue::PropertyGetter|QJSValue::PropertySetter);
2332 obj.setProperty("x", num);
2333 QJSValue ret = obj.property(1);
2334 QVERIFY(ret.isValid());
2335 QVERIFY(ret.equals(num));
2339 obj.setProperty(1, num);
2340 QJSValue ret = obj.property(1);
2341 QVERIFY(ret.isValid());
2342 QVERIFY(ret.equals(num));
2343 QVERIFY(ret.equals(obj.property("1")));
2345 QCOMPARE(obj.propertyFlags("1"), QJSValue::PropertyGetter|QJSValue::PropertySetter);
2347 obj.setProperty(1, QJSValue(), QJSValue::PropertyGetter|QJSValue::PropertySetter);
2348 QVERIFY(obj.propertyFlags("1") == 0);
2352 void tst_QJSValue::getSetPrototype_cyclicPrototype()
2355 QJSValue prototype = eng.newObject();
2356 QJSValue object = eng.newObject();
2357 object.setPrototype(prototype);
2359 QJSValue previousPrototype = prototype.prototype();
2360 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setPrototype() failed: cyclic prototype value");
2361 prototype.setPrototype(prototype);
2362 QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true);
2364 object.setPrototype(prototype);
2365 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setPrototype() failed: cyclic prototype value");
2366 prototype.setPrototype(object);
2367 QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true);
2371 void tst_QJSValue::getSetPrototype_evalCyclicPrototype()
2374 QJSValue ret = eng.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
2375 QCOMPARE(eng.hasUncaughtException(), true);
2376 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
2377 QCOMPARE(ret.isError(), true);
2378 QCOMPARE(ret.toString(), QLatin1String("Error: Cyclic __proto__ value"));
2381 void tst_QJSValue::getSetPrototype_eval()
2384 QJSValue ret = eng.evaluate("p = { }; p.__proto__ = { }");
2385 QCOMPARE(eng.hasUncaughtException(), false);
2386 QCOMPARE(ret.isError(), false);
2389 void tst_QJSValue::getSetPrototype_invalidPrototype()
2393 QJSValue object = eng.newObject();
2394 QJSValue proto = object.prototype();
2395 QVERIFY(object.prototype().strictlyEquals(proto));
2396 inv.setPrototype(object);
2397 QCOMPARE(inv.prototype().isValid(), false);
2398 object.setPrototype(inv);
2399 QVERIFY(object.prototype().strictlyEquals(proto));
2402 void tst_QJSValue::getSetPrototype_twoEngines()
2405 QJSValue prototype = eng.newObject();
2406 QJSValue object = eng.newObject();
2407 object.setPrototype(prototype);
2408 QJSEngine otherEngine;
2409 QJSValue newPrototype = otherEngine.newObject();
2410 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setPrototype() failed: cannot set a prototype created in a different engine");
2411 object.setPrototype(newPrototype);
2412 QCOMPARE(object.prototype().strictlyEquals(prototype), true);
2416 void tst_QJSValue::getSetPrototype_null()
2419 QJSValue object = eng.newObject();
2420 object.setPrototype(QJSValue(QJSValue::NullValue));
2421 QVERIFY(object.prototype().isNull());
2423 QJSValue newProto = eng.newObject();
2424 object.setPrototype(newProto);
2425 QVERIFY(object.prototype().equals(newProto));
2427 object.setPrototype(QJSValue(&eng, QJSValue::NullValue));
2428 QVERIFY(object.prototype().isNull());
2431 void tst_QJSValue::getSetPrototype_notObjectOrNull()
2434 QJSValue object = eng.newObject();
2435 QJSValue originalProto = object.prototype();
2438 object.setPrototype(true);
2439 QVERIFY(object.prototype().equals(originalProto));
2440 object.setPrototype(QJSValue(&eng, true));
2441 QVERIFY(object.prototype().equals(originalProto));
2444 object.setPrototype(123);
2445 QVERIFY(object.prototype().equals(originalProto));
2446 object.setPrototype(QJSValue(&eng, 123));
2447 QVERIFY(object.prototype().equals(originalProto));
2450 object.setPrototype("foo");
2451 QVERIFY(object.prototype().equals(originalProto));
2452 object.setPrototype(QJSValue(&eng, QLatin1String("foo")));
2453 QVERIFY(object.prototype().equals(originalProto));
2456 object.setPrototype(QJSValue(QJSValue::UndefinedValue));
2457 QVERIFY(object.prototype().equals(originalProto));
2458 object.setPrototype(QJSValue(&eng, QJSValue::UndefinedValue));
2459 QVERIFY(object.prototype().equals(originalProto));
2462 void tst_QJSValue::getSetPrototype()
2465 QJSValue prototype = eng.newObject();
2466 QJSValue object = eng.newObject();
2467 object.setPrototype(prototype);
2468 QCOMPARE(object.prototype().strictlyEquals(prototype), true);
2471 void tst_QJSValue::getSetScope()
2473 #if 0 // FIXME: No QJSValue::scope
2476 QJSValue object = eng.newObject();
2477 QCOMPARE(object.scope().isValid(), false);
2479 QJSValue object2 = eng.newObject();
2480 object2.setScope(object);
2482 QEXPECT_FAIL("", "FIXME: scope not implemented yet", Abort);
2483 QCOMPARE(object2.scope().strictlyEquals(object), true);
2485 object.setProperty("foo", 123);
2486 QVERIFY(!object2.property("foo").isValid());
2488 QJSValue ret = object2.property("foo", QJSValue::ResolveScope);
2489 QVERIFY(ret.isNumber());
2490 QCOMPARE(ret.toInt32(), 123);
2494 inv.setScope(object);
2495 QCOMPARE(inv.scope().isValid(), false);
2497 QScriptEngine otherEngine;
2498 QJSValue object3 = otherEngine.newObject();
2499 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setScope() failed: cannot set a scope object created in a different engine");
2500 object2.setScope(object3);
2501 QCOMPARE(object2.scope().strictlyEquals(object), true);
2503 object2.setScope(QJSValue());
2504 QVERIFY(!object2.scope().isValid());
2508 void tst_QJSValue::getSetData_objects_data()
2510 #if 0 // FIXME: no setData/data API
2513 QTest::addColumn<QJSValue>("object");
2515 QTest::newRow("object from evaluate") << engine->evaluate("new Object()");
2516 QTest::newRow("object from engine") << engine->newObject();
2517 QTest::newRow("Array") << engine->newArray();
2518 QTest::newRow("Date") << engine->newDate(12324);
2519 QTest::newRow("QObject") << engine->newQObject(this);
2520 QTest::newRow("RegExp") << engine->newRegExp(QRegExp());
2524 void tst_QJSValue::getSetData_objects()
2526 #if 0 // FIXME: no setData/data API
2527 QFETCH(QJSValue, object);
2529 QVERIFY(!object.data().isValid());
2532 QVERIFY(object.data().strictlyEquals(v1));
2535 QVERIFY(object.data().strictlyEquals(v2));
2536 QJSValue v3 = engine->newObject();
2538 QVERIFY(object.data().strictlyEquals(v3));
2539 object.setData(QJSValue());
2540 QVERIFY(!object.data().isValid());
2544 void tst_QJSValue::getSetData_nonObjects_data()
2546 #if 0 // FIXME: no setData/data API
2549 QTest::addColumn<QJSValue>("value");
2551 QTest::newRow("undefined (bound)") << engine->undefinedValue();
2552 QTest::newRow("null (bound)") << engine->nullValue();
2553 QTest::newRow("string (bound)") << QJSValue(engine, "Pong");
2554 QTest::newRow("bool (bound)") << QJSValue(engine, false);
2556 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
2557 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
2558 QTest::newRow("string") << QJSValue("Pong");
2559 QTest::newRow("bool") << QJSValue(true);
2563 void tst_QJSValue::getSetData_nonObjects()
2565 #if 0 // FIXME: no setData/data API
2566 QFETCH(QJSValue, value);
2568 QVERIFY(!value.data().isValid());
2571 QVERIFY(!value.data().isValid());
2574 QVERIFY(!value.data().isValid());
2575 QJSValue v3 = engine->newObject();
2577 QVERIFY(!value.data().isValid());
2578 value.setData(QJSValue());
2579 QVERIFY(!value.data().isValid());
2583 void tst_QJSValue::setData_QTBUG15144()
2585 #if 0 // FIXME: no setData/data API
2587 QJSValue obj = eng.newObject();
2588 for (int i = 0; i < 10000; ++i) {
2589 // Create an object with property 'fooN' on it, and immediately kill
2590 // the reference to the object so it and the property name become garbage.
2591 eng.evaluate(QString::fromLatin1("o = {}; o.foo%0 = 10; o = null;").arg(i));
2592 // Setting the data will cause a JS string to be allocated, which could
2593 // trigger a GC. This should not cause a crash.
2594 obj.setData("foodfight");
2599 #if 0 // FIXME: no QScriptClass
2600 class TestScriptClass : public QScriptClass
2603 TestScriptClass(QScriptEngine *engine) : QScriptClass(engine) {}
2606 void tst_QJSValue::getSetScriptClass_emptyClass_data()
2609 QTest::addColumn<QJSValue>("value");
2611 QTest::newRow("invalid") << QJSValue();
2612 QTest::newRow("number") << QJSValue(123);
2613 QTest::newRow("string") << QJSValue("pong");
2614 QTest::newRow("bool") << QJSValue(false);
2615 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
2616 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
2618 QTest::newRow("number") << QJSValue(engine, 123);
2619 QTest::newRow("string") << QJSValue(engine, "pong");
2620 QTest::newRow("bool") << QJSValue(engine, true);
2621 QTest::newRow("null") << QJSValue(engine->nullValue());
2622 QTest::newRow("undefined") << QJSValue(engine->undefinedValue());
2623 QTest::newRow("object") << QJSValue(engine->newObject());
2624 QTest::newRow("date") << QJSValue(engine->evaluate("new Date()"));
2625 QTest::newRow("qobject") << QJSValue(engine->newQObject(this));
2628 void tst_QJSValue::getSetScriptClass_emptyClass()
2630 QFETCH(QJSValue, value);
2631 QCOMPARE(value.scriptClass(), (QScriptClass*)0);
2634 void tst_QJSValue::getSetScriptClass_JSObjectFromCpp()
2637 TestScriptClass testClass(&eng);
2638 // object created in C++ (newObject())
2640 QJSValue obj = eng.newObject();
2641 obj.setScriptClass(&testClass);
2642 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2643 obj.setScriptClass(0);
2644 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2648 void tst_QJSValue::getSetScriptClass_JSObjectFromJS()
2651 TestScriptClass testClass(&eng);
2652 // object created in JS
2654 QJSValue obj = eng.evaluate("new Object");
2655 QVERIFY(!eng.hasUncaughtException());
2656 QVERIFY(obj.isObject());
2657 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2658 obj.setScriptClass(&testClass);
2659 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2660 obj.setScriptClass(0);
2661 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2665 void tst_QJSValue::getSetScriptClass_QVariant()
2668 TestScriptClass testClass(&eng);
2669 // object that already has a(n internal) class
2671 QJSValue obj = eng.newVariant(QUrl("http://example.com"));
2672 QVERIFY(obj.isVariant());
2673 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2674 obj.setScriptClass(&testClass);
2675 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2676 QVERIFY(obj.isObject());
2677 QVERIFY(!obj.isVariant());
2678 QCOMPARE(obj.toVariant(), QVariant(QVariantMap()));
2682 void tst_QJSValue::getSetScriptClass_QObject()
2685 TestScriptClass testClass(&eng);
2687 QJSValue obj = eng.newQObject(this);
2688 QVERIFY(obj.isQObject());
2689 obj.setScriptClass(&testClass);
2690 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2691 QVERIFY(obj.isObject());
2692 QVERIFY(!obj.isQObject());
2693 QVERIFY(obj.toQObject() == 0);
2698 #if 0 // FIXME: No c-style callbacks
2699 static QJSValue getArg(QScriptContext *ctx, QScriptEngine *)
2701 return ctx->argument(0);
2704 static QJSValue evaluateArg(QScriptContext *, QScriptEngine *eng)
2706 return eng->evaluate("arguments[0]");
2709 static QJSValue addArgs(QScriptContext *, QScriptEngine *eng)
2711 return eng->evaluate("arguments[0] + arguments[1]");
2714 static QJSValue returnInvalidValue(QScriptContext *, QScriptEngine *)
2720 void tst_QJSValue::call_function()
2723 QJSValue fun = eng.evaluate("(function() { return 1; })");
2724 QVERIFY(fun.isFunction());
2725 QJSValue result = fun.call();
2726 QVERIFY(result.isNumber());
2727 QCOMPARE(result.toInt32(), 1);
2730 void tst_QJSValue::call_object()
2733 QJSValue Object = eng.evaluate("Object");
2734 QCOMPARE(Object.isFunction(), true);
2735 QJSValue result = Object.call(Object);
2736 QCOMPARE(result.isObject(), true);
2739 void tst_QJSValue::call_newObjects()
2742 // test that call() doesn't construct new objects
2743 QJSValue Number = eng.evaluate("Number");
2744 QJSValue Object = eng.evaluate("Object");
2745 QCOMPARE(Object.isFunction(), true);
2747 args << QJSValue(&eng, 123);
2748 QJSValue result = Number.call(Object, args);
2749 QCOMPARE(result.strictlyEquals(args.at(0)), true);
2752 void tst_QJSValue::call_this()
2755 // test that correct "this" object is used
2756 QJSValue fun = eng.evaluate("(function() { return this; })");
2757 QCOMPARE(fun.isFunction(), true);
2759 QJSValue numberObject = QJSValue(&eng, 123.0).toObject();
2760 QJSValue result = fun.call(numberObject);
2761 QCOMPARE(result.isObject(), true);
2762 QCOMPARE(result.toNumber(), 123.0);
2765 void tst_QJSValue::call_arguments()
2768 // test that correct arguments are passed
2770 QJSValue fun = eng.evaluate("(function() { return arguments[0]; })");
2771 QCOMPARE(fun.isFunction(), true);
2773 QJSValue result = fun.call(eng.undefinedValue());
2774 QCOMPARE(result.isUndefined(), true);
2778 args << QJSValue(&eng, 123.0);
2779 QJSValue result = fun.call(eng.undefinedValue(), args);
2780 QCOMPARE(result.isNumber(), true);
2781 QCOMPARE(result.toNumber(), 123.0);
2786 args << QJSValue(123.0);
2787 QJSValue result = fun.call(eng.undefinedValue(), args);
2788 QCOMPARE(result.isNumber(), true);
2789 QCOMPARE(result.toNumber(), 123.0);
2791 #if 0 // FIXME: The feature of interpreting a passed array as argument list has been removed from the API
2793 QJSValue args = eng.newArray();
2794 args.setProperty(0, 123);
2795 QJSValue result = fun.call(eng.undefinedValue(), args);
2796 QVERIFY(result.isNumber());
2797 QCOMPARE(result.toNumber(), 123.0);
2802 void tst_QJSValue::call()
2806 QJSValue fun = eng.evaluate("(function() { return arguments[1]; })");
2807 QCOMPARE(fun.isFunction(), true);
2811 args << QJSValue(&eng, 123.0) << QJSValue(&eng, 456.0);
2812 QJSValue result = fun.call(eng.undefinedValue(), args);
2813 QCOMPARE(result.isNumber(), true);
2814 QCOMPARE(result.toNumber(), 456.0);
2816 #if 0 // FIXME: The feature of interpreting a passed array as argument list has been removed from the API
2818 QJSValue args = eng.newArray();
2819 args.setProperty(0, 123);
2820 args.setProperty(1, 456);
2821 QJSValue result = fun.call(eng.undefinedValue(), args);
2822 QVERIFY(result.isNumber());
2823 QCOMPARE(result.toNumber(), 456.0);
2828 QJSValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
2829 QCOMPARE(fun.isFunction(), true);
2830 QVERIFY(!eng.hasUncaughtException());
2833 QJSValue result = fun.call();
2834 QCOMPARE(result.isError(), true);
2835 QCOMPARE(eng.hasUncaughtException(), true);
2836 QVERIFY(result.strictlyEquals(eng.uncaughtException()));
2839 #if 0 // FIXME: No c-style callbacks
2841 eng.clearExceptions();
2842 QJSValue fun = eng.newFunction(getArg);
2845 args << QJSValue(&eng, 123.0);
2846 QJSValue result = fun.call(eng.undefinedValue(), args);
2847 QVERIFY(!eng.hasUncaughtException());
2848 QCOMPARE(result.isNumber(), true);
2849 QCOMPARE(result.toNumber(), 123.0);
2854 args << QJSValue(123.0);
2855 QJSValue result = fun.call(eng.undefinedValue(), args);
2856 QCOMPARE(result.isNumber(), true);
2857 QCOMPARE(result.toNumber(), 123.0);
2859 #if 0 // FIXME: The feature of interpreting a passed array as argument list has been removed from the API
2861 QJSValue args = eng.newArray();
2862 args.setProperty(0, 123);
2863 QJSValue result = fun.call(eng.undefinedValue(), args);
2864 QVERIFY(result.isNumber());
2865 QCOMPARE(result.toNumber(), 123.0);
2870 QJSValue fun = eng.newFunction(evaluateArg);
2873 args << QJSValue(&eng, 123.0);
2874 QJSValue result = fun.call(eng.undefinedValue(), args);
2875 QVERIFY(!eng.hasUncaughtException());
2876 QCOMPARE(result.isNumber(), true);
2877 QCOMPARE(result.toNumber(), 123.0);
2883 void tst_QJSValue::call_invalidArguments()
2885 #if 0 // FIXME: No c-style callbacks
2886 // test that invalid arguments are handled gracefully
2889 QJSValue fun = eng.newFunction(getArg);
2893 QJSValue ret = fun.call(QJSValue(), args);
2894 QVERIFY(!eng.hasUncaughtException());
2895 QCOMPARE(ret.isValid(), true);
2896 QCOMPARE(ret.isUndefined(), true);
2900 QJSValue fun = eng.newFunction(evaluateArg);
2904 QJSValue ret = fun.call(QJSValue(), args);
2905 QCOMPARE(ret.isValid(), true);
2906 QCOMPARE(ret.isUndefined(), true);
2910 QJSValue fun = eng.newFunction(addArgs);
2913 args << QJSValue() << QJSValue();
2914 QJSValue ret = fun.call(QJSValue(), args);
2915 QCOMPARE(ret.isValid(), true);
2916 QCOMPARE(ret.isNumber(), true);
2917 QCOMPARE(qIsNaN(ret.toNumber()), true);
2923 void tst_QJSValue::call_invalidReturn()
2925 #if 0 // FIXME: No c-style callbacks
2926 // test that invalid return value is handled gracefully
2928 QJSValue fun = eng.newFunction(returnInvalidValue);
2929 eng.globalObject().setProperty("returnInvalidValue", fun);
2930 QJSValue ret = eng.evaluate("returnInvalidValue() + returnInvalidValue()");
2931 QCOMPARE(ret.isValid(), true);
2932 QCOMPARE(ret.isNumber(), true);
2933 QCOMPARE(qIsNaN(ret.toNumber()), true);
2937 void tst_QJSValue::call_twoEngines()
2940 QJSValue object = eng.evaluate("Object");
2941 QJSEngine otherEngine;
2942 QJSValue fun = otherEngine.evaluate("(function() { return 1; })");
2943 QVERIFY(fun.isFunction());
2944 QTest::ignoreMessage(QtWarningMsg, "JSValue can't be rassigned to an another engine.");
2945 QTest::ignoreMessage(QtWarningMsg, "QJSValue::call() failed: "
2946 "cannot call function with thisObject created in "
2947 "a different engine");
2948 QCOMPARE(fun.call(object).isValid(), false);
2949 QTest::ignoreMessage(QtWarningMsg, "QJSValue::call() failed: "
2950 "cannot call function with argument created in "
2951 "a different engine");
2952 QCOMPARE(fun.call(QJSValue(), QJSValueList() << QJSValue(&eng, 123)).isValid(), false);
2954 QJSValue fun = eng.evaluate("Object");
2955 QVERIFY(fun.isFunction());
2957 QJSValue objectInDifferentEngine = eng2.newObject();
2959 args << objectInDifferentEngine;
2960 QTest::ignoreMessage(QtWarningMsg, "QJSValue::call() failed: cannot call function with argument created in a different engine");
2961 fun.call(QJSValue(), args);
2965 void tst_QJSValue::call_array()
2967 #if 0 // FIXME: The feature of interpreting an array as argument list has been removed from the API
2969 QJSValue fun = eng.evaluate("(function() { return arguments; })");
2970 QVERIFY(fun.isFunction());
2971 QJSValue array = eng.newArray(3);
2972 array.setProperty(0, QJSValue(&eng, 123.0));
2973 array.setProperty(1, QJSValue(&eng, 456.0));
2974 array.setProperty(2, QJSValue(&eng, 789.0));
2975 // call with single array object as arguments
2976 QJSValue ret = fun.call(QJSValue(), array);
2977 QVERIFY(!eng.hasUncaughtException());
2978 QCOMPARE(ret.isError(), false);
2979 QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
2980 QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
2981 QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
2982 // call with arguments object as arguments
2983 QJSValue ret2 = fun.call(QJSValue(), ret);
2984 QCOMPARE(ret2.isError(), false);
2985 QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
2986 QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
2987 QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
2988 // call with null as arguments
2989 QJSValue ret3 = fun.call(QJSValue(), eng.nullValue());
2990 QCOMPARE(ret3.isError(), false);
2991 QCOMPARE(ret3.property("length").isNumber(), true);
2992 QCOMPARE(ret3.property("length").toNumber(), 0.0);
2993 // call with undefined as arguments
2994 QJSValue ret4 = fun.call(QJSValue(), eng.undefinedValue());
2995 QCOMPARE(ret4.isError(), false);
2996 QCOMPARE(ret4.property("length").isNumber(), true);
2997 QCOMPARE(ret4.property("length").toNumber(), 0.0);
2998 // call with something else as arguments
2999 QJSValue ret5 = fun.call(QJSValue(), QJSValue(&eng, 123.0));
3000 QCOMPARE(ret5.isError(), true);
3001 // call with a non-array object as arguments
3002 QJSValue ret6 = fun.call(QJSValue(), eng.globalObject());
3003 QVERIFY(ret6.isError());
3004 QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
3009 void tst_QJSValue::call_nonFunction_data()
3012 QTest::addColumn<QJSValue>("value");
3014 QTest::newRow("invalid") << QJSValue();
3015 QTest::newRow("bool") << QJSValue(false);
3016 QTest::newRow("int") << QJSValue(123);
3017 QTest::newRow("string") << QJSValue(QString::fromLatin1("ciao"));
3018 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
3019 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
3021 QTest::newRow("bool bound") << QJSValue(engine, false);
3022 QTest::newRow("int bound") << QJSValue(engine, 123);
3023 QTest::newRow("string bound") << QJSValue(engine, QString::fromLatin1("ciao"));
3024 QTest::newRow("undefined bound") << engine->undefinedValue();
3025 QTest::newRow("null bound") << engine->nullValue();
3028 void tst_QJSValue::call_nonFunction()
3030 // calling things that are not functions
3031 QFETCH(QJSValue, value);
3032 QVERIFY(!value.call().isValid());
3035 #if 0 // FIXME: no c-style callbacks
3036 static QJSValue ctorReturningUndefined(QScriptContext *ctx, QScriptEngine *)
3038 ctx->thisObject().setProperty("foo", 123);
3039 return QJSValue(QJSValue::UndefinedValue);
3042 static QJSValue ctorReturningNewObject(QScriptContext *, QScriptEngine *eng)
3044 QJSValue result = eng->newObject();
3045 result.setProperty("bar", 456);
3050 void tst_QJSValue::construct_nonFunction_data()
3053 QTest::addColumn<QJSValue>("value");
3055 QTest::newRow("invalid") << QJSValue();
3056 QTest::newRow("bool") << QJSValue(false);
3057 QTest::newRow("int") << QJSValue(123);
3058 QTest::newRow("string") << QJSValue(QString::fromLatin1("ciao"));
3059 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
3060 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
3062 QTest::newRow("bool bound") << QJSValue(engine, false);
3063 QTest::newRow("int bound") << QJSValue(engine, 123);
3064 QTest::newRow("string bound") << QJSValue(engine, QString::fromLatin1("ciao"));
3065 QTest::newRow("undefined bound") << engine->undefinedValue();
3066 QTest::newRow("null bound") << engine->nullValue();
3069 void tst_QJSValue::construct_nonFunction()
3071 QFETCH(QJSValue, value);
3072 QVERIFY(!value.construct().isValid());
3075 void tst_QJSValue::construct_simple()
3078 QJSValue fun = eng.evaluate("(function () { this.foo = 123; })");
3079 QVERIFY(fun.isFunction());
3080 QJSValue ret = fun.construct();
3081 QVERIFY(ret.isObject());
3082 QVERIFY(ret.instanceOf(fun));
3083 QCOMPARE(ret.property("foo").toInt32(), 123);
3086 void tst_QJSValue::construct_newObjectJS()
3089 // returning a different object overrides the default-constructed one
3090 QJSValue fun = eng.evaluate("(function () { return { bar: 456 }; })");
3091 QVERIFY(fun.isFunction());
3092 QJSValue ret = fun.construct();
3093 QVERIFY(ret.isObject());
3094 QVERIFY(!ret.instanceOf(fun));
3095 QCOMPARE(ret.property("bar").toInt32(), 456);
3098 #if 0 // FIXME: no c-style callbacks
3099 void tst_QJSValue::construct_undefined()
3102 QJSValue fun = eng.newFunction(ctorReturningUndefined);
3103 QJSValue ret = fun.construct();
3104 QVERIFY(ret.isObject());
3105 QVERIFY(ret.instanceOf(fun));
3106 QCOMPARE(ret.property("foo").toInt32(), 123);
3109 void tst_QJSValue::construct_newObjectCpp()
3112 QJSValue fun = eng.newFunction(ctorReturningNewObject);
3113 QJSValue ret = fun.construct();
3114 QVERIFY(ret.isObject());
3115 QVERIFY(!ret.instanceOf(fun));
3116 QCOMPARE(ret.property("bar").toInt32(), 456);
3120 void tst_QJSValue::construct_arg()
3123 QJSValue Number = eng.evaluate("Number");
3124 QCOMPARE(Number.isFunction(), true);
3126 args << QJSValue(&eng, 123);
3127 QJSValue ret = Number.construct(args);
3128 QCOMPARE(ret.isObject(), true);
3129 QCOMPARE(ret.toNumber(), args.at(0).toNumber());
3132 void tst_QJSValue::construct_proto()
3135 // test that internal prototype is set correctly
3136 QJSValue fun = eng.evaluate("(function() { return this.__proto__; })");
3137 QCOMPARE(fun.isFunction(), true);
3138 QCOMPARE(fun.property("prototype").isObject(), true);
3139 QJSValue ret = fun.construct();
3140 QCOMPARE(fun.property("prototype").strictlyEquals(ret), true);
3143 void tst_QJSValue::construct_returnInt()
3146 // test that we return the new object even if a non-object value is returned from the function
3147 QJSValue fun = eng.evaluate("(function() { return 123; })");
3148 QCOMPARE(fun.isFunction(), true);
3149 QJSValue ret = fun.construct();
3150 QCOMPARE(ret.isObject(), true);
3153 void tst_QJSValue::construct_throw()
3156 QJSValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
3157 QCOMPARE(fun.isFunction(), true);
3158 QJSValue ret = fun.construct();
3159 QCOMPARE(ret.isError(), true);
3160 QCOMPARE(eng.hasUncaughtException(), true);
3161 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3164 #if 0 // FIXME: The feature of interpreting an array as argument list has been removed from the API
3165 void tst_QJSValue::construct()
3168 QJSValue fun = eng.evaluate("(function() { return arguments; })");
3169 QVERIFY(fun.isFunction());
3170 QJSValue array = eng.newArray(3);
3171 array.setProperty(0, QJSValue(&eng, 123.0));
3172 array.setProperty(1, QJSValue(&eng, 456.0));
3173 array.setProperty(2, QJSValue(&eng, 789.0));
3174 // construct with single array object as arguments
3175 QJSValue ret = fun.construct(array);
3176 QVERIFY(!eng.hasUncaughtException());
3177 QVERIFY(ret.isValid());
3178 QVERIFY(ret.isObject());
3179 QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
3180 QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
3181 QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
3182 // construct with arguments object as arguments
3183 QJSValue ret2 = fun.construct(ret);
3184 QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
3185 QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
3186 QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
3187 // construct with null as arguments
3188 QJSValue ret3 = fun.construct(eng.nullValue());
3189 QCOMPARE(ret3.isError(), false);
3190 QCOMPARE(ret3.property("length").isNumber(), true);
3191 QCOMPARE(ret3.property("length").toNumber(), 0.0);
3192 // construct with undefined as arguments
3193 QJSValue ret4 = fun.construct(eng.undefinedValue());
3194 QCOMPARE(ret4.isError(), false);
3195 QCOMPARE(ret4.property("length").isNumber(), true);
3196 QCOMPARE(ret4.property("length").toNumber(), 0.0);
3197 // construct with something else as arguments
3198 QJSValue ret5 = fun.construct(QJSValue(&eng, 123.0));
3199 QCOMPARE(ret5.isError(), true);
3200 // construct with a non-array object as arguments
3201 QJSValue ret6 = fun.construct(eng.globalObject());
3202 QVERIFY(ret6.isError());
3203 QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
3207 void tst_QJSValue::construct_twoEngines()
3210 QJSEngine otherEngine;
3211 QJSValue ctor = engine.evaluate("(function (a, b) { this.foo = 123; })");
3212 QJSValue arg(&otherEngine, 124567);
3213 QTest::ignoreMessage(QtWarningMsg, "QJSValue::construct() failed: cannot construct function with argument created in a different engine");
3214 QVERIFY(!ctor.construct(QJSValueList() << arg).isValid());
3215 QTest::ignoreMessage(QtWarningMsg, "QJSValue::construct() failed: cannot construct function with argument created in a different engine");
3216 QVERIFY(!ctor.construct(QJSValueList() << arg << otherEngine.newObject()).isValid());
3219 void tst_QJSValue::construct_constructorThrowsPrimitive()
3222 QJSValue fun = eng.evaluate("(function() { throw 123; })");
3223 QVERIFY(fun.isFunction());
3224 // construct(QJSValueList)
3226 QJSValue ret = fun.construct();
3227 QVERIFY(ret.isNumber());
3228 QCOMPARE(ret.toNumber(), 123.0);
3229 QVERIFY(eng.hasUncaughtException());
3230 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3231 eng.clearExceptions();
3233 #if 0 // FIXME: The feature of interpreting an array as argument list has been removed from the API
3234 // construct(QJSValue)
3236 QJSValue ret = fun.construct(eng.newArray());
3237 QVERIFY(ret.isNumber());
3238 QCOMPARE(ret.toNumber(), 123.0);
3239 QVERIFY(eng.hasUncaughtException());
3240 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3241 eng.clearExceptions();
3246 #if 0 // FIXME: No QJSValue::lessThan
3247 void tst_QJSValue::lessThan()
3251 QVERIFY(!QJSValue().lessThan(QJSValue()));
3253 QJSValue num = QJSValue(&eng, 123);
3254 QCOMPARE(num.lessThan(QJSValue(&eng, 124)), true);
3255 QCOMPARE(num.lessThan(QJSValue(&eng, 122)), false);
3256 QCOMPARE(num.lessThan(QJSValue(&eng, 123)), false);
3257 QCOMPARE(num.lessThan(QJSValue(&eng, "124")), true);
3258 QCOMPARE(num.lessThan(QJSValue(&eng, "122")), false);
3259 QCOMPARE(num.lessThan(QJSValue(&eng, "123")), false);
3260 QCOMPARE(num.lessThan(QJSValue(&eng, qSNaN())), false);
3261 QCOMPARE(num.lessThan(QJSValue(&eng, +qInf())), true);
3262 QCOMPARE(num.lessThan(QJSValue(&eng, -qInf())), false);
3263 QCOMPARE(num.lessThan(num), false);
3264 QCOMPARE(num.lessThan(QJSValue(&eng, 124).toObject()), true);
3265 QCOMPARE(num.lessThan(QJSValue(&eng, 122).toObject()), false);
3266 QCOMPARE(num.lessThan(QJSValue(&eng, 123).toObject()), false);
3267 QCOMPARE(num.lessThan(QJSValue(&eng, "124").toObject()), true);
3268 QCOMPARE(num.lessThan(QJSValue(&eng, "122").toObject()), false);
3269 QCOMPARE(num.lessThan(QJSValue(&eng, "123").toObject()), false);
3270 QCOMPARE(num.lessThan(QJSValue(&eng, qSNaN()).toObject()), false);
3271 QCOMPARE(num.lessThan(QJSValue(&eng, +qInf()).toObject()), true);
3272 QCOMPARE(num.lessThan(QJSValue(&eng, -qInf()).toObject()), false);
3273 QCOMPARE(num.lessThan(num.toObject()), false);
3274 QCOMPARE(num.lessThan(QJSValue()), false);
3276 QJSValue str = QJSValue(&eng, "123");
3277 QCOMPARE(str.lessThan(QJSValue(&eng, "124")), true);
3278 QCOMPARE(str.lessThan(QJSValue(&eng, "122")), false);
3279 QCOMPARE(str.lessThan(QJSValue(&eng, "123")), false);
3280 QCOMPARE(str.lessThan(QJSValue(&eng, 124)), true);
3281 QCOMPARE(str.lessThan(QJSValue(&eng, 122)), false);
3282 QCOMPARE(str.lessThan(QJSValue(&eng, 123)), false);
3283 QCOMPARE(str.lessThan(str), false);
3284 QCOMPARE(str.lessThan(QJSValue(&eng, "124").toObject()), true);
3285 QCOMPARE(str.lessThan(QJSValue(&eng, "122").toObject()), false);
3286 QCOMPARE(str.lessThan(QJSValue(&eng, "123").toObject()), false);
3287 QCOMPARE(str.lessThan(QJSValue(&eng, 124).toObject()), true);
3288 QCOMPARE(str.lessThan(QJSValue(&eng, 122).toObject()), false);
3289 QCOMPARE(str.lessThan(QJSValue(&eng, 123).toObject()), false);
3290 QCOMPARE(str.lessThan(str.toObject()), false);
3291 QCOMPARE(str.lessThan(QJSValue()), false);
3294 QJSValue num2 = QJSValue(123);
3295 QCOMPARE(num2.lessThan(QJSValue(124)), true);
3296 QCOMPARE(num2.lessThan(QJSValue(122)), false);
3297 QCOMPARE(num2.lessThan(QJSValue(123)), false);
3298 QCOMPARE(num2.lessThan(QJSValue("124")), true);
3299 QCOMPARE(num2.lessThan(QJSValue("122")), false);
3300 QCOMPARE(num2.lessThan(QJSValue("123")), false);
3301 QCOMPARE(num2.lessThan(QJSValue(qSNaN())), false);
3302 QCOMPARE(num2.lessThan(QJSValue(+qInf())), true);
3303 QCOMPARE(num2.lessThan(QJSValue(-qInf())), false);
3304 QCOMPARE(num2.lessThan(num), false);
3305 QCOMPARE(num2.lessThan(QJSValue()), false);
3307 QJSValue str2 = QJSValue("123");
3308 QCOMPARE(str2.lessThan(QJSValue("124")), true);
3309 QCOMPARE(str2.lessThan(QJSValue("122")), false);
3310 QCOMPARE(str2.lessThan(QJSValue("123")), false);
3311 QCOMPARE(str2.lessThan(QJSValue(124)), true);
3312 QCOMPARE(str2.lessThan(QJSValue(122)), false);
3313 QCOMPARE(str2.lessThan(QJSValue(123)), false);
3314 QCOMPARE(str2.lessThan(str), false);
3315 QCOMPARE(str2.lessThan(QJSValue()), false);
3317 QJSValue obj1 = eng.newObject();
3318 QJSValue obj2 = eng.newObject();
3319 QCOMPARE(obj1.lessThan(obj2), false);
3320 QCOMPARE(obj2.lessThan(obj1), false);
3321 QCOMPARE(obj1.lessThan(obj1), false);
3322 QCOMPARE(obj2.lessThan(obj2), false);
3324 QJSValue date1 = eng.newDate(QDateTime(QDate(2000, 1, 1)));
3325 QJSValue date2 = eng.newDate(QDateTime(QDate(1999, 1, 1)));
3326 QCOMPARE(date1.lessThan(date2), false);
3327 QCOMPARE(date2.lessThan(date1), true);
3328 QCOMPARE(date1.lessThan(date1), false);
3329 QCOMPARE(date2.lessThan(date2), false);
3330 QCOMPARE(date1.lessThan(QJSValue()), false);
3332 QCOMPARE(QJSValue().lessThan(date2), false);
3334 QScriptEngine otherEngine;
3335 QTest::ignoreMessage(QtWarningMsg, "QJSValue::lessThan: "
3336 "cannot compare to a value created in "
3337 "a different engine");
3338 QCOMPARE(date1.lessThan(QJSValue(&otherEngine, 123)), false);
3342 void tst_QJSValue::equals()
3346 QVERIFY(QJSValue().equals(QJSValue()));
3348 QJSValue num = QJSValue(&eng, 123);
3349 QCOMPARE(num.equals(QJSValue(&eng, 123)), true);
3350 QCOMPARE(num.equals(QJSValue(&eng, 321)), false);
3351 QCOMPARE(num.equals(QJSValue(&eng, QLatin1String("123"))), true);
3352 QCOMPARE(num.equals(QJSValue(&eng, QLatin1String("321"))), false);
3353 QCOMPARE(num.equals(QJSValue(&eng, 123).toObject()), true);
3354 QCOMPARE(num.equals(QJSValue(&eng, 321).toObject()), false);
3355 QCOMPARE(num.equals(QJSValue(&eng, QLatin1String("123")).toObject()), true);
3356 QCOMPARE(num.equals(QJSValue(&eng, QLatin1String("321")).toObject()), false);
3357 QVERIFY(num.toObject().equals(num));
3358 QCOMPARE(num.equals(QJSValue()), false);
3360 QJSValue str = QJSValue(&eng, QLatin1String("123"));
3361 QCOMPARE(str.equals(QJSValue(&eng, QLatin1String("123"))), true);
3362 QCOMPARE(str.equals(QJSValue(&eng, QLatin1String("321"))), false);
3363 QCOMPARE(str.equals(QJSValue(&eng, 123)), true);
3364 QCOMPARE(str.equals(QJSValue(&eng, 321)), false);
3365 QCOMPARE(str.equals(QJSValue(&eng, QLatin1String("123")).toObject()), true);
3366 QCOMPARE(str.equals(QJSValue(&eng, QLatin1String("321")).toObject()), false);
3367 QCOMPARE(str.equals(QJSValue(&eng, 123).toObject()), true);
3368 QCOMPARE(str.equals(QJSValue(&eng, 321).toObject()), false);
3369 QVERIFY(str.toObject().equals(str));
3370 QCOMPARE(str.equals(QJSValue()), false);
3372 QJSValue num2 = QJSValue(123);
3373 QCOMPARE(num2.equals(QJSValue(123)), true);
3374 QCOMPARE(num2.equals(QJSValue(321)), false);
3375 QCOMPARE(num2.equals(QJSValue("123")), true);
3376 QCOMPARE(num2.equals(QJSValue("321")), false);
3377 QCOMPARE(num2.equals(QJSValue()), false);
3379 QJSValue str2 = QJSValue("123");
3380 QCOMPARE(str2.equals(QJSValue("123")), true);
3381 QCOMPARE(str2.equals(QJSValue("321")), false);
3382 QCOMPARE(str2.equals(QJSValue(123)), true);
3383 QCOMPARE(str2.equals(QJSValue(321)), false);
3384 QCOMPARE(str2.equals(QJSValue()), false);
3386 QJSValue date1 = eng.newDate(QDateTime(QDate(2000, 1, 1)));
3387 QJSValue date2 = eng.newDate(QDateTime(QDate(1999, 1, 1)));
3388 QCOMPARE(date1.equals(date2), false);
3389 QCOMPARE(date1.equals(date1), true);
3390 QCOMPARE(date2.equals(date2), true);
3392 QJSValue undefined = eng.undefinedValue();
3393 QJSValue null = eng.nullValue();
3394 QCOMPARE(undefined.equals(undefined), true);
3395 QCOMPARE(null.equals(null), true);
3396 QCOMPARE(undefined.equals(null), true);
3397 QCOMPARE(null.equals(undefined), true);
3398 QCOMPARE(undefined.equals(QJSValue()), false);
3399 QCOMPARE(null.equals(QJSValue()), false);
3400 QVERIFY(!null.equals(num));
3401 QVERIFY(!undefined.equals(num));
3403 QJSValue sant = QJSValue(&eng, true);
3404 QVERIFY(sant.equals(QJSValue(&eng, 1)));
3405 QVERIFY(sant.equals(QJSValue(&eng, QLatin1String("1"))));
3406 QVERIFY(sant.equals(sant));
3407 QVERIFY(sant.equals(QJSValue(&eng, 1).toObject()));
3408 QVERIFY(sant.equals(QJSValue(&eng, QLatin1String("1")).toObject()));
3409 QVERIFY(sant.equals(sant.toObject()));
3410 QVERIFY(sant.toObject().equals(sant));
3411 QVERIFY(!sant.equals(QJSValue(&eng, 0)));
3412 QVERIFY(!sant.equals(undefined));
3413 QVERIFY(!sant.equals(null));
3415 QJSValue falskt = QJSValue(&eng, false);
3416 QVERIFY(falskt.equals(QJSValue(&eng, 0)));
3417 QVERIFY(falskt.equals(QJSValue(&eng, QLatin1String("0"))));
3418 QVERIFY(falskt.equals(falskt));
3419 QVERIFY(falskt.equals(QJSValue(&eng, 0).toObject()));
3420 QVERIFY(falskt.equals(QJSValue(&eng, QLatin1String("0")).toObject()));
3421 QVERIFY(falskt.equals(falskt.toObject()));
3422 QVERIFY(falskt.toObject().equals(falskt));
3423 QVERIFY(!falskt.equals(sant));
3424 QVERIFY(!falskt.equals(undefined));
3425 QVERIFY(!falskt.equals(null));
3427 QJSValue obj1 = eng.newObject();
3428 QJSValue obj2 = eng.newObject();
3429 QCOMPARE(obj1.equals(obj2), false);
3430 QCOMPARE(obj2.equals(obj1), false);
3431 QCOMPARE(obj1.equals(obj1), true);
3432 QCOMPARE(obj2.equals(obj2), true);
3434 QJSValue qobj1 = eng.newQObject(this);
3435 QJSValue qobj2 = eng.newQObject(this);
3436 QJSValue qobj3 = eng.newQObject(0);
3438 // FIXME: No ScriptOwnership: QJSValue qobj4 = eng.newQObject(new QObject(), QScriptEngine::ScriptOwnership);
3439 QJSValue qobj4 = eng.newQObject(new QObject());
3441 QVERIFY(qobj1.equals(qobj2)); // compares the QObject pointers
3442 QVERIFY(!qobj2.equals(qobj4)); // compares the QObject pointers
3443 QVERIFY(!qobj2.equals(obj2)); // compares the QObject pointers
3445 QJSValue compareFun = eng.evaluate("(function(a, b) { return a == b; })");
3446 QVERIFY(compareFun.isFunction());
3448 QJSValue ret = compareFun.call(QJSValue(), QJSValueList() << qobj1 << qobj2);
3449 QVERIFY(ret.isBool());
3450 ret = compareFun.call(QJSValue(), QJSValueList() << qobj1 << qobj3);
3451 QVERIFY(ret.isBool());
3452 QVERIFY(!ret.toBool());
3453 ret = compareFun.call(QJSValue(), QJSValueList() << qobj1 << qobj4);
3454 QVERIFY(ret.isBool());
3455 QVERIFY(!ret.toBool());
3456 ret = compareFun.call(QJSValue(), QJSValueList() << qobj1 << obj1);
3457 QVERIFY(ret.isBool());
3458 QVERIFY(!ret.toBool());
3462 QJSValue var1 = eng.newVariant(QVariant(false));
3463 QJSValue var2 = eng.newVariant(QVariant(false));
3464 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3465 QVERIFY(var1.equals(var2));
3467 QJSValue ret = compareFun.call(QJSValue(), QJSValueList() << var1 << var2);
3468 QVERIFY(ret.isBool());
3472 QJSValue var1 = eng.newVariant(QVariant(false));
3473 QJSValue var2 = eng.newVariant(QVariant(0));
3474 // QVariant::operator==() performs type conversion
3475 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3476 QVERIFY(var1.equals(var2));
3479 QJSValue var1 = eng.newVariant(QVariant(QStringList() << "a"));
3480 QJSValue var2 = eng.newVariant(QVariant(QStringList() << "a"));
3481 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3482 QVERIFY(var1.equals(var2));
3485 QJSValue var1 = eng.newVariant(QVariant(QStringList() << "a"));
3486 QJSValue var2 = eng.newVariant(QVariant(QStringList() << "b"));
3487 QVERIFY(!var1.equals(var2));
3490 QJSValue var1 = eng.newVariant(QVariant(QPoint(1, 2)));
3491 QJSValue var2 = eng.newVariant(QVariant(QPoint(1, 2)));
3492 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3493 QVERIFY(var1.equals(var2));
3496 QJSValue var1 = eng.newVariant(QVariant(QPoint(1, 2)));
3497 QJSValue var2 = eng.newVariant(QVariant(QPoint(3, 4)));
3498 QVERIFY(!var1.equals(var2));
3501 QJSValue var1 = eng.newVariant(QVariant(int(1)));
3502 QJSValue var2 = eng.newVariant(QVariant(double(1)));
3503 // QVariant::operator==() performs type conversion
3504 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3505 QVERIFY(var1.equals(var2));
3508 QJSValue var1 = eng.newVariant(QVariant(QString::fromLatin1("123")));
3509 QJSValue var2 = eng.newVariant(QVariant(double(123)));
3510 QJSValue var3(QString::fromLatin1("123"));
3513 QVERIFY(var1.equals(var1));
3514 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3515 QVERIFY(var1.equals(var2));
3516 QVERIFY(var1.equals(var3));
3517 QVERIFY(var1.equals(var4));
3519 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3520 QVERIFY(var2.equals(var1));
3521 QVERIFY(var2.equals(var2));
3522 QVERIFY(var2.equals(var3));
3523 QVERIFY(var2.equals(var4));
3525 QVERIFY(var3.equals(var1));
3526 QVERIFY(var3.equals(var2));
3527 QVERIFY(var3.equals(var3));
3528 QVERIFY(var3.equals(var4));
3530 QVERIFY(var4.equals(var1));
3531 QVERIFY(var4.equals(var2));
3532 QVERIFY(var4.equals(var3));
3533 QVERIFY(var4.equals(var4));
3536 QJSEngine otherEngine;
3537 QTest::ignoreMessage(QtWarningMsg, "QJSValue::equals: "
3538 "cannot compare to a value created in "
3539 "a different engine");
3540 QCOMPARE(date1.equals(QJSValue(&otherEngine, 123)), false);
3543 void tst_QJSValue::strictlyEquals()
3547 QVERIFY(QJSValue().strictlyEquals(QJSValue()));
3549 QJSValue num = QJSValue(&eng, 123);
3550 QCOMPARE(num.strictlyEquals(QJSValue(&eng, 123)), true);
3551 QCOMPARE(num.strictlyEquals(QJSValue(&eng, 321)), false);
3552 QCOMPARE(num.strictlyEquals(QJSValue(&eng, QLatin1String("123"))), false);
3553 QCOMPARE(num.strictlyEquals(QJSValue(&eng, QLatin1String("321"))), false);
3554 QCOMPARE(num.strictlyEquals(QJSValue(&eng, 123).toObject()), false);
3555 QCOMPARE(num.strictlyEquals(QJSValue(&eng, 321).toObject()), false);
3556 QCOMPARE(num.strictlyEquals(QJSValue(&eng, QLatin1String("123")).toObject()), false);
3557 QCOMPARE(num.strictlyEquals(QJSValue(&eng, QLatin1String("321")).toObject()), false);
3558 QVERIFY(!num.toObject().strictlyEquals(num));
3559 QVERIFY(!num.strictlyEquals(QJSValue()));
3560 QVERIFY(!QJSValue().strictlyEquals(num));
3562 QJSValue str = QJSValue(&eng, QLatin1String("123"));
3563 QCOMPARE(str.strictlyEquals(QJSValue(&eng, QLatin1String("123"))), true);
3564 QCOMPARE(str.strictlyEquals(QJSValue(&eng, QLatin1String("321"))), false);
3565 QCOMPARE(str.strictlyEquals(QJSValue(&eng, 123)), false);
3566 QCOMPARE(str.strictlyEquals(QJSValue(&eng, 321)), false);
3567 QCOMPARE(str.strictlyEquals(QJSValue(&eng, QLatin1String("123")).toObject()), false);
3568 QCOMPARE(str.strictlyEquals(QJSValue(&eng, QLatin1String("321")).toObject()), false);
3569 QCOMPARE(str.strictlyEquals(QJSValue(&eng, 123).toObject()), false);
3570 QCOMPARE(str.strictlyEquals(QJSValue(&eng, 321).toObject()), false);
3571 QVERIFY(!str.toObject().strictlyEquals(str));
3572 QVERIFY(!str.strictlyEquals(QJSValue()));
3574 QJSValue num2 = QJSValue(123);
3575 QCOMPARE(num2.strictlyEquals(QJSValue(123)), true);
3576 QCOMPARE(num2.strictlyEquals(QJSValue(321)), false);
3577 QCOMPARE(num2.strictlyEquals(QJSValue("123")), false);
3578 QCOMPARE(num2.strictlyEquals(QJSValue("321")), false);
3579 QVERIFY(!num2.strictlyEquals(QJSValue()));
3581 QJSValue str2 = QJSValue("123");
3582 QCOMPARE(str2.strictlyEquals(QJSValue("123")), true);
3583 QCOMPARE(str2.strictlyEquals(QJSValue("321")), false);
3584 QCOMPARE(str2.strictlyEquals(QJSValue(123)), false);
3585 QCOMPARE(str2.strictlyEquals(QJSValue(321)), false);
3586 QVERIFY(!str2.strictlyEquals(QJSValue()));
3588 QJSValue date1 = eng.newDate(QDateTime(QDate(2000, 1, 1)));
3589 QJSValue date2 = eng.newDate(QDateTime(QDate(1999, 1, 1)));
3590 QCOMPARE(date1.strictlyEquals(date2), false);
3591 QCOMPARE(date1.strictlyEquals(date1), true);
3592 QCOMPARE(date2.strictlyEquals(date2), true);
3593 QVERIFY(!date1.strictlyEquals(QJSValue()));
3595 QJSValue undefined = eng.undefinedValue();
3596 QJSValue null = eng.nullValue();
3597 QCOMPARE(undefined.strictlyEquals(undefined), true);
3598 QCOMPARE(null.strictlyEquals(null), true);
3599 QCOMPARE(undefined.strictlyEquals(null), false);
3600 QCOMPARE(null.strictlyEquals(undefined), false);
3601 QVERIFY(!null.strictlyEquals(QJSValue()));
3603 QJSValue sant = QJSValue(&eng, true);
3604 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, 1)));
3605 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, QLatin1String("1"))));
3606 QVERIFY(sant.strictlyEquals(sant));
3607 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, 1).toObject()));
3608 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, QLatin1String("1")).toObject()));
3609 QVERIFY(!sant.strictlyEquals(sant.toObject()));
3610 QVERIFY(!sant.toObject().strictlyEquals(sant));
3611 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, 0)));
3612 QVERIFY(!sant.strictlyEquals(undefined));
3613 QVERIFY(!sant.strictlyEquals(null));
3614 QVERIFY(!sant.strictlyEquals(QJSValue()));
3616 QJSValue falskt = QJSValue(&eng, false);
3617 QVERIFY(!falskt.strictlyEquals(QJSValue(&eng, 0)));
3618 QVERIFY(!falskt.strictlyEquals(QJSValue(&eng, QLatin1String("0"))));
3619 QVERIFY(falskt.strictlyEquals(falskt));
3620 QVERIFY(!falskt.strictlyEquals(QJSValue(&eng, 0).toObject()));
3621 QVERIFY(!falskt.strictlyEquals(QJSValue(&eng, QLatin1String("0")).toObject()));
3622 QVERIFY(!falskt.strictlyEquals(falskt.toObject()));
3623 QVERIFY(!falskt.toObject().strictlyEquals(falskt));
3624 QVERIFY(!falskt.strictlyEquals(sant));
3625 QVERIFY(!falskt.strictlyEquals(undefined));
3626 QVERIFY(!falskt.strictlyEquals(null));
3627 QVERIFY(!falskt.strictlyEquals(QJSValue()));
3629 QVERIFY(!QJSValue(false).strictlyEquals(123));
3630 QVERIFY(!QJSValue(QJSValue::UndefinedValue).strictlyEquals(123));
3631 QVERIFY(!QJSValue(QJSValue::NullValue).strictlyEquals(123));
3632 QVERIFY(!QJSValue(false).strictlyEquals("ciao"));
3633 QVERIFY(!QJSValue(QJSValue::UndefinedValue).strictlyEquals("ciao"));
3634 QVERIFY(!QJSValue(QJSValue::NullValue).strictlyEquals("ciao"));
3635 QVERIFY(QJSValue(&eng, QLatin1String("ciao")).strictlyEquals("ciao"));
3636 QVERIFY(QJSValue("ciao").strictlyEquals(QJSValue(&eng, QLatin1String("ciao"))));
3637 QVERIFY(!QJSValue("ciao").strictlyEquals(123));
3638 QVERIFY(!QJSValue("ciao").strictlyEquals(QJSValue(&eng, 123)));
3639 QVERIFY(!QJSValue(123).strictlyEquals("ciao"));
3640 QVERIFY(!QJSValue(123).strictlyEquals(QJSValue(&eng, QLatin1String("ciao"))));
3641 QVERIFY(!QJSValue(&eng, 123).strictlyEquals("ciao"));
3643 QJSValue obj1 = eng.newObject();
3644 QJSValue obj2 = eng.newObject();
3645 QCOMPARE(obj1.strictlyEquals(obj2), false);
3646 QCOMPARE(obj2.strictlyEquals(obj1), false);
3647 QCOMPARE(obj1.strictlyEquals(obj1), true);
3648 QCOMPARE(obj2.strictlyEquals(obj2), true);
3649 QVERIFY(!obj1.strictlyEquals(QJSValue()));
3651 QJSValue qobj1 = eng.newQObject(this);
3652 QJSValue qobj2 = eng.newQObject(this);
3653 QVERIFY(qobj1.strictlyEquals(qobj2));
3656 QJSValue var1 = eng.newVariant(QVariant(false));
3657 QJSValue var2 = eng.newVariant(QVariant(false));
3658 QVERIFY(!var1.strictlyEquals(var2));
3659 QVERIFY(!var1.strictlyEquals(QJSValue()));
3662 QJSValue var1 = eng.newVariant(QVariant(false));
3663 QJSValue var2 = eng.newVariant(QVariant(0));
3664 QVERIFY(!var1.strictlyEquals(var2));
3667 QJSValue var1 = eng.newVariant(QVariant(QStringList() << "a"));
3668 QJSValue var2 = eng.newVariant(QVariant(QStringList() << "a"));
3669 QVERIFY(!var1.strictlyEquals(var2));
3672 QJSValue var1 = eng.newVariant(QVariant(QStringList() << "a"));
3673 QJSValue var2 = eng.newVariant(QVariant(QStringList() << "b"));
3674 QVERIFY(!var1.strictlyEquals(var2));
3677 QJSValue var1 = eng.newVariant(QVariant(QPoint(1, 2)));
3678 QJSValue var2 = eng.newVariant(QVariant(QPoint(1, 2)));
3679 QVERIFY(!var1.strictlyEquals(var2));
3682 QJSValue var1 = eng.newVariant(QVariant(QPoint(1, 2)));
3683 QJSValue var2 = eng.newVariant(QVariant(QPoint(3, 4)));
3684 QVERIFY(!var1.strictlyEquals(var2));
3687 QJSEngine otherEngine;
3688 QTest::ignoreMessage(QtWarningMsg, "QJSValue::strictlyEquals: "
3689 "cannot compare to a value created in "
3690 "a different engine");
3691 QCOMPARE(date1.strictlyEquals(QJSValue(&otherEngine, 123)), false);
3694 Q_DECLARE_METATYPE(int*)
3695 Q_DECLARE_METATYPE(double*)
3696 Q_DECLARE_METATYPE(QColor*)
3697 Q_DECLARE_METATYPE(QBrush*)
3699 void tst_QJSValue::castToPointer()
3703 QJSValue v = eng.newVariant(int(123));
3704 int *ip = qjsvalue_cast<int*>(v);
3708 QCOMPARE(qjsvalue_cast<int>(v), 456);
3710 double *dp = qjsvalue_cast<double*>(v);
3713 QJSValue v2 = eng.newVariant(qVariantFromValue(ip));
3714 QCOMPARE(qjsvalue_cast<int*>(v2), ip);
3717 QColor c(123, 210, 231);
3718 QJSValue v = eng.newVariant(c);
3719 QColor *cp = qjsvalue_cast<QColor*>(v);
3723 QBrush *bp = qjsvalue_cast<QBrush*>(v);
3726 QJSValue v2 = eng.newVariant(qVariantFromValue(cp));
3727 QCOMPARE(qjsvalue_cast<QColor*>(v2), cp);
3731 void tst_QJSValue::prettyPrinter_data()
3733 QTest::addColumn<QString>("function");
3734 QTest::addColumn<QString>("expected");
3735 QTest::newRow("function() { }") << QString("function() { }") << QString("function () { }");
3736 QTest::newRow("function foo() { }") << QString("(function foo() { })") << QString("function foo() { }");
3737 QTest::newRow("function foo(bar) { }") << QString("(function foo(bar) { })") << QString("function foo(bar) { }");
3738 QTest::newRow("function foo(bar, baz) { }") << QString("(function foo(bar, baz) { })") << QString("function foo(bar, baz) { }");
3739 QTest::newRow("this") << QString("function() { this; }") << QString("function () { this; }");
3740 QTest::newRow("identifier") << QString("function(a) { a; }") << QString("function (a) { a; }");
3741 QTest::newRow("null") << QString("function() { null; }") << QString("function () { null; }");
3742 QTest::newRow("true") << QString("function() { true; }") << QString("function () { true; }");
3743 QTest::newRow("false") << QString("function() { false; }") << QString("function () { false; }");
3744 QTest::newRow("string") << QString("function() { 'test'; }") << QString("function () { \'test\'; }");
3745 QTest::newRow("string") << QString("function() { \"test\"; }") << QString("function () { \"test\"; }");
3746 QTest::newRow("number") << QString("function() { 123; }") << QString("function () { 123; }");
3747 QTest::newRow("number") << QString("function() { 123.456; }") << QString("function () { 123.456; }");
3748 QTest::newRow("regexp") << QString("function() { /hello/; }") << QString("function () { /hello/; }");
3749 QTest::newRow("regexp") << QString("function() { /hello/gim; }") << QString("function () { /hello/gim; }");
3750 QTest::newRow("array") << QString("function() { []; }") << QString("function () { []; }");
3751 QTest::newRow("array") << QString("function() { [10]; }") << QString("function () { [10]; }");
3752 QTest::newRow("array") << QString("function() { [10, 20, 30]; }") << QString("function () { [10, 20, 30]; }");
3753 QTest::newRow("array") << QString("function() { [10, 20, , 40]; }") << QString("function () { [10, 20, , 40]; }");
3754 QTest::newRow("array") << QString("function() { [,]; }") << QString("function () { [,]; }");
3755 QTest::newRow("array") << QString("function() { [, 10]; }") << QString("function () { [, 10]; }");
3756 QTest::newRow("array") << QString("function() { [, 10, ]; }") << QString("function () { [, 10, ]; }");
3757 QTest::newRow("array") << QString("function() { [, 10, ,]; }") << QString("function () { [, 10, ,]; }");
3758 QTest::newRow("array") << QString("function() { [[10], [20]]; }") << QString("function () { [[10], [20]]; }");
3759 QTest::newRow("member") << QString("function() { a.b; }") << QString("function () { a.b; }");
3760 QTest::newRow("member") << QString("function() { a.b.c; }") << QString("function () { a.b.c; }");
3761 QTest::newRow("call") << QString("function() { f(); }") << QString("function () { f(); }");
3762 QTest::newRow("call") << QString("function() { f(a); }") << QString("function () { f(a); }");
3763 QTest::newRow("call") << QString("function() { f(a, b); }") << QString("function () { f(a, b); }");
3764 QTest::newRow("new") << QString("function() { new C(); }") << QString("function () { new C(); }");
3765 QTest::newRow("new") << QString("function() { new C(a); }") << QString("function () { new C(a); }");
3766 QTest::newRow("new") << QString("function() { new C(a, b); }") << QString("function () { new C(a, b); }");
3767 QTest::newRow("++") << QString("function() { a++; }") << QString("function () { a++; }");
3768 QTest::newRow("++") << QString("function() { ++a; }") << QString("function () { ++a; }");
3769 QTest::newRow("--") << QString("function() { a--; }") << QString("function () { a--; }");
3770 QTest::newRow("--") << QString("function() { --a; }") << QString("function () { --a; }");
3771 QTest::newRow("delete") << QString("function() { delete a; }") << QString("function () { delete a; }");
3772 QTest::newRow("void") << QString("function() { void a; }") << QString("function () { void a; }");
3773 QTest::newRow("typeof") << QString("function() { typeof a; }") << QString("function () { typeof a; }");
3774 QTest::newRow("+") << QString("function() { +a; }") << QString("function () { +a; }");
3775 QTest::newRow("-") << QString("function() { -a; }") << QString("function () { -a; }");
3776 QTest::newRow("~") << QString("function() { ~a; }") << QString("function () { ~a; }");
3777 QTest::newRow("!") << QString("function() { !a; }") << QString("function () { !a; }");
3778 QTest::newRow("+") << QString("function() { a + b; }") << QString("function () { a + b; }");
3779 QTest::newRow("&&") << QString("function() { a && b; }") << QString("function () { a && b; }");
3780 QTest::newRow("&=") << QString("function() { a &= b; }") << QString("function () { a &= b; }");
3781 QTest::newRow("=") << QString("function() { a = b; }") << QString("function () { a = b; }");
3782 QTest::newRow("&") << QString("function() { a & b; }") << QString("function () { a & b; }");
3783 QTest::newRow("|") << QString("function() { a | b; }") << QString("function () { a | b; }");
3784 QTest::newRow("^") << QString("function() { a ^ b; }") << QString("function () { a ^ b; }");
3785 QTest::newRow("-=") << QString("function() { a -= b; }") << QString("function () { a -= b; }");
3786 QTest::newRow("/") << QString("function() { a / b; }") << QString("function () { a / b; }");
3787 QTest::newRow("/=") << QString("function() { a /= b; }") << QString("function () { a /= b; }");
3788 QTest::newRow("==") << QString("function() { a == b; }") << QString("function () { a == b; }");
3789 QTest::newRow(">=") << QString("function() { a >= b; }") << QString("function () { a >= b; }");
3790 QTest::newRow(">") << QString("function() { a > b; }") << QString("function () { a > b; }");
3791 QTest::newRow("in") << QString("function() { a in b; }") << QString("function () { a in b; }");
3792 QTest::newRow("+=") << QString("function() { a += b; }") << QString("function () { a += b; }");
3793 QTest::newRow("instanceof") << QString("function() { a instanceof b; }") << QString("function () { a instanceof b; }");
3794 QTest::newRow("<=") << QString("function() { a <= b; }") << QString("function () { a <= b; }");
3795 QTest::newRow("<<") << QString("function() { a << b; }") << QString("function () { a << b; }");
3796 QTest::newRow("<<=") << QString("function() { a <<= b; }") << QString("function () { a <<= b; }");
3797 QTest::newRow("<") << QString("function() { a < b; }") << QString("function () { a < b; }");
3798 QTest::newRow("%") << QString("function() { a % b; }") << QString("function () { a % b; }");
3799 QTest::newRow("%=") << QString("function() { a %= b; }") << QString("function () { a %= b; }");
3800 QTest::newRow("*") << QString("function() { a * b; }") << QString("function () { a * b; }");
3801 QTest::newRow("*=") << QString("function() { a *= b; }") << QString("function () { a *= b; }");
3802 QTest::newRow("!=") << QString("function() { a != b; }") << QString("function () { a != b; }");
3803 QTest::newRow("||") << QString("function() { a || b; }") << QString("function () { a || b; }");
3804 QTest::newRow("|=") << QString("function() { a |= b; }") << QString("function () { a |= b; }");
3805 QTest::newRow(">>") << QString("function() { a >> b; }") << QString("function () { a >> b; }");
3806 QTest::newRow(">>=") << QString("function() { a >>= b; }") << QString("function () { a >>= b; }");
3807 QTest::newRow("===") << QString("function() { a === b; }") << QString("function () { a === b; }");
3808 QTest::newRow("!==") << QString("function() { a !== b; }") << QString("function () { a !== b; }");
3809 QTest::newRow("-") << QString("function() { a - b; }") << QString("function () { a - b; }");
3810 QTest::newRow(">>>") << QString("function() { a >>> b; }") << QString("function () { a >>> b; }");
3811 QTest::newRow(">>>=") << QString("function() { a >>>= b; }") << QString("function () { a >>>= b; }");
3812 QTest::newRow("^=") << QString("function() { a ^= b; }") << QString("function () { a ^= b; }");
3813 QTest::newRow("? :") << QString("function() { a ? b : c; }") << QString("function () { a ? b : c; }");
3814 QTest::newRow("a; b; c") << QString("function() { a; b; c; }") << QString("function () { a; b; c; }");
3815 QTest::newRow("var a;") << QString("function() { var a; }") << QString("function () { var a; }");
3816 QTest::newRow("var a, b;") << QString("function() { var a, b; }") << QString("function () { var a, b; }");
3817 QTest::newRow("var a = 10;") << QString("function() { var a = 10; }") << QString("function () { var a = 10; }");
3818 QTest::newRow("var a, b = 20;") << QString("function() { var a, b = 20; }") << QString("function () { var a, b = 20; }");
3819 QTest::newRow("var a = 10, b = 20;") << QString("function() { var a = 10, b = 20; }") << QString("function () { var a = 10, b = 20; }");
3820 QTest::newRow("if") << QString("function() { if (a) b; }") << QString("function () { if (a) b; }");
3821 QTest::newRow("if") << QString("function() { if (a) { b; c; } }") << QString("function () { if (a) { b; c; } }");
3822 QTest::newRow("if-else") << QString("function() { if (a) b; else c; }") << QString("function () { if (a) b; else c; }");
3823 QTest::newRow("if-else") << QString("function() { if (a) { b; c; } else { d; e; } }") << QString("function () { if (a) { b; c; } else { d; e; } }");
3824 QTest::newRow("do-while") << QString("function() { do { a; } while (b); }") << QString("function () { do { a; } while (b); }");
3825 QTest::newRow("do-while") << QString("function() { do { a; b; c; } while (d); }") << QString("function () { do { a; b; c; } while (d); }");
3826 QTest::newRow("while") << QString("function() { while (a) { b; } }") << QString("function () { while (a) { b; } }");
3827 QTest::newRow("while") << QString("function() { while (a) { b; c; } }") << QString("function () { while (a) { b; c; } }");
3828 QTest::newRow("for") << QString("function() { for (a; b; c) { } }") << QString("function () { for (a; b; c) { } }");
3829 QTest::newRow("for") << QString("function() { for (; a; b) { } }") << QString("function () { for (; a; b) { } }");
3830 QTest::newRow("for") << QString("function() { for (; ; a) { } }") << QString("function () { for (; ; a) { } }");
3831 QTest::newRow("for") << QString("function() { for (; ; ) { } }") << QString("function () { for (; ; ) { } }");
3832 QTest::newRow("for") << QString("function() { for (var a; b; c) { } }") << QString("function () { for (var a; b; c) { } }");
3833 QTest::newRow("for") << QString("function() { for (var a, b, c; d; e) { } }") << QString("function () { for (var a, b, c; d; e) { } }");
3834 QTest::newRow("continue") << QString("function() { for (; ; ) { continue; } }") << QString("function () { for (; ; ) { continue; } }");
3835 QTest::newRow("break") << QString("function() { for (; ; ) { break; } }") << QString("function () { for (; ; ) { break; } }");
3836 QTest::newRow("return") << QString("function() { return; }") << QString("function () { return; }");
3837 QTest::newRow("return") << QString("function() { return 10; }") << QString("function () { return 10; }");
3838 QTest::newRow("with") << QString("function() { with (a) { b; } }") << QString("function () { with (a) { b; } }");
3839 QTest::newRow("with") << QString("function() { with (a) { b; c; } }") << QString("function () { with (a) { b; c; } }");
3840 QTest::newRow("switch") << QString("function() { switch (a) { } }") << QString("function () { switch (a) { } }");
3841 QTest::newRow("switch") << QString("function() { switch (a) { case 1: ; } }") << QString("function () { switch (a) { case 1: ; } }");
3842 QTest::newRow("switch") << QString("function() { switch (a) { case 1: b; break; } }") << QString("function () { switch (a) { case 1: b; break; } }");
3843 QTest::newRow("switch") << QString("function() { switch (a) { case 1: b; break; case 2: break; } }") << QString("function () { switch (a) { case 1: b; break; case 2: break; } }");
3844 QTest::newRow("switch") << QString("function() { switch (a) { case 1: case 2: ; } }") << QString("function () { switch (a) { case 1: case 2: ; } }");
3845 QTest::newRow("switch") << QString("function() { switch (a) { case 1: default: ; } }") << QString("function () { switch (a) { case 1: default: ; } }");
3846 QTest::newRow("switch") << QString("function() { switch (a) { case 1: default: ; case 3: ; } }") << QString("function () { switch (a) { case 1: default: ; case 3: ; } }");
3847 QTest::newRow("label") << QString("function() { a: b; }") << QString("function () { a: b; }");
3848 QTest::newRow("throw") << QString("function() { throw a; }") << QString("function () { throw a; }");
3849 QTest::newRow("try-catch") << QString("function() { try { a; } catch (e) { b; } }") << QString("function () { try { a; } catch (e) { b; } }");
3850 QTest::newRow("try-finally") << QString("function() { try { a; } finally { b; } }") << QString("function () { try { a; } finally { b; } }");
3851 QTest::newRow("try-catch-finally") << QString("function() { try { a; } catch (e) { b; } finally { c; } }") << QString("function () { try { a; } catch (e) { b; } finally { c; } }");
3852 QTest::newRow("a + b + c + d") << QString("function() { a + b + c + d; }") << QString("function () { a + b + c + d; }");
3853 QTest::newRow("a + b - c") << QString("function() { a + b - c; }") << QString("function () { a + b - c; }");
3854 QTest::newRow("a + -b") << QString("function() { a + -b; }") << QString("function () { a + -b; }");
3855 QTest::newRow("a + ~b") << QString("function() { a + ~b; }") << QString("function () { a + ~b; }");
3856 QTest::newRow("a + !b") << QString("function() { a + !b; }") << QString("function () { a + !b; }");
3857 QTest::newRow("a + +b") << QString("function() { a + +b; }") << QString("function () { a + +b; }");
3858 QTest::newRow("(a + b) - c") << QString("function() { (a + b) - c; }") << QString("function () { (a + b) - c; }");
3859 QTest::newRow("(a - b + c") << QString("function() { a - b + c; }") << QString("function () { a - b + c; }");
3860 QTest::newRow("(a - (b + c)") << QString("function() { a - (b + c); }") << QString("function () { a - (b + c); }");
3861 QTest::newRow("a + -(b + c)") << QString("function() { a + -(b + c); }") << QString("function () { a + -(b + c); }");
3862 QTest::newRow("a + ~(b + c)") << QString("function() { a + ~(b + c); }") << QString("function () { a + ~(b + c); }");
3863 QTest::newRow("a + !(b + c)") << QString("function() { a + !(b + c); }") << QString("function () { a + !(b + c); }");
3864 QTest::newRow("a + +(b + c)") << QString("function() { a + +(b + c); }") << QString("function () { a + +(b + c); }");
3865 QTest::newRow("a + b * c") << QString("function() { a + b * c; }") << QString("function () { a + b * c; }");
3866 QTest::newRow("(a + b) * c") << QString("function() { (a + b) * c; }") << QString("function () { (a + b) * c; }");
3867 QTest::newRow("(a + b) * (c + d)") << QString("function() { (a + b) * (c + d); }") << QString("function () { (a + b) * (c + d); }");
3868 QTest::newRow("a + (b * c)") << QString("function() { a + (b * c); }") << QString("function () { a + (b * c); }");
3869 QTest::newRow("a + (b / c)") << QString("function() { a + (b / c); }") << QString("function () { a + (b / c); }");
3870 QTest::newRow("(a / b) * c") << QString("function() { (a / b) * c; }") << QString("function () { (a / b) * c; }");
3871 QTest::newRow("a / (b * c)") << QString("function() { a / (b * c); }") << QString("function () { a / (b * c); }");
3872 QTest::newRow("a / (b % c)") << QString("function() { a / (b % c); }") << QString("function () { a / (b % c); }");
3873 QTest::newRow("a && b || c") << QString("function() { a && b || c; }") << QString("function () { a && b || c; }");
3874 QTest::newRow("a && (b || c)") << QString("function() { a && (b || c); }") << QString("function () { a && (b || c); }");
3875 QTest::newRow("a & b | c") << QString("function() { a & b | c; }") << QString("function () { a & b | c; }");
3876 QTest::newRow("a & (b | c)") << QString("function() { a & (b | c); }") << QString("function () { a & (b | c); }");
3877 QTest::newRow("a & b | c ^ d") << QString("function() { a & b | c ^ d; }") << QString("function () { a & b | c ^ d; }");
3878 QTest::newRow("a & (b | c ^ d)") << QString("function() { a & (b | c ^ d); }") << QString("function () { a & (b | c ^ d); }");
3879 QTest::newRow("(a & b | c) ^ d") << QString("function() { (a & b | c) ^ d; }") << QString("function () { (a & b | c) ^ d; }");
3880 QTest::newRow("a << b + c") << QString("function() { a << b + c; }") << QString("function () { a << b + c; }");
3881 QTest::newRow("(a << b) + c") << QString("function() { (a << b) + c; }") << QString("function () { (a << b) + c; }");
3882 QTest::newRow("a >> b + c") << QString("function() { a >> b + c; }") << QString("function () { a >> b + c; }");
3883 QTest::newRow("(a >> b) + c") << QString("function() { (a >> b) + c; }") << QString("function () { (a >> b) + c; }");
3884 QTest::newRow("a >>> b + c") << QString("function() { a >>> b + c; }") << QString("function () { a >>> b + c; }");
3885 QTest::newRow("(a >>> b) + c") << QString("function() { (a >>> b) + c; }") << QString("function () { (a >>> b) + c; }");
3886 QTest::newRow("a == b || c != d") << QString("function() { a == b || c != d; }") << QString("function () { a == b || c != d; }");
3887 QTest::newRow("a == (b || c != d)") << QString("function() { a == (b || c != d); }") << QString("function () { a == (b || c != d); }");
3888 QTest::newRow("a === b || c !== d") << QString("function() { a === b || c !== d; }") << QString("function () { a === b || c !== d; }");
3889 QTest::newRow("a === (b || c !== d)") << QString("function() { a === (b || c !== d); }") << QString("function () { a === (b || c !== d); }");
3890 QTest::newRow("a &= b + c") << QString("function() { a &= b + c; }") << QString("function () { a &= b + c; }");
3891 QTest::newRow("debugger") << QString("function() { debugger; }") << QString("function () { debugger; }");
3894 void tst_QJSValue::prettyPrinter()
3896 QFETCH(QString, function);
3897 QFETCH(QString, expected);
3899 QJSValue val = eng.evaluate("(" + function + ")");
3900 QVERIFY(val.isFunction());
3901 QString actual = val.toString();
3902 int count = qMin(actual.size(), expected.size());
3903 // qDebug() << actual << expected;
3904 for (int i = 0; i < count; ++i) {
3905 // qDebug() << i << actual.at(i) << expected.at(i);
3906 QCOMPARE(actual.at(i), expected.at(i));
3908 QCOMPARE(actual.size(), expected.size());
3911 void tst_QJSValue::engineDeleted()
3913 QJSEngine *eng = new QJSEngine;
3914 QJSValue v1(eng, 123);
3915 QVERIFY(v1.isNumber());
3916 QJSValue v2(eng, QString("ciao"));
3917 QVERIFY(v2.isString());
3918 QJSValue v3 = eng->newObject();
3919 QVERIFY(v3.isObject());
3920 QJSValue v4 = eng->newQObject(this);
3921 QVERIFY(v4.isQObject());
3922 QJSValue v5 = "Hello";
3923 QVERIFY(v2.isString());
3927 QVERIFY(!v1.isValid());
3928 QVERIFY(v1.engine() == 0);
3929 QVERIFY(!v2.isValid());
3930 QVERIFY(v2.engine() == 0);
3931 QVERIFY(!v3.isValid());
3932 QVERIFY(v3.engine() == 0);
3933 QVERIFY(!v4.isValid());
3934 QVERIFY(v4.engine() == 0);
3935 QVERIFY(v5.isValid());
3936 QVERIFY(v5.engine() == 0);
3938 QVERIFY(!v3.property("foo").isValid());
3941 void tst_QJSValue::valueOfWithClosure()
3946 QJSValue obj = eng.evaluate("o = {}; (function(foo) { o.valueOf = function() { return foo; } })(123); o");
3947 QVERIFY(obj.isObject());
3948 QCOMPARE(obj.toInt32(), 123);
3952 QJSValue obj = eng.evaluate("o = {}; (function(foo) { o.toString = function() { return foo; } })('ciao'); o");
3953 QVERIFY(obj.isObject());
3954 QCOMPARE(obj.toString(), QString::fromLatin1("ciao"));
3958 #if 0 // FIXME: no objectId()
3959 void tst_QJSValue::objectId()
3961 QCOMPARE(QJSValue().objectId(), (qint64)-1);
3962 QCOMPARE(QJSValue(QJSValue::UndefinedValue).objectId(), (qint64)-1);
3963 QCOMPARE(QJSValue(QJSValue::NullValue).objectId(), (qint64)-1);
3964 QCOMPARE(QJSValue(false).objectId(), (qint64)-1);
3965 QCOMPARE(QJSValue(123).objectId(), (qint64)-1);
3966 QCOMPARE(QJSValue(uint(123)).objectId(), (qint64)-1);
3967 QCOMPARE(QJSValue(123.5).objectId(), (qint64)-1);
3968 QCOMPARE(QJSValue("ciao").objectId(), (qint64)-1);
3971 QJSValue o1 = eng.newObject();
3972 QVERIFY(o1.objectId() != -1);
3973 QJSValue o2 = eng.newObject();
3974 QVERIFY(o2.objectId() != -1);
3975 QVERIFY(o1.objectId() != o2.objectId());
3977 QVERIFY(eng.objectById(o1.objectId()).strictlyEquals(o1));
3978 QVERIFY(eng.objectById(o2.objectId()).strictlyEquals(o2));
3980 qint64 globalObjectId = -1;
3982 QJSValue global = eng.globalObject();
3983 globalObjectId = global.objectId();
3984 QVERIFY(globalObjectId != -1);
3985 QVERIFY(eng.objectById(globalObjectId).strictlyEquals(global));
3987 QJSValue obj = eng.objectById(globalObjectId);
3988 QVERIFY(obj.isObject());
3989 QVERIFY(obj.strictlyEquals(eng.globalObject()));
3993 void tst_QJSValue::nestedObjectToVariant_data()
3995 QTest::addColumn<QString>("program");
3996 QTest::addColumn<QVariant>("expected");
3999 QTest::newRow("[[]]")
4000 << QString::fromLatin1("[[]]")
4001 << QVariant(QVariantList() << (QVariant(QVariantList())));
4002 QTest::newRow("[[123]]")
4003 << QString::fromLatin1("[[123]]")
4004 << QVariant(QVariantList() << (QVariant(QVariantList() << 123)));
4005 QTest::newRow("[[], 123]")
4006 << QString::fromLatin1("[[], 123]")
4007 << QVariant(QVariantList() << QVariant(QVariantList()) << 123);
4010 QTest::newRow("var a=[]; a.push(a)")
4011 << QString::fromLatin1("var a=[]; a.push(a); a")
4012 << QVariant(QVariantList() << QVariant(QVariantList()));
4013 QTest::newRow("var a=[]; a.push(123, a)")
4014 << QString::fromLatin1("var a=[]; a.push(123, a); a")
4015 << QVariant(QVariantList() << 123 << QVariant(QVariantList()));
4016 QTest::newRow("var a=[]; var b=[]; a.push(b); b.push(a)")
4017 << QString::fromLatin1("var a=[]; var b=[]; a.push(b); b.push(a); a")
4018 << QVariant(QVariantList() << QVariant(QVariantList() << QVariant(QVariantList())));
4019 QTest::newRow("var a=[]; var b=[]; a.push(123, b); b.push(456, a)")
4020 << QString::fromLatin1("var a=[]; var b=[]; a.push(123, b); b.push(456, a); a")
4021 << QVariant(QVariantList() << 123 << QVariant(QVariantList() << 456 << QVariant(QVariantList())));
4026 m["a"] = QVariantMap();
4027 QTest::newRow("{ a:{} }")
4028 << QString::fromLatin1("({ a:{} })")
4036 QTest::newRow("{ a:{b:10, c:20} }")
4037 << QString::fromLatin1("({ a:{b:10, c:20} })")
4043 m["b"] = QVariantList() << 20 << 30;
4044 QTest::newRow("{ a:10, b:[20, 30]}")
4045 << QString::fromLatin1("({ a:10, b:[20,30]})")
4052 m["p"] = QVariantMap();
4053 QTest::newRow("var o={}; o.p=o")
4054 << QString::fromLatin1("var o={}; o.p=o; o")
4060 m["q"] = QVariantMap();
4061 QTest::newRow("var o={}; o.p=123; o.q=o")
4062 << QString::fromLatin1("var o={}; o.p=123; o.q=o; o")
4067 void tst_QJSValue::nestedObjectToVariant()
4070 QFETCH(QString, program);
4071 QFETCH(QVariant, expected);
4072 QJSValue o = eng.evaluate(program);
4073 QVERIFY(!o.isError());
4074 QVERIFY(o.isObject());
4075 QCOMPARE(o.toVariant(), expected);
4078 void tst_QJSValue::propertyFlags_data()
4080 QTest::addColumn<QString>("program");
4081 QTest::addColumn<uint>("expected");
4083 QTest::newRow("nothing") << "" << 0u;
4084 #if 0 // FIXME: No getter/setter API
4085 QTest::newRow("getter") << "o.__defineGetter__('prop', function() { return 'blah' } );\n" << uint(QJSValue::PropertyGetter);
4086 QTest::newRow("setter") << "o.__defineSetter__('prop', function(a) { this.setted_prop2 = a; } );\n" << uint(QJSValue::PropertySetter);
4087 QTest::newRow("getterSetter") << "o.__defineGetter__('prop', function() { return 'ploup' } );\n"
4088 "o.__defineSetter__('prop', function(a) { this.setted_prop3 = a; } );\n" << uint(QJSValue::PropertySetter|QJSValue::PropertyGetter);
4090 QTest::newRow("nothing2") << "o.prop = 'nothing'" << 0u;
4093 void tst_QJSValue::propertyFlags()
4095 QFETCH(QString, program);
4096 QFETCH(uint, expected);
4098 eng.evaluate("o = new Object;");
4099 eng.evaluate(program);
4100 QJSValue o = eng.evaluate("o");
4102 QCOMPARE(uint(o.propertyFlags("prop")), expected);
4106 QTEST_MAIN(tst_QJSValue)