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