1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtDeclarative/qdeclarativeengine.h>
43 #include <QtDeclarative/qdeclarativecomponent.h>
44 #include <QtCore/qcoreapplication.h>
45 #include <QtCore/qfile.h>
46 #include <QtCore/qdebug.h>
47 #include <QtCore/qfileinfo.h>
48 #include <QtCore/qdir.h>
50 #include <private/qdeclarativeproperty_p.h>
51 #include <private/qdeclarativemetatype_p.h>
52 #include <private/qdeclarativeglobal_p.h>
54 #include "testtypes.h"
55 #include "testhttpserver.h"
57 DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)
60 Returns the path to some testdata file or directory.
62 QString testdata(QString const& name = QString())
64 static const QString dataDirectory = QDir::currentPath() + QLatin1String("/data");
65 QString result = dataDirectory;
66 if (!name.isEmpty()) {
67 result += QLatin1Char('/');
74 This test case covers QML language issues. This covers everything that does not
75 involve evaluating ECMAScript expressions and bindings.
77 Evaluation of expressions and bindings is covered in qmlecmascript
79 class tst_qdeclarativelanguage : public QObject
83 tst_qdeclarativelanguage() {
84 QDeclarativeMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter);
85 engine.addImportPath(testdata("lib"));
90 void cleanupTestCase();
95 void insertedSemicolon_data();
96 void insertedSemicolon();
99 void simpleContainer();
100 void interfaceProperty();
101 void interfaceQList();
102 void assignObjectToSignal();
103 void assignObjectToVariant();
104 void assignLiteralSignalProperty();
105 void assignQmlComponent();
106 void assignBasicTypes();
107 void assignTypeExtremes();
108 void assignCompositeToType();
109 void assignLiteralToVariant();
110 void assignLiteralToVar();
111 void customParserTypes();
112 void rootAsQmlComponent();
113 void inlineQmlComponents();
115 void autoNotifyConnection();
117 void dynamicProperties();
118 void dynamicPropertiesNested();
119 void listProperties();
120 void dynamicObjectProperties();
121 void dynamicSignalsAndSlots();
122 void simpleBindings();
123 void autoComponentCreation();
124 void propertyValueSource();
125 void attachedProperties();
126 void dynamicObjects();
127 void customVariantTypes();
130 void aliasProperties();
131 void aliasPropertiesAndSignals();
132 void aliasPropertyChangeSignals();
133 void componentCompositeType();
137 void onDestruction();
139 void defaultPropertyListOrder();
140 void declaredPropertyValues();
141 void dontDoubleCallClassBegin();
142 void reservedWords_data();
143 void reservedWords();
144 void inlineAssignmentsOverrideBindings();
145 void nestedComponentRoots();
146 void registrationOrder();
149 void basicRemote_data();
151 void importsBuiltin_data();
152 void importsBuiltin();
153 void importsLocal_data();
155 void importsRemote_data();
156 void importsRemote();
157 void importsInstalled_data();
158 void importsInstalled();
159 void importsOrder_data();
161 void importIncorrectCase();
163 void qmlAttachedPropertiesObjectMethod();
164 void customOnProperty();
165 void variantNotify();
168 void revisionOverloads();
171 void remoteLoadCrash();
173 // regression tests for crashes
178 QDeclarativeEngine engine;
179 void testType(const QString& qml, const QString& type, const QString& error);
182 #define VERIFY_ERRORS(errorfile) \
184 if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
185 qWarning() << "Unexpected Errors:" << component.errors(); \
186 QVERIFY(!component.isError()); \
187 QVERIFY(component.errors().isEmpty()); \
189 QFile file(testdata(QLatin1String(errorfile))); \
190 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
191 QByteArray data = file.readAll(); \
193 QList<QByteArray> expected = data.split('\n'); \
194 expected.removeAll(QByteArray("")); \
195 QList<QDeclarativeError> errors = component.errors(); \
196 QList<QByteArray> actual; \
197 for (int ii = 0; ii < errors.count(); ++ii) { \
198 const QDeclarativeError &error = errors.at(ii); \
199 QByteArray errorStr = QByteArray::number(error.line()) + ":" + \
200 QByteArray::number(error.column()) + ":" + \
201 error.description().toUtf8(); \
202 actual << errorStr; \
204 if (qgetenv("DEBUG") != "" && expected != actual) \
205 qWarning() << "Expected:" << expected << "Actual:" << actual; \
206 if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
207 QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
208 QVERIFY(file.open(QIODevice::WriteOnly)); \
209 for (int ii = 0; ii < actual.count(); ++ii) { \
210 file.write(actual.at(ii)); file.write("\n"); \
214 QCOMPARE(expected, actual); \
218 inline QUrl TEST_FILE(const QString &filename)
220 return QUrl::fromLocalFile(testdata(filename));
223 inline QUrl TEST_FILE(const char *filename)
225 return TEST_FILE(QLatin1String(filename));
228 void tst_qdeclarativelanguage::cleanupTestCase()
230 QVERIFY(QFile::remove(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile()));
233 void tst_qdeclarativelanguage::insertedSemicolon_data()
235 QTest::addColumn<QString>("file");
236 QTest::addColumn<QString>("errorFile");
237 QTest::addColumn<bool>("create");
239 QTest::newRow("insertedSemicolon.1") << "insertedSemicolon.1.qml" << "insertedSemicolon.1.errors.txt" << false;
242 void tst_qdeclarativelanguage::insertedSemicolon()
244 QFETCH(QString, file);
245 QFETCH(QString, errorFile);
246 QFETCH(bool, create);
248 QDeclarativeComponent component(&engine, TEST_FILE(file));
251 QObject *object = component.create();
252 QVERIFY(object == 0);
255 VERIFY_ERRORS(errorFile.toLatin1().constData());
258 void tst_qdeclarativelanguage::errors_data()
260 QTest::addColumn<QString>("file");
261 QTest::addColumn<QString>("errorFile");
262 QTest::addColumn<bool>("create");
264 QTest::newRow("nonexistantProperty.1") << "nonexistantProperty.1.qml" << "nonexistantProperty.1.errors.txt" << false;
265 QTest::newRow("nonexistantProperty.2") << "nonexistantProperty.2.qml" << "nonexistantProperty.2.errors.txt" << false;
266 QTest::newRow("nonexistantProperty.3") << "nonexistantProperty.3.qml" << "nonexistantProperty.3.errors.txt" << false;
267 QTest::newRow("nonexistantProperty.4") << "nonexistantProperty.4.qml" << "nonexistantProperty.4.errors.txt" << false;
268 QTest::newRow("nonexistantProperty.5") << "nonexistantProperty.5.qml" << "nonexistantProperty.5.errors.txt" << false;
269 QTest::newRow("nonexistantProperty.6") << "nonexistantProperty.6.qml" << "nonexistantProperty.6.errors.txt" << false;
271 QTest::newRow("wrongType (string for int)") << "wrongType.1.qml" << "wrongType.1.errors.txt" << false;
272 QTest::newRow("wrongType (int for bool)") << "wrongType.2.qml" << "wrongType.2.errors.txt" << false;
273 QTest::newRow("wrongType (bad rect)") << "wrongType.3.qml" << "wrongType.3.errors.txt" << false;
275 QTest::newRow("wrongType (invalid enum)") << "wrongType.4.qml" << "wrongType.4.errors.txt" << false;
276 QTest::newRow("wrongType (int for uint)") << "wrongType.5.qml" << "wrongType.5.errors.txt" << false;
277 QTest::newRow("wrongType (string for real)") << "wrongType.6.qml" << "wrongType.6.errors.txt" << false;
278 QTest::newRow("wrongType (int for color)") << "wrongType.7.qml" << "wrongType.7.errors.txt" << false;
279 QTest::newRow("wrongType (int for date)") << "wrongType.8.qml" << "wrongType.8.errors.txt" << false;
280 QTest::newRow("wrongType (int for time)") << "wrongType.9.qml" << "wrongType.9.errors.txt" << false;
281 QTest::newRow("wrongType (int for datetime)") << "wrongType.10.qml" << "wrongType.10.errors.txt" << false;
282 QTest::newRow("wrongType (string for point)") << "wrongType.11.qml" << "wrongType.11.errors.txt" << false;
283 QTest::newRow("wrongType (color for size)") << "wrongType.12.qml" << "wrongType.12.errors.txt" << false;
284 QTest::newRow("wrongType (number string for int)") << "wrongType.13.qml" << "wrongType.13.errors.txt" << false;
285 QTest::newRow("wrongType (int for string)") << "wrongType.14.qml" << "wrongType.14.errors.txt" << false;
286 QTest::newRow("wrongType (int for url)") << "wrongType.15.qml" << "wrongType.15.errors.txt" << false;
287 QTest::newRow("wrongType (invalid object)") << "wrongType.16.qml" << "wrongType.16.errors.txt" << false;
288 QTest::newRow("wrongType (int for enum)") << "wrongType.17.qml" << "wrongType.17.errors.txt" << false;
290 QTest::newRow("readOnly.1") << "readOnly.1.qml" << "readOnly.1.errors.txt" << false;
291 QTest::newRow("readOnly.2") << "readOnly.2.qml" << "readOnly.2.errors.txt" << false;
292 QTest::newRow("readOnly.3") << "readOnly.3.qml" << "readOnly.3.errors.txt" << false;
293 QTest::newRow("readOnly.4") << "readOnly.4.qml" << "readOnly.4.errors.txt" << false;
294 QTest::newRow("readOnly.5") << "readOnly.5.qml" << "readOnly.5.errors.txt" << false;
296 QTest::newRow("listAssignment.1") << "listAssignment.1.qml" << "listAssignment.1.errors.txt" << false;
297 QTest::newRow("listAssignment.2") << "listAssignment.2.qml" << "listAssignment.2.errors.txt" << false;
298 QTest::newRow("listAssignment.3") << "listAssignment.3.qml" << "listAssignment.3.errors.txt" << false;
300 QTest::newRow("invalidID.1") << "invalidID.qml" << "invalidID.errors.txt" << false;
301 QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
302 QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
303 QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
304 QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
305 QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false;
306 QTest::newRow("invalidID.7") << "invalidID.7.qml" << "invalidID.7.errors.txt" << false;
307 QTest::newRow("invalidID.8") << "invalidID.8.qml" << "invalidID.8.errors.txt" << false;
308 QTest::newRow("invalidID.9") << "invalidID.9.qml" << "invalidID.9.errors.txt" << false;
310 QTest::newRow("scriptString.1") << "scriptString.1.qml" << "scriptString.1.errors.txt" << false;
311 QTest::newRow("scriptString.2") << "scriptString.2.qml" << "scriptString.2.errors.txt" << false;
313 QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
314 QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;
315 QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false;
316 QTest::newRow("duplicateIDs") << "duplicateIDs.qml" << "duplicateIDs.errors.txt" << false;
317 QTest::newRow("unregisteredObject") << "unregisteredObject.qml" << "unregisteredObject.errors.txt" << false;
318 QTest::newRow("empty") << "empty.qml" << "empty.errors.txt" << false;
319 QTest::newRow("missingObject") << "missingObject.qml" << "missingObject.errors.txt" << false;
320 QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
321 QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
322 QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
323 QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
325 QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
326 QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
327 QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
328 QTest::newRow("invalidGroupedProperty.4") << "invalidGroupedProperty.4.qml" << "invalidGroupedProperty.4.errors.txt" << false;
329 QTest::newRow("invalidGroupedProperty.5") << "invalidGroupedProperty.5.qml" << "invalidGroupedProperty.5.errors.txt" << false;
330 QTest::newRow("invalidGroupedProperty.6") << "invalidGroupedProperty.6.qml" << "invalidGroupedProperty.6.errors.txt" << false;
331 QTest::newRow("invalidGroupedProperty.7") << "invalidGroupedProperty.7.qml" << "invalidGroupedProperty.7.errors.txt" << true;
332 QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
333 QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
334 QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
336 QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
337 QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
338 QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false;
339 QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false;
340 QTest::newRow("importNonExistOlder (installed)") << "importNonExistOlder.qml" << "importNonExistOlder.errors.txt" << false;
341 QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false;
342 QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false;
343 QTest::newRow("importFile") << "importFile.qml" << "importFile.errors.txt" << false;
345 QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false;
346 QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false;
347 QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false;
348 QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false;
350 QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
352 QTest::newRow("property.1") << "property.1.qml" << "property.1.errors.txt" << false;
353 QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
354 QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
355 QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
356 QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
357 QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
359 QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
361 QTest::newRow("Component.1") << "component.1.qml" << "component.1.errors.txt" << false;
362 QTest::newRow("Component.2") << "component.2.qml" << "component.2.errors.txt" << false;
363 QTest::newRow("Component.3") << "component.3.qml" << "component.3.errors.txt" << false;
364 QTest::newRow("Component.4") << "component.4.qml" << "component.4.errors.txt" << false;
365 QTest::newRow("Component.5") << "component.5.qml" << "component.5.errors.txt" << false;
366 QTest::newRow("Component.6") << "component.6.qml" << "component.6.errors.txt" << false;
367 QTest::newRow("Component.7") << "component.7.qml" << "component.7.errors.txt" << false;
368 QTest::newRow("Component.8") << "component.8.qml" << "component.8.errors.txt" << false;
369 QTest::newRow("Component.9") << "component.9.qml" << "component.9.errors.txt" << false;
371 QTest::newRow("MultiSet.1") << "multiSet.1.qml" << "multiSet.1.errors.txt" << false;
372 QTest::newRow("MultiSet.2") << "multiSet.2.qml" << "multiSet.2.errors.txt" << false;
373 QTest::newRow("MultiSet.3") << "multiSet.3.qml" << "multiSet.3.errors.txt" << false;
374 QTest::newRow("MultiSet.4") << "multiSet.4.qml" << "multiSet.4.errors.txt" << false;
375 QTest::newRow("MultiSet.5") << "multiSet.5.qml" << "multiSet.5.errors.txt" << false;
376 QTest::newRow("MultiSet.6") << "multiSet.6.qml" << "multiSet.6.errors.txt" << false;
377 QTest::newRow("MultiSet.7") << "multiSet.7.qml" << "multiSet.7.errors.txt" << false;
378 QTest::newRow("MultiSet.8") << "multiSet.8.qml" << "multiSet.8.errors.txt" << false;
379 QTest::newRow("MultiSet.9") << "multiSet.9.qml" << "multiSet.9.errors.txt" << false;
380 QTest::newRow("MultiSet.10") << "multiSet.10.qml" << "multiSet.10.errors.txt" << false;
381 QTest::newRow("MultiSet.11") << "multiSet.11.qml" << "multiSet.11.errors.txt" << false;
383 QTest::newRow("dynamicMeta.1") << "dynamicMeta.1.qml" << "dynamicMeta.1.errors.txt" << false;
384 QTest::newRow("dynamicMeta.2") << "dynamicMeta.2.qml" << "dynamicMeta.2.errors.txt" << false;
385 QTest::newRow("dynamicMeta.3") << "dynamicMeta.3.qml" << "dynamicMeta.3.errors.txt" << false;
386 QTest::newRow("dynamicMeta.4") << "dynamicMeta.4.qml" << "dynamicMeta.4.errors.txt" << false;
387 QTest::newRow("dynamicMeta.5") << "dynamicMeta.5.qml" << "dynamicMeta.5.errors.txt" << false;
389 QTest::newRow("invalidAlias.1") << "invalidAlias.1.qml" << "invalidAlias.1.errors.txt" << false;
390 QTest::newRow("invalidAlias.2") << "invalidAlias.2.qml" << "invalidAlias.2.errors.txt" << false;
391 QTest::newRow("invalidAlias.3") << "invalidAlias.3.qml" << "invalidAlias.3.errors.txt" << false;
392 QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false;
393 QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
394 QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
395 QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false;
396 QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
397 QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
398 QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
400 QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
401 QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
402 QTest::newRow("invalidAttachedProperty.3") << "invalidAttachedProperty.3.qml" << "invalidAttachedProperty.3.errors.txt" << false;
403 QTest::newRow("invalidAttachedProperty.4") << "invalidAttachedProperty.4.qml" << "invalidAttachedProperty.4.errors.txt" << false;
404 QTest::newRow("invalidAttachedProperty.5") << "invalidAttachedProperty.5.qml" << "invalidAttachedProperty.5.errors.txt" << false;
405 QTest::newRow("invalidAttachedProperty.6") << "invalidAttachedProperty.6.qml" << "invalidAttachedProperty.6.errors.txt" << false;
406 QTest::newRow("invalidAttachedProperty.7") << "invalidAttachedProperty.7.qml" << "invalidAttachedProperty.7.errors.txt" << false;
407 QTest::newRow("invalidAttachedProperty.8") << "invalidAttachedProperty.8.qml" << "invalidAttachedProperty.8.errors.txt" << false;
408 QTest::newRow("invalidAttachedProperty.9") << "invalidAttachedProperty.9.qml" << "invalidAttachedProperty.9.errors.txt" << false;
409 QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false;
410 QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false;
411 QTest::newRow("invalidAttachedProperty.12") << "invalidAttachedProperty.12.qml" << "invalidAttachedProperty.12.errors.txt" << false;
412 QTest::newRow("invalidAttachedProperty.13") << "invalidAttachedProperty.13.qml" << "invalidAttachedProperty.13.errors.txt" << false;
414 QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
415 QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
417 QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false;
418 QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false;
419 QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false;
420 QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false;
421 QTest::newRow("objectValueTypeProperty") << "objectValueTypeProperty.qml" << "objectValueTypeProperty.errors.txt" << false;
422 QTest::newRow("enumTypes") << "enumTypes.qml" << "enumTypes.errors.txt" << false;
423 QTest::newRow("noCreation") << "noCreation.qml" << "noCreation.errors.txt" << false;
424 QTest::newRow("destroyedSignal") << "destroyedSignal.qml" << "destroyedSignal.errors.txt" << false;
425 QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false;
426 QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false;
427 QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false;
428 QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false;
429 QTest::newRow("notAvailable") << "notAvailable.qml" << "notAvailable.errors.txt" << false;
430 QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
431 QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
432 QTest::newRow("incorrectCase") << "incorrectCase.qml"
433 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
434 << "incorrectCase.errors.insensitive.txt"
436 << "incorrectCase.errors.sensitive.txt"
440 QTest::newRow("metaobjectRevision.1") << "metaobjectRevision.1.qml" << "metaobjectRevision.1.errors.txt" << false;
441 QTest::newRow("metaobjectRevision.2") << "metaobjectRevision.2.qml" << "metaobjectRevision.2.errors.txt" << false;
442 QTest::newRow("metaobjectRevision.3") << "metaobjectRevision.3.qml" << "metaobjectRevision.3.errors.txt" << false;
444 QTest::newRow("invalidRoot.1") << "invalidRoot.1.qml" << "invalidRoot.1.errors.txt" << false;
445 QTest::newRow("invalidRoot.2") << "invalidRoot.2.qml" << "invalidRoot.2.errors.txt" << false;
446 QTest::newRow("invalidRoot.3") << "invalidRoot.3.qml" << "invalidRoot.3.errors.txt" << false;
447 QTest::newRow("invalidRoot.4") << "invalidRoot.4.qml" << "invalidRoot.4.errors.txt" << false;
449 QTest::newRow("invalidTypeName.1") << "invalidTypeName.1.qml" << "invalidTypeName.1.errors.txt" << false;
450 QTest::newRow("invalidTypeName.2") << "invalidTypeName.2.qml" << "invalidTypeName.2.errors.txt" << false;
451 QTest::newRow("invalidTypeName.3") << "invalidTypeName.3.qml" << "invalidTypeName.3.errors.txt" << false;
452 QTest::newRow("invalidTypeName.4") << "invalidTypeName.4.qml" << "invalidTypeName.4.errors.txt" << false;
454 QTest::newRow("Major version isolation") << "majorVersionIsolation.qml" << "majorVersionIsolation.errors.txt" << false;
458 void tst_qdeclarativelanguage::errors()
460 QFETCH(QString, file);
461 QFETCH(QString, errorFile);
462 QFETCH(bool, create);
464 QDeclarativeComponent component(&engine, TEST_FILE(file));
467 QObject *object = component.create();
468 QVERIFY(object == 0);
471 VERIFY_ERRORS(errorFile.toLatin1().constData());
474 void tst_qdeclarativelanguage::simpleObject()
476 QDeclarativeComponent component(&engine, TEST_FILE("simpleObject.qml"));
478 QObject *object = component.create();
479 QVERIFY(object != 0);
482 void tst_qdeclarativelanguage::simpleContainer()
484 QDeclarativeComponent component(&engine, TEST_FILE("simpleContainer.qml"));
486 MyContainer *container= qobject_cast<MyContainer*>(component.create());
487 QVERIFY(container != 0);
488 QCOMPARE(container->getChildren()->count(),2);
491 void tst_qdeclarativelanguage::interfaceProperty()
493 QDeclarativeComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
495 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
496 QVERIFY(object != 0);
497 QVERIFY(object->interface());
498 QVERIFY(object->interface()->id == 913);
501 void tst_qdeclarativelanguage::interfaceQList()
503 QDeclarativeComponent component(&engine, TEST_FILE("interfaceQList.qml"));
505 MyContainer *container= qobject_cast<MyContainer*>(component.create());
506 QVERIFY(container != 0);
507 QVERIFY(container->getQListInterfaces()->count() == 2);
508 for(int ii = 0; ii < 2; ++ii)
509 QVERIFY(container->getQListInterfaces()->at(ii)->id == 913);
512 void tst_qdeclarativelanguage::assignObjectToSignal()
514 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
516 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
517 QVERIFY(object != 0);
518 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
519 emit object->basicSignal();
522 void tst_qdeclarativelanguage::assignObjectToVariant()
524 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
526 QObject *object = component.create();
527 QVERIFY(object != 0);
528 QVariant v = object->property("a");
529 QVERIFY(v.userType() == qMetaTypeId<QObject *>());
532 void tst_qdeclarativelanguage::assignLiteralSignalProperty()
534 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
536 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
537 QVERIFY(object != 0);
538 QCOMPARE(object->onLiteralSignal(), 10);
541 // Test is an external component can be loaded and assigned (to a qlist)
542 void tst_qdeclarativelanguage::assignQmlComponent()
544 QDeclarativeComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
546 MyContainer *object = qobject_cast<MyContainer *>(component.create());
547 QVERIFY(object != 0);
548 QVERIFY(object->getChildren()->count() == 1);
549 QObject *child = object->getChildren()->at(0);
550 QCOMPARE(child->property("x"), QVariant(10));
551 QCOMPARE(child->property("y"), QVariant(11));
554 // Test literal assignment to all the basic types
555 void tst_qdeclarativelanguage::assignBasicTypes()
557 QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
559 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
560 QVERIFY(object != 0);
561 QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
562 QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
563 QCOMPARE(object->stringProperty(), QString("Hello World!"));
564 QCOMPARE(object->uintProperty(), uint(10));
565 QCOMPARE(object->intProperty(), -19);
566 QCOMPARE((float)object->realProperty(), float(23.2));
567 QCOMPARE((float)object->doubleProperty(), float(-19.7));
568 QCOMPARE((float)object->floatProperty(), float(8.5));
569 QCOMPARE(object->colorProperty(), QColor("red"));
570 QCOMPARE(object->dateProperty(), QDate(1982, 11, 25));
571 QCOMPARE(object->timeProperty(), QTime(11, 11, 32));
572 QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1)));
573 QCOMPARE(object->pointProperty(), QPoint(99,13));
574 QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3));
575 QCOMPARE(object->sizeProperty(), QSize(99, 13));
576 QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2));
577 QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200));
578 QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99));
579 QCOMPARE(object->boolProperty(), true);
580 QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
581 QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2));
582 QCOMPARE(object->vector4Property(), QVector4D(10, 1, 2.2, 2.3));
584 encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
585 QCOMPARE(object->urlProperty(), component.url().resolved(encoded));
586 QVERIFY(object->objectProperty() != 0);
587 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
589 QCOMPARE(child->intProperty(), 8);
592 // Test edge case type assignments
593 void tst_qdeclarativelanguage::assignTypeExtremes()
595 QDeclarativeComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
597 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
598 QVERIFY(object != 0);
599 QCOMPARE(object->uintProperty(), 0xEE6B2800);
600 QCOMPARE(object->intProperty(), -0x77359400);
603 // Test that a composite type can assign to a property of its base type
604 void tst_qdeclarativelanguage::assignCompositeToType()
606 QDeclarativeComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
608 QObject *object = component.create();
609 QVERIFY(object != 0);
612 // Test that literals are stored correctly in variant properties
613 void tst_qdeclarativelanguage::assignLiteralToVariant()
615 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
617 QObject *object = component.create();
618 QVERIFY(object != 0);
620 QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
621 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
622 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
623 QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
624 QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
625 QCOMPARE(object->property("test6").userType(), (int)QVariant::PointF);
626 QCOMPARE(object->property("test7").userType(), (int)QVariant::SizeF);
627 QCOMPARE(object->property("test8").userType(), (int)QVariant::Vector3D);
628 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
629 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
630 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
631 QCOMPARE(object->property("test12").userType(), (int)QVariant::Vector4D);
633 QVERIFY(object->property("test1") == QVariant(1));
634 QVERIFY(object->property("test2") == QVariant((double)1.7));
635 QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!"))));
636 QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800)));
637 QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10)));
638 QVERIFY(object->property("test6") == QVariant(QPointF(10, 10)));
639 QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10)));
640 QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100)));
641 QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800"))));
642 QVERIFY(object->property("test10") == QVariant(bool(true)));
643 QVERIFY(object->property("test11") == QVariant(bool(false)));
644 QVERIFY(object->property("test12") == QVariant(QVector4D(100, 100, 100, 100)));
649 // Test that literals are stored correctly in "var" properties
650 // Note that behaviour differs from "variant" properties in that
651 // no conversion from "special strings" to QVariants is performed.
652 void tst_qdeclarativelanguage::assignLiteralToVar()
654 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVar.qml"));
656 QObject *object = component.create();
657 QVERIFY(object != 0);
659 QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
660 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
661 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
662 QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
663 QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
664 QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
665 QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
666 QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
667 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
668 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
669 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
670 QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
671 QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
672 QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
673 QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
674 QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
675 QCOMPARE(object->property("variantTest1Bound").userType(), (int)QMetaType::Int);
676 QCOMPARE(object->property("test1Bound").userType(), (int)QMetaType::Int);
678 QCOMPARE(object->property("test1"), QVariant(5));
679 QCOMPARE(object->property("test2"), QVariant((double)1.7));
680 QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
681 QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
682 QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
683 QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
684 QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
685 QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
686 QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
687 QCOMPARE(object->property("test10"), QVariant(bool(true)));
688 QCOMPARE(object->property("test11"), QVariant(bool(false)));
689 QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
690 QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
691 QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
692 QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
693 QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
694 QCOMPARE(object->property("variantTest1Bound"), QVariant(9));
695 QCOMPARE(object->property("test1Bound"), QVariant(11));
700 // Tests that custom parser types can be instantiated
701 void tst_qdeclarativelanguage::customParserTypes()
703 QDeclarativeComponent component(&engine, TEST_FILE("customParserTypes.qml"));
705 QObject *object = component.create();
706 QVERIFY(object != 0);
707 QVERIFY(object->property("count") == QVariant(2));
710 // Tests that the root item can be a custom component
711 void tst_qdeclarativelanguage::rootAsQmlComponent()
713 QDeclarativeComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
715 MyContainer *object = qobject_cast<MyContainer *>(component.create());
716 QVERIFY(object != 0);
717 QCOMPARE(object->property("x"), QVariant(11));
718 QCOMPARE(object->getChildren()->count(), 2);
721 // Tests that components can be specified inline
722 void tst_qdeclarativelanguage::inlineQmlComponents()
724 QDeclarativeComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
726 MyContainer *object = qobject_cast<MyContainer *>(component.create());
727 QVERIFY(object != 0);
728 QCOMPARE(object->getChildren()->count(), 1);
729 QDeclarativeComponent *comp = qobject_cast<QDeclarativeComponent *>(object->getChildren()->at(0));
731 MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
732 QVERIFY(compObject != 0);
733 QCOMPARE(compObject->value(), 11);
736 // Tests that types that have an id property have it set
737 void tst_qdeclarativelanguage::idProperty()
739 QDeclarativeComponent component(&engine, TEST_FILE("idProperty.qml"));
741 MyContainer *object = qobject_cast<MyContainer *>(component.create());
742 QVERIFY(object != 0);
743 QCOMPARE(object->getChildren()->count(), 1);
744 MyTypeObject *child =
745 qobject_cast<MyTypeObject *>(object->getChildren()->at(0));
747 QCOMPARE(child->id(), QString("myObjectId"));
748 QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
751 // Tests automatic connection to notify signals if "onBlahChanged" syntax is used
752 // even if the notify signal for "blah" is not called "blahChanged"
753 void tst_qdeclarativelanguage::autoNotifyConnection()
755 QDeclarativeComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
757 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
758 QVERIFY(object != 0);
759 QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
760 QVERIFY(prop.isValid());
762 QCOMPARE(prop.read(object), QVariant::fromValue(false));
763 object->setPropertyWithNotify(1);
764 QCOMPARE(prop.read(object), QVariant::fromValue(true));
767 // Tests that signals can be assigned to
768 void tst_qdeclarativelanguage::assignSignal()
770 QDeclarativeComponent component(&engine, TEST_FILE("assignSignal.qml"));
772 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
773 QVERIFY(object != 0);
774 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
775 emit object->basicSignal();
776 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)");
777 emit object->basicParameterizedSignal(9);
780 // Tests the creation and assignment of dynamic properties
781 void tst_qdeclarativelanguage::dynamicProperties()
783 QDeclarativeComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
785 QObject *object = component.create();
786 QVERIFY(object != 0);
787 QCOMPARE(object->property("intProperty"), QVariant(10));
788 QCOMPARE(object->property("boolProperty"), QVariant(false));
789 QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
790 QCOMPARE(object->property("realProperty"), QVariant((qreal)-19.9));
791 QCOMPARE(object->property("stringProperty"), QVariant("Hello World!"));
792 QCOMPARE(object->property("urlProperty"), QVariant(TEST_FILE("main.qml")));
793 QCOMPARE(object->property("colorProperty"), QVariant(QColor("red")));
794 QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2)));
795 QCOMPARE(object->property("varProperty"), QVariant("Hello World!"));
798 // Test that nested types can use dynamic properties
799 void tst_qdeclarativelanguage::dynamicPropertiesNested()
801 QDeclarativeComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
803 QObject *object = component.create();
804 QVERIFY(object != 0);
806 QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
807 QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
808 QCOMPARE(object->property("a").toInt(), 13); // New
809 QCOMPARE(object->property("b").toInt(), 12); // New
814 // Tests the creation and assignment to dynamic list properties
815 void tst_qdeclarativelanguage::listProperties()
817 QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml"));
819 QObject *object = component.create();
820 QVERIFY(object != 0);
822 QCOMPARE(object->property("test").toInt(), 2);
825 // Tests the creation and assignment of dynamic object properties
827 void tst_qdeclarativelanguage::dynamicObjectProperties()
830 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
832 QObject *object = component.create();
833 QVERIFY(object != 0);
835 QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
836 QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
839 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
840 QEXPECT_FAIL("", "QTBUG-10822", Abort);
842 QObject *object = component.create();
843 QVERIFY(object != 0);
845 QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
849 // Tests the declaration of dynamic signals and slots
850 void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
852 QTest::ignoreMessage(QtDebugMsg, "1921");
854 QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
856 QObject *object = component.create();
857 QVERIFY(object != 0);
858 QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
859 QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
860 QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1);
861 QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
863 QCOMPARE(object->property("test").toInt(), 0);
864 QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
865 QCOMPARE(object->property("test").toInt(), 10);
868 void tst_qdeclarativelanguage::simpleBindings()
870 QDeclarativeComponent component(&engine, TEST_FILE("simpleBindings.qml"));
872 QObject *object = component.create();
873 QVERIFY(object != 0);
874 QCOMPARE(object->property("value1"), QVariant(10));
875 QCOMPARE(object->property("value2"), QVariant(10));
876 QCOMPARE(object->property("value3"), QVariant(21));
877 QCOMPARE(object->property("value4"), QVariant(10));
878 QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
881 void tst_qdeclarativelanguage::autoComponentCreation()
883 QDeclarativeComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
885 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
886 QVERIFY(object != 0);
887 QVERIFY(object->componentProperty() != 0);
888 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
890 QCOMPARE(child->realProperty(), qreal(9));
893 void tst_qdeclarativelanguage::propertyValueSource()
896 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
898 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
899 QVERIFY(object != 0);
901 QList<QObject *> valueSources;
902 QObjectList allChildren = object->findChildren<QObject*>();
903 foreach (QObject *child, allChildren) {
904 if (qobject_cast<QDeclarativePropertyValueSource *>(child))
905 valueSources.append(child);
908 QCOMPARE(valueSources.count(), 1);
909 MyPropertyValueSource *valueSource =
910 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
911 QVERIFY(valueSource != 0);
912 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
913 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
917 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
919 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
920 QVERIFY(object != 0);
922 QList<QObject *> valueSources;
923 QObjectList allChildren = object->findChildren<QObject*>();
924 foreach (QObject *child, allChildren) {
925 if (qobject_cast<QDeclarativePropertyValueSource *>(child))
926 valueSources.append(child);
929 QCOMPARE(valueSources.count(), 1);
930 MyPropertyValueSource *valueSource =
931 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
932 QVERIFY(valueSource != 0);
933 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
934 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
938 void tst_qdeclarativelanguage::attachedProperties()
940 QDeclarativeComponent component(&engine, TEST_FILE("attachedProperties.qml"));
942 QObject *object = component.create();
943 QVERIFY(object != 0);
944 QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
945 QVERIFY(attached != 0);
946 QCOMPARE(attached->property("value"), QVariant(10));
947 QCOMPARE(attached->property("value2"), QVariant(13));
950 // Tests non-static object properties
951 void tst_qdeclarativelanguage::dynamicObjects()
953 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
955 QObject *object = component.create();
956 QVERIFY(object != 0);
959 // Tests the registration of custom variant string converters
960 void tst_qdeclarativelanguage::customVariantTypes()
962 QDeclarativeComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
964 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
965 QVERIFY(object != 0);
966 QCOMPARE(object->customType().a, 10);
969 void tst_qdeclarativelanguage::valueTypes()
971 QDeclarativeComponent component(&engine, TEST_FILE("valueTypes.qml"));
974 QString message = component.url().toString() + ":2:1: QML MyTypeObject: Binding loop detected for property \"rectProperty.width\"";
975 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
976 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
978 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
979 QVERIFY(object != 0);
982 QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
983 QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
984 QCOMPARE(object->intProperty(), 10);
986 QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
987 QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
988 QCOMPARE(object->intProperty(), 12);
992 QDeclarativeProperty p(object, "rectProperty.x");
993 QCOMPARE(p.read(), QVariant(12));
995 QCOMPARE(p.read(), QVariant(13));
997 quint32 r = QDeclarativePropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
998 QDeclarativeProperty p2;
999 QDeclarativePropertyPrivate::restore(p2, r, object);
1000 QCOMPARE(p2.read(), QVariant(13));
1004 void tst_qdeclarativelanguage::cppnamespace()
1007 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.qml"));
1009 QObject *object = component.create();
1010 QVERIFY(object != 0);
1015 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
1017 QObject *object = component.create();
1018 QVERIFY(object != 0);
1023 void tst_qdeclarativelanguage::aliasProperties()
1025 // Simple "int" alias
1027 QDeclarativeComponent component(&engine, TEST_FILE("alias.1.qml"));
1029 QObject *object = component.create();
1030 QVERIFY(object != 0);
1032 // Read through alias
1033 QCOMPARE(object->property("valueAlias").toInt(), 10);
1034 object->setProperty("value", QVariant(13));
1035 QCOMPARE(object->property("valueAlias").toInt(), 13);
1037 // Write through alias
1038 object->setProperty("valueAlias", QVariant(19));
1039 QCOMPARE(object->property("valueAlias").toInt(), 19);
1040 QCOMPARE(object->property("value").toInt(), 19);
1045 // Complex object alias
1047 QDeclarativeComponent component(&engine, TEST_FILE("alias.2.qml"));
1049 QObject *object = component.create();
1050 QVERIFY(object != 0);
1052 // Read through alias
1054 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1056 QCOMPARE(v->value(), 10);
1058 // Write through alias
1059 MyQmlObject *v2 = new MyQmlObject();
1060 v2->setParent(object);
1061 object->setProperty("aliasObject", qVariantFromValue(v2));
1063 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1072 QDeclarativeComponent component(&engine, TEST_FILE("alias.3.qml"));
1074 QObject *object = component.create();
1075 QVERIFY(object != 0);
1077 QCOMPARE(object->property("value").toInt(), 1892);
1078 QCOMPARE(object->property("value2").toInt(), 1892);
1080 object->setProperty("value", QVariant(1313));
1081 QCOMPARE(object->property("value").toInt(), 1313);
1082 QCOMPARE(object->property("value2").toInt(), 1313);
1084 object->setProperty("value2", QVariant(8080));
1085 QCOMPARE(object->property("value").toInt(), 8080);
1086 QCOMPARE(object->property("value2").toInt(), 8080);
1093 QDeclarativeComponent component(&engine, TEST_FILE("alias.4.qml"));
1095 QObject *object = component.create();
1096 QVERIFY(object != 0);
1098 QCOMPARE(object->property("enumAlias").toInt(), 1);
1105 QDeclarativeComponent component(&engine, TEST_FILE("alias.5.qml"));
1107 QObject *object = component.create();
1108 QVERIFY(object != 0);
1110 QVariant v = object->property("otherAlias");
1111 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1112 MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
1113 QCOMPARE(o->value(), 10);
1117 v = object->property("otherAlias");
1118 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1119 o = qvariant_cast<MyQmlObject*>(v);
1125 // Nested aliases - this used to cause a crash
1127 QDeclarativeComponent component(&engine, TEST_FILE("alias.6.qml"));
1129 QObject *object = component.create();
1130 QVERIFY(object != 0);
1132 QCOMPARE(object->property("a").toInt(), 1923);
1135 // Ptr Alias Cleanup - check that aliases to ptr types return 0
1136 // if the object aliased to is removed
1138 QDeclarativeComponent component(&engine, TEST_FILE("alias.7.qml"));
1141 QObject *object = component.create();
1142 QVERIFY(object != 0);
1144 QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
1145 QVERIFY(object1 != 0);
1146 QObject *object2 = qvariant_cast<QObject *>(object1->property("object"));
1147 QVERIFY(object2 != 0);
1149 QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
1150 QVERIFY(alias == object2);
1154 QObject *alias2 = object; // "Random" start value
1156 void *a[] = { &alias2, 0, &status };
1157 QMetaObject::metacall(object, QMetaObject::ReadProperty,
1158 object->metaObject()->indexOfProperty("aliasedObject"), a);
1159 QVERIFY(alias2 == 0);
1162 // Simple composite type
1164 QDeclarativeComponent component(&engine, TEST_FILE("alias.8.qml"));
1166 QObject *object = component.create();
1167 QVERIFY(object != 0);
1169 QCOMPARE(object->property("value").toInt(), 10);
1174 // Complex composite type
1176 QDeclarativeComponent component(&engine, TEST_FILE("alias.9.qml"));
1178 QObject *object = component.create();
1179 QVERIFY(object != 0);
1181 QCOMPARE(object->property("value").toInt(), 10);
1187 // Simple "int" alias
1189 QDeclarativeComponent component(&engine, TEST_FILE("alias.10.qml"));
1191 QObject *object = component.create();
1192 QVERIFY(object != 0);
1194 // Read through alias
1195 QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8));
1196 object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
1197 QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
1199 // Write through alias
1200 object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
1201 QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
1202 QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
1207 // Valuetype sub-alias
1209 QDeclarativeComponent component(&engine, TEST_FILE("alias.11.qml"));
1211 QObject *object = component.create();
1212 QVERIFY(object != 0);
1214 // Read through alias
1215 QCOMPARE(object->property("aliasProperty").toInt(), 19);
1216 object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
1217 QCOMPARE(object->property("aliasProperty").toInt(), 33);
1219 // Write through alias
1220 object->setProperty("aliasProperty", QVariant(4));
1221 QCOMPARE(object->property("aliasProperty").toInt(), 4);
1222 QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
1228 // QTBUG-13374 Test that alias properties and signals can coexist
1229 void tst_qdeclarativelanguage::aliasPropertiesAndSignals()
1231 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
1233 QObject *o = component.create();
1235 QCOMPARE(o->property("test").toBool(), true);
1239 // Test that the root element in a composite type can be a Component
1240 void tst_qdeclarativelanguage::componentCompositeType()
1242 QDeclarativeComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
1244 QObject *object = component.create();
1245 QVERIFY(object != 0);
1248 class TestType : public QObject {
1251 TestType(QObject *p=0) : QObject(p) {}
1254 class TestType2 : public QObject {
1257 TestType2(QObject *p=0) : QObject(p) {}
1260 void tst_qdeclarativelanguage::i18n_data()
1262 QTest::addColumn<QString>("file");
1263 QTest::addColumn<QString>("stringProperty");
1264 QTest::newRow("i18nStrings") << "i18nStrings.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245 (5 accented 'a' letters)");
1265 QTest::newRow("i18nDeclaredPropertyNames") << "i18nDeclaredPropertyNames.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 10");
1266 QTest::newRow("i18nDeclaredPropertyUse") << "i18nDeclaredPropertyUse.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 15");
1267 QTest::newRow("i18nScript") << "i18nScript.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 20");
1268 QTest::newRow("i18nType") << "i18nType.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 30");
1269 QTest::newRow("i18nNameSpace") << "i18nNameSpace.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 40");
1272 void tst_qdeclarativelanguage::i18n()
1274 QFETCH(QString, file);
1275 QFETCH(QString, stringProperty);
1276 QDeclarativeComponent component(&engine, TEST_FILE(file));
1278 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1279 QVERIFY(object != 0);
1280 QCOMPARE(object->stringProperty(), stringProperty);
1285 // Check that the Component::onCompleted attached property works
1286 void tst_qdeclarativelanguage::onCompleted()
1288 QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
1290 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1291 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1292 QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
1293 QObject *object = component.create();
1294 QVERIFY(object != 0);
1297 // Check that the Component::onDestruction attached property works
1298 void tst_qdeclarativelanguage::onDestruction()
1300 QDeclarativeComponent component(&engine, TEST_FILE("onDestruction.qml"));
1302 QObject *object = component.create();
1303 QVERIFY(object != 0);
1304 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1305 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1306 QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
1310 // Check that assignments to QDeclarativeScriptString properties work
1311 void tst_qdeclarativelanguage::scriptString()
1314 QDeclarativeComponent component(&engine, TEST_FILE("scriptString.qml"));
1317 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1318 QVERIFY(object != 0);
1319 QCOMPARE(object->scriptProperty().script(), QString("foo + bar"));
1320 QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object));
1321 QCOMPARE(object->scriptProperty().context(), qmlContext(object));
1323 QVERIFY(object->grouped() != 0);
1324 QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)"));
1325 QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object));
1326 QCOMPARE(object->grouped()->script().context(), qmlContext(object));
1330 QDeclarativeComponent component(&engine, TEST_FILE("scriptString2.qml"));
1333 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1334 QVERIFY(object != 0);
1335 QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
1339 QDeclarativeComponent component(&engine, TEST_FILE("scriptString3.qml"));
1342 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1343 QVERIFY(object != 0);
1344 QCOMPARE(object->scriptProperty().script(), QString("12.345"));
1348 QDeclarativeComponent component(&engine, TEST_FILE("scriptString4.qml"));
1351 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1352 QVERIFY(object != 0);
1353 QCOMPARE(object->scriptProperty().script(), QString("true"));
1357 // Check that default property assignments are correctly spliced into explicit
1358 // property assignments
1359 void tst_qdeclarativelanguage::defaultPropertyListOrder()
1361 QDeclarativeComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
1364 MyContainer *container = qobject_cast<MyContainer *>(component.create());
1365 QVERIFY(container != 0);
1367 QCOMPARE(container->getChildren()->count(), 6);
1368 QCOMPARE(container->getChildren()->at(0)->property("index"), QVariant(0));
1369 QCOMPARE(container->getChildren()->at(1)->property("index"), QVariant(1));
1370 QCOMPARE(container->getChildren()->at(2)->property("index"), QVariant(2));
1371 QCOMPARE(container->getChildren()->at(3)->property("index"), QVariant(3));
1372 QCOMPARE(container->getChildren()->at(4)->property("index"), QVariant(4));
1373 QCOMPARE(container->getChildren()->at(5)->property("index"), QVariant(5));
1376 void tst_qdeclarativelanguage::declaredPropertyValues()
1378 QDeclarativeComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
1382 void tst_qdeclarativelanguage::dontDoubleCallClassBegin()
1384 QDeclarativeComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml"));
1385 QObject *o = component.create();
1388 MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
1390 QCOMPARE(o2->classBeginCount(), 1);
1391 QCOMPARE(o2->componentCompleteCount(), 1);
1396 void tst_qdeclarativelanguage::reservedWords_data()
1398 QTest::addColumn<QByteArray>("word");
1400 QTest::newRow("abstract") << QByteArray("abstract");
1401 QTest::newRow("as") << QByteArray("as");
1402 QTest::newRow("boolean") << QByteArray("boolean");
1403 QTest::newRow("break") << QByteArray("break");
1404 QTest::newRow("byte") << QByteArray("byte");
1405 QTest::newRow("case") << QByteArray("case");
1406 QTest::newRow("catch") << QByteArray("catch");
1407 QTest::newRow("char") << QByteArray("char");
1408 QTest::newRow("class") << QByteArray("class");
1409 QTest::newRow("continue") << QByteArray("continue");
1410 QTest::newRow("const") << QByteArray("const");
1411 QTest::newRow("debugger") << QByteArray("debugger");
1412 QTest::newRow("default") << QByteArray("default");
1413 QTest::newRow("delete") << QByteArray("delete");
1414 QTest::newRow("do") << QByteArray("do");
1415 QTest::newRow("double") << QByteArray("double");
1416 QTest::newRow("else") << QByteArray("else");
1417 QTest::newRow("enum") << QByteArray("enum");
1418 QTest::newRow("export") << QByteArray("export");
1419 QTest::newRow("extends") << QByteArray("extends");
1420 QTest::newRow("false") << QByteArray("false");
1421 QTest::newRow("final") << QByteArray("final");
1422 QTest::newRow("finally") << QByteArray("finally");
1423 QTest::newRow("float") << QByteArray("float");
1424 QTest::newRow("for") << QByteArray("for");
1425 QTest::newRow("function") << QByteArray("function");
1426 QTest::newRow("goto") << QByteArray("goto");
1427 QTest::newRow("if") << QByteArray("if");
1428 QTest::newRow("implements") << QByteArray("implements");
1429 QTest::newRow("import") << QByteArray("import");
1430 QTest::newRow("in") << QByteArray("in");
1431 QTest::newRow("instanceof") << QByteArray("instanceof");
1432 QTest::newRow("int") << QByteArray("int");
1433 QTest::newRow("interface") << QByteArray("interface");
1434 QTest::newRow("long") << QByteArray("long");
1435 QTest::newRow("native") << QByteArray("native");
1436 QTest::newRow("new") << QByteArray("new");
1437 QTest::newRow("null") << QByteArray("null");
1438 QTest::newRow("package") << QByteArray("package");
1439 QTest::newRow("private") << QByteArray("private");
1440 QTest::newRow("protected") << QByteArray("protected");
1441 QTest::newRow("public") << QByteArray("public");
1442 QTest::newRow("return") << QByteArray("return");
1443 QTest::newRow("short") << QByteArray("short");
1444 QTest::newRow("static") << QByteArray("static");
1445 QTest::newRow("super") << QByteArray("super");
1446 QTest::newRow("switch") << QByteArray("switch");
1447 QTest::newRow("synchronized") << QByteArray("synchronized");
1448 QTest::newRow("this") << QByteArray("this");
1449 QTest::newRow("throw") << QByteArray("throw");
1450 QTest::newRow("throws") << QByteArray("throws");
1451 QTest::newRow("transient") << QByteArray("transient");
1452 QTest::newRow("true") << QByteArray("true");
1453 QTest::newRow("try") << QByteArray("try");
1454 QTest::newRow("typeof") << QByteArray("typeof");
1455 QTest::newRow("var") << QByteArray("var");
1456 QTest::newRow("void") << QByteArray("void");
1457 QTest::newRow("volatile") << QByteArray("volatile");
1458 QTest::newRow("while") << QByteArray("while");
1459 QTest::newRow("with") << QByteArray("with");
1462 void tst_qdeclarativelanguage::reservedWords()
1464 QFETCH(QByteArray, word);
1465 QDeclarativeComponent component(&engine);
1466 component.setData("import QtQuick 2.0\nQtObject { property string " + word + " }", QUrl());
1467 QCOMPARE(component.errorString(), QLatin1String(":2 Expected token `identifier'\n"));
1470 // Check that first child of qml is of given type. Empty type insists on error.
1471 void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, const QString& expectederror)
1473 QDeclarativeComponent component(&engine);
1474 component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
1476 QTRY_VERIFY(!component.isLoading());
1478 if (type.isEmpty()) {
1479 QVERIFY(component.isError());
1480 QString actualerror;
1481 foreach (const QDeclarativeError e, component.errors()) {
1482 if (!actualerror.isEmpty())
1483 actualerror.append("; ");
1484 actualerror.append(e.description());
1486 QCOMPARE(actualerror,expectederror);
1489 QObject *object = component.create();
1490 QVERIFY(object != 0);
1491 QCOMPARE(QString(object->metaObject()->className()), type);
1497 void tst_qdeclarativelanguage::inlineAssignmentsOverrideBindings()
1499 QDeclarativeComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml"));
1501 QObject *o = component.create();
1503 QCOMPARE(o->property("test").toInt(), 11);
1508 void tst_qdeclarativelanguage::nestedComponentRoots()
1510 QDeclarativeComponent component(&engine, TEST_FILE("nestedComponentRoots.qml"));
1513 // Import tests (QT-558)
1514 void tst_qdeclarativelanguage::importsBuiltin_data()
1518 QTest::addColumn<QString>("qml");
1519 QTest::addColumn<QString>("type");
1520 QTest::addColumn<QString>("error");
1523 QTest::newRow("missing import")
1526 << "Test is not a type";
1527 QTest::newRow("not in version 0.0")
1528 << "import com.nokia.Test 0.0\n"
1531 << "Test is not a type";
1532 QTest::newRow("version not installed")
1533 << "import com.nokia.Test 99.0\n"
1536 << "module \"com.nokia.Test\" version 99.0 is not installed";
1537 QTest::newRow("in version 0.0")
1538 << "import com.nokia.Test 0.0\n"
1542 QTest::newRow("qualified in version 0.0")
1543 << "import com.nokia.Test 0.0 as T\n"
1547 QTest::newRow("in version 1.0")
1548 << "import com.nokia.Test 1.0\n"
1552 QTest::newRow("qualified wrong")
1553 << "import com.nokia.Test 1.0 as T\n" // QT-610
1556 << "Test is not a type";
1557 QTest::newRow("qualified right")
1558 << "import com.nokia.Test 1.0 as T\n"
1562 QTest::newRow("qualified right but not in version 0.0")
1563 << "import com.nokia.Test 0.0 as T\n"
1566 << "T.Test is not a type";
1567 QTest::newRow("in version 1.1")
1568 << "import com.nokia.Test 1.1\n"
1572 QTest::newRow("in version 1.3")
1573 << "import com.nokia.Test 1.3\n"
1577 QTest::newRow("in version 1.5")
1578 << "import com.nokia.Test 1.5\n"
1582 QTest::newRow("changed in version 1.8")
1583 << "import com.nokia.Test 1.8\n"
1587 QTest::newRow("in version 1.12")
1588 << "import com.nokia.Test 1.12\n"
1592 QTest::newRow("old in version 1.9")
1593 << "import com.nokia.Test 1.9\n"
1597 QTest::newRow("old in version 1.11")
1598 << "import com.nokia.Test 1.11\n"
1602 QTest::newRow("multiversion 1")
1603 << "import com.nokia.Test 1.11\n"
1604 "import com.nokia.Test 1.12\n"
1606 << (!qmlCheckTypes()?"TestType2":"")
1607 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1608 QTest::newRow("multiversion 2")
1609 << "import com.nokia.Test 1.11\n"
1610 "import com.nokia.Test 1.12\n"
1612 << (!qmlCheckTypes()?"TestType":"")
1613 << (!qmlCheckTypes()?"":"OldTest is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1614 QTest::newRow("qualified multiversion 3")
1615 << "import com.nokia.Test 1.0 as T0\n"
1616 "import com.nokia.Test 1.8 as T8\n"
1620 QTest::newRow("qualified multiversion 4")
1621 << "import com.nokia.Test 1.0 as T0\n"
1622 "import com.nokia.Test 1.8 as T8\n"
1628 void tst_qdeclarativelanguage::importsBuiltin()
1630 QFETCH(QString, qml);
1631 QFETCH(QString, type);
1632 QFETCH(QString, error);
1633 testType(qml,type,error);
1636 void tst_qdeclarativelanguage::importsLocal_data()
1638 QTest::addColumn<QString>("qml");
1639 QTest::addColumn<QString>("type");
1640 QTest::addColumn<QString>("error");
1643 QTest::newRow("local import")
1644 << "import \"subdir\"\n" // QT-613
1646 << "QQuickRectangle"
1648 QTest::newRow("local import second")
1649 << "import QtQuick 2.0\nimport \"subdir\"\n"
1651 << "QQuickRectangle"
1653 QTest::newRow("local import subsubdir")
1654 << "import QtQuick 2.0\nimport \"subdir/subsubdir\"\n"
1656 << "QQuickRectangle"
1658 QTest::newRow("local import QTBUG-7721 A")
1659 << "subdir.Test {}" // no longer allowed (QTBUG-7721)
1661 << "subdir.Test - subdir is not a namespace";
1662 QTest::newRow("local import QTBUG-7721 B")
1663 << "import \"subdir\" as X\n"
1664 "X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
1666 << "X.subsubdir.SubTest - nested namespaces not allowed";
1667 QTest::newRow("local import as")
1668 << "import \"subdir\" as T\n"
1670 << "QQuickRectangle"
1672 QTest::newRow("wrong local import as")
1673 << "import \"subdir\" as T\n"
1676 << "Test is not a type";
1677 QTest::newRow("library precedence over local import")
1678 << "import \"subdir\"\n"
1679 "import com.nokia.Test 1.0\n"
1681 << (!qmlCheckTypes()?"TestType":"")
1682 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test and in subdir");
1685 void tst_qdeclarativelanguage::importsLocal()
1687 QFETCH(QString, qml);
1688 QFETCH(QString, type);
1689 QFETCH(QString, error);
1690 testType(qml,type,error);
1693 void tst_qdeclarativelanguage::basicRemote_data()
1695 QTest::addColumn<QUrl>("url");
1696 QTest::addColumn<QString>("type");
1697 QTest::addColumn<QString>("error");
1699 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage/";
1701 QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
1702 QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << "";
1703 QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
1706 void tst_qdeclarativelanguage::basicRemote()
1709 QFETCH(QString, type);
1710 QFETCH(QString, error);
1712 TestHTTPServer server(14447);
1713 server.serveDirectory(testdata());
1715 QDeclarativeComponent component(&engine, url);
1717 QTRY_VERIFY(!component.isLoading());
1719 if (error.isEmpty()) {
1720 if (component.isError())
1721 qDebug() << component.errors();
1722 QVERIFY(!component.isError());
1724 QVERIFY(component.isError());
1728 void tst_qdeclarativelanguage::importsRemote_data()
1730 QTest::addColumn<QString>("qml");
1731 QTest::addColumn<QString>("type");
1732 QTest::addColumn<QString>("error");
1734 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage";
1736 QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QQuickRectangle"
1738 QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QQuickText"
1740 QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QQuickImage"
1742 QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
1743 << "WrongTestLocal is not a type";
1744 QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
1745 << "LocalInternal is not a type";
1746 QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""
1747 << "UndeclaredLocal is not a type";
1750 void tst_qdeclarativelanguage::importsRemote()
1752 QFETCH(QString, qml);
1753 QFETCH(QString, type);
1754 QFETCH(QString, error);
1756 TestHTTPServer server(14447);
1757 server.serveDirectory(testdata());
1759 testType(qml,type,error);
1762 void tst_qdeclarativelanguage::importsInstalled_data()
1766 QTest::addColumn<QString>("qml");
1767 QTest::addColumn<QString>("type");
1768 QTest::addColumn<QString>("error");
1771 QTest::newRow("installed import 0")
1772 << "import com.nokia.installedtest0 0.0\n"
1773 "InstalledTestTP {}"
1774 << "QQuickRectangle"
1776 QTest::newRow("installed import 0 as TP")
1777 << "import com.nokia.installedtest0 0.0 as TP\n"
1778 "TP.InstalledTestTP {}"
1779 << "QQuickRectangle"
1781 QTest::newRow("installed import 1")
1782 << "import com.nokia.installedtest 1.0\n"
1784 << "QQuickRectangle"
1786 QTest::newRow("installed import 2")
1787 << "import com.nokia.installedtest 1.3\n"
1789 << "QQuickRectangle"
1791 QTest::newRow("installed import 3")
1792 << "import com.nokia.installedtest 1.4\n"
1796 QTest::newRow("installed import minor version not available") // QTBUG-11936
1797 << "import com.nokia.installedtest 0.1\n"
1800 << "module \"com.nokia.installedtest\" version 0.1 is not installed";
1801 QTest::newRow("installed import minor version not available") // QTBUG-9627
1802 << "import com.nokia.installedtest 1.10\n"
1805 << "module \"com.nokia.installedtest\" version 1.10 is not installed";
1806 QTest::newRow("installed import major version not available") // QTBUG-9627
1807 << "import com.nokia.installedtest 9.0\n"
1810 << "module \"com.nokia.installedtest\" version 9.0 is not installed";
1811 QTest::newRow("installed import visibility") // QT-614
1812 << "import com.nokia.installedtest 1.4\n"
1815 << "PrivateType is not a type";
1818 void tst_qdeclarativelanguage::importsInstalled()
1820 QFETCH(QString, qml);
1821 QFETCH(QString, type);
1822 QFETCH(QString, error);
1823 testType(qml,type,error);
1827 void tst_qdeclarativelanguage::importsOrder_data()
1829 QTest::addColumn<QString>("qml");
1830 QTest::addColumn<QString>("type");
1831 QTest::addColumn<QString>("error");
1833 QTest::newRow("double import") <<
1834 "import com.nokia.installedtest 1.4\n"
1835 "import com.nokia.installedtest 1.4\n"
1837 << (!qmlCheckTypes()?"QQuickText":"")
1838 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.4");
1839 QTest::newRow("installed import overrides 1") <<
1840 "import com.nokia.installedtest 1.0\n"
1841 "import com.nokia.installedtest 1.4\n"
1843 << (!qmlCheckTypes()?"QQuickText":"")
1844 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1845 QTest::newRow("installed import overrides 2") <<
1846 "import com.nokia.installedtest 1.4\n"
1847 "import com.nokia.installedtest 1.0\n"
1849 << (!qmlCheckTypes()?"QQuickRectangle":"")
1850 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1851 QTest::newRow("installed import re-overrides 1") <<
1852 "import com.nokia.installedtest 1.4\n"
1853 "import com.nokia.installedtest 1.0\n"
1854 "import com.nokia.installedtest 1.4\n"
1856 << (!qmlCheckTypes()?"QQuickText":"")
1857 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1858 QTest::newRow("installed import re-overrides 2") <<
1859 "import com.nokia.installedtest 1.4\n"
1860 "import com.nokia.installedtest 1.0\n"
1861 "import com.nokia.installedtest 1.4\n"
1862 "import com.nokia.installedtest 1.0\n"
1864 << (!qmlCheckTypes()?"QQuickRectangle":"")
1865 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1867 QTest::newRow("installed import versus builtin 1") <<
1868 "import com.nokia.installedtest 1.5\n"
1869 "import QtQuick 2.0\n"
1871 << (!qmlCheckTypes()?"QQuickRectangle":"")
1872 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in Qt and in lib/com/nokia/installedtest");
1873 QTest::newRow("installed import versus builtin 2") <<
1874 "import QtQuick 2.0\n"
1875 "import com.nokia.installedtest 1.5\n"
1877 << (!qmlCheckTypes()?"QQuickText":"")
1878 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest and in Qt");
1879 QTest::newRow("namespaces cannot be overridden by types 1") <<
1880 "import QtQuick 2.0 as Rectangle\n"
1881 "import com.nokia.installedtest 1.5\n"
1884 << "Namespace Rectangle cannot be used as a type";
1885 QTest::newRow("namespaces cannot be overridden by types 2") <<
1886 "import QtQuick 2.0 as Rectangle\n"
1887 "import com.nokia.installedtest 1.5\n"
1888 "Rectangle.Image {}"
1891 QTest::newRow("local last 1") <<
1895 QTest::newRow("local last 2") <<
1896 "import com.nokia.installedtest 1.0\n"
1898 << (!qmlCheckTypes()?"QQuickRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
1899 << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest and in local directory");
1902 void tst_qdeclarativelanguage::importsOrder()
1904 QFETCH(QString, qml);
1905 QFETCH(QString, type);
1906 QFETCH(QString, error);
1907 testType(qml,type,error);
1910 void tst_qdeclarativelanguage::importIncorrectCase()
1912 QDeclarativeComponent component(&engine, TEST_FILE("importIncorrectCase.qml"));
1914 QList<QDeclarativeError> errors = component.errors();
1915 QCOMPARE(errors.count(), 1);
1917 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1918 QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + testdata("lib/com/Nokia/installedtest/qmldir") + QLatin1String("\"");
1920 QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
1923 QCOMPARE(errors.at(0).description(), expectedError);
1926 void tst_qdeclarativelanguage::qmlAttachedPropertiesObjectMethod()
1930 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
1931 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
1934 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
1936 QObject *object = component.create();
1937 QVERIFY(object != 0);
1939 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
1940 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1944 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
1946 QObject *object = component.create();
1947 QVERIFY(object != 0);
1949 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
1950 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1954 void tst_qdeclarativelanguage::crash1()
1956 QDeclarativeComponent component(&engine);
1957 component.setData("import QtQuick 2.0\nComponent {}", QUrl());
1960 void tst_qdeclarativelanguage::crash2()
1962 QDeclarativeComponent component(&engine, TEST_FILE("crash2.qml"));
1966 void tst_qdeclarativelanguage::customOnProperty()
1968 QDeclarativeComponent component(&engine, TEST_FILE("customOnProperty.qml"));
1971 QObject *object = component.create();
1972 QVERIFY(object != 0);
1974 QCOMPARE(object->property("on").toInt(), 10);
1980 void tst_qdeclarativelanguage::variantNotify()
1982 QDeclarativeComponent component(&engine, TEST_FILE("variantNotify.qml"));
1985 QObject *object = component.create();
1986 QVERIFY(object != 0);
1988 QCOMPARE(object->property("notifyCount").toInt(), 1);
1993 void tst_qdeclarativelanguage::revisions()
1996 QDeclarativeComponent component(&engine, TEST_FILE("revisions11.qml"));
1999 MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
2000 QVERIFY(object != 0);
2002 QCOMPARE(object->prop2(), 10.0);
2007 QDeclarativeEngine myEngine;
2008 QDeclarativeComponent component(&myEngine, TEST_FILE("revisionssub11.qml"));
2011 MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
2012 QVERIFY(object != 0);
2014 QCOMPARE(object->prop1(), 10.0);
2015 QCOMPARE(object->prop2(), 10.0);
2016 QCOMPARE(object->prop3(), 10.0);
2017 QCOMPARE(object->prop4(), 10.0);
2022 QDeclarativeComponent component(&engine, TEST_FILE("versionedbase.qml"));
2024 MySubclass *object = qobject_cast<MySubclass*>(component.create());
2025 QVERIFY(object != 0);
2027 QCOMPARE(object->prop1(), 10.0);
2028 QCOMPARE(object->prop2(), 10.0);
2034 void tst_qdeclarativelanguage::revisionOverloads()
2037 QDeclarativeComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml"));
2041 QDeclarativeComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml"));
2042 QEXPECT_FAIL("", "QTBUG-13849", Abort);
2044 VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt");
2048 void tst_qdeclarativelanguage::initTestCase()
2050 QString testdataDir = QFileInfo(QFINDTESTDATA("data")).absolutePath();
2051 QVERIFY2(QDir::setCurrent(testdataDir), qPrintable("Could not chdir to " + testdataDir));
2055 // Registering the TestType class in other modules should have no adverse effects
2056 qmlRegisterType<TestType>("com.nokia.TestPre", 1, 0, "Test");
2058 qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP");
2059 qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test");
2060 qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test");
2061 qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test");
2062 qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest");
2063 qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test");
2065 // Registering the TestType class in other modules should have no adverse effects
2066 qmlRegisterType<TestType>("com.nokia.TestPost", 1, 0, "Test");
2068 // Create locale-specific file
2069 // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit
2070 // For iso8859-1 locale, this will just be data/I18nType?????.qml where ????? is 5 8-bit characters
2071 // For utf-8 locale, this will be data/I18nType??????????.qml where ?????????? is 5 8-bit characters, UTF-8 encoded
2072 QFile in(TEST_FILE(QLatin1String("I18nType30.qml")).toLocalFile());
2073 QVERIFY2(in.open(QIODevice::ReadOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(in.fileName(), in.errorString())));
2074 QFile out(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile());
2075 QVERIFY2(out.open(QIODevice::WriteOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(out.fileName(), out.errorString())));
2076 out.write(in.readAll());
2079 void tst_qdeclarativelanguage::aliasPropertyChangeSignals()
2082 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.qml"));
2085 QObject *o = component.create();
2088 QCOMPARE(o->property("test").toBool(), true);
2093 // QTCREATORBUG-2769
2095 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.2.qml"));
2098 QObject *o = component.create();
2101 QCOMPARE(o->property("test").toBool(), true);
2107 // Tests property initializers
2108 void tst_qdeclarativelanguage::propertyInit()
2111 QDeclarativeComponent component(&engine, TEST_FILE("propertyInit.1.qml"));
2114 QObject *o = component.create();
2117 QCOMPARE(o->property("test").toInt(), 1);
2123 QDeclarativeComponent component(&engine, TEST_FILE("propertyInit.2.qml"));
2126 QObject *o = component.create();
2129 QCOMPARE(o->property("test").toInt(), 123);
2135 // Test that registration order doesn't break type availability
2137 void tst_qdeclarativelanguage::registrationOrder()
2139 QDeclarativeComponent component(&engine, TEST_FILE("registrationOrder.qml"));
2141 QObject *o = component.create();
2143 QVERIFY(o->metaObject() == &MyVersion2Class::staticMetaObject);
2147 void tst_qdeclarativelanguage::readonly()
2149 QDeclarativeComponent component(&engine, TEST_FILE("readonly.qml"));
2151 QObject *o = component.create();
2154 QCOMPARE(o->property("test1").toInt(), 10);
2155 QCOMPARE(o->property("test2").toInt(), 18);
2156 QCOMPARE(o->property("test3").toInt(), 13);
2158 o->setProperty("testData", 13);
2160 QCOMPARE(o->property("test1").toInt(), 10);
2161 QCOMPARE(o->property("test2").toInt(), 22);
2162 QCOMPARE(o->property("test3").toInt(), 13);
2164 o->setProperty("testData2", 2);
2166 QCOMPARE(o->property("test1").toInt(), 10);
2167 QCOMPARE(o->property("test2").toInt(), 22);
2168 QCOMPARE(o->property("test3").toInt(), 2);
2170 o->setProperty("test1", 11);
2171 o->setProperty("test2", 11);
2172 o->setProperty("test3", 11);
2174 QCOMPARE(o->property("test1").toInt(), 10);
2175 QCOMPARE(o->property("test2").toInt(), 22);
2176 QCOMPARE(o->property("test3").toInt(), 2);
2182 void tst_qdeclarativelanguage::remoteLoadCrash()
2184 TestHTTPServer server(14448);
2185 server.serveDirectory(testdata());
2187 QDeclarativeComponent component(&engine);
2188 component.setData("import QtQuick 1.0; Text {}", QUrl("http://127.0.0.1:14448/remoteLoadCrash.qml"));
2189 while (component.isLoading())
2190 QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
2192 QObject *o = component.create();
2196 QTEST_MAIN(tst_qdeclarativelanguage)
2198 #include "tst_qdeclarativelanguage.moc"