~saviq/ubuntu/saucy/qtdeclarative-opensource-src/add-qtquick-delegate-range

« back to all changes in this revision

Viewing changes to tests/auto/qml/v4/tst_v4.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 14:17:19 UTC
  • Revision ID: package-import@ubuntu.com-20130205141719-qqeyml8wslpyez52
Tags: upstream-5.0.1
ImportĀ upstreamĀ versionĀ 5.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the test suite of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
#include <qtest.h>
 
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>
 
49
#include <QtCore/qnumeric.h>
 
50
 
 
51
#include <private/qv4compiler_p.h>
 
52
 
 
53
#include "../../shared/util.h"
 
54
#include "testtypes.h"
 
55
 
 
56
class tst_v4 : public QQmlDataTest
 
57
{
 
58
    Q_OBJECT
 
59
public:
 
60
    tst_v4() {}
 
61
 
 
62
private slots:
 
63
    void initTestCase();
 
64
 
 
65
    void unnecessaryReeval();
 
66
    void logicalOr();
 
67
    void nestedLogicalOr();
 
68
    void logicalAnd();
 
69
    void nestedLogicalAnd();
 
70
    void conditionalExpr();
 
71
    void qtscript();
 
72
    void qtscript_data();
 
73
    void nestedObjectAccess();
 
74
    void subscriptionsInConditionalExpressions();
 
75
    void qtbug_21883();
 
76
    void qtbug_22816();
 
77
    void stringComparison();
 
78
    void unaryMinus();
 
79
    void unaryPlus();
 
80
    void colorType();
 
81
    void mathAbs();
 
82
    void mathCeil();
 
83
    void mathFloor();
 
84
    void mathMax();
 
85
    void mathMin();
 
86
    void mathCos();
 
87
    void mathSin();
 
88
    void singletonType();
 
89
    void integerOperations();
 
90
 
 
91
    void conversions_data();
 
92
    void conversions();
 
93
    void subscriptions();
 
94
 
 
95
    void debuggingDumpInstructions(); // this test should be last.
 
96
 
 
97
private:
 
98
    QQmlEngine engine;
 
99
};
 
100
 
 
101
void tst_v4::initTestCase()
 
102
{
 
103
    QQmlDataTest::initTestCase();
 
104
    registerTypes();
 
105
}
 
106
 
 
107
void tst_v4::qtscript()
 
108
{
 
109
    QFETCH(QString, file);
 
110
    QV4Compiler::enableBindingsTest(true);
 
111
 
 
112
    QQmlComponent component(&engine, testFileUrl(file));
 
113
 
 
114
    QQmlTestMessageHandler messageHandler;
 
115
 
 
116
    QObject *o = component.create();
 
117
    delete o;
 
118
 
 
119
    QEXPECT_FAIL("jsvalueHandling", "QTBUG-26951 - QJSValue has a different representation of NULL to QV8Engine", Continue);
 
120
    const int v4ErrorCount = messageHandler.messages().filter(QLatin1String("QV4")).size();
 
121
    QVERIFY2(v4ErrorCount == 0, qPrintable(messageHandler.messageString()));
 
122
 
 
123
    QV4Compiler::enableBindingsTest(false);
 
124
}
 
125
 
 
126
void tst_v4::qtscript_data()
 
127
{
 
128
    QTest::addColumn<QString>("file");
 
129
 
 
130
    QTest::newRow("equals") << "equals.qml";
 
131
    QTest::newRow("strict equals") << "strictEquals.qml";
 
132
    QTest::newRow("qreal -> int rounding") << "qrealToIntRounding.qml";
 
133
    QTest::newRow("exception on fetch") << "fetchException.qml";
 
134
    QTest::newRow("logical or") << "logicalOr.qml";
 
135
    QTest::newRow("conditional expressions") << "conditionalExpr.qml";
 
136
    QTest::newRow("double bool jump") << "doubleBoolJump.qml";
 
137
    QTest::newRow("unary minus") << "unaryMinus.qml";
 
138
    QTest::newRow("null qobject") << "nullQObject.qml";
 
139
    QTest::newRow("qobject -> bool") << "objectToBool.qml";
 
140
    QTest::newRow("conversion from bool") << "conversions.1.qml";
 
141
    QTest::newRow("conversion from int") << "conversions.2.qml";
 
142
    QTest::newRow("conversion from float") << "conversions.3.qml";
 
143
    QTest::newRow("conversion from double") << "conversions.4.qml";
 
144
    QTest::newRow("conversion from real") << "conversions.5.qml";
 
145
    QTest::newRow("conversion from string") << "conversions.6.qml";
 
146
    QTest::newRow("conversion from url") << "conversions.7.qml";
 
147
    QTest::newRow("conversion from vec3") << "conversions.8.qml";
 
148
    QTest::newRow("variantHandling") << "variantHandling.qml";
 
149
    QTest::newRow("varHandling") << "varHandling.qml";
 
150
    QTest::newRow("jsvalueHandling") << "jsvalueHandling.qml";
 
151
    QTest::newRow("integerOperations") << "integerOperations.qml";
 
152
}
 
153
 
 
154
void tst_v4::unnecessaryReeval()
 
155
{
 
156
    QQmlComponent component(&engine, testFileUrl("unnecessaryReeval.qml"));
 
157
 
 
158
    QObject *o = component.create();
 
159
    QVERIFY(o != 0);
 
160
 
 
161
    ResultObject *ro = qobject_cast<ResultObject *>(o);
 
162
    QVERIFY(ro != 0);
 
163
 
 
164
    QCOMPARE(ro->resultCounter(),  1);
 
165
    QCOMPARE(ro->result(), 19);
 
166
    ro->resetResultCounter();
 
167
 
 
168
    ro->setProperty("b", 6);
 
169
 
 
170
    QCOMPARE(ro->resultCounter(),  1);
 
171
    QCOMPARE(ro->result(), 6);
 
172
    ro->resetResultCounter();
 
173
 
 
174
    ro->setProperty("a", 14);
 
175
 
 
176
    QCOMPARE(ro->resultCounter(),  1);
 
177
    QCOMPARE(ro->result(), 7);
 
178
    ro->resetResultCounter();
 
179
 
 
180
    ro->setProperty("b", 14);
 
181
    QCOMPARE(ro->resultCounter(),  0);
 
182
    QCOMPARE(ro->result(), 7);
 
183
 
 
184
    delete o;
 
185
}
 
186
 
 
187
void tst_v4::logicalOr()
 
188
{
 
189
    {
 
190
        QQmlComponent component(&engine, testFileUrl("logicalOr.qml"));
 
191
 
 
192
        QObject *o = component.create();
 
193
        QVERIFY(o != 0);
 
194
 
 
195
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
196
        QVERIFY(ro != 0);
 
197
 
 
198
        QCOMPARE(ro->result(), 0);
 
199
        delete o;
 
200
    }
 
201
 
 
202
    {
 
203
        QQmlComponent component(&engine, testFileUrl("logicalOr.2.qml"));
 
204
 
 
205
        QObject *o = component.create();
 
206
        QVERIFY(o != 0);
 
207
 
 
208
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
209
        QVERIFY(ro != 0);
 
210
 
 
211
        QCOMPARE(ro->result(), 1);
 
212
        delete o;
 
213
    }
 
214
}
 
215
 
 
216
void tst_v4::nestedLogicalOr()
 
217
{
 
218
    //we are primarily testing that v4 does not get caught in a loop (QTBUG-24038)
 
219
    QQmlComponent component(&engine, testFileUrl("nestedLogicalOr.qml"));
 
220
 
 
221
    QObject *o = component.create();
 
222
    QVERIFY(o != 0);
 
223
 
 
224
    ResultObject *ro = qobject_cast<ResultObject *>(o);
 
225
    QVERIFY(ro != 0);
 
226
 
 
227
    QCOMPARE(ro->result(), 1);
 
228
    delete o;
 
229
}
 
230
 
 
231
void tst_v4::logicalAnd()
 
232
{
 
233
    {
 
234
        QQmlComponent component(&engine, testFileUrl("logicalAnd.qml"));
 
235
 
 
236
        QObject *o = component.create();
 
237
        QVERIFY(o != 0);
 
238
 
 
239
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
240
        QVERIFY(ro != 0);
 
241
 
 
242
        QCOMPARE(ro->result(), 0);
 
243
        delete o;
 
244
    }
 
245
 
 
246
    {
 
247
        QQmlComponent component(&engine, testFileUrl("logicalAnd.2.qml"));
 
248
 
 
249
        QObject *o = component.create();
 
250
        QVERIFY(o != 0);
 
251
 
 
252
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
253
        QVERIFY(ro != 0);
 
254
 
 
255
        QCOMPARE(ro->result(), 1);
 
256
        delete o;
 
257
    }
 
258
 
 
259
    {
 
260
        QQmlComponent component(&engine, testFileUrl("logicalAnd.3.qml"));
 
261
 
 
262
        QObject *o = component.create();
 
263
        QVERIFY(o != 0);
 
264
 
 
265
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
266
        QVERIFY(ro != 0);
 
267
 
 
268
        QCOMPARE(ro->result(), 1);
 
269
        delete o;
 
270
    }
 
271
 
 
272
    {
 
273
        // QTBUG-24660
 
274
        QQmlComponent component(&engine, testFileUrl("logicalAnd.4.qml"));
 
275
 
 
276
        QObject *o = component.create();
 
277
        QVERIFY(o != 0);
 
278
 
 
279
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
280
        QVERIFY(ro != 0);
 
281
 
 
282
        QCOMPARE(ro->result(), 1);
 
283
        delete o;
 
284
    }
 
285
 
 
286
    {
 
287
        QQmlComponent component(&engine, testFileUrl("logicalAnd.5.qml"));
 
288
 
 
289
        QObject *o = component.create();
 
290
        QVERIFY(o != 0);
 
291
 
 
292
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
293
        QVERIFY(ro != 0);
 
294
 
 
295
        QCOMPARE(ro->result(), 1);
 
296
        delete o;
 
297
    }
 
298
 
 
299
    {
 
300
        QQmlComponent component(&engine, testFileUrl("logicalAnd.6.qml"));
 
301
 
 
302
        QObject *o = component.create();
 
303
        QVERIFY(o != 0);
 
304
 
 
305
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
306
        QVERIFY(ro != 0);
 
307
 
 
308
        QCOMPARE(ro->result(), 1);
 
309
        delete o;
 
310
    }
 
311
 
 
312
    {
 
313
        QQmlComponent component(&engine, testFileUrl("logicalAnd.7.qml"));
 
314
 
 
315
        QObject *o = component.create();
 
316
        QVERIFY(o != 0);
 
317
 
 
318
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
319
        QVERIFY(ro != 0);
 
320
 
 
321
        QCOMPARE(ro->result(), 1);
 
322
        delete o;
 
323
    }
 
324
}
 
325
 
 
326
void tst_v4::nestedLogicalAnd()
 
327
{
 
328
    QQmlComponent component(&engine, testFileUrl("nestedLogicalAnd.qml"));
 
329
 
 
330
    QObject *o = component.create();
 
331
    QVERIFY(o != 0);
 
332
 
 
333
    ResultObject *ro = qobject_cast<ResultObject *>(o);
 
334
    QVERIFY(ro != 0);
 
335
 
 
336
    QCOMPARE(ro->result(), 1);
 
337
    delete o;
 
338
}
 
339
 
 
340
void tst_v4::conditionalExpr()
 
341
{
 
342
    {
 
343
        QQmlComponent component(&engine, testFileUrl("conditionalExpr.qml"));
 
344
 
 
345
        QObject *o = component.create();
 
346
        QVERIFY(o != 0);
 
347
 
 
348
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
349
        QVERIFY(ro != 0);
 
350
 
 
351
        QCOMPARE(ro->result(), 0);
 
352
        delete o;
 
353
    }
 
354
}
 
355
 
 
356
// This would previously use the metaObject of the root element to result the nested access.
 
357
// That is, the index for accessing "result" would have been RootObject::result, instead of
 
358
// NestedObject::result.
 
359
void tst_v4::nestedObjectAccess()
 
360
{
 
361
    {
 
362
        QQmlComponent component(&engine, testFileUrl("nestedObjectAccess.qml"));
 
363
 
 
364
        QObject *o = component.create();
 
365
        QVERIFY(o != 0);
 
366
 
 
367
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
368
        QVERIFY(ro != 0);
 
369
 
 
370
        QCOMPARE(ro->result(), 37);
 
371
 
 
372
        delete o;
 
373
    }
 
374
 
 
375
    {
 
376
        QQmlComponent component(&engine, testFileUrl("nestedObjectAccess2.qml"));
 
377
 
 
378
        QObject *o = component.create();
 
379
        QVERIFY(o != 0);
 
380
 
 
381
        ResultObject *ro = qobject_cast<ResultObject *>(o);
 
382
        QVERIFY(ro != 0);
 
383
 
 
384
        QCOMPARE(ro->result(), 37);
 
385
 
 
386
        delete o;
 
387
    }
 
388
}
 
389
 
 
390
void tst_v4::subscriptionsInConditionalExpressions()
 
391
{
 
392
    QQmlComponent component(&engine, testFileUrl("subscriptionsInConditionalExpressions.qml"));
 
393
 
 
394
    QObject *o = component.create();
 
395
    QVERIFY(o != 0);
 
396
 
 
397
    QObject *ro = qobject_cast<QObject *>(o);
 
398
    QVERIFY(ro != 0);
 
399
 
 
400
    QCOMPARE(ro->property("result").toReal(), qreal(2));
 
401
 
 
402
    delete o;
 
403
}
 
404
 
 
405
// Crash test
 
406
void tst_v4::qtbug_21883()
 
407
{
 
408
    QQmlComponent component(&engine, testFileUrl("qtbug_21883.qml"));
 
409
 
 
410
    QString warning = component.url().toString() + ":4: Unable to assign null to ResultObject*";
 
411
    QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
 
412
 
 
413
    QObject *o = component.create();
 
414
    QVERIFY(o != 0);
 
415
    delete o;
 
416
}
 
417
 
 
418
void tst_v4::qtbug_22816()
 
419
{
 
420
    QQmlComponent component(&engine, testFileUrl("qtbug_22816.qml"));
 
421
 
 
422
    QObject *o = component.create();
 
423
    QVERIFY(o != 0);
 
424
    QCOMPARE(o->property("test1").toBool(), false);
 
425
    QCOMPARE(o->property("test2").toBool(), false);
 
426
    delete o;
 
427
}
 
428
 
 
429
void tst_v4::stringComparison()
 
430
{
 
431
    QQmlComponent component(&engine, testFileUrl("stringComparison.qml"));
 
432
 
 
433
    QObject *o = component.create();
 
434
    QVERIFY(o != 0);
 
435
    QCOMPARE(o->property("test1").toBool(), true);
 
436
    QCOMPARE(o->property("test2").toBool(), true);
 
437
    QCOMPARE(o->property("test3").toBool(), true);
 
438
    QCOMPARE(o->property("test4").toBool(), true);
 
439
    QCOMPARE(o->property("test5").toBool(), true);
 
440
    QCOMPARE(o->property("test6").toBool(), true);
 
441
    QCOMPARE(o->property("test7").toBool(), true);
 
442
    QCOMPARE(o->property("test8").toBool(), true);
 
443
    QCOMPARE(o->property("test9").toBool(), true);
 
444
    QCOMPARE(o->property("test10").toBool(), true);
 
445
    QCOMPARE(o->property("test11").toBool(), true);
 
446
    QCOMPARE(o->property("test12").toBool(), true);
 
447
    QCOMPARE(o->property("test13").toBool(), true);
 
448
    QCOMPARE(o->property("test14").toBool(), true);
 
449
    QCOMPARE(o->property("test15").toBool(), true);
 
450
    QCOMPARE(o->property("test16").toBool(), true);
 
451
    QCOMPARE(o->property("test17").toBool(), true);
 
452
    QCOMPARE(o->property("test18").toBool(), true);
 
453
    QCOMPARE(o->property("test19").toBool(), true);
 
454
    QCOMPARE(o->property("test20").toBool(), true);
 
455
    QCOMPARE(o->property("test21").toBool(), true);
 
456
    QCOMPARE(o->property("test22").toBool(), true);
 
457
    delete o;
 
458
}
 
459
 
 
460
void tst_v4::unaryMinus()
 
461
{
 
462
    QQmlComponent component(&engine, testFileUrl("unaryMinus.qml"));
 
463
 
 
464
    QObject *o = component.create();
 
465
    QVERIFY(o != 0);
 
466
 
 
467
    QCOMPARE(o->property("test1").toReal(), qreal(-18));
 
468
    QCOMPARE(o->property("test2").toInt(), -18);
 
469
    QCOMPARE(o->property("test3").toReal(), qreal(3.7));
 
470
    QCOMPARE(o->property("test4").toInt(), 4);
 
471
    QCOMPARE(o->property("test5").toReal(), qreal(3.3));
 
472
    QCOMPARE(o->property("test6").toInt(), 3);
 
473
    QCOMPARE(o->property("test7").toReal(), qreal(7));
 
474
    QCOMPARE(o->property("test8").toInt(), 7);
 
475
    QCOMPARE(o->property("test9").toReal(), qreal(-4.4));
 
476
    QCOMPARE(o->property("test10").toInt(), -4);
 
477
 
 
478
    delete o;
 
479
}
 
480
 
 
481
void tst_v4::unaryPlus()
 
482
{
 
483
    QQmlComponent component(&engine, testFileUrl("unaryPlus.qml"));
 
484
 
 
485
    QObject *o = component.create();
 
486
    QVERIFY(o != 0);
 
487
 
 
488
    QCOMPARE(o->property("test1").toReal(), qreal(18));
 
489
    QCOMPARE(o->property("test2").toInt(), 18);
 
490
    QCOMPARE(o->property("test3").toReal(), qreal(-3.7));
 
491
    QCOMPARE(o->property("test4").toInt(), -4);
 
492
    QCOMPARE(o->property("test5").toReal(), qreal(-3.3));
 
493
    QCOMPARE(o->property("test6").toInt(), -3);
 
494
    QCOMPARE(o->property("test7").toReal(), qreal(-7));
 
495
    QCOMPARE(o->property("test8").toInt(), -7);
 
496
    QCOMPARE(o->property("test9").toReal(), qreal(4.4));
 
497
    QCOMPARE(o->property("test10").toInt(), 4);
 
498
 
 
499
    delete o;
 
500
}
 
501
 
 
502
void tst_v4::colorType()
 
503
{
 
504
    QQmlComponent component(&engine, testFileUrl("colorType.qml"));
 
505
 
 
506
    QObject *o = component.create();
 
507
    QVERIFY(o != 0);
 
508
    QCOMPARE(o->property("test1").value<QColor>(), QColor("red"));
 
509
    QCOMPARE(o->property("test2").value<QColor>(), QColor("red"));
 
510
    QCOMPARE(o->property("test3").value<QColor>(), QColor("red"));
 
511
    QCOMPARE(o->property("test4").toBool(), true);
 
512
    QCOMPARE(o->property("test5").toBool(), true);
 
513
    QCOMPARE(o->property("test6").toBool(), true);
 
514
    QCOMPARE(o->property("test7").toBool(), true);
 
515
    delete o;
 
516
}
 
517
 
 
518
void tst_v4::mathAbs()
 
519
{
 
520
    QQmlComponent component(&engine, testFileUrl("mathAbs.qml"));
 
521
 
 
522
    QObject *o = component.create();
 
523
    QVERIFY(o != 0);
 
524
 
 
525
    QCOMPARE(o->property("test1").toReal(), qreal(3.7));
 
526
    QCOMPARE(o->property("test2").toReal(), qreal(4.5));
 
527
    QCOMPARE(o->property("test3").toInt(), 18);
 
528
    QCOMPARE(o->property("test4").toInt(), 72);
 
529
    QCOMPARE(o->property("test5").toBool(), true);
 
530
    QCOMPARE(o->property("test6").toBool(), true);
 
531
    QCOMPARE(o->property("test7").toBool(), true);
 
532
    QCOMPARE(o->property("test8").toInt(), 82);
 
533
    QCOMPARE(o->property("test9").toBool(), true);
 
534
    QCOMPARE(o->property("test10").toBool(), true);
 
535
    QCOMPARE(o->property("test11").toInt(), 0);
 
536
    QCOMPARE(o->property("test12").toBool(), true);
 
537
 
 
538
    delete o;
 
539
}
 
540
 
 
541
void tst_v4::mathCeil()
 
542
{
 
543
    QQmlComponent component(&engine, testFileUrl("mathCeil.qml"));
 
544
 
 
545
    QObject *o = component.create();
 
546
    QVERIFY(o != 0);
 
547
 
 
548
    QCOMPARE(o->property("test1").toReal(), qreal(-3));
 
549
    QCOMPARE(o->property("test2").toReal(), qreal(5));
 
550
    QCOMPARE(o->property("test3").toBool(), true);
 
551
    QCOMPARE(o->property("test4").toBool(), true);
 
552
    QCOMPARE(o->property("test5").toBool(), true);
 
553
    QCOMPARE(o->property("test6").toReal(), qreal(83));
 
554
    QCOMPARE(o->property("test7").toBool(), true);
 
555
    QCOMPARE(o->property("test8").toBool(), true);
 
556
    QCOMPARE(o->property("test9").toInt(), 0);
 
557
    QCOMPARE(o->property("test10").toBool(), true);
 
558
    QCOMPARE(o->property("test11").toBool(), true);
 
559
 
 
560
    delete o;
 
561
}
 
562
 
 
563
void tst_v4::mathFloor()
 
564
{
 
565
    QQmlComponent component(&engine, testFileUrl("mathFloor.qml"));
 
566
 
 
567
    QObject *o = component.create();
 
568
    QVERIFY(o != 0);
 
569
 
 
570
    QCOMPARE(o->property("test1").toReal(), qreal(-4));
 
571
    QCOMPARE(o->property("test2").toReal(), qreal(4));
 
572
    QCOMPARE(o->property("test3").toBool(), true);
 
573
    QCOMPARE(o->property("test4").toBool(), true);
 
574
    QCOMPARE(o->property("test5").toBool(), true);
 
575
    QCOMPARE(o->property("test6").toReal(), qreal(82));
 
576
    QCOMPARE(o->property("test7").toBool(), true);
 
577
    QCOMPARE(o->property("test8").toBool(), true);
 
578
    QCOMPARE(o->property("test9").toInt(), 0);
 
579
    QCOMPARE(o->property("test10").toBool(), true);
 
580
 
 
581
    delete o;
 
582
}
 
583
 
 
584
void tst_v4::mathMax()
 
585
{
 
586
    QQmlComponent component(&engine, testFileUrl("mathMax.qml"));
 
587
 
 
588
    QObject *o = component.create();
 
589
    QVERIFY(o != 0);
 
590
 
 
591
    QCOMPARE(o->property("test1").toReal(), qreal(4.4));
 
592
    QCOMPARE(o->property("test2").toReal(), qreal(7));
 
593
    QCOMPARE(o->property("test3").toBool(), true);
 
594
    QCOMPARE(o->property("test4").toBool(), true);
 
595
    QCOMPARE(o->property("test5").toBool(), true);
 
596
    QCOMPARE(o->property("test6").toReal(), qreal(82.6));
 
597
    QCOMPARE(o->property("test7").toReal(), qreal(4.4));
 
598
    QCOMPARE(o->property("test8").toBool(), true);
 
599
    QCOMPARE(o->property("test9").toBool(), true);
 
600
    QCOMPARE(o->property("test10").toBool(), true);
 
601
    QCOMPARE(o->property("test11").toReal(), qreal(0));
 
602
    QCOMPARE(o->property("test12").toReal(), qreal(4.4));
 
603
    QCOMPARE(o->property("test13").toReal(), qreal(7));
 
604
 
 
605
    delete o;
 
606
}
 
607
 
 
608
void tst_v4::mathMin()
 
609
{
 
610
    QQmlComponent component(&engine, testFileUrl("mathMin.qml"));
 
611
 
 
612
    QObject *o = component.create();
 
613
    QVERIFY(o != 0);
 
614
 
 
615
    QCOMPARE(o->property("test1").toReal(), qreal(-3.7));
 
616
    QCOMPARE(o->property("test2").toReal(), qreal(4.4));
 
617
    QCOMPARE(o->property("test3").toBool(), true);
 
618
    QCOMPARE(o->property("test4").toBool(), true);
 
619
    QCOMPARE(o->property("test5").toBool(), true);
 
620
    QCOMPARE(o->property("test6").toReal(), qreal(82.6));
 
621
    QCOMPARE(o->property("test7").toBool(), true);
 
622
    QCOMPARE(o->property("test8").toReal(), qreal(4.4));
 
623
    QCOMPARE(o->property("test9").toBool(), true);
 
624
    QCOMPARE(o->property("test10").toBool(), true);
 
625
    QCOMPARE(o->property("test11").toReal(), qreal(-3.7));
 
626
    QCOMPARE(o->property("test12").toReal(), qreal(0));
 
627
    QCOMPARE(o->property("test13").toReal(), qreal(-3.7));
 
628
    delete o;
 
629
}
 
630
 
 
631
static bool fuzzyCompare(qreal a, qreal b)
 
632
{
 
633
    const qreal EPSILON = 0.0001;
 
634
    return (a + EPSILON > b) && (a - EPSILON < b);
 
635
}
 
636
 
 
637
void tst_v4::mathCos()
 
638
{
 
639
    QQmlComponent component(&engine, testFileUrl("mathCos.qml"));
 
640
 
 
641
    QObject *o = component.create();
 
642
    QVERIFY(o != 0);
 
643
 
 
644
    QVERIFY(fuzzyCompare(o->property("test1").toReal(), qreal(-0.848100)));
 
645
    QVERIFY(fuzzyCompare(o->property("test2").toReal(), qreal(-0.307333)));
 
646
    QCOMPARE(o->property("test3").toBool(), true);
 
647
    QCOMPARE(o->property("test4").toBool(), true);
 
648
    QCOMPARE(o->property("test5").toBool(), true);
 
649
    QVERIFY(fuzzyCompare(o->property("test6").toReal(), qreal(0.606941)));
 
650
    QCOMPARE(o->property("test7").toBool(), true);
 
651
    QCOMPARE(o->property("test8").toBool(), true);
 
652
    QCOMPARE(o->property("test9").toBool(), true);
 
653
    QCOMPARE(o->property("test10").toBool(), true);
 
654
    QVERIFY(fuzzyCompare(o->property("test11").toReal(), qreal(0.890792)));
 
655
 
 
656
    delete o;
 
657
}
 
658
 
 
659
void tst_v4::mathSin()
 
660
{
 
661
    QQmlComponent component(&engine, testFileUrl("mathSin.qml"));
 
662
 
 
663
    QObject *o = component.create();
 
664
    QVERIFY(o != 0);
 
665
 
 
666
    QVERIFY(fuzzyCompare(o->property("test1").toReal(), qreal(0.529836)));
 
667
    QVERIFY(fuzzyCompare(o->property("test2").toReal(), qreal(-0.951602)));
 
668
    QCOMPARE(o->property("test3").toBool(), true);
 
669
    QCOMPARE(o->property("test4").toBool(), true);
 
670
    QCOMPARE(o->property("test5").toBool(), true);
 
671
    QVERIFY(fuzzyCompare(o->property("test6").toReal(), qreal(0.794747)));
 
672
    QCOMPARE(o->property("test7").toBool(), true);
 
673
    QCOMPARE(o->property("test8").toBool(), true);
 
674
    QCOMPARE(o->property("test9").toBool(), true);
 
675
    QCOMPARE(o->property("test10").toBool(), true);
 
676
    QVERIFY(fuzzyCompare(o->property("test11").toReal(), qreal(0.454411)));
 
677
 
 
678
    delete o;
 
679
}
 
680
 
 
681
void tst_v4::integerOperations()
 
682
{
 
683
    QQmlComponent component(&engine, testFileUrl("integerOperations.qml"));
 
684
 
 
685
    QObject *o = component.create();
 
686
    QVERIFY(o != 0);
 
687
 
 
688
    QCOMPARE(o->property("testa1").toInt(), 333);
 
689
    QCOMPARE(o->property("testa2").toInt(), -666);
 
690
 
 
691
    QCOMPARE(o->property("testb1").toInt(), 0);
 
692
    QCOMPARE(o->property("testb2").toInt(), 2);
 
693
    QCOMPARE(o->property("testb3").toInt(), 0);
 
694
    QCOMPARE(o->property("testb4").toInt(), 2);
 
695
    QCOMPARE(o->property("testb5").toInt(), 0);
 
696
    QCOMPARE(o->property("testb6").toInt(), 2);
 
697
    QCOMPARE(o->property("testb7").toInt(), 0);
 
698
    QCOMPARE(o->property("testb8").toInt(), 2);
 
699
 
 
700
    QCOMPARE(o->property("testc1").toInt(), 335);
 
701
    QCOMPARE(o->property("testc2").toInt(), -666);
 
702
    QCOMPARE(o->property("testc3").toInt(), 335);
 
703
    QCOMPARE(o->property("testc4").toInt(), -666);
 
704
    QCOMPARE(o->property("testc5").toInt(), 335);
 
705
    QCOMPARE(o->property("testc6").toInt(), -666);
 
706
    QCOMPARE(o->property("testc7").toInt(), 335);
 
707
    QCOMPARE(o->property("testc8").toInt(), -666);
 
708
 
 
709
    QCOMPARE(o->property("testd1").toInt(), 330);
 
710
    QCOMPARE(o->property("testd2").toInt(), 330);
 
711
    QCOMPARE(o->property("testd3").toInt(), 330);
 
712
    QCOMPARE(o->property("testd4").toInt(), 330);
 
713
 
 
714
    QCOMPARE(o->property("teste1").toInt(), 28);
 
715
    QCOMPARE(o->property("teste2").toInt(), -28);
 
716
    QCOMPARE(o->property("teste3").toInt(), 256);
 
717
    QCOMPARE(o->property("teste4").toInt(), 28);
 
718
    QCOMPARE(o->property("teste5").toInt(), -28);
 
719
    QCOMPARE(o->property("teste6").toInt(), 256);
 
720
 
 
721
    QCOMPARE(o->property("testf1").toInt(), 1);
 
722
    QCOMPARE(o->property("testf2").toInt(), -2);
 
723
    QCOMPARE(o->property("testf3").toInt(), 0);
 
724
    QCOMPARE(o->property("testf4").toInt(), 1);
 
725
    QCOMPARE(o->property("testf5").toInt(), -2);
 
726
    QCOMPARE(o->property("testf6").toInt(), 0);
 
727
 
 
728
    QCOMPARE(o->property("testg1").toInt(), 1);
 
729
    QCOMPARE(o->property("testg2").toInt(), 0x3FFFFFFE);
 
730
    QCOMPARE(o->property("testg3").toInt(), 0);
 
731
    QCOMPARE(o->property("testg4").toInt(), 1);
 
732
    QCOMPARE(o->property("testg5").toInt(), 0x3FFFFFFE);
 
733
    QCOMPARE(o->property("testg6").toInt(), 0);
 
734
 
 
735
    delete o;
 
736
}
 
737
 
 
738
class V4SingletonType : public QObject
 
739
{
 
740
    Q_OBJECT
 
741
    Q_PROPERTY(int ip READ ip WRITE setIp NOTIFY ipChanged FINAL)
 
742
public:
 
743
    V4SingletonType() : m_ip(12) {}
 
744
    ~V4SingletonType() {}
 
745
 
 
746
    Q_INVOKABLE int random() { static int prng = 3; prng++; m_ip++; emit ipChanged(); return prng; }
 
747
 
 
748
    int ip() const { return m_ip; }
 
749
    void setIp(int v) { m_ip = v; emit ipChanged(); }
 
750
 
 
751
signals:
 
752
    void ipChanged();
 
753
 
 
754
private:
 
755
    int m_ip;
 
756
};
 
757
 
 
758
static QObject *v4_module_api_factory(QQmlEngine*, QJSEngine*)
 
759
{
 
760
    return new V4SingletonType;
 
761
}
 
762
 
 
763
void tst_v4::singletonType()
 
764
{
 
765
    // register singleton type, providing typeinfo via template
 
766
    qmlRegisterSingletonType<V4SingletonType>("Qt.test", 1, 0, "V4", v4_module_api_factory);
 
767
    QQmlComponent component(&engine, testFileUrl("singletonType.qml"));
 
768
    QObject *o = component.create();
 
769
    QVERIFY(o != 0);
 
770
    QCOMPARE(o->property("testProp").toInt(), 12);
 
771
    QCOMPARE(o->property("testProp2").toInt(), 2);
 
772
    QMetaObject::invokeMethod(o, "getRandom");
 
773
    QCOMPARE(o->property("testProp").toInt(), 13);
 
774
    QCOMPARE(o->property("testProp2").toInt(), 4);
 
775
    delete o;
 
776
}
 
777
 
 
778
void tst_v4::conversions_data()
 
779
{
 
780
    QTest::addColumn<QUrl>("file");
 
781
    QTest::addColumn<QStringList>("warnings");
 
782
    QTest::addColumn<bool>("boolProp");
 
783
    QTest::addColumn<int>("intProp");
 
784
    QTest::addColumn<float>("floatProp");
 
785
    QTest::addColumn<double>("doubleProp");
 
786
    QTest::addColumn<qreal>("qrealProp");
 
787
    QTest::addColumn<QString>("qstringProp");
 
788
    QTest::addColumn<QUrl>("qurlProp");
 
789
    QTest::addColumn<QVector3D>("vec3Prop");
 
790
 
 
791
    QTest::newRow("from bool") << testFileUrl("conversions.1.qml")
 
792
            << (QStringList() << (testFileUrl("conversions.1.qml").toString() + QLatin1String(":11:15: Unable to assign bool to QUrl")))
 
793
            << true
 
794
            << (int)true
 
795
            << (float)1.0
 
796
            << (double)1.0
 
797
            << (qreal)1.0
 
798
            << QString(QLatin1String("true"))
 
799
            << QUrl() // cannot assign bool to url.
 
800
            << QVector3D(1, 1, 1);
 
801
 
 
802
    QTest::newRow("from integer") << testFileUrl("conversions.2.qml")
 
803
            << (QStringList() << (testFileUrl("conversions.2.qml").toString() + QLatin1String(":11:15: Unable to assign int to QUrl")))
 
804
            << (bool)4
 
805
            << 4
 
806
            << (float)4.0
 
807
            << (double)4.0
 
808
            << (qreal)4.0
 
809
            << QString(QLatin1String("4"))
 
810
            << QUrl() // cannot assign int to url.
 
811
            << QVector3D(4, 4, 4);
 
812
 
 
813
    QTest::newRow("from float") << testFileUrl("conversions.3.qml")
 
814
            << (QStringList() << (testFileUrl("conversions.3.qml").toString() + QLatin1String(":11:15: Unable to assign number to QUrl")))
 
815
            << (bool)4.4
 
816
            << (int)4.4
 
817
            << (float)4.4
 
818
            << (double)((float)4.4)
 
819
            << (qreal)((float)4.4)
 
820
            << QString::number((double)((float)4.4), 'g', 16)
 
821
            << QUrl() // cannot assign number to url.
 
822
            << QVector3D(4.4, 4.4, 4.4);
 
823
 
 
824
    QTest::newRow("from double") << testFileUrl("conversions.4.qml")
 
825
            << (QStringList() << (testFileUrl("conversions.4.qml").toString() + QLatin1String(":11:15: Unable to assign number to QUrl")))
 
826
            << (bool)4.444444444
 
827
            << (int)4.444444444
 
828
            << (float)4.444444444
 
829
            << (double)4.444444444
 
830
            << (qreal)4.444444444
 
831
            << QString::number((double)4.444444444, 'g', 16)
 
832
            << QUrl() // cannot assign number to url.
 
833
            << QVector3D(4.444444444, 4.444444444, 4.444444444);
 
834
 
 
835
    QTest::newRow("from qreal") << testFileUrl("conversions.5.qml")
 
836
            << (QStringList() << (testFileUrl("conversions.5.qml").toString() + QLatin1String(":11:15: Unable to assign number to QUrl")))
 
837
            << (bool)4.44
 
838
            << (int)4.44
 
839
            << (float)4.44
 
840
            << (double)4.44
 
841
            << (qreal)4.44
 
842
            << QString(QLatin1String("4.44"))
 
843
            << QUrl() // cannot assign number to url.
 
844
            << QVector3D(4.44, 4.44, 4.44);
 
845
 
 
846
    QTest::newRow("from string") << testFileUrl("conversions.6.qml")
 
847
            << (QStringList())
 
848
            << true
 
849
            << 4
 
850
            << (float)4.0
 
851
            << (double)4.0
 
852
            << (qreal)4.0
 
853
            << QString(QLatin1String("4"))
 
854
            << QUrl(testFileUrl("").toString() + QString(QLatin1String("4")))
 
855
            << QVector3D(4, 4, 4);
 
856
 
 
857
    QTest::newRow("from url") << testFileUrl("conversions.7.qml")
 
858
            << (QStringList() << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":6:14: Unable to assign QUrl to int"))
 
859
                              << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":7:16: Unable to assign QUrl to number"))
 
860
                              << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":8:17: Unable to assign QUrl to number"))
 
861
                              << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":9:16: Unable to assign QUrl to number")))
 
862
            << true
 
863
            << 0
 
864
            << (float) 0
 
865
            << (double) 0
 
866
            << (qreal) 0
 
867
            << QString(testFileUrl("").toString() + QString(QLatin1String("4")))
 
868
            << QUrl(testFileUrl("").toString() + QString(QLatin1String("4")))
 
869
            << QVector3D(qQNaN(), qQNaN(), qQNaN());
 
870
 
 
871
    QTest::newRow("from vector") << testFileUrl("conversions.8.qml")
 
872
            << (QStringList() << (testFileUrl("conversions.8.qml").toString() + QLatin1String(":11: Unable to assign QVector3D to QUrl"))
 
873
                              << (testFileUrl("conversions.8.qml").toString() + QLatin1String(":10: Unable to assign QVector3D to QString"))
 
874
                              << (testFileUrl("conversions.8.qml").toString() + QLatin1String(":9: Unable to assign QVector3D to double"))
 
875
                              << (testFileUrl("conversions.8.qml").toString() + QLatin1String(":8: Unable to assign QVector3D to double"))
 
876
                              << (testFileUrl("conversions.8.qml").toString() + QLatin1String(":7: Unable to assign QVector3D to float"))
 
877
                              << (testFileUrl("conversions.8.qml").toString() + QLatin1String(":6: Unable to assign QVector3D to int")))
 
878
            << true                // non-null therefore true
 
879
            << (int)0              // the other values should be the default-ctor values.
 
880
            << (float)0
 
881
            << (double)0
 
882
            << (qreal)0
 
883
            << QString()
 
884
            << QUrl()
 
885
            << QVector3D(4, 4, 4); // except this one.
 
886
}
 
887
 
 
888
#define COMPARE_NUMBER(type, prop, expected) \
 
889
    if (qIsNaN(expected)) \
 
890
        QVERIFY(qIsNaN(qvariant_cast<type>(prop))); \
 
891
    else \
 
892
        QCOMPARE((prop), QVariant::fromValue<type>(expected));
 
893
 
 
894
void tst_v4::conversions()
 
895
{
 
896
    QFETCH(QUrl, file);
 
897
    QFETCH(QStringList, warnings);
 
898
    QFETCH(bool, boolProp);
 
899
    QFETCH(int, intProp);
 
900
    QFETCH(float, floatProp);
 
901
    QFETCH(double, doubleProp);
 
902
    QFETCH(qreal, qrealProp);
 
903
    QFETCH(QString, qstringProp);
 
904
    QFETCH(QUrl, qurlProp);
 
905
    QFETCH(QVector3D, vec3Prop);
 
906
 
 
907
    foreach (const QString &w, warnings)
 
908
        QTest::ignoreMessage(QtWarningMsg, qPrintable(w));
 
909
 
 
910
    QQmlComponent component(&engine, file);
 
911
    QObject *o = component.create();
 
912
    QVERIFY(o != 0);
 
913
    QCOMPARE(o->property("boolProp"), QVariant::fromValue<bool>(boolProp));
 
914
    QCOMPARE(o->property("intProp"), QVariant::fromValue<int>(intProp));
 
915
    COMPARE_NUMBER(float, o->property("floatProp"), floatProp);
 
916
    COMPARE_NUMBER(double, o->property("doubleProp"), doubleProp);
 
917
    COMPARE_NUMBER(qreal, o->property("qrealProp"), qrealProp);
 
918
    QCOMPARE(o->property("qstringProp"), QVariant::fromValue<QString>(qstringProp));
 
919
    QCOMPARE(o->property("qurlProp"), QVariant::fromValue<QUrl>(qurlProp));
 
920
 
 
921
    QVector3D vec3 = qvariant_cast<QVector3D>(o->property("vec3Prop"));
 
922
    COMPARE_NUMBER(qreal, QVariant::fromValue<qreal>(vec3.x()), vec3Prop.x());
 
923
    COMPARE_NUMBER(qreal, QVariant::fromValue<qreal>(vec3.y()), vec3Prop.y());
 
924
    COMPARE_NUMBER(qreal, QVariant::fromValue<qreal>(vec3.z()), vec3Prop.z());
 
925
    delete o;
 
926
}
 
927
 
 
928
void tst_v4::subscriptions()
 
929
{
 
930
    {
 
931
        QQmlComponent component(&engine, testFileUrl("subscriptions.1.qml"));
 
932
 
 
933
        QObject *o = component.create();
 
934
        QVERIFY(o != 0);
 
935
 
 
936
        QObject *ro = qobject_cast<QObject *>(o);
 
937
        QVERIFY(ro != 0);
 
938
 
 
939
        QCOMPARE(ro->property("targetHeight"), QVariant::fromValue<qreal>(201));
 
940
 
 
941
        delete o;
 
942
    }
 
943
}
 
944
 
 
945
static QByteArray getAddress(int address)
 
946
{
 
947
    return QByteArray::number(address);
 
948
}
 
949
 
 
950
static QByteArray getLeading(int address)
 
951
{
 
952
    QByteArray leading;
 
953
    if (address != -1) {
 
954
        leading = getAddress(address);
 
955
        leading.prepend(QByteArray(8 - leading.count(), ' '));
 
956
    }
 
957
    return leading;
 
958
}
 
959
 
 
960
#include <private/qv4instruction_p.h>
 
961
void tst_v4::debuggingDumpInstructions()
 
962
{
 
963
    QStringList expectedPreAddress;
 
964
    expectedPreAddress << "\t\tNoop";
 
965
    expectedPreAddress << "\t0:0:";
 
966
    expectedPreAddress << "\t\tSubscribeId\t\tId_Offset(0) -> Subscribe_Slot(0)";
 
967
    expectedPreAddress << "\t\tFetchAndSubscribe\tObject_Reg(0) Fast_Accessor(0x0) -> Output_Reg(0) Subscription_Slot(0)";
 
968
    expectedPreAddress << "\t\tLoadId\t\t\tId_Offset(0) -> Output_Reg(0)";
 
969
    expectedPreAddress << "\t\tLoadScope\t\t-> Output_Reg(0)";
 
970
    expectedPreAddress << "\t\tLoadRoot\t\t-> Output_Reg(0)";
 
971
    expectedPreAddress << "\t\tLoadSingletonObject\t\t) -> Output_Reg(0)";
 
972
    expectedPreAddress << "\t\tLoadAttached\t\tObject_Reg(0) Attached_Index(0) -> Output_Reg(0)";
 
973
    expectedPreAddress << "\t\tUnaryNot\t\tInput_Reg(0) -> Output_Reg(0)";
 
974
    expectedPreAddress << "\t\tUnaryMinusNumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
975
    expectedPreAddress << "\t\tUnaryMinusInt\t\tInput_Reg(0) -> Output_Reg(0)";
 
976
    expectedPreAddress << "\t\tUnaryPlusNumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
977
    expectedPreAddress << "\t\tUnaryPlusInt\t\tInput_Reg(0) -> Output_Reg(0)";
 
978
    expectedPreAddress << "\t\tConvertBoolToInt\tInput_Reg(0) -> Output_Reg(0)";
 
979
    expectedPreAddress << "\t\tConvertBoolToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
980
    expectedPreAddress << "\t\tConvertBoolToNumber\tInput_Reg(0) -> Output_Reg(0)";
 
981
    expectedPreAddress << "\t\tConvertBoolToString\tInput_Reg(0) -> Output_Reg(0)";
 
982
    expectedPreAddress << "\t\tConvertBoolToVariant\tInput_Reg(0) -> Output_Reg(0)";
 
983
    expectedPreAddress << "\t\tConvertBoolToVar\tInput_Reg(0) -> Output_Reg(0)";
 
984
    expectedPreAddress << "\t\tConvertIntToBool\tInput_Reg(0) -> Output_Reg(0)";
 
985
    expectedPreAddress << "\t\tConvertIntToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
986
    expectedPreAddress << "\t\tConvertIntToNumber\tInput_Reg(0) -> Output_Reg(0)";
 
987
    expectedPreAddress << "\t\tConvertIntToString\tInput_Reg(0) -> Output_Reg(0)";
 
988
    expectedPreAddress << "\t\tConvertIntToVariant\tInput_Reg(0) -> Output_Reg(0)";
 
989
    expectedPreAddress << "\t\tConvertIntToVar\tInput_Reg(0) -> Output_Reg(0)";
 
990
    expectedPreAddress << "\t\tConvertJSValueToVar\tInput_Reg(0) -> Output_Reg(0)";
 
991
    expectedPreAddress << "\t\tConvertNumberToBool\tInput_Reg(0) -> Output_Reg(0)";
 
992
    expectedPreAddress << "\t\tConvertNumberToInt\tInput_Reg(0) -> Output_Reg(0)";
 
993
    expectedPreAddress << "\t\tConvertNumberToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
994
    expectedPreAddress << "\t\tConvertNumberToString\tInput_Reg(0) -> Output_Reg(0)";
 
995
    expectedPreAddress << "\t\tConvertNumberToVariant\tInput_Reg(0) -> Output_Reg(0)";
 
996
    expectedPreAddress << "\t\tConvertNumberToVar\tInput_Reg(0) -> Output_Reg(0)";
 
997
    expectedPreAddress << "\t\tConvertStringToBool\tInput_Reg(0) -> Output_Reg(0)";
 
998
    expectedPreAddress << "\t\tConvertStringToInt\tInput_Reg(0) -> Output_Reg(0)";
 
999
    expectedPreAddress << "\t\tConvertStringToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
1000
    expectedPreAddress << "\t\tConvertStringToNumber\tInput_Reg(0) -> Output_Reg(0)";
 
1001
    expectedPreAddress << "\t\tConvertStringToUrl\tInput_Reg(0) -> Output_Reg(0)";
 
1002
    expectedPreAddress << "\t\tConvertStringToColor\tInput_Reg(0) -> Output_Reg(0)";
 
1003
    expectedPreAddress << "\t\tConvertStringToVariant\tInput_Reg(0) -> Output_Reg(0)";
 
1004
    expectedPreAddress << "\t\tConvertStringToVar\tInput_Reg(0) -> Output_Reg(0)";
 
1005
    expectedPreAddress << "\t\tConvertUrlToBool\tInput_Reg(0) -> Output_Reg(0)";
 
1006
    expectedPreAddress << "\t\tConvertUrlToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
1007
    expectedPreAddress << "\t\tConvertUrlToString\tInput_Reg(0) -> Output_Reg(0)";
 
1008
    expectedPreAddress << "\t\tConvertUrlToVariant\tInput_Reg(0) -> Output_Reg(0)";
 
1009
    expectedPreAddress << "\t\tConvertUrlToVar\tInput_Reg(0) -> Output_Reg(0)";
 
1010
    expectedPreAddress << "\t\tConvertColorToBool\tInput_Reg(0) -> Output_Reg(0)";
 
1011
    expectedPreAddress << "\t\tConvertColorToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
1012
    expectedPreAddress << "\t\tConvertColorToString\tInput_Reg(0) -> Output_Reg(0)";
 
1013
    expectedPreAddress << "\t\tConvertColorToVariant\tInput_Reg(0) -> Output_Reg(0)";
 
1014
    expectedPreAddress << "\t\tConvertColorToVar\tInput_Reg(0) -> Output_Reg(0)";
 
1015
    expectedPreAddress << "\t\tConvertObjectToBool\tInput_Reg(0) -> Output_Reg(0)";
 
1016
    expectedPreAddress << "\t\tConvertObjectToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
1017
    expectedPreAddress << "\t\tConvertObjectToVariant\tInput_Reg(0) -> Output_Reg(0)";
 
1018
    expectedPreAddress << "\t\tConvertObjectToVar\tInput_Reg(0) -> Output_Reg(0)";
 
1019
    expectedPreAddress << "\t\tConvertVarToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
1020
    expectedPreAddress << "\t\tConvertNullToJSValue\tInput_Reg(0) -> Output_Reg(0)";
 
1021
    expectedPreAddress << "\t\tConvertNullToObject\tInput_Reg(0) -> Output_Reg(0)";
 
1022
    expectedPreAddress << "\t\tConvertNullToVariant\tInput_Reg(0) -> Output_Reg(0)";
 
1023
    expectedPreAddress << "\t\tConvertNullToVar\tInput_Reg(0) -> Output_Reg(0)";
 
1024
    expectedPreAddress << "\t\tResolveUrl\t\tInput_Reg(0) -> Output_Reg(0)";
 
1025
    expectedPreAddress << "\t\tMathSinNumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
1026
    expectedPreAddress << "\t\tMathCosNumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
1027
    expectedPreAddress << "\t\tMathAbsNumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
1028
    expectedPreAddress << "\t\tMathRoundNumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
1029
    expectedPreAddress << "\t\tMathFloorNumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
1030
    expectedPreAddress << "\t\tMathCeilNumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
1031
    expectedPreAddress << "\t\tMathPINumber\t\tInput_Reg(0) -> Output_Reg(0)";
 
1032
    expectedPreAddress << "\t\tLoadNull\t\tConstant(null) -> Output_Reg(0)";
 
1033
    expectedPreAddress << "\t\tLoadNumber\t\tConstant(0) -> Output_Reg(0)";
 
1034
    expectedPreAddress << "\t\tLoadInt\t\t\tConstant(0) -> Output_Reg(0)";
 
1035
    expectedPreAddress << "\t\tLoadBool\t\tConstant(false) -> Output_Reg(0)";
 
1036
    expectedPreAddress << "\t\tLoadString\t\tString_DataIndex(0) String_Length(0) -> Output_Register(0)";
 
1037
    expectedPreAddress << "\t\tEnableV4Test\t\tString_DataIndex(0) String_Length(0)";
 
1038
    expectedPreAddress << "\t\tTestV4Store\t\tInput_Reg(0) Reg_Type(0)";
 
1039
    expectedPreAddress << "\t\tBitAndInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1040
    expectedPreAddress << "\t\tBitOrInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1041
    expectedPreAddress << "\t\tBitXorInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1042
    expectedPreAddress << "\t\tAddNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1043
    expectedPreAddress << "\t\tAddString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1044
    expectedPreAddress << "\t\tSubNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1045
    expectedPreAddress << "\t\tMulNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1046
    expectedPreAddress << "\t\tDivNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1047
    expectedPreAddress << "\t\tModNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1048
    expectedPreAddress << "\t\tLShiftInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1049
    expectedPreAddress << "\t\tRShiftInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1050
    expectedPreAddress << "\t\tURShiftInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1051
    expectedPreAddress << "\t\tGtNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1052
    expectedPreAddress << "\t\tLtNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1053
    expectedPreAddress << "\t\tGeNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1054
    expectedPreAddress << "\t\tLeNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1055
    expectedPreAddress << "\t\tEqualNumber\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1056
    expectedPreAddress << "\t\tNotEqualNumber\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1057
    expectedPreAddress << "\t\tStrictEqualNumber\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1058
    expectedPreAddress << "\t\tStrictNotEqualNumber\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1059
    expectedPreAddress << "\t\tGtString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1060
    expectedPreAddress << "\t\tLtString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1061
    expectedPreAddress << "\t\tGeString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1062
    expectedPreAddress << "\t\tLeString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1063
    expectedPreAddress << "\t\tEqualString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1064
    expectedPreAddress << "\t\tNotEqualString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1065
    expectedPreAddress << "\t\tStrictEqualString\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1066
    expectedPreAddress << "\t\tStrictNotEqualString\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1067
    expectedPreAddress << "\t\tEqualObject\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1068
    expectedPreAddress << "\t\tNotEqualObject\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1069
    expectedPreAddress << "\t\tStrictEqualObject\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1070
    expectedPreAddress << "\t\tStrictNotEqualObject\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1071
    expectedPreAddress << "\t\tMathMaxNumber\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1072
    expectedPreAddress << "\t\tMathMinNumber\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)";
 
1073
    expectedPreAddress << "\t\tNewString\t\tRegister(0)";
 
1074
    expectedPreAddress << "\t\tNewUrl\t\t\tRegister(0)";
 
1075
    expectedPreAddress << "\t\tCleanupRegister\t\tRegister(0)";
 
1076
    expectedPreAddress << "\t\tCopy\t\t\tInput_Reg(0) -> Output_Reg(0)";
 
1077
    expectedPreAddress << "\t\tFetch\t\t\tObject_Reg(0) Property_Index(0) -> Output_Reg(0)";
 
1078
    expectedPreAddress << "\t\tStore\t\t\tInput_Reg(0) -> Object_Reg(0) Property_Index(0)";
 
1079
    expectedPreAddress << "\t\tJump\t\t\tAddress(UNIT_TEST_JUMP_ADDRESS) [if false == Input_Reg(0)]";         //(address + size() + i->jump.count)
 
1080
    expectedPreAddress << "\t\tBranchTrue\t\tAddress(UNIT_TEST_BRANCH_ADDRESS) [if true == Input_Reg(0)]";    //(address + size() + i->branchop.offset)
 
1081
    expectedPreAddress << "\t\tBranchFalse\t\tAddress(UNIT_TEST_BRANCH_ADDRESS) [if false == Input_Reg(0)]";  //(address + size() + i->branchop.offset)
 
1082
    expectedPreAddress << "\t\tBranch\t\t\tAddress(UNIT_TEST_BRANCH_ADDRESS)";                                //(address + size() + i->branchop.offset)
 
1083
    expectedPreAddress << "\t\tBlock\t\t\tMask(0)";
 
1084
    expectedPreAddress << "\t\tThrow\t\t\tInputReg(0)";
 
1085
    expectedPreAddress << "\t\tInitString\t\tString_DataIndex(0) -> String_Slot(0)";
 
1086
    QStringList expected;
 
1087
 
 
1088
    QQmlTestMessageHandler messageHandler;
 
1089
 
 
1090
    QQmlJS::Bytecode bc;
 
1091
#define DUMP_INSTR_IN_UNIT_TEST(I, FMT) { QQmlJS::V4InstrData<QQmlJS::V4Instr::I> i; memset(&i, 0, sizeof(i)); bc.append(i); }
 
1092
    FOR_EACH_V4_INSTR(DUMP_INSTR_IN_UNIT_TEST);
 
1093
#undef DUMP_INSTR_IN_UNIT_TEST // NOTE: we memset in order to ensure stable output.
 
1094
    const char *start = bc.constData();
 
1095
    const char *end = start + bc.size();
 
1096
    const char *codeAddr = start;
 
1097
    int whichExpected = 0;
 
1098
#define DUMP_INSTR_SIZE_IN_UNIT_TEST(I, FMT) {                              \
 
1099
            QString currExpected = whichExpected < expectedPreAddress.size() ? expectedPreAddress.at(whichExpected++) : QString();  \
 
1100
            currExpected.prepend(getLeading(codeAddr - start));             \
 
1101
            expected.append(currExpected);                                  \
 
1102
            codeAddr += QQmlJS::V4Instr::size(static_cast<QQmlJS::V4Instr::Type>(QQmlJS::V4Instr::I)); \
 
1103
        }
 
1104
    FOR_EACH_V4_INSTR(DUMP_INSTR_SIZE_IN_UNIT_TEST);
 
1105
#undef DUMP_INSTR_SIZE_IN_UNIT_TEST // so that we generate the correct address for each instruction comparison
 
1106
    bc.dump(start, end);
 
1107
 
 
1108
    // ensure that the output was expected.
 
1109
    const int messageCount = messageHandler.messages().count();
 
1110
    QCOMPARE(messageCount, expected.count());
 
1111
    for (int ii = 0; ii < messageCount; ++ii) {
 
1112
        // Calculating the destination address of a null jump/branch instruction is tricky
 
1113
        // so instead we simply don't compare that part of those instructions.
 
1114
        QRegExp ignoreAddress("\\bAddress\\((\\w*)\\)");
 
1115
        ignoreAddress.setMinimal(true);
 
1116
        QString expectOut = expected.at(ii); expectOut.replace(ignoreAddress, "");
 
1117
        QString actualOut = messageHandler.messages().at(ii); actualOut.replace(ignoreAddress, "");
 
1118
        QCOMPARE(actualOut, expectOut);
 
1119
    }
 
1120
}
 
1121
 
 
1122
 
 
1123
QTEST_MAIN(tst_v4)
 
1124
 
 
1125
#include "tst_v4.moc"