1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
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.isBool(), true);
101 QCOMPARE(v.isBool(), true);
102 QCOMPARE(v.isObject(), false);
103 QCOMPARE(v.toBool(), 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.toInt(), 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.toUInt(), 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.isBool(), true);
287 QCOMPARE(v.isBool(), true);
288 QCOMPARE(v.isObject(), false);
289 QCOMPARE(v.toBool(), 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.toBool(), false);
540 QCOMPARE(qjsvalue_cast<bool>(undefined), false);
542 QJSValue null = eng.nullValue();
543 QCOMPARE(null.toBool(), false);
544 QCOMPARE(qjsvalue_cast<bool>(null), false);
547 QJSValue falskt = QJSValue(&eng, false);
548 QCOMPARE(falskt.toBool(), false);
549 QCOMPARE(qjsvalue_cast<bool>(falskt), false);
551 QJSValue sant = QJSValue(&eng, true);
552 QCOMPARE(sant.toBool(), true);
553 QCOMPARE(qjsvalue_cast<bool>(sant), true);
555 QJSValue number = QJSValue(&eng, 0.0);
556 QCOMPARE(number.toBool(), false);
557 QCOMPARE(qjsvalue_cast<bool>(number), false);
559 QJSValue number2 = QJSValue(&eng, qSNaN());
560 QCOMPARE(number2.toBool(), false);
561 QCOMPARE(qjsvalue_cast<bool>(number2), false);
563 QJSValue number3 = QJSValue(&eng, 123.0);
564 QCOMPARE(number3.toBool(), true);
565 QCOMPARE(qjsvalue_cast<bool>(number3), true);
567 QJSValue number4 = QJSValue(&eng, -456.0);
568 QCOMPARE(number4.toBool(), true);
569 QCOMPARE(qjsvalue_cast<bool>(number4), true);
571 QJSValue str = QJSValue(&eng, QString(""));
572 QCOMPARE(str.toBool(), false);
573 QCOMPARE(qjsvalue_cast<bool>(str), false);
575 QJSValue str2 = QJSValue(&eng, QString("123"));
576 QCOMPARE(str2.toBool(), true);
577 QCOMPARE(qjsvalue_cast<bool>(str2), true);
580 QJSValue object = eng.newObject();
581 QCOMPARE(object.toBool(), 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.toBool(), false);
593 QCOMPARE(qjsvalue_cast<bool>(inv), false);
597 QJSValue falskt = QJSValue(false);
598 QCOMPARE(falskt.toBool(), false);
599 QCOMPARE(qjsvalue_cast<bool>(falskt), false);
601 QJSValue sant = QJSValue(true);
602 QCOMPARE(sant.toBool(), true);
603 QCOMPARE(qjsvalue_cast<bool>(sant), true);
605 QJSValue number = QJSValue(0.0);
606 QCOMPARE(number.toBool(), false);
607 QCOMPARE(qjsvalue_cast<bool>(number), false);
609 QJSValue number2 = QJSValue(qSNaN());
610 QCOMPARE(number2.toBool(), false);
611 QCOMPARE(qjsvalue_cast<bool>(number2), false);
613 QJSValue number3 = QJSValue(123.0);
614 QCOMPARE(number3.toBool(), true);
615 QCOMPARE(qjsvalue_cast<bool>(number3), true);
617 QJSValue number4 = QJSValue(-456.0);
618 QCOMPARE(number4.toBool(), true);
619 QCOMPARE(qjsvalue_cast<bool>(number4), true);
621 QJSValue number5 = QJSValue(0x43211234);
622 QCOMPARE(number5.toBool(), true);
624 QJSValue str = QJSValue(QString(""));
625 QCOMPARE(str.toBool(), false);
626 QCOMPARE(qjsvalue_cast<bool>(str), false);
628 QJSValue str2 = QJSValue(QString("123"));
629 QCOMPARE(str2.toBool(), 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::toInt()
826 QJSValue zer0 = QJSValue(&eng, 0.0);
827 QCOMPARE(zer0.toInt(), 0);
828 QCOMPARE(qjsvalue_cast<qint32>(zer0), 0);
830 QJSValue number = QJSValue(&eng, 123.0);
831 QCOMPARE(number.toInt(), 123);
832 QCOMPARE(qjsvalue_cast<qint32>(number), 123);
834 QJSValue number2 = QJSValue(&eng, qSNaN());
835 QCOMPARE(number2.toInt(), 0);
836 QCOMPARE(qjsvalue_cast<qint32>(number2), 0);
838 QJSValue number3 = QJSValue(&eng, +qInf());
839 QCOMPARE(number3.toInt(), 0);
840 QCOMPARE(qjsvalue_cast<qint32>(number3), 0);
842 QJSValue number3_2 = QJSValue(&eng, -qInf());
843 QCOMPARE(number3_2.toInt(), 0);
844 QCOMPARE(qjsvalue_cast<qint32>(number3_2), 0);
846 QJSValue number4 = QJSValue(&eng, 0.5);
847 QCOMPARE(number4.toInt(), 0);
848 QCOMPARE(qjsvalue_cast<qint32>(number4), 0);
850 QJSValue number5 = QJSValue(&eng, 123.5);
851 QCOMPARE(number5.toInt(), 123);
852 QCOMPARE(qjsvalue_cast<qint32>(number5), 123);
854 QJSValue number6 = QJSValue(&eng, -456.5);
855 QCOMPARE(number6.toInt(), -456);
856 QCOMPARE(qjsvalue_cast<qint32>(number6), -456);
858 QJSValue str = QJSValue(&eng, QLatin1String("123.0"));
859 QCOMPARE(str.toInt(), 123);
860 QCOMPARE(qjsvalue_cast<qint32>(str), 123);
862 QJSValue str2 = QJSValue(&eng, QLatin1String("NaN"));
863 QCOMPARE(str2.toInt(), 0);
864 QCOMPARE(qjsvalue_cast<qint32>(str2), 0);
866 QJSValue str3 = QJSValue(&eng, QLatin1String("Infinity"));
867 QCOMPARE(str3.toInt(), 0);
868 QCOMPARE(qjsvalue_cast<qint32>(str3), 0);
870 QJSValue str3_2 = QJSValue(&eng, QLatin1String("-Infinity"));
871 QCOMPARE(str3_2.toInt(), 0);
872 QCOMPARE(qjsvalue_cast<qint32>(str3_2), 0);
874 QJSValue str4 = QJSValue(&eng, QLatin1String("0.5"));
875 QCOMPARE(str4.toInt(), 0);
876 QCOMPARE(qjsvalue_cast<qint32>(str4), 0);
878 QJSValue str5 = QJSValue(&eng, QLatin1String("123.5"));
879 QCOMPARE(str5.toInt(), 123);
880 QCOMPARE(qjsvalue_cast<qint32>(str5), 123);
882 QJSValue str6 = QJSValue(&eng, QLatin1String("-456.5"));
883 QCOMPARE(str6.toInt(), -456);
884 QCOMPARE(qjsvalue_cast<qint32>(str6), -456);
888 QJSValue zer0 = QJSValue(0.0);
889 QCOMPARE(zer0.toInt(), 0);
890 QCOMPARE(qjsvalue_cast<qint32>(zer0), 0);
892 QJSValue number = QJSValue(123.0);
893 QCOMPARE(number.toInt(), 123);
894 QCOMPARE(qjsvalue_cast<qint32>(number), 123);
896 QJSValue number2 = QJSValue(qSNaN());
897 QCOMPARE(number2.toInt(), 0);
898 QCOMPARE(qjsvalue_cast<qint32>(number2), 0);
900 QJSValue number3 = QJSValue(+qInf());
901 QCOMPARE(number3.toInt(), 0);
902 QCOMPARE(qjsvalue_cast<qint32>(number3), 0);
904 QJSValue number3_2 = QJSValue(-qInf());
905 QCOMPARE(number3_2.toInt(), 0);
906 QCOMPARE(qjsvalue_cast<qint32>(number3_2), 0);
908 QJSValue number4 = QJSValue(0.5);
909 QCOMPARE(number4.toInt(), 0);
910 QCOMPARE(qjsvalue_cast<qint32>(number4), 0);
912 QJSValue number5 = QJSValue(123.5);
913 QCOMPARE(number5.toInt(), 123);
914 QCOMPARE(qjsvalue_cast<qint32>(number5), 123);
916 QJSValue number6 = QJSValue(-456.5);
917 QCOMPARE(number6.toInt(), -456);
918 QCOMPARE(qjsvalue_cast<qint32>(number6), -456);
920 QJSValue number7 = QJSValue(0x43211234);
921 QCOMPARE(number7.toInt(), 0x43211234);
923 QJSValue str = QJSValue("123.0");
924 QCOMPARE(str.toInt(), 123);
925 QCOMPARE(qjsvalue_cast<qint32>(str), 123);
927 QJSValue str2 = QJSValue("NaN");
928 QCOMPARE(str2.toInt(), 0);
929 QCOMPARE(qjsvalue_cast<qint32>(str2), 0);
931 QJSValue str3 = QJSValue("Infinity");
932 QCOMPARE(str3.toInt(), 0);
933 QCOMPARE(qjsvalue_cast<qint32>(str3), 0);
935 QJSValue str3_2 = QJSValue("-Infinity");
936 QCOMPARE(str3_2.toInt(), 0);
937 QCOMPARE(qjsvalue_cast<qint32>(str3_2), 0);
939 QJSValue str4 = QJSValue("0.5");
940 QCOMPARE(str4.toInt(), 0);
941 QCOMPARE(qjsvalue_cast<qint32>(str4), 0);
943 QJSValue str5 = QJSValue("123.5");
944 QCOMPARE(str5.toInt(), 123);
945 QCOMPARE(qjsvalue_cast<qint32>(str5), 123);
947 QJSValue str6 = QJSValue("-456.5");
948 QCOMPARE(str6.toInt(), -456);
949 QCOMPARE(qjsvalue_cast<qint32>(str6), -456);
953 QCOMPARE(inv.toInt(), 0);
954 QCOMPARE(qjsvalue_cast<qint32>(inv), 0);
957 void tst_QJSValue::toUInt()
962 QJSValue zer0 = eng.toScriptValue(0.0);
963 QCOMPARE(zer0.toUInt(), quint32(0));
964 QCOMPARE(qjsvalue_cast<quint32>(zer0), quint32(0));
966 QJSValue number = eng.toScriptValue(123.0);
967 QCOMPARE(number.toUInt(), quint32(123));
968 QCOMPARE(qjsvalue_cast<quint32>(number), quint32(123));
970 QJSValue number2 = eng.toScriptValue(qSNaN());
971 QCOMPARE(number2.toUInt(), quint32(0));
972 QCOMPARE(qjsvalue_cast<quint32>(number2), quint32(0));
974 QJSValue number3 = eng.toScriptValue(+qInf());
975 QCOMPARE(number3.toUInt(), quint32(0));
976 QCOMPARE(qjsvalue_cast<quint32>(number3), quint32(0));
978 QJSValue number3_2 = eng.toScriptValue(-qInf());
979 QCOMPARE(number3_2.toUInt(), quint32(0));
980 QCOMPARE(qjsvalue_cast<quint32>(number3_2), quint32(0));
982 QJSValue number4 = eng.toScriptValue(0.5);
983 QCOMPARE(number4.toUInt(), quint32(0));
985 QJSValue number5 = eng.toScriptValue(123.5);
986 QCOMPARE(number5.toUInt(), quint32(123));
988 QJSValue number6 = eng.toScriptValue(-456.5);
989 QCOMPARE(number6.toUInt(), quint32(-456));
990 QCOMPARE(qjsvalue_cast<quint32>(number6), quint32(-456));
992 QJSValue str = eng.toScriptValue(QString::fromLatin1("123.0"));
993 QCOMPARE(str.toUInt(), quint32(123));
994 QCOMPARE(qjsvalue_cast<quint32>(str), quint32(123));
996 QJSValue str2 = eng.toScriptValue(QString::fromLatin1("NaN"));
997 QCOMPARE(str2.toUInt(), quint32(0));
998 QCOMPARE(qjsvalue_cast<quint32>(str2), quint32(0));
1000 QJSValue str3 = eng.toScriptValue(QString::fromLatin1("Infinity"));
1001 QCOMPARE(str3.toUInt(), quint32(0));
1002 QCOMPARE(qjsvalue_cast<quint32>(str3), quint32(0));
1004 QJSValue str3_2 = eng.toScriptValue(QString::fromLatin1("-Infinity"));
1005 QCOMPARE(str3_2.toUInt(), quint32(0));
1006 QCOMPARE(qjsvalue_cast<quint32>(str3_2), quint32(0));
1008 QJSValue str4 = eng.toScriptValue(QString::fromLatin1("0.5"));
1009 QCOMPARE(str4.toUInt(), quint32(0));
1010 QCOMPARE(qjsvalue_cast<quint32>(str4), quint32(0));
1012 QJSValue str5 = eng.toScriptValue(QString::fromLatin1("123.5"));
1013 QCOMPARE(str5.toUInt(), quint32(123));
1014 QCOMPARE(qjsvalue_cast<quint32>(str5), quint32(123));
1016 QJSValue str6 = eng.toScriptValue(QString::fromLatin1("-456.5"));
1017 QCOMPARE(str6.toUInt(), quint32(-456));
1018 QCOMPARE(qjsvalue_cast<quint32>(str6), quint32(-456));
1022 QJSValue zer0 = QJSValue(0.0);
1023 QCOMPARE(zer0.toUInt(), quint32(0));
1024 QCOMPARE(qjsvalue_cast<quint32>(zer0), quint32(0));
1026 QJSValue number = QJSValue(123.0);
1027 QCOMPARE(number.toUInt(), quint32(123));
1028 QCOMPARE(qjsvalue_cast<quint32>(number), quint32(123));
1030 QJSValue number2 = QJSValue(qSNaN());
1031 QCOMPARE(number2.toUInt(), quint32(0));
1032 QCOMPARE(qjsvalue_cast<quint32>(number2), quint32(0));
1034 QJSValue number3 = QJSValue(+qInf());
1035 QCOMPARE(number3.toUInt(), quint32(0));
1036 QCOMPARE(qjsvalue_cast<quint32>(number3), quint32(0));
1038 QJSValue number3_2 = QJSValue(-qInf());
1039 QCOMPARE(number3_2.toUInt(), quint32(0));
1040 QCOMPARE(qjsvalue_cast<quint32>(number3_2), quint32(0));
1042 QJSValue number4 = QJSValue(0.5);
1043 QCOMPARE(number4.toUInt(), quint32(0));
1045 QJSValue number5 = QJSValue(123.5);
1046 QCOMPARE(number5.toUInt(), quint32(123));
1048 QJSValue number6 = QJSValue(-456.5);
1049 QCOMPARE(number6.toUInt(), quint32(-456));
1050 QCOMPARE(qjsvalue_cast<quint32>(number6), quint32(-456));
1052 QJSValue number7 = QJSValue(0x43211234);
1053 QCOMPARE(number7.toUInt(), quint32(0x43211234));
1055 QJSValue str = QJSValue(QLatin1String("123.0"));
1056 QCOMPARE(str.toUInt(), quint32(123));
1057 QCOMPARE(qjsvalue_cast<quint32>(str), quint32(123));
1059 QJSValue str2 = QJSValue(QLatin1String("NaN"));
1060 QCOMPARE(str2.toUInt(), quint32(0));
1061 QCOMPARE(qjsvalue_cast<quint32>(str2), quint32(0));
1063 QJSValue str3 = QJSValue(QLatin1String("Infinity"));
1064 QCOMPARE(str3.toUInt(), quint32(0));
1065 QCOMPARE(qjsvalue_cast<quint32>(str3), quint32(0));
1067 QJSValue str3_2 = QJSValue(QLatin1String("-Infinity"));
1068 QCOMPARE(str3_2.toUInt(), quint32(0));
1069 QCOMPARE(qjsvalue_cast<quint32>(str3_2), quint32(0));
1071 QJSValue str4 = QJSValue(QLatin1String("0.5"));
1072 QCOMPARE(str4.toUInt(), quint32(0));
1073 QCOMPARE(qjsvalue_cast<quint32>(str4), quint32(0));
1075 QJSValue str5 = QJSValue(QLatin1String("123.5"));
1076 QCOMPARE(str5.toUInt(), quint32(123));
1077 QCOMPARE(qjsvalue_cast<quint32>(str5), quint32(123));
1079 QJSValue str6 = QJSValue(QLatin1String("-456.5"));
1080 QCOMPARE(str6.toUInt(), quint32(-456));
1081 QCOMPARE(qjsvalue_cast<quint32>(str6), quint32(-456));
1085 QCOMPARE(inv.toUInt(), 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").toInt(), 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").toInt(), array.property("length").toInt());
1354 for (int i = 0; i < array.property("length").toInt(); ++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.toInt(), number.toInt());
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.isCallable());
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::hasProperty_basic()
1798 QJSValue obj = eng.newObject();
1799 QVERIFY(obj.hasProperty("hasOwnProperty")); // inherited from Object.prototype
1800 QVERIFY(!obj.hasOwnProperty("hasOwnProperty"));
1802 QVERIFY(!obj.hasProperty("foo"));
1803 QVERIFY(!obj.hasOwnProperty("foo"));
1804 obj.setProperty("foo", 123);
1805 QVERIFY(obj.hasProperty("foo"));
1806 QVERIFY(obj.hasOwnProperty("foo"));
1808 QVERIFY(!obj.hasProperty("bar"));
1809 QVERIFY(!obj.hasOwnProperty("bar"));
1812 void tst_QJSValue::hasProperty_globalObject()
1815 QJSValue global = eng.globalObject();
1816 QVERIFY(global.hasProperty("Math"));
1817 QVERIFY(global.hasOwnProperty("Math"));
1818 QVERIFY(!global.hasProperty("NoSuchStandardProperty"));
1819 QVERIFY(!global.hasOwnProperty("NoSuchStandardProperty"));
1821 QVERIFY(!global.hasProperty("foo"));
1822 QVERIFY(!global.hasOwnProperty("foo"));
1823 global.setProperty("foo", 123);
1824 QVERIFY(global.hasProperty("foo"));
1825 QVERIFY(global.hasOwnProperty("foo"));
1828 void tst_QJSValue::hasProperty_changePrototype()
1831 QJSValue obj = eng.newObject();
1832 QJSValue proto = eng.newObject();
1833 obj.setPrototype(proto);
1835 QVERIFY(!obj.hasProperty("foo"));
1836 QVERIFY(!obj.hasOwnProperty("foo"));
1837 proto.setProperty("foo", 123);
1838 QVERIFY(obj.hasProperty("foo"));
1839 QVERIFY(!obj.hasOwnProperty("foo"));
1841 obj.setProperty("foo", 456); // override prototype property
1842 QVERIFY(obj.hasProperty("foo"));
1843 QVERIFY(obj.hasOwnProperty("foo"));
1846 void tst_QJSValue::deleteProperty_basic()
1849 QJSValue obj = eng.newObject();
1850 // deleteProperty() behavior matches JS delete operator
1851 QVERIFY(obj.deleteProperty("foo"));
1853 obj.setProperty("foo", 123);
1854 QVERIFY(obj.deleteProperty("foo"));
1855 QVERIFY(!obj.hasOwnProperty("foo"));
1858 void tst_QJSValue::deleteProperty_globalObject()
1861 QJSValue global = eng.globalObject();
1862 // deleteProperty() behavior matches JS delete operator
1863 QVERIFY(global.deleteProperty("foo"));
1865 global.setProperty("foo", 123);
1866 QVERIFY(global.deleteProperty("foo"));
1867 QVERIFY(!global.hasProperty("foo"));
1869 QVERIFY(global.deleteProperty("Math"));
1870 QVERIFY(!global.hasProperty("Math"));
1872 QVERIFY(!global.deleteProperty("NaN")); // read-only
1873 QVERIFY(global.hasProperty("NaN"));
1876 void tst_QJSValue::deleteProperty_inPrototype()
1879 QJSValue obj = eng.newObject();
1880 QJSValue proto = eng.newObject();
1881 obj.setPrototype(proto);
1883 proto.setProperty("foo", 123);
1884 QVERIFY(obj.hasProperty("foo"));
1885 // deleteProperty() behavior matches JS delete operator
1886 QVERIFY(obj.deleteProperty("foo"));
1887 QVERIFY(obj.hasProperty("foo"));
1890 void tst_QJSValue::getSetProperty_HooliganTask162051()
1893 // task 162051 -- detecting whether the property is an array index or not
1894 QVERIFY(eng.evaluate("a = []; a['00'] = 123; a['00']").strictlyEquals(QJSValue(&eng, 123)));
1895 QVERIFY(eng.evaluate("a.length").strictlyEquals(QJSValue(&eng, 0)));
1896 QVERIFY(eng.evaluate("a.hasOwnProperty('00')").strictlyEquals(QJSValue(&eng, true)));
1897 QVERIFY(eng.evaluate("a.hasOwnProperty('0')").strictlyEquals(QJSValue(&eng, false)));
1898 QVERIFY(eng.evaluate("a[0]").isUndefined());
1899 QVERIFY(eng.evaluate("a[0.5] = 456; a[0.5]").strictlyEquals(QJSValue(&eng, 456)));
1900 QVERIFY(eng.evaluate("a.length").strictlyEquals(QJSValue(&eng, 0)));
1901 QVERIFY(eng.evaluate("a.hasOwnProperty('0.5')").strictlyEquals(QJSValue(&eng, true)));
1902 QVERIFY(eng.evaluate("a[0]").isUndefined());
1903 QVERIFY(eng.evaluate("a[0] = 789; a[0]").strictlyEquals(QJSValue(&eng, 789)));
1904 QVERIFY(eng.evaluate("a.length").strictlyEquals(QJSValue(&eng, 1)));
1907 void tst_QJSValue::getSetProperty_HooliganTask183072()
1910 // task 183072 -- 0x800000000 is not an array index
1911 eng.evaluate("a = []; a[0x800000000] = 123");
1912 QVERIFY(eng.evaluate("a.length").strictlyEquals(QJSValue(&eng, 0)));
1913 QVERIFY(eng.evaluate("a[0]").isUndefined());
1914 QVERIFY(eng.evaluate("a[0x800000000]").strictlyEquals(QJSValue(&eng, 123)));
1917 void tst_QJSValue::getSetProperty_propertyRemoval()
1919 // test property removal (setProperty(QJSValue()))
1921 QJSValue object = eng.newObject();
1922 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
1923 QJSValue num = QJSValue(&eng, 123.0);
1925 object.setProperty("foo", num);
1926 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1927 object.setProperty("bar", str);
1928 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1929 object.setProperty("foo", QJSValue());
1930 QCOMPARE(object.property("foo").isValid(), false);
1931 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1932 object.setProperty("foo", num);
1933 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1934 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1935 object.setProperty("bar", QJSValue());
1936 QCOMPARE(object.property("bar").isValid(), false);
1937 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1938 object.setProperty("foo", QJSValue());
1939 object.setProperty("foo", QJSValue());
1941 eng.globalObject().setProperty("object3", object);
1942 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
1943 .strictlyEquals(QJSValue(&eng, false)), true);
1944 object.setProperty("foo", num);
1945 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
1946 .strictlyEquals(QJSValue(&eng, true)), true);
1947 eng.globalObject().setProperty("object3", QJSValue());
1948 QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')")
1949 .strictlyEquals(QJSValue(&eng, false)), true);
1952 void tst_QJSValue::getSetProperty_resolveMode()
1956 QJSValue object = eng.newObject();
1957 QJSValue prototype = eng.newObject();
1958 object.setPrototype(prototype);
1959 QJSValue num2 = QJSValue(&eng, 456.0);
1960 prototype.setProperty("propertyInPrototype", num2);
1961 // default is ResolvePrototype
1962 QCOMPARE(object.property("propertyInPrototype")
1963 .strictlyEquals(num2), true);
1964 #if 0 // FIXME: ResolveFlags removed from API
1965 QCOMPARE(object.property("propertyInPrototype", QJSValue::ResolvePrototype)
1966 .strictlyEquals(num2), true);
1967 QCOMPARE(object.property("propertyInPrototype", QJSValue::ResolveLocal)
1969 QCOMPARE(object.property("propertyInPrototype", QJSValue::ResolveScope)
1970 .strictlyEquals(num2), false);
1971 QCOMPARE(object.property("propertyInPrototype", QJSValue::ResolveFull)
1972 .strictlyEquals(num2), true);
1976 void tst_QJSValue::getSetProperty_twoEngines()
1979 QJSValue object = engine.newObject();
1981 QJSEngine otherEngine;
1982 QJSValue otherNum = QJSValue(&otherEngine, 123);
1983 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setProperty(oof) failed: cannot set value created in a different engine");
1984 object.setProperty("oof", otherNum);
1985 QCOMPARE(object.property("oof").isValid(), false);
1989 void tst_QJSValue::getSetProperty_gettersAndSetters()
1991 #if 0 // FIXME: No setters/getters right now
1993 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
1994 QJSValue num = QJSValue(&eng, 123.0);
1995 QJSValue object = eng.newObject();
1996 for (int x = 0; x < 2; ++x) {
1997 object.setProperty("foo", QJSValue());
1998 // getter() returns this.x
1999 object.setProperty("foo", eng.newFunction(getter),
2000 QJSValue::PropertyGetter | QJSValue::UserRange);
2001 QCOMPARE(object.propertyFlags("foo") & ~QJSValue::UserRange,
2002 QJSValue::PropertyGetter );
2004 QEXPECT_FAIL("", "QTBUG-17615: User-range flags are not retained for getter/setter properties", Continue);
2005 QCOMPARE(object.propertyFlags("foo"),
2006 QJSValue::PropertyGetter | QJSValue::UserRange);
2007 object.setProperty("x", num);
2008 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2010 // setter() sets this.x
2011 object.setProperty("foo", eng.newFunction(setter),
2012 QJSValue::PropertySetter);
2013 QCOMPARE(object.propertyFlags("foo") & ~QJSValue::UserRange,
2014 QJSValue::PropertySetter | QJSValue::PropertyGetter);
2016 QCOMPARE(object.propertyFlags("foo"),
2017 QJSValue::PropertySetter | QJSValue::PropertyGetter);
2018 object.setProperty("foo", str);
2019 QCOMPARE(object.property("x").strictlyEquals(str), true);
2020 QCOMPARE(object.property("foo").strictlyEquals(str), true);
2023 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
2024 QVERIFY(!(object.propertyFlags("foo") & QJSValue::PropertyGetter));
2025 QVERIFY(object.propertyFlags("foo") & QJSValue::PropertySetter);
2026 QCOMPARE(object.property("foo").isUndefined(), true);
2028 // setter should still work
2029 object.setProperty("foo", num);
2030 QCOMPARE(object.property("x").strictlyEquals(num), true);
2032 // kill the setter too
2033 object.setProperty("foo", QJSValue(), QJSValue::PropertySetter);
2034 QVERIFY(!(object.propertyFlags("foo") & QJSValue::PropertySetter));
2035 // now foo is just a regular property
2036 object.setProperty("foo", str);
2037 QCOMPARE(object.property("x").strictlyEquals(num), true);
2038 QCOMPARE(object.property("foo").strictlyEquals(str), true);
2041 for (int x = 0; x < 2; ++x) {
2042 object.setProperty("foo", QJSValue());
2043 // setter() sets this.x
2044 object.setProperty("foo", eng.newFunction(setter), QJSValue::PropertySetter);
2045 object.setProperty("foo", str);
2046 QCOMPARE(object.property("x").strictlyEquals(str), true);
2047 QCOMPARE(object.property("foo").isUndefined(), true);
2049 // getter() returns this.x
2050 object.setProperty("foo", eng.newFunction(getter), QJSValue::PropertyGetter);
2051 object.setProperty("x", num);
2052 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2055 object.setProperty("foo", QJSValue(), QJSValue::PropertySetter);
2056 object.setProperty("foo", str);
2058 // getter should still work
2059 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2061 // kill the getter too
2062 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
2063 // now foo is just a regular property
2064 object.setProperty("foo", str);
2065 QCOMPARE(object.property("x").strictlyEquals(num), true);
2066 QCOMPARE(object.property("foo").strictlyEquals(str), true);
2069 // use a single function as both getter and setter
2070 object.setProperty("foo", QJSValue());
2071 object.setProperty("foo", eng.newFunction(getterSetter),
2072 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2073 QCOMPARE(object.propertyFlags("foo"),
2074 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2075 object.setProperty("x", num);
2076 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2078 // killing the getter will preserve the setter, even though they are the same function
2079 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
2080 QVERIFY(object.propertyFlags("foo") & QJSValue::PropertySetter);
2081 QCOMPARE(object.property("foo").isUndefined(), true);
2085 void tst_QJSValue::getSetProperty_gettersAndSettersThrowErrorNative()
2087 #if 0 // FIXME: No setters/getters right now
2088 // getter/setter that throws an error
2090 QJSValue str = QJSValue(&eng, "bar");
2091 QJSValue object = eng.newObject();
2093 object.setProperty("foo", eng.newFunction(getterSetterThrowingError),
2094 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2095 QVERIFY(!eng.hasUncaughtException());
2096 QJSValue ret = object.property("foo");
2097 QVERIFY(ret.isError());
2098 QVERIFY(eng.hasUncaughtException());
2099 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
2100 QCOMPARE(ret.toString(), QLatin1String("Error: get foo"));
2101 eng.evaluate("Object"); // clear exception state...
2102 QVERIFY(!eng.hasUncaughtException());
2103 object.setProperty("foo", str);
2104 QVERIFY(eng.hasUncaughtException());
2105 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
2109 void tst_QJSValue::getSetProperty_gettersAndSettersThrowErrorJS()
2111 // getter/setter that throws an error (from js function)
2113 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
2115 eng.evaluate("o = new Object; "
2116 "o.__defineGetter__('foo', function() { throw new Error('get foo') }); "
2117 "o.__defineSetter__('foo', function() { throw new Error('set foo') }); ");
2118 QJSValue object = eng.evaluate("o");
2119 QVERIFY(!eng.hasUncaughtException());
2120 QJSValue ret = object.property("foo");
2121 QVERIFY(ret.isError());
2122 QVERIFY(eng.hasUncaughtException());
2123 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
2124 QCOMPARE(ret.toString(), QLatin1String("Error: get foo"));
2125 eng.evaluate("Object"); // clear exception state...
2126 QVERIFY(!eng.hasUncaughtException());
2127 object.setProperty("foo", str);
2128 QVERIFY(eng.hasUncaughtException());
2129 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
2132 void tst_QJSValue::getSetProperty_gettersAndSettersOnNative()
2134 #if 0 // FIXME: No c-style functions right now
2135 // attempt to install getter+setter on built-in (native) property
2137 QJSValue object = eng.newObject();
2138 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2140 QJSValue fun = eng.newFunction(getSet__proto__);
2141 fun.setProperty("value", QJSValue(&eng, "boo"));
2142 /* QTest::ignoreMessage(QtWarningMsg, "QJSValue::setProperty() failed: "
2143 "cannot set getter or setter of native property "
2145 object.setProperty("__proto__", fun,
2146 QJSValue::PropertyGetter | QJSValue::PropertySetter
2147 | QJSValue::UserRange);
2148 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2150 object.setProperty("__proto__", QJSValue(),
2151 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2152 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2156 void tst_QJSValue::getSetProperty_gettersAndSettersOnGlobalObject()
2158 #if 0 // FIXME: No c-style functions right now
2159 // global property that's a getter+setter
2161 eng.globalObject().setProperty("globalGetterSetterProperty", eng.newFunction(getterSetter),
2162 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2163 eng.evaluate("globalGetterSetterProperty = 123");
2165 QJSValue ret = eng.evaluate("globalGetterSetterProperty");
2166 QVERIFY(ret.isNumber());
2167 QVERIFY(ret.strictlyEquals(QJSValue(&eng, 123)));
2169 QCOMPARE(eng.evaluate("typeof globalGetterSetterProperty").toString(),
2170 QString::fromLatin1("number"));
2172 QJSValue ret = eng.evaluate("this.globalGetterSetterProperty()");
2173 QVERIFY(ret.isError());
2174 QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Property 'globalGetterSetterProperty' of object #<Object> is not a function"));
2177 QJSValue ret = eng.evaluate("new this.globalGetterSetterProperty()");
2178 QVERIFY(ret.isError());
2179 QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: number is not a function"));
2184 void tst_QJSValue::getSetProperty_gettersAndSettersChange()
2186 #if 0 // FIXME: No setters/getters API right now
2187 // "upgrading" an existing property to become a getter+setter
2189 QJSValue object = eng.newObject();
2190 QJSValue num(&eng, 123);
2191 object.setProperty("foo", num);
2192 object.setProperty("foo", eng.newFunction(getterSetter),
2193 QJSValue::PropertyGetter | QJSValue::PropertySetter);
2194 QVERIFY(!object.property("x").isValid());
2195 object.setProperty("foo", num);
2196 QVERIFY(object.property("x").equals(num));
2198 eng.globalObject().setProperty("object", object);
2199 QJSValue res = eng.evaluate("object.x = 89; var a = object.foo; object.foo = 65; a");
2200 QCOMPARE(res.toInt(), 89);
2201 QCOMPARE(object.property("x").toInt(), 65);
2202 QCOMPARE(object.property("foo").toInt(), 65);
2206 void tst_QJSValue::getSetProperty_array()
2209 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
2210 QJSValue num = QJSValue(&eng, 123.0);
2211 QJSValue array = eng.newArray();
2213 QVERIFY(array.isArray());
2214 array.setProperty(0, num);
2215 QCOMPARE(array.property(0).toNumber(), num.toNumber());
2216 QCOMPARE(array.property("0").toNumber(), num.toNumber());
2217 QCOMPARE(array.property("length").toUInt(), quint32(1));
2218 array.setProperty(1, str);
2219 QCOMPARE(array.property(1).toString(), str.toString());
2220 QCOMPARE(array.property("1").toString(), str.toString());
2221 QCOMPARE(array.property("length").toUInt(), quint32(2));
2222 array.setProperty("length", QJSValue(&eng, 1));
2223 QCOMPARE(array.property("length").toUInt(), quint32(1));
2224 QCOMPARE(array.property(1).isValid(), false);
2227 void tst_QJSValue::getSetProperty_gettersAndSettersStupid()
2229 #if 0 // FIXME: No setters/getters API right now
2230 //removing unexisting Setter or Getter should not crash.
2232 QJSValue num = QJSValue(&eng, 123.0);
2235 QJSValue object = eng.newObject();
2236 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
2237 QVERIFY(!object.property("foo").isValid());
2238 object.setProperty("foo", num);
2239 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2243 QJSValue object = eng.newObject();
2244 object.setProperty("foo", QJSValue(), QJSValue::PropertySetter);
2245 QVERIFY(!object.property("foo").isValid());
2246 object.setProperty("foo", num);
2247 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2251 QJSValue object = eng.globalObject();
2252 object.setProperty("foo", QJSValue(), QJSValue::PropertySetter);
2253 object.setProperty("foo", QJSValue(), QJSValue::PropertyGetter);
2254 QVERIFY(!object.property("foo").isValid());
2255 object.setProperty("foo", num);
2256 QCOMPARE(object.property("foo").strictlyEquals(num), true);
2261 void tst_QJSValue::getSetProperty()
2265 QJSValue object = eng.newObject();
2267 QJSValue str = QJSValue(&eng, QLatin1String("bar"));
2268 object.setProperty("foo", str);
2269 QCOMPARE(object.property("foo").toString(), str.toString());
2271 QJSValue num = QJSValue(&eng, 123.0);
2272 object.setProperty("baz", num);
2273 QCOMPARE(object.property("baz").toNumber(), num.toNumber());
2275 QJSValue strstr = QJSValue("bar");
2276 QCOMPARE(strstr.engine(), (QJSEngine *)0);
2277 object.setProperty("foo", strstr);
2278 QCOMPARE(object.property("foo").toString(), strstr.toString());
2279 QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine
2281 QJSValue numnum = QJSValue(123.0);
2282 object.setProperty("baz", numnum);
2283 QCOMPARE(object.property("baz").toNumber(), numnum.toNumber());
2286 inv.setProperty("foo", num);
2287 QCOMPARE(inv.property("foo").isValid(), false);
2289 eng.globalObject().setProperty("object", object);
2291 #if 0 // FIXME: no setProperty API with flags
2293 object.setProperty("readOnlyProperty", num, QJSValue::ReadOnly);
2294 QCOMPARE(object.propertyFlags("readOnlyProperty"), QJSValue::ReadOnly);
2295 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
2296 eng.evaluate("object.readOnlyProperty = !object.readOnlyProperty");
2297 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
2298 // should still be part of enumeration
2300 QJSValue ret = eng.evaluate(
2302 "for (var p in object) {"
2303 " if (p == 'readOnlyProperty') {"
2304 " found = true; break;"
2307 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), true);
2309 // should still be deletable
2311 QJSValue ret = eng.evaluate("delete object.readOnlyProperty");
2312 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), true);
2313 QCOMPARE(object.property("readOnlyProperty").isValid(), false);
2317 object.setProperty("undeletableProperty", num, QJSValue::Undeletable);
2318 QCOMPARE(object.propertyFlags("undeletableProperty"), QJSValue::Undeletable);
2319 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
2321 QJSValue ret = eng.evaluate("delete object.undeletableProperty");
2322 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), false);
2323 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
2325 // should still be writable
2326 eng.evaluate("object.undeletableProperty = object.undeletableProperty + 1");
2327 QCOMPARE(object.property("undeletableProperty").toNumber(), num.toNumber() + 1);
2328 // should still be part of enumeration
2330 QJSValue ret = eng.evaluate(
2332 "for (var p in object) {"
2333 " if (p == 'undeletableProperty') {"
2334 " found = true; break;"
2337 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), true);
2339 // should still be deletable from C++
2340 object.setProperty("undeletableProperty", QJSValue());
2341 QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
2342 QVERIFY(!object.property("undeletableProperty").isValid());
2343 QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
2344 QCOMPARE(object.propertyFlags("undeletableProperty"), 0);
2346 // SkipInEnumeration
2347 object.setProperty("dontEnumProperty", num, QJSValue::SkipInEnumeration);
2348 QCOMPARE(object.propertyFlags("dontEnumProperty"), QJSValue::SkipInEnumeration);
2349 QCOMPARE(object.property("dontEnumProperty").strictlyEquals(num), true);
2350 // should not be part of enumeration
2352 QJSValue ret = eng.evaluate(
2354 "for (var p in object) {"
2355 " if (p == 'dontEnumProperty') {"
2356 " found = true; break;"
2359 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, false)), true);
2361 // should still be writable
2362 eng.evaluate("object.dontEnumProperty = object.dontEnumProperty + 1");
2363 QCOMPARE(object.property("dontEnumProperty").toNumber(), num.toNumber() + 1);
2364 // should still be deletable
2366 QJSValue ret = eng.evaluate("delete object.dontEnumProperty");
2367 QCOMPARE(ret.strictlyEquals(QJSValue(&eng, true)), true);
2368 QCOMPARE(object.property("dontEnumProperty").isValid(), false);
2372 object.setProperty("flagProperty", str);
2373 QCOMPARE(object.propertyFlags("flagProperty"), static_cast<QJSValue::PropertyFlags>(0));
2375 QEXPECT_FAIL("", "FIXME: v8 does not support changing flags of existing properties", Continue);
2376 //v8::i::JSObject::SetProperty(LookupResult* result, ... ) does not take in account the attributes
2377 // if the result->isFound()
2378 object.setProperty("flagProperty", str, QJSValue::ReadOnly);
2379 QCOMPARE(object.propertyFlags("flagProperty"), QJSValue::ReadOnly);
2381 QEXPECT_FAIL("", "FIXME: v8 does not support changing flags of existing properties", Continue);
2382 object.setProperty("flagProperty", str, object.propertyFlags("flagProperty") | QJSValue::SkipInEnumeration);
2383 QCOMPARE(object.propertyFlags("flagProperty"), QJSValue::ReadOnly | QJSValue::SkipInEnumeration);
2385 QEXPECT_FAIL("", "FIXME: v8 does not support changing flags of existing properties", Continue);
2386 object.setProperty("flagProperty", str, QJSValue::KeepExistingFlags);
2387 QCOMPARE(object.propertyFlags("flagProperty"), QJSValue::ReadOnly | QJSValue::SkipInEnumeration);
2389 QEXPECT_FAIL("", "FIXME: v8 does not support UserRange", Continue);
2390 object.setProperty("flagProperty", str, QJSValue::UserRange);
2391 QCOMPARE(object.propertyFlags("flagProperty"), QJSValue::UserRange);
2393 // flags of property in the prototype
2395 QJSValue object2 = eng.newObject();
2396 object2.setPrototype(object);
2397 QCOMPARE(object2.propertyFlags("flagProperty", QJSValue::ResolveLocal), 0);
2398 QEXPECT_FAIL("", "FIXME: v8 does not support UserRange", Continue);
2399 QCOMPARE(object2.propertyFlags("flagProperty"), QJSValue::UserRange);
2402 // using interned strings
2403 QScriptString foo = eng.toStringHandle("foo");
2405 object.setProperty(foo, QJSValue());
2406 QVERIFY(!object.property(foo).isValid());
2408 object.setProperty(foo, num);
2409 QVERIFY(object.property(foo).strictlyEquals(num));
2410 QVERIFY(object.property("foo").strictlyEquals(num));
2411 QVERIFY(object.propertyFlags(foo) == 0);
2414 // Setting index property on non-Array
2415 object.setProperty(13, num);
2416 QVERIFY(object.property(13).equals(num));
2419 void tst_QJSValue::arrayElementGetterSetter()
2421 #if 0 // FIXME: No c-style functions
2423 QJSValue obj = eng.newObject();
2424 obj.setProperty(1, eng.newFunction(getterSetter), QJSValue::PropertyGetter|QJSValue::PropertySetter);
2427 obj.setProperty("x", num);
2428 QJSValue ret = obj.property(1);
2429 QVERIFY(ret.isValid());
2430 QVERIFY(ret.equals(num));
2434 obj.setProperty(1, num);
2435 QJSValue ret = obj.property(1);
2436 QVERIFY(ret.isValid());
2437 QVERIFY(ret.equals(num));
2438 QVERIFY(ret.equals(obj.property("1")));
2440 QCOMPARE(obj.propertyFlags("1"), QJSValue::PropertyGetter|QJSValue::PropertySetter);
2442 obj.setProperty(1, QJSValue(), QJSValue::PropertyGetter|QJSValue::PropertySetter);
2443 QVERIFY(obj.propertyFlags("1") == 0);
2447 void tst_QJSValue::getSetPrototype_cyclicPrototype()
2450 QJSValue prototype = eng.newObject();
2451 QJSValue object = eng.newObject();
2452 object.setPrototype(prototype);
2454 QJSValue previousPrototype = prototype.prototype();
2455 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setPrototype() failed: cyclic prototype value");
2456 prototype.setPrototype(prototype);
2457 QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true);
2459 object.setPrototype(prototype);
2460 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setPrototype() failed: cyclic prototype value");
2461 prototype.setPrototype(object);
2462 QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true);
2466 void tst_QJSValue::getSetPrototype_evalCyclicPrototype()
2469 QJSValue ret = eng.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
2470 QCOMPARE(eng.hasUncaughtException(), true);
2471 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
2472 QCOMPARE(ret.isError(), true);
2473 QCOMPARE(ret.toString(), QLatin1String("Error: Cyclic __proto__ value"));
2476 void tst_QJSValue::getSetPrototype_eval()
2479 QJSValue ret = eng.evaluate("p = { }; p.__proto__ = { }");
2480 QCOMPARE(eng.hasUncaughtException(), false);
2481 QCOMPARE(ret.isError(), false);
2484 void tst_QJSValue::getSetPrototype_invalidPrototype()
2488 QJSValue object = eng.newObject();
2489 QJSValue proto = object.prototype();
2490 QVERIFY(object.prototype().strictlyEquals(proto));
2491 inv.setPrototype(object);
2492 QCOMPARE(inv.prototype().isValid(), false);
2493 object.setPrototype(inv);
2494 QVERIFY(object.prototype().strictlyEquals(proto));
2497 void tst_QJSValue::getSetPrototype_twoEngines()
2500 QJSValue prototype = eng.newObject();
2501 QJSValue object = eng.newObject();
2502 object.setPrototype(prototype);
2503 QJSEngine otherEngine;
2504 QJSValue newPrototype = otherEngine.newObject();
2505 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setPrototype() failed: cannot set a prototype created in a different engine");
2506 object.setPrototype(newPrototype);
2507 QCOMPARE(object.prototype().strictlyEquals(prototype), true);
2511 void tst_QJSValue::getSetPrototype_null()
2514 QJSValue object = eng.newObject();
2515 object.setPrototype(QJSValue(QJSValue::NullValue));
2516 QVERIFY(object.prototype().isNull());
2518 QJSValue newProto = eng.newObject();
2519 object.setPrototype(newProto);
2520 QVERIFY(object.prototype().equals(newProto));
2522 object.setPrototype(QJSValue(&eng, QJSValue::NullValue));
2523 QVERIFY(object.prototype().isNull());
2526 void tst_QJSValue::getSetPrototype_notObjectOrNull()
2529 QJSValue object = eng.newObject();
2530 QJSValue originalProto = object.prototype();
2533 object.setPrototype(true);
2534 QVERIFY(object.prototype().equals(originalProto));
2535 object.setPrototype(QJSValue(&eng, true));
2536 QVERIFY(object.prototype().equals(originalProto));
2539 object.setPrototype(123);
2540 QVERIFY(object.prototype().equals(originalProto));
2541 object.setPrototype(QJSValue(&eng, 123));
2542 QVERIFY(object.prototype().equals(originalProto));
2545 object.setPrototype("foo");
2546 QVERIFY(object.prototype().equals(originalProto));
2547 object.setPrototype(QJSValue(&eng, QLatin1String("foo")));
2548 QVERIFY(object.prototype().equals(originalProto));
2551 object.setPrototype(QJSValue(QJSValue::UndefinedValue));
2552 QVERIFY(object.prototype().equals(originalProto));
2553 object.setPrototype(QJSValue(&eng, QJSValue::UndefinedValue));
2554 QVERIFY(object.prototype().equals(originalProto));
2557 void tst_QJSValue::getSetPrototype()
2560 QJSValue prototype = eng.newObject();
2561 QJSValue object = eng.newObject();
2562 object.setPrototype(prototype);
2563 QCOMPARE(object.prototype().strictlyEquals(prototype), true);
2566 void tst_QJSValue::getSetScope()
2568 #if 0 // FIXME: No QJSValue::scope
2571 QJSValue object = eng.newObject();
2572 QCOMPARE(object.scope().isValid(), false);
2574 QJSValue object2 = eng.newObject();
2575 object2.setScope(object);
2577 QEXPECT_FAIL("", "FIXME: scope not implemented yet", Abort);
2578 QCOMPARE(object2.scope().strictlyEquals(object), true);
2580 object.setProperty("foo", 123);
2581 QVERIFY(!object2.property("foo").isValid());
2583 QJSValue ret = object2.property("foo", QJSValue::ResolveScope);
2584 QVERIFY(ret.isNumber());
2585 QCOMPARE(ret.toInt(), 123);
2589 inv.setScope(object);
2590 QCOMPARE(inv.scope().isValid(), false);
2592 QScriptEngine otherEngine;
2593 QJSValue object3 = otherEngine.newObject();
2594 QTest::ignoreMessage(QtWarningMsg, "QJSValue::setScope() failed: cannot set a scope object created in a different engine");
2595 object2.setScope(object3);
2596 QCOMPARE(object2.scope().strictlyEquals(object), true);
2598 object2.setScope(QJSValue());
2599 QVERIFY(!object2.scope().isValid());
2603 void tst_QJSValue::getSetData_objects_data()
2605 #if 0 // FIXME: no setData/data API
2608 QTest::addColumn<QJSValue>("object");
2610 QTest::newRow("object from evaluate") << engine->evaluate("new Object()");
2611 QTest::newRow("object from engine") << engine->newObject();
2612 QTest::newRow("Array") << engine->newArray();
2613 QTest::newRow("Date") << engine->newDate(12324);
2614 QTest::newRow("QObject") << engine->newQObject(this);
2615 QTest::newRow("RegExp") << engine->newRegExp(QRegExp());
2619 void tst_QJSValue::getSetData_objects()
2621 #if 0 // FIXME: no setData/data API
2622 QFETCH(QJSValue, object);
2624 QVERIFY(!object.data().isValid());
2627 QVERIFY(object.data().strictlyEquals(v1));
2630 QVERIFY(object.data().strictlyEquals(v2));
2631 QJSValue v3 = engine->newObject();
2633 QVERIFY(object.data().strictlyEquals(v3));
2634 object.setData(QJSValue());
2635 QVERIFY(!object.data().isValid());
2639 void tst_QJSValue::getSetData_nonObjects_data()
2641 #if 0 // FIXME: no setData/data API
2644 QTest::addColumn<QJSValue>("value");
2646 QTest::newRow("undefined (bound)") << engine->undefinedValue();
2647 QTest::newRow("null (bound)") << engine->nullValue();
2648 QTest::newRow("string (bound)") << QJSValue(engine, "Pong");
2649 QTest::newRow("bool (bound)") << QJSValue(engine, false);
2651 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
2652 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
2653 QTest::newRow("string") << QJSValue("Pong");
2654 QTest::newRow("bool") << QJSValue(true);
2658 void tst_QJSValue::getSetData_nonObjects()
2660 #if 0 // FIXME: no setData/data API
2661 QFETCH(QJSValue, value);
2663 QVERIFY(!value.data().isValid());
2666 QVERIFY(!value.data().isValid());
2669 QVERIFY(!value.data().isValid());
2670 QJSValue v3 = engine->newObject();
2672 QVERIFY(!value.data().isValid());
2673 value.setData(QJSValue());
2674 QVERIFY(!value.data().isValid());
2678 void tst_QJSValue::setData_QTBUG15144()
2680 #if 0 // FIXME: no setData/data API
2682 QJSValue obj = eng.newObject();
2683 for (int i = 0; i < 10000; ++i) {
2684 // Create an object with property 'fooN' on it, and immediately kill
2685 // the reference to the object so it and the property name become garbage.
2686 eng.evaluate(QString::fromLatin1("o = {}; o.foo%0 = 10; o = null;").arg(i));
2687 // Setting the data will cause a JS string to be allocated, which could
2688 // trigger a GC. This should not cause a crash.
2689 obj.setData("foodfight");
2694 #if 0 // FIXME: no QScriptClass
2695 class TestScriptClass : public QScriptClass
2698 TestScriptClass(QScriptEngine *engine) : QScriptClass(engine) {}
2701 void tst_QJSValue::getSetScriptClass_emptyClass_data()
2704 QTest::addColumn<QJSValue>("value");
2706 QTest::newRow("invalid") << QJSValue();
2707 QTest::newRow("number") << QJSValue(123);
2708 QTest::newRow("string") << QJSValue("pong");
2709 QTest::newRow("bool") << QJSValue(false);
2710 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
2711 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
2713 QTest::newRow("number") << QJSValue(engine, 123);
2714 QTest::newRow("string") << QJSValue(engine, "pong");
2715 QTest::newRow("bool") << QJSValue(engine, true);
2716 QTest::newRow("null") << QJSValue(engine->nullValue());
2717 QTest::newRow("undefined") << QJSValue(engine->undefinedValue());
2718 QTest::newRow("object") << QJSValue(engine->newObject());
2719 QTest::newRow("date") << QJSValue(engine->evaluate("new Date()"));
2720 QTest::newRow("qobject") << QJSValue(engine->newQObject(this));
2723 void tst_QJSValue::getSetScriptClass_emptyClass()
2725 QFETCH(QJSValue, value);
2726 QCOMPARE(value.scriptClass(), (QScriptClass*)0);
2729 void tst_QJSValue::getSetScriptClass_JSObjectFromCpp()
2732 TestScriptClass testClass(&eng);
2733 // object created in C++ (newObject())
2735 QJSValue obj = eng.newObject();
2736 obj.setScriptClass(&testClass);
2737 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2738 obj.setScriptClass(0);
2739 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2743 void tst_QJSValue::getSetScriptClass_JSObjectFromJS()
2746 TestScriptClass testClass(&eng);
2747 // object created in JS
2749 QJSValue obj = eng.evaluate("new Object");
2750 QVERIFY(!eng.hasUncaughtException());
2751 QVERIFY(obj.isObject());
2752 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2753 obj.setScriptClass(&testClass);
2754 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2755 obj.setScriptClass(0);
2756 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2760 void tst_QJSValue::getSetScriptClass_QVariant()
2763 TestScriptClass testClass(&eng);
2764 // object that already has a(n internal) class
2766 QJSValue obj = eng.newVariant(QUrl("http://example.com"));
2767 QVERIFY(obj.isVariant());
2768 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2769 obj.setScriptClass(&testClass);
2770 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2771 QVERIFY(obj.isObject());
2772 QVERIFY(!obj.isVariant());
2773 QCOMPARE(obj.toVariant(), QVariant(QVariantMap()));
2777 void tst_QJSValue::getSetScriptClass_QObject()
2780 TestScriptClass testClass(&eng);
2782 QJSValue obj = eng.newQObject(this);
2783 QVERIFY(obj.isQObject());
2784 obj.setScriptClass(&testClass);
2785 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2786 QVERIFY(obj.isObject());
2787 QVERIFY(!obj.isQObject());
2788 QVERIFY(obj.toQObject() == 0);
2793 #if 0 // FIXME: No c-style callbacks
2794 static QJSValue getArg(QScriptContext *ctx, QScriptEngine *)
2796 return ctx->argument(0);
2799 static QJSValue evaluateArg(QScriptContext *, QScriptEngine *eng)
2801 return eng->evaluate("arguments[0]");
2804 static QJSValue addArgs(QScriptContext *, QScriptEngine *eng)
2806 return eng->evaluate("arguments[0] + arguments[1]");
2809 static QJSValue returnInvalidValue(QScriptContext *, QScriptEngine *)
2815 void tst_QJSValue::call_function()
2818 QJSValue fun = eng.evaluate("(function() { return 1; })");
2819 QVERIFY(fun.isCallable());
2820 QJSValue result = fun.call();
2821 QVERIFY(result.isNumber());
2822 QCOMPARE(result.toInt(), 1);
2825 void tst_QJSValue::call_object()
2828 QJSValue Object = eng.evaluate("Object");
2829 QCOMPARE(Object.isCallable(), true);
2830 QJSValue result = Object.callWithInstance(Object);
2831 QCOMPARE(result.isObject(), true);
2834 void tst_QJSValue::call_newObjects()
2837 // test that call() doesn't construct new objects
2838 QJSValue Number = eng.evaluate("Number");
2839 QJSValue Object = eng.evaluate("Object");
2840 QCOMPARE(Object.isCallable(), true);
2842 args << QJSValue(&eng, 123);
2843 QJSValue result = Number.callWithInstance(Object, args);
2844 QCOMPARE(result.strictlyEquals(args.at(0)), true);
2847 void tst_QJSValue::call_this()
2850 // test that correct "this" object is used
2851 QJSValue fun = eng.evaluate("(function() { return this; })");
2852 QCOMPARE(fun.isCallable(), true);
2854 QJSValue numberObject = QJSValue(&eng, 123.0).toObject();
2855 QJSValue result = fun.callWithInstance(numberObject);
2856 QCOMPARE(result.isObject(), true);
2857 QCOMPARE(result.toNumber(), 123.0);
2860 void tst_QJSValue::call_arguments()
2863 // test that correct arguments are passed
2865 QJSValue fun = eng.evaluate("(function() { return arguments[0]; })");
2866 QCOMPARE(fun.isCallable(), true);
2868 QJSValue result = fun.callWithInstance(eng.undefinedValue());
2869 QCOMPARE(result.isUndefined(), true);
2873 args << QJSValue(&eng, 123.0);
2874 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2875 QCOMPARE(result.isNumber(), true);
2876 QCOMPARE(result.toNumber(), 123.0);
2881 args << QJSValue(123.0);
2882 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2883 QCOMPARE(result.isNumber(), true);
2884 QCOMPARE(result.toNumber(), 123.0);
2886 #if 0 // FIXME: The feature of interpreting a passed array as argument list has been removed from the API
2888 QJSValue args = eng.newArray();
2889 args.setProperty(0, 123);
2890 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2891 QVERIFY(result.isNumber());
2892 QCOMPARE(result.toNumber(), 123.0);
2897 void tst_QJSValue::call()
2901 QJSValue fun = eng.evaluate("(function() { return arguments[1]; })");
2902 QCOMPARE(fun.isCallable(), true);
2906 args << QJSValue(&eng, 123.0) << QJSValue(&eng, 456.0);
2907 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2908 QCOMPARE(result.isNumber(), true);
2909 QCOMPARE(result.toNumber(), 456.0);
2911 #if 0 // FIXME: The feature of interpreting a passed array as argument list has been removed from the API
2913 QJSValue args = eng.newArray();
2914 args.setProperty(0, 123);
2915 args.setProperty(1, 456);
2916 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2917 QVERIFY(result.isNumber());
2918 QCOMPARE(result.toNumber(), 456.0);
2923 QJSValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
2924 QCOMPARE(fun.isCallable(), true);
2925 QVERIFY(!eng.hasUncaughtException());
2928 QJSValue result = fun.call();
2929 QCOMPARE(result.isError(), true);
2930 QCOMPARE(eng.hasUncaughtException(), true);
2931 QVERIFY(result.strictlyEquals(eng.uncaughtException()));
2934 #if 0 // FIXME: No c-style callbacks
2936 eng.clearExceptions();
2937 QJSValue fun = eng.newFunction(getArg);
2940 args << QJSValue(&eng, 123.0);
2941 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2942 QVERIFY(!eng.hasUncaughtException());
2943 QCOMPARE(result.isNumber(), true);
2944 QCOMPARE(result.toNumber(), 123.0);
2949 args << QJSValue(123.0);
2950 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2951 QCOMPARE(result.isNumber(), true);
2952 QCOMPARE(result.toNumber(), 123.0);
2954 #if 0 // FIXME: The feature of interpreting a passed array as argument list has been removed from the API
2956 QJSValue args = eng.newArray();
2957 args.setProperty(0, 123);
2958 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2959 QVERIFY(result.isNumber());
2960 QCOMPARE(result.toNumber(), 123.0);
2965 QJSValue fun = eng.newFunction(evaluateArg);
2968 args << QJSValue(&eng, 123.0);
2969 QJSValue result = fun.callWithInstance(eng.undefinedValue(), args);
2970 QVERIFY(!eng.hasUncaughtException());
2971 QCOMPARE(result.isNumber(), true);
2972 QCOMPARE(result.toNumber(), 123.0);
2978 void tst_QJSValue::call_invalidArguments()
2980 #if 0 // FIXME: No c-style callbacks
2981 // test that invalid arguments are handled gracefully
2984 QJSValue fun = eng.newFunction(getArg);
2988 QJSValue ret = fun.callWithInstance(args);
2989 QVERIFY(!eng.hasUncaughtException());
2990 QCOMPARE(ret.isValid(), true);
2991 QCOMPARE(ret.isUndefined(), true);
2995 QJSValue fun = eng.newFunction(evaluateArg);
2999 QJSValue ret = fun.call(args);
3000 QCOMPARE(ret.isValid(), true);
3001 QCOMPARE(ret.isUndefined(), true);
3005 QJSValue fun = eng.newFunction(addArgs);
3008 args << QJSValue() << QJSValue();
3009 QJSValue ret = fun.call(args);
3010 QCOMPARE(ret.isValid(), true);
3011 QCOMPARE(ret.isNumber(), true);
3012 QCOMPARE(qIsNaN(ret.toNumber()), true);
3018 void tst_QJSValue::call_invalidReturn()
3020 #if 0 // FIXME: No c-style callbacks
3021 // test that invalid return value is handled gracefully
3023 QJSValue fun = eng.newFunction(returnInvalidValue);
3024 eng.globalObject().setProperty("returnInvalidValue", fun);
3025 QJSValue ret = eng.evaluate("returnInvalidValue() + returnInvalidValue()");
3026 QCOMPARE(ret.isValid(), true);
3027 QCOMPARE(ret.isNumber(), true);
3028 QCOMPARE(qIsNaN(ret.toNumber()), true);
3032 void tst_QJSValue::call_twoEngines()
3035 QJSValue object = eng.evaluate("Object");
3036 QJSEngine otherEngine;
3037 QJSValue fun = otherEngine.evaluate("(function() { return 1; })");
3038 QVERIFY(fun.isCallable());
3039 QTest::ignoreMessage(QtWarningMsg, "JSValue can't be rassigned to an another engine.");
3040 QTest::ignoreMessage(QtWarningMsg, "QJSValue::call() failed: "
3041 "cannot call function with thisObject created in "
3042 "a different engine");
3043 QCOMPARE(fun.callWithInstance(object).isValid(), false);
3044 QTest::ignoreMessage(QtWarningMsg, "QJSValue::call() failed: "
3045 "cannot call function with argument created in "
3046 "a different engine");
3047 QCOMPARE(fun.call(QJSValueList() << QJSValue(&eng, 123)).isValid(), false);
3049 QJSValue fun = eng.evaluate("Object");
3050 QVERIFY(fun.isCallable());
3052 QJSValue objectInDifferentEngine = eng2.newObject();
3054 args << objectInDifferentEngine;
3055 QTest::ignoreMessage(QtWarningMsg, "QJSValue::call() failed: cannot call function with argument created in a different engine");
3060 void tst_QJSValue::call_array()
3062 #if 0 // FIXME: The feature of interpreting an array as argument list has been removed from the API
3064 QJSValue fun = eng.evaluate("(function() { return arguments; })");
3065 QVERIFY(fun.isCallable());
3066 QJSValue array = eng.newArray(3);
3067 array.setProperty(0, QJSValue(&eng, 123.0));
3068 array.setProperty(1, QJSValue(&eng, 456.0));
3069 array.setProperty(2, QJSValue(&eng, 789.0));
3070 // call with single array object as arguments
3071 QJSValue ret = fun.call(QJSValue(), array);
3072 QVERIFY(!eng.hasUncaughtException());
3073 QCOMPARE(ret.isError(), false);
3074 QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
3075 QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
3076 QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
3077 // call with arguments object as arguments
3078 QJSValue ret2 = fun.call(QJSValue(), ret);
3079 QCOMPARE(ret2.isError(), false);
3080 QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
3081 QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
3082 QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
3083 // call with null as arguments
3084 QJSValue ret3 = fun.call(QJSValue(), eng.nullValue());
3085 QCOMPARE(ret3.isError(), false);
3086 QCOMPARE(ret3.property("length").isNumber(), true);
3087 QCOMPARE(ret3.property("length").toNumber(), 0.0);
3088 // call with undefined as arguments
3089 QJSValue ret4 = fun.call(QJSValue(), eng.undefinedValue());
3090 QCOMPARE(ret4.isError(), false);
3091 QCOMPARE(ret4.property("length").isNumber(), true);
3092 QCOMPARE(ret4.property("length").toNumber(), 0.0);
3093 // call with something else as arguments
3094 QJSValue ret5 = fun.call(QJSValue(), QJSValue(&eng, 123.0));
3095 QCOMPARE(ret5.isError(), true);
3096 // call with a non-array object as arguments
3097 QJSValue ret6 = fun.call(QJSValue(), eng.globalObject());
3098 QVERIFY(ret6.isError());
3099 QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
3104 void tst_QJSValue::call_nonFunction_data()
3107 QTest::addColumn<QJSValue>("value");
3109 QTest::newRow("invalid") << QJSValue();
3110 QTest::newRow("bool") << QJSValue(false);
3111 QTest::newRow("int") << QJSValue(123);
3112 QTest::newRow("string") << QJSValue(QString::fromLatin1("ciao"));
3113 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
3114 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
3116 QTest::newRow("bool bound") << QJSValue(engine, false);
3117 QTest::newRow("int bound") << QJSValue(engine, 123);
3118 QTest::newRow("string bound") << QJSValue(engine, QString::fromLatin1("ciao"));
3119 QTest::newRow("undefined bound") << engine->undefinedValue();
3120 QTest::newRow("null bound") << engine->nullValue();
3123 void tst_QJSValue::call_nonFunction()
3125 // calling things that are not functions
3126 QFETCH(QJSValue, value);
3127 QVERIFY(!value.call().isValid());
3130 #if 0 // FIXME: no c-style callbacks
3131 static QJSValue ctorReturningUndefined(QScriptContext *ctx, QScriptEngine *)
3133 ctx->thisObject().setProperty("foo", 123);
3134 return QJSValue(QJSValue::UndefinedValue);
3137 static QJSValue ctorReturningNewObject(QScriptContext *, QScriptEngine *eng)
3139 QJSValue result = eng->newObject();
3140 result.setProperty("bar", 456);
3145 void tst_QJSValue::construct_nonFunction_data()
3148 QTest::addColumn<QJSValue>("value");
3150 QTest::newRow("invalid") << QJSValue();
3151 QTest::newRow("bool") << QJSValue(false);
3152 QTest::newRow("int") << QJSValue(123);
3153 QTest::newRow("string") << QJSValue(QString::fromLatin1("ciao"));
3154 QTest::newRow("undefined") << QJSValue(QJSValue::UndefinedValue);
3155 QTest::newRow("null") << QJSValue(QJSValue::NullValue);
3157 QTest::newRow("bool bound") << QJSValue(engine, false);
3158 QTest::newRow("int bound") << QJSValue(engine, 123);
3159 QTest::newRow("string bound") << QJSValue(engine, QString::fromLatin1("ciao"));
3160 QTest::newRow("undefined bound") << engine->undefinedValue();
3161 QTest::newRow("null bound") << engine->nullValue();
3164 void tst_QJSValue::construct_nonFunction()
3166 QFETCH(QJSValue, value);
3167 QVERIFY(!value.callAsConstructor().isValid());
3170 void tst_QJSValue::construct_simple()
3173 QJSValue fun = eng.evaluate("(function () { this.foo = 123; })");
3174 QVERIFY(fun.isCallable());
3175 QJSValue ret = fun.callAsConstructor();
3176 QVERIFY(ret.isObject());
3177 QVERIFY(ret.instanceOf(fun));
3178 QCOMPARE(ret.property("foo").toInt(), 123);
3181 void tst_QJSValue::construct_newObjectJS()
3184 // returning a different object overrides the default-constructed one
3185 QJSValue fun = eng.evaluate("(function () { return { bar: 456 }; })");
3186 QVERIFY(fun.isCallable());
3187 QJSValue ret = fun.callAsConstructor();
3188 QVERIFY(ret.isObject());
3189 QVERIFY(!ret.instanceOf(fun));
3190 QCOMPARE(ret.property("bar").toInt(), 456);
3193 #if 0 // FIXME: no c-style callbacks
3194 void tst_QJSValue::construct_undefined()
3197 QJSValue fun = eng.newFunction(ctorReturningUndefined);
3198 QJSValue ret = fun.callAsConstructor();
3199 QVERIFY(ret.isObject());
3200 QVERIFY(ret.instanceOf(fun));
3201 QCOMPARE(ret.property("foo").toInt(), 123);
3204 void tst_QJSValue::construct_newObjectCpp()
3207 QJSValue fun = eng.newFunction(ctorReturningNewObject);
3208 QJSValue ret = fun.callAsConstructor();
3209 QVERIFY(ret.isObject());
3210 QVERIFY(!ret.instanceOf(fun));
3211 QCOMPARE(ret.property("bar").toInt(), 456);
3215 void tst_QJSValue::construct_arg()
3218 QJSValue Number = eng.evaluate("Number");
3219 QCOMPARE(Number.isCallable(), true);
3221 args << QJSValue(&eng, 123);
3222 QJSValue ret = Number.callAsConstructor(args);
3223 QCOMPARE(ret.isObject(), true);
3224 QCOMPARE(ret.toNumber(), args.at(0).toNumber());
3227 void tst_QJSValue::construct_proto()
3230 // test that internal prototype is set correctly
3231 QJSValue fun = eng.evaluate("(function() { return this.__proto__; })");
3232 QCOMPARE(fun.isCallable(), true);
3233 QCOMPARE(fun.property("prototype").isObject(), true);
3234 QJSValue ret = fun.callAsConstructor();
3235 QCOMPARE(fun.property("prototype").strictlyEquals(ret), true);
3238 void tst_QJSValue::construct_returnInt()
3241 // test that we return the new object even if a non-object value is returned from the function
3242 QJSValue fun = eng.evaluate("(function() { return 123; })");
3243 QCOMPARE(fun.isCallable(), true);
3244 QJSValue ret = fun.callAsConstructor();
3245 QCOMPARE(ret.isObject(), true);
3248 void tst_QJSValue::construct_throw()
3251 QJSValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
3252 QCOMPARE(fun.isCallable(), true);
3253 QJSValue ret = fun.callAsConstructor();
3254 QCOMPARE(ret.isError(), true);
3255 QCOMPARE(eng.hasUncaughtException(), true);
3256 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3259 #if 0 // FIXME: The feature of interpreting an array as argument list has been removed from the API
3260 void tst_QJSValue::construct()
3263 QJSValue fun = eng.evaluate("(function() { return arguments; })");
3264 QVERIFY(fun.isCallable());
3265 QJSValue array = eng.newArray(3);
3266 array.setProperty(0, QJSValue(&eng, 123.0));
3267 array.setProperty(1, QJSValue(&eng, 456.0));
3268 array.setProperty(2, QJSValue(&eng, 789.0));
3269 // construct with single array object as arguments
3270 QJSValue ret = fun.callAsConstructor(array);
3271 QVERIFY(!eng.hasUncaughtException());
3272 QVERIFY(ret.isValid());
3273 QVERIFY(ret.isObject());
3274 QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
3275 QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
3276 QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
3277 // construct with arguments object as arguments
3278 QJSValue ret2 = fun.callAsConstructor(ret);
3279 QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
3280 QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
3281 QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
3282 // construct with null as arguments
3283 QJSValue ret3 = fun.callAsConstructor(eng.nullValue());
3284 QCOMPARE(ret3.isError(), false);
3285 QCOMPARE(ret3.property("length").isNumber(), true);
3286 QCOMPARE(ret3.property("length").toNumber(), 0.0);
3287 // construct with undefined as arguments
3288 QJSValue ret4 = fun.callAsConstructor(eng.undefinedValue());
3289 QCOMPARE(ret4.isError(), false);
3290 QCOMPARE(ret4.property("length").isNumber(), true);
3291 QCOMPARE(ret4.property("length").toNumber(), 0.0);
3292 // construct with something else as arguments
3293 QJSValue ret5 = fun.callAsConstructor(QJSValue(&eng, 123.0));
3294 QCOMPARE(ret5.isError(), true);
3295 // construct with a non-array object as arguments
3296 QJSValue ret6 = fun.callAsConstructor(eng.globalObject());
3297 QVERIFY(ret6.isError());
3298 QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
3302 void tst_QJSValue::construct_twoEngines()
3305 QJSEngine otherEngine;
3306 QJSValue ctor = engine.evaluate("(function (a, b) { this.foo = 123; })");
3307 QJSValue arg(&otherEngine, 124567);
3308 QTest::ignoreMessage(QtWarningMsg, "QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
3309 QVERIFY(!ctor.callAsConstructor(QJSValueList() << arg).isValid());
3310 QTest::ignoreMessage(QtWarningMsg, "QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
3311 QVERIFY(!ctor.callAsConstructor(QJSValueList() << arg << otherEngine.newObject()).isValid());
3314 void tst_QJSValue::construct_constructorThrowsPrimitive()
3317 QJSValue fun = eng.evaluate("(function() { throw 123; })");
3318 QVERIFY(fun.isCallable());
3319 // construct(QJSValueList)
3321 QJSValue ret = fun.callAsConstructor();
3322 QVERIFY(ret.isNumber());
3323 QCOMPARE(ret.toNumber(), 123.0);
3324 QVERIFY(eng.hasUncaughtException());
3325 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3326 eng.clearExceptions();
3328 #if 0 // FIXME: The feature of interpreting an array as argument list has been removed from the API
3329 // construct(QJSValue)
3331 QJSValue ret = fun.callAsConstructor(eng.newArray());
3332 QVERIFY(ret.isNumber());
3333 QCOMPARE(ret.toNumber(), 123.0);
3334 QVERIFY(eng.hasUncaughtException());
3335 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3336 eng.clearExceptions();
3341 #if 0 // FIXME: No QJSValue::lessThan
3342 void tst_QJSValue::lessThan()
3346 QVERIFY(!QJSValue().lessThan(QJSValue()));
3348 QJSValue num = QJSValue(&eng, 123);
3349 QCOMPARE(num.lessThan(QJSValue(&eng, 124)), true);
3350 QCOMPARE(num.lessThan(QJSValue(&eng, 122)), false);
3351 QCOMPARE(num.lessThan(QJSValue(&eng, 123)), false);
3352 QCOMPARE(num.lessThan(QJSValue(&eng, "124")), true);
3353 QCOMPARE(num.lessThan(QJSValue(&eng, "122")), false);
3354 QCOMPARE(num.lessThan(QJSValue(&eng, "123")), false);
3355 QCOMPARE(num.lessThan(QJSValue(&eng, qSNaN())), false);
3356 QCOMPARE(num.lessThan(QJSValue(&eng, +qInf())), true);
3357 QCOMPARE(num.lessThan(QJSValue(&eng, -qInf())), false);
3358 QCOMPARE(num.lessThan(num), false);
3359 QCOMPARE(num.lessThan(QJSValue(&eng, 124).toObject()), true);
3360 QCOMPARE(num.lessThan(QJSValue(&eng, 122).toObject()), false);
3361 QCOMPARE(num.lessThan(QJSValue(&eng, 123).toObject()), false);
3362 QCOMPARE(num.lessThan(QJSValue(&eng, "124").toObject()), true);
3363 QCOMPARE(num.lessThan(QJSValue(&eng, "122").toObject()), false);
3364 QCOMPARE(num.lessThan(QJSValue(&eng, "123").toObject()), false);
3365 QCOMPARE(num.lessThan(QJSValue(&eng, qSNaN()).toObject()), false);
3366 QCOMPARE(num.lessThan(QJSValue(&eng, +qInf()).toObject()), true);
3367 QCOMPARE(num.lessThan(QJSValue(&eng, -qInf()).toObject()), false);
3368 QCOMPARE(num.lessThan(num.toObject()), false);
3369 QCOMPARE(num.lessThan(QJSValue()), false);
3371 QJSValue str = QJSValue(&eng, "123");
3372 QCOMPARE(str.lessThan(QJSValue(&eng, "124")), true);
3373 QCOMPARE(str.lessThan(QJSValue(&eng, "122")), false);
3374 QCOMPARE(str.lessThan(QJSValue(&eng, "123")), false);
3375 QCOMPARE(str.lessThan(QJSValue(&eng, 124)), true);
3376 QCOMPARE(str.lessThan(QJSValue(&eng, 122)), false);
3377 QCOMPARE(str.lessThan(QJSValue(&eng, 123)), false);
3378 QCOMPARE(str.lessThan(str), false);
3379 QCOMPARE(str.lessThan(QJSValue(&eng, "124").toObject()), true);
3380 QCOMPARE(str.lessThan(QJSValue(&eng, "122").toObject()), false);
3381 QCOMPARE(str.lessThan(QJSValue(&eng, "123").toObject()), false);
3382 QCOMPARE(str.lessThan(QJSValue(&eng, 124).toObject()), true);
3383 QCOMPARE(str.lessThan(QJSValue(&eng, 122).toObject()), false);
3384 QCOMPARE(str.lessThan(QJSValue(&eng, 123).toObject()), false);
3385 QCOMPARE(str.lessThan(str.toObject()), false);
3386 QCOMPARE(str.lessThan(QJSValue()), false);
3389 QJSValue num2 = QJSValue(123);
3390 QCOMPARE(num2.lessThan(QJSValue(124)), true);
3391 QCOMPARE(num2.lessThan(QJSValue(122)), false);
3392 QCOMPARE(num2.lessThan(QJSValue(123)), false);
3393 QCOMPARE(num2.lessThan(QJSValue("124")), true);
3394 QCOMPARE(num2.lessThan(QJSValue("122")), false);
3395 QCOMPARE(num2.lessThan(QJSValue("123")), false);
3396 QCOMPARE(num2.lessThan(QJSValue(qSNaN())), false);
3397 QCOMPARE(num2.lessThan(QJSValue(+qInf())), true);
3398 QCOMPARE(num2.lessThan(QJSValue(-qInf())), false);
3399 QCOMPARE(num2.lessThan(num), false);
3400 QCOMPARE(num2.lessThan(QJSValue()), false);
3402 QJSValue str2 = QJSValue("123");
3403 QCOMPARE(str2.lessThan(QJSValue("124")), true);
3404 QCOMPARE(str2.lessThan(QJSValue("122")), false);
3405 QCOMPARE(str2.lessThan(QJSValue("123")), false);
3406 QCOMPARE(str2.lessThan(QJSValue(124)), true);
3407 QCOMPARE(str2.lessThan(QJSValue(122)), false);
3408 QCOMPARE(str2.lessThan(QJSValue(123)), false);
3409 QCOMPARE(str2.lessThan(str), false);
3410 QCOMPARE(str2.lessThan(QJSValue()), false);
3412 QJSValue obj1 = eng.newObject();
3413 QJSValue obj2 = eng.newObject();
3414 QCOMPARE(obj1.lessThan(obj2), false);
3415 QCOMPARE(obj2.lessThan(obj1), false);
3416 QCOMPARE(obj1.lessThan(obj1), false);
3417 QCOMPARE(obj2.lessThan(obj2), false);
3419 QJSValue date1 = eng.newDate(QDateTime(QDate(2000, 1, 1)));
3420 QJSValue date2 = eng.newDate(QDateTime(QDate(1999, 1, 1)));
3421 QCOMPARE(date1.lessThan(date2), false);
3422 QCOMPARE(date2.lessThan(date1), true);
3423 QCOMPARE(date1.lessThan(date1), false);
3424 QCOMPARE(date2.lessThan(date2), false);
3425 QCOMPARE(date1.lessThan(QJSValue()), false);
3427 QCOMPARE(QJSValue().lessThan(date2), false);
3429 QScriptEngine otherEngine;
3430 QTest::ignoreMessage(QtWarningMsg, "QJSValue::lessThan: "
3431 "cannot compare to a value created in "
3432 "a different engine");
3433 QCOMPARE(date1.lessThan(QJSValue(&otherEngine, 123)), false);
3437 void tst_QJSValue::equals()
3441 QVERIFY(QJSValue().equals(QJSValue()));
3443 QJSValue num = QJSValue(&eng, 123);
3444 QCOMPARE(num.equals(QJSValue(&eng, 123)), true);
3445 QCOMPARE(num.equals(QJSValue(&eng, 321)), false);
3446 QCOMPARE(num.equals(QJSValue(&eng, QLatin1String("123"))), true);
3447 QCOMPARE(num.equals(QJSValue(&eng, QLatin1String("321"))), false);
3448 QCOMPARE(num.equals(QJSValue(&eng, 123).toObject()), true);
3449 QCOMPARE(num.equals(QJSValue(&eng, 321).toObject()), false);
3450 QCOMPARE(num.equals(QJSValue(&eng, QLatin1String("123")).toObject()), true);
3451 QCOMPARE(num.equals(QJSValue(&eng, QLatin1String("321")).toObject()), false);
3452 QVERIFY(num.toObject().equals(num));
3453 QCOMPARE(num.equals(QJSValue()), false);
3455 QJSValue str = QJSValue(&eng, QLatin1String("123"));
3456 QCOMPARE(str.equals(QJSValue(&eng, QLatin1String("123"))), true);
3457 QCOMPARE(str.equals(QJSValue(&eng, QLatin1String("321"))), false);
3458 QCOMPARE(str.equals(QJSValue(&eng, 123)), true);
3459 QCOMPARE(str.equals(QJSValue(&eng, 321)), false);
3460 QCOMPARE(str.equals(QJSValue(&eng, QLatin1String("123")).toObject()), true);
3461 QCOMPARE(str.equals(QJSValue(&eng, QLatin1String("321")).toObject()), false);
3462 QCOMPARE(str.equals(QJSValue(&eng, 123).toObject()), true);
3463 QCOMPARE(str.equals(QJSValue(&eng, 321).toObject()), false);
3464 QVERIFY(str.toObject().equals(str));
3465 QCOMPARE(str.equals(QJSValue()), false);
3467 QJSValue num2 = QJSValue(123);
3468 QCOMPARE(num2.equals(QJSValue(123)), true);
3469 QCOMPARE(num2.equals(QJSValue(321)), false);
3470 QCOMPARE(num2.equals(QJSValue("123")), true);
3471 QCOMPARE(num2.equals(QJSValue("321")), false);
3472 QCOMPARE(num2.equals(QJSValue()), false);
3474 QJSValue str2 = QJSValue("123");
3475 QCOMPARE(str2.equals(QJSValue("123")), true);
3476 QCOMPARE(str2.equals(QJSValue("321")), false);
3477 QCOMPARE(str2.equals(QJSValue(123)), true);
3478 QCOMPARE(str2.equals(QJSValue(321)), false);
3479 QCOMPARE(str2.equals(QJSValue()), false);
3481 QJSValue date1 = eng.newDate(QDateTime(QDate(2000, 1, 1)));
3482 QJSValue date2 = eng.newDate(QDateTime(QDate(1999, 1, 1)));
3483 QCOMPARE(date1.equals(date2), false);
3484 QCOMPARE(date1.equals(date1), true);
3485 QCOMPARE(date2.equals(date2), true);
3487 QJSValue undefined = eng.undefinedValue();
3488 QJSValue null = eng.nullValue();
3489 QCOMPARE(undefined.equals(undefined), true);
3490 QCOMPARE(null.equals(null), true);
3491 QCOMPARE(undefined.equals(null), true);
3492 QCOMPARE(null.equals(undefined), true);
3493 QCOMPARE(undefined.equals(QJSValue()), false);
3494 QCOMPARE(null.equals(QJSValue()), false);
3495 QVERIFY(!null.equals(num));
3496 QVERIFY(!undefined.equals(num));
3498 QJSValue sant = QJSValue(&eng, true);
3499 QVERIFY(sant.equals(QJSValue(&eng, 1)));
3500 QVERIFY(sant.equals(QJSValue(&eng, QLatin1String("1"))));
3501 QVERIFY(sant.equals(sant));
3502 QVERIFY(sant.equals(QJSValue(&eng, 1).toObject()));
3503 QVERIFY(sant.equals(QJSValue(&eng, QLatin1String("1")).toObject()));
3504 QVERIFY(sant.equals(sant.toObject()));
3505 QVERIFY(sant.toObject().equals(sant));
3506 QVERIFY(!sant.equals(QJSValue(&eng, 0)));
3507 QVERIFY(!sant.equals(undefined));
3508 QVERIFY(!sant.equals(null));
3510 QJSValue falskt = QJSValue(&eng, false);
3511 QVERIFY(falskt.equals(QJSValue(&eng, 0)));
3512 QVERIFY(falskt.equals(QJSValue(&eng, QLatin1String("0"))));
3513 QVERIFY(falskt.equals(falskt));
3514 QVERIFY(falskt.equals(QJSValue(&eng, 0).toObject()));
3515 QVERIFY(falskt.equals(QJSValue(&eng, QLatin1String("0")).toObject()));
3516 QVERIFY(falskt.equals(falskt.toObject()));
3517 QVERIFY(falskt.toObject().equals(falskt));
3518 QVERIFY(!falskt.equals(sant));
3519 QVERIFY(!falskt.equals(undefined));
3520 QVERIFY(!falskt.equals(null));
3522 QJSValue obj1 = eng.newObject();
3523 QJSValue obj2 = eng.newObject();
3524 QCOMPARE(obj1.equals(obj2), false);
3525 QCOMPARE(obj2.equals(obj1), false);
3526 QCOMPARE(obj1.equals(obj1), true);
3527 QCOMPARE(obj2.equals(obj2), true);
3529 QJSValue qobj1 = eng.newQObject(this);
3530 QJSValue qobj2 = eng.newQObject(this);
3531 QJSValue qobj3 = eng.newQObject(0);
3533 // FIXME: No ScriptOwnership: QJSValue qobj4 = eng.newQObject(new QObject(), QScriptEngine::ScriptOwnership);
3534 QJSValue qobj4 = eng.newQObject(new QObject());
3536 QVERIFY(qobj1.equals(qobj2)); // compares the QObject pointers
3537 QVERIFY(!qobj2.equals(qobj4)); // compares the QObject pointers
3538 QVERIFY(!qobj2.equals(obj2)); // compares the QObject pointers
3540 QJSValue compareFun = eng.evaluate("(function(a, b) { return a == b; })");
3541 QVERIFY(compareFun.isCallable());
3543 QJSValue ret = compareFun.call(QJSValueList() << qobj1 << qobj2);
3544 QVERIFY(ret.isBool());
3545 ret = compareFun.call(QJSValueList() << qobj1 << qobj3);
3546 QVERIFY(ret.isBool());
3547 QVERIFY(!ret.toBool());
3548 ret = compareFun.call(QJSValueList() << qobj1 << qobj4);
3549 QVERIFY(ret.isBool());
3550 QVERIFY(!ret.toBool());
3551 ret = compareFun.call(QJSValueList() << qobj1 << obj1);
3552 QVERIFY(ret.isBool());
3553 QVERIFY(!ret.toBool());
3557 QJSValue var1 = eng.newVariant(QVariant(false));
3558 QJSValue var2 = eng.newVariant(QVariant(false));
3559 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3560 QVERIFY(var1.equals(var2));
3562 QJSValue ret = compareFun.call(QJSValue(), QJSValueList() << var1 << var2);
3563 QVERIFY(ret.isBool());
3567 QJSValue var1 = eng.newVariant(QVariant(false));
3568 QJSValue var2 = eng.newVariant(QVariant(0));
3569 // QVariant::operator==() performs type conversion
3570 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3571 QVERIFY(var1.equals(var2));
3574 QJSValue var1 = eng.newVariant(QVariant(QStringList() << "a"));
3575 QJSValue var2 = eng.newVariant(QVariant(QStringList() << "a"));
3576 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3577 QVERIFY(var1.equals(var2));
3580 QJSValue var1 = eng.newVariant(QVariant(QStringList() << "a"));
3581 QJSValue var2 = eng.newVariant(QVariant(QStringList() << "b"));
3582 QVERIFY(!var1.equals(var2));
3585 QJSValue var1 = eng.newVariant(QVariant(QPoint(1, 2)));
3586 QJSValue var2 = eng.newVariant(QVariant(QPoint(1, 2)));
3587 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3588 QVERIFY(var1.equals(var2));
3591 QJSValue var1 = eng.newVariant(QVariant(QPoint(1, 2)));
3592 QJSValue var2 = eng.newVariant(QVariant(QPoint(3, 4)));
3593 QVERIFY(!var1.equals(var2));
3596 QJSValue var1 = eng.newVariant(QVariant(int(1)));
3597 QJSValue var2 = eng.newVariant(QVariant(double(1)));
3598 // QVariant::operator==() performs type conversion
3599 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3600 QVERIFY(var1.equals(var2));
3603 QJSValue var1 = eng.newVariant(QVariant(QString::fromLatin1("123")));
3604 QJSValue var2 = eng.newVariant(QVariant(double(123)));
3605 QJSValue var3(QString::fromLatin1("123"));
3608 QVERIFY(var1.equals(var1));
3609 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3610 QVERIFY(var1.equals(var2));
3611 QVERIFY(var1.equals(var3));
3612 QVERIFY(var1.equals(var4));
3614 QEXPECT_FAIL("", "FIXME: QVariant comparison does not work with v8", Continue);
3615 QVERIFY(var2.equals(var1));
3616 QVERIFY(var2.equals(var2));
3617 QVERIFY(var2.equals(var3));
3618 QVERIFY(var2.equals(var4));
3620 QVERIFY(var3.equals(var1));
3621 QVERIFY(var3.equals(var2));
3622 QVERIFY(var3.equals(var3));
3623 QVERIFY(var3.equals(var4));
3625 QVERIFY(var4.equals(var1));
3626 QVERIFY(var4.equals(var2));
3627 QVERIFY(var4.equals(var3));
3628 QVERIFY(var4.equals(var4));
3631 QJSEngine otherEngine;
3632 QTest::ignoreMessage(QtWarningMsg, "QJSValue::equals: "
3633 "cannot compare to a value created in "
3634 "a different engine");
3635 QCOMPARE(date1.equals(QJSValue(&otherEngine, 123)), false);
3638 void tst_QJSValue::strictlyEquals()
3642 QVERIFY(QJSValue().strictlyEquals(QJSValue()));
3644 QJSValue num = QJSValue(&eng, 123);
3645 QCOMPARE(num.strictlyEquals(QJSValue(&eng, 123)), true);
3646 QCOMPARE(num.strictlyEquals(QJSValue(&eng, 321)), false);
3647 QCOMPARE(num.strictlyEquals(QJSValue(&eng, QLatin1String("123"))), false);
3648 QCOMPARE(num.strictlyEquals(QJSValue(&eng, QLatin1String("321"))), false);
3649 QCOMPARE(num.strictlyEquals(QJSValue(&eng, 123).toObject()), false);
3650 QCOMPARE(num.strictlyEquals(QJSValue(&eng, 321).toObject()), false);
3651 QCOMPARE(num.strictlyEquals(QJSValue(&eng, QLatin1String("123")).toObject()), false);
3652 QCOMPARE(num.strictlyEquals(QJSValue(&eng, QLatin1String("321")).toObject()), false);
3653 QVERIFY(!num.toObject().strictlyEquals(num));
3654 QVERIFY(!num.strictlyEquals(QJSValue()));
3655 QVERIFY(!QJSValue().strictlyEquals(num));
3657 QJSValue str = QJSValue(&eng, QLatin1String("123"));
3658 QCOMPARE(str.strictlyEquals(QJSValue(&eng, QLatin1String("123"))), true);
3659 QCOMPARE(str.strictlyEquals(QJSValue(&eng, QLatin1String("321"))), false);
3660 QCOMPARE(str.strictlyEquals(QJSValue(&eng, 123)), false);
3661 QCOMPARE(str.strictlyEquals(QJSValue(&eng, 321)), false);
3662 QCOMPARE(str.strictlyEquals(QJSValue(&eng, QLatin1String("123")).toObject()), false);
3663 QCOMPARE(str.strictlyEquals(QJSValue(&eng, QLatin1String("321")).toObject()), false);
3664 QCOMPARE(str.strictlyEquals(QJSValue(&eng, 123).toObject()), false);
3665 QCOMPARE(str.strictlyEquals(QJSValue(&eng, 321).toObject()), false);
3666 QVERIFY(!str.toObject().strictlyEquals(str));
3667 QVERIFY(!str.strictlyEquals(QJSValue()));
3669 QJSValue num2 = QJSValue(123);
3670 QCOMPARE(num2.strictlyEquals(QJSValue(123)), true);
3671 QCOMPARE(num2.strictlyEquals(QJSValue(321)), false);
3672 QCOMPARE(num2.strictlyEquals(QJSValue("123")), false);
3673 QCOMPARE(num2.strictlyEquals(QJSValue("321")), false);
3674 QVERIFY(!num2.strictlyEquals(QJSValue()));
3676 QJSValue str2 = QJSValue("123");
3677 QCOMPARE(str2.strictlyEquals(QJSValue("123")), true);
3678 QCOMPARE(str2.strictlyEquals(QJSValue("321")), false);
3679 QCOMPARE(str2.strictlyEquals(QJSValue(123)), false);
3680 QCOMPARE(str2.strictlyEquals(QJSValue(321)), false);
3681 QVERIFY(!str2.strictlyEquals(QJSValue()));
3683 QJSValue date1 = eng.newDate(QDateTime(QDate(2000, 1, 1)));
3684 QJSValue date2 = eng.newDate(QDateTime(QDate(1999, 1, 1)));
3685 QCOMPARE(date1.strictlyEquals(date2), false);
3686 QCOMPARE(date1.strictlyEquals(date1), true);
3687 QCOMPARE(date2.strictlyEquals(date2), true);
3688 QVERIFY(!date1.strictlyEquals(QJSValue()));
3690 QJSValue undefined = eng.undefinedValue();
3691 QJSValue null = eng.nullValue();
3692 QCOMPARE(undefined.strictlyEquals(undefined), true);
3693 QCOMPARE(null.strictlyEquals(null), true);
3694 QCOMPARE(undefined.strictlyEquals(null), false);
3695 QCOMPARE(null.strictlyEquals(undefined), false);
3696 QVERIFY(!null.strictlyEquals(QJSValue()));
3698 QJSValue sant = QJSValue(&eng, true);
3699 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, 1)));
3700 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, QLatin1String("1"))));
3701 QVERIFY(sant.strictlyEquals(sant));
3702 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, 1).toObject()));
3703 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, QLatin1String("1")).toObject()));
3704 QVERIFY(!sant.strictlyEquals(sant.toObject()));
3705 QVERIFY(!sant.toObject().strictlyEquals(sant));
3706 QVERIFY(!sant.strictlyEquals(QJSValue(&eng, 0)));
3707 QVERIFY(!sant.strictlyEquals(undefined));
3708 QVERIFY(!sant.strictlyEquals(null));
3709 QVERIFY(!sant.strictlyEquals(QJSValue()));
3711 QJSValue falskt = QJSValue(&eng, false);
3712 QVERIFY(!falskt.strictlyEquals(QJSValue(&eng, 0)));
3713 QVERIFY(!falskt.strictlyEquals(QJSValue(&eng, QLatin1String("0"))));
3714 QVERIFY(falskt.strictlyEquals(falskt));
3715 QVERIFY(!falskt.strictlyEquals(QJSValue(&eng, 0).toObject()));
3716 QVERIFY(!falskt.strictlyEquals(QJSValue(&eng, QLatin1String("0")).toObject()));
3717 QVERIFY(!falskt.strictlyEquals(falskt.toObject()));
3718 QVERIFY(!falskt.toObject().strictlyEquals(falskt));
3719 QVERIFY(!falskt.strictlyEquals(sant));
3720 QVERIFY(!falskt.strictlyEquals(undefined));
3721 QVERIFY(!falskt.strictlyEquals(null));
3722 QVERIFY(!falskt.strictlyEquals(QJSValue()));
3724 QVERIFY(!QJSValue(false).strictlyEquals(123));
3725 QVERIFY(!QJSValue(QJSValue::UndefinedValue).strictlyEquals(123));
3726 QVERIFY(!QJSValue(QJSValue::NullValue).strictlyEquals(123));
3727 QVERIFY(!QJSValue(false).strictlyEquals("ciao"));
3728 QVERIFY(!QJSValue(QJSValue::UndefinedValue).strictlyEquals("ciao"));
3729 QVERIFY(!QJSValue(QJSValue::NullValue).strictlyEquals("ciao"));
3730 QVERIFY(QJSValue(&eng, QLatin1String("ciao")).strictlyEquals("ciao"));
3731 QVERIFY(QJSValue("ciao").strictlyEquals(QJSValue(&eng, QLatin1String("ciao"))));
3732 QVERIFY(!QJSValue("ciao").strictlyEquals(123));
3733 QVERIFY(!QJSValue("ciao").strictlyEquals(QJSValue(&eng, 123)));
3734 QVERIFY(!QJSValue(123).strictlyEquals("ciao"));
3735 QVERIFY(!QJSValue(123).strictlyEquals(QJSValue(&eng, QLatin1String("ciao"))));
3736 QVERIFY(!QJSValue(&eng, 123).strictlyEquals("ciao"));
3738 QJSValue obj1 = eng.newObject();
3739 QJSValue obj2 = eng.newObject();
3740 QCOMPARE(obj1.strictlyEquals(obj2), false);
3741 QCOMPARE(obj2.strictlyEquals(obj1), false);
3742 QCOMPARE(obj1.strictlyEquals(obj1), true);
3743 QCOMPARE(obj2.strictlyEquals(obj2), true);
3744 QVERIFY(!obj1.strictlyEquals(QJSValue()));
3746 QJSValue qobj1 = eng.newQObject(this);
3747 QJSValue qobj2 = eng.newQObject(this);
3748 QVERIFY(qobj1.strictlyEquals(qobj2));
3751 QJSValue var1 = eng.newVariant(QVariant(false));
3752 QJSValue var2 = eng.newVariant(QVariant(false));
3753 QVERIFY(!var1.strictlyEquals(var2));
3754 QVERIFY(!var1.strictlyEquals(QJSValue()));
3757 QJSValue var1 = eng.newVariant(QVariant(false));
3758 QJSValue var2 = eng.newVariant(QVariant(0));
3759 QVERIFY(!var1.strictlyEquals(var2));
3762 QJSValue var1 = eng.newVariant(QVariant(QStringList() << "a"));
3763 QJSValue var2 = eng.newVariant(QVariant(QStringList() << "a"));
3764 QVERIFY(!var1.strictlyEquals(var2));
3767 QJSValue var1 = eng.newVariant(QVariant(QStringList() << "a"));
3768 QJSValue var2 = eng.newVariant(QVariant(QStringList() << "b"));
3769 QVERIFY(!var1.strictlyEquals(var2));
3772 QJSValue var1 = eng.newVariant(QVariant(QPoint(1, 2)));
3773 QJSValue var2 = eng.newVariant(QVariant(QPoint(1, 2)));
3774 QVERIFY(!var1.strictlyEquals(var2));
3777 QJSValue var1 = eng.newVariant(QVariant(QPoint(1, 2)));
3778 QJSValue var2 = eng.newVariant(QVariant(QPoint(3, 4)));
3779 QVERIFY(!var1.strictlyEquals(var2));
3782 QJSEngine otherEngine;
3783 QTest::ignoreMessage(QtWarningMsg, "QJSValue::strictlyEquals: "
3784 "cannot compare to a value created in "
3785 "a different engine");
3786 QCOMPARE(date1.strictlyEquals(QJSValue(&otherEngine, 123)), false);
3789 Q_DECLARE_METATYPE(int*)
3790 Q_DECLARE_METATYPE(double*)
3791 Q_DECLARE_METATYPE(QColor*)
3792 Q_DECLARE_METATYPE(QBrush*)
3794 void tst_QJSValue::castToPointer()
3798 QJSValue v = eng.newVariant(int(123));
3799 int *ip = qjsvalue_cast<int*>(v);
3803 QCOMPARE(qjsvalue_cast<int>(v), 456);
3805 double *dp = qjsvalue_cast<double*>(v);
3808 QJSValue v2 = eng.newVariant(qVariantFromValue(ip));
3809 QCOMPARE(qjsvalue_cast<int*>(v2), ip);
3812 QColor c(123, 210, 231);
3813 QJSValue v = eng.newVariant(c);
3814 QColor *cp = qjsvalue_cast<QColor*>(v);
3818 QBrush *bp = qjsvalue_cast<QBrush*>(v);
3821 QJSValue v2 = eng.newVariant(qVariantFromValue(cp));
3822 QCOMPARE(qjsvalue_cast<QColor*>(v2), cp);
3826 void tst_QJSValue::prettyPrinter_data()
3828 QTest::addColumn<QString>("function");
3829 QTest::addColumn<QString>("expected");
3830 QTest::newRow("function() { }") << QString("function() { }") << QString("function () { }");
3831 QTest::newRow("function foo() { }") << QString("(function foo() { })") << QString("function foo() { }");
3832 QTest::newRow("function foo(bar) { }") << QString("(function foo(bar) { })") << QString("function foo(bar) { }");
3833 QTest::newRow("function foo(bar, baz) { }") << QString("(function foo(bar, baz) { })") << QString("function foo(bar, baz) { }");
3834 QTest::newRow("this") << QString("function() { this; }") << QString("function () { this; }");
3835 QTest::newRow("identifier") << QString("function(a) { a; }") << QString("function (a) { a; }");
3836 QTest::newRow("null") << QString("function() { null; }") << QString("function () { null; }");
3837 QTest::newRow("true") << QString("function() { true; }") << QString("function () { true; }");
3838 QTest::newRow("false") << QString("function() { false; }") << QString("function () { false; }");
3839 QTest::newRow("string") << QString("function() { 'test'; }") << QString("function () { \'test\'; }");
3840 QTest::newRow("string") << QString("function() { \"test\"; }") << QString("function () { \"test\"; }");
3841 QTest::newRow("number") << QString("function() { 123; }") << QString("function () { 123; }");
3842 QTest::newRow("number") << QString("function() { 123.456; }") << QString("function () { 123.456; }");
3843 QTest::newRow("regexp") << QString("function() { /hello/; }") << QString("function () { /hello/; }");
3844 QTest::newRow("regexp") << QString("function() { /hello/gim; }") << QString("function () { /hello/gim; }");
3845 QTest::newRow("array") << QString("function() { []; }") << QString("function () { []; }");
3846 QTest::newRow("array") << QString("function() { [10]; }") << QString("function () { [10]; }");
3847 QTest::newRow("array") << QString("function() { [10, 20, 30]; }") << QString("function () { [10, 20, 30]; }");
3848 QTest::newRow("array") << QString("function() { [10, 20, , 40]; }") << QString("function () { [10, 20, , 40]; }");
3849 QTest::newRow("array") << QString("function() { [,]; }") << QString("function () { [,]; }");
3850 QTest::newRow("array") << QString("function() { [, 10]; }") << QString("function () { [, 10]; }");
3851 QTest::newRow("array") << QString("function() { [, 10, ]; }") << QString("function () { [, 10, ]; }");
3852 QTest::newRow("array") << QString("function() { [, 10, ,]; }") << QString("function () { [, 10, ,]; }");
3853 QTest::newRow("array") << QString("function() { [[10], [20]]; }") << QString("function () { [[10], [20]]; }");
3854 QTest::newRow("member") << QString("function() { a.b; }") << QString("function () { a.b; }");
3855 QTest::newRow("member") << QString("function() { a.b.c; }") << QString("function () { a.b.c; }");
3856 QTest::newRow("call") << QString("function() { f(); }") << QString("function () { f(); }");
3857 QTest::newRow("call") << QString("function() { f(a); }") << QString("function () { f(a); }");
3858 QTest::newRow("call") << QString("function() { f(a, b); }") << QString("function () { f(a, b); }");
3859 QTest::newRow("new") << QString("function() { new C(); }") << QString("function () { new C(); }");
3860 QTest::newRow("new") << QString("function() { new C(a); }") << QString("function () { new C(a); }");
3861 QTest::newRow("new") << QString("function() { new C(a, b); }") << QString("function () { new C(a, b); }");
3862 QTest::newRow("++") << QString("function() { a++; }") << QString("function () { a++; }");
3863 QTest::newRow("++") << QString("function() { ++a; }") << QString("function () { ++a; }");
3864 QTest::newRow("--") << QString("function() { a--; }") << QString("function () { a--; }");
3865 QTest::newRow("--") << QString("function() { --a; }") << QString("function () { --a; }");
3866 QTest::newRow("delete") << QString("function() { delete a; }") << QString("function () { delete a; }");
3867 QTest::newRow("void") << QString("function() { void a; }") << QString("function () { void a; }");
3868 QTest::newRow("typeof") << QString("function() { typeof a; }") << QString("function () { typeof a; }");
3869 QTest::newRow("+") << QString("function() { +a; }") << QString("function () { +a; }");
3870 QTest::newRow("-") << QString("function() { -a; }") << QString("function () { -a; }");
3871 QTest::newRow("~") << QString("function() { ~a; }") << QString("function () { ~a; }");
3872 QTest::newRow("!") << QString("function() { !a; }") << QString("function () { !a; }");
3873 QTest::newRow("+") << QString("function() { a + b; }") << QString("function () { a + b; }");
3874 QTest::newRow("&&") << QString("function() { a && b; }") << QString("function () { a && b; }");
3875 QTest::newRow("&=") << QString("function() { a &= b; }") << QString("function () { a &= b; }");
3876 QTest::newRow("=") << QString("function() { a = b; }") << QString("function () { a = b; }");
3877 QTest::newRow("&") << QString("function() { a & b; }") << QString("function () { a & b; }");
3878 QTest::newRow("|") << QString("function() { a | b; }") << QString("function () { a | b; }");
3879 QTest::newRow("^") << QString("function() { a ^ b; }") << QString("function () { a ^ b; }");
3880 QTest::newRow("-=") << QString("function() { a -= b; }") << QString("function () { a -= b; }");
3881 QTest::newRow("/") << QString("function() { a / b; }") << QString("function () { a / b; }");
3882 QTest::newRow("/=") << QString("function() { a /= b; }") << QString("function () { a /= b; }");
3883 QTest::newRow("==") << QString("function() { a == b; }") << QString("function () { a == b; }");
3884 QTest::newRow(">=") << QString("function() { a >= b; }") << QString("function () { a >= b; }");
3885 QTest::newRow(">") << QString("function() { a > b; }") << QString("function () { a > b; }");
3886 QTest::newRow("in") << QString("function() { a in b; }") << QString("function () { a in b; }");
3887 QTest::newRow("+=") << QString("function() { a += b; }") << QString("function () { a += b; }");
3888 QTest::newRow("instanceof") << QString("function() { a instanceof b; }") << QString("function () { a instanceof b; }");
3889 QTest::newRow("<=") << QString("function() { a <= b; }") << QString("function () { a <= b; }");
3890 QTest::newRow("<<") << QString("function() { a << b; }") << QString("function () { a << b; }");
3891 QTest::newRow("<<=") << QString("function() { a <<= b; }") << QString("function () { a <<= b; }");
3892 QTest::newRow("<") << QString("function() { a < b; }") << QString("function () { a < b; }");
3893 QTest::newRow("%") << QString("function() { a % b; }") << QString("function () { a % b; }");
3894 QTest::newRow("%=") << QString("function() { a %= b; }") << QString("function () { a %= b; }");
3895 QTest::newRow("*") << QString("function() { a * b; }") << QString("function () { a * b; }");
3896 QTest::newRow("*=") << QString("function() { a *= b; }") << QString("function () { a *= b; }");
3897 QTest::newRow("!=") << QString("function() { a != b; }") << QString("function () { a != b; }");
3898 QTest::newRow("||") << QString("function() { a || b; }") << QString("function () { a || b; }");
3899 QTest::newRow("|=") << QString("function() { a |= b; }") << QString("function () { a |= b; }");
3900 QTest::newRow(">>") << QString("function() { a >> b; }") << QString("function () { a >> b; }");
3901 QTest::newRow(">>=") << QString("function() { a >>= b; }") << QString("function () { a >>= b; }");
3902 QTest::newRow("===") << QString("function() { a === b; }") << QString("function () { a === b; }");
3903 QTest::newRow("!==") << QString("function() { a !== b; }") << QString("function () { a !== b; }");
3904 QTest::newRow("-") << QString("function() { a - b; }") << QString("function () { a - b; }");
3905 QTest::newRow(">>>") << QString("function() { a >>> b; }") << QString("function () { a >>> b; }");
3906 QTest::newRow(">>>=") << QString("function() { a >>>= b; }") << QString("function () { a >>>= b; }");
3907 QTest::newRow("^=") << QString("function() { a ^= b; }") << QString("function () { a ^= b; }");
3908 QTest::newRow("? :") << QString("function() { a ? b : c; }") << QString("function () { a ? b : c; }");
3909 QTest::newRow("a; b; c") << QString("function() { a; b; c; }") << QString("function () { a; b; c; }");
3910 QTest::newRow("var a;") << QString("function() { var a; }") << QString("function () { var a; }");
3911 QTest::newRow("var a, b;") << QString("function() { var a, b; }") << QString("function () { var a, b; }");
3912 QTest::newRow("var a = 10;") << QString("function() { var a = 10; }") << QString("function () { var a = 10; }");
3913 QTest::newRow("var a, b = 20;") << QString("function() { var a, b = 20; }") << QString("function () { var a, b = 20; }");
3914 QTest::newRow("var a = 10, b = 20;") << QString("function() { var a = 10, b = 20; }") << QString("function () { var a = 10, b = 20; }");
3915 QTest::newRow("if") << QString("function() { if (a) b; }") << QString("function () { if (a) b; }");
3916 QTest::newRow("if") << QString("function() { if (a) { b; c; } }") << QString("function () { if (a) { b; c; } }");
3917 QTest::newRow("if-else") << QString("function() { if (a) b; else c; }") << QString("function () { if (a) b; else c; }");
3918 QTest::newRow("if-else") << QString("function() { if (a) { b; c; } else { d; e; } }") << QString("function () { if (a) { b; c; } else { d; e; } }");
3919 QTest::newRow("do-while") << QString("function() { do { a; } while (b); }") << QString("function () { do { a; } while (b); }");
3920 QTest::newRow("do-while") << QString("function() { do { a; b; c; } while (d); }") << QString("function () { do { a; b; c; } while (d); }");
3921 QTest::newRow("while") << QString("function() { while (a) { b; } }") << QString("function () { while (a) { b; } }");
3922 QTest::newRow("while") << QString("function() { while (a) { b; c; } }") << QString("function () { while (a) { b; c; } }");
3923 QTest::newRow("for") << QString("function() { for (a; b; c) { } }") << QString("function () { for (a; b; c) { } }");
3924 QTest::newRow("for") << QString("function() { for (; a; b) { } }") << QString("function () { for (; a; b) { } }");
3925 QTest::newRow("for") << QString("function() { for (; ; a) { } }") << QString("function () { for (; ; a) { } }");
3926 QTest::newRow("for") << QString("function() { for (; ; ) { } }") << QString("function () { for (; ; ) { } }");
3927 QTest::newRow("for") << QString("function() { for (var a; b; c) { } }") << QString("function () { for (var a; b; c) { } }");
3928 QTest::newRow("for") << QString("function() { for (var a, b, c; d; e) { } }") << QString("function () { for (var a, b, c; d; e) { } }");
3929 QTest::newRow("continue") << QString("function() { for (; ; ) { continue; } }") << QString("function () { for (; ; ) { continue; } }");
3930 QTest::newRow("break") << QString("function() { for (; ; ) { break; } }") << QString("function () { for (; ; ) { break; } }");
3931 QTest::newRow("return") << QString("function() { return; }") << QString("function () { return; }");
3932 QTest::newRow("return") << QString("function() { return 10; }") << QString("function () { return 10; }");
3933 QTest::newRow("with") << QString("function() { with (a) { b; } }") << QString("function () { with (a) { b; } }");
3934 QTest::newRow("with") << QString("function() { with (a) { b; c; } }") << QString("function () { with (a) { b; c; } }");
3935 QTest::newRow("switch") << QString("function() { switch (a) { } }") << QString("function () { switch (a) { } }");
3936 QTest::newRow("switch") << QString("function() { switch (a) { case 1: ; } }") << QString("function () { switch (a) { case 1: ; } }");
3937 QTest::newRow("switch") << QString("function() { switch (a) { case 1: b; break; } }") << QString("function () { switch (a) { case 1: b; break; } }");
3938 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; } }");
3939 QTest::newRow("switch") << QString("function() { switch (a) { case 1: case 2: ; } }") << QString("function () { switch (a) { case 1: case 2: ; } }");
3940 QTest::newRow("switch") << QString("function() { switch (a) { case 1: default: ; } }") << QString("function () { switch (a) { case 1: default: ; } }");
3941 QTest::newRow("switch") << QString("function() { switch (a) { case 1: default: ; case 3: ; } }") << QString("function () { switch (a) { case 1: default: ; case 3: ; } }");
3942 QTest::newRow("label") << QString("function() { a: b; }") << QString("function () { a: b; }");
3943 QTest::newRow("throw") << QString("function() { throw a; }") << QString("function () { throw a; }");
3944 QTest::newRow("try-catch") << QString("function() { try { a; } catch (e) { b; } }") << QString("function () { try { a; } catch (e) { b; } }");
3945 QTest::newRow("try-finally") << QString("function() { try { a; } finally { b; } }") << QString("function () { try { a; } finally { b; } }");
3946 QTest::newRow("try-catch-finally") << QString("function() { try { a; } catch (e) { b; } finally { c; } }") << QString("function () { try { a; } catch (e) { b; } finally { c; } }");
3947 QTest::newRow("a + b + c + d") << QString("function() { a + b + c + d; }") << QString("function () { a + b + c + d; }");
3948 QTest::newRow("a + b - c") << QString("function() { a + b - c; }") << QString("function () { a + b - c; }");
3949 QTest::newRow("a + -b") << QString("function() { a + -b; }") << QString("function () { a + -b; }");
3950 QTest::newRow("a + ~b") << QString("function() { a + ~b; }") << QString("function () { a + ~b; }");
3951 QTest::newRow("a + !b") << QString("function() { a + !b; }") << QString("function () { a + !b; }");
3952 QTest::newRow("a + +b") << QString("function() { a + +b; }") << QString("function () { a + +b; }");
3953 QTest::newRow("(a + b) - c") << QString("function() { (a + b) - c; }") << QString("function () { (a + b) - c; }");
3954 QTest::newRow("(a - b + c") << QString("function() { a - b + c; }") << QString("function () { a - b + c; }");
3955 QTest::newRow("(a - (b + c)") << QString("function() { a - (b + c); }") << QString("function () { a - (b + c); }");
3956 QTest::newRow("a + -(b + c)") << QString("function() { a + -(b + c); }") << QString("function () { a + -(b + c); }");
3957 QTest::newRow("a + ~(b + c)") << QString("function() { a + ~(b + c); }") << QString("function () { a + ~(b + c); }");
3958 QTest::newRow("a + !(b + c)") << QString("function() { a + !(b + c); }") << QString("function () { a + !(b + c); }");
3959 QTest::newRow("a + +(b + c)") << QString("function() { a + +(b + c); }") << QString("function () { a + +(b + c); }");
3960 QTest::newRow("a + b * c") << QString("function() { a + b * c; }") << QString("function () { a + b * c; }");
3961 QTest::newRow("(a + b) * c") << QString("function() { (a + b) * c; }") << QString("function () { (a + b) * c; }");
3962 QTest::newRow("(a + b) * (c + d)") << QString("function() { (a + b) * (c + d); }") << QString("function () { (a + b) * (c + d); }");
3963 QTest::newRow("a + (b * c)") << QString("function() { a + (b * c); }") << QString("function () { a + (b * c); }");
3964 QTest::newRow("a + (b / c)") << QString("function() { a + (b / c); }") << QString("function () { a + (b / c); }");
3965 QTest::newRow("(a / b) * c") << QString("function() { (a / b) * c; }") << QString("function () { (a / b) * c; }");
3966 QTest::newRow("a / (b * c)") << QString("function() { a / (b * c); }") << QString("function () { a / (b * c); }");
3967 QTest::newRow("a / (b % c)") << QString("function() { a / (b % c); }") << QString("function () { a / (b % c); }");
3968 QTest::newRow("a && b || c") << QString("function() { a && b || c; }") << QString("function () { a && b || c; }");
3969 QTest::newRow("a && (b || c)") << QString("function() { a && (b || c); }") << QString("function () { a && (b || c); }");
3970 QTest::newRow("a & b | c") << QString("function() { a & b | c; }") << QString("function () { a & b | c; }");
3971 QTest::newRow("a & (b | c)") << QString("function() { a & (b | c); }") << QString("function () { a & (b | c); }");
3972 QTest::newRow("a & b | c ^ d") << QString("function() { a & b | c ^ d; }") << QString("function () { a & b | c ^ d; }");
3973 QTest::newRow("a & (b | c ^ d)") << QString("function() { a & (b | c ^ d); }") << QString("function () { a & (b | c ^ d); }");
3974 QTest::newRow("(a & b | c) ^ d") << QString("function() { (a & b | c) ^ d; }") << QString("function () { (a & b | c) ^ d; }");
3975 QTest::newRow("a << b + c") << QString("function() { a << b + c; }") << QString("function () { a << b + c; }");
3976 QTest::newRow("(a << b) + c") << QString("function() { (a << b) + c; }") << QString("function () { (a << b) + c; }");
3977 QTest::newRow("a >> b + c") << QString("function() { a >> b + c; }") << QString("function () { a >> b + c; }");
3978 QTest::newRow("(a >> b) + c") << QString("function() { (a >> b) + c; }") << QString("function () { (a >> b) + c; }");
3979 QTest::newRow("a >>> b + c") << QString("function() { a >>> b + c; }") << QString("function () { a >>> b + c; }");
3980 QTest::newRow("(a >>> b) + c") << QString("function() { (a >>> b) + c; }") << QString("function () { (a >>> b) + c; }");
3981 QTest::newRow("a == b || c != d") << QString("function() { a == b || c != d; }") << QString("function () { a == b || c != d; }");
3982 QTest::newRow("a == (b || c != d)") << QString("function() { a == (b || c != d); }") << QString("function () { a == (b || c != d); }");
3983 QTest::newRow("a === b || c !== d") << QString("function() { a === b || c !== d; }") << QString("function () { a === b || c !== d; }");
3984 QTest::newRow("a === (b || c !== d)") << QString("function() { a === (b || c !== d); }") << QString("function () { a === (b || c !== d); }");
3985 QTest::newRow("a &= b + c") << QString("function() { a &= b + c; }") << QString("function () { a &= b + c; }");
3986 QTest::newRow("debugger") << QString("function() { debugger; }") << QString("function () { debugger; }");
3989 void tst_QJSValue::prettyPrinter()
3991 QFETCH(QString, function);
3992 QFETCH(QString, expected);
3994 QJSValue val = eng.evaluate("(" + function + ")");
3995 QVERIFY(val.isCallable());
3996 QString actual = val.toString();
3997 int count = qMin(actual.size(), expected.size());
3998 // qDebug() << actual << expected;
3999 for (int i = 0; i < count; ++i) {
4000 // qDebug() << i << actual.at(i) << expected.at(i);
4001 QCOMPARE(actual.at(i), expected.at(i));
4003 QCOMPARE(actual.size(), expected.size());
4006 void tst_QJSValue::engineDeleted()
4008 QJSEngine *eng = new QJSEngine;
4009 QJSValue v1(eng, 123);
4010 QVERIFY(v1.isNumber());
4011 QJSValue v2(eng, QString("ciao"));
4012 QVERIFY(v2.isString());
4013 QJSValue v3 = eng->newObject();
4014 QVERIFY(v3.isObject());
4015 QJSValue v4 = eng->newQObject(this);
4016 QVERIFY(v4.isQObject());
4017 QJSValue v5 = "Hello";
4018 QVERIFY(v2.isString());
4022 QVERIFY(!v1.isValid());
4023 QVERIFY(v1.engine() == 0);
4024 QVERIFY(!v2.isValid());
4025 QVERIFY(v2.engine() == 0);
4026 QVERIFY(!v3.isValid());
4027 QVERIFY(v3.engine() == 0);
4028 QVERIFY(!v4.isValid());
4029 QVERIFY(v4.engine() == 0);
4030 QVERIFY(v5.isValid());
4031 QVERIFY(v5.engine() == 0);
4033 QVERIFY(!v3.property("foo").isValid());
4036 void tst_QJSValue::valueOfWithClosure()
4041 QJSValue obj = eng.evaluate("o = {}; (function(foo) { o.valueOf = function() { return foo; } })(123); o");
4042 QVERIFY(obj.isObject());
4043 QCOMPARE(obj.toInt(), 123);
4047 QJSValue obj = eng.evaluate("o = {}; (function(foo) { o.toString = function() { return foo; } })('ciao'); o");
4048 QVERIFY(obj.isObject());
4049 QCOMPARE(obj.toString(), QString::fromLatin1("ciao"));
4053 #if 0 // FIXME: no objectId()
4054 void tst_QJSValue::objectId()
4056 QCOMPARE(QJSValue().objectId(), (qint64)-1);
4057 QCOMPARE(QJSValue(QJSValue::UndefinedValue).objectId(), (qint64)-1);
4058 QCOMPARE(QJSValue(QJSValue::NullValue).objectId(), (qint64)-1);
4059 QCOMPARE(QJSValue(false).objectId(), (qint64)-1);
4060 QCOMPARE(QJSValue(123).objectId(), (qint64)-1);
4061 QCOMPARE(QJSValue(uint(123)).objectId(), (qint64)-1);
4062 QCOMPARE(QJSValue(123.5).objectId(), (qint64)-1);
4063 QCOMPARE(QJSValue("ciao").objectId(), (qint64)-1);
4066 QJSValue o1 = eng.newObject();
4067 QVERIFY(o1.objectId() != -1);
4068 QJSValue o2 = eng.newObject();
4069 QVERIFY(o2.objectId() != -1);
4070 QVERIFY(o1.objectId() != o2.objectId());
4072 QVERIFY(eng.objectById(o1.objectId()).strictlyEquals(o1));
4073 QVERIFY(eng.objectById(o2.objectId()).strictlyEquals(o2));
4075 qint64 globalObjectId = -1;
4077 QJSValue global = eng.globalObject();
4078 globalObjectId = global.objectId();
4079 QVERIFY(globalObjectId != -1);
4080 QVERIFY(eng.objectById(globalObjectId).strictlyEquals(global));
4082 QJSValue obj = eng.objectById(globalObjectId);
4083 QVERIFY(obj.isObject());
4084 QVERIFY(obj.strictlyEquals(eng.globalObject()));
4088 void tst_QJSValue::nestedObjectToVariant_data()
4090 QTest::addColumn<QString>("program");
4091 QTest::addColumn<QVariant>("expected");
4094 QTest::newRow("[[]]")
4095 << QString::fromLatin1("[[]]")
4096 << QVariant(QVariantList() << (QVariant(QVariantList())));
4097 QTest::newRow("[[123]]")
4098 << QString::fromLatin1("[[123]]")
4099 << QVariant(QVariantList() << (QVariant(QVariantList() << 123)));
4100 QTest::newRow("[[], 123]")
4101 << QString::fromLatin1("[[], 123]")
4102 << QVariant(QVariantList() << QVariant(QVariantList()) << 123);
4105 QTest::newRow("var a=[]; a.push(a)")
4106 << QString::fromLatin1("var a=[]; a.push(a); a")
4107 << QVariant(QVariantList() << QVariant(QVariantList()));
4108 QTest::newRow("var a=[]; a.push(123, a)")
4109 << QString::fromLatin1("var a=[]; a.push(123, a); a")
4110 << QVariant(QVariantList() << 123 << QVariant(QVariantList()));
4111 QTest::newRow("var a=[]; var b=[]; a.push(b); b.push(a)")
4112 << QString::fromLatin1("var a=[]; var b=[]; a.push(b); b.push(a); a")
4113 << QVariant(QVariantList() << QVariant(QVariantList() << QVariant(QVariantList())));
4114 QTest::newRow("var a=[]; var b=[]; a.push(123, b); b.push(456, a)")
4115 << QString::fromLatin1("var a=[]; var b=[]; a.push(123, b); b.push(456, a); a")
4116 << QVariant(QVariantList() << 123 << QVariant(QVariantList() << 456 << QVariant(QVariantList())));
4122 << QString::fromLatin1("({})")
4127 m["a"] = QVariantMap();
4128 QTest::newRow("{ a:{} }")
4129 << QString::fromLatin1("({ a:{} })")
4137 QTest::newRow("{ a:{b:10, c:20} }")
4138 << QString::fromLatin1("({ a:{b:10, c:20} })")
4144 m["b"] = QVariantList() << 20 << 30;
4145 QTest::newRow("{ a:10, b:[20, 30]}")
4146 << QString::fromLatin1("({ a:10, b:[20,30]})")
4153 m["p"] = QVariantMap();
4154 QTest::newRow("var o={}; o.p=o")
4155 << QString::fromLatin1("var o={}; o.p=o; o")
4161 m["q"] = QVariantMap();
4162 QTest::newRow("var o={}; o.p=123; o.q=o")
4163 << QString::fromLatin1("var o={}; o.p=123; o.q=o; o")
4168 void tst_QJSValue::nestedObjectToVariant()
4171 QFETCH(QString, program);
4172 QFETCH(QVariant, expected);
4173 QJSValue o = eng.evaluate(program);
4174 QVERIFY(!o.isError());
4175 QVERIFY(o.isObject());
4176 QCOMPARE(o.toVariant(), expected);
4179 void tst_QJSValue::propertyFlags_data()
4181 QTest::addColumn<QString>("program");
4182 QTest::addColumn<uint>("expected");
4184 QTest::newRow("nothing") << "" << 0u;
4185 #if 0 // FIXME: No getter/setter API
4186 QTest::newRow("getter") << "o.__defineGetter__('prop', function() { return 'blah' } );\n" << uint(QJSValue::PropertyGetter);
4187 QTest::newRow("setter") << "o.__defineSetter__('prop', function(a) { this.setted_prop2 = a; } );\n" << uint(QJSValue::PropertySetter);
4188 QTest::newRow("getterSetter") << "o.__defineGetter__('prop', function() { return 'ploup' } );\n"
4189 "o.__defineSetter__('prop', function(a) { this.setted_prop3 = a; } );\n" << uint(QJSValue::PropertySetter|QJSValue::PropertyGetter);
4191 QTest::newRow("nothing2") << "o.prop = 'nothing'" << 0u;
4194 void tst_QJSValue::propertyFlags()
4196 QFETCH(QString, program);
4197 QFETCH(uint, expected);
4199 eng.evaluate("o = new Object;");
4200 eng.evaluate(program);
4201 QJSValue o = eng.evaluate("o");
4203 QCOMPARE(uint(o.propertyFlags("prop")), expected);
4207 QTEST_MAIN(tst_QJSValue)