Initial import from the monolithic Qt.
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qdeclarativevaluetypes / tst_qdeclarativevaluetypes.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <qtest.h>
43 #include <QDeclarativeEngine>
44 #include <QDeclarativeComponent>
45 #include <QDebug>
46 #include <private/qdeclarativevaluetype_p.h>
47 #include "testtypes.h"
48
49 #ifdef Q_OS_SYMBIAN
50 // In Symbian OS test data is located in applications private dir
51 #define SRCDIR "."
52 #endif
53
54 QT_BEGIN_NAMESPACE
55 extern int qt_defaultDpi();
56 QT_END_NAMESPACE
57
58 class tst_qdeclarativevaluetypes : public QObject
59 {
60     Q_OBJECT
61 public:
62     tst_qdeclarativevaluetypes() {}
63
64 private slots:
65     void initTestCase();
66
67     void point();
68     void pointf();
69     void size();
70     void sizef();
71     void sizereadonly();
72     void rect();
73     void rectf();
74     void vector2d();
75     void vector3d();
76     void vector4d();
77     void quaternion();
78     void matrix4x4();
79     void font();
80     void variant();
81
82     void bindingAssignment();
83     void bindingRead();
84     void staticAssignment();
85     void scriptAccess();
86     void autoBindingRemoval();
87     void valueSources();
88     void valueInterceptors();
89     void bindingConflict();
90     void deletedObject();
91     void bindingVariantCopy();
92     void scriptVariantCopy();
93     void cppClasses();
94     void enums();
95     void conflictingBindings();
96     void returnValues();
97     void varAssignment();
98     void bindingsSpliceCorrectly();
99
100 private:
101     QDeclarativeEngine engine;
102 };
103
104 void tst_qdeclarativevaluetypes::initTestCase()
105 {
106     registerTypes();
107 }
108
109 inline QUrl TEST_FILE(const QString &filename)
110 {
111     return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
112 }
113
114 void tst_qdeclarativevaluetypes::point()
115 {
116     {
117         QDeclarativeComponent component(&engine, TEST_FILE("point_read.qml"));
118         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
119         QVERIFY(object != 0);
120
121         QCOMPARE(object->property("p_x").toInt(), 10);
122         QCOMPARE(object->property("p_y").toInt(), 4);
123         QCOMPARE(object->property("copy"), QVariant(QPoint(10, 4)));
124
125         delete object;
126     }
127
128     {
129         QDeclarativeComponent component(&engine, TEST_FILE("point_write.qml"));
130         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
131         QVERIFY(object != 0);
132
133         QCOMPARE(object->point(), QPoint(11, 12));
134
135         delete object;
136     }
137 }
138
139 void tst_qdeclarativevaluetypes::pointf()
140 {
141     {
142         QDeclarativeComponent component(&engine, TEST_FILE("pointf_read.qml"));
143         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
144         QVERIFY(object != 0);
145
146         QCOMPARE(float(object->property("p_x").toDouble()), float(11.3));
147         QCOMPARE(float(object->property("p_y").toDouble()), float(-10.9));
148         QCOMPARE(object->property("copy"), QVariant(QPointF(11.3, -10.9)));
149
150         delete object;
151     }
152
153     {
154         QDeclarativeComponent component(&engine, TEST_FILE("pointf_write.qml"));
155         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
156         QVERIFY(object != 0);
157
158         QCOMPARE(object->pointf(), QPointF(6.8, 9.3));
159
160         delete object;
161     }
162 }
163
164 void tst_qdeclarativevaluetypes::size()
165 {
166     {
167         QDeclarativeComponent component(&engine, TEST_FILE("size_read.qml"));
168         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
169         QVERIFY(object != 0);
170
171         QCOMPARE(object->property("s_width").toInt(), 1912);
172         QCOMPARE(object->property("s_height").toInt(), 1913);
173         QCOMPARE(object->property("copy"), QVariant(QSize(1912, 1913)));
174
175         delete object;
176     }
177
178     {
179         QDeclarativeComponent component(&engine, TEST_FILE("size_write.qml"));
180         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
181         QVERIFY(object != 0);
182
183         QCOMPARE(object->size(), QSize(13, 88));
184
185         delete object;
186     }
187 }
188
189 void tst_qdeclarativevaluetypes::sizef()
190 {
191     {
192         QDeclarativeComponent component(&engine, TEST_FILE("sizef_read.qml"));
193         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
194         QVERIFY(object != 0);
195
196         QCOMPARE(float(object->property("s_width").toDouble()), float(0.1));
197         QCOMPARE(float(object->property("s_height").toDouble()), float(100923.2));
198         QCOMPARE(object->property("copy"), QVariant(QSizeF(0.1, 100923.2)));
199
200         delete object;
201     }
202
203     {
204         QDeclarativeComponent component(&engine, TEST_FILE("sizef_write.qml"));
205         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
206         QVERIFY(object != 0);
207
208         QCOMPARE(object->sizef(), QSizeF(44.3, 92.8));
209
210         delete object;
211     }
212 }
213
214 void tst_qdeclarativevaluetypes::variant()
215 {
216     QDeclarativeComponent component(&engine, TEST_FILE("variant_read.qml"));
217     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
218     QVERIFY(object != 0);
219
220     QCOMPARE(float(object->property("s_width").toDouble()), float(0.1));
221     QCOMPARE(float(object->property("s_height").toDouble()), float(100923.2));
222     QCOMPARE(object->property("copy"), QVariant(QSizeF(0.1, 100923.2)));
223
224     delete object;
225 }
226
227 void tst_qdeclarativevaluetypes::sizereadonly()
228 {
229     {
230         QDeclarativeComponent component(&engine, TEST_FILE("sizereadonly_read.qml"));
231         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
232         QVERIFY(object != 0);
233
234         QCOMPARE(object->property("s_width").toInt(), 1912);
235         QCOMPARE(object->property("s_height").toInt(), 1913);
236         QCOMPARE(object->property("copy"), QVariant(QSize(1912, 1913)));
237
238         delete object;
239     }
240
241     {
242         QDeclarativeComponent component(&engine, TEST_FILE("sizereadonly_writeerror.qml"));
243         QVERIFY(component.isError());
244         QCOMPARE(component.errors().at(0).description(), QLatin1String("Invalid property assignment: \"sizereadonly\" is a read-only property"));
245     }
246
247     {
248         QDeclarativeComponent component(&engine, TEST_FILE("sizereadonly_writeerror2.qml"));
249         QVERIFY(component.isError());
250         QCOMPARE(component.errors().at(0).description(), QLatin1String("Invalid property assignment: \"sizereadonly\" is a read-only property"));
251     }
252
253     {
254         QDeclarativeComponent component(&engine, TEST_FILE("sizereadonly_writeerror3.qml"));
255         QVERIFY(component.isError());
256         QCOMPARE(component.errors().at(0).description(), QLatin1String("Invalid property assignment: \"sizereadonly\" is a read-only property"));
257     }
258
259     {
260         QDeclarativeComponent component(&engine, TEST_FILE("sizereadonly_writeerror4.qml"));
261
262         QObject *object = component.create();
263         QVERIFY(object);
264
265         QCOMPARE(object->property("sizereadonly").toSize(), QSize(1912, 1913));
266
267         delete object;
268     }
269 }
270
271 void tst_qdeclarativevaluetypes::rect()
272 {
273     {
274         QDeclarativeComponent component(&engine, TEST_FILE("rect_read.qml"));
275         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
276         QVERIFY(object != 0);
277
278         QCOMPARE(object->property("r_x").toInt(), 2);
279         QCOMPARE(object->property("r_y").toInt(), 3);
280         QCOMPARE(object->property("r_width").toInt(), 109);
281         QCOMPARE(object->property("r_height").toInt(), 102);
282         QCOMPARE(object->property("copy"), QVariant(QRect(2, 3, 109, 102)));
283
284         delete object;
285     }
286
287     {
288         QDeclarativeComponent component(&engine, TEST_FILE("rect_write.qml"));
289         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
290         QVERIFY(object != 0);
291
292         QCOMPARE(object->rect(), QRect(1234, 7, 56, 63));
293
294         delete object;
295     }
296 }
297
298 void tst_qdeclarativevaluetypes::rectf()
299 {
300     {
301         QDeclarativeComponent component(&engine, TEST_FILE("rectf_read.qml"));
302         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
303         QVERIFY(object != 0);
304
305         QCOMPARE(float(object->property("r_x").toDouble()), float(103.8));
306         QCOMPARE(float(object->property("r_y").toDouble()), float(99.2));
307         QCOMPARE(float(object->property("r_width").toDouble()), float(88.1));
308         QCOMPARE(float(object->property("r_height").toDouble()), float(77.6));
309         QCOMPARE(object->property("copy"), QVariant(QRectF(103.8, 99.2, 88.1, 77.6)));
310
311         delete object;
312     }
313
314     {
315         QDeclarativeComponent component(&engine, TEST_FILE("rectf_write.qml"));
316         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
317         QVERIFY(object != 0);
318
319         QCOMPARE(object->rectf(), QRectF(70.1, -113.2, 80924.8, 99.2));
320
321         delete object;
322     }
323 }
324
325 void tst_qdeclarativevaluetypes::vector2d()
326 {
327     {
328         QDeclarativeComponent component(&engine, TEST_FILE("vector2d_read.qml"));
329         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
330         QVERIFY(object != 0);
331
332         QCOMPARE((float)object->property("v_x").toDouble(), (float)32.88);
333         QCOMPARE((float)object->property("v_y").toDouble(), (float)1.3);
334         QCOMPARE(object->property("copy"), QVariant(QVector2D(32.88, 1.3)));
335
336         delete object;
337     }
338
339     {
340         QDeclarativeComponent component(&engine, TEST_FILE("vector2d_write.qml"));
341         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
342         QVERIFY(object != 0);
343
344         QCOMPARE(object->vector2(), QVector2D(-0.3, -12.9));
345
346         delete object;
347     }
348 }
349
350 void tst_qdeclarativevaluetypes::vector3d()
351 {
352     {
353         QDeclarativeComponent component(&engine, TEST_FILE("vector3d_read.qml"));
354         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
355         QVERIFY(object != 0);
356
357         QCOMPARE((float)object->property("v_x").toDouble(), (float)23.88);
358         QCOMPARE((float)object->property("v_y").toDouble(), (float)3.1);
359         QCOMPARE((float)object->property("v_z").toDouble(), (float)4.3);
360         QCOMPARE(object->property("copy"), QVariant(QVector3D(23.88, 3.1, 4.3)));
361
362         delete object;
363     }
364
365     {
366         QDeclarativeComponent component(&engine, TEST_FILE("vector3d_write.qml"));
367         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
368         QVERIFY(object != 0);
369
370         QCOMPARE(object->vector(), QVector3D(-0.3, -12.9, 907.4));
371
372         delete object;
373     }
374 }
375
376 void tst_qdeclarativevaluetypes::vector4d()
377 {
378     {
379         QDeclarativeComponent component(&engine, TEST_FILE("vector4d_read.qml"));
380         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
381         QVERIFY(object != 0);
382
383         QCOMPARE((float)object->property("v_x").toDouble(), (float)54.2);
384         QCOMPARE((float)object->property("v_y").toDouble(), (float)23.88);
385         QCOMPARE((float)object->property("v_z").toDouble(), (float)3.1);
386         QCOMPARE((float)object->property("v_w").toDouble(), (float)4.3);
387         QCOMPARE(object->property("copy"), QVariant(QVector4D(54.2, 23.88, 3.1, 4.3)));
388
389         delete object;
390     }
391
392     {
393         QDeclarativeComponent component(&engine, TEST_FILE("vector4d_write.qml"));
394         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
395         QVERIFY(object != 0);
396
397         QCOMPARE(object->vector4(), QVector4D(-0.3, -12.9, 907.4, 88.5));
398
399         delete object;
400     }
401 }
402
403 void tst_qdeclarativevaluetypes::quaternion()
404 {
405     {
406         QDeclarativeComponent component(&engine, TEST_FILE("quaternion_read.qml"));
407         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
408         QVERIFY(object != 0);
409
410         QCOMPARE((float)object->property("v_scalar").toDouble(), (float)4.3);
411         QCOMPARE((float)object->property("v_x").toDouble(), (float)54.2);
412         QCOMPARE((float)object->property("v_y").toDouble(), (float)23.88);
413         QCOMPARE((float)object->property("v_z").toDouble(), (float)3.1);
414         QCOMPARE(object->property("copy"), QVariant(QQuaternion(4.3, 54.2, 23.88, 3.1)));
415
416         delete object;
417     }
418
419     {
420         QDeclarativeComponent component(&engine, TEST_FILE("quaternion_write.qml"));
421         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
422         QVERIFY(object != 0);
423
424         QCOMPARE(object->quaternion(), QQuaternion(88.5, -0.3, -12.9, 907.4));
425
426         delete object;
427     }
428 }
429
430 void tst_qdeclarativevaluetypes::matrix4x4()
431 {
432     {
433         QDeclarativeComponent component(&engine, TEST_FILE("matrix4x4_read.qml"));
434         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
435         QVERIFY(object != 0);
436
437         QCOMPARE((float)object->property("v_m11").toDouble(), (float)1);
438         QCOMPARE((float)object->property("v_m12").toDouble(), (float)2);
439         QCOMPARE((float)object->property("v_m13").toDouble(), (float)3);
440         QCOMPARE((float)object->property("v_m14").toDouble(), (float)4);
441         QCOMPARE((float)object->property("v_m21").toDouble(), (float)5);
442         QCOMPARE((float)object->property("v_m22").toDouble(), (float)6);
443         QCOMPARE((float)object->property("v_m23").toDouble(), (float)7);
444         QCOMPARE((float)object->property("v_m24").toDouble(), (float)8);
445         QCOMPARE((float)object->property("v_m31").toDouble(), (float)9);
446         QCOMPARE((float)object->property("v_m32").toDouble(), (float)10);
447         QCOMPARE((float)object->property("v_m33").toDouble(), (float)11);
448         QCOMPARE((float)object->property("v_m34").toDouble(), (float)12);
449         QCOMPARE((float)object->property("v_m41").toDouble(), (float)13);
450         QCOMPARE((float)object->property("v_m42").toDouble(), (float)14);
451         QCOMPARE((float)object->property("v_m43").toDouble(), (float)15);
452         QCOMPARE((float)object->property("v_m44").toDouble(), (float)16);
453         QCOMPARE(object->property("copy"),
454                  QVariant(QMatrix4x4(1, 2, 3, 4,
455                                      5, 6, 7, 8,
456                                      9, 10, 11, 12,
457                                      13, 14, 15, 16)));
458
459         delete object;
460     }
461
462     {
463         QDeclarativeComponent component(&engine, TEST_FILE("matrix4x4_write.qml"));
464         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
465         QVERIFY(object != 0);
466
467         QCOMPARE(object->matrix(), QMatrix4x4(11, 12, 13, 14,
468                                               21, 22, 23, 24,
469                                               31, 32, 33, 34,
470                                               41, 42, 43, 44));
471
472         delete object;
473     }
474 }
475
476 void tst_qdeclarativevaluetypes::font()
477 {
478     {
479         QDeclarativeComponent component(&engine, TEST_FILE("font_read.qml"));
480         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
481         QVERIFY(object != 0);
482
483         QCOMPARE(object->property("f_family").toString(), object->font().family());
484         QCOMPARE(object->property("f_bold").toBool(), object->font().bold());
485         QCOMPARE(object->property("f_weight").toInt(), object->font().weight());
486         QCOMPARE(object->property("f_italic").toBool(), object->font().italic());
487         QCOMPARE(object->property("f_underline").toBool(), object->font().underline());
488         QCOMPARE(object->property("f_overline").toBool(), object->font().overline());
489         QCOMPARE(object->property("f_strikeout").toBool(), object->font().strikeOut());
490         QCOMPARE(object->property("f_pointSize").toDouble(), object->font().pointSizeF());
491         QCOMPARE(object->property("f_pixelSize").toInt(), int((object->font().pointSizeF() * qt_defaultDpi()) / qreal(72.)));
492         QCOMPARE(object->property("f_capitalization").toInt(), (int)object->font().capitalization());
493         QCOMPARE(object->property("f_letterSpacing").toDouble(), object->font().letterSpacing());
494         QCOMPARE(object->property("f_wordSpacing").toDouble(), object->font().wordSpacing());
495
496         QCOMPARE(object->property("copy"), QVariant(object->font()));
497
498         delete object;
499     }
500
501     {
502         QDeclarativeComponent component(&engine, TEST_FILE("font_write.qml"));
503         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
504         QVERIFY(object != 0);
505
506         QFont font;
507         font.setFamily("Helvetica");
508         font.setBold(false);
509         font.setWeight(QFont::Normal);
510         font.setItalic(false);
511         font.setUnderline(false);
512         font.setStrikeOut(false);
513         font.setPointSize(15);
514         font.setCapitalization(QFont::AllLowercase);
515         font.setLetterSpacing(QFont::AbsoluteSpacing, 9.7);
516         font.setWordSpacing(11.2);
517
518         QFont f = object->font();
519         QCOMPARE(f.family(), font.family());
520         QCOMPARE(f.bold(), font.bold());
521         QCOMPARE(f.weight(), font.weight());
522         QCOMPARE(f.italic(), font.italic());
523         QCOMPARE(f.underline(), font.underline());
524         QCOMPARE(f.strikeOut(), font.strikeOut());
525         QCOMPARE(f.pointSize(), font.pointSize());
526         QCOMPARE(f.capitalization(), font.capitalization());
527         QCOMPARE(f.letterSpacing(), font.letterSpacing());
528         QCOMPARE(f.wordSpacing(), font.wordSpacing());
529
530         delete object;
531     }
532
533     // Test pixelSize
534     {
535         QDeclarativeComponent component(&engine, TEST_FILE("font_write.2.qml"));
536         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
537         QVERIFY(object != 0);
538
539         QCOMPARE(object->font().pixelSize(), 10);
540
541         delete object;
542     }
543
544     // Test pixelSize and pointSize
545     {
546         QDeclarativeComponent component(&engine, TEST_FILE("font_write.3.qml"));
547         QTest::ignoreMessage(QtWarningMsg, "Both point size and pixel size set. Using pixel size. ");
548         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
549         QVERIFY(object != 0);
550
551         QCOMPARE(object->font().pixelSize(), 10);
552
553         delete object;
554     }
555     {
556         QDeclarativeComponent component(&engine, TEST_FILE("font_write.4.qml"));
557         QTest::ignoreMessage(QtWarningMsg, "Both point size and pixel size set. Using pixel size. ");
558         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
559         QVERIFY(object != 0);
560
561         QCOMPARE(object->font().pixelSize(), 10);
562
563         delete object;
564     }
565     {
566         QDeclarativeComponent component(&engine, TEST_FILE("font_write.5.qml"));
567         QObject *object = qobject_cast<QObject *>(component.create());
568         QVERIFY(object != 0);
569         MyTypeObject *object1 = object->findChild<MyTypeObject *>("object1");
570         QVERIFY(object1 != 0);
571         MyTypeObject *object2 = object->findChild<MyTypeObject *>("object2");
572         QVERIFY(object2 != 0);
573
574         QCOMPARE(object1->font().pixelSize(), 19);
575         QCOMPARE(object2->font().pointSize(), 14);
576
577         delete object;
578     }
579 }
580
581 // Test bindings can write to value types
582 void tst_qdeclarativevaluetypes::bindingAssignment()
583 {
584     QDeclarativeComponent component(&engine, TEST_FILE("bindingAssignment.qml"));
585     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
586     QVERIFY(object != 0);
587
588     QCOMPARE(object->rect().x(), 10);
589
590     object->setProperty("value", QVariant(92));
591
592     QCOMPARE(object->rect().x(), 92);
593
594     delete object;
595 }
596
597 // Test bindings can read from value types
598 void tst_qdeclarativevaluetypes::bindingRead()
599 {
600     QDeclarativeComponent component(&engine, TEST_FILE("bindingRead.qml"));
601     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
602     QVERIFY(object != 0);
603
604     QCOMPARE(object->property("value").toInt(), 2);
605
606     object->setRect(QRect(19, 3, 88, 2));
607
608     QCOMPARE(object->property("value").toInt(), 19);
609
610     delete object;
611 }
612
613 // Test static values can assign to value types
614 void tst_qdeclarativevaluetypes::staticAssignment()
615 {
616     QDeclarativeComponent component(&engine, TEST_FILE("staticAssignment.qml"));
617     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
618     QVERIFY(object != 0);
619
620     QCOMPARE(object->rect().x(), 9);
621
622     delete object;
623 }
624
625 // Test scripts can read/write value types
626 void tst_qdeclarativevaluetypes::scriptAccess()
627 {
628     QDeclarativeComponent component(&engine, TEST_FILE("scriptAccess.qml"));
629     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
630     QVERIFY(object != 0);
631
632     QCOMPARE(object->property("valuePre").toInt(), 2);
633     QCOMPARE(object->rect().x(), 19);
634     QCOMPARE(object->property("valuePost").toInt(), 19);
635
636     delete object;
637 }
638
639 // Test that assigning a constant from script removes any binding
640 void tst_qdeclarativevaluetypes::autoBindingRemoval()
641 {
642     {
643         QDeclarativeComponent component(&engine, TEST_FILE("autoBindingRemoval.qml"));
644         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
645         QVERIFY(object != 0);
646
647         QCOMPARE(object->rect().x(), 10);
648
649         object->setProperty("value", QVariant(13));
650
651         QCOMPARE(object->rect().x(), 13);
652
653         object->emitRunScript();
654
655         QCOMPARE(object->rect().x(), 42);
656
657         object->setProperty("value", QVariant(92));
658
659         QCOMPARE(object->rect().x(), 42);
660
661         delete object;
662     }
663
664     /*
665     {
666         QDeclarativeComponent component(&engine, TEST_FILE("autoBindingRemoval.2.qml"));
667         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
668         QVERIFY(object != 0);
669
670         QCOMPARE(object->rect().x(), 10);
671
672         object->setProperty("value", QVariant(13));
673
674         QCOMPARE(object->rect().x(), 13);
675
676         object->emitRunScript();
677
678         QCOMPARE(object->rect(), QRect(10, 10, 10, 10));
679
680         object->setProperty("value", QVariant(92));
681
682         QCOMPARE(object->rect(), QRect(10, 10, 10, 10));
683
684         delete object;
685     }
686
687     {
688         QDeclarativeComponent component(&engine, TEST_FILE("autoBindingRemoval.3.qml"));
689         MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
690         QVERIFY(object != 0);
691
692         object->setProperty("value", QVariant(QRect(9, 22, 33, 44)));
693
694         QCOMPARE(object->rect(), QRect(9, 22, 33, 44));
695
696         object->emitRunScript();
697
698         QCOMPARE(object->rect(), QRect(44, 22, 33, 44));
699
700         object->setProperty("value", QVariant(QRect(19, 3, 4, 8)));
701
702         QCOMPARE(object->rect(), QRect(44, 22, 33, 44));
703
704         delete object;
705     }
706 */
707 }
708
709 // Test that property value sources assign to value types
710 void tst_qdeclarativevaluetypes::valueSources()
711 {
712     QDeclarativeComponent component(&engine, TEST_FILE("valueSources.qml"));
713     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
714     QVERIFY(object != 0);
715
716     QCOMPARE(object->rect().x(), 3345);
717
718     delete object;
719 }
720
721 static void checkNoErrors(QDeclarativeComponent& component)
722 {
723     QList<QDeclarativeError> errors = component.errors();
724     if (errors.isEmpty())
725         return;
726     for (int ii = 0; ii < errors.count(); ++ii) {
727         const QDeclarativeError &error = errors.at(ii);
728         qWarning("%d:%d:%s",error.line(),error.column(),error.description().toUtf8().constData());
729     }
730 }
731
732 // Test that property value interceptors can be applied to value types
733 void tst_qdeclarativevaluetypes::valueInterceptors()
734 {
735     QDeclarativeComponent component(&engine, TEST_FILE("valueInterceptors.qml"));
736     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
737     checkNoErrors(component);
738     QVERIFY(object != 0);
739
740     QCOMPARE(object->rect().x(), 13);
741
742     object->setProperty("value", 99);
743
744     QCOMPARE(object->rect().x(), 112);
745
746     delete object;
747 }
748
749 // Test that you can't assign a binding to the "root" value type, and a sub-property
750 void tst_qdeclarativevaluetypes::bindingConflict()
751 {
752     QDeclarativeComponent component(&engine, TEST_FILE("bindingConflict.qml"));
753     QCOMPARE(component.isError(), true);
754 }
755
756 #define CPP_TEST(type, v) \
757 { \
758     type *t = new type; \
759     QVariant value(v); \
760     t->setValue(value); \
761     QCOMPARE(t->value(), value); \
762     delete t; \
763 }
764
765 // Test that accessing a reference to a valuetype after the owning object is deleted
766 // doesn't crash
767 void tst_qdeclarativevaluetypes::deletedObject()
768 {
769     QDeclarativeComponent component(&engine, TEST_FILE("deletedObject.qml"));
770     QTest::ignoreMessage(QtDebugMsg, "Test: 2");
771     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
772     QVERIFY(object != 0);
773
774     QObject *dObject = qvariant_cast<QObject *>(object->property("object"));
775     QVERIFY(dObject != 0);
776     delete dObject;
777
778     QTest::ignoreMessage(QtDebugMsg, "Test: undefined");
779     object->emitRunScript();
780
781     delete object;
782 }
783
784 // Test that value types can be assigned to another value type property in a binding
785 void tst_qdeclarativevaluetypes::bindingVariantCopy()
786 {
787     QDeclarativeComponent component(&engine, TEST_FILE("bindingVariantCopy.qml"));
788     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
789     QVERIFY(object != 0);
790
791     QCOMPARE(object->rect(), QRect(19, 33, 5, 99));
792
793     delete object;
794 }
795
796 // Test that value types can be assigned to another value type property in script
797 void tst_qdeclarativevaluetypes::scriptVariantCopy()
798 {
799     QDeclarativeComponent component(&engine, TEST_FILE("scriptVariantCopy.qml"));
800     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
801     QVERIFY(object != 0);
802
803     QCOMPARE(object->rect(), QRect(2, 3, 109, 102));
804
805     object->emitRunScript();
806
807     QCOMPARE(object->rect(), QRect(19, 33, 5, 99));
808
809     delete object;
810 }
811
812
813 // Test that the value type classes can be used manually
814 void tst_qdeclarativevaluetypes::cppClasses()
815 {
816     CPP_TEST(QDeclarativePointValueType, QPoint(19, 33));
817     CPP_TEST(QDeclarativePointFValueType, QPointF(33.6, -23));
818     CPP_TEST(QDeclarativeSizeValueType, QSize(-100, 18));
819     CPP_TEST(QDeclarativeSizeFValueType, QSizeF(-100.7, 18.2));
820     CPP_TEST(QDeclarativeRectValueType, QRect(13, 39, 10928, 88));
821     CPP_TEST(QDeclarativeRectFValueType, QRectF(88.2, -90.1, 103.2, 118));
822     CPP_TEST(QDeclarativeVector2DValueType, QVector2D(19.7, 1002));
823     CPP_TEST(QDeclarativeVector3DValueType, QVector3D(18.2, 19.7, 1002));
824     CPP_TEST(QDeclarativeVector4DValueType, QVector4D(18.2, 19.7, 1002, 54));
825     CPP_TEST(QDeclarativeQuaternionValueType, QQuaternion(18.2, 19.7, 1002, 54));
826     CPP_TEST(QDeclarativeMatrix4x4ValueType,
827              QMatrix4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16));
828     CPP_TEST(QDeclarativeFontValueType, QFont("Helvetica"));
829
830 }
831
832 void tst_qdeclarativevaluetypes::enums()
833 {
834     {
835     QDeclarativeComponent component(&engine, TEST_FILE("enums.1.qml"));
836     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
837     QVERIFY(object != 0);
838     QVERIFY(object->font().capitalization() == QFont::AllUppercase);
839     delete object;
840     }
841
842     {
843     QDeclarativeComponent component(&engine, TEST_FILE("enums.2.qml"));
844     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
845     QVERIFY(object != 0);
846     QVERIFY(object->font().capitalization() == QFont::AllUppercase);
847     delete object;
848     }
849
850     {
851     QDeclarativeComponent component(&engine, TEST_FILE("enums.3.qml"));
852     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
853     QVERIFY(object != 0);
854     QVERIFY(object->font().capitalization() == QFont::AllUppercase);
855     delete object;
856     }
857
858     {
859     QDeclarativeComponent component(&engine, TEST_FILE("enums.4.qml"));
860     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
861     QVERIFY(object != 0);
862     QVERIFY(object->font().capitalization() == QFont::AllUppercase);
863     delete object;
864     }
865
866     {
867     QDeclarativeComponent component(&engine, TEST_FILE("enums.5.qml"));
868     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
869     QVERIFY(object != 0);
870     QVERIFY(object->font().capitalization() == QFont::AllUppercase);
871     delete object;
872     }
873 }
874
875 // Tests switching between "conflicting" bindings (eg. a binding on the core
876 // property, to a binding on the value-type sub-property)
877 void tst_qdeclarativevaluetypes::conflictingBindings()
878 {
879     {
880     QDeclarativeComponent component(&engine, TEST_FILE("conflicting.1.qml"));
881     QObject *object = component.create();
882     QVERIFY(object != 0);
883
884     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12);
885
886     QMetaObject::invokeMethod(object, "toggle");
887
888     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 6);
889
890     QMetaObject::invokeMethod(object, "toggle");
891
892     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12);
893
894     delete object;
895     }
896
897     {
898     QDeclarativeComponent component(&engine, TEST_FILE("conflicting.2.qml"));
899     QObject *object = component.create();
900     QVERIFY(object != 0);
901
902     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 6);
903
904     QMetaObject::invokeMethod(object, "toggle");
905
906     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12);
907
908     QMetaObject::invokeMethod(object, "toggle");
909
910     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 6);
911
912     delete object;
913     }
914
915     {
916     QDeclarativeComponent component(&engine, TEST_FILE("conflicting.3.qml"));
917     QObject *object = component.create();
918     QVERIFY(object != 0);
919
920     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12);
921
922     QMetaObject::invokeMethod(object, "toggle");
923
924     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 24);
925
926     QMetaObject::invokeMethod(object, "toggle");
927
928     QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12);
929
930     delete object;
931     }
932 }
933
934 void tst_qdeclarativevaluetypes::returnValues()
935 {
936     QDeclarativeComponent component(&engine, TEST_FILE("returnValues.qml"));
937     QObject *object = component.create();
938     QVERIFY(object != 0);
939
940     QCOMPARE(object->property("test1").toBool(), true);
941     QCOMPARE(object->property("test2").toBool(), true);
942     QCOMPARE(object->property("size").toSize(), QSize(13, 14));
943
944     delete object;
945 }
946
947 void tst_qdeclarativevaluetypes::varAssignment()
948 {
949     QDeclarativeComponent component(&engine, TEST_FILE("varAssignment.qml"));
950     QObject *object = component.create();
951     QVERIFY(object != 0);
952
953     QCOMPARE(object->property("x").toInt(), 1);
954     QCOMPARE(object->property("y").toInt(), 2);
955     QCOMPARE(object->property("z").toInt(), 3);
956
957     delete object;
958 }
959
960 // Test bindings splice together correctly
961 void tst_qdeclarativevaluetypes::bindingsSpliceCorrectly()
962 {
963     {
964     QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.1.qml"));
965     QObject *object = component.create();
966     QVERIFY(object != 0);
967
968     QCOMPARE(object->property("test").toBool(), true);
969
970     delete object;
971     }
972
973     {
974     QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.2.qml"));
975     QObject *object = component.create();
976     QVERIFY(object != 0);
977
978     QCOMPARE(object->property("test").toBool(), true);
979
980     delete object;
981     }
982
983
984     {
985     QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.3.qml"));
986     QObject *object = component.create();
987     QVERIFY(object != 0);
988
989     QCOMPARE(object->property("test").toBool(), true);
990
991     delete object;
992     }
993
994     {
995     QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.4.qml"));
996     QObject *object = component.create();
997     QVERIFY(object != 0);
998
999     QCOMPARE(object->property("test").toBool(), true);
1000
1001     delete object;
1002     }
1003
1004     {
1005     QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.5.qml"));
1006     QObject *object = component.create();
1007     QVERIFY(object != 0);
1008
1009     QCOMPARE(object->property("test").toBool(), true);
1010
1011     delete object;
1012     }
1013 }
1014
1015 QTEST_MAIN(tst_qdeclarativevaluetypes)
1016
1017 #include "tst_qdeclarativevaluetypes.moc"