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