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