1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtCore/qobject.h>
43 #include <QtCore/qfileinfo.h>
44 #include <QtCore/qdir.h>
45 #include <QtQml/qqmlengine.h>
46 #include <QtQml/qqmlcomponent.h>
47 #include <QtCore/qdebug.h>
48 #include <QtGui/qcolor.h>
50 #include <private/qv4compiler_p.h>
52 #include "../../shared/util.h"
53 #include "testtypes.h"
55 class tst_v4 : public QQmlDataTest
64 void unnecessaryReeval();
66 void nestedLogicalOr();
68 void nestedLogicalAnd();
69 void conditionalExpr();
72 void nestedObjectAccess();
73 void subscriptionsInConditionalExpressions();
76 void stringComparison();
89 void tst_v4::initTestCase()
91 QQmlDataTest::initTestCase();
95 static int v4ErrorsMsgCount = 0;
96 static void v4ErrorsMsgHandler(QtMsgType, const char *message)
98 QByteArray m(message);
99 if (m.contains("QV4"))
103 void tst_v4::qtscript()
105 QFETCH(QString, file);
106 QV4Compiler::enableBindingsTest(true);
108 QQmlComponent component(&engine, testFileUrl(file));
110 v4ErrorsMsgCount = 0;
111 QtMsgHandler old = qInstallMsgHandler(v4ErrorsMsgHandler);
113 QObject *o = component.create();
116 qInstallMsgHandler(old);
118 QCOMPARE(v4ErrorsMsgCount, 0);
120 QV4Compiler::enableBindingsTest(false);
123 void tst_v4::qtscript_data()
125 QTest::addColumn<QString>("file");
127 QTest::newRow("equals") << "equals.qml";
128 QTest::newRow("strict equals") << "strictEquals.qml";
129 QTest::newRow("qreal -> int rounding") << "qrealToIntRounding.qml";
130 QTest::newRow("exception on fetch") << "fetchException.qml";
131 QTest::newRow("logical or") << "logicalOr.qml";
132 QTest::newRow("conditional expressions") << "conditionalExpr.qml";
133 QTest::newRow("double bool jump") << "doubleBoolJump.qml";
134 QTest::newRow("unary minus") << "unaryMinus.qml";
135 QTest::newRow("null qobject") << "nullQObject.qml";
138 void tst_v4::unnecessaryReeval()
140 QQmlComponent component(&engine, testFileUrl("unnecessaryReeval.qml"));
142 QObject *o = component.create();
145 ResultObject *ro = qobject_cast<ResultObject *>(o);
148 QCOMPARE(ro->resultCounter(), 1);
149 QCOMPARE(ro->result(), 19);
150 ro->resetResultCounter();
152 ro->setProperty("b", 6);
154 QCOMPARE(ro->resultCounter(), 1);
155 QCOMPARE(ro->result(), 6);
156 ro->resetResultCounter();
158 ro->setProperty("a", 14);
160 QCOMPARE(ro->resultCounter(), 1);
161 QCOMPARE(ro->result(), 7);
162 ro->resetResultCounter();
164 ro->setProperty("b", 14);
165 QCOMPARE(ro->resultCounter(), 0);
166 QCOMPARE(ro->result(), 7);
171 void tst_v4::logicalOr()
174 QQmlComponent component(&engine, testFileUrl("logicalOr.qml"));
176 QObject *o = component.create();
179 ResultObject *ro = qobject_cast<ResultObject *>(o);
182 QCOMPARE(ro->result(), 0);
187 QQmlComponent component(&engine, testFileUrl("logicalOr.2.qml"));
189 QObject *o = component.create();
192 ResultObject *ro = qobject_cast<ResultObject *>(o);
195 QCOMPARE(ro->result(), 1);
200 void tst_v4::nestedLogicalOr()
202 //we are primarily testing that v4 does not get caught in a loop (QTBUG-24038)
203 QQmlComponent component(&engine, testFileUrl("nestedLogicalOr.qml"));
205 QObject *o = component.create();
208 ResultObject *ro = qobject_cast<ResultObject *>(o);
211 QCOMPARE(ro->result(), 1);
215 void tst_v4::logicalAnd()
218 QQmlComponent component(&engine, testFileUrl("logicalAnd.qml"));
220 QObject *o = component.create();
223 ResultObject *ro = qobject_cast<ResultObject *>(o);
226 QCOMPARE(ro->result(), 0);
231 QQmlComponent component(&engine, testFileUrl("logicalAnd.2.qml"));
233 QObject *o = component.create();
236 ResultObject *ro = qobject_cast<ResultObject *>(o);
239 QCOMPARE(ro->result(), 1);
244 QQmlComponent component(&engine, testFileUrl("logicalAnd.3.qml"));
246 QObject *o = component.create();
249 ResultObject *ro = qobject_cast<ResultObject *>(o);
252 QCOMPARE(ro->result(), 1);
258 QQmlComponent component(&engine, testFileUrl("logicalAnd.4.qml"));
260 QObject *o = component.create();
263 ResultObject *ro = qobject_cast<ResultObject *>(o);
266 QCOMPARE(ro->result(), 1);
271 QQmlComponent component(&engine, testFileUrl("logicalAnd.5.qml"));
273 QObject *o = component.create();
276 ResultObject *ro = qobject_cast<ResultObject *>(o);
279 QCOMPARE(ro->result(), 1);
284 QQmlComponent component(&engine, testFileUrl("logicalAnd.6.qml"));
286 QObject *o = component.create();
289 ResultObject *ro = qobject_cast<ResultObject *>(o);
292 QCOMPARE(ro->result(), 1);
297 QQmlComponent component(&engine, testFileUrl("logicalAnd.7.qml"));
299 QObject *o = component.create();
302 ResultObject *ro = qobject_cast<ResultObject *>(o);
305 QCOMPARE(ro->result(), 1);
310 void tst_v4::nestedLogicalAnd()
312 QQmlComponent component(&engine, testFileUrl("nestedLogicalAnd.qml"));
314 QObject *o = component.create();
317 ResultObject *ro = qobject_cast<ResultObject *>(o);
320 QCOMPARE(ro->result(), 1);
324 void tst_v4::conditionalExpr()
327 QQmlComponent component(&engine, testFileUrl("conditionalExpr.qml"));
329 QObject *o = component.create();
332 ResultObject *ro = qobject_cast<ResultObject *>(o);
335 QCOMPARE(ro->result(), 0);
340 // This would previously use the metaObject of the root element to result the nested access.
341 // That is, the index for accessing "result" would have been RootObject::result, instead of
342 // NestedObject::result.
343 void tst_v4::nestedObjectAccess()
346 QQmlComponent component(&engine, testFileUrl("nestedObjectAccess.qml"));
348 QObject *o = component.create();
351 ResultObject *ro = qobject_cast<ResultObject *>(o);
354 QCOMPARE(ro->result(), 37);
360 QQmlComponent component(&engine, testFileUrl("nestedObjectAccess2.qml"));
362 QObject *o = component.create();
365 ResultObject *ro = qobject_cast<ResultObject *>(o);
368 QCOMPARE(ro->result(), 37);
374 void tst_v4::subscriptionsInConditionalExpressions()
376 QQmlComponent component(&engine, testFileUrl("subscriptionsInConditionalExpressions.qml"));
378 QObject *o = component.create();
381 QObject *ro = qobject_cast<QObject *>(o);
384 QCOMPARE(ro->property("result").toReal(), qreal(2));
390 void tst_v4::qtbug_21883()
392 QQmlComponent component(&engine, testFileUrl("qtbug_21883.qml"));
394 QString warning = component.url().toString() + ":4: Unable to assign null to ResultObject*";
395 QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
397 QObject *o = component.create();
402 void tst_v4::qtbug_22816()
404 QQmlComponent component(&engine, testFileUrl("qtbug_22816.qml"));
406 QObject *o = component.create();
408 QCOMPARE(o->property("test1").toBool(), false);
409 QCOMPARE(o->property("test2").toBool(), false);
413 void tst_v4::stringComparison()
415 QQmlComponent component(&engine, testFileUrl("stringComparison.qml"));
417 QObject *o = component.create();
419 QCOMPARE(o->property("test1").toBool(), true);
420 QCOMPARE(o->property("test2").toBool(), true);
421 QCOMPARE(o->property("test3").toBool(), true);
422 QCOMPARE(o->property("test4").toBool(), true);
423 QCOMPARE(o->property("test5").toBool(), true);
424 QCOMPARE(o->property("test6").toBool(), true);
425 QCOMPARE(o->property("test7").toBool(), true);
426 QCOMPARE(o->property("test8").toBool(), true);
427 QCOMPARE(o->property("test9").toBool(), true);
428 QCOMPARE(o->property("test10").toBool(), true);
429 QCOMPARE(o->property("test11").toBool(), true);
430 QCOMPARE(o->property("test12").toBool(), true);
431 QCOMPARE(o->property("test13").toBool(), true);
432 QCOMPARE(o->property("test14").toBool(), true);
433 QCOMPARE(o->property("test15").toBool(), true);
434 QCOMPARE(o->property("test16").toBool(), true);
435 QCOMPARE(o->property("test17").toBool(), true);
436 QCOMPARE(o->property("test18").toBool(), true);
437 QCOMPARE(o->property("test19").toBool(), true);
438 QCOMPARE(o->property("test20").toBool(), true);
439 QCOMPARE(o->property("test21").toBool(), true);
440 QCOMPARE(o->property("test22").toBool(), true);
444 void tst_v4::unaryMinus()
446 QQmlComponent component(&engine, testFileUrl("unaryMinus.qml"));
448 QObject *o = component.create();
451 QCOMPARE(o->property("test1").toReal(), qreal(-18));
452 QCOMPARE(o->property("test2").toInt(), -18);
453 QCOMPARE(o->property("test3").toReal(), qreal(3.7));
454 QCOMPARE(o->property("test4").toInt(), 4);
455 QCOMPARE(o->property("test5").toReal(), qreal(3.3));
456 QCOMPARE(o->property("test6").toInt(), 3);
457 QCOMPARE(o->property("test7").toReal(), qreal(7));
458 QCOMPARE(o->property("test8").toInt(), 7);
459 QCOMPARE(o->property("test9").toReal(), qreal(-4.4));
460 QCOMPARE(o->property("test10").toInt(), -4);
465 void tst_v4::unaryPlus()
467 QQmlComponent component(&engine, testFileUrl("unaryPlus.qml"));
469 QObject *o = component.create();
472 QCOMPARE(o->property("test1").toReal(), qreal(18));
473 QCOMPARE(o->property("test2").toInt(), 18);
474 QCOMPARE(o->property("test3").toReal(), qreal(-3.7));
475 QCOMPARE(o->property("test4").toInt(), -4);
476 QCOMPARE(o->property("test5").toReal(), qreal(-3.3));
477 QCOMPARE(o->property("test6").toInt(), -3);
478 QCOMPARE(o->property("test7").toReal(), qreal(-7));
479 QCOMPARE(o->property("test8").toInt(), -7);
480 QCOMPARE(o->property("test9").toReal(), qreal(4.4));
481 QCOMPARE(o->property("test10").toInt(), 4);
486 void tst_v4::colorType()
488 QQmlComponent component(&engine, testFileUrl("colorType.qml"));
490 QObject *o = component.create();
492 QCOMPARE(o->property("test1").value<QColor>(), QColor("red"));
493 QCOMPARE(o->property("test2").value<QColor>(), QColor("red"));
494 QCOMPARE(o->property("test3").value<QColor>(), QColor("red"));
495 QCOMPARE(o->property("test4").toBool(), true);
496 QCOMPARE(o->property("test5").toBool(), true);
497 QCOMPARE(o->property("test6").toBool(), true);
498 QCOMPARE(o->property("test7").toBool(), true);
502 void tst_v4::mathAbs()
504 QQmlComponent component(&engine, testFileUrl("mathAbs.qml"));
506 QObject *o = component.create();
509 QCOMPARE(o->property("test1").toReal(), qreal(3.7));
510 QCOMPARE(o->property("test2").toReal(), qreal(4.5));
511 QCOMPARE(o->property("test3").toInt(), 18);
512 QCOMPARE(o->property("test4").toInt(), 72);
513 QCOMPARE(o->property("test5").toBool(), true);
514 QCOMPARE(o->property("test6").toBool(), true);
515 QCOMPARE(o->property("test7").toBool(), true);
516 QCOMPARE(o->property("test8").toInt(), 82);
517 QCOMPARE(o->property("test9").toBool(), true);
518 QCOMPARE(o->property("test10").toBool(), true);
519 QCOMPARE(o->property("test11").toInt(), 0);
520 //QCOMPARE(o->property("test12").toBool(), true); //QTBUG-24706
525 void tst_v4::mathCeil()
527 QQmlComponent component(&engine, testFileUrl("mathCeil.qml"));
529 QObject *o = component.create();
532 QCOMPARE(o->property("test1").toReal(), qreal(-3));
533 QCOMPARE(o->property("test2").toReal(), qreal(5));
534 QCOMPARE(o->property("test3").toBool(), true);
535 //QCOMPARE(o->property("test4").toBool(), true); //QTBUG-24706
536 QCOMPARE(o->property("test5").toBool(), true);
537 QCOMPARE(o->property("test6").toReal(), qreal(83));
538 //QCOMPARE(o->property("test7").toBool(), true); //QTBUG-24706
539 //QCOMPARE(o->property("test8").toBool(), true); //QTBUG-24706
540 QCOMPARE(o->property("test9").toInt(), 0);
541 //QCOMPARE(o->property("test10").toBool(), true); //QTBUG-24706
546 void tst_v4::mathMax()
548 QQmlComponent component(&engine, testFileUrl("mathMax.qml"));
550 QObject *o = component.create();
553 QCOMPARE(o->property("test1").toReal(), qreal(4.4));
554 QCOMPARE(o->property("test2").toReal(), qreal(7));
555 QCOMPARE(o->property("test3").toBool(), true);
556 QCOMPARE(o->property("test4").toBool(), true);
557 QCOMPARE(o->property("test5").toBool(), true);
558 QCOMPARE(o->property("test6").toReal(), qreal(82.6));
559 QCOMPARE(o->property("test7").toReal(), qreal(4.4));
560 QCOMPARE(o->property("test8").toBool(), true);
561 //QCOMPARE(o->property("test9").toBool(), true); //QTBUG-24706
562 QCOMPARE(o->property("test10").toReal(), qreal(0));
563 QCOMPARE(o->property("test11").toReal(), qreal(4.4));
564 QCOMPARE(o->property("test12").toReal(), qreal(7));
569 void tst_v4::mathMin()
571 QQmlComponent component(&engine, testFileUrl("mathMin.qml"));
573 QObject *o = component.create();
576 QCOMPARE(o->property("test1").toReal(), qreal(-3.7));
577 QCOMPARE(o->property("test2").toReal(), qreal(4.4));
578 QCOMPARE(o->property("test3").toBool(), true);
579 QCOMPARE(o->property("test4").toBool(), true);
580 QCOMPARE(o->property("test5").toBool(), true);
581 QCOMPARE(o->property("test6").toReal(), qreal(82.6));
582 QCOMPARE(o->property("test7").toBool(), true);
583 QCOMPARE(o->property("test8").toReal(), qreal(4.4));
584 //QCOMPARE(o->property("test9").toBool(), true); //QTBUG-24706
585 QCOMPARE(o->property("test10").toReal(), qreal(-3.7));
586 QCOMPARE(o->property("test11").toReal(), qreal(0));
587 QCOMPARE(o->property("test12").toReal(), qreal(-3.7));
593 #include "tst_v4.moc"