1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
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
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
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>
49 #include <private/qdeclarativeproperty_p.h>
50 #include <private/qdeclarativemetatype_p.h>
51 #include <private/qdeclarativeglobal_p.h>
53 #include "testtypes.h"
55 #include "../../../shared/util.h"
56 #include "testhttpserver.h"
59 // In Symbian OS test data is located in applications private dir
63 DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)
67 This test case covers QML language issues. This covers everything that does not
68 involve evaluating ECMAScript expressions and bindings.
70 Evaluation of expressions and bindings is covered in qmlecmascript
72 class tst_qdeclarativelanguage : public QObject
76 tst_qdeclarativelanguage() {
77 QDeclarativeMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter);
78 QFileInfo fileInfo(__FILE__);
79 engine.addImportPath(fileInfo.absoluteDir().filePath(QLatin1String("data/lib")));
84 void cleanupTestCase();
89 void insertedSemicolon_data();
90 void insertedSemicolon();
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();
108 void autoNotifyConnection();
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();
123 void aliasProperties();
124 void aliasPropertiesAndSignals();
125 void aliasPropertyChangeSignals();
126 void componentCompositeType();
130 void onDestruction();
132 void defaultPropertyListOrder();
133 void declaredPropertyValues();
134 void dontDoubleCallClassBegin();
135 void reservedWords_data();
136 void reservedWords();
137 void inlineAssignmentsOverrideBindings();
139 void basicRemote_data();
141 void importsBuiltin_data();
142 void importsBuiltin();
143 void importsLocal_data();
145 void importsRemote_data();
146 void importsRemote();
147 void importsInstalled_data();
148 void importsInstalled();
149 void importsOrder_data();
151 void importIncorrectCase();
153 void qmlAttachedPropertiesObjectMethod();
154 void customOnProperty();
155 void variantNotify();
158 void revisionOverloads();
160 // regression tests for crashes
165 QDeclarativeEngine engine;
166 void testType(const QString& qml, const QString& type, const QString& error);
169 #define VERIFY_ERRORS(errorfile) \
171 if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
172 qWarning() << "Unexpected Errors:" << component.errors(); \
173 QVERIFY(!component.isError()); \
174 QVERIFY(component.errors().isEmpty()); \
176 QFile file(QLatin1String(SRCDIR) + QLatin1String("/data/") + QLatin1String(errorfile)); \
177 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
178 QByteArray data = file.readAll(); \
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; \
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"); \
201 QCOMPARE(expected, actual); \
205 inline QUrl TEST_FILE(const QString &filename)
207 QFileInfo fileInfo(__FILE__);
208 return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(QLatin1String("data/") + filename));
211 inline QUrl TEST_FILE(const char *filename)
213 return TEST_FILE(QLatin1String(filename));
216 void tst_qdeclarativelanguage::cleanupTestCase()
218 QVERIFY(QFile::remove(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile()));
221 void tst_qdeclarativelanguage::insertedSemicolon_data()
223 QTest::addColumn<QString>("file");
224 QTest::addColumn<QString>("errorFile");
225 QTest::addColumn<bool>("create");
227 QTest::newRow("insertedSemicolon.1") << "insertedSemicolon.1.qml" << "insertedSemicolon.1.errors.txt" << false;
230 void tst_qdeclarativelanguage::insertedSemicolon()
232 QFETCH(QString, file);
233 QFETCH(QString, errorFile);
234 QFETCH(bool, create);
236 QDeclarativeComponent component(&engine, TEST_FILE(file));
239 QObject *object = component.create();
240 QVERIFY(object == 0);
243 VERIFY_ERRORS(errorFile.toLatin1().constData());
246 void tst_qdeclarativelanguage::errors_data()
248 QTest::addColumn<QString>("file");
249 QTest::addColumn<QString>("errorFile");
250 QTest::addColumn<bool>("create");
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;
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;
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 QTest::newRow("wrongType (int for enum)") << "wrongType.17.qml" << "wrongType.17.errors.txt" << false;
278 QTest::newRow("readOnly.1") << "readOnly.1.qml" << "readOnly.1.errors.txt" << false;
279 QTest::newRow("readOnly.2") << "readOnly.2.qml" << "readOnly.2.errors.txt" << false;
280 QTest::newRow("readOnly.3") << "readOnly.3.qml" << "readOnly.3.errors.txt" << false;
281 QTest::newRow("readOnly.4") << "readOnly.4.qml" << "readOnly.4.errors.txt" << false;
282 QTest::newRow("readOnly.5") << "readOnly.5.qml" << "readOnly.5.errors.txt" << false;
284 QTest::newRow("listAssignment.1") << "listAssignment.1.qml" << "listAssignment.1.errors.txt" << false;
285 QTest::newRow("listAssignment.2") << "listAssignment.2.qml" << "listAssignment.2.errors.txt" << false;
286 QTest::newRow("listAssignment.3") << "listAssignment.3.qml" << "listAssignment.3.errors.txt" << false;
288 QTest::newRow("invalidID.1") << "invalidID.qml" << "invalidID.errors.txt" << false;
289 QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
290 QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
291 QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
292 QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
293 QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false;
294 QTest::newRow("invalidID.7") << "invalidID.7.qml" << "invalidID.7.errors.txt" << false;
295 QTest::newRow("invalidID.8") << "invalidID.8.qml" << "invalidID.8.errors.txt" << false;
296 QTest::newRow("invalidID.9") << "invalidID.9.qml" << "invalidID.9.errors.txt" << false;
298 QTest::newRow("scriptString.1") << "scriptString.1.qml" << "scriptString.1.errors.txt" << false;
299 QTest::newRow("scriptString.2") << "scriptString.2.qml" << "scriptString.2.errors.txt" << false;
301 QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
302 QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;
303 QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false;
304 QTest::newRow("duplicateIDs") << "duplicateIDs.qml" << "duplicateIDs.errors.txt" << false;
305 QTest::newRow("unregisteredObject") << "unregisteredObject.qml" << "unregisteredObject.errors.txt" << false;
306 QTest::newRow("empty") << "empty.qml" << "empty.errors.txt" << false;
307 QTest::newRow("missingObject") << "missingObject.qml" << "missingObject.errors.txt" << false;
308 QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
309 QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
310 QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
311 QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
313 QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
314 QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
315 QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
316 QTest::newRow("invalidGroupedProperty.4") << "invalidGroupedProperty.4.qml" << "invalidGroupedProperty.4.errors.txt" << false;
317 QTest::newRow("invalidGroupedProperty.5") << "invalidGroupedProperty.5.qml" << "invalidGroupedProperty.5.errors.txt" << false;
318 QTest::newRow("invalidGroupedProperty.6") << "invalidGroupedProperty.6.qml" << "invalidGroupedProperty.6.errors.txt" << false;
319 QTest::newRow("invalidGroupedProperty.7") << "invalidGroupedProperty.7.qml" << "invalidGroupedProperty.7.errors.txt" << true;
320 QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
321 QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
322 QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
324 QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
325 QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
326 QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false;
327 QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false;
328 QTest::newRow("importNonExistOlder (installed)") << "importNonExistOlder.qml" << "importNonExistOlder.errors.txt" << false;
329 QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false;
330 QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false;
331 QTest::newRow("importFile") << "importFile.qml" << "importFile.errors.txt" << false;
333 QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false;
334 QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false;
335 QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false;
336 QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false;
338 QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
340 QTest::newRow("property.1") << "property.1.qml" << "property.1.errors.txt" << false;
341 QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
342 QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
343 QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
344 QTest::newRow("property.5") << "property.5.qml" << "property.5.errors.txt" << false;
345 QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
346 QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
348 QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
350 QTest::newRow("Component.1") << "component.1.qml" << "component.1.errors.txt" << false;
351 QTest::newRow("Component.2") << "component.2.qml" << "component.2.errors.txt" << false;
352 QTest::newRow("Component.3") << "component.3.qml" << "component.3.errors.txt" << false;
353 QTest::newRow("Component.4") << "component.4.qml" << "component.4.errors.txt" << false;
354 QTest::newRow("Component.5") << "component.5.qml" << "component.5.errors.txt" << false;
355 QTest::newRow("Component.6") << "component.6.qml" << "component.6.errors.txt" << false;
356 QTest::newRow("Component.7") << "component.7.qml" << "component.7.errors.txt" << false;
357 QTest::newRow("Component.8") << "component.8.qml" << "component.8.errors.txt" << false;
358 QTest::newRow("Component.9") << "component.9.qml" << "component.9.errors.txt" << false;
360 QTest::newRow("MultiSet.1") << "multiSet.1.qml" << "multiSet.1.errors.txt" << false;
361 QTest::newRow("MultiSet.2") << "multiSet.2.qml" << "multiSet.2.errors.txt" << false;
362 QTest::newRow("MultiSet.3") << "multiSet.3.qml" << "multiSet.3.errors.txt" << false;
363 QTest::newRow("MultiSet.4") << "multiSet.4.qml" << "multiSet.4.errors.txt" << false;
364 QTest::newRow("MultiSet.5") << "multiSet.5.qml" << "multiSet.5.errors.txt" << false;
365 QTest::newRow("MultiSet.6") << "multiSet.6.qml" << "multiSet.6.errors.txt" << false;
366 QTest::newRow("MultiSet.7") << "multiSet.7.qml" << "multiSet.7.errors.txt" << false;
367 QTest::newRow("MultiSet.8") << "multiSet.8.qml" << "multiSet.8.errors.txt" << false;
368 QTest::newRow("MultiSet.9") << "multiSet.9.qml" << "multiSet.9.errors.txt" << false;
369 QTest::newRow("MultiSet.10") << "multiSet.10.qml" << "multiSet.10.errors.txt" << false;
370 QTest::newRow("MultiSet.11") << "multiSet.11.qml" << "multiSet.11.errors.txt" << false;
372 QTest::newRow("dynamicMeta.1") << "dynamicMeta.1.qml" << "dynamicMeta.1.errors.txt" << false;
373 QTest::newRow("dynamicMeta.2") << "dynamicMeta.2.qml" << "dynamicMeta.2.errors.txt" << false;
374 QTest::newRow("dynamicMeta.3") << "dynamicMeta.3.qml" << "dynamicMeta.3.errors.txt" << false;
375 QTest::newRow("dynamicMeta.4") << "dynamicMeta.4.qml" << "dynamicMeta.4.errors.txt" << false;
376 QTest::newRow("dynamicMeta.5") << "dynamicMeta.5.qml" << "dynamicMeta.5.errors.txt" << false;
378 QTest::newRow("invalidAlias.1") << "invalidAlias.1.qml" << "invalidAlias.1.errors.txt" << false;
379 QTest::newRow("invalidAlias.2") << "invalidAlias.2.qml" << "invalidAlias.2.errors.txt" << false;
380 QTest::newRow("invalidAlias.3") << "invalidAlias.3.qml" << "invalidAlias.3.errors.txt" << false;
381 QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false;
382 QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
383 QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
384 QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false;
385 QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
386 QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
387 QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
389 QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
390 QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
391 QTest::newRow("invalidAttachedProperty.3") << "invalidAttachedProperty.3.qml" << "invalidAttachedProperty.3.errors.txt" << false;
392 QTest::newRow("invalidAttachedProperty.4") << "invalidAttachedProperty.4.qml" << "invalidAttachedProperty.4.errors.txt" << false;
393 QTest::newRow("invalidAttachedProperty.5") << "invalidAttachedProperty.5.qml" << "invalidAttachedProperty.5.errors.txt" << false;
394 QTest::newRow("invalidAttachedProperty.6") << "invalidAttachedProperty.6.qml" << "invalidAttachedProperty.6.errors.txt" << false;
395 QTest::newRow("invalidAttachedProperty.7") << "invalidAttachedProperty.7.qml" << "invalidAttachedProperty.7.errors.txt" << false;
396 QTest::newRow("invalidAttachedProperty.8") << "invalidAttachedProperty.8.qml" << "invalidAttachedProperty.8.errors.txt" << false;
397 QTest::newRow("invalidAttachedProperty.9") << "invalidAttachedProperty.9.qml" << "invalidAttachedProperty.9.errors.txt" << false;
398 QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false;
399 QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false;
400 QTest::newRow("invalidAttachedProperty.12") << "invalidAttachedProperty.12.qml" << "invalidAttachedProperty.12.errors.txt" << false;
401 QTest::newRow("invalidAttachedProperty.13") << "invalidAttachedProperty.13.qml" << "invalidAttachedProperty.13.errors.txt" << false;
403 QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
404 QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
406 QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false;
407 QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false;
408 QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false;
409 QTest::newRow("invalidRoot") << "invalidRoot.qml" << "invalidRoot.errors.txt" << false;
410 QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false;
411 QTest::newRow("objectValueTypeProperty") << "objectValueTypeProperty.qml" << "objectValueTypeProperty.errors.txt" << false;
412 QTest::newRow("enumTypes") << "enumTypes.qml" << "enumTypes.errors.txt" << false;
413 QTest::newRow("noCreation") << "noCreation.qml" << "noCreation.errors.txt" << false;
414 QTest::newRow("destroyedSignal") << "destroyedSignal.qml" << "destroyedSignal.errors.txt" << false;
415 QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false;
416 QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false;
417 QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false;
418 QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false;
419 QTest::newRow("notAvailable") << "notAvailable.qml" << "notAvailable.errors.txt" << false;
420 QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
421 QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
422 QTest::newRow("incorrectCase") << "incorrectCase.qml"
423 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
424 << "incorrectCase.errors.insensitive.txt"
426 << "incorrectCase.errors.sensitive.txt"
430 QTest::newRow("metaobjectRevision.1") << "metaobjectRevision.1.qml" << "metaobjectRevision.1.errors.txt" << false;
431 QTest::newRow("metaobjectRevision.2") << "metaobjectRevision.2.qml" << "metaobjectRevision.2.errors.txt" << false;
432 QTest::newRow("metaobjectRevision.3") << "metaobjectRevision.3.qml" << "metaobjectRevision.3.errors.txt" << false;
436 void tst_qdeclarativelanguage::errors()
438 QFETCH(QString, file);
439 QFETCH(QString, errorFile);
440 QFETCH(bool, create);
442 QDeclarativeComponent component(&engine, TEST_FILE(file));
445 QObject *object = component.create();
446 QVERIFY(object == 0);
449 VERIFY_ERRORS(errorFile.toLatin1().constData());
452 void tst_qdeclarativelanguage::simpleObject()
454 QDeclarativeComponent component(&engine, TEST_FILE("simpleObject.qml"));
456 QObject *object = component.create();
457 QVERIFY(object != 0);
460 void tst_qdeclarativelanguage::simpleContainer()
462 QDeclarativeComponent component(&engine, TEST_FILE("simpleContainer.qml"));
464 MyContainer *container= qobject_cast<MyContainer*>(component.create());
465 QVERIFY(container != 0);
466 QCOMPARE(container->getChildren()->count(),2);
469 void tst_qdeclarativelanguage::interfaceProperty()
471 QDeclarativeComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
473 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
474 QVERIFY(object != 0);
475 QVERIFY(object->interface());
476 QVERIFY(object->interface()->id == 913);
479 void tst_qdeclarativelanguage::interfaceQList()
481 QDeclarativeComponent component(&engine, TEST_FILE("interfaceQList.qml"));
483 MyContainer *container= qobject_cast<MyContainer*>(component.create());
484 QVERIFY(container != 0);
485 QVERIFY(container->getQListInterfaces()->count() == 2);
486 for(int ii = 0; ii < 2; ++ii)
487 QVERIFY(container->getQListInterfaces()->at(ii)->id == 913);
490 void tst_qdeclarativelanguage::assignObjectToSignal()
492 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
494 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
495 QVERIFY(object != 0);
496 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
497 emit object->basicSignal();
500 void tst_qdeclarativelanguage::assignObjectToVariant()
502 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
504 QObject *object = component.create();
505 QVERIFY(object != 0);
506 QVariant v = object->property("a");
507 QVERIFY(v.userType() == qMetaTypeId<QObject *>());
510 void tst_qdeclarativelanguage::assignLiteralSignalProperty()
512 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
514 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
515 QVERIFY(object != 0);
516 QCOMPARE(object->onLiteralSignal(), 10);
519 // Test is an external component can be loaded and assigned (to a qlist)
520 void tst_qdeclarativelanguage::assignQmlComponent()
522 QDeclarativeComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
524 MyContainer *object = qobject_cast<MyContainer *>(component.create());
525 QVERIFY(object != 0);
526 QVERIFY(object->getChildren()->count() == 1);
527 QObject *child = object->getChildren()->at(0);
528 QCOMPARE(child->property("x"), QVariant(10));
529 QCOMPARE(child->property("y"), QVariant(11));
532 // Test literal assignment to all the basic types
533 void tst_qdeclarativelanguage::assignBasicTypes()
535 QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
537 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
538 QVERIFY(object != 0);
539 QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
540 QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
541 QCOMPARE(object->stringProperty(), QString("Hello World!"));
542 QCOMPARE(object->uintProperty(), uint(10));
543 QCOMPARE(object->intProperty(), -19);
544 QCOMPARE((float)object->realProperty(), float(23.2));
545 QCOMPARE((float)object->doubleProperty(), float(-19.7));
546 QCOMPARE((float)object->floatProperty(), float(8.5));
547 QCOMPARE(object->colorProperty(), QColor("red"));
548 QCOMPARE(object->dateProperty(), QDate(1982, 11, 25));
549 QCOMPARE(object->timeProperty(), QTime(11, 11, 32));
550 QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1)));
551 QCOMPARE(object->pointProperty(), QPoint(99,13));
552 QCOMPARE(object->pointFProperty(), QPointF((float)-10.1, (float)12.3));
553 QCOMPARE(object->sizeProperty(), QSize(99, 13));
554 QCOMPARE(object->sizeFProperty(), QSizeF((float)0.1, (float)0.2));
555 QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200));
556 QCOMPARE(object->rectFProperty(), QRectF((float)1000.1, (float)-10.9, (float)400, (float)90.99));
557 QCOMPARE(object->boolProperty(), true);
558 QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
559 QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2));
560 QCOMPARE(object->urlProperty(), component.url().resolved(QUrl("main.qml")));
561 QVERIFY(object->objectProperty() != 0);
562 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
564 QCOMPARE(child->intProperty(), 8);
567 // Test edge case type assignments
568 void tst_qdeclarativelanguage::assignTypeExtremes()
570 QDeclarativeComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
572 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
573 QVERIFY(object != 0);
574 QCOMPARE(object->uintProperty(), 0xEE6B2800);
575 QCOMPARE(object->intProperty(), -0x77359400);
578 // Test that a composite type can assign to a property of its base type
579 void tst_qdeclarativelanguage::assignCompositeToType()
581 QDeclarativeComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
583 QObject *object = component.create();
584 QVERIFY(object != 0);
587 // Test that literals are stored correctly in variant properties
588 void tst_qdeclarativelanguage::assignLiteralToVariant()
590 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
592 QObject *object = component.create();
593 QVERIFY(object != 0);
595 QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
596 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
597 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
598 QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
599 QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
600 QCOMPARE(object->property("test6").userType(), (int)QVariant::PointF);
601 QCOMPARE(object->property("test7").userType(), (int)QVariant::SizeF);
602 QCOMPARE(object->property("test8").userType(), (int)QVariant::Vector3D);
603 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
604 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
605 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
607 QVERIFY(object->property("test1") == QVariant(1));
608 QVERIFY(object->property("test2") == QVariant((double)1.7));
609 QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!"))));
610 QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800)));
611 QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10)));
612 QVERIFY(object->property("test6") == QVariant(QPointF(10, 10)));
613 QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10)));
614 QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100)));
615 QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800"))));
616 QVERIFY(object->property("test10") == QVariant(bool(true)));
617 QVERIFY(object->property("test11") == QVariant(bool(false)));
622 // Tests that custom parser types can be instantiated
623 void tst_qdeclarativelanguage::customParserTypes()
625 QDeclarativeComponent component(&engine, TEST_FILE("customParserTypes.qml"));
627 QObject *object = component.create();
628 QVERIFY(object != 0);
629 QVERIFY(object->property("count") == QVariant(2));
632 // Tests that the root item can be a custom component
633 void tst_qdeclarativelanguage::rootAsQmlComponent()
635 QDeclarativeComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
637 MyContainer *object = qobject_cast<MyContainer *>(component.create());
638 QVERIFY(object != 0);
639 QCOMPARE(object->property("x"), QVariant(11));
640 QCOMPARE(object->getChildren()->count(), 2);
643 // Tests that components can be specified inline
644 void tst_qdeclarativelanguage::inlineQmlComponents()
646 QDeclarativeComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
648 MyContainer *object = qobject_cast<MyContainer *>(component.create());
649 QVERIFY(object != 0);
650 QCOMPARE(object->getChildren()->count(), 1);
651 QDeclarativeComponent *comp = qobject_cast<QDeclarativeComponent *>(object->getChildren()->at(0));
653 MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
654 QVERIFY(compObject != 0);
655 QCOMPARE(compObject->value(), 11);
658 // Tests that types that have an id property have it set
659 void tst_qdeclarativelanguage::idProperty()
661 QDeclarativeComponent component(&engine, TEST_FILE("idProperty.qml"));
663 MyContainer *object = qobject_cast<MyContainer *>(component.create());
664 QVERIFY(object != 0);
665 QCOMPARE(object->getChildren()->count(), 1);
666 MyTypeObject *child =
667 qobject_cast<MyTypeObject *>(object->getChildren()->at(0));
669 QCOMPARE(child->id(), QString("myObjectId"));
670 QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
673 // Tests automatic connection to notify signals if "onBlahChanged" syntax is used
674 // even if the notify signal for "blah" is not called "blahChanged"
675 void tst_qdeclarativelanguage::autoNotifyConnection()
677 QDeclarativeComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
679 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
680 QVERIFY(object != 0);
681 QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
682 QVERIFY(prop.isValid());
684 QCOMPARE(prop.read(object), QVariant::fromValue(false));
685 object->setPropertyWithNotify(1);
686 QCOMPARE(prop.read(object), QVariant::fromValue(true));
689 // Tests that signals can be assigned to
690 void tst_qdeclarativelanguage::assignSignal()
692 QDeclarativeComponent component(&engine, TEST_FILE("assignSignal.qml"));
694 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
695 QVERIFY(object != 0);
696 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
697 emit object->basicSignal();
698 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)");
699 emit object->basicParameterizedSignal(9);
702 // Tests the creation and assignment of dynamic properties
703 void tst_qdeclarativelanguage::dynamicProperties()
705 QDeclarativeComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
707 QObject *object = component.create();
708 QVERIFY(object != 0);
709 QCOMPARE(object->property("intProperty"), QVariant(10));
710 QCOMPARE(object->property("boolProperty"), QVariant(false));
711 QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
712 QCOMPARE(object->property("realProperty"), QVariant((qreal)-19.9));
713 QCOMPARE(object->property("stringProperty"), QVariant("Hello World!"));
714 QCOMPARE(object->property("urlProperty"), QVariant(TEST_FILE("main.qml")));
715 QCOMPARE(object->property("colorProperty"), QVariant(QColor("red")));
716 QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2)));
717 QCOMPARE(object->property("varProperty"), QVariant("Hello World!"));
720 // Test that nested types can use dynamic properties
721 void tst_qdeclarativelanguage::dynamicPropertiesNested()
723 QDeclarativeComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
725 QObject *object = component.create();
726 QVERIFY(object != 0);
728 QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
729 QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
730 QCOMPARE(object->property("a").toInt(), 13); // New
731 QCOMPARE(object->property("b").toInt(), 12); // New
736 // Tests the creation and assignment to dynamic list properties
737 void tst_qdeclarativelanguage::listProperties()
739 QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml"));
741 QObject *object = component.create();
742 QVERIFY(object != 0);
744 QCOMPARE(object->property("test").toInt(), 2);
747 // Tests the creation and assignment of dynamic object properties
749 void tst_qdeclarativelanguage::dynamicObjectProperties()
752 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
754 QObject *object = component.create();
755 QVERIFY(object != 0);
757 QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
758 QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
761 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
762 QEXPECT_FAIL("", "QTBUG-10822", Abort);
764 QObject *object = component.create();
765 QVERIFY(object != 0);
767 QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
771 // Tests the declaration of dynamic signals and slots
772 void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
774 QTest::ignoreMessage(QtDebugMsg, "1921");
776 QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
778 QObject *object = component.create();
779 QVERIFY(object != 0);
780 QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
781 QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
782 QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1);
783 QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
785 QCOMPARE(object->property("test").toInt(), 0);
786 QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
787 QCOMPARE(object->property("test").toInt(), 10);
790 void tst_qdeclarativelanguage::simpleBindings()
792 QDeclarativeComponent component(&engine, TEST_FILE("simpleBindings.qml"));
794 QObject *object = component.create();
795 QVERIFY(object != 0);
796 QCOMPARE(object->property("value1"), QVariant(10));
797 QCOMPARE(object->property("value2"), QVariant(10));
798 QCOMPARE(object->property("value3"), QVariant(21));
799 QCOMPARE(object->property("value4"), QVariant(10));
800 QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
803 void tst_qdeclarativelanguage::autoComponentCreation()
805 QDeclarativeComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
807 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
808 QVERIFY(object != 0);
809 QVERIFY(object->componentProperty() != 0);
810 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
812 QCOMPARE(child->realProperty(), qreal(9));
815 void tst_qdeclarativelanguage::propertyValueSource()
818 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
820 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
821 QVERIFY(object != 0);
823 QList<QObject *> valueSources;
824 QObjectList allChildren = object->findChildren<QObject*>();
825 foreach (QObject *child, allChildren) {
826 if (qobject_cast<QDeclarativePropertyValueSource *>(child))
827 valueSources.append(child);
830 QCOMPARE(valueSources.count(), 1);
831 MyPropertyValueSource *valueSource =
832 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
833 QVERIFY(valueSource != 0);
834 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
835 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
839 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
841 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
842 QVERIFY(object != 0);
844 QList<QObject *> valueSources;
845 QObjectList allChildren = object->findChildren<QObject*>();
846 foreach (QObject *child, allChildren) {
847 if (qobject_cast<QDeclarativePropertyValueSource *>(child))
848 valueSources.append(child);
851 QCOMPARE(valueSources.count(), 1);
852 MyPropertyValueSource *valueSource =
853 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
854 QVERIFY(valueSource != 0);
855 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
856 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
860 void tst_qdeclarativelanguage::attachedProperties()
862 QDeclarativeComponent component(&engine, TEST_FILE("attachedProperties.qml"));
864 QObject *object = component.create();
865 QVERIFY(object != 0);
866 QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
867 QVERIFY(attached != 0);
868 QCOMPARE(attached->property("value"), QVariant(10));
869 QCOMPARE(attached->property("value2"), QVariant(13));
872 // Tests non-static object properties
873 void tst_qdeclarativelanguage::dynamicObjects()
875 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
877 QObject *object = component.create();
878 QVERIFY(object != 0);
881 // Tests the registration of custom variant string converters
882 void tst_qdeclarativelanguage::customVariantTypes()
884 QDeclarativeComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
886 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
887 QVERIFY(object != 0);
888 QCOMPARE(object->customType().a, 10);
891 void tst_qdeclarativelanguage::valueTypes()
893 QDeclarativeComponent component(&engine, TEST_FILE("valueTypes.qml"));
896 QString message = component.url().toString() + ":2:1: QML MyTypeObject: Binding loop detected for property \"rectProperty.width\"";
897 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
898 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
900 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
901 QVERIFY(object != 0);
904 QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
905 QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
906 QCOMPARE(object->intProperty(), 10);
908 QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
909 QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
910 QCOMPARE(object->intProperty(), 12);
914 QDeclarativeProperty p(object, "rectProperty.x");
915 QCOMPARE(p.read(), QVariant(12));
917 QCOMPARE(p.read(), QVariant(13));
919 quint32 r = QDeclarativePropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
920 QDeclarativeProperty p2;
921 QDeclarativePropertyPrivate::restore(p2, r, object);
922 QCOMPARE(p2.read(), QVariant(13));
926 void tst_qdeclarativelanguage::cppnamespace()
929 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.qml"));
931 QObject *object = component.create();
932 QVERIFY(object != 0);
937 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
939 QObject *object = component.create();
940 QVERIFY(object != 0);
945 void tst_qdeclarativelanguage::aliasProperties()
947 // Simple "int" alias
949 QDeclarativeComponent component(&engine, TEST_FILE("alias.1.qml"));
951 QObject *object = component.create();
952 QVERIFY(object != 0);
954 // Read through alias
955 QCOMPARE(object->property("valueAlias").toInt(), 10);
956 object->setProperty("value", QVariant(13));
957 QCOMPARE(object->property("valueAlias").toInt(), 13);
959 // Write through alias
960 object->setProperty("valueAlias", QVariant(19));
961 QCOMPARE(object->property("valueAlias").toInt(), 19);
962 QCOMPARE(object->property("value").toInt(), 19);
967 // Complex object alias
969 QDeclarativeComponent component(&engine, TEST_FILE("alias.2.qml"));
971 QObject *object = component.create();
972 QVERIFY(object != 0);
974 // Read through alias
976 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
978 QCOMPARE(v->value(), 10);
980 // Write through alias
981 MyQmlObject *v2 = new MyQmlObject();
982 v2->setParent(object);
983 object->setProperty("aliasObject", qVariantFromValue(v2));
985 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
994 QDeclarativeComponent component(&engine, TEST_FILE("alias.3.qml"));
996 QObject *object = component.create();
997 QVERIFY(object != 0);
999 QCOMPARE(object->property("value").toInt(), 1892);
1000 QCOMPARE(object->property("value2").toInt(), 1892);
1002 object->setProperty("value", QVariant(1313));
1003 QCOMPARE(object->property("value").toInt(), 1313);
1004 QCOMPARE(object->property("value2").toInt(), 1313);
1006 object->setProperty("value2", QVariant(8080));
1007 QCOMPARE(object->property("value").toInt(), 8080);
1008 QCOMPARE(object->property("value2").toInt(), 8080);
1015 QDeclarativeComponent component(&engine, TEST_FILE("alias.4.qml"));
1017 QObject *object = component.create();
1018 QVERIFY(object != 0);
1020 QCOMPARE(object->property("enumAlias").toInt(), 1);
1027 QDeclarativeComponent component(&engine, TEST_FILE("alias.5.qml"));
1029 QObject *object = component.create();
1030 QVERIFY(object != 0);
1032 QVariant v = object->property("otherAlias");
1033 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1034 MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
1035 QCOMPARE(o->value(), 10);
1039 v = object->property("otherAlias");
1040 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1041 o = qvariant_cast<MyQmlObject*>(v);
1047 // Nested aliases - this used to cause a crash
1049 QDeclarativeComponent component(&engine, TEST_FILE("alias.6.qml"));
1051 QObject *object = component.create();
1052 QVERIFY(object != 0);
1054 QCOMPARE(object->property("a").toInt(), 1923);
1057 // Ptr Alias Cleanup - check that aliases to ptr types return 0
1058 // if the object aliased to is removed
1060 QDeclarativeComponent component(&engine, TEST_FILE("alias.7.qml"));
1063 QObject *object = component.create();
1064 QVERIFY(object != 0);
1066 QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
1067 QVERIFY(object1 != 0);
1068 QObject *object2 = qvariant_cast<QObject *>(object1->property("object"));
1069 QVERIFY(object2 != 0);
1071 QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
1072 QVERIFY(alias == object2);
1076 QObject *alias2 = object; // "Random" start value
1078 void *a[] = { &alias2, 0, &status };
1079 QMetaObject::metacall(object, QMetaObject::ReadProperty,
1080 object->metaObject()->indexOfProperty("aliasedObject"), a);
1081 QVERIFY(alias2 == 0);
1084 // Simple composite type
1086 QDeclarativeComponent component(&engine, TEST_FILE("alias.8.qml"));
1088 QObject *object = component.create();
1089 QVERIFY(object != 0);
1091 QCOMPARE(object->property("value").toInt(), 10);
1096 // Complex composite type
1098 QDeclarativeComponent component(&engine, TEST_FILE("alias.9.qml"));
1100 QObject *object = component.create();
1101 QVERIFY(object != 0);
1103 QCOMPARE(object->property("value").toInt(), 10);
1109 // Simple "int" alias
1111 QDeclarativeComponent component(&engine, TEST_FILE("alias.10.qml"));
1113 QObject *object = component.create();
1114 QVERIFY(object != 0);
1116 // Read through alias
1117 QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8));
1118 object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
1119 QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
1121 // Write through alias
1122 object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
1123 QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
1124 QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
1129 // Valuetype sub-alias
1131 QDeclarativeComponent component(&engine, TEST_FILE("alias.11.qml"));
1133 QObject *object = component.create();
1134 QVERIFY(object != 0);
1136 // Read through alias
1137 QCOMPARE(object->property("aliasProperty").toInt(), 19);
1138 object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
1139 QCOMPARE(object->property("aliasProperty").toInt(), 33);
1141 // Write through alias
1142 object->setProperty("aliasProperty", QVariant(4));
1143 QCOMPARE(object->property("aliasProperty").toInt(), 4);
1144 QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
1150 // QTBUG-13374 Test that alias properties and signals can coexist
1151 void tst_qdeclarativelanguage::aliasPropertiesAndSignals()
1153 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
1155 QObject *o = component.create();
1157 QCOMPARE(o->property("test").toBool(), true);
1161 // Test that the root element in a composite type can be a Component
1162 void tst_qdeclarativelanguage::componentCompositeType()
1164 QDeclarativeComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
1166 QObject *object = component.create();
1167 QVERIFY(object != 0);
1170 class TestType : public QObject {
1173 TestType(QObject *p=0) : QObject(p) {}
1176 class TestType2 : public QObject {
1179 TestType2(QObject *p=0) : QObject(p) {}
1182 void tst_qdeclarativelanguage::i18n_data()
1184 QTest::addColumn<QString>("file");
1185 QTest::addColumn<QString>("stringProperty");
1186 QTest::newRow("i18nStrings") << "i18nStrings.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245 (5 accented 'a' letters)");
1187 QTest::newRow("i18nDeclaredPropertyNames") << "i18nDeclaredPropertyNames.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 10");
1188 QTest::newRow("i18nDeclaredPropertyUse") << "i18nDeclaredPropertyUse.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 15");
1189 QTest::newRow("i18nScript") << "i18nScript.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 20");
1190 QTest::newRow("i18nType") << "i18nType.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 30");
1191 QTest::newRow("i18nNameSpace") << "i18nNameSpace.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 40");
1194 void tst_qdeclarativelanguage::i18n()
1196 QFETCH(QString, file);
1197 QFETCH(QString, stringProperty);
1198 QDeclarativeComponent component(&engine, TEST_FILE(file));
1200 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1201 QVERIFY(object != 0);
1202 QCOMPARE(object->stringProperty(), stringProperty);
1207 // Check that the Component::onCompleted attached property works
1208 void tst_qdeclarativelanguage::onCompleted()
1210 QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
1212 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1213 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1214 QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
1215 QObject *object = component.create();
1216 QVERIFY(object != 0);
1219 // Check that the Component::onDestruction attached property works
1220 void tst_qdeclarativelanguage::onDestruction()
1222 QDeclarativeComponent component(&engine, TEST_FILE("onDestruction.qml"));
1224 QObject *object = component.create();
1225 QVERIFY(object != 0);
1227 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1228 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1229 QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
1233 // Check that assignments to QDeclarativeScriptString properties work
1234 void tst_qdeclarativelanguage::scriptString()
1237 QDeclarativeComponent component(&engine, TEST_FILE("scriptString.qml"));
1240 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1241 QVERIFY(object != 0);
1242 QCOMPARE(object->scriptProperty().script(), QString("foo + bar"));
1243 QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object));
1244 QCOMPARE(object->scriptProperty().context(), qmlContext(object));
1246 QVERIFY(object->grouped() != 0);
1247 QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)"));
1248 QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object));
1249 QCOMPARE(object->grouped()->script().context(), qmlContext(object));
1253 QDeclarativeComponent component(&engine, TEST_FILE("scriptString2.qml"));
1256 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1257 QVERIFY(object != 0);
1258 QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
1262 QDeclarativeComponent component(&engine, TEST_FILE("scriptString3.qml"));
1265 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1266 QVERIFY(object != 0);
1267 QCOMPARE(object->scriptProperty().script(), QString("12.345"));
1271 QDeclarativeComponent component(&engine, TEST_FILE("scriptString4.qml"));
1274 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1275 QVERIFY(object != 0);
1276 QCOMPARE(object->scriptProperty().script(), QString("true"));
1280 // Check that default property assignments are correctly spliced into explicit
1281 // property assignments
1282 void tst_qdeclarativelanguage::defaultPropertyListOrder()
1284 QDeclarativeComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
1287 MyContainer *container = qobject_cast<MyContainer *>(component.create());
1288 QVERIFY(container != 0);
1290 QCOMPARE(container->getChildren()->count(), 6);
1291 QCOMPARE(container->getChildren()->at(0)->property("index"), QVariant(0));
1292 QCOMPARE(container->getChildren()->at(1)->property("index"), QVariant(1));
1293 QCOMPARE(container->getChildren()->at(2)->property("index"), QVariant(2));
1294 QCOMPARE(container->getChildren()->at(3)->property("index"), QVariant(3));
1295 QCOMPARE(container->getChildren()->at(4)->property("index"), QVariant(4));
1296 QCOMPARE(container->getChildren()->at(5)->property("index"), QVariant(5));
1299 void tst_qdeclarativelanguage::declaredPropertyValues()
1301 QDeclarativeComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
1305 void tst_qdeclarativelanguage::dontDoubleCallClassBegin()
1307 QDeclarativeComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml"));
1308 QObject *o = component.create();
1311 MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
1313 QCOMPARE(o2->classBeginCount(), 1);
1314 QCOMPARE(o2->componentCompleteCount(), 1);
1319 void tst_qdeclarativelanguage::reservedWords_data()
1321 QTest::addColumn<QByteArray>("word");
1323 QTest::newRow("abstract") << QByteArray("abstract");
1324 QTest::newRow("as") << QByteArray("as");
1325 QTest::newRow("boolean") << QByteArray("boolean");
1326 QTest::newRow("break") << QByteArray("break");
1327 QTest::newRow("byte") << QByteArray("byte");
1328 QTest::newRow("case") << QByteArray("case");
1329 QTest::newRow("catch") << QByteArray("catch");
1330 QTest::newRow("char") << QByteArray("char");
1331 QTest::newRow("class") << QByteArray("class");
1332 QTest::newRow("continue") << QByteArray("continue");
1333 QTest::newRow("const") << QByteArray("const");
1334 QTest::newRow("debugger") << QByteArray("debugger");
1335 QTest::newRow("default") << QByteArray("default");
1336 QTest::newRow("delete") << QByteArray("delete");
1337 QTest::newRow("do") << QByteArray("do");
1338 QTest::newRow("double") << QByteArray("double");
1339 QTest::newRow("else") << QByteArray("else");
1340 QTest::newRow("enum") << QByteArray("enum");
1341 QTest::newRow("export") << QByteArray("export");
1342 QTest::newRow("extends") << QByteArray("extends");
1343 QTest::newRow("false") << QByteArray("false");
1344 QTest::newRow("final") << QByteArray("final");
1345 QTest::newRow("finally") << QByteArray("finally");
1346 QTest::newRow("float") << QByteArray("float");
1347 QTest::newRow("for") << QByteArray("for");
1348 QTest::newRow("function") << QByteArray("function");
1349 QTest::newRow("goto") << QByteArray("goto");
1350 QTest::newRow("if") << QByteArray("if");
1351 QTest::newRow("implements") << QByteArray("implements");
1352 QTest::newRow("import") << QByteArray("import");
1353 QTest::newRow("in") << QByteArray("in");
1354 QTest::newRow("instanceof") << QByteArray("instanceof");
1355 QTest::newRow("int") << QByteArray("int");
1356 QTest::newRow("interface") << QByteArray("interface");
1357 QTest::newRow("long") << QByteArray("long");
1358 QTest::newRow("native") << QByteArray("native");
1359 QTest::newRow("new") << QByteArray("new");
1360 QTest::newRow("null") << QByteArray("null");
1361 QTest::newRow("package") << QByteArray("package");
1362 QTest::newRow("private") << QByteArray("private");
1363 QTest::newRow("protected") << QByteArray("protected");
1364 QTest::newRow("public") << QByteArray("public");
1365 QTest::newRow("return") << QByteArray("return");
1366 QTest::newRow("short") << QByteArray("short");
1367 QTest::newRow("static") << QByteArray("static");
1368 QTest::newRow("super") << QByteArray("super");
1369 QTest::newRow("switch") << QByteArray("switch");
1370 QTest::newRow("synchronized") << QByteArray("synchronized");
1371 QTest::newRow("this") << QByteArray("this");
1372 QTest::newRow("throw") << QByteArray("throw");
1373 QTest::newRow("throws") << QByteArray("throws");
1374 QTest::newRow("transient") << QByteArray("transient");
1375 QTest::newRow("true") << QByteArray("true");
1376 QTest::newRow("try") << QByteArray("try");
1377 QTest::newRow("typeof") << QByteArray("typeof");
1378 QTest::newRow("var") << QByteArray("var");
1379 QTest::newRow("void") << QByteArray("void");
1380 QTest::newRow("volatile") << QByteArray("volatile");
1381 QTest::newRow("while") << QByteArray("while");
1382 QTest::newRow("with") << QByteArray("with");
1385 void tst_qdeclarativelanguage::reservedWords()
1387 QFETCH(QByteArray, word);
1388 QDeclarativeComponent component(&engine);
1389 component.setData("import QtQuick 1.0\nQtObject { property string " + word + " }", QUrl());
1390 QCOMPARE(component.errorString(), QLatin1String(":2 Expected token `identifier'\n"));
1393 // Check that first child of qml is of given type. Empty type insists on error.
1394 void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, const QString& expectederror)
1396 QDeclarativeComponent component(&engine);
1397 component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
1399 QTRY_VERIFY(!component.isLoading());
1401 if (type.isEmpty()) {
1402 QVERIFY(component.isError());
1403 QString actualerror;
1404 foreach (const QDeclarativeError e, component.errors()) {
1405 if (!actualerror.isEmpty())
1406 actualerror.append("; ");
1407 actualerror.append(e.description());
1409 QCOMPARE(actualerror,expectederror);
1412 QObject *object = component.create();
1413 QVERIFY(object != 0);
1414 QCOMPARE(QString(object->metaObject()->className()), type);
1419 void tst_qdeclarativelanguage::inlineAssignmentsOverrideBindings()
1421 QDeclarativeComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml"));
1423 QObject *o = component.create();
1425 QCOMPARE(o->property("test").toInt(), 11);
1429 // Import tests (QT-558)
1430 void tst_qdeclarativelanguage::importsBuiltin_data()
1434 QTest::addColumn<QString>("qml");
1435 QTest::addColumn<QString>("type");
1436 QTest::addColumn<QString>("error");
1439 QTest::newRow("missing import")
1442 << "Test is not a type";
1443 QTest::newRow("not in version 0.0")
1444 << "import com.nokia.Test 0.0\n"
1447 << "Test is not a type";
1448 QTest::newRow("version not installed")
1449 << "import com.nokia.Test 99.0\n"
1452 << "module \"com.nokia.Test\" version 99.0 is not installed";
1453 QTest::newRow("in version 0.0")
1454 << "import com.nokia.Test 0.0\n"
1458 QTest::newRow("qualified in version 0.0")
1459 << "import com.nokia.Test 0.0 as T\n"
1463 QTest::newRow("in version 1.0")
1464 << "import com.nokia.Test 1.0\n"
1468 QTest::newRow("qualified wrong")
1469 << "import com.nokia.Test 1.0 as T\n" // QT-610
1472 << "Test is not a type";
1473 QTest::newRow("qualified right")
1474 << "import com.nokia.Test 1.0 as T\n"
1478 QTest::newRow("qualified right but not in version 0.0")
1479 << "import com.nokia.Test 0.0 as T\n"
1482 << "T.Test is not a type";
1483 QTest::newRow("in version 1.1")
1484 << "import com.nokia.Test 1.1\n"
1488 QTest::newRow("in version 1.3")
1489 << "import com.nokia.Test 1.3\n"
1493 QTest::newRow("in version 1.5")
1494 << "import com.nokia.Test 1.5\n"
1498 QTest::newRow("changed in version 1.8")
1499 << "import com.nokia.Test 1.8\n"
1503 QTest::newRow("in version 1.12")
1504 << "import com.nokia.Test 1.12\n"
1508 QTest::newRow("old in version 1.9")
1509 << "import com.nokia.Test 1.9\n"
1513 QTest::newRow("old in version 1.11")
1514 << "import com.nokia.Test 1.11\n"
1518 QTest::newRow("multiversion 1")
1519 << "import com.nokia.Test 1.11\n"
1520 "import com.nokia.Test 1.12\n"
1522 << (!qmlCheckTypes()?"TestType2":"")
1523 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1524 QTest::newRow("multiversion 2")
1525 << "import com.nokia.Test 1.11\n"
1526 "import com.nokia.Test 1.12\n"
1528 << (!qmlCheckTypes()?"TestType":"")
1529 << (!qmlCheckTypes()?"":"OldTest is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1530 QTest::newRow("qualified multiversion 3")
1531 << "import com.nokia.Test 1.0 as T0\n"
1532 "import com.nokia.Test 1.8 as T8\n"
1536 QTest::newRow("qualified multiversion 4")
1537 << "import com.nokia.Test 1.0 as T0\n"
1538 "import com.nokia.Test 1.8 as T8\n"
1544 void tst_qdeclarativelanguage::importsBuiltin()
1546 QFETCH(QString, qml);
1547 QFETCH(QString, type);
1548 QFETCH(QString, error);
1549 testType(qml,type,error);
1552 void tst_qdeclarativelanguage::importsLocal_data()
1554 QTest::addColumn<QString>("qml");
1555 QTest::addColumn<QString>("type");
1556 QTest::addColumn<QString>("error");
1559 QTest::newRow("local import")
1560 << "import \"subdir\"\n" // QT-613
1562 << "QDeclarativeRectangle"
1564 QTest::newRow("local import second")
1565 << "import QtQuick 1.0\nimport \"subdir\"\n"
1567 << "QDeclarativeRectangle"
1569 QTest::newRow("local import subsubdir")
1570 << "import QtQuick 1.0\nimport \"subdir/subsubdir\"\n"
1572 << "QDeclarativeRectangle"
1574 QTest::newRow("local import QTBUG-7721 A")
1575 << "subdir.Test {}" // no longer allowed (QTBUG-7721)
1577 << "subdir.Test - subdir is not a namespace";
1578 QTest::newRow("local import QTBUG-7721 B")
1579 << "import \"subdir\" as X\n"
1580 "X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
1582 << "X.subsubdir.SubTest - nested namespaces not allowed";
1583 QTest::newRow("local import as")
1584 << "import \"subdir\" as T\n"
1586 << "QDeclarativeRectangle"
1588 QTest::newRow("wrong local import as")
1589 << "import \"subdir\" as T\n"
1592 << "Test is not a type";
1593 QTest::newRow("library precedence over local import")
1594 << "import \"subdir\"\n"
1595 "import com.nokia.Test 1.0\n"
1597 << (!qmlCheckTypes()?"TestType":"")
1598 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test and in subdir");
1601 void tst_qdeclarativelanguage::importsLocal()
1603 QFETCH(QString, qml);
1604 QFETCH(QString, type);
1605 QFETCH(QString, error);
1606 testType(qml,type,error);
1609 void tst_qdeclarativelanguage::basicRemote_data()
1611 QTest::addColumn<QUrl>("url");
1612 QTest::addColumn<QString>("type");
1613 QTest::addColumn<QString>("error");
1615 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage/";
1617 QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
1618 QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << "";
1619 QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
1622 void tst_qdeclarativelanguage::basicRemote()
1625 QFETCH(QString, type);
1626 QFETCH(QString, error);
1628 TestHTTPServer server(14447);
1629 server.serveDirectory(SRCDIR);
1631 QDeclarativeComponent component(&engine, url);
1633 QTRY_VERIFY(!component.isLoading());
1635 if (error.isEmpty()) {
1636 if (component.isError())
1637 qDebug() << component.errors();
1638 QVERIFY(!component.isError());
1640 QVERIFY(component.isError());
1644 void tst_qdeclarativelanguage::importsRemote_data()
1646 QTest::addColumn<QString>("qml");
1647 QTest::addColumn<QString>("type");
1648 QTest::addColumn<QString>("error");
1650 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage";
1652 QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QDeclarativeRectangle"
1654 QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QDeclarativeText"
1656 QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QDeclarativeImage"
1658 QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
1659 << "WrongTestLocal is not a type";
1660 QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
1661 << "LocalInternal is not a type";
1662 QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""
1663 << "UndeclaredLocal is not a type";
1666 void tst_qdeclarativelanguage::importsRemote()
1668 QFETCH(QString, qml);
1669 QFETCH(QString, type);
1670 QFETCH(QString, error);
1672 TestHTTPServer server(14447);
1673 server.serveDirectory(SRCDIR);
1675 testType(qml,type,error);
1678 void tst_qdeclarativelanguage::importsInstalled_data()
1682 QTest::addColumn<QString>("qml");
1683 QTest::addColumn<QString>("type");
1684 QTest::addColumn<QString>("error");
1687 QTest::newRow("installed import 0")
1688 << "import com.nokia.installedtest0 0.0\n"
1689 "InstalledTestTP {}"
1690 << "QDeclarativeRectangle"
1692 QTest::newRow("installed import 0 as TP")
1693 << "import com.nokia.installedtest0 0.0 as TP\n"
1694 "TP.InstalledTestTP {}"
1695 << "QDeclarativeRectangle"
1697 QTest::newRow("installed import 1")
1698 << "import com.nokia.installedtest 1.0\n"
1700 << "QDeclarativeRectangle"
1702 QTest::newRow("installed import 2")
1703 << "import com.nokia.installedtest 1.3\n"
1705 << "QDeclarativeRectangle"
1707 QTest::newRow("installed import 3")
1708 << "import com.nokia.installedtest 1.4\n"
1710 << "QDeclarativeText"
1712 QTest::newRow("installed import minor version not available") // QTBUG-11936
1713 << "import com.nokia.installedtest 0.1\n"
1716 << "module \"com.nokia.installedtest\" version 0.1 is not installed";
1717 QTest::newRow("installed import minor version not available") // QTBUG-9627
1718 << "import com.nokia.installedtest 1.10\n"
1721 << "module \"com.nokia.installedtest\" version 1.10 is not installed";
1722 QTest::newRow("installed import major version not available") // QTBUG-9627
1723 << "import com.nokia.installedtest 9.0\n"
1726 << "module \"com.nokia.installedtest\" version 9.0 is not installed";
1727 QTest::newRow("installed import visibility") // QT-614
1728 << "import com.nokia.installedtest 1.4\n"
1731 << "PrivateType is not a type";
1734 void tst_qdeclarativelanguage::importsInstalled()
1736 QFETCH(QString, qml);
1737 QFETCH(QString, type);
1738 QFETCH(QString, error);
1739 testType(qml,type,error);
1743 void tst_qdeclarativelanguage::importsOrder_data()
1745 QTest::addColumn<QString>("qml");
1746 QTest::addColumn<QString>("type");
1747 QTest::addColumn<QString>("error");
1749 QTest::newRow("double import") <<
1750 "import com.nokia.installedtest 1.4\n"
1751 "import com.nokia.installedtest 1.4\n"
1753 << (!qmlCheckTypes()?"QDeclarativeText":"")
1754 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.4");
1755 QTest::newRow("installed import overrides 1") <<
1756 "import com.nokia.installedtest 1.0\n"
1757 "import com.nokia.installedtest 1.4\n"
1759 << (!qmlCheckTypes()?"QDeclarativeText":"")
1760 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1761 QTest::newRow("installed import overrides 2") <<
1762 "import com.nokia.installedtest 1.4\n"
1763 "import com.nokia.installedtest 1.0\n"
1765 << (!qmlCheckTypes()?"QDeclarativeRectangle":"")
1766 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1767 QTest::newRow("installed import re-overrides 1") <<
1768 "import com.nokia.installedtest 1.4\n"
1769 "import com.nokia.installedtest 1.0\n"
1770 "import com.nokia.installedtest 1.4\n"
1772 << (!qmlCheckTypes()?"QDeclarativeText":"")
1773 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1774 QTest::newRow("installed import re-overrides 2") <<
1775 "import com.nokia.installedtest 1.4\n"
1776 "import com.nokia.installedtest 1.0\n"
1777 "import com.nokia.installedtest 1.4\n"
1778 "import com.nokia.installedtest 1.0\n"
1780 << (!qmlCheckTypes()?"QDeclarativeRectangle":"")
1781 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1783 QTest::newRow("installed import versus builtin 1") <<
1784 "import com.nokia.installedtest 1.5\n"
1785 "import QtQuick 1.0\n"
1787 << (!qmlCheckTypes()?"QDeclarativeRectangle":"")
1788 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in Qt and in lib/com/nokia/installedtest");
1789 QTest::newRow("installed import versus builtin 2") <<
1790 "import QtQuick 1.0\n"
1791 "import com.nokia.installedtest 1.5\n"
1793 << (!qmlCheckTypes()?"QDeclarativeText":"")
1794 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest and in Qt");
1795 QTest::newRow("namespaces cannot be overridden by types 1") <<
1796 "import QtQuick 1.0 as Rectangle\n"
1797 "import com.nokia.installedtest 1.5\n"
1800 << "Namespace Rectangle cannot be used as a type";
1801 QTest::newRow("namespaces cannot be overridden by types 2") <<
1802 "import QtQuick 1.0 as Rectangle\n"
1803 "import com.nokia.installedtest 1.5\n"
1804 "Rectangle.Image {}"
1805 << "QDeclarativeImage"
1807 QTest::newRow("local last 1") <<
1809 << "QDeclarativeText"
1811 QTest::newRow("local last 2") <<
1812 "import com.nokia.installedtest 1.0\n"
1814 << (!qmlCheckTypes()?"QDeclarativeRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
1815 << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest and in local directory");
1818 void tst_qdeclarativelanguage::importsOrder()
1820 QFETCH(QString, qml);
1821 QFETCH(QString, type);
1822 QFETCH(QString, error);
1823 testType(qml,type,error);
1826 void tst_qdeclarativelanguage::importIncorrectCase()
1828 QDeclarativeComponent component(&engine, TEST_FILE("importIncorrectCase.qml"));
1830 QList<QDeclarativeError> errors = component.errors();
1831 QCOMPARE(errors.count(), 1);
1833 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1834 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("\"");
1836 QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
1839 QCOMPARE(errors.at(0).description(), expectedError);
1842 void tst_qdeclarativelanguage::qmlAttachedPropertiesObjectMethod()
1846 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
1847 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
1850 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
1852 QObject *object = component.create();
1853 QVERIFY(object != 0);
1855 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
1856 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1860 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
1862 QObject *object = component.create();
1863 QVERIFY(object != 0);
1865 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
1866 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1870 void tst_qdeclarativelanguage::crash1()
1872 QDeclarativeComponent component(&engine);
1873 component.setData("import QtQuick 1.0\nComponent {}", QUrl());
1876 void tst_qdeclarativelanguage::crash2()
1878 QDeclarativeComponent component(&engine, TEST_FILE("crash2.qml"));
1882 void tst_qdeclarativelanguage::customOnProperty()
1884 QDeclarativeComponent component(&engine, TEST_FILE("customOnProperty.qml"));
1887 QObject *object = component.create();
1888 QVERIFY(object != 0);
1890 QCOMPARE(object->property("on").toInt(), 10);
1896 void tst_qdeclarativelanguage::variantNotify()
1898 QDeclarativeComponent component(&engine, TEST_FILE("variantNotify.qml"));
1901 QObject *object = component.create();
1902 QVERIFY(object != 0);
1904 QCOMPARE(object->property("notifyCount").toInt(), 1);
1909 void tst_qdeclarativelanguage::revisions()
1912 QDeclarativeComponent component(&engine, TEST_FILE("revisions11.qml"));
1915 MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
1916 QVERIFY(object != 0);
1918 QCOMPARE(object->prop2(), 10.0);
1923 QDeclarativeEngine myEngine;
1924 QDeclarativeComponent component(&myEngine, TEST_FILE("revisionssub11.qml"));
1927 MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
1928 QVERIFY(object != 0);
1930 QCOMPARE(object->prop1(), 10.0);
1931 QCOMPARE(object->prop2(), 10.0);
1932 QCOMPARE(object->prop3(), 10.0);
1933 QCOMPARE(object->prop4(), 10.0);
1938 QDeclarativeComponent component(&engine, TEST_FILE("versionedbase.qml"));
1940 MySubclass *object = qobject_cast<MySubclass*>(component.create());
1941 QVERIFY(object != 0);
1943 QCOMPARE(object->prop1(), 10.0);
1944 QCOMPARE(object->prop2(), 10.0);
1950 void tst_qdeclarativelanguage::revisionOverloads()
1953 QDeclarativeComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml"));
1957 QDeclarativeComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml"));
1958 QEXPECT_FAIL("", "QTBUG-13849", Abort);
1960 VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt");
1964 void tst_qdeclarativelanguage::initTestCase()
1968 // Registering the TestType class in other modules should have no adverse effects
1969 qmlRegisterType<TestType>("com.nokia.TestPre", 1, 0, "Test");
1971 qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP");
1972 qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test");
1973 qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test");
1974 qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test");
1975 qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest");
1976 qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test");
1978 // Registering the TestType class in other modules should have no adverse effects
1979 qmlRegisterType<TestType>("com.nokia.TestPost", 1, 0, "Test");
1981 // Create locale-specific file
1982 // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit
1983 // For iso8859-1 locale, this will just be data/I18nType?????.qml where ????? is 5 8-bit characters
1984 // For utf-8 locale, this will be data/I18nType??????????.qml where ?????????? is 5 8-bit characters, UTF-8 encoded
1985 QFile in(TEST_FILE(QLatin1String("I18nType30.qml")).toLocalFile());
1986 QVERIFY(in.open(QIODevice::ReadOnly));
1987 QFile out(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile());
1988 QVERIFY(out.open(QIODevice::WriteOnly));
1989 out.write(in.readAll());
1992 void tst_qdeclarativelanguage::aliasPropertyChangeSignals()
1995 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.qml"));
1998 QObject *o = component.create();
2001 QCOMPARE(o->property("test").toBool(), true);
2006 // QTCREATORBUG-2769
2008 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.2.qml"));
2011 QObject *o = component.create();
2014 QCOMPARE(o->property("test").toBool(), true);
2020 QTEST_MAIN(tst_qdeclarativelanguage)
2022 #include "tst_qdeclarativelanguage.moc"