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 <QtQml/qqmlengine.h>
43 #include <QtQml/qqmlcomponent.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>
51 #include <private/qqmlproperty_p.h>
52 #include <private/qqmlmetatype_p.h>
53 #include <private/qqmlglobal_p.h>
55 #include "testtypes.h"
56 #include "testhttpserver.h"
58 DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)
61 Returns the path to some testdata file or directory.
63 QString testdata(QString const& name = QString())
65 static const QString dataDirectory = QDir::currentPath() + QLatin1String("/data");
66 QString result = dataDirectory;
67 if (!name.isEmpty()) {
68 result += QLatin1Char('/');
75 This test case covers QML language issues. This covers everything that does not
76 involve evaluating ECMAScript expressions and bindings.
78 Evaluation of expressions and bindings is covered in qmlecmascript
80 class tst_qqmllanguage : public QObject
85 QQmlMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter);
86 engine.addImportPath(testdata("lib"));
91 void cleanupTestCase();
96 void insertedSemicolon_data();
97 void insertedSemicolon();
100 void simpleContainer();
101 void interfaceProperty();
102 void interfaceQList();
103 void assignObjectToSignal();
104 void assignObjectToVariant();
105 void assignLiteralSignalProperty();
106 void assignQmlComponent();
107 void assignBasicTypes();
108 void assignTypeExtremes();
109 void assignCompositeToType();
110 void assignLiteralToVariant();
111 void assignLiteralToVar();
112 void customParserTypes();
113 void rootAsQmlComponent();
114 void inlineQmlComponents();
116 void autoNotifyConnection();
118 void dynamicProperties();
119 void dynamicPropertiesNested();
120 void listProperties();
121 void dynamicObjectProperties();
122 void dynamicSignalsAndSlots();
123 void simpleBindings();
124 void autoComponentCreation();
125 void propertyValueSource();
126 void attachedProperties();
127 void dynamicObjects();
128 void customVariantTypes();
131 void aliasProperties();
132 void aliasPropertiesAndSignals();
133 void aliasPropertyChangeSignals();
134 void componentCompositeType();
138 void onDestruction();
140 void defaultPropertyListOrder();
141 void declaredPropertyValues();
142 void dontDoubleCallClassBegin();
143 void reservedWords_data();
144 void reservedWords();
145 void inlineAssignmentsOverrideBindings();
146 void nestedComponentRoots();
147 void registrationOrder();
151 void basicRemote_data();
153 void importsBuiltin_data();
154 void importsBuiltin();
155 void importsLocal_data();
157 void importsRemote_data();
158 void importsRemote();
159 void importsInstalled_data();
160 void importsInstalled();
161 void importsOrder_data();
163 void importIncorrectCase();
164 void importJs_data();
167 void qmlAttachedPropertiesObjectMethod();
168 void customOnProperty();
169 void variantNotify();
172 void revisionOverloads();
175 void remoteLoadCrash();
176 void signalWithDefaultArg();
178 // regression tests for crashes
186 void testType(const QString& qml, const QString& type, const QString& error, bool partialMatch = false);
189 #define DETERMINE_ERRORS(errorfile,expected,actual)\
190 QList<QByteArray> expected; \
191 QList<QByteArray> actual; \
193 QFile file(testdata(QLatin1String(errorfile))); \
194 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
195 QByteArray data = file.readAll(); \
197 expected = data.split('\n'); \
198 expected.removeAll(QByteArray("")); \
199 QList<QQmlError> errors = component.errors(); \
200 for (int ii = 0; ii < errors.count(); ++ii) { \
201 const QQmlError &error = errors.at(ii); \
202 QByteArray errorStr = QByteArray::number(error.line()) + ":" + \
203 QByteArray::number(error.column()) + ":" + \
204 error.description().toUtf8(); \
205 actual << errorStr; \
209 #define VERIFY_ERRORS(errorfile) \
211 if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
212 qWarning() << "Unexpected Errors:" << component.errors(); \
213 QVERIFY(!component.isError()); \
214 QVERIFY(component.errors().isEmpty()); \
216 DETERMINE_ERRORS(errorfile,actual,expected);\
217 if (qgetenv("DEBUG") != "" && expected != actual) \
218 qWarning() << "Expected:" << expected << "Actual:" << actual; \
219 if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
220 QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
221 QVERIFY(file.open(QIODevice::WriteOnly)); \
222 for (int ii = 0; ii < actual.count(); ++ii) { \
223 file.write(actual.at(ii)); file.write("\n"); \
227 QCOMPARE(expected, actual); \
231 inline QUrl TEST_FILE(const QString &filename)
233 return QUrl::fromLocalFile(testdata(filename));
236 inline QUrl TEST_FILE(const char *filename)
238 return TEST_FILE(QLatin1String(filename));
241 void tst_qqmllanguage::cleanupTestCase()
243 QVERIFY(QFile::remove(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile()));
246 void tst_qqmllanguage::insertedSemicolon_data()
248 QTest::addColumn<QString>("file");
249 QTest::addColumn<QString>("errorFile");
250 QTest::addColumn<bool>("create");
252 QTest::newRow("insertedSemicolon.1") << "insertedSemicolon.1.qml" << "insertedSemicolon.1.errors.txt" << false;
255 void tst_qqmllanguage::insertedSemicolon()
257 QFETCH(QString, file);
258 QFETCH(QString, errorFile);
259 QFETCH(bool, create);
261 QQmlComponent component(&engine, TEST_FILE(file));
264 QObject *object = component.create();
265 QVERIFY(object == 0);
268 VERIFY_ERRORS(errorFile.toLatin1().constData());
271 void tst_qqmllanguage::errors_data()
273 QTest::addColumn<QString>("file");
274 QTest::addColumn<QString>("errorFile");
275 QTest::addColumn<bool>("create");
277 QTest::newRow("nonexistantProperty.1") << "nonexistantProperty.1.qml" << "nonexistantProperty.1.errors.txt" << false;
278 QTest::newRow("nonexistantProperty.2") << "nonexistantProperty.2.qml" << "nonexistantProperty.2.errors.txt" << false;
279 QTest::newRow("nonexistantProperty.3") << "nonexistantProperty.3.qml" << "nonexistantProperty.3.errors.txt" << false;
280 QTest::newRow("nonexistantProperty.4") << "nonexistantProperty.4.qml" << "nonexistantProperty.4.errors.txt" << false;
281 QTest::newRow("nonexistantProperty.5") << "nonexistantProperty.5.qml" << "nonexistantProperty.5.errors.txt" << false;
282 QTest::newRow("nonexistantProperty.6") << "nonexistantProperty.6.qml" << "nonexistantProperty.6.errors.txt" << false;
284 QTest::newRow("wrongType (string for int)") << "wrongType.1.qml" << "wrongType.1.errors.txt" << false;
285 QTest::newRow("wrongType (int for bool)") << "wrongType.2.qml" << "wrongType.2.errors.txt" << false;
286 QTest::newRow("wrongType (bad rect)") << "wrongType.3.qml" << "wrongType.3.errors.txt" << false;
288 QTest::newRow("wrongType (invalid enum)") << "wrongType.4.qml" << "wrongType.4.errors.txt" << false;
289 QTest::newRow("wrongType (int for uint)") << "wrongType.5.qml" << "wrongType.5.errors.txt" << false;
290 QTest::newRow("wrongType (string for real)") << "wrongType.6.qml" << "wrongType.6.errors.txt" << false;
291 QTest::newRow("wrongType (int for color)") << "wrongType.7.qml" << "wrongType.7.errors.txt" << false;
292 QTest::newRow("wrongType (int for date)") << "wrongType.8.qml" << "wrongType.8.errors.txt" << false;
293 QTest::newRow("wrongType (int for time)") << "wrongType.9.qml" << "wrongType.9.errors.txt" << false;
294 QTest::newRow("wrongType (int for datetime)") << "wrongType.10.qml" << "wrongType.10.errors.txt" << false;
295 QTest::newRow("wrongType (string for point)") << "wrongType.11.qml" << "wrongType.11.errors.txt" << false;
296 QTest::newRow("wrongType (color for size)") << "wrongType.12.qml" << "wrongType.12.errors.txt" << false;
297 QTest::newRow("wrongType (number string for int)") << "wrongType.13.qml" << "wrongType.13.errors.txt" << false;
298 QTest::newRow("wrongType (int for string)") << "wrongType.14.qml" << "wrongType.14.errors.txt" << false;
299 QTest::newRow("wrongType (int for url)") << "wrongType.15.qml" << "wrongType.15.errors.txt" << false;
300 QTest::newRow("wrongType (invalid object)") << "wrongType.16.qml" << "wrongType.16.errors.txt" << false;
301 QTest::newRow("wrongType (int for enum)") << "wrongType.17.qml" << "wrongType.17.errors.txt" << false;
303 QTest::newRow("readOnly.1") << "readOnly.1.qml" << "readOnly.1.errors.txt" << false;
304 QTest::newRow("readOnly.2") << "readOnly.2.qml" << "readOnly.2.errors.txt" << false;
305 QTest::newRow("readOnly.3") << "readOnly.3.qml" << "readOnly.3.errors.txt" << false;
306 QTest::newRow("readOnly.4") << "readOnly.4.qml" << "readOnly.4.errors.txt" << false;
307 QTest::newRow("readOnly.5") << "readOnly.5.qml" << "readOnly.5.errors.txt" << false;
309 QTest::newRow("listAssignment.1") << "listAssignment.1.qml" << "listAssignment.1.errors.txt" << false;
310 QTest::newRow("listAssignment.2") << "listAssignment.2.qml" << "listAssignment.2.errors.txt" << false;
311 QTest::newRow("listAssignment.3") << "listAssignment.3.qml" << "listAssignment.3.errors.txt" << false;
313 QTest::newRow("invalidID.1") << "invalidID.qml" << "invalidID.errors.txt" << false;
314 QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
315 QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
316 QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
317 QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
318 QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false;
319 QTest::newRow("invalidID.7") << "invalidID.7.qml" << "invalidID.7.errors.txt" << false;
320 QTest::newRow("invalidID.8") << "invalidID.8.qml" << "invalidID.8.errors.txt" << false;
321 QTest::newRow("invalidID.9") << "invalidID.9.qml" << "invalidID.9.errors.txt" << false;
323 QTest::newRow("scriptString.1") << "scriptString.1.qml" << "scriptString.1.errors.txt" << false;
324 QTest::newRow("scriptString.2") << "scriptString.2.qml" << "scriptString.2.errors.txt" << false;
326 QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
327 QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;
328 QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false;
329 QTest::newRow("duplicateIDs") << "duplicateIDs.qml" << "duplicateIDs.errors.txt" << false;
330 QTest::newRow("unregisteredObject") << "unregisteredObject.qml" << "unregisteredObject.errors.txt" << false;
331 QTest::newRow("empty") << "empty.qml" << "empty.errors.txt" << false;
332 QTest::newRow("missingObject") << "missingObject.qml" << "missingObject.errors.txt" << false;
333 QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
334 QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
335 QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
336 QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
338 QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
339 QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
340 QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
341 QTest::newRow("invalidGroupedProperty.4") << "invalidGroupedProperty.4.qml" << "invalidGroupedProperty.4.errors.txt" << false;
342 QTest::newRow("invalidGroupedProperty.5") << "invalidGroupedProperty.5.qml" << "invalidGroupedProperty.5.errors.txt" << false;
343 QTest::newRow("invalidGroupedProperty.6") << "invalidGroupedProperty.6.qml" << "invalidGroupedProperty.6.errors.txt" << false;
344 QTest::newRow("invalidGroupedProperty.7") << "invalidGroupedProperty.7.qml" << "invalidGroupedProperty.7.errors.txt" << true;
345 QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
346 QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
347 QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
349 QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
350 QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
351 QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false;
352 QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false;
353 QTest::newRow("importNonExistOlder (installed)") << "importNonExistOlder.qml" << "importNonExistOlder.errors.txt" << false;
354 QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false;
355 QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false;
356 QTest::newRow("importFile") << "importFile.qml" << "importFile.errors.txt" << false;
358 QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false;
359 QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false;
360 QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false;
361 QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false;
362 QTest::newRow("signal.5") << "signal.5.qml" << "signal.5.errors.txt" << false;
364 QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
366 QTest::newRow("property.1") << "property.1.qml" << "property.1.errors.txt" << false;
367 QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
368 QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
369 QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
370 QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
371 QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
373 QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
375 QTest::newRow("Component.1") << "component.1.qml" << "component.1.errors.txt" << false;
376 QTest::newRow("Component.2") << "component.2.qml" << "component.2.errors.txt" << false;
377 QTest::newRow("Component.3") << "component.3.qml" << "component.3.errors.txt" << false;
378 QTest::newRow("Component.4") << "component.4.qml" << "component.4.errors.txt" << false;
379 QTest::newRow("Component.5") << "component.5.qml" << "component.5.errors.txt" << false;
380 QTest::newRow("Component.6") << "component.6.qml" << "component.6.errors.txt" << false;
381 QTest::newRow("Component.7") << "component.7.qml" << "component.7.errors.txt" << false;
382 QTest::newRow("Component.8") << "component.8.qml" << "component.8.errors.txt" << false;
383 QTest::newRow("Component.9") << "component.9.qml" << "component.9.errors.txt" << false;
385 QTest::newRow("MultiSet.1") << "multiSet.1.qml" << "multiSet.1.errors.txt" << false;
386 QTest::newRow("MultiSet.2") << "multiSet.2.qml" << "multiSet.2.errors.txt" << false;
387 QTest::newRow("MultiSet.3") << "multiSet.3.qml" << "multiSet.3.errors.txt" << false;
388 QTest::newRow("MultiSet.4") << "multiSet.4.qml" << "multiSet.4.errors.txt" << false;
389 QTest::newRow("MultiSet.5") << "multiSet.5.qml" << "multiSet.5.errors.txt" << false;
390 QTest::newRow("MultiSet.6") << "multiSet.6.qml" << "multiSet.6.errors.txt" << false;
391 QTest::newRow("MultiSet.7") << "multiSet.7.qml" << "multiSet.7.errors.txt" << false;
392 QTest::newRow("MultiSet.8") << "multiSet.8.qml" << "multiSet.8.errors.txt" << false;
393 QTest::newRow("MultiSet.9") << "multiSet.9.qml" << "multiSet.9.errors.txt" << false;
394 QTest::newRow("MultiSet.10") << "multiSet.10.qml" << "multiSet.10.errors.txt" << false;
395 QTest::newRow("MultiSet.11") << "multiSet.11.qml" << "multiSet.11.errors.txt" << false;
397 QTest::newRow("dynamicMeta.1") << "dynamicMeta.1.qml" << "dynamicMeta.1.errors.txt" << false;
398 QTest::newRow("dynamicMeta.2") << "dynamicMeta.2.qml" << "dynamicMeta.2.errors.txt" << false;
399 QTest::newRow("dynamicMeta.3") << "dynamicMeta.3.qml" << "dynamicMeta.3.errors.txt" << false;
400 QTest::newRow("dynamicMeta.4") << "dynamicMeta.4.qml" << "dynamicMeta.4.errors.txt" << false;
401 QTest::newRow("dynamicMeta.5") << "dynamicMeta.5.qml" << "dynamicMeta.5.errors.txt" << false;
403 QTest::newRow("invalidAlias.1") << "invalidAlias.1.qml" << "invalidAlias.1.errors.txt" << false;
404 QTest::newRow("invalidAlias.2") << "invalidAlias.2.qml" << "invalidAlias.2.errors.txt" << false;
405 QTest::newRow("invalidAlias.3") << "invalidAlias.3.qml" << "invalidAlias.3.errors.txt" << false;
406 QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false;
407 QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
408 QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
409 QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false;
410 QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
411 QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
412 QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
414 QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
415 QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
416 QTest::newRow("invalidAttachedProperty.3") << "invalidAttachedProperty.3.qml" << "invalidAttachedProperty.3.errors.txt" << false;
417 QTest::newRow("invalidAttachedProperty.4") << "invalidAttachedProperty.4.qml" << "invalidAttachedProperty.4.errors.txt" << false;
418 QTest::newRow("invalidAttachedProperty.5") << "invalidAttachedProperty.5.qml" << "invalidAttachedProperty.5.errors.txt" << false;
419 QTest::newRow("invalidAttachedProperty.6") << "invalidAttachedProperty.6.qml" << "invalidAttachedProperty.6.errors.txt" << false;
420 QTest::newRow("invalidAttachedProperty.7") << "invalidAttachedProperty.7.qml" << "invalidAttachedProperty.7.errors.txt" << false;
421 QTest::newRow("invalidAttachedProperty.8") << "invalidAttachedProperty.8.qml" << "invalidAttachedProperty.8.errors.txt" << false;
422 QTest::newRow("invalidAttachedProperty.9") << "invalidAttachedProperty.9.qml" << "invalidAttachedProperty.9.errors.txt" << false;
423 QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false;
424 QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false;
425 QTest::newRow("invalidAttachedProperty.12") << "invalidAttachedProperty.12.qml" << "invalidAttachedProperty.12.errors.txt" << false;
426 QTest::newRow("invalidAttachedProperty.13") << "invalidAttachedProperty.13.qml" << "invalidAttachedProperty.13.errors.txt" << false;
428 QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
429 QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
431 QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false;
432 QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false;
433 QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false;
434 QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false;
435 QTest::newRow("objectValueTypeProperty") << "objectValueTypeProperty.qml" << "objectValueTypeProperty.errors.txt" << false;
436 QTest::newRow("enumTypes") << "enumTypes.qml" << "enumTypes.errors.txt" << false;
437 QTest::newRow("noCreation") << "noCreation.qml" << "noCreation.errors.txt" << false;
438 QTest::newRow("destroyedSignal") << "destroyedSignal.qml" << "destroyedSignal.errors.txt" << false;
439 QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false;
440 QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false;
441 QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false;
442 QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false;
443 QTest::newRow("notAvailable") << "notAvailable.qml" << "notAvailable.errors.txt" << false;
444 QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
445 QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
446 QTest::newRow("incorrectCase") << "incorrectCase.qml"
447 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
448 << "incorrectCase.errors.insensitive.txt"
450 << "incorrectCase.errors.sensitive.txt"
454 QTest::newRow("metaobjectRevision.1") << "metaobjectRevision.1.qml" << "metaobjectRevision.1.errors.txt" << false;
455 QTest::newRow("metaobjectRevision.2") << "metaobjectRevision.2.qml" << "metaobjectRevision.2.errors.txt" << false;
456 QTest::newRow("metaobjectRevision.3") << "metaobjectRevision.3.qml" << "metaobjectRevision.3.errors.txt" << false;
458 QTest::newRow("invalidRoot.1") << "invalidRoot.1.qml" << "invalidRoot.1.errors.txt" << false;
459 QTest::newRow("invalidRoot.2") << "invalidRoot.2.qml" << "invalidRoot.2.errors.txt" << false;
460 QTest::newRow("invalidRoot.3") << "invalidRoot.3.qml" << "invalidRoot.3.errors.txt" << false;
461 QTest::newRow("invalidRoot.4") << "invalidRoot.4.qml" << "invalidRoot.4.errors.txt" << false;
463 QTest::newRow("invalidTypeName.1") << "invalidTypeName.1.qml" << "invalidTypeName.1.errors.txt" << false;
464 QTest::newRow("invalidTypeName.2") << "invalidTypeName.2.qml" << "invalidTypeName.2.errors.txt" << false;
465 QTest::newRow("invalidTypeName.3") << "invalidTypeName.3.qml" << "invalidTypeName.3.errors.txt" << false;
466 QTest::newRow("invalidTypeName.4") << "invalidTypeName.4.qml" << "invalidTypeName.4.errors.txt" << false;
468 QTest::newRow("Major version isolation") << "majorVersionIsolation.qml" << "majorVersionIsolation.errors.txt" << false;
472 void tst_qqmllanguage::errors()
474 QFETCH(QString, file);
475 QFETCH(QString, errorFile);
476 QFETCH(bool, create);
478 QQmlComponent component(&engine, TEST_FILE(file));
481 QObject *object = component.create();
482 QVERIFY(object == 0);
485 VERIFY_ERRORS(errorFile.toLatin1().constData());
488 void tst_qqmllanguage::simpleObject()
490 QQmlComponent component(&engine, TEST_FILE("simpleObject.qml"));
492 QObject *object = component.create();
493 QVERIFY(object != 0);
496 void tst_qqmllanguage::simpleContainer()
498 QQmlComponent component(&engine, TEST_FILE("simpleContainer.qml"));
500 MyContainer *container= qobject_cast<MyContainer*>(component.create());
501 QVERIFY(container != 0);
502 QCOMPARE(container->getChildren()->count(),2);
505 void tst_qqmllanguage::interfaceProperty()
507 QQmlComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
509 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
510 QVERIFY(object != 0);
511 QVERIFY(object->interface());
512 QVERIFY(object->interface()->id == 913);
515 void tst_qqmllanguage::interfaceQList()
517 QQmlComponent component(&engine, TEST_FILE("interfaceQList.qml"));
519 MyContainer *container= qobject_cast<MyContainer*>(component.create());
520 QVERIFY(container != 0);
521 QVERIFY(container->getQListInterfaces()->count() == 2);
522 for(int ii = 0; ii < 2; ++ii)
523 QVERIFY(container->getQListInterfaces()->at(ii)->id == 913);
526 void tst_qqmllanguage::assignObjectToSignal()
528 QQmlComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
530 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
531 QVERIFY(object != 0);
532 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
533 emit object->basicSignal();
536 void tst_qqmllanguage::assignObjectToVariant()
538 QQmlComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
540 QObject *object = component.create();
541 QVERIFY(object != 0);
542 QVariant v = object->property("a");
543 QVERIFY(v.userType() == qMetaTypeId<QObject *>());
546 void tst_qqmllanguage::assignLiteralSignalProperty()
548 QQmlComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
550 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
551 QVERIFY(object != 0);
552 QCOMPARE(object->onLiteralSignal(), 10);
555 // Test is an external component can be loaded and assigned (to a qlist)
556 void tst_qqmllanguage::assignQmlComponent()
558 QQmlComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
560 MyContainer *object = qobject_cast<MyContainer *>(component.create());
561 QVERIFY(object != 0);
562 QVERIFY(object->getChildren()->count() == 1);
563 QObject *child = object->getChildren()->at(0);
564 QCOMPARE(child->property("x"), QVariant(10));
565 QCOMPARE(child->property("y"), QVariant(11));
568 // Test literal assignment to all the basic types
569 void tst_qqmllanguage::assignBasicTypes()
571 QQmlComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
573 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
574 QVERIFY(object != 0);
575 QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
576 QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
577 QCOMPARE(object->stringProperty(), QString("Hello World!"));
578 QCOMPARE(object->uintProperty(), uint(10));
579 QCOMPARE(object->intProperty(), -19);
580 QCOMPARE((float)object->realProperty(), float(23.2));
581 QCOMPARE((float)object->doubleProperty(), float(-19.7));
582 QCOMPARE((float)object->floatProperty(), float(8.5));
583 QCOMPARE(object->colorProperty(), QColor("red"));
584 QCOMPARE(object->dateProperty(), QDate(1982, 11, 25));
585 QCOMPARE(object->timeProperty(), QTime(11, 11, 32));
586 QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1)));
587 QCOMPARE(object->pointProperty(), QPoint(99,13));
588 QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3));
589 QCOMPARE(object->sizeProperty(), QSize(99, 13));
590 QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2));
591 QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200));
592 QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99));
593 QCOMPARE(object->boolProperty(), true);
594 QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
595 QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2));
596 QCOMPARE(object->vector4Property(), QVector4D(10, 1, 2.2, 2.3));
598 encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
599 QCOMPARE(object->urlProperty(), component.url().resolved(encoded));
600 QVERIFY(object->objectProperty() != 0);
601 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
603 QCOMPARE(child->intProperty(), 8);
606 // Test edge case type assignments
607 void tst_qqmllanguage::assignTypeExtremes()
609 QQmlComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
611 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
612 QVERIFY(object != 0);
613 QCOMPARE(object->uintProperty(), 0xEE6B2800);
614 QCOMPARE(object->intProperty(), -0x77359400);
617 // Test that a composite type can assign to a property of its base type
618 void tst_qqmllanguage::assignCompositeToType()
620 QQmlComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
622 QObject *object = component.create();
623 QVERIFY(object != 0);
626 // Test that literals are stored correctly in variant properties
627 void tst_qqmllanguage::assignLiteralToVariant()
629 QQmlComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
631 QObject *object = component.create();
632 QVERIFY(object != 0);
634 QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
635 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
636 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
637 QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
638 QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
639 QCOMPARE(object->property("test6").userType(), (int)QVariant::PointF);
640 QCOMPARE(object->property("test7").userType(), (int)QVariant::SizeF);
641 QCOMPARE(object->property("test8").userType(), (int)QVariant::Vector3D);
642 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
643 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
644 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
645 QCOMPARE(object->property("test12").userType(), (int)QVariant::Vector4D);
647 QVERIFY(object->property("test1") == QVariant(1));
648 QVERIFY(object->property("test2") == QVariant((double)1.7));
649 QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!"))));
650 QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800)));
651 QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10)));
652 QVERIFY(object->property("test6") == QVariant(QPointF(10, 10)));
653 QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10)));
654 QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100)));
655 QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800"))));
656 QVERIFY(object->property("test10") == QVariant(bool(true)));
657 QVERIFY(object->property("test11") == QVariant(bool(false)));
658 QVERIFY(object->property("test12") == QVariant(QVector4D(100, 100, 100, 100)));
663 // Test that literals are stored correctly in "var" properties
664 // Note that behaviour differs from "variant" properties in that
665 // no conversion from "special strings" to QVariants is performed.
666 void tst_qqmllanguage::assignLiteralToVar()
668 QQmlComponent component(&engine, TEST_FILE("assignLiteralToVar.qml"));
670 QObject *object = component.create();
671 QVERIFY(object != 0);
673 QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
674 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
675 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
676 QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
677 QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
678 QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
679 QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
680 QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
681 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
682 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
683 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
684 QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
685 QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
686 QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
687 QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
688 QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
689 QCOMPARE(object->property("variantTest1Bound").userType(), (int)QMetaType::Int);
690 QCOMPARE(object->property("test1Bound").userType(), (int)QMetaType::Int);
692 QCOMPARE(object->property("test1"), QVariant(5));
693 QCOMPARE(object->property("test2"), QVariant((double)1.7));
694 QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
695 QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
696 QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
697 QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
698 QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
699 QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
700 QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
701 QCOMPARE(object->property("test10"), QVariant(bool(true)));
702 QCOMPARE(object->property("test11"), QVariant(bool(false)));
703 QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
704 QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
705 QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
706 QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
707 QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
708 QCOMPARE(object->property("variantTest1Bound"), QVariant(9));
709 QCOMPARE(object->property("test1Bound"), QVariant(11));
714 // Tests that custom parser types can be instantiated
715 void tst_qqmllanguage::customParserTypes()
717 QQmlComponent component(&engine, TEST_FILE("customParserTypes.qml"));
719 QObject *object = component.create();
720 QVERIFY(object != 0);
721 QVERIFY(object->property("count") == QVariant(2));
724 // Tests that the root item can be a custom component
725 void tst_qqmllanguage::rootAsQmlComponent()
727 QQmlComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
729 MyContainer *object = qobject_cast<MyContainer *>(component.create());
730 QVERIFY(object != 0);
731 QCOMPARE(object->property("x"), QVariant(11));
732 QCOMPARE(object->getChildren()->count(), 2);
735 // Tests that components can be specified inline
736 void tst_qqmllanguage::inlineQmlComponents()
738 QQmlComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
740 MyContainer *object = qobject_cast<MyContainer *>(component.create());
741 QVERIFY(object != 0);
742 QCOMPARE(object->getChildren()->count(), 1);
743 QQmlComponent *comp = qobject_cast<QQmlComponent *>(object->getChildren()->at(0));
745 MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
746 QVERIFY(compObject != 0);
747 QCOMPARE(compObject->value(), 11);
750 // Tests that types that have an id property have it set
751 void tst_qqmllanguage::idProperty()
753 QQmlComponent component(&engine, TEST_FILE("idProperty.qml"));
755 MyContainer *object = qobject_cast<MyContainer *>(component.create());
756 QVERIFY(object != 0);
757 QCOMPARE(object->getChildren()->count(), 1);
758 MyTypeObject *child =
759 qobject_cast<MyTypeObject *>(object->getChildren()->at(0));
761 QCOMPARE(child->id(), QString("myObjectId"));
762 QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
765 // Tests automatic connection to notify signals if "onBlahChanged" syntax is used
766 // even if the notify signal for "blah" is not called "blahChanged"
767 void tst_qqmllanguage::autoNotifyConnection()
769 QQmlComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
771 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
772 QVERIFY(object != 0);
773 QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
774 QVERIFY(prop.isValid());
776 QCOMPARE(prop.read(object), QVariant::fromValue(false));
777 object->setPropertyWithNotify(1);
778 QCOMPARE(prop.read(object), QVariant::fromValue(true));
781 // Tests that signals can be assigned to
782 void tst_qqmllanguage::assignSignal()
784 QQmlComponent component(&engine, TEST_FILE("assignSignal.qml"));
786 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
787 QVERIFY(object != 0);
788 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
789 emit object->basicSignal();
790 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)");
791 emit object->basicParameterizedSignal(9);
794 // Tests the creation and assignment of dynamic properties
795 void tst_qqmllanguage::dynamicProperties()
797 QQmlComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
799 QObject *object = component.create();
800 QVERIFY(object != 0);
801 QCOMPARE(object->property("intProperty"), QVariant(10));
802 QCOMPARE(object->property("boolProperty"), QVariant(false));
803 QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
804 QCOMPARE(object->property("realProperty"), QVariant((qreal)-19.9));
805 QCOMPARE(object->property("stringProperty"), QVariant("Hello World!"));
806 QCOMPARE(object->property("urlProperty"), QVariant(TEST_FILE("main.qml")));
807 QCOMPARE(object->property("colorProperty"), QVariant(QColor("red")));
808 QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2)));
809 QCOMPARE(object->property("varProperty"), QVariant("Hello World!"));
812 // Test that nested types can use dynamic properties
813 void tst_qqmllanguage::dynamicPropertiesNested()
815 QQmlComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
817 QObject *object = component.create();
818 QVERIFY(object != 0);
820 QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
821 QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
822 QCOMPARE(object->property("a").toInt(), 13); // New
823 QCOMPARE(object->property("b").toInt(), 12); // New
828 // Tests the creation and assignment to dynamic list properties
829 void tst_qqmllanguage::listProperties()
831 QQmlComponent component(&engine, TEST_FILE("listProperties.qml"));
833 QObject *object = component.create();
834 QVERIFY(object != 0);
836 QCOMPARE(object->property("test").toInt(), 2);
839 // Tests the creation and assignment of dynamic object properties
841 void tst_qqmllanguage::dynamicObjectProperties()
844 QQmlComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
846 QObject *object = component.create();
847 QVERIFY(object != 0);
849 QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
850 QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
853 QQmlComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
854 QEXPECT_FAIL("", "QTBUG-10822", Abort);
856 QObject *object = component.create();
857 QVERIFY(object != 0);
859 QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
863 // Tests the declaration of dynamic signals and slots
864 void tst_qqmllanguage::dynamicSignalsAndSlots()
866 QTest::ignoreMessage(QtDebugMsg, "1921");
868 QQmlComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
870 QObject *object = component.create();
871 QVERIFY(object != 0);
872 QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
873 QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
874 QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1);
875 QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
877 QCOMPARE(object->property("test").toInt(), 0);
878 QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
879 QCOMPARE(object->property("test").toInt(), 10);
882 void tst_qqmllanguage::simpleBindings()
884 QQmlComponent component(&engine, TEST_FILE("simpleBindings.qml"));
886 QObject *object = component.create();
887 QVERIFY(object != 0);
888 QCOMPARE(object->property("value1"), QVariant(10));
889 QCOMPARE(object->property("value2"), QVariant(10));
890 QCOMPARE(object->property("value3"), QVariant(21));
891 QCOMPARE(object->property("value4"), QVariant(10));
892 QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
895 void tst_qqmllanguage::autoComponentCreation()
897 QQmlComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
899 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
900 QVERIFY(object != 0);
901 QVERIFY(object->componentProperty() != 0);
902 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
904 QCOMPARE(child->realProperty(), qreal(9));
907 void tst_qqmllanguage::propertyValueSource()
910 QQmlComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
912 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
913 QVERIFY(object != 0);
915 QList<QObject *> valueSources;
916 QObjectList allChildren = object->findChildren<QObject*>();
917 foreach (QObject *child, allChildren) {
918 if (qobject_cast<QQmlPropertyValueSource *>(child))
919 valueSources.append(child);
922 QCOMPARE(valueSources.count(), 1);
923 MyPropertyValueSource *valueSource =
924 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
925 QVERIFY(valueSource != 0);
926 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
927 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
931 QQmlComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
933 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
934 QVERIFY(object != 0);
936 QList<QObject *> valueSources;
937 QObjectList allChildren = object->findChildren<QObject*>();
938 foreach (QObject *child, allChildren) {
939 if (qobject_cast<QQmlPropertyValueSource *>(child))
940 valueSources.append(child);
943 QCOMPARE(valueSources.count(), 1);
944 MyPropertyValueSource *valueSource =
945 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
946 QVERIFY(valueSource != 0);
947 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
948 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
952 void tst_qqmllanguage::attachedProperties()
954 QQmlComponent component(&engine, TEST_FILE("attachedProperties.qml"));
956 QObject *object = component.create();
957 QVERIFY(object != 0);
958 QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
959 QVERIFY(attached != 0);
960 QCOMPARE(attached->property("value"), QVariant(10));
961 QCOMPARE(attached->property("value2"), QVariant(13));
964 // Tests non-static object properties
965 void tst_qqmllanguage::dynamicObjects()
967 QQmlComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
969 QObject *object = component.create();
970 QVERIFY(object != 0);
973 // Tests the registration of custom variant string converters
974 void tst_qqmllanguage::customVariantTypes()
976 QQmlComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
978 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
979 QVERIFY(object != 0);
980 QCOMPARE(object->customType().a, 10);
983 void tst_qqmllanguage::valueTypes()
985 QQmlComponent component(&engine, TEST_FILE("valueTypes.qml"));
988 QString message = component.url().toString() + ":2:1: QML MyTypeObject: Binding loop detected for property \"rectProperty.width\"";
989 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
990 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
992 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
993 QVERIFY(object != 0);
996 QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
997 QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
998 QCOMPARE(object->intProperty(), 10);
1000 QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
1001 QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
1002 QCOMPARE(object->intProperty(), 12);
1006 QQmlProperty p(object, "rectProperty.x");
1007 QCOMPARE(p.read(), QVariant(12));
1009 QCOMPARE(p.read(), QVariant(13));
1011 quint32 r = QQmlPropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
1013 QQmlPropertyPrivate::restore(p2, r, object);
1014 QCOMPARE(p2.read(), QVariant(13));
1018 void tst_qqmllanguage::cppnamespace()
1021 QQmlComponent component(&engine, TEST_FILE("cppnamespace.qml"));
1023 QObject *object = component.create();
1024 QVERIFY(object != 0);
1029 QQmlComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
1031 QObject *object = component.create();
1032 QVERIFY(object != 0);
1037 void tst_qqmllanguage::aliasProperties()
1039 // Simple "int" alias
1041 QQmlComponent component(&engine, TEST_FILE("alias.1.qml"));
1043 QObject *object = component.create();
1044 QVERIFY(object != 0);
1046 // Read through alias
1047 QCOMPARE(object->property("valueAlias").toInt(), 10);
1048 object->setProperty("value", QVariant(13));
1049 QCOMPARE(object->property("valueAlias").toInt(), 13);
1051 // Write through alias
1052 object->setProperty("valueAlias", QVariant(19));
1053 QCOMPARE(object->property("valueAlias").toInt(), 19);
1054 QCOMPARE(object->property("value").toInt(), 19);
1059 // Complex object alias
1061 QQmlComponent component(&engine, TEST_FILE("alias.2.qml"));
1063 QObject *object = component.create();
1064 QVERIFY(object != 0);
1066 // Read through alias
1068 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1070 QCOMPARE(v->value(), 10);
1072 // Write through alias
1073 MyQmlObject *v2 = new MyQmlObject();
1074 v2->setParent(object);
1075 object->setProperty("aliasObject", qVariantFromValue(v2));
1077 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1086 QQmlComponent component(&engine, TEST_FILE("alias.3.qml"));
1088 QObject *object = component.create();
1089 QVERIFY(object != 0);
1091 QCOMPARE(object->property("value").toInt(), 1892);
1092 QCOMPARE(object->property("value2").toInt(), 1892);
1094 object->setProperty("value", QVariant(1313));
1095 QCOMPARE(object->property("value").toInt(), 1313);
1096 QCOMPARE(object->property("value2").toInt(), 1313);
1098 object->setProperty("value2", QVariant(8080));
1099 QCOMPARE(object->property("value").toInt(), 8080);
1100 QCOMPARE(object->property("value2").toInt(), 8080);
1107 QQmlComponent component(&engine, TEST_FILE("alias.4.qml"));
1109 QObject *object = component.create();
1110 QVERIFY(object != 0);
1112 QCOMPARE(object->property("enumAlias").toInt(), 1);
1119 QQmlComponent component(&engine, TEST_FILE("alias.5.qml"));
1121 QObject *object = component.create();
1122 QVERIFY(object != 0);
1124 QVariant v = object->property("otherAlias");
1125 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1126 MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
1127 QCOMPARE(o->value(), 10);
1131 v = object->property("otherAlias");
1132 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1133 o = qvariant_cast<MyQmlObject*>(v);
1139 // Nested aliases - this used to cause a crash
1141 QQmlComponent component(&engine, TEST_FILE("alias.6.qml"));
1143 QObject *object = component.create();
1144 QVERIFY(object != 0);
1146 QCOMPARE(object->property("a").toInt(), 1923);
1149 // Ptr Alias Cleanup - check that aliases to ptr types return 0
1150 // if the object aliased to is removed
1152 QQmlComponent component(&engine, TEST_FILE("alias.7.qml"));
1155 QObject *object = component.create();
1156 QVERIFY(object != 0);
1158 QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
1159 QVERIFY(object1 != 0);
1160 QObject *object2 = qvariant_cast<QObject *>(object1->property("object"));
1161 QVERIFY(object2 != 0);
1163 QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
1164 QVERIFY(alias == object2);
1168 QObject *alias2 = object; // "Random" start value
1170 void *a[] = { &alias2, 0, &status };
1171 QMetaObject::metacall(object, QMetaObject::ReadProperty,
1172 object->metaObject()->indexOfProperty("aliasedObject"), a);
1173 QVERIFY(alias2 == 0);
1176 // Simple composite type
1178 QQmlComponent component(&engine, TEST_FILE("alias.8.qml"));
1180 QObject *object = component.create();
1181 QVERIFY(object != 0);
1183 QCOMPARE(object->property("value").toInt(), 10);
1188 // Complex composite type
1190 QQmlComponent component(&engine, TEST_FILE("alias.9.qml"));
1192 QObject *object = component.create();
1193 QVERIFY(object != 0);
1195 QCOMPARE(object->property("value").toInt(), 10);
1201 // Simple "int" alias
1203 QQmlComponent component(&engine, TEST_FILE("alias.10.qml"));
1205 QObject *object = component.create();
1206 QVERIFY(object != 0);
1208 // Read through alias
1209 QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8));
1210 object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
1211 QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
1213 // Write through alias
1214 object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
1215 QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
1216 QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
1221 // Valuetype sub-alias
1223 QQmlComponent component(&engine, TEST_FILE("alias.11.qml"));
1225 QObject *object = component.create();
1226 QVERIFY(object != 0);
1228 // Read through alias
1229 QCOMPARE(object->property("aliasProperty").toInt(), 19);
1230 object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
1231 QCOMPARE(object->property("aliasProperty").toInt(), 33);
1233 // Write through alias
1234 object->setProperty("aliasProperty", QVariant(4));
1235 QCOMPARE(object->property("aliasProperty").toInt(), 4);
1236 QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
1242 // QTBUG-13374 Test that alias properties and signals can coexist
1243 void tst_qqmllanguage::aliasPropertiesAndSignals()
1245 QQmlComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
1247 QObject *o = component.create();
1249 QCOMPARE(o->property("test").toBool(), true);
1253 // Test that the root element in a composite type can be a Component
1254 void tst_qqmllanguage::componentCompositeType()
1256 QQmlComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
1258 QObject *object = component.create();
1259 QVERIFY(object != 0);
1262 class TestType : public QObject {
1265 TestType(QObject *p=0) : QObject(p) {}
1268 class TestType2 : public QObject {
1271 TestType2(QObject *p=0) : QObject(p) {}
1274 void tst_qqmllanguage::i18n_data()
1276 QTest::addColumn<QString>("file");
1277 QTest::addColumn<QString>("stringProperty");
1278 QTest::newRow("i18nStrings") << "i18nStrings.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245 (5 accented 'a' letters)");
1279 QTest::newRow("i18nDeclaredPropertyNames") << "i18nDeclaredPropertyNames.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 10");
1280 QTest::newRow("i18nDeclaredPropertyUse") << "i18nDeclaredPropertyUse.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 15");
1281 QTest::newRow("i18nScript") << "i18nScript.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 20");
1282 QTest::newRow("i18nType") << "i18nType.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 30");
1283 QTest::newRow("i18nNameSpace") << "i18nNameSpace.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 40");
1286 void tst_qqmllanguage::i18n()
1288 QFETCH(QString, file);
1289 QFETCH(QString, stringProperty);
1290 QQmlComponent component(&engine, TEST_FILE(file));
1292 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1293 QVERIFY(object != 0);
1294 QCOMPARE(object->stringProperty(), stringProperty);
1299 // Check that the Component::onCompleted attached property works
1300 void tst_qqmllanguage::onCompleted()
1302 QQmlComponent component(&engine, TEST_FILE("onCompleted.qml"));
1304 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1305 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1306 QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
1307 QObject *object = component.create();
1308 QVERIFY(object != 0);
1311 // Check that the Component::onDestruction attached property works
1312 void tst_qqmllanguage::onDestruction()
1314 QQmlComponent component(&engine, TEST_FILE("onDestruction.qml"));
1316 QObject *object = component.create();
1317 QVERIFY(object != 0);
1318 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1319 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1320 QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
1324 // Check that assignments to QQmlScriptString properties work
1325 void tst_qqmllanguage::scriptString()
1328 QQmlComponent component(&engine, TEST_FILE("scriptString.qml"));
1331 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1332 QVERIFY(object != 0);
1333 QCOMPARE(object->scriptProperty().script(), QString("foo + bar"));
1334 QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object));
1335 QCOMPARE(object->scriptProperty().context(), qmlContext(object));
1337 QVERIFY(object->grouped() != 0);
1338 QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)"));
1339 QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object));
1340 QCOMPARE(object->grouped()->script().context(), qmlContext(object));
1344 QQmlComponent component(&engine, TEST_FILE("scriptString2.qml"));
1347 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1348 QVERIFY(object != 0);
1349 QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
1353 QQmlComponent component(&engine, TEST_FILE("scriptString3.qml"));
1356 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1357 QVERIFY(object != 0);
1358 QCOMPARE(object->scriptProperty().script(), QString("12.345"));
1362 QQmlComponent component(&engine, TEST_FILE("scriptString4.qml"));
1365 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1366 QVERIFY(object != 0);
1367 QCOMPARE(object->scriptProperty().script(), QString("true"));
1371 // Check that default property assignments are correctly spliced into explicit
1372 // property assignments
1373 void tst_qqmllanguage::defaultPropertyListOrder()
1375 QQmlComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
1378 MyContainer *container = qobject_cast<MyContainer *>(component.create());
1379 QVERIFY(container != 0);
1381 QCOMPARE(container->getChildren()->count(), 6);
1382 QCOMPARE(container->getChildren()->at(0)->property("index"), QVariant(0));
1383 QCOMPARE(container->getChildren()->at(1)->property("index"), QVariant(1));
1384 QCOMPARE(container->getChildren()->at(2)->property("index"), QVariant(2));
1385 QCOMPARE(container->getChildren()->at(3)->property("index"), QVariant(3));
1386 QCOMPARE(container->getChildren()->at(4)->property("index"), QVariant(4));
1387 QCOMPARE(container->getChildren()->at(5)->property("index"), QVariant(5));
1390 void tst_qqmllanguage::declaredPropertyValues()
1392 QQmlComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
1396 void tst_qqmllanguage::dontDoubleCallClassBegin()
1398 QQmlComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml"));
1399 QObject *o = component.create();
1402 MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
1404 QCOMPARE(o2->classBeginCount(), 1);
1405 QCOMPARE(o2->componentCompleteCount(), 1);
1410 void tst_qqmllanguage::reservedWords_data()
1412 QTest::addColumn<QByteArray>("word");
1414 QTest::newRow("abstract") << QByteArray("abstract");
1415 QTest::newRow("as") << QByteArray("as");
1416 QTest::newRow("boolean") << QByteArray("boolean");
1417 QTest::newRow("break") << QByteArray("break");
1418 QTest::newRow("byte") << QByteArray("byte");
1419 QTest::newRow("case") << QByteArray("case");
1420 QTest::newRow("catch") << QByteArray("catch");
1421 QTest::newRow("char") << QByteArray("char");
1422 QTest::newRow("class") << QByteArray("class");
1423 QTest::newRow("continue") << QByteArray("continue");
1424 QTest::newRow("const") << QByteArray("const");
1425 QTest::newRow("debugger") << QByteArray("debugger");
1426 QTest::newRow("default") << QByteArray("default");
1427 QTest::newRow("delete") << QByteArray("delete");
1428 QTest::newRow("do") << QByteArray("do");
1429 QTest::newRow("double") << QByteArray("double");
1430 QTest::newRow("else") << QByteArray("else");
1431 QTest::newRow("enum") << QByteArray("enum");
1432 QTest::newRow("export") << QByteArray("export");
1433 QTest::newRow("extends") << QByteArray("extends");
1434 QTest::newRow("false") << QByteArray("false");
1435 QTest::newRow("final") << QByteArray("final");
1436 QTest::newRow("finally") << QByteArray("finally");
1437 QTest::newRow("float") << QByteArray("float");
1438 QTest::newRow("for") << QByteArray("for");
1439 QTest::newRow("function") << QByteArray("function");
1440 QTest::newRow("goto") << QByteArray("goto");
1441 QTest::newRow("if") << QByteArray("if");
1442 QTest::newRow("implements") << QByteArray("implements");
1443 QTest::newRow("import") << QByteArray("import");
1444 QTest::newRow("in") << QByteArray("in");
1445 QTest::newRow("instanceof") << QByteArray("instanceof");
1446 QTest::newRow("int") << QByteArray("int");
1447 QTest::newRow("interface") << QByteArray("interface");
1448 QTest::newRow("long") << QByteArray("long");
1449 QTest::newRow("native") << QByteArray("native");
1450 QTest::newRow("new") << QByteArray("new");
1451 QTest::newRow("null") << QByteArray("null");
1452 QTest::newRow("package") << QByteArray("package");
1453 QTest::newRow("private") << QByteArray("private");
1454 QTest::newRow("protected") << QByteArray("protected");
1455 QTest::newRow("public") << QByteArray("public");
1456 QTest::newRow("return") << QByteArray("return");
1457 QTest::newRow("short") << QByteArray("short");
1458 QTest::newRow("static") << QByteArray("static");
1459 QTest::newRow("super") << QByteArray("super");
1460 QTest::newRow("switch") << QByteArray("switch");
1461 QTest::newRow("synchronized") << QByteArray("synchronized");
1462 QTest::newRow("this") << QByteArray("this");
1463 QTest::newRow("throw") << QByteArray("throw");
1464 QTest::newRow("throws") << QByteArray("throws");
1465 QTest::newRow("transient") << QByteArray("transient");
1466 QTest::newRow("true") << QByteArray("true");
1467 QTest::newRow("try") << QByteArray("try");
1468 QTest::newRow("typeof") << QByteArray("typeof");
1469 QTest::newRow("var") << QByteArray("var");
1470 QTest::newRow("void") << QByteArray("void");
1471 QTest::newRow("volatile") << QByteArray("volatile");
1472 QTest::newRow("while") << QByteArray("while");
1473 QTest::newRow("with") << QByteArray("with");
1476 void tst_qqmllanguage::reservedWords()
1478 QFETCH(QByteArray, word);
1479 QQmlComponent component(&engine);
1480 component.setData("import QtQuick 2.0\nQtObject { property string " + word + " }", QUrl());
1481 QCOMPARE(component.errorString(), QLatin1String(":2 Expected token `identifier'\n"));
1484 // Check that first child of qml is of given type. Empty type insists on error.
1485 void tst_qqmllanguage::testType(const QString& qml, const QString& type, const QString& expectederror, bool partialMatch)
1487 QQmlComponent component(&engine);
1488 component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
1490 QTRY_VERIFY(!component.isLoading());
1492 if (type.isEmpty()) {
1493 QVERIFY(component.isError());
1494 QString actualerror;
1495 foreach (const QQmlError e, component.errors()) {
1496 if (!actualerror.isEmpty())
1497 actualerror.append("; ");
1498 actualerror.append(e.description());
1500 QCOMPARE(actualerror.left(partialMatch ? expectederror.length(): -1),expectederror);
1503 QObject *object = component.create();
1504 QVERIFY(object != 0);
1505 QCOMPARE(QString(object->metaObject()->className()), type);
1511 void tst_qqmllanguage::inlineAssignmentsOverrideBindings()
1513 QQmlComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml"));
1515 QObject *o = component.create();
1517 QCOMPARE(o->property("test").toInt(), 11);
1522 void tst_qqmllanguage::nestedComponentRoots()
1524 QQmlComponent component(&engine, TEST_FILE("nestedComponentRoots.qml"));
1527 // Import tests (QT-558)
1528 void tst_qqmllanguage::importsBuiltin_data()
1532 QTest::addColumn<QString>("qml");
1533 QTest::addColumn<QString>("type");
1534 QTest::addColumn<QString>("error");
1537 QTest::newRow("missing import")
1540 << "Test is not a type";
1541 QTest::newRow("not in version 0.0")
1542 << "import com.nokia.Test 0.0\n"
1545 << "Test is not a type";
1546 QTest::newRow("version not installed")
1547 << "import com.nokia.Test 99.0\n"
1550 << "module \"com.nokia.Test\" version 99.0 is not installed";
1551 QTest::newRow("in version 0.0")
1552 << "import com.nokia.Test 0.0\n"
1556 QTest::newRow("qualified in version 0.0")
1557 << "import com.nokia.Test 0.0 as T\n"
1561 QTest::newRow("in version 1.0")
1562 << "import com.nokia.Test 1.0\n"
1566 QTest::newRow("qualified wrong")
1567 << "import com.nokia.Test 1.0 as T\n" // QT-610
1570 << "Test is not a type";
1571 QTest::newRow("qualified right")
1572 << "import com.nokia.Test 1.0 as T\n"
1576 QTest::newRow("qualified right but not in version 0.0")
1577 << "import com.nokia.Test 0.0 as T\n"
1580 << "T.Test is not a type";
1581 QTest::newRow("in version 1.1")
1582 << "import com.nokia.Test 1.1\n"
1586 QTest::newRow("in version 1.3")
1587 << "import com.nokia.Test 1.3\n"
1591 QTest::newRow("in version 1.5")
1592 << "import com.nokia.Test 1.5\n"
1596 QTest::newRow("changed in version 1.8")
1597 << "import com.nokia.Test 1.8\n"
1601 QTest::newRow("in version 1.12")
1602 << "import com.nokia.Test 1.12\n"
1606 QTest::newRow("old in version 1.9")
1607 << "import com.nokia.Test 1.9\n"
1611 QTest::newRow("old in version 1.11")
1612 << "import com.nokia.Test 1.11\n"
1616 QTest::newRow("multiversion 1")
1617 << "import com.nokia.Test 1.11\n"
1618 "import com.nokia.Test 1.12\n"
1620 << (!qmlCheckTypes()?"TestType2":"")
1621 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test/ in version 1.12 and 1.11");
1622 QTest::newRow("multiversion 2")
1623 << "import com.nokia.Test 1.11\n"
1624 "import com.nokia.Test 1.12\n"
1626 << (!qmlCheckTypes()?"TestType":"")
1627 << (!qmlCheckTypes()?"":"OldTest is ambiguous. Found in com/nokia/Test/ in version 1.12 and 1.11");
1628 QTest::newRow("qualified multiversion 3")
1629 << "import com.nokia.Test 1.0 as T0\n"
1630 "import com.nokia.Test 1.8 as T8\n"
1634 QTest::newRow("qualified multiversion 4")
1635 << "import com.nokia.Test 1.0 as T0\n"
1636 "import com.nokia.Test 1.8 as T8\n"
1642 void tst_qqmllanguage::importsBuiltin()
1644 QFETCH(QString, qml);
1645 QFETCH(QString, type);
1646 QFETCH(QString, error);
1647 testType(qml,type,error);
1650 void tst_qqmllanguage::importsLocal_data()
1652 QTest::addColumn<QString>("qml");
1653 QTest::addColumn<QString>("type");
1654 QTest::addColumn<QString>("error");
1657 QTest::newRow("local import")
1658 << "import \"subdir\"\n" // QT-613
1660 << "QQuickRectangle"
1662 QTest::newRow("local import second")
1663 << "import QtQuick 2.0\nimport \"subdir\"\n"
1665 << "QQuickRectangle"
1667 QTest::newRow("local import subsubdir")
1668 << "import QtQuick 2.0\nimport \"subdir/subsubdir\"\n"
1670 << "QQuickRectangle"
1672 QTest::newRow("local import QTBUG-7721 A")
1673 << "subdir.Test {}" // no longer allowed (QTBUG-7721)
1675 << "subdir.Test - subdir is not a namespace";
1676 QTest::newRow("local import QTBUG-7721 B")
1677 << "import \"subdir\" as X\n"
1678 "X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
1680 << "X.subsubdir.SubTest - nested namespaces not allowed";
1681 QTest::newRow("local import as")
1682 << "import \"subdir\" as T\n"
1684 << "QQuickRectangle"
1686 QTest::newRow("wrong local import as")
1687 << "import \"subdir\" as T\n"
1690 << "Test is not a type";
1691 QTest::newRow("library precedence over local import")
1692 << "import \"subdir\"\n"
1693 "import com.nokia.Test 1.0\n"
1695 << (!qmlCheckTypes()?"TestType":"")
1696 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test/ and in subdir/");
1699 void tst_qqmllanguage::importsLocal()
1701 QFETCH(QString, qml);
1702 QFETCH(QString, type);
1703 QFETCH(QString, error);
1704 testType(qml,type,error);
1707 void tst_qqmllanguage::basicRemote_data()
1709 QTest::addColumn<QUrl>("url");
1710 QTest::addColumn<QString>("type");
1711 QTest::addColumn<QString>("error");
1713 QString serverdir = "http://127.0.0.1:14447/qtest/qml/qqmllanguage/";
1715 QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
1716 QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << "";
1717 QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
1720 void tst_qqmllanguage::basicRemote()
1723 QFETCH(QString, type);
1724 QFETCH(QString, error);
1726 TestHTTPServer server(14447);
1727 server.serveDirectory(testdata());
1729 QQmlComponent component(&engine, url);
1731 QTRY_VERIFY(!component.isLoading());
1733 if (error.isEmpty()) {
1734 if (component.isError())
1735 qDebug() << component.errors();
1736 QVERIFY(!component.isError());
1738 QVERIFY(component.isError());
1742 void tst_qqmllanguage::importsRemote_data()
1744 QTest::addColumn<QString>("qml");
1745 QTest::addColumn<QString>("type");
1746 QTest::addColumn<QString>("error");
1748 QString serverdir = "http://127.0.0.1:14447/qtest/qml/qqmllanguage";
1750 QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QQuickRectangle"
1752 QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QQuickText"
1754 QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QQuickImage"
1756 QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
1757 << "WrongTestLocal is not a type";
1758 QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
1759 << "LocalInternal is not a type";
1760 QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""
1761 << "UndeclaredLocal is not a type";
1764 void tst_qqmllanguage::importsRemote()
1766 QFETCH(QString, qml);
1767 QFETCH(QString, type);
1768 QFETCH(QString, error);
1770 TestHTTPServer server(14447);
1771 server.serveDirectory(testdata());
1773 testType(qml,type,error);
1776 void tst_qqmllanguage::importsInstalled_data()
1780 QTest::addColumn<QString>("qml");
1781 QTest::addColumn<QString>("type");
1782 QTest::addColumn<QString>("error");
1785 QTest::newRow("installed import 0")
1786 << "import com.nokia.installedtest0 0.0\n"
1787 "InstalledTestTP {}"
1788 << "QQuickRectangle"
1790 QTest::newRow("installed import 0 as TP")
1791 << "import com.nokia.installedtest0 0.0 as TP\n"
1792 "TP.InstalledTestTP {}"
1793 << "QQuickRectangle"
1795 QTest::newRow("installed import 1")
1796 << "import com.nokia.installedtest 1.0\n"
1798 << "QQuickRectangle"
1800 QTest::newRow("installed import 2")
1801 << "import com.nokia.installedtest 1.3\n"
1803 << "QQuickRectangle"
1805 QTest::newRow("installed import 3")
1806 << "import com.nokia.installedtest 1.4\n"
1810 QTest::newRow("installed import minor version not available") // QTBUG-11936
1811 << "import com.nokia.installedtest 0.1\n"
1814 << "module \"com.nokia.installedtest\" version 0.1 is not installed";
1815 QTest::newRow("installed import minor version not available") // QTBUG-9627
1816 << "import com.nokia.installedtest 1.10\n"
1819 << "module \"com.nokia.installedtest\" version 1.10 is not installed";
1820 QTest::newRow("installed import major version not available") // QTBUG-9627
1821 << "import com.nokia.installedtest 9.0\n"
1824 << "module \"com.nokia.installedtest\" version 9.0 is not installed";
1825 QTest::newRow("installed import visibility") // QT-614
1826 << "import com.nokia.installedtest 1.4\n"
1829 << "PrivateType is not a type";
1832 void tst_qqmllanguage::importsInstalled()
1834 QFETCH(QString, qml);
1835 QFETCH(QString, type);
1836 QFETCH(QString, error);
1837 testType(qml,type,error);
1841 void tst_qqmllanguage::importsOrder_data()
1843 QTest::addColumn<QString>("qml");
1844 QTest::addColumn<QString>("type");
1845 QTest::addColumn<QString>("error");
1846 QTest::addColumn<bool>("partialMatch");
1848 QTest::newRow("double import") <<
1849 "import com.nokia.installedtest 1.4\n"
1850 "import com.nokia.installedtest 1.4\n"
1852 << (!qmlCheckTypes()?"QQuickText":"")
1853 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.4 and 1.4")
1855 QTest::newRow("installed import overrides 1") <<
1856 "import com.nokia.installedtest 1.0\n"
1857 "import com.nokia.installedtest 1.4\n"
1859 << (!qmlCheckTypes()?"QQuickText":"")
1860 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.4 and 1.0")
1862 QTest::newRow("installed import overrides 2") <<
1863 "import com.nokia.installedtest 1.4\n"
1864 "import com.nokia.installedtest 1.0\n"
1866 << (!qmlCheckTypes()?"QQuickRectangle":"")
1867 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.0 and 1.4")
1869 QTest::newRow("installed import re-overrides 1") <<
1870 "import com.nokia.installedtest 1.4\n"
1871 "import com.nokia.installedtest 1.0\n"
1872 "import com.nokia.installedtest 1.4\n"
1874 << (!qmlCheckTypes()?"QQuickText":"")
1875 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.4 and 1.0")
1877 QTest::newRow("installed import re-overrides 2") <<
1878 "import com.nokia.installedtest 1.4\n"
1879 "import com.nokia.installedtest 1.0\n"
1880 "import com.nokia.installedtest 1.4\n"
1881 "import com.nokia.installedtest 1.0\n"
1883 << (!qmlCheckTypes()?"QQuickRectangle":"")
1884 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.0 and 1.4")
1886 QTest::newRow("installed import versus builtin 1") <<
1887 "import com.nokia.installedtest 1.5\n"
1888 "import QtQuick 2.0\n"
1890 << (!qmlCheckTypes()?"QQuickRectangle":"")
1891 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in file://")
1893 QTest::newRow("installed import versus builtin 2") <<
1894 "import QtQuick 2.0\n"
1895 "import com.nokia.installedtest 1.5\n"
1897 << (!qmlCheckTypes()?"QQuickText":"")
1898 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest/ and in file://")
1900 QTest::newRow("namespaces cannot be overridden by types 1") <<
1901 "import QtQuick 2.0 as Rectangle\n"
1902 "import com.nokia.installedtest 1.5\n"
1905 << "Namespace Rectangle cannot be used as a type"
1907 QTest::newRow("namespaces cannot be overridden by types 2") <<
1908 "import QtQuick 2.0 as Rectangle\n"
1909 "import com.nokia.installedtest 1.5\n"
1910 "Rectangle.Image {}"
1914 QTest::newRow("local last 1") <<
1919 QTest::newRow("local last 2") <<
1920 "import com.nokia.installedtest 1.0\n"
1922 << (!qmlCheckTypes()?"QQuickRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
1923 << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest/ and in ")
1927 void tst_qqmllanguage::importsOrder()
1929 QFETCH(QString, qml);
1930 QFETCH(QString, type);
1931 QFETCH(QString, error);
1932 QFETCH(bool, partialMatch);
1933 testType(qml,type,error,partialMatch);
1936 void tst_qqmllanguage::importIncorrectCase()
1938 QQmlComponent component(&engine, TEST_FILE("importIncorrectCase.qml"));
1940 QList<QQmlError> errors = component.errors();
1941 QCOMPARE(errors.count(), 1);
1943 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1944 QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + testdata("lib/com/Nokia/installedtest/qmldir") + QLatin1String("\"");
1946 QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
1949 QCOMPARE(errors.at(0).description(), expectedError);
1952 void tst_qqmllanguage::importJs_data()
1954 QTest::addColumn<QString>("file");
1955 QTest::addColumn<QString>("errorFile");
1956 QTest::addColumn<bool>("performTest");
1958 QTest::newRow("defaultVersion")
1960 << "importJs.1.errors.txt"
1963 QTest::newRow("specifiedVersion")
1965 << "importJs.2.errors.txt"
1968 QTest::newRow("excludeExcessiveVersion")
1970 << "importJs.3.errors.txt"
1973 QTest::newRow("includeAppropriateVersion")
1975 << "importJs.4.errors.txt"
1978 QTest::newRow("noDefaultVersion")
1980 << "importJs.5.errors.txt"
1983 QTest::newRow("repeatImportFails")
1985 << "importJs.6.errors.txt"
1988 QTest::newRow("multipleVersionImportFails")
1990 << "importJs.7.errors.txt"
1993 QTest::newRow("namespacedImport")
1995 << "importJs.8.errors.txt"
1998 QTest::newRow("namespacedVersionedImport")
2000 << "importJs.9.errors.txt"
2003 QTest::newRow("namespacedRepeatImport")
2004 << "importJs.10.qml"
2005 << "importJs.10.errors.txt"
2009 void tst_qqmllanguage::importJs()
2011 QFETCH(QString, file);
2012 QFETCH(QString, errorFile);
2013 QFETCH(bool, performTest);
2015 QQmlComponent component(&engine, TEST_FILE(file));
2018 DETERMINE_ERRORS(errorFile.toLatin1().constData(),expected,actual);
2019 QCOMPARE(expected.size(), actual.size());
2020 for (int i = 0; i < expected.size(); ++i)
2022 size_t compareLen = std::min(expected.at(i).length(), actual.at(i).length());
2023 QCOMPARE(expected.at(i).left(compareLen), actual.at(i).left(compareLen));
2028 QObject *object = component.create();
2029 QVERIFY(object != 0);
2030 QCOMPARE(object->property("test").toBool(),true);
2035 void tst_qqmllanguage::qmlAttachedPropertiesObjectMethod()
2039 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
2040 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
2043 QQmlComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
2045 QObject *object = component.create();
2046 QVERIFY(object != 0);
2048 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
2049 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
2053 QQmlComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
2055 QObject *object = component.create();
2056 QVERIFY(object != 0);
2058 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
2059 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
2063 void tst_qqmllanguage::crash1()
2065 QQmlComponent component(&engine);
2066 component.setData("import QtQuick 2.0\nComponent {}", QUrl());
2069 void tst_qqmllanguage::crash2()
2071 QQmlComponent component(&engine, TEST_FILE("crash2.qml"));
2075 void tst_qqmllanguage::customOnProperty()
2077 QQmlComponent component(&engine, TEST_FILE("customOnProperty.qml"));
2080 QObject *object = component.create();
2081 QVERIFY(object != 0);
2083 QCOMPARE(object->property("on").toInt(), 10);
2089 void tst_qqmllanguage::variantNotify()
2091 QQmlComponent component(&engine, TEST_FILE("variantNotify.qml"));
2094 QObject *object = component.create();
2095 QVERIFY(object != 0);
2097 QCOMPARE(object->property("notifyCount").toInt(), 1);
2102 void tst_qqmllanguage::revisions()
2105 QQmlComponent component(&engine, TEST_FILE("revisions11.qml"));
2108 MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
2109 QVERIFY(object != 0);
2111 QCOMPARE(object->prop2(), 10.0);
2116 QQmlEngine myEngine;
2117 QQmlComponent component(&myEngine, TEST_FILE("revisionssub11.qml"));
2120 MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
2121 QVERIFY(object != 0);
2123 QCOMPARE(object->prop1(), 10.0);
2124 QCOMPARE(object->prop2(), 10.0);
2125 QCOMPARE(object->prop3(), 10.0);
2126 QCOMPARE(object->prop4(), 10.0);
2131 QQmlComponent component(&engine, TEST_FILE("versionedbase.qml"));
2133 MySubclass *object = qobject_cast<MySubclass*>(component.create());
2134 QVERIFY(object != 0);
2136 QCOMPARE(object->prop1(), 10.0);
2137 QCOMPARE(object->prop2(), 10.0);
2143 void tst_qqmllanguage::revisionOverloads()
2146 QQmlComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml"));
2150 QQmlComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml"));
2151 QEXPECT_FAIL("", "QTBUG-13849", Abort);
2153 VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt");
2157 void tst_qqmllanguage::initTestCase()
2159 QString testdataDir = QFileInfo(QFINDTESTDATA("data")).absolutePath();
2160 QVERIFY2(QDir::setCurrent(testdataDir), qPrintable("Could not chdir to " + testdataDir));
2164 // Registering the TestType class in other modules should have no adverse effects
2165 qmlRegisterType<TestType>("com.nokia.TestPre", 1, 0, "Test");
2167 qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP");
2168 qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test");
2169 qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test");
2170 qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test");
2171 qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest");
2172 qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test");
2174 // Registering the TestType class in other modules should have no adverse effects
2175 qmlRegisterType<TestType>("com.nokia.TestPost", 1, 0, "Test");
2177 // Create locale-specific file
2178 // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit
2179 // For iso8859-1 locale, this will just be data/I18nType?????.qml where ????? is 5 8-bit characters
2180 // For utf-8 locale, this will be data/I18nType??????????.qml where ?????????? is 5 8-bit characters, UTF-8 encoded
2181 QFile in(TEST_FILE(QLatin1String("I18nType30.qml")).toLocalFile());
2182 QVERIFY2(in.open(QIODevice::ReadOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(in.fileName(), in.errorString())));
2183 QFile out(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile());
2184 QVERIFY2(out.open(QIODevice::WriteOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(out.fileName(), out.errorString())));
2185 out.write(in.readAll());
2188 void tst_qqmllanguage::aliasPropertyChangeSignals()
2191 QQmlComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.qml"));
2194 QObject *o = component.create();
2197 QCOMPARE(o->property("test").toBool(), true);
2202 // QTCREATORBUG-2769
2204 QQmlComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.2.qml"));
2207 QObject *o = component.create();
2210 QCOMPARE(o->property("test").toBool(), true);
2216 // Tests property initializers
2217 void tst_qqmllanguage::propertyInit()
2220 QQmlComponent component(&engine, TEST_FILE("propertyInit.1.qml"));
2223 QObject *o = component.create();
2226 QCOMPARE(o->property("test").toInt(), 1);
2232 QQmlComponent component(&engine, TEST_FILE("propertyInit.2.qml"));
2235 QObject *o = component.create();
2238 QCOMPARE(o->property("test").toInt(), 123);
2244 // Test that registration order doesn't break type availability
2246 void tst_qqmllanguage::registrationOrder()
2248 QQmlComponent component(&engine, TEST_FILE("registrationOrder.qml"));
2250 QObject *o = component.create();
2252 QVERIFY(o->metaObject() == &MyVersion2Class::staticMetaObject);
2256 void tst_qqmllanguage::readonly()
2258 QQmlComponent component(&engine, TEST_FILE("readonly.qml"));
2260 QObject *o = component.create();
2263 QCOMPARE(o->property("test1").toInt(), 10);
2264 QCOMPARE(o->property("test2").toInt(), 18);
2265 QCOMPARE(o->property("test3").toInt(), 13);
2267 o->setProperty("testData", 13);
2269 QCOMPARE(o->property("test1").toInt(), 10);
2270 QCOMPARE(o->property("test2").toInt(), 22);
2271 QCOMPARE(o->property("test3").toInt(), 13);
2273 o->setProperty("testData2", 2);
2275 QCOMPARE(o->property("test1").toInt(), 10);
2276 QCOMPARE(o->property("test2").toInt(), 22);
2277 QCOMPARE(o->property("test3").toInt(), 2);
2279 o->setProperty("test1", 11);
2280 o->setProperty("test2", 11);
2281 o->setProperty("test3", 11);
2283 QCOMPARE(o->property("test1").toInt(), 10);
2284 QCOMPARE(o->property("test2").toInt(), 22);
2285 QCOMPARE(o->property("test3").toInt(), 2);
2290 void tst_qqmllanguage::receivers()
2292 QQmlComponent component(&engine, TEST_FILE("receivers.qml"));
2294 MyReceiversTestObject *o = qobject_cast<MyReceiversTestObject*>(component.create());
2296 QCOMPARE(o->mySignalCount(), 1);
2297 QCOMPARE(o->propChangedCount(), 2);
2303 void tst_qqmllanguage::remoteLoadCrash()
2305 TestHTTPServer server(14448);
2306 server.serveDirectory(testdata());
2308 QQmlComponent component(&engine);
2309 component.setData("import QtQuick 2.0; Text {}", QUrl("http://127.0.0.1:14448/remoteLoadCrash.qml"));
2310 while (component.isLoading())
2311 QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
2313 QObject *o = component.create();
2317 void tst_qqmllanguage::signalWithDefaultArg()
2319 QQmlComponent component(&engine, TEST_FILE("signalWithDefaultArg.qml"));
2321 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
2322 QVERIFY(object != 0);
2324 QCOMPARE(object->property("signalCount").toInt(), 0);
2325 QCOMPARE(object->property("signalArg").toInt(), 0);
2327 emit object->signalWithDefaultArg();
2328 QCOMPARE(object-> property("signalCount").toInt(), 1);
2329 QCOMPARE(object->property("signalArg").toInt(), 5);
2331 emit object->signalWithDefaultArg(15);
2332 QCOMPARE(object->property("signalCount").toInt(), 2);
2333 QCOMPARE(object->property("signalArg").toInt(), 15);
2335 const QMetaObject *metaObject = object->metaObject();
2337 metaObject->invokeMethod(object, "emitNoArgSignal");
2338 QCOMPARE(object->property("signalCount").toInt(), 3);
2339 QCOMPARE(object->property("signalArg").toInt(), 5);
2341 metaObject->invokeMethod(object, "emitArgSignal");
2342 QCOMPARE(object->property("signalCount").toInt(), 4);
2343 QCOMPARE(object->property("signalArg").toInt(), 22);
2349 void tst_qqmllanguage::globalEnums()
2351 qRegisterMetaType<MyEnum1Class::EnumA>();
2352 qRegisterMetaType<MyEnum2Class::EnumB>();
2353 qRegisterMetaType<Qt::TextFormat>();
2355 QQmlComponent component(&engine, TEST_FILE("globalEnums.qml"));
2357 QObject *o = component.create();
2360 MyEnum1Class *enum1Class = o->findChild<MyEnum1Class *>(QString::fromLatin1("enum1Class"));
2361 QVERIFY(enum1Class != 0);
2362 QVERIFY(enum1Class->getValue() == -1);
2364 MyEnumDerivedClass *enum2Class = o->findChild<MyEnumDerivedClass *>(QString::fromLatin1("enumDerivedClass"));
2365 QVERIFY(enum2Class != 0);
2366 QVERIFY(enum2Class->getValueA() == -1);
2367 QVERIFY(enum2Class->getValueB() == -1);
2368 QVERIFY(enum2Class->getValueC() == 0);
2369 QVERIFY(enum2Class->getValueD() == 0);
2370 QVERIFY(enum2Class->getValueE() == -1);
2371 QVERIFY(enum2Class->getValueE2() == -1);
2373 QVERIFY(enum2Class->property("aValue") == 0);
2374 QVERIFY(enum2Class->property("bValue") == 0);
2375 QVERIFY(enum2Class->property("cValue") == 0);
2376 QVERIFY(enum2Class->property("dValue") == 0);
2377 QVERIFY(enum2Class->property("eValue") == 0);
2378 QVERIFY(enum2Class->property("e2Value") == 0);
2380 QSignalSpy signalA(enum2Class, SIGNAL(valueAChanged(MyEnum1Class::EnumA)));
2381 QSignalSpy signalB(enum2Class, SIGNAL(valueBChanged(MyEnum2Class::EnumB)));
2383 QMetaObject::invokeMethod(o, "setEnumValues");
2385 QVERIFY(enum1Class->getValue() == MyEnum1Class::A_13);
2386 QVERIFY(enum2Class->getValueA() == MyEnum1Class::A_11);
2387 QVERIFY(enum2Class->getValueB() == MyEnum2Class::B_37);
2388 QVERIFY(enum2Class->getValueC() == Qt::RichText);
2389 QVERIFY(enum2Class->getValueD() == Qt::ElideMiddle);
2390 QVERIFY(enum2Class->getValueE() == MyEnum2Class::E_14);
2391 QVERIFY(enum2Class->getValueE2() == MyEnum2Class::E_76);
2393 QVERIFY(signalA.count() == 1);
2394 QVERIFY(signalB.count() == 1);
2396 QVERIFY(enum2Class->property("aValue") == MyEnum1Class::A_11);
2397 QVERIFY(enum2Class->property("bValue") == 37);
2398 QVERIFY(enum2Class->property("cValue") == 1);
2399 QVERIFY(enum2Class->property("dValue") == 2);
2400 QVERIFY(enum2Class->property("eValue") == 14);
2401 QVERIFY(enum2Class->property("e2Value") == 76);
2406 QTEST_MAIN(tst_qqmllanguage)
2408 #include "tst_qqmllanguage.moc"