1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** 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();
162 void importJs_data();
165 void qmlAttachedPropertiesObjectMethod();
166 void customOnProperty();
167 void variantNotify();
170 void revisionOverloads();
173 void remoteLoadCrash();
175 // regression tests for crashes
180 QDeclarativeEngine engine;
181 void testType(const QString& qml, const QString& type, const QString& error);
184 #define DETERMINE_ERRORS(errorfile,expected,actual)\
185 QList<QByteArray> expected; \
186 QList<QByteArray> actual; \
188 QFile file(testdata(QLatin1String(errorfile))); \
189 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
190 QByteArray data = file.readAll(); \
192 expected = data.split('\n'); \
193 expected.removeAll(QByteArray("")); \
194 QList<QDeclarativeError> errors = component.errors(); \
195 for (int ii = 0; ii < errors.count(); ++ii) { \
196 const QDeclarativeError &error = errors.at(ii); \
197 QByteArray errorStr = QByteArray::number(error.line()) + ":" + \
198 QByteArray::number(error.column()) + ":" + \
199 error.description().toUtf8(); \
200 actual << errorStr; \
204 #define VERIFY_ERRORS(errorfile) \
206 if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
207 qWarning() << "Unexpected Errors:" << component.errors(); \
208 QVERIFY(!component.isError()); \
209 QVERIFY(component.errors().isEmpty()); \
211 DETERMINE_ERRORS(errorfile,actual,expected);\
212 if (qgetenv("DEBUG") != "" && expected != actual) \
213 qWarning() << "Expected:" << expected << "Actual:" << actual; \
214 if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
215 QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
216 QVERIFY(file.open(QIODevice::WriteOnly)); \
217 for (int ii = 0; ii < actual.count(); ++ii) { \
218 file.write(actual.at(ii)); file.write("\n"); \
222 QCOMPARE(expected, actual); \
226 inline QUrl TEST_FILE(const QString &filename)
228 return QUrl::fromLocalFile(testdata(filename));
231 inline QUrl TEST_FILE(const char *filename)
233 return TEST_FILE(QLatin1String(filename));
236 void tst_qdeclarativelanguage::cleanupTestCase()
238 QVERIFY(QFile::remove(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile()));
241 void tst_qdeclarativelanguage::insertedSemicolon_data()
243 QTest::addColumn<QString>("file");
244 QTest::addColumn<QString>("errorFile");
245 QTest::addColumn<bool>("create");
247 QTest::newRow("insertedSemicolon.1") << "insertedSemicolon.1.qml" << "insertedSemicolon.1.errors.txt" << false;
250 void tst_qdeclarativelanguage::insertedSemicolon()
252 QFETCH(QString, file);
253 QFETCH(QString, errorFile);
254 QFETCH(bool, create);
256 QDeclarativeComponent component(&engine, TEST_FILE(file));
259 QObject *object = component.create();
260 QVERIFY(object == 0);
263 VERIFY_ERRORS(errorFile.toLatin1().constData());
266 void tst_qdeclarativelanguage::errors_data()
268 QTest::addColumn<QString>("file");
269 QTest::addColumn<QString>("errorFile");
270 QTest::addColumn<bool>("create");
272 QTest::newRow("nonexistantProperty.1") << "nonexistantProperty.1.qml" << "nonexistantProperty.1.errors.txt" << false;
273 QTest::newRow("nonexistantProperty.2") << "nonexistantProperty.2.qml" << "nonexistantProperty.2.errors.txt" << false;
274 QTest::newRow("nonexistantProperty.3") << "nonexistantProperty.3.qml" << "nonexistantProperty.3.errors.txt" << false;
275 QTest::newRow("nonexistantProperty.4") << "nonexistantProperty.4.qml" << "nonexistantProperty.4.errors.txt" << false;
276 QTest::newRow("nonexistantProperty.5") << "nonexistantProperty.5.qml" << "nonexistantProperty.5.errors.txt" << false;
277 QTest::newRow("nonexistantProperty.6") << "nonexistantProperty.6.qml" << "nonexistantProperty.6.errors.txt" << false;
279 QTest::newRow("wrongType (string for int)") << "wrongType.1.qml" << "wrongType.1.errors.txt" << false;
280 QTest::newRow("wrongType (int for bool)") << "wrongType.2.qml" << "wrongType.2.errors.txt" << false;
281 QTest::newRow("wrongType (bad rect)") << "wrongType.3.qml" << "wrongType.3.errors.txt" << false;
283 QTest::newRow("wrongType (invalid enum)") << "wrongType.4.qml" << "wrongType.4.errors.txt" << false;
284 QTest::newRow("wrongType (int for uint)") << "wrongType.5.qml" << "wrongType.5.errors.txt" << false;
285 QTest::newRow("wrongType (string for real)") << "wrongType.6.qml" << "wrongType.6.errors.txt" << false;
286 QTest::newRow("wrongType (int for color)") << "wrongType.7.qml" << "wrongType.7.errors.txt" << false;
287 QTest::newRow("wrongType (int for date)") << "wrongType.8.qml" << "wrongType.8.errors.txt" << false;
288 QTest::newRow("wrongType (int for time)") << "wrongType.9.qml" << "wrongType.9.errors.txt" << false;
289 QTest::newRow("wrongType (int for datetime)") << "wrongType.10.qml" << "wrongType.10.errors.txt" << false;
290 QTest::newRow("wrongType (string for point)") << "wrongType.11.qml" << "wrongType.11.errors.txt" << false;
291 QTest::newRow("wrongType (color for size)") << "wrongType.12.qml" << "wrongType.12.errors.txt" << false;
292 QTest::newRow("wrongType (number string for int)") << "wrongType.13.qml" << "wrongType.13.errors.txt" << false;
293 QTest::newRow("wrongType (int for string)") << "wrongType.14.qml" << "wrongType.14.errors.txt" << false;
294 QTest::newRow("wrongType (int for url)") << "wrongType.15.qml" << "wrongType.15.errors.txt" << false;
295 QTest::newRow("wrongType (invalid object)") << "wrongType.16.qml" << "wrongType.16.errors.txt" << false;
296 QTest::newRow("wrongType (int for enum)") << "wrongType.17.qml" << "wrongType.17.errors.txt" << false;
298 QTest::newRow("readOnly.1") << "readOnly.1.qml" << "readOnly.1.errors.txt" << false;
299 QTest::newRow("readOnly.2") << "readOnly.2.qml" << "readOnly.2.errors.txt" << false;
300 QTest::newRow("readOnly.3") << "readOnly.3.qml" << "readOnly.3.errors.txt" << false;
301 QTest::newRow("readOnly.4") << "readOnly.4.qml" << "readOnly.4.errors.txt" << false;
302 QTest::newRow("readOnly.5") << "readOnly.5.qml" << "readOnly.5.errors.txt" << false;
304 QTest::newRow("listAssignment.1") << "listAssignment.1.qml" << "listAssignment.1.errors.txt" << false;
305 QTest::newRow("listAssignment.2") << "listAssignment.2.qml" << "listAssignment.2.errors.txt" << false;
306 QTest::newRow("listAssignment.3") << "listAssignment.3.qml" << "listAssignment.3.errors.txt" << false;
308 QTest::newRow("invalidID.1") << "invalidID.qml" << "invalidID.errors.txt" << false;
309 QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
310 QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
311 QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
312 QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
313 QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false;
314 QTest::newRow("invalidID.7") << "invalidID.7.qml" << "invalidID.7.errors.txt" << false;
315 QTest::newRow("invalidID.8") << "invalidID.8.qml" << "invalidID.8.errors.txt" << false;
316 QTest::newRow("invalidID.9") << "invalidID.9.qml" << "invalidID.9.errors.txt" << false;
318 QTest::newRow("scriptString.1") << "scriptString.1.qml" << "scriptString.1.errors.txt" << false;
319 QTest::newRow("scriptString.2") << "scriptString.2.qml" << "scriptString.2.errors.txt" << false;
321 QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
322 QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;
323 QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false;
324 QTest::newRow("duplicateIDs") << "duplicateIDs.qml" << "duplicateIDs.errors.txt" << false;
325 QTest::newRow("unregisteredObject") << "unregisteredObject.qml" << "unregisteredObject.errors.txt" << false;
326 QTest::newRow("empty") << "empty.qml" << "empty.errors.txt" << false;
327 QTest::newRow("missingObject") << "missingObject.qml" << "missingObject.errors.txt" << false;
328 QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
329 QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
330 QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
331 QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
333 QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
334 QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
335 QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
336 QTest::newRow("invalidGroupedProperty.4") << "invalidGroupedProperty.4.qml" << "invalidGroupedProperty.4.errors.txt" << false;
337 QTest::newRow("invalidGroupedProperty.5") << "invalidGroupedProperty.5.qml" << "invalidGroupedProperty.5.errors.txt" << false;
338 QTest::newRow("invalidGroupedProperty.6") << "invalidGroupedProperty.6.qml" << "invalidGroupedProperty.6.errors.txt" << false;
339 QTest::newRow("invalidGroupedProperty.7") << "invalidGroupedProperty.7.qml" << "invalidGroupedProperty.7.errors.txt" << true;
340 QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
341 QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
342 QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
344 QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
345 QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
346 QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false;
347 QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false;
348 QTest::newRow("importNonExistOlder (installed)") << "importNonExistOlder.qml" << "importNonExistOlder.errors.txt" << false;
349 QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false;
350 QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false;
351 QTest::newRow("importFile") << "importFile.qml" << "importFile.errors.txt" << false;
353 QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false;
354 QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false;
355 QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false;
356 QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false;
358 QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
360 QTest::newRow("property.1") << "property.1.qml" << "property.1.errors.txt" << false;
361 QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
362 QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
363 QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
364 QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
365 QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
367 QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
369 QTest::newRow("Component.1") << "component.1.qml" << "component.1.errors.txt" << false;
370 QTest::newRow("Component.2") << "component.2.qml" << "component.2.errors.txt" << false;
371 QTest::newRow("Component.3") << "component.3.qml" << "component.3.errors.txt" << false;
372 QTest::newRow("Component.4") << "component.4.qml" << "component.4.errors.txt" << false;
373 QTest::newRow("Component.5") << "component.5.qml" << "component.5.errors.txt" << false;
374 QTest::newRow("Component.6") << "component.6.qml" << "component.6.errors.txt" << false;
375 QTest::newRow("Component.7") << "component.7.qml" << "component.7.errors.txt" << false;
376 QTest::newRow("Component.8") << "component.8.qml" << "component.8.errors.txt" << false;
377 QTest::newRow("Component.9") << "component.9.qml" << "component.9.errors.txt" << false;
379 QTest::newRow("MultiSet.1") << "multiSet.1.qml" << "multiSet.1.errors.txt" << false;
380 QTest::newRow("MultiSet.2") << "multiSet.2.qml" << "multiSet.2.errors.txt" << false;
381 QTest::newRow("MultiSet.3") << "multiSet.3.qml" << "multiSet.3.errors.txt" << false;
382 QTest::newRow("MultiSet.4") << "multiSet.4.qml" << "multiSet.4.errors.txt" << false;
383 QTest::newRow("MultiSet.5") << "multiSet.5.qml" << "multiSet.5.errors.txt" << false;
384 QTest::newRow("MultiSet.6") << "multiSet.6.qml" << "multiSet.6.errors.txt" << false;
385 QTest::newRow("MultiSet.7") << "multiSet.7.qml" << "multiSet.7.errors.txt" << false;
386 QTest::newRow("MultiSet.8") << "multiSet.8.qml" << "multiSet.8.errors.txt" << false;
387 QTest::newRow("MultiSet.9") << "multiSet.9.qml" << "multiSet.9.errors.txt" << false;
388 QTest::newRow("MultiSet.10") << "multiSet.10.qml" << "multiSet.10.errors.txt" << false;
389 QTest::newRow("MultiSet.11") << "multiSet.11.qml" << "multiSet.11.errors.txt" << false;
391 QTest::newRow("dynamicMeta.1") << "dynamicMeta.1.qml" << "dynamicMeta.1.errors.txt" << false;
392 QTest::newRow("dynamicMeta.2") << "dynamicMeta.2.qml" << "dynamicMeta.2.errors.txt" << false;
393 QTest::newRow("dynamicMeta.3") << "dynamicMeta.3.qml" << "dynamicMeta.3.errors.txt" << false;
394 QTest::newRow("dynamicMeta.4") << "dynamicMeta.4.qml" << "dynamicMeta.4.errors.txt" << false;
395 QTest::newRow("dynamicMeta.5") << "dynamicMeta.5.qml" << "dynamicMeta.5.errors.txt" << false;
397 QTest::newRow("invalidAlias.1") << "invalidAlias.1.qml" << "invalidAlias.1.errors.txt" << false;
398 QTest::newRow("invalidAlias.2") << "invalidAlias.2.qml" << "invalidAlias.2.errors.txt" << false;
399 QTest::newRow("invalidAlias.3") << "invalidAlias.3.qml" << "invalidAlias.3.errors.txt" << false;
400 QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false;
401 QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
402 QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
403 QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false;
404 QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
405 QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
406 QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
408 QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
409 QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
410 QTest::newRow("invalidAttachedProperty.3") << "invalidAttachedProperty.3.qml" << "invalidAttachedProperty.3.errors.txt" << false;
411 QTest::newRow("invalidAttachedProperty.4") << "invalidAttachedProperty.4.qml" << "invalidAttachedProperty.4.errors.txt" << false;
412 QTest::newRow("invalidAttachedProperty.5") << "invalidAttachedProperty.5.qml" << "invalidAttachedProperty.5.errors.txt" << false;
413 QTest::newRow("invalidAttachedProperty.6") << "invalidAttachedProperty.6.qml" << "invalidAttachedProperty.6.errors.txt" << false;
414 QTest::newRow("invalidAttachedProperty.7") << "invalidAttachedProperty.7.qml" << "invalidAttachedProperty.7.errors.txt" << false;
415 QTest::newRow("invalidAttachedProperty.8") << "invalidAttachedProperty.8.qml" << "invalidAttachedProperty.8.errors.txt" << false;
416 QTest::newRow("invalidAttachedProperty.9") << "invalidAttachedProperty.9.qml" << "invalidAttachedProperty.9.errors.txt" << false;
417 QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false;
418 QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false;
419 QTest::newRow("invalidAttachedProperty.12") << "invalidAttachedProperty.12.qml" << "invalidAttachedProperty.12.errors.txt" << false;
420 QTest::newRow("invalidAttachedProperty.13") << "invalidAttachedProperty.13.qml" << "invalidAttachedProperty.13.errors.txt" << false;
422 QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
423 QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
425 QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false;
426 QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false;
427 QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false;
428 QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false;
429 QTest::newRow("objectValueTypeProperty") << "objectValueTypeProperty.qml" << "objectValueTypeProperty.errors.txt" << false;
430 QTest::newRow("enumTypes") << "enumTypes.qml" << "enumTypes.errors.txt" << false;
431 QTest::newRow("noCreation") << "noCreation.qml" << "noCreation.errors.txt" << false;
432 QTest::newRow("destroyedSignal") << "destroyedSignal.qml" << "destroyedSignal.errors.txt" << false;
433 QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false;
434 QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false;
435 QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false;
436 QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false;
437 QTest::newRow("notAvailable") << "notAvailable.qml" << "notAvailable.errors.txt" << false;
438 QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
439 QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
440 QTest::newRow("incorrectCase") << "incorrectCase.qml"
441 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
442 << "incorrectCase.errors.insensitive.txt"
444 << "incorrectCase.errors.sensitive.txt"
448 QTest::newRow("metaobjectRevision.1") << "metaobjectRevision.1.qml" << "metaobjectRevision.1.errors.txt" << false;
449 QTest::newRow("metaobjectRevision.2") << "metaobjectRevision.2.qml" << "metaobjectRevision.2.errors.txt" << false;
450 QTest::newRow("metaobjectRevision.3") << "metaobjectRevision.3.qml" << "metaobjectRevision.3.errors.txt" << false;
452 QTest::newRow("invalidRoot.1") << "invalidRoot.1.qml" << "invalidRoot.1.errors.txt" << false;
453 QTest::newRow("invalidRoot.2") << "invalidRoot.2.qml" << "invalidRoot.2.errors.txt" << false;
454 QTest::newRow("invalidRoot.3") << "invalidRoot.3.qml" << "invalidRoot.3.errors.txt" << false;
455 QTest::newRow("invalidRoot.4") << "invalidRoot.4.qml" << "invalidRoot.4.errors.txt" << false;
457 QTest::newRow("invalidTypeName.1") << "invalidTypeName.1.qml" << "invalidTypeName.1.errors.txt" << false;
458 QTest::newRow("invalidTypeName.2") << "invalidTypeName.2.qml" << "invalidTypeName.2.errors.txt" << false;
459 QTest::newRow("invalidTypeName.3") << "invalidTypeName.3.qml" << "invalidTypeName.3.errors.txt" << false;
460 QTest::newRow("invalidTypeName.4") << "invalidTypeName.4.qml" << "invalidTypeName.4.errors.txt" << false;
462 QTest::newRow("Major version isolation") << "majorVersionIsolation.qml" << "majorVersionIsolation.errors.txt" << false;
466 void tst_qdeclarativelanguage::errors()
468 QFETCH(QString, file);
469 QFETCH(QString, errorFile);
470 QFETCH(bool, create);
472 QDeclarativeComponent component(&engine, TEST_FILE(file));
475 QObject *object = component.create();
476 QVERIFY(object == 0);
479 VERIFY_ERRORS(errorFile.toLatin1().constData());
482 void tst_qdeclarativelanguage::simpleObject()
484 QDeclarativeComponent component(&engine, TEST_FILE("simpleObject.qml"));
486 QObject *object = component.create();
487 QVERIFY(object != 0);
490 void tst_qdeclarativelanguage::simpleContainer()
492 QDeclarativeComponent component(&engine, TEST_FILE("simpleContainer.qml"));
494 MyContainer *container= qobject_cast<MyContainer*>(component.create());
495 QVERIFY(container != 0);
496 QCOMPARE(container->getChildren()->count(),2);
499 void tst_qdeclarativelanguage::interfaceProperty()
501 QDeclarativeComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
503 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
504 QVERIFY(object != 0);
505 QVERIFY(object->interface());
506 QVERIFY(object->interface()->id == 913);
509 void tst_qdeclarativelanguage::interfaceQList()
511 QDeclarativeComponent component(&engine, TEST_FILE("interfaceQList.qml"));
513 MyContainer *container= qobject_cast<MyContainer*>(component.create());
514 QVERIFY(container != 0);
515 QVERIFY(container->getQListInterfaces()->count() == 2);
516 for(int ii = 0; ii < 2; ++ii)
517 QVERIFY(container->getQListInterfaces()->at(ii)->id == 913);
520 void tst_qdeclarativelanguage::assignObjectToSignal()
522 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
524 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
525 QVERIFY(object != 0);
526 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
527 emit object->basicSignal();
530 void tst_qdeclarativelanguage::assignObjectToVariant()
532 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
534 QObject *object = component.create();
535 QVERIFY(object != 0);
536 QVariant v = object->property("a");
537 QVERIFY(v.userType() == qMetaTypeId<QObject *>());
540 void tst_qdeclarativelanguage::assignLiteralSignalProperty()
542 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
544 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
545 QVERIFY(object != 0);
546 QCOMPARE(object->onLiteralSignal(), 10);
549 // Test is an external component can be loaded and assigned (to a qlist)
550 void tst_qdeclarativelanguage::assignQmlComponent()
552 QDeclarativeComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
554 MyContainer *object = qobject_cast<MyContainer *>(component.create());
555 QVERIFY(object != 0);
556 QVERIFY(object->getChildren()->count() == 1);
557 QObject *child = object->getChildren()->at(0);
558 QCOMPARE(child->property("x"), QVariant(10));
559 QCOMPARE(child->property("y"), QVariant(11));
562 // Test literal assignment to all the basic types
563 void tst_qdeclarativelanguage::assignBasicTypes()
565 QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
567 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
568 QVERIFY(object != 0);
569 QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
570 QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
571 QCOMPARE(object->stringProperty(), QString("Hello World!"));
572 QCOMPARE(object->uintProperty(), uint(10));
573 QCOMPARE(object->intProperty(), -19);
574 QCOMPARE((float)object->realProperty(), float(23.2));
575 QCOMPARE((float)object->doubleProperty(), float(-19.7));
576 QCOMPARE((float)object->floatProperty(), float(8.5));
577 QCOMPARE(object->colorProperty(), QColor("red"));
578 QCOMPARE(object->dateProperty(), QDate(1982, 11, 25));
579 QCOMPARE(object->timeProperty(), QTime(11, 11, 32));
580 QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1)));
581 QCOMPARE(object->pointProperty(), QPoint(99,13));
582 QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3));
583 QCOMPARE(object->sizeProperty(), QSize(99, 13));
584 QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2));
585 QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200));
586 QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99));
587 QCOMPARE(object->boolProperty(), true);
588 QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
589 QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2));
590 QCOMPARE(object->vector4Property(), QVector4D(10, 1, 2.2, 2.3));
592 encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
593 QCOMPARE(object->urlProperty(), component.url().resolved(encoded));
594 QVERIFY(object->objectProperty() != 0);
595 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
597 QCOMPARE(child->intProperty(), 8);
600 // Test edge case type assignments
601 void tst_qdeclarativelanguage::assignTypeExtremes()
603 QDeclarativeComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
605 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
606 QVERIFY(object != 0);
607 QCOMPARE(object->uintProperty(), 0xEE6B2800);
608 QCOMPARE(object->intProperty(), -0x77359400);
611 // Test that a composite type can assign to a property of its base type
612 void tst_qdeclarativelanguage::assignCompositeToType()
614 QDeclarativeComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
616 QObject *object = component.create();
617 QVERIFY(object != 0);
620 // Test that literals are stored correctly in variant properties
621 void tst_qdeclarativelanguage::assignLiteralToVariant()
623 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
625 QObject *object = component.create();
626 QVERIFY(object != 0);
628 QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
629 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
630 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
631 QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
632 QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
633 QCOMPARE(object->property("test6").userType(), (int)QVariant::PointF);
634 QCOMPARE(object->property("test7").userType(), (int)QVariant::SizeF);
635 QCOMPARE(object->property("test8").userType(), (int)QVariant::Vector3D);
636 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
637 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
638 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
639 QCOMPARE(object->property("test12").userType(), (int)QVariant::Vector4D);
641 QVERIFY(object->property("test1") == QVariant(1));
642 QVERIFY(object->property("test2") == QVariant((double)1.7));
643 QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!"))));
644 QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800)));
645 QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10)));
646 QVERIFY(object->property("test6") == QVariant(QPointF(10, 10)));
647 QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10)));
648 QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100)));
649 QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800"))));
650 QVERIFY(object->property("test10") == QVariant(bool(true)));
651 QVERIFY(object->property("test11") == QVariant(bool(false)));
652 QVERIFY(object->property("test12") == QVariant(QVector4D(100, 100, 100, 100)));
657 // Test that literals are stored correctly in "var" properties
658 // Note that behaviour differs from "variant" properties in that
659 // no conversion from "special strings" to QVariants is performed.
660 void tst_qdeclarativelanguage::assignLiteralToVar()
662 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVar.qml"));
664 QObject *object = component.create();
665 QVERIFY(object != 0);
667 QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
668 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
669 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
670 QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
671 QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
672 QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
673 QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
674 QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
675 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
676 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
677 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
678 QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
679 QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
680 QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
681 QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
682 QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
683 QCOMPARE(object->property("variantTest1Bound").userType(), (int)QMetaType::Int);
684 QCOMPARE(object->property("test1Bound").userType(), (int)QMetaType::Int);
686 QCOMPARE(object->property("test1"), QVariant(5));
687 QCOMPARE(object->property("test2"), QVariant((double)1.7));
688 QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
689 QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
690 QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
691 QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
692 QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
693 QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
694 QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
695 QCOMPARE(object->property("test10"), QVariant(bool(true)));
696 QCOMPARE(object->property("test11"), QVariant(bool(false)));
697 QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
698 QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
699 QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
700 QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
701 QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
702 QCOMPARE(object->property("variantTest1Bound"), QVariant(9));
703 QCOMPARE(object->property("test1Bound"), QVariant(11));
708 // Tests that custom parser types can be instantiated
709 void tst_qdeclarativelanguage::customParserTypes()
711 QDeclarativeComponent component(&engine, TEST_FILE("customParserTypes.qml"));
713 QObject *object = component.create();
714 QVERIFY(object != 0);
715 QVERIFY(object->property("count") == QVariant(2));
718 // Tests that the root item can be a custom component
719 void tst_qdeclarativelanguage::rootAsQmlComponent()
721 QDeclarativeComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
723 MyContainer *object = qobject_cast<MyContainer *>(component.create());
724 QVERIFY(object != 0);
725 QCOMPARE(object->property("x"), QVariant(11));
726 QCOMPARE(object->getChildren()->count(), 2);
729 // Tests that components can be specified inline
730 void tst_qdeclarativelanguage::inlineQmlComponents()
732 QDeclarativeComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
734 MyContainer *object = qobject_cast<MyContainer *>(component.create());
735 QVERIFY(object != 0);
736 QCOMPARE(object->getChildren()->count(), 1);
737 QDeclarativeComponent *comp = qobject_cast<QDeclarativeComponent *>(object->getChildren()->at(0));
739 MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
740 QVERIFY(compObject != 0);
741 QCOMPARE(compObject->value(), 11);
744 // Tests that types that have an id property have it set
745 void tst_qdeclarativelanguage::idProperty()
747 QDeclarativeComponent component(&engine, TEST_FILE("idProperty.qml"));
749 MyContainer *object = qobject_cast<MyContainer *>(component.create());
750 QVERIFY(object != 0);
751 QCOMPARE(object->getChildren()->count(), 1);
752 MyTypeObject *child =
753 qobject_cast<MyTypeObject *>(object->getChildren()->at(0));
755 QCOMPARE(child->id(), QString("myObjectId"));
756 QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
759 // Tests automatic connection to notify signals if "onBlahChanged" syntax is used
760 // even if the notify signal for "blah" is not called "blahChanged"
761 void tst_qdeclarativelanguage::autoNotifyConnection()
763 QDeclarativeComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
765 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
766 QVERIFY(object != 0);
767 QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
768 QVERIFY(prop.isValid());
770 QCOMPARE(prop.read(object), QVariant::fromValue(false));
771 object->setPropertyWithNotify(1);
772 QCOMPARE(prop.read(object), QVariant::fromValue(true));
775 // Tests that signals can be assigned to
776 void tst_qdeclarativelanguage::assignSignal()
778 QDeclarativeComponent component(&engine, TEST_FILE("assignSignal.qml"));
780 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
781 QVERIFY(object != 0);
782 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
783 emit object->basicSignal();
784 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)");
785 emit object->basicParameterizedSignal(9);
788 // Tests the creation and assignment of dynamic properties
789 void tst_qdeclarativelanguage::dynamicProperties()
791 QDeclarativeComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
793 QObject *object = component.create();
794 QVERIFY(object != 0);
795 QCOMPARE(object->property("intProperty"), QVariant(10));
796 QCOMPARE(object->property("boolProperty"), QVariant(false));
797 QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
798 QCOMPARE(object->property("realProperty"), QVariant((qreal)-19.9));
799 QCOMPARE(object->property("stringProperty"), QVariant("Hello World!"));
800 QCOMPARE(object->property("urlProperty"), QVariant(TEST_FILE("main.qml")));
801 QCOMPARE(object->property("colorProperty"), QVariant(QColor("red")));
802 QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2)));
803 QCOMPARE(object->property("varProperty"), QVariant("Hello World!"));
806 // Test that nested types can use dynamic properties
807 void tst_qdeclarativelanguage::dynamicPropertiesNested()
809 QDeclarativeComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
811 QObject *object = component.create();
812 QVERIFY(object != 0);
814 QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
815 QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
816 QCOMPARE(object->property("a").toInt(), 13); // New
817 QCOMPARE(object->property("b").toInt(), 12); // New
822 // Tests the creation and assignment to dynamic list properties
823 void tst_qdeclarativelanguage::listProperties()
825 QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml"));
827 QObject *object = component.create();
828 QVERIFY(object != 0);
830 QCOMPARE(object->property("test").toInt(), 2);
833 // Tests the creation and assignment of dynamic object properties
835 void tst_qdeclarativelanguage::dynamicObjectProperties()
838 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
840 QObject *object = component.create();
841 QVERIFY(object != 0);
843 QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
844 QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
847 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
848 QEXPECT_FAIL("", "QTBUG-10822", Abort);
850 QObject *object = component.create();
851 QVERIFY(object != 0);
853 QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
857 // Tests the declaration of dynamic signals and slots
858 void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
860 QTest::ignoreMessage(QtDebugMsg, "1921");
862 QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
864 QObject *object = component.create();
865 QVERIFY(object != 0);
866 QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
867 QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
868 QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1);
869 QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
871 QCOMPARE(object->property("test").toInt(), 0);
872 QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
873 QCOMPARE(object->property("test").toInt(), 10);
876 void tst_qdeclarativelanguage::simpleBindings()
878 QDeclarativeComponent component(&engine, TEST_FILE("simpleBindings.qml"));
880 QObject *object = component.create();
881 QVERIFY(object != 0);
882 QCOMPARE(object->property("value1"), QVariant(10));
883 QCOMPARE(object->property("value2"), QVariant(10));
884 QCOMPARE(object->property("value3"), QVariant(21));
885 QCOMPARE(object->property("value4"), QVariant(10));
886 QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
889 void tst_qdeclarativelanguage::autoComponentCreation()
891 QDeclarativeComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
893 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
894 QVERIFY(object != 0);
895 QVERIFY(object->componentProperty() != 0);
896 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
898 QCOMPARE(child->realProperty(), qreal(9));
901 void tst_qdeclarativelanguage::propertyValueSource()
904 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
906 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
907 QVERIFY(object != 0);
909 QList<QObject *> valueSources;
910 QObjectList allChildren = object->findChildren<QObject*>();
911 foreach (QObject *child, allChildren) {
912 if (qobject_cast<QDeclarativePropertyValueSource *>(child))
913 valueSources.append(child);
916 QCOMPARE(valueSources.count(), 1);
917 MyPropertyValueSource *valueSource =
918 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
919 QVERIFY(valueSource != 0);
920 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
921 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
925 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
927 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
928 QVERIFY(object != 0);
930 QList<QObject *> valueSources;
931 QObjectList allChildren = object->findChildren<QObject*>();
932 foreach (QObject *child, allChildren) {
933 if (qobject_cast<QDeclarativePropertyValueSource *>(child))
934 valueSources.append(child);
937 QCOMPARE(valueSources.count(), 1);
938 MyPropertyValueSource *valueSource =
939 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
940 QVERIFY(valueSource != 0);
941 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
942 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
946 void tst_qdeclarativelanguage::attachedProperties()
948 QDeclarativeComponent component(&engine, TEST_FILE("attachedProperties.qml"));
950 QObject *object = component.create();
951 QVERIFY(object != 0);
952 QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
953 QVERIFY(attached != 0);
954 QCOMPARE(attached->property("value"), QVariant(10));
955 QCOMPARE(attached->property("value2"), QVariant(13));
958 // Tests non-static object properties
959 void tst_qdeclarativelanguage::dynamicObjects()
961 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
963 QObject *object = component.create();
964 QVERIFY(object != 0);
967 // Tests the registration of custom variant string converters
968 void tst_qdeclarativelanguage::customVariantTypes()
970 QDeclarativeComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
972 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
973 QVERIFY(object != 0);
974 QCOMPARE(object->customType().a, 10);
977 void tst_qdeclarativelanguage::valueTypes()
979 QDeclarativeComponent component(&engine, TEST_FILE("valueTypes.qml"));
982 QString message = component.url().toString() + ":2:1: QML MyTypeObject: Binding loop detected for property \"rectProperty.width\"";
983 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
984 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
986 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
987 QVERIFY(object != 0);
990 QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
991 QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
992 QCOMPARE(object->intProperty(), 10);
994 QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
995 QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
996 QCOMPARE(object->intProperty(), 12);
1000 QDeclarativeProperty p(object, "rectProperty.x");
1001 QCOMPARE(p.read(), QVariant(12));
1003 QCOMPARE(p.read(), QVariant(13));
1005 quint32 r = QDeclarativePropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
1006 QDeclarativeProperty p2;
1007 QDeclarativePropertyPrivate::restore(p2, r, object);
1008 QCOMPARE(p2.read(), QVariant(13));
1012 void tst_qdeclarativelanguage::cppnamespace()
1015 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.qml"));
1017 QObject *object = component.create();
1018 QVERIFY(object != 0);
1023 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
1025 QObject *object = component.create();
1026 QVERIFY(object != 0);
1031 void tst_qdeclarativelanguage::aliasProperties()
1033 // Simple "int" alias
1035 QDeclarativeComponent component(&engine, TEST_FILE("alias.1.qml"));
1037 QObject *object = component.create();
1038 QVERIFY(object != 0);
1040 // Read through alias
1041 QCOMPARE(object->property("valueAlias").toInt(), 10);
1042 object->setProperty("value", QVariant(13));
1043 QCOMPARE(object->property("valueAlias").toInt(), 13);
1045 // Write through alias
1046 object->setProperty("valueAlias", QVariant(19));
1047 QCOMPARE(object->property("valueAlias").toInt(), 19);
1048 QCOMPARE(object->property("value").toInt(), 19);
1053 // Complex object alias
1055 QDeclarativeComponent component(&engine, TEST_FILE("alias.2.qml"));
1057 QObject *object = component.create();
1058 QVERIFY(object != 0);
1060 // Read through alias
1062 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1064 QCOMPARE(v->value(), 10);
1066 // Write through alias
1067 MyQmlObject *v2 = new MyQmlObject();
1068 v2->setParent(object);
1069 object->setProperty("aliasObject", qVariantFromValue(v2));
1071 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1080 QDeclarativeComponent component(&engine, TEST_FILE("alias.3.qml"));
1082 QObject *object = component.create();
1083 QVERIFY(object != 0);
1085 QCOMPARE(object->property("value").toInt(), 1892);
1086 QCOMPARE(object->property("value2").toInt(), 1892);
1088 object->setProperty("value", QVariant(1313));
1089 QCOMPARE(object->property("value").toInt(), 1313);
1090 QCOMPARE(object->property("value2").toInt(), 1313);
1092 object->setProperty("value2", QVariant(8080));
1093 QCOMPARE(object->property("value").toInt(), 8080);
1094 QCOMPARE(object->property("value2").toInt(), 8080);
1101 QDeclarativeComponent component(&engine, TEST_FILE("alias.4.qml"));
1103 QObject *object = component.create();
1104 QVERIFY(object != 0);
1106 QCOMPARE(object->property("enumAlias").toInt(), 1);
1113 QDeclarativeComponent component(&engine, TEST_FILE("alias.5.qml"));
1115 QObject *object = component.create();
1116 QVERIFY(object != 0);
1118 QVariant v = object->property("otherAlias");
1119 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1120 MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
1121 QCOMPARE(o->value(), 10);
1125 v = object->property("otherAlias");
1126 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1127 o = qvariant_cast<MyQmlObject*>(v);
1133 // Nested aliases - this used to cause a crash
1135 QDeclarativeComponent component(&engine, TEST_FILE("alias.6.qml"));
1137 QObject *object = component.create();
1138 QVERIFY(object != 0);
1140 QCOMPARE(object->property("a").toInt(), 1923);
1143 // Ptr Alias Cleanup - check that aliases to ptr types return 0
1144 // if the object aliased to is removed
1146 QDeclarativeComponent component(&engine, TEST_FILE("alias.7.qml"));
1149 QObject *object = component.create();
1150 QVERIFY(object != 0);
1152 QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
1153 QVERIFY(object1 != 0);
1154 QObject *object2 = qvariant_cast<QObject *>(object1->property("object"));
1155 QVERIFY(object2 != 0);
1157 QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
1158 QVERIFY(alias == object2);
1162 QObject *alias2 = object; // "Random" start value
1164 void *a[] = { &alias2, 0, &status };
1165 QMetaObject::metacall(object, QMetaObject::ReadProperty,
1166 object->metaObject()->indexOfProperty("aliasedObject"), a);
1167 QVERIFY(alias2 == 0);
1170 // Simple composite type
1172 QDeclarativeComponent component(&engine, TEST_FILE("alias.8.qml"));
1174 QObject *object = component.create();
1175 QVERIFY(object != 0);
1177 QCOMPARE(object->property("value").toInt(), 10);
1182 // Complex composite type
1184 QDeclarativeComponent component(&engine, TEST_FILE("alias.9.qml"));
1186 QObject *object = component.create();
1187 QVERIFY(object != 0);
1189 QCOMPARE(object->property("value").toInt(), 10);
1195 // Simple "int" alias
1197 QDeclarativeComponent component(&engine, TEST_FILE("alias.10.qml"));
1199 QObject *object = component.create();
1200 QVERIFY(object != 0);
1202 // Read through alias
1203 QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8));
1204 object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
1205 QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
1207 // Write through alias
1208 object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
1209 QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
1210 QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
1215 // Valuetype sub-alias
1217 QDeclarativeComponent component(&engine, TEST_FILE("alias.11.qml"));
1219 QObject *object = component.create();
1220 QVERIFY(object != 0);
1222 // Read through alias
1223 QCOMPARE(object->property("aliasProperty").toInt(), 19);
1224 object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
1225 QCOMPARE(object->property("aliasProperty").toInt(), 33);
1227 // Write through alias
1228 object->setProperty("aliasProperty", QVariant(4));
1229 QCOMPARE(object->property("aliasProperty").toInt(), 4);
1230 QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
1236 // QTBUG-13374 Test that alias properties and signals can coexist
1237 void tst_qdeclarativelanguage::aliasPropertiesAndSignals()
1239 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
1241 QObject *o = component.create();
1243 QCOMPARE(o->property("test").toBool(), true);
1247 // Test that the root element in a composite type can be a Component
1248 void tst_qdeclarativelanguage::componentCompositeType()
1250 QDeclarativeComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
1252 QObject *object = component.create();
1253 QVERIFY(object != 0);
1256 class TestType : public QObject {
1259 TestType(QObject *p=0) : QObject(p) {}
1262 class TestType2 : public QObject {
1265 TestType2(QObject *p=0) : QObject(p) {}
1268 void tst_qdeclarativelanguage::i18n_data()
1270 QTest::addColumn<QString>("file");
1271 QTest::addColumn<QString>("stringProperty");
1272 QTest::newRow("i18nStrings") << "i18nStrings.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245 (5 accented 'a' letters)");
1273 QTest::newRow("i18nDeclaredPropertyNames") << "i18nDeclaredPropertyNames.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 10");
1274 QTest::newRow("i18nDeclaredPropertyUse") << "i18nDeclaredPropertyUse.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 15");
1275 QTest::newRow("i18nScript") << "i18nScript.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 20");
1276 QTest::newRow("i18nType") << "i18nType.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 30");
1277 QTest::newRow("i18nNameSpace") << "i18nNameSpace.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 40");
1280 void tst_qdeclarativelanguage::i18n()
1282 QFETCH(QString, file);
1283 QFETCH(QString, stringProperty);
1284 QDeclarativeComponent component(&engine, TEST_FILE(file));
1286 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1287 QVERIFY(object != 0);
1288 QCOMPARE(object->stringProperty(), stringProperty);
1293 // Check that the Component::onCompleted attached property works
1294 void tst_qdeclarativelanguage::onCompleted()
1296 QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
1298 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1299 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1300 QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
1301 QObject *object = component.create();
1302 QVERIFY(object != 0);
1305 // Check that the Component::onDestruction attached property works
1306 void tst_qdeclarativelanguage::onDestruction()
1308 QDeclarativeComponent component(&engine, TEST_FILE("onDestruction.qml"));
1310 QObject *object = component.create();
1311 QVERIFY(object != 0);
1312 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1313 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1314 QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
1318 // Check that assignments to QDeclarativeScriptString properties work
1319 void tst_qdeclarativelanguage::scriptString()
1322 QDeclarativeComponent component(&engine, TEST_FILE("scriptString.qml"));
1325 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1326 QVERIFY(object != 0);
1327 QCOMPARE(object->scriptProperty().script(), QString("foo + bar"));
1328 QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object));
1329 QCOMPARE(object->scriptProperty().context(), qmlContext(object));
1331 QVERIFY(object->grouped() != 0);
1332 QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)"));
1333 QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object));
1334 QCOMPARE(object->grouped()->script().context(), qmlContext(object));
1338 QDeclarativeComponent component(&engine, TEST_FILE("scriptString2.qml"));
1341 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1342 QVERIFY(object != 0);
1343 QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
1347 QDeclarativeComponent component(&engine, TEST_FILE("scriptString3.qml"));
1350 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1351 QVERIFY(object != 0);
1352 QCOMPARE(object->scriptProperty().script(), QString("12.345"));
1356 QDeclarativeComponent component(&engine, TEST_FILE("scriptString4.qml"));
1359 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1360 QVERIFY(object != 0);
1361 QCOMPARE(object->scriptProperty().script(), QString("true"));
1365 // Check that default property assignments are correctly spliced into explicit
1366 // property assignments
1367 void tst_qdeclarativelanguage::defaultPropertyListOrder()
1369 QDeclarativeComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
1372 MyContainer *container = qobject_cast<MyContainer *>(component.create());
1373 QVERIFY(container != 0);
1375 QCOMPARE(container->getChildren()->count(), 6);
1376 QCOMPARE(container->getChildren()->at(0)->property("index"), QVariant(0));
1377 QCOMPARE(container->getChildren()->at(1)->property("index"), QVariant(1));
1378 QCOMPARE(container->getChildren()->at(2)->property("index"), QVariant(2));
1379 QCOMPARE(container->getChildren()->at(3)->property("index"), QVariant(3));
1380 QCOMPARE(container->getChildren()->at(4)->property("index"), QVariant(4));
1381 QCOMPARE(container->getChildren()->at(5)->property("index"), QVariant(5));
1384 void tst_qdeclarativelanguage::declaredPropertyValues()
1386 QDeclarativeComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
1390 void tst_qdeclarativelanguage::dontDoubleCallClassBegin()
1392 QDeclarativeComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml"));
1393 QObject *o = component.create();
1396 MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
1398 QCOMPARE(o2->classBeginCount(), 1);
1399 QCOMPARE(o2->componentCompleteCount(), 1);
1404 void tst_qdeclarativelanguage::reservedWords_data()
1406 QTest::addColumn<QByteArray>("word");
1408 QTest::newRow("abstract") << QByteArray("abstract");
1409 QTest::newRow("as") << QByteArray("as");
1410 QTest::newRow("boolean") << QByteArray("boolean");
1411 QTest::newRow("break") << QByteArray("break");
1412 QTest::newRow("byte") << QByteArray("byte");
1413 QTest::newRow("case") << QByteArray("case");
1414 QTest::newRow("catch") << QByteArray("catch");
1415 QTest::newRow("char") << QByteArray("char");
1416 QTest::newRow("class") << QByteArray("class");
1417 QTest::newRow("continue") << QByteArray("continue");
1418 QTest::newRow("const") << QByteArray("const");
1419 QTest::newRow("debugger") << QByteArray("debugger");
1420 QTest::newRow("default") << QByteArray("default");
1421 QTest::newRow("delete") << QByteArray("delete");
1422 QTest::newRow("do") << QByteArray("do");
1423 QTest::newRow("double") << QByteArray("double");
1424 QTest::newRow("else") << QByteArray("else");
1425 QTest::newRow("enum") << QByteArray("enum");
1426 QTest::newRow("export") << QByteArray("export");
1427 QTest::newRow("extends") << QByteArray("extends");
1428 QTest::newRow("false") << QByteArray("false");
1429 QTest::newRow("final") << QByteArray("final");
1430 QTest::newRow("finally") << QByteArray("finally");
1431 QTest::newRow("float") << QByteArray("float");
1432 QTest::newRow("for") << QByteArray("for");
1433 QTest::newRow("function") << QByteArray("function");
1434 QTest::newRow("goto") << QByteArray("goto");
1435 QTest::newRow("if") << QByteArray("if");
1436 QTest::newRow("implements") << QByteArray("implements");
1437 QTest::newRow("import") << QByteArray("import");
1438 QTest::newRow("in") << QByteArray("in");
1439 QTest::newRow("instanceof") << QByteArray("instanceof");
1440 QTest::newRow("int") << QByteArray("int");
1441 QTest::newRow("interface") << QByteArray("interface");
1442 QTest::newRow("long") << QByteArray("long");
1443 QTest::newRow("native") << QByteArray("native");
1444 QTest::newRow("new") << QByteArray("new");
1445 QTest::newRow("null") << QByteArray("null");
1446 QTest::newRow("package") << QByteArray("package");
1447 QTest::newRow("private") << QByteArray("private");
1448 QTest::newRow("protected") << QByteArray("protected");
1449 QTest::newRow("public") << QByteArray("public");
1450 QTest::newRow("return") << QByteArray("return");
1451 QTest::newRow("short") << QByteArray("short");
1452 QTest::newRow("static") << QByteArray("static");
1453 QTest::newRow("super") << QByteArray("super");
1454 QTest::newRow("switch") << QByteArray("switch");
1455 QTest::newRow("synchronized") << QByteArray("synchronized");
1456 QTest::newRow("this") << QByteArray("this");
1457 QTest::newRow("throw") << QByteArray("throw");
1458 QTest::newRow("throws") << QByteArray("throws");
1459 QTest::newRow("transient") << QByteArray("transient");
1460 QTest::newRow("true") << QByteArray("true");
1461 QTest::newRow("try") << QByteArray("try");
1462 QTest::newRow("typeof") << QByteArray("typeof");
1463 QTest::newRow("var") << QByteArray("var");
1464 QTest::newRow("void") << QByteArray("void");
1465 QTest::newRow("volatile") << QByteArray("volatile");
1466 QTest::newRow("while") << QByteArray("while");
1467 QTest::newRow("with") << QByteArray("with");
1470 void tst_qdeclarativelanguage::reservedWords()
1472 QFETCH(QByteArray, word);
1473 QDeclarativeComponent component(&engine);
1474 component.setData("import QtQuick 2.0\nQtObject { property string " + word + " }", QUrl());
1475 QCOMPARE(component.errorString(), QLatin1String(":2 Expected token `identifier'\n"));
1478 // Check that first child of qml is of given type. Empty type insists on error.
1479 void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, const QString& expectederror)
1481 QDeclarativeComponent component(&engine);
1482 component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
1484 QTRY_VERIFY(!component.isLoading());
1486 if (type.isEmpty()) {
1487 QVERIFY(component.isError());
1488 QString actualerror;
1489 foreach (const QDeclarativeError e, component.errors()) {
1490 if (!actualerror.isEmpty())
1491 actualerror.append("; ");
1492 actualerror.append(e.description());
1494 QCOMPARE(actualerror,expectederror);
1497 QObject *object = component.create();
1498 QVERIFY(object != 0);
1499 QCOMPARE(QString(object->metaObject()->className()), type);
1505 void tst_qdeclarativelanguage::inlineAssignmentsOverrideBindings()
1507 QDeclarativeComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml"));
1509 QObject *o = component.create();
1511 QCOMPARE(o->property("test").toInt(), 11);
1516 void tst_qdeclarativelanguage::nestedComponentRoots()
1518 QDeclarativeComponent component(&engine, TEST_FILE("nestedComponentRoots.qml"));
1521 // Import tests (QT-558)
1522 void tst_qdeclarativelanguage::importsBuiltin_data()
1526 QTest::addColumn<QString>("qml");
1527 QTest::addColumn<QString>("type");
1528 QTest::addColumn<QString>("error");
1531 QTest::newRow("missing import")
1534 << "Test is not a type";
1535 QTest::newRow("not in version 0.0")
1536 << "import com.nokia.Test 0.0\n"
1539 << "Test is not a type";
1540 QTest::newRow("version not installed")
1541 << "import com.nokia.Test 99.0\n"
1544 << "module \"com.nokia.Test\" version 99.0 is not installed";
1545 QTest::newRow("in version 0.0")
1546 << "import com.nokia.Test 0.0\n"
1550 QTest::newRow("qualified in version 0.0")
1551 << "import com.nokia.Test 0.0 as T\n"
1555 QTest::newRow("in version 1.0")
1556 << "import com.nokia.Test 1.0\n"
1560 QTest::newRow("qualified wrong")
1561 << "import com.nokia.Test 1.0 as T\n" // QT-610
1564 << "Test is not a type";
1565 QTest::newRow("qualified right")
1566 << "import com.nokia.Test 1.0 as T\n"
1570 QTest::newRow("qualified right but not in version 0.0")
1571 << "import com.nokia.Test 0.0 as T\n"
1574 << "T.Test is not a type";
1575 QTest::newRow("in version 1.1")
1576 << "import com.nokia.Test 1.1\n"
1580 QTest::newRow("in version 1.3")
1581 << "import com.nokia.Test 1.3\n"
1585 QTest::newRow("in version 1.5")
1586 << "import com.nokia.Test 1.5\n"
1590 QTest::newRow("changed in version 1.8")
1591 << "import com.nokia.Test 1.8\n"
1595 QTest::newRow("in version 1.12")
1596 << "import com.nokia.Test 1.12\n"
1600 QTest::newRow("old in version 1.9")
1601 << "import com.nokia.Test 1.9\n"
1605 QTest::newRow("old in version 1.11")
1606 << "import com.nokia.Test 1.11\n"
1610 QTest::newRow("multiversion 1")
1611 << "import com.nokia.Test 1.11\n"
1612 "import com.nokia.Test 1.12\n"
1614 << (!qmlCheckTypes()?"TestType2":"")
1615 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1616 QTest::newRow("multiversion 2")
1617 << "import com.nokia.Test 1.11\n"
1618 "import com.nokia.Test 1.12\n"
1620 << (!qmlCheckTypes()?"TestType":"")
1621 << (!qmlCheckTypes()?"":"OldTest is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1622 QTest::newRow("qualified multiversion 3")
1623 << "import com.nokia.Test 1.0 as T0\n"
1624 "import com.nokia.Test 1.8 as T8\n"
1628 QTest::newRow("qualified multiversion 4")
1629 << "import com.nokia.Test 1.0 as T0\n"
1630 "import com.nokia.Test 1.8 as T8\n"
1636 void tst_qdeclarativelanguage::importsBuiltin()
1638 QFETCH(QString, qml);
1639 QFETCH(QString, type);
1640 QFETCH(QString, error);
1641 testType(qml,type,error);
1644 void tst_qdeclarativelanguage::importsLocal_data()
1646 QTest::addColumn<QString>("qml");
1647 QTest::addColumn<QString>("type");
1648 QTest::addColumn<QString>("error");
1651 QTest::newRow("local import")
1652 << "import \"subdir\"\n" // QT-613
1654 << "QQuickRectangle"
1656 QTest::newRow("local import second")
1657 << "import QtQuick 2.0\nimport \"subdir\"\n"
1659 << "QQuickRectangle"
1661 QTest::newRow("local import subsubdir")
1662 << "import QtQuick 2.0\nimport \"subdir/subsubdir\"\n"
1664 << "QQuickRectangle"
1666 QTest::newRow("local import QTBUG-7721 A")
1667 << "subdir.Test {}" // no longer allowed (QTBUG-7721)
1669 << "subdir.Test - subdir is not a namespace";
1670 QTest::newRow("local import QTBUG-7721 B")
1671 << "import \"subdir\" as X\n"
1672 "X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
1674 << "X.subsubdir.SubTest - nested namespaces not allowed";
1675 QTest::newRow("local import as")
1676 << "import \"subdir\" as T\n"
1678 << "QQuickRectangle"
1680 QTest::newRow("wrong local import as")
1681 << "import \"subdir\" as T\n"
1684 << "Test is not a type";
1685 QTest::newRow("library precedence over local import")
1686 << "import \"subdir\"\n"
1687 "import com.nokia.Test 1.0\n"
1689 << (!qmlCheckTypes()?"TestType":"")
1690 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test and in subdir");
1693 void tst_qdeclarativelanguage::importsLocal()
1695 QFETCH(QString, qml);
1696 QFETCH(QString, type);
1697 QFETCH(QString, error);
1698 testType(qml,type,error);
1701 void tst_qdeclarativelanguage::basicRemote_data()
1703 QTest::addColumn<QUrl>("url");
1704 QTest::addColumn<QString>("type");
1705 QTest::addColumn<QString>("error");
1707 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage/";
1709 QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
1710 QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << "";
1711 QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
1714 void tst_qdeclarativelanguage::basicRemote()
1717 QFETCH(QString, type);
1718 QFETCH(QString, error);
1720 TestHTTPServer server(14447);
1721 server.serveDirectory(testdata());
1723 QDeclarativeComponent component(&engine, url);
1725 QTRY_VERIFY(!component.isLoading());
1727 if (error.isEmpty()) {
1728 if (component.isError())
1729 qDebug() << component.errors();
1730 QVERIFY(!component.isError());
1732 QVERIFY(component.isError());
1736 void tst_qdeclarativelanguage::importsRemote_data()
1738 QTest::addColumn<QString>("qml");
1739 QTest::addColumn<QString>("type");
1740 QTest::addColumn<QString>("error");
1742 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage";
1744 QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QQuickRectangle"
1746 QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QQuickText"
1748 QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QQuickImage"
1750 QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
1751 << "WrongTestLocal is not a type";
1752 QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
1753 << "LocalInternal is not a type";
1754 QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""
1755 << "UndeclaredLocal is not a type";
1758 void tst_qdeclarativelanguage::importsRemote()
1760 QFETCH(QString, qml);
1761 QFETCH(QString, type);
1762 QFETCH(QString, error);
1764 TestHTTPServer server(14447);
1765 server.serveDirectory(testdata());
1767 testType(qml,type,error);
1770 void tst_qdeclarativelanguage::importsInstalled_data()
1774 QTest::addColumn<QString>("qml");
1775 QTest::addColumn<QString>("type");
1776 QTest::addColumn<QString>("error");
1779 QTest::newRow("installed import 0")
1780 << "import com.nokia.installedtest0 0.0\n"
1781 "InstalledTestTP {}"
1782 << "QQuickRectangle"
1784 QTest::newRow("installed import 0 as TP")
1785 << "import com.nokia.installedtest0 0.0 as TP\n"
1786 "TP.InstalledTestTP {}"
1787 << "QQuickRectangle"
1789 QTest::newRow("installed import 1")
1790 << "import com.nokia.installedtest 1.0\n"
1792 << "QQuickRectangle"
1794 QTest::newRow("installed import 2")
1795 << "import com.nokia.installedtest 1.3\n"
1797 << "QQuickRectangle"
1799 QTest::newRow("installed import 3")
1800 << "import com.nokia.installedtest 1.4\n"
1804 QTest::newRow("installed import minor version not available") // QTBUG-11936
1805 << "import com.nokia.installedtest 0.1\n"
1808 << "module \"com.nokia.installedtest\" version 0.1 is not installed";
1809 QTest::newRow("installed import minor version not available") // QTBUG-9627
1810 << "import com.nokia.installedtest 1.10\n"
1813 << "module \"com.nokia.installedtest\" version 1.10 is not installed";
1814 QTest::newRow("installed import major version not available") // QTBUG-9627
1815 << "import com.nokia.installedtest 9.0\n"
1818 << "module \"com.nokia.installedtest\" version 9.0 is not installed";
1819 QTest::newRow("installed import visibility") // QT-614
1820 << "import com.nokia.installedtest 1.4\n"
1823 << "PrivateType is not a type";
1826 void tst_qdeclarativelanguage::importsInstalled()
1828 QFETCH(QString, qml);
1829 QFETCH(QString, type);
1830 QFETCH(QString, error);
1831 testType(qml,type,error);
1835 void tst_qdeclarativelanguage::importsOrder_data()
1837 QTest::addColumn<QString>("qml");
1838 QTest::addColumn<QString>("type");
1839 QTest::addColumn<QString>("error");
1841 QTest::newRow("double import") <<
1842 "import com.nokia.installedtest 1.4\n"
1843 "import com.nokia.installedtest 1.4\n"
1845 << (!qmlCheckTypes()?"QQuickText":"")
1846 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.4");
1847 QTest::newRow("installed import overrides 1") <<
1848 "import com.nokia.installedtest 1.0\n"
1849 "import com.nokia.installedtest 1.4\n"
1851 << (!qmlCheckTypes()?"QQuickText":"")
1852 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1853 QTest::newRow("installed import overrides 2") <<
1854 "import com.nokia.installedtest 1.4\n"
1855 "import com.nokia.installedtest 1.0\n"
1857 << (!qmlCheckTypes()?"QQuickRectangle":"")
1858 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1859 QTest::newRow("installed import re-overrides 1") <<
1860 "import com.nokia.installedtest 1.4\n"
1861 "import com.nokia.installedtest 1.0\n"
1862 "import com.nokia.installedtest 1.4\n"
1864 << (!qmlCheckTypes()?"QQuickText":"")
1865 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1866 QTest::newRow("installed import re-overrides 2") <<
1867 "import com.nokia.installedtest 1.4\n"
1868 "import com.nokia.installedtest 1.0\n"
1869 "import com.nokia.installedtest 1.4\n"
1870 "import com.nokia.installedtest 1.0\n"
1872 << (!qmlCheckTypes()?"QQuickRectangle":"")
1873 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1875 QTest::newRow("installed import versus builtin 1") <<
1876 "import com.nokia.installedtest 1.5\n"
1877 "import QtQuick 2.0\n"
1879 << (!qmlCheckTypes()?"QQuickRectangle":"")
1880 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in Qt and in lib/com/nokia/installedtest");
1881 QTest::newRow("installed import versus builtin 2") <<
1882 "import QtQuick 2.0\n"
1883 "import com.nokia.installedtest 1.5\n"
1885 << (!qmlCheckTypes()?"QQuickText":"")
1886 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest and in Qt");
1887 QTest::newRow("namespaces cannot be overridden by types 1") <<
1888 "import QtQuick 2.0 as Rectangle\n"
1889 "import com.nokia.installedtest 1.5\n"
1892 << "Namespace Rectangle cannot be used as a type";
1893 QTest::newRow("namespaces cannot be overridden by types 2") <<
1894 "import QtQuick 2.0 as Rectangle\n"
1895 "import com.nokia.installedtest 1.5\n"
1896 "Rectangle.Image {}"
1899 QTest::newRow("local last 1") <<
1903 QTest::newRow("local last 2") <<
1904 "import com.nokia.installedtest 1.0\n"
1906 << (!qmlCheckTypes()?"QQuickRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
1907 << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest and in local directory");
1910 void tst_qdeclarativelanguage::importsOrder()
1912 QFETCH(QString, qml);
1913 QFETCH(QString, type);
1914 QFETCH(QString, error);
1915 testType(qml,type,error);
1918 void tst_qdeclarativelanguage::importIncorrectCase()
1920 QDeclarativeComponent component(&engine, TEST_FILE("importIncorrectCase.qml"));
1922 QList<QDeclarativeError> errors = component.errors();
1923 QCOMPARE(errors.count(), 1);
1925 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1926 QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + testdata("lib/com/Nokia/installedtest/qmldir") + QLatin1String("\"");
1928 QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
1931 QCOMPARE(errors.at(0).description(), expectedError);
1934 void tst_qdeclarativelanguage::importJs_data()
1936 QTest::addColumn<QString>("file");
1937 QTest::addColumn<QString>("errorFile");
1938 QTest::addColumn<bool>("performTest");
1940 QTest::newRow("defaultVersion")
1942 << "importJs.1.errors.txt"
1945 QTest::newRow("specifiedVersion")
1947 << "importJs.2.errors.txt"
1950 QTest::newRow("excludeExcessiveVersion")
1952 << "importJs.3.errors.txt"
1955 QTest::newRow("includeAppropriateVersion")
1957 << "importJs.4.errors.txt"
1960 QTest::newRow("noDefaultVersion")
1962 << "importJs.5.errors.txt"
1965 QTest::newRow("repeatImportFails")
1967 << "importJs.6.errors.txt"
1970 QTest::newRow("multipleVersionImportFails")
1972 << "importJs.7.errors.txt"
1975 QTest::newRow("namespacedImport")
1977 << "importJs.8.errors.txt"
1980 QTest::newRow("namespacedVersionedImport")
1982 << "importJs.9.errors.txt"
1985 QTest::newRow("namespacedRepeatImport")
1986 << "importJs.10.qml"
1987 << "importJs.10.errors.txt"
1991 void tst_qdeclarativelanguage::importJs()
1993 QFETCH(QString, file);
1994 QFETCH(QString, errorFile);
1995 QFETCH(bool, performTest);
1997 QDeclarativeComponent component(&engine, TEST_FILE(file));
2000 DETERMINE_ERRORS(errorFile.toLatin1().constData(),expected,actual);
2001 QCOMPARE(expected.size(), actual.size());
2002 for (int i = 0; i < expected.size(); ++i)
2004 size_t compareLen = std::min(expected.at(i).length(), actual.at(i).length());
2005 QCOMPARE(expected.at(i).left(compareLen), actual.at(i).left(compareLen));
2010 QObject *object = component.create();
2011 QVERIFY(object != 0);
2012 QCOMPARE(object->property("test").toBool(),true);
2017 void tst_qdeclarativelanguage::qmlAttachedPropertiesObjectMethod()
2021 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
2022 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
2025 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
2027 QObject *object = component.create();
2028 QVERIFY(object != 0);
2030 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
2031 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
2035 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
2037 QObject *object = component.create();
2038 QVERIFY(object != 0);
2040 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
2041 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
2045 void tst_qdeclarativelanguage::crash1()
2047 QDeclarativeComponent component(&engine);
2048 component.setData("import QtQuick 2.0\nComponent {}", QUrl());
2051 void tst_qdeclarativelanguage::crash2()
2053 QDeclarativeComponent component(&engine, TEST_FILE("crash2.qml"));
2057 void tst_qdeclarativelanguage::customOnProperty()
2059 QDeclarativeComponent component(&engine, TEST_FILE("customOnProperty.qml"));
2062 QObject *object = component.create();
2063 QVERIFY(object != 0);
2065 QCOMPARE(object->property("on").toInt(), 10);
2071 void tst_qdeclarativelanguage::variantNotify()
2073 QDeclarativeComponent component(&engine, TEST_FILE("variantNotify.qml"));
2076 QObject *object = component.create();
2077 QVERIFY(object != 0);
2079 QCOMPARE(object->property("notifyCount").toInt(), 1);
2084 void tst_qdeclarativelanguage::revisions()
2087 QDeclarativeComponent component(&engine, TEST_FILE("revisions11.qml"));
2090 MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
2091 QVERIFY(object != 0);
2093 QCOMPARE(object->prop2(), 10.0);
2098 QDeclarativeEngine myEngine;
2099 QDeclarativeComponent component(&myEngine, TEST_FILE("revisionssub11.qml"));
2102 MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
2103 QVERIFY(object != 0);
2105 QCOMPARE(object->prop1(), 10.0);
2106 QCOMPARE(object->prop2(), 10.0);
2107 QCOMPARE(object->prop3(), 10.0);
2108 QCOMPARE(object->prop4(), 10.0);
2113 QDeclarativeComponent component(&engine, TEST_FILE("versionedbase.qml"));
2115 MySubclass *object = qobject_cast<MySubclass*>(component.create());
2116 QVERIFY(object != 0);
2118 QCOMPARE(object->prop1(), 10.0);
2119 QCOMPARE(object->prop2(), 10.0);
2125 void tst_qdeclarativelanguage::revisionOverloads()
2128 QDeclarativeComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml"));
2132 QDeclarativeComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml"));
2133 QEXPECT_FAIL("", "QTBUG-13849", Abort);
2135 VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt");
2139 void tst_qdeclarativelanguage::initTestCase()
2141 QString testdataDir = QFileInfo(QFINDTESTDATA("data")).absolutePath();
2142 QVERIFY2(QDir::setCurrent(testdataDir), qPrintable("Could not chdir to " + testdataDir));
2146 // Registering the TestType class in other modules should have no adverse effects
2147 qmlRegisterType<TestType>("com.nokia.TestPre", 1, 0, "Test");
2149 qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP");
2150 qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test");
2151 qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test");
2152 qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test");
2153 qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest");
2154 qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test");
2156 // Registering the TestType class in other modules should have no adverse effects
2157 qmlRegisterType<TestType>("com.nokia.TestPost", 1, 0, "Test");
2159 // Create locale-specific file
2160 // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit
2161 // For iso8859-1 locale, this will just be data/I18nType?????.qml where ????? is 5 8-bit characters
2162 // For utf-8 locale, this will be data/I18nType??????????.qml where ?????????? is 5 8-bit characters, UTF-8 encoded
2163 QFile in(TEST_FILE(QLatin1String("I18nType30.qml")).toLocalFile());
2164 QVERIFY2(in.open(QIODevice::ReadOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(in.fileName(), in.errorString())));
2165 QFile out(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile());
2166 QVERIFY2(out.open(QIODevice::WriteOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(out.fileName(), out.errorString())));
2167 out.write(in.readAll());
2170 void tst_qdeclarativelanguage::aliasPropertyChangeSignals()
2173 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.qml"));
2176 QObject *o = component.create();
2179 QCOMPARE(o->property("test").toBool(), true);
2184 // QTCREATORBUG-2769
2186 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.2.qml"));
2189 QObject *o = component.create();
2192 QCOMPARE(o->property("test").toBool(), true);
2198 // Tests property initializers
2199 void tst_qdeclarativelanguage::propertyInit()
2202 QDeclarativeComponent component(&engine, TEST_FILE("propertyInit.1.qml"));
2205 QObject *o = component.create();
2208 QCOMPARE(o->property("test").toInt(), 1);
2214 QDeclarativeComponent component(&engine, TEST_FILE("propertyInit.2.qml"));
2217 QObject *o = component.create();
2220 QCOMPARE(o->property("test").toInt(), 123);
2226 // Test that registration order doesn't break type availability
2228 void tst_qdeclarativelanguage::registrationOrder()
2230 QDeclarativeComponent component(&engine, TEST_FILE("registrationOrder.qml"));
2232 QObject *o = component.create();
2234 QVERIFY(o->metaObject() == &MyVersion2Class::staticMetaObject);
2238 void tst_qdeclarativelanguage::readonly()
2240 QDeclarativeComponent component(&engine, TEST_FILE("readonly.qml"));
2242 QObject *o = component.create();
2245 QCOMPARE(o->property("test1").toInt(), 10);
2246 QCOMPARE(o->property("test2").toInt(), 18);
2247 QCOMPARE(o->property("test3").toInt(), 13);
2249 o->setProperty("testData", 13);
2251 QCOMPARE(o->property("test1").toInt(), 10);
2252 QCOMPARE(o->property("test2").toInt(), 22);
2253 QCOMPARE(o->property("test3").toInt(), 13);
2255 o->setProperty("testData2", 2);
2257 QCOMPARE(o->property("test1").toInt(), 10);
2258 QCOMPARE(o->property("test2").toInt(), 22);
2259 QCOMPARE(o->property("test3").toInt(), 2);
2261 o->setProperty("test1", 11);
2262 o->setProperty("test2", 11);
2263 o->setProperty("test3", 11);
2265 QCOMPARE(o->property("test1").toInt(), 10);
2266 QCOMPARE(o->property("test2").toInt(), 22);
2267 QCOMPARE(o->property("test3").toInt(), 2);
2273 void tst_qdeclarativelanguage::remoteLoadCrash()
2275 TestHTTPServer server(14448);
2276 server.serveDirectory(testdata());
2278 QDeclarativeComponent component(&engine);
2279 component.setData("import QtQuick 1.0; Text {}", QUrl("http://127.0.0.1:14448/remoteLoadCrash.qml"));
2280 while (component.isLoading())
2281 QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
2283 QObject *o = component.create();
2287 QTEST_MAIN(tst_qdeclarativelanguage)
2289 #include "tst_qdeclarativelanguage.moc"