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;
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;
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;
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;
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;
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;
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;
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;
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;
337 QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
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;
347 QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
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;
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;
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;
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;
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;
402 QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
403 QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
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"
425 << "incorrectCase.errors.sensitive.txt"
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;
435 void tst_qdeclarativelanguage::errors()
437 QFETCH(QString, file);
438 QFETCH(QString, errorFile);
439 QFETCH(bool, create);
441 QDeclarativeComponent component(&engine, TEST_FILE(file));
444 QObject *object = component.create();
445 QVERIFY(object == 0);
448 VERIFY_ERRORS(errorFile.toLatin1().constData());
451 void tst_qdeclarativelanguage::simpleObject()
453 QDeclarativeComponent component(&engine, TEST_FILE("simpleObject.qml"));
455 QObject *object = component.create();
456 QVERIFY(object != 0);
459 void tst_qdeclarativelanguage::simpleContainer()
461 QDeclarativeComponent component(&engine, TEST_FILE("simpleContainer.qml"));
463 MyContainer *container= qobject_cast<MyContainer*>(component.create());
464 QVERIFY(container != 0);
465 QCOMPARE(container->getChildren()->count(),2);
468 void tst_qdeclarativelanguage::interfaceProperty()
470 QDeclarativeComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
472 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
473 QVERIFY(object != 0);
474 QVERIFY(object->interface());
475 QVERIFY(object->interface()->id == 913);
478 void tst_qdeclarativelanguage::interfaceQList()
480 QDeclarativeComponent component(&engine, TEST_FILE("interfaceQList.qml"));
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);
489 void tst_qdeclarativelanguage::assignObjectToSignal()
491 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
493 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
494 QVERIFY(object != 0);
495 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
496 emit object->basicSignal();
499 void tst_qdeclarativelanguage::assignObjectToVariant()
501 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
503 QObject *object = component.create();
504 QVERIFY(object != 0);
505 QVariant v = object->property("a");
506 QVERIFY(v.userType() == qMetaTypeId<QObject *>());
509 void tst_qdeclarativelanguage::assignLiteralSignalProperty()
511 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
513 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
514 QVERIFY(object != 0);
515 QCOMPARE(object->onLiteralSignal(), 10);
518 // Test is an external component can be loaded and assigned (to a qlist)
519 void tst_qdeclarativelanguage::assignQmlComponent()
521 QDeclarativeComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
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));
531 // Test literal assignment to all the basic types
532 void tst_qdeclarativelanguage::assignBasicTypes()
534 QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
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());
563 QCOMPARE(child->intProperty(), 8);
566 // Test edge case type assignments
567 void tst_qdeclarativelanguage::assignTypeExtremes()
569 QDeclarativeComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
571 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
572 QVERIFY(object != 0);
573 QCOMPARE(object->uintProperty(), 0xEE6B2800);
574 QCOMPARE(object->intProperty(), -0x77359400);
577 // Test that a composite type can assign to a property of its base type
578 void tst_qdeclarativelanguage::assignCompositeToType()
580 QDeclarativeComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
582 QObject *object = component.create();
583 QVERIFY(object != 0);
586 // Test that literals are stored correctly in variant properties
587 void tst_qdeclarativelanguage::assignLiteralToVariant()
589 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
591 QObject *object = component.create();
592 QVERIFY(object != 0);
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);
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)));
621 // Tests that custom parser types can be instantiated
622 void tst_qdeclarativelanguage::customParserTypes()
624 QDeclarativeComponent component(&engine, TEST_FILE("customParserTypes.qml"));
626 QObject *object = component.create();
627 QVERIFY(object != 0);
628 QVERIFY(object->property("count") == QVariant(2));
631 // Tests that the root item can be a custom component
632 void tst_qdeclarativelanguage::rootAsQmlComponent()
634 QDeclarativeComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
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);
642 // Tests that components can be specified inline
643 void tst_qdeclarativelanguage::inlineQmlComponents()
645 QDeclarativeComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
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));
652 MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
653 QVERIFY(compObject != 0);
654 QCOMPARE(compObject->value(), 11);
657 // Tests that types that have an id property have it set
658 void tst_qdeclarativelanguage::idProperty()
660 QDeclarativeComponent component(&engine, TEST_FILE("idProperty.qml"));
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));
668 QCOMPARE(child->id(), QString("myObjectId"));
669 QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
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()
676 QDeclarativeComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
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());
683 QCOMPARE(prop.read(object), QVariant::fromValue(false));
684 object->setPropertyWithNotify(1);
685 QCOMPARE(prop.read(object), QVariant::fromValue(true));
688 // Tests that signals can be assigned to
689 void tst_qdeclarativelanguage::assignSignal()
691 QDeclarativeComponent component(&engine, TEST_FILE("assignSignal.qml"));
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);
701 // Tests the creation and assignment of dynamic properties
702 void tst_qdeclarativelanguage::dynamicProperties()
704 QDeclarativeComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
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!"));
719 // Test that nested types can use dynamic properties
720 void tst_qdeclarativelanguage::dynamicPropertiesNested()
722 QDeclarativeComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
724 QObject *object = component.create();
725 QVERIFY(object != 0);
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
735 // Tests the creation and assignment to dynamic list properties
736 void tst_qdeclarativelanguage::listProperties()
738 QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml"));
740 QObject *object = component.create();
741 QVERIFY(object != 0);
743 QCOMPARE(object->property("test").toInt(), 2);
746 // Tests the creation and assignment of dynamic object properties
748 void tst_qdeclarativelanguage::dynamicObjectProperties()
751 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
753 QObject *object = component.create();
754 QVERIFY(object != 0);
756 QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
757 QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
760 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
761 QEXPECT_FAIL("", "QTBUG-10822", Abort);
763 QObject *object = component.create();
764 QVERIFY(object != 0);
766 QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
770 // Tests the declaration of dynamic signals and slots
771 void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
773 QTest::ignoreMessage(QtDebugMsg, "1921");
775 QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
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);
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);
789 void tst_qdeclarativelanguage::simpleBindings()
791 QDeclarativeComponent component(&engine, TEST_FILE("simpleBindings.qml"));
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));
802 void tst_qdeclarativelanguage::autoComponentCreation()
804 QDeclarativeComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
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());
811 QCOMPARE(child->realProperty(), qreal(9));
814 void tst_qdeclarativelanguage::propertyValueSource()
817 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
819 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
820 QVERIFY(object != 0);
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);
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")));
838 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
840 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
841 QVERIFY(object != 0);
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);
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")));
859 void tst_qdeclarativelanguage::attachedProperties()
861 QDeclarativeComponent component(&engine, TEST_FILE("attachedProperties.qml"));
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));
871 // Tests non-static object properties
872 void tst_qdeclarativelanguage::dynamicObjects()
874 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
876 QObject *object = component.create();
877 QVERIFY(object != 0);
880 // Tests the registration of custom variant string converters
881 void tst_qdeclarativelanguage::customVariantTypes()
883 QDeclarativeComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
885 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
886 QVERIFY(object != 0);
887 QCOMPARE(object->customType().a, 10);
890 void tst_qdeclarativelanguage::valueTypes()
892 QDeclarativeComponent component(&engine, TEST_FILE("valueTypes.qml"));
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));
899 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
900 QVERIFY(object != 0);
903 QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
904 QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
905 QCOMPARE(object->intProperty(), 10);
907 QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
908 QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
909 QCOMPARE(object->intProperty(), 12);
913 QDeclarativeProperty p(object, "rectProperty.x");
914 QCOMPARE(p.read(), QVariant(12));
916 QCOMPARE(p.read(), QVariant(13));
918 quint32 r = QDeclarativePropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
919 QDeclarativeProperty p2;
920 QDeclarativePropertyPrivate::restore(p2, r, object);
921 QCOMPARE(p2.read(), QVariant(13));
925 void tst_qdeclarativelanguage::cppnamespace()
928 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.qml"));
930 QObject *object = component.create();
931 QVERIFY(object != 0);
936 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
938 QObject *object = component.create();
939 QVERIFY(object != 0);
944 void tst_qdeclarativelanguage::aliasProperties()
946 // Simple "int" alias
948 QDeclarativeComponent component(&engine, TEST_FILE("alias.1.qml"));
950 QObject *object = component.create();
951 QVERIFY(object != 0);
953 // Read through alias
954 QCOMPARE(object->property("valueAlias").toInt(), 10);
955 object->setProperty("value", QVariant(13));
956 QCOMPARE(object->property("valueAlias").toInt(), 13);
958 // Write through alias
959 object->setProperty("valueAlias", QVariant(19));
960 QCOMPARE(object->property("valueAlias").toInt(), 19);
961 QCOMPARE(object->property("value").toInt(), 19);
966 // Complex object alias
968 QDeclarativeComponent component(&engine, TEST_FILE("alias.2.qml"));
970 QObject *object = component.create();
971 QVERIFY(object != 0);
973 // Read through alias
975 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
977 QCOMPARE(v->value(), 10);
979 // Write through alias
980 MyQmlObject *v2 = new MyQmlObject();
981 v2->setParent(object);
982 object->setProperty("aliasObject", qVariantFromValue(v2));
984 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
993 QDeclarativeComponent component(&engine, TEST_FILE("alias.3.qml"));
995 QObject *object = component.create();
996 QVERIFY(object != 0);
998 QCOMPARE(object->property("value").toInt(), 1892);
999 QCOMPARE(object->property("value2").toInt(), 1892);
1001 object->setProperty("value", QVariant(1313));
1002 QCOMPARE(object->property("value").toInt(), 1313);
1003 QCOMPARE(object->property("value2").toInt(), 1313);
1005 object->setProperty("value2", QVariant(8080));
1006 QCOMPARE(object->property("value").toInt(), 8080);
1007 QCOMPARE(object->property("value2").toInt(), 8080);
1014 QDeclarativeComponent component(&engine, TEST_FILE("alias.4.qml"));
1016 QObject *object = component.create();
1017 QVERIFY(object != 0);
1019 QCOMPARE(object->property("enumAlias").toInt(), 1);
1026 QDeclarativeComponent component(&engine, TEST_FILE("alias.5.qml"));
1028 QObject *object = component.create();
1029 QVERIFY(object != 0);
1031 QVariant v = object->property("otherAlias");
1032 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1033 MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
1034 QCOMPARE(o->value(), 10);
1038 v = object->property("otherAlias");
1039 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1040 o = qvariant_cast<MyQmlObject*>(v);
1046 // Nested aliases - this used to cause a crash
1048 QDeclarativeComponent component(&engine, TEST_FILE("alias.6.qml"));
1050 QObject *object = component.create();
1051 QVERIFY(object != 0);
1053 QCOMPARE(object->property("a").toInt(), 1923);
1056 // Ptr Alias Cleanup - check that aliases to ptr types return 0
1057 // if the object aliased to is removed
1059 QDeclarativeComponent component(&engine, TEST_FILE("alias.7.qml"));
1062 QObject *object = component.create();
1063 QVERIFY(object != 0);
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);
1070 QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
1071 QVERIFY(alias == object2);
1075 QObject *alias2 = object; // "Random" start value
1077 void *a[] = { &alias2, 0, &status };
1078 QMetaObject::metacall(object, QMetaObject::ReadProperty,
1079 object->metaObject()->indexOfProperty("aliasedObject"), a);
1080 QVERIFY(alias2 == 0);
1083 // Simple composite type
1085 QDeclarativeComponent component(&engine, TEST_FILE("alias.8.qml"));
1087 QObject *object = component.create();
1088 QVERIFY(object != 0);
1090 QCOMPARE(object->property("value").toInt(), 10);
1095 // Complex composite type
1097 QDeclarativeComponent component(&engine, TEST_FILE("alias.9.qml"));
1099 QObject *object = component.create();
1100 QVERIFY(object != 0);
1102 QCOMPARE(object->property("value").toInt(), 10);
1108 // Simple "int" alias
1110 QDeclarativeComponent component(&engine, TEST_FILE("alias.10.qml"));
1112 QObject *object = component.create();
1113 QVERIFY(object != 0);
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));
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));
1128 // Valuetype sub-alias
1130 QDeclarativeComponent component(&engine, TEST_FILE("alias.11.qml"));
1132 QObject *object = component.create();
1133 QVERIFY(object != 0);
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);
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));
1149 // QTBUG-13374 Test that alias properties and signals can coexist
1150 void tst_qdeclarativelanguage::aliasPropertiesAndSignals()
1152 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
1154 QObject *o = component.create();
1156 QCOMPARE(o->property("test").toBool(), true);
1160 // Test that the root element in a composite type can be a Component
1161 void tst_qdeclarativelanguage::componentCompositeType()
1163 QDeclarativeComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
1165 QObject *object = component.create();
1166 QVERIFY(object != 0);
1169 class TestType : public QObject {
1172 TestType(QObject *p=0) : QObject(p) {}
1175 class TestType2 : public QObject {
1178 TestType2(QObject *p=0) : QObject(p) {}
1181 void tst_qdeclarativelanguage::i18n_data()
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");
1193 void tst_qdeclarativelanguage::i18n()
1195 QFETCH(QString, file);
1196 QFETCH(QString, stringProperty);
1197 QDeclarativeComponent component(&engine, TEST_FILE(file));
1199 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1200 QVERIFY(object != 0);
1201 QCOMPARE(object->stringProperty(), stringProperty);
1206 // Check that the Component::onCompleted attached property works
1207 void tst_qdeclarativelanguage::onCompleted()
1209 QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
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);
1218 // Check that the Component::onDestruction attached property works
1219 void tst_qdeclarativelanguage::onDestruction()
1221 QDeclarativeComponent component(&engine, TEST_FILE("onDestruction.qml"));
1223 QObject *object = component.create();
1224 QVERIFY(object != 0);
1226 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1227 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1228 QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
1232 // Check that assignments to QDeclarativeScriptString properties work
1233 void tst_qdeclarativelanguage::scriptString()
1236 QDeclarativeComponent component(&engine, TEST_FILE("scriptString.qml"));
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));
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));
1252 QDeclarativeComponent component(&engine, TEST_FILE("scriptString2.qml"));
1255 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1256 QVERIFY(object != 0);
1257 QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
1261 QDeclarativeComponent component(&engine, TEST_FILE("scriptString3.qml"));
1264 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1265 QVERIFY(object != 0);
1266 QCOMPARE(object->scriptProperty().script(), QString("12.345"));
1270 QDeclarativeComponent component(&engine, TEST_FILE("scriptString4.qml"));
1273 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1274 QVERIFY(object != 0);
1275 QCOMPARE(object->scriptProperty().script(), QString("true"));
1279 // Check that default property assignments are correctly spliced into explicit
1280 // property assignments
1281 void tst_qdeclarativelanguage::defaultPropertyListOrder()
1283 QDeclarativeComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
1286 MyContainer *container = qobject_cast<MyContainer *>(component.create());
1287 QVERIFY(container != 0);
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));
1298 void tst_qdeclarativelanguage::declaredPropertyValues()
1300 QDeclarativeComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
1304 void tst_qdeclarativelanguage::dontDoubleCallClassBegin()
1306 QDeclarativeComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml"));
1307 QObject *o = component.create();
1310 MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
1312 QCOMPARE(o2->classBeginCount(), 1);
1313 QCOMPARE(o2->componentCompleteCount(), 1);
1318 void tst_qdeclarativelanguage::reservedWords_data()
1320 QTest::addColumn<QByteArray>("word");
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");
1384 void tst_qdeclarativelanguage::reservedWords()
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"));
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)
1395 QDeclarativeComponent component(&engine);
1396 component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
1398 QTRY_VERIFY(!component.isLoading());
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());
1408 QCOMPARE(actualerror,expectederror);
1411 QObject *object = component.create();
1412 QVERIFY(object != 0);
1413 QCOMPARE(QString(object->metaObject()->className()), type);
1418 void tst_qdeclarativelanguage::inlineAssignmentsOverrideBindings()
1420 QDeclarativeComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml"));
1422 QObject *o = component.create();
1424 QCOMPARE(o->property("test").toInt(), 11);
1428 // Import tests (QT-558)
1429 void tst_qdeclarativelanguage::importsBuiltin_data()
1433 QTest::addColumn<QString>("qml");
1434 QTest::addColumn<QString>("type");
1435 QTest::addColumn<QString>("error");
1438 QTest::newRow("missing import")
1441 << "Test is not a type";
1442 QTest::newRow("not in version 0.0")
1443 << "import com.nokia.Test 0.0\n"
1446 << "Test is not a type";
1447 QTest::newRow("version not installed")
1448 << "import com.nokia.Test 99.0\n"
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"
1457 QTest::newRow("qualified in version 0.0")
1458 << "import com.nokia.Test 0.0 as T\n"
1462 QTest::newRow("in version 1.0")
1463 << "import com.nokia.Test 1.0\n"
1467 QTest::newRow("qualified wrong")
1468 << "import com.nokia.Test 1.0 as T\n" // QT-610
1471 << "Test is not a type";
1472 QTest::newRow("qualified right")
1473 << "import com.nokia.Test 1.0 as T\n"
1477 QTest::newRow("qualified right but not in version 0.0")
1478 << "import com.nokia.Test 0.0 as T\n"
1481 << "T.Test is not a type";
1482 QTest::newRow("in version 1.1")
1483 << "import com.nokia.Test 1.1\n"
1487 QTest::newRow("in version 1.3")
1488 << "import com.nokia.Test 1.3\n"
1492 QTest::newRow("in version 1.5")
1493 << "import com.nokia.Test 1.5\n"
1497 QTest::newRow("changed in version 1.8")
1498 << "import com.nokia.Test 1.8\n"
1502 QTest::newRow("in version 1.12")
1503 << "import com.nokia.Test 1.12\n"
1507 QTest::newRow("old in version 1.9")
1508 << "import com.nokia.Test 1.9\n"
1512 QTest::newRow("old in version 1.11")
1513 << "import com.nokia.Test 1.11\n"
1517 QTest::newRow("multiversion 1")
1518 << "import com.nokia.Test 1.11\n"
1519 "import com.nokia.Test 1.12\n"
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"
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"
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"
1543 void tst_qdeclarativelanguage::importsBuiltin()
1545 QFETCH(QString, qml);
1546 QFETCH(QString, type);
1547 QFETCH(QString, error);
1548 testType(qml,type,error);
1551 void tst_qdeclarativelanguage::importsLocal_data()
1553 QTest::addColumn<QString>("qml");
1554 QTest::addColumn<QString>("type");
1555 QTest::addColumn<QString>("error");
1558 QTest::newRow("local import")
1559 << "import \"subdir\"\n" // QT-613
1561 << "QDeclarativeRectangle"
1563 QTest::newRow("local import second")
1564 << "import QtQuick 1.0\nimport \"subdir\"\n"
1566 << "QDeclarativeRectangle"
1568 QTest::newRow("local import subsubdir")
1569 << "import QtQuick 1.0\nimport \"subdir/subsubdir\"\n"
1571 << "QDeclarativeRectangle"
1573 QTest::newRow("local import QTBUG-7721 A")
1574 << "subdir.Test {}" // no longer allowed (QTBUG-7721)
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)
1581 << "X.subsubdir.SubTest - nested namespaces not allowed";
1582 QTest::newRow("local import as")
1583 << "import \"subdir\" as T\n"
1585 << "QDeclarativeRectangle"
1587 QTest::newRow("wrong local import as")
1588 << "import \"subdir\" as T\n"
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"
1596 << (!qmlCheckTypes()?"TestType":"")
1597 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test and in subdir");
1600 void tst_qdeclarativelanguage::importsLocal()
1602 QFETCH(QString, qml);
1603 QFETCH(QString, type);
1604 QFETCH(QString, error);
1605 testType(qml,type,error);
1608 void tst_qdeclarativelanguage::basicRemote_data()
1610 QTest::addColumn<QUrl>("url");
1611 QTest::addColumn<QString>("type");
1612 QTest::addColumn<QString>("error");
1614 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage/";
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") << "" << "";
1621 void tst_qdeclarativelanguage::basicRemote()
1624 QFETCH(QString, type);
1625 QFETCH(QString, error);
1627 TestHTTPServer server(14447);
1628 server.serveDirectory(SRCDIR);
1630 QDeclarativeComponent component(&engine, url);
1632 QTRY_VERIFY(!component.isLoading());
1634 if (error.isEmpty()) {
1635 if (component.isError())
1636 qDebug() << component.errors();
1637 QVERIFY(!component.isError());
1639 QVERIFY(component.isError());
1643 void tst_qdeclarativelanguage::importsRemote_data()
1645 QTest::addColumn<QString>("qml");
1646 QTest::addColumn<QString>("type");
1647 QTest::addColumn<QString>("error");
1649 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage";
1651 QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QDeclarativeRectangle"
1653 QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QDeclarativeText"
1655 QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QDeclarativeImage"
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";
1665 void tst_qdeclarativelanguage::importsRemote()
1667 QFETCH(QString, qml);
1668 QFETCH(QString, type);
1669 QFETCH(QString, error);
1671 TestHTTPServer server(14447);
1672 server.serveDirectory(SRCDIR);
1674 testType(qml,type,error);
1677 void tst_qdeclarativelanguage::importsInstalled_data()
1681 QTest::addColumn<QString>("qml");
1682 QTest::addColumn<QString>("type");
1683 QTest::addColumn<QString>("error");
1686 QTest::newRow("installed import 0")
1687 << "import com.nokia.installedtest0 0.0\n"
1688 "InstalledTestTP {}"
1689 << "QDeclarativeRectangle"
1691 QTest::newRow("installed import 0 as TP")
1692 << "import com.nokia.installedtest0 0.0 as TP\n"
1693 "TP.InstalledTestTP {}"
1694 << "QDeclarativeRectangle"
1696 QTest::newRow("installed import 1")
1697 << "import com.nokia.installedtest 1.0\n"
1699 << "QDeclarativeRectangle"
1701 QTest::newRow("installed import 2")
1702 << "import com.nokia.installedtest 1.3\n"
1704 << "QDeclarativeRectangle"
1706 QTest::newRow("installed import 3")
1707 << "import com.nokia.installedtest 1.4\n"
1709 << "QDeclarativeText"
1711 QTest::newRow("installed import minor version not available") // QTBUG-11936
1712 << "import com.nokia.installedtest 0.1\n"
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"
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"
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"
1730 << "PrivateType is not a type";
1733 void tst_qdeclarativelanguage::importsInstalled()
1735 QFETCH(QString, qml);
1736 QFETCH(QString, type);
1737 QFETCH(QString, error);
1738 testType(qml,type,error);
1742 void tst_qdeclarativelanguage::importsOrder_data()
1744 QTest::addColumn<QString>("qml");
1745 QTest::addColumn<QString>("type");
1746 QTest::addColumn<QString>("error");
1748 QTest::newRow("double import") <<
1749 "import com.nokia.installedtest 1.4\n"
1750 "import com.nokia.installedtest 1.4\n"
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"
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"
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"
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"
1779 << (!qmlCheckTypes()?"QDeclarativeRectangle":"")
1780 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1782 QTest::newRow("installed import versus builtin 1") <<
1783 "import com.nokia.installedtest 1.5\n"
1784 "import QtQuick 1.0\n"
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"
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"
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"
1806 QTest::newRow("local last 1") <<
1808 << "QDeclarativeText"
1810 QTest::newRow("local last 2") <<
1811 "import com.nokia.installedtest 1.0\n"
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");
1817 void tst_qdeclarativelanguage::importsOrder()
1819 QFETCH(QString, qml);
1820 QFETCH(QString, type);
1821 QFETCH(QString, error);
1822 testType(qml,type,error);
1825 void tst_qdeclarativelanguage::importIncorrectCase()
1827 QDeclarativeComponent component(&engine, TEST_FILE("importIncorrectCase.qml"));
1829 QList<QDeclarativeError> errors = component.errors();
1830 QCOMPARE(errors.count(), 1);
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("\"");
1835 QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
1838 QCOMPARE(errors.at(0).description(), expectedError);
1841 void tst_qdeclarativelanguage::qmlAttachedPropertiesObjectMethod()
1845 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
1846 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
1849 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
1851 QObject *object = component.create();
1852 QVERIFY(object != 0);
1854 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
1855 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1859 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
1861 QObject *object = component.create();
1862 QVERIFY(object != 0);
1864 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
1865 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1869 void tst_qdeclarativelanguage::crash1()
1871 QDeclarativeComponent component(&engine);
1872 component.setData("import QtQuick 1.0\nComponent {}", QUrl());
1875 void tst_qdeclarativelanguage::crash2()
1877 QDeclarativeComponent component(&engine, TEST_FILE("crash2.qml"));
1881 void tst_qdeclarativelanguage::customOnProperty()
1883 QDeclarativeComponent component(&engine, TEST_FILE("customOnProperty.qml"));
1886 QObject *object = component.create();
1887 QVERIFY(object != 0);
1889 QCOMPARE(object->property("on").toInt(), 10);
1895 void tst_qdeclarativelanguage::variantNotify()
1897 QDeclarativeComponent component(&engine, TEST_FILE("variantNotify.qml"));
1900 QObject *object = component.create();
1901 QVERIFY(object != 0);
1903 QCOMPARE(object->property("notifyCount").toInt(), 1);
1908 void tst_qdeclarativelanguage::revisions()
1911 QDeclarativeComponent component(&engine, TEST_FILE("revisions11.qml"));
1914 MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
1915 QVERIFY(object != 0);
1917 QCOMPARE(object->prop2(), 10.0);
1922 QDeclarativeEngine myEngine;
1923 QDeclarativeComponent component(&myEngine, TEST_FILE("revisionssub11.qml"));
1926 MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
1927 QVERIFY(object != 0);
1929 QCOMPARE(object->prop1(), 10.0);
1930 QCOMPARE(object->prop2(), 10.0);
1931 QCOMPARE(object->prop3(), 10.0);
1932 QCOMPARE(object->prop4(), 10.0);
1937 QDeclarativeComponent component(&engine, TEST_FILE("versionedbase.qml"));
1939 MySubclass *object = qobject_cast<MySubclass*>(component.create());
1940 QVERIFY(object != 0);
1942 QCOMPARE(object->prop1(), 10.0);
1943 QCOMPARE(object->prop2(), 10.0);
1949 void tst_qdeclarativelanguage::revisionOverloads()
1952 QDeclarativeComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml"));
1956 QDeclarativeComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml"));
1957 QEXPECT_FAIL("", "QTBUG-13849", Abort);
1959 VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt");
1963 void tst_qdeclarativelanguage::initTestCase()
1967 // Registering the TestType class in other modules should have no adverse effects
1968 qmlRegisterType<TestType>("com.nokia.TestPre", 1, 0, "Test");
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");
1977 // Registering the TestType class in other modules should have no adverse effects
1978 qmlRegisterType<TestType>("com.nokia.TestPost", 1, 0, "Test");
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());
1991 void tst_qdeclarativelanguage::aliasPropertyChangeSignals()
1994 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.qml"));
1997 QObject *o = component.create();
2000 QCOMPARE(o->property("test").toBool(), true);
2005 // QTCREATORBUG-2769
2007 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.2.qml"));
2010 QObject *o = component.create();
2013 QCOMPARE(o->property("test").toBool(), true);
2019 QTEST_MAIN(tst_qdeclarativelanguage)
2021 #include "tst_qdeclarativelanguage.moc"