aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml')
-rw-r--r--tests/auto/qml/bindingdependencyapi/bindingdependencyapi.pro11
-rw-r--r--tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp360
-rw-r--r--tests/auto/qml/debugger/debugger.pro3
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro2
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp84
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp153
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp534
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp3
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro4
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro14
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp126
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp (renamed from tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp)37
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro11
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp24
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro4
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp86
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro4
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp106
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro2
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp26
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro2
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp83
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml7
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml2
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml9
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro3
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp760
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp37
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.cpp241
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.pri11
-rw-r--r--tests/auto/qml/debugger/shared/debugutil_p.h84
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugprocess.cpp245
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugprocess_p.h99
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp2
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations148
m---------tests/auto/qml/ecmascripttests/test2620
-rwxr-xr-xtests/auto/qml/ecmascripttests/test262.py4
-rw-r--r--tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp36
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp29
-rw-r--r--tests/auto/qml/qjsonbinding/qjsonbinding.pro1
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp4
-rw-r--r--tests/auto/qml/qml.pro20
-rw-r--r--tests/auto/qml/qmlcachegen/qmlcachegen.pro6
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp87
-rw-r--r--tests/auto/qml/qmlcachegen/worker.js3
-rw-r--r--tests/auto/qml/qmlcachegen/worker.qml12
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp50
-rw-r--r--tests/auto/qml/qmlmin/qmlmin.pro6
-rw-r--r--tests/auto/qml/qmlmin/tst_qmlmin.cpp2
-rw-r--r--tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/Singleton.qml (renamed from tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml)0
-rw-r--r--tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/qmldir (renamed from tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir)0
-rw-r--r--tests/auto/qml/qmlplugindump/qmlplugindump.pro6
-rw-r--r--tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp13
-rw-r--r--tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro6
-rw-r--r--tests/auto/qml/qqmlbinding/data/bindingOverwriting.qml13
-rw-r--r--tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp16
-rw-r--r--tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp29
-rw-r--r--tests/auto/qml/qqmlcomponent/qqmlcomponent.pro1
-rw-r--r--tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp2
-rw-r--r--tests/auto/qml/qqmlconnections/data/connection-no-signal-name.qml15
-rw-r--r--tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp10
-rw-r--r--tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp29
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.1.qml25
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.2.qml17
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.3.qml29
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.4.qml29
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.5.qml37
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.6.qml33
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.qml19
-rw-r--r--tests/auto/qml/qqmlecmascript/data/dynamicString.qml2
-rw-r--r--tests/auto/qml/qqmlecmascript/data/nonNotifyableConstant.qml5
-rw-r--r--tests/auto/qml/qqmlecmascript/data/sequenceSort.qml14
-rw-r--r--tests/auto/qml/qqmlecmascript/qqmlecmascript.pro1
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp24
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h7
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp314
-rw-r--r--tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml10
-rw-r--r--tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml10
-rw-r--r--tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml7
-rw-r--r--tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml7
-rw-r--r--tests/auto/qml/qqmlengine/qqmlengine.pro5
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp19
-rw-r--r--tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp2
-rw-r--r--tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro1
-rw-r--r--tests/auto/qml/qqmlinstantiator/stringmodel.h4
-rw-r--r--tests/auto/qml/qqmlitemmodels/qtestmodel.h2
-rw-r--r--tests/auto/qml/qqmllanguage/data/TypeWithEnum.qml28
-rw-r--r--tests/auto/qml/qqmllanguage/data/circularSingleton.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppnamespace.qml1
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceOf/qmldir2
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml13
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml13
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml14
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml26
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml27
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/NonSingletonType.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/SingletonType.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/qmldir4
-rw-r--r--tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/test.js1
-rw-r--r--tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/mixedModuleWithSelfImport.qml3
-rw-r--r--tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml2
-rw-r--r--tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir3
-rw-r--r--tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml1
-rw-r--r--tests/auto/qml/qqmllanguage/data/scopedEnum.qml21
-rw-r--r--tests/auto/qml/qqmllanguage/data/scopedEnumList.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/scopedEnumList.qml10
-rw-r--r--tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml12
-rw-r--r--tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir1
-rw-r--r--tests/auto/qml/qqmllanguage/data/usingTypeWithEnum.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/qqmllanguage.pro1
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp2
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h18
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp311
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp32
-rw-r--r--tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp8
-rw-r--r--tests/auto/qml/qqmllocale/tst_qqmllocale.cpp8
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp6
-rw-r--r--tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp6
-rw-r--r--tests/auto/qml/qqmlqt/tst_qqmlqt.cpp5
-rw-r--r--tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml5
-rw-r--r--tests/auto/qml/qqmltranslation/data/translationChange.qml10
-rw-r--r--tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp46
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expectbin0 -> 223 bytes
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.qml23
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro1
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp3
-rw-r--r--tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp16
-rw-r--r--tests/auto/qml/qwidgetsinqml/qwidgetsinqml.pro7
-rw-r--r--tests/auto/qml/qwidgetsinqml/tst_qwidgetsinqml.cpp283
155 files changed, 3734 insertions, 1723 deletions
diff --git a/tests/auto/qml/bindingdependencyapi/bindingdependencyapi.pro b/tests/auto/qml/bindingdependencyapi/bindingdependencyapi.pro
new file mode 100644
index 0000000000..430d87ab5b
--- /dev/null
+++ b/tests/auto/qml/bindingdependencyapi/bindingdependencyapi.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_bindingdependencyapi
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_bindingdependencyapi.cpp
+
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+QT += core-private gui-private qml-private quick-private testlib
diff --git a/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp b/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp
new file mode 100644
index 0000000000..6f24f85f6d
--- /dev/null
+++ b/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp
@@ -0,0 +1,360 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <private/qqmldata_p.h>
+#include <private/qqmlbinding_p.h>
+#include <QtQuick/private/qquicktext_p.h>
+#include <QtQuick/private/qquickrectangle_p.h>
+#include "../../shared/util.h"
+#include <qqmlcontext.h>
+
+class tst_bindingdependencyapi : public QObject
+{
+ Q_OBJECT
+public:
+ tst_bindingdependencyapi();
+
+private slots:
+ void testSingleDep_data();
+ void testSingleDep();
+ void testManyDeps_data();
+ void testManyDeps();
+ void testConditionalDependencies_data();
+ void testConditionalDependencies();
+ void testBindingLoop();
+
+private:
+ bool findProperties(const QVector<QQmlProperty> &properties, QObject *obj, const QString &propertyName, const QVariant &value);
+};
+
+tst_bindingdependencyapi::tst_bindingdependencyapi()
+{
+}
+
+
+void tst_bindingdependencyapi::testSingleDep_data()
+{
+ QTest::addColumn<QByteArray>("code");
+ QTest::addColumn<QString>("referencedObjectName");
+
+ QTest::addRow("context property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "objectName: \"rect\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { text: labelText }\n"
+ "}") << "rect";
+
+ QTest::addRow("scope property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "property string labelText: \"I am wrong!\"\n"
+ "Text {\n"
+ "objectName: \"text\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "text: labelText\n"
+ "}\n"
+ "}") << "text";
+
+ QTest::addRow("id object property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: \"rect\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { text: rect.labelText }\n"
+ "}") << "rect";
+
+ QTest::addRow("dynamic context property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "objectName: \"rect\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { Component.onCompleted: text = Qt.binding(function() { return labelText; }); }\n"
+ "}") << "rect";
+
+ QTest::addRow("dynamic scope property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "property string labelText: \"I am wrong!\"\n"
+ "Text {\n"
+ "objectName: \"text\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Component.onCompleted: text = Qt.binding(function() { return labelText; });\n"
+ "}\n"
+ "}") << "text";
+
+ QTest::addRow("dynamic id object property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: \"rect\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { Component.onCompleted: text = Qt.binding(function() { return rect.labelText; }); }\n"
+ "}") << "rect";
+}
+
+void tst_bindingdependencyapi::testSingleDep()
+{
+ QFETCH(QByteArray, code);
+ QFETCH(QString, referencedObjectName);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(code, QUrl());
+ QObject *rect = c.create();
+ QTest::qWait(10);
+ QVERIFY(rect != 0);
+ QObject *text = rect->findChildren<QQuickText *>().front();
+
+ QObject *referencedObject = rect->objectName() == referencedObjectName ? rect : rect->findChild<QObject *>(referencedObjectName);
+
+ auto data = QQmlData::get(text);
+ QVERIFY(data);
+ auto b = data->bindings;
+ QVERIFY(b);
+ auto binding = dynamic_cast<QQmlBinding*>(b);
+ QVERIFY(binding);
+ auto dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 1);
+ auto dependency = dependencies.front();
+ QVERIFY(dependency.isValid());
+ QCOMPARE(quintptr(dependency.object()), quintptr(referencedObject));
+ QCOMPARE(dependency.property().name(), "labelText");
+ QCOMPARE(dependency.read().toString(), QStringLiteral("Hello world!"));
+ QCOMPARE(dependency, QQmlProperty(referencedObject, "labelText"));
+
+ delete rect;
+}
+
+bool tst_bindingdependencyapi::findProperties(const QVector<QQmlProperty> &properties, QObject *obj, const QString &propertyName, const QVariant &value)
+{
+ auto dep = std::find_if(properties.cbegin(), properties.cend(), [&](const QQmlProperty &dep) {
+ return dep.object() == obj
+ && dep.property().name() == propertyName
+ && dep.read() == value;
+ });
+ if (dep == properties.cend()) {
+ qWarning() << "Searched for property with:" << "{ object:" << obj << ", propertyName:" << propertyName << ", value:" << value << "}" << "but only found:";
+ for (auto dep : properties) {
+ qWarning() << "{ object:" << dep.object() << ", propertyName:" << dep.property().name() << ", value:" << dep.read() << "}";
+ }
+ return false;
+ }
+ return true;
+}
+
+void tst_bindingdependencyapi::testManyDeps_data()
+{
+ QTest::addColumn<QByteArray>("code");
+
+ QTest::addRow("permanent binding")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: 'rect'\n"
+ "property string name: 'world'\n"
+ "Text {\n"
+ "text: config.helloWorldTemplate.arg(greeting).arg(rect.name) \n"
+ "property string greeting: 'Hello'\n"
+ "}\n"
+ "QtObject { id: config; objectName: 'config'; property string helloWorldTemplate: '%1 %2!' }\n"
+ "}");
+
+ QTest::addRow("dynamic binding")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: 'rect'\n"
+ "property string name: 'world'\n"
+ "Text {\n"
+ "Component.onCompleted: text = Qt.binding(function() { return config.helloWorldTemplate.arg(greeting).arg(rect.name); }); \n"
+ "property string greeting: 'Hello'\n"
+ "}\n"
+ "QtObject { id: config; objectName: 'config'; property string helloWorldTemplate: '%1 %2!' }\n"
+ "}");
+}
+
+void tst_bindingdependencyapi::testManyDeps()
+{
+ QFETCH(QByteArray, code);
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(code, QUrl());
+ QObject *rect = c.create();
+ if (c.isError()) {
+ qWarning() << c.errorString();
+ }
+ QTest::qWait(100);
+ QVERIFY(rect != 0);
+ QObject *text = rect->findChildren<QQuickText *>().front();
+ QObject *configObj = rect->findChild<QObject *>("config");
+
+ auto data = QQmlData::get(text);
+ QVERIFY(data);
+ auto b = data->bindings;
+ QVERIFY(b);
+ auto binding = dynamic_cast<QQmlBinding*>(b);
+ QVERIFY(binding);
+ auto dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 3);
+
+ QVERIFY(findProperties(dependencies, rect, "name", "world"));
+ QVERIFY(findProperties(dependencies, text, "greeting", "Hello"));
+ QVERIFY(findProperties(dependencies, configObj, "helloWorldTemplate", "%1 %2!"));
+
+ delete rect;
+}
+
+void tst_bindingdependencyapi::testConditionalDependencies_data()
+{
+ QTest::addColumn<QByteArray>("code");
+ QTest::addColumn<QString>("referencedObjectName");
+
+ QTest::addRow("id object property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: \"rect\"\n"
+ "property bool haveDep: false\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { text: rect.haveDep ? rect.labelText : '' }\n"
+ "}") << "rect";
+
+ QTest::addRow("dynamic context property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "objectName: \"rect\"\n"
+ "property bool haveDep: false\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { Component.onCompleted: text = Qt.binding(function() { return haveDep ? labelText : ''; }); }\n"
+ "}") << "rect";
+
+ QTest::addRow("dynamic scope property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "property string labelText: \"I am wrong!\"\n"
+ "Text {\n"
+ "objectName: \"text\"\n"
+ "property bool haveDep: false\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Component.onCompleted: text = Qt.binding(function() { return haveDep ? labelText : ''; });\n"
+ "}\n"
+ "}") << "text";
+
+ QTest::addRow("dynamic id object property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: \"rect\"\n"
+ "property bool haveDep: false\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { Component.onCompleted: text = Qt.binding(function() { return rect.haveDep ? rect.labelText : ''; }); }\n"
+ "}") << "rect";
+}
+
+void tst_bindingdependencyapi::testConditionalDependencies()
+{
+ QFETCH(QByteArray, code);
+ QFETCH(QString, referencedObjectName);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(code, QUrl());
+ QObject *rect = c.create();
+ QTest::qWait(10);
+ QVERIFY(rect != 0);
+ QObject *text = rect->findChildren<QQuickText *>().front();
+
+ QObject *referencedObject = rect->objectName() == referencedObjectName ? rect : rect->findChild<QObject *>(referencedObjectName);
+
+ auto data = QQmlData::get(text);
+ QVERIFY(data);
+ auto b = data->bindings;
+ QVERIFY(b);
+ auto binding = dynamic_cast<QQmlBinding*>(b);
+ QVERIFY(binding);
+ auto dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 1);
+ QVERIFY(findProperties(dependencies, referencedObject, "haveDep", false));
+
+ referencedObject->setProperty("haveDep", true);
+ dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 2);
+ QVERIFY(findProperties(dependencies, referencedObject, "haveDep", true));
+ QVERIFY(findProperties(dependencies, referencedObject, "labelText", "Hello world!"));
+
+ referencedObject->setProperty("haveDep", false);
+ dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 1);
+ QVERIFY(findProperties(dependencies, referencedObject, "haveDep", false));
+
+ delete rect;
+}
+
+void tst_bindingdependencyapi::testBindingLoop()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "property string labelText: label.text\n"
+ "Text {\n"
+ "id: label\n"
+ "text: labelText\n"
+ "}\n"
+ "}"), QUrl());
+ QObject *rect = c.create();
+ if (c.isError()) {
+ qWarning() << c.errorString();
+ }
+ QTest::qWait(100);
+ QVERIFY(rect != 0);
+ QObject *text = rect->findChildren<QQuickText *>().front();
+
+ auto data = QQmlData::get(text);
+ QVERIFY(data);
+ auto b = data->bindings;
+ QVERIFY(b);
+ auto binding = dynamic_cast<QQmlBinding*>(b);
+ QVERIFY(binding);
+ auto dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 1);
+ auto dependency = dependencies.front();
+ QVERIFY(dependency.isValid());
+ QCOMPARE(quintptr(dependency.object()), quintptr(rect));
+ QCOMPARE(dependency.property().name(), "labelText");
+
+ delete rect;
+}
+
+QTEST_MAIN(tst_bindingdependencyapi)
+
+#include "tst_bindingdependencyapi.moc"
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index a50411e18b..63721cc575 100644
--- a/tests/auto/qml/debugger/debugger.pro
+++ b/tests/auto/qml/debugger/debugger.pro
@@ -10,7 +10,8 @@ PUBLICTESTS += \
qqmlenginedebuginspectorintegrationtest \
qqmlenginecontrol \
qqmldebuggingenabler \
- qqmlnativeconnector
+ qqmlnativeconnector \
+ qqmldebugprocess
PRIVATETESTS += \
qqmldebugclient \
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
index 6c729ab235..9cf323ba36 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
+++ b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
@@ -5,8 +5,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qdebugmessageservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
index f193d3928a..f851688b5e 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
+++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
@@ -28,7 +28,6 @@
//QQmlDebugTest
#include "debugutil_p.h"
-#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
@@ -38,31 +37,19 @@
#include <QtCore/qlibraryinfo.h>
#include <QtTest/qtest.h>
-const char *NORMALMODE = "-qmljsdebugger=port:3777,3787,block";
const char *QMLFILE = "test.qml";
class QQmlDebugMsgClient;
-class tst_QDebugMessageService : public QQmlDataTest
+class tst_QDebugMessageService : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QDebugMessageService();
-
- void init();
-
private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void cleanup();
-
void retrieveDebugOutput();
private:
- QQmlDebugProcess *m_process;
- QQmlDebugMsgClient *m_client;
- QQmlDebugConnection *m_connection;
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QQmlDebugMsgClient> m_client;
};
struct LogEntry {
@@ -150,73 +137,16 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data)
}
}
-tst_QDebugMessageService::tst_QDebugMessageService()
-{
-}
-
-void tst_QDebugMessageService::initTestCase()
-{
- QQmlDataTest::initTestCase();
- m_process = 0;
- m_client = 0;
- m_connection = 0;
-}
-
-void tst_QDebugMessageService::cleanupTestCase()
+QList<QQmlDebugClient *> tst_QDebugMessageService::createClients()
{
- if (m_process)
- delete m_process;
-
- if (m_client)
- delete m_client;
-
- if (m_connection)
- delete m_connection;
-}
-
-void tst_QDebugMessageService::init()
-{
- m_connection = new QQmlDebugConnection();
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", this);
m_client = new QQmlDebugMsgClient(m_connection);
-
- m_process->start(QStringList() << QLatin1String(NORMALMODE) << QQmlDataTest::instance()->testFile(QMLFILE));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- const int port = m_process->debugPort();
- m_connection->connectToHost("127.0.0.1", port);
- QVERIFY(m_connection->waitForConnected());
-
- if (m_client->state() != QQmlDebugClient::Enabled)
- QQmlDebugTest::waitForSignal(m_client, SIGNAL(enabled()));
-
- QCOMPARE(m_client->state(), QQmlDebugClient::Enabled);
-}
-
-void tst_QDebugMessageService::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
- if (m_process)
- delete m_process;
-
- if (m_client)
- delete m_client;
-
- if (m_connection)
- delete m_connection;
-
- m_process = 0;
- m_client = 0;
- m_connection = 0;
+ return QList<QQmlDebugClient *>({m_client});
}
void tst_QDebugMessageService::retrieveDebugOutput()
{
- init();
+ QCOMPARE(QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ QString(), testFile(QMLFILE), true), ConnectSuccess);
QTRY_VERIFY(m_client->logBuffer.size() >= 2);
diff --git a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
index a7c0fa7f8e..b1e3835844 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
+++ b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
@@ -4,7 +4,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qpacketprotocol.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
QT += qml network testlib gui-private core-private
diff --git a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
index 622b373692..673330a3cf 100644
--- a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
+++ b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
@@ -7,7 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebugclient.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
DEFINES += QT_QML_DEBUG_NO_WARNING
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
index f8014f04f4..bd382ebaab 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmldebuggingenabler.cpp
-INCLUDEPATH += ../../shared
-include(../../../../shared/util.pri)
include(../../shared/debugutil.pri)
OTHER_FILES += data/test.qml
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
index 3aa3a5c87e..a76740a3f9 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
@@ -27,11 +27,14 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+
#include <QtTest/qtest.h>
#include <QtCore/qprocess.h>
#include <QtCore/qtimer.h>
@@ -40,17 +43,11 @@
#include <QtCore/qmutex.h>
#include <QtCore/qlibraryinfo.h>
-class tst_QQmlDebuggingEnabler : public QQmlDataTest
+class tst_QQmlDebuggingEnabler : public QQmlDebugTest
{
Q_OBJECT
- bool init(bool blockMode, bool qmlscene, int portFrom, int portTo);
-
private slots:
- void initTestCase();
- void cleanupTestCase();
- void cleanup();
-
void qmlscene_data();
void qmlscene();
void custom_data();
@@ -58,88 +55,8 @@ private slots:
private:
void data();
- QQmlDebugProcess *process;
- QQmlDebugConnection *connection;
- QTime t;
};
-void tst_QQmlDebuggingEnabler::initTestCase()
-{
- QQmlDataTest::initTestCase();
- t.start();
- process = 0;
- connection = 0;
-}
-
-void tst_QQmlDebuggingEnabler::cleanupTestCase()
-{
- if (process) {
- process->stop();
- delete process;
- }
-
- if (connection)
- delete connection;
-}
-
-bool tst_QQmlDebuggingEnabler::init(bool blockMode, bool qmlscene, int portFrom, int portTo)
-{
- connection = new QQmlDebugConnection();
-
- if (qmlscene) {
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
- process->setMaximumBindErrors(1);
- } else {
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebuggingenablerserver"), this);
- process->setMaximumBindErrors(portTo - portFrom);
- }
-
- if (qmlscene) {
- process->start(QStringList() << QLatin1String("-qmljsdebugger=port:") +
- QString::number(portFrom) + QLatin1Char(',') + QString::number(portTo) +
- QLatin1String(blockMode ? ",block": "") <<
- testFile(QLatin1String("test.qml")));
- } else {
- QStringList args;
- if (blockMode)
- args << QLatin1String("-block");
- args << QString::number(portFrom) << QString::number(portTo);
- process->start(args);
- }
-
- if (!process->waitForSessionStart()) {
- return false;
- }
-
- const int port = process->debugPort();
- connection->connectToHost("127.0.0.1", port);
- if (!connection->waitForConnected()) {
- qDebug() << "could not connect to host!";
- return false;
- }
- return true;
-}
-
-void tst_QQmlDebuggingEnabler::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << process->state();
- qDebug() << "Application Output:" << process->output();
- }
-
- if (process) {
- process->stop();
- delete process;
- }
-
-
- if (connection)
- delete connection;
-
- process = 0;
- connection = 0;
-}
-
void tst_QQmlDebuggingEnabler::data()
{
QTest::addColumn<QString>("connector");
@@ -185,32 +102,32 @@ void tst_QQmlDebuggingEnabler::qmlscene()
QFETCH(bool, blockMode);
QFETCH(QStringList, services);
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
- this);
- process->setMaximumBindErrors(1);
- process->start(QStringList()
- << QString::fromLatin1("-qmljsdebugger=connector:%1%2%3%4")
- .arg(connector + (connector == QLatin1String("QQmlDebugServer") ?
- QLatin1String(",port:5555,5565") : QString()))
- .arg(blockMode ? QLatin1String(",block") : QString())
- .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
- .arg(services.isEmpty() ? QString() : services.join(","))
- << testFile(QLatin1String("test.qml")));
+ m_process = new QQmlDebugProcess(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ m_process->setMaximumBindErrors(1);
+ m_process->start(QStringList()
+ << QString::fromLatin1("-qmljsdebugger=connector:%1%2%3%4")
+ .arg(connector + (connector == QLatin1String("QQmlDebugServer")
+ ? QLatin1String(",port:5555,5565") : QString()))
+ .arg(blockMode ? QLatin1String(",block") : QString())
+ .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
+ .arg(services.isEmpty() ? QString() : services.join(","))
+ << testFile(QLatin1String("test.qml")));
if (connector == QLatin1String("QQmlDebugServer")) {
- QVERIFY(process->waitForSessionStart());
- connection = new QQmlDebugConnection();
- QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
- foreach (QQmlDebugClient *client, clients)
+ QVERIFY(m_process->waitForSessionStart());
+ m_connection = new QQmlDebugConnection();
+ m_clients = QQmlDebugTest::createOtherClients(m_connection);
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+ foreach (QQmlDebugClient *client, m_clients)
QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
- QCOMPARE(process->state(), QLatin1String("running"));
+ QCOMPARE(m_process->state(), QLatin1String("running"));
if (!blockMode)
- QTRY_VERIFY(process->output().contains(QLatin1String("qml: Component.onCompleted")));
+ QTRY_VERIFY(m_process->output().contains(QLatin1String("qml: Component.onCompleted")));
}
void tst_QQmlDebuggingEnabler::custom_data()
@@ -226,9 +143,9 @@ void tst_QQmlDebuggingEnabler::custom()
const int portFrom = 5555;
const int portTo = 5565;
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
- QLatin1String("/qqmldebuggingenablerserver"), this);
- process->setMaximumBindErrors(portTo - portFrom);
+ m_process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
+ QLatin1String("/qqmldebuggingenablerserver"), this);
+ m_process->setMaximumBindErrors(portTo - portFrom);
QStringList args;
if (blockMode)
@@ -240,22 +157,22 @@ void tst_QQmlDebuggingEnabler::custom()
if (!services.isEmpty())
args << QLatin1String("-services") << services;
- process->start(args);
+ m_process->start(args);
if (connector == QLatin1String("QQmlDebugServer")) {
- QVERIFY(process->waitForSessionStart());
- connection = new QQmlDebugConnection();
- QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
- foreach (QQmlDebugClient *client, clients)
+ QVERIFY(m_process->waitForSessionStart());
+ m_connection = new QQmlDebugConnection();
+ m_clients = QQmlDebugTest::createOtherClients(m_connection);
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+ for (QQmlDebugClient *client : qAsConst(m_clients))
QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
- QCOMPARE(process->state(), QLatin1String("running"));
+ QCOMPARE(m_process->state(), QLatin1String("running"));
if (!blockMode)
- QTRY_VERIFY(process->output().contains(QLatin1String("QQmlEngine created")));
+ QTRY_VERIFY(m_process->output().contains(QLatin1String("QQmlEngine created")));
}
QTEST_MAIN(tst_QQmlDebuggingEnabler)
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
index cbaf3b5309..90623c75a6 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmldebugjs.cpp
-INCLUDEPATH += ../../shared
-include(../../../../shared/util.pri)
include(../../shared/debugutil.pri)
include(../../shared/qqmlenginedebugclient.pri)
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
index d248cf9708..3cd359cf48 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../shared/qqmlenginedebugclient.h"
#include "../../../../shared/util.h"
@@ -136,7 +137,7 @@ const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
do {\
if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
if (QTest::currentTestFailed()) \
- qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
+ qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << m_process->output();\
return;\
}\
} while (0)
@@ -144,18 +145,12 @@ do {\
class QJSDebugClient;
-class tst_QQmlDebugJS : public QQmlDataTest
+class tst_QQmlDebugJS : public QQmlDebugTest
{
Q_OBJECT
- void init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true,
- bool restrictServices = false);
-
private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void cleanup();
+ void initTestCase() override;
void connect_data();
void connect();
@@ -223,11 +218,12 @@ private slots:
void getScripts();
private:
- void targetData();
+ ConnectResult init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE),
+ bool blockMode = true, bool restrictServices = false);
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QJSDebugClient> m_client;
- QQmlDebugProcess *process;
- QJSDebugClient *client;
- QQmlDebugConnection *connection;
+ void targetData();
QTime t;
};
@@ -280,7 +276,6 @@ protected:
void messageReceived(const QByteArray &data);
signals:
- void enabled();
void connected();
void interruptRequested();
void result();
@@ -667,10 +662,8 @@ void QJSDebugClient::disconnect()
void QJSDebugClient::stateChanged(State state)
{
- if (state == Enabled) {
+ if (state == Enabled)
flushSendBuffer();
- emit enabled();
- }
}
void QJSDebugClient::messageReceived(const QByteArray &data)
@@ -763,85 +756,19 @@ QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray
void tst_QQmlDebugJS::initTestCase()
{
- QQmlDataTest::initTestCase();
+ QQmlDebugTest::initTestCase();
t.start();
- process = 0;
- client = 0;
- connection = 0;
}
-void tst_QQmlDebugJS::cleanupTestCase()
+QQmlDebugTest::ConnectResult tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile,
+ bool blockMode, bool restrictServices)
{
- if (process) {
- process->stop();
- delete process;
- }
-
- if (client)
- delete client;
-
- if (connection)
- delete connection;
-}
-
-void tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile, bool blockMode,
- bool restrictServices)
-{
- connection = new QQmlDebugConnection();
- if (qmlscene)
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- "/qmlscene", this);
- else
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
- QLatin1String("/qqmldebugjsserver"), this);
- client = new QJSDebugClient(connection);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(connection);
-
- const char *args = 0;
- if (blockMode)
- args = restrictServices ? BLOCKRESTRICTEDMODE : BLOCKMODE;
- else
- args = restrictServices ? NORMALRESTRICTEDMODE : NORMALMODE;
-
- process->start(QStringList() << QLatin1String(args) << testFile(qmlFile));
-
- QVERIFY(process->waitForSessionStart());
-
- const int port = process->debugPort();
- connection->connectToHost("127.0.0.1", port);
- QVERIFY(connection->waitForConnected());
-
-
- if (client->state() != QQmlDebugClient::Enabled)
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled())));
-
- foreach (QQmlDebugClient *otherClient, others)
- QCOMPARE(otherClient->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
-}
-
-void tst_QQmlDebugJS::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << process->state();
- qDebug() << "Application Output:" << process->output();
- }
-
- if (process) {
- process->stop();
- delete process;
- }
-
- if (client)
- delete client;
-
- if (connection)
- delete connection;
-
- process = 0;
- client = 0;
- connection = 0;
+ const QString executable = qmlscene
+ ? QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"
+ : QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebugjsserver");
+ return QQmlDebugTest::connect(
+ executable, restrictServices ? QStringLiteral("V8Debugger") : QString(),
+ testFile(qmlFile), blockMode);
}
void tst_QQmlDebugJS::connect_data()
@@ -864,9 +791,9 @@ void tst_QQmlDebugJS::connect()
QFETCH(bool, blockMode);
QFETCH(bool, restrictMode);
QFETCH(bool, qmlscene);
- init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode);
- client->connect();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
+ QCOMPARE(init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode), ConnectSuccess);
+ m_client->connect();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(connected())));
}
void tst_QQmlDebugJS::interrupt()
@@ -876,11 +803,11 @@ void tst_QQmlDebugJS::interrupt()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->interrupt();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested())));
+ m_client->interrupt();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(interruptRequested())));
}
void tst_QQmlDebugJS::getVersion()
@@ -890,12 +817,12 @@ void tst_QQmlDebugJS::getVersion()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(connected())));
- client->version();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->version();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getVersionWhenAttaching()
@@ -905,11 +832,11 @@ void tst_QQmlDebugJS::getVersionWhenAttaching()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, QLatin1String(TIMER_QMLFILE), false);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene, QLatin1String(TIMER_QMLFILE), false), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->version();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->version();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::disconnect()
@@ -919,11 +846,11 @@ void tst_QQmlDebugJS::disconnect()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->disconnect();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->disconnect();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
@@ -934,14 +861,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -957,14 +884,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, CREATECOMPONENT_QMLFILE);
+ QCOMPARE(init(qmlscene, CREATECOMPONENT_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -978,16 +905,16 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
int sourceLine = 35;
- init(qmlscene, TIMER_QMLFILE);
+ QCOMPARE(init(qmlscene, TIMER_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//We can set the breakpoint after connect() here because the timer is repeating and if we miss
//its first iteration we can still catch the second one.
- client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1003,14 +930,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
QFETCH(bool, namesAsObjects);
int sourceLine = 31;
- init(qmlscene, LOADJSFILE_QMLFILE);
+ QCOMPARE(init(qmlscene, LOADJSFILE_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1027,15 +954,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
int sourceLine = 34;
int actualLine = 36;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()), 1));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1052,15 +979,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
int sourceLine = 35;
int actualLine = 36;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()), 1));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1076,14 +1003,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
QFETCH(bool, namesAsObjects);
int sourceLine = 39;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1098,28 +1025,28 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
QFETCH(bool, namesAsObjects);
int out = 10;
int sourceLine = 37;
- init(qmlscene, CONDITION_QMLFILE);
+ QCOMPARE(init(qmlscene, CONDITION_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//The breakpoint is in a timer loop so we can set it after connect().
- client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Get the frame index
- QString jsonString = client->response;
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString = m_client->response;
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
{
QVariantMap body = value.value("body").toMap();
int frameIndex = body.value("index").toInt();
//Verify the value of 'result'
- client->evaluate(QLatin1String("a"),frameIndex);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->evaluate(QLatin1String("a"),frameIndex);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
- jsonString = client->response;
- QJSValue val = client->parser.call(QJSValueList() << QJSValue(jsonString));
+ jsonString = m_client->response;
+ QJSValue val = m_client->parser.call(QJSValueList() << QJSValue(jsonString));
QVERIFY(val.isObject());
QJSValue body = val.property(QStringLiteral("body"));
QVERIFY(body.isObject());
@@ -1135,42 +1062,42 @@ void tst_QQmlDebugJS::setBreakpointInScriptThatQuits()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, QUIT_QMLFILE);
+ QCOMPARE(init(qmlscene, QUIT_QMLFILE), ConnectSuccess);
int sourceLine = 36;
- client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE));
- client->continueDebugging(QJSDebugClient::Continue);
- QVERIFY(process->waitForFinished());
- QCOMPARE(process->exitStatus(), QProcess::NormalExit);
+ m_client->continueDebugging(QJSDebugClient::Continue);
+ QVERIFY(m_process->waitForFinished());
+ QCOMPARE(m_process->exitStatus(), QProcess::NormalExit);
}
void tst_QQmlDebugJS::setBreakpointWhenAttaching()
{
int sourceLine = 35;
- init(true, QLatin1String(TIMER_QMLFILE), false);
+ QCOMPARE(init(true, QLatin1String(TIMER_QMLFILE), false), ConnectSuccess);
- client->connect();
+ m_client->connect();
QSKIP("\nThe breakpoint may not hit because the engine may run in JIT mode or not have debug\n"
"instructions, as we've connected in non-blocking mode above. That means we may have\n"
"connected after the engine was already running, with all the QML already compiled.");
//The breakpoint is in a timer loop so we can set it after connect().
- client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine);
+ m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
}
void tst_QQmlDebugJS::clearBreakpoint()
@@ -1182,41 +1109,41 @@ void tst_QQmlDebugJS::clearBreakpoint()
int sourceLine1 = 37;
int sourceLine2 = 38;
- init(qmlscene, CHANGEBREAKPOINT_QMLFILE);
+ QCOMPARE(init(qmlscene, CHANGEBREAKPOINT_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//The breakpoints are in a timer loop so we can set them after connect().
//Furthermore the breakpoints should be hit in the right order because setting of breakpoints
//can only occur in the QML event loop. (see QCOMPARE for sourceLine2 below)
- client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
- client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Will hit 1st brakpoint, change this breakpoint enable = false
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
int breakpoint = breakpointsHit.at(0).toInt();
- client->clearBreakpoint(breakpoint);
+ m_client->clearBreakpoint(breakpoint);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Continue with debugging
- client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QJSDebugClient::Continue);
//Hit 2nd breakpoint
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Continue with debugging
- client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QJSDebugClient::Continue);
//Should stop at 2nd breakpoint
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- jsonString = client->response;
- value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ jsonString = m_client->response;
+ value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
body = value.value("body").toMap();
@@ -1230,10 +1157,10 @@ void tst_QQmlDebugJS::setExceptionBreak()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, EXCEPTION_QMLFILE);
- client->setExceptionBreak(QJSDebugClient::All,true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QCOMPARE(init(qmlscene, EXCEPTION_QMLFILE), ConnectSuccess);
+ m_client->setExceptionBreak(QJSDebugClient::All,true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
}
void tst_QQmlDebugJS::stepNext()
@@ -1244,17 +1171,17 @@ void tst_QQmlDebugJS::stepNext()
QFETCH(bool, namesAsObjects);
int sourceLine = 37;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->continueDebugging(QJSDebugClient::Next);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->continueDebugging(QJSDebugClient::Next);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1262,6 +1189,14 @@ void tst_QQmlDebugJS::stepNext()
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
+static QVariantMap responseBody(QJSDebugClient *client)
+{
+ const QString jsonString(client->response);
+ const QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString))
+ .toVariant().toMap();
+ return value.value("body").toMap();
+}
+
void tst_QQmlDebugJS::stepIn()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
@@ -1270,21 +1205,18 @@ void tst_QQmlDebugJS::stepIn()
QFETCH(bool, namesAsObjects);
int sourceLine = 41;
- int actualLine = 37;
- init(qmlscene, STEPACTION_QMLFILE);
-
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->continueDebugging(QJSDebugClient::In);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ int actualLine = 36;
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
- QVariantMap body = value.value("body").toMap();
+ m_client->continueDebugging(QJSDebugClient::In);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ const QVariantMap body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
@@ -1298,20 +1230,17 @@ void tst_QQmlDebugJS::stepOut()
int sourceLine = 37;
int actualLine = 41;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
- client->continueDebugging(QJSDebugClient::Out);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ m_client->continueDebugging(QJSDebugClient::Out);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ const QVariantMap body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
@@ -1325,18 +1254,18 @@ void tst_QQmlDebugJS::continueDebugging()
int sourceLine1 = 41;
int sourceLine2 = 38;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->continueDebugging(QJSDebugClient::Continue);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->continueDebugging(QJSDebugClient::Continue);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1352,14 +1281,14 @@ void tst_QQmlDebugJS::backtrace()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->backtrace();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->backtrace();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getFrameDetails()
@@ -1370,14 +1299,14 @@ void tst_QQmlDebugJS::getFrameDetails()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->frame();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->frame();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getScopeDetails()
@@ -1388,33 +1317,32 @@ void tst_QQmlDebugJS::getScopeDetails()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->scope();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->scope();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::evaluateInGlobalScope()
{
//void evaluate(QString expr, int frame = -1);
- init(true);
+ QCOMPARE(init(true), ConnectSuccess);
- client->connect();
+ m_client->connect();
- do {
+ for (int i = 0; i < 10; ++i) {
// The engine might not be initialized, yet. We just try until it shows up.
- client->evaluate(QLatin1String("console.log('Hello World')"));
- } while (!QQmlDebugTest::waitForSignal(client, SIGNAL(result()), 500));
+ m_client->evaluate(QLatin1String("console.log('Hello World')"));
+ if (QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()), 500))
+ break;
+ }
//Verify the return value of 'console.log()', which is "undefined"
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
- QVariantMap body = value.value("body").toMap();
- QCOMPARE(body.value("type").toString(),QLatin1String("undefined"));
+ QCOMPARE(responseBody(m_client).value("type").toString(), QLatin1String("undefined"));
}
void tst_QQmlDebugJS::evaluateInLocalScope()
@@ -1425,29 +1353,29 @@ void tst_QQmlDebugJS::evaluateInLocalScope()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->frame();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->frame();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Get the frame index
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
int frameIndex = body.value("index").toInt();
- client->evaluate(QLatin1String("root.a"), frameIndex);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->evaluate(QLatin1String("root.a"), frameIndex);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Verify the value of 'timer.interval'
- jsonString = client->response;
- value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ jsonString = m_client->response;
+ value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
body = value.value("body").toMap();
@@ -1456,25 +1384,25 @@ void tst_QQmlDebugJS::evaluateInLocalScope()
void tst_QQmlDebugJS::evaluateInContext()
{
- connection = new QQmlDebugConnection();
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ m_connection = new QQmlDebugConnection();
+ m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ "/qmlscene", this);
- client = new QJSDebugClient(connection);
- QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(connection));
- process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
+ m_client = new QJSDebugClient(m_connection);
+ QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(m_connection));
+ m_process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
- QVERIFY(process->waitForSessionStart());
+ QVERIFY(m_process->waitForSessionStart());
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
- QTRY_COMPARE(client->state(), QQmlEngineDebugClient::Enabled);
+ QTRY_COMPARE(m_client->state(), QQmlEngineDebugClient::Enabled);
QTRY_COMPARE(engineClient->state(), QQmlEngineDebugClient::Enabled);
- client->connect();
+ m_client->connect();
// "a" not accessible without extra context
- client->evaluate(QLatin1String("a + 10"), -1, -1);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(failure())));
+ m_client->evaluate(QLatin1String("a + 10"), -1, -1);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(failure())));
bool success = false;
engineClient->queryAvailableEngines(&success);
@@ -1496,14 +1424,10 @@ void tst_QQmlDebugJS::evaluateInContext()
auto object = engineClient->object();
// "a" accessible in context of surrounding object
- client->evaluate(QLatin1String("a + 10"), -1, object.debugId);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-
- QString jsonString = client->response;
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ m_client->evaluate(QLatin1String("a + 10"), -1, object.debugId);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
- QVariantMap body = value.value("body").toMap();
- QTRY_COMPARE(body.value("value").toInt(), 20);
+ QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 20);
}
void tst_QQmlDebugJS::getScripts()
@@ -1513,16 +1437,16 @@ void tst_QQmlDebugJS::getScripts()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
- client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->scripts();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList()
+ m_client->scripts();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList()
<< QJSValue(jsonString)).toVariant().toMap();
QList<QVariant> scripts = value.value("body").toList();
@@ -1531,6 +1455,12 @@ void tst_QQmlDebugJS::getScripts()
QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml")));
}
+QList<QQmlDebugClient *> tst_QQmlDebugJS::createClients()
+{
+ m_client = new QJSDebugClient(m_connection);
+ return QList<QQmlDebugClient *>({m_client});
+}
+
void tst_QQmlDebugJS::targetData()
{
QTest::addColumn<bool>("qmlscene");
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
index 860d39cca4..1dc9de8f34 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
+++ b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
@@ -7,7 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebuglocal.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
QT += qml-private testlib gui-private core-private
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
index 8d21a8a45a..4b28857fc0 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
+++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
@@ -32,6 +32,9 @@
#include <private/qqmldebugconnector_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+#include <QtQml/qqmlengine.h>
+
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
#include <QtNetwork/qhostaddress.h>
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro
new file mode 100644
index 0000000000..331d87b9f1
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = qqmldebugprocess qqmldebugprocessprocess
+
+qqmldebugprocess.depends = qqmldebugprocessprocess
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro
new file mode 100644
index 0000000000..9bea2d222c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qqmldebugprocess
+QT = core testlib
+CONFIG -= debug_and_release_target
+macos:CONFIG -= app_bundle
+
+SOURCES += \
+ ../../shared/qqmldebugprocess.cpp \
+ tst_qqmldebugprocess.cpp
+
+HEADERS += \
+ ../../shared/qqmldebugprocess_p.h
+
+INCLUDEPATH += ../../shared
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp
new file mode 100644
index 0000000000..993a1d5f63
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qqmldebugprocess_p.h>
+#include <QtTest>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qscopedpointer.h>
+
+class tst_QQmlDebugProcess : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void sessionStart_data();
+ void sessionStart();
+};
+
+void tst_QQmlDebugProcess::sessionStart_data()
+{
+ QTest::addColumn<int>("delay");
+ QTest::addColumn<QString>("arg");
+ QTest::addColumn<bool>("sessionExpected");
+ QTest::addColumn<bool>("outputExpected");
+
+ QTest::addRow("synchronous / waiting") << -1
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("synchronous / failed") << -1 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("synchronous / unknown") << -1 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("synchronous / appout") << -1 << "Output from app itself."
+ << false << true;
+
+ QTest::addRow("no delay / waiting") << 0
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("no delay / failed") << 0 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("no delay / unknown") << 0 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("no delay / appout") << 0 << "Output from app itself."
+ << false << true;
+
+ QTest::addRow("delay / waiting") << 1000
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("delay / failed") << 1000 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("delay / unknown") << 1000 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("delay / appout") << 1000 << "Output from app itself."
+ << false << true;
+}
+
+void tst_QQmlDebugProcess::sessionStart()
+{
+ QFETCH(int, delay);
+ QFETCH(QString, arg);
+ QFETCH(bool, sessionExpected);
+ QFETCH(bool, outputExpected);
+
+ QScopedPointer<QQmlDebugProcess> process(
+ new QQmlDebugProcess(QCoreApplication::applicationDirPath()
+ + QLatin1String("/qqmldebugprocessprocess"), this));
+ QVERIFY(process);
+
+ bool outputReceived = false;
+ connect(process.data(), &QQmlDebugProcess::readyReadStandardOutput, this, [&]() {
+ QVERIFY(outputExpected);
+ QVERIFY(!outputReceived);
+ QCOMPARE(process->output().trimmed(), arg);
+ outputReceived = true;
+ QTimer::singleShot(qMax(delay, 0), process.data(), &QQmlDebugProcess::stop);
+ });
+
+ if (!outputExpected && !sessionExpected)
+ QTest::ignoreMessage(QtWarningMsg, "App was unable to bind to port!");
+ process->start(QStringList({arg}));
+
+ bool done = false;
+ auto wait = [&](){
+ QCOMPARE(process->waitForSessionStart(), sessionExpected);
+ QCOMPARE(outputReceived, outputExpected);
+ process->stop();
+ done = true;
+ };
+
+ if (delay < 0)
+ wait();
+ else
+ QTimer::singleShot(delay, process.data(), wait);
+
+ QTRY_VERIFY(done);
+ QVERIFY(process->state().startsWith("not running"));
+}
+
+QTEST_MAIN(tst_QQmlDebugProcess)
+
+#include "tst_qqmldebugprocess.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp
index fe01507412..21cce53fc3 100644
--- a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -25,32 +25,15 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <QStringList>
-#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-#include <QDebug>
-
-class MyPluginType : public QObject
-{
- Q_OBJECT
-public:
- MyPluginType(QObject *parent=0) : QObject(parent) {}
-};
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
-class MyPlugin : public QQmlExtensionPlugin
+// Process that just outputs a fake "Waiting" message.
+int main(int argc, char **argv)
{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
-
-public:
- MyPlugin() {}
-
- void registerTypes(const char *uri)
- {
- Q_ASSERT(QLatin1String(uri) == "org.qtproject.InvalidStrictModule");
- qmlRegisterType<MyPluginType>("org.qtproject.SomeOtherModule", 1, 0, "MyPluginType");
- }
-};
-
-#include "plugin.moc"
+ QCoreApplication app(argc, argv);
+ if (argc > 1)
+ qDebug() << argv[1];
+ return app.exec();
+}
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro
new file mode 100644
index 0000000000..a8eb4885d4
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro
@@ -0,0 +1,11 @@
+QT = core
+macos:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+CONFIG += console
+SOURCES += qqmldebugprocessprocess.cpp
+
+DESTDIR = ../qqmldebugprocess
+
+target.path = $$[QT_INSTALL_TESTS]/tst_qqmldebugprocess
+INSTALLS += target
+
diff --git a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
index 79cbe52331..3101d09ea5 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
+++ b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
@@ -7,8 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebugservice.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
index 8092faba04..4e103e9a65 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
@@ -29,6 +29,7 @@
#include "qqmldebugtestservice.h"
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
@@ -105,10 +106,13 @@ void tst_QQmlDebugService::initTestCase()
void tst_QQmlDebugService::checkPortRange()
{
- QQmlDebugConnection *connection1 = new QQmlDebugConnection();
- QQmlDebugProcess *process1 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ QScopedPointer<QQmlDebugConnection> connection1(new QQmlDebugConnection());
+ QScopedPointer<QQmlDebugProcess> process1(
+ new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ + "/qmlscene", this));
- process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792") << testFile("test.qml"));
+ process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792")
+ << testFile("test.qml"));
if (!process1->waitForSessionStart())
QFAIL("could not launch application, or did not get 'Waiting for connection'.");
@@ -119,10 +123,13 @@ void tst_QQmlDebugService::checkPortRange()
QFAIL("could not connect to host!");
// Second instance
- QQmlDebugConnection *connection2 = new QQmlDebugConnection();
- QQmlDebugProcess *process2 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ QScopedPointer<QQmlDebugConnection> connection2(new QQmlDebugConnection());
+ QScopedPointer<QQmlDebugProcess> process2(
+ new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ + "/qmlscene", this));
- process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792") << testFile("test.qml"));
+ process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792")
+ << testFile("test.qml"));
if (!process2->waitForSessionStart())
QFAIL("could not launch application, or did not get 'Waiting for connection'.");
@@ -131,11 +138,6 @@ void tst_QQmlDebugService::checkPortRange()
connection2->connectToHost("127.0.0.1", port2);
if (!connection2->waitForConnected())
QFAIL("could not connect to host!");
-
- delete connection1;
- delete process1;
- delete connection2;
- delete process2;
}
void tst_QQmlDebugService::name()
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
index 40ec1230d6..73455bd903 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
@@ -4,13 +4,11 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginecontrol.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
-QT += core qml testlib testlib-private gui-private core-private
+QT += core qml testlib gui-private core-private
OTHER_FILES += \
data/test.qml \
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
index 2c515d7cf5..a8c43b1c75 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
@@ -35,12 +35,8 @@
#include <private/qqmlenginecontrolclient_p.h>
#include <QtTest/qtest.h>
-#include <private/qtestresult_p.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "13773"
-#define STR_PORT_TO "13783"
-
class QQmlEngineBlocker : public QObject
{
Q_OBJECT
@@ -65,77 +61,37 @@ void QQmlEngineBlocker::blockEngine(int engineId, const QString &name)
static_cast<QQmlEngineControlClient *>(parent())->blockEngine(engineId);
}
-class tst_QQmlEngineControl : public QQmlDataTest
+class tst_QQmlEngineControl : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlEngineControl()
- : m_process(0)
- , m_connection(0)
- , m_client(0)
- {}
-
private:
- QQmlDebugProcess *m_process;
- QQmlDebugConnection *m_connection;
- QQmlEngineControlClient *m_client;
+ ConnectResult connect(const QString &testFile, bool restrictServices);
+ QList<QQmlDebugClient *> createClients() override;
- void connect(const QString &testFile, bool restrictServices);
void engine_data();
+ QPointer<QQmlEngineControlClient> m_client;
private slots:
- void cleanup();
-
void startEngine_data();
void startEngine();
void stopEngine_data();
void stopEngine();
};
-void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connect(const QString &file,
+ bool restrictServices)
{
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
- QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:EngineControl") : QString());
-
- arguments << QQmlDataTest::instance()->testFile(testFile);
-
- m_process = new QQmlDebugProcess(executable, this);
- m_process->start(QStringList() << arguments);
- QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_connection = new QQmlDebugConnection();
- m_client = new QQmlEngineControlClient(m_connection);
- new QQmlEngineBlocker(m_client);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- const int port = m_process->debugPort();
- m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
-
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+ return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ restrictServices ? QStringLiteral("EngineControl") : QString(),
+ testFile(file), true);
}
-void tst_QQmlEngineControl::cleanup()
+QList<QQmlDebugClient *> tst_QQmlEngineControl::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
- qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
- qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
- }
- delete m_process;
- m_process = 0;
- delete m_client;
- m_client = 0;
- delete m_connection;
- m_connection = 0;
+ m_client = new QQmlEngineControlClient(m_connection);
+ new QQmlEngineBlocker(m_client);
+ return QList<QQmlDebugClient *>({m_client});
}
void tst_QQmlEngineControl::engine_data()
@@ -153,16 +109,16 @@ void tst_QQmlEngineControl::startEngine_data()
void tst_QQmlEngineControl::startEngine()
{
QFETCH(bool, restrictMode);
-
- connect("test.qml", restrictMode);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect("test.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
+
+ QVERIFY(m_client->blockedEngines().isEmpty());
}
void tst_QQmlEngineControl::stopEngine_data()
@@ -174,21 +130,23 @@ void tst_QQmlEngineControl::stopEngine()
{
QFETCH(bool, restrictMode);
- connect("exit.qml", restrictMode);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect("exit.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAboutToBeRemoved(int,QString))),
"No engine about to stop message received in time.");
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineRemoved(int,QString))),
"No engine stop message received in time.");
+ QVERIFY(m_client->blockedEngines().isEmpty());
}
QTEST_MAIN(tst_QQmlEngineControl)
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
index b8b4c3fc8b..5f58e5ec7f 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
@@ -1,13 +1,11 @@
CONFIG += testcase
TARGET = tst_qqmlenginedebuginspectorintegration
-QT += qml testlib testlib-private gui-private core-private
+QT += qml testlib gui-private core-private
osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginedebuginspectorintegration.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlinspectorclient.pri)
include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
index aba9eb39ab..249416a3b9 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
@@ -34,7 +34,6 @@
#include <private/qqmldebugconnection_p.h>
#include <QtTest/qtest.h>
-#include <private/qtestresult_p.h>
#include <QtTest/qsignalspy.h>
#include <QtNetwork/qhostaddress.h>
#include <QtCore/qtimer.h>
@@ -42,35 +41,21 @@
#include <QtCore/qthread.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "3776"
-#define STR_PORT_TO "3786"
-
-class tst_QQmlEngineDebugInspectorIntegration : public QQmlDataTest
+class tst_QQmlEngineDebugInspectorIntegration : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlEngineDebugInspectorIntegration()
- : m_process(0)
- , m_inspectorClient(0)
- , m_engineDebugClient(0)
- , m_recipient(0)
- {
- }
-
-
private:
- void init(bool restrictServices);
+ ConnectResult init(bool restrictServices);
+ QList<QQmlDebugClient *> createClients() override;
+
QmlDebugObjectReference findRootObject();
- QQmlDebugProcess *m_process;
- QQmlInspectorClient *m_inspectorClient;
- QQmlEngineDebugClient *m_engineDebugClient;
- QQmlInspectorResultRecipient *m_recipient;
+ QPointer<QQmlInspectorClient> m_inspectorClient;
+ QPointer<QQmlEngineDebugClient> m_engineDebugClient;
+ QPointer<QQmlInspectorResultRecipient> m_recipient;
private slots:
- void cleanup();
-
void connect_data();
void connect();
void objectLocationLookup();
@@ -100,53 +85,22 @@ QmlDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject(
return m_engineDebugClient->object();
}
-void tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
{
- const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:QmlDebugger,QmlInspector") :
- QString());
-
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
- this);
- m_process->start(QStringList() << argument << testFile("qtquick2.qml"));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- QQmlDebugConnection *m_connection = new QQmlDebugConnection(this);
- m_inspectorClient = new QQmlInspectorClient(m_connection);
- m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
- m_recipient = new QQmlInspectorResultRecipient(this);
- QObject::connect(m_inspectorClient, &QQmlInspectorClient::responseReceived,
- m_recipient, &QQmlInspectorResultRecipient::recordResponse);
-
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
- QVERIFY(m_connection->waitForConnected());
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
-
- QTRY_COMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
- QTRY_COMPARE(m_engineDebugClient->state(), QQmlDebugClient::Enabled);
+ return QQmlDebugTest::connect(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ restrictServices ? QStringLiteral("QmlDebugger,QmlInspector") : QString(),
+ testFile("qtquick2.qml"), true);
}
-void tst_QQmlEngineDebugInspectorIntegration::cleanup()
+QList<QQmlDebugClient *> tst_QQmlEngineDebugInspectorIntegration::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
- delete m_process;
- m_process = 0;
- delete m_engineDebugClient;
- m_engineDebugClient = 0;
- delete m_inspectorClient;
- m_inspectorClient = 0;
- delete m_recipient;
- m_recipient = 0;
+ m_inspectorClient = new QQmlInspectorClient(m_connection);
+ m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
+ m_recipient = new QQmlInspectorResultRecipient(m_inspectorClient);
+ QObject::connect(m_inspectorClient.data(), &QQmlInspectorClient::responseReceived,
+ m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
+ return QList<QQmlDebugClient *>({m_inspectorClient, m_engineDebugClient});
}
void tst_QQmlEngineDebugInspectorIntegration::connect_data()
@@ -159,14 +113,12 @@ void tst_QQmlEngineDebugInspectorIntegration::connect_data()
void tst_QQmlEngineDebugInspectorIntegration::connect()
{
QFETCH(bool, restrictMode);
- init(restrictMode);
+ QCOMPARE(init(restrictMode), ConnectSuccess);
}
void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
bool success = false;
QmlDebugObjectReference rootObject = findRootObject();
@@ -192,9 +144,7 @@ void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
void tst_QQmlEngineDebugInspectorIntegration::select()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QmlDebugObjectReference rootObject = findRootObject();
QList<int> childIds;
@@ -212,9 +162,7 @@ void tst_QQmlEngineDebugInspectorIntegration::select()
void tst_QQmlEngineDebugInspectorIntegration::createObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QString qml = QLatin1String("Rectangle {\n"
" id: xxxyxxx\n"
@@ -241,9 +189,7 @@ void tst_QQmlEngineDebugInspectorIntegration::createObject()
void tst_QQmlEngineDebugInspectorIntegration::moveObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
QmlDebugObjectReference rootObject = findRootObject();
@@ -268,9 +214,7 @@ void tst_QQmlEngineDebugInspectorIntegration::moveObject()
void tst_QQmlEngineDebugInspectorIntegration::destroyObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
QmlDebugObjectReference rootObject = findRootObject();
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
index 06250d9940..33ee023c06 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
@@ -5,8 +5,6 @@ osx:CONFIG -= app_bundle
SOURCES += \
tst_qqmlenginedebugservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index 6d31ff9219..8993ce7cf4 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -229,9 +229,23 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
QCOMPARE(p.name, QString::fromUtf8(pmeta.name()));
- if (pmeta.type() < QVariant::UserType && pmeta.userType() !=
- QMetaType::QVariant) // TODO test complex types
- QCOMPARE(p.value , pmeta.read(o));
+ if (pmeta.userType() == QMetaType::QObjectStar) {
+ const QmlDebugObjectReference ref = qvariant_cast<QmlDebugObjectReference>(p.value);
+ QObject *pobj = qvariant_cast<QObject *>(pmeta.read(o));
+ if (pobj) {
+ if (pobj->objectName().isEmpty())
+ QCOMPARE(ref.name, QString("<unnamed object>"));
+ else
+ QCOMPARE(ref.name, pobj->objectName());
+ } else {
+ QCOMPARE(ref.name, QString("<unknown value>"));
+ }
+ } else if (pmeta.type() < QVariant::UserType && pmeta.userType() != QMetaType::QVariant) {
+ const QVariant expected = pmeta.read(o);
+ QVERIFY2(p.value == expected, QString::fromLatin1("%1 != %2. Details: %3/%4/%5/%6")
+ .arg(QTest::toString(p.value)).arg(QTest::toString(expected)).arg(p.name)
+ .arg(p.valueTypeName).arg(pmeta.type()).arg(pmeta.userType()).toUtf8());
+ }
if (p.name == "parent")
QVERIFY(p.valueTypeName == "QGraphicsObject*" ||
@@ -1259,7 +1273,8 @@ void tst_QQmlEngineDebugService::queryObjectTree()
QmlDebugObjectReference targetReference = qvariant_cast<QmlDebugObjectReference>(propertyChangeTarget.value);
QVERIFY(!targetReference.className.isEmpty());
- QVERIFY(targetReference.debugId != -1);
+ QCOMPARE(targetReference.debugId, -1);
+ QCOMPARE(targetReference.name, QString("<unnamed object>"));
// check transition
QmlDebugObjectReference transition = obj.children[0];
@@ -1277,7 +1292,8 @@ void tst_QQmlEngineDebugService::queryObjectTree()
targetReference = qvariant_cast<QmlDebugObjectReference>(animationTarget.value);
QVERIFY(!targetReference.className.isEmpty());
- QVERIFY(targetReference.debugId != -1);
+ QCOMPARE(targetReference.debugId, -1);
+ QCOMPARE(targetReference.name, QString("<unnamed object>"));
QCOMPARE(findProperty(animation.properties,"property").value.toString(), QString("width"));
QCOMPARE(findProperty(animation.properties,"duration").value.toInt(), 100);
diff --git a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
index ee5f3c708a..fd07255ae5 100644
--- a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
+++ b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlinspector.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlinspectorclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index 9461922eff..5c9506eb21 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -28,6 +28,7 @@
#include "qqmlinspectorclient.h"
#include "../shared/debugutil_p.h"
+#include "../shared/qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugconnection_p.h>
@@ -40,64 +41,32 @@
#include <QtCore/qlibraryinfo.h>
#include <QtNetwork/qhostaddress.h>
-#define STR_PORT_FROM "3772"
-#define STR_PORT_TO "3782"
-
-
-class tst_QQmlInspector : public QQmlDataTest
+class tst_QQmlInspector : public QQmlDebugTest
{
Q_OBJECT
private:
- void startQmlProcess(const QString &qmlFile, bool restrictMode = true);
+ ConnectResult startQmlProcess(const QString &qmlFile, bool restrictMode = true);
void checkAnimationSpeed(int targetMillisPerDegree);
+ QList<QQmlDebugClient *> createClients() override;
+ QQmlDebugProcess *createProcess(const QString &executable) override;
-private:
- QScopedPointer<QQmlDebugProcess> m_process;
- QScopedPointer<QQmlDebugConnection> m_connection;
- QScopedPointer<QQmlInspectorClient> m_client;
- QScopedPointer<QQmlInspectorResultRecipient> m_recipient;
+ QPointer<QQmlInspectorClient> m_client;
+ QPointer<QQmlInspectorResultRecipient> m_recipient;
private slots:
- void cleanup();
-
void connect_data();
void connect();
void setAnimationSpeed();
void showAppOnTop();
};
-void tst_QQmlInspector::startQmlProcess(const QString &qmlFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlInspector::startQmlProcess(const QString &qmlFile,
+ bool restrictServices)
{
- const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:QmlInspector") : QString());
-
- m_process.reset(new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- "/qml"));
- // Make sure the animation timing is exact
- m_process->addEnvironment(QLatin1String("QSG_RENDER_LOOP=basic"));
- m_process->start(QStringList() << argument << testFile(qmlFile));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_client.reset();
- m_connection.reset(new QQmlDebugConnection);
- m_client.reset(new QQmlInspectorClient(m_connection.data()));
-
- m_recipient.reset(new QQmlInspectorResultRecipient);
- QObject::connect(m_client.data(), &QQmlInspectorClient::responseReceived,
- m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
-
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection.data());
-
- m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
-
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+ return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ restrictServices ? QStringLiteral("QmlInspector") : QString(),
+ testFile(qmlFile), true);
}
void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
@@ -114,8 +83,7 @@ void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
QString output = m_process->output();
int position = output.length();
do {
- QVERIFY(QQmlDebugTest::waitForSignal(m_process.data(),
- SIGNAL(readyReadStandardOutput())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
output = m_process->output();
} while (!output.mid(position).contains(markerString));
@@ -144,12 +112,21 @@ void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
.arg(targetMillisPerDegree).toLocal8Bit().constData());
}
-void tst_QQmlInspector::cleanup()
+QList<QQmlDebugClient *> tst_QQmlInspector::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
+ m_client = new QQmlInspectorClient(m_connection);
+ m_recipient = new QQmlInspectorResultRecipient(m_client);
+ QObject::connect(m_client.data(), &QQmlInspectorClient::responseReceived,
+ m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
+ return QList<QQmlDebugClient *>({m_client});
+}
+
+QQmlDebugProcess *tst_QQmlInspector::createProcess(const QString &executable)
+{
+ QQmlDebugProcess *process = QQmlDebugTest::createProcess(executable);
+ // Make sure the animation timing is exact
+ process->addEnvironment(QLatin1String("QSG_RENDER_LOOP=basic"));
+ return process;
}
void tst_QQmlInspector::connect_data()
@@ -166,7 +143,7 @@ void tst_QQmlInspector::connect()
{
QFETCH(QString, file);
QFETCH(bool, restrictMode);
- startQmlProcess(file, restrictMode);
+ QCOMPARE(startQmlProcess(file, restrictMode), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
@@ -181,7 +158,7 @@ void tst_QQmlInspector::connect()
void tst_QQmlInspector::showAppOnTop()
{
- startQmlProcess("qtquick2.qml");
+ QCOMPARE(startQmlProcess("qtquick2.qml"), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
@@ -196,7 +173,7 @@ void tst_QQmlInspector::showAppOnTop()
void tst_QQmlInspector::setAnimationSpeed()
{
- startQmlProcess("qtquick2.qml");
+ QCOMPARE(startQmlProcess("qtquick2.qml"), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
checkAnimationSpeed(10);
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
index dd7cb2055d..4235a2d55f 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
@@ -43,13 +43,6 @@ QtObject {
interval: 1000
onTriggered: {
console.profileEnd();
- endTimer.start();
}
}
-
- property var endTimer: Timer {
- id: endTimer
- interval: 1000
- onTriggered: Qt.quit();
- }
}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
index 4236d70ea3..3b28e65174 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
@@ -1,7 +1,7 @@
import QtQml 2.0
QtObject {
- Timer {
+ property Timer timer: Timer {
running: true
interval: 1
onTriggered: Qt.quit();
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml
new file mode 100644
index 0000000000..09dcd34b5c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml
@@ -0,0 +1,9 @@
+import QtQml 2.0
+
+Timer {
+ property string stuff: qsTr("foo")
+
+ running: true
+ interval: 1
+ onTriggered: Qt.quit();
+}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
index 56840d5c8f..7c78b5fcb3 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
@@ -4,8 +4,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlprofilerservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
@@ -22,4 +20,5 @@ OTHER_FILES += \
data/signalSourceLocation.qml \
data/javascript.qml \
data/timer.qml \
+ data/qstr.qml \
data/memory.qml
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index bc6c51707a..db28d3202d 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmlprofilerclient_p.h>
@@ -36,246 +37,144 @@
#include <private/qtestresult_p.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "13773"
-#define STR_PORT_TO "13783"
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
-struct QQmlProfilerData
-{
- QQmlProfilerData(qint64 time = -2, int messageType = -1, int detailType = -1,
- const QString &detailData = QString()) :
- time(time), messageType(messageType), detailType(detailType), detailData(detailData),
- line(-1), column(-1), framerate(-1), animationcount(-1), amount(-1)
- {}
-
- qint64 time;
- int messageType;
- int detailType;
-
- //###
- QString detailData; //used by RangeData and RangeLocation
- int line; //used by RangeLocation
- int column; //used by RangeLocation
- int framerate; //used by animation events
- int animationcount; //used by animation events
- qint64 amount; //used by heap events
-};
-
-class QQmlProfilerTestClient : public QQmlProfilerClient
+class QQmlProfilerTestClient : public QQmlProfilerEventReceiver, public QQmlProfilerDefinitions
{
Q_OBJECT
public:
- QQmlProfilerTestClient(QQmlDebugConnection *connection) : QQmlProfilerClient(connection),
- lastTimestamp(-1) {}
+ QQmlProfilerTestClient(QQmlDebugConnection *connection) :
+ client(new QQmlProfilerClient(connection, this))
+ {
+ connect(client.data(), &QQmlProfilerClient::traceStarted,
+ this, &QQmlProfilerTestClient::startTrace);
+ connect(client.data(), &QQmlProfilerClient::traceFinished,
+ this, &QQmlProfilerTestClient::endTrace);
+ }
- QVector<QQmlProfilerData> qmlMessages;
- QVector<QQmlProfilerData> javascriptMessages;
- QVector<QQmlProfilerData> jsHeapMessages;
- QVector<QQmlProfilerData> asynchronousMessages;
- QVector<QQmlProfilerData> pixmapMessages;
+ void startTrace(qint64 timestamp, const QList<int> &engineIds);
+ void endTrace(qint64 timestamp, const QList<int> &engineIds);
- qint64 lastTimestamp;
+ QPointer<QQmlProfilerClient> client; // Owned by QQmlDebugTest
+ QVector<QQmlProfilerEventType> types;
-signals:
- void recordingFinished();
+ QVector<QQmlProfilerEvent> qmlMessages;
+ QVector<QQmlProfilerEvent> javascriptMessages;
+ QVector<QQmlProfilerEvent> jsHeapMessages;
+ QVector<QQmlProfilerEvent> asynchronousMessages;
+ QVector<QQmlProfilerEvent> pixmapMessages;
-private:
- void traceStarted(qint64 time, int engineId);
- void traceFinished(qint64 time, int engineId);
- void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime);
- void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data);
- void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location);
- void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime);
- void animationFrame(qint64 time, int frameRate, int animationCount, int threadId);
- void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
- qint64 numericData1, qint64 numericData2, qint64 numericData3,
- qint64 numericData4, qint64 numericData5);
- void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QString &url, int numericData1, int numericData2);
- void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount);
- void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b);
- void complete();
-
- void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, int detailType);
- void unknownData(QPacket &stream);
+ int numLoadedEventTypes() const override;
+ void addEventType(const QQmlProfilerEventType &type) override;
+ void addEvent(const QQmlProfilerEvent &event) override;
};
-void QQmlProfilerTestClient::traceStarted(qint64 time, int engineId)
-{
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::StartTrace,
- QString::number(engineId)));
-}
-
-void QQmlProfilerTestClient::traceFinished(qint64 time, int engineId)
+void QQmlProfilerTestClient::startTrace(qint64 timestamp, const QList<int> &engineIds)
{
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::EndTrace,
- QString::number(engineId)));
+ types.append(QQmlProfilerEventType(Event, MaximumRangeType, StartTrace));
+ asynchronousMessages.append(QQmlProfilerEvent(timestamp, types.length() - 1,
+ engineIds.toVector()));
}
-void QQmlProfilerTestClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
+void QQmlProfilerTestClient::endTrace(qint64 timestamp, const QList<int> &engineIds)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= startTime);
- lastTimestamp = startTime;
- QQmlProfilerData data(startTime, QQmlProfilerDefinitions::RangeStart, type);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ types.append(QQmlProfilerEventType(Event, MaximumRangeType, EndTrace));
+ asynchronousMessages.append(QQmlProfilerEvent(timestamp, types.length() - 1,
+ engineIds.toVector()));
}
-void QQmlProfilerTestClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QString &string)
+int QQmlProfilerTestClient::numLoadedEventTypes() const
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeData, type, string);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ return types.length();
}
-void QQmlProfilerTestClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location)
+void QQmlProfilerTestClient::addEventType(const QQmlProfilerEventType &type)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(location.line >= -2);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeLocation, type, location.filename);
- data.line = location.line;
- data.column = location.column;
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ types.append(type);
}
-void QQmlProfilerTestClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
+void QQmlProfilerTestClient::addEvent(const QQmlProfilerEvent &event)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= endTime);
- lastTimestamp = endTime;
- QQmlProfilerData data(endTime, QQmlProfilerDefinitions::RangeEnd, type);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
-}
+ const int typeIndex = event.typeIndex();
+ QVERIFY(typeIndex < types.length());
-void QQmlProfilerTestClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId)
-{
- QVERIFY(threadId >= 0);
- QVERIFY(frameRate != -1);
- QVERIFY(animationCount != -1);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::AnimationFrame);
- data.framerate = frameRate;
- data.animationcount = animationCount;
- asynchronousMessages.append(data);
-}
-
-void QQmlProfilerTestClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
- qint64 time, qint64 numericData1, qint64 numericData2,
- qint64 numericData3, qint64 numericData4,
- qint64 numericData5)
-{
- Q_UNUSED(numericData1);
- Q_UNUSED(numericData2);
- Q_UNUSED(numericData3);
- Q_UNUSED(numericData4);
- Q_UNUSED(numericData5);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::SceneGraphFrame,
- type));
-}
+ const QQmlProfilerEventType &type = types[typeIndex];
-void QQmlProfilerTestClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
- qint64 time, const QString &url, int numericData1,
- int numericData2)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::PixmapCacheEvent, type, url);
- switch (type) {
- case QQmlProfilerDefinitions::PixmapSizeKnown:
- data.line = numericData1;
- data.column = numericData2;
+ switch (type.message()) {
+ case Event: {
+ switch (type.detailType()) {
+ case StartTrace:
+ QFAIL("StartTrace should not be passed on as event");
+ break;
+ case EndTrace:
+ QFAIL("EndTrace should not be passed on as event");
+ break;
+ case AnimationFrame:
+ asynchronousMessages.append(event);
+ break;
+ case Mouse:
+ case Key:
+ qmlMessages.append(event);
+ break;
+ default:
+ QFAIL(qPrintable(QString::fromLatin1("Event with unknown detailType %1 received at %2.")
+ .arg(type.detailType()).arg(event.timestamp())));
+ break;
+ }
+ break;
+ }
+ case RangeStart:
+ case RangeData:
+ case RangeLocation:
+ case RangeEnd:
+ QFAIL("Range stages are transmitted as part of events");
+ break;
+ case Complete:
+ QFAIL("Complete should not be passed on as event");
+ break;
+ case PixmapCacheEvent:
+ pixmapMessages.append(event);
+ break;
+ case SceneGraphFrame:
+ asynchronousMessages.append(event);
break;
- case QQmlProfilerDefinitions::PixmapReferenceCountChanged:
- case QQmlProfilerDefinitions::PixmapCacheCountChanged:
- data.animationcount = numericData1;
+ case MemoryAllocation:
+ jsHeapMessages.append(event);
break;
- default:
+ case DebugMessage:
+ // Unhandled
+ break;
+ case MaximumMessage:
+ switch (type.rangeType()) {
+ case Painting:
+ QFAIL("QtQuick1 paint message received.");
+ break;
+ case Compiling:
+ case Creating:
+ case Binding:
+ case HandlingSignal:
+ qmlMessages.append(event);
+ break;
+ case Javascript:
+ javascriptMessages.append(event);
+ break;
+ default:
+ QFAIL(qPrintable(
+ QString::fromLatin1("Unknown range event %1 received at %2.")
+ .arg(type.rangeType()).arg(event.timestamp())));
+ break;
+ }
break;
}
- pixmapMessages.append(data);
-}
-
-void QQmlProfilerTestClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
- qint64 amount)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::MemoryAllocation, type);
- data.amount = amount;
- jsHeapMessages.append(data);
}
-void QQmlProfilerTestClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
- int a, int b)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- qmlMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, type,
- QString::number(a) + QLatin1Char('x') +
- QString::number(b)));
-}
-
-void QQmlProfilerTestClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
- int detailType)
-{
- QFAIL(qPrintable(QString::fromLatin1("Unknown event %1 with detail type %2 received at %3.")
- .arg(messageType).arg(detailType).arg(time)));
-}
-
-void QQmlProfilerTestClient::unknownData(QPacket &stream)
-{
- QFAIL(qPrintable(QString::fromLatin1("%1 bytes of extra data after receiving message.")
- .arg(stream.device()->bytesAvailable())));
-}
-
-void QQmlProfilerTestClient::complete()
-{
- emit recordingFinished();
-}
-
-class tst_QQmlProfilerService : public QQmlDataTest
+class tst_QQmlProfilerService : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlProfilerService()
- : m_process(0)
- , m_connection(0)
- , m_client(0)
- {
- }
-
-
private:
- QQmlDebugProcess *m_process;
- QQmlDebugConnection *m_connection;
- QQmlProfilerTestClient *m_client;
-
enum MessageListType {
MessageListQML,
MessageListJavaScript,
@@ -290,18 +189,26 @@ private:
CheckLine = 1 << 2,
CheckColumn = 1 << 3,
CheckDataEndsWith = 1 << 4,
+ CheckFileEndsWith = 1 << 5,
+ CheckNumbers = 1 << 6,
- CheckAll = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckDataEndsWith
+ CheckType = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckFileEndsWith
};
- void connect(bool block, const QString &testFile, bool restrictServices = true);
+ ConnectResult connect(bool block, const QString &testFile, bool recordFromStart = true,
+ uint flushInterval = 0, bool restrictServices = true);
+ void checkProcessTerminated();
void checkTraceReceived();
void checkJsHeap();
- bool verify(MessageListType type, int expectedPosition, const QQmlProfilerData &expected,
- quint32 checks);
+ bool verify(MessageListType type, int expectedPosition,
+ const QQmlProfilerEventType &expectedType, quint32 checks,
+ const QVector<qint64> &numbers);
+
+ QList<QQmlDebugClient *> createClients() override;
+ QScopedPointer<QQmlProfilerTestClient> m_client;
private slots:
- void cleanup();
+ void cleanup() override;
void connect_data();
void connect();
@@ -312,55 +219,69 @@ private slots:
void signalSourceLocation();
void javascript();
void flushInterval();
+ void translationBinding();
void memory();
+
+private:
+ bool m_recordFromStart = true;
+ bool m_flushInterval = 0;
+ bool m_isComplete = false;
+
+ // Don't use ({...}) here as MSVC will interpret that as the "QVector(int size)" ctor.
+ const QVector<qint64> m_rangeStart = (QVector<qint64>() << QQmlProfilerDefinitions::RangeStart);
+ const QVector<qint64> m_rangeEnd = (QVector<qint64>() << QQmlProfilerDefinitions::RangeEnd);
};
-#define VERIFY(type, position, expected, checks) QVERIFY(verify(type, position, expected, checks))
+#define VERIFY(type, position, expected, checks, numbers) \
+ QVERIFY(verify(type, position, expected, checks, numbers))
-void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect(
+ bool block, const QString &file, bool recordFromStart, uint flushInterval,
+ bool restrictServices)
{
+ m_recordFromStart = recordFromStart;
+ m_flushInterval = flushInterval;
+ m_isComplete = false;
+
// ### Still using qmlscene due to QTBUG-33377
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
- QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2%3%4")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(block ? QStringLiteral(",block") : QString())
- .arg(restrictServices ? QStringLiteral(",services:CanvasFrameRate") : QString())
- << QQmlDataTest::instance()->testFile(testFile);
-
- m_process = new QQmlDebugProcess(executable, this);
- m_process->start(QStringList() << arguments);
- QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_connection = new QQmlDebugConnection();
- m_client = new QQmlProfilerTestClient(m_connection);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- const int port = m_process->debugPort();
- m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
- QVERIFY(m_client);
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
+ return QQmlDebugTest::connect(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ restrictServices ? QQmlDebuggingEnabler::profilerServices().join(',') : QString(),
+ testFile(file), block);
+}
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+void tst_QQmlProfilerService::checkProcessTerminated()
+{
+ // If the process ends before connect(), we get a non-success value from connect()
+ // That's not a problem as we will still receive the trace. We check that process has terminated
+ // cleanly here.
+
+ // Wait for the process to finish by itself, if that hasn't happened already
+ QVERIFY(m_client);
+ QVERIFY(m_client->client);
+ QTRY_COMPARE(m_client->client->state(), QQmlDebugClient::NotConnected);
+ QVERIFY(m_process);
+ QTRY_COMPARE(m_process->exitStatus(), QProcess::NormalExit);
}
void tst_QQmlProfilerService::checkTraceReceived()
{
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(recordingFinished())),
- "No trace received in time.");
+ QTRY_VERIFY2(m_isComplete, "No trace received in time.");
+
+ QVector<qint64> numbers;
// must start with "StartTrace"
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::StartTrace);
- VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType);
+ QQmlProfilerEventType expected(QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::MaximumRangeType,
+ QQmlProfilerDefinitions::StartTrace);
+ VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType, numbers);
// must end with "EndTrace"
- expected.detailType = QQmlProfilerDefinitions::EndTrace;
+ expected = QQmlProfilerEventType(QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::MaximumRangeType,
+ QQmlProfilerDefinitions::EndTrace);
VERIFY(MessageListAsynchronous, m_client->asynchronousMessages.length() - 1, expected,
- CheckMessageType | CheckDetailType);
+ CheckMessageType | CheckDetailType, numbers);
}
void tst_QQmlProfilerService::checkJsHeap()
@@ -373,33 +294,35 @@ void tst_QQmlProfilerService::checkJsHeap()
qint64 allocated = 0;
qint64 used = 0;
qint64 lastTimestamp = -1;
- foreach (const QQmlProfilerData &message, m_client->jsHeapMessages) {
- switch (message.detailType) {
+ foreach (const QQmlProfilerEvent &message, m_client->jsHeapMessages) {
+ const qint64 amount = message.number<qint64>(0);
+ const QQmlProfilerEventType &type = m_client->types.at(message.typeIndex());
+ switch (type.detailType()) {
case QV4::Profiling::HeapPage:
- allocated += message.amount;
+ allocated += amount;
seen_alloc = true;
break;
case QV4::Profiling::SmallItem:
- used += message.amount;
+ used += amount;
seen_small = true;
break;
case QV4::Profiling::LargeItem:
- allocated += message.amount;
- used += message.amount;
+ allocated += amount;
+ used += amount;
seen_large = true;
break;
}
- QVERIFY(message.time >= lastTimestamp);
+ QVERIFY(message.timestamp() >= lastTimestamp);
// The heap will only be consistent after all events of the same timestamp are processed.
if (lastTimestamp == -1) {
- lastTimestamp = message.time;
+ lastTimestamp = message.timestamp();
continue;
- } else if (message.time == lastTimestamp) {
+ } else if (message.timestamp() == lastTimestamp) {
continue;
}
- lastTimestamp = message.time;
+ lastTimestamp = message.timestamp();
QVERIFY2(used >= 0, QString::fromLatin1("Negative memory usage seen: %1")
.arg(used).toUtf8().constData());
@@ -418,10 +341,10 @@ void tst_QQmlProfilerService::checkJsHeap()
}
bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType type,
- int expectedPosition, const QQmlProfilerData &expected,
- quint32 checks)
+ int expectedPosition, const QQmlProfilerEventType &expected,
+ quint32 checks, const QVector<qint64> &expectedNumbers)
{
- QVector<QQmlProfilerData> *target = 0;
+ const QVector<QQmlProfilerEvent> *target = 0;
switch (type) {
case MessageListQML: target = &(m_client->qmlMessages); break;
case MessageListJavaScript: target = &(m_client->javascriptMessages); break;
@@ -437,41 +360,81 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty
}
uint position = expectedPosition;
- qint64 timestamp = target->at(expectedPosition).time;
- while (position > 0 && target->at(position - 1).time == timestamp)
+ qint64 timestamp = target->at(expectedPosition).timestamp();
+ while (position > 0 && target->at(position - 1).timestamp() == timestamp)
--position;
QStringList warnings;
do {
- const QQmlProfilerData &actual = target->at(position);
- if ((checks & CheckMessageType) && actual.messageType != expected.messageType) {
- warnings << QString::fromLatin1("%1: unexpected messageType. actual: %2 - expected: %3")
- .arg(position).arg(actual.messageType).arg(expected.messageType);
+ const QQmlProfilerEvent &event = target->at(position);
+ const QQmlProfilerEventType &actual = m_client->types.at(event.typeIndex());
+ if ((checks & CheckMessageType) &&
+ (actual.message() != expected.message()
+ || actual.rangeType() != expected.rangeType())) {
+ warnings << QString::fromLatin1("%1: unexpected messageType or rangeType. "
+ "actual: %2, %3 - expected: %4, %5")
+ .arg(position).arg(actual.message()).arg(actual.rangeType())
+ .arg(expected.message()).arg(expected.rangeType());
continue;
}
- if ((checks & CheckDetailType) && actual.detailType != expected.detailType) {
+ if ((checks & CheckDetailType) && actual.detailType() != expected.detailType()) {
warnings << QString::fromLatin1("%1: unexpected detailType. actual: %2 - expected: %3")
- .arg(position).arg(actual.detailType).arg(expected.detailType);
+ .arg(position).arg(actual.detailType()).arg(expected.detailType());
continue;
}
- if ((checks & CheckLine) && actual.line != expected.line) {
+
+ const QQmlProfilerEventLocation expectedLocation = expected.location();
+ const QQmlProfilerEventLocation actualLocation = actual.location();
+
+ if ((checks & CheckLine) && actualLocation.line() != expectedLocation.line()) {
warnings << QString::fromLatin1("%1: unexpected line. actual: %2 - expected: %3")
- .arg(position).arg(actual.line).arg(expected.line);
+ .arg(position).arg(actualLocation.line())
+ .arg(expectedLocation.line());
continue;
}
- if ((checks & CheckColumn) && actual.column != expected.column) {
+ if ((checks & CheckColumn) && actualLocation.column() != expectedLocation.column()) {
warnings << QString::fromLatin1("%1: unexpected column. actual: %2 - expected: %3")
- .arg(position).arg(actual.column).arg(expected.column);
+ .arg(position).arg(actualLocation.column())
+ .arg(expectedLocation.column());
+ continue;
+ }
+ if ((checks & CheckFileEndsWith) &&
+ !actualLocation.filename().endsWith(expectedLocation.filename())) {
+ warnings << QString::fromLatin1("%1: unexpected fileName. actual: %2 - expected: %3")
+ .arg(position).arg(actualLocation.filename())
+ .arg(expectedLocation.filename());
continue;
}
- if ((checks & CheckDataEndsWith) && !actual.detailData.endsWith(expected.detailData)) {
+
+ if ((checks & CheckDataEndsWith) && !actual.data().endsWith(expected.data())) {
warnings << QString::fromLatin1("%1: unexpected detailData. actual: %2 - expected: %3")
- .arg(position).arg(actual.detailData).arg(expected.detailData);
+ .arg(position).arg(actual.data()).arg(expected.data());
continue;
}
+
+ if (checks & CheckNumbers) {
+ const QVector<qint64> actualNumbers = event.numbers<QVector<qint64>>();
+ if (actualNumbers != expectedNumbers) {
+
+ QStringList expectedList;
+ for (qint64 number : expectedNumbers)
+ expectedList.append(QString::number(number));
+ QStringList actualList;
+ for (qint64 number : actualNumbers)
+ actualList.append(QString::number(number));
+
+ warnings << QString::fromLatin1(
+ "%1: unexpected numbers. actual [%2] - expected: [%3]")
+ .arg(position)
+ .arg(actualList.join(QLatin1String(", ")))
+ .arg(expectedList.join(QLatin1String(", ")));
+ continue;
+ }
+ }
+
return true;
- } while (target->at(++position).time == timestamp);
+ } while (target->at(++position).timestamp() == timestamp);
foreach (const QString &message, warnings)
qWarning() << message.toLocal8Bit().constData();
@@ -479,54 +442,62 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty
return false;
}
+QList<QQmlDebugClient *> tst_QQmlProfilerService::createClients()
+{
+ m_client.reset(new QQmlProfilerTestClient(m_connection));
+ m_client->client->setRecording(m_recordFromStart);
+ m_client->client->setFlushInterval(m_flushInterval);
+ QObject::connect(m_client->client, &QQmlProfilerClient::complete,
+ this, [this](){ m_isComplete = true; });
+ return QList<QQmlDebugClient *>({m_client->client});
+}
+
void tst_QQmlProfilerService::cleanup()
{
+ auto log = [this](const QQmlProfilerEvent &data, int i) {
+ const QQmlProfilerEventType &type = m_client->types.at(data.typeIndex());
+ const QQmlProfilerEventLocation location = type.location();
+ qDebug() << i << data.timestamp() << type.message() << type.rangeType() << type.detailType()
+ << location.filename() << location.line() << location.column()
+ << data.numbers<QVector<qint64>>();
+ };
+
if (m_client && QTest::currentTestFailed()) {
qDebug() << "QML Messages:" << m_client->qmlMessages.count();
int i = 0;
- foreach (const QQmlProfilerData &data, m_client->qmlMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->qmlMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "JavaScript Messages:" << m_client->javascriptMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->javascriptMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->javascriptMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Asynchronous Messages:" << m_client->asynchronousMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->asynchronousMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.framerate << data.animationcount << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->asynchronousMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Pixmap Cache Messages:" << m_client->pixmapMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->pixmapMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->pixmapMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Javascript Heap Messages:" << m_client->jsHeapMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->jsHeapMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->jsHeapMessages))
+ log(data, i++);
+
qDebug() << " ";
- qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
- qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
- qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
}
- delete m_process;
- m_process = 0;
- delete m_client;
- m_client = 0;
- delete m_connection;
- m_connection = 0;
+
+ m_client.reset();
+ QQmlDebugTest::cleanup();
}
void tst_QQmlProfilerService::connect_data()
@@ -550,67 +521,62 @@ void tst_QQmlProfilerService::connect()
QFETCH(bool, restrictMode);
QFETCH(bool, traceEnabled);
- connect(blockMode, "test.qml", restrictMode);
+ QCOMPARE(connect(blockMode, "test.qml", traceEnabled, 0, restrictMode), ConnectSuccess);
- // if the engine is waiting, then the first message determines if it starts with trace enabled
if (!traceEnabled)
- m_client->sendRecordingStatus(false);
- m_client->sendRecordingStatus(true);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(true);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
void tst_QQmlProfilerService::pixmapCacheData()
{
- connect(true, "pixmapCacheTest.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
- m_client->sendRecordingStatus(true);
- QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
+ QCOMPARE(connect(true, "pixmapCacheTest.qml"), ConnectSuccess);
+ // Don't wait for readyReadStandardOutput before the loop. It may have already arrived.
while (m_process->output().indexOf(QLatin1String("image loaded")) == -1 &&
m_process->output().indexOf(QLatin1String("image error")) == -1)
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::PixmapCacheEvent);
+ auto createType = [](QQmlProfilerDefinitions::PixmapEventType type) {
+ return QQmlProfilerEventType(QQmlProfilerDefinitions::PixmapCacheEvent,
+ QQmlProfilerDefinitions::MaximumRangeType, type);
+ };
+
+ QVector<qint64> numbers;
// image starting to load
- expected.detailType = QQmlProfilerDefinitions::PixmapLoadingStarted;
- VERIFY(MessageListPixmap, 0, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 0, createType(QQmlProfilerDefinitions::PixmapLoadingStarted),
+ CheckMessageType | CheckDetailType, numbers);
// image size
- expected.detailType = QQmlProfilerDefinitions::PixmapSizeKnown;
- expected.line = expected.column = 2; // width and height, in fact
- VERIFY(MessageListPixmap, 1, expected,
- CheckMessageType | CheckDetailType | CheckLine | CheckColumn);
+ numbers = QVector<qint64>({2, 2, 1});
+ VERIFY(MessageListPixmap, 1, createType(QQmlProfilerDefinitions::PixmapSizeKnown),
+ CheckMessageType | CheckDetailType | CheckNumbers, numbers);
// image loaded
- expected.detailType = QQmlProfilerDefinitions::PixmapLoadingFinished;
- VERIFY(MessageListPixmap, 2, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 2, createType(QQmlProfilerDefinitions::PixmapLoadingFinished),
+ CheckMessageType | CheckDetailType, numbers);
// cache size
- expected.detailType = QQmlProfilerDefinitions::PixmapCacheCountChanged;
- VERIFY(MessageListPixmap, 3, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 3, createType(QQmlProfilerDefinitions::PixmapCacheCountChanged),
+ CheckMessageType | CheckDetailType, numbers);
}
void tst_QQmlProfilerService::scenegraphData()
{
- connect(true, "scenegraphTest.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ QCOMPARE(connect(true, "scenegraphTest.qml"), ConnectSuccess);
while (!m_process->output().contains(QLatin1String("tick")))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
@@ -625,34 +591,39 @@ void tst_QQmlProfilerService::scenegraphData()
qint64 contextFrameTime = -1;
qint64 renderFrameTime = -1;
#if QT_CONFIG(opengl) //Software renderer doesn't have context frames
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphContextFrame) {
- contextFrameTime = msg.time;
- break;
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.message() == QQmlProfilerDefinitions::SceneGraphFrame) {
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphContextFrame) {
+ contextFrameTime = msg.timestamp();
+ break;
+ }
}
}
- }
- QVERIFY(contextFrameTime != -1);
+ QVERIFY(contextFrameTime != -1);
+ }
#endif
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
- QVERIFY(msg.time >= contextFrameTime);
- renderFrameTime = msg.time;
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
+ QVERIFY(msg.timestamp() >= contextFrameTime);
+ renderFrameTime = msg.timestamp();
break;
}
}
QVERIFY(renderFrameTime != -1);
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) {
- if (msg.time >= contextFrameTime) {
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) {
+ if (msg.timestamp() >= contextFrameTime) {
// Make sure SceneGraphRenderLoopFrame is not between SceneGraphContextFrame and
// SceneGraphRendererFrame. A SceneGraphRenderLoopFrame before everything else is
// OK as the scene graph might decide to do an initial rendering.
- QVERIFY(msg.time >= renderFrameTime);
+ QVERIFY(msg.timestamp() >= renderFrameTime);
break;
}
}
@@ -662,10 +633,7 @@ void tst_QQmlProfilerService::scenegraphData()
void tst_QQmlProfilerService::profileOnExit()
{
connect(true, "exit.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
@@ -673,104 +641,108 @@ void tst_QQmlProfilerService::profileOnExit()
void tst_QQmlProfilerService::controlFromJS()
{
- connect(true, "controlFromJS.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "controlFromJS.qml", false), ConnectSuccess);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
void tst_QQmlProfilerService::signalSourceLocation()
{
- connect(true, "signalSourceLocation.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "signalSourceLocation.qml"), ConnectSuccess);
- m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("500"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeLocation,
- QQmlProfilerDefinitions::HandlingSignal,
- QLatin1String("signalSourceLocation.qml"));
- expected.line = 8;
- expected.column = 28;
- VERIFY(MessageListQML, 9, expected, CheckAll);
+ auto createType = [](int line, int column) {
+ return QQmlProfilerEventType(
+ QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::HandlingSignal, -1,
+ QQmlProfilerEventLocation(QLatin1String("signalSourceLocation.qml"), line,
+ column));
+ };
- expected.line = 7;
- expected.column = 21;
- VERIFY(MessageListQML, 11, expected, CheckAll);
+ VERIFY(MessageListQML, 4, createType(8, 28), CheckType | CheckNumbers, m_rangeStart);
+ VERIFY(MessageListQML, 6, createType(7, 21), CheckType | CheckNumbers, m_rangeEnd);
}
void tst_QQmlProfilerService::javascript()
{
- connect(true, "javascript.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "javascript.qml"), ConnectSuccess);
- m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("done"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeStart,
- QQmlProfilerDefinitions::Javascript);
- VERIFY(MessageListJavaScript, 6, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListJavaScript, 2, QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript),
+ CheckMessageType | CheckDetailType | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeLocation;
- expected.detailData = QLatin1String("javascript.qml");
- expected.line = 4;
- expected.column = 5;
- VERIFY(MessageListJavaScript, 7, expected, CheckAll);
+ VERIFY(MessageListJavaScript, 3,
+ QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript, -1,
+ QQmlProfilerEventLocation(QLatin1String("javascript.qml"), 4, 5)),
+ CheckType | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeData;
- expected.detailData = QLatin1String("something");
- VERIFY(MessageListJavaScript, 8, expected,
- CheckMessageType | CheckDetailType | CheckDataEndsWith);
+ VERIFY(MessageListJavaScript, 4, QQmlProfilerEventType(
+ QQmlProfilerDefinitions::MaximumMessage, QQmlProfilerDefinitions::Javascript, -1,
+ QQmlProfilerEventLocation(), QLatin1String("something")),
+ CheckMessageType | CheckDetailType | CheckDataEndsWith | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeEnd;
- VERIFY(MessageListJavaScript, 21, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListJavaScript, 10, QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript),
+ CheckMessageType | CheckDetailType | CheckNumbers, m_rangeEnd);
}
void tst_QQmlProfilerService::flushInterval()
{
- connect(true, "timer.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true, -1, 1);
+ QCOMPARE(connect(true, "timer.qml", true, 1), ConnectSuccess);
// Make sure we get multiple messages
QTRY_VERIFY(m_client->qmlMessages.length() > 0);
QVERIFY(m_client->qmlMessages.length() < 100);
QTRY_VERIFY(m_client->qmlMessages.length() > 100);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
+void tst_QQmlProfilerService::translationBinding()
+{
+ connect(true, "qstr.qml");
+ checkProcessTerminated();
+
+ checkTraceReceived();
+ checkJsHeap();
+
+ const QQmlProfilerEventType type(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Binding);
+
+ VERIFY(MessageListQML, 4, type, CheckDetailType | CheckMessageType | CheckNumbers,
+ m_rangeStart);
+ VERIFY(MessageListQML, 5, type, CheckDetailType | CheckMessageType | CheckNumbers,
+ m_rangeEnd);
+}
+
void tst_QQmlProfilerService::memory()
{
connect(true, "memory.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
int smallItems = 0;
for (auto message : m_client->jsHeapMessages) {
- if (message.detailType == QV4::Profiling::SmallItem)
+ const QQmlProfilerEventType &type = m_client->types[message.typeIndex()];
+ if (type.detailType() == QV4::Profiling::SmallItem)
++smallItems;
}
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 441f8c113f..b569ad6b3c 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -38,7 +38,6 @@
#include <private/qv4debugging_p.h>
#include <private/qv8engine_p.h>
#include <private/qv4objectiterator_p.h>
-#include <private/qv4isel_moth_p.h>
#include <private/qv4string_p.h>
#include <private/qqmlbuiltinfunctions_p.h>
#include <private/qqmldebugservice_p.h>
@@ -46,7 +45,7 @@
using namespace QV4;
using namespace QV4::Debugging;
-typedef void (*InjectedFunction)(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+typedef QV4::ReturnedValue (*InjectedFunction)(const FunctionObject *b, const QV4::Value *, const QV4::Value *, int);
Q_DECLARE_METATYPE(InjectedFunction)
static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000)
@@ -79,7 +78,7 @@ public:
emit evaluateFinished();
}
- QV4::ExecutionEngine *v4Engine() { return QV8Engine::getV4(this); }
+ QV4::ExecutionEngine *v4Engine() { return handle(); }
Q_INVOKABLE void injectFunction(const QString &functionName, InjectedFunction injectedFunction)
{
@@ -88,7 +87,7 @@ public:
QV4::ScopedString name(scope, v4->newString(functionName));
QV4::ScopedContext ctx(scope, v4->rootContext());
- QV4::ScopedValue function(scope, BuiltinFunction::create(ctx, name, injectedFunction));
+ QV4::ScopedValue function(scope, FunctionObject::createBuiltinFunction(ctx, name, injectedFunction));
v4->globalObject->put(name, function);
}
@@ -343,7 +342,6 @@ void tst_qv4debugger::init()
m_javaScriptThread = new QThread;
m_engine = new TestEngine;
m_v4 = m_engine->v4Engine();
- m_v4->iselFactory.reset(new QV4::Moth::ISelFactory);
m_v4->setDebugger(new QV4Debugger(m_v4));
m_engine->moveToThread(m_javaScriptThread);
m_javaScriptThread->start();
@@ -438,9 +436,9 @@ void tst_qv4debugger::addBreakPointWhilePaused()
QCOMPARE(state.lineNumber, 2);
}
-static void someCall(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
+static QV4::ReturnedValue someCall(const FunctionObject *function, const QV4::Value *, const QV4::Value *, int)
{
- static_cast<QV4Debugger *>(scope.engine->debugger())
+ static_cast<QV4Debugger *>(function->engine()->debugger())
->removeBreakPoint("removeBreakPointForNextInstruction", 2);
RETURN_UNDEFINED();
}
@@ -464,7 +462,7 @@ void tst_qv4debugger::conditionalBreakPoint()
{
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function test() {\n"
+ "var test = function() {\n"
" for (var i = 0; i < 15; ++i) {\n"
" var x = i;\n"
" }\n"
@@ -489,9 +487,8 @@ void tst_qv4debugger::conditionalBreakPoint()
void tst_qv4debugger::conditionalBreakPointInQml()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
+ QV4::ExecutionEngine *v4 = engine.handle();
QV4Debugger *v4Debugger = new QV4Debugger(v4);
- v4->iselFactory.reset(new QV4::Moth::ISelFactory);
v4->setDebugger(v4Debugger);
QScopedPointer<QThread> debugThread(new QThread);
@@ -531,7 +528,7 @@ void tst_qv4debugger::readArguments()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a, b, c, d) {\n"
+ "var f = function(a, b, c, d) {\n"
" return a === b\n"
"}\n"
"var four;\n"
@@ -557,7 +554,7 @@ void tst_qv4debugger::readLocals()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a, b) {\n"
+ "var f = function(a, b) {\n"
" var c = a + b\n"
" var d = a - b\n" // breakpoint, c should be set, d should be undefined
" return c === d\n"
@@ -583,7 +580,7 @@ void tst_qv4debugger::readObject()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a) {\n"
+ "var f = function(a) {\n"
" var b = a\n"
" return b\n"
"}\n"
@@ -630,7 +627,7 @@ void tst_qv4debugger::readObject()
QCOMPARE(b_tail_head.value("value").toString(), QStringLiteral("asdf"));
QJsonObject b_tail_tail = b_tail_props.at(1).toObject();
QCOMPARE(b_tail_tail.value("name").toString(), QStringLiteral("tail"));
- QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("null"));
+ QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("object"));
QVERIFY(b_tail_tail.value("value").isNull());
}
@@ -641,7 +638,7 @@ void tst_qv4debugger::readContextInAllFrames()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function fact(n) {\n"
+ "var fact = function(n) {\n"
" if (n > 1) {\n"
" var n_1 = n - 1;\n"
" n_1 = fact(n_1);\n"
@@ -814,13 +811,13 @@ void tst_qv4debugger::lastLineOfConditional_data()
QTest::newRow("do..while {block}") << "do {\n" << "} while (ret < 10);" << 4 << 7;
QTest::newRow("if true {block}") << "if (true) {\n" << "}"
- << 4 << 7;
+ << 4 << 8;
QTest::newRow("if false {block}") << "if (false) {\n" << "}"
<< 2 << 8;
QTest::newRow("if true else {block}") << "if (true) {\n" << "} else {\n ret += 8;\n}"
- << 4 << 7;
+ << 4 << 10;
QTest::newRow("if false else {block}") << "if (false) {\n" << "} else {\n ret += 8;\n}"
- << 8 << 9;
+ << 8 << 10;
QTest::newRow("for statement") << "for (var i = 0; i < 10; ++i)\n" << "" << 4 << 2;
QTest::newRow("for..in statement") << "for (var i in [0, 1, 2, 3, 4])\n" << "" << 4 << 2;
@@ -829,11 +826,11 @@ void tst_qv4debugger::lastLineOfConditional_data()
// For two nested if statements without blocks, we need to map the jump from the inner to the
// outer one on the outer "if". There is just no better place.
- QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 2;
+ QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 8;
QTest::newRow("if false statement") << "if (false)\n" << "" << 2 << 8;
// Also two nested ifs without blocks.
- QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 2;
+ QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 9;
QTest::newRow("if false else statement") << "if (false)\n" << "else\n ret += 8;" << 8 << 9;
}
diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp
index d31efc84cf..8ecbe53822 100644
--- a/tests/auto/qml/debugger/shared/debugutil.cpp
+++ b/tests/auto/qml/debugger/shared/debugutil.cpp
@@ -27,13 +27,14 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+
#include <QtCore/qeventloop.h>
#include <QtCore/qtimer.h>
-#include <QtCore/qfileinfo.h>
-#include <QtCore/qdir.h>
bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) {
QEventLoop loop;
@@ -116,192 +117,114 @@ void QQmlDebugTestClient::messageReceived(const QByteArray &ba)
emit serverMessage(ba);
}
-QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent)
- : QObject(parent)
- , m_executable(executable)
- , m_started(false)
- , m_port(0)
- , m_maximumBindErrors(0)
- , m_receivedBindErrors(0)
-{
- m_process.setProcessChannelMode(QProcess::MergedChannels);
- m_timer.setSingleShot(true);
- m_timer.setInterval(15000);
- connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput()));
- connect(&m_process, SIGNAL(errorOccurred(QProcess::ProcessError)),
- this, SLOT(processError(QProcess::ProcessError)));
- connect(&m_timer, SIGNAL(timeout()), SLOT(timeout()));
-}
+template<typename F>
+struct Finalizer {
+ F m_lambda;
+ Finalizer(F &&lambda) : m_lambda(std::forward<F>(lambda)) {}
+ ~Finalizer() { m_lambda(); }
+};
-QQmlDebugProcess::~QQmlDebugProcess()
+template<typename F>
+static Finalizer<F> defer(F &&lambda)
{
- stop();
+ return Finalizer<F>(std::forward<F>(lambda));
}
-QString QQmlDebugProcess::state()
+QQmlDebugTest::ConnectResult QQmlDebugTest::connect(
+ const QString &executable, const QString &services, const QString &extraArgs,
+ bool block)
{
- QString stateStr;
- switch (m_process.state()) {
- case QProcess::NotRunning: {
- stateStr = "not running";
- if (m_process.exitStatus() == QProcess::CrashExit)
- stateStr += " (crashed!)";
- else
- stateStr += ", return value " + QString::number(m_process.exitCode());
- break;
- }
- case QProcess::Starting: stateStr = "starting"; break;
- case QProcess::Running: stateStr = "running"; break;
- }
- return stateStr;
-}
+ QStringList arguments;
+ arguments << QString::fromLatin1("-qmljsdebugger=port:13773,13783%3%4")
+ .arg(block ? QStringLiteral(",block") : QString())
+ .arg(services.isEmpty() ? services : (QStringLiteral(",services:") + services))
+ << extraArgs;
-void QQmlDebugProcess::start(const QStringList &arguments)
-{
-#ifdef Q_OS_MAC
- // make sure m_executable points to the actual binary even if it's inside an app bundle
- QFileInfo binFile(m_executable);
- if (!binFile.isExecutable()) {
- QDir bundleDir(m_executable + ".app");
- if (bundleDir.exists()) {
- m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
- //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
- }
- }
-#endif
- m_mutex.lock();
- m_port = 0;
- m_process.setEnvironment(QProcess::systemEnvironment() + m_environment);
- m_process.start(m_executable, arguments);
- if (!m_process.waitForStarted()) {
- qWarning() << "QML Debug Client: Could not launch app " << m_executable
- << ": " << m_process.errorString();
- m_eventLoop.quit();
- } else {
- m_timer.start();
- }
- m_mutex.unlock();
-}
+ m_process = createProcess(executable);
+ if (!m_process)
+ return ProcessFailed;
-void QQmlDebugProcess::stop()
-{
- if (m_process.state() != QProcess::NotRunning) {
- m_process.kill();
- m_process.waitForFinished(5000);
- }
-}
+ m_process->start(QStringList() << arguments);
+ if (!m_process->waitForSessionStart())
+ return SessionFailed;
-void QQmlDebugProcess::setMaximumBindErrors(int ignore)
-{
- m_maximumBindErrors = ignore;
-}
+ m_connection = createConnection();
+ if (!m_connection)
+ return ConnectionFailed;
-void QQmlDebugProcess::timeout()
-{
- qWarning() << "Timeout while waiting for QML debugging messages "
- "in application output. Process is in state" << m_process.state() << ", Output:" << m_output << ".";
- m_eventLoop.quit();
-}
+ m_clients = createClients();
+ if (m_clients.contains(nullptr))
+ return ClientsFailed;
-bool QQmlDebugProcess::waitForSessionStart()
-{
- if (m_process.state() != QProcess::Running) {
- qWarning() << "Could not start up " << m_executable;
- return false;
- } else if (m_started) {
+ auto allEnabled = [this]() {
+ for (QQmlDebugClient *client : m_clients) {
+ if (client->state() != QQmlDebugClient::Enabled)
+ return false;
+ }
return true;
+ };
+
+ QList<QQmlDebugClient *> others = createOtherClients(m_connection);
+ auto deleter = defer([&others]() { qDeleteAll(others); });
+ Q_UNUSED(deleter);
+
+ const int port = m_process->debugPort();
+ m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
+ for (int tries = 0; tries < 100 && !allEnabled(); ++tries)
+ QTest::qWait(50);
+ if (!allEnabled())
+ return EnableFailed;
+
+ const QQmlDebugClient::State expectedState = services.isEmpty() ? QQmlDebugClient::Enabled
+ : QQmlDebugClient::Unavailable;
+ for (QQmlDebugClient *other : others) {
+ if (other->state() != expectedState)
+ return RestrictFailed;
}
- m_eventLoop.exec();
-
- return m_started;
+ return ConnectSuccess;
}
-int QQmlDebugProcess::debugPort() const
+QList<QQmlDebugClient *> QQmlDebugTest::createClients()
{
- return m_port;
+ return QList<QQmlDebugClient *>();
}
-bool QQmlDebugProcess::waitForFinished()
+QQmlDebugProcess *QQmlDebugTest::createProcess(const QString &executable)
{
- return m_process.waitForFinished();
+ return new QQmlDebugProcess(executable, this);
}
-QProcess::ExitStatus QQmlDebugProcess::exitStatus() const
+QQmlDebugConnection *QQmlDebugTest::createConnection()
{
- return m_process.exitStatus();
+ return new QQmlDebugConnection(this);
}
-void QQmlDebugProcess::addEnvironment(const QString &environment)
+void QQmlDebugTest::cleanup()
{
- m_environment.append(environment);
-}
+ if (QTest::currentTestFailed()) {
+ const QString null = QStringLiteral("null");
-QString QQmlDebugProcess::output() const
-{
- return m_output;
-}
-
-void QQmlDebugProcess::processAppOutput()
-{
- m_mutex.lock();
-
- bool outputFromAppItself = false;
-
- QString newOutput = m_process.readAll();
- m_output.append(newOutput);
- m_outputBuffer.append(newOutput);
-
- while (true) {
- const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
- if (nlIndex < 0) // no further complete lines
- break;
- const QString line = m_outputBuffer.left(nlIndex);
- m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
-
- if (line.contains("QML Debugger:")) {
- const QRegExp portRx("Waiting for connection on port (\\d+)");
- if (portRx.indexIn(line) != -1) {
- m_port = portRx.cap(1).toInt();
- m_timer.stop();
- m_started = true;
- m_eventLoop.quit();
- continue;
- }
- if (line.contains("Unable to listen")) {
- if (++m_receivedBindErrors >= m_maximumBindErrors) {
- if (m_maximumBindErrors == 0)
- qWarning() << "App was unable to bind to port!";
- m_timer.stop();
- m_eventLoop.quit();
- }
- continue;
- }
- } else {
- // set to true if there is output not coming from the debugger
- outputFromAppItself = true;
+ qDebug() << "Process State:" << (m_process ? m_process->state() : null);
+ qDebug() << "Application Output:" << (m_process ? m_process->output() : null);
+ qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
+ for (QQmlDebugClient *client : m_clients) {
+ if (client)
+ qDebug() << client->name() << "State:" << QQmlDebugTest::clientStateString(client);
+ else
+ qDebug() << "Failed Client:" << null;
}
}
- m_mutex.unlock();
- if (outputFromAppItself)
- emit readyReadStandardOutput();
-}
+ qDeleteAll(m_clients);
+ m_clients.clear();
-void QQmlDebugProcess::processError(QProcess::ProcessError error)
-{
- if (!m_eventLoop.isRunning())
- return;
-
- qDebug() << "An error occurred while waiting for debug process to become available:";
- switch (error) {
- case QProcess::FailedToStart: qDebug() << "Process failed to start."; break;
- case QProcess::Crashed: qDebug() << "Process crashed."; break;
- case QProcess::Timedout: qDebug() << "Process timed out."; break;
- case QProcess::WriteError: qDebug() << "Error while writing to process."; break;
- case QProcess::ReadError: qDebug() << "Error while reading from process."; break;
- case QProcess::UnknownError: qDebug() << "Unknown process error."; break;
- }
+ delete m_connection;
+ m_connection = nullptr;
- m_eventLoop.exit();
+ if (m_process) {
+ m_process->stop();
+ delete m_process;
+ m_process = nullptr;
+ }
}
diff --git a/tests/auto/qml/debugger/shared/debugutil.pri b/tests/auto/qml/debugger/shared/debugutil.pri
index 1983f3583e..13dcdb91d8 100644
--- a/tests/auto/qml/debugger/shared/debugutil.pri
+++ b/tests/auto/qml/debugger/shared/debugutil.pri
@@ -1,4 +1,11 @@
QT += qmldebug-private
-HEADERS += $$PWD/debugutil_p.h
-SOURCES += $$PWD/debugutil.cpp
+INCLUDEPATH += $$PWD
+include($$PWD/../../../shared/util.pri)
+
+HEADERS += \
+ $$PWD/debugutil_p.h \
+ $$PWD/qqmldebugprocess_p.h
+SOURCES += \
+ $$PWD/debugutil.cpp \
+ $$PWD/qqmldebugprocess.cpp
diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h
index 1ec0a6513d..94ad83bfce 100644
--- a/tests/auto/qml/debugger/shared/debugutil_p.h
+++ b/tests/auto/qml/debugger/shared/debugutil_p.h
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
@@ -41,23 +40,43 @@
// We mean it.
//
+#include <../../../shared/util.h>
#include <private/qqmldebugclient_p.h>
-#include <QtCore/qeventloop.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qprocess.h>
-#include <QtCore/qmutex.h>
-#include <QtTest/qtest.h>
-#include <QtQml/qqmlengine.h>
-
-class QQmlDebugTest
+class QQmlDebugProcess;
+class QQmlDebugTest : public QQmlDataTest
{
+ Q_OBJECT
public:
static bool waitForSignal(QObject *receiver, const char *member, int timeout = 5000);
static QList<QQmlDebugClient *> createOtherClients(QQmlDebugConnection *connection);
static QString clientStateString(const QQmlDebugClient *client);
static QString connectionStateString(const QQmlDebugConnection *connection);
+
+protected:
+ enum ConnectResult {
+ ConnectSuccess,
+ ProcessFailed,
+ SessionFailed,
+ ConnectionFailed,
+ ClientsFailed,
+ EnableFailed,
+ RestrictFailed
+ };
+
+ ConnectResult connect(const QString &executable, const QString &services,
+ const QString &extraArgs, bool block);
+
+ virtual QQmlDebugProcess *createProcess(const QString &executable);
+ virtual QQmlDebugConnection *createConnection();
+ virtual QList<QQmlDebugClient *> createClients();
+
+ QQmlDebugProcess *m_process = nullptr;
+ QQmlDebugConnection *m_connection = nullptr;
+ QList<QQmlDebugClient *> m_clients;
+
+protected slots:
+ virtual void cleanup();
};
class QQmlDebugTestClient : public QQmlDebugClient
@@ -80,51 +99,6 @@ private:
QByteArray lastMsg;
};
-class QQmlDebugProcess : public QObject
-{
- Q_OBJECT
-public:
- QQmlDebugProcess(const QString &executable, QObject *parent = 0);
- ~QQmlDebugProcess();
-
- QString state();
-
- void addEnvironment(const QString &environment);
-
- void start(const QStringList &arguments);
- bool waitForSessionStart();
- int debugPort() const;
-
- bool waitForFinished();
- QProcess::ExitStatus exitStatus() const;
-
- QString output() const;
- void stop();
- void setMaximumBindErrors(int numErrors);
-
-signals:
- void readyReadStandardOutput();
-
-private slots:
- void timeout();
- void processAppOutput();
- void processError(QProcess::ProcessError error);
-
-private:
- QString m_executable;
- QProcess m_process;
- QString m_outputBuffer;
- QString m_output;
- QTimer m_timer;
- QEventLoop m_eventLoop;
- QMutex m_mutex;
- bool m_started;
- QStringList m_environment;
- int m_port;
- int m_maximumBindErrors;
- int m_receivedBindErrors;
-};
-
class QQmlInspectorResultRecipient : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp
new file mode 100644
index 0000000000..201a6b1a76
--- /dev/null
+++ b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugprocess_p.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+
+QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent)
+ : QObject(parent)
+ , m_executable(executable)
+ , m_state(SessionUnknown)
+ , m_port(0)
+ , m_maximumBindErrors(0)
+ , m_receivedBindErrors(0)
+{
+ m_process.setProcessChannelMode(QProcess::MergedChannels);
+ m_timer.setSingleShot(true);
+ m_timer.setInterval(15000);
+ connect(&m_process, &QProcess::readyReadStandardOutput,
+ this, &QQmlDebugProcess::processAppOutput);
+ connect(&m_process, &QProcess::errorOccurred,
+ this, &QQmlDebugProcess::processError);
+ connect(&m_process, QOverload<int>::of(&QProcess::finished),
+ this, [this]() {
+ m_timer.stop();
+ m_eventLoop.quit();
+ });
+ connect(&m_timer, &QTimer::timeout,
+ this, &QQmlDebugProcess::timeout);
+}
+
+QQmlDebugProcess::~QQmlDebugProcess()
+{
+ stop();
+}
+
+QString QQmlDebugProcess::state()
+{
+ QString stateStr;
+ switch (m_process.state()) {
+ case QProcess::NotRunning: {
+ stateStr = "not running";
+ if (m_process.exitStatus() == QProcess::CrashExit)
+ stateStr += " (crashed!)";
+ else
+ stateStr += ", return value " + QString::number(m_process.exitCode());
+ break;
+ }
+ case QProcess::Starting:
+ stateStr = "starting";
+ break;
+ case QProcess::Running:
+ stateStr = "running";
+ break;
+ }
+ return stateStr;
+}
+
+void QQmlDebugProcess::start(const QStringList &arguments)
+{
+#ifdef Q_OS_MAC
+ // make sure m_executable points to the actual binary even if it's inside an app bundle
+ QFileInfo binFile(m_executable);
+ if (!binFile.isExecutable()) {
+ QDir bundleDir(m_executable + ".app");
+ if (bundleDir.exists()) {
+ m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
+ //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
+ }
+ }
+#endif
+ m_mutex.lock();
+ m_port = 0;
+ m_process.setEnvironment(QProcess::systemEnvironment() + m_environment);
+ m_process.start(m_executable, arguments);
+ if (!m_process.waitForStarted()) {
+ qWarning() << "QML Debug Client: Could not launch app " << m_executable
+ << ": " << m_process.errorString();
+ m_eventLoop.quit();
+ }
+ m_mutex.unlock();
+}
+
+void QQmlDebugProcess::stop()
+{
+ if (m_process.state() != QProcess::NotRunning) {
+ disconnect(&m_process, &QProcess::errorOccurred, this, &QQmlDebugProcess::processError);
+ m_process.kill();
+ m_process.waitForFinished(5000);
+ }
+}
+
+void QQmlDebugProcess::setMaximumBindErrors(int ignore)
+{
+ m_maximumBindErrors = ignore;
+}
+
+void QQmlDebugProcess::timeout()
+{
+ qWarning() << "Timeout while waiting for QML debugging messages "
+ "in application output. Process is in state" << m_process.state()
+ << ", Output:" << m_output << ".";
+ m_eventLoop.quit();
+}
+
+bool QQmlDebugProcess::waitForSessionStart()
+{
+ if (m_process.state() != QProcess::Running) {
+ qWarning() << "Could not start up " << m_executable;
+ return false;
+ } else if (m_state == SessionStarted) {
+ return true;
+ } else if (m_state == SessionFailed) {
+ return false;
+ }
+
+ m_timer.start();
+ m_eventLoop.exec();
+
+ return m_state == SessionStarted;
+}
+
+int QQmlDebugProcess::debugPort() const
+{
+ return m_port;
+}
+
+bool QQmlDebugProcess::waitForFinished()
+{
+ return m_process.waitForFinished();
+}
+
+QProcess::ExitStatus QQmlDebugProcess::exitStatus() const
+{
+ return m_process.exitStatus();
+}
+
+void QQmlDebugProcess::addEnvironment(const QString &environment)
+{
+ m_environment.append(environment);
+}
+
+QString QQmlDebugProcess::output() const
+{
+ return m_output;
+}
+
+void QQmlDebugProcess::processAppOutput()
+{
+ m_mutex.lock();
+
+ bool outputFromAppItself = false;
+
+ QString newOutput = m_process.readAll();
+ m_output.append(newOutput);
+ m_outputBuffer.append(newOutput);
+
+ while (true) {
+ const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
+ if (nlIndex < 0) // no further complete lines
+ break;
+ const QString line = m_outputBuffer.left(nlIndex);
+ m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
+
+ if (line.contains("QML Debugger:")) {
+ const QRegExp portRx("Waiting for connection on port (\\d+)");
+ if (portRx.indexIn(line) != -1) {
+ m_port = portRx.cap(1).toInt();
+ m_timer.stop();
+ m_state = SessionStarted;
+ m_eventLoop.quit();
+ continue;
+ }
+ if (line.contains("Unable to listen")) {
+ if (++m_receivedBindErrors >= m_maximumBindErrors) {
+ if (m_maximumBindErrors == 0)
+ qWarning() << "App was unable to bind to port!";
+ m_timer.stop();
+ m_state = SessionFailed;
+ m_eventLoop.quit();
+ }
+ continue;
+ }
+ }
+
+ // set to true if there is output not coming from the debugger or we don't understand it
+ outputFromAppItself = true;
+ }
+ m_mutex.unlock();
+
+ if (outputFromAppItself)
+ emit readyReadStandardOutput();
+}
+
+void QQmlDebugProcess::processError(QProcess::ProcessError error)
+{
+ qDebug() << "An error occurred while waiting for debug process to become available:";
+ switch (error) {
+ case QProcess::FailedToStart:
+ qDebug() << "Process failed to start.";
+ break;
+ case QProcess::Crashed:
+ qDebug() << "Process crashed.";
+ break;
+ case QProcess::Timedout:
+ qDebug() << "Process timed out.";
+ break;
+ case QProcess::WriteError:
+ qDebug() << "Error while writing to process.";
+ break;
+ case QProcess::ReadError:
+ qDebug() << "Error while reading from process.";
+ break;
+ case QProcess::UnknownError:
+ qDebug() << "Unknown process error.";
+ break;
+ }
+}
diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h
new file mode 100644
index 0000000000..fd2c89bb41
--- /dev/null
+++ b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLDEBUGPROCESS_P_H
+#define QQMLDEBUGPROCESS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qprocess.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qeventloop.h>
+#include <QtCore/qmutex.h>
+
+class QQmlDebugProcess : public QObject
+{
+ Q_OBJECT
+public:
+ QQmlDebugProcess(const QString &executable, QObject *parent = 0);
+ ~QQmlDebugProcess();
+
+ QString state();
+
+ void addEnvironment(const QString &environment);
+
+ void start(const QStringList &arguments);
+ bool waitForSessionStart();
+ int debugPort() const;
+
+ bool waitForFinished();
+ QProcess::ExitStatus exitStatus() const;
+
+ QString output() const;
+ void stop();
+ void setMaximumBindErrors(int numErrors);
+
+signals:
+ void readyReadStandardOutput();
+
+private slots:
+ void timeout();
+ void processAppOutput();
+ void processError(QProcess::ProcessError error);
+
+private:
+ enum SessionState {
+ SessionUnknown,
+ SessionStarted,
+ SessionFailed
+ };
+
+ QString m_executable;
+ QProcess m_process;
+ QString m_outputBuffer;
+ QString m_output;
+ QTimer m_timer;
+ QEventLoop m_eventLoop;
+ QMutex m_mutex;
+ SessionState m_state;
+ QStringList m_environment;
+ int m_port;
+ int m_maximumBindErrors;
+ int m_receivedBindErrors;
+};
+
+#endif // QQMLDEBUGPROCESS_P_H
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
index c0252a0290..7e736ec400 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
@@ -385,7 +385,7 @@ void QQmlEngineDebugClient::decode(QPacket &ds,
case QmlObjectProperty::Object:
{
QmlDebugObjectReference obj;
- obj.debugId = prop.value.toInt();
+ obj.name = data.value.toString();
obj.className = prop.valueTypeName;
prop.value = qVariantFromValue(obj);
break;
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 49f107452a..589f25d174 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -15,7 +15,6 @@ S15.1.2.3_A2_T10
15.5.4.20-3-5
15.5.4.20-3-6
-10.4.3-1-106 failing
11.2.3-3_3 failing
S13_A15_T4 failing
S15.4.4.3_A1_T1 failing
@@ -29,3 +28,150 @@ Sbp_12.5_A9_T3 failing
Sbp_12.6.1_A13_T3 failing
Sbp_12.6.2_A13_T3 failing
Sbp_12.6.4_A13_T3 failing
+
+# es6: function length attributes are configurable, wasn't in es5
+S15.1.2.2_A9.2 failing
+S15.1.3.1_A5.2 failing
+S15.1.3.2_A5.2 failing
+S15.1.3.3_A5.2 failing
+S15.1.2.3_A7.2 failing
+S15.1.2.4_A2.2 failing
+S15.1.2.5_A2.2 failing
+S15.1.3.4_A5.2 failing
+15.2.3.3-4-186 failing
+S15.2.4.2_A9 failing
+S15.2.4.3_A9 failing
+S15.2.4.4_A9 failing
+S15.2.4.5_A9 failing
+S15.2.4.6_A9 failing
+S15.2.4.7_A9 failing
+15.3.3.2-1 failing
+15.4.4.2_A4.2
+S15.3.4.2_A9 failing
+S15.3.4.3_A9 failing
+S15.3.4.4_A9 failing
+15.3.4.5-15-2 failing
+S15.4.4.2_A4.2 failing
+S15.4.4.3_A4.2 failing
+S15.4.4.4_A4.2 failing
+S15.4.4.5_A6.2 failing
+S15.4.4.6_A5.2 failing
+S15.4.4.7_A6.2 failing
+S15.4.4.8_A5.2 failing
+S15.4.4.9_A5.2 failing
+S15.4.4.10_A5.2 failing
+S15.4.4.11_A7.2 failing
+S15.4.4.12_A5.2 failing
+S15.4.4.13_A5.2 failing
+S15.5.4.10_A9 failing
+S15.5.4.11_A9 failing
+S15.5.4.12_A9 failing
+S15.5.4.13_A9 failing
+S15.5.4.14_A9 failing
+S15.5.4.15_A9 failing
+S15.5.4.16_A9 failing
+S15.5.4.17_A9 failing
+S15.5.4.18_A9 failing
+S15.5.4.19_A9 failing
+S15.5.4.4_A9 failing
+S15.5.4.5_A9 failing
+S15.5.4.6_A9 failing
+S15.5.4.7_A9 failing
+S15.5.4.8_A9 failing
+S15.5.4.9_A9 failing
+S15.9.4.2_A3_T2 failing
+S15.9.4.3_A3_T2 failing
+S15.9.5.2_A3_T2 failing
+S15.9.5.3_A3_T2 failing
+S15.9.5.4_A3_T2 failing
+S15.9.5.5_A3_T2 failing
+S15.9.5.1_A3_T2 failing
+S15.9.5.10_A3_T2 failing
+S15.9.5.11_A3_T2 failing
+S15.9.5.12_A3_T2 failing
+S15.9.5.13_A3_T2 failing
+S15.9.5.14_A3_T2 failing
+S15.9.5.15_A3_T2 failing
+S15.9.5.16_A3_T2 failing
+S15.9.5.17_A3_T2 failing
+S15.9.5.18_A3_T2 failing
+S15.9.5.19_A3_T2 failing
+S15.9.5.20_A3_T2 failing
+S15.9.5.21_A3_T2 failing
+S15.9.5.22_A3_T2 failing
+S15.9.5.23_A3_T2 failing
+S15.9.5.24_A3_T2 failing
+S15.9.5.25_A3_T2 failing
+S15.9.5.26_A3_T2 failing
+S15.9.5.27_A3_T2 failing
+S15.9.5.28_A3_T2 failing
+S15.9.5.29_A3_T2 failing
+S15.9.5.30_A3_T2 failing
+S15.9.5.31_A3_T2 failing
+S15.9.5.32_A3_T2 failing
+S15.9.5.33_A3_T2 failing
+S15.9.5.34_A3_T2 failing
+S15.9.5.35_A3_T2 failing
+S15.9.5.36_A3_T2 failing
+S15.9.5.37_A3_T2 failing
+S15.9.5.38_A3_T2 failing
+S15.9.5.39_A3_T2 failing
+S15.9.5.40_A3_T2 failing
+S15.9.5.41_A3_T2 failing
+S15.9.5.42_A3_T2 failing
+S15.9.5.6_A3_T2 failing
+S15.9.5.7_A3_T2 failing
+S15.9.5.8_A3_T2 failing
+S15.9.5.9_A3_T2 failing
+S15.10.6.2_A9 failing
+S15.10.6.3_A9 failing
+S15.10.6.4_A9 failing
+
+# es6: Object.freeze(v) on a non-object returns v, no longer TypeError
+15.2.3.9-1 failing
+15.2.3.9-1-1 failing
+15.2.3.9-1-2 failing
+15.2.3.9-1-3 failing
+15.2.3.9-1-4 failing
+# es6: Object.preventExtensions(O) on a non-object, no longer TypeError
+15.2.3.10-1 failing
+15.2.3.10-1-3 failing
+15.2.3.10-1-4 failing
+# es6: Object.isSealed(O) on a non-object, no longer TypeError
+15.2.3.11-1
+# es6: Object.isFrozen(O) on a non-object, no longer TypeError
+15.2.3.12-1
+15.2.3.12-1-3
+15.2.3.12-1-4
+# es6: Object.isExtensible(O) on a non-object, no longer TypeError
+15.2.3.13-1
+15.2.3.13-1-3
+15.2.3.13-1-4
+# es6: Object.keys(O) on a non-object, no longer TypeError
+15.2.3.14-1-1
+15.2.3.14-1-2
+15.2.3.14-1-3
+15.2.3.14-1
+15.2.3.14-2
+15.2.3.14-3
+# es6: Object.getOwnPropertyDescriptor(O) on a non-object, no longer TypeError
+15.2.3.3-1
+15.2.3.3-1-3
+15.2.3.3-1-4
+# es6: Object.getPrototypeOf(O) on a non-object, no longer TypeError
+15.2.3.2-1
+15.2.3.2-1-3
+15.2.3.2-1-4
+# es6: Object.getOwnPropertyNames(O) on a non-object, no longer TypeError
+15.2.3.4-1
+15.2.3.4-1-4
+15.2.3.4-1-5
+# es6: Object.seal(O) on a non-object, no longer TypeError
+15.2.3.8-1
+15.2.3.8-1-1
+15.2.3.8-1-2
+15.2.3.8-1-3
+15.2.3.8-1-4
+
+# es6: Date.prototype is no longer a DateObject
+15.9.5.40_1 failing
diff --git a/tests/auto/qml/ecmascripttests/test262 b/tests/auto/qml/ecmascripttests/test262
-Subproject fe58b18c13d1ea5d42951e5b698efc3bfab6dc8
+Subproject d60c4ed97e69639bc5bc1db43a98828debf80c8
diff --git a/tests/auto/qml/ecmascripttests/test262.py b/tests/auto/qml/ecmascripttests/test262.py
index 437cd1b27d..ae4c54df9d 100755
--- a/tests/auto/qml/ecmascripttests/test262.py
+++ b/tests/auto/qml/ecmascripttests/test262.py
@@ -552,10 +552,10 @@ class TestSuite(object):
def Main():
- # Some date tests rely on being run in pacific time.
# Uncomment the next line for more logging info.
#logging.basicConfig(level=logging.DEBUG)
- os.environ["TZ"] = "PST8PDT"
+ # Some date tests rely on being run in pacific time and the USA's locale:
+ os.environ["TZ"] = "America/Vancouver"
os.environ["LANG"] = "en_US.UTF-8"
os.environ["LC_TIME"] = "en_US.UTF-8"
parser = BuildOptions()
diff --git a/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
index 880e254543..0d58d045b9 100644
--- a/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
+++ b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
@@ -34,29 +34,29 @@
class tst_EcmaScriptTests : public QObject
{
Q_OBJECT
-private slots:
- void runTests_data();
- void runTests();
-};
-void tst_EcmaScriptTests::runTests_data()
-{
- QTest::addColumn<QString>("qmljsParameter");
+ void runTests(bool interpret);
- QTest::newRow("jit") << QStringLiteral("--jit");
- QTest::newRow("interpreter") << QStringLiteral("--interpret");
-}
+private slots:
+ void runInterpreted();
+ void runJitted();
+};
-void tst_EcmaScriptTests::runTests()
+void tst_EcmaScriptTests::runTests(bool interpret)
{
#if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86_64)
- QFETCH(QString, qmljsParameter);
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ if (interpret)
+ env.insert("QV4_FORCE_INTERPRETER", "1");
+ else
+ env.insert("QV4_JIT_CALL_THRESHOLD", "0");
QProcess process;
process.setProcessChannelMode(QProcess::ForwardedChannels);
process.setWorkingDirectory(QLatin1String(SRCDIR));
process.setProgram("python");
- process.setArguments(QStringList() << "test262.py" << "--command=" + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmljs " + qmljsParameter << "--parallel" << "--with-test-expectations");
+ process.setProcessEnvironment(env);
+ process.setArguments(QStringList() << "test262.py" << "--command=" + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmljs" << "--parallel" << "--with-test-expectations");
qDebug() << "Going to run" << process.program() << process.arguments() << "in" << process.workingDirectory();
@@ -71,6 +71,16 @@ void tst_EcmaScriptTests::runTests()
#endif
}
+void tst_EcmaScriptTests::runInterpreted()
+{
+ runTests(true);
+}
+
+void tst_EcmaScriptTests::runJitted()
+{
+ runTests(false);
+}
+
QTEST_GUILESS_MAIN(tst_EcmaScriptTests)
#include "tst_ecmascripttests.moc"
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 8b815f7a06..519c57efb2 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -201,6 +201,8 @@ private slots:
void malformedExpression();
+ void scriptScopes();
+
signals:
void testSignal();
};
@@ -569,10 +571,6 @@ void tst_QJSEngine::newDate()
QCOMPARE(date.isDate(), true);
QCOMPARE(date.isObject(), true);
QVERIFY(!date.isCallable());
- // prototype should be Date.prototype
- QVERIFY(!date.prototype().isUndefined());
- QCOMPARE(date.prototype().isDate(), true);
- QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true);
}
{
@@ -581,10 +579,6 @@ void tst_QJSEngine::newDate()
QVERIFY(!date.isUndefined());
QCOMPARE(date.isDate(), true);
QCOMPARE(date.isObject(), true);
- // prototype should be Date.prototype
- QVERIFY(!date.prototype().isUndefined());
- QCOMPARE(date.prototype().isDate(), true);
- QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true);
QCOMPARE(date.toDateTime(), dt);
}
@@ -1115,7 +1109,7 @@ void tst_QJSEngine::builtinFunctionNames_data()
QTest::newRow("Date.prototype.setFullYear") << QString("Date.prototype.setFullYear") << QString("setFullYear");
QTest::newRow("Date.prototype.setUTCFullYear") << QString("Date.prototype.setUTCFullYear") << QString("setUTCFullYear");
QTest::newRow("Date.prototype.toUTCString") << QString("Date.prototype.toUTCString") << QString("toUTCString");
- QTest::newRow("Date.prototype.toGMTString") << QString("Date.prototype.toGMTString") << QString("toGMTString");
+ QTest::newRow("Date.prototype.toGMTString") << QString("Date.prototype.toGMTString") << QString("toUTCString"); // yes, this is per spec
QTest::newRow("Error") << QString("Error") << QString("Error");
// QTest::newRow("Error.prototype.backtrace") << QString("Error.prototype.backtrace") << QString("backtrace");
@@ -1193,6 +1187,7 @@ void tst_QJSEngine::builtinFunctionNames_data()
QTest::newRow("String.prototype.lastIndexOf") << QString("String.prototype.lastIndexOf") << QString("lastIndexOf");
QTest::newRow("String.prototype.localeCompare") << QString("String.prototype.localeCompare") << QString("localeCompare");
QTest::newRow("String.prototype.match") << QString("String.prototype.match") << QString("match");
+ QTest::newRow("String.prototype.repeat") << QString("String.prototype.repeat") << QString("repeat");
QTest::newRow("String.prototype.replace") << QString("String.prototype.replace") << QString("replace");
QTest::newRow("String.prototype.search") << QString("String.prototype.search") << QString("search");
QTest::newRow("String.prototype.slice") << QString("String.prototype.slice") << QString("slice");
@@ -4125,6 +4120,22 @@ void tst_QJSEngine::malformedExpression()
engine.evaluate("5%55555&&5555555\n7-0");
}
+void tst_QJSEngine::scriptScopes()
+{
+ QJSEngine engine;
+
+ QJSValue def = engine.evaluate("'use strict'; function foo() { return 42 }");
+ QVERIFY(!def.isError());
+ QJSValue globalObject = engine.globalObject();
+ QJSValue foo = globalObject.property("foo");
+ QVERIFY(foo.isObject());
+ QVERIFY(foo.isCallable());
+
+ QJSValue use = engine.evaluate("'use strict'; foo()");
+ QVERIFY(use.isNumber());
+ QCOMPARE(use.toInt(), 42);
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
diff --git a/tests/auto/qml/qjsonbinding/qjsonbinding.pro b/tests/auto/qml/qjsonbinding/qjsonbinding.pro
index 75b48aa854..f7a185d27a 100644
--- a/tests/auto/qml/qjsonbinding/qjsonbinding.pro
+++ b/tests/auto/qml/qjsonbinding/qjsonbinding.pro
@@ -3,7 +3,6 @@ TARGET = tst_qjsonbinding
macx:CONFIG -= app_bundle
SOURCES += tst_qjsonbinding.cpp
-INCLUDEPATH += ../../shared
include (../../shared/util.pri)
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index 12c33909cf..db99c44261 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -970,10 +970,6 @@ void tst_QJSValue::toUInt()
QCOMPARE(qjsvalue_cast<quint32>(inv), quint32(0));
}
-#if defined Q_CC_MSVC && _MSC_VER < 1300
-Q_DECLARE_METATYPE(QVariant)
-#endif
-
void tst_QJSValue::toVariant()
{
QJSEngine eng;
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index 42a5400dc1..9557393a2e 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
+QT_FOR_CONFIG += qml
METATYPETESTS += \
qqmlmetatype
@@ -10,7 +11,6 @@ PUBLICTESTS += \
qqmlfile \
qqmlfileselector
-!boot2qt {
PUBLICTESTS += \
qmlmin \
qqmlcomponent \
@@ -32,15 +32,12 @@ PUBLICTESTS += \
qqmlsettings \
qqmlstatemachine \
qmldiskcache
-}
PRIVATETESTS += \
qqmlcpputils \
qqmldirparser \
- v4misc \
qmlcachegen
-!boot2qt {
PRIVATETESTS += \
animation \
qqmlecmascript \
@@ -73,20 +70,23 @@ PRIVATETESTS += \
qqmlimport \
qqmlobjectmodel \
qv4mm \
- ecmascripttests
-}
+ ecmascripttests \
+ bindingdependencyapi
qtHaveModule(widgets) {
PUBLICTESTS += \
qjsengine \
- qjsvalue
+ qjsvalue \
+# qwidgetsinqml
}
SUBDIRS += $$PUBLICTESTS
SUBDIRS += $$METATYPETESTS
-qtConfig(process):!boot2qt {
- !contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger
- SUBDIRS += qmllint qmlplugindump
+qtConfig(process) {
+ qtConfig(qml-debug): SUBDIRS += debugger
+ !boot2qt {
+ SUBDIRS += qmllint qmlplugindump
+ }
}
qtConfig(library) {
diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
index 8d8b37be15..a8b72224ba 100644
--- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro
+++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
@@ -1,7 +1,11 @@
-CONFIG += testcase
+CONFIG += testcase qtquickcompiler
TARGET = tst_qmlcachegen
macos:CONFIG -= app_bundle
SOURCES += tst_qmlcachegen.cpp
+workerscripts_test.files = worker.js worker.qml
+workerscripts_test.prefix = /workerscripts
+RESOURCES += workerscripts_test
+
QT += core-private qml-private testlib
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index 98a3a9d6ef..2f5ff0022e 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -44,7 +44,11 @@ private slots:
void loadGeneratedFile();
void translationExpressionSupport();
+ void signalHandlerParameters();
void errorOnArgumentsInSignalHandler();
+ void aheadOfTimeCompilation();
+
+ void workerScripts();
};
// A wrapper around QQmlComponent to ensure the temporary reference counts
@@ -75,7 +79,7 @@ static bool generateCache(const QString &qmlFileName, QByteArray *capturedStderr
if (capturedStderr == nullptr)
proc.setProcessChannelMode(QProcess::ForwardedChannels);
proc.setProgram(QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator() + QLatin1String("qmlcachegen"));
- proc.setArguments(QStringList() << (QLatin1String("--target-architecture=") + QSysInfo::buildCpuArchitecture()) << (QLatin1String("--target-abi=") + QSysInfo::buildAbi()) << qmlFileName);
+ proc.setArguments(QStringList() << qmlFileName);
proc.start();
if (!proc.waitForFinished())
return false;
@@ -182,6 +186,41 @@ void tst_qmlcachegen::translationExpressionSupport()
QCOMPARE(obj->property("text").toString(), QString("All Ok"));
}
+void tst_qmlcachegen::signalHandlerParameters()
+{
+ QTemporaryDir tempDir;
+ QVERIFY(tempDir.isValid());
+
+ const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) {
+ QFile f(tempDir.path() + '/' + fileName);
+ const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ Q_ASSERT(ok);
+ f.write(contents);
+ return f.fileName();
+ };
+
+ const QString testFilePath = writeTempFile("test.qml", "import QtQml 2.0\n"
+ "QtObject {\n"
+ " property real result: 0\n"
+ " signal testMe(real value);\n"
+ " onTestMe: result = value;\n"
+ " function runTest() { testMe(42); }\n"
+ "}");
+
+ QVERIFY(generateCache(testFilePath));
+
+ const QString cacheFilePath = testFilePath + QLatin1Char('c');
+ QVERIFY(QFile::exists(cacheFilePath));
+ QVERIFY(QFile::remove(testFilePath));
+
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QMetaObject::invokeMethod(obj.data(), "runTest");
+ QCOMPARE(obj->property("result").toInt(), 42);
+}
+
void tst_qmlcachegen::errorOnArgumentsInSignalHandler()
{
QTemporaryDir tempDir;
@@ -207,6 +246,52 @@ void tst_qmlcachegen::errorOnArgumentsInSignalHandler()
QVERIFY2(errorOutput.contains("error: The use of the arguments object in signal handlers is"), errorOutput);
}
+void tst_qmlcachegen::aheadOfTimeCompilation()
+{
+ QTemporaryDir tempDir;
+ QVERIFY(tempDir.isValid());
+
+ const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) {
+ QFile f(tempDir.path() + '/' + fileName);
+ const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ Q_ASSERT(ok);
+ f.write(contents);
+ return f.fileName();
+ };
+
+ const QString testFilePath = writeTempFile("test.qml", "import QtQml 2.0\n"
+ "QtObject {\n"
+ " function runTest() { var x = 0; while (x < 42) { ++x }; return x; }\n"
+ "}");
+
+ QVERIFY(generateCache(testFilePath));
+
+ const QString cacheFilePath = testFilePath + QLatin1Char('c');
+ QVERIFY(QFile::exists(cacheFilePath));
+ QVERIFY(QFile::remove(testFilePath));
+
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QVariant result;
+ QMetaObject::invokeMethod(obj.data(), "runTest", Q_RETURN_ARG(QVariant, result));
+ QCOMPARE(result.toInt(), 42);
+}
+
+void tst_qmlcachegen::workerScripts()
+{
+ QVERIFY(QFile::exists(":/workerscripts/worker.js"));
+ QVERIFY(QFile::exists(":/workerscripts/worker.qml"));
+ QCOMPARE(QFileInfo(":/workerscripts/worker.js").size(), 0);
+
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, QUrl("qrc:///workerscripts/worker.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QTRY_VERIFY(obj->property("success").toBool());
+}
+
QTEST_GUILESS_MAIN(tst_qmlcachegen)
#include "tst_qmlcachegen.moc"
diff --git a/tests/auto/qml/qmlcachegen/worker.js b/tests/auto/qml/qmlcachegen/worker.js
new file mode 100644
index 0000000000..dd2d0b843d
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/worker.js
@@ -0,0 +1,3 @@
+WorkerScript.onMessage = function(message) {
+ WorkerScript.sendMessage({ reply: message });
+}
diff --git a/tests/auto/qml/qmlcachegen/worker.qml b/tests/auto/qml/qmlcachegen/worker.qml
new file mode 100644
index 0000000000..1f1c9d1ac7
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/worker.qml
@@ -0,0 +1,12 @@
+import QtQml 2.0
+import QtQuick 2.0
+QtObject {
+ property bool success: false
+ property WorkerScript worker: WorkerScript {
+ source: "worker.js"
+ onMessage: {
+ success = true
+ }
+ }
+ Component.onCompleted: worker.sendMessage("Hello")
+}
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index e75e51ed29..f5905758f3 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -30,10 +30,9 @@
#include <private/qv4compileddata_p.h>
#include <private/qv4compiler_p.h>
-#include <private/qv4jsir_p.h>
-#include <private/qv4isel_p.h>
#include <private/qv8engine_p.h>
#include <private/qv4engine_p.h>
+#include <private/qv4codegen_p.h>
#include <QQmlComponent>
#include <QQmlEngine>
#include <QQmlFileSelector>
@@ -174,9 +173,8 @@ struct TestCompiler
bool verify()
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
- return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), v4->iselFactory.data(), &lastErrorString);
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Compiler::Codegen::createUnitForLoading();
+ return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), &lastErrorString);
}
void closeMapping()
@@ -231,12 +229,14 @@ void tst_qmldiskcache::regenerateAfterChange()
const QV4::CompiledData::Object *obj = testUnit->objectAt(0);
QCOMPARE(quint32(obj->nBindings), quint32(1));
QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Script));
- QCOMPARE(quint32(obj->bindingTable()->value.compiledScriptIndex), quint32(1));
+ QCOMPARE(quint32(obj->bindingTable()->value.compiledScriptIndex), quint32(0));
- QCOMPARE(quint32(testUnit->functionTableSize), quint32(2));
+ QCOMPARE(quint32(testUnit->functionTableSize), quint32(1));
- const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(1);
- QVERIFY(bindingFunction->codeOffset > testUnit->unitSize);
+ const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(0);
+ QCOMPARE(testUnit->stringAt(bindingFunction->nameIndex), QString("expression for blah")); // check if we have the correct function
+ QVERIFY(bindingFunction->codeSize > 0);
+ QVERIFY(bindingFunction->codeOffset < testUnit->unitSize);
}
{
@@ -257,10 +257,12 @@ void tst_qmldiskcache::regenerateAfterChange()
QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Number));
QCOMPARE(obj->bindingTable()->valueAsNumber(), double(42));
- QCOMPARE(quint32(testUnit->functionTableSize), quint32(2));
+ QCOMPARE(quint32(testUnit->functionTableSize), quint32(1));
- const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(1);
- QVERIFY(bindingFunction->codeOffset > testUnit->unitSize);
+ const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(0);
+ QCOMPARE(testUnit->stringAt(bindingFunction->nameIndex), QString("expression for blah")); // check if we have the correct function
+ QVERIFY(bindingFunction->codeSize > 0);
+ QVERIFY(bindingFunction->codeOffset < testUnit->unitSize);
}
}
@@ -342,30 +344,6 @@ void tst_qmldiskcache::basicVersionChecks()
QVERIFY(!testCompiler.verify());
QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("V4 data structure version mismatch. Found 0 expected %1").arg(QV4_DATA_STRUCTURE_VERSION, 0, 16));
}
-
- {
- testCompiler.clearCache();
- QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
-
- testCompiler.tweakHeader([](QV4::CompiledData::Unit *header) {
- header->architectureIndex = 0;
- });
-
- QVERIFY(!testCompiler.verify());
- QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("Architecture mismatch. Found expected %1").arg(QSysInfo::buildAbi()));
- }
-
- {
- testCompiler.clearCache();
- QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
-
- testCompiler.tweakHeader([](QV4::CompiledData::Unit *header) {
- header->codeGeneratorIndex = 0;
- });
-
- QVERIFY(!testCompiler.verify());
- QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("Code generator mismatch. Found code generated by but expected %1").arg(QV8Engine::getV4(&engine)->iselFactory->codeGeneratorName));
- }
}
class TypeVersion1 : public QObject
diff --git a/tests/auto/qml/qmlmin/qmlmin.pro b/tests/auto/qml/qmlmin/qmlmin.pro
index 6af6653270..93e5caabcf 100644
--- a/tests/auto/qml/qmlmin/qmlmin.pro
+++ b/tests/auto/qml/qmlmin/qmlmin.pro
@@ -6,5 +6,7 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qmlmin.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-
-cross_compile: DEFINES += QTEST_CROSS_COMPILED
+# Boot2qt is cross compiled but it has sources available
+!boot2qt {
+ cross_compile: DEFINES += QTEST_CROSS_COMPILED
+}
diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
index 171c2bda8a..5941385c80 100644
--- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp
+++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
@@ -98,6 +98,8 @@ void tst_qmlmin::initTestCase()
invalidFiles << "tests/auto/qml/qqmllanguage/data/insertedSemicolon.1.qml";
invalidFiles << "tests/auto/qml/qqmllanguage/data/nonexistantProperty.5.qml";
invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidRoot.1.qml";
+ invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml";
+ invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml";
invalidFiles << "tests/auto/qml/qquickfolderlistmodel/data/dummy.qml";
invalidFiles << "tests/auto/qml/qqmlecmascript/data/qtbug_22843.js";
invalidFiles << "tests/auto/qml/qqmlecmascript/data/qtbug_22843.library.js";
diff --git a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml b/tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/Singleton.qml
index b47d2e98f4..b47d2e98f4 100644
--- a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml
+++ b/tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/Singleton.qml
diff --git a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir b/tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/qmldir
index 8df57f6d47..8df57f6d47 100644
--- a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir
+++ b/tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/qmldir
diff --git a/tests/auto/qml/qmlplugindump/qmlplugindump.pro b/tests/auto/qml/qmlplugindump/qmlplugindump.pro
index 9327beffa6..ab915c819c 100644
--- a/tests/auto/qml/qmlplugindump/qmlplugindump.pro
+++ b/tests/auto/qml/qmlplugindump/qmlplugindump.pro
@@ -1,7 +1,7 @@
-CONFIG += testcase
-TARGET = tst_qmlplugindump
-QT += testlib gui-private
+QT += testlib gui-private qml
macx:CONFIG -= app_bundle
+include(../../shared/util.pri)
+
DEFINES += QT_QMLTEST_DIR=\\\"$${_PRO_FILE_PWD_}\\\"
SOURCES += tst_qmlplugindump.cpp
diff --git a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
index 235cf6fac9..ffddc52f9c 100644
--- a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
+++ b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
@@ -26,6 +26,8 @@
**
****************************************************************************/
+#include "util.h"
+
#include <qtest.h>
#include <QLibraryInfo>
#include <QDir>
@@ -33,7 +35,7 @@
#include <QDebug>
#include <cstdlib>
-class tst_qmlplugindump : public QObject
+class tst_qmlplugindump : public QQmlDataTest
{
Q_OBJECT
public:
@@ -54,6 +56,7 @@ tst_qmlplugindump::tst_qmlplugindump()
void tst_qmlplugindump::initTestCase()
{
+ QQmlDataTest::initTestCase();
qmlplugindumpPath = QLibraryInfo::location(QLibraryInfo::BinariesPath);
#if defined(Q_OS_WIN)
@@ -105,12 +108,12 @@ void tst_qmlplugindump::singleton()
args << QLatin1String("tests.dumper.CompositeSingleton") << QLatin1String("1.0")
<< QLatin1String(QT_QMLTEST_DIR);
dumper.start(qmlplugindumpPath, args);
- dumper.waitForFinished();
+ QVERIFY2(dumper.waitForStarted(), qPrintable(dumper.errorString()));
+ QVERIFY2(dumper.waitForFinished(), qPrintable(dumper.errorString()));
const QString &result = dumper.readAllStandardOutput();
- qDebug() << "result: " << result;
- QVERIFY(result.contains(QLatin1String("exports: [\"Singleton 1.0\"]")));
- QVERIFY(result.contains(QLatin1String("exportMetaObjectRevisions: [0]")));
+ QVERIFY2(result.contains(QLatin1String("exports: [\"Singleton 1.0\"]")), qPrintable(result));
+ QVERIFY2(result.contains(QLatin1String("exportMetaObjectRevisions: [0]")), qPrintable(result));
}
QTEST_MAIN(tst_qmlplugindump)
diff --git a/tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro b/tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro
index 4a2dde7c47..3adad3759b 100644
--- a/tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro
+++ b/tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro
@@ -1,3 +1,5 @@
TEMPLATE = subdirs
-SUBDIRS = tst_qqmlapplicationengine.pro \
- testapp
+SUBDIRS = testapp \
+ tst_qqmlapplicationengine.pro
+
+CONFIG += ordered
diff --git a/tests/auto/qml/qqmlbinding/data/bindingOverwriting.qml b/tests/auto/qml/qqmlbinding/data/bindingOverwriting.qml
new file mode 100644
index 0000000000..767ca0c719
--- /dev/null
+++ b/tests/auto/qml/qqmlbinding/data/bindingOverwriting.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.9
+
+Text {
+ visible: text && enabled
+ enabled: font.pixelSize === 25
+ font: enabled ? Qt.font({ "pixelSize": 25 }) : Qt.font({ "pixelSize": 50 })
+
+ Component.onCompleted: {
+ enabled = Qt.binding(function() { return visible; }); // replacement binding, not breaking
+ visible = true; // breaks visible binding
+ font.bold = true; // breaks font binding
+ }
+}
diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
index 6f1d82eca5..4b485d2ce8 100644
--- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
+++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
@@ -50,6 +50,7 @@ private slots:
void disabledOnUnknownProperty();
void disabledOnReadonlyProperty();
void delayed();
+ void bindingOverwriting();
private:
QQmlEngine engine;
@@ -303,6 +304,21 @@ void tst_qqmlbinding::delayed()
delete item;
}
+void tst_qqmlbinding::bindingOverwriting()
+{
+ QQmlTestMessageHandler messageHandler;
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.qml.binding.removal.info=true"));
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("bindingOverwriting.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QVERIFY(item);
+ delete item;
+
+ QLoggingCategory::setFilterRules(QString());
+ QCOMPARE(messageHandler.messages().count(), 2);
+}
+
QTEST_MAIN(tst_qqmlbinding)
#include "tst_qqmlbinding.moc"
diff --git a/tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp b/tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp
index da7956a5fb..f12c3432c2 100644
--- a/tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp
+++ b/tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp
@@ -26,6 +26,7 @@
**
****************************************************************************/
#include <qtest.h>
+#include <qrandom.h>
#include <private/qqmlchangeset_p.h>
class tst_qqmlchangeset : public QObject
@@ -1462,23 +1463,19 @@ void tst_qqmlchangeset::debug()
void tst_qqmlchangeset::random_data()
{
- QTest::addColumn<int>("seed");
QTest::addColumn<int>("combinations");
QTest::addColumn<int>("depth");
- QTest::newRow("1*5") << 32 << 1 << 5;
- QTest::newRow("2*2") << 32 << 2 << 2;
- QTest::newRow("3*2") << 32 << 3 << 2;
- QTest::newRow("3*5") << 32 << 3 << 5;
+ QTest::newRow("1*5") << 1 << 5;
+ QTest::newRow("2*2") << 2 << 2;
+ QTest::newRow("3*2") << 3 << 2;
+ QTest::newRow("3*5") << 3 << 5;
}
void tst_qqmlchangeset::random()
{
- QFETCH(int, seed);
QFETCH(int, combinations);
QFETCH(int, depth);
- qsrand(seed);
-
int failures = 0;
for (int i = 0; i < 20000; ++i) {
QQmlChangeSet accumulatedSet;
@@ -1490,27 +1487,27 @@ void tst_qqmlchangeset::random()
for (int j = 0; j < combinations; ++j) {
QQmlChangeSet set;
for (int k = 0; k < depth; ++k) {
- switch (-(qrand() % 3)) {
+ switch (-QRandomGenerator::global()->bounded(3)) {
case InsertOp: {
- int index = qrand() % (modelCount + 1);
- int count = qrand() % 5 + 1;
+ int index = QRandomGenerator::global()->bounded(modelCount + 1);
+ int count = QRandomGenerator::global()->bounded(5) + 1;
set.insert(index, count);
input.append(Insert(index, count));
modelCount += count;
break;
}
case RemoveOp: {
- const int index = qrand() % (modelCount + 1);
- const int count = qrand() % (modelCount - index + 1);
+ const int index = QRandomGenerator::global()->bounded(modelCount + 1);
+ const int count = QRandomGenerator::global()->bounded(modelCount - index + 1);
set.remove(index, count);
input.append(Remove(index, count));
modelCount -= count;
break;
}
case MoveOp: {
- const int from = qrand() % (modelCount + 1);
- const int count = qrand() % (modelCount - from + 1);
- const int to = qrand() % (modelCount - count + 1);
+ const int from = QRandomGenerator::global()->bounded(modelCount + 1);
+ const int count = QRandomGenerator::global()->bounded(modelCount - from + 1);
+ const int to = QRandomGenerator::global()->bounded(modelCount - count + 1);
const int moveId = moveCount++;
set.move(from, to, count, moveId);
input.append(Move(from, to, count, moveId));
diff --git a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
index 0d501ebefd..54012e050c 100644
--- a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
+++ b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
TARGET = tst_qqmlcomponent
macx:CONFIG -= app_bundle
-INCLUDEPATH += ../../shared/
SOURCES += tst_qqmlcomponent.cpp \
../../shared/testhttpserver.cpp
diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
index 3c78f6601e..105469fbcf 100644
--- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
+++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
@@ -544,7 +544,7 @@ public:
QJSEngine *jsEngine = qjsEngine(this);
if (!jsEngine)
return;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(jsEngine);
+ QV4::ExecutionEngine *v4 = jsEngine->handle();
if (!v4)
return;
QV4::Scope scope(v4);
diff --git a/tests/auto/qml/qqmlconnections/data/connection-no-signal-name.qml b/tests/auto/qml/qqmlconnections/data/connection-no-signal-name.qml
new file mode 100644
index 0000000000..462a9577ff
--- /dev/null
+++ b/tests/auto/qml/qqmlconnections/data/connection-no-signal-name.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.4
+
+Item {
+ id: blaBlaBla
+ function hint() {
+ }
+
+ Connections {
+ //target: blaBlaBla
+ //onHint: hint();
+ on: true
+ }
+}
+
+
diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
index fe45495f74..22e9724c61 100644
--- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
+++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
@@ -54,6 +54,7 @@ private slots:
void enableDisable_QTBUG_36350();
void disabledAtStart();
void clearImplicitTarget();
+ void onWithoutASignal();
private:
QQmlEngine engine;
@@ -397,6 +398,15 @@ void tst_qqmlconnections::clearImplicitTarget()
delete item;
}
+void tst_qqmlconnections::onWithoutASignal()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("connection-no-signal-name.qml"));
+ QVERIFY(c.isError()); // Cannot assign to non-existent property "on" expected
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(c.create()));
+ QVERIFY(item == nullptr); // should parse error, and not give us an item (or crash).
+}
+
QTEST_MAIN(tst_qqmlconnections)
#include "tst_qqmlconnections.moc"
diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
index 574e6e2834..783b5cb786 100644
--- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
+++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
@@ -49,6 +49,7 @@ private slots:
void engineMethod();
void parentContext();
void setContextProperty();
+ void setContextProperties();
void setContextObject();
void destruction();
void idAsContextProperty();
@@ -366,6 +367,32 @@ void tst_qqmlcontext::setContextProperty()
}
}
+void tst_qqmlcontext::setContextProperties()
+{
+ QQmlContext ctxt(&engine);
+
+ TestObject obj1;
+ obj1.setA(3345);
+ TestObject obj2;
+ obj2.setA(-19);
+
+ QVector<QQmlContext::PropertyPair> properties;
+
+ properties.append({QString("a"), QVariant(10)});
+ properties.append({QString("b"), QVariant(19)});
+ properties.append({QString("d"), QVariant::fromValue<TestObject*>(&obj2)});
+ properties.append({QString("c"), QVariant(QString("Hello World!"))});
+ properties.append({QString("e"), QVariant::fromValue<TestObject*>(&obj1)});
+
+ ctxt.setContextProperties(properties);
+
+ TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(10));
+ TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(19));
+ TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(QString("Hello World!")));
+ TEST_CONTEXT_PROPERTY(&ctxt, d.a, QVariant(-19));
+ TEST_CONTEXT_PROPERTY(&ctxt, e.a, QVariant(3345));
+}
+
void tst_qqmlcontext::setContextObject()
{
QQmlContext ctxt(&engine);
@@ -777,7 +804,7 @@ void tst_qqmlcontext::contextLeak()
QV4::Scope scope(ddata->jsWrapper.engine());
QV4::ScopedValue scriptContextWrapper(scope);
scriptContextWrapper = context->importedScripts.valueRef()->as<QV4::Object>()->getIndexed(0);
- scriptContext = scriptContextWrapper->as<QV4::QmlContextWrapper>()->getContext();
+ scriptContext = scriptContextWrapper->as<QV4::QQmlContextWrapper>()->getContext();
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.1.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.1.qml
index efca6cdb80..8912d2a314 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.1.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.1.qml
@@ -11,25 +11,26 @@ MyTypeObject {
dateTimeProperty = dateTimeVar
dateTimeProperty2 = dateTimeVar2
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 12) &&
+ (dateTimeProperty.getUTCHours() == 0) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 23) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.2.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.2.qml
index 71dd188f05..f8c1f6eb8f 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.2.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.2.qml
@@ -12,24 +12,25 @@ MyTypeObject {
var dateTimeVar = new Date("2009-05-12T00:00:01")
var dateTimeVar2 = new Date("2009-05-12T23:59:59")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
+ (dateTimeProperty.getDate() == 12) &&
+ (dateTimeProperty.getHours() == 0) &&
(dateTimeProperty.getMinutes() == 0) &&
(dateTimeProperty.getSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
+ (dateTimeProperty2.getDate() == 12) &&
+ (dateTimeProperty2.getHours() == 23) &&
(dateTimeProperty2.getMinutes() == 59) &&
(dateTimeProperty2.getSeconds() == 59)
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.3.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.3.qml
index 2cf740645c..e960eef193 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.3.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.3.qml
@@ -2,35 +2,36 @@ import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
- dateProperty: if (1) "2009-05-12Z"
+ dateProperty: if (1) "2009-05-12"
dateTimeProperty: if (1) "2009-05-12T00:00:01Z"
dateTimeProperty2: if (1) "2009-05-12T23:59:59Z"
boolProperty: false
Component.onCompleted: {
- var dateVar = new Date("2009-05-12Z")
+ var dateVar = new Date("2009-05-12")
var dateTimeVar = new Date("2009-05-12T00:00:01Z")
var dateTimeVar2 = new Date("2009-05-12T23:59:59Z")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 12) &&
+ (dateTimeProperty.getUTCHours() == 0) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 23) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.4.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.4.qml
index 9b4975c833..6dd29afbc9 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.4.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.4.qml
@@ -2,35 +2,36 @@ import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
- dateProperty: if (1) new Date("2009-05-12Z")
+ dateProperty: if (1) new Date("2009-05-12")
dateTimeProperty: if (1) new Date("2009-05-12T00:00:01Z")
dateTimeProperty2: if (1) new Date("2009-05-12T23:59:59Z")
boolProperty: false
Component.onCompleted: {
- var dateVar = new Date("2009-05-12Z")
+ var dateVar = new Date("2009-05-12")
var dateTimeVar = new Date("2009-05-12T00:00:01Z")
var dateTimeVar2 = new Date("2009-05-12T23:59:59Z")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 12) &&
+ (dateTimeProperty.getUTCHours() == 0) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 23) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.5.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.5.qml
index 2cf740645c..cfadaafc54 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.5.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.5.qml
@@ -2,35 +2,36 @@ import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
- dateProperty: if (1) "2009-05-12Z"
- dateTimeProperty: if (1) "2009-05-12T00:00:01Z"
- dateTimeProperty2: if (1) "2009-05-12T23:59:59Z"
+ dateProperty: if (1) "2009-05-12"
+ dateTimeProperty: if (1) "2009-05-12T00:00:01+02:00"
+ dateTimeProperty2: if (1) "2009-05-12T23:59:59+02:00"
boolProperty: false
Component.onCompleted: {
- var dateVar = new Date("2009-05-12Z")
- var dateTimeVar = new Date("2009-05-12T00:00:01Z")
- var dateTimeVar2 = new Date("2009-05-12T23:59:59Z")
+ var dateVar = new Date("2009-05-12")
+ var dateTimeVar = new Date("2009-05-12T00:00:01+02:00")
+ var dateTimeVar2 = new Date("2009-05-12T23:59:59+02:00")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 11) &&
+ (dateTimeProperty.getUTCHours() == 22) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 21) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.6.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.6.qml
index 73e26db0c8..97cd0d1e60 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.6.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.6.qml
@@ -3,34 +3,35 @@ import QtQuick 2.0
MyTypeObject {
dateProperty: if (1) new Date("2009-05-12")
- dateTimeProperty: if (1) new Date("2009-05-12T02:00:01+02:00")
- dateTimeProperty2: if (1) new Date("2009-05-13T01:59:59+02:00")
+ dateTimeProperty: if (1) new Date("2009-05-12T00:00:01+02:00")
+ dateTimeProperty2: if (1) new Date("2009-05-12T23:59:59+02:00")
boolProperty: false
Component.onCompleted: {
var dateVar = new Date("2009-05-12")
- var dateTimeVar = new Date("2009-05-12T02:00:01+02:00")
- var dateTimeVar2 = new Date("2009-05-13T01:59:59+02:00")
+ var dateTimeVar = new Date("2009-05-12T00:00:01+02:00")
+ var dateTimeVar2 = new Date("2009-05-12T23:59:59+02:00")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 11) &&
+ (dateTimeProperty.getUTCHours() == 22) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 21) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.qml
index 14fe20787b..73677e99f1 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.qml
@@ -7,28 +7,31 @@ MyTypeObject {
var dateTimeVar = new Date("2009-05-12T00:00:01")
var dateTimeVar2 = new Date("2009-05-12T23:59:59")
+ // Date, with no zone specified, is implicitly UTC
dateProperty = dateVar
+ // Date-time, with no zone, is implicitly local-time
dateTimeProperty = dateTimeVar
dateTimeProperty2 = dateTimeVar2
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
+ (dateTimeProperty.getDate() == 12) &&
+ (dateTimeProperty.getHours() == 0) &&
(dateTimeProperty.getMinutes() == 0) &&
(dateTimeProperty.getSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
+ (dateTimeProperty2.getDate() == 12) &&
+ (dateTimeProperty2.getHours() == 23) &&
(dateTimeProperty2.getMinutes() == 59) &&
(dateTimeProperty2.getSeconds() == 59)
}
diff --git a/tests/auto/qml/qqmlecmascript/data/dynamicString.qml b/tests/auto/qml/qqmlecmascript/data/dynamicString.qml
index 5693794c71..c704161eb5 100644
--- a/tests/auto/qml/qqmlecmascript/data/dynamicString.qml
+++ b/tests/auto/qml/qqmlecmascript/data/dynamicString.qml
@@ -11,6 +11,6 @@ MyTypeObject {
date.setHours(5);
date.setMinutes(30);
date.setSeconds(50);
- stringProperty = stringProperty.arg("Hello World").arg(false).arg(true).arg(100).arg(-100).arg(3.1415926).arg(Qt.formatDateTime(date, "yyyy-MM-dd hh::mm:ss"));
+ stringProperty = stringProperty.arg("Hello World").arg(false).arg(true).arg(100).arg(-100).arg(Math.PI).arg(Qt.formatDateTime(date, "yyyy-MM-dd hh::mm:ss"));
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/nonNotifyableConstant.qml b/tests/auto/qml/qqmlecmascript/data/nonNotifyableConstant.qml
new file mode 100644
index 0000000000..424b3e8b07
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/nonNotifyableConstant.qml
@@ -0,0 +1,5 @@
+import Qt.test 1.0
+
+MyQmlObject {
+ objectName: trueProperty ? "foo" : "bar"
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml b/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml
index 74c7cda9a3..c6732efc05 100644
--- a/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml
+++ b/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml
@@ -52,7 +52,11 @@ Item {
function doStringTest(stringList, fn) {
var expected = createExpected(stringList, fn);
var actual = msc.strings(stringList);
- return checkResults(expected, actual, fn);
+ var actual2 = msc.stringsVector(stringList);
+ var actual3 = msc.stringsStdVector(stringList);
+ return checkResults(expected, actual, fn)
+ && checkResults(expected, actual2, fn)
+ && checkResults(expected, actual3, fn)
}
function doIntTest(intList, fn) {
var expected = createExpected(intList, fn);
@@ -67,12 +71,16 @@ Item {
function doIntVectorTest(intList, fn) {
var expected = createExpected(intList, fn);
var actual = msc.integerVector(intList);
- return checkResults(expected, actual, fn);
+ var actual2 = msc.integerStdVector(intList);
+ return checkResults(expected, actual, fn)
+ && checkResults(expected, actual2, fn)
}
function doRealVectorTest(realList, fn) {
var expected = createExpected(realList, fn);
var actual = msc.realVector(realList);
- return checkResults(expected, actual, fn);
+ var actual2 = msc.realStdVector(realList);
+ return checkResults(expected, actual, fn)
+ && checkResults(expected, actual2, fn)
}
function test_qtbug_25269(useCustomCompare) {
diff --git a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
index 101181bba0..0dd9365366 100644
--- a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
+++ b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
@@ -7,7 +7,6 @@ SOURCES += tst_qqmlecmascript.cpp \
../../shared/testhttpserver.cpp
HEADERS += testtypes.h \
../../shared/testhttpserver.h
-INCLUDEPATH += ../../shared
RESOURCES += qqmlecmascript.qrc
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index 13bb0435cd..80da5d7e52 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -290,6 +290,15 @@ public:
{
return stringList;
}
+ Q_INVOKABLE QVector<QString> stringsVector(const QStringList& stringList) const
+ {
+ return stringList.toVector();
+ }
+ Q_INVOKABLE
+ std::vector<QString> stringsStdVector(const QStringList& stringList) const
+ {
+ return std::vector<QString>(stringList.begin(), stringList.end());
+ }
Q_INVOKABLE QList<int> integers(QList<int> v) const
{
return v;
@@ -306,14 +315,29 @@ public:
{
return v;
}
+ Q_INVOKABLE
+ std::vector<int> integerStdVector(std::vector<int> v) const
+ {
+ return v;
+ }
Q_INVOKABLE QVector<qreal> realVector(QVector<qreal> v) const
{
return v;
}
+ Q_INVOKABLE
+ std::vector<qreal> realStdVector(std::vector<qreal> v) const
+ {
+ return v;
+ }
Q_INVOKABLE QVector<bool> boolVector(QVector<bool> v) const
{
return v;
}
+ Q_INVOKABLE
+ std::vector<bool> boolStdVector(std::vector<bool> v) const
+ {
+ return v;
+ }
};
static MyInheritedQmlObject *theSingletonObject = 0;
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index ec20714c51..8d89df31db 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -1262,7 +1262,6 @@ public:
{
CircularReferenceObject *retn = new CircularReferenceObject(parent);
retn->m_dtorCount = m_dtorCount;
- retn->m_engine = m_engine;
return retn;
}
@@ -1283,14 +1282,8 @@ public:
thisObject->defineDefaultProperty(QStringLiteral("autoTestStrongRef"), v);
}
- void setEngine(QQmlEngine* declarativeEngine)
- {
- m_engine = QQmlEnginePrivate::get(declarativeEngine)->v8engine();
- }
-
private:
int *m_dtorCount;
- QV8Engine* m_engine;
};
Q_DECLARE_METATYPE(CircularReferenceObject*)
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 14447383c1..5e752d124b 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2017 Crimson AS <info@crimson.no>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
@@ -42,6 +43,7 @@
#include "../../shared/util.h"
#include <private/qv4functionobject_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4alloca_p.h>
#include <private/qv4runtime_p.h>
#include <private/qv4object_p.h>
@@ -259,6 +261,7 @@ private slots:
void doubleEvaluate();
void forInLoop();
void nonNotifyable();
+ void nonNotifyableConstant();
void deleteWhileBindingRunning();
void callQtInvokables();
void resolveClashingProperties();
@@ -335,9 +338,17 @@ private slots:
void stringify_qtbug_50592();
void instanceof_data();
void instanceof();
+ void constkw_data();
+ void constkw();
+ void redefineGlobalProp();
void freeze_empty_object();
void singleBlockLoops();
void qtbug_60547();
+ void delayLoadingArgs();
+ void manyArguments();
+ void forInIterator();
+ void localForInIterator();
+ void shadowedFunctionName();
void anotherNaN();
private:
@@ -440,29 +451,37 @@ void tst_qqmlecmascript::assignBasicTypes()
void tst_qqmlecmascript::assignDate_data()
{
QTest::addColumn<QUrl>("source");
+ QTest::addColumn<int>("timeOffset"); // -1 for local-time, else minutes from UTC
- QTest::newRow("Component.onComplete JS Parse") << testFileUrl("assignDate.qml");
- QTest::newRow("Component.onComplete JS") << testFileUrl("assignDate.1.qml");
- QTest::newRow("Binding JS") << testFileUrl("assignDate.2.qml");
- QTest::newRow("Binding UTC") << testFileUrl("assignDate.3.qml");
- QTest::newRow("Binding JS UTC") << testFileUrl("assignDate.4.qml");
- QTest::newRow("Binding UTC+2") << testFileUrl("assignDate.5.qml");
- QTest::newRow("Binding JS UTC+2 ") << testFileUrl("assignDate.6.qml");
+ QTest::newRow("Component.onComplete JS Parse") << testFileUrl("assignDate.qml") << -1;
+ QTest::newRow("Component.onComplete JS") << testFileUrl("assignDate.1.qml") << 0;
+ QTest::newRow("Binding JS") << testFileUrl("assignDate.2.qml") << -1;
+ QTest::newRow("Binding UTC") << testFileUrl("assignDate.3.qml") << 0;
+ QTest::newRow("Binding JS UTC") << testFileUrl("assignDate.4.qml") << 0;
+ QTest::newRow("Binding UTC+2") << testFileUrl("assignDate.5.qml") << 120;
+ QTest::newRow("Binding JS UTC+2 ") << testFileUrl("assignDate.6.qml") << 120;
}
void tst_qqmlecmascript::assignDate()
{
QFETCH(QUrl, source);
+ QFETCH(int, timeOffset);
QQmlComponent component(&engine, source);
QScopedPointer<QObject> obj(component.create());
MyTypeObject *object = qobject_cast<MyTypeObject *>(obj.data());
QVERIFY(object != 0);
- // Dates received from JS are automatically converted to local time
- QDate expectedDate(QDateTime(QDate(2009, 5, 12), QTime(0, 0, 0), Qt::UTC).toLocalTime().date());
- QDateTime expectedDateTime(QDateTime(QDate(2009, 5, 12), QTime(0, 0, 1), Qt::UTC).toLocalTime());
- QDateTime expectedDateTime2(QDateTime(QDate(2009, 5, 12), QTime(23, 59, 59), Qt::UTC).toLocalTime());
+ QDate expectedDate(2009, 5, 12);
+ QDateTime expectedDateTime;
+ QDateTime expectedDateTime2;
+ if (timeOffset == -1) {
+ expectedDateTime = QDateTime(QDate(2009, 5, 12), QTime(0, 0, 1), Qt::LocalTime);
+ expectedDateTime2 = QDateTime(QDate(2009, 5, 12), QTime(23, 59, 59), Qt::LocalTime);
+ } else {
+ expectedDateTime = QDateTime(QDate(2009, 5, 12), QTime(0, 0, 1), Qt::OffsetFromUTC, timeOffset * 60);
+ expectedDateTime2 = QDateTime(QDate(2009, 5, 12), QTime(23, 59, 59), Qt::OffsetFromUTC, timeOffset * 60);
+ }
QCOMPARE(object->dateProperty(), expectedDate);
QCOMPARE(object->dateTimeProperty(), expectedDateTime);
@@ -2329,13 +2348,13 @@ void tst_qqmlecmascript::regExpBug()
}
}
-static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const char *source)
+static inline bool evaluate_error(QV4::ExecutionEngine *v4, const QV4::Value &o, const char *source)
{
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
- QV4::Scope scope(QV8Engine::getV4(engine));
- QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
+ QV4::Scope scope(v4);
+ QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), QV4::Compiler::EvalCode, functionSource);
program.inheritContext = true;
QV4::ScopedFunctionObject function(scope, program.run());
@@ -2343,10 +2362,10 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const
scope.engine->catchException();
return true;
}
- QV4::ScopedCallData d(scope, 1);
- d->args[0] = o;
- d->thisObject = engine->global();
- function->call(scope, d);
+ QV4::JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = o;
+ *jsCallData->thisObject = v4->global();
+ function->call(jsCallData);
if (scope.engine->hasException) {
scope.engine->catchException();
return true;
@@ -2354,14 +2373,14 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const
return false;
}
-static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
+static inline bool evaluate_value(QV4::ExecutionEngine *v4, const QV4::Value &o,
const char *source, const QV4::Value &result)
{
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
- QV4::Scope scope(QV8Engine::getV4(engine));
- QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
+ QV4::Scope scope(v4);
+ QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), QV4::Compiler::EvalCode, functionSource);
program.inheritContext = true;
QV4::ScopedFunctionObject function(scope, program.run());
@@ -2372,26 +2391,27 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
if (!function)
return false;
- QV4::ScopedCallData d(scope, 1);
- d->args[0] = o;
- d->thisObject = engine->global();
- function->call(scope, d);
+ QV4::ScopedValue value(scope);
+ QV4::JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = o;
+ *jsCallData->thisObject = v4->global();
+ value = function->call(jsCallData);
if (scope.engine->hasException) {
scope.engine->catchException();
return false;
}
- return QV4::Runtime::method_strictEqual(scope.result, result);
+ return QV4::Runtime::method_strictEqual(value, result);
}
-static inline QV4::ReturnedValue evaluate(QV8Engine *engine, const QV4::Value &o,
- const char *source)
+static inline QV4::ReturnedValue evaluate(QV4::ExecutionEngine *v4, const QV4::Value &o,
+ const char *source)
{
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
- QV4::Scope scope(QV8Engine::getV4(engine));
+ QV4::Scope scope(v4);
- QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
+ QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), QV4::Compiler::EvalCode, functionSource);
program.inheritContext = true;
QV4::ScopedFunctionObject function(scope, program.run());
@@ -2401,15 +2421,15 @@ static inline QV4::ReturnedValue evaluate(QV8Engine *engine, const QV4::Value &o
}
if (!function)
return QV4::Encode::undefined();
- QV4::ScopedCallData d(scope, 1);
- d->args[0] = o;
- d->thisObject = engine->global();
- function->call(scope, d);
+ QV4::JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = o;
+ *jsCallData->thisObject = v4->global();
+ QV4::ScopedValue result(scope, function->call(jsCallData));
if (scope.engine->hasException) {
scope.engine->catchException();
return QV4::Encode::undefined();
}
- return scope.result.asReturnedValue();
+ return result->asReturnedValue();
}
#define EVALUATE_ERROR(source) evaluate_error(engine, object, source)
@@ -2423,12 +2443,11 @@ void tst_qqmlecmascript::callQtInvokables()
MyInvokableObject *o = new MyInvokableObject();
QQmlEngine qmlengine;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&qmlengine);
- QV8Engine *engine = ep->v8engine();
- QV4::Scope scope(QV8Engine::getV4(engine));
+ QV4::ExecutionEngine *engine = qmlengine.handle();
+ QV4::Scope scope(engine);
- QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o));
+ QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o));
// Non-existent methods
o->reset();
@@ -2996,9 +3015,8 @@ void tst_qqmlecmascript::resolveClashingProperties()
{
ClashingNames *o = new ClashingNames();
QQmlEngine qmlengine;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&qmlengine);
- QV4::ExecutionEngine *engine = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *engine = qmlengine.handle();
QV4::Scope scope(engine);
QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o));
@@ -4028,11 +4046,10 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) {
QQmlContextData *childCtxt = ctxt->childContexts;
if (!ctxt->importedScripts.isNullOrUndefined()) {
- QV8Engine *engine = QV8Engine::get(ctxt->engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::ExecutionEngine *v4 = ctxt->engine->handle();
QV4::Scope scope(v4);
QV4::ScopedArrayObject scripts(scope, ctxt->importedScripts.value());
- QV4::Scoped<QV4::QmlContextWrapper> qml(scope);
+ QV4::Scoped<QV4::QQmlContextWrapper> qml(scope);
for (quint32 i = 0; i < scripts->getLength(); ++i) {
QQmlContextData *scriptContext, *newContext;
qml = scripts->getIndexed(i);
@@ -4041,7 +4058,7 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) {
qml = QV4::Encode::undefined();
{
- QV4::Scope scope(QV8Engine::getV4((engine)));
+ QV4::Scope scope(v4);
QV4::ScopedContext temporaryScope(scope, QV4::QmlContext::create(scope.engine->rootContext(), scriptContext, 0));
Q_UNUSED(temporaryScope)
}
@@ -4358,8 +4375,7 @@ void tst_qqmlecmascript::scarceResources_other()
QPixmap origPixmap(100, 100);
origPixmap.fill(Qt::blue);
QString srp_name, expectedWarning;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = engine.handle();
ScarceResourceObject *eo = 0;
QObject *srsc = 0;
QObject *object = 0;
@@ -4730,8 +4746,7 @@ void tst_qqmlecmascript::scarceResources()
QFETCH(QVariantList, expectedValues);
QFETCH(QStringList, expectedErrors);
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = engine.handle();
ScarceResourceObject *eo = 0;
QObject *object = 0;
@@ -5171,9 +5186,9 @@ void tst_qqmlecmascript::propertyVarInheritance()
// XXX NOTE: this is very implementation dependent. QDVMEMO->vmeProperty() is the only
// public function which can return us a handle to something in the varProperties array.
QV4::ReturnedValue tmp = icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ"));
- icoCanaryHandle.set(QQmlEnginePrivate::getV4Engine(&engine), tmp);
+ icoCanaryHandle.set(engine.handle(), tmp);
tmp = ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ"));
- ccoCanaryHandle.set(QQmlEnginePrivate::getV4Engine(&engine), tmp);
+ ccoCanaryHandle.set(engine.handle(), tmp);
tmp = QV4::Encode::null();
QVERIFY(!icoCanaryHandle.isUndefined());
QVERIFY(!ccoCanaryHandle.isUndefined());
@@ -5211,7 +5226,7 @@ void tst_qqmlecmascript::propertyVarInheritance2()
QCOMPARE(childObject->property("textCanary").toInt(), 10);
QV4::WeakValue childObjectVarArrayValueHandle;
{
- childObjectVarArrayValueHandle.set(QQmlEnginePrivate::getV4Engine(&engine),
+ childObjectVarArrayValueHandle.set(engine.handle(),
QQmlVMEMetaObject::get(childObject)->vmeProperty(childObject->metaObject()->indexOfProperty("vp")));
QVERIFY(!childObjectVarArrayValueHandle.isUndefined());
gc(engine);
@@ -5299,7 +5314,6 @@ void tst_qqmlecmascript::handleReferenceManagement()
QObject *object = component.create();
QVERIFY(object != 0);
CircularReferenceObject *cro = object->findChild<CircularReferenceObject*>("cro");
- cro->setEngine(&hrmEngine);
cro->setDtorCount(&dtorCount);
QMetaObject::invokeMethod(object, "createReference");
gc(hrmEngine);
@@ -5319,7 +5333,6 @@ void tst_qqmlecmascript::handleReferenceManagement()
QObject *object = component.create();
QVERIFY(object != 0);
CircularReferenceObject *cro = object->findChild<CircularReferenceObject*>("cro");
- cro->setEngine(&hrmEngine);
cro->setDtorCount(&dtorCount);
QMetaObject::invokeMethod(object, "circularReference");
gc(hrmEngine);
@@ -6232,10 +6245,6 @@ void tst_qqmlecmascript::include()
void tst_qqmlecmascript::includeRemoteSuccess()
{
-#if defined(Q_CC_MSVC) && _MSC_VER == 1700
- QSKIP("This test does not work reliably with MSVC2012 on Win8 64-bit in release mode.");
-#endif
-
// Remote - success
TestHTTPServer server;
QVERIFY2(server.listen(), qPrintable(server.errorString()));
@@ -6881,6 +6890,18 @@ void tst_qqmlecmascript::nonNotifyable()
delete object;
}
+void tst_qqmlecmascript::nonNotifyableConstant()
+{
+ QQmlComponent component(&engine, testFileUrl("nonNotifyableConstant.qml"));
+ QQmlTestMessageHandler messageHandler;
+
+ // Shouldn't produce an error message about non-NOTIFYable properties,
+ // as the property has the CONSTANT attribute.
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(object);
+ QCOMPARE(messageHandler.messages().size(), 0);
+}
+
void tst_qqmlecmascript::forInLoop()
{
QQmlComponent component(&engine, testFileUrl("forInLoop.qml"));
@@ -7278,8 +7299,8 @@ class WeakReferenceMutator : public QObject
Q_OBJECT
public:
WeakReferenceMutator()
- : resultPtr(Q_NULLPTR)
- , weakRef(Q_NULLPTR)
+ : resultPtr(nullptr)
+ , weakRef(nullptr)
{}
void init(QV4::ExecutionEngine *v4, QV4::WeakValue *weakRef, bool *resultPtr)
@@ -7298,7 +7319,7 @@ private slots:
*resultPtr = weakRef->valueRef() && weakRef->isNullOrUndefined();
if (!*resultPtr)
return;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(this));
+ QV4::ExecutionEngine *v4 = qmlEngine(this)->handle();
weakRef->set(v4, v4->newObject());
*resultPtr = weakRef->valueRef() && !weakRef->isNullOrUndefined();
}
@@ -7348,7 +7369,7 @@ void tst_qqmlecmascript::onDestructionViaGC()
qmlRegisterType<WeakReferenceMutator>("Test", 1, 0, "WeakReferenceMutator");
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
+ QV4::ExecutionEngine *v4 =engine.handle();
QQmlComponent component(&engine, testFileUrl("DestructionHelper.qml"));
@@ -8174,6 +8195,8 @@ void tst_qqmlecmascript::stringify_qtbug_50592()
QCOMPARE(obj->property("source").toString(), QString::fromLatin1("http://example.org/some_nonexistant_image.png"));
}
+// Tests for the JS-only instanceof. Tests for the QML extensions for
+// instanceof belong in tst_qqmllanguage!
void tst_qqmlecmascript::instanceof_data()
{
QTest::addColumn<QString>("setupCode");
@@ -8226,7 +8249,7 @@ void tst_qqmlecmascript::instanceof()
QJSEngine engine;
QJSValue ret = engine.evaluate(setupCode + ";\n" + QTest::currentDataTag());
- if (expectedValue.type() == QMetaType::Bool) {
+ if (expectedValue.type() == QVariant::Bool) {
bool returnValue = ret.toBool();
QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
QCOMPARE(returnValue, expectedValue.toBool());
@@ -8236,6 +8259,108 @@ void tst_qqmlecmascript::instanceof()
}
}
+void tst_qqmlecmascript::constkw_data()
+{
+ QTest::addColumn<QString>("sourceCode");
+ QTest::addColumn<bool>("exceptionExpected");
+ QTest::addColumn<QVariant>("expectedValue");
+
+ QTest::newRow("simpleconst")
+ << "const v = 5\n"
+ "v\n"
+ << false
+ << QVariant(5);
+ QTest::newRow("twoconst")
+ << "const v = 5, i = 10\n"
+ "v + i\n"
+ << false
+ << QVariant(15);
+ QTest::newRow("constandvar")
+ << "const v = 5\n"
+ "var i = 20\n"
+ "v + i\n"
+ << false
+ << QVariant(25);
+ QTest::newRow("const-multiple-scopes-same-var")
+ << "const v = 3\n"
+ "function f() { const v = 1; return v; }\n"
+ "v + f()\n"
+ << false
+ << QVariant(4);
+
+ // error cases
+ QTest::newRow("const-no-initializer")
+ << "const v\n"
+ << true
+ << QVariant("SyntaxError: Missing initializer in const declaration");
+ QTest::newRow("const-no-initializer-comma")
+ << "const v = 1, i\n"
+ << true
+ << QVariant("SyntaxError: Missing initializer in const declaration");
+ QTest::newRow("const-no-duplicate")
+ << "const v = 1, v = 2\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("const-no-duplicate-2")
+ << "const v = 1\n"
+ "const v = 2\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("const-no-duplicate-var")
+ << "const v = 1\n"
+ "var v = 1\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("var-no-duplicate-const")
+ << "var v = 1\n"
+ "const v = 1\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("const-no-duplicate-let")
+ << "const v = 1\n"
+ "let v = 1\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("let-no-duplicate-const")
+ << "let v = 1\n"
+ "const v = 1\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+}
+
+void tst_qqmlecmascript::constkw()
+{
+ QFETCH(QString, sourceCode);
+ QFETCH(bool, exceptionExpected);
+ QFETCH(QVariant, expectedValue);
+
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate(sourceCode);
+
+ if (!exceptionExpected) {
+ QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
+ QCOMPARE(ret.toVariant(), expectedValue);
+ } else {
+ QVERIFY2(ret.isError(), qPrintable(ret.toString()));
+ QCOMPARE(ret.toString(), expectedValue.toString());
+ }
+}
+
+// Redefine a property found on the global object. It shouldn't throw.
+void tst_qqmlecmascript::redefineGlobalProp()
+{
+ {
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate("\"use strict\"\n var toString = 1;");
+ QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
+ }
+ {
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate("var toString = 1;");
+ QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
+ }
+}
+
void tst_qqmlecmascript::freeze_empty_object()
{
// this shouldn't crash
@@ -8281,6 +8406,69 @@ void tst_qqmlecmascript::anotherNaN()
object->setProperty("prop", d); // don't crash
}
+void tst_qqmlecmascript::delayLoadingArgs()
+{
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate("(function(x){return x + (x+=2)})(20)");
+ QCOMPARE(ret.toInt(), 42); // esp. not 44.
+}
+
+void tst_qqmlecmascript::manyArguments()
+{
+ const char *testCase =
+ "function x() { var sum; for (var i = 0; i < arguments.length; ++i) sum += arguments[i][0]; }"
+ "x([0],[1],[2],[3],[4],[5],[6],[7],[8],[9], [0],[1],[2],[3],[4],[5],[6],[7],[8],[9], [0],[1],[2],[3],[4],[5],[6],[7],[8],[9])";
+
+ QJSEngine engine;
+ engine.evaluate(testCase);
+}
+
+void tst_qqmlecmascript::forInIterator()
+{
+ auto testCase =
+ "(function(){\n"
+ "var x = 'yoyo'\n"
+ "var i\n"
+ "for (i in x) {\n"
+ "}\n"
+ "return i\n"
+ "})()";
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate(testCase);
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QStringLiteral("3"));
+}
+
+void tst_qqmlecmascript::localForInIterator()
+{
+ auto testCase =
+ "(function(){\n"
+ "var x = 'yoyo'\n"
+ "for (var i in x) {\n"
+ "}\n"
+ "return i\n"
+ "})()";
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate(testCase);
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QStringLiteral("3"));
+}
+
+void tst_qqmlecmascript::shadowedFunctionName()
+{
+ // verify that arguments shadow the function name
+ QJSEngine engine;
+ QJSValue v = engine.evaluate(QString::fromLatin1(
+ "function f(f) { return f; }\n"
+ "f(true)\n"
+ ));
+ QVERIFY(!v.isError());
+ QVERIFY(v.isBool());
+ QCOMPARE(v.toBool(), true);
+}
+
+
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml
new file mode 100644
index 0000000000..1047926750
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.8
+
+Item {
+ property alias textEdit: textEdit
+
+ TextEdit {
+ id: textEdit
+
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml
new file mode 100644
index 0000000000..552c6c3791
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+
+Item {
+ property alias textEdit: textEdit
+
+ TextEdit {
+ id: textEdit
+
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml
new file mode 100644
index 0000000000..39bd01fe40
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.8
+
+Item {
+ GroupedPropertiesRevisionComponent1 {
+ textEdit.onEditingFinished: console.log("test")
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml
new file mode 100644
index 0000000000..bb9ba79b01
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.8
+
+Item {
+ GroupedPropertiesRevisionComponent2 {
+ textEdit.onEditingFinished: console.log("test")
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/qqmlengine.pro b/tests/auto/qml/qqmlengine/qqmlengine.pro
index e7952d8e3a..8d1e149d62 100644
--- a/tests/auto/qml/qqmlengine/qqmlengine.pro
+++ b/tests/auto/qml/qqmlengine/qqmlengine.pro
@@ -7,3 +7,8 @@ include (../../shared/util.pri)
SOURCES += tst_qqmlengine.cpp
QT += core-private gui-private qml-private network testlib
+
+boot2qt: {
+ # GC corruption test is too heavy for qemu-arm
+ DEFINES += SKIP_GCCORRUPTION_TEST
+}
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index dac6ddaebd..d6d7506c48 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -75,6 +75,7 @@ private slots:
void urlInterceptor();
void qmlContextProperties();
void testGCCorruption();
+ void testGroupedPropertyRevisions();
public slots:
QObject *createAQObjectForOwnershipTest ()
@@ -741,6 +742,9 @@ public:
if (url.path().endsWith("Test.2/qmldir"))//Special case
return QUrl::fromLocalFile(m_base.path() + "interception/module/intercepted/qmldir");
+ // Special case: with 5.10 we always add the implicit import, so we need to explicitly handle this case now
+ if (url.path().endsWith("intercepted/qmldir"))
+ return url;
QString alteredPath = url.path();
int a = alteredPath.lastIndexOf('/');
@@ -859,6 +863,10 @@ void tst_qqmlengine::qmlContextProperties()
void tst_qqmlengine::testGCCorruption()
{
+#ifdef SKIP_GCCORRUPTION_TEST
+ QSKIP("Test too heavy for qemu");
+#endif
+
QQmlEngine e;
QQmlComponent c(&e, testFileUrl("testGCCorruption.qml"));
@@ -866,6 +874,17 @@ void tst_qqmlengine::testGCCorruption()
QVERIFY2(o, qPrintable(c.errorString()));
}
+void tst_qqmlengine::testGroupedPropertyRevisions()
+{
+ QQmlEngine e;
+
+ QQmlComponent c(&e, testFileUrl("testGroupedPropertiesRevision.1.qml"));
+ QScopedPointer<QObject> object(c.create());
+ QVERIFY2(object.data(), qPrintable(c.errorString()));
+ QQmlComponent c2(&e, testFileUrl("testGroupedPropertiesRevision.2.qml"));
+ QVERIFY(!c2.errorString().isEmpty());
+}
+
QTEST_MAIN(tst_qqmlengine)
#include "tst_qqmlengine.moc"
diff --git a/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp b/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
index 268010ead8..2511eebefe 100644
--- a/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
+++ b/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
@@ -105,7 +105,7 @@ void tst_qqmlextensionplugin::iidCheck()
QPluginLoader loader(filePath);
QVERIFY2(loader.load(), qPrintable(loader.errorString()));
- QVERIFY(loader.instance() != Q_NULLPTR);
+ QVERIFY(loader.instance() != nullptr);
if (qobject_cast<QQmlExtensionPlugin *>(loader.instance())) {
QString iid = loader.metaData().value(QStringLiteral("IID")).toString();
diff --git a/tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro b/tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro
index 719fd6c350..542ec44736 100644
--- a/tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro
+++ b/tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
TARGET = tst_qqmlinstantiator
macx:CONFIG -= app_bundle
-INCLUDEPATH += ../../shared/
SOURCES += tst_qqmlinstantiator.cpp
HEADERS += stringmodel.h
diff --git a/tests/auto/qml/qqmlinstantiator/stringmodel.h b/tests/auto/qml/qqmlinstantiator/stringmodel.h
index 0bd4ada55e..b01817375a 100644
--- a/tests/auto/qml/qqmlinstantiator/stringmodel.h
+++ b/tests/auto/qml/qqmlinstantiator/stringmodel.h
@@ -65,7 +65,7 @@ public:
return items.count();
}
- virtual QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE
+ QHash<int, QByteArray> roleNames() const override
{
return roles;
}
@@ -75,7 +75,7 @@ public:
return 1;
}
- virtual bool hasChildren(const QModelIndex &) const Q_DECL_OVERRIDE
+ bool hasChildren(const QModelIndex &) const override
{
return rowCount(QModelIndex()) > 0;
}
diff --git a/tests/auto/qml/qqmlitemmodels/qtestmodel.h b/tests/auto/qml/qqmlitemmodels/qtestmodel.h
index 8724ef927f..6a022b3135 100644
--- a/tests/auto/qml/qqmlitemmodels/qtestmodel.h
+++ b/tests/auto/qml/qqmlitemmodels/qtestmodel.h
@@ -91,8 +91,6 @@ public:
}
int rowCount(const QModelIndex& parent = QModelIndex()) const {
- if (!fetched)
- qFatal("%s: rowCount should not be called before fetching", Q_FUNC_INFO);
if ((parent.column() > 0) || (level(parent) > levels)
|| (alternateChildlessRows && parent.row() > 0 && (parent.row() & 1)))
return 0;
diff --git a/tests/auto/qml/qqmllanguage/data/TypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/TypeWithEnum.qml
new file mode 100644
index 0000000000..c6788f787a
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/TypeWithEnum.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2,
+ EnumValue3
+ }
+
+ enum MyOtherEnum {
+ OtherEnumValue1 = 24,
+ OtherEnumValue2,
+ OtherEnumValue3 = 24,
+ OtherEnumValue4,
+ OtherEnumValue5 = 1
+ }
+
+ property int enumValue: TypeWithEnum.EnumValue2
+ property int enumValue2
+ property int scopedEnumValue: TypeWithEnum.MyEnum.EnumValue2
+ Component.onCompleted: enumValue2 = TypeWithEnum.EnumValue3
+
+ property int otherEnumValue1: TypeWithEnum.OtherEnumValue1
+ property int otherEnumValue2: TypeWithEnum.OtherEnumValue2
+ property int otherEnumValue3: TypeWithEnum.OtherEnumValue3
+ property int otherEnumValue4: TypeWithEnum.OtherEnumValue4
+ property int otherEnumValue5: TypeWithEnum.OtherEnumValue5
+}
diff --git a/tests/auto/qml/qqmllanguage/data/circularSingleton.qml b/tests/auto/qml/qqmllanguage/data/circularSingleton.qml
new file mode 100644
index 0000000000..e569111956
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/circularSingleton.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.10
+import "singleton/circular"
+
+QtObject {
+ property int value: MySingleton.value
+}
diff --git a/tests/auto/qml/qqmllanguage/data/cppnamespace.qml b/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
index efedf2b14a..48f7eb6715 100644
--- a/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
+++ b/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
@@ -2,4 +2,5 @@ import Test 1.0
MyNamespacedType {
myEnum: MyNamespace.Key5
+ property int intProperty: MyNamespace.MyOtherNSEnum.OtherKey2
}
diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml
new file mode 100644
index 0000000000..f6ec5848c1
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.6
+
+MouseArea {
+
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml
new file mode 100644
index 0000000000..b3fa43a671
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.6
+
+Rectangle {
+}
diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml
new file mode 100644
index 0000000000..cf566b9315
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.6
+
+Rectangle {
+ property int somethingCustom: 0
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir b/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir
new file mode 100644
index 0000000000..144c93d8e3
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir
@@ -0,0 +1,2 @@
+CustomRectangle 1.0 CustomRectangle.qml
+CustomMouseArea 1.0 CustomMouseArea.qml
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml
new file mode 100644
index 0000000000..d74b172cf8
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml
@@ -0,0 +1,13 @@
+import QtQml 2.0
+
+QtObject {
+ id: qtobjectInstance
+
+ property Timer aTimer: Timer {
+ id: timerInstance
+ }
+
+ property Connections aConnections: Connections {
+ id: connectionsInstance
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml
new file mode 100644
index 0000000000..a8e303363e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml
@@ -0,0 +1,13 @@
+import QtQml 2.0 as QmlImport
+
+QmlImport.QtObject {
+ id: qtobjectInstance
+
+ property QmlImport.Timer aTimer: QmlImport.Timer {
+ id: timerInstance
+ }
+
+ property QmlImport.Connections aConnections: QmlImport.Connections {
+ id: connectionsInstance
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml
new file mode 100644
index 0000000000..9c1808d515
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ id: itemInstance
+
+ Rectangle {
+ id: rectangleInstance
+ }
+
+ MouseArea {
+ id: mouseAreaInstance
+ }
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml
new file mode 100644
index 0000000000..78fc112805
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+import "instanceOf"
+
+Item {
+ id: itemInstance
+
+ Rectangle {
+ id: rectangleInstance
+ }
+
+ MouseArea {
+ id: mouseAreaInstance
+ }
+
+ CustomRectangle {
+ id: customRectangleInstance
+ }
+ CustomRectangleWithProp {
+ id: customRectangleWithPropInstance
+ }
+ CustomMouseArea {
+ id: customMouseAreaInstance
+ }
+}
+
+
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml
new file mode 100644
index 0000000000..97361b7334
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0 as QuickImport
+import "instanceOf" as CustomImport
+
+QuickImport.Item {
+ id: itemInstance
+
+ QuickImport.Rectangle {
+ id: rectangleInstance
+ }
+
+ QuickImport.MouseArea {
+ id: mouseAreaInstance
+ }
+
+ CustomImport.CustomRectangle {
+ id: customRectangleInstance
+ }
+ CustomImport.CustomRectangleWithProp {
+ id: customRectangleWithPropInstance
+ }
+ CustomImport.CustomMouseArea {
+ id: customMouseAreaInstance
+ }
+}
+
+
+
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.errors.txt
new file mode 100644
index 0000000000..a96fe376aa
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.errors.txt
@@ -0,0 +1 @@
+6:22:Expected token `numeric literal'
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml
new file mode 100644
index 0000000000..fef23ecbef
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2 = "hello",
+ EnumValue3
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.errors.txt
new file mode 100644
index 0000000000..a96fe376aa
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.errors.txt
@@ -0,0 +1 @@
+6:22:Expected token `numeric literal'
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml
new file mode 100644
index 0000000000..9892fcd19c
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2 = hello,
+ EnumValue3
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.errors.txt
new file mode 100644
index 0000000000..43465c60ec
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.errors.txt
@@ -0,0 +1 @@
+7:22:Enum value out of range
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml
new file mode 100644
index 0000000000..654bc0e626
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2,
+ EnumValue3 = 2147483648
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.errors.txt
new file mode 100644
index 0000000000..12756dc593
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.errors.txt
@@ -0,0 +1 @@
+7:22:Enum value must be an integer
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.qml b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.qml
new file mode 100644
index 0000000000..4a0aafba5e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2,
+ EnumValue3 = 17.5
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/NonSingletonType.qml b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/NonSingletonType.qml
new file mode 100644
index 0000000000..ec7c76c055
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/NonSingletonType.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+import org.qtproject.MixedModule 1.0
+
+Item {
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/SingletonType.qml b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/SingletonType.qml
new file mode 100644
index 0000000000..7763c783f1
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/SingletonType.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+pragma Singleton
+
+Item {
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/qmldir b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/qmldir
new file mode 100644
index 0000000000..cd03a5f941
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/qmldir
@@ -0,0 +1,4 @@
+module org.qtproject.MixedModule
+singleton SingletonType 1.0 SingletonType.qml
+NonSingletonType 1.0 NonSingletonType.qml
+Test 1.0 test.js
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/test.js b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/test.js
new file mode 100644
index 0000000000..6a53b53b02
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/test.js
@@ -0,0 +1 @@
+var foo = 1
diff --git a/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.errors.txt b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.errors.txt
new file mode 100644
index 0000000000..d1bd2bcff4
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.errors.txt
@@ -0,0 +1 @@
+6:9:Enum names must begin with an upper case letter
diff --git a/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.qml b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.qml
new file mode 100644
index 0000000000..0b50820128
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ enumValue2,
+ EnumValue3
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.errors.txt b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.errors.txt
new file mode 100644
index 0000000000..3e051c416e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.errors.txt
@@ -0,0 +1 @@
+4:5:Scoped enum names must begin with an upper case letter
diff --git a/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.qml b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.qml
new file mode 100644
index 0000000000..bb7aea6aa4
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum myEnum {
+ EnumValue1,
+ EnumValue2,
+ EnumValue3
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/mixedModuleWithSelfImport.qml b/tests/auto/qml/qqmllanguage/data/mixedModuleWithSelfImport.qml
new file mode 100644
index 0000000000..7768a6aedf
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/mixedModuleWithSelfImport.qml
@@ -0,0 +1,3 @@
+import org.qtproject.MixedModule 1.0
+
+NonSingletonType {}
diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml
new file mode 100644
index 0000000000..0e69012662
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml
@@ -0,0 +1,2 @@
+import QtQml 2.0
+QtObject {}
diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml
new file mode 100644
index 0000000000..c6b38d51a9
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ property InternalType myInternalType: InternalType {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml
new file mode 100644
index 0000000000..9b488f92da
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+import modulewithinternaltypes 1.0
+QtObject {
+ property InternalType myInternalType: InternalType {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir
new file mode 100644
index 0000000000..3593845329
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir
@@ -0,0 +1,3 @@
+PublicType 1.0 MyPublicType.qml
+PublicTypeWithExplicitImport 1.0 MyPublicTypeWithExplicitImport.qml
+internal InternalType MyInternalType.qml
diff --git a/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml
index 5f8c11e5f6..b6a07693f2 100644
--- a/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml
+++ b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml
@@ -3,4 +3,5 @@ import Test 1.0
RegisteredCompositeTypeWithEnum {
property int enumValue0: RegisteredCompositeTypeWithEnum.EnumValue0
property int enumValue42: RegisteredCompositeTypeWithEnum.EnumValue42
+ property int enumValue15: RegisteredCompositeTypeWithEnum.ScopedCompositeEnum.EnumValue15
}
diff --git a/tests/auto/qml/qqmllanguage/data/scopedEnum.qml b/tests/auto/qml/qqmllanguage/data/scopedEnum.qml
new file mode 100644
index 0000000000..7f4177af76
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/scopedEnum.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.0
+import Test 1.0
+
+MyTypeObject {
+ id: obj
+ scopedEnum: MyTypeObject.MyScopedEnum.ScopedVal1
+ intProperty: MyTypeObject.MyScopedEnum.ScopedVal2
+ property int listValue: myModel.get(0).myData
+ property int noScope: MyTypeObject.ScopedVal1
+
+ function assignNewValue() {
+ scopedEnum = MyTypeObject.MyScopedEnum.ScopedVal2
+ noScope = MyTypeObject.ScopedVal2
+ }
+
+ property ListModel myModel: ListModel {
+ ListElement {
+ myData: MyTypeObject.MyScopedEnum.ScopedVal3
+ }
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/scopedEnumList.errors.txt b/tests/auto/qml/qqmllanguage/data/scopedEnumList.errors.txt
new file mode 100644
index 0000000000..67576dfd8d
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/scopedEnumList.errors.txt
@@ -0,0 +1 @@
+7:13:ListElement: cannot use script for property value
diff --git a/tests/auto/qml/qqmllanguage/data/scopedEnumList.qml b/tests/auto/qml/qqmllanguage/data/scopedEnumList.qml
new file mode 100644
index 0000000000..8655139683
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/scopedEnumList.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+import Test 1.0
+
+MyTypeObject {
+ property ListModel myModel: ListModel {
+ ListElement {
+ myData: MyTypeObject.MyScopedEnum
+ }
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml b/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml
new file mode 100644
index 0000000000..1253018789
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml
@@ -0,0 +1,12 @@
+pragma Singleton
+import QtQuick 2.10
+
+QtObject {
+ enum MyEnum {
+ Value0,
+ Value1,
+ Value2
+ }
+
+ property int value: MySingleton.Value2
+}
diff --git a/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir b/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir
new file mode 100644
index 0000000000..3bc50738dd
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir
@@ -0,0 +1 @@
+singleton MySingleton MySingleton.qml
diff --git a/tests/auto/qml/qqmllanguage/data/usingTypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/usingTypeWithEnum.qml
new file mode 100644
index 0000000000..2509fc0df1
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/usingTypeWithEnum.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+QtObject {
+ property int enumValue: TypeWithEnum.EnumValue2
+ property int enumValue2: -1
+ property int scopedEnumValue: TypeWithEnum.MyEnum.EnumValue3
+ Component.onCompleted: enumValue2 = TypeWithEnum.EnumValue1
+}
diff --git a/tests/auto/qml/qqmllanguage/qqmllanguage.pro b/tests/auto/qml/qqmllanguage/qqmllanguage.pro
index 99c0c3e823..3e88f3f0db 100644
--- a/tests/auto/qml/qqmllanguage/qqmllanguage.pro
+++ b/tests/auto/qml/qqmllanguage/qqmllanguage.pro
@@ -6,7 +6,6 @@ SOURCES += tst_qqmllanguage.cpp \
testtypes.cpp
HEADERS += testtypes.h
-INCLUDEPATH += ../../shared/
HEADERS += ../../shared/testhttpserver.h
SOURCES += ../../shared/testhttpserver.cpp
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index d2240d25a9..1a81528bc4 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -136,7 +136,7 @@ void CustomBinding::componentComplete()
QQmlContextData *context = QQmlContextData::get(qmlContext(this));
QQmlProperty property(m_target, name, qmlContext(this));
- QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this)));
+ QV4::Scope scope(qmlEngine(this)->handle());
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(scope.engine->rootContext(), context, m_target));
QQmlBinding *qmlBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core,
compilationUnit->runtimeFunctions[bindingId], m_target, context, qmlContext);
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index d9ddff20a7..5025a6e7f2 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -223,6 +223,7 @@ class MyTypeObject : public QObject
Q_PROPERTY(Qt::TextFormat qtEnumProperty READ qtEnumProperty WRITE setQtEnumProperty NOTIFY qtEnumPropertyChanged)
Q_PROPERTY(MyMirroredEnum mirroredEnumProperty READ mirroredEnumProperty WRITE setMirroredEnumProperty NOTIFY mirroredEnumPropertyChanged)
Q_PROPERTY(MyEnumContainer::RelatedEnum relatedEnumProperty READ relatedEnumProperty WRITE setRelatedEnumProperty)
+ Q_PROPERTY(MyScopedEnum scopedEnum READ scopedEnum WRITE setScopedEnum)
Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringPropertyChanged)
Q_PROPERTY(QByteArray byteArrayProperty READ byteArrayProperty WRITE setByteArrayProperty NOTIFY byteArrayPropertyChanged)
Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty NOTIFY uintPropertyChanged)
@@ -339,6 +340,14 @@ public:
relatedEnumPropertyValue = v;
}
+ enum class MyScopedEnum : int { ScopedVal1, ScopedVal2, ScopedVal3 };
+ Q_ENUM(MyScopedEnum)
+ MyScopedEnum scopedEnumPropertyValue;
+ MyScopedEnum scopedEnum() const { return scopedEnumPropertyValue; }
+ void setScopedEnum(MyScopedEnum v) {
+ scopedEnumPropertyValue = v;
+ }
+
QString stringPropertyValue;
QString stringProperty() const {
return stringPropertyValue;
@@ -738,6 +747,13 @@ namespace MyNamespace {
};
Q_ENUM_NS(MyNSEnum);
+ enum class MyOtherNSEnum {
+ OtherKey1 = 1,
+ OtherKey2
+ };
+ Q_ENUM_NS(MyOtherNSEnum);
+
+
class MyNamespacedType : public QObject
{
Q_OBJECT
@@ -1171,9 +1187,11 @@ class MyCompositeBaseType : public QObject
{
Q_OBJECT
Q_ENUMS(CompositeEnum)
+ Q_ENUMS(ScopedCompositeEnum)
public:
enum CompositeEnum { EnumValue0, EnumValue42 = 42 };
+ enum class ScopedCompositeEnum : int { EnumValue15 = 15 };
static QObject *qmlAttachedProperties(QObject *parent) { return new QObject(parent); }
};
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 83151fb6e2..03d53b755d 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -179,6 +179,8 @@ private slots:
void importIncorrectCase();
void importJs_data();
void importJs();
+ void explicitSelfImport();
+ void importInternalType();
void qmlAttachedPropertiesObjectMethod();
void customOnProperty();
@@ -209,6 +211,8 @@ private slots:
void lowercaseEnumRuntime();
void lowercaseEnumCompileTime_data();
void lowercaseEnumCompileTime();
+ void scopedEnum();
+ void qmlEnums();
void literals_data();
void literals();
@@ -237,6 +241,7 @@ private slots:
void compositeSingletonJavaScriptPragma();
void compositeSingletonSelectors();
void compositeSingletonRegistered();
+ void compositeSingletonCircular();
void customParserBindingScopes();
void customParserEvaluateEnum();
@@ -267,6 +272,9 @@ private slots:
void qmlTypeCanBeResolvedByName_data();
void qmlTypeCanBeResolvedByName();
+ void instanceof_data();
+ void instanceof();
+
void concurrentLoadQmlDir();
void accessDeletedObject();
@@ -319,7 +327,7 @@ private:
if (!errorfile) { \
if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
qWarning() << "Unexpected Errors:" << component.errors(); \
- QVERIFY(!component.isError()); \
+ QVERIFY2(!component.isError(), qPrintable(component.errorString())); \
QVERIFY(component.errors().isEmpty()); \
} else { \
DETERMINE_ERRORS(errorfile,expected,actual);\
@@ -550,6 +558,14 @@ void tst_qqmllanguage::errors_data()
QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
+ QTest::newRow("scopedEnumList") << "scopedEnumList.qml" << "scopedEnumList.errors.txt" << false;
+ QTest::newRow("lowercase enum value") << "lowercaseQmlEnum.1.qml" << "lowercaseQmlEnum.1.errors.txt" << false;
+ QTest::newRow("lowercase enum type") << "lowercaseQmlEnum.2.qml" << "lowercaseQmlEnum.2.errors.txt" << false;
+ QTest::newRow("string enum value") << "invalidQmlEnumValue.1.qml" << "invalidQmlEnumValue.1.errors.txt" << false;
+ QTest::newRow("identifier enum type") << "invalidQmlEnumValue.2.qml" << "invalidQmlEnumValue.2.errors.txt" << false;
+ QTest::newRow("enum value too large") << "invalidQmlEnumValue.3.qml" << "invalidQmlEnumValue.3.errors.txt" << false;
+ QTest::newRow("non-integer enum value") << "invalidQmlEnumValue.4.qml" << "invalidQmlEnumValue.4.errors.txt" << false;
+
const QString expectedError = isCaseSensitiveFileSystem(dataDirectory()) ?
QStringLiteral("incorrectCase.errors.sensitive.txt") :
QStringLiteral("incorrectCase.errors.insensitive.txt");
@@ -1610,6 +1626,9 @@ void tst_qqmllanguage::cppnamespace()
VERIFY_ERRORS(0);
QObject *object = component.create();
QVERIFY(object != 0);
+
+ QCOMPARE(object->property("intProperty").toInt(), (int)MyNamespace::MyOtherNSEnum::OtherKey2);
+
delete object;
}
@@ -3068,12 +3087,45 @@ void tst_qqmllanguage::importJs()
engine.setImportPathList(defaultImportPathList);
}
+void tst_qqmllanguage::explicitSelfImport()
+{
+ engine.setImportPathList(QStringList(defaultImportPathList) << testFile("lib"));
+
+ QQmlComponent component(&engine, testFileUrl("mixedModuleWithSelfImport.qml"));
+ QVERIFY(component.errors().count() == 0);
+
+ engine.setImportPathList(defaultImportPathList);
+}
+
+void tst_qqmllanguage::importInternalType()
+{
+ QQmlEngine engine;
+ engine.addImportPath(dataDirectory());
+
+ {
+ QQmlComponent component(&engine);
+ component.setData("import modulewithinternaltypes 1.0\nPublicType{}", QUrl());
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QVERIFY(obj->property("myInternalType").value<QObject*>() != 0);
+ }
+ {
+ QQmlComponent component(&engine);
+ component.setData("import modulewithinternaltypes 1.0\nPublicTypeWithExplicitImport{}", QUrl());
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QVERIFY(obj->property("myInternalType").value<QObject*>() != 0);
+ }
+}
+
void tst_qqmllanguage::qmlAttachedPropertiesObjectMethod()
{
QObject object;
QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
- QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
+ QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(&object, true));
{
QQmlComponent component(&engine, testFileUrl("qmlAttachedPropertiesObjectMethod.1.qml"));
@@ -3510,6 +3562,7 @@ void tst_qqmllanguage::registeredCompositeTypeWithEnum()
QCOMPARE(o->property("enumValue0").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue0));
QCOMPARE(o->property("enumValue42").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue42));
+ QCOMPARE(o->property("enumValue15").toInt(), static_cast<int>(MyCompositeBaseType::ScopedCompositeEnum::EnumValue15));
delete o;
}
@@ -3690,6 +3743,50 @@ void tst_qqmllanguage::lowercaseEnumCompileTime()
VERIFY_ERRORS(qPrintable(errorFile));
}
+void tst_qqmllanguage::scopedEnum()
+{
+ QQmlComponent component(&engine, testFileUrl("scopedEnum.qml"));
+
+ MyTypeObject *o = qobject_cast<MyTypeObject *>(component.create());
+ QVERIFY(o != 0);
+
+ QCOMPARE(o->scopedEnum(), MyTypeObject::MyScopedEnum::ScopedVal1);
+ QCOMPARE(o->intProperty(), (int)MyTypeObject::MyScopedEnum::ScopedVal2);
+ QCOMPARE(o->property("listValue").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal3);
+ QCOMPARE(o->property("noScope").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal1);
+
+ QMetaObject::invokeMethod(o, "assignNewValue");
+ QCOMPARE(o->scopedEnum(), MyTypeObject::MyScopedEnum::ScopedVal2);
+ QCOMPARE(o->property("noScope").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal2);
+}
+
+void tst_qqmllanguage::qmlEnums()
+{
+ {
+ QQmlComponent component(&engine, testFileUrl("TypeWithEnum.qml"));
+ QObject *o = component.create();
+ QVERIFY(o);
+ QCOMPARE(o->property("enumValue").toInt(), 1);
+ QCOMPARE(o->property("enumValue2").toInt(), 2);
+ QCOMPARE(o->property("scopedEnumValue").toInt(), 1);
+
+ QCOMPARE(o->property("otherEnumValue1").toInt(), 24);
+ QCOMPARE(o->property("otherEnumValue2").toInt(), 25);
+ QCOMPARE(o->property("otherEnumValue3").toInt(), 24);
+ QCOMPARE(o->property("otherEnumValue4").toInt(), 25);
+ QCOMPARE(o->property("otherEnumValue5").toInt(), 1);
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("usingTypeWithEnum.qml"));
+ QObject *o = component.create();
+ QVERIFY(o);
+ QCOMPARE(o->property("enumValue").toInt(), 1);
+ QCOMPARE(o->property("enumValue2").toInt(), 0);
+ QCOMPARE(o->property("scopedEnumValue").toInt(), 2);
+ }
+}
+
void tst_qqmllanguage::literals_data()
{
QTest::addColumn<QString>("property");
@@ -4123,6 +4220,22 @@ void tst_qqmllanguage::compositeSingletonRegistered()
verifyCompositeSingletonPropertyValues(o, "value1", 925, "value2", 755);
}
+void tst_qqmllanguage::compositeSingletonCircular()
+{
+ QQmlComponent component(&engine, testFile("circularSingleton.qml"));
+ VERIFY_ERRORS(0);
+
+ QQmlTestMessageHandler messageHandler;
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ // ensure we aren't hitting the recursion warning
+ QVERIFY2(messageHandler.messages().isEmpty(), qPrintable(messageHandler.messageString()));
+
+ QCOMPARE(o->property("value").toInt(), 2);
+}
+
void tst_qqmllanguage::customParserBindingScopes()
{
QQmlComponent component(&engine, testFile("customParserBindingScopes.qml"));
@@ -4562,6 +4675,200 @@ void tst_qqmllanguage::qmlTypeCanBeResolvedByName()
QVERIFY(!o.isNull());
}
+// Tests for the QML-only extensions of instanceof. Tests for the regular JS
+// instanceof belong in tst_qqmlecmascript!
+void tst_qqmllanguage::instanceof_data()
+{
+ QTest::addColumn<QUrl>("documentToTestIn");
+ QTest::addColumn<QVariant>("expectedValue");
+
+ // so the way this works is that the name of the test tag defines the test
+ // to run.
+ //
+ // the expectedValue is either a boolean true or false for whether the two
+ // operands are indeed an instanceof each other, or a string for the
+ // expected error message.
+
+ // assert that basic types don't convert to QObject
+ QTest::newRow("1 instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+ QTest::newRow("true instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+ QTest::newRow("\"foobar\" instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+
+ // assert that Managed don't either
+ QTest::newRow("new String(\"foobar\") instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+ QTest::newRow("new Object() instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+ QTest::newRow("new Date() instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+
+ // test that simple QtQml comparisons work
+ QTest::newRow("qtobjectInstance instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+ QTest::newRow("qtobjectInstance instanceof Timer")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(false);
+ QTest::newRow("timerInstance instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+ QTest::newRow("timerInstance instanceof Timer")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+ QTest::newRow("connectionsInstance instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+ QTest::newRow("connectionsInstance instanceof Timer")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(false);
+ QTest::newRow("connectionsInstance instanceof Connections")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+
+ // make sure they still work when imported with a qualifier
+ QTest::newRow("qtobjectInstance instanceof QmlImport.QtObject")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("qtobjectInstance instanceof QmlImport.Timer")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(false);
+ QTest::newRow("timerInstance instanceof QmlImport.QtObject")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("timerInstance instanceof QmlImport.Timer")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("connectionsInstance instanceof QmlImport.QtObject")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("connectionsInstance instanceof QmlImport.Timer")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(false);
+ QTest::newRow("connectionsInstance instanceof QmlImport.Connections")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+
+ // test that Quick C++ types work ok
+ QTest::newRow("itemInstance instanceof QtObject")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+ QTest::newRow("itemInstance instanceof Timer")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(false);
+ QTest::newRow("itemInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(false);
+ QTest::newRow("rectangleInstance instanceof Item")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+ QTest::newRow("rectangleInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+ QTest::newRow("rectangleInstance instanceof MouseArea")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(false);
+ QTest::newRow("mouseAreaInstance instanceof Item")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+ QTest::newRow("mouseAreaInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(false);
+ QTest::newRow("mouseAreaInstance instanceof MouseArea")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+
+ // test that unqualified quick composite types work ok
+ QTest::newRow("rectangleInstance instanceof CustomRectangle")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(false);
+ QTest::newRow("customRectangleInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleInstance instanceof Item")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleWithPropInstance instanceof CustomRectangleWithProp")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleWithPropInstance instanceof CustomRectangle")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(false); // ### XXX: QTBUG-58477
+ QTest::newRow("customRectangleWithPropInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleInstance instanceof MouseArea")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(false);
+ QTest::newRow("customMouseAreaInstance instanceof MouseArea")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+
+ // test that they still work when qualified
+ QTest::newRow("rectangleInstance instanceof CustomImport.CustomRectangle")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(false);
+ QTest::newRow("customRectangleInstance instanceof QuickImport.Rectangle")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleInstance instanceof QuickImport.Item")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleWithPropInstance instanceof CustomImport.CustomRectangleWithProp")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleWithPropInstance instanceof CustomImport.CustomRectangle")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(false); // ### XXX: QTBUG-58477
+ QTest::newRow("customRectangleWithPropInstance instanceof QuickImport.Rectangle")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleInstance instanceof QuickImport.MouseArea")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(false);
+ QTest::newRow("customMouseAreaInstance instanceof QuickImport.MouseArea")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+}
+
+void tst_qqmllanguage::instanceof()
+{
+ QFETCH(QUrl, documentToTestIn);
+ QFETCH(QVariant, expectedValue);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine, documentToTestIn);
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o != 0);
+
+ QQmlExpression expr(engine.contextForObject(o.data()), 0, QString::fromLatin1(QTest::currentDataTag()));
+ QVariant ret = expr.evaluate();
+
+ if (expectedValue.type() == QVariant::Bool) {
+ // no error expected
+ QVERIFY2(!expr.hasError(), qPrintable(expr.error().description()));
+ bool returnValue = ret.toBool();
+
+ if (QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomRectangle") ||
+ QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomImport.CustomRectangle"))
+ QEXPECT_FAIL("", "QTBUG-58477: QML type rules are a little lax", Continue);
+ QCOMPARE(returnValue, expectedValue.toBool());
+ } else {
+ QVERIFY(expr.hasError());
+ QCOMPARE(expr.error().description(), expectedValue.toString());
+ }
+}
+
void tst_qqmllanguage::concurrentLoadQmlDir()
{
ThreadedTestHTTPServer server(dataDirectory());
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index f5c0e5ddf7..73aec7c55b 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -124,6 +124,7 @@ private slots:
void modify_through_delegate();
void bindingsOnGetResult();
void stringifyModelEntry();
+ void qobjectTrackerForDynamicModelObjects();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1205,8 +1206,8 @@ void tst_qqmllistmodel::role_mode_data()
QTest::newRow("default1") << "{append({'a':1});dynamicRoles}" << 0 << "";
QTest::newRow("enableDynamic0") << "{dynamicRoles=true;dynamicRoles}" << 1 << "";
- QTest::newRow("enableDynamic1") << "{append({'a':1});dynamicRoles=true;dynamicRoles}" << 0 << "<Unknown File>: QML ListModel: unable to enable dynamic roles as this model is not empty!";
- QTest::newRow("enableDynamic2") << "{dynamicRoles=true;append({'a':1});dynamicRoles=false;dynamicRoles}" << 1 << "<Unknown File>: QML ListModel: unable to enable static roles as this model is not empty!";
+ QTest::newRow("enableDynamic1") << "{append({'a':1});dynamicRoles=true;dynamicRoles}" << 0 << "<Unknown File>: QML ListModel: unable to enable dynamic roles as this model is not empty";
+ QTest::newRow("enableDynamic2") << "{dynamicRoles=true;append({'a':1});dynamicRoles=false;dynamicRoles}" << 1 << "<Unknown File>: QML ListModel: unable to enable static roles as this model is not empty";
}
void tst_qqmllistmodel::role_mode()
@@ -1505,6 +1506,33 @@ void tst_qqmllistmodel::stringifyModelEntry()
QCOMPARE(v.toString(), expectedString);
}
+void tst_qqmllistmodel::qobjectTrackerForDynamicModelObjects()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ " ListModel {\n"
+ " id: testModel\n"
+ " objectName: \"testModel\"\n"
+ " ListElement { name: \"Joe\"; age: 22 }\n"
+ " }\n"
+ "}\n", QUrl());
+ QScopedPointer<QObject> scene(component.create());
+ QQmlListModel *model = scene->findChild<QQmlListModel*>("testModel");
+ QQmlExpression expr(engine.rootContext(), model, "get(0);");
+ QVariant v = expr.evaluate();
+ QVERIFY2(!expr.hasError(), QTest::toString(expr.error().toString()));
+
+ QObject *obj = v.value<QObject*>();
+ QVERIFY(obj);
+
+ QQmlData *ddata = QQmlData::get(obj, /*create*/false);
+ QVERIFY(ddata);
+ QVERIFY(!ddata->jsWrapper.isNullOrUndefined());
+}
+
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"
diff --git a/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp b/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp
index 9564d6a8b2..6301c35676 100644
--- a/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp
+++ b/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp
@@ -192,7 +192,7 @@ void tst_qqmllistmodelworkerscript::dynamic_data()
QTest::addColumn<QString>("warning");
QTest::addColumn<bool>("dynamicRoles");
- for (int i=0 ; i < 2 ; ++i) {
+ for (int i = 0; i < 2; ++i) {
bool dr = (i != 0);
// Simple flat model
@@ -434,7 +434,7 @@ void tst_qqmllistmodelworkerscript::get_data()
QTest::addColumn<QVariant>("roleValue");
QTest::addColumn<bool>("dynamicRoles");
- for (int i=0 ; i < 2 ; ++i) {
+ for (int i =0; i < 2; ++i) {
bool dr = (i != 0);
QTest::newRow("simple value") << "get(0).roleA = 500" << 0 << "roleA" << QVariant(500) << dr;
@@ -515,7 +515,7 @@ void tst_qqmllistmodelworkerscript::property_changes_data()
QTest::addColumn<QString>("testExpression");
QTest::addColumn<bool>("dynamicRoles");
- for (int i=0 ; i < 2 ; ++i) {
+ for (int i=1 ; i < 2 ; ++i) {
bool dr = (i != 0);
QTest::newRow("set: plain") << "append({'a':123, 'b':456, 'c':789});" << "set(0,{'b':123});"
@@ -574,7 +574,7 @@ void tst_qqmllistmodelworkerscript::property_changes_data()
<< "b" << 0 << true << "get(0).b.get(0).a == 1 && get(0).b.get(1).a == 2 && get(0).b.get(2).a == 3" << dr;
QTest::newRow("nested-set: list, no changes, empty") << "append({'a':123, 'b':[], 'c':789});" << "set(0,{'b':[]});"
- << "b" << 0 << true << "get(0).b.count == 0" << dr;
+ << "b" << 0 << false << "get(0).b.count == 0" << dr;
}
}
diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
index d0ce83b997..4f4deaafe5 100644
--- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
+++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
@@ -1268,8 +1268,8 @@ void tst_qqmllocale::timeZoneUpdated()
{
QByteArray original(qgetenv("TZ"));
- // Set the timezone to Brisbane time
- setTimeZone(QByteArray("AEST-10:00"));
+ // Set the timezone to Brisbane time, AEST-10:00
+ setTimeZone(QByteArray("Australia/Brisbane"));
DateFormatter formatter;
@@ -1281,8 +1281,8 @@ void tst_qqmllocale::timeZoneUpdated()
QVERIFY(obj);
QVERIFY(obj->property("success").toBool());
- // Change to Indian time
- setTimeZone(QByteArray("IST-05:30"));
+ // Change to Indian time, IST-05:30
+ setTimeZone(QByteArray("Asia/Kolkata"));
QMetaObject::invokeMethod(obj.data(), "check");
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
deleted file mode 100644
index 150f2f08d3..0000000000
--- a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-TEMPLATE = lib
-CONFIG += plugin
-SOURCES = plugin.cpp
-QT = core qml
-DESTDIR = ../imports/org/qtproject/InvalidStrictModule
-
-QT += core-private gui-private qml-private
-
-IMPORT_FILES = \
- qmldir
-
-include (../../../shared/imports.pri)
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir
deleted file mode 100644
index 20716dc9f9..0000000000
--- a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir
+++ /dev/null
@@ -1,2 +0,0 @@
-module org.qtproject.InvalidStrictModule
-plugin invalidStrictModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
index 0f548aa6f8..ae13a041cc 100644
--- a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
@@ -11,7 +11,6 @@ SUBDIRS =\
nestedPlugin\
strictModule\
strictModule.2\
- invalidStrictModule\
nonstrictModule\
preemptiveModule\
preemptedStrictModule\
diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
index 9abff7b2f6..85e4918b61 100644
--- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
@@ -580,12 +580,6 @@ void tst_qqmlmoduleplugin::importStrictModule_data()
<< QString()
<< QString();
- QTest::newRow("wrong target")
- << "import org.qtproject.InvalidStrictModule 1.0\n"
- "MyPluginType {}"
- << QString()
- << ":1:1: plugin cannot be loaded for module \"org.qtproject.InvalidStrictModule\": Cannot install element 'MyPluginType' into unregistered namespace 'org.qtproject.SomeOtherModule'";
-
QTest::newRow("non-strict clash")
<< "import org.qtproject.NonstrictModule 1.0\n"
"MyPluginType {}"
diff --git a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
index beb60925bb..88a5d41975 100644
--- a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
+++ b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
@@ -98,7 +98,7 @@ public:
}
protected:
- void connectNotify(const QMetaMethod &signal) Q_DECL_OVERRIDE {
+ void connectNotify(const QMetaMethod &signal) override {
if (signal.name() == "qmlObjectPropChanged") qmlObjectPropConnections++;
if (signal.name() == "cppObjectPropChanged") cppObjectPropConnections++;
if (signal.name() == "unboundPropChanged") unboundPropConnections++;
@@ -112,7 +112,7 @@ protected:
//qDebug() << Q_FUNC_INFO << this << signal.name();
}
- void disconnectNotify(const QMetaMethod &signal) Q_DECL_OVERRIDE {
+ void disconnectNotify(const QMetaMethod &signal) override {
if (signal.name() == "qmlObjectPropChanged") qmlObjectPropConnections--;
if (signal.name() == "cppObjectPropChanged") cppObjectPropConnections--;
if (signal.name() == "unboundPropChanged") unboundPropConnections--;
@@ -146,7 +146,7 @@ public:
{}
private slots:
- void initTestCase() Q_DECL_OVERRIDE;
+ void initTestCase() override;
void cleanupTestCase();
void testConnectNotify();
diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
index 0576650d01..0bc1127069 100644
--- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
+++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
@@ -888,7 +888,8 @@ void tst_qqmlqt::dateTimeFormattingVariants_data()
QTest::newRow("formatTime, qtime") << "formatTime" << QVariant::fromValue(time) << (QStringList() << temporary.time().toString(Qt::DefaultLocaleShortDate) << temporary.time().toString(Qt::DefaultLocaleLongDate) << temporary.time().toString("H:m:s a") << temporary.time().toString("hh:mm:ss.zzz"));
QDate date(2011,5,31);
- temporary = QDateTime(date);
+ // V4 reads the date in UTC but DateObject::toQDateTime() gives it back in local time:
+ temporary = QDateTime(date, QTime(0, 0, 0), Qt::UTC).toLocalTime();
QTest::newRow("formatDate, qdate") << "formatDate" << QVariant::fromValue(date) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy"));
QTest::newRow("formatDateTime, qdate") << "formatDateTime" << QVariant::fromValue(date) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a"));
QTest::newRow("formatTime, qdate") << "formatTime" << QVariant::fromValue(date) << (QStringList() << temporary.time().toString(Qt::DefaultLocaleShortDate) << temporary.time().toString(Qt::DefaultLocaleLongDate) << temporary.time().toString("H:m:s a") << temporary.time().toString("hh:mm:ss.zzz"));
@@ -997,7 +998,7 @@ void tst_qqmlqt::exit()
QSignalSpy spy(&engine, &QQmlEngine::exit);
QObject *object = component.create();
- QVERIFY(object != Q_NULLPTR);
+ QVERIFY(object != nullptr);
QCOMPARE(spy.count(), 1);
QList<QVariant> arguments = spy.takeFirst();
QVERIFY(arguments.at(0).toInt() == object->property("returnCode").toInt());
diff --git a/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml b/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml
new file mode 100644
index 0000000000..c447c84987
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ property string baseProperty: qsTr("translate me");
+}
diff --git a/tests/auto/qml/qqmltranslation/data/translationChange.qml b/tests/auto/qml/qqmltranslation/data/translationChange.qml
new file mode 100644
index 0000000000..23b87c2493
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/translationChange.qml
@@ -0,0 +1,10 @@
+import QtQml 2.0
+
+TranslationChangeBase {
+ baseProperty: "do not translate"
+ property string text1: qsTr("translate me")
+ function weDoTranslations() {
+ return qsTr("translate me")
+ }
+ property string text2: weDoTranslations()
+}
diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
index dd4edeb97d..80c54bdf8e 100644
--- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
+++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
@@ -44,6 +44,7 @@ private slots:
void translation_data();
void translation();
void idTranslation();
+ void translationChange();
};
void tst_qqmltranslation::translation_data()
@@ -162,6 +163,51 @@ void tst_qqmltranslation::idTranslation()
delete object;
}
+class DummyTranslator : public QTranslator
+{
+ Q_OBJECT
+
+ QString translate(const char *context, const char *sourceText, const char *disambiguation, int n) const override
+ {
+ Q_UNUSED(context);
+ Q_UNUSED(disambiguation);
+ Q_UNUSED(n);
+ if (!qstrcmp(sourceText, "translate me"))
+ return QString::fromUtf8("xxx");
+ return QString();
+ }
+
+ bool isEmpty() const override
+ {
+ return false;
+ }
+};
+
+void tst_qqmltranslation::translationChange()
+{
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("translationChange.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QCOMPARE(object->property("baseProperty").toString(), QString::fromUtf8("do not translate"));
+ QCOMPARE(object->property("text1").toString(), QString::fromUtf8("translate me"));
+ QCOMPARE(object->property("text2").toString(), QString::fromUtf8("translate me"));
+
+ DummyTranslator translator;
+ QCoreApplication::installTranslator(&translator);
+
+ QEvent ev(QEvent::LanguageChange);
+ QCoreApplication::sendEvent(&engine, &ev);
+
+ QCOMPARE(object->property("baseProperty").toString(), QString::fromUtf8("do not translate"));
+ QCOMPARE(object->property("text1").toString(), QString::fromUtf8("xxx"));
+ QCOMPARE(object->property("text2").toString(), QString::fromUtf8("xxx"));
+
+ QCoreApplication::removeTranslator(&translator);
+}
+
QTEST_MAIN(tst_qqmltranslation)
#include "tst_qqmltranslation.moc"
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect
new file mode 100644
index 0000000000..6d34e1d2bb
--- /dev/null
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect
Binary files differ
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.qml b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.qml
new file mode 100644
index 0000000000..ba9761201e
--- /dev/null
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+QtObject {
+ property string url
+
+ property bool dataOK: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+ x.open("POST", url);
+ x.setRequestHeader("Accept-Language","en-US");
+
+ // Test to the end
+ x.onreadystatechange = function() {
+ if (x.readyState == XMLHttpRequest.DONE) {
+ dataOK = (x.responseText == "QML Rocks!\n");
+ }
+ }
+
+ var data = new Uint8Array([1, 2, 3, 0, 3, 2, 1])
+ x.send(data.buffer);
+ }
+}
diff --git a/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro b/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
index 44b2963918..572ab1d572 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
+++ b/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
TARGET = tst_qqmlxmlhttprequest
macx:CONFIG -= app_bundle
-INCLUDEPATH += ../../shared/
HEADERS += ../../shared/testhttpserver.h
SOURCES += tst_qqmlxmlhttprequest.cpp \
diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
index 1ce07ecdab..59716acc0d 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
+++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
@@ -291,7 +291,7 @@ class TestThreadedHTTPServer : public QObject
Q_OBJECT
public:
TestThreadedHTTPServer(const QUrl &expectUrl, const QUrl &replyUrl, const QUrl &bodyUrl)
- : m_server(Q_NULLPTR) {
+ : m_server(nullptr) {
QMutexLocker locker(&m_lock);
moveToThread(&m_thread);
m_thread.start();
@@ -597,6 +597,7 @@ void tst_qqmlxmlhttprequest::send_withdata_data()
QTest::newRow("Incorrect content-type - out of order") << "send_data.4.expect" << "send_data.5.qml";
QTest::newRow("PUT") << "send_data.6.expect" << "send_data.6.qml";
QTest::newRow("Correct content-type - no charset") << "send_data.1.expect" << "send_data.7.qml";
+ QTest::newRow("ArrayBuffer") << "send_data.11.expect" << "send_data.11.qml";
}
void tst_qqmlxmlhttprequest::send_options()
diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
index f19e82032a..1a23286ede 100644
--- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
+++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
@@ -42,6 +42,7 @@
// From qquickfolderlistmodel.h
const int FileNameRole = Qt::UserRole+1;
enum SortField { Unsorted, Name, Time, Size, Type };
+enum Status { Null, Ready, Loading };
class tst_qquickfolderlistmodel : public QQmlDataTest
{
@@ -58,6 +59,7 @@ public slots:
private slots:
void initTestCase();
void basicProperties();
+ void status();
void showFiles();
void resetFiltering();
void nameFilters();
@@ -141,6 +143,20 @@ void tst_qquickfolderlistmodel::basicProperties()
QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(""));
}
+void tst_qquickfolderlistmodel::status()
+{
+ QQmlComponent component(&engine, testFileUrl("basic.qml"));
+ checkNoErrors(component);
+
+ QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create());
+ QVERIFY(flm != 0);
+ QTRY_COMPARE(flm->property("status").toInt(), int(Ready));
+ flm->setProperty("folder", QUrl::fromLocalFile(""));
+ QTRY_COMPARE(flm->property("status").toInt(), int(Null));
+ flm->setProperty("folder", QUrl::fromLocalFile(QDir::currentPath()));
+ QTRY_COMPARE(flm->property("status").toInt(), int(Ready));
+}
+
void tst_qquickfolderlistmodel::showFiles()
{
QQmlComponent component(&engine, testFileUrl("basic.qml"));
diff --git a/tests/auto/qml/qwidgetsinqml/qwidgetsinqml.pro b/tests/auto/qml/qwidgetsinqml/qwidgetsinqml.pro
new file mode 100644
index 0000000000..c86365d5ea
--- /dev/null
+++ b/tests/auto/qml/qwidgetsinqml/qwidgetsinqml.pro
@@ -0,0 +1,7 @@
+CONFIG += testcase
+CONFIG += parallel_test
+TARGET = tst_qwidgetsinqml
+macos:CONFIG -= app_bundle
+QT += qml widgets testlib gui-private
+SOURCES += tst_qwidgetsinqml.cpp
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qwidgetsinqml/tst_qwidgetsinqml.cpp b/tests/auto/qml/qwidgetsinqml/tst_qwidgetsinqml.cpp
new file mode 100644
index 0000000000..c7bbb55474
--- /dev/null
+++ b/tests/auto/qml/qwidgetsinqml/tst_qwidgetsinqml.cpp
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QQmlEngine>
+#include <QtQml>
+#include <QWidget>
+
+class tst_QWidgetsInQml : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QWidgetsInQml();
+
+private slots:
+ void instantiateWidget();
+ void instantiateWidgetWithoutParentWidget();
+ void widgetAsDefaultPropertyCollected();
+ void widgetAsDefaultPropertyKept();
+ void widgetAsDefaultPropertyKeptDuringCreation();
+};
+
+static void gc(QQmlEngine &engine)
+{
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+}
+
+// Like QtObject, but with default property
+class QObjectContainer : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("DefaultProperty", "data");
+ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false);
+public:
+ QObjectContainer()
+ : widgetParent(0)
+ , gcOnAppend(false)
+ {}
+
+ QQmlListProperty<QObject> data() {
+ return QQmlListProperty<QObject>(this, 0, children_append, children_count, children_at, children_clear);
+ }
+
+ static void children_append(QQmlListProperty<QObject> *prop, QObject *o)
+ {
+ QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
+ that->dataChildren.append(o);
+ QObject::connect(o, SIGNAL(destroyed(QObject*)), prop->object, SLOT(childDestroyed(QObject*)));
+ QWidget *widget = qobject_cast<QWidget*>(o);
+ if (widget && that->widgetParent)
+ widget->setParent(that->widgetParent);
+
+ if (that->gcOnAppend) {
+ QQmlEngine *engine = qmlEngine(that);
+ gc(*engine);
+ }
+ }
+
+ static int children_count(QQmlListProperty<QObject> *prop)
+ {
+ return static_cast<QObjectContainer*>(prop->object)->dataChildren.count();
+ }
+
+ static QObject *children_at(QQmlListProperty<QObject> *prop, int index)
+ {
+ return static_cast<QObjectContainer*>(prop->object)->dataChildren.at(index);
+ }
+
+ static void children_clear(QQmlListProperty<QObject> *prop)
+ {
+ QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
+ foreach (QObject *c, that->dataChildren)
+ QObject::disconnect(c, SIGNAL(destroyed(QObject*)), that, SLOT(childDestroyed(QObject*)));
+ that->dataChildren.clear();
+ }
+
+ QList<QObject*> dataChildren;
+ QWidget *widgetParent;
+ bool gcOnAppend;
+
+protected slots:
+ void childDestroyed(QObject *child) {
+ dataChildren.removeAll(child);
+ }
+};
+
+class QWidgetContainer : public QObjectContainer
+{
+ Q_OBJECT
+public:
+ QWidgetContainer()
+ {
+ widgetParent = new QWidget;
+ QQmlEngine::setObjectOwnership(widgetParent, QQmlEngine::CppOwnership);
+ }
+ virtual ~QWidgetContainer()
+ {
+ delete widgetParent;
+ widgetParent = 0;
+ }
+};
+
+class QObjectContainerWithGCOnAppend : public QObjectContainer
+{
+ Q_OBJECT
+public:
+ QObjectContainerWithGCOnAppend()
+ {
+ gcOnAppend = true;
+ }
+};
+
+tst_QWidgetsInQml::tst_QWidgetsInQml()
+{
+ qmlRegisterType<QWidget>("Qt.Widgets", 1, 0, "QWidget");
+ qmlRegisterType<QObjectContainer>("Qt.Widgets", 1, 0, "QObjectContainer");
+ qmlRegisterType<QWidgetContainer>("Qt.Widgets", 1, 0, "QWidgetContainer");
+ qmlRegisterType<QObjectContainerWithGCOnAppend>("Qt.Widgets", 1, 0, "QObjectContainerWithGCOnAppend");
+}
+
+void tst_QWidgetsInQml::instantiateWidget()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\nQWidget { property QWidget child: QWidget { objectName: 'child' } }", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ QWidget *rootWidget = qobject_cast<QWidget*>(object.data());
+ QVERIFY(rootWidget != 0);
+ QCOMPARE(rootWidget->children().count(), 1);
+ QWidget *firstChildWidget = qobject_cast<QWidget*>(rootWidget->children().first());
+ QVERIFY(firstChildWidget != 0);
+
+ QWidget *widgetProperty = qvariant_cast<QWidget*>(object->property("child"));
+ QVERIFY(widgetProperty != 0);
+ QCOMPARE(firstChildWidget, widgetProperty);
+ QCOMPARE(firstChildWidget->objectName(), QString("child"));
+}
+
+void tst_QWidgetsInQml::instantiateWidgetWithoutParentWidget()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\n"
+ "import QtQml 2.0;\n"
+ "QtObject { property QtObject child: QWidget { objectName: 'child' } }", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QPointer<QWidget> widgetProperty = qvariant_cast<QWidget*>(object->property("child"));
+ QVERIFY(!widgetProperty.isNull());
+ QCOMPARE(widgetProperty->objectName(), QString("child"));
+
+ QVERIFY(!widgetProperty->parent());
+ gc(engine);
+ // Don't collect, the property reference should keep it alive
+ QVERIFY(!widgetProperty.isNull());
+}
+
+void tst_QWidgetsInQml::widgetAsDefaultPropertyCollected()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\n"
+ "import QtQml 2.0;\n"
+ "QObjectContainer {\n"
+ " QWidget {\n"
+ " id: parentLessChild;\n"
+ " objectName: 'child'\n"
+ " }\n"
+ " property var widgetHolder;\n"
+ " Component.onCompleted: {\n"
+ " widgetHolder = parentLessChild;\n"
+ " }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QObjectContainer *container = qobject_cast<QObjectContainer*>(object.data());
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ QJSValue holder = qvariant_cast<QJSValue>(object->property("widgetHolder"));
+ QVERIFY(!holder.isNull());
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ holder = QJSValue();
+ object->setProperty("widgetHolder", QVariant::fromValue(holder));
+
+ gc(engine);
+ // The QWidget is without a parent and nobody is referencing it anymore (the children
+ // list in QObjectContainer is weak!), so it should get collected.
+ QCOMPARE(container->dataChildren.count(), 0);
+}
+
+void tst_QWidgetsInQml::widgetAsDefaultPropertyKept()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\n"
+ "import QtQml 2.0;\n"
+ "QWidgetContainer {\n"
+ " QWidget {\n"
+ " id: parentLessChild;\n"
+ " objectName: 'child'\n"
+ " }\n"
+ " property var widgetHolder;\n"
+ " Component.onCompleted: {\n"
+ " widgetHolder = parentLessChild;\n"
+ " }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QWidgetContainer *container = qobject_cast<QWidgetContainer*>(object.data());
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ QJSValue holder = qvariant_cast<QJSValue>(object->property("widgetHolder"));
+ QVERIFY(!holder.isNull());
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ holder = QJSValue();
+ object->setProperty("widgetHolder", QVariant::fromValue(holder));
+
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 1);
+}
+
+void tst_QWidgetsInQml::widgetAsDefaultPropertyKeptDuringCreation()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\n"
+ "import QtQml 2.0;\n"
+ "QObjectContainerWithGCOnAppend {\n"
+ " QWidget {\n"
+ " id: parentLessChild;\n"
+ " objectName: 'child'\n"
+ " property var blah;\n" // Ensures that we have a JS wrapper
+ " }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QObjectContainer *container = qobject_cast<QObjectContainer*>(object.data());
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 0);
+
+}
+
+QTEST_MAIN(tst_QWidgetsInQml)
+
+#include "tst_qwidgetsinqml.moc"