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 assignLiteralToJSValue();
113 void bindJSValueToVar();
114 void bindJSValueToVariant();
115 void bindJSValueToType();
116 void bindTypeToJSValue();
117 void customParserTypes();
118 void rootAsQmlComponent();
119 void inlineQmlComponents();
121 void autoNotifyConnection();
123 void dynamicProperties();
124 void dynamicPropertiesNested();
125 void listProperties();
126 void dynamicObjectProperties();
127 void dynamicSignalsAndSlots();
128 void simpleBindings();
129 void autoComponentCreation();
130 void propertyValueSource();
131 void attachedProperties();
132 void dynamicObjects();
133 void customVariantTypes();
136 void aliasProperties();
137 void aliasPropertiesAndSignals();
138 void aliasPropertyChangeSignals();
139 void componentCompositeType();
143 void onDestruction();
145 void defaultPropertyListOrder();
146 void declaredPropertyValues();
147 void dontDoubleCallClassBegin();
148 void reservedWords_data();
149 void reservedWords();
150 void inlineAssignmentsOverrideBindings();
151 void nestedComponentRoots();
152 void registrationOrder();
156 void basicRemote_data();
158 void importsBuiltin_data();
159 void importsBuiltin();
160 void importsLocal_data();
162 void importsRemote_data();
163 void importsRemote();
164 void importsInstalled_data();
165 void importsInstalled();
166 void importsOrder_data();
168 void importIncorrectCase();
169 void importJs_data();
172 void qmlAttachedPropertiesObjectMethod();
173 void customOnProperty();
174 void variantNotify();
177 void revisionOverloads();
179 void subclassedUncreateableRevision_data();
180 void subclassedUncreateableRevision();
183 void remoteLoadCrash();
184 void signalWithDefaultArg();
186 // regression tests for crashes
191 void literals_data();
196 void testType(const QString& qml, const QString& type, const QString& error, bool partialMatch = false);
199 #define DETERMINE_ERRORS(errorfile,expected,actual)\
200 QList<QByteArray> expected; \
201 QList<QByteArray> actual; \
203 QFile file(testdata(QLatin1String(errorfile))); \
204 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
205 QByteArray data = file.readAll(); \
207 expected = data.split('\n'); \
208 expected.removeAll(QByteArray("")); \
209 QList<QQmlError> errors = component.errors(); \
210 for (int ii = 0; ii < errors.count(); ++ii) { \
211 const QQmlError &error = errors.at(ii); \
212 QByteArray errorStr = QByteArray::number(error.line()) + ":" + \
213 QByteArray::number(error.column()) + ":" + \
214 error.description().toUtf8(); \
215 actual << errorStr; \
219 #define VERIFY_ERRORS(errorfile) \
221 if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
222 qWarning() << "Unexpected Errors:" << component.errors(); \
223 QVERIFY(!component.isError()); \
224 QVERIFY(component.errors().isEmpty()); \
226 DETERMINE_ERRORS(errorfile,actual,expected);\
227 if (qgetenv("DEBUG") != "" && expected != actual) \
228 qWarning() << "Expected:" << expected << "Actual:" << actual; \
229 if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
230 QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
231 QVERIFY(file.open(QIODevice::WriteOnly)); \
232 for (int ii = 0; ii < actual.count(); ++ii) { \
233 file.write(actual.at(ii)); file.write("\n"); \
237 QCOMPARE(expected, actual); \
241 inline QUrl TEST_FILE(const QString &filename)
243 return QUrl::fromLocalFile(testdata(filename));
246 inline QUrl TEST_FILE(const char *filename)
248 return TEST_FILE(QLatin1String(filename));
251 void tst_qqmllanguage::cleanupTestCase()
253 QVERIFY(QFile::remove(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile()));
256 void tst_qqmllanguage::insertedSemicolon_data()
258 QTest::addColumn<QString>("file");
259 QTest::addColumn<QString>("errorFile");
260 QTest::addColumn<bool>("create");
262 QTest::newRow("insertedSemicolon.1") << "insertedSemicolon.1.qml" << "insertedSemicolon.1.errors.txt" << false;
265 void tst_qqmllanguage::insertedSemicolon()
267 QFETCH(QString, file);
268 QFETCH(QString, errorFile);
269 QFETCH(bool, create);
271 QQmlComponent component(&engine, TEST_FILE(file));
274 QObject *object = component.create();
275 QVERIFY(object == 0);
278 VERIFY_ERRORS(errorFile.toLatin1().constData());
281 void tst_qqmllanguage::errors_data()
283 QTest::addColumn<QString>("file");
284 QTest::addColumn<QString>("errorFile");
285 QTest::addColumn<bool>("create");
287 QTest::newRow("nonexistantProperty.1") << "nonexistantProperty.1.qml" << "nonexistantProperty.1.errors.txt" << false;
288 QTest::newRow("nonexistantProperty.2") << "nonexistantProperty.2.qml" << "nonexistantProperty.2.errors.txt" << false;
289 QTest::newRow("nonexistantProperty.3") << "nonexistantProperty.3.qml" << "nonexistantProperty.3.errors.txt" << false;
290 QTest::newRow("nonexistantProperty.4") << "nonexistantProperty.4.qml" << "nonexistantProperty.4.errors.txt" << false;
291 QTest::newRow("nonexistantProperty.5") << "nonexistantProperty.5.qml" << "nonexistantProperty.5.errors.txt" << false;
292 QTest::newRow("nonexistantProperty.6") << "nonexistantProperty.6.qml" << "nonexistantProperty.6.errors.txt" << false;
294 QTest::newRow("wrongType (string for int)") << "wrongType.1.qml" << "wrongType.1.errors.txt" << false;
295 QTest::newRow("wrongType (int for bool)") << "wrongType.2.qml" << "wrongType.2.errors.txt" << false;
296 QTest::newRow("wrongType (bad rect)") << "wrongType.3.qml" << "wrongType.3.errors.txt" << false;
298 QTest::newRow("wrongType (invalid enum)") << "wrongType.4.qml" << "wrongType.4.errors.txt" << false;
299 QTest::newRow("wrongType (int for uint)") << "wrongType.5.qml" << "wrongType.5.errors.txt" << false;
300 QTest::newRow("wrongType (string for real)") << "wrongType.6.qml" << "wrongType.6.errors.txt" << false;
301 QTest::newRow("wrongType (int for color)") << "wrongType.7.qml" << "wrongType.7.errors.txt" << false;
302 QTest::newRow("wrongType (int for date)") << "wrongType.8.qml" << "wrongType.8.errors.txt" << false;
303 QTest::newRow("wrongType (int for time)") << "wrongType.9.qml" << "wrongType.9.errors.txt" << false;
304 QTest::newRow("wrongType (int for datetime)") << "wrongType.10.qml" << "wrongType.10.errors.txt" << false;
305 QTest::newRow("wrongType (string for point)") << "wrongType.11.qml" << "wrongType.11.errors.txt" << false;
306 QTest::newRow("wrongType (color for size)") << "wrongType.12.qml" << "wrongType.12.errors.txt" << false;
307 QTest::newRow("wrongType (number string for int)") << "wrongType.13.qml" << "wrongType.13.errors.txt" << false;
308 QTest::newRow("wrongType (int for string)") << "wrongType.14.qml" << "wrongType.14.errors.txt" << false;
309 QTest::newRow("wrongType (int for url)") << "wrongType.15.qml" << "wrongType.15.errors.txt" << false;
310 QTest::newRow("wrongType (invalid object)") << "wrongType.16.qml" << "wrongType.16.errors.txt" << false;
311 QTest::newRow("wrongType (int for enum)") << "wrongType.17.qml" << "wrongType.17.errors.txt" << false;
313 QTest::newRow("readOnly.1") << "readOnly.1.qml" << "readOnly.1.errors.txt" << false;
314 QTest::newRow("readOnly.2") << "readOnly.2.qml" << "readOnly.2.errors.txt" << false;
315 QTest::newRow("readOnly.3") << "readOnly.3.qml" << "readOnly.3.errors.txt" << false;
316 QTest::newRow("readOnly.4") << "readOnly.4.qml" << "readOnly.4.errors.txt" << false;
317 QTest::newRow("readOnly.5") << "readOnly.5.qml" << "readOnly.5.errors.txt" << false;
319 QTest::newRow("listAssignment.1") << "listAssignment.1.qml" << "listAssignment.1.errors.txt" << false;
320 QTest::newRow("listAssignment.2") << "listAssignment.2.qml" << "listAssignment.2.errors.txt" << false;
321 QTest::newRow("listAssignment.3") << "listAssignment.3.qml" << "listAssignment.3.errors.txt" << false;
323 QTest::newRow("invalidID.1") << "invalidID.qml" << "invalidID.errors.txt" << false;
324 QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
325 QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
326 QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
327 QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
328 QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false;
329 QTest::newRow("invalidID.7") << "invalidID.7.qml" << "invalidID.7.errors.txt" << false;
330 QTest::newRow("invalidID.8") << "invalidID.8.qml" << "invalidID.8.errors.txt" << false;
331 QTest::newRow("invalidID.9") << "invalidID.9.qml" << "invalidID.9.errors.txt" << false;
333 QTest::newRow("scriptString.1") << "scriptString.1.qml" << "scriptString.1.errors.txt" << false;
334 QTest::newRow("scriptString.2") << "scriptString.2.qml" << "scriptString.2.errors.txt" << false;
336 QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
337 QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;
338 QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false;
339 QTest::newRow("duplicateIDs") << "duplicateIDs.qml" << "duplicateIDs.errors.txt" << false;
340 QTest::newRow("unregisteredObject") << "unregisteredObject.qml" << "unregisteredObject.errors.txt" << false;
341 QTest::newRow("empty") << "empty.qml" << "empty.errors.txt" << false;
342 QTest::newRow("missingObject") << "missingObject.qml" << "missingObject.errors.txt" << false;
343 QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
344 QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
345 QTest::newRow("missingSignal2") << "missingSignal.2.qml" << "missingSignal.2.errors.txt" << false;
346 QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
347 QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
349 QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
350 QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
351 QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
352 QTest::newRow("invalidGroupedProperty.4") << "invalidGroupedProperty.4.qml" << "invalidGroupedProperty.4.errors.txt" << false;
353 QTest::newRow("invalidGroupedProperty.5") << "invalidGroupedProperty.5.qml" << "invalidGroupedProperty.5.errors.txt" << false;
354 QTest::newRow("invalidGroupedProperty.6") << "invalidGroupedProperty.6.qml" << "invalidGroupedProperty.6.errors.txt" << false;
355 QTest::newRow("invalidGroupedProperty.7") << "invalidGroupedProperty.7.qml" << "invalidGroupedProperty.7.errors.txt" << true;
356 QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
357 QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
358 QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
360 QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
361 QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
362 QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false;
363 QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false;
364 QTest::newRow("importNonExistOlder (installed)") << "importNonExistOlder.qml" << "importNonExistOlder.errors.txt" << false;
365 QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false;
366 QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false;
367 QTest::newRow("importFile") << "importFile.qml" << "importFile.errors.txt" << false;
369 QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false;
370 QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false;
371 QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false;
372 QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false;
373 QTest::newRow("signal.5") << "signal.5.qml" << "signal.5.errors.txt" << false;
375 QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false;
377 QTest::newRow("property.1") << "property.1.qml" << "property.1.errors.txt" << false;
378 QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
379 QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
380 QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
381 QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
382 QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
384 QTest::newRow("importScript.1") << "importscript.1.qml" << "importscript.1.errors.txt" << false;
386 QTest::newRow("Component.1") << "component.1.qml" << "component.1.errors.txt" << false;
387 QTest::newRow("Component.2") << "component.2.qml" << "component.2.errors.txt" << false;
388 QTest::newRow("Component.3") << "component.3.qml" << "component.3.errors.txt" << false;
389 QTest::newRow("Component.4") << "component.4.qml" << "component.4.errors.txt" << false;
390 QTest::newRow("Component.5") << "component.5.qml" << "component.5.errors.txt" << false;
391 QTest::newRow("Component.6") << "component.6.qml" << "component.6.errors.txt" << false;
392 QTest::newRow("Component.7") << "component.7.qml" << "component.7.errors.txt" << false;
393 QTest::newRow("Component.8") << "component.8.qml" << "component.8.errors.txt" << false;
394 QTest::newRow("Component.9") << "component.9.qml" << "component.9.errors.txt" << false;
396 QTest::newRow("MultiSet.1") << "multiSet.1.qml" << "multiSet.1.errors.txt" << false;
397 QTest::newRow("MultiSet.2") << "multiSet.2.qml" << "multiSet.2.errors.txt" << false;
398 QTest::newRow("MultiSet.3") << "multiSet.3.qml" << "multiSet.3.errors.txt" << false;
399 QTest::newRow("MultiSet.4") << "multiSet.4.qml" << "multiSet.4.errors.txt" << false;
400 QTest::newRow("MultiSet.5") << "multiSet.5.qml" << "multiSet.5.errors.txt" << false;
401 QTest::newRow("MultiSet.6") << "multiSet.6.qml" << "multiSet.6.errors.txt" << false;
402 QTest::newRow("MultiSet.7") << "multiSet.7.qml" << "multiSet.7.errors.txt" << false;
403 QTest::newRow("MultiSet.8") << "multiSet.8.qml" << "multiSet.8.errors.txt" << false;
404 QTest::newRow("MultiSet.9") << "multiSet.9.qml" << "multiSet.9.errors.txt" << false;
405 QTest::newRow("MultiSet.10") << "multiSet.10.qml" << "multiSet.10.errors.txt" << false;
406 QTest::newRow("MultiSet.11") << "multiSet.11.qml" << "multiSet.11.errors.txt" << false;
408 QTest::newRow("dynamicMeta.1") << "dynamicMeta.1.qml" << "dynamicMeta.1.errors.txt" << false;
409 QTest::newRow("dynamicMeta.2") << "dynamicMeta.2.qml" << "dynamicMeta.2.errors.txt" << false;
410 QTest::newRow("dynamicMeta.3") << "dynamicMeta.3.qml" << "dynamicMeta.3.errors.txt" << false;
411 QTest::newRow("dynamicMeta.4") << "dynamicMeta.4.qml" << "dynamicMeta.4.errors.txt" << false;
412 QTest::newRow("dynamicMeta.5") << "dynamicMeta.5.qml" << "dynamicMeta.5.errors.txt" << false;
414 QTest::newRow("invalidAlias.1") << "invalidAlias.1.qml" << "invalidAlias.1.errors.txt" << false;
415 QTest::newRow("invalidAlias.2") << "invalidAlias.2.qml" << "invalidAlias.2.errors.txt" << false;
416 QTest::newRow("invalidAlias.3") << "invalidAlias.3.qml" << "invalidAlias.3.errors.txt" << false;
417 QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false;
418 QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
419 QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
420 QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false;
421 QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
422 QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
423 QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
425 QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
426 QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
427 QTest::newRow("invalidAttachedProperty.3") << "invalidAttachedProperty.3.qml" << "invalidAttachedProperty.3.errors.txt" << false;
428 QTest::newRow("invalidAttachedProperty.4") << "invalidAttachedProperty.4.qml" << "invalidAttachedProperty.4.errors.txt" << false;
429 QTest::newRow("invalidAttachedProperty.5") << "invalidAttachedProperty.5.qml" << "invalidAttachedProperty.5.errors.txt" << false;
430 QTest::newRow("invalidAttachedProperty.6") << "invalidAttachedProperty.6.qml" << "invalidAttachedProperty.6.errors.txt" << false;
431 QTest::newRow("invalidAttachedProperty.7") << "invalidAttachedProperty.7.qml" << "invalidAttachedProperty.7.errors.txt" << false;
432 QTest::newRow("invalidAttachedProperty.8") << "invalidAttachedProperty.8.qml" << "invalidAttachedProperty.8.errors.txt" << false;
433 QTest::newRow("invalidAttachedProperty.9") << "invalidAttachedProperty.9.qml" << "invalidAttachedProperty.9.errors.txt" << false;
434 QTest::newRow("invalidAttachedProperty.10") << "invalidAttachedProperty.10.qml" << "invalidAttachedProperty.10.errors.txt" << false;
435 QTest::newRow("invalidAttachedProperty.11") << "invalidAttachedProperty.11.qml" << "invalidAttachedProperty.11.errors.txt" << false;
436 QTest::newRow("invalidAttachedProperty.12") << "invalidAttachedProperty.12.qml" << "invalidAttachedProperty.12.errors.txt" << false;
437 QTest::newRow("invalidAttachedProperty.13") << "invalidAttachedProperty.13.qml" << "invalidAttachedProperty.13.errors.txt" << false;
439 QTest::newRow("assignValueToSignal") << "assignValueToSignal.qml" << "assignValueToSignal.errors.txt" << false;
440 QTest::newRow("emptySignal") << "emptySignal.qml" << "emptySignal.errors.txt" << false;
442 QTest::newRow("nestedErrors") << "nestedErrors.qml" << "nestedErrors.errors.txt" << false;
443 QTest::newRow("defaultGrouped") << "defaultGrouped.qml" << "defaultGrouped.errors.txt" << false;
444 QTest::newRow("doubleSignal") << "doubleSignal.qml" << "doubleSignal.errors.txt" << false;
445 QTest::newRow("missingValueTypeProperty") << "missingValueTypeProperty.qml" << "missingValueTypeProperty.errors.txt" << false;
446 QTest::newRow("objectValueTypeProperty") << "objectValueTypeProperty.qml" << "objectValueTypeProperty.errors.txt" << false;
447 QTest::newRow("enumTypes") << "enumTypes.qml" << "enumTypes.errors.txt" << false;
448 QTest::newRow("noCreation") << "noCreation.qml" << "noCreation.errors.txt" << false;
449 QTest::newRow("destroyedSignal") << "destroyedSignal.qml" << "destroyedSignal.errors.txt" << false;
450 QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false;
451 QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false;
452 QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false;
453 QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false;
454 QTest::newRow("notAvailable") << "notAvailable.qml" << "notAvailable.errors.txt" << false;
455 QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
456 QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
457 QTest::newRow("incorrectCase") << "incorrectCase.qml"
458 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
459 << "incorrectCase.errors.insensitive.txt"
461 << "incorrectCase.errors.sensitive.txt"
465 QTest::newRow("metaobjectRevision.1") << "metaobjectRevision.1.qml" << "metaobjectRevision.1.errors.txt" << false;
466 QTest::newRow("metaobjectRevision.2") << "metaobjectRevision.2.qml" << "metaobjectRevision.2.errors.txt" << false;
467 QTest::newRow("metaobjectRevision.3") << "metaobjectRevision.3.qml" << "metaobjectRevision.3.errors.txt" << false;
469 QTest::newRow("invalidRoot.1") << "invalidRoot.1.qml" << "invalidRoot.1.errors.txt" << false;
470 QTest::newRow("invalidRoot.2") << "invalidRoot.2.qml" << "invalidRoot.2.errors.txt" << false;
471 QTest::newRow("invalidRoot.3") << "invalidRoot.3.qml" << "invalidRoot.3.errors.txt" << false;
472 QTest::newRow("invalidRoot.4") << "invalidRoot.4.qml" << "invalidRoot.4.errors.txt" << false;
474 QTest::newRow("invalidTypeName.1") << "invalidTypeName.1.qml" << "invalidTypeName.1.errors.txt" << false;
475 QTest::newRow("invalidTypeName.2") << "invalidTypeName.2.qml" << "invalidTypeName.2.errors.txt" << false;
476 QTest::newRow("invalidTypeName.3") << "invalidTypeName.3.qml" << "invalidTypeName.3.errors.txt" << false;
477 QTest::newRow("invalidTypeName.4") << "invalidTypeName.4.qml" << "invalidTypeName.4.errors.txt" << false;
479 QTest::newRow("Major version isolation") << "majorVersionIsolation.qml" << "majorVersionIsolation.errors.txt" << false;
483 void tst_qqmllanguage::errors()
485 QFETCH(QString, file);
486 QFETCH(QString, errorFile);
487 QFETCH(bool, create);
489 QQmlComponent component(&engine, TEST_FILE(file));
492 QObject *object = component.create();
493 QVERIFY(object == 0);
496 VERIFY_ERRORS(errorFile.toLatin1().constData());
499 void tst_qqmllanguage::simpleObject()
501 QQmlComponent component(&engine, TEST_FILE("simpleObject.qml"));
503 QObject *object = component.create();
504 QVERIFY(object != 0);
507 void tst_qqmllanguage::simpleContainer()
509 QQmlComponent component(&engine, TEST_FILE("simpleContainer.qml"));
511 MyContainer *container= qobject_cast<MyContainer*>(component.create());
512 QVERIFY(container != 0);
513 QCOMPARE(container->getChildren()->count(),2);
516 void tst_qqmllanguage::interfaceProperty()
518 QQmlComponent component(&engine, TEST_FILE("interfaceProperty.qml"));
520 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
521 QVERIFY(object != 0);
522 QVERIFY(object->interface());
523 QVERIFY(object->interface()->id == 913);
526 void tst_qqmllanguage::interfaceQList()
528 QQmlComponent component(&engine, TEST_FILE("interfaceQList.qml"));
530 MyContainer *container= qobject_cast<MyContainer*>(component.create());
531 QVERIFY(container != 0);
532 QVERIFY(container->getQListInterfaces()->count() == 2);
533 for(int ii = 0; ii < 2; ++ii)
534 QVERIFY(container->getQListInterfaces()->at(ii)->id == 913);
537 void tst_qqmllanguage::assignObjectToSignal()
539 QQmlComponent component(&engine, TEST_FILE("assignObjectToSignal.qml"));
541 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
542 QVERIFY(object != 0);
543 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
544 emit object->basicSignal();
547 void tst_qqmllanguage::assignObjectToVariant()
549 QQmlComponent component(&engine, TEST_FILE("assignObjectToVariant.qml"));
551 QObject *object = component.create();
552 QVERIFY(object != 0);
553 QVariant v = object->property("a");
554 QVERIFY(v.userType() == qMetaTypeId<QObject *>());
557 void tst_qqmllanguage::assignLiteralSignalProperty()
559 QQmlComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.qml"));
561 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
562 QVERIFY(object != 0);
563 QCOMPARE(object->onLiteralSignal(), 10);
566 // Test is an external component can be loaded and assigned (to a qlist)
567 void tst_qqmllanguage::assignQmlComponent()
569 QQmlComponent component(&engine, TEST_FILE("assignQmlComponent.qml"));
571 MyContainer *object = qobject_cast<MyContainer *>(component.create());
572 QVERIFY(object != 0);
573 QVERIFY(object->getChildren()->count() == 1);
574 QObject *child = object->getChildren()->at(0);
575 QCOMPARE(child->property("x"), QVariant(10));
576 QCOMPARE(child->property("y"), QVariant(11));
579 // Test literal assignment to all the basic types
580 void tst_qqmllanguage::assignBasicTypes()
582 QQmlComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
584 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
585 QVERIFY(object != 0);
586 QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
587 QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
588 QCOMPARE(object->qtEnumProperty(), Qt::RichText);
589 QCOMPARE(object->mirroredEnumProperty(), MyTypeObject::MirroredEnumVal3);
590 QCOMPARE(object->relatedEnumProperty(), MyEnumContainer::RelatedValue);
591 QCOMPARE(object->stringProperty(), QString("Hello World!"));
592 QCOMPARE(object->uintProperty(), uint(10));
593 QCOMPARE(object->intProperty(), -19);
594 QCOMPARE((float)object->realProperty(), float(23.2));
595 QCOMPARE((float)object->doubleProperty(), float(-19.7));
596 QCOMPARE((float)object->floatProperty(), float(8.5));
597 QCOMPARE(object->colorProperty(), QColor("red"));
598 QCOMPARE(object->dateProperty(), QDate(1982, 11, 25));
599 QCOMPARE(object->timeProperty(), QTime(11, 11, 32));
600 QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1)));
601 QCOMPARE(object->pointProperty(), QPoint(99,13));
602 QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3));
603 QCOMPARE(object->sizeProperty(), QSize(99, 13));
604 QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2));
605 QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200));
606 QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99));
607 QCOMPARE(object->boolProperty(), true);
608 QCOMPARE(object->variantProperty(), QVariant("Hello World!"));
609 QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2));
610 QCOMPARE(object->vector4Property(), QVector4D(10, 1, 2.2, 2.3));
612 encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
613 QCOMPARE(object->urlProperty(), component.url().resolved(encoded));
614 QVERIFY(object->objectProperty() != 0);
615 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty());
617 QCOMPARE(child->intProperty(), 8);
619 //these used to go via script. Ensure they no longer do
620 QCOMPARE(object->property("qtEnumTriggeredChange").toBool(), false);
621 QCOMPARE(object->property("mirroredEnumTriggeredChange").toBool(), false);
624 // Test edge case type assignments
625 void tst_qqmllanguage::assignTypeExtremes()
627 QQmlComponent component(&engine, TEST_FILE("assignTypeExtremes.qml"));
629 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
630 QVERIFY(object != 0);
631 QCOMPARE(object->uintProperty(), 0xEE6B2800);
632 QCOMPARE(object->intProperty(), -0x77359400);
635 // Test that a composite type can assign to a property of its base type
636 void tst_qqmllanguage::assignCompositeToType()
638 QQmlComponent component(&engine, TEST_FILE("assignCompositeToType.qml"));
640 QObject *object = component.create();
641 QVERIFY(object != 0);
644 // Test that literals are stored correctly in variant properties
645 void tst_qqmllanguage::assignLiteralToVariant()
647 QQmlComponent component(&engine, TEST_FILE("assignLiteralToVariant.qml"));
649 QObject *object = component.create();
650 QVERIFY(object != 0);
652 QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
653 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
654 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
655 QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
656 QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
657 QCOMPARE(object->property("test6").userType(), (int)QVariant::PointF);
658 QCOMPARE(object->property("test7").userType(), (int)QVariant::SizeF);
659 QCOMPARE(object->property("test8").userType(), (int)QVariant::Vector3D);
660 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
661 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
662 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
663 QCOMPARE(object->property("test12").userType(), (int)QVariant::Vector4D);
665 QVERIFY(object->property("test1") == QVariant(1));
666 QVERIFY(object->property("test2") == QVariant((double)1.7));
667 QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!"))));
668 QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800)));
669 QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10)));
670 QVERIFY(object->property("test6") == QVariant(QPointF(10, 10)));
671 QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10)));
672 QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100)));
673 QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800"))));
674 QVERIFY(object->property("test10") == QVariant(bool(true)));
675 QVERIFY(object->property("test11") == QVariant(bool(false)));
676 QVERIFY(object->property("test12") == QVariant(QVector4D(100, 100, 100, 100)));
681 // Test that literals are stored correctly in "var" properties
682 // Note that behaviour differs from "variant" properties in that
683 // no conversion from "special strings" to QVariants is performed.
684 void tst_qqmllanguage::assignLiteralToVar()
686 QQmlComponent component(&engine, TEST_FILE("assignLiteralToVar.qml"));
688 QObject *object = component.create();
689 QVERIFY(object != 0);
691 QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
692 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
693 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
694 QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
695 QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
696 QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
697 QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
698 QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
699 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
700 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
701 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
702 QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
703 QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
704 QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
705 QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
706 QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
707 QCOMPARE(object->property("variantTest1Bound").userType(), (int)QMetaType::Int);
708 QCOMPARE(object->property("test1Bound").userType(), (int)QMetaType::Int);
710 QCOMPARE(object->property("test1"), QVariant(5));
711 QCOMPARE(object->property("test2"), QVariant((double)1.7));
712 QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
713 QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
714 QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
715 QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
716 QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
717 QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
718 QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
719 QCOMPARE(object->property("test10"), QVariant(bool(true)));
720 QCOMPARE(object->property("test11"), QVariant(bool(false)));
721 QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
722 QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
723 QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
724 QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
725 QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
726 QCOMPARE(object->property("variantTest1Bound"), QVariant(9));
727 QCOMPARE(object->property("test1Bound"), QVariant(11));
732 void tst_qqmllanguage::assignLiteralToJSValue()
734 QQmlComponent component(&engine, TEST_FILE("assignLiteralToJSValue.qml"));
736 QObject *root = component.create();
740 MyQmlObject *object = root->findChild<MyQmlObject *>("test1");
741 QJSValue value = object->qjsvalue();
742 QVERIFY(value.isNumber());
743 QCOMPARE(value.toNumber(), qreal(5));
745 MyQmlObject *object = root->findChild<MyQmlObject *>("test2");
746 QJSValue value = object->qjsvalue();
747 QVERIFY(value.isNumber());
748 QCOMPARE(value.toNumber(), qreal(1.7));
750 MyQmlObject *object = root->findChild<MyQmlObject *>("test3");
751 QJSValue value = object->qjsvalue();
752 QVERIFY(value.isString());
753 QCOMPARE(value.toString(), QString(QLatin1String("Hello world!")));
755 MyQmlObject *object = root->findChild<MyQmlObject *>("test4");
756 QJSValue value = object->qjsvalue();
757 QVERIFY(value.isString());
758 QCOMPARE(value.toString(), QString(QLatin1String("#FF008800")));
760 MyQmlObject *object = root->findChild<MyQmlObject *>("test5");
761 QJSValue value = object->qjsvalue();
762 QVERIFY(value.isString());
763 QCOMPARE(value.toString(), QString(QLatin1String("10,10,10x10")));
765 MyQmlObject *object = root->findChild<MyQmlObject *>("test6");
766 QJSValue value = object->qjsvalue();
767 QVERIFY(value.isString());
768 QCOMPARE(value.toString(), QString(QLatin1String("10,10")));
770 MyQmlObject *object = root->findChild<MyQmlObject *>("test7");
771 QJSValue value = object->qjsvalue();
772 QVERIFY(value.isString());
773 QCOMPARE(value.toString(), QString(QLatin1String("10x10")));
775 MyQmlObject *object = root->findChild<MyQmlObject *>("test8");
776 QJSValue value = object->qjsvalue();
777 QVERIFY(value.isString());
778 QCOMPARE(value.toString(), QString(QLatin1String("100,100,100")));
780 MyQmlObject *object = root->findChild<MyQmlObject *>("test9");
781 QJSValue value = object->qjsvalue();
782 QVERIFY(value.isString());
783 QCOMPARE(value.toString(), QString(QLatin1String("#FF008800")));
785 MyQmlObject *object = root->findChild<MyQmlObject *>("test10");
786 QJSValue value = object->qjsvalue();
787 QVERIFY(value.isBool());
788 QCOMPARE(value.toBool(), true);
790 MyQmlObject *object = root->findChild<MyQmlObject *>("test11");
791 QJSValue value = object->qjsvalue();
792 QVERIFY(value.isBool());
793 QCOMPARE(value.toBool(), false);
795 MyQmlObject *object = root->findChild<MyQmlObject *>("test20");
796 QJSValue value = object->qjsvalue();
797 QVERIFY(value.isCallable());
798 QCOMPARE(value.call(QList<QJSValue> () << QJSValue(4)).toInt(), 12);
800 MyQmlObject *object = root->findChild<MyQmlObject *>("test21");
801 QJSValue value = object->qjsvalue();
802 QVERIFY(value.isUndefined());
804 MyQmlObject *object = root->findChild<MyQmlObject *>("test22");
805 QJSValue value = object->qjsvalue();
806 QVERIFY(value.isNull());
808 MyQmlObject *object = root->findChild<MyQmlObject *>("test1Bound");
809 QJSValue value = object->qjsvalue();
810 QVERIFY(value.isNumber());
811 QCOMPARE(value.toNumber(), qreal(9));
813 MyQmlObject *object = root->findChild<MyQmlObject *>("test20Bound");
814 QJSValue value = object->qjsvalue();
815 QVERIFY(value.isNumber());
816 QCOMPARE(value.toNumber(), qreal(27));
820 void tst_qqmllanguage::bindJSValueToVar()
822 QQmlComponent component(&engine, TEST_FILE("assignLiteralToJSValue.qml"));
825 QObject *root = component.create();
828 QObject *object = root->findChild<QObject *>("varProperties");
830 QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
831 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
832 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
833 QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
834 QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
835 QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
836 QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
837 QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
838 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
839 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
840 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
841 QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
842 QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
843 QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
844 QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
845 QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
846 QCOMPARE(object->property("test1Bound").userType(), (int)QVariant::Int);
847 QCOMPARE(object->property("test20Bound").userType(), (int)QVariant::Int);
849 QCOMPARE(object->property("test1"), QVariant(5));
850 QCOMPARE(object->property("test2"), QVariant((double)1.7));
851 QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
852 QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
853 QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
854 QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
855 QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
856 QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
857 QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
858 QCOMPARE(object->property("test10"), QVariant(bool(true)));
859 QCOMPARE(object->property("test11"), QVariant(bool(false)));
860 QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
861 QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
862 QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
863 QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
864 QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
865 QCOMPARE(object->property("test1Bound"), QVariant(9));
866 QCOMPARE(object->property("test20Bound"), QVariant(27));
869 void tst_qqmllanguage::bindJSValueToVariant()
871 QQmlComponent component(&engine, TEST_FILE("assignLiteralToJSValue.qml"));
874 QObject *root = component.create();
877 QObject *object = root->findChild<QObject *>("variantProperties");
879 QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
880 QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
881 QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
882 QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
883 QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
884 QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
885 QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
886 QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
887 QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
888 QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
889 QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
890 QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
891 QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
892 QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
893 QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
894 QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
895 QCOMPARE(object->property("test1Bound").userType(), (int)QVariant::Int);
896 QCOMPARE(object->property("test20Bound").userType(), (int)QVariant::Int);
898 QCOMPARE(object->property("test1"), QVariant(5));
899 QCOMPARE(object->property("test2"), QVariant((double)1.7));
900 QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
901 QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
902 QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
903 QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
904 QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
905 QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
906 QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
907 QCOMPARE(object->property("test10"), QVariant(bool(true)));
908 QCOMPARE(object->property("test11"), QVariant(bool(false)));
909 QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
910 QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
911 QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
912 QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
913 QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
914 QCOMPARE(object->property("test1Bound"), QVariant(9));
915 QCOMPARE(object->property("test20Bound"), QVariant(27));
918 void tst_qqmllanguage::bindJSValueToType()
920 QQmlComponent component(&engine, TEST_FILE("assignLiteralToJSValue.qml"));
923 QObject *root = component.create();
927 MyTypeObject *object = root->findChild<MyTypeObject *>("typedProperties");
929 QCOMPARE(object->intProperty(), 5);
930 QCOMPARE(object->doubleProperty(), double(1.7));
931 QCOMPARE(object->stringProperty(), QString(QLatin1String("Hello world!")));
932 QCOMPARE(object->boolProperty(), true);
933 QCOMPARE(object->colorProperty(), QColor::fromRgbF(0.2, 0.3, 0.4, 0.5));
934 QCOMPARE(object->rectFProperty(), QRectF(10, 10, 10, 10));
935 QCOMPARE(object->pointFProperty(), QPointF(10, 10));
936 QCOMPARE(object->sizeFProperty(), QSizeF(10, 10));
937 QCOMPARE(object->vectorProperty(), QVector3D(100, 100, 100));
939 MyTypeObject *object = root->findChild<MyTypeObject *>("stringProperties");
941 QCOMPARE(object->intProperty(), 1);
942 QCOMPARE(object->doubleProperty(), double(1.7));
943 QCOMPARE(object->stringProperty(), QString(QLatin1String("Hello world!")));
944 QCOMPARE(object->boolProperty(), true);
945 QCOMPARE(object->colorProperty(), QColor::fromRgb(0x00, 0x88, 0x00, 0xFF));
946 QCOMPARE(object->rectFProperty(), QRectF(10, 10, 10, 10));
947 QCOMPARE(object->pointFProperty(), QPointF(10, 10));
948 QCOMPARE(object->sizeFProperty(), QSizeF(10, 10));
949 QCOMPARE(object->vectorProperty(), QVector3D(100, 100, 100));
953 void tst_qqmllanguage::bindTypeToJSValue()
955 QQmlComponent component(&engine, TEST_FILE("bindTypeToJSValue.qml"));
958 QObject *root = component.create();
962 MyQmlObject *object = root->findChild<MyQmlObject *>("flagProperty");
964 QJSValue value = object->qjsvalue();
965 QVERIFY(value.isNumber());
966 QCOMPARE(value.toNumber(), qreal(MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3));
968 MyQmlObject *object = root->findChild<MyQmlObject *>("enumProperty");
969 QJSValue value = object->qjsvalue();
970 QVERIFY(value.isNumber());
971 QCOMPARE(value.toNumber(), qreal(MyTypeObject::EnumVal2));
973 MyQmlObject *object = root->findChild<MyQmlObject *>("stringProperty");
974 QJSValue value = object->qjsvalue();
975 QVERIFY(value.isString());
976 QCOMPARE(value.toString(), QString(QLatin1String("Hello World!")));
978 MyQmlObject *object = root->findChild<MyQmlObject *>("uintProperty");
979 QJSValue value = object->qjsvalue();
980 QVERIFY(value.isNumber());
981 QCOMPARE(value.toNumber(), qreal(10));
983 MyQmlObject *object = root->findChild<MyQmlObject *>("intProperty");
984 QJSValue value = object->qjsvalue();
985 QVERIFY(value.isNumber());
986 QCOMPARE(value.toNumber(), qreal(-19));
988 MyQmlObject *object = root->findChild<MyQmlObject *>("realProperty");
989 QJSValue value = object->qjsvalue();
990 QVERIFY(value.isNumber());
991 QCOMPARE(value.toNumber(), qreal(23.2));
993 MyQmlObject *object = root->findChild<MyQmlObject *>("doubleProperty");
994 QJSValue value = object->qjsvalue();
995 QVERIFY(value.isNumber());
996 QCOMPARE(value.toNumber(), qreal(-19.7));
998 MyQmlObject *object = root->findChild<MyQmlObject *>("floatProperty");
999 QJSValue value = object->qjsvalue();
1000 QVERIFY(value.isNumber());
1001 QCOMPARE(value.toNumber(), qreal(8.5));
1003 MyQmlObject *object = root->findChild<MyQmlObject *>("colorProperty");
1004 QJSValue value = object->qjsvalue();
1005 QVERIFY(value.isObject());
1006 QCOMPARE(value.property(QLatin1String("r")).toNumber(), qreal(1.0));
1007 QCOMPARE(value.property(QLatin1String("g")).toNumber(), qreal(0.0));
1008 QCOMPARE(value.property(QLatin1String("b")).toNumber(), qreal(0.0));
1010 MyQmlObject *object = root->findChild<MyQmlObject *>("dateProperty");
1011 QJSValue value = object->qjsvalue();
1012 QCOMPARE(value.toDateTime().isValid(), true);
1014 MyQmlObject *object = root->findChild<MyQmlObject *>("timeProperty");
1015 QJSValue value = object->qjsvalue();
1016 QCOMPARE(value.toDateTime().isValid(), true);
1018 MyQmlObject *object = root->findChild<MyQmlObject *>("dateTimeProperty");
1019 QJSValue value = object->qjsvalue();
1020 QCOMPARE(value.toDateTime().isValid(), true);
1022 MyQmlObject *object = root->findChild<MyQmlObject *>("pointProperty");
1023 QJSValue value = object->qjsvalue();
1024 QVERIFY(value.isObject());
1025 QCOMPARE(value.property(QLatin1String("x")).toNumber(), qreal(99));
1026 QCOMPARE(value.property(QLatin1String("y")).toNumber(), qreal(13));
1028 MyQmlObject *object = root->findChild<MyQmlObject *>("pointFProperty");
1029 QJSValue value = object->qjsvalue();
1030 QVERIFY(value.isObject());
1031 QCOMPARE(value.property(QLatin1String("x")).toNumber(), qreal(-10.1));
1032 QCOMPARE(value.property(QLatin1String("y")).toNumber(), qreal(12.3));
1034 MyQmlObject *object = root->findChild<MyQmlObject *>("rectProperty");
1035 QJSValue value = object->qjsvalue();
1036 QVERIFY(value.isObject());
1037 QCOMPARE(value.property(QLatin1String("x")).toNumber(), qreal(9));
1038 QCOMPARE(value.property(QLatin1String("y")).toNumber(), qreal(7));
1039 QCOMPARE(value.property(QLatin1String("width")).toNumber(), qreal(100));
1040 QCOMPARE(value.property(QLatin1String("height")).toNumber(), qreal(200));
1042 MyQmlObject *object = root->findChild<MyQmlObject *>("rectFProperty");
1043 QJSValue value = object->qjsvalue();
1044 QVERIFY(value.isObject());
1045 QCOMPARE(value.property(QLatin1String("x")).toNumber(), qreal(1000.1));
1046 QCOMPARE(value.property(QLatin1String("y")).toNumber(), qreal(-10.9));
1047 QCOMPARE(value.property(QLatin1String("width")).toNumber(), qreal(400));
1048 QCOMPARE(value.property(QLatin1String("height")).toNumber(), qreal(90.99));
1050 MyQmlObject *object = root->findChild<MyQmlObject *>("boolProperty");
1051 QJSValue value = object->qjsvalue();
1052 QVERIFY(value.isBool());
1053 QCOMPARE(value.toBool(), true);
1055 MyQmlObject *object = root->findChild<MyQmlObject *>("variantProperty");
1056 QJSValue value = object->qjsvalue();
1057 QVERIFY(value.isString());
1058 QCOMPARE(value.toString(), QString(QLatin1String("Hello World!")));
1060 MyQmlObject *object = root->findChild<MyQmlObject *>("vectorProperty");
1061 QJSValue value = object->qjsvalue();
1062 QVERIFY(value.isObject());
1063 QCOMPARE(value.property(QLatin1String("x")).toNumber(), qreal(10.0f));
1064 QCOMPARE(value.property(QLatin1String("y")).toNumber(), qreal(1.0f));
1065 QCOMPARE(value.property(QLatin1String("z")).toNumber(), qreal(2.2f));
1067 MyQmlObject *object = root->findChild<MyQmlObject *>("vector4Property");
1068 QJSValue value = object->qjsvalue();
1069 QVERIFY(value.isObject());
1070 QCOMPARE(value.property(QLatin1String("x")).toNumber(), qreal(10.0f));
1071 QCOMPARE(value.property(QLatin1String("y")).toNumber(), qreal(1.0f));
1072 QCOMPARE(value.property(QLatin1String("z")).toNumber(), qreal(2.2f));
1073 QCOMPARE(value.property(QLatin1String("w")).toNumber(), qreal(2.3f));
1075 MyQmlObject *object = root->findChild<MyQmlObject *>("urlProperty");
1076 QJSValue value = object->qjsvalue();
1077 QVERIFY(value.isString());
1079 encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode);
1080 QCOMPARE(value.toString(), component.url().resolved(encoded).toString());
1082 MyQmlObject *object = root->findChild<MyQmlObject *>("objectProperty");
1083 QJSValue value = object->qjsvalue();
1084 QVERIFY(value.isQObject());
1085 QVERIFY(qobject_cast<MyTypeObject *>(value.toQObject()));
1087 MyQmlObject *object = root->findChild<MyQmlObject *>("varProperty");
1088 QJSValue value = object->qjsvalue();
1089 QVERIFY(value.isString());
1090 QCOMPARE(value.toString(), QString(QLatin1String("Hello World!")));
1094 // Tests that custom parser types can be instantiated
1095 void tst_qqmllanguage::customParserTypes()
1097 QQmlComponent component(&engine, TEST_FILE("customParserTypes.qml"));
1099 QObject *object = component.create();
1100 QVERIFY(object != 0);
1101 QVERIFY(object->property("count") == QVariant(2));
1104 // Tests that the root item can be a custom component
1105 void tst_qqmllanguage::rootAsQmlComponent()
1107 QQmlComponent component(&engine, TEST_FILE("rootAsQmlComponent.qml"));
1109 MyContainer *object = qobject_cast<MyContainer *>(component.create());
1110 QVERIFY(object != 0);
1111 QCOMPARE(object->property("x"), QVariant(11));
1112 QCOMPARE(object->getChildren()->count(), 2);
1115 // Tests that components can be specified inline
1116 void tst_qqmllanguage::inlineQmlComponents()
1118 QQmlComponent component(&engine, TEST_FILE("inlineQmlComponents.qml"));
1120 MyContainer *object = qobject_cast<MyContainer *>(component.create());
1121 QVERIFY(object != 0);
1122 QCOMPARE(object->getChildren()->count(), 1);
1123 QQmlComponent *comp = qobject_cast<QQmlComponent *>(object->getChildren()->at(0));
1125 MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
1126 QVERIFY(compObject != 0);
1127 QCOMPARE(compObject->value(), 11);
1130 // Tests that types that have an id property have it set
1131 void tst_qqmllanguage::idProperty()
1133 QQmlComponent component(&engine, TEST_FILE("idProperty.qml"));
1135 MyContainer *object = qobject_cast<MyContainer *>(component.create());
1136 QVERIFY(object != 0);
1137 QCOMPARE(object->getChildren()->count(), 1);
1138 MyTypeObject *child =
1139 qobject_cast<MyTypeObject *>(object->getChildren()->at(0));
1140 QVERIFY(child != 0);
1141 QCOMPARE(child->id(), QString("myObjectId"));
1142 QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child));
1145 // Tests automatic connection to notify signals if "onBlahChanged" syntax is used
1146 // even if the notify signal for "blah" is not called "blahChanged"
1147 void tst_qqmllanguage::autoNotifyConnection()
1149 QQmlComponent component(&engine, TEST_FILE("autoNotifyConnection.qml"));
1151 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
1152 QVERIFY(object != 0);
1153 QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
1154 QVERIFY(prop.isValid());
1156 QCOMPARE(prop.read(object), QVariant::fromValue(false));
1157 object->setPropertyWithNotify(1);
1158 QCOMPARE(prop.read(object), QVariant::fromValue(true));
1161 // Tests that signals can be assigned to
1162 void tst_qqmllanguage::assignSignal()
1164 QQmlComponent component(&engine, TEST_FILE("assignSignal.qml"));
1166 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
1167 QVERIFY(object != 0);
1168 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
1169 emit object->basicSignal();
1170 QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)");
1171 emit object->basicParameterizedSignal(9);
1174 // Tests the creation and assignment of dynamic properties
1175 void tst_qqmllanguage::dynamicProperties()
1177 QQmlComponent component(&engine, TEST_FILE("dynamicProperties.qml"));
1179 QObject *object = component.create();
1180 QVERIFY(object != 0);
1181 QCOMPARE(object->property("intProperty"), QVariant(10));
1182 QCOMPARE(object->property("boolProperty"), QVariant(false));
1183 QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
1184 QCOMPARE(object->property("realProperty"), QVariant((qreal)-19.9));
1185 QCOMPARE(object->property("stringProperty"), QVariant("Hello World!"));
1186 QCOMPARE(object->property("urlProperty"), QVariant(TEST_FILE("main.qml")));
1187 QCOMPARE(object->property("colorProperty"), QVariant(QColor("red")));
1188 QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2)));
1189 QCOMPARE(object->property("varProperty"), QVariant("Hello World!"));
1192 // Test that nested types can use dynamic properties
1193 void tst_qqmllanguage::dynamicPropertiesNested()
1195 QQmlComponent component(&engine, TEST_FILE("dynamicPropertiesNested.qml"));
1197 QObject *object = component.create();
1198 QVERIFY(object != 0);
1200 QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
1201 QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
1202 QCOMPARE(object->property("a").toInt(), 13); // New
1203 QCOMPARE(object->property("b").toInt(), 12); // New
1208 // Tests the creation and assignment to dynamic list properties
1209 void tst_qqmllanguage::listProperties()
1211 QQmlComponent component(&engine, TEST_FILE("listProperties.qml"));
1213 QObject *object = component.create();
1214 QVERIFY(object != 0);
1216 QCOMPARE(object->property("test").toInt(), 2);
1219 // Tests the creation and assignment of dynamic object properties
1221 void tst_qqmllanguage::dynamicObjectProperties()
1224 QQmlComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml"));
1226 QObject *object = component.create();
1227 QVERIFY(object != 0);
1229 QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0));
1230 QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0));
1233 QQmlComponent component(&engine, TEST_FILE("dynamicObjectProperties.2.qml"));
1234 QEXPECT_FAIL("", "QTBUG-10822", Abort);
1236 QObject *object = component.create();
1237 QVERIFY(object != 0);
1239 QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)0));
1243 // Tests the declaration of dynamic signals and slots
1244 void tst_qqmllanguage::dynamicSignalsAndSlots()
1246 QTest::ignoreMessage(QtDebugMsg, "1921");
1248 QQmlComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
1250 QObject *object = component.create();
1251 QVERIFY(object != 0);
1252 QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
1253 QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
1254 QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1);
1255 QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
1257 QCOMPARE(object->property("test").toInt(), 0);
1258 QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
1259 QCOMPARE(object->property("test").toInt(), 10);
1262 void tst_qqmllanguage::simpleBindings()
1264 QQmlComponent component(&engine, TEST_FILE("simpleBindings.qml"));
1266 QObject *object = component.create();
1267 QVERIFY(object != 0);
1268 QCOMPARE(object->property("value1"), QVariant(10));
1269 QCOMPARE(object->property("value2"), QVariant(10));
1270 QCOMPARE(object->property("value3"), QVariant(21));
1271 QCOMPARE(object->property("value4"), QVariant(10));
1272 QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
1275 void tst_qqmllanguage::autoComponentCreation()
1277 QQmlComponent component(&engine, TEST_FILE("autoComponentCreation.qml"));
1279 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1280 QVERIFY(object != 0);
1281 QVERIFY(object->componentProperty() != 0);
1282 MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
1283 QVERIFY(child != 0);
1284 QCOMPARE(child->realProperty(), qreal(9));
1287 void tst_qqmllanguage::propertyValueSource()
1290 QQmlComponent component(&engine, TEST_FILE("propertyValueSource.qml"));
1292 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1293 QVERIFY(object != 0);
1295 QList<QObject *> valueSources;
1296 QObjectList allChildren = object->findChildren<QObject*>();
1297 foreach (QObject *child, allChildren) {
1298 if (qobject_cast<QQmlPropertyValueSource *>(child))
1299 valueSources.append(child);
1302 QCOMPARE(valueSources.count(), 1);
1303 MyPropertyValueSource *valueSource =
1304 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
1305 QVERIFY(valueSource != 0);
1306 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
1307 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
1311 QQmlComponent component(&engine, TEST_FILE("propertyValueSource.2.qml"));
1313 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1314 QVERIFY(object != 0);
1316 QList<QObject *> valueSources;
1317 QObjectList allChildren = object->findChildren<QObject*>();
1318 foreach (QObject *child, allChildren) {
1319 if (qobject_cast<QQmlPropertyValueSource *>(child))
1320 valueSources.append(child);
1323 QCOMPARE(valueSources.count(), 1);
1324 MyPropertyValueSource *valueSource =
1325 qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
1326 QVERIFY(valueSource != 0);
1327 QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
1328 QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
1332 void tst_qqmllanguage::attachedProperties()
1334 QQmlComponent component(&engine, TEST_FILE("attachedProperties.qml"));
1336 QObject *object = component.create();
1337 QVERIFY(object != 0);
1338 QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
1339 QVERIFY(attached != 0);
1340 QCOMPARE(attached->property("value"), QVariant(10));
1341 QCOMPARE(attached->property("value2"), QVariant(13));
1344 // Tests non-static object properties
1345 void tst_qqmllanguage::dynamicObjects()
1347 QQmlComponent component(&engine, TEST_FILE("dynamicObject.1.qml"));
1349 QObject *object = component.create();
1350 QVERIFY(object != 0);
1353 // Tests the registration of custom variant string converters
1354 void tst_qqmllanguage::customVariantTypes()
1356 QQmlComponent component(&engine, TEST_FILE("customVariantTypes.qml"));
1358 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
1359 QVERIFY(object != 0);
1360 QCOMPARE(object->customType().a, 10);
1363 void tst_qqmllanguage::valueTypes()
1365 QQmlComponent component(&engine, TEST_FILE("valueTypes.qml"));
1368 QString message = component.url().toString() + ":2:1: QML MyTypeObject: Binding loop detected for property \"rectProperty.width\"";
1369 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
1370 QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
1372 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1373 QVERIFY(object != 0);
1376 QCOMPARE(object->rectProperty(), QRect(10, 11, 12, 13));
1377 QCOMPARE(object->rectProperty2(), QRect(10, 11, 12, 13));
1378 QCOMPARE(object->intProperty(), 10);
1380 QCOMPARE(object->rectProperty(), QRect(12, 11, 14, 13));
1381 QCOMPARE(object->rectProperty2(), QRect(12, 11, 14, 13));
1382 QCOMPARE(object->intProperty(), 12);
1386 QQmlProperty p(object, "rectProperty.x");
1387 QCOMPARE(p.read(), QVariant(12));
1389 QCOMPARE(p.read(), QVariant(13));
1391 quint32 r = QQmlPropertyPrivate::saveValueType(p.coreIndex(), p.valueTypeCoreIndex());
1393 QQmlPropertyPrivate::restore(p2, r, object);
1394 QCOMPARE(p2.read(), QVariant(13));
1398 void tst_qqmllanguage::cppnamespace()
1401 QQmlComponent component(&engine, TEST_FILE("cppnamespace.qml"));
1403 QObject *object = component.create();
1404 QVERIFY(object != 0);
1409 QQmlComponent component(&engine, TEST_FILE("cppnamespace.2.qml"));
1411 QObject *object = component.create();
1412 QVERIFY(object != 0);
1417 void tst_qqmllanguage::aliasProperties()
1419 // Simple "int" alias
1421 QQmlComponent component(&engine, TEST_FILE("alias.1.qml"));
1423 QObject *object = component.create();
1424 QVERIFY(object != 0);
1426 // Read through alias
1427 QCOMPARE(object->property("valueAlias").toInt(), 10);
1428 object->setProperty("value", QVariant(13));
1429 QCOMPARE(object->property("valueAlias").toInt(), 13);
1431 // Write through alias
1432 object->setProperty("valueAlias", QVariant(19));
1433 QCOMPARE(object->property("valueAlias").toInt(), 19);
1434 QCOMPARE(object->property("value").toInt(), 19);
1439 // Complex object alias
1441 QQmlComponent component(&engine, TEST_FILE("alias.2.qml"));
1443 QObject *object = component.create();
1444 QVERIFY(object != 0);
1446 // Read through alias
1448 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1450 QCOMPARE(v->value(), 10);
1452 // Write through alias
1453 MyQmlObject *v2 = new MyQmlObject();
1454 v2->setParent(object);
1455 object->setProperty("aliasObject", qVariantFromValue(v2));
1457 qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
1466 QQmlComponent component(&engine, TEST_FILE("alias.3.qml"));
1468 QObject *object = component.create();
1469 QVERIFY(object != 0);
1471 QCOMPARE(object->property("value").toInt(), 1892);
1472 QCOMPARE(object->property("value2").toInt(), 1892);
1474 object->setProperty("value", QVariant(1313));
1475 QCOMPARE(object->property("value").toInt(), 1313);
1476 QCOMPARE(object->property("value2").toInt(), 1313);
1478 object->setProperty("value2", QVariant(8080));
1479 QCOMPARE(object->property("value").toInt(), 8080);
1480 QCOMPARE(object->property("value2").toInt(), 8080);
1487 QQmlComponent component(&engine, TEST_FILE("alias.4.qml"));
1489 QObject *object = component.create();
1490 QVERIFY(object != 0);
1492 QCOMPARE(object->property("enumAlias").toInt(), 1);
1499 QQmlComponent component(&engine, TEST_FILE("alias.5.qml"));
1501 QObject *object = component.create();
1502 QVERIFY(object != 0);
1504 QVariant v = object->property("otherAlias");
1505 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1506 MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
1507 QCOMPARE(o->value(), 10);
1511 v = object->property("otherAlias");
1512 QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
1513 o = qvariant_cast<MyQmlObject*>(v);
1519 // Nested aliases - this used to cause a crash
1521 QQmlComponent component(&engine, TEST_FILE("alias.6.qml"));
1523 QObject *object = component.create();
1524 QVERIFY(object != 0);
1526 QCOMPARE(object->property("a").toInt(), 1923);
1529 // Ptr Alias Cleanup - check that aliases to ptr types return 0
1530 // if the object aliased to is removed
1532 QQmlComponent component(&engine, TEST_FILE("alias.7.qml"));
1535 QObject *object = component.create();
1536 QVERIFY(object != 0);
1538 QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
1539 QVERIFY(object1 != 0);
1540 QObject *object2 = qvariant_cast<QObject *>(object1->property("object"));
1541 QVERIFY(object2 != 0);
1543 QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject"));
1544 QVERIFY(alias == object2);
1548 QObject *alias2 = object; // "Random" start value
1550 void *a[] = { &alias2, 0, &status };
1551 QMetaObject::metacall(object, QMetaObject::ReadProperty,
1552 object->metaObject()->indexOfProperty("aliasedObject"), a);
1553 QVERIFY(alias2 == 0);
1556 // Simple composite type
1558 QQmlComponent component(&engine, TEST_FILE("alias.8.qml"));
1560 QObject *object = component.create();
1561 QVERIFY(object != 0);
1563 QCOMPARE(object->property("value").toInt(), 10);
1568 // Complex composite type
1570 QQmlComponent component(&engine, TEST_FILE("alias.9.qml"));
1572 QObject *object = component.create();
1573 QVERIFY(object != 0);
1575 QCOMPARE(object->property("value").toInt(), 10);
1581 // Simple "int" alias
1583 QQmlComponent component(&engine, TEST_FILE("alias.10.qml"));
1585 QObject *object = component.create();
1586 QVERIFY(object != 0);
1588 // Read through alias
1589 QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8));
1590 object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
1591 QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
1593 // Write through alias
1594 object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
1595 QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
1596 QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
1601 // Valuetype sub-alias
1603 QQmlComponent component(&engine, TEST_FILE("alias.11.qml"));
1605 QObject *object = component.create();
1606 QVERIFY(object != 0);
1608 // Read through alias
1609 QCOMPARE(object->property("aliasProperty").toInt(), 19);
1610 object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
1611 QCOMPARE(object->property("aliasProperty").toInt(), 33);
1613 // Write through alias
1614 object->setProperty("aliasProperty", QVariant(4));
1615 QCOMPARE(object->property("aliasProperty").toInt(), 4);
1616 QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
1622 // QTBUG-13374 Test that alias properties and signals can coexist
1623 void tst_qqmllanguage::aliasPropertiesAndSignals()
1625 QQmlComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
1627 QObject *o = component.create();
1629 QCOMPARE(o->property("test").toBool(), true);
1633 // Test that the root element in a composite type can be a Component
1634 void tst_qqmllanguage::componentCompositeType()
1636 QQmlComponent component(&engine, TEST_FILE("componentCompositeType.qml"));
1638 QObject *object = component.create();
1639 QVERIFY(object != 0);
1642 class TestType : public QObject {
1645 TestType(QObject *p=0) : QObject(p) {}
1648 class TestType2 : public QObject {
1651 TestType2(QObject *p=0) : QObject(p) {}
1654 void tst_qqmllanguage::i18n_data()
1656 QTest::addColumn<QString>("file");
1657 QTest::addColumn<QString>("stringProperty");
1658 QTest::newRow("i18nStrings") << "i18nStrings.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245 (5 accented 'a' letters)");
1659 QTest::newRow("i18nDeclaredPropertyNames") << "i18nDeclaredPropertyNames.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 10");
1660 QTest::newRow("i18nDeclaredPropertyUse") << "i18nDeclaredPropertyUse.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 15");
1661 QTest::newRow("i18nScript") << "i18nScript.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 20");
1662 QTest::newRow("i18nType") << "i18nType.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 30");
1663 QTest::newRow("i18nNameSpace") << "i18nNameSpace.qml" << QString::fromUtf8("Test \303\241\303\242\303\243\303\244\303\245: 40");
1666 void tst_qqmllanguage::i18n()
1668 QFETCH(QString, file);
1669 QFETCH(QString, stringProperty);
1670 QQmlComponent component(&engine, TEST_FILE(file));
1672 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
1673 QVERIFY(object != 0);
1674 QCOMPARE(object->stringProperty(), stringProperty);
1679 // Check that the Component::onCompleted attached property works
1680 void tst_qqmllanguage::onCompleted()
1682 QQmlComponent component(&engine, TEST_FILE("onCompleted.qml"));
1684 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1685 QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
1686 QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
1687 QObject *object = component.create();
1688 QVERIFY(object != 0);
1691 // Check that the Component::onDestruction attached property works
1692 void tst_qqmllanguage::onDestruction()
1694 QQmlComponent component(&engine, TEST_FILE("onDestruction.qml"));
1696 QObject *object = component.create();
1697 QVERIFY(object != 0);
1698 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1699 QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
1700 QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
1704 // Check that assignments to QQmlScriptString properties work
1705 void tst_qqmllanguage::scriptString()
1708 QQmlComponent component(&engine, TEST_FILE("scriptString.qml"));
1711 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1712 QVERIFY(object != 0);
1713 QCOMPARE(object->scriptProperty().script(), QString("foo + bar"));
1714 QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object));
1715 QCOMPARE(object->scriptProperty().context(), qmlContext(object));
1717 QVERIFY(object->grouped() != 0);
1718 QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)"));
1719 QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object));
1720 QCOMPARE(object->grouped()->script().context(), qmlContext(object));
1724 QQmlComponent component(&engine, TEST_FILE("scriptString2.qml"));
1727 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1728 QVERIFY(object != 0);
1729 QCOMPARE(object->scriptProperty().script(), QString("\"hello\\n\\\"world\\\"\""));
1733 QQmlComponent component(&engine, TEST_FILE("scriptString3.qml"));
1736 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1737 QVERIFY(object != 0);
1738 QCOMPARE(object->scriptProperty().script(), QString("12.345"));
1742 QQmlComponent component(&engine, TEST_FILE("scriptString4.qml"));
1745 MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
1746 QVERIFY(object != 0);
1747 QCOMPARE(object->scriptProperty().script(), QString("true"));
1751 // Check that default property assignments are correctly spliced into explicit
1752 // property assignments
1753 void tst_qqmllanguage::defaultPropertyListOrder()
1755 QQmlComponent component(&engine, TEST_FILE("defaultPropertyListOrder.qml"));
1758 MyContainer *container = qobject_cast<MyContainer *>(component.create());
1759 QVERIFY(container != 0);
1761 QCOMPARE(container->getChildren()->count(), 6);
1762 QCOMPARE(container->getChildren()->at(0)->property("index"), QVariant(0));
1763 QCOMPARE(container->getChildren()->at(1)->property("index"), QVariant(1));
1764 QCOMPARE(container->getChildren()->at(2)->property("index"), QVariant(2));
1765 QCOMPARE(container->getChildren()->at(3)->property("index"), QVariant(3));
1766 QCOMPARE(container->getChildren()->at(4)->property("index"), QVariant(4));
1767 QCOMPARE(container->getChildren()->at(5)->property("index"), QVariant(5));
1770 void tst_qqmllanguage::declaredPropertyValues()
1772 QQmlComponent component(&engine, TEST_FILE("declaredPropertyValues.qml"));
1776 void tst_qqmllanguage::dontDoubleCallClassBegin()
1778 QQmlComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml"));
1779 QObject *o = component.create();
1782 MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
1784 QCOMPARE(o2->classBeginCount(), 1);
1785 QCOMPARE(o2->componentCompleteCount(), 1);
1790 void tst_qqmllanguage::reservedWords_data()
1792 QTest::addColumn<QByteArray>("word");
1794 QTest::newRow("abstract") << QByteArray("abstract");
1795 QTest::newRow("as") << QByteArray("as");
1796 QTest::newRow("boolean") << QByteArray("boolean");
1797 QTest::newRow("break") << QByteArray("break");
1798 QTest::newRow("byte") << QByteArray("byte");
1799 QTest::newRow("case") << QByteArray("case");
1800 QTest::newRow("catch") << QByteArray("catch");
1801 QTest::newRow("char") << QByteArray("char");
1802 QTest::newRow("class") << QByteArray("class");
1803 QTest::newRow("continue") << QByteArray("continue");
1804 QTest::newRow("const") << QByteArray("const");
1805 QTest::newRow("debugger") << QByteArray("debugger");
1806 QTest::newRow("default") << QByteArray("default");
1807 QTest::newRow("delete") << QByteArray("delete");
1808 QTest::newRow("do") << QByteArray("do");
1809 QTest::newRow("double") << QByteArray("double");
1810 QTest::newRow("else") << QByteArray("else");
1811 QTest::newRow("enum") << QByteArray("enum");
1812 QTest::newRow("export") << QByteArray("export");
1813 QTest::newRow("extends") << QByteArray("extends");
1814 QTest::newRow("false") << QByteArray("false");
1815 QTest::newRow("final") << QByteArray("final");
1816 QTest::newRow("finally") << QByteArray("finally");
1817 QTest::newRow("float") << QByteArray("float");
1818 QTest::newRow("for") << QByteArray("for");
1819 QTest::newRow("function") << QByteArray("function");
1820 QTest::newRow("goto") << QByteArray("goto");
1821 QTest::newRow("if") << QByteArray("if");
1822 QTest::newRow("implements") << QByteArray("implements");
1823 QTest::newRow("import") << QByteArray("import");
1824 QTest::newRow("in") << QByteArray("in");
1825 QTest::newRow("instanceof") << QByteArray("instanceof");
1826 QTest::newRow("int") << QByteArray("int");
1827 QTest::newRow("interface") << QByteArray("interface");
1828 QTest::newRow("long") << QByteArray("long");
1829 QTest::newRow("native") << QByteArray("native");
1830 QTest::newRow("new") << QByteArray("new");
1831 QTest::newRow("null") << QByteArray("null");
1832 QTest::newRow("package") << QByteArray("package");
1833 QTest::newRow("private") << QByteArray("private");
1834 QTest::newRow("protected") << QByteArray("protected");
1835 QTest::newRow("public") << QByteArray("public");
1836 QTest::newRow("return") << QByteArray("return");
1837 QTest::newRow("short") << QByteArray("short");
1838 QTest::newRow("static") << QByteArray("static");
1839 QTest::newRow("super") << QByteArray("super");
1840 QTest::newRow("switch") << QByteArray("switch");
1841 QTest::newRow("synchronized") << QByteArray("synchronized");
1842 QTest::newRow("this") << QByteArray("this");
1843 QTest::newRow("throw") << QByteArray("throw");
1844 QTest::newRow("throws") << QByteArray("throws");
1845 QTest::newRow("transient") << QByteArray("transient");
1846 QTest::newRow("true") << QByteArray("true");
1847 QTest::newRow("try") << QByteArray("try");
1848 QTest::newRow("typeof") << QByteArray("typeof");
1849 QTest::newRow("var") << QByteArray("var");
1850 QTest::newRow("void") << QByteArray("void");
1851 QTest::newRow("volatile") << QByteArray("volatile");
1852 QTest::newRow("while") << QByteArray("while");
1853 QTest::newRow("with") << QByteArray("with");
1856 void tst_qqmllanguage::reservedWords()
1858 QFETCH(QByteArray, word);
1859 QQmlComponent component(&engine);
1860 component.setData("import QtQuick 2.0\nQtObject { property string " + word + " }", QUrl());
1861 QCOMPARE(component.errorString(), QLatin1String(":2 Expected token `identifier'\n"));
1864 // Check that first child of qml is of given type. Empty type insists on error.
1865 void tst_qqmllanguage::testType(const QString& qml, const QString& type, const QString& expectederror, bool partialMatch)
1867 QQmlComponent component(&engine);
1868 component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
1870 QTRY_VERIFY(!component.isLoading());
1872 if (type.isEmpty()) {
1873 QVERIFY(component.isError());
1874 QString actualerror;
1875 foreach (const QQmlError e, component.errors()) {
1876 if (!actualerror.isEmpty())
1877 actualerror.append("; ");
1878 actualerror.append(e.description());
1880 QCOMPARE(actualerror.left(partialMatch ? expectederror.length(): -1),expectederror);
1883 QObject *object = component.create();
1884 QVERIFY(object != 0);
1885 QCOMPARE(QString(object->metaObject()->className()), type);
1891 void tst_qqmllanguage::inlineAssignmentsOverrideBindings()
1893 QQmlComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml"));
1895 QObject *o = component.create();
1897 QCOMPARE(o->property("test").toInt(), 11);
1902 void tst_qqmllanguage::nestedComponentRoots()
1904 QQmlComponent component(&engine, TEST_FILE("nestedComponentRoots.qml"));
1907 // Import tests (QT-558)
1908 void tst_qqmllanguage::importsBuiltin_data()
1912 QTest::addColumn<QString>("qml");
1913 QTest::addColumn<QString>("type");
1914 QTest::addColumn<QString>("error");
1917 QTest::newRow("missing import")
1920 << "Test is not a type";
1921 QTest::newRow("not in version 0.0")
1922 << "import com.nokia.Test 0.0\n"
1925 << "Test is not a type";
1926 QTest::newRow("version not installed")
1927 << "import com.nokia.Test 99.0\n"
1930 << "module \"com.nokia.Test\" version 99.0 is not installed";
1931 QTest::newRow("in version 0.0")
1932 << "import com.nokia.Test 0.0\n"
1936 QTest::newRow("qualified in version 0.0")
1937 << "import com.nokia.Test 0.0 as T\n"
1941 QTest::newRow("in version 1.0")
1942 << "import com.nokia.Test 1.0\n"
1946 QTest::newRow("qualified wrong")
1947 << "import com.nokia.Test 1.0 as T\n" // QT-610
1950 << "Test is not a type";
1951 QTest::newRow("qualified right")
1952 << "import com.nokia.Test 1.0 as T\n"
1956 QTest::newRow("qualified right but not in version 0.0")
1957 << "import com.nokia.Test 0.0 as T\n"
1960 << "T.Test is not a type";
1961 QTest::newRow("in version 1.1")
1962 << "import com.nokia.Test 1.1\n"
1966 QTest::newRow("in version 1.3")
1967 << "import com.nokia.Test 1.3\n"
1971 QTest::newRow("in version 1.5")
1972 << "import com.nokia.Test 1.5\n"
1976 QTest::newRow("changed in version 1.8")
1977 << "import com.nokia.Test 1.8\n"
1981 QTest::newRow("in version 1.12")
1982 << "import com.nokia.Test 1.12\n"
1986 QTest::newRow("old in version 1.9")
1987 << "import com.nokia.Test 1.9\n"
1991 QTest::newRow("old in version 1.11")
1992 << "import com.nokia.Test 1.11\n"
1996 QTest::newRow("multiversion 1")
1997 << "import com.nokia.Test 1.11\n"
1998 "import com.nokia.Test 1.12\n"
2000 << (!qmlCheckTypes()?"TestType2":"")
2001 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test/ in version 1.12 and 1.11");
2002 QTest::newRow("multiversion 2")
2003 << "import com.nokia.Test 1.11\n"
2004 "import com.nokia.Test 1.12\n"
2006 << (!qmlCheckTypes()?"TestType":"")
2007 << (!qmlCheckTypes()?"":"OldTest is ambiguous. Found in com/nokia/Test/ in version 1.12 and 1.11");
2008 QTest::newRow("qualified multiversion 3")
2009 << "import com.nokia.Test 1.0 as T0\n"
2010 "import com.nokia.Test 1.8 as T8\n"
2014 QTest::newRow("qualified multiversion 4")
2015 << "import com.nokia.Test 1.0 as T0\n"
2016 "import com.nokia.Test 1.8 as T8\n"
2022 void tst_qqmllanguage::importsBuiltin()
2024 QFETCH(QString, qml);
2025 QFETCH(QString, type);
2026 QFETCH(QString, error);
2027 testType(qml,type,error);
2030 void tst_qqmllanguage::importsLocal_data()
2032 QTest::addColumn<QString>("qml");
2033 QTest::addColumn<QString>("type");
2034 QTest::addColumn<QString>("error");
2037 QTest::newRow("local import")
2038 << "import \"subdir\"\n" // QT-613
2040 << "QQuickRectangle"
2042 QTest::newRow("local import second")
2043 << "import QtQuick 2.0\nimport \"subdir\"\n"
2045 << "QQuickRectangle"
2047 QTest::newRow("local import subsubdir")
2048 << "import QtQuick 2.0\nimport \"subdir/subsubdir\"\n"
2050 << "QQuickRectangle"
2052 QTest::newRow("local import QTBUG-7721 A")
2053 << "subdir.Test {}" // no longer allowed (QTBUG-7721)
2055 << "subdir.Test - subdir is not a namespace";
2056 QTest::newRow("local import QTBUG-7721 B")
2057 << "import \"subdir\" as X\n"
2058 "X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
2060 << "X.subsubdir.SubTest - nested namespaces not allowed";
2061 QTest::newRow("local import as")
2062 << "import \"subdir\" as T\n"
2064 << "QQuickRectangle"
2066 QTest::newRow("wrong local import as")
2067 << "import \"subdir\" as T\n"
2070 << "Test is not a type";
2071 QTest::newRow("library precedence over local import")
2072 << "import \"subdir\"\n"
2073 "import com.nokia.Test 1.0\n"
2075 << (!qmlCheckTypes()?"TestType":"")
2076 << (!qmlCheckTypes()?"":"Test is ambiguous. Found in com/nokia/Test/ and in subdir/");
2079 void tst_qqmllanguage::importsLocal()
2081 QFETCH(QString, qml);
2082 QFETCH(QString, type);
2083 QFETCH(QString, error);
2084 testType(qml,type,error);
2087 void tst_qqmllanguage::basicRemote_data()
2089 QTest::addColumn<QUrl>("url");
2090 QTest::addColumn<QString>("type");
2091 QTest::addColumn<QString>("error");
2093 QString serverdir = "http://127.0.0.1:14447/qtest/qml/qqmllanguage/";
2095 QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
2096 QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << "";
2097 QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
2100 void tst_qqmllanguage::basicRemote()
2103 QFETCH(QString, type);
2104 QFETCH(QString, error);
2106 TestHTTPServer server(14447);
2107 server.serveDirectory(testdata());
2109 QQmlComponent component(&engine, url);
2111 QTRY_VERIFY(!component.isLoading());
2113 if (error.isEmpty()) {
2114 if (component.isError())
2115 qDebug() << component.errors();
2116 QVERIFY(!component.isError());
2118 QVERIFY(component.isError());
2122 void tst_qqmllanguage::importsRemote_data()
2124 QTest::addColumn<QString>("qml");
2125 QTest::addColumn<QString>("type");
2126 QTest::addColumn<QString>("error");
2128 QString serverdir = "http://127.0.0.1:14447/qtest/qml/qqmllanguage";
2130 QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QQuickRectangle"
2132 QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QQuickText"
2134 QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QQuickImage"
2136 QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
2137 << "WrongTestLocal is not a type";
2138 QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
2139 << "LocalInternal is not a type";
2140 QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""
2141 << "UndeclaredLocal is not a type";
2144 void tst_qqmllanguage::importsRemote()
2146 QFETCH(QString, qml);
2147 QFETCH(QString, type);
2148 QFETCH(QString, error);
2150 TestHTTPServer server(14447);
2151 server.serveDirectory(testdata());
2153 testType(qml,type,error);
2156 void tst_qqmllanguage::importsInstalled_data()
2160 QTest::addColumn<QString>("qml");
2161 QTest::addColumn<QString>("type");
2162 QTest::addColumn<QString>("error");
2165 QTest::newRow("installed import 0")
2166 << "import com.nokia.installedtest0 0.0\n"
2167 "InstalledTestTP {}"
2168 << "QQuickRectangle"
2170 QTest::newRow("installed import 0 as TP")
2171 << "import com.nokia.installedtest0 0.0 as TP\n"
2172 "TP.InstalledTestTP {}"
2173 << "QQuickRectangle"
2175 QTest::newRow("installed import 1")
2176 << "import com.nokia.installedtest 1.0\n"
2178 << "QQuickRectangle"
2180 QTest::newRow("installed import 2")
2181 << "import com.nokia.installedtest 1.3\n"
2183 << "QQuickRectangle"
2185 QTest::newRow("installed import 3")
2186 << "import com.nokia.installedtest 1.4\n"
2190 QTest::newRow("installed import minor version not available") // QTBUG-11936
2191 << "import com.nokia.installedtest 0.1\n"
2194 << "module \"com.nokia.installedtest\" version 0.1 is not installed";
2195 QTest::newRow("installed import minor version not available") // QTBUG-9627
2196 << "import com.nokia.installedtest 1.10\n"
2199 << "module \"com.nokia.installedtest\" version 1.10 is not installed";
2200 QTest::newRow("installed import major version not available") // QTBUG-9627
2201 << "import com.nokia.installedtest 9.0\n"
2204 << "module \"com.nokia.installedtest\" version 9.0 is not installed";
2205 QTest::newRow("installed import visibility") // QT-614
2206 << "import com.nokia.installedtest 1.4\n"
2209 << "PrivateType is not a type";
2210 QTest::newRow("installed import version QML clash")
2211 << "import com.nokia.installedtest1 1.0\n"
2214 << "\"Test\" version 1.0 is already defined in module \"com.nokia.installedtest1\"";
2215 QTest::newRow("installed import version JS clash")
2216 << "import com.nokia.installedtest2 1.0\n"
2219 << "\"Test\" version 1.0 is already defined in module \"com.nokia.installedtest2\"";
2222 void tst_qqmllanguage::importsInstalled()
2224 QFETCH(QString, qml);
2225 QFETCH(QString, type);
2226 QFETCH(QString, error);
2227 testType(qml,type,error);
2231 void tst_qqmllanguage::importsOrder_data()
2233 QTest::addColumn<QString>("qml");
2234 QTest::addColumn<QString>("type");
2235 QTest::addColumn<QString>("error");
2236 QTest::addColumn<bool>("partialMatch");
2238 QTest::newRow("double import") <<
2239 "import com.nokia.installedtest 1.4\n"
2240 "import com.nokia.installedtest 1.4\n"
2242 << (!qmlCheckTypes()?"QQuickText":"")
2243 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.4 and 1.4")
2245 QTest::newRow("installed import overrides 1") <<
2246 "import com.nokia.installedtest 1.0\n"
2247 "import com.nokia.installedtest 1.4\n"
2249 << (!qmlCheckTypes()?"QQuickText":"")
2250 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.4 and 1.0")
2252 QTest::newRow("installed import overrides 2") <<
2253 "import com.nokia.installedtest 1.4\n"
2254 "import com.nokia.installedtest 1.0\n"
2256 << (!qmlCheckTypes()?"QQuickRectangle":"")
2257 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.0 and 1.4")
2259 QTest::newRow("installed import re-overrides 1") <<
2260 "import com.nokia.installedtest 1.4\n"
2261 "import com.nokia.installedtest 1.0\n"
2262 "import com.nokia.installedtest 1.4\n"
2264 << (!qmlCheckTypes()?"QQuickText":"")
2265 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.4 and 1.0")
2267 QTest::newRow("installed import re-overrides 2") <<
2268 "import com.nokia.installedtest 1.4\n"
2269 "import com.nokia.installedtest 1.0\n"
2270 "import com.nokia.installedtest 1.4\n"
2271 "import com.nokia.installedtest 1.0\n"
2273 << (!qmlCheckTypes()?"QQuickRectangle":"")
2274 << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.0 and 1.4")
2276 QTest::newRow("installed import versus builtin 1") <<
2277 "import com.nokia.installedtest 1.5\n"
2278 "import QtQuick 2.0\n"
2280 << (!qmlCheckTypes()?"QQuickRectangle":"")
2281 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in file://")
2283 QTest::newRow("installed import versus builtin 2") <<
2284 "import QtQuick 2.0\n"
2285 "import com.nokia.installedtest 1.5\n"
2287 << (!qmlCheckTypes()?"QQuickText":"")
2288 << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest/ and in file://")
2290 QTest::newRow("namespaces cannot be overridden by types 1") <<
2291 "import QtQuick 2.0 as Rectangle\n"
2292 "import com.nokia.installedtest 1.5\n"
2295 << "Namespace Rectangle cannot be used as a type"
2297 QTest::newRow("namespaces cannot be overridden by types 2") <<
2298 "import QtQuick 2.0 as Rectangle\n"
2299 "import com.nokia.installedtest 1.5\n"
2300 "Rectangle.Image {}"
2304 QTest::newRow("local last 1") <<
2309 QTest::newRow("local last 2") <<
2310 "import com.nokia.installedtest 1.0\n"
2312 << (!qmlCheckTypes()?"QQuickRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
2313 << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest/ and in ")
2317 void tst_qqmllanguage::importsOrder()
2319 QFETCH(QString, qml);
2320 QFETCH(QString, type);
2321 QFETCH(QString, error);
2322 QFETCH(bool, partialMatch);
2323 testType(qml,type,error,partialMatch);
2326 void tst_qqmllanguage::importIncorrectCase()
2328 QQmlComponent component(&engine, TEST_FILE("importIncorrectCase.qml"));
2330 QList<QQmlError> errors = component.errors();
2331 QCOMPARE(errors.count(), 1);
2333 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
2334 QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + testdata("lib/com/Nokia/installedtest/qmldir") + QLatin1String("\"");
2336 QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
2339 QCOMPARE(errors.at(0).description(), expectedError);
2342 void tst_qqmllanguage::importJs_data()
2344 QTest::addColumn<QString>("file");
2345 QTest::addColumn<QString>("errorFile");
2346 QTest::addColumn<bool>("performTest");
2348 QTest::newRow("defaultVersion")
2350 << "importJs.1.errors.txt"
2353 QTest::newRow("specifiedVersion")
2355 << "importJs.2.errors.txt"
2358 QTest::newRow("excludeExcessiveVersion")
2360 << "importJs.3.errors.txt"
2363 QTest::newRow("includeAppropriateVersion")
2365 << "importJs.4.errors.txt"
2368 QTest::newRow("noDefaultVersion")
2370 << "importJs.5.errors.txt"
2373 QTest::newRow("repeatImportFails")
2375 << "importJs.6.errors.txt"
2378 QTest::newRow("multipleVersionImportFails")
2380 << "importJs.7.errors.txt"
2383 QTest::newRow("namespacedImport")
2385 << "importJs.8.errors.txt"
2388 QTest::newRow("namespacedVersionedImport")
2390 << "importJs.9.errors.txt"
2393 QTest::newRow("namespacedRepeatImport")
2394 << "importJs.10.qml"
2395 << "importJs.10.errors.txt"
2399 void tst_qqmllanguage::importJs()
2401 QFETCH(QString, file);
2402 QFETCH(QString, errorFile);
2403 QFETCH(bool, performTest);
2405 QQmlComponent component(&engine, TEST_FILE(file));
2408 DETERMINE_ERRORS(errorFile.toLatin1().constData(),expected,actual);
2409 QCOMPARE(expected.size(), actual.size());
2410 for (int i = 0; i < expected.size(); ++i)
2412 size_t compareLen = std::min(expected.at(i).length(), actual.at(i).length());
2413 QCOMPARE(expected.at(i).left(compareLen), actual.at(i).left(compareLen));
2418 QObject *object = component.create();
2419 QVERIFY(object != 0);
2420 QCOMPARE(object->property("test").toBool(),true);
2425 void tst_qqmllanguage::qmlAttachedPropertiesObjectMethod()
2429 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
2430 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
2433 QQmlComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml"));
2435 QObject *object = component.create();
2436 QVERIFY(object != 0);
2438 QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0);
2439 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
2443 QQmlComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml"));
2445 QObject *object = component.create();
2446 QVERIFY(object != 0);
2448 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0);
2449 QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0);
2453 void tst_qqmllanguage::crash1()
2455 QQmlComponent component(&engine);
2456 component.setData("import QtQuick 2.0\nComponent {}", QUrl());
2459 void tst_qqmllanguage::crash2()
2461 QQmlComponent component(&engine, TEST_FILE("crash2.qml"));
2465 void tst_qqmllanguage::customOnProperty()
2467 QQmlComponent component(&engine, TEST_FILE("customOnProperty.qml"));
2470 QObject *object = component.create();
2471 QVERIFY(object != 0);
2473 QCOMPARE(object->property("on").toInt(), 10);
2479 void tst_qqmllanguage::variantNotify()
2481 QQmlComponent component(&engine, TEST_FILE("variantNotify.qml"));
2484 QObject *object = component.create();
2485 QVERIFY(object != 0);
2487 QCOMPARE(object->property("notifyCount").toInt(), 1);
2492 void tst_qqmllanguage::revisions()
2495 QQmlComponent component(&engine, TEST_FILE("revisions11.qml"));
2498 MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
2499 QVERIFY(object != 0);
2501 QCOMPARE(object->prop2(), 10.0);
2506 QQmlEngine myEngine;
2507 QQmlComponent component(&myEngine, TEST_FILE("revisionssub11.qml"));
2510 MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
2511 QVERIFY(object != 0);
2513 QCOMPARE(object->prop1(), 10.0);
2514 QCOMPARE(object->prop2(), 10.0);
2515 QCOMPARE(object->prop3(), 10.0);
2516 QCOMPARE(object->prop4(), 10.0);
2521 QQmlComponent component(&engine, TEST_FILE("versionedbase.qml"));
2523 MySubclass *object = qobject_cast<MySubclass*>(component.create());
2524 QVERIFY(object != 0);
2526 QCOMPARE(object->prop1(), 10.0);
2527 QCOMPARE(object->prop2(), 10.0);
2533 void tst_qqmllanguage::revisionOverloads()
2536 QQmlComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml"));
2540 QQmlComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml"));
2541 QEXPECT_FAIL("", "QTBUG-13849", Abort);
2543 VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt");
2547 void tst_qqmllanguage::subclassedUncreateableRevision_data()
2549 QTest::addColumn<QString>("version");
2550 QTest::addColumn<QString>("prop");
2551 QTest::addColumn<bool>("shouldWork");
2553 QTest::newRow("prop1 exists in 1.0") << "1.0" << "prop1" << true;
2554 QTest::newRow("prop2 does not exist in 1.0") << "1.0" << "prop2" << false;
2555 QTest::newRow("prop3 does not exist in 1.0") << "1.0" << "prop3" << false;
2557 QTest::newRow("prop1 exists in 1.1") << "1.1" << "prop1" << true;
2558 QTest::newRow("prop2 works because it's re-declared in Derived") << "1.1" << "prop2" << true;
2559 QTest::newRow("prop3 only works if the Base REVISION 1 is picked up") << "1.1" << "prop3" << true;
2563 void tst_qqmllanguage::subclassedUncreateableRevision()
2565 QFETCH(QString, version);
2566 QFETCH(QString, prop);
2567 QFETCH(bool, shouldWork);
2571 QString qml = QString("import QtQuick 2.0\nimport Test %1\nMyUncreateableBaseClass {}").arg(version);
2572 QQmlComponent c(&engine);
2573 QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
2574 c.setData(qml.toUtf8(), QUrl::fromLocalFile(QDir::currentPath()));
2575 QObject *obj = c.create();
2576 QCOMPARE(obj, static_cast<QObject*>(0));
2577 QCOMPARE(c.errors().count(), 1);
2578 QCOMPARE(c.errors().first().description(), QString("Cannot create MyUncreateableBaseClass"));
2582 QString qml = QString("import QtQuick 2.0\nimport Test %1\nMyCreateableDerivedClass {\n%3: true\n}").arg(version).arg(prop);
2583 QQmlComponent c(&engine);
2585 QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
2586 c.setData(qml.toUtf8(), QUrl::fromLocalFile(QDir::currentPath()));
2587 QObject *obj = c.create();
2589 QCOMPARE(obj, static_cast<QObject*>(0));
2594 MyUncreateableBaseClass *base = qobject_cast<MyUncreateableBaseClass*>(obj);
2596 QCOMPARE(base->property(prop.toLatin1()).toBool(), true);
2600 void tst_qqmllanguage::initTestCase()
2602 QString testdataDir = QFileInfo(QFINDTESTDATA("data")).absolutePath();
2603 QVERIFY2(QDir::setCurrent(testdataDir), qPrintable("Could not chdir to " + testdataDir));
2607 // Registering the TestType class in other modules should have no adverse effects
2608 qmlRegisterType<TestType>("com.nokia.TestPre", 1, 0, "Test");
2610 qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP");
2611 qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test");
2612 qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test");
2613 qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test");
2614 qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest");
2615 qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test");
2617 // Registering the TestType class in other modules should have no adverse effects
2618 qmlRegisterType<TestType>("com.nokia.TestPost", 1, 0, "Test");
2620 // Create locale-specific file
2621 // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit
2622 // For iso8859-1 locale, this will just be data/I18nType?????.qml where ????? is 5 8-bit characters
2623 // For utf-8 locale, this will be data/I18nType??????????.qml where ?????????? is 5 8-bit characters, UTF-8 encoded
2624 QFile in(TEST_FILE(QLatin1String("I18nType30.qml")).toLocalFile());
2625 QVERIFY2(in.open(QIODevice::ReadOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(in.fileName(), in.errorString())));
2626 QFile out(TEST_FILE(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml")).toLocalFile());
2627 QVERIFY2(out.open(QIODevice::WriteOnly), qPrintable(QString::fromLatin1("Cannot open '%1': %2").arg(out.fileName(), out.errorString())));
2628 out.write(in.readAll());
2631 void tst_qqmllanguage::aliasPropertyChangeSignals()
2634 QQmlComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.qml"));
2637 QObject *o = component.create();
2640 QCOMPARE(o->property("test").toBool(), true);
2645 // QTCREATORBUG-2769
2647 QQmlComponent component(&engine, TEST_FILE("aliasPropertyChangeSignals.2.qml"));
2650 QObject *o = component.create();
2653 QCOMPARE(o->property("test").toBool(), true);
2659 // Tests property initializers
2660 void tst_qqmllanguage::propertyInit()
2663 QQmlComponent component(&engine, TEST_FILE("propertyInit.1.qml"));
2666 QObject *o = component.create();
2669 QCOMPARE(o->property("test").toInt(), 1);
2675 QQmlComponent component(&engine, TEST_FILE("propertyInit.2.qml"));
2678 QObject *o = component.create();
2681 QCOMPARE(o->property("test").toInt(), 123);
2687 // Test that registration order doesn't break type availability
2689 void tst_qqmllanguage::registrationOrder()
2691 QQmlComponent component(&engine, TEST_FILE("registrationOrder.qml"));
2693 QObject *o = component.create();
2695 QVERIFY(o->metaObject() == &MyVersion2Class::staticMetaObject);
2699 void tst_qqmllanguage::readonly()
2701 QQmlComponent component(&engine, TEST_FILE("readonly.qml"));
2703 QObject *o = component.create();
2706 QCOMPARE(o->property("test1").toInt(), 10);
2707 QCOMPARE(o->property("test2").toInt(), 18);
2708 QCOMPARE(o->property("test3").toInt(), 13);
2710 o->setProperty("testData", 13);
2712 QCOMPARE(o->property("test1").toInt(), 10);
2713 QCOMPARE(o->property("test2").toInt(), 22);
2714 QCOMPARE(o->property("test3").toInt(), 13);
2716 o->setProperty("testData2", 2);
2718 QCOMPARE(o->property("test1").toInt(), 10);
2719 QCOMPARE(o->property("test2").toInt(), 22);
2720 QCOMPARE(o->property("test3").toInt(), 2);
2722 o->setProperty("test1", 11);
2723 o->setProperty("test2", 11);
2724 o->setProperty("test3", 11);
2726 QCOMPARE(o->property("test1").toInt(), 10);
2727 QCOMPARE(o->property("test2").toInt(), 22);
2728 QCOMPARE(o->property("test3").toInt(), 2);
2733 void tst_qqmllanguage::receivers()
2735 QQmlComponent component(&engine, TEST_FILE("receivers.qml"));
2737 MyReceiversTestObject *o = qobject_cast<MyReceiversTestObject*>(component.create());
2739 QCOMPARE(o->mySignalCount(), 1);
2740 QCOMPARE(o->propChangedCount(), 2);
2741 QCOMPARE(o->myUnconnectedSignalCount(), 0);
2743 QVERIFY(o->isSignalConnected(QMetaMethod::fromSignal(&MyReceiversTestObject::mySignal)));
2744 QVERIFY(o->isSignalConnected(QMetaMethod::fromSignal(&MyReceiversTestObject::propChanged)));
2745 QVERIFY(!o->isSignalConnected(QMetaMethod::fromSignal(&MyReceiversTestObject::myUnconnectedSignal)));
2751 void tst_qqmllanguage::remoteLoadCrash()
2753 TestHTTPServer server(14448);
2754 server.serveDirectory(testdata());
2756 QQmlComponent component(&engine);
2757 component.setData("import QtQuick 2.0; Text {}", QUrl("http://127.0.0.1:14448/remoteLoadCrash.qml"));
2758 while (component.isLoading())
2759 QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
2761 QObject *o = component.create();
2765 void tst_qqmllanguage::signalWithDefaultArg()
2767 QQmlComponent component(&engine, TEST_FILE("signalWithDefaultArg.qml"));
2769 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
2770 QVERIFY(object != 0);
2772 QCOMPARE(object->property("signalCount").toInt(), 0);
2773 QCOMPARE(object->property("signalArg").toInt(), 0);
2775 emit object->signalWithDefaultArg();
2776 QCOMPARE(object-> property("signalCount").toInt(), 1);
2777 QCOMPARE(object->property("signalArg").toInt(), 5);
2779 emit object->signalWithDefaultArg(15);
2780 QCOMPARE(object->property("signalCount").toInt(), 2);
2781 QCOMPARE(object->property("signalArg").toInt(), 15);
2783 const QMetaObject *metaObject = object->metaObject();
2785 metaObject->invokeMethod(object, "emitNoArgSignal");
2786 QCOMPARE(object->property("signalCount").toInt(), 3);
2787 QCOMPARE(object->property("signalArg").toInt(), 5);
2789 metaObject->invokeMethod(object, "emitArgSignal");
2790 QCOMPARE(object->property("signalCount").toInt(), 4);
2791 QCOMPARE(object->property("signalArg").toInt(), 22);
2797 void tst_qqmllanguage::globalEnums()
2799 qRegisterMetaType<MyEnum1Class::EnumA>();
2800 qRegisterMetaType<MyEnum2Class::EnumB>();
2801 qRegisterMetaType<Qt::TextFormat>();
2803 QQmlComponent component(&engine, TEST_FILE("globalEnums.qml"));
2805 QObject *o = component.create();
2808 MyEnum1Class *enum1Class = o->findChild<MyEnum1Class *>(QString::fromLatin1("enum1Class"));
2809 QVERIFY(enum1Class != 0);
2810 QVERIFY(enum1Class->getValue() == -1);
2812 MyEnumDerivedClass *enum2Class = o->findChild<MyEnumDerivedClass *>(QString::fromLatin1("enumDerivedClass"));
2813 QVERIFY(enum2Class != 0);
2814 QVERIFY(enum2Class->getValueA() == -1);
2815 QVERIFY(enum2Class->getValueB() == -1);
2816 QVERIFY(enum2Class->getValueC() == 0);
2817 QVERIFY(enum2Class->getValueD() == 0);
2818 QVERIFY(enum2Class->getValueE() == -1);
2819 QVERIFY(enum2Class->getValueE2() == -1);
2821 QVERIFY(enum2Class->property("aValue") == 0);
2822 QVERIFY(enum2Class->property("bValue") == 0);
2823 QVERIFY(enum2Class->property("cValue") == 0);
2824 QVERIFY(enum2Class->property("dValue") == 0);
2825 QVERIFY(enum2Class->property("eValue") == 0);
2826 QVERIFY(enum2Class->property("e2Value") == 0);
2828 QSignalSpy signalA(enum2Class, SIGNAL(valueAChanged(MyEnum1Class::EnumA)));
2829 QSignalSpy signalB(enum2Class, SIGNAL(valueBChanged(MyEnum2Class::EnumB)));
2831 QMetaObject::invokeMethod(o, "setEnumValues");
2833 QVERIFY(enum1Class->getValue() == MyEnum1Class::A_13);
2834 QVERIFY(enum2Class->getValueA() == MyEnum1Class::A_11);
2835 QVERIFY(enum2Class->getValueB() == MyEnum2Class::B_37);
2836 QVERIFY(enum2Class->getValueC() == Qt::RichText);
2837 QVERIFY(enum2Class->getValueD() == Qt::ElideMiddle);
2838 QVERIFY(enum2Class->getValueE() == MyEnum2Class::E_14);
2839 QVERIFY(enum2Class->getValueE2() == MyEnum2Class::E_76);
2841 QVERIFY(signalA.count() == 1);
2842 QVERIFY(signalB.count() == 1);
2844 QVERIFY(enum2Class->property("aValue") == MyEnum1Class::A_11);
2845 QVERIFY(enum2Class->property("bValue") == 37);
2846 QVERIFY(enum2Class->property("cValue") == 1);
2847 QVERIFY(enum2Class->property("dValue") == 2);
2848 QVERIFY(enum2Class->property("eValue") == 14);
2849 QVERIFY(enum2Class->property("e2Value") == 76);
2854 void tst_qqmllanguage::literals_data()
2856 QTest::addColumn<QString>("property");
2857 QTest::addColumn<QVariant>("value");
2859 QTest::newRow("hex") << "n1" << QVariant(0xfe32);
2860 // Octal integer literals are deprecated
2861 // QTest::newRow("octal") << "n2" << QVariant(015);
2862 QTest::newRow("fp1") << "n3" << QVariant(-4.2E11);
2863 QTest::newRow("fp2") << "n4" << QVariant(.1e9);
2864 QTest::newRow("fp3") << "n5" << QVariant(3e-12);
2865 QTest::newRow("fp4") << "n6" << QVariant(3e+12);
2866 QTest::newRow("fp5") << "n7" << QVariant(0.1e9);
2868 QTest::newRow("special1") << "c1" << QVariant(QString("\b"));
2869 QTest::newRow("special2") << "c2" << QVariant(QString("\f"));
2870 QTest::newRow("special3") << "c3" << QVariant(QString("\n"));
2871 QTest::newRow("special4") << "c4" << QVariant(QString("\r"));
2872 QTest::newRow("special5") << "c5" << QVariant(QString("\t"));
2873 QTest::newRow("special6") << "c6" << QVariant(QString("\v"));
2874 QTest::newRow("special7") << "c7" << QVariant(QString("\'"));
2875 QTest::newRow("special8") << "c8" << QVariant(QString("\""));
2876 QTest::newRow("special9") << "c9" << QVariant(QString("\\"));
2877 // We don't handle octal escape sequences
2878 // QTest::newRow("special10") << "c10" << QVariant(QString("\251"));
2879 QTest::newRow("special11") << "c11" << QVariant(QString::fromLatin1("\xa9"));
2880 QTest::newRow("special12") << "c12" << QVariant(QString::fromUtf8("\u00A9"));
2883 void tst_qqmllanguage::literals()
2885 QFETCH(QString, property);
2886 QFETCH(QVariant, value);
2888 QQmlComponent component(&engine, TEST_FILE("literals.qml"));
2890 QObject *object = component.create();
2891 QVERIFY(object != 0);
2892 QCOMPARE(object->property(property.toLatin1()), value);
2896 QTEST_MAIN(tst_qqmllanguage)
2898 #include "tst_qqmllanguage.moc"