Update obsolete contact address.
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qdeclarativelanguage / tst_qdeclarativelanguage.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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/qcoreapplication.h>
45 #include <QtCore/qfile.h>
46 #include <QtCore/qdebug.h>
47 #include <QtCore/qfileinfo.h>
48 #include <QtCore/qdir.h>
49
50 #include <private/qdeclarativeproperty_p.h>
51 #include <private/qdeclarativemetatype_p.h>
52 #include <private/qdeclarativeglobal_p.h>
53
54 #include "testtypes.h"
55 #include "testhttpserver.h"
56
57 DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)
58
59 /*
60     Returns the path to some testdata file or directory.
61 */
62 QString testdata(QString const& name = QString())
63 {
64     static const QString dataDirectory = QDir::currentPath() + QLatin1String("/data");
65     QString result = dataDirectory;
66     if (!name.isEmpty()) {
67         result += QLatin1Char('/');
68         result += name;
69     }
70     return result;
71 }
72
73 /*
74 This test case covers QML language issues.  This covers everything that does not
75 involve evaluating ECMAScript expressions and bindings.
76
77 Evaluation of expressions and bindings is covered in qmlecmascript
78 */
79 class tst_qdeclarativelanguage : public QObject
80 {
81     Q_OBJECT
82 public:
83     tst_qdeclarativelanguage() {
84         QDeclarativeMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter);
85         engine.addImportPath(testdata("lib"));
86     }
87
88 private slots:
89     void initTestCase();
90     void cleanupTestCase();
91
92     void errors_data();
93     void errors();
94
95     void insertedSemicolon_data();
96     void insertedSemicolon();
97
98     void simpleObject();
99     void simpleContainer();
100     void interfaceProperty();
101     void interfaceQList();
102     void assignObjectToSignal();
103     void assignObjectToVariant();
104     void assignLiteralSignalProperty();
105     void assignQmlComponent();
106     void assignBasicTypes();
107     void assignTypeExtremes();
108     void assignCompositeToType();
109     void assignLiteralToVariant();
110     void assignLiteralToVar();
111     void customParserTypes();
112     void rootAsQmlComponent();
113     void inlineQmlComponents();
114     void idProperty();
115     void autoNotifyConnection();
116     void assignSignal();
117     void dynamicProperties();
118     void dynamicPropertiesNested();
119     void listProperties();
120     void dynamicObjectProperties();
121     void dynamicSignalsAndSlots();
122     void simpleBindings();
123     void autoComponentCreation();
124     void propertyValueSource();
125     void attachedProperties();
126     void dynamicObjects();
127     void customVariantTypes();
128     void valueTypes();
129     void cppnamespace();
130     void aliasProperties();
131     void aliasPropertiesAndSignals();
132     void aliasPropertyChangeSignals();
133     void componentCompositeType();
134     void i18n();
135     void i18n_data();
136     void onCompleted();
137     void onDestruction();
138     void scriptString();
139     void defaultPropertyListOrder();
140     void declaredPropertyValues();
141     void dontDoubleCallClassBegin();
142     void reservedWords_data();
143     void reservedWords();
144     void inlineAssignmentsOverrideBindings();
145     void nestedComponentRoots();
146     void registrationOrder();
147     void readonly();
148
149     void basicRemote_data();
150     void basicRemote();
151     void importsBuiltin_data();
152     void importsBuiltin();
153     void importsLocal_data();
154     void importsLocal();
155     void importsRemote_data();
156     void importsRemote();
157     void importsInstalled_data();
158     void importsInstalled();
159     void importsOrder_data();
160     void importsOrder();
161     void importIncorrectCase();
162
163     void qmlAttachedPropertiesObjectMethod();
164     void customOnProperty();
165     void variantNotify();
166
167     void revisions();
168     void revisionOverloads();
169
170     void propertyInit();
171     void remoteLoadCrash();
172
173     // regression tests for crashes
174     void crash1();
175     void crash2();
176
177 private:
178     QDeclarativeEngine engine;
179     void testType(const QString& qml, const QString& type, const QString& error);
180 };
181
182 #define VERIFY_ERRORS(errorfile) \
183     if (!errorfile) { \
184         if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
185             qWarning() << "Unexpected Errors:" << component.errors(); \
186         QVERIFY(!component.isError()); \
187         QVERIFY(component.errors().isEmpty()); \
188     } else { \
189         QFile file(testdata(QLatin1String(errorfile))); \
190         QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
191         QByteArray data = file.readAll(); \
192         file.close(); \
193         QList<QByteArray> expected = data.split('\n'); \
194         expected.removeAll(QByteArray("")); \
195         QList<QDeclarativeError> errors = component.errors(); \
196         QList<QByteArray> actual; \
197         for (int ii = 0; ii < errors.count(); ++ii) { \
198             const QDeclarativeError &error = errors.at(ii); \
199             QByteArray errorStr = QByteArray::number(error.line()) + ":" +  \
200                                   QByteArray::number(error.column()) + ":" + \
201                                   error.description().toUtf8(); \
202             actual << errorStr; \
203         } \
204         if (qgetenv("DEBUG") != "" && expected != actual) \
205             qWarning() << "Expected:" << expected << "Actual:" << actual;  \
206         if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
207             QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
208             QVERIFY(file.open(QIODevice::WriteOnly)); \
209             for (int ii = 0; ii < actual.count(); ++ii) { \
210                 file.write(actual.at(ii)); file.write("\n"); \
211             } \
212             file.close(); \
213         } else { \
214             QCOMPARE(expected, actual); \
215         } \
216     }
217
218 inline QUrl TEST_FILE(const QString &filename)
219 {
220     return QUrl::fromLocalFile(testdata(filename));
221 }
222
223 inline QUrl TEST_FILE(const char *filename)
224 {
225     return TEST_FILE(QLatin1String(filename));
226 }
227
228 void tst_qdeclarativelanguage::cleanupTestCase()
229 {
230     QVERIFY(QFile::remove(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile()));
231 }
232
233 void tst_qdeclarativelanguage::insertedSemicolon_data()
234 {
235     QTest::addColumn<QString>("file");
236     QTest::addColumn<QString>("errorFile");
237     QTest::addColumn<bool>("create");
238
239     QTest::newRow("insertedSemicolon.1") << "insertedSemicolon.1.qml" << "insertedSemicolon.1.errors.txt" << false;
240 }
241
242 void tst_qdeclarativelanguage::insertedSemicolon()
243 {
244     QFETCH(QString, file);
245     QFETCH(QString, errorFile);
246     QFETCH(bool, create);
247
248     QDeclarativeComponent component(&engine, TEST_FILE(file));
249
250     if(create) {
251         QObject *object = component.create();
252         QVERIFY(object == 0);
253     }
254
255     VERIFY_ERRORS(errorFile.toLatin1().constData());
256 }
257
258 void tst_qdeclarativelanguage::errors_data()
259 {
260     QTest::addColumn<QString>("file");
261     QTest::addColumn<QString>("errorFile");
262     QTest::addColumn<bool>("create");
263
264     QTest::newRow("nonexistantProperty.1") << "nonexistantProperty.1.qml" << "nonexistantProperty.1.errors.txt" << false;
265     QTest::newRow("nonexistantProperty.2") << "nonexistantProperty.2.qml" << "nonexistantProperty.2.errors.txt" << false;
266     QTest::newRow("nonexistantProperty.3") << "nonexistantProperty.3.qml" << "nonexistantProperty.3.errors.txt" << false;
267     QTest::newRow("nonexistantProperty.4") << "nonexistantProperty.4.qml" << "nonexistantProperty.4.errors.txt" << false;
268     QTest::newRow("nonexistantProperty.5") << "nonexistantProperty.5.qml" << "nonexistantProperty.5.errors.txt" << false;
269     QTest::newRow("nonexistantProperty.6") << "nonexistantProperty.6.qml" << "nonexistantProperty.6.errors.txt" << false;
270
271     QTest::newRow("wrongType (string for int)") << "wrongType.1.qml" << "wrongType.1.errors.txt" << false;
272     QTest::newRow("wrongType (int for bool)") << "wrongType.2.qml" << "wrongType.2.errors.txt" << false;
273     QTest::newRow("wrongType (bad rect)") << "wrongType.3.qml" << "wrongType.3.errors.txt" << false;
274
275     QTest::newRow("wrongType (invalid enum)") << "wrongType.4.qml" << "wrongType.4.errors.txt" << false;
276     QTest::newRow("wrongType (int for uint)") << "wrongType.5.qml" << "wrongType.5.errors.txt" << false;
277     QTest::newRow("wrongType (string for real)") << "wrongType.6.qml" << "wrongType.6.errors.txt" << false;
278     QTest::newRow("wrongType (int for color)") << "wrongType.7.qml" << "wrongType.7.errors.txt" << false;
279     QTest::newRow("wrongType (int for date)") << "wrongType.8.qml" << "wrongType.8.errors.txt" << false;
280     QTest::newRow("wrongType (int for time)") << "wrongType.9.qml" << "wrongType.9.errors.txt" << false;
281     QTest::newRow("wrongType (int for datetime)") << "wrongType.10.qml" << "wrongType.10.errors.txt" << false;
282     QTest::newRow("wrongType (string for point)") << "wrongType.11.qml" << "wrongType.11.errors.txt" << false;
283     QTest::newRow("wrongType (color for size)") << "wrongType.12.qml" << "wrongType.12.errors.txt" << false;
284     QTest::newRow("wrongType (number string for int)") << "wrongType.13.qml" << "wrongType.13.errors.txt" << false;
285     QTest::newRow("wrongType (int for string)") << "wrongType.14.qml" << "wrongType.14.errors.txt" << false;
286     QTest::newRow("wrongType (int for url)") << "wrongType.15.qml" << "wrongType.15.errors.txt" << false;
287     QTest::newRow("wrongType (invalid object)") << "wrongType.16.qml" << "wrongType.16.errors.txt" << false;
288     QTest::newRow("wrongType (int for enum)") << "wrongType.17.qml" << "wrongType.17.errors.txt" << false;
289
290     QTest::newRow("readOnly.1") << "readOnly.1.qml" << "readOnly.1.errors.txt" << false;
291     QTest::newRow("readOnly.2") << "readOnly.2.qml" << "readOnly.2.errors.txt" << false;
292     QTest::newRow("readOnly.3") << "readOnly.3.qml" << "readOnly.3.errors.txt" << false;
293     QTest::newRow("readOnly.4") << "readOnly.4.qml" << "readOnly.4.errors.txt" << false;
294     QTest::newRow("readOnly.5") << "readOnly.5.qml" << "readOnly.5.errors.txt" << false;
295
296     QTest::newRow("listAssignment.1") << "listAssignment.1.qml" << "listAssignment.1.errors.txt" << false;
297     QTest::newRow("listAssignment.2") << "listAssignment.2.qml" << "listAssignment.2.errors.txt" << false;
298     QTest::newRow("listAssignment.3") << "listAssignment.3.qml" << "listAssignment.3.errors.txt" << false;
299
300     QTest::newRow("invalidID.1") << "invalidID.qml" << "invalidID.errors.txt" << false;
301     QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
302     QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
303     QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
304     QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
305     QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false;
306     QTest::newRow("invalidID.7") << "invalidID.7.qml" << "invalidID.7.errors.txt" << false;
307     QTest::newRow("invalidID.8") << "invalidID.8.qml" << "invalidID.8.errors.txt" << false;
308     QTest::newRow("invalidID.9") << "invalidID.9.qml" << "invalidID.9.errors.txt" << false;
309
310     QTest::newRow("scriptString.1") << "scriptString.1.qml" << "scriptString.1.errors.txt" << false;
311     QTest::newRow("scriptString.2") << "scriptString.2.qml" << "scriptString.2.errors.txt" << false;
312
313     QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
314     QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;
315     QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false;
316     QTest::newRow("duplicateIDs") << "duplicateIDs.qml" << "duplicateIDs.errors.txt" << false;
317     QTest::newRow("unregisteredObject") << "unregisteredObject.qml" << "unregisteredObject.errors.txt" << false;
318     QTest::newRow("empty") << "empty.qml" << "empty.errors.txt" << false;
319     QTest::newRow("missingObject") << "missingObject.qml" << "missingObject.errors.txt" << false;
320     QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
321     QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
322     QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
323     QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
324
325     QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
326     QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
327     QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
328     QTest::newRow("invalidGroupedProperty.4") << "invalidGroupedProperty.4.qml" << "invalidGroupedProperty.4.errors.txt" << false;
329     QTest::newRow("invalidGroupedProperty.5") << "invalidGroupedProperty.5.qml" << "invalidGroupedProperty.5.errors.txt" << false;
330     QTest::newRow("invalidGroupedProperty.6") << "invalidGroupedProperty.6.qml" << "invalidGroupedProperty.6.errors.txt" << false;
331     QTest::newRow("invalidGroupedProperty.7") << "invalidGroupedProperty.7.qml" << "invalidGroupedProperty.7.errors.txt" << true;
332     QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
333     QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
334     QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
335
336     QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
337     QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
338     QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false;
339     QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false;
340     QTest::newRow("importNonExistOlder (installed)") << "importNonExistOlder.qml" << "importNonExistOlder.errors.txt" << false;
341     QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false;
342     QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false;
343     QTest::newRow("importFile") << "importFile.qml" << "importFile.errors.txt" << false;
344
345     QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false;
346     QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false;
347     QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false;
348     QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false;
349
350     QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
351
352     QTest::newRow("property.1") << "property.1.qml" << "property.1.errors.txt" << false;
353     QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
354     QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
355     QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
356     QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
357     QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
358
359     QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
360
361     QTest::newRow("Component.1") << "component.1.qml" << "component.1.errors.txt" << false;
362     QTest::newRow("Component.2") << "component.2.qml" << "component.2.errors.txt" << false;
363     QTest::newRow("Component.3") << "component.3.qml" << "component.3.errors.txt" << false;
364     QTest::newRow("Component.4") << "component.4.qml" << "component.4.errors.txt" << false;
365     QTest::newRow("Component.5") << "component.5.qml" << "component.5.errors.txt" << false;
366     QTest::newRow("Component.6") << "component.6.qml" << "component.6.errors.txt" << false;
367     QTest::newRow("Component.7") << "component.7.qml" << "component.7.errors.txt" << false;
368     QTest::newRow("Component.8") << "component.8.qml" << "component.8.errors.txt" << false;
369     QTest::newRow("Component.9") << "component.9.qml" << "component.9.errors.txt" << false;
370
371     QTest::newRow("MultiSet.1") << "multiSet.1.qml" << "multiSet.1.errors.txt" << false;
372     QTest::newRow("MultiSet.2") << "multiSet.2.qml" << "multiSet.2.errors.txt" << false;
373     QTest::newRow("MultiSet.3") << "multiSet.3.qml" << "multiSet.3.errors.txt" << false;
374     QTest::newRow("MultiSet.4") << "multiSet.4.qml" << "multiSet.4.errors.txt" << false;
375     QTest::newRow("MultiSet.5") << "multiSet.5.qml" << "multiSet.5.errors.txt" << false;
376     QTest::newRow("MultiSet.6") << "multiSet.6.qml" << "multiSet.6.errors.txt" << false;
377     QTest::newRow("MultiSet.7") << "multiSet.7.qml" << "multiSet.7.errors.txt" << false;
378     QTest::newRow("MultiSet.8") << "multiSet.8.qml" << "multiSet.8.errors.txt" << false;
379     QTest::newRow("MultiSet.9") << "multiSet.9.qml" << "multiSet.9.errors.txt" << false;
380     QTest::newRow("MultiSet.10") << "multiSet.10.qml" << "multiSet.10.errors.txt" << false;
381     QTest::newRow("MultiSet.11") << "multiSet.11.qml" << "multiSet.11.errors.txt" << false;
382
383     QTest::newRow("dynamicMeta.1") << "dynamicMeta.1.qml" << "dynamicMeta.1.errors.txt" << false;
384     QTest::newRow("dynamicMeta.2") << "dynamicMeta.2.qml" << "dynamicMeta.2.errors.txt" << false;
385     QTest::newRow("dynamicMeta.3") << "dynamicMeta.3.qml" << "dynamicMeta.3.errors.txt" << false;
386     QTest::newRow("dynamicMeta.4") << "dynamicMeta.4.qml" << "dynamicMeta.4.errors.txt" << false;
387     QTest::newRow("dynamicMeta.5") << "dynamicMeta.5.qml" << "dynamicMeta.5.errors.txt" << false;
388
389     QTest::newRow("invalidAlias.1") << "invalidAlias.1.qml" << "invalidAlias.1.errors.txt" << false;
390     QTest::newRow("invalidAlias.2") << "invalidAlias.2.qml" << "invalidAlias.2.errors.txt" << false;
391     QTest::newRow("invalidAlias.3") << "invalidAlias.3.qml" << "invalidAlias.3.errors.txt" << false;
392     QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false;
393     QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
394     QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
395     QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false;
396     QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
397     QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
398     QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
399
400     QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
401     QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
402     QTest::newRow("invalidAttachedProperty.3") << "invalidAttachedProperty.3.qml" << "invalidAttachedProperty.3.errors.txt" << false;
403     QTest::newRow("invalidAttachedProperty.4") << "invalidAttachedProperty.4.qml" << "invalidAttachedProperty.4.errors.txt" << false;
404     QTest::newRow("invalidAttachedProperty.5") << "invalidAttachedProperty.5.qml" << "invalidAttachedProperty.5.errors.txt" << false;
405     QTest::newRow("invalidAttachedProperty.6") << "invalidAttachedProperty.6.qml" << "invalidAttachedProperty.6.errors.txt" << false;
406     QTest::newRow("invalidAttachedProperty.7") << "invalidAttachedProperty.7.qml" << "invalidAttachedProperty.7.errors.txt" << false;
407     QTest::newRow("invalidAttachedProperty.8") << "invalidAttachedProperty.8.qml" << "invalidAttachedProperty.8.errors.txt" << false;
408     QTest::newRow("invalidAttachedProperty.9") << "invalidAttachedProperty.9.qml" << "invalidAttachedProperty.9.errors.txt" << false;
409     QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false;
410     QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false;
411     QTest::newRow("invalidAttachedProperty.12") << "invalidAttachedProperty.12.qml" << "invalidAttachedProperty.12.errors.txt" << false;
412     QTest::newRow("invalidAttachedProperty.13") << "invalidAttachedProperty.13.qml" << "invalidAttachedProperty.13.errors.txt" << false;
413
414     QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
415     QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
416
417     QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false;
418     QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false;
419     QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false;
420     QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false;
421     QTest::newRow("objectValueTypeProperty") << "objectValueTypeProperty.qml" << "objectValueTypeProperty.errors.txt" << false;
422     QTest::newRow("enumTypes") << "enumTypes.qml" << "enumTypes.errors.txt" << false;
423     QTest::newRow("noCreation") << "noCreation.qml" << "noCreation.errors.txt" << false;
424     QTest::newRow("destroyedSignal") << "destroyedSignal.qml" << "destroyedSignal.errors.txt" << false;
425     QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false;
426     QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false;
427     QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false;
428     QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false;
429     QTest::newRow("notAvailable") << "notAvailable.qml" << "notAvailable.errors.txt" << false;
430     QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
431     QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
432     QTest::newRow("incorrectCase") << "incorrectCase.qml" 
433 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
434         << "incorrectCase.errors.insensitive.txt" 
435 #else
436         << "incorrectCase.errors.sensitive.txt" 
437 #endif
438         << false;
439
440     QTest::newRow("metaobjectRevision.1") << "metaobjectRevision.1.qml" << "metaobjectRevision.1.errors.txt" << false;
441     QTest::newRow("metaobjectRevision.2") << "metaobjectRevision.2.qml" << "metaobjectRevision.2.errors.txt" << false;
442     QTest::newRow("metaobjectRevision.3") << "metaobjectRevision.3.qml" << "metaobjectRevision.3.errors.txt" << false;
443
444     QTest::newRow("invalidRoot.1") << "invalidRoot.1.qml" << "invalidRoot.1.errors.txt" << false;
445     QTest::newRow("invalidRoot.2") << "invalidRoot.2.qml" << "invalidRoot.2.errors.txt" << false;
446     QTest::newRow("invalidRoot.3") << "invalidRoot.3.qml" << "invalidRoot.3.errors.txt" << false;
447     QTest::newRow("invalidRoot.4") << "invalidRoot.4.qml" << "invalidRoot.4.errors.txt" << false;
448
449     QTest::newRow("invalidTypeName.1") << "invalidTypeName.1.qml" << "invalidTypeName.1.errors.txt" << false;
450     QTest::newRow("invalidTypeName.2") << "invalidTypeName.2.qml" << "invalidTypeName.2.errors.txt" << false;
451     QTest::newRow("invalidTypeName.3") << "invalidTypeName.3.qml" << "invalidTypeName.3.errors.txt" << false;
452     QTest::newRow("invalidTypeName.4") << "invalidTypeName.4.qml" << "invalidTypeName.4.errors.txt" << false;
453
454     QTest::newRow("Major version isolation") << "majorVersionIsolation.qml" << "majorVersionIsolation.errors.txt" << false;
455 }
456
457
458 void tst_qdeclarativelanguage::errors()
459 {
460     QFETCH(QString, file);
461     QFETCH(QString, errorFile);
462     QFETCH(bool, create);
463
464     QDeclarativeComponent component(&engine, TEST_FILE(file));
465
466     if(create) {
467         QObject *object = component.create();
468         QVERIFY(object == 0);
469     }
470
471     VERIFY_ERRORS(errorFile.toLatin1().constData());
472 }
473
474 void tst_qdeclarativelanguage::simpleObject()
475 {
476     QDeclarativeComponent component(&engine, TEST_FILE("simpleObject.qml"));
477     VERIFY_ERRORS(0);
478     QObject *object = component.create();
479     QVERIFY(object != 0);
480 }
481
482 void tst_qdeclarativelanguage::simpleContainer()
483 {
484     QDeclarativeComponent component(&engine, TEST_FILE("simpleContainer.qml"));
485     VERIFY_ERRORS(0);
486     MyContainer *container= qobject_cast<MyContainer*>(component.create());
487     QVERIFY(container != 0);
488     QCOMPARE(container->getChildren()->count(),2);
489 }
490
491 void tst_qdeclarativelanguage::interfaceProperty()
492 {
493     QDeclarativeComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
494     VERIFY_ERRORS(0);
495     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
496     QVERIFY(object != 0);
497     QVERIFY(object->interface());
498     QVERIFY(object->interface()->id == 913);
499 }
500
501 void tst_qdeclarativelanguage::interfaceQList()
502 {
503     QDeclarativeComponent component(&engine, TEST_FILE("interfaceQList.qml"));
504     VERIFY_ERRORS(0);
505     MyContainer *container= qobject_cast<MyContainer*>(component.create());
506     QVERIFY(container != 0);
507     QVERIFY(container->getQListInterfaces()->count() == 2);
508     for(int ii = 0; ii < 2; ++ii)
509         QVERIFY(container->getQListInterfaces()->at(ii)->id == 913);
510 }
511
512 void tst_qdeclarativelanguage::assignObjectToSignal()
513 {
514     QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
515     VERIFY_ERRORS(0);
516     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
517     QVERIFY(object != 0);
518     QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
519     emit object->basicSignal();
520 }
521
522 void tst_qdeclarativelanguage::assignObjectToVariant()
523 {
524     QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
525     VERIFY_ERRORS(0);
526     QObject *object = component.create();
527     QVERIFY(object != 0);
528     QVariant v = object->property("a");
529     QVERIFY(v.userType() == qMetaTypeId<QObject *>());
530 }
531
532 void tst_qdeclarativelanguage::assignLiteralSignalProperty()
533 {
534     QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
535     VERIFY_ERRORS(0);
536     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
537     QVERIFY(object != 0);
538     QCOMPARE(object->onLiteralSignal(), 10);
539 }
540
541 // Test is an external component can be loaded and assigned (to a qlist)
542 void tst_qdeclarativelanguage::assignQmlComponent()
543 {
544     QDeclarativeComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
545     VERIFY_ERRORS(0);
546     MyContainer *object = qobject_cast<MyContainer *>(component.create());
547     QVERIFY(object != 0);
548     QVERIFY(object->getChildren()->count() == 1);
549     QObject *child = object->getChildren()->at(0);
550     QCOMPARE(child->property("x"), QVariant(10));
551     QCOMPARE(child->property("y"), QVariant(11));
552 }
553
554 // Test literal assignment to all the basic types 
555 void tst_qdeclarativelanguage::assignBasicTypes()
556 {
557     QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
558     VERIFY_ERRORS(0);
559     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
560     QVERIFY(object != 0);
561     QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
562     QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
563     QCOMPARE(object->stringProperty(), QString("Hello World!"));
564     QCOMPARE(object->uintProperty(), uint(10));
565     QCOMPARE(object->intProperty(), -19);
566     QCOMPARE((float)object->realProperty(), float(23.2));
567     QCOMPARE((float)object->doubleProperty(), float(-19.7));
568     QCOMPARE((float)object->floatProperty(), float(8.5));
569     QCOMPARE(object->colorProperty(), QColor("red"));
570     QCOMPARE(object->dateProperty(), QDate(1982, 11, 25));
571     QCOMPARE(object->timeProperty(), QTime(11, 11, 32));
572     QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1)));
573     QCOMPARE(object->pointProperty(), QPoint(99,13));
574     QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3));
575     QCOMPARE(object->sizeProperty(), QSize(99, 13));
576     QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2));
577     QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200));
578     QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99));
579     QCOMPARE(object->boolProperty(), true);
580     QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
581     QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2));
582     QCOMPARE(object->vector4Property(), QVector4D(10, 1, 2.2, 2.3));
583     QUrl encoded;
584     encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
585     QCOMPARE(object->urlProperty(), component.url().resolved(encoded));
586     QVERIFY(object->objectProperty() != 0);
587     MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
588     QVERIFY(child != 0);
589     QCOMPARE(child->intProperty(), 8);
590 }
591
592 // Test edge case type assignments
593 void tst_qdeclarativelanguage::assignTypeExtremes()
594 {
595     QDeclarativeComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
596     VERIFY_ERRORS(0);
597     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
598     QVERIFY(object != 0);
599     QCOMPARE(object->uintProperty(), 0xEE6B2800);
600     QCOMPARE(object->intProperty(), -0x77359400);
601 }
602
603 // Test that a composite type can assign to a property of its base type
604 void tst_qdeclarativelanguage::assignCompositeToType()
605 {
606     QDeclarativeComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
607     VERIFY_ERRORS(0);
608     QObject *object = component.create();
609     QVERIFY(object != 0);
610 }
611
612 // Test that literals are stored correctly in variant properties
613 void tst_qdeclarativelanguage::assignLiteralToVariant()
614 {
615     QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
616     VERIFY_ERRORS(0);
617     QObject *object = component.create();
618     QVERIFY(object != 0);
619
620     QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
621     QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
622     QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
623     QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
624     QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
625     QCOMPARE(object->property("test6").userType(), (int)QVariant::PointF);
626     QCOMPARE(object->property("test7").userType(), (int)QVariant::SizeF);
627     QCOMPARE(object->property("test8").userType(), (int)QVariant::Vector3D);
628     QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
629     QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
630     QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
631     QCOMPARE(object->property("test12").userType(), (int)QVariant::Vector4D);
632
633     QVERIFY(object->property("test1") == QVariant(1));
634     QVERIFY(object->property("test2") == QVariant((double)1.7));
635     QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!"))));
636     QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800)));
637     QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10)));
638     QVERIFY(object->property("test6") == QVariant(QPointF(10, 10)));
639     QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10)));
640     QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100)));
641     QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800"))));
642     QVERIFY(object->property("test10") == QVariant(bool(true)));
643     QVERIFY(object->property("test11") == QVariant(bool(false)));
644     QVERIFY(object->property("test12") == QVariant(QVector4D(100, 100, 100, 100)));
645
646     delete object;
647 }
648
649 // Test that literals are stored correctly in "var" properties
650 // Note that behaviour differs from "variant" properties in that
651 // no conversion from "special strings" to QVariants is performed.
652 void tst_qdeclarativelanguage::assignLiteralToVar()
653 {
654     QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVar.qml"));
655     VERIFY_ERRORS(0);
656     QObject *object = component.create();
657     QVERIFY(object != 0);
658
659     QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
660     QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
661     QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
662     QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
663     QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
664     QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
665     QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
666     QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
667     QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
668     QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
669     QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
670     QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
671     QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
672     QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
673     QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
674     QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
675     QCOMPARE(object->property("variantTest1Bound").userType(), (int)QMetaType::Int);
676     QCOMPARE(object->property("test1Bound").userType(), (int)QMetaType::Int);
677
678     QCOMPARE(object->property("test1"), QVariant(5));
679     QCOMPARE(object->property("test2"), QVariant((double)1.7));
680     QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
681     QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
682     QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
683     QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
684     QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
685     QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
686     QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
687     QCOMPARE(object->property("test10"), QVariant(bool(true)));
688     QCOMPARE(object->property("test11"), QVariant(bool(false)));
689     QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
690     QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
691     QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
692     QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
693     QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
694     QCOMPARE(object->property("variantTest1Bound"), QVariant(9));
695     QCOMPARE(object->property("test1Bound"), QVariant(11));
696
697     delete object;
698 }
699
700 // Tests that custom parser types can be instantiated
701 void tst_qdeclarativelanguage::customParserTypes()
702 {
703     QDeclarativeComponent component(&engine, TEST_FILE("customParserTypes.qml"));
704     VERIFY_ERRORS(0);
705     QObject *object = component.create();
706     QVERIFY(object != 0);
707     QVERIFY(object->property("count") == QVariant(2));
708 }
709
710 // Tests that the root item can be a custom component
711 void tst_qdeclarativelanguage::rootAsQmlComponent()
712 {
713     QDeclarativeComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
714     VERIFY_ERRORS(0);
715     MyContainer *object = qobject_cast<MyContainer *>(component.create());
716     QVERIFY(object != 0);
717     QCOMPARE(object->property("x"), QVariant(11));
718     QCOMPARE(object->getChildren()->count(), 2);
719 }
720
721 // Tests that components can be specified inline
722 void tst_qdeclarativelanguage::inlineQmlComponents()
723 {
724     QDeclarativeComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
725     VERIFY_ERRORS(0);
726     MyContainer *object = qobject_cast<MyContainer *>(component.create());
727     QVERIFY(object != 0);
728     QCOMPARE(object->getChildren()->count(), 1);
729     QDeclarativeComponent *comp = qobject_cast<QDeclarativeComponent *>(object->getChildren()->at(0));
730     QVERIFY(comp != 0);
731     MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
732     QVERIFY(compObject != 0);
733     QCOMPARE(compObject->value(), 11);
734 }
735
736 // Tests that types that have an id property have it set
737 void tst_qdeclarativelanguage::idProperty()
738 {
739     QDeclarativeComponent component(&engine, TEST_FILE("idProperty.qml"));
740     VERIFY_ERRORS(0);
741     MyContainer *object = qobject_cast<MyContainer *>(component.create());
742     QVERIFY(object != 0);
743     QCOMPARE(object->getChildren()->count(), 1);
744     MyTypeObject *child = 
745         qobject_cast<MyTypeObject *>(object->getChildren()->at(0));
746     QVERIFY(child != 0);
747     QCOMPARE(child->id(), QString("myObjectId"));
748     QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
749 }
750
751 // Tests automatic connection to notify signals if "onBlahChanged" syntax is used
752 // even if the notify signal for "blah" is not called "blahChanged"
753 void tst_qdeclarativelanguage::autoNotifyConnection()
754 {
755     QDeclarativeComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
756     VERIFY_ERRORS(0);
757     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
758     QVERIFY(object != 0);
759     QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
760     QVERIFY(prop.isValid());
761
762     QCOMPARE(prop.read(object), QVariant::fromValue(false));
763     object->setPropertyWithNotify(1);
764     QCOMPARE(prop.read(object), QVariant::fromValue(true));
765 }
766
767 // Tests that signals can be assigned to
768 void tst_qdeclarativelanguage::assignSignal()
769 {
770     QDeclarativeComponent component(&engine, TEST_FILE("assignSignal.qml"));
771     VERIFY_ERRORS(0);
772     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
773     QVERIFY(object != 0);
774     QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
775     emit object->basicSignal();
776     QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)");
777     emit object->basicParameterizedSignal(9);
778 }
779
780 // Tests the creation and assignment of dynamic properties
781 void tst_qdeclarativelanguage::dynamicProperties()
782 {
783     QDeclarativeComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
784     VERIFY_ERRORS(0);
785     QObject *object = component.create();
786     QVERIFY(object != 0);
787     QCOMPARE(object->property("intProperty"), QVariant(10));
788     QCOMPARE(object->property("boolProperty"), QVariant(false));
789     QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
790     QCOMPARE(object->property("realProperty"), QVariant((qreal)-19.9));
791     QCOMPARE(object->property("stringProperty"), QVariant("Hello World!"));
792     QCOMPARE(object->property("urlProperty"), QVariant(TEST_FILE("main.qml")));
793     QCOMPARE(object->property("colorProperty"), QVariant(QColor("red")));
794     QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2)));
795     QCOMPARE(object->property("varProperty"), QVariant("Hello World!"));
796 }
797
798 // Test that nested types can use dynamic properties
799 void tst_qdeclarativelanguage::dynamicPropertiesNested()
800 {
801     QDeclarativeComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
802     VERIFY_ERRORS(0);
803     QObject *object = component.create();
804     QVERIFY(object != 0);
805
806     QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
807     QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
808     QCOMPARE(object->property("a").toInt(), 13); // New
809     QCOMPARE(object->property("b").toInt(), 12); // New
810
811     delete object;
812 }
813
814 // Tests the creation and assignment to dynamic list properties
815 void tst_qdeclarativelanguage::listProperties()
816 {
817     QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml"));
818     VERIFY_ERRORS(0);
819     QObject *object = component.create();
820     QVERIFY(object != 0);
821
822     QCOMPARE(object->property("test").toInt(), 2);
823 }
824
825 // Tests the creation and assignment of dynamic object properties
826 // ### Not complete
827 void tst_qdeclarativelanguage::dynamicObjectProperties()
828 {
829     {
830     QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
831     VERIFY_ERRORS(0);
832     QObject *object = component.create();
833     QVERIFY(object != 0);
834
835     QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
836     QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
837     }
838     {
839     QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
840     QEXPECT_FAIL("", "QTBUG-10822", Abort);
841     VERIFY_ERRORS(0);
842     QObject *object = component.create();
843     QVERIFY(object != 0);
844
845     QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
846     }
847 }
848
849 // Tests the declaration of dynamic signals and slots
850 void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
851 {
852     QTest::ignoreMessage(QtDebugMsg, "1921");
853
854     QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
855     VERIFY_ERRORS(0);
856     QObject *object = component.create();
857     QVERIFY(object != 0);
858     QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
859     QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
860     QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1);
861     QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
862
863     QCOMPARE(object->property("test").toInt(), 0);
864     QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
865     QCOMPARE(object->property("test").toInt(), 10);
866 }
867
868 void tst_qdeclarativelanguage::simpleBindings()
869 {
870     QDeclarativeComponent component(&engine, TEST_FILE("simpleBindings.qml"));
871     VERIFY_ERRORS(0);
872     QObject *object = component.create();
873     QVERIFY(object != 0);
874     QCOMPARE(object->property("value1"), QVariant(10));
875     QCOMPARE(object->property("value2"), QVariant(10));
876     QCOMPARE(object->property("value3"), QVariant(21));
877     QCOMPARE(object->property("value4"), QVariant(10));
878     QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
879 }
880
881 void tst_qdeclarativelanguage::autoComponentCreation()
882 {
883     QDeclarativeComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
884     VERIFY_ERRORS(0);
885     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
886     QVERIFY(object != 0);
887     QVERIFY(object->componentProperty() != 0);
888     MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
889     QVERIFY(child != 0);
890     QCOMPARE(child->realProperty(), qreal(9));
891 }
892
893 void tst_qdeclarativelanguage::propertyValueSource()
894 {
895     {
896     QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
897     VERIFY_ERRORS(0);
898     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
899     QVERIFY(object != 0);
900
901     QList<QObject *> valueSources;
902     QObjectList allChildren = object->findChildren<QObject*>();
903     foreach (QObject *child, allChildren) {
904         if (qobject_cast<QDeclarativePropertyValueSource *>(child)) 
905             valueSources.append(child);
906     }
907
908     QCOMPARE(valueSources.count(), 1);
909     MyPropertyValueSource *valueSource = 
910         qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
911     QVERIFY(valueSource != 0);
912     QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
913     QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
914     }
915
916     {
917     QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
918     VERIFY_ERRORS(0);
919     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
920     QVERIFY(object != 0);
921
922     QList<QObject *> valueSources;
923     QObjectList allChildren = object->findChildren<QObject*>();
924     foreach (QObject *child, allChildren) {
925         if (qobject_cast<QDeclarativePropertyValueSource *>(child)) 
926             valueSources.append(child);
927     }
928
929     QCOMPARE(valueSources.count(), 1);
930     MyPropertyValueSource *valueSource = 
931         qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
932     QVERIFY(valueSource != 0);
933     QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
934     QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
935     }
936 }
937
938 void tst_qdeclarativelanguage::attachedProperties()
939 {
940     QDeclarativeComponent component(&engine, TEST_FILE("attachedProperties.qml"));
941     VERIFY_ERRORS(0);
942     QObject *object = component.create();
943     QVERIFY(object != 0);
944     QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
945     QVERIFY(attached != 0);
946     QCOMPARE(attached->property("value"), QVariant(10));
947     QCOMPARE(attached->property("value2"), QVariant(13));
948 }
949
950 // Tests non-static object properties
951 void tst_qdeclarativelanguage::dynamicObjects()
952 {
953     QDeclarativeComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
954     VERIFY_ERRORS(0);
955     QObject *object = component.create();
956     QVERIFY(object != 0);
957 }
958
959 // Tests the registration of custom variant string converters
960 void tst_qdeclarativelanguage::customVariantTypes()
961 {
962     QDeclarativeComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
963     VERIFY_ERRORS(0);
964     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
965     QVERIFY(object != 0);
966     QCOMPARE(object->customType().a, 10);
967 }
968
969 void tst_qdeclarativelanguage::valueTypes()
970 {
971     QDeclarativeComponent component(&engine, TEST_FILE("valueTypes.qml"));
972     VERIFY_ERRORS(0);
973
974     QString message = component.url().toString() + ":2:1: QML MyTypeObject: Binding loop detected for property \"rectProperty.width\"";
975     QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
976     QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
977
978     MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
979     QVERIFY(object != 0);
980
981
982     QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
983     QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
984     QCOMPARE(object->intProperty(), 10);
985     object->doAction();
986     QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
987     QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
988     QCOMPARE(object->intProperty(), 12);
989
990     // ###
991 #if 0
992     QDeclarativeProperty p(object, "rectProperty.x");
993     QCOMPARE(p.read(), QVariant(12));
994     p.write(13);
995     QCOMPARE(p.read(), QVariant(13));
996
997     quint32 r = QDeclarativePropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
998     QDeclarativeProperty p2;
999     QDeclarativePropertyPrivate::restore(p2, r, object);
1000     QCOMPARE(p2.read(), QVariant(13));
1001 #endif
1002 }
1003
1004 void tst_qdeclarativelanguage::cppnamespace()
1005 {
1006     {
1007         QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.qml"));
1008         VERIFY_ERRORS(0);
1009         QObject *object = component.create();
1010         QVERIFY(object != 0);
1011         delete object;
1012     }
1013
1014     {
1015         QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
1016         VERIFY_ERRORS(0);
1017         QObject *object = component.create();
1018         QVERIFY(object != 0);
1019         delete object;
1020     }
1021 }
1022
1023 void tst_qdeclarativelanguage::aliasProperties()
1024 {
1025     // Simple "int" alias
1026     {
1027         QDeclarativeComponent component(&engine, TEST_FILE("alias.1.qml"));
1028         VERIFY_ERRORS(0);
1029         QObject *object = component.create();
1030         QVERIFY(object != 0);
1031
1032         // Read through alias
1033         QCOMPARE(object->property("valueAlias").toInt(), 10);
1034         object->setProperty("value", QVariant(13));
1035         QCOMPARE(object->property("valueAlias").toInt(), 13);
1036
1037         // Write through alias
1038         object->setProperty("valueAlias", QVariant(19));
1039         QCOMPARE(object->property("valueAlias").toInt(), 19);
1040         QCOMPARE(object->property("value").toInt(), 19);
1041
1042         delete object;
1043     }
1044
1045     // Complex object alias
1046     {
1047         QDeclarativeComponent component(&engine, TEST_FILE("alias.2.qml"));
1048         VERIFY_ERRORS(0);
1049         QObject *object = component.create();
1050         QVERIFY(object != 0);
1051
1052         // Read through alias
1053         MyQmlObject *v = 
1054             qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1055         QVERIFY(v != 0);
1056         QCOMPARE(v->value(), 10);
1057
1058         // Write through alias
1059         MyQmlObject *v2 = new MyQmlObject();
1060         v2->setParent(object);
1061         object->setProperty("aliasObject", qVariantFromValue(v2));
1062         MyQmlObject *v3 = 
1063             qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1064         QVERIFY(v3 != 0);
1065         QCOMPARE(v3, v2);
1066
1067         delete object;
1068     }
1069
1070     // Nested aliases
1071     {
1072         QDeclarativeComponent component(&engine, TEST_FILE("alias.3.qml"));
1073         VERIFY_ERRORS(0);
1074         QObject *object = component.create();
1075         QVERIFY(object != 0);
1076
1077         QCOMPARE(object->property("value").toInt(), 1892);
1078         QCOMPARE(object->property("value2").toInt(), 1892);
1079
1080         object->setProperty("value", QVariant(1313));
1081         QCOMPARE(object->property("value").toInt(), 1313);
1082         QCOMPARE(object->property("value2").toInt(), 1313);
1083
1084         object->setProperty("value2", QVariant(8080));
1085         QCOMPARE(object->property("value").toInt(), 8080);
1086         QCOMPARE(object->property("value2").toInt(), 8080);
1087
1088         delete object;
1089     }
1090
1091     // Enum aliases
1092     {
1093         QDeclarativeComponent component(&engine, TEST_FILE("alias.4.qml"));
1094         VERIFY_ERRORS(0);
1095         QObject *object = component.create();
1096         QVERIFY(object != 0);
1097
1098         QCOMPARE(object->property("enumAlias").toInt(), 1);
1099
1100         delete object;
1101     }
1102
1103     // Id aliases
1104     {
1105         QDeclarativeComponent component(&engine, TEST_FILE("alias.5.qml"));
1106         VERIFY_ERRORS(0);
1107         QObject *object = component.create();
1108         QVERIFY(object != 0);
1109
1110         QVariant v = object->property("otherAlias");
1111         QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1112         MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
1113         QCOMPARE(o->value(), 10);
1114
1115         delete o;
1116
1117         v = object->property("otherAlias");
1118         QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1119         o = qvariant_cast<MyQmlObject*>(v);
1120         QVERIFY(o == 0);
1121
1122         delete object;
1123     }
1124
1125     // Nested aliases - this used to cause a crash
1126     {
1127         QDeclarativeComponent component(&engine, TEST_FILE("alias.6.qml"));
1128         VERIFY_ERRORS(0);
1129         QObject *object = component.create();
1130         QVERIFY(object != 0);
1131
1132         QCOMPARE(object->property("a").toInt(), 1923);
1133     }
1134
1135     // Ptr Alias Cleanup - check that aliases to ptr types return 0 
1136     // if the object aliased to is removed
1137     {
1138         QDeclarativeComponent component(&engine, TEST_FILE("alias.7.qml"));
1139         VERIFY_ERRORS(0);
1140
1141         QObject *object = component.create();
1142         QVERIFY(object != 0);
1143
1144         QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
1145         QVERIFY(object1 != 0);
1146         QObject *object2 = qvariant_cast<QObject *>(object1->property("object"));
1147         QVERIFY(object2 != 0);
1148
1149         QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
1150         QVERIFY(alias == object2);
1151
1152         delete object1;
1153
1154         QObject *alias2 = object; // "Random" start value
1155         int status = -1;
1156         void *a[] = { &alias2, 0, &status };
1157         QMetaObject::metacall(object, QMetaObject::ReadProperty,
1158                               object->metaObject()->indexOfProperty("aliasedObject"), a);
1159         QVERIFY(alias2 == 0);
1160     }
1161
1162     // Simple composite type
1163     {
1164         QDeclarativeComponent component(&engine, TEST_FILE("alias.8.qml"));
1165         VERIFY_ERRORS(0);
1166         QObject *object = component.create();
1167         QVERIFY(object != 0);
1168
1169         QCOMPARE(object->property("value").toInt(), 10);
1170
1171         delete object;
1172     }
1173
1174     // Complex composite type
1175     {
1176         QDeclarativeComponent component(&engine, TEST_FILE("alias.9.qml"));
1177         VERIFY_ERRORS(0);
1178         QObject *object = component.create();
1179         QVERIFY(object != 0);
1180
1181         QCOMPARE(object->property("value").toInt(), 10);
1182
1183         delete object;
1184     }
1185
1186     // Valuetype alias
1187     // Simple "int" alias
1188     {
1189         QDeclarativeComponent component(&engine, TEST_FILE("alias.10.qml"));
1190         VERIFY_ERRORS(0);
1191         QObject *object = component.create();
1192         QVERIFY(object != 0);
1193
1194         // Read through alias
1195         QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8));
1196         object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
1197         QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
1198
1199         // Write through alias
1200         object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
1201         QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
1202         QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
1203
1204         delete object;
1205     }
1206
1207     // Valuetype sub-alias
1208     {
1209         QDeclarativeComponent component(&engine, TEST_FILE("alias.11.qml"));
1210         VERIFY_ERRORS(0);
1211         QObject *object = component.create();
1212         QVERIFY(object != 0);
1213
1214         // Read through alias
1215         QCOMPARE(object->property("aliasProperty").toInt(), 19);
1216         object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
1217         QCOMPARE(object->property("aliasProperty").toInt(), 33);
1218
1219         // Write through alias
1220         object->setProperty("aliasProperty", QVariant(4));
1221         QCOMPARE(object->property("aliasProperty").toInt(), 4);
1222         QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
1223
1224         delete object;
1225     }
1226 }
1227
1228 // QTBUG-13374 Test that alias properties and signals can coexist
1229 void tst_qdeclarativelanguage::aliasPropertiesAndSignals()
1230 {
1231     QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
1232     VERIFY_ERRORS(0);
1233     QObject *o = component.create();
1234     QVERIFY(o);
1235     QCOMPARE(o->property("test").toBool(), true);
1236     delete o;
1237 }
1238
1239 // Test that the root element in a composite type can be a Component
1240 void tst_qdeclarativelanguage::componentCompositeType()
1241 {
1242     QDeclarativeComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
1243     VERIFY_ERRORS(0);
1244     QObject *object = component.create();
1245     QVERIFY(object != 0);
1246 }
1247
1248 class TestType : public QObject {
1249     Q_OBJECT
1250 public:
1251     TestType(QObject *p=0) : QObject(p) {}
1252 };
1253
1254 class TestType2 : public QObject {
1255     Q_OBJECT
1256 public:
1257     TestType2(QObject *p=0) : QObject(p) {}
1258 };
1259
1260 void tst_qdeclarativelanguage::i18n_data()
1261 {
1262     QTest::addColumn<QString>("file");
1263     QTest::addColumn<QString>("stringProperty");
1264     QTest::newRow("i18nStrings") << "i18nStrings.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245 (5 accented 'a' letters)");
1265     QTest::newRow("i18nDeclaredPropertyNames") << "i18nDeclaredPropertyNames.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 10");
1266     QTest::newRow("i18nDeclaredPropertyUse") << "i18nDeclaredPropertyUse.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 15");
1267     QTest::newRow("i18nScript") << "i18nScript.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 20");
1268     QTest::newRow("i18nType") << "i18nType.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 30");
1269     QTest::newRow("i18nNameSpace") << "i18nNameSpace.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 40");
1270 }
1271
1272 void tst_qdeclarativelanguage::i18n()
1273 {
1274     QFETCH(QString, file);
1275     QFETCH(QString, stringProperty);
1276     QDeclarativeComponent component(&engine, TEST_FILE(file));
1277     VERIFY_ERRORS(0);
1278     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1279     QVERIFY(object != 0);
1280     QCOMPARE(object->stringProperty(), stringProperty);
1281
1282     delete object;
1283 }
1284
1285 // Check that the Component::onCompleted attached property works
1286 void tst_qdeclarativelanguage::onCompleted()
1287 {
1288     QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
1289     VERIFY_ERRORS(0);
1290     QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1291     QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1292     QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
1293     QObject *object = component.create();
1294     QVERIFY(object != 0);
1295 }
1296
1297 // Check that the Component::onDestruction attached property works
1298 void tst_qdeclarativelanguage::onDestruction()
1299 {
1300     QDeclarativeComponent component(&engine, TEST_FILE("onDestruction.qml"));
1301     VERIFY_ERRORS(0);
1302     QObject *object = component.create();
1303     QVERIFY(object != 0);
1304     QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1305     QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1306     QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
1307     delete object;
1308 }
1309
1310 // Check that assignments to QDeclarativeScriptString properties work
1311 void tst_qdeclarativelanguage::scriptString()
1312 {
1313     {
1314         QDeclarativeComponent component(&engine, TEST_FILE("scriptString.qml"));
1315         VERIFY_ERRORS(0);
1316
1317         MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1318         QVERIFY(object != 0);
1319         QCOMPARE(object->scriptProperty().script(), QString("foo + bar"));
1320         QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object));
1321         QCOMPARE(object->scriptProperty().context(), qmlContext(object));
1322
1323         QVERIFY(object->grouped() != 0);
1324         QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)"));
1325         QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object));
1326         QCOMPARE(object->grouped()->script().context(), qmlContext(object));
1327     }
1328
1329     {
1330         QDeclarativeComponent component(&engine, TEST_FILE("scriptString2.qml"));
1331         VERIFY_ERRORS(0);
1332
1333         MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1334         QVERIFY(object != 0);
1335         QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
1336     }
1337
1338     {
1339         QDeclarativeComponent component(&engine, TEST_FILE("scriptString3.qml"));
1340         VERIFY_ERRORS(0);
1341
1342         MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1343         QVERIFY(object != 0);
1344         QCOMPARE(object->scriptProperty().script(), QString("12.345"));
1345     }
1346
1347     {
1348         QDeclarativeComponent component(&engine, TEST_FILE("scriptString4.qml"));
1349         VERIFY_ERRORS(0);
1350
1351         MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1352         QVERIFY(object != 0);
1353         QCOMPARE(object->scriptProperty().script(), QString("true"));
1354     }
1355 }
1356
1357 // Check that default property assignments are correctly spliced into explicit 
1358 // property assignments
1359 void tst_qdeclarativelanguage::defaultPropertyListOrder()
1360 {
1361     QDeclarativeComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
1362     VERIFY_ERRORS(0);
1363
1364     MyContainer *container = qobject_cast<MyContainer *>(component.create());
1365     QVERIFY(container  != 0);
1366
1367     QCOMPARE(container->getChildren()->count(), 6);
1368     QCOMPARE(container->getChildren()->at(0)->property("index"), QVariant(0));
1369     QCOMPARE(container->getChildren()->at(1)->property("index"), QVariant(1));
1370     QCOMPARE(container->getChildren()->at(2)->property("index"), QVariant(2));
1371     QCOMPARE(container->getChildren()->at(3)->property("index"), QVariant(3));
1372     QCOMPARE(container->getChildren()->at(4)->property("index"), QVariant(4));
1373     QCOMPARE(container->getChildren()->at(5)->property("index"), QVariant(5));
1374 }
1375
1376 void tst_qdeclarativelanguage::declaredPropertyValues()
1377 {
1378     QDeclarativeComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
1379     VERIFY_ERRORS(0);
1380 }
1381
1382 void tst_qdeclarativelanguage::dontDoubleCallClassBegin()
1383 {
1384     QDeclarativeComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml"));
1385     QObject *o = component.create();
1386     QVERIFY(o);
1387
1388     MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
1389     QVERIFY(o2);
1390     QCOMPARE(o2->classBeginCount(), 1);
1391     QCOMPARE(o2->componentCompleteCount(), 1);
1392
1393     delete o;
1394 }
1395
1396 void tst_qdeclarativelanguage::reservedWords_data()
1397 {
1398     QTest::addColumn<QByteArray>("word");
1399
1400     QTest::newRow("abstract") << QByteArray("abstract");
1401     QTest::newRow("as") << QByteArray("as");
1402     QTest::newRow("boolean") << QByteArray("boolean");
1403     QTest::newRow("break") << QByteArray("break");
1404     QTest::newRow("byte") << QByteArray("byte");
1405     QTest::newRow("case") << QByteArray("case");
1406     QTest::newRow("catch") << QByteArray("catch");
1407     QTest::newRow("char") << QByteArray("char");
1408     QTest::newRow("class") << QByteArray("class");
1409     QTest::newRow("continue") << QByteArray("continue");
1410     QTest::newRow("const") << QByteArray("const");
1411     QTest::newRow("debugger") << QByteArray("debugger");
1412     QTest::newRow("default") << QByteArray("default");
1413     QTest::newRow("delete") << QByteArray("delete");
1414     QTest::newRow("do") << QByteArray("do");
1415     QTest::newRow("double") << QByteArray("double");
1416     QTest::newRow("else") << QByteArray("else");
1417     QTest::newRow("enum") << QByteArray("enum");
1418     QTest::newRow("export") << QByteArray("export");
1419     QTest::newRow("extends") << QByteArray("extends");
1420     QTest::newRow("false") << QByteArray("false");
1421     QTest::newRow("final") << QByteArray("final");
1422     QTest::newRow("finally") << QByteArray("finally");
1423     QTest::newRow("float") << QByteArray("float");
1424     QTest::newRow("for") << QByteArray("for");
1425     QTest::newRow("function") << QByteArray("function");
1426     QTest::newRow("goto") << QByteArray("goto");
1427     QTest::newRow("if") << QByteArray("if");
1428     QTest::newRow("implements") << QByteArray("implements");
1429     QTest::newRow("import") << QByteArray("import");
1430     QTest::newRow("in") << QByteArray("in");
1431     QTest::newRow("instanceof") << QByteArray("instanceof");
1432     QTest::newRow("int") << QByteArray("int");
1433     QTest::newRow("interface") << QByteArray("interface");
1434     QTest::newRow("long") << QByteArray("long");
1435     QTest::newRow("native") << QByteArray("native");
1436     QTest::newRow("new") << QByteArray("new");
1437     QTest::newRow("null") << QByteArray("null");
1438     QTest::newRow("package") << QByteArray("package");
1439     QTest::newRow("private") << QByteArray("private");
1440     QTest::newRow("protected") << QByteArray("protected");
1441     QTest::newRow("public") << QByteArray("public");
1442     QTest::newRow("return") << QByteArray("return");
1443     QTest::newRow("short") << QByteArray("short");
1444     QTest::newRow("static") << QByteArray("static");
1445     QTest::newRow("super") << QByteArray("super");
1446     QTest::newRow("switch") << QByteArray("switch");
1447     QTest::newRow("synchronized") << QByteArray("synchronized");
1448     QTest::newRow("this") << QByteArray("this");
1449     QTest::newRow("throw") << QByteArray("throw");
1450     QTest::newRow("throws") << QByteArray("throws");
1451     QTest::newRow("transient") << QByteArray("transient");
1452     QTest::newRow("true") << QByteArray("true");
1453     QTest::newRow("try") << QByteArray("try");
1454     QTest::newRow("typeof") << QByteArray("typeof");
1455     QTest::newRow("var") << QByteArray("var");
1456     QTest::newRow("void") << QByteArray("void");
1457     QTest::newRow("volatile") << QByteArray("volatile");
1458     QTest::newRow("while") << QByteArray("while");
1459     QTest::newRow("with") << QByteArray("with");
1460 }
1461
1462 void tst_qdeclarativelanguage::reservedWords()
1463 {
1464     QFETCH(QByteArray, word);
1465     QDeclarativeComponent component(&engine);
1466     component.setData("import QtQuick 2.0\nQtObject { property string " + word + " }", QUrl());
1467     QCOMPARE(component.errorString(), QLatin1String(":2 Expected token `identifier'\n"));
1468 }
1469
1470 // Check that first child of qml is of given type. Empty type insists on error.
1471 void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, const QString& expectederror)
1472 {
1473     QDeclarativeComponent component(&engine);
1474     component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
1475
1476     QTRY_VERIFY(!component.isLoading());
1477
1478     if (type.isEmpty()) {
1479         QVERIFY(component.isError());
1480         QString actualerror;
1481         foreach (const QDeclarativeError e, component.errors()) {
1482             if (!actualerror.isEmpty())
1483                 actualerror.append("; ");
1484             actualerror.append(e.description());
1485         }
1486         QCOMPARE(actualerror,expectederror);
1487     } else {
1488         VERIFY_ERRORS(0);
1489         QObject *object = component.create();
1490         QVERIFY(object != 0);
1491         QCOMPARE(QString(object->metaObject()->className()), type);
1492         delete object;
1493     }
1494 }
1495
1496 // QTBUG-17276
1497 void tst_qdeclarativelanguage::inlineAssignmentsOverrideBindings()
1498 {
1499     QDeclarativeComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml"));
1500
1501     QObject *o = component.create();
1502     QVERIFY(o != 0);
1503     QCOMPARE(o->property("test").toInt(), 11);
1504     delete o;
1505 }
1506
1507 // QTBUG-19354
1508 void tst_qdeclarativelanguage::nestedComponentRoots()
1509 {
1510     QDeclarativeComponent component(&engine, TEST_FILE("nestedComponentRoots.qml"));
1511 }
1512
1513 // Import tests (QT-558)
1514 void tst_qdeclarativelanguage::importsBuiltin_data()
1515 {
1516     // QT-610
1517
1518     QTest::addColumn<QString>("qml");
1519     QTest::addColumn<QString>("type");
1520     QTest::addColumn<QString>("error");
1521
1522     // import built-ins
1523     QTest::newRow("missing import")
1524         << "Test {}"
1525         << ""
1526         << "Test is not a type";
1527     QTest::newRow("not in version 0.0")
1528         << "import com.nokia.Test 0.0\n"
1529            "Test {}"
1530         << ""
1531         << "Test is not a type";
1532     QTest::newRow("version not installed")
1533         << "import com.nokia.Test 99.0\n"
1534            "Test {}"
1535         << ""
1536         << "module \"com.nokia.Test\" version 99.0 is not installed";
1537     QTest::newRow("in version 0.0")
1538         << "import com.nokia.Test 0.0\n"
1539            "TestTP {}"
1540         << "TestType"
1541         << "";
1542     QTest::newRow("qualified in version 0.0")
1543         << "import com.nokia.Test 0.0 as T\n"
1544            "T.TestTP {}"
1545         << "TestType"
1546         << "";
1547     QTest::newRow("in version 1.0")
1548         << "import com.nokia.Test 1.0\n"
1549            "Test {}"
1550         << "TestType"
1551         << "";
1552     QTest::newRow("qualified wrong")
1553         << "import com.nokia.Test 1.0 as T\n" // QT-610
1554            "Test {}"
1555         << ""
1556         << "Test is not a type";
1557     QTest::newRow("qualified right")
1558         << "import com.nokia.Test 1.0 as T\n"
1559            "T.Test {}"
1560         << "TestType"
1561         << "";
1562     QTest::newRow("qualified right but not in version 0.0")
1563         << "import com.nokia.Test 0.0 as T\n"
1564            "T.Test {}"
1565         << ""
1566         << "T.Test is not a type";
1567     QTest::newRow("in version 1.1")
1568         << "import com.nokia.Test 1.1\n"
1569            "Test {}"
1570         << "TestType"
1571         << "";
1572     QTest::newRow("in version 1.3")
1573         << "import com.nokia.Test 1.3\n"
1574            "Test {}"
1575         << "TestType"
1576         << "";
1577     QTest::newRow("in version 1.5")
1578         << "import com.nokia.Test 1.5\n"
1579            "Test {}"
1580         << "TestType"
1581         << "";
1582     QTest::newRow("changed in version 1.8")
1583         << "import com.nokia.Test 1.8\n"
1584            "Test {}"
1585         << "TestType2"
1586         << "";
1587     QTest::newRow("in version 1.12")
1588         << "import com.nokia.Test 1.12\n"
1589            "Test {}"
1590         << "TestType2"
1591         << "";
1592     QTest::newRow("old in version 1.9")
1593         << "import com.nokia.Test 1.9\n"
1594            "OldTest {}"
1595         << "TestType"
1596         << "";
1597     QTest::newRow("old in version 1.11")
1598         << "import com.nokia.Test 1.11\n"
1599            "OldTest {}"
1600         << "TestType"
1601         << "";
1602     QTest::newRow("multiversion 1")
1603         << "import com.nokia.Test 1.11\n"
1604            "import com.nokia.Test 1.12\n"
1605            "Test {}"
1606         << (!qmlCheckTypes()?"TestType2":"")
1607         << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1608     QTest::newRow("multiversion 2")
1609         << "import com.nokia.Test 1.11\n"
1610            "import com.nokia.Test 1.12\n"
1611            "OldTest {}"
1612         << (!qmlCheckTypes()?"TestType":"")
1613         << (!qmlCheckTypes()?"":"OldTest is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1614     QTest::newRow("qualified multiversion 3")
1615         << "import com.nokia.Test 1.0 as T0\n"
1616            "import com.nokia.Test 1.8 as T8\n"
1617            "T0.Test {}"
1618         << "TestType"
1619         << "";
1620     QTest::newRow("qualified multiversion 4")
1621         << "import com.nokia.Test 1.0 as T0\n"
1622            "import com.nokia.Test 1.8 as T8\n"
1623            "T8.Test {}"
1624         << "TestType2"
1625         << "";
1626 }
1627
1628 void tst_qdeclarativelanguage::importsBuiltin()
1629 {
1630     QFETCH(QString, qml);
1631     QFETCH(QString, type);
1632     QFETCH(QString, error);
1633     testType(qml,type,error);
1634 }
1635
1636 void tst_qdeclarativelanguage::importsLocal_data()
1637 {
1638     QTest::addColumn<QString>("qml");
1639     QTest::addColumn<QString>("type");
1640     QTest::addColumn<QString>("error");
1641
1642     // import locals
1643     QTest::newRow("local import")
1644         << "import \"subdir\"\n" // QT-613
1645            "Test {}"
1646         << "QQuickRectangle"
1647         << "";
1648     QTest::newRow("local import second")
1649         << "import QtQuick 2.0\nimport \"subdir\"\n"
1650            "Test {}"
1651         << "QQuickRectangle"
1652         << "";
1653     QTest::newRow("local import subsubdir")
1654         << "import QtQuick 2.0\nimport \"subdir/subsubdir\"\n"
1655            "SubTest {}"
1656         << "QQuickRectangle"
1657         << "";
1658     QTest::newRow("local import QTBUG-7721 A")
1659         << "subdir.Test {}" // no longer allowed (QTBUG-7721)
1660         << ""
1661         << "subdir.Test - subdir is not a namespace";
1662     QTest::newRow("local import QTBUG-7721 B")
1663         << "import \"subdir\" as X\n"
1664            "X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
1665         << ""
1666         << "X.subsubdir.SubTest - nested namespaces not allowed";
1667     QTest::newRow("local import as")
1668         << "import \"subdir\" as T\n"
1669            "T.Test {}"
1670         << "QQuickRectangle"
1671         << "";
1672     QTest::newRow("wrong local import as")
1673         << "import \"subdir\" as T\n"
1674            "Test {}"
1675         << ""
1676         << "Test is not a type";
1677     QTest::newRow("library precedence over local import")
1678         << "import \"subdir\"\n"
1679            "import com.nokia.Test 1.0\n"
1680            "Test {}"
1681         << (!qmlCheckTypes()?"TestType":"")
1682         << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test and in subdir");
1683 }
1684
1685 void tst_qdeclarativelanguage::importsLocal()
1686 {
1687     QFETCH(QString, qml);
1688     QFETCH(QString, type);
1689     QFETCH(QString, error);
1690     testType(qml,type,error);
1691 }
1692
1693 void tst_qdeclarativelanguage::basicRemote_data()
1694 {
1695     QTest::addColumn<QUrl>("url");
1696     QTest::addColumn<QString>("type");
1697     QTest::addColumn<QString>("error");
1698
1699     QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage/";
1700
1701     QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
1702     QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << "";
1703     QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
1704 }
1705
1706 void tst_qdeclarativelanguage::basicRemote()
1707 {
1708     QFETCH(QUrl, url);
1709     QFETCH(QString, type);
1710     QFETCH(QString, error);
1711
1712     TestHTTPServer server(14447);
1713     server.serveDirectory(testdata());
1714
1715     QDeclarativeComponent component(&engine, url);
1716
1717     QTRY_VERIFY(!component.isLoading());
1718
1719     if (error.isEmpty()) {
1720         if (component.isError())
1721             qDebug() << component.errors();
1722         QVERIFY(!component.isError());
1723     } else {
1724         QVERIFY(component.isError());
1725     }
1726 }
1727
1728 void tst_qdeclarativelanguage::importsRemote_data()
1729 {
1730     QTest::addColumn<QString>("qml");
1731     QTest::addColumn<QString>("type");
1732     QTest::addColumn<QString>("error");
1733
1734     QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage";
1735
1736     QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QQuickRectangle"
1737         << "";
1738     QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QQuickText"
1739         << "";
1740     QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QQuickImage"
1741         << "";
1742     QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
1743         << "WrongTestLocal is not a type";
1744     QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
1745         << "LocalInternal is not a type";
1746     QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""
1747         << "UndeclaredLocal is not a type";
1748 }
1749
1750 void tst_qdeclarativelanguage::importsRemote()
1751 {
1752     QFETCH(QString, qml);
1753     QFETCH(QString, type);
1754     QFETCH(QString, error);
1755
1756     TestHTTPServer server(14447);
1757     server.serveDirectory(testdata());
1758
1759     testType(qml,type,error);
1760 }
1761
1762 void tst_qdeclarativelanguage::importsInstalled_data()
1763 {
1764     // QT-610
1765
1766     QTest::addColumn<QString>("qml");
1767     QTest::addColumn<QString>("type");
1768     QTest::addColumn<QString>("error");
1769
1770     // import installed
1771     QTest::newRow("installed import 0")
1772         << "import com.nokia.installedtest0 0.0\n"
1773            "InstalledTestTP {}"
1774         << "QQuickRectangle"
1775         << "";
1776     QTest::newRow("installed import 0 as TP")
1777         << "import com.nokia.installedtest0 0.0 as TP\n"
1778            "TP.InstalledTestTP {}"
1779         << "QQuickRectangle"
1780         << "";
1781     QTest::newRow("installed import 1")
1782         << "import com.nokia.installedtest 1.0\n"
1783            "InstalledTest {}"
1784         << "QQuickRectangle"
1785         << "";
1786     QTest::newRow("installed import 2")
1787         << "import com.nokia.installedtest 1.3\n"
1788            "InstalledTest {}"
1789         << "QQuickRectangle"
1790         << "";
1791     QTest::newRow("installed import 3")
1792         << "import com.nokia.installedtest 1.4\n"
1793            "InstalledTest {}"
1794         << "QQuickText"
1795         << "";
1796     QTest::newRow("installed import minor version not available") // QTBUG-11936
1797         << "import com.nokia.installedtest 0.1\n"
1798            "InstalledTest {}"
1799         << ""
1800         << "module \"com.nokia.installedtest\" version 0.1 is not installed";
1801     QTest::newRow("installed import minor version not available") // QTBUG-9627
1802         << "import com.nokia.installedtest 1.10\n"
1803            "InstalledTest {}"
1804         << ""
1805         << "module \"com.nokia.installedtest\" version 1.10 is not installed";
1806     QTest::newRow("installed import major version not available") // QTBUG-9627
1807         << "import com.nokia.installedtest 9.0\n"
1808            "InstalledTest {}"
1809         << ""
1810         << "module \"com.nokia.installedtest\" version 9.0 is not installed";
1811     QTest::newRow("installed import visibility") // QT-614
1812         << "import com.nokia.installedtest 1.4\n"
1813            "PrivateType {}"
1814         << ""
1815         << "PrivateType is not a type";
1816 }
1817
1818 void tst_qdeclarativelanguage::importsInstalled()
1819 {
1820     QFETCH(QString, qml);
1821     QFETCH(QString, type);
1822     QFETCH(QString, error);
1823     testType(qml,type,error);
1824 }
1825
1826
1827 void tst_qdeclarativelanguage::importsOrder_data()
1828 {
1829     QTest::addColumn<QString>("qml");
1830     QTest::addColumn<QString>("type");
1831     QTest::addColumn<QString>("error");
1832
1833     QTest::newRow("double import") <<
1834            "import com.nokia.installedtest 1.4\n"
1835            "import com.nokia.installedtest 1.4\n"
1836            "InstalledTest {}"
1837            << (!qmlCheckTypes()?"QQuickText":"")
1838            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.4");
1839     QTest::newRow("installed import overrides 1") <<
1840            "import com.nokia.installedtest 1.0\n"
1841            "import com.nokia.installedtest 1.4\n"
1842            "InstalledTest {}"
1843            << (!qmlCheckTypes()?"QQuickText":"")
1844            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1845     QTest::newRow("installed import overrides 2") <<
1846            "import com.nokia.installedtest 1.4\n"
1847            "import com.nokia.installedtest 1.0\n"
1848            "InstalledTest {}"
1849            << (!qmlCheckTypes()?"QQuickRectangle":"")
1850            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1851     QTest::newRow("installed import re-overrides 1") <<
1852            "import com.nokia.installedtest 1.4\n"
1853            "import com.nokia.installedtest 1.0\n"
1854            "import com.nokia.installedtest 1.4\n"
1855            "InstalledTest {}"
1856            << (!qmlCheckTypes()?"QQuickText":"")
1857            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1858     QTest::newRow("installed import re-overrides 2") <<
1859            "import com.nokia.installedtest 1.4\n"
1860            "import com.nokia.installedtest 1.0\n"
1861            "import com.nokia.installedtest 1.4\n"
1862            "import com.nokia.installedtest 1.0\n"
1863            "InstalledTest {}"
1864            << (!qmlCheckTypes()?"QQuickRectangle":"")
1865            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1866
1867     QTest::newRow("installed import versus builtin 1") <<
1868            "import com.nokia.installedtest 1.5\n"
1869            "import QtQuick 2.0\n"
1870            "Rectangle {}"
1871            << (!qmlCheckTypes()?"QQuickRectangle":"")
1872            << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in Qt and in lib/com/nokia/installedtest");
1873     QTest::newRow("installed import versus builtin 2") <<
1874            "import QtQuick 2.0\n"
1875            "import com.nokia.installedtest 1.5\n"
1876            "Rectangle {}"
1877            << (!qmlCheckTypes()?"QQuickText":"")
1878            << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest and in Qt");
1879     QTest::newRow("namespaces cannot be overridden by types 1") <<
1880            "import QtQuick 2.0 as Rectangle\n"
1881            "import com.nokia.installedtest 1.5\n"
1882            "Rectangle {}"
1883         << ""
1884         << "Namespace Rectangle cannot be used as a type";
1885     QTest::newRow("namespaces cannot be overridden by types 2") <<
1886            "import QtQuick 2.0 as Rectangle\n"
1887            "import com.nokia.installedtest 1.5\n"
1888            "Rectangle.Image {}"
1889         << "QQuickImage"
1890         << "";
1891     QTest::newRow("local last 1") <<
1892            "LocalLast {}"
1893         << "QQuickText"
1894         << "";
1895     QTest::newRow("local last 2") <<
1896            "import com.nokia.installedtest 1.0\n"
1897            "LocalLast {}"
1898            << (!qmlCheckTypes()?"QQuickRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
1899            << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest and in local directory");
1900 }
1901
1902 void tst_qdeclarativelanguage::importsOrder()
1903 {
1904     QFETCH(QString, qml);
1905     QFETCH(QString, type);
1906     QFETCH(QString, error);
1907     testType(qml,type,error);
1908 }
1909
1910 void tst_qdeclarativelanguage::importIncorrectCase()
1911 {
1912     QDeclarativeComponent component(&engine, TEST_FILE("importIncorrectCase.qml"));
1913
1914     QList<QDeclarativeError> errors = component.errors();
1915     QCOMPARE(errors.count(), 1);
1916
1917 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1918     QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + testdata("lib/com/Nokia/installedtest/qmldir") + QLatin1String("\"");
1919 #else
1920     QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
1921 #endif
1922
1923     QCOMPARE(errors.at(0).description(), expectedError);
1924 }
1925
1926 void tst_qdeclarativelanguage::qmlAttachedPropertiesObjectMethod()
1927 {
1928     QObject object;
1929
1930     QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
1931     QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
1932
1933     {
1934         QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
1935         VERIFY_ERRORS(0);
1936         QObject *object = component.create();
1937         QVERIFY(object != 0);
1938
1939         QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
1940         QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1941     }
1942
1943     {
1944         QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
1945         VERIFY_ERRORS(0);
1946         QObject *object = component.create();
1947         QVERIFY(object != 0);
1948
1949         QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
1950         QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1951     }
1952 }
1953
1954 void tst_qdeclarativelanguage::crash1()
1955 {
1956     QDeclarativeComponent component(&engine);
1957     component.setData("import QtQuick 2.0\nComponent {}", QUrl());
1958 }
1959
1960 void tst_qdeclarativelanguage::crash2()
1961 {
1962     QDeclarativeComponent component(&engine, TEST_FILE("crash2.qml"));
1963 }
1964
1965 // QTBUG-8676
1966 void tst_qdeclarativelanguage::customOnProperty()
1967 {
1968     QDeclarativeComponent component(&engine, TEST_FILE("customOnProperty.qml"));
1969
1970     VERIFY_ERRORS(0);
1971     QObject *object = component.create();
1972     QVERIFY(object != 0);
1973
1974     QCOMPARE(object->property("on").toInt(), 10);
1975
1976     delete object;
1977 }
1978
1979 // QTBUG-12601
1980 void tst_qdeclarativelanguage::variantNotify()
1981 {
1982     QDeclarativeComponent component(&engine, TEST_FILE("variantNotify.qml"));
1983
1984     VERIFY_ERRORS(0);
1985     QObject *object = component.create();
1986     QVERIFY(object != 0);
1987
1988     QCOMPARE(object->property("notifyCount").toInt(), 1);
1989
1990     delete object;
1991 }
1992
1993 void tst_qdeclarativelanguage::revisions()
1994 {
1995     {
1996         QDeclarativeComponent component(&engine, TEST_FILE("revisions11.qml"));
1997
1998         VERIFY_ERRORS(0);
1999         MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
2000         QVERIFY(object != 0);
2001
2002         QCOMPARE(object->prop2(), 10.0);
2003
2004         delete object;
2005     }
2006     {
2007         QDeclarativeEngine myEngine;
2008         QDeclarativeComponent component(&myEngine, TEST_FILE("revisionssub11.qml"));
2009
2010         VERIFY_ERRORS(0);
2011         MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
2012         QVERIFY(object != 0);
2013
2014         QCOMPARE(object->prop1(), 10.0);
2015         QCOMPARE(object->prop2(), 10.0);
2016         QCOMPARE(object->prop3(), 10.0);
2017         QCOMPARE(object->prop4(), 10.0);
2018
2019         delete object;
2020     }
2021     {
2022         QDeclarativeComponent component(&engine, TEST_FILE("versionedbase.qml"));
2023         VERIFY_ERRORS(0);
2024         MySubclass *object = qobject_cast<MySubclass*>(component.create());
2025         QVERIFY(object != 0);
2026
2027         QCOMPARE(object->prop1(), 10.0);
2028         QCOMPARE(object->prop2(), 10.0);
2029
2030         delete object;
2031     }
2032 }
2033
2034 void tst_qdeclarativelanguage::revisionOverloads()
2035 {
2036     {
2037     QDeclarativeComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml"));
2038     VERIFY_ERRORS(0);
2039     }
2040     {
2041     QDeclarativeComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml"));
2042     QEXPECT_FAIL("", "QTBUG-13849", Abort);
2043     QVERIFY(0);
2044     VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt");
2045     }
2046 }
2047
2048 void tst_qdeclarativelanguage::initTestCase()
2049 {
2050     QString testdataDir = QFileInfo(QFINDTESTDATA("data")).absolutePath();
2051     QVERIFY2(QDir::setCurrent(testdataDir), qPrintable("Could not chdir to " + testdataDir));
2052
2053     registerTypes();
2054
2055     // Registering the TestType class in other modules should have no adverse effects
2056     qmlRegisterType<TestType>("com.nokia.TestPre", 1, 0, "Test");
2057
2058     qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP");
2059     qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test");
2060     qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test");
2061     qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test");
2062     qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest");
2063     qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test");
2064
2065     // Registering the TestType class in other modules should have no adverse effects
2066     qmlRegisterType<TestType>("com.nokia.TestPost", 1, 0, "Test");
2067
2068     // Create locale-specific file
2069     // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit
2070     // For iso8859-1 locale, this will just be data/I18nType?????.qml where ????? is 5 8-bit characters
2071     // For utf-8 locale, this will be data/I18nType??????????.qml where ?????????? is 5 8-bit characters, UTF-8 encoded
2072     QFile in(TEST_FILE(QLatin1String("I18nType30.qml")).toLocalFile());
2073     QVERIFY2(in.open(QIODevice::ReadOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(in.fileName(), in.errorString())));
2074     QFile out(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile());
2075     QVERIFY2(out.open(QIODevice::WriteOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(out.fileName(), out.errorString())));
2076     out.write(in.readAll());
2077 }
2078
2079 void tst_qdeclarativelanguage::aliasPropertyChangeSignals()
2080 {
2081     {
2082         QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.qml"));
2083
2084         VERIFY_ERRORS(0);
2085         QObject *o = component.create();
2086         QVERIFY(o != 0);
2087
2088         QCOMPARE(o->property("test").toBool(), true);
2089
2090         delete o;
2091     }
2092
2093     // QTCREATORBUG-2769
2094     {
2095         QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.2.qml"));
2096
2097         VERIFY_ERRORS(0);
2098         QObject *o = component.create();
2099         QVERIFY(o != 0);
2100
2101         QCOMPARE(o->property("test").toBool(), true);
2102
2103         delete o;
2104     }
2105 }
2106
2107 // Tests property initializers
2108 void tst_qdeclarativelanguage::propertyInit()
2109 {
2110     {
2111         QDeclarativeComponent component(&engine, TEST_FILE("propertyInit.1.qml"));
2112
2113         VERIFY_ERRORS(0);
2114         QObject *o = component.create();
2115         QVERIFY(o != 0);
2116
2117         QCOMPARE(o->property("test").toInt(), 1);
2118
2119         delete o;
2120     }
2121
2122     {
2123         QDeclarativeComponent component(&engine, TEST_FILE("propertyInit.2.qml"));
2124
2125         VERIFY_ERRORS(0);
2126         QObject *o = component.create();
2127         QVERIFY(o != 0);
2128
2129         QCOMPARE(o->property("test").toInt(), 123);
2130
2131         delete o;
2132     }
2133 }
2134
2135 // Test that registration order doesn't break type availability
2136 // QTBUG-16878
2137 void tst_qdeclarativelanguage::registrationOrder()
2138 {
2139     QDeclarativeComponent component(&engine, TEST_FILE("registrationOrder.qml"));
2140
2141     QObject *o = component.create();
2142     QVERIFY(o != 0);
2143     QVERIFY(o->metaObject() == &MyVersion2Class::staticMetaObject);
2144     delete o;
2145 }
2146
2147 void tst_qdeclarativelanguage::readonly()
2148 {
2149     QDeclarativeComponent component(&engine, TEST_FILE("readonly.qml"));
2150
2151     QObject *o = component.create();
2152     QVERIFY(o != 0);
2153
2154     QCOMPARE(o->property("test1").toInt(), 10);
2155     QCOMPARE(o->property("test2").toInt(), 18);
2156     QCOMPARE(o->property("test3").toInt(), 13);
2157
2158     o->setProperty("testData", 13);
2159
2160     QCOMPARE(o->property("test1").toInt(), 10);
2161     QCOMPARE(o->property("test2").toInt(), 22);
2162     QCOMPARE(o->property("test3").toInt(), 13);
2163
2164     o->setProperty("testData2", 2);
2165
2166     QCOMPARE(o->property("test1").toInt(), 10);
2167     QCOMPARE(o->property("test2").toInt(), 22);
2168     QCOMPARE(o->property("test3").toInt(), 2);
2169
2170     o->setProperty("test1", 11);
2171     o->setProperty("test2", 11);
2172     o->setProperty("test3", 11);
2173
2174     QCOMPARE(o->property("test1").toInt(), 10);
2175     QCOMPARE(o->property("test2").toInt(), 22);
2176     QCOMPARE(o->property("test3").toInt(), 2);
2177
2178     delete o;
2179 }
2180
2181 // QTBUG-18268
2182 void tst_qdeclarativelanguage::remoteLoadCrash()
2183 {
2184     TestHTTPServer server(14448);
2185     server.serveDirectory(testdata());
2186
2187     QDeclarativeComponent component(&engine);
2188     component.setData("import QtQuick 1.0; Text {}", QUrl("http://127.0.0.1:14448/remoteLoadCrash.qml"));
2189     while (component.isLoading()) 
2190         QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
2191
2192     QObject *o = component.create();
2193     delete o;
2194 }
2195
2196 QTEST_MAIN(tst_qdeclarativelanguage)
2197
2198 #include "tst_qdeclarativelanguage.moc"