1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <qtest.h>
42 #include <QtDeclarative/qdeclarativeengine.h>
43 #include <QtDeclarative/qdeclarativecomponent.h>
44 #include <QtDeclarative/private/qdeclarativedom_p.h>
45
46 #include <QtCore/QDebug>
47 #include <QtCore/QFile>
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 class tst_qdeclarativedom : public QObject
55 {
56 Q_OBJECT
57 public:
tst_qdeclarativedom()58 tst_qdeclarativedom() {}
59
60 private slots:
61 void loadSimple();
62 void loadProperties();
63 void loadGroupedProperties();
64 void loadChildObject();
65 void loadComposite();
66 void loadImports();
67 void loadErrors();
68 void loadSyntaxErrors();
69 void loadRemoteErrors();
70 void loadDynamicProperty();
71 void loadComponent();
72
73 void testValueSource();
74 void testValueInterceptor();
75
76 void object_dynamicProperty();
77 void object_property();
78 void object_url();
79
80 void copy();
81 void position();
82 private:
83 QDeclarativeEngine engine;
84 };
85
86
loadSimple()87 void tst_qdeclarativedom::loadSimple()
88 {
89 QByteArray qml = "import QtQuick 1.0\n"
90 "Item {}";
91
92 QDeclarativeDomDocument document;
93 QVERIFY(document.load(&engine, qml));
94 QVERIFY(document.errors().isEmpty());
95
96 QDeclarativeDomObject rootObject = document.rootObject();
97 QVERIFY(rootObject.isValid());
98 QVERIFY(!rootObject.isComponent());
99 QVERIFY(!rootObject.isCustomType());
100 QVERIFY(rootObject.objectType() == "QtQuick/Item");
101 QVERIFY(rootObject.objectTypeMajorVersion() == 1);
102 QVERIFY(rootObject.objectTypeMinorVersion() == 0);
103 }
104
105 // Test regular properties
loadProperties()106 void tst_qdeclarativedom::loadProperties()
107 {
108 QByteArray qml = "import QtQuick 1.0\n"
109 "Item { id : item; x : 300; visible : true }";
110
111 QDeclarativeDomDocument document;
112 QVERIFY(document.load(&engine, qml));
113
114 QDeclarativeDomObject rootObject = document.rootObject();
115 QVERIFY(rootObject.isValid());
116 QVERIFY(rootObject.objectId() == "item");
117 QCOMPARE(rootObject.properties().size(), 3);
118
119 QDeclarativeDomProperty xProperty = rootObject.property("x");
120 QVERIFY(xProperty.propertyName() == "x");
121 QCOMPARE(xProperty.propertyNameParts().count(), 1);
122 QVERIFY(xProperty.propertyNameParts().at(0) == "x");
123 QCOMPARE(xProperty.position(), 37);
124 QCOMPARE(xProperty.length(), 1);
125 QVERIFY(xProperty.value().isLiteral());
126 QVERIFY(xProperty.value().toLiteral().literal() == "300");
127
128 QDeclarativeDomProperty visibleProperty = rootObject.property("visible");
129 QVERIFY(visibleProperty.propertyName() == "visible");
130 QCOMPARE(visibleProperty.propertyNameParts().count(), 1);
131 QVERIFY(visibleProperty.propertyNameParts().at(0) == "visible");
132 QCOMPARE(visibleProperty.position(), 46);
133 QCOMPARE(visibleProperty.length(), 7);
134 QVERIFY(visibleProperty.value().isLiteral());
135 QVERIFY(visibleProperty.value().toLiteral().literal() == "true");
136 }
137
138 // Test grouped properties
loadGroupedProperties()139 void tst_qdeclarativedom::loadGroupedProperties()
140 {
141 {
142 QByteArray qml = "import QtQuick 1.0\n"
143 "Item { anchors.left: parent.left; anchors.right: parent.right }";
144
145 QDeclarativeDomDocument document;
146 QVERIFY(document.load(&engine, qml));
147
148 QDeclarativeDomObject rootItem = document.rootObject();
149 QVERIFY(rootItem.isValid());
150 QVERIFY(rootItem.properties().size() == 2);
151
152 // Order is not deterministic
153 QDeclarativeDomProperty p0 = rootItem.properties().at(0);
154 QDeclarativeDomProperty p1 = rootItem.properties().at(1);
155 QDeclarativeDomProperty leftProperty;
156 QDeclarativeDomProperty rightProperty;
157 if (p0.propertyName() == "anchors.left") {
158 leftProperty = p0;
159 rightProperty = p1;
160 } else {
161 leftProperty = p1;
162 rightProperty = p0;
163 }
164
165 QVERIFY(leftProperty.propertyName() == "anchors.left");
166 QCOMPARE(leftProperty.propertyNameParts().count(), 2);
167 QVERIFY(leftProperty.propertyNameParts().at(0) == "anchors");
168 QVERIFY(leftProperty.propertyNameParts().at(1) == "left");
169 QCOMPARE(leftProperty.position(), 26);
170 QCOMPARE(leftProperty.length(), 12);
171 QVERIFY(leftProperty.value().isBinding());
172 QVERIFY(leftProperty.value().toBinding().binding() == "parent.left");
173
174 QVERIFY(rightProperty.propertyName() == "anchors.right");
175 QCOMPARE(rightProperty.propertyNameParts().count(), 2);
176 QVERIFY(rightProperty.propertyNameParts().at(0) == "anchors");
177 QVERIFY(rightProperty.propertyNameParts().at(1) == "right");
178 QCOMPARE(rightProperty.position(), 53);
179 QCOMPARE(rightProperty.length(), 13);
180 QVERIFY(rightProperty.value().isBinding());
181 QVERIFY(rightProperty.value().toBinding().binding() == "parent.right");
182 }
183
184 {
185 QByteArray qml = "import QtQuick 1.0\n"
186 "Item { \n"
187 " anchors {\n"
188 " left: parent.left\n"
189 " right: parent.right\n"
190 " }\n"
191 "}";
192
193 QDeclarativeDomDocument document;
194 QVERIFY(document.load(&engine, qml));
195
196 QDeclarativeDomObject rootItem = document.rootObject();
197 QVERIFY(rootItem.isValid());
198 QVERIFY(rootItem.properties().size() == 2);
199
200 // Order is not deterministic
201 QDeclarativeDomProperty p0 = rootItem.properties().at(0);
202 QDeclarativeDomProperty p1 = rootItem.properties().at(1);
203 QDeclarativeDomProperty leftProperty;
204 QDeclarativeDomProperty rightProperty;
205 if (p0.propertyName() == "anchors.left") {
206 leftProperty = p0;
207 rightProperty = p1;
208 } else {
209 leftProperty = p1;
210 rightProperty = p0;
211 }
212
213 QVERIFY(leftProperty.propertyName() == "anchors.left");
214 QCOMPARE(leftProperty.propertyNameParts().count(), 2);
215 QVERIFY(leftProperty.propertyNameParts().at(0) == "anchors");
216 QVERIFY(leftProperty.propertyNameParts().at(1) == "left");
217 QCOMPARE(leftProperty.position(), 49);
218 QCOMPARE(leftProperty.length(), 4);
219 QVERIFY(leftProperty.value().isBinding());
220 QVERIFY(leftProperty.value().toBinding().binding() == "parent.left");
221
222 QVERIFY(rightProperty.propertyName() == "anchors.right");
223 QCOMPARE(rightProperty.propertyNameParts().count(), 2);
224 QVERIFY(rightProperty.propertyNameParts().at(0) == "anchors");
225 QVERIFY(rightProperty.propertyNameParts().at(1) == "right");
226 QCOMPARE(rightProperty.position(), 75);
227 QCOMPARE(rightProperty.length(), 5);
228 QVERIFY(rightProperty.value().isBinding());
229 QVERIFY(rightProperty.value().toBinding().binding() == "parent.right");
230 }
231
232 }
233
loadChildObject()234 void tst_qdeclarativedom::loadChildObject()
235 {
236 QByteArray qml = "import QtQuick 1.0\n"
237 "Item { Item {} }";
238
239 QDeclarativeDomDocument document;
240 QVERIFY(document.load(&engine, qml));
241
242 QDeclarativeDomObject rootItem = document.rootObject();
243 QVERIFY(rootItem.isValid());
244 QVERIFY(rootItem.properties().size() == 1);
245
246 QDeclarativeDomProperty listProperty = rootItem.properties().at(0);
247 QVERIFY(listProperty.isDefaultProperty());
248 QVERIFY(listProperty.value().isList());
249
250 QDeclarativeDomList list = listProperty.value().toList();
251 QVERIFY(list.values().size() == 1);
252
253 QDeclarativeDomObject childItem = list.values().first().toObject();
254 QVERIFY(childItem.isValid());
255 QVERIFY(childItem.objectType() == "QtQuick/Item");
256 }
257
loadComposite()258 void tst_qdeclarativedom::loadComposite()
259 {
260 QFile file(SRCDIR "/data/top.qml");
261 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
262
263 QDeclarativeDomDocument document;
264 QVERIFY(document.load(&engine, file.readAll(), QUrl::fromLocalFile(file.fileName())));
265 QVERIFY(document.errors().isEmpty());
266
267 QDeclarativeDomObject rootItem = document.rootObject();
268 QVERIFY(rootItem.isValid());
269 QCOMPARE(rootItem.objectType(), QByteArray("MyComponent"));
270 QCOMPARE(rootItem.properties().size(), 2);
271
272 QDeclarativeDomProperty widthProperty = rootItem.property("width");
273 QVERIFY(widthProperty.value().isLiteral());
274
275 QDeclarativeDomProperty heightProperty = rootItem.property("height");
276 QVERIFY(heightProperty.value().isLiteral());
277 }
278
testValueSource()279 void tst_qdeclarativedom::testValueSource()
280 {
281 QByteArray qml = "import QtQuick 1.0\n"
282 "Rectangle { SpringAnimation on height { spring: 1.4; damping: .15; to: Math.min(Math.max(-130, value*2.2 - 130), 133); }}";
283
284 QDeclarativeEngine freshEngine;
285 QDeclarativeDomDocument document;
286 QVERIFY(document.load(&freshEngine, qml));
287
288 QDeclarativeDomObject rootItem = document.rootObject();
289 QVERIFY(rootItem.isValid());
290 QDeclarativeDomProperty heightProperty = rootItem.properties().at(0);
291 QVERIFY(heightProperty.propertyName() == "height");
292 QVERIFY(heightProperty.value().isValueSource());
293
294 const QDeclarativeDomValueValueSource valueSource = heightProperty.value().toValueSource();
295 QDeclarativeDomObject valueSourceObject = valueSource.object();
296 QVERIFY(valueSourceObject.isValid());
297
298 QVERIFY(valueSourceObject.objectType() == "QtQuick/SpringAnimation");
299
300 const QDeclarativeDomValue springValue = valueSourceObject.property("spring").value();
301 QVERIFY(!springValue.isInvalid());
302 QVERIFY(springValue.isLiteral());
303 QVERIFY(springValue.toLiteral().literal() == "1.4");
304
305 const QDeclarativeDomValue sourceValue = valueSourceObject.property("to").value();
306 QVERIFY(!sourceValue.isInvalid());
307 QVERIFY(sourceValue.isBinding());
308 QVERIFY(sourceValue.toBinding().binding() == "Math.min(Math.max(-130, value*2.2 - 130), 133)");
309 }
310
testValueInterceptor()311 void tst_qdeclarativedom::testValueInterceptor()
312 {
313 QByteArray qml = "import QtQuick 1.0\n"
314 "Rectangle { Behavior on height { NumberAnimation { duration: 100 } } }";
315
316 QDeclarativeEngine freshEngine;
317 QDeclarativeDomDocument document;
318 QVERIFY(document.load(&freshEngine, qml));
319
320 QDeclarativeDomObject rootItem = document.rootObject();
321 QVERIFY(rootItem.isValid());
322 QDeclarativeDomProperty heightProperty = rootItem.properties().at(0);
323 QVERIFY(heightProperty.propertyName() == "height");
324 QVERIFY(heightProperty.value().isValueInterceptor());
325
326 const QDeclarativeDomValueValueInterceptor valueInterceptor = heightProperty.value().toValueInterceptor();
327 QDeclarativeDomObject valueInterceptorObject = valueInterceptor.object();
328 QVERIFY(valueInterceptorObject.isValid());
329
330 QVERIFY(valueInterceptorObject.objectType() == "QtQuick/Behavior");
331
332 const QDeclarativeDomValue animationValue = valueInterceptorObject.property("animation").value();
333 QVERIFY(!animationValue.isInvalid());
334 QVERIFY(animationValue.isObject());
335 }
336
337 // Test QDeclarativeDomDocument::imports()
loadImports()338 void tst_qdeclarativedom::loadImports()
339 {
340 QByteArray qml = "import QtQuick 1.0\n"
341 "import importlib.sublib 1.1\n"
342 "import importlib.sublib 1.0 as NewFoo\n"
343 "import 'import'\n"
344 "import 'import' as X\n"
345 "Item {}";
346
347 QDeclarativeEngine engine;
348 engine.addImportPath(SRCDIR "/data");
349 QDeclarativeDomDocument document;
350 QVERIFY(document.load(&engine, qml, QUrl::fromLocalFile(SRCDIR "/data/dummy.qml")));
351
352 QCOMPARE(document.imports().size(), 5);
353
354 QDeclarativeDomImport import = document.imports().at(0);
355 QCOMPARE(import.type(), QDeclarativeDomImport::Library);
356 QCOMPARE(import.uri(), QLatin1String("QtQuick"));
357 QCOMPARE(import.qualifier(), QString());
358 QCOMPARE(import.version(), QLatin1String("1.0"));
359
360 import = document.imports().at(1);
361 QCOMPARE(import.type(), QDeclarativeDomImport::Library);
362 QCOMPARE(import.uri(), QLatin1String("importlib.sublib"));
363 QCOMPARE(import.qualifier(), QString());
364 QCOMPARE(import.version(), QLatin1String("1.1"));
365
366 import = document.imports().at(2);
367 QCOMPARE(import.type(), QDeclarativeDomImport::Library);
368 QCOMPARE(import.uri(), QLatin1String("importlib.sublib"));
369 QCOMPARE(import.qualifier(), QLatin1String("NewFoo"));
370 QCOMPARE(import.version(), QLatin1String("1.0"));
371
372 import = document.imports().at(3);
373 QCOMPARE(import.type(), QDeclarativeDomImport::File);
374 QCOMPARE(import.uri(), QLatin1String("import"));
375 QCOMPARE(import.qualifier(), QLatin1String(""));
376 QCOMPARE(import.version(), QLatin1String(""));
377
378 import = document.imports().at(4);
379 QCOMPARE(import.type(), QDeclarativeDomImport::File);
380 QCOMPARE(import.uri(), QLatin1String("import"));
381 QCOMPARE(import.qualifier(), QLatin1String("X"));
382 QCOMPARE(import.version(), QLatin1String(""));
383 }
384
385 // Test loading a file with errors
loadErrors()386 void tst_qdeclarativedom::loadErrors()
387 {
388 QByteArray qml = "import QtQuick 1.0\n"
389 "Item {\n"
390 " foo: 12\n"
391 "}";
392
393 QDeclarativeDomDocument document;
394 QVERIFY(false == document.load(&engine, qml));
395
396 QCOMPARE(document.errors().count(), 1);
397 QDeclarativeError error = document.errors().first();
398
399 QCOMPARE(error.url(), QUrl());
400 QCOMPARE(error.line(), 3);
401 QCOMPARE(error.column(), 3);
402 QCOMPARE(error.description(), QString("Cannot assign to non-existent property \"foo\""));
403 }
404
405 // Test loading a file with syntax errors
loadSyntaxErrors()406 void tst_qdeclarativedom::loadSyntaxErrors()
407 {
408 QByteArray qml = "import QtQuick 1.0\n"
409 "asdf";
410
411 QDeclarativeDomDocument document;
412 QVERIFY(false == document.load(&engine, qml));
413
414 QCOMPARE(document.errors().count(), 1);
415 QDeclarativeError error = document.errors().first();
416
417 QCOMPARE(error.url(), QUrl());
418 QCOMPARE(error.line(), 2);
419 QCOMPARE(error.column(), 1);
420 QCOMPARE(error.description(), QString("Syntax error"));
421 }
422
423 // Test attempting to load a file with remote references
loadRemoteErrors()424 void tst_qdeclarativedom::loadRemoteErrors()
425 {
426 QByteArray qml = "import QtQuick 1.0\n"
427 "import \"http://localhost/exampleQmlScript.js\" as Script\n"
428 "Item {\n"
429 "}";
430 QDeclarativeDomDocument document;
431 QVERIFY(false == document.load(&engine, qml));
432
433 QCOMPARE(document.errors().count(), 1);
434 QDeclarativeError error = document.errors().first();
435
436 QCOMPARE(error.url(), QUrl());
437 QCOMPARE(error.line(), -1);
438 QCOMPARE(error.column(), -1);
439 QCOMPARE(error.description(), QString("QDeclarativeDomDocument supports local types only"));
440 }
441
442 // Test dynamic property declarations
loadDynamicProperty()443 void tst_qdeclarativedom::loadDynamicProperty()
444 {
445 {
446 QByteArray qml = "import QtQuick 1.0\n"
447 "Item {\n"
448 " property int a\n"
449 " property bool b\n"
450 " property double c\n"
451 " property real d\n"
452 " property string e\n"
453 " property url f\n"
454 " property color g\n"
455 " property date h\n"
456 " property variant i\n"
457 " property QtObject j\n"
458 "}";
459
460 QDeclarativeDomDocument document;
461 QVERIFY(document.load(&engine, qml));
462
463 QDeclarativeDomObject rootObject = document.rootObject();
464 QVERIFY(rootObject.isValid());
465
466 QCOMPARE(rootObject.dynamicProperties().count(), 10);
467
468 #define DP_TEST(index, name, type, test_position, test_length, propTypeName) \
469 { \
470 QDeclarativeDomDynamicProperty d = rootObject.dynamicProperties().at(index); \
471 QVERIFY(d.isValid()); \
472 QVERIFY(d.propertyName() == # name ); \
473 QVERIFY(d.propertyType() == type); \
474 QVERIFY(d.propertyTypeName() == propTypeName); \
475 QVERIFY(d.isDefaultProperty() == false); \
476 QVERIFY(d.defaultValue().isValid() == false); \
477 QCOMPARE(d.position(), test_position); \
478 QCOMPARE(d.length(), test_length); \
479 } \
480
481 DP_TEST(0, a, QVariant::Int, 30, 14, "int");
482 DP_TEST(1, b, QVariant::Bool, 49, 15, "bool");
483 DP_TEST(2, c, QMetaType::QReal, 69, 17, "double");
484 DP_TEST(3, d, QMetaType::QReal, 91, 15, "real");
485 DP_TEST(4, e, QVariant::String, 111, 17, "string");
486 DP_TEST(5, f, QVariant::Url, 133, 14, "url");
487 DP_TEST(6, g, QVariant::Color, 152, 16, "color");
488 DP_TEST(7, h, QVariant::DateTime, 173, 15, "date");
489 DP_TEST(8, i, qMetaTypeId<QVariant>(), 193, 18, "variant");
490 DP_TEST(9, j, -1, 216, 19, "QtObject");
491 }
492
493 {
494 QByteArray qml = "import QtQuick 1.0\n"
495 "Item {\n"
496 " id: item\n"
497 " property int a: 12\n"
498 " property int b: a + 6\n"
499 " default property QtObject c\n"
500 " property alias d: item.a\n"
501 "}\n";
502
503 QDeclarativeDomDocument document;
504 QVERIFY(document.load(&engine, qml));
505
506 QDeclarativeDomObject rootObject = document.rootObject();
507 QVERIFY(rootObject.isValid());
508
509 QCOMPARE(rootObject.dynamicProperties().count(), 4);
510
511 {
512 QDeclarativeDomDynamicProperty d = rootObject.dynamicProperties().at(0);
513 QVERIFY(d.isDefaultProperty() == false);
514 QVERIFY(d.isAlias() == false);
515 QVERIFY(d.defaultValue().isValid());
516 QVERIFY(d.defaultValue().propertyName() == "a");
517 QVERIFY(d.defaultValue().value().isLiteral());
518 }
519
520 {
521 QDeclarativeDomDynamicProperty d = rootObject.dynamicProperties().at(1);
522 QVERIFY(d.isDefaultProperty() == false);
523 QVERIFY(d.isAlias() == false);
524 QVERIFY(d.defaultValue().isValid());
525 QVERIFY(d.defaultValue().propertyName() == "b");
526 QVERIFY(d.defaultValue().value().isBinding());
527 }
528
529 {
530 QDeclarativeDomDynamicProperty d = rootObject.dynamicProperties().at(2);
531 QVERIFY(d.isDefaultProperty() == true);
532 QVERIFY(d.isAlias() == false);
533 QVERIFY(d.defaultValue().isValid() == false);
534 }
535
536 {
537 QDeclarativeDomDynamicProperty d = rootObject.dynamicProperties().at(3);
538 QVERIFY(d.isDefaultProperty() == false);
539 QVERIFY(d.isAlias() == true);
540 }
541 }
542 }
543
544 // Test inline components
loadComponent()545 void tst_qdeclarativedom::loadComponent()
546 {
547 // Explicit component
548 {
549 QByteArray qml = "import QtQuick 1.0\n"
550 "Item {\n"
551 " Component {\n"
552 " id: myComponent\n"
553 " Item {}\n"
554 " }\n"
555 "}";
556
557 QDeclarativeDomDocument document;
558 QVERIFY(document.load(&engine, qml));
559
560 QDeclarativeDomObject rootItem = document.rootObject();
561 QVERIFY(rootItem.isValid());
562 QVERIFY(rootItem.properties().size() == 1);
563
564 QDeclarativeDomProperty listProperty = rootItem.properties().at(0);
565 QVERIFY(listProperty.isDefaultProperty());
566 QVERIFY(listProperty.value().isList());
567
568 QDeclarativeDomList list = listProperty.value().toList();
569 QVERIFY(list.values().size() == 1);
570
571 QDeclarativeDomObject componentObject = list.values().first().toObject();
572 QVERIFY(componentObject.isValid());
573 QVERIFY(componentObject.objectClassName() == "Component");
574 QVERIFY(componentObject.isComponent());
575
576 QDeclarativeDomComponent component = componentObject.toComponent();
577 QVERIFY(component.isValid());
578 QVERIFY(component.objectType() == "QtQuick/Component");
579 QVERIFY(component.objectTypeMajorVersion() == 1);
580 QVERIFY(component.objectTypeMinorVersion() == 0);
581 QVERIFY(component.objectClassName() == "Component");
582 QVERIFY(component.objectId() == "myComponent");
583 QVERIFY(component.properties().isEmpty());
584 QVERIFY(component.dynamicProperties().isEmpty());
585 QVERIFY(component.isCustomType() == false);
586 QVERIFY(component.customTypeData() == "");
587 QVERIFY(component.isComponent());
588 QCOMPARE(component.position(), 30);
589 QCOMPARE(component.length(), 57);
590
591 QVERIFY(component.componentRoot().isValid());
592 QVERIFY(component.componentRoot().objectClassName() == "Item");
593 }
594
595 // Implicit component
596 {
597 QByteArray qml = "import QtQuick 1.0\n"
598 "ListView {\n"
599 " delegate: Item {}\n"
600 "}";
601
602 QDeclarativeDomDocument document;
603 QVERIFY(document.load(&engine, qml));
604
605 QDeclarativeDomObject rootItem = document.rootObject();
606 QVERIFY(rootItem.isValid());
607 QVERIFY(rootItem.properties().size() == 1);
608
609 QDeclarativeDomProperty delegate = rootItem.property("delegate");
610
611 QDeclarativeDomObject componentObject = delegate.value().toObject();
612 QVERIFY(componentObject.isValid());
613 QVERIFY(componentObject.objectClassName() == "Component");
614 QVERIFY(componentObject.isComponent());
615
616 QDeclarativeDomComponent component = componentObject.toComponent();
617 QVERIFY(component.isValid());
618 QVERIFY(component.objectType() == "QtQuick/Component");
619 QVERIFY(component.objectClassName() == "Component");
620 QVERIFY(component.objectId() == "");
621 QVERIFY(component.properties().isEmpty());
622 QVERIFY(component.dynamicProperties().isEmpty());
623 QVERIFY(component.isCustomType() == false);
624 QVERIFY(component.customTypeData() == "");
625 QVERIFY(component.isComponent());
626 QCOMPARE(component.position(), 44);
627 QCOMPARE(component.length(), 7);
628
629 QVERIFY(component.componentRoot().isValid());
630 QVERIFY(component.componentRoot().objectClassName() == "Item");
631 }
632 }
633
634 // Test QDeclarativeDomObject::dynamicProperty() method
object_dynamicProperty()635 void tst_qdeclarativedom::object_dynamicProperty()
636 {
637 // Invalid object
638 {
639 QDeclarativeDomObject object;
640 QVERIFY(object.dynamicProperty("").isValid() == false);
641 QVERIFY(object.dynamicProperty("foo").isValid() == false);
642 }
643
644
645 // Valid object, no dynamic properties
646 {
647 QByteArray qml = "import QtQuick 1.0\n"
648 "Item {}";
649
650 QDeclarativeDomDocument document;
651 QVERIFY(document.load(&engine, qml));
652
653 QDeclarativeDomObject rootObject = document.rootObject();
654 QVERIFY(rootObject.isValid());
655
656 QVERIFY(rootObject.dynamicProperty("").isValid() == false);
657 QVERIFY(rootObject.dynamicProperty("foo").isValid() == false);
658 }
659
660 // Valid object, dynamic properties
661 {
662 QByteArray qml = "import QtQuick 1.0\n"
663 "Item {\n"
664 " property int a\n"
665 "}";
666
667 QDeclarativeDomDocument document;
668 QVERIFY(document.load(&engine, qml));
669
670 QDeclarativeDomObject rootObject = document.rootObject();
671 QVERIFY(rootObject.isValid());
672
673 QVERIFY(rootObject.dynamicProperty("").isValid() == false);
674 QVERIFY(rootObject.dynamicProperty("foo").isValid() == false);
675
676 QDeclarativeDomDynamicProperty p = rootObject.dynamicProperty("a");
677 QVERIFY(p.isValid());
678 QVERIFY(p.propertyName() == "a");
679 QVERIFY(p.propertyType() == QVariant::Int);
680 QVERIFY(p.propertyTypeName() == "int");
681 QVERIFY(p.isDefaultProperty() == false);
682 QCOMPARE(p.position(), 30);
683 QCOMPARE(p.length(), 14);
684 }
685
686 }
687
688 // Test QDeclarativeObject::property() method
object_property()689 void tst_qdeclarativedom::object_property()
690 {
691 // Invalid object
692 {
693 QDeclarativeDomObject object;
694 QVERIFY(object.property("").isValid() == false);
695 QVERIFY(object.property("foo").isValid() == false);
696 }
697
698 // Valid object - no default
699 {
700 QByteArray qml = "import QtQuick 1.0\n"
701 "Item {\n"
702 " x: 10\n"
703 " y: 12\n"
704 "}\n";
705
706 QDeclarativeDomDocument document;
707 QVERIFY(document.load(&engine, qml));
708
709 QDeclarativeDomObject rootObject = document.rootObject();
710 QVERIFY(rootObject.isValid());
711
712 QVERIFY(rootObject.property("").isValid() == false);
713 QVERIFY(rootObject.property("foo").isValid() == false);
714
715 QDeclarativeDomProperty x = rootObject.property("x");
716 QVERIFY(x.isValid());
717 QVERIFY(x.propertyName() == "x");
718 QVERIFY(x.propertyNameParts().count() == 1);
719 QVERIFY(x.propertyNameParts().at(0) == "x");
720 QVERIFY(x.isDefaultProperty() == false);
721 QVERIFY(x.value().isLiteral());
722 QVERIFY(x.value().toLiteral().literal() == "10");
723 QCOMPARE(x.position(), 30);
724 QCOMPARE(x.length(), 1);
725
726 QDeclarativeDomProperty y = rootObject.property("y");
727 QVERIFY(y.isValid());
728 QVERIFY(y.propertyName() == "y");
729 QVERIFY(y.propertyNameParts().count() == 1);
730 QVERIFY(y.propertyNameParts().at(0) == "y");
731 QVERIFY(y.isDefaultProperty() == false);
732 QVERIFY(y.value().isLiteral());
733 QVERIFY(y.value().toLiteral().literal() == "12");
734 QCOMPARE(y.position(), 40);
735 QCOMPARE(y.length(), 1);
736 }
737
738 // Valid object - with default
739 {
740 QByteArray qml = "import QtQuick 1.0\n"
741 "Item {\n"
742 " x: 10\n"
743 " y: 12\n"
744 " Item {}\n"
745 "}\n";
746
747 QDeclarativeDomDocument document;
748 QVERIFY(document.load(&engine, qml));
749
750 QDeclarativeDomObject rootObject = document.rootObject();
751 QVERIFY(rootObject.isValid());
752
753 QVERIFY(rootObject.property("").isValid() == false);
754 QVERIFY(rootObject.property("foo").isValid() == false);
755
756 QDeclarativeDomProperty x = rootObject.property("x");
757 QVERIFY(x.isValid());
758 QVERIFY(x.propertyName() == "x");
759 QVERIFY(x.propertyNameParts().count() == 1);
760 QVERIFY(x.propertyNameParts().at(0) == "x");
761 QVERIFY(x.isDefaultProperty() == false);
762 QVERIFY(x.value().isLiteral());
763 QVERIFY(x.value().toLiteral().literal() == "10");
764 QCOMPARE(x.position(), 30);
765 QCOMPARE(x.length(), 1);
766
767 QDeclarativeDomProperty y = rootObject.property("y");
768 QVERIFY(y.isValid());
769 QVERIFY(y.propertyName() == "y");
770 QVERIFY(y.propertyNameParts().count() == 1);
771 QVERIFY(y.propertyNameParts().at(0) == "y");
772 QVERIFY(y.isDefaultProperty() == false);
773 QVERIFY(y.value().isLiteral());
774 QVERIFY(y.value().toLiteral().literal() == "12");
775 QCOMPARE(y.position(), 40);
776 QCOMPARE(y.length(), 1);
777
778 QDeclarativeDomProperty data = rootObject.property("data");
779 QVERIFY(data.isValid());
780 QVERIFY(data.propertyName() == "data");
781 QVERIFY(data.propertyNameParts().count() == 1);
782 QVERIFY(data.propertyNameParts().at(0) == "data");
783 QVERIFY(data.isDefaultProperty() == true);
784 QVERIFY(data.value().isList());
785 QCOMPARE(data.position(), 50);
786 QCOMPARE(data.length(), 0);
787 }
788 }
789
790 // Tests the QDeclarativeDomObject::url() method
object_url()791 void tst_qdeclarativedom::object_url()
792 {
793 // Invalid object
794 {
795 QDeclarativeDomObject object;
796 QCOMPARE(object.url(), QUrl());
797 }
798
799 // Valid builtin object
800 {
801 QByteArray qml = "import QtQuick 1.0\n"
802 "Item {}";
803
804 QDeclarativeDomDocument document;
805 QVERIFY(document.load(&engine, qml));
806
807 QDeclarativeDomObject rootObject = document.rootObject();
808 QVERIFY(rootObject.isValid());
809 QCOMPARE(rootObject.url(), QUrl());
810 }
811
812 // Valid composite object
813 {
814 QByteArray qml = "import QtQuick 1.0\n"
815 "MyItem {}";
816
817 QUrl myUrl = QUrl::fromLocalFile(SRCDIR "/data/main.qml");
818 QUrl subUrl = QUrl::fromLocalFile(SRCDIR "/data/MyItem.qml");
819
820 QDeclarativeDomDocument document;
821 QVERIFY(document.load(&engine, qml, myUrl));
822
823 QDeclarativeDomObject rootObject = document.rootObject();
824 QVERIFY(rootObject.isValid());
825 QCOMPARE(rootObject.url(), subUrl);
826 }
827 }
828
829 // Test copy constructors and operators
copy()830 void tst_qdeclarativedom::copy()
831 {
832 QByteArray qml = "import QtQuick 1.0\n"
833 "MyItem {\n"
834 " id: myItem\n"
835 " property int a: 10\n"
836 " x: 10\n"
837 " y: x + 10\n"
838 " NumberAnimation on z {}\n"
839 " Behavior on opacity {}\n"
840 " Component {\n"
841 " Item{}\n"
842 " }\n"
843 " children: [ Item{}, Item{} ]\n"
844 "}\n";
845
846 QUrl myUrl = QUrl::fromLocalFile(SRCDIR "/data/main.qml");
847
848 QDeclarativeDomDocument document;
849 QVERIFY(document.load(&engine, qml, myUrl));
850
851 // QDeclarativeDomDocument
852 {
853 QDeclarativeDomDocument document2(document);
854 QDeclarativeDomDocument document3;
855 document3 = document;
856
857 QCOMPARE(document.imports().count(), document2.imports().count());
858 QCOMPARE(document.errors().count(), document2.errors().count());
859 QCOMPARE(document.rootObject().objectClassName(), document2.rootObject().objectClassName());
860
861 QCOMPARE(document.imports().count(), document3.imports().count());
862 QCOMPARE(document.errors().count(), document3.errors().count());
863 QCOMPARE(document.rootObject().objectClassName(), document3.rootObject().objectClassName());
864 }
865
866 // QDeclarativeDomImport
867 {
868 QCOMPARE(document.imports().count(), 1);
869 QDeclarativeDomImport import = document.imports().at(0);
870
871 QDeclarativeDomImport import2(import);
872 QDeclarativeDomImport import3;
873 import3 = import2;
874
875 QCOMPARE(import.type(), import2.type());
876 QCOMPARE(import.uri(), import2.uri());
877 QCOMPARE(import.version(), import2.version());
878 QCOMPARE(import.qualifier(), import2.qualifier());
879
880 QCOMPARE(import.type(), import3.type());
881 QCOMPARE(import.uri(), import3.uri());
882 QCOMPARE(import.version(), import3.version());
883 QCOMPARE(import.qualifier(), import3.qualifier());
884 }
885
886 // QDeclarativeDomObject
887 {
888 QDeclarativeDomObject object = document.rootObject();
889 QVERIFY(object.isValid());
890
891 QDeclarativeDomObject object2(object);
892 QDeclarativeDomObject object3;
893 object3 = object;
894
895 QCOMPARE(object.isValid(), object2.isValid());
896 QCOMPARE(object.objectType(), object2.objectType());
897 QCOMPARE(object.objectClassName(), object2.objectClassName());
898 QCOMPARE(object.objectTypeMajorVersion(), object2.objectTypeMajorVersion());
899 QCOMPARE(object.objectTypeMinorVersion(), object2.objectTypeMinorVersion());
900 QCOMPARE(object.objectId(), object2.objectId());
901 QCOMPARE(object.properties().count(), object2.properties().count());
902 QCOMPARE(object.dynamicProperties().count(), object2.dynamicProperties().count());
903 QCOMPARE(object.isCustomType(), object2.isCustomType());
904 QCOMPARE(object.customTypeData(), object2.customTypeData());
905 QCOMPARE(object.isComponent(), object2.isComponent());
906 QCOMPARE(object.position(), object2.position());
907 QCOMPARE(object.length(), object2.length());
908 QCOMPARE(object.url(), object2.url());
909
910 QCOMPARE(object.isValid(), object3.isValid());
911 QCOMPARE(object.objectType(), object3.objectType());
912 QCOMPARE(object.objectClassName(), object3.objectClassName());
913 QCOMPARE(object.objectTypeMajorVersion(), object3.objectTypeMajorVersion());
914 QCOMPARE(object.objectTypeMinorVersion(), object3.objectTypeMinorVersion());
915 QCOMPARE(object.objectId(), object3.objectId());
916 QCOMPARE(object.properties().count(), object3.properties().count());
917 QCOMPARE(object.dynamicProperties().count(), object3.dynamicProperties().count());
918 QCOMPARE(object.isCustomType(), object3.isCustomType());
919 QCOMPARE(object.customTypeData(), object3.customTypeData());
920 QCOMPARE(object.isComponent(), object3.isComponent());
921 QCOMPARE(object.position(), object3.position());
922 QCOMPARE(object.length(), object3.length());
923 QCOMPARE(object.url(), object3.url());
924 }
925
926 // QDeclarativeDomDynamicProperty
927 {
928 QDeclarativeDomObject object = document.rootObject();
929 QDeclarativeDomDynamicProperty property = object.dynamicProperty("a");
930
931 QDeclarativeDomDynamicProperty property2(property);
932 QDeclarativeDomDynamicProperty property3;
933 property3 = property;
934
935 QCOMPARE(property.isValid(), property2.isValid());
936 QCOMPARE(property.propertyName(), property2.propertyName());
937 QCOMPARE(property.propertyType(), property2.propertyType());
938 QCOMPARE(property.propertyTypeName(), property2.propertyTypeName());
939 QCOMPARE(property.isDefaultProperty(), property2.isDefaultProperty());
940 QCOMPARE(property.defaultValue().propertyName(), property2.defaultValue().propertyName());
941 QCOMPARE(property.position(), property2.position());
942 QCOMPARE(property.length(), property2.length());
943
944 QCOMPARE(property.isValid(), property3.isValid());
945 QCOMPARE(property.propertyName(), property3.propertyName());
946 QCOMPARE(property.propertyType(), property3.propertyType());
947 QCOMPARE(property.propertyTypeName(), property3.propertyTypeName());
948 QCOMPARE(property.isDefaultProperty(), property3.isDefaultProperty());
949 QCOMPARE(property.defaultValue().propertyName(), property3.defaultValue().propertyName());
950 QCOMPARE(property.position(), property3.position());
951 QCOMPARE(property.length(), property3.length());
952 }
953
954 // QDeclarativeDomProperty
955 {
956 QDeclarativeDomObject object = document.rootObject();
957 QDeclarativeDomProperty property = object.property("opacity");
958
959 QDeclarativeDomProperty property2(property);
960 QDeclarativeDomProperty property3;
961 property3 = property;
962
963 QCOMPARE(property.isValid(), property2.isValid());
964 QCOMPARE(property.propertyName(), property2.propertyName());
965 QCOMPARE(property.propertyNameParts(), property2.propertyNameParts());
966 QCOMPARE(property.isDefaultProperty(), property2.isDefaultProperty());
967 QCOMPARE(property.value().type(), property2.value().type());
968 QCOMPARE(property.position(), property2.position());
969 QCOMPARE(property.length(), property2.length());
970
971 QCOMPARE(property.isValid(), property3.isValid());
972 QCOMPARE(property.propertyName(), property3.propertyName());
973 QCOMPARE(property.propertyNameParts(), property3.propertyNameParts());
974 QCOMPARE(property.isDefaultProperty(), property3.isDefaultProperty());
975 QCOMPARE(property.value().type(), property3.value().type());
976 QCOMPARE(property.position(), property3.position());
977 QCOMPARE(property.length(), property3.length());
978 }
979
980 // QDeclarativeDomValueLiteral
981 {
982 QDeclarativeDomObject object = document.rootObject();
983 QDeclarativeDomProperty property = object.property("x");
984 QDeclarativeDomValueLiteral literal = property.value().toLiteral();
985 QCOMPARE(literal.literal(), QString("10"));
986
987 QDeclarativeDomValueLiteral literal2(literal);
988 QDeclarativeDomValueLiteral literal3;
989 literal3 = literal2;
990
991 QCOMPARE(literal2.literal(), QString("10"));
992 QCOMPARE(literal3.literal(), QString("10"));
993 }
994
995
996 // QDeclarativeDomValueBinding
997 {
998 QDeclarativeDomObject object = document.rootObject();
999 QDeclarativeDomProperty property = object.property("y");
1000 QDeclarativeDomValueBinding binding = property.value().toBinding();
1001 QCOMPARE(binding.binding(), QString("x + 10"));
1002
1003 QDeclarativeDomValueBinding binding2(binding);
1004 QDeclarativeDomValueBinding binding3;
1005 binding3 = binding2;
1006
1007 QCOMPARE(binding2.binding(), QString("x + 10"));
1008 QCOMPARE(binding3.binding(), QString("x + 10"));
1009 }
1010
1011 // QDeclarativeDomValueValueSource
1012 {
1013 QDeclarativeDomObject object = document.rootObject();
1014 QDeclarativeDomProperty property = object.property("z");
1015 QDeclarativeDomValueValueSource source = property.value().toValueSource();
1016 QCOMPARE(source.object().objectClassName(), QByteArray("NumberAnimation"));
1017
1018 QDeclarativeDomValueValueSource source2(source);
1019 QDeclarativeDomValueValueSource source3;
1020 source3 = source;
1021
1022 QCOMPARE(source2.object().objectClassName(), QByteArray("NumberAnimation"));
1023 QCOMPARE(source3.object().objectClassName(), QByteArray("NumberAnimation"));
1024 }
1025
1026 // QDeclarativeDomValueValueInterceptor
1027 {
1028 QDeclarativeDomObject object = document.rootObject();
1029 QDeclarativeDomProperty property = object.property("opacity");
1030 QDeclarativeDomValueValueInterceptor interceptor = property.value().toValueInterceptor();
1031 QCOMPARE(interceptor.object().objectClassName(), QByteArray("Behavior"));
1032
1033 QDeclarativeDomValueValueInterceptor interceptor2(interceptor);
1034 QDeclarativeDomValueValueInterceptor interceptor3;
1035 interceptor3 = interceptor;
1036
1037 QCOMPARE(interceptor2.object().objectClassName(), QByteArray("Behavior"));
1038 QCOMPARE(interceptor3.object().objectClassName(), QByteArray("Behavior"));
1039 }
1040
1041 // QDeclarativeDomComponent
1042 {
1043 QDeclarativeDomObject object = document.rootObject();
1044 QDeclarativeDomProperty property = object.property("data");
1045 QCOMPARE(property.value().toList().values().count(), 1);
1046 QDeclarativeDomComponent component =
1047 property.value().toList().values().at(0).toObject().toComponent();
1048 QCOMPARE(component.componentRoot().objectClassName(), QByteArray("Item"));
1049
1050 QDeclarativeDomComponent component2(component);
1051 QDeclarativeDomComponent component3;
1052 component3 = component;
1053
1054 QCOMPARE(component.componentRoot().objectClassName(), component2.componentRoot().objectClassName());
1055 QCOMPARE(component.isValid(), component2.isValid());
1056 QCOMPARE(component.objectType(), component2.objectType());
1057 QCOMPARE(component.objectClassName(), component2.objectClassName());
1058 QCOMPARE(component.objectTypeMajorVersion(), component2.objectTypeMajorVersion());
1059 QCOMPARE(component.objectTypeMinorVersion(), component2.objectTypeMinorVersion());
1060 QCOMPARE(component.objectId(), component2.objectId());
1061 QCOMPARE(component.properties().count(), component2.properties().count());
1062 QCOMPARE(component.dynamicProperties().count(), component2.dynamicProperties().count());
1063 QCOMPARE(component.isCustomType(), component2.isCustomType());
1064 QCOMPARE(component.customTypeData(), component2.customTypeData());
1065 QCOMPARE(component.isComponent(), component2.isComponent());
1066 QCOMPARE(component.position(), component2.position());
1067 QCOMPARE(component.length(), component2.length());
1068 QCOMPARE(component.url(), component2.url());
1069
1070 QCOMPARE(component.componentRoot().objectClassName(), component3.componentRoot().objectClassName());
1071 QCOMPARE(component.isValid(), component3.isValid());
1072 QCOMPARE(component.objectType(), component3.objectType());
1073 QCOMPARE(component.objectClassName(), component3.objectClassName());
1074 QCOMPARE(component.objectTypeMajorVersion(), component3.objectTypeMajorVersion());
1075 QCOMPARE(component.objectTypeMinorVersion(), component3.objectTypeMinorVersion());
1076 QCOMPARE(component.objectId(), component3.objectId());
1077 QCOMPARE(component.properties().count(), component3.properties().count());
1078 QCOMPARE(component.dynamicProperties().count(), component3.dynamicProperties().count());
1079 QCOMPARE(component.isCustomType(), component3.isCustomType());
1080 QCOMPARE(component.customTypeData(), component3.customTypeData());
1081 QCOMPARE(component.isComponent(), component3.isComponent());
1082 QCOMPARE(component.position(), component3.position());
1083 QCOMPARE(component.length(), component3.length());
1084 QCOMPARE(component.url(), component3.url());
1085 }
1086
1087 // QDeclarativeDomValue
1088 {
1089 QDeclarativeDomObject object = document.rootObject();
1090 QDeclarativeDomProperty property = object.property("data");
1091 QDeclarativeDomValue value = property.value();
1092
1093 QDeclarativeDomValue value2(value);
1094 QDeclarativeDomValue value3;
1095 value3 = value;
1096
1097 QCOMPARE(value.type(), value2.type());
1098 QCOMPARE(value.isInvalid(), value2.isInvalid());
1099 QCOMPARE(value.isLiteral(), value2.isLiteral());
1100 QCOMPARE(value.isBinding(), value2.isBinding());
1101 QCOMPARE(value.isValueSource(), value2.isValueSource());
1102 QCOMPARE(value.isValueInterceptor(), value2.isValueInterceptor());
1103 QCOMPARE(value.isObject(), value2.isObject());
1104 QCOMPARE(value.isList(), value2.isList());
1105 QCOMPARE(value.position(), value2.position());
1106 QCOMPARE(value.length(), value2.length());
1107
1108 QCOMPARE(value.type(), value3.type());
1109 QCOMPARE(value.isInvalid(), value3.isInvalid());
1110 QCOMPARE(value.isLiteral(), value3.isLiteral());
1111 QCOMPARE(value.isBinding(), value3.isBinding());
1112 QCOMPARE(value.isValueSource(), value3.isValueSource());
1113 QCOMPARE(value.isValueInterceptor(), value3.isValueInterceptor());
1114 QCOMPARE(value.isObject(), value3.isObject());
1115 QCOMPARE(value.isList(), value3.isList());
1116 QCOMPARE(value.position(), value3.position());
1117 QCOMPARE(value.length(), value3.length());
1118 }
1119 {
1120 QDeclarativeDomObject object = document.rootObject();
1121 QDeclarativeDomProperty property = object.property("x");
1122 QDeclarativeDomValue value = property.value();
1123
1124 QDeclarativeDomValue value2(value);
1125 QDeclarativeDomValue value3;
1126 value3 = value;
1127
1128 QCOMPARE(value.type(), value2.type());
1129 QCOMPARE(value.isInvalid(), value2.isInvalid());
1130 QCOMPARE(value.isLiteral(), value2.isLiteral());
1131 QCOMPARE(value.isBinding(), value2.isBinding());
1132 QCOMPARE(value.isValueSource(), value2.isValueSource());
1133 QCOMPARE(value.isValueInterceptor(), value2.isValueInterceptor());
1134 QCOMPARE(value.isObject(), value2.isObject());
1135 QCOMPARE(value.isList(), value2.isList());
1136 QCOMPARE(value.position(), value2.position());
1137 QCOMPARE(value.length(), value2.length());
1138
1139 QCOMPARE(value.type(), value3.type());
1140 QCOMPARE(value.isInvalid(), value3.isInvalid());
1141 QCOMPARE(value.isLiteral(), value3.isLiteral());
1142 QCOMPARE(value.isBinding(), value3.isBinding());
1143 QCOMPARE(value.isValueSource(), value3.isValueSource());
1144 QCOMPARE(value.isValueInterceptor(), value3.isValueInterceptor());
1145 QCOMPARE(value.isObject(), value3.isObject());
1146 QCOMPARE(value.isList(), value3.isList());
1147 QCOMPARE(value.position(), value3.position());
1148 QCOMPARE(value.length(), value3.length());
1149 }
1150 {
1151 QDeclarativeDomValue value;
1152
1153 QDeclarativeDomValue value2(value);
1154 QDeclarativeDomValue value3;
1155 value3 = value;
1156
1157 QCOMPARE(value.type(), value2.type());
1158 QCOMPARE(value.isInvalid(), value2.isInvalid());
1159 QCOMPARE(value.isLiteral(), value2.isLiteral());
1160 QCOMPARE(value.isBinding(), value2.isBinding());
1161 QCOMPARE(value.isValueSource(), value2.isValueSource());
1162 QCOMPARE(value.isValueInterceptor(), value2.isValueInterceptor());
1163 QCOMPARE(value.isObject(), value2.isObject());
1164 QCOMPARE(value.isList(), value2.isList());
1165 QCOMPARE(value.position(), value2.position());
1166 QCOMPARE(value.length(), value2.length());
1167
1168 QCOMPARE(value.type(), value3.type());
1169 QCOMPARE(value.isInvalid(), value3.isInvalid());
1170 QCOMPARE(value.isLiteral(), value3.isLiteral());
1171 QCOMPARE(value.isBinding(), value3.isBinding());
1172 QCOMPARE(value.isValueSource(), value3.isValueSource());
1173 QCOMPARE(value.isValueInterceptor(), value3.isValueInterceptor());
1174 QCOMPARE(value.isObject(), value3.isObject());
1175 QCOMPARE(value.isList(), value3.isList());
1176 QCOMPARE(value.position(), value3.position());
1177 QCOMPARE(value.length(), value3.length());
1178 }
1179
1180 // QDeclarativeDomList
1181 {
1182 QDeclarativeDomObject object = document.rootObject();
1183 QDeclarativeDomProperty property = object.property("children");
1184 QDeclarativeDomList list = property.value().toList();
1185 QCOMPARE(list.values().count(), 2);
1186
1187 QDeclarativeDomList list2(list);
1188 QDeclarativeDomList list3;
1189 list3 = list2;
1190
1191 QCOMPARE(list.values().count(), list2.values().count());
1192 QCOMPARE(list.position(), list2.position());
1193 QCOMPARE(list.length(), list2.length());
1194 QCOMPARE(list.commaPositions(), list2.commaPositions());
1195
1196 QCOMPARE(list.values().count(), list3.values().count());
1197 QCOMPARE(list.position(), list3.position());
1198 QCOMPARE(list.length(), list3.length());
1199 QCOMPARE(list.commaPositions(), list3.commaPositions());
1200
1201 }
1202 }
1203
1204 // Tests the position/length of various elements
position()1205 void tst_qdeclarativedom::position()
1206 {
1207 QByteArray qml = "import QtQuick 1.0\n"
1208 "Item {\n"
1209 " id: myItem\n"
1210 " property int a: 10\n"
1211 " x: 10\n"
1212 " y: x + 10\n"
1213 " NumberAnimation on z {}\n"
1214 " Behavior on opacity {}\n"
1215 " Component {\n"
1216 " Item{}\n"
1217 " }\n"
1218 " children: [ Item{}, Item{} ]\n"
1219 "}\n";
1220
1221
1222 QDeclarativeDomDocument document;
1223 QVERIFY(document.load(&engine, qml));
1224
1225 QDeclarativeDomObject root = document.rootObject();
1226
1227 // All QDeclarativeDomDynamicProperty
1228 QDeclarativeDomDynamicProperty dynProp = root.dynamicProperty("a");
1229 QCOMPARE(dynProp.position(), 45);
1230 QCOMPARE(dynProp.length(), 18);
1231
1232 // All QDeclarativeDomProperty
1233 QDeclarativeDomProperty x = root.property("x");
1234 QCOMPARE(x.position(), 68);
1235 QCOMPARE(x.length(), 1);
1236
1237 QDeclarativeDomProperty y = root.property("y");
1238 QCOMPARE(y.position(), 78);
1239 QCOMPARE(y.length(), 1);
1240
1241 QDeclarativeDomProperty z = root.property("z");
1242 QCOMPARE(z.position(), 111);
1243 QCOMPARE(z.length(), 1);
1244
1245 QDeclarativeDomProperty opacity = root.property("opacity");
1246 QCOMPARE(opacity.position(), 132);
1247 QCOMPARE(opacity.length(), 7);
1248
1249 QDeclarativeDomProperty data = root.property("data");
1250 QCOMPARE(data.position(), 147);
1251 QCOMPARE(data.length(), 0);
1252
1253 QDeclarativeDomProperty children = root.property("children");
1254 QCOMPARE(children.position(), 184);
1255 QCOMPARE(children.length(), 8);
1256
1257 QDeclarativeDomList dataList = data.value().toList();
1258 QCOMPARE(dataList.values().count(), 1);
1259 QDeclarativeDomList childrenList = children.value().toList();
1260 QCOMPARE(childrenList.values().count(), 2);
1261
1262 // All QDeclarativeDomObject
1263 QCOMPARE(root.position(), 19);
1264 QCOMPARE(root.length(), 195);
1265
1266 QDeclarativeDomObject numberAnimation = z.value().toValueSource().object();
1267 QCOMPARE(numberAnimation.position(), 92);
1268 QCOMPARE(numberAnimation.length(), 23);
1269
1270 QDeclarativeDomObject behavior = opacity.value().toValueInterceptor().object();
1271 QCOMPARE(behavior.position(), 120);
1272 QCOMPARE(behavior.length(), 22);
1273
1274 QDeclarativeDomObject component = dataList.values().at(0).toObject();
1275 QCOMPARE(component.position(), 147);
1276 QCOMPARE(component.length(), 32);
1277
1278 QDeclarativeDomObject componentRoot = component.toComponent().componentRoot();
1279 QCOMPARE(componentRoot.position(), 167);
1280 QCOMPARE(componentRoot.length(), 6);
1281
1282 QDeclarativeDomObject child1 = childrenList.values().at(0).toObject();
1283 QCOMPARE(child1.position(), 196);
1284 QCOMPARE(child1.length(), 6);
1285
1286 QDeclarativeDomObject child2 = childrenList.values().at(1).toObject();
1287 QCOMPARE(child2.position(), 204);
1288 QCOMPARE(child2.length(), 6);
1289
1290 // All QDeclarativeDomValue
1291 QDeclarativeDomValue xValue = x.value();
1292 QCOMPARE(xValue.position(), 71);
1293 QCOMPARE(xValue.length(), 2);
1294
1295 QDeclarativeDomValue yValue = y.value();
1296 QCOMPARE(yValue.position(), 81);
1297 QCOMPARE(yValue.length(), 6);
1298
1299 QDeclarativeDomValue zValue = z.value();
1300 QCOMPARE(zValue.position(), 92);
1301 QCOMPARE(zValue.length(), 23);
1302
1303 QDeclarativeDomValue opacityValue = opacity.value();
1304 QCOMPARE(opacityValue.position(), 120);
1305 QCOMPARE(opacityValue.length(), 22);
1306
1307 QDeclarativeDomValue dataValue = data.value();
1308 QCOMPARE(dataValue.position(), 147);
1309 QCOMPARE(dataValue.length(), 32);
1310
1311 QDeclarativeDomValue child1Value = childrenList.values().at(0);
1312 QCOMPARE(child1Value.position(), 196);
1313 QCOMPARE(child1Value.length(), 6);
1314
1315 QDeclarativeDomValue child2Value = childrenList.values().at(1);
1316 QCOMPARE(child2Value.position(), 204);
1317 QCOMPARE(child2Value.length(), 6);
1318
1319 // All QDeclarativeDomList
1320 QCOMPARE(childrenList.position(), 194);
1321 QCOMPARE(childrenList.length(), 18);
1322 }
1323
1324 QTEST_MAIN(tst_qdeclarativedom)
1325
1326 #include "tst_qdeclarativedom.moc"
1327