1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** 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())
65 Try to find it relative to the binary.
66 Note we are looking for a _directory_ which exists, but the _file_ itself need not exist,
67 to support the case of finding a path to a testdata file which doesn't exist yet (i.e.
68 a file we are about to create).
70 QFileInfo relative = QDir(QCoreApplication::applicationDirPath()).filePath(QLatin1String("data/") + name);
71 if (relative.dir().exists()) {
72 return relative.absoluteFilePath();
75 qWarning("requested testdata %s could not be found (looked at %s)",
77 qPrintable(relative.filePath())
80 // Chances are the calling test will now fail.
86 This test case covers QML language issues. This covers everything that does not
87 involve evaluating ECMAScript expressions and bindings.
89 Evaluation of expressions and bindings is covered in qmlecmascript
91 class tst_qdeclarativelanguage : public QObject
95 tst_qdeclarativelanguage() {
96 QDeclarativeMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter);
97 engine.addImportPath(testdata("lib"));
102 void cleanupTestCase();
107 void insertedSemicolon_data();
108 void insertedSemicolon();
111 void simpleContainer();
112 void interfaceProperty();
113 void interfaceQList();
114 void assignObjectToSignal();
115 void assignObjectToVariant();
116 void assignLiteralSignalProperty();
117 void assignQmlComponent();
118 void assignBasicTypes();
119 void assignTypeExtremes();
120 void assignCompositeToType();
121 void assignLiteralToVariant();
122 void assignLiteralToVar();
123 void customParserTypes();
124 void rootAsQmlComponent();
125 void inlineQmlComponents();
127 void autoNotifyConnection();
129 void dynamicProperties();
130 void dynamicPropertiesNested();
131 void listProperties();
132 void dynamicObjectProperties();
133 void dynamicSignalsAndSlots();
134 void simpleBindings();
135 void autoComponentCreation();
136 void propertyValueSource();
137 void attachedProperties();
138 void dynamicObjects();
139 void customVariantTypes();
142 void aliasProperties();
143 void aliasPropertiesAndSignals();
144 void aliasPropertyChangeSignals();
145 void componentCompositeType();
149 void onDestruction();
151 void defaultPropertyListOrder();
152 void declaredPropertyValues();
153 void dontDoubleCallClassBegin();
154 void reservedWords_data();
155 void reservedWords();
156 void inlineAssignmentsOverrideBindings();
157 void nestedComponentRoots();
158 void registrationOrder();
160 void basicRemote_data();
162 void importsBuiltin_data();
163 void importsBuiltin();
164 void importsLocal_data();
166 void importsRemote_data();
167 void importsRemote();
168 void importsInstalled_data();
169 void importsInstalled();
170 void importsOrder_data();
172 void importIncorrectCase();
174 void qmlAttachedPropertiesObjectMethod();
175 void customOnProperty();
176 void variantNotify();
179 void revisionOverloads();
182 void remoteLoadCrash();
184 // regression tests for crashes
189 QDeclarativeEngine engine;
190 void testType(const QString& qml, const QString& type, const QString& error);
193 #define VERIFY_ERRORS(errorfile) \
195 if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
196 qWarning() << "Unexpected Errors:" << component.errors(); \
197 QVERIFY(!component.isError()); \
198 QVERIFY(component.errors().isEmpty()); \
200 QFile file(testdata(QLatin1String(errorfile))); \
201 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
202 QByteArray data = file.readAll(); \
204 QList<QByteArray> expected = data.split('\n'); \
205 expected.removeAll(QByteArray("")); \
206 QList<QDeclarativeError> errors = component.errors(); \
207 QList<QByteArray> actual; \
208 for (int ii = 0; ii < errors.count(); ++ii) { \
209 const QDeclarativeError &error = errors.at(ii); \
210 QByteArray errorStr = QByteArray::number(error.line()) + ":" + \
211 QByteArray::number(error.column()) + ":" + \
212 error.description().toUtf8(); \
213 actual << errorStr; \
215 if (qgetenv("DEBUG") != "" && expected != actual) \
216 qWarning() << "Expected:" << expected << "Actual:" << actual; \
217 if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
218 QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
219 QVERIFY(file.open(QIODevice::WriteOnly)); \
220 for (int ii = 0; ii < actual.count(); ++ii) { \
221 file.write(actual.at(ii)); file.write("\n"); \
225 QCOMPARE(expected, actual); \
229 inline QUrl TEST_FILE(const QString &filename)
231 return QUrl::fromLocalFile(testdata(filename));
234 inline QUrl TEST_FILE(const char *filename)
236 return TEST_FILE(QLatin1String(filename));
239 void tst_qdeclarativelanguage::cleanupTestCase()
241 QVERIFY(QFile::remove(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile()));
244 void tst_qdeclarativelanguage::insertedSemicolon_data()
246 QTest::addColumn<QString>("file");
247 QTest::addColumn<QString>("errorFile");
248 QTest::addColumn<bool>("create");
250 QTest::newRow("insertedSemicolon.1") << "insertedSemicolon.1.qml" << "insertedSemicolon.1.errors.txt" << false;
253 void tst_qdeclarativelanguage::insertedSemicolon()
255 QFETCH(QString, file);
256 QFETCH(QString, errorFile);
257 QFETCH(bool, create);
259 QDeclarativeComponent component(&engine, TEST_FILE(file));
262 QObject *object = component.create();
263 QVERIFY(object == 0);
266 VERIFY_ERRORS(errorFile.toLatin1().constData());
269 void tst_qdeclarativelanguage::errors_data()
271 QTest::addColumn<QString>("file");
272 QTest::addColumn<QString>("errorFile");
273 QTest::addColumn<bool>("create");
275 QTest::newRow("nonexistantProperty.1") << "nonexistantProperty.1.qml" << "nonexistantProperty.1.errors.txt" << false;
276 QTest::newRow("nonexistantProperty.2") << "nonexistantProperty.2.qml" << "nonexistantProperty.2.errors.txt" << false;
277 QTest::newRow("nonexistantProperty.3") << "nonexistantProperty.3.qml" << "nonexistantProperty.3.errors.txt" << false;
278 QTest::newRow("nonexistantProperty.4") << "nonexistantProperty.4.qml" << "nonexistantProperty.4.errors.txt" << false;
279 QTest::newRow("nonexistantProperty.5") << "nonexistantProperty.5.qml" << "nonexistantProperty.5.errors.txt" << false;
280 QTest::newRow("nonexistantProperty.6") << "nonexistantProperty.6.qml" << "nonexistantProperty.6.errors.txt" << false;
282 QTest::newRow("wrongType (string for int)") << "wrongType.1.qml" << "wrongType.1.errors.txt" << false;
283 QTest::newRow("wrongType (int for bool)") << "wrongType.2.qml" << "wrongType.2.errors.txt" << false;
284 QTest::newRow("wrongType (bad rect)") << "wrongType.3.qml" << "wrongType.3.errors.txt" << false;
286 QTest::newRow("wrongType (invalid enum)") << "wrongType.4.qml" << "wrongType.4.errors.txt" << false;
287 QTest::newRow("wrongType (int for uint)") << "wrongType.5.qml" << "wrongType.5.errors.txt" << false;
288 QTest::newRow("wrongType (string for real)") << "wrongType.6.qml" << "wrongType.6.errors.txt" << false;
289 QTest::newRow("wrongType (int for color)") << "wrongType.7.qml" << "wrongType.7.errors.txt" << false;
290 QTest::newRow("wrongType (int for date)") << "wrongType.8.qml" << "wrongType.8.errors.txt" << false;
291 QTest::newRow("wrongType (int for time)") << "wrongType.9.qml" << "wrongType.9.errors.txt" << false;
292 QTest::newRow("wrongType (int for datetime)") << "wrongType.10.qml" << "wrongType.10.errors.txt" << false;
293 QTest::newRow("wrongType (string for point)") << "wrongType.11.qml" << "wrongType.11.errors.txt" << false;
294 QTest::newRow("wrongType (color for size)") << "wrongType.12.qml" << "wrongType.12.errors.txt" << false;
295 QTest::newRow("wrongType (number string for int)") << "wrongType.13.qml" << "wrongType.13.errors.txt" << false;
296 QTest::newRow("wrongType (int for string)") << "wrongType.14.qml" << "wrongType.14.errors.txt" << false;
297 QTest::newRow("wrongType (int for url)") << "wrongType.15.qml" << "wrongType.15.errors.txt" << false;
298 QTest::newRow("wrongType (invalid object)") << "wrongType.16.qml" << "wrongType.16.errors.txt" << false;
299 QTest::newRow("wrongType (int for enum)") << "wrongType.17.qml" << "wrongType.17.errors.txt" << false;
301 QTest::newRow("readOnly.1") << "readOnly.1.qml" << "readOnly.1.errors.txt" << false;
302 QTest::newRow("readOnly.2") << "readOnly.2.qml" << "readOnly.2.errors.txt" << false;
303 QTest::newRow("readOnly.3") << "readOnly.3.qml" << "readOnly.3.errors.txt" << false;
304 QTest::newRow("readOnly.4") << "readOnly.4.qml" << "readOnly.4.errors.txt" << false;
305 QTest::newRow("readOnly.5") << "readOnly.5.qml" << "readOnly.5.errors.txt" << false;
307 QTest::newRow("listAssignment.1") << "listAssignment.1.qml" << "listAssignment.1.errors.txt" << false;
308 QTest::newRow("listAssignment.2") << "listAssignment.2.qml" << "listAssignment.2.errors.txt" << false;
309 QTest::newRow("listAssignment.3") << "listAssignment.3.qml" << "listAssignment.3.errors.txt" << false;
311 QTest::newRow("invalidID.1") << "invalidID.qml" << "invalidID.errors.txt" << false;
312 QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
313 QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
314 QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
315 QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
316 QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false;
317 QTest::newRow("invalidID.7") << "invalidID.7.qml" << "invalidID.7.errors.txt" << false;
318 QTest::newRow("invalidID.8") << "invalidID.8.qml" << "invalidID.8.errors.txt" << false;
319 QTest::newRow("invalidID.9") << "invalidID.9.qml" << "invalidID.9.errors.txt" << false;
321 QTest::newRow("scriptString.1") << "scriptString.1.qml" << "scriptString.1.errors.txt" << false;
322 QTest::newRow("scriptString.2") << "scriptString.2.qml" << "scriptString.2.errors.txt" << false;
324 QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
325 QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;
326 QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false;
327 QTest::newRow("duplicateIDs") << "duplicateIDs.qml" << "duplicateIDs.errors.txt" << false;
328 QTest::newRow("unregisteredObject") << "unregisteredObject.qml" << "unregisteredObject.errors.txt" << false;
329 QTest::newRow("empty") << "empty.qml" << "empty.errors.txt" << false;
330 QTest::newRow("missingObject") << "missingObject.qml" << "missingObject.errors.txt" << false;
331 QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
332 QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
333 QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
334 QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
336 QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
337 QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
338 QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
339 QTest::newRow("invalidGroupedProperty.4") << "invalidGroupedProperty.4.qml" << "invalidGroupedProperty.4.errors.txt" << false;
340 QTest::newRow("invalidGroupedProperty.5") << "invalidGroupedProperty.5.qml" << "invalidGroupedProperty.5.errors.txt" << false;
341 QTest::newRow("invalidGroupedProperty.6") << "invalidGroupedProperty.6.qml" << "invalidGroupedProperty.6.errors.txt" << false;
342 QTest::newRow("invalidGroupedProperty.7") << "invalidGroupedProperty.7.qml" << "invalidGroupedProperty.7.errors.txt" << true;
343 QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
344 QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
345 QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
347 QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
348 QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
349 QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false;
350 QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false;
351 QTest::newRow("importNonExistOlder (installed)") << "importNonExistOlder.qml" << "importNonExistOlder.errors.txt" << false;
352 QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false;
353 QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false;
354 QTest::newRow("importFile") << "importFile.qml" << "importFile.errors.txt" << false;
356 QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false;
357 QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false;
358 QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false;
359 QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false;
361 QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
363 QTest::newRow("property.1") << "property.1.qml" << "property.1.errors.txt" << false;
364 QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
365 QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
366 QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
367 QTest::newRow("property.5") << "property.5.qml" << "property.5.errors.txt" << false;
368 QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
369 QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
371 QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
373 QTest::newRow("Component.1") << "component.1.qml" << "component.1.errors.txt" << false;
374 QTest::newRow("Component.2") << "component.2.qml" << "component.2.errors.txt" << false;
375 QTest::newRow("Component.3") << "component.3.qml" << "component.3.errors.txt" << false;
376 QTest::newRow("Component.4") << "component.4.qml" << "component.4.errors.txt" << false;
377 QTest::newRow("Component.5") << "component.5.qml" << "component.5.errors.txt" << false;
378 QTest::newRow("Component.6") << "component.6.qml" << "component.6.errors.txt" << false;
379 QTest::newRow("Component.7") << "component.7.qml" << "component.7.errors.txt" << false;
380 QTest::newRow("Component.8") << "component.8.qml" << "component.8.errors.txt" << false;
381 QTest::newRow("Component.9") << "component.9.qml" << "component.9.errors.txt" << false;
383 QTest::newRow("MultiSet.1") << "multiSet.1.qml" << "multiSet.1.errors.txt" << false;
384 QTest::newRow("MultiSet.2") << "multiSet.2.qml" << "multiSet.2.errors.txt" << false;
385 QTest::newRow("MultiSet.3") << "multiSet.3.qml" << "multiSet.3.errors.txt" << false;
386 QTest::newRow("MultiSet.4") << "multiSet.4.qml" << "multiSet.4.errors.txt" << false;
387 QTest::newRow("MultiSet.5") << "multiSet.5.qml" << "multiSet.5.errors.txt" << false;
388 QTest::newRow("MultiSet.6") << "multiSet.6.qml" << "multiSet.6.errors.txt" << false;
389 QTest::newRow("MultiSet.7") << "multiSet.7.qml" << "multiSet.7.errors.txt" << false;
390 QTest::newRow("MultiSet.8") << "multiSet.8.qml" << "multiSet.8.errors.txt" << false;
391 QTest::newRow("MultiSet.9") << "multiSet.9.qml" << "multiSet.9.errors.txt" << false;
392 QTest::newRow("MultiSet.10") << "multiSet.10.qml" << "multiSet.10.errors.txt" << false;
393 QTest::newRow("MultiSet.11") << "multiSet.11.qml" << "multiSet.11.errors.txt" << false;
395 QTest::newRow("dynamicMeta.1") << "dynamicMeta.1.qml" << "dynamicMeta.1.errors.txt" << false;
396 QTest::newRow("dynamicMeta.2") << "dynamicMeta.2.qml" << "dynamicMeta.2.errors.txt" << false;
397 QTest::newRow("dynamicMeta.3") << "dynamicMeta.3.qml" << "dynamicMeta.3.errors.txt" << false;
398 QTest::newRow("dynamicMeta.4") << "dynamicMeta.4.qml" << "dynamicMeta.4.errors.txt" << false;
399 QTest::newRow("dynamicMeta.5") << "dynamicMeta.5.qml" << "dynamicMeta.5.errors.txt" << false;
401 QTest::newRow("invalidAlias.1") << "invalidAlias.1.qml" << "invalidAlias.1.errors.txt" << false;
402 QTest::newRow("invalidAlias.2") << "invalidAlias.2.qml" << "invalidAlias.2.errors.txt" << false;
403 QTest::newRow("invalidAlias.3") << "invalidAlias.3.qml" << "invalidAlias.3.errors.txt" << false;
404 QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false;
405 QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
406 QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
407 QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false;
408 QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
409 QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
410 QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
412 QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
413 QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
414 QTest::newRow("invalidAttachedProperty.3") << "invalidAttachedProperty.3.qml" << "invalidAttachedProperty.3.errors.txt" << false;
415 QTest::newRow("invalidAttachedProperty.4") << "invalidAttachedProperty.4.qml" << "invalidAttachedProperty.4.errors.txt" << false;
416 QTest::newRow("invalidAttachedProperty.5") << "invalidAttachedProperty.5.qml" << "invalidAttachedProperty.5.errors.txt" << false;
417 QTest::newRow("invalidAttachedProperty.6") << "invalidAttachedProperty.6.qml" << "invalidAttachedProperty.6.errors.txt" << false;
418 QTest::newRow("invalidAttachedProperty.7") << "invalidAttachedProperty.7.qml" << "invalidAttachedProperty.7.errors.txt" << false;
419 QTest::newRow("invalidAttachedProperty.8") << "invalidAttachedProperty.8.qml" << "invalidAttachedProperty.8.errors.txt" << false;
420 QTest::newRow("invalidAttachedProperty.9") << "invalidAttachedProperty.9.qml" << "invalidAttachedProperty.9.errors.txt" << false;
421 QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false;
422 QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false;
423 QTest::newRow("invalidAttachedProperty.12") << "invalidAttachedProperty.12.qml" << "invalidAttachedProperty.12.errors.txt" << false;
424 QTest::newRow("invalidAttachedProperty.13") << "invalidAttachedProperty.13.qml" << "invalidAttachedProperty.13.errors.txt" << false;
426 QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
427 QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
429 QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false;
430 QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false;
431 QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false;
432 QTest::newRow("invalidRoot") << "invalidRoot.qml" << "invalidRoot.errors.txt" << false;
433 QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false;
434 QTest::newRow("objectValueTypeProperty") << "objectValueTypeProperty.qml" << "objectValueTypeProperty.errors.txt" << false;
435 QTest::newRow("enumTypes") << "enumTypes.qml" << "enumTypes.errors.txt" << false;
436 QTest::newRow("noCreation") << "noCreation.qml" << "noCreation.errors.txt" << false;
437 QTest::newRow("destroyedSignal") << "destroyedSignal.qml" << "destroyedSignal.errors.txt" << false;
438 QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false;
439 QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false;
440 QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false;
441 QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false;
442 QTest::newRow("notAvailable") << "notAvailable.qml" << "notAvailable.errors.txt" << false;
443 QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
444 QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
445 QTest::newRow("incorrectCase") << "incorrectCase.qml"
446 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
447 << "incorrectCase.errors.insensitive.txt"
449 << "incorrectCase.errors.sensitive.txt"
453 QTest::newRow("metaobjectRevision.1") << "metaobjectRevision.1.qml" << "metaobjectRevision.1.errors.txt" << false;
454 QTest::newRow("metaobjectRevision.2") << "metaobjectRevision.2.qml" << "metaobjectRevision.2.errors.txt" << false;
455 QTest::newRow("metaobjectRevision.3") << "metaobjectRevision.3.qml" << "metaobjectRevision.3.errors.txt" << false;
457 QTest::newRow("Major version isolation") << "majorVersionIsolation.qml" << "majorVersionIsolation.errors.txt" << false;
461 void tst_qdeclarativelanguage::errors()
463 QFETCH(QString, file);
464 QFETCH(QString, errorFile);
465 QFETCH(bool, create);
467 QDeclarativeComponent component(&engine, TEST_FILE(file));
470 QObject *object = component.create();
471 QVERIFY(object == 0);
474 VERIFY_ERRORS(errorFile.toLatin1().constData());
477 void tst_qdeclarativelanguage::simpleObject()
479 QDeclarativeComponent component(&engine, TEST_FILE("simpleObject.qml"));
481 QObject *object = component.create();
482 QVERIFY(object != 0);
485 void tst_qdeclarativelanguage::simpleContainer()
487 QDeclarativeComponent component(&engine, TEST_FILE("simpleContainer.qml"));
489 MyContainer *container= qobject_cast<MyContainer*>(component.create());
490 QVERIFY(container != 0);
491 QCOMPARE(container->getChildren()->count(),2);
494 void tst_qdeclarativelanguage::interfaceProperty()
496 QDeclarativeComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
498 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
499 QVERIFY(object != 0);
500 QVERIFY(object->interface());
501 QVERIFY(object->interface()->id == 913);
504 void tst_qdeclarativelanguage::interfaceQList()
506 QDeclarativeComponent component(&engine, TEST_FILE("interfaceQList.qml"));
508 MyContainer *container= qobject_cast<MyContainer*>(component.create());
509 QVERIFY(container != 0);
510 QVERIFY(container->getQListInterfaces()->count() == 2);
511 for(int ii = 0; ii < 2; ++ii)
512 QVERIFY(container->getQListInterfaces()->at(ii)->id == 913);
515 void tst_qdeclarativelanguage::assignObjectToSignal()
517 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
519 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
520 QVERIFY(object != 0);
521 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
522 emit object->basicSignal();
525 void tst_qdeclarativelanguage::assignObjectToVariant()
527 QDeclarativeComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
529 QObject *object = component.create();
530 QVERIFY(object != 0);
531 QVariant v = object->property("a");
532 QVERIFY(v.userType() == qMetaTypeId<QObject *>());
535 void tst_qdeclarativelanguage::assignLiteralSignalProperty()
537 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
539 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
540 QVERIFY(object != 0);
541 QCOMPARE(object->onLiteralSignal(), 10);
544 // Test is an external component can be loaded and assigned (to a qlist)
545 void tst_qdeclarativelanguage::assignQmlComponent()
547 QDeclarativeComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
549 MyContainer *object = qobject_cast<MyContainer *>(component.create());
550 QVERIFY(object != 0);
551 QVERIFY(object->getChildren()->count() == 1);
552 QObject *child = object->getChildren()->at(0);
553 QCOMPARE(child->property("x"), QVariant(10));
554 QCOMPARE(child->property("y"), QVariant(11));
557 // Test literal assignment to all the basic types
558 void tst_qdeclarativelanguage::assignBasicTypes()
560 QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
562 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
563 QVERIFY(object != 0);
564 QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
565 QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
566 QCOMPARE(object->stringProperty(), QString("Hello World!"));
567 QCOMPARE(object->uintProperty(), uint(10));
568 QCOMPARE(object->intProperty(), -19);
569 QCOMPARE((float)object->realProperty(), float(23.2));
570 QCOMPARE((float)object->doubleProperty(), float(-19.7));
571 QCOMPARE((float)object->floatProperty(), float(8.5));
572 QCOMPARE(object->colorProperty(), QColor("red"));
573 QCOMPARE(object->dateProperty(), QDate(1982, 11, 25));
574 QCOMPARE(object->timeProperty(), QTime(11, 11, 32));
575 QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1)));
576 QCOMPARE(object->pointProperty(), QPoint(99,13));
577 QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3));
578 QCOMPARE(object->sizeProperty(), QSize(99, 13));
579 QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2));
580 QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200));
581 QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99));
582 QCOMPARE(object->boolProperty(), true);
583 QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
584 QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2));
585 QCOMPARE(object->vector4Property(), QVector4D(10, 1, 2.2, 2.3));
586 QCOMPARE(object->urlProperty(), component.url().resolved(QUrl("main.qml")));
587 QVERIFY(object->objectProperty() != 0);
588 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
590 QCOMPARE(child->intProperty(), 8);
593 // Test edge case type assignments
594 void tst_qdeclarativelanguage::assignTypeExtremes()
596 QDeclarativeComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
598 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
599 QVERIFY(object != 0);
600 QCOMPARE(object->uintProperty(), 0xEE6B2800);
601 QCOMPARE(object->intProperty(), -0x77359400);
604 // Test that a composite type can assign to a property of its base type
605 void tst_qdeclarativelanguage::assignCompositeToType()
607 QDeclarativeComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
609 QObject *object = component.create();
610 QVERIFY(object != 0);
613 // Test that literals are stored correctly in variant properties
614 void tst_qdeclarativelanguage::assignLiteralToVariant()
616 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
618 QObject *object = component.create();
619 QVERIFY(object != 0);
621 QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
622 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
623 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
624 QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
625 QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
626 QCOMPARE(object->property("test6").userType(), (int)QVariant::PointF);
627 QCOMPARE(object->property("test7").userType(), (int)QVariant::SizeF);
628 QCOMPARE(object->property("test8").userType(), (int)QVariant::Vector3D);
629 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
630 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
631 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
632 QCOMPARE(object->property("test12").userType(), (int)QVariant::Vector4D);
634 QVERIFY(object->property("test1") == QVariant(1));
635 QVERIFY(object->property("test2") == QVariant((double)1.7));
636 QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!"))));
637 QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800)));
638 QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10)));
639 QVERIFY(object->property("test6") == QVariant(QPointF(10, 10)));
640 QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10)));
641 QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100)));
642 QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800"))));
643 QVERIFY(object->property("test10") == QVariant(bool(true)));
644 QVERIFY(object->property("test11") == QVariant(bool(false)));
645 QVERIFY(object->property("test12") == QVariant(QVector4D(100, 100, 100, 100)));
650 // Test that literals are stored correctly in "var" properties
651 // Note that behaviour differs from "variant" properties in that
652 // no conversion from "special strings" to QVariants is performed.
653 void tst_qdeclarativelanguage::assignLiteralToVar()
655 QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVar.qml"));
657 QObject *object = component.create();
658 QVERIFY(object != 0);
660 QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
661 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
662 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
663 QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
664 QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
665 QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
666 QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
667 QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
668 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
669 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
670 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
671 QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
672 QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
673 QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
674 QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
675 QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
676 QCOMPARE(object->property("variantTest1Bound").userType(), (int)QMetaType::Int);
677 QCOMPARE(object->property("test1Bound").userType(), (int)QMetaType::Int);
679 QCOMPARE(object->property("test1"), QVariant(5));
680 QCOMPARE(object->property("test2"), QVariant((double)1.7));
681 QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
682 QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
683 QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
684 QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
685 QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
686 QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
687 QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
688 QCOMPARE(object->property("test10"), QVariant(bool(true)));
689 QCOMPARE(object->property("test11"), QVariant(bool(false)));
690 QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
691 QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
692 QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
693 QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
694 QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
695 QCOMPARE(object->property("variantTest1Bound"), QVariant(9));
696 QCOMPARE(object->property("test1Bound"), QVariant(11));
701 // Tests that custom parser types can be instantiated
702 void tst_qdeclarativelanguage::customParserTypes()
704 QDeclarativeComponent component(&engine, TEST_FILE("customParserTypes.qml"));
706 QObject *object = component.create();
707 QVERIFY(object != 0);
708 QVERIFY(object->property("count") == QVariant(2));
711 // Tests that the root item can be a custom component
712 void tst_qdeclarativelanguage::rootAsQmlComponent()
714 QDeclarativeComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
716 MyContainer *object = qobject_cast<MyContainer *>(component.create());
717 QVERIFY(object != 0);
718 QCOMPARE(object->property("x"), QVariant(11));
719 QCOMPARE(object->getChildren()->count(), 2);
722 // Tests that components can be specified inline
723 void tst_qdeclarativelanguage::inlineQmlComponents()
725 QDeclarativeComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
727 MyContainer *object = qobject_cast<MyContainer *>(component.create());
728 QVERIFY(object != 0);
729 QCOMPARE(object->getChildren()->count(), 1);
730 QDeclarativeComponent *comp = qobject_cast<QDeclarativeComponent *>(object->getChildren()->at(0));
732 MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
733 QVERIFY(compObject != 0);
734 QCOMPARE(compObject->value(), 11);
737 // Tests that types that have an id property have it set
738 void tst_qdeclarativelanguage::idProperty()
740 QDeclarativeComponent component(&engine, TEST_FILE("idProperty.qml"));
742 MyContainer *object = qobject_cast<MyContainer *>(component.create());
743 QVERIFY(object != 0);
744 QCOMPARE(object->getChildren()->count(), 1);
745 MyTypeObject *child =
746 qobject_cast<MyTypeObject *>(object->getChildren()->at(0));
748 QCOMPARE(child->id(), QString("myObjectId"));
749 QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
752 // Tests automatic connection to notify signals if "onBlahChanged" syntax is used
753 // even if the notify signal for "blah" is not called "blahChanged"
754 void tst_qdeclarativelanguage::autoNotifyConnection()
756 QDeclarativeComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
758 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
759 QVERIFY(object != 0);
760 QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
761 QVERIFY(prop.isValid());
763 QCOMPARE(prop.read(object), QVariant::fromValue(false));
764 object->setPropertyWithNotify(1);
765 QCOMPARE(prop.read(object), QVariant::fromValue(true));
768 // Tests that signals can be assigned to
769 void tst_qdeclarativelanguage::assignSignal()
771 QDeclarativeComponent component(&engine, TEST_FILE("assignSignal.qml"));
773 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
774 QVERIFY(object != 0);
775 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
776 emit object->basicSignal();
777 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)");
778 emit object->basicParameterizedSignal(9);
781 // Tests the creation and assignment of dynamic properties
782 void tst_qdeclarativelanguage::dynamicProperties()
784 QDeclarativeComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
786 QObject *object = component.create();
787 QVERIFY(object != 0);
788 QCOMPARE(object->property("intProperty"), QVariant(10));
789 QCOMPARE(object->property("boolProperty"), QVariant(false));
790 QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
791 QCOMPARE(object->property("realProperty"), QVariant((qreal)-19.9));
792 QCOMPARE(object->property("stringProperty"), QVariant("Hello World!"));
793 QCOMPARE(object->property("urlProperty"), QVariant(TEST_FILE("main.qml")));
794 QCOMPARE(object->property("colorProperty"), QVariant(QColor("red")));
795 QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2)));
796 QCOMPARE(object->property("varProperty"), QVariant("Hello World!"));
799 // Test that nested types can use dynamic properties
800 void tst_qdeclarativelanguage::dynamicPropertiesNested()
802 QDeclarativeComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
804 QObject *object = component.create();
805 QVERIFY(object != 0);
807 QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
808 QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
809 QCOMPARE(object->property("a").toInt(), 13); // New
810 QCOMPARE(object->property("b").toInt(), 12); // New
815 // Tests the creation and assignment to dynamic list properties
816 void tst_qdeclarativelanguage::listProperties()
818 QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml"));
820 QObject *object = component.create();
821 QVERIFY(object != 0);
823 QCOMPARE(object->property("test").toInt(), 2);
826 // Tests the creation and assignment of dynamic object properties
828 void tst_qdeclarativelanguage::dynamicObjectProperties()
831 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
833 QObject *object = component.create();
834 QVERIFY(object != 0);
836 QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
837 QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
840 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
841 QEXPECT_FAIL("", "QTBUG-10822", Abort);
843 QObject *object = component.create();
844 QVERIFY(object != 0);
846 QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
850 // Tests the declaration of dynamic signals and slots
851 void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
853 QTest::ignoreMessage(QtDebugMsg, "1921");
855 QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
857 QObject *object = component.create();
858 QVERIFY(object != 0);
859 QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
860 QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
861 QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1);
862 QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
864 QCOMPARE(object->property("test").toInt(), 0);
865 QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
866 QCOMPARE(object->property("test").toInt(), 10);
869 void tst_qdeclarativelanguage::simpleBindings()
871 QDeclarativeComponent component(&engine, TEST_FILE("simpleBindings.qml"));
873 QObject *object = component.create();
874 QVERIFY(object != 0);
875 QCOMPARE(object->property("value1"), QVariant(10));
876 QCOMPARE(object->property("value2"), QVariant(10));
877 QCOMPARE(object->property("value3"), QVariant(21));
878 QCOMPARE(object->property("value4"), QVariant(10));
879 QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
882 void tst_qdeclarativelanguage::autoComponentCreation()
884 QDeclarativeComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
886 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
887 QVERIFY(object != 0);
888 QVERIFY(object->componentProperty() != 0);
889 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
891 QCOMPARE(child->realProperty(), qreal(9));
894 void tst_qdeclarativelanguage::propertyValueSource()
897 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
899 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
900 QVERIFY(object != 0);
902 QList<QObject *> valueSources;
903 QObjectList allChildren = object->findChildren<QObject*>();
904 foreach (QObject *child, allChildren) {
905 if (qobject_cast<QDeclarativePropertyValueSource *>(child))
906 valueSources.append(child);
909 QCOMPARE(valueSources.count(), 1);
910 MyPropertyValueSource *valueSource =
911 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
912 QVERIFY(valueSource != 0);
913 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
914 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
918 QDeclarativeComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
920 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
921 QVERIFY(object != 0);
923 QList<QObject *> valueSources;
924 QObjectList allChildren = object->findChildren<QObject*>();
925 foreach (QObject *child, allChildren) {
926 if (qobject_cast<QDeclarativePropertyValueSource *>(child))
927 valueSources.append(child);
930 QCOMPARE(valueSources.count(), 1);
931 MyPropertyValueSource *valueSource =
932 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
933 QVERIFY(valueSource != 0);
934 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
935 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
939 void tst_qdeclarativelanguage::attachedProperties()
941 QDeclarativeComponent component(&engine, TEST_FILE("attachedProperties.qml"));
943 QObject *object = component.create();
944 QVERIFY(object != 0);
945 QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
946 QVERIFY(attached != 0);
947 QCOMPARE(attached->property("value"), QVariant(10));
948 QCOMPARE(attached->property("value2"), QVariant(13));
951 // Tests non-static object properties
952 void tst_qdeclarativelanguage::dynamicObjects()
954 QDeclarativeComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
956 QObject *object = component.create();
957 QVERIFY(object != 0);
960 // Tests the registration of custom variant string converters
961 void tst_qdeclarativelanguage::customVariantTypes()
963 QDeclarativeComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
965 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
966 QVERIFY(object != 0);
967 QCOMPARE(object->customType().a, 10);
970 void tst_qdeclarativelanguage::valueTypes()
972 QDeclarativeComponent component(&engine, TEST_FILE("valueTypes.qml"));
975 QString message = component.url().toString() + ":2:1: QML MyTypeObject: Binding loop detected for property \"rectProperty.width\"";
976 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
977 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
979 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
980 QVERIFY(object != 0);
983 QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
984 QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
985 QCOMPARE(object->intProperty(), 10);
987 QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
988 QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
989 QCOMPARE(object->intProperty(), 12);
993 QDeclarativeProperty p(object, "rectProperty.x");
994 QCOMPARE(p.read(), QVariant(12));
996 QCOMPARE(p.read(), QVariant(13));
998 quint32 r = QDeclarativePropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
999 QDeclarativeProperty p2;
1000 QDeclarativePropertyPrivate::restore(p2, r, object);
1001 QCOMPARE(p2.read(), QVariant(13));
1005 void tst_qdeclarativelanguage::cppnamespace()
1008 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.qml"));
1010 QObject *object = component.create();
1011 QVERIFY(object != 0);
1016 QDeclarativeComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
1018 QObject *object = component.create();
1019 QVERIFY(object != 0);
1024 void tst_qdeclarativelanguage::aliasProperties()
1026 // Simple "int" alias
1028 QDeclarativeComponent component(&engine, TEST_FILE("alias.1.qml"));
1030 QObject *object = component.create();
1031 QVERIFY(object != 0);
1033 // Read through alias
1034 QCOMPARE(object->property("valueAlias").toInt(), 10);
1035 object->setProperty("value", QVariant(13));
1036 QCOMPARE(object->property("valueAlias").toInt(), 13);
1038 // Write through alias
1039 object->setProperty("valueAlias", QVariant(19));
1040 QCOMPARE(object->property("valueAlias").toInt(), 19);
1041 QCOMPARE(object->property("value").toInt(), 19);
1046 // Complex object alias
1048 QDeclarativeComponent component(&engine, TEST_FILE("alias.2.qml"));
1050 QObject *object = component.create();
1051 QVERIFY(object != 0);
1053 // Read through alias
1055 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1057 QCOMPARE(v->value(), 10);
1059 // Write through alias
1060 MyQmlObject *v2 = new MyQmlObject();
1061 v2->setParent(object);
1062 object->setProperty("aliasObject", qVariantFromValue(v2));
1064 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1073 QDeclarativeComponent component(&engine, TEST_FILE("alias.3.qml"));
1075 QObject *object = component.create();
1076 QVERIFY(object != 0);
1078 QCOMPARE(object->property("value").toInt(), 1892);
1079 QCOMPARE(object->property("value2").toInt(), 1892);
1081 object->setProperty("value", QVariant(1313));
1082 QCOMPARE(object->property("value").toInt(), 1313);
1083 QCOMPARE(object->property("value2").toInt(), 1313);
1085 object->setProperty("value2", QVariant(8080));
1086 QCOMPARE(object->property("value").toInt(), 8080);
1087 QCOMPARE(object->property("value2").toInt(), 8080);
1094 QDeclarativeComponent component(&engine, TEST_FILE("alias.4.qml"));
1096 QObject *object = component.create();
1097 QVERIFY(object != 0);
1099 QCOMPARE(object->property("enumAlias").toInt(), 1);
1106 QDeclarativeComponent component(&engine, TEST_FILE("alias.5.qml"));
1108 QObject *object = component.create();
1109 QVERIFY(object != 0);
1111 QVariant v = object->property("otherAlias");
1112 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1113 MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
1114 QCOMPARE(o->value(), 10);
1118 v = object->property("otherAlias");
1119 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1120 o = qvariant_cast<MyQmlObject*>(v);
1126 // Nested aliases - this used to cause a crash
1128 QDeclarativeComponent component(&engine, TEST_FILE("alias.6.qml"));
1130 QObject *object = component.create();
1131 QVERIFY(object != 0);
1133 QCOMPARE(object->property("a").toInt(), 1923);
1136 // Ptr Alias Cleanup - check that aliases to ptr types return 0
1137 // if the object aliased to is removed
1139 QDeclarativeComponent component(&engine, TEST_FILE("alias.7.qml"));
1142 QObject *object = component.create();
1143 QVERIFY(object != 0);
1145 QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
1146 QVERIFY(object1 != 0);
1147 QObject *object2 = qvariant_cast<QObject *>(object1->property("object"));
1148 QVERIFY(object2 != 0);
1150 QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
1151 QVERIFY(alias == object2);
1155 QObject *alias2 = object; // "Random" start value
1157 void *a[] = { &alias2, 0, &status };
1158 QMetaObject::metacall(object, QMetaObject::ReadProperty,
1159 object->metaObject()->indexOfProperty("aliasedObject"), a);
1160 QVERIFY(alias2 == 0);
1163 // Simple composite type
1165 QDeclarativeComponent component(&engine, TEST_FILE("alias.8.qml"));
1167 QObject *object = component.create();
1168 QVERIFY(object != 0);
1170 QCOMPARE(object->property("value").toInt(), 10);
1175 // Complex composite type
1177 QDeclarativeComponent component(&engine, TEST_FILE("alias.9.qml"));
1179 QObject *object = component.create();
1180 QVERIFY(object != 0);
1182 QCOMPARE(object->property("value").toInt(), 10);
1188 // Simple "int" alias
1190 QDeclarativeComponent component(&engine, TEST_FILE("alias.10.qml"));
1192 QObject *object = component.create();
1193 QVERIFY(object != 0);
1195 // Read through alias
1196 QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8));
1197 object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
1198 QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
1200 // Write through alias
1201 object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
1202 QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
1203 QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
1208 // Valuetype sub-alias
1210 QDeclarativeComponent component(&engine, TEST_FILE("alias.11.qml"));
1212 QObject *object = component.create();
1213 QVERIFY(object != 0);
1215 // Read through alias
1216 QCOMPARE(object->property("aliasProperty").toInt(), 19);
1217 object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
1218 QCOMPARE(object->property("aliasProperty").toInt(), 33);
1220 // Write through alias
1221 object->setProperty("aliasProperty", QVariant(4));
1222 QCOMPARE(object->property("aliasProperty").toInt(), 4);
1223 QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
1229 // QTBUG-13374 Test that alias properties and signals can coexist
1230 void tst_qdeclarativelanguage::aliasPropertiesAndSignals()
1232 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
1234 QObject *o = component.create();
1236 QCOMPARE(o->property("test").toBool(), true);
1240 // Test that the root element in a composite type can be a Component
1241 void tst_qdeclarativelanguage::componentCompositeType()
1243 QDeclarativeComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
1245 QObject *object = component.create();
1246 QVERIFY(object != 0);
1249 class TestType : public QObject {
1252 TestType(QObject *p=0) : QObject(p) {}
1255 class TestType2 : public QObject {
1258 TestType2(QObject *p=0) : QObject(p) {}
1261 void tst_qdeclarativelanguage::i18n_data()
1263 QTest::addColumn<QString>("file");
1264 QTest::addColumn<QString>("stringProperty");
1265 QTest::newRow("i18nStrings") << "i18nStrings.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245 (5 accented 'a' letters)");
1266 QTest::newRow("i18nDeclaredPropertyNames") << "i18nDeclaredPropertyNames.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 10");
1267 QTest::newRow("i18nDeclaredPropertyUse") << "i18nDeclaredPropertyUse.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 15");
1268 QTest::newRow("i18nScript") << "i18nScript.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 20");
1269 QTest::newRow("i18nType") << "i18nType.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 30");
1270 QTest::newRow("i18nNameSpace") << "i18nNameSpace.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 40");
1273 void tst_qdeclarativelanguage::i18n()
1275 QFETCH(QString, file);
1276 QFETCH(QString, stringProperty);
1277 QDeclarativeComponent component(&engine, TEST_FILE(file));
1279 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1280 QVERIFY(object != 0);
1281 QCOMPARE(object->stringProperty(), stringProperty);
1286 // Check that the Component::onCompleted attached property works
1287 void tst_qdeclarativelanguage::onCompleted()
1289 QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
1291 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1292 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1293 QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
1294 QObject *object = component.create();
1295 QVERIFY(object != 0);
1298 // Check that the Component::onDestruction attached property works
1299 void tst_qdeclarativelanguage::onDestruction()
1301 QDeclarativeComponent component(&engine, TEST_FILE("onDestruction.qml"));
1303 QObject *object = component.create();
1304 QVERIFY(object != 0);
1306 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1307 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1308 QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
1312 // Check that assignments to QDeclarativeScriptString properties work
1313 void tst_qdeclarativelanguage::scriptString()
1316 QDeclarativeComponent component(&engine, TEST_FILE("scriptString.qml"));
1319 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1320 QVERIFY(object != 0);
1321 QCOMPARE(object->scriptProperty().script(), QString("foo + bar"));
1322 QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object));
1323 QCOMPARE(object->scriptProperty().context(), qmlContext(object));
1325 QVERIFY(object->grouped() != 0);
1326 QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)"));
1327 QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object));
1328 QCOMPARE(object->grouped()->script().context(), qmlContext(object));
1332 QDeclarativeComponent component(&engine, TEST_FILE("scriptString2.qml"));
1335 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1336 QVERIFY(object != 0);
1337 QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
1341 QDeclarativeComponent component(&engine, TEST_FILE("scriptString3.qml"));
1344 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1345 QVERIFY(object != 0);
1346 QCOMPARE(object->scriptProperty().script(), QString("12.345"));
1350 QDeclarativeComponent component(&engine, TEST_FILE("scriptString4.qml"));
1353 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1354 QVERIFY(object != 0);
1355 QCOMPARE(object->scriptProperty().script(), QString("true"));
1359 // Check that default property assignments are correctly spliced into explicit
1360 // property assignments
1361 void tst_qdeclarativelanguage::defaultPropertyListOrder()
1363 QDeclarativeComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
1366 MyContainer *container = qobject_cast<MyContainer *>(component.create());
1367 QVERIFY(container != 0);
1369 QCOMPARE(container->getChildren()->count(), 6);
1370 QCOMPARE(container->getChildren()->at(0)->property("index"), QVariant(0));
1371 QCOMPARE(container->getChildren()->at(1)->property("index"), QVariant(1));
1372 QCOMPARE(container->getChildren()->at(2)->property("index"), QVariant(2));
1373 QCOMPARE(container->getChildren()->at(3)->property("index"), QVariant(3));
1374 QCOMPARE(container->getChildren()->at(4)->property("index"), QVariant(4));
1375 QCOMPARE(container->getChildren()->at(5)->property("index"), QVariant(5));
1378 void tst_qdeclarativelanguage::declaredPropertyValues()
1380 QDeclarativeComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
1384 void tst_qdeclarativelanguage::dontDoubleCallClassBegin()
1386 QDeclarativeComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml"));
1387 QObject *o = component.create();
1390 MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
1392 QCOMPARE(o2->classBeginCount(), 1);
1393 QCOMPARE(o2->componentCompleteCount(), 1);
1398 void tst_qdeclarativelanguage::reservedWords_data()
1400 QTest::addColumn<QByteArray>("word");
1402 QTest::newRow("abstract") << QByteArray("abstract");
1403 QTest::newRow("as") << QByteArray("as");
1404 QTest::newRow("boolean") << QByteArray("boolean");
1405 QTest::newRow("break") << QByteArray("break");
1406 QTest::newRow("byte") << QByteArray("byte");
1407 QTest::newRow("case") << QByteArray("case");
1408 QTest::newRow("catch") << QByteArray("catch");
1409 QTest::newRow("char") << QByteArray("char");
1410 QTest::newRow("class") << QByteArray("class");
1411 QTest::newRow("continue") << QByteArray("continue");
1412 QTest::newRow("const") << QByteArray("const");
1413 QTest::newRow("debugger") << QByteArray("debugger");
1414 QTest::newRow("default") << QByteArray("default");
1415 QTest::newRow("delete") << QByteArray("delete");
1416 QTest::newRow("do") << QByteArray("do");
1417 QTest::newRow("double") << QByteArray("double");
1418 QTest::newRow("else") << QByteArray("else");
1419 QTest::newRow("enum") << QByteArray("enum");
1420 QTest::newRow("export") << QByteArray("export");
1421 QTest::newRow("extends") << QByteArray("extends");
1422 QTest::newRow("false") << QByteArray("false");
1423 QTest::newRow("final") << QByteArray("final");
1424 QTest::newRow("finally") << QByteArray("finally");
1425 QTest::newRow("float") << QByteArray("float");
1426 QTest::newRow("for") << QByteArray("for");
1427 QTest::newRow("function") << QByteArray("function");
1428 QTest::newRow("goto") << QByteArray("goto");
1429 QTest::newRow("if") << QByteArray("if");
1430 QTest::newRow("implements") << QByteArray("implements");
1431 QTest::newRow("import") << QByteArray("import");
1432 QTest::newRow("in") << QByteArray("in");
1433 QTest::newRow("instanceof") << QByteArray("instanceof");
1434 QTest::newRow("int") << QByteArray("int");
1435 QTest::newRow("interface") << QByteArray("interface");
1436 QTest::newRow("long") << QByteArray("long");
1437 QTest::newRow("native") << QByteArray("native");
1438 QTest::newRow("new") << QByteArray("new");
1439 QTest::newRow("null") << QByteArray("null");
1440 QTest::newRow("package") << QByteArray("package");
1441 QTest::newRow("private") << QByteArray("private");
1442 QTest::newRow("protected") << QByteArray("protected");
1443 QTest::newRow("public") << QByteArray("public");
1444 QTest::newRow("return") << QByteArray("return");
1445 QTest::newRow("short") << QByteArray("short");
1446 QTest::newRow("static") << QByteArray("static");
1447 QTest::newRow("super") << QByteArray("super");
1448 QTest::newRow("switch") << QByteArray("switch");
1449 QTest::newRow("synchronized") << QByteArray("synchronized");
1450 QTest::newRow("this") << QByteArray("this");
1451 QTest::newRow("throw") << QByteArray("throw");
1452 QTest::newRow("throws") << QByteArray("throws");
1453 QTest::newRow("transient") << QByteArray("transient");
1454 QTest::newRow("true") << QByteArray("true");
1455 QTest::newRow("try") << QByteArray("try");
1456 QTest::newRow("typeof") << QByteArray("typeof");
1457 QTest::newRow("var") << QByteArray("var");
1458 QTest::newRow("void") << QByteArray("void");
1459 QTest::newRow("volatile") << QByteArray("volatile");
1460 QTest::newRow("while") << QByteArray("while");
1461 QTest::newRow("with") << QByteArray("with");
1464 void tst_qdeclarativelanguage::reservedWords()
1466 QFETCH(QByteArray, word);
1467 QDeclarativeComponent component(&engine);
1468 component.setData("import QtQuick 2.0\nQtObject { property string " + word + " }", QUrl());
1469 QCOMPARE(component.errorString(), QLatin1String(":2 Expected token `identifier'\n"));
1472 // Check that first child of qml is of given type. Empty type insists on error.
1473 void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, const QString& expectederror)
1475 QDeclarativeComponent component(&engine);
1476 component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
1478 QTRY_VERIFY(!component.isLoading());
1480 if (type.isEmpty()) {
1481 QVERIFY(component.isError());
1482 QString actualerror;
1483 foreach (const QDeclarativeError e, component.errors()) {
1484 if (!actualerror.isEmpty())
1485 actualerror.append("; ");
1486 actualerror.append(e.description());
1488 QCOMPARE(actualerror,expectederror);
1491 QObject *object = component.create();
1492 QVERIFY(object != 0);
1493 QCOMPARE(QString(object->metaObject()->className()), type);
1498 void tst_qdeclarativelanguage::inlineAssignmentsOverrideBindings()
1500 QDeclarativeComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml"));
1502 QObject *o = component.create();
1504 QCOMPARE(o->property("test").toInt(), 11);
1509 void tst_qdeclarativelanguage::nestedComponentRoots()
1511 QDeclarativeComponent component(&engine, TEST_FILE("nestedComponentRoots.qml"));
1514 // Import tests (QT-558)
1515 void tst_qdeclarativelanguage::importsBuiltin_data()
1519 QTest::addColumn<QString>("qml");
1520 QTest::addColumn<QString>("type");
1521 QTest::addColumn<QString>("error");
1524 QTest::newRow("missing import")
1527 << "Test is not a type";
1528 QTest::newRow("not in version 0.0")
1529 << "import com.nokia.Test 0.0\n"
1532 << "Test is not a type";
1533 QTest::newRow("version not installed")
1534 << "import com.nokia.Test 99.0\n"
1537 << "module \"com.nokia.Test\" version 99.0 is not installed";
1538 QTest::newRow("in version 0.0")
1539 << "import com.nokia.Test 0.0\n"
1543 QTest::newRow("qualified in version 0.0")
1544 << "import com.nokia.Test 0.0 as T\n"
1548 QTest::newRow("in version 1.0")
1549 << "import com.nokia.Test 1.0\n"
1553 QTest::newRow("qualified wrong")
1554 << "import com.nokia.Test 1.0 as T\n" // QT-610
1557 << "Test is not a type";
1558 QTest::newRow("qualified right")
1559 << "import com.nokia.Test 1.0 as T\n"
1563 QTest::newRow("qualified right but not in version 0.0")
1564 << "import com.nokia.Test 0.0 as T\n"
1567 << "T.Test is not a type";
1568 QTest::newRow("in version 1.1")
1569 << "import com.nokia.Test 1.1\n"
1573 QTest::newRow("in version 1.3")
1574 << "import com.nokia.Test 1.3\n"
1578 QTest::newRow("in version 1.5")
1579 << "import com.nokia.Test 1.5\n"
1583 QTest::newRow("changed in version 1.8")
1584 << "import com.nokia.Test 1.8\n"
1588 QTest::newRow("in version 1.12")
1589 << "import com.nokia.Test 1.12\n"
1593 QTest::newRow("old in version 1.9")
1594 << "import com.nokia.Test 1.9\n"
1598 QTest::newRow("old in version 1.11")
1599 << "import com.nokia.Test 1.11\n"
1603 QTest::newRow("multiversion 1")
1604 << "import com.nokia.Test 1.11\n"
1605 "import com.nokia.Test 1.12\n"
1607 << (!qmlCheckTypes()?"TestType2":"")
1608 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1609 QTest::newRow("multiversion 2")
1610 << "import com.nokia.Test 1.11\n"
1611 "import com.nokia.Test 1.12\n"
1613 << (!qmlCheckTypes()?"TestType":"")
1614 << (!qmlCheckTypes()?"":"OldTest is ambiguous. Found in com/nokia/Test in version 1.12 and 1.11");
1615 QTest::newRow("qualified multiversion 3")
1616 << "import com.nokia.Test 1.0 as T0\n"
1617 "import com.nokia.Test 1.8 as T8\n"
1621 QTest::newRow("qualified multiversion 4")
1622 << "import com.nokia.Test 1.0 as T0\n"
1623 "import com.nokia.Test 1.8 as T8\n"
1629 void tst_qdeclarativelanguage::importsBuiltin()
1631 QFETCH(QString, qml);
1632 QFETCH(QString, type);
1633 QFETCH(QString, error);
1634 testType(qml,type,error);
1637 void tst_qdeclarativelanguage::importsLocal_data()
1639 QTest::addColumn<QString>("qml");
1640 QTest::addColumn<QString>("type");
1641 QTest::addColumn<QString>("error");
1644 QTest::newRow("local import")
1645 << "import \"subdir\"\n" // QT-613
1649 QTest::newRow("local import second")
1650 << "import QtQuick 2.0\nimport \"subdir\"\n"
1654 QTest::newRow("local import subsubdir")
1655 << "import QtQuick 2.0\nimport \"subdir/subsubdir\"\n"
1659 QTest::newRow("local import QTBUG-7721 A")
1660 << "subdir.Test {}" // no longer allowed (QTBUG-7721)
1662 << "subdir.Test - subdir is not a namespace";
1663 QTest::newRow("local import QTBUG-7721 B")
1664 << "import \"subdir\" as X\n"
1665 "X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
1667 << "X.subsubdir.SubTest - nested namespaces not allowed";
1668 QTest::newRow("local import as")
1669 << "import \"subdir\" as T\n"
1673 QTest::newRow("wrong local import as")
1674 << "import \"subdir\" as T\n"
1677 << "Test is not a type";
1678 QTest::newRow("library precedence over local import")
1679 << "import \"subdir\"\n"
1680 "import com.nokia.Test 1.0\n"
1682 << (!qmlCheckTypes()?"TestType":"")
1683 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test and in subdir");
1686 void tst_qdeclarativelanguage::importsLocal()
1688 QFETCH(QString, qml);
1689 QFETCH(QString, type);
1690 QFETCH(QString, error);
1691 testType(qml,type,error);
1694 void tst_qdeclarativelanguage::basicRemote_data()
1696 QTest::addColumn<QUrl>("url");
1697 QTest::addColumn<QString>("type");
1698 QTest::addColumn<QString>("error");
1700 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage/";
1702 QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
1703 QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << "";
1704 QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
1707 void tst_qdeclarativelanguage::basicRemote()
1710 QFETCH(QString, type);
1711 QFETCH(QString, error);
1713 TestHTTPServer server(14447);
1714 server.serveDirectory(testdata());
1716 QDeclarativeComponent component(&engine, url);
1718 QTRY_VERIFY(!component.isLoading());
1720 if (error.isEmpty()) {
1721 if (component.isError())
1722 qDebug() << component.errors();
1723 QVERIFY(!component.isError());
1725 QVERIFY(component.isError());
1729 void tst_qdeclarativelanguage::importsRemote_data()
1731 QTest::addColumn<QString>("qml");
1732 QTest::addColumn<QString>("type");
1733 QTest::addColumn<QString>("error");
1735 QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage";
1737 QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QSGRectangle"
1739 QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QSGText"
1741 QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QSGImage"
1743 QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
1744 << "WrongTestLocal is not a type";
1745 QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
1746 << "LocalInternal is not a type";
1747 QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""
1748 << "UndeclaredLocal is not a type";
1751 void tst_qdeclarativelanguage::importsRemote()
1753 QFETCH(QString, qml);
1754 QFETCH(QString, type);
1755 QFETCH(QString, error);
1757 TestHTTPServer server(14447);
1758 server.serveDirectory(testdata());
1760 testType(qml,type,error);
1763 void tst_qdeclarativelanguage::importsInstalled_data()
1767 QTest::addColumn<QString>("qml");
1768 QTest::addColumn<QString>("type");
1769 QTest::addColumn<QString>("error");
1772 QTest::newRow("installed import 0")
1773 << "import com.nokia.installedtest0 0.0\n"
1774 "InstalledTestTP {}"
1777 QTest::newRow("installed import 0 as TP")
1778 << "import com.nokia.installedtest0 0.0 as TP\n"
1779 "TP.InstalledTestTP {}"
1782 QTest::newRow("installed import 1")
1783 << "import com.nokia.installedtest 1.0\n"
1787 QTest::newRow("installed import 2")
1788 << "import com.nokia.installedtest 1.3\n"
1792 QTest::newRow("installed import 3")
1793 << "import com.nokia.installedtest 1.4\n"
1797 QTest::newRow("installed import minor version not available") // QTBUG-11936
1798 << "import com.nokia.installedtest 0.1\n"
1801 << "module \"com.nokia.installedtest\" version 0.1 is not installed";
1802 QTest::newRow("installed import minor version not available") // QTBUG-9627
1803 << "import com.nokia.installedtest 1.10\n"
1806 << "module \"com.nokia.installedtest\" version 1.10 is not installed";
1807 QTest::newRow("installed import major version not available") // QTBUG-9627
1808 << "import com.nokia.installedtest 9.0\n"
1811 << "module \"com.nokia.installedtest\" version 9.0 is not installed";
1812 QTest::newRow("installed import visibility") // QT-614
1813 << "import com.nokia.installedtest 1.4\n"
1816 << "PrivateType is not a type";
1819 void tst_qdeclarativelanguage::importsInstalled()
1821 QFETCH(QString, qml);
1822 QFETCH(QString, type);
1823 QFETCH(QString, error);
1824 testType(qml,type,error);
1828 void tst_qdeclarativelanguage::importsOrder_data()
1830 QTest::addColumn<QString>("qml");
1831 QTest::addColumn<QString>("type");
1832 QTest::addColumn<QString>("error");
1834 QTest::newRow("double import") <<
1835 "import com.nokia.installedtest 1.4\n"
1836 "import com.nokia.installedtest 1.4\n"
1838 << (!qmlCheckTypes()?"QSGText":"")
1839 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.4");
1840 QTest::newRow("installed import overrides 1") <<
1841 "import com.nokia.installedtest 1.0\n"
1842 "import com.nokia.installedtest 1.4\n"
1844 << (!qmlCheckTypes()?"QSGText":"")
1845 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1846 QTest::newRow("installed import overrides 2") <<
1847 "import com.nokia.installedtest 1.4\n"
1848 "import com.nokia.installedtest 1.0\n"
1850 << (!qmlCheckTypes()?"QSGRectangle":"")
1851 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1852 QTest::newRow("installed import re-overrides 1") <<
1853 "import com.nokia.installedtest 1.4\n"
1854 "import com.nokia.installedtest 1.0\n"
1855 "import com.nokia.installedtest 1.4\n"
1857 << (!qmlCheckTypes()?"QSGText":"")
1858 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
1859 QTest::newRow("installed import re-overrides 2") <<
1860 "import com.nokia.installedtest 1.4\n"
1861 "import com.nokia.installedtest 1.0\n"
1862 "import com.nokia.installedtest 1.4\n"
1863 "import com.nokia.installedtest 1.0\n"
1865 << (!qmlCheckTypes()?"QSGRectangle":"")
1866 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
1868 QTest::newRow("installed import versus builtin 1") <<
1869 "import com.nokia.installedtest 1.5\n"
1870 "import QtQuick 2.0\n"
1872 << (!qmlCheckTypes()?"QSGRectangle":"")
1873 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in Qt and in lib/com/nokia/installedtest");
1874 QTest::newRow("installed import versus builtin 2") <<
1875 "import QtQuick 2.0\n"
1876 "import com.nokia.installedtest 1.5\n"
1878 << (!qmlCheckTypes()?"QSGText":"")
1879 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest and in Qt");
1880 QTest::newRow("namespaces cannot be overridden by types 1") <<
1881 "import QtQuick 2.0 as Rectangle\n"
1882 "import com.nokia.installedtest 1.5\n"
1885 << "Namespace Rectangle cannot be used as a type";
1886 QTest::newRow("namespaces cannot be overridden by types 2") <<
1887 "import QtQuick 2.0 as Rectangle\n"
1888 "import com.nokia.installedtest 1.5\n"
1889 "Rectangle.Image {}"
1892 QTest::newRow("local last 1") <<
1896 QTest::newRow("local last 2") <<
1897 "import com.nokia.installedtest 1.0\n"
1899 << (!qmlCheckTypes()?"QSGRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
1900 << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest and in local directory");
1903 void tst_qdeclarativelanguage::importsOrder()
1905 QFETCH(QString, qml);
1906 QFETCH(QString, type);
1907 QFETCH(QString, error);
1908 testType(qml,type,error);
1911 void tst_qdeclarativelanguage::importIncorrectCase()
1913 QDeclarativeComponent component(&engine, TEST_FILE("importIncorrectCase.qml"));
1915 QList<QDeclarativeError> errors = component.errors();
1916 QCOMPARE(errors.count(), 1);
1918 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1919 QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + testdata("lib/com/Nokia/installedtest/qmldir") + QLatin1String("\"");
1921 QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
1924 QCOMPARE(errors.at(0).description(), expectedError);
1927 void tst_qdeclarativelanguage::qmlAttachedPropertiesObjectMethod()
1931 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
1932 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
1935 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
1937 QObject *object = component.create();
1938 QVERIFY(object != 0);
1940 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
1941 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1945 QDeclarativeComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
1947 QObject *object = component.create();
1948 QVERIFY(object != 0);
1950 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
1951 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
1955 void tst_qdeclarativelanguage::crash1()
1957 QDeclarativeComponent component(&engine);
1958 component.setData("import QtQuick 2.0\nComponent {}", QUrl());
1961 void tst_qdeclarativelanguage::crash2()
1963 QDeclarativeComponent component(&engine, TEST_FILE("crash2.qml"));
1967 void tst_qdeclarativelanguage::customOnProperty()
1969 QDeclarativeComponent component(&engine, TEST_FILE("customOnProperty.qml"));
1972 QObject *object = component.create();
1973 QVERIFY(object != 0);
1975 QCOMPARE(object->property("on").toInt(), 10);
1981 void tst_qdeclarativelanguage::variantNotify()
1983 QDeclarativeComponent component(&engine, TEST_FILE("variantNotify.qml"));
1986 QObject *object = component.create();
1987 QVERIFY(object != 0);
1989 QCOMPARE(object->property("notifyCount").toInt(), 1);
1994 void tst_qdeclarativelanguage::revisions()
1997 QDeclarativeComponent component(&engine, TEST_FILE("revisions11.qml"));
2000 MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
2001 QVERIFY(object != 0);
2003 QCOMPARE(object->prop2(), 10.0);
2008 QDeclarativeEngine myEngine;
2009 QDeclarativeComponent component(&myEngine, TEST_FILE("revisionssub11.qml"));
2012 MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
2013 QVERIFY(object != 0);
2015 QCOMPARE(object->prop1(), 10.0);
2016 QCOMPARE(object->prop2(), 10.0);
2017 QCOMPARE(object->prop3(), 10.0);
2018 QCOMPARE(object->prop4(), 10.0);
2023 QDeclarativeComponent component(&engine, TEST_FILE("versionedbase.qml"));
2025 MySubclass *object = qobject_cast<MySubclass*>(component.create());
2026 QVERIFY(object != 0);
2028 QCOMPARE(object->prop1(), 10.0);
2029 QCOMPARE(object->prop2(), 10.0);
2035 void tst_qdeclarativelanguage::revisionOverloads()
2038 QDeclarativeComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml"));
2042 QDeclarativeComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml"));
2043 QEXPECT_FAIL("", "QTBUG-13849", Abort);
2045 VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt");
2049 void tst_qdeclarativelanguage::initTestCase()
2053 // Registering the TestType class in other modules should have no adverse effects
2054 qmlRegisterType<TestType>("com.nokia.TestPre", 1, 0, "Test");
2056 qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP");
2057 qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test");
2058 qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test");
2059 qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test");
2060 qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest");
2061 qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test");
2063 // Registering the TestType class in other modules should have no adverse effects
2064 qmlRegisterType<TestType>("com.nokia.TestPost", 1, 0, "Test");
2066 // Create locale-specific file
2067 // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit
2068 // For iso8859-1 locale, this will just be data/I18nType?????.qml where ????? is 5 8-bit characters
2069 // For utf-8 locale, this will be data/I18nType??????????.qml where ?????????? is 5 8-bit characters, UTF-8 encoded
2070 QFile in(TEST_FILE(QLatin1String("I18nType30.qml")).toLocalFile());
2071 QVERIFY(in.open(QIODevice::ReadOnly));
2072 QFile out(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile());
2073 QVERIFY(out.open(QIODevice::WriteOnly));
2074 out.write(in.readAll());
2077 void tst_qdeclarativelanguage::aliasPropertyChangeSignals()
2080 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.qml"));
2083 QObject *o = component.create();
2086 QCOMPARE(o->property("test").toBool(), true);
2091 // QTCREATORBUG-2769
2093 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.2.qml"));
2096 QObject *o = component.create();
2099 QCOMPARE(o->property("test").toBool(), true);
2105 // Tests property initializers
2106 void tst_qdeclarativelanguage::propertyInit()
2109 QDeclarativeComponent component(&engine, TEST_FILE("propertyInit.1.qml"));
2112 QObject *o = component.create();
2115 QCOMPARE(o->property("test").toInt(), 1);
2121 QDeclarativeComponent component(&engine, TEST_FILE("propertyInit.2.qml"));
2124 QObject *o = component.create();
2127 QCOMPARE(o->property("test").toInt(), 123);
2133 // Test that registration order doesn't break type availability
2135 void tst_qdeclarativelanguage::registrationOrder()
2137 QDeclarativeComponent component(&engine, TEST_FILE("registrationOrder.qml"));
2139 QObject *o = component.create();
2141 QVERIFY(o->metaObject() == &MyVersion2Class::staticMetaObject);
2146 void tst_qdeclarativelanguage::remoteLoadCrash()
2148 TestHTTPServer server(14448);
2149 server.serveDirectory(testdata());
2151 QDeclarativeComponent component(&engine);
2152 component.setData("import QtQuick 1.0; Text {}", QUrl("http://127.0.0.1:14448/remoteLoadCrash.qml"));
2153 while (component.isLoading())
2154 QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
2156 QObject *o = component.create();
2160 QTEST_MAIN(tst_qdeclarativelanguage)
2162 #include "tst_qdeclarativelanguage.moc"