tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     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 <QtCore/qfile.h>
       
    45 #include <QtCore/qdebug.h>
       
    46 #include <QtCore/qfileinfo.h>
       
    47 #include <QtCore/qdir.h>
       
    48 
       
    49 #include <private/qdeclarativeproperty_p.h>
       
    50 #include <private/qdeclarativemetatype_p.h>
       
    51 #include <private/qdeclarativeglobal_p.h>
       
    52 
       
    53 #include "testtypes.h"
       
    54 
       
    55 #include "../../../shared/util.h"
       
    56 #include "testhttpserver.h"
       
    57 
       
    58 DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)
       
    59 
       
    60 
       
    61 /*
       
    62 This test case covers QML language issues.  This covers everything that does not
       
    63 involve evaluating ECMAScript expressions and bindings.
       
    64 
       
    65 Evaluation of expressions and bindings is covered in qmlecmascript
       
    66 */
       
    67 class tst_qdeclarativelanguage : public QObject
       
    68 {
       
    69     Q_OBJECT
       
    70 public:
       
    71     tst_qdeclarativelanguage() {
       
    72         QDeclarativeMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter);
       
    73         QFileInfo fileInfo(__FILE__);
       
    74         engine.addImportPath(fileInfo.absoluteDir().filePath(QLatin1String("data/lib")));
       
    75     }
       
    76 
       
    77 private slots:
       
    78     void initTestCase();
       
    79     void cleanupTestCase();
       
    80 
       
    81     void errors_data();
       
    82     void errors();
       
    83 
       
    84     void simpleObject();
       
    85     void simpleContainer();
       
    86     void interfaceProperty();
       
    87     void interfaceQList();
       
    88     void assignObjectToSignal();
       
    89     void assignObjectToVariant();
       
    90     void assignLiteralSignalProperty();
       
    91     void assignQmlComponent();
       
    92     void assignBasicTypes();
       
    93     void assignTypeExtremes();
       
    94     void assignCompositeToType();
       
    95     void assignLiteralToVariant();
       
    96     void customParserTypes();
       
    97     void rootAsQmlComponent();
       
    98     void inlineQmlComponents();
       
    99     void idProperty();
       
   100     void autoNotifyConnection();
       
   101     void assignSignal();
       
   102     void dynamicProperties();
       
   103     void dynamicPropertiesNested();
       
   104     void listProperties();
       
   105     void dynamicObjectProperties();
       
   106     void dynamicSignalsAndSlots();
       
   107     void simpleBindings();
       
   108     void autoComponentCreation();
       
   109     void propertyValueSource();
       
   110     void attachedProperties();
       
   111     void dynamicObjects();
       
   112     void customVariantTypes();
       
   113     void valueTypes();
       
   114     void cppnamespace();
       
   115     void aliasProperties();
       
   116     void componentCompositeType();
       
   117     void i18n();
       
   118     void i18n_data();
       
   119     void onCompleted();
       
   120     void onDestruction();
       
   121     void scriptString();
       
   122     void defaultPropertyListOrder();
       
   123     void declaredPropertyValues();
       
   124 
       
   125     void basicRemote_data();
       
   126     void basicRemote();
       
   127     void importsBuiltin_data();
       
   128     void importsBuiltin();
       
   129     void importsLocal_data();
       
   130     void importsLocal();
       
   131     void importsRemote_data();
       
   132     void importsRemote();
       
   133     void importsInstalled_data();
       
   134     void importsInstalled();
       
   135     void importsOrder_data();
       
   136     void importsOrder();
       
   137 
       
   138     void qmlAttachedPropertiesObjectMethod();
       
   139 
       
   140     void customOnProperty();
       
   141 
       
   142     // regression tests for crashes
       
   143     void crash1();
       
   144     void crash2();
       
   145 
       
   146 private:
       
   147     QDeclarativeEngine engine;
       
   148     void testType(const QString& qml, const QString& type, const QString& error);
       
   149 };
       
   150 
       
   151 #define VERIFY_ERRORS(errorfile) \
       
   152     if (!errorfile) { \
       
   153         if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
       
   154             qWarning() << "Unexpected Errors:" << component.errors(); \
       
   155         QVERIFY(!component.isError()); \
       
   156         QVERIFY(component.errors().isEmpty()); \
       
   157     } else { \
       
   158         QFile file(QLatin1String(SRCDIR) + QLatin1String("/data/") + QLatin1String(errorfile)); \
       
   159         QVERIFY(file.open(QIODevice::ReadOnly)); \
       
   160         QByteArray data = file.readAll(); \
       
   161         file.close(); \
       
   162         QList<QByteArray> expected = data.split('\n'); \
       
   163         expected.removeAll(QByteArray("")); \
       
   164         QList<QDeclarativeError> errors = component.errors(); \
       
   165         QList<QByteArray> actual; \
       
   166         for (int ii = 0; ii < errors.count(); ++ii) { \
       
   167             const QDeclarativeError &error = errors.at(ii); \
       
   168             QByteArray errorStr = QByteArray::number(error.line()) + ":" +  \
       
   169                                   QByteArray::number(error.column()) + ":" + \
       
   170                                   error.description().toUtf8(); \
       
   171             actual << errorStr; \
       
   172         } \
       
   173         if (qgetenv("DEBUG") != "" && expected != actual) \
       
   174             qWarning() << "Expected:" << expected << "Actual:" << actual;  \
       
   175         if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
       
   176             QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
       
   177             QVERIFY(file.open(QIODevice::WriteOnly)); \
       
   178             for (int ii = 0; ii < actual.count(); ++ii) { \
       
   179                 file.write(actual.at(ii)); file.write("\n"); \
       
   180             } \
       
   181             file.close(); \
       
   182         } else { \
       
   183             QCOMPARE(expected, actual); \
       
   184         } \
       
   185     }
       
   186 
       
   187 inline QUrl TEST_FILE(const QString &filename)
       
   188 {
       
   189     QFileInfo fileInfo(__FILE__);
       
   190     return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(QLatin1String("data/") + filename));
       
   191 }
       
   192 
       
   193 inline QUrl TEST_FILE(const char *filename)
       
   194 {
       
   195     return TEST_FILE(QLatin1String(filename));
       
   196 }
       
   197 
       
   198 void tst_qdeclarativelanguage::cleanupTestCase()
       
   199 {
       
   200     QVERIFY(QFile::remove(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile()));
       
   201 }
       
   202 
       
   203 void tst_qdeclarativelanguage::errors_data()
       
   204 {
       
   205     QTest::addColumn<QString>("file");
       
   206     QTest::addColumn<QString>("errorFile");
       
   207     QTest::addColumn<bool>("create");
       
   208 
       
   209     QTest::newRow("nonexistantProperty.1") << "nonexistantProperty.1.qml" << "nonexistantProperty.1.errors.txt" << false;
       
   210     QTest::newRow("nonexistantProperty.2") << "nonexistantProperty.2.qml" << "nonexistantProperty.2.errors.txt" << false;
       
   211     QTest::newRow("nonexistantProperty.3") << "nonexistantProperty.3.qml" << "nonexistantProperty.3.errors.txt" << false;
       
   212     QTest::newRow("nonexistantProperty.4") << "nonexistantProperty.4.qml" << "nonexistantProperty.4.errors.txt" << false;
       
   213     QTest::newRow("nonexistantProperty.5") << "nonexistantProperty.5.qml" << "nonexistantProperty.5.errors.txt" << false;
       
   214     QTest::newRow("nonexistantProperty.6") << "nonexistantProperty.6.qml" << "nonexistantProperty.6.errors.txt" << false;
       
   215 
       
   216     QTest::newRow("wrongType (string for int)") << "wrongType.1.qml" << "wrongType.1.errors.txt" << false;
       
   217     QTest::newRow("wrongType (int for bool)") << "wrongType.2.qml" << "wrongType.2.errors.txt" << false;
       
   218     QTest::newRow("wrongType (bad rect)") << "wrongType.3.qml" << "wrongType.3.errors.txt" << false;
       
   219 
       
   220     QTest::newRow("wrongType (invalid enum)") << "wrongType.4.qml" << "wrongType.4.errors.txt" << false;
       
   221     QTest::newRow("wrongType (int for uint)") << "wrongType.5.qml" << "wrongType.5.errors.txt" << false;
       
   222     QTest::newRow("wrongType (string for real)") << "wrongType.6.qml" << "wrongType.6.errors.txt" << false;
       
   223     QTest::newRow("wrongType (int for color)") << "wrongType.7.qml" << "wrongType.7.errors.txt" << false;
       
   224     QTest::newRow("wrongType (int for date)") << "wrongType.8.qml" << "wrongType.8.errors.txt" << false;
       
   225     QTest::newRow("wrongType (int for time)") << "wrongType.9.qml" << "wrongType.9.errors.txt" << false;
       
   226     QTest::newRow("wrongType (int for datetime)") << "wrongType.10.qml" << "wrongType.10.errors.txt" << false;
       
   227     QTest::newRow("wrongType (string for point)") << "wrongType.11.qml" << "wrongType.11.errors.txt" << false;
       
   228     QTest::newRow("wrongType (color for size)") << "wrongType.12.qml" << "wrongType.12.errors.txt" << false;
       
   229     QTest::newRow("wrongType (number string for int)") << "wrongType.13.qml" << "wrongType.13.errors.txt" << false;
       
   230     QTest::newRow("wrongType (int for string)") << "wrongType.14.qml" << "wrongType.14.errors.txt" << false;
       
   231     QTest::newRow("wrongType (int for url)") << "wrongType.15.qml" << "wrongType.15.errors.txt" << false;
       
   232     QTest::newRow("wrongType (invalid object)") << "wrongType.16.qml" << "wrongType.16.errors.txt" << false;
       
   233 
       
   234     QTest::newRow("readOnly.1") << "readOnly.1.qml" << "readOnly.1.errors.txt" << false;
       
   235     QTest::newRow("readOnly.2") << "readOnly.2.qml" << "readOnly.2.errors.txt" << false;
       
   236     QTest::newRow("readOnly.3") << "readOnly.3.qml" << "readOnly.3.errors.txt" << false;
       
   237     QTest::newRow("readOnly.4") << "readOnly.4.qml" << "readOnly.4.errors.txt" << false;
       
   238     QTest::newRow("readOnly.5") << "readOnly.5.qml" << "readOnly.5.errors.txt" << false;
       
   239 
       
   240     QTest::newRow("listAssignment.1") << "listAssignment.1.qml" << "listAssignment.1.errors.txt" << false;
       
   241     QTest::newRow("listAssignment.2") << "listAssignment.2.qml" << "listAssignment.2.errors.txt" << false;
       
   242     QTest::newRow("listAssignment.3") << "listAssignment.3.qml" << "listAssignment.3.errors.txt" << false;
       
   243 
       
   244     QTest::newRow("invalidID.1") << "invalidID.qml" << "invalidID.errors.txt" << false;
       
   245     QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
       
   246     QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
       
   247     QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
       
   248     QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
       
   249     QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false;
       
   250     QTest::newRow("invalidID.7") << "invalidID.7.qml" << "invalidID.7.errors.txt" << false;
       
   251     QTest::newRow("invalidID.8") << "invalidID.8.qml" << "invalidID.8.errors.txt" << false;
       
   252     QTest::newRow("invalidID.9") << "invalidID.9.qml" << "invalidID.9.errors.txt" << false;
       
   253 
       
   254     QTest::newRow("scriptString.1") << "scriptString.1.qml" << "scriptString.1.errors.txt" << false;
       
   255     QTest::newRow("scriptString.2") << "scriptString.2.qml" << "scriptString.2.errors.txt" << false;
       
   256 
       
   257     QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
       
   258     QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;
       
   259     QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false;
       
   260     QTest::newRow("duplicateIDs") << "duplicateIDs.qml" << "duplicateIDs.errors.txt" << false;
       
   261     QTest::newRow("unregisteredObject") << "unregisteredObject.qml" << "unregisteredObject.errors.txt" << false;
       
   262     QTest::newRow("empty") << "empty.qml" << "empty.errors.txt" << false;
       
   263     QTest::newRow("missingObject") << "missingObject.qml" << "missingObject.errors.txt" << false;
       
   264     QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
       
   265     QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
       
   266     QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
       
   267     QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
       
   268 
       
   269     QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
       
   270     QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
       
   271     QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
       
   272     QTest::newRow("invalidGroupedProperty.4") << "invalidGroupedProperty.4.qml" << "invalidGroupedProperty.4.errors.txt" << false;
       
   273     QTest::newRow("invalidGroupedProperty.5") << "invalidGroupedProperty.5.qml" << "invalidGroupedProperty.5.errors.txt" << false;
       
   274     QTest::newRow("invalidGroupedProperty.6") << "invalidGroupedProperty.6.qml" << "invalidGroupedProperty.6.errors.txt" << false;
       
   275     QTest::newRow("invalidGroupedProperty.7") << "invalidGroupedProperty.7.qml" << "invalidGroupedProperty.7.errors.txt" << true;
       
   276     QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
       
   277     QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
       
   278     QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
       
   279 
       
   280     QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
       
   281     QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
       
   282     QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false;
       
   283     QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false;
       
   284     QTest::newRow("importNonExistOlder (installed)") << "importNonExistOlder.qml" << "importNonExistOlder.errors.txt" << false;
       
   285     QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false;
       
   286     QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false;
       
   287 
       
   288     QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false;
       
   289     QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false;
       
   290     QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false;
       
   291     QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false;
       
   292 
       
   293     QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
       
   294 
       
   295     QTest::newRow("property.1") << "property.1.qml" << "property.1.errors.txt" << false;
       
   296     QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
       
   297     QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
       
   298     QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
       
   299     QTest::newRow("property.5") << "property.5.qml" << "property.5.errors.txt" << false;
       
   300     QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
       
   301     QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
       
   302 
       
   303     QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
       
   304 
       
   305     QTest::newRow("Component.1") << "component.1.qml" << "component.1.errors.txt" << false;
       
   306     QTest::newRow("Component.2") << "component.2.qml" << "component.2.errors.txt" << false;
       
   307     QTest::newRow("Component.3") << "component.3.qml" << "component.3.errors.txt" << false;
       
   308     QTest::newRow("Component.4") << "component.4.qml" << "component.4.errors.txt" << false;
       
   309     QTest::newRow("Component.5") << "component.5.qml" << "component.5.errors.txt" << false;
       
   310     QTest::newRow("Component.6") << "component.6.qml" << "component.6.errors.txt" << false;
       
   311     QTest::newRow("Component.7") << "component.7.qml" << "component.7.errors.txt" << false;
       
   312     QTest::newRow("Component.8") << "component.8.qml" << "component.8.errors.txt" << false;
       
   313     QTest::newRow("Component.9") << "component.9.qml" << "component.9.errors.txt" << false;
       
   314 
       
   315     QTest::newRow("MultiSet.1") << "multiSet.1.qml" << "multiSet.1.errors.txt" << false;
       
   316     QTest::newRow("MultiSet.2") << "multiSet.2.qml" << "multiSet.2.errors.txt" << false;
       
   317     QTest::newRow("MultiSet.3") << "multiSet.3.qml" << "multiSet.3.errors.txt" << false;
       
   318     QTest::newRow("MultiSet.4") << "multiSet.4.qml" << "multiSet.4.errors.txt" << false;
       
   319     QTest::newRow("MultiSet.5") << "multiSet.5.qml" << "multiSet.5.errors.txt" << false;
       
   320     QTest::newRow("MultiSet.6") << "multiSet.6.qml" << "multiSet.6.errors.txt" << false;
       
   321     QTest::newRow("MultiSet.7") << "multiSet.7.qml" << "multiSet.7.errors.txt" << false;
       
   322     QTest::newRow("MultiSet.8") << "multiSet.8.qml" << "multiSet.8.errors.txt" << false;
       
   323     QTest::newRow("MultiSet.9") << "multiSet.9.qml" << "multiSet.9.errors.txt" << false;
       
   324     QTest::newRow("MultiSet.10") << "multiSet.10.qml" << "multiSet.10.errors.txt" << false;
       
   325     QTest::newRow("MultiSet.11") << "multiSet.11.qml" << "multiSet.11.errors.txt" << false;
       
   326 
       
   327     QTest::newRow("dynamicMeta.1") << "dynamicMeta.1.qml" << "dynamicMeta.1.errors.txt" << false;
       
   328     QTest::newRow("dynamicMeta.2") << "dynamicMeta.2.qml" << "dynamicMeta.2.errors.txt" << false;
       
   329     QTest::newRow("dynamicMeta.3") << "dynamicMeta.3.qml" << "dynamicMeta.3.errors.txt" << false;
       
   330     QTest::newRow("dynamicMeta.4") << "dynamicMeta.4.qml" << "dynamicMeta.4.errors.txt" << false;
       
   331     QTest::newRow("dynamicMeta.5") << "dynamicMeta.5.qml" << "dynamicMeta.5.errors.txt" << false;
       
   332 
       
   333     QTest::newRow("invalidAlias.1") << "invalidAlias.1.qml" << "invalidAlias.1.errors.txt" << false;
       
   334     QTest::newRow("invalidAlias.2") << "invalidAlias.2.qml" << "invalidAlias.2.errors.txt" << false;
       
   335     QTest::newRow("invalidAlias.3") << "invalidAlias.3.qml" << "invalidAlias.3.errors.txt" << false;
       
   336     QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false;
       
   337     QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
       
   338     QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
       
   339 
       
   340     QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
       
   341     QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
       
   342     QTest::newRow("invalidAttachedProperty.3") << "invalidAttachedProperty.3.qml" << "invalidAttachedProperty.3.errors.txt" << false;
       
   343     QTest::newRow("invalidAttachedProperty.4") << "invalidAttachedProperty.4.qml" << "invalidAttachedProperty.4.errors.txt" << false;
       
   344     QTest::newRow("invalidAttachedProperty.5") << "invalidAttachedProperty.5.qml" << "invalidAttachedProperty.5.errors.txt" << false;
       
   345     QTest::newRow("invalidAttachedProperty.6") << "invalidAttachedProperty.6.qml" << "invalidAttachedProperty.6.errors.txt" << false;
       
   346     QTest::newRow("invalidAttachedProperty.7") << "invalidAttachedProperty.7.qml" << "invalidAttachedProperty.7.errors.txt" << false;
       
   347     QTest::newRow("invalidAttachedProperty.8") << "invalidAttachedProperty.8.qml" << "invalidAttachedProperty.8.errors.txt" << false;
       
   348     QTest::newRow("invalidAttachedProperty.9") << "invalidAttachedProperty.9.qml" << "invalidAttachedProperty.9.errors.txt" << false;
       
   349     QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false;
       
   350     QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false;
       
   351     QTest::newRow("invalidAttachedProperty.12") << "invalidAttachedProperty.12.qml" << "invalidAttachedProperty.12.errors.txt" << false;
       
   352     QTest::newRow("invalidAttachedProperty.13") << "invalidAttachedProperty.13.qml" << "invalidAttachedProperty.13.errors.txt" << false;
       
   353 
       
   354     QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
       
   355     QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
       
   356 
       
   357     QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false;
       
   358     QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false;
       
   359     QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false;
       
   360     QTest::newRow("invalidRoot") << "invalidRoot.qml" << "invalidRoot.errors.txt" << false;
       
   361     QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false;
       
   362     QTest::newRow("objectValueTypeProperty") << "objectValueTypeProperty.qml" << "objectValueTypeProperty.errors.txt" << false;
       
   363     QTest::newRow("enumTypes") << "enumTypes.qml" << "enumTypes.errors.txt" << false;
       
   364     QTest::newRow("noCreation") << "noCreation.qml" << "noCreation.errors.txt" << false;
       
   365     QTest::newRow("destroyedSignal") << "destroyedSignal.qml" << "destroyedSignal.errors.txt" << false;
       
   366     QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false;
       
   367     QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false;
       
   368 }
       
   369 
       
   370 
       
   371 void tst_qdeclarativelanguage::errors()
       
   372 {
       
   373     QFETCH(QString, file);
       
   374     QFETCH(QString, errorFile);
       
   375     QFETCH(bool, create);
       
   376 
       
   377     QDeclarativeComponent component(&engine, TEST_FILE(file));
       
   378 
       
   379     if(create) {
       
   380         QObject *object = component.create();
       
   381         QVERIFY(object == 0);
       
   382     }
       
   383 
       
   384     VERIFY_ERRORS(errorFile.toLatin1().constData());
       
   385 }
       
   386 
       
   387 void tst_qdeclarativelanguage::simpleObject()
       
   388 {
       
   389     QDeclarativeComponent component(&engine, TEST_FILE("simpleObject.qml"));
       
   390     VERIFY_ERRORS(0);
       
   391     QObject *object = component.create();
       
   392     QVERIFY(object != 0);
       
   393 }
       
   394 
       
   395 void tst_qdeclarativelanguage::simpleContainer()
       
   396 {
       
   397     QDeclarativeComponent component(&engine, TEST_FILE("simpleContainer.qml"));
       
   398     VERIFY_ERRORS(0);
       
   399     MyContainer *container= qobject_cast<MyContainer*>(component.create());
       
   400     QVERIFY(container != 0);
       
   401     QCOMPARE(container->getChildren()->count(),2);
       
   402 }
       
   403 
       
   404 void tst_qdeclarativelanguage::interfaceProperty()
       
   405 {
       
   406     QDeclarativeComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
       
   407     VERIFY_ERRORS(0);
       
   408     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
       
   409     QVERIFY(object != 0);
       
   410     QVERIFY(object->interface());
       
   411     QVERIFY(object->interface()->id == 913);
       
   412 }
       
   413 
       
   414 void tst_qdeclarativelanguage::interfaceQList()
       
   415 {
       
   416     QDeclarativeComponent component(&engine, TEST_FILE("interfaceQList.qml"));
       
   417     VERIFY_ERRORS(0);
       
   418     MyContainer *container= qobject_cast<MyContainer*>(component.create());
       
   419     QVERIFY(container != 0);
       
   420     QVERIFY(container->getQListInterfaces()->count() == 2);
       
   421     for(int ii = 0; ii < 2; ++ii)
       
   422         QVERIFY(container->getQListInterfaces()->at(ii)->id == 913);
       
   423 }
       
   424 
       
   425 void tst_qdeclarativelanguage::assignObjectToSignal()
       
   426 {
       
   427     QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
       
   428     VERIFY_ERRORS(0);
       
   429     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
       
   430     QVERIFY(object != 0);
       
   431     QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
       
   432     emit object->basicSignal();
       
   433 }
       
   434 
       
   435 void tst_qdeclarativelanguage::assignObjectToVariant()
       
   436 {
       
   437     QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
       
   438     VERIFY_ERRORS(0);
       
   439     QObject *object = component.create();
       
   440     QVERIFY(object != 0);
       
   441     QVariant v = object->property("a");
       
   442     QVERIFY(v.userType() == qMetaTypeId<QObject *>());
       
   443 }
       
   444 
       
   445 void tst_qdeclarativelanguage::assignLiteralSignalProperty()
       
   446 {
       
   447     QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
       
   448     VERIFY_ERRORS(0);
       
   449     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
       
   450     QVERIFY(object != 0);
       
   451     QCOMPARE(object->onLiteralSignal(), 10);
       
   452 }
       
   453 
       
   454 // Test is an external component can be loaded and assigned (to a qlist)
       
   455 void tst_qdeclarativelanguage::assignQmlComponent()
       
   456 {
       
   457     QDeclarativeComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
       
   458     VERIFY_ERRORS(0);
       
   459     MyContainer *object = qobject_cast<MyContainer *>(component.create());
       
   460     QVERIFY(object != 0);
       
   461     QVERIFY(object->getChildren()->count() == 1);
       
   462     QObject *child = object->getChildren()->at(0);
       
   463     QCOMPARE(child->property("x"), QVariant(10));
       
   464     QCOMPARE(child->property("y"), QVariant(11));
       
   465 }
       
   466 
       
   467 // Test literal assignment to all the basic types 
       
   468 void tst_qdeclarativelanguage::assignBasicTypes()
       
   469 {
       
   470     QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
       
   471     VERIFY_ERRORS(0);
       
   472     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
       
   473     QVERIFY(object != 0);
       
   474     QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
       
   475     QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
       
   476     QCOMPARE(object->stringProperty(), QString("Hello World!"));
       
   477     QCOMPARE(object->uintProperty(), uint(10));
       
   478     QCOMPARE(object->intProperty(), -19);
       
   479     QCOMPARE((float)object->realProperty(), float(23.2));
       
   480     QCOMPARE((float)object->doubleProperty(), float(-19.7));
       
   481     QCOMPARE((float)object->floatProperty(), float(8.5));
       
   482     QCOMPARE(object->colorProperty(), QColor("red"));
       
   483     QCOMPARE(object->dateProperty(), QDate(1982, 11, 25));
       
   484     QCOMPARE(object->timeProperty(), QTime(11, 11, 32));
       
   485     QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1)));
       
   486     QCOMPARE(object->pointProperty(), QPoint(99,13));
       
   487     QCOMPARE(object->pointFProperty(), QPointF((float)-10.1, (float)12.3));
       
   488     QCOMPARE(object->sizeProperty(), QSize(99, 13));
       
   489     QCOMPARE(object->sizeFProperty(), QSizeF((float)0.1, (float)0.2));
       
   490     QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200));
       
   491     QCOMPARE(object->rectFProperty(), QRectF((float)1000.1, (float)-10.9, (float)400, (float)90.99));
       
   492     QCOMPARE(object->boolProperty(), true);
       
   493     QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
       
   494     QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2));
       
   495     QCOMPARE(object->urlProperty(), component.url().resolved(QUrl("main.qml")));
       
   496     QVERIFY(object->objectProperty() != 0);
       
   497     MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
       
   498     QVERIFY(child != 0);
       
   499     QCOMPARE(child->intProperty(), 8);
       
   500 }
       
   501 
       
   502 // Test edge case type assignments
       
   503 void tst_qdeclarativelanguage::assignTypeExtremes()
       
   504 {
       
   505     QDeclarativeComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
       
   506     VERIFY_ERRORS(0);
       
   507     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
       
   508     QVERIFY(object != 0);
       
   509     QCOMPARE(object->uintProperty(), 0xEE6B2800);
       
   510     QCOMPARE(object->intProperty(), -0x77359400);
       
   511 }
       
   512 
       
   513 // Test that a composite type can assign to a property of its base type
       
   514 void tst_qdeclarativelanguage::assignCompositeToType()
       
   515 {
       
   516     QDeclarativeComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
       
   517     VERIFY_ERRORS(0);
       
   518     QObject *object = component.create();
       
   519     QVERIFY(object != 0);
       
   520 }
       
   521 
       
   522 // Test that literals are stored correctly in variant properties
       
   523 void tst_qdeclarativelanguage::assignLiteralToVariant()
       
   524 {
       
   525     QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
       
   526     VERIFY_ERRORS(0);
       
   527     QObject *object = component.create();
       
   528     QVERIFY(object != 0);
       
   529 
       
   530     QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
       
   531     QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
       
   532     QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
       
   533     QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
       
   534     QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
       
   535     QCOMPARE(object->property("test6").userType(), (int)QVariant::PointF);
       
   536     QCOMPARE(object->property("test7").userType(), (int)QVariant::SizeF);
       
   537     QCOMPARE(object->property("test8").userType(), (int)QVariant::Vector3D);
       
   538     QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
       
   539     QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
       
   540     QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
       
   541 
       
   542     QVERIFY(object->property("test1") == QVariant(1));
       
   543     QVERIFY(object->property("test2") == QVariant((double)1.7));
       
   544     QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!"))));
       
   545     QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800)));
       
   546     QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10)));
       
   547     QVERIFY(object->property("test6") == QVariant(QPointF(10, 10)));
       
   548     QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10)));
       
   549     QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100)));
       
   550     QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800"))));
       
   551     QVERIFY(object->property("test10") == QVariant(bool(true)));
       
   552     QVERIFY(object->property("test11") == QVariant(bool(false)));
       
   553 
       
   554     delete object;
       
   555 }
       
   556 
       
   557 // Tests that custom parser types can be instantiated
       
   558 void tst_qdeclarativelanguage::customParserTypes()
       
   559 {
       
   560     QDeclarativeComponent component(&engine, TEST_FILE("customParserTypes.qml"));
       
   561     VERIFY_ERRORS(0);
       
   562     QObject *object = component.create();
       
   563     QVERIFY(object != 0);
       
   564     QVERIFY(object->property("count") == QVariant(2));
       
   565 }
       
   566 
       
   567 // Tests that the root item can be a custom component
       
   568 void tst_qdeclarativelanguage::rootAsQmlComponent()
       
   569 {
       
   570     QDeclarativeComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
       
   571     VERIFY_ERRORS(0);
       
   572     MyContainer *object = qobject_cast<MyContainer *>(component.create());
       
   573     QVERIFY(object != 0);
       
   574     QCOMPARE(object->property("x"), QVariant(11));
       
   575     QCOMPARE(object->getChildren()->count(), 2);
       
   576 }
       
   577 
       
   578 // Tests that components can be specified inline
       
   579 void tst_qdeclarativelanguage::inlineQmlComponents()
       
   580 {
       
   581     QDeclarativeComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
       
   582     VERIFY_ERRORS(0);
       
   583     MyContainer *object = qobject_cast<MyContainer *>(component.create());
       
   584     QVERIFY(object != 0);
       
   585     QCOMPARE(object->getChildren()->count(), 1);
       
   586     QDeclarativeComponent *comp = qobject_cast<QDeclarativeComponent *>(object->getChildren()->at(0));
       
   587     QVERIFY(comp != 0);
       
   588     MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
       
   589     QVERIFY(compObject != 0);
       
   590     QCOMPARE(compObject->value(), 11);
       
   591 }
       
   592 
       
   593 // Tests that types that have an id property have it set
       
   594 void tst_qdeclarativelanguage::idProperty()
       
   595 {
       
   596     QDeclarativeComponent component(&engine, TEST_FILE("idProperty.qml"));
       
   597     VERIFY_ERRORS(0);
       
   598     MyContainer *object = qobject_cast<MyContainer *>(component.create());
       
   599     QVERIFY(object != 0);
       
   600     QCOMPARE(object->getChildren()->count(), 1);
       
   601     MyTypeObject *child = 
       
   602         qobject_cast<MyTypeObject *>(object->getChildren()->at(0));
       
   603     QVERIFY(child != 0);
       
   604     QCOMPARE(child->id(), QString("myObjectId"));
       
   605     QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
       
   606 }
       
   607 
       
   608 // Tests automatic connection to notify signals if "onBlahChanged" syntax is used
       
   609 // even if the notify signal for "blah" is not called "blahChanged"
       
   610 void tst_qdeclarativelanguage::autoNotifyConnection()
       
   611 {
       
   612     QDeclarativeComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
       
   613     VERIFY_ERRORS(0);
       
   614     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
       
   615     QVERIFY(object != 0);
       
   616     QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
       
   617     QVERIFY(prop.isValid());
       
   618 
       
   619     QCOMPARE(prop.read(object), QVariant::fromValue(false));
       
   620     object->setPropertyWithNotify(1);
       
   621     QCOMPARE(prop.read(object), QVariant::fromValue(true));
       
   622 }
       
   623 
       
   624 // Tests that signals can be assigned to
       
   625 void tst_qdeclarativelanguage::assignSignal()
       
   626 {
       
   627     QDeclarativeComponent component(&engine, TEST_FILE("assignSignal.qml"));
       
   628     VERIFY_ERRORS(0);
       
   629     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
       
   630     QVERIFY(object != 0);
       
   631     QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
       
   632     emit object->basicSignal();
       
   633     QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)");
       
   634     emit object->basicParameterizedSignal(9);
       
   635 }
       
   636 
       
   637 // Tests the creation and assignment of dynamic properties
       
   638 void tst_qdeclarativelanguage::dynamicProperties()
       
   639 {
       
   640     QDeclarativeComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
       
   641     VERIFY_ERRORS(0);
       
   642     QObject *object = component.create();
       
   643     QVERIFY(object != 0);
       
   644     QCOMPARE(object->property("intProperty"), QVariant(10));
       
   645     QCOMPARE(object->property("boolProperty"), QVariant(false));
       
   646     QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
       
   647     QCOMPARE(object->property("realProperty"), QVariant((qreal)-19.9));
       
   648     QCOMPARE(object->property("stringProperty"), QVariant("Hello World!"));
       
   649     QCOMPARE(object->property("urlProperty"), QVariant(TEST_FILE("main.qml")));
       
   650     QCOMPARE(object->property("colorProperty"), QVariant(QColor("red")));
       
   651     QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2)));
       
   652     QCOMPARE(object->property("varProperty"), QVariant("Hello World!"));
       
   653 }
       
   654 
       
   655 // Test that nested types can use dynamic properties
       
   656 void tst_qdeclarativelanguage::dynamicPropertiesNested()
       
   657 {
       
   658     QDeclarativeComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
       
   659     VERIFY_ERRORS(0);
       
   660     QObject *object = component.create();
       
   661     QVERIFY(object != 0);
       
   662 
       
   663     QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
       
   664     QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
       
   665     QCOMPARE(object->property("a").toInt(), 13); // New
       
   666     QCOMPARE(object->property("b").toInt(), 12); // New
       
   667 
       
   668     delete object;
       
   669 }
       
   670 
       
   671 // Tests the creation and assignment to dynamic list properties
       
   672 void tst_qdeclarativelanguage::listProperties()
       
   673 {
       
   674     QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml"));
       
   675     VERIFY_ERRORS(0);
       
   676     QObject *object = component.create();
       
   677     QVERIFY(object != 0);
       
   678 
       
   679     QCOMPARE(object->property("test").toInt(), 2);
       
   680 }
       
   681 
       
   682 // Tests the creation and assignment of dynamic object properties
       
   683 // ### Not complete
       
   684 void tst_qdeclarativelanguage::dynamicObjectProperties()
       
   685 {
       
   686     {
       
   687     QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
       
   688     VERIFY_ERRORS(0);
       
   689     QObject *object = component.create();
       
   690     QVERIFY(object != 0);
       
   691 
       
   692     QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
       
   693     QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
       
   694     }
       
   695     {
       
   696     QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
       
   697     QEXPECT_FAIL("", "QTBUG-10822", Abort);
       
   698     VERIFY_ERRORS(0);
       
   699     QObject *object = component.create();
       
   700     QVERIFY(object != 0);
       
   701 
       
   702     QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
       
   703     }
       
   704 }
       
   705 
       
   706 // Tests the declaration of dynamic signals and slots
       
   707 void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
       
   708 {
       
   709     QTest::ignoreMessage(QtDebugMsg, "1921");
       
   710 
       
   711     QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
       
   712     VERIFY_ERRORS(0);
       
   713     QObject *object = component.create();
       
   714     QVERIFY(object != 0);
       
   715     QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
       
   716     QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
       
   717     QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1);
       
   718     QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
       
   719 
       
   720     QCOMPARE(object->property("test").toInt(), 0);
       
   721     QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
       
   722     QCOMPARE(object->property("test").toInt(), 10);
       
   723 }
       
   724 
       
   725 void tst_qdeclarativelanguage::simpleBindings()
       
   726 {
       
   727     QDeclarativeComponent component(&engine, TEST_FILE("simpleBindings.qml"));
       
   728     VERIFY_ERRORS(0);
       
   729     QObject *object = component.create();
       
   730     QVERIFY(object != 0);
       
   731     QCOMPARE(object->property("value1"), QVariant(10));
       
   732     QCOMPARE(object->property("value2"), QVariant(10));
       
   733     QCOMPARE(object->property("value3"), QVariant(21));
       
   734     QCOMPARE(object->property("value4"), QVariant(10));
       
   735     QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
       
   736 }
       
   737 
       
   738 void tst_qdeclarativelanguage::autoComponentCreation()
       
   739 {
       
   740     QDeclarativeComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
       
   741     VERIFY_ERRORS(0);
       
   742     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
       
   743     QVERIFY(object != 0);
       
   744     QVERIFY(object->componentProperty() != 0);
       
   745     MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
       
   746     QVERIFY(child != 0);
       
   747     QCOMPARE(child->realProperty(), qreal(9));
       
   748 }
       
   749 
       
   750 void tst_qdeclarativelanguage::propertyValueSource()
       
   751 {
       
   752     {
       
   753     QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
       
   754     VERIFY_ERRORS(0);
       
   755     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
       
   756     QVERIFY(object != 0);
       
   757 
       
   758     QList<QObject *> valueSources;
       
   759     QObjectList allChildren = object->findChildren<QObject*>();
       
   760     foreach (QObject *child, allChildren) {
       
   761         if (qobject_cast<QDeclarativePropertyValueSource *>(child)) 
       
   762             valueSources.append(child);
       
   763     }
       
   764 
       
   765     QCOMPARE(valueSources.count(), 1);
       
   766     MyPropertyValueSource *valueSource = 
       
   767         qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
       
   768     QVERIFY(valueSource != 0);
       
   769     QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
       
   770     QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
       
   771     }
       
   772 
       
   773     {
       
   774     QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
       
   775     VERIFY_ERRORS(0);
       
   776     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
       
   777     QVERIFY(object != 0);
       
   778 
       
   779     QList<QObject *> valueSources;
       
   780     QObjectList allChildren = object->findChildren<QObject*>();
       
   781     foreach (QObject *child, allChildren) {
       
   782         if (qobject_cast<QDeclarativePropertyValueSource *>(child)) 
       
   783             valueSources.append(child);
       
   784     }
       
   785 
       
   786     QCOMPARE(valueSources.count(), 1);
       
   787     MyPropertyValueSource *valueSource = 
       
   788         qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
       
   789     QVERIFY(valueSource != 0);
       
   790     QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
       
   791     QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
       
   792     }
       
   793 }
       
   794 
       
   795 void tst_qdeclarativelanguage::attachedProperties()
       
   796 {
       
   797     QDeclarativeComponent component(&engine, TEST_FILE("attachedProperties.qml"));
       
   798     VERIFY_ERRORS(0);
       
   799     QObject *object = component.create();
       
   800     QVERIFY(object != 0);
       
   801     QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
       
   802     QVERIFY(attached != 0);
       
   803     QCOMPARE(attached->property("value"), QVariant(10));
       
   804     QCOMPARE(attached->property("value2"), QVariant(13));
       
   805 }
       
   806 
       
   807 // Tests non-static object properties
       
   808 void tst_qdeclarativelanguage::dynamicObjects()
       
   809 {
       
   810     QDeclarativeComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
       
   811     VERIFY_ERRORS(0);
       
   812     QObject *object = component.create();
       
   813     QVERIFY(object != 0);
       
   814 }
       
   815 
       
   816 // Tests the registration of custom variant string converters
       
   817 void tst_qdeclarativelanguage::customVariantTypes()
       
   818 {
       
   819     QDeclarativeComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
       
   820     VERIFY_ERRORS(0);
       
   821     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
       
   822     QVERIFY(object != 0);
       
   823     QCOMPARE(object->customType().a, 10);
       
   824 }
       
   825 
       
   826 void tst_qdeclarativelanguage::valueTypes()
       
   827 {
       
   828     QDeclarativeComponent component(&engine, TEST_FILE("valueTypes.qml"));
       
   829     VERIFY_ERRORS(0);
       
   830 
       
   831     QString message = component.url().toString() + ":2:1: QML MyTypeObject: Binding loop detected for property \"rectProperty.width\"";
       
   832     QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
       
   833     QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
       
   834 
       
   835     MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
       
   836     QVERIFY(object != 0);
       
   837 
       
   838 
       
   839     QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
       
   840     QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
       
   841     QCOMPARE(object->intProperty(), 10);
       
   842     object->doAction();
       
   843     QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
       
   844     QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
       
   845     QCOMPARE(object->intProperty(), 12);
       
   846 
       
   847     // ###
       
   848 #if 0
       
   849     QDeclarativeProperty p(object, "rectProperty.x");
       
   850     QCOMPARE(p.read(), QVariant(12));
       
   851     p.write(13);
       
   852     QCOMPARE(p.read(), QVariant(13));
       
   853 
       
   854     quint32 r = QDeclarativePropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
       
   855     QDeclarativeProperty p2;
       
   856     QDeclarativePropertyPrivate::restore(p2, r, object);
       
   857     QCOMPARE(p2.read(), QVariant(13));
       
   858 #endif
       
   859 }
       
   860 
       
   861 void tst_qdeclarativelanguage::cppnamespace()
       
   862 {
       
   863     {
       
   864         QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.qml"));
       
   865         VERIFY_ERRORS(0);
       
   866         QObject *object = component.create();
       
   867         QVERIFY(object != 0);
       
   868         delete object;
       
   869     }
       
   870 
       
   871     {
       
   872         QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
       
   873         VERIFY_ERRORS(0);
       
   874         QObject *object = component.create();
       
   875         QVERIFY(object != 0);
       
   876         delete object;
       
   877     }
       
   878 }
       
   879 
       
   880 void tst_qdeclarativelanguage::aliasProperties()
       
   881 {
       
   882     // Simple "int" alias
       
   883     {
       
   884         QDeclarativeComponent component(&engine, TEST_FILE("alias.1.qml"));
       
   885         VERIFY_ERRORS(0);
       
   886         QObject *object = component.create();
       
   887         QVERIFY(object != 0);
       
   888 
       
   889         // Read through alias
       
   890         QCOMPARE(object->property("valueAlias").toInt(), 10);
       
   891         object->setProperty("value", QVariant(13));
       
   892         QCOMPARE(object->property("valueAlias").toInt(), 13);
       
   893 
       
   894         // Write throught alias
       
   895         object->setProperty("valueAlias", QVariant(19));
       
   896         QCOMPARE(object->property("valueAlias").toInt(), 19);
       
   897         QCOMPARE(object->property("value").toInt(), 19);
       
   898 
       
   899         delete object;
       
   900     }
       
   901 
       
   902     // Complex object alias
       
   903     {
       
   904         QDeclarativeComponent component(&engine, TEST_FILE("alias.2.qml"));
       
   905         VERIFY_ERRORS(0);
       
   906         QObject *object = component.create();
       
   907         QVERIFY(object != 0);
       
   908 
       
   909         // Read through alias
       
   910         MyQmlObject *v = 
       
   911             qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
       
   912         QVERIFY(v != 0);
       
   913         QCOMPARE(v->value(), 10);
       
   914 
       
   915         // Write through alias
       
   916         MyQmlObject *v2 = new MyQmlObject();
       
   917         v2->setParent(object);
       
   918         object->setProperty("aliasObject", qVariantFromValue(v2));
       
   919         MyQmlObject *v3 = 
       
   920             qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
       
   921         QVERIFY(v3 != 0);
       
   922         QCOMPARE(v3, v2);
       
   923 
       
   924         delete object;
       
   925     }
       
   926 
       
   927     // Nested aliases
       
   928     {
       
   929         QDeclarativeComponent component(&engine, TEST_FILE("alias.3.qml"));
       
   930         VERIFY_ERRORS(0);
       
   931         QObject *object = component.create();
       
   932         QVERIFY(object != 0);
       
   933 
       
   934         QCOMPARE(object->property("value").toInt(), 1892);
       
   935         QCOMPARE(object->property("value2").toInt(), 1892);
       
   936 
       
   937         object->setProperty("value", QVariant(1313));
       
   938         QCOMPARE(object->property("value").toInt(), 1313);
       
   939         QCOMPARE(object->property("value2").toInt(), 1313);
       
   940 
       
   941         object->setProperty("value2", QVariant(8080));
       
   942         QCOMPARE(object->property("value").toInt(), 8080);
       
   943         QCOMPARE(object->property("value2").toInt(), 8080);
       
   944 
       
   945         delete object;
       
   946     }
       
   947 
       
   948     // Enum aliases
       
   949     {
       
   950         QDeclarativeComponent component(&engine, TEST_FILE("alias.4.qml"));
       
   951         VERIFY_ERRORS(0);
       
   952         QObject *object = component.create();
       
   953         QVERIFY(object != 0);
       
   954 
       
   955         QCOMPARE(object->property("enumAlias").toInt(), 1);
       
   956 
       
   957         delete object;
       
   958     }
       
   959 
       
   960     // Id aliases
       
   961     {
       
   962         QDeclarativeComponent component(&engine, TEST_FILE("alias.5.qml"));
       
   963         VERIFY_ERRORS(0);
       
   964         QObject *object = component.create();
       
   965         QVERIFY(object != 0);
       
   966 
       
   967         QVariant v = object->property("otherAlias");
       
   968         QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
       
   969         MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
       
   970         QCOMPARE(o->value(), 10);
       
   971 
       
   972         delete o;
       
   973 
       
   974         v = object->property("otherAlias");
       
   975         QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
       
   976         o = qvariant_cast<MyQmlObject*>(v);
       
   977         QVERIFY(o == 0);
       
   978 
       
   979         delete object;
       
   980     }
       
   981 
       
   982     // Nested aliases - this used to cause a crash
       
   983     {
       
   984         QDeclarativeComponent component(&engine, TEST_FILE("alias.6.qml"));
       
   985         VERIFY_ERRORS(0);
       
   986         QObject *object = component.create();
       
   987         QVERIFY(object != 0);
       
   988 
       
   989         QCOMPARE(object->property("a").toInt(), 1923);
       
   990     }
       
   991 
       
   992     // Ptr Alias Cleanup - check that aliases to ptr types return 0 
       
   993     // if the object aliased to is removed
       
   994     {
       
   995         QDeclarativeComponent component(&engine, TEST_FILE("alias.7.qml"));
       
   996         VERIFY_ERRORS(0);
       
   997 
       
   998         QObject *object = component.create();
       
   999         QVERIFY(object != 0);
       
  1000 
       
  1001         QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
       
  1002         QVERIFY(object1 != 0);
       
  1003         QObject *object2 = qvariant_cast<QObject *>(object1->property("object"));
       
  1004         QVERIFY(object2 != 0);
       
  1005 
       
  1006         QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
       
  1007         QVERIFY(alias == object2);
       
  1008 
       
  1009         delete object1;
       
  1010 
       
  1011         QObject *alias2 = object; // "Random" start value
       
  1012         int status = -1;
       
  1013         void *a[] = { &alias2, 0, &status };
       
  1014         QMetaObject::metacall(object, QMetaObject::ReadProperty,
       
  1015                               object->metaObject()->indexOfProperty("aliasedObject"), a);
       
  1016         QVERIFY(alias2 == 0);
       
  1017     }
       
  1018 
       
  1019     // Simple composite type
       
  1020     {
       
  1021         QDeclarativeComponent component(&engine, TEST_FILE("alias.8.qml"));
       
  1022         VERIFY_ERRORS(0);
       
  1023         QObject *object = component.create();
       
  1024         QVERIFY(object != 0);
       
  1025 
       
  1026         QCOMPARE(object->property("value").toInt(), 10);
       
  1027 
       
  1028         delete object;
       
  1029     }
       
  1030 
       
  1031     // Complex composite type
       
  1032     {
       
  1033         QDeclarativeComponent component(&engine, TEST_FILE("alias.9.qml"));
       
  1034         VERIFY_ERRORS(0);
       
  1035         QObject *object = component.create();
       
  1036         QVERIFY(object != 0);
       
  1037 
       
  1038         QCOMPARE(object->property("value").toInt(), 10);
       
  1039 
       
  1040         delete object;
       
  1041     }
       
  1042 }
       
  1043 
       
  1044 // Test that the root element in a composite type can be a Component
       
  1045 void tst_qdeclarativelanguage::componentCompositeType()
       
  1046 {
       
  1047     QDeclarativeComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
       
  1048     VERIFY_ERRORS(0);
       
  1049     QObject *object = component.create();
       
  1050     QVERIFY(object != 0);
       
  1051 }
       
  1052 
       
  1053 class TestType : public QObject {
       
  1054     Q_OBJECT
       
  1055 public:
       
  1056     TestType(QObject *p=0) : QObject(p) {}
       
  1057 };
       
  1058 
       
  1059 class TestType2 : public QObject {
       
  1060     Q_OBJECT
       
  1061 public:
       
  1062     TestType2(QObject *p=0) : QObject(p) {}
       
  1063 };
       
  1064 
       
  1065 void tst_qdeclarativelanguage::i18n_data()
       
  1066 {
       
  1067     QTest::addColumn<QString>("file");
       
  1068     QTest::addColumn<QString>("stringProperty");
       
  1069     QTest::newRow("i18nStrings") << "i18nStrings.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245 (5 accented 'a' letters)");
       
  1070     QTest::newRow("i18nDeclaredPropertyNames") << "i18nDeclaredPropertyNames.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 10");
       
  1071     QTest::newRow("i18nDeclaredPropertyUse") << "i18nDeclaredPropertyUse.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 15");
       
  1072     QTest::newRow("i18nScript") << "i18nScript.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 20");
       
  1073     QTest::newRow("i18nType") << "i18nType.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 30");
       
  1074     QTest::newRow("i18nNameSpace") << "i18nNameSpace.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 40");
       
  1075 }
       
  1076 
       
  1077 void tst_qdeclarativelanguage::i18n()
       
  1078 {
       
  1079     QFETCH(QString, file);
       
  1080     QFETCH(QString, stringProperty);
       
  1081     QDeclarativeComponent component(&engine, TEST_FILE(file));
       
  1082     VERIFY_ERRORS(0);
       
  1083     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
       
  1084     QVERIFY(object != 0);
       
  1085     QCOMPARE(object->stringProperty(), stringProperty);
       
  1086 
       
  1087     delete object;
       
  1088 }
       
  1089 
       
  1090 // Check that the Component::onCompleted attached property works
       
  1091 void tst_qdeclarativelanguage::onCompleted()
       
  1092 {
       
  1093     QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
       
  1094     VERIFY_ERRORS(0);
       
  1095     QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
       
  1096     QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
       
  1097     QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
       
  1098     QObject *object = component.create();
       
  1099     QVERIFY(object != 0);
       
  1100 }
       
  1101 
       
  1102 // Check that the Component::onDestruction attached property works
       
  1103 void tst_qdeclarativelanguage::onDestruction()
       
  1104 {
       
  1105     QDeclarativeComponent component(&engine, TEST_FILE("onDestruction.qml"));
       
  1106     VERIFY_ERRORS(0);
       
  1107     QObject *object = component.create();
       
  1108     QVERIFY(object != 0);
       
  1109 
       
  1110     QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
       
  1111     QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
       
  1112     QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
       
  1113     delete object;
       
  1114 }
       
  1115 
       
  1116 // Check that assignments to QDeclarativeScriptString properties work
       
  1117 void tst_qdeclarativelanguage::scriptString()
       
  1118 {
       
  1119     {
       
  1120         QDeclarativeComponent component(&engine, TEST_FILE("scriptString.qml"));
       
  1121         VERIFY_ERRORS(0);
       
  1122 
       
  1123         MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
       
  1124         QVERIFY(object != 0);
       
  1125         QCOMPARE(object->scriptProperty().script(), QString("foo + bar"));
       
  1126         QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object));
       
  1127         QCOMPARE(object->scriptProperty().context(), qmlContext(object));
       
  1128 
       
  1129         QVERIFY(object->grouped() != 0);
       
  1130         QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)"));
       
  1131         QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object));
       
  1132         QCOMPARE(object->grouped()->script().context(), qmlContext(object));
       
  1133     }
       
  1134 
       
  1135     {
       
  1136         QDeclarativeComponent component(&engine, TEST_FILE("scriptString2.qml"));
       
  1137         VERIFY_ERRORS(0);
       
  1138 
       
  1139         MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
       
  1140         QVERIFY(object != 0);
       
  1141         QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
       
  1142     }
       
  1143 
       
  1144     {
       
  1145         QDeclarativeComponent component(&engine, TEST_FILE("scriptString3.qml"));
       
  1146         VERIFY_ERRORS(0);
       
  1147 
       
  1148         MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
       
  1149         QVERIFY(object != 0);
       
  1150         QCOMPARE(object->scriptProperty().script(), QString("12.345"));
       
  1151     }
       
  1152 
       
  1153     {
       
  1154         QDeclarativeComponent component(&engine, TEST_FILE("scriptString4.qml"));
       
  1155         VERIFY_ERRORS(0);
       
  1156 
       
  1157         MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
       
  1158         QVERIFY(object != 0);
       
  1159         QCOMPARE(object->scriptProperty().script(), QString("true"));
       
  1160     }
       
  1161 }
       
  1162 
       
  1163 // Check that default property assignments are correctly spliced into explicit 
       
  1164 // property assignments
       
  1165 void tst_qdeclarativelanguage::defaultPropertyListOrder()
       
  1166 {
       
  1167     QDeclarativeComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
       
  1168     VERIFY_ERRORS(0);
       
  1169 
       
  1170     MyContainer *container = qobject_cast<MyContainer *>(component.create());
       
  1171     QVERIFY(container  != 0);
       
  1172 
       
  1173     QCOMPARE(container->getChildren()->count(), 6);
       
  1174     QCOMPARE(container->getChildren()->at(0)->property("index"), QVariant(0));
       
  1175     QCOMPARE(container->getChildren()->at(1)->property("index"), QVariant(1));
       
  1176     QCOMPARE(container->getChildren()->at(2)->property("index"), QVariant(2));
       
  1177     QCOMPARE(container->getChildren()->at(3)->property("index"), QVariant(3));
       
  1178     QCOMPARE(container->getChildren()->at(4)->property("index"), QVariant(4));
       
  1179     QCOMPARE(container->getChildren()->at(5)->property("index"), QVariant(5));
       
  1180 }
       
  1181 
       
  1182 void tst_qdeclarativelanguage::declaredPropertyValues()
       
  1183 {
       
  1184     QDeclarativeComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
       
  1185     VERIFY_ERRORS(0);
       
  1186 }
       
  1187 
       
  1188 // Check that first child of qml is of given type. Empty type insists on error.
       
  1189 void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, const QString& expectederror)
       
  1190 {
       
  1191     QDeclarativeComponent component(&engine);
       
  1192     component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
       
  1193 
       
  1194     QTRY_VERIFY(!component.isLoading());
       
  1195 
       
  1196     if (type.isEmpty()) {
       
  1197         QVERIFY(component.isError());
       
  1198         QString actualerror;
       
  1199         foreach (const QDeclarativeError e, component.errors()) {
       
  1200             if (!actualerror.isEmpty())
       
  1201                 actualerror.append("; ");
       
  1202             actualerror.append(e.description());
       
  1203         }
       
  1204         QCOMPARE(actualerror,expectederror);
       
  1205     } else {
       
  1206         VERIFY_ERRORS(0);
       
  1207         QObject *object = component.create();
       
  1208         QVERIFY(object != 0);
       
  1209         QCOMPARE(QString(object->metaObject()->className()), type);
       
  1210     }
       
  1211 }
       
  1212 
       
  1213 
       
  1214 // Import tests (QT-558)
       
  1215 
       
  1216 void tst_qdeclarativelanguage::importsBuiltin_data()
       
  1217 {
       
  1218     // QT-610
       
  1219 
       
  1220     QTest::addColumn<QString>("qml");
       
  1221     QTest::addColumn<QString>("type");
       
  1222     QTest::addColumn<QString>("error");
       
  1223 
       
  1224     // import built-ins
       
  1225     QTest::newRow("missing import")
       
  1226         << "Test {}"
       
  1227         << ""
       
  1228         << "Test is not a type";
       
  1229     QTest::newRow("not in version 0.0")
       
  1230         << "import com.nokia.Test 0.0\n"
       
  1231            "Test {}"
       
  1232         << ""
       
  1233         << "Test is not a type";
       
  1234     QTest::newRow("version not installed")
       
  1235         << "import com.nokia.Test 99.0\n"
       
  1236            "Test {}"
       
  1237         << ""
       
  1238         << "module \"com.nokia.Test\" version 99.0 is not installed";
       
  1239     QTest::newRow("in version 0.0")
       
  1240         << "import com.nokia.Test 0.0\n"
       
  1241            "TestTP {}"
       
  1242         << "TestType"
       
  1243         << "";
       
  1244     QTest::newRow("qualified in version 0.0")
       
  1245         << "import com.nokia.Test 0.0 as T\n"
       
  1246            "T.TestTP {}"
       
  1247         << "TestType"
       
  1248         << "";
       
  1249     QTest::newRow("in version 1.0")
       
  1250         << "import com.nokia.Test 1.0\n"
       
  1251            "Test {}"
       
  1252         << "TestType"
       
  1253         << "";
       
  1254     QTest::newRow("qualified wrong")
       
  1255         << "import com.nokia.Test 1.0 as T\n" // QT-610
       
  1256            "Test {}"
       
  1257         << ""
       
  1258         << "Test is not a type";
       
  1259     QTest::newRow("qualified right")
       
  1260         << "import com.nokia.Test 1.0 as T\n"
       
  1261            "T.Test {}"
       
  1262         << "TestType"
       
  1263         << "";
       
  1264     QTest::newRow("qualified right but not in version 0.0")
       
  1265         << "import com.nokia.Test 0.0 as T\n"
       
  1266            "T.Test {}"
       
  1267         << ""
       
  1268         << "T.Test is not a type";
       
  1269     QTest::newRow("in version 1.1")
       
  1270         << "import com.nokia.Test 1.1\n"
       
  1271            "Test {}"
       
  1272         << "TestType"
       
  1273         << "";
       
  1274     QTest::newRow("in version 1.3")
       
  1275         << "import com.nokia.Test 1.3\n"
       
  1276            "Test {}"
       
  1277         << "TestType"
       
  1278         << "";
       
  1279     QTest::newRow("in version 1.5")
       
  1280         << "import com.nokia.Test 1.5\n"
       
  1281            "Test {}"
       
  1282         << "TestType"
       
  1283         << "";
       
  1284     QTest::newRow("changed in version 1.8")
       
  1285         << "import com.nokia.Test 1.8\n"
       
  1286            "Test {}"
       
  1287         << "TestType2"
       
  1288         << "";
       
  1289     QTest::newRow("in version 1.12")
       
  1290         << "import com.nokia.Test 1.12\n"
       
  1291            "Test {}"
       
  1292         << "TestType2"
       
  1293         << "";
       
  1294     QTest::newRow("old in version 1.9")
       
  1295         << "import com.nokia.Test 1.9\n"
       
  1296            "OldTest {}"
       
  1297         << "TestType"
       
  1298         << "";
       
  1299     QTest::newRow("old in version 1.11")
       
  1300         << "import com.nokia.Test 1.11\n"
       
  1301            "OldTest {}"
       
  1302         << "TestType"
       
  1303         << "";
       
  1304     QTest::newRow("multiversion 1")
       
  1305         << "import com.nokia.Test 1.11\n"
       
  1306            "import com.nokia.Test 1.12\n"
       
  1307            "Test {}"
       
  1308         << (!qmlCheckTypes()?"TestType2":"")
       
  1309         << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
       
  1310     QTest::newRow("multiversion 2")
       
  1311         << "import com.nokia.Test 1.11\n"
       
  1312            "import com.nokia.Test 1.12\n"
       
  1313            "OldTest {}"
       
  1314         << (!qmlCheckTypes()?"TestType":"")
       
  1315         << (!qmlCheckTypes()?"":"OldTest is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
       
  1316     QTest::newRow("qualified multiversion 3")
       
  1317         << "import com.nokia.Test 1.0 as T0\n"
       
  1318            "import com.nokia.Test 1.8 as T8\n"
       
  1319            "T0.Test {}"
       
  1320         << "TestType"
       
  1321         << "";
       
  1322     QTest::newRow("qualified multiversion 4")
       
  1323         << "import com.nokia.Test 1.0 as T0\n"
       
  1324            "import com.nokia.Test 1.8 as T8\n"
       
  1325            "T8.Test {}"
       
  1326         << "TestType2"
       
  1327         << "";
       
  1328 }
       
  1329 
       
  1330 void tst_qdeclarativelanguage::importsBuiltin()
       
  1331 {
       
  1332     QFETCH(QString, qml);
       
  1333     QFETCH(QString, type);
       
  1334     QFETCH(QString, error);
       
  1335     testType(qml,type,error);
       
  1336 }
       
  1337 
       
  1338 void tst_qdeclarativelanguage::importsLocal_data()
       
  1339 {
       
  1340     QTest::addColumn<QString>("qml");
       
  1341     QTest::addColumn<QString>("type");
       
  1342     QTest::addColumn<QString>("error");
       
  1343 
       
  1344     // import locals
       
  1345     QTest::newRow("local import")
       
  1346         << "import \"subdir\"\n" // QT-613
       
  1347            "Test {}"
       
  1348         << "QDeclarativeRectangle"
       
  1349         << "";
       
  1350     QTest::newRow("local import second")
       
  1351         << "import Qt 4.7\nimport \"subdir\"\n"
       
  1352            "Test {}"
       
  1353         << "QDeclarativeRectangle"
       
  1354         << "";
       
  1355     QTest::newRow("local import subsubdir")
       
  1356         << "import Qt 4.7\nimport \"subdir/subsubdir\"\n"
       
  1357            "SubTest {}"
       
  1358         << "QDeclarativeRectangle"
       
  1359         << "";
       
  1360     QTest::newRow("local import QTBUG-7721 A")
       
  1361         << "subdir.Test {}" // no longer allowed (QTBUG-7721)
       
  1362         << ""
       
  1363         << "subdir.Test - subdir is not a namespace";
       
  1364     QTest::newRow("local import QTBUG-7721 B")
       
  1365         << "import \"subdir\" as X\n"
       
  1366            "X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
       
  1367         << ""
       
  1368         << "X.subsubdir.SubTest - nested namespaces not allowed";
       
  1369     QTest::newRow("local import as")
       
  1370         << "import \"subdir\" as T\n"
       
  1371            "T.Test {}"
       
  1372         << "QDeclarativeRectangle"
       
  1373         << "";
       
  1374     QTest::newRow("wrong local import as")
       
  1375         << "import \"subdir\" as T\n"
       
  1376            "Test {}"
       
  1377         << ""
       
  1378         << "Test is not a type";
       
  1379     QTest::newRow("library precedence over local import")
       
  1380         << "import \"subdir\"\n"
       
  1381            "import com.nokia.Test 1.0\n"
       
  1382            "Test {}"
       
  1383         << (!qmlCheckTypes()?"TestType":"")
       
  1384         << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test and in subdir");
       
  1385 }
       
  1386 
       
  1387 void tst_qdeclarativelanguage::importsLocal()
       
  1388 {
       
  1389     QFETCH(QString, qml);
       
  1390     QFETCH(QString, type);
       
  1391     QFETCH(QString, error);
       
  1392     testType(qml,type,error);
       
  1393 }
       
  1394 
       
  1395 void tst_qdeclarativelanguage::basicRemote_data()
       
  1396 {
       
  1397     QTest::addColumn<QUrl>("url");
       
  1398     QTest::addColumn<QString>("type");
       
  1399     QTest::addColumn<QString>("error");
       
  1400 
       
  1401     QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage/";
       
  1402 
       
  1403     QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
       
  1404     QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
       
  1405 }
       
  1406 
       
  1407 void tst_qdeclarativelanguage::basicRemote()
       
  1408 {
       
  1409     QFETCH(QUrl, url);
       
  1410     QFETCH(QString, type);
       
  1411     QFETCH(QString, error);
       
  1412 
       
  1413     TestHTTPServer server(14447);
       
  1414     server.serveDirectory(SRCDIR);
       
  1415 
       
  1416     QDeclarativeComponent component(&engine, url);
       
  1417 
       
  1418     QTRY_VERIFY(!component.isLoading());
       
  1419 
       
  1420     if (error.isEmpty()) {
       
  1421         if (component.isError())
       
  1422             qDebug() << component.errors();
       
  1423         QVERIFY(!component.isError());
       
  1424     } else {
       
  1425         QVERIFY(component.isError());
       
  1426     }
       
  1427 }
       
  1428 
       
  1429 void tst_qdeclarativelanguage::importsRemote_data()
       
  1430 {
       
  1431     QTest::addColumn<QString>("qml");
       
  1432     QTest::addColumn<QString>("type");
       
  1433     QTest::addColumn<QString>("error");
       
  1434 
       
  1435     QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage";
       
  1436 
       
  1437     QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QDeclarativeRectangle"
       
  1438         << "";
       
  1439     QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QDeclarativeText"
       
  1440         << "";
       
  1441     QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QDeclarativeImage"
       
  1442         << "";
       
  1443     QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
       
  1444         << "WrongTestLocal is not a type";
       
  1445     QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
       
  1446         << "LocalInternal is not a type";
       
  1447     QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""
       
  1448         << "UndeclaredLocal is not a type";
       
  1449 }
       
  1450 
       
  1451 void tst_qdeclarativelanguage::importsRemote()
       
  1452 {
       
  1453     QFETCH(QString, qml);
       
  1454     QFETCH(QString, type);
       
  1455     QFETCH(QString, error);
       
  1456 
       
  1457     TestHTTPServer server(14447);
       
  1458     server.serveDirectory(SRCDIR);
       
  1459 
       
  1460     testType(qml,type,error);
       
  1461 }
       
  1462 
       
  1463 void tst_qdeclarativelanguage::importsInstalled_data()
       
  1464 {
       
  1465     // QT-610
       
  1466 
       
  1467     QTest::addColumn<QString>("qml");
       
  1468     QTest::addColumn<QString>("type");
       
  1469     QTest::addColumn<QString>("error");
       
  1470 
       
  1471     // import installed
       
  1472     QTest::newRow("installed import 0")
       
  1473         << "import com.nokia.installedtest 0.0\n"
       
  1474            "InstalledTestTP {}"
       
  1475         << "QDeclarativeRectangle"
       
  1476         << "";
       
  1477     QTest::newRow("installed import 0 as TP")
       
  1478         << "import com.nokia.installedtest 0.0 as TP\n"
       
  1479            "TP.InstalledTestTP {}"
       
  1480         << "QDeclarativeRectangle"
       
  1481         << "";
       
  1482     QTest::newRow("installed import 1")
       
  1483         << "import com.nokia.installedtest 1.0\n"
       
  1484            "InstalledTest {}"
       
  1485         << "QDeclarativeRectangle"
       
  1486         << "";
       
  1487     QTest::newRow("installed import 2")
       
  1488         << "import com.nokia.installedtest 1.3\n"
       
  1489            "InstalledTest {}"
       
  1490         << "QDeclarativeRectangle"
       
  1491         << "";
       
  1492     QTest::newRow("installed import 3")
       
  1493         << "import com.nokia.installedtest 1.4\n"
       
  1494            "InstalledTest {}"
       
  1495         << "QDeclarativeText"
       
  1496         << "";
       
  1497     QTest::newRow("installed import minor version not available") // QTBUG-9627
       
  1498         << "import com.nokia.installedtest 1.10\n"
       
  1499            "InstalledTest {}"
       
  1500         << ""
       
  1501         << "module \"com.nokia.installedtest\" version 1.10 is not installed";
       
  1502     QTest::newRow("installed import major version not available") // QTBUG-9627
       
  1503         << "import com.nokia.installedtest 9.0\n"
       
  1504            "InstalledTest {}"
       
  1505         << ""
       
  1506         << "module \"com.nokia.installedtest\" version 9.0 is not installed";
       
  1507     QTest::newRow("installed import visibility") // QT-614
       
  1508         << "import com.nokia.installedtest 1.4\n"
       
  1509            "PrivateType {}"
       
  1510         << ""
       
  1511         << "PrivateType is not a type";
       
  1512 }
       
  1513 
       
  1514 void tst_qdeclarativelanguage::importsInstalled()
       
  1515 {
       
  1516     QFETCH(QString, qml);
       
  1517     QFETCH(QString, type);
       
  1518     QFETCH(QString, error);
       
  1519     testType(qml,type,error);
       
  1520 }
       
  1521 
       
  1522 
       
  1523 void tst_qdeclarativelanguage::importsOrder_data()
       
  1524 {
       
  1525     QTest::addColumn<QString>("qml");
       
  1526     QTest::addColumn<QString>("type");
       
  1527     QTest::addColumn<QString>("error");
       
  1528 
       
  1529     QTest::newRow("double import") <<
       
  1530            "import com.nokia.installedtest 1.4\n"
       
  1531            "import com.nokia.installedtest 1.4\n"
       
  1532            "InstalledTest {}"
       
  1533            << (!qmlCheckTypes()?"QDeclarativeText":"")
       
  1534            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.4");
       
  1535     QTest::newRow("installed import overrides 1") <<
       
  1536            "import com.nokia.installedtest 1.0\n"
       
  1537            "import com.nokia.installedtest 1.4\n"
       
  1538            "InstalledTest {}"
       
  1539            << (!qmlCheckTypes()?"QDeclarativeText":"")
       
  1540            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
       
  1541     QTest::newRow("installed import overrides 2") <<
       
  1542            "import com.nokia.installedtest 1.4\n"
       
  1543            "import com.nokia.installedtest 1.0\n"
       
  1544            "InstalledTest {}"
       
  1545            << (!qmlCheckTypes()?"QDeclarativeRectangle":"")
       
  1546            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
       
  1547     QTest::newRow("installed import re-overrides 1") <<
       
  1548            "import com.nokia.installedtest 1.4\n"
       
  1549            "import com.nokia.installedtest 1.0\n"
       
  1550            "import com.nokia.installedtest 1.4\n"
       
  1551            "InstalledTest {}"
       
  1552            << (!qmlCheckTypes()?"QDeclarativeText":"")
       
  1553            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
       
  1554     QTest::newRow("installed import re-overrides 2") <<
       
  1555            "import com.nokia.installedtest 1.4\n"
       
  1556            "import com.nokia.installedtest 1.0\n"
       
  1557            "import com.nokia.installedtest 1.4\n"
       
  1558            "import com.nokia.installedtest 1.0\n"
       
  1559            "InstalledTest {}"
       
  1560            << (!qmlCheckTypes()?"QDeclarativeRectangle":"")
       
  1561            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
       
  1562 
       
  1563     QTest::newRow("installed import versus builtin 1") <<
       
  1564            "import com.nokia.installedtest 1.5\n"
       
  1565            "import Qt 4.7\n"
       
  1566            "Rectangle {}"
       
  1567            << (!qmlCheckTypes()?"QDeclarativeRectangle":"")
       
  1568            << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in Qt and in lib/com/nokia/installedtest");
       
  1569     QTest::newRow("installed import versus builtin 2") <<
       
  1570            "import Qt 4.7\n"
       
  1571            "import com.nokia.installedtest 1.5\n"
       
  1572            "Rectangle {}"
       
  1573            << (!qmlCheckTypes()?"QDeclarativeText":"")
       
  1574            << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest and in Qt");
       
  1575     QTest::newRow("namespaces cannot be overridden by types 1") <<
       
  1576            "import Qt 4.7 as Rectangle\n"
       
  1577            "import com.nokia.installedtest 1.5\n"
       
  1578            "Rectangle {}"
       
  1579         << ""
       
  1580         << "Namespace Rectangle cannot be used as a type";
       
  1581     QTest::newRow("namespaces cannot be overridden by types 2") <<
       
  1582            "import Qt 4.7 as Rectangle\n"
       
  1583            "import com.nokia.installedtest 1.5\n"
       
  1584            "Rectangle.Image {}"
       
  1585         << "QDeclarativeImage"
       
  1586         << "";
       
  1587     QTest::newRow("local last 1") <<
       
  1588            "LocalLast {}"
       
  1589         << "QDeclarativeText"
       
  1590         << "";
       
  1591     QTest::newRow("local last 2") <<
       
  1592            "import com.nokia.installedtest 1.0\n"
       
  1593            "LocalLast {}"
       
  1594            << (!qmlCheckTypes()?"QDeclarativeRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
       
  1595            << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest and in local directory");
       
  1596 }
       
  1597 
       
  1598 void tst_qdeclarativelanguage::importsOrder()
       
  1599 {
       
  1600     QFETCH(QString, qml);
       
  1601     QFETCH(QString, type);
       
  1602     QFETCH(QString, error);
       
  1603     testType(qml,type,error);
       
  1604 }
       
  1605 
       
  1606 void tst_qdeclarativelanguage::qmlAttachedPropertiesObjectMethod()
       
  1607 {
       
  1608     QObject object;
       
  1609 
       
  1610     QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
       
  1611     QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
       
  1612 
       
  1613     {
       
  1614         QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
       
  1615         VERIFY_ERRORS(0);
       
  1616         QObject *object = component.create();
       
  1617         QVERIFY(object != 0);
       
  1618 
       
  1619         QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
       
  1620         QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
       
  1621     }
       
  1622 
       
  1623     {
       
  1624         QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
       
  1625         VERIFY_ERRORS(0);
       
  1626         QObject *object = component.create();
       
  1627         QVERIFY(object != 0);
       
  1628 
       
  1629         QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
       
  1630         QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
       
  1631     }
       
  1632 }
       
  1633 
       
  1634 void tst_qdeclarativelanguage::crash1()
       
  1635 {
       
  1636     QDeclarativeComponent component(&engine);
       
  1637     component.setData("import Qt 4.7\nComponent {}", QUrl());
       
  1638 }
       
  1639 
       
  1640 void tst_qdeclarativelanguage::crash2()
       
  1641 {
       
  1642     QDeclarativeComponent component(&engine, TEST_FILE("crash2.qml"));
       
  1643 }
       
  1644 
       
  1645 // QTBUG-8676
       
  1646 void tst_qdeclarativelanguage::customOnProperty()
       
  1647 {
       
  1648     QDeclarativeComponent component(&engine, TEST_FILE("customOnProperty.qml"));
       
  1649 
       
  1650     VERIFY_ERRORS(0);
       
  1651     QObject *object = component.create();
       
  1652     QVERIFY(object != 0);
       
  1653 
       
  1654     QCOMPARE(object->property("on").toInt(), 10);
       
  1655 
       
  1656     delete object;
       
  1657 }
       
  1658 
       
  1659 void tst_qdeclarativelanguage::initTestCase()
       
  1660 {
       
  1661     registerTypes();
       
  1662 
       
  1663     qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP");
       
  1664     qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test");
       
  1665     qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test");
       
  1666     qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test");
       
  1667     qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest");
       
  1668     qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test");
       
  1669 
       
  1670     // Create locale-specific file
       
  1671     // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit
       
  1672     // For iso8859-1 locale, this will just be data/I18nType?????.qml where ????? is 5 8-bit characters
       
  1673     // For utf-8 locale, this will be data/I18nType??????????.qml where ?????????? is 5 8-bit characters, UTF-8 encoded
       
  1674     QFile in(TEST_FILE(QLatin1String("I18nType30.qml")).toLocalFile());
       
  1675     QVERIFY(in.open(QIODevice::ReadOnly));
       
  1676     QFile out(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile());
       
  1677     QVERIFY(out.open(QIODevice::WriteOnly));
       
  1678     out.write(in.readAll());
       
  1679 }
       
  1680 
       
  1681 QTEST_MAIN(tst_qdeclarativelanguage)
       
  1682 
       
  1683 #include "tst_qdeclarativelanguage.moc"