From 31d05c6734057bed56ac783d4f9d03d3c2ecbcbb Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 23 Jan 2020 11:01:33 +0100 Subject: ArrayPrototype::method_filter: Check for exception after callback If there was an exception we cannot assume the returned value holds anything sensible. Also, we should immediately return. Fixes: QTBUG-81581 Change-Id: I822c204c476e05d6de78124b66ab2f939ca38ffd Reviewed-by: Lars Knoll --- tests/auto/qml/ecmascripttests/BLACKLIST | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 tests/auto/qml/ecmascripttests/BLACKLIST (limited to 'tests') diff --git a/tests/auto/qml/ecmascripttests/BLACKLIST b/tests/auto/qml/ecmascripttests/BLACKLIST deleted file mode 100644 index 1ed255e9e2..0000000000 --- a/tests/auto/qml/ecmascripttests/BLACKLIST +++ /dev/null @@ -1,4 +0,0 @@ -[runInterpreted] -macos ci -[runJitted] -macos -- cgit v1.2.3 From 34f8582c100320ffc7846760aeab225db8fcddf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 23 Jan 2020 12:54:28 +0100 Subject: Blacklist tst_QQuickWidget::enterLeave on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie5437ad18fdfdba95c87adb68345b43dc1003155 Reviewed-by: Morten Johan Sørvig --- tests/auto/quickwidgets/qquickwidget/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/auto/quickwidgets/qquickwidget/BLACKLIST b/tests/auto/quickwidgets/qquickwidget/BLACKLIST index 18ea65bb72..095e9ee484 100644 --- a/tests/auto/quickwidgets/qquickwidget/BLACKLIST +++ b/tests/auto/quickwidgets/qquickwidget/BLACKLIST @@ -1,3 +1,5 @@ [tabKey] opensuse-42.3 opensuse-leap +[enterLeave] +macos -- cgit v1.2.3 From b6143c08077c7d692fad9daa628f3ded8fa97f68 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 27 Jan 2020 13:55:14 +0100 Subject: tst_qqmlengine: Don't rename the QObject QML type Registering a plain QObject as singleton instance does interesting things to following tests. This didn't break in the CI as the CI then retries the failed tests in isolation, which works. Change-Id: Ieaa898067cb470f3e90f6e9059fb4b4b3a42de00 Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmlengine/tst_qqmlengine.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index ab4c083b65..cfbbd2a94c 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -997,6 +997,11 @@ public: SomeQObjectClass() : QObject(nullptr){} }; +class Dayfly : public QObject +{ + Q_OBJECT +}; + void tst_qqmlengine::singletonInstance() { QQmlEngine engine; @@ -1115,7 +1120,7 @@ void tst_qqmlengine::singletonInstance() { // deleted object - auto dayfly = new QObject{}; + auto dayfly = new Dayfly{}; auto id = qmlRegisterSingletonInstance("Vanity", 1, 0, "Dayfly", dayfly); delete dayfly; QTest::ignoreMessage(QtMsgType::QtWarningMsg, ": The registered singleton has already been deleted. Ensure that it outlives the engine."); -- cgit v1.2.3 From 688ac0d553c531a673507db0139231e8f2acb379 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 28 Jan 2020 13:07:17 +0100 Subject: Fix tst_qqmlvaluetypes::colorProperty when run standalone The test relied on implicit registration of QQmlProperty in the meta-type system. Change-Id: I21e08a44f8e3d3b1376977cb9c959e0630789ef9 Reviewed-by: Fabian Kosmale --- tests/auto/qml/qqmlvaluetypes/testtypes.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/auto/qml/qqmlvaluetypes/testtypes.h b/tests/auto/qml/qqmlvaluetypes/testtypes.h index e11d831236..78797f06b1 100644 --- a/tests/auto/qml/qqmlvaluetypes/testtypes.h +++ b/tests/auto/qml/qqmlvaluetypes/testtypes.h @@ -48,6 +48,8 @@ #include #include +Q_DECLARE_METATYPE(QQmlProperty) + class MyTypeObject : public QObject { Q_OBJECT -- cgit v1.2.3 From 4b1c40570300248a7a7744aa7ddf8e77457bdc2b Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Wed, 22 Jan 2020 16:00:13 +0100 Subject: Handle required properties declared in C++ Fixes: QTBUG-81561 Change-Id: I97a0f5013b6e3662ffaad53c5cc871404e11a310 Reviewed-by: Ulf Hermann --- .../qml/qqmllanguage/data/cppRequiredProperty.qml | 4 ++ .../data/cppRequiredPropertyInChildAndParent.qml | 4 ++ .../cppRequiredPropertyInChildAndParentNotSet.qml | 4 ++ .../data/cppRequiredPropertyInParent.qml | 4 ++ .../data/cppRequiredPropertyInParentNotSet.qml | 4 ++ .../data/cppRequiredPropertyNotSet.qml | 4 ++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 71 ++++++++++++++++++++++ 7 files changed, 95 insertions(+) create mode 100644 tests/auto/qml/qqmllanguage/data/cppRequiredProperty.qml create mode 100644 tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParent.qml create mode 100644 tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParentNotSet.qml create mode 100644 tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParent.qml create mode 100644 tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParentNotSet.qml create mode 100644 tests/auto/qml/qqmllanguage/data/cppRequiredPropertyNotSet.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredProperty.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredProperty.qml new file mode 100644 index 0000000000..76673f6409 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppRequiredProperty.qml @@ -0,0 +1,4 @@ +import QtQuick 2.15 +import example.org 1.0 + +MyClass {test: 42} diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParent.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParent.qml new file mode 100644 index 0000000000..d4c059581c --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParent.qml @@ -0,0 +1,4 @@ +import QtQuick 2.15 +import example.org 1.0 + +Child2 {test: test2; test2: 18} diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParentNotSet.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParentNotSet.qml new file mode 100644 index 0000000000..082e22dc3f --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParentNotSet.qml @@ -0,0 +1,4 @@ +import QtQuick 2.15 +import example.org 1.0 + +Child2 { test: 13 } diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParent.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParent.qml new file mode 100644 index 0000000000..6602684542 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParent.qml @@ -0,0 +1,4 @@ +import QtQuick 2.15 +import example.org 1.0 + +Child {test: 42} diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParentNotSet.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParentNotSet.qml new file mode 100644 index 0000000000..5971b0c263 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParentNotSet.qml @@ -0,0 +1,4 @@ +import QtQuick 2.15 +import example.org 1.0 + +Child {} diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyNotSet.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyNotSet.qml new file mode 100644 index 0000000000..dab48a3d71 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyNotSet.qml @@ -0,0 +1,4 @@ +import QtQuick 2.15 +import example.org 1.0 + +MyClass {} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 4d2f773dbf..64696e7f3f 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -133,6 +133,8 @@ private slots: void autoComponentCreationInGroupProperty(); void propertyValueSource(); void requiredProperty(); + void requiredPropertyFromCpp_data(); + void requiredPropertyFromCpp(); void attachedProperties(); void dynamicObjects(); void customVariantTypes(); @@ -1679,6 +1681,75 @@ void tst_qqmllanguage::requiredProperty() } } +class MyClassWithRequiredProperty : public QObject +{ +public: + Q_OBJECT + Q_PROPERTY(int test MEMBER m_test REQUIRED NOTIFY testChanged) + Q_SIGNAL void testChanged(); +private: + int m_test; +}; + +class ChildClassWithoutOwnRequired : public MyClassWithRequiredProperty +{ +public: + Q_OBJECT + Q_PROPERTY(int test2 MEMBER m_test2 NOTIFY test2Changed) + Q_SIGNAL void test2Changed(); +private: + int m_test2; +}; + +class ChildClassWithOwnRequired : public MyClassWithRequiredProperty +{ +public: + Q_OBJECT + Q_PROPERTY(int test2 MEMBER m_test2 REQUIRED NOTIFY test2Changed) + Q_SIGNAL void test2Changed(); +private: + int m_test2; +}; + +void tst_qqmllanguage::requiredPropertyFromCpp_data() +{ + qmlRegisterType("example.org", 1, 0, "MyClass"); + qmlRegisterType("example.org", 1, 0, "Child"); + qmlRegisterType("example.org", 1, 0, "Child2"); + + + QTest::addColumn("setFile"); + QTest::addColumn("notSetFile"); + QTest::addColumn("errorMessage"); + QTest::addColumn("expectedValue"); + + QTest::addRow("direct") << testFileUrl("cppRequiredProperty.qml") << testFileUrl("cppRequiredPropertyNotSet.qml") << QString(":4 Required property test was not initialized\n") << 42; + QTest::addRow("in parent") << testFileUrl("cppRequiredPropertyInParent.qml") << testFileUrl("cppRequiredPropertyInParentNotSet.qml") << QString(":4 Required property test was not initialized\n") << 42; + QTest::addRow("in child and parent") << testFileUrl("cppRequiredPropertyInChildAndParent.qml") << testFileUrl("cppRequiredPropertyInChildAndParentNotSet.qml") << QString(":4 Required property test2 was not initialized\n") << 18; +} + +void tst_qqmllanguage::requiredPropertyFromCpp() +{ + QQmlEngine engine; + QFETCH(QUrl, setFile); + QFETCH(QUrl, notSetFile); + QFETCH(QString, errorMessage); + QFETCH(int, expectedValue); + { + QQmlComponent comp(&engine, notSetFile); + QScopedPointer o { comp.create() }; + QVERIFY(o.isNull()); + QVERIFY(comp.isError()); + QCOMPARE(comp.errorString(), notSetFile.toString() + errorMessage); + } + { + QQmlComponent comp(&engine, setFile); + QScopedPointer o { comp.create() }; + QVERIFY(!o.isNull()); + QCOMPARE(o->property("test").toInt(), expectedValue); + } +} + void tst_qqmllanguage::attachedProperties() { QQmlComponent component(&engine, testFileUrl("attachedProperties.qml")); -- cgit v1.2.3 From a82b1b278ace7a500f95473f2a873923d2d4e60a Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 29 Jan 2020 10:13:08 +0100 Subject: QQuickFlickable: fix division by zero The issue could be seen when enabling exceptions and running the following QML code: Flickable { id: flickable anchors.fill: parent contentWidth: 1000 contentHeight: 1000 Text { text: flickable.visibleArea.xPosition } } Change-Id: I615f9f9dc84903fb3a902f416a55e3ce3fece64c Fixes: QTBUG-81098 Reviewed-by: Ulf Hermann --- .../qquickflickable/data/visibleAreaBinding.qml | 38 ++++++++++++++++++++++ .../quick/qquickflickable/tst_qquickflickable.cpp | 11 +++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/auto/quick/qquickflickable/data/visibleAreaBinding.qml (limited to 'tests') diff --git a/tests/auto/quick/qquickflickable/data/visibleAreaBinding.qml b/tests/auto/quick/qquickflickable/data/visibleAreaBinding.qml new file mode 100644 index 0000000000..6f7bc89793 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/visibleAreaBinding.qml @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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$ +** +****************************************************************************/ + +import QtQuick 2.14 + +Flickable { + id: flickable + // Deliberately has no size set. + + Text { + text: flickable.visibleArea.xPosition + } +} diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index c104eecbcd..da4bf5dae3 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -205,6 +205,7 @@ private slots: void overshoot_reentrant(); void synchronousDrag_data(); void synchronousDrag(); + void visibleAreaBinding(); private: void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to); @@ -2541,6 +2542,16 @@ void tst_qquickflickable::synchronousDrag() QTest::touchEvent(window, touchDevice).release(0, p5, window); } +// QTBUG-81098: tests that a binding to visibleArea doesn't result +// in a division-by-zero exception (when exceptions are enabled). +void tst_qquickflickable::visibleAreaBinding() +{ + QScopedPointer window(new QQuickView); + window->setSource(testFileUrl("visibleAreaBinding.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + // Shouldn't crash. +} + QTEST_MAIN(tst_qquickflickable) #include "tst_qquickflickable.moc" -- cgit v1.2.3 From 19a74ba56e58e007449486b0f545be7415a9f95b Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 29 Jan 2020 12:14:20 +0100 Subject: Fix vertical position of PathText The PathText would always translate to y=0, regardless of what y was set to. We should obviously get the y coordinate of the shape *before* translating it into position to find the distance from the baseline. This change also updates the example, which had not been updated to the changed origin of the PathText, and it adds a Lancelot test for keeping track of the PathText shape rendering. Change-Id: I940ac956af5229842739f8d8751a1f13bb86b8e7 Reviewed-by: Eirik Aavitsland --- .../scenegraph_lancelot/data/shape/shape_text.qml | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tests/manual/scenegraph_lancelot/data/shape/shape_text.qml (limited to 'tests') diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_text.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_text.qml new file mode 100644 index 0000000000..37367054b5 --- /dev/null +++ b/tests/manual/scenegraph_lancelot/data/shape/shape_text.qml @@ -0,0 +1,91 @@ +import QtQuick 2.15 +import QtQuick.Shapes 1.0 + +Item { + width: 320 + height: 480 + + Column { + Item { + width: 200 + height: 160 + + Shape { + anchors.fill: parent + vendorExtensionsEnabled: false + + ShapePath { + fillColor: "transparent" + strokeColor: "blue" + strokeStyle: ShapePath.DashLine + strokeWidth: 4 + + PathText { + x: 96 + y: 10 + font.pixelSize: 120 + text: "Qt" + } + } + } + } + + Item { + width: 200 + height: 160 + + Rectangle { + anchors.fill: parent + color: "blue" + } + + Shape { + anchors.fill: parent + vendorExtensionsEnabled: false + + ShapePath { + fillColor: "red" + strokeColor: "blue" + strokeStyle: ShapePath.DashLine + capStyle: ShapePath.RoundCap + strokeWidth: 8 + + PathText { + x: 96; y: 10 + font.pixelSize: 150 + text: "Qt" + } + } + } + } + + Item { + width: 200 + height: 160 + + Shape { + anchors.fill: parent + vendorExtensionsEnabled: false + + ShapePath { + fillGradient: LinearGradient { + x1: 0; x2: 200; y1: 0; y2: 160 + spread: ShapeGradient.PadSpread + GradientStop { position: 0.0; color: "red"; } + GradientStop { position: 1.0; color: "green"; } + } + strokeColor: "blue" + strokeStyle: ShapePath.DashLine + joinStyle: ShapePath.RoundJoin + strokeWidth: 4 + + PathText { + x: 96; y: 10 + font.pixelSize: 150 + text: "Qt" + } + } + } + } + } +} -- cgit v1.2.3 From da9fee11bbf7842d72bbf7c0cd2072b020c71626 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Wed, 29 Jan 2020 13:22:35 +0100 Subject: Required properties: Allow required default properties This was already possible from C++, this change adds the required changes to the grammar to allow declaring required default properties in QML. Change-Id: I76cb4d70e573bf161676da8295ab257fe95ed4ae Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmlcomponent/data/RequiredDefault.qml | 5 +++++ tests/auto/qml/qqmlcomponent/data/requiredDefault.1.qml | 5 +++++ tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml | 3 +++ tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml | 6 ++++++ tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml | 4 ++++ tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp | 16 ++++++++++++++++ .../auto/qml/qqmllanguage/data/requiredProperties.3.qml | 4 ---- tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 4 ---- 8 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 tests/auto/qml/qqmlcomponent/data/RequiredDefault.qml create mode 100644 tests/auto/qml/qqmlcomponent/data/requiredDefault.1.qml create mode 100644 tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml create mode 100644 tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml create mode 100644 tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml delete mode 100644 tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmlcomponent/data/RequiredDefault.qml b/tests/auto/qml/qqmlcomponent/data/RequiredDefault.qml new file mode 100644 index 0000000000..7e8f225a52 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/RequiredDefault.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +Item { + required default property Text requiredDefault +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredDefault.1.qml b/tests/auto/qml/qqmlcomponent/data/requiredDefault.1.qml new file mode 100644 index 0000000000..68dff22f33 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredDefault.1.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +RequiredDefault { + Text {text: "Hello, world!"} +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml b/tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml new file mode 100644 index 0000000000..a6c4e8ea3f --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml @@ -0,0 +1,3 @@ +import QtQuick 2.15 + +RequiredDefault { } diff --git a/tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml b/tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml new file mode 100644 index 0000000000..19b3271858 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml @@ -0,0 +1,6 @@ +import QtQuick 2.15 +import qt.test 1.0 + +RequiredDefaultCpp { + Text {text: "Hello, world!"} +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml b/tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml new file mode 100644 index 0000000000..acd56db328 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml @@ -0,0 +1,4 @@ +import QtQuick 2.15 +import qt.test 1.0 + +RequiredDefaultCpp { } diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index 2acc62ca28..43cbd93396 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -671,8 +671,20 @@ void tst_qqmlcomponent::setDataNoEngineNoSegfault() QVERIFY(!c); } +class RequiredDefaultCpp : public QObject +{ + Q_OBJECT +public: + Q_PROPERTY(QQuickItem *defaultProperty MEMBER m_defaultProperty NOTIFY defaultPropertyChanged REQUIRED) + Q_SIGNAL void defaultPropertyChanged(); + Q_CLASSINFO("DefaultProperty", "defaultProperty") +private: + QQuickItem *m_defaultProperty = nullptr; +}; + void tst_qqmlcomponent::testRequiredProperties_data() { + qmlRegisterType("qt.test", 1, 0, "RequiredDefaultCpp"); QTest::addColumn("testFile"); QTest::addColumn("shouldSucceed"); QTest::addColumn("errorMsg"); @@ -687,6 +699,10 @@ void tst_qqmlcomponent::testRequiredProperties_data() QTest::addRow("setLater") << testFileUrl("requiredSetLater.qml") << true << ""; QTest::addRow("setViaAliasToSubcomponent") << testFileUrl("setViaAliasToSubcomponent.qml") << true << ""; QTest::addRow("aliasToSubcomponentNotSet") << testFileUrl("aliasToSubcomponentNotSet.qml") << false << "It can be set via the alias property i_alias"; + QTest::addRow("required default set") << testFileUrl("requiredDefault.1.qml") << true << ""; + QTest::addRow("required default not set") << testFileUrl("requiredDefault.2.qml") << false << "Required property requiredDefault was not initialized"; + QTest::addRow("required default set (C++)") << testFileUrl("requiredDefault.3.qml") << true << ""; + QTest::addRow("required default not set (C++)") << testFileUrl("requiredDefault.4.qml") << false << "Required property defaultProperty was not initialized"; } diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml deleted file mode 100644 index 534322215f..0000000000 --- a/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml +++ /dev/null @@ -1,4 +0,0 @@ -import QtQuick 2.13 -Item { - default required property int test // cannot have required default property -} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 64696e7f3f..5027c0825f 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -1675,10 +1675,6 @@ void tst_qqmllanguage::requiredProperty() QQmlComponent component(&engine, testFileUrl("requiredProperties.2.qml")); QVERIFY(!component.errors().empty()); } - { - QQmlComponent component(&engine, testFileUrl("requiredProperties.3.qml")); - QVERIFY(!component.errors().empty()); - } } class MyClassWithRequiredProperty : public QObject -- cgit v1.2.3 From e4e8b27f1a10d023a0e5388890e480754a5ab39d Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 29 Jan 2020 15:30:23 +0100 Subject: tst_qqmlproperty: Avoid memory leaks Change-Id: I38c414edbf75409b3278d89f55f1dbe97fc1fda0 Reviewed-by: Simon Hausmann Reviewed-by: Fabian Kosmale --- tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 62 ++++++++++++------------ 1 file changed, 32 insertions(+), 30 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index f039ccc110..83e173f379 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -1224,10 +1224,10 @@ void tst_qqmlproperty::read() } { QQmlComponent component(&engine, testFileUrl("readSynthesizedObject.qml")); - QObject *object = component.create(); + QScopedPointer object(component.create()); QVERIFY(object != nullptr); - QQmlProperty p(object, "test", &engine); + QQmlProperty p(object.data(), "test", &engine); QCOMPARE(p.propertyTypeCategory(), QQmlProperty::Object); QVERIFY(p.propertyType() != QMetaType::QObjectStar); @@ -1239,10 +1239,10 @@ void tst_qqmlproperty::read() } { // static QQmlComponent component(&engine, testFileUrl("readSynthesizedObject.qml")); - QObject *object = component.create(); + QScopedPointer object(component.create()); QVERIFY(object != nullptr); - QVariant v = QQmlProperty::read(object, "test", &engine); + QVariant v = QQmlProperty::read(object.data(), "test", &engine); QCOMPARE(v.userType(), int(QMetaType::QObjectStar)); QCOMPARE(qvariant_cast(v)->property("a").toInt(), 10); QCOMPARE(qvariant_cast(v)->property("b").toInt(), 19); @@ -1252,41 +1252,38 @@ void tst_qqmlproperty::read() { QQmlComponent component(&engine); component.setData("import Test 1.0\nMyContainer { }", QUrl()); - QObject *object = component.create(); + QScopedPointer object(component.create()); QVERIFY(object != nullptr); - QQmlProperty p(object, "MyContainer.foo", qmlContext(object)); + QQmlProperty p(object.data(), "MyContainer.foo", qmlContext(object.data())); QCOMPARE(p.read(), QVariant(13)); - delete object; } { QQmlComponent component(&engine); component.setData("import Test 1.0\nMyContainer { MyContainer.foo: 10 }", QUrl()); - QObject *object = component.create(); + QScopedPointer object(component.create()); QVERIFY(object != nullptr); - QQmlProperty p(object, "MyContainer.foo", qmlContext(object)); + QQmlProperty p(object.data(), "MyContainer.foo", qmlContext(object.data())); QCOMPARE(p.read(), QVariant(10)); - delete object; } { QQmlComponent component(&engine); component.setData("import Test 1.0 as Foo\nFoo.MyContainer { Foo.MyContainer.foo: 10 }", QUrl()); - QObject *object = component.create(); + QScopedPointer object(component.create()); QVERIFY(object != nullptr); - QQmlProperty p(object, "Foo.MyContainer.foo", qmlContext(object)); + QQmlProperty p(object.data(), "Foo.MyContainer.foo", qmlContext(object.data())); QCOMPARE(p.read(), QVariant(10)); - delete object; } { // static QQmlComponent component(&engine); component.setData("import Test 1.0 as Foo\nFoo.MyContainer { Foo.MyContainer.foo: 10 }", QUrl()); - QObject *object = component.create(); + QScopedPointer object(component.create()); QVERIFY(object != nullptr); - QCOMPARE(QQmlProperty::read(object, "Foo.MyContainer.foo", qmlContext(object)), QVariant(10)); - delete object; + QCOMPARE(QQmlProperty::read(object.data(), "Foo.MyContainer.foo", + qmlContext(object.data())), QVariant(10)); } } @@ -1447,11 +1444,12 @@ void tst_qqmlproperty::write() { // QChar -> QString QQmlComponent component(&engine); component.setData("import Test 1.0\nPropertyObject { stringProperty: constQChar }", QUrl()); - PropertyObject *obj = qobject_cast(component.create()); - QVERIFY(obj != nullptr); - if (obj) { - QQmlProperty stringProperty(obj, "stringProperty"); - QCOMPARE(stringProperty.read(), QVariant(QString(obj->constQChar()))); + QScopedPointer object(component.create()); + PropertyObject *propertyObject = qobject_cast(object.data()); + QVERIFY(propertyObject != nullptr); + if (propertyObject) { + QQmlProperty stringProperty(propertyObject, "stringProperty"); + QCOMPARE(stringProperty.read(), QVariant(QString(propertyObject->constQChar()))); } } @@ -1628,29 +1626,32 @@ void tst_qqmlproperty::writeObjectToList() { QQmlComponent containerComponent(&engine); containerComponent.setData("import Test 1.0\nMyContainer { children: MyQmlObject {} }", QUrl()); - MyContainer *container = qobject_cast(containerComponent.create()); + QScopedPointer object(containerComponent.create()); + MyContainer *container = qobject_cast(object.data()); QVERIFY(container != nullptr); QQmlListReference list(container, "children"); QCOMPARE(list.count(), 1); - MyQmlObject *object = new MyQmlObject; + QScopedPointer childObject(new MyQmlObject); QQmlProperty prop(container, "children"); - prop.write(QVariant::fromValue(object)); + prop.write(QVariant::fromValue(childObject.data())); QCOMPARE(list.count(), 1); - QCOMPARE(list.at(0), qobject_cast(object)); + QCOMPARE(list.at(0), qobject_cast(childObject.data())); } void tst_qqmlproperty::writeListToList() { QQmlComponent containerComponent(&engine); containerComponent.setData("import Test 1.0\nMyContainer { children: MyQmlObject {} }", QUrl()); - MyContainer *container = qobject_cast(containerComponent.create()); + QScopedPointer object(containerComponent.create()); + MyContainer *container = qobject_cast(object.data()); QVERIFY(container != nullptr); QQmlListReference list(container, "children"); QCOMPARE(list.count(), 1); QList objList; - objList << new MyQmlObject() << new MyQmlObject() << new MyQmlObject() << new MyQmlObject(); + objList << new MyQmlObject(this) << new MyQmlObject(this) + << new MyQmlObject(this) << new MyQmlObject(this); QQmlProperty prop(container, "children"); prop.write(QVariant::fromValue(objList)); QCOMPARE(list.count(), 4); @@ -1828,10 +1829,11 @@ void tst_qqmlproperty::crashOnValueProperty() QQmlComponent component(engine); component.setData("import Test 1.0\nPropertyObject { wrectProperty.x: 10 }", QUrl()); - PropertyObject *obj = qobject_cast(component.create()); - QVERIFY(obj != nullptr); + QScopedPointer object(component.create()); + PropertyObject *propertyObject = qobject_cast(object.data()); + QVERIFY(propertyObject != nullptr); - QQmlProperty p(obj, "wrectProperty.x", qmlContext(obj)); + QQmlProperty p(propertyObject, "wrectProperty.x", qmlContext(propertyObject)); QCOMPARE(p.name(), QString("wrectProperty.x")); QCOMPARE(p.read(), QVariant(10)); -- cgit v1.2.3 From e080f48f905be597b1a645f1641b2b06553df6a2 Mon Sep 17 00:00:00 2001 From: Maximilian Goldstein Date: Fri, 17 Jan 2020 14:28:09 +0100 Subject: qmlformat: Support even more language features Adds support (among other things) for: - Pragmas - Type annotations - get / set properties - Some previously unsupported escape sequences (\b,\v...) - Calling methods on numeric literals Also now checks whether the dumped code is still parsable. Change-Id: Ia142a7c0b3e608115e79c1d98a62b682dce4eec9 Reviewed-by: Ulf Hermann --- .../qmlformat/data/Example1.formatted.nosort.qml | 8 +++--- .../auto/qml/qmlformat/data/Example1.formatted.qml | 8 +++--- .../qml/qmlformat/data/readOnlyProps.formatted.qml | 29 ++++++++++++++++++++++ tests/auto/qml/qmlformat/data/readOnlyProps.qml | 15 +++++++++++ tests/auto/qml/qmlformat/tst_qmlformat.cpp | 11 ++++++++ 5 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml create mode 100644 tests/auto/qml/qmlformat/data/readOnlyProps.qml (limited to 'tests') diff --git a/tests/auto/qml/qmlformat/data/Example1.formatted.nosort.qml b/tests/auto/qml/qmlformat/data/Example1.formatted.nosort.qml index 080cec438e..34d58cf571 100644 --- a/tests/auto/qml/qmlformat/data/Example1.formatted.nosort.qml +++ b/tests/auto/qml/qmlformat/data/Example1.formatted.nosort.qml @@ -91,11 +91,11 @@ Item { x = 100; break; } - if (x == 50) + if (x == 50) console.log("true"); - else if (x == 50) + else if (x == 50) console.log("other thing"); - else + else console.log("false"); if (x == 50) { @@ -132,6 +132,7 @@ Item { Rectangle { } ] + Text { required property string batman @@ -143,6 +144,7 @@ Item { // This comment is related to the property animation PropertyAnimation on x { id: foo + x: 3 y: x + 3 } diff --git a/tests/auto/qml/qmlformat/data/Example1.formatted.qml b/tests/auto/qml/qmlformat/data/Example1.formatted.qml index 4b65b9add6..b06734eb0b 100644 --- a/tests/auto/qml/qmlformat/data/Example1.formatted.qml +++ b/tests/auto/qml/qmlformat/data/Example1.formatted.qml @@ -91,11 +91,11 @@ Item { x = 100; break; } - if (x == 50) + if (x == 50) console.log("true"); - else if (x == 50) + else if (x == 50) console.log("other thing"); - else + else console.log("false"); if (x == 50) { @@ -132,6 +132,7 @@ Item { Rectangle { } ] + Text { required property string batman @@ -143,6 +144,7 @@ Item { // This comment is related to the property animation PropertyAnimation on x { id: foo + x: 3 y: x + 3 } diff --git a/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml b/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml new file mode 100644 index 0000000000..6e7cc31dcf --- /dev/null +++ b/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +QtObject { + // Testing UiObjectBinding + readonly property Item + item: Item { + id: test + + signal foo() + } + // End comment + + // Testing UiArrayBinding + readonly property list array: [ + Item { + id: test1 + + signal foo() + }, + Item { + id: test2 + + signal bar() + } + ] + // Testing UiScriptBinding + readonly property int script: Math.sin(Math.PI) + property bool normalProperty: true +} diff --git a/tests/auto/qml/qmlformat/data/readOnlyProps.qml b/tests/auto/qml/qmlformat/data/readOnlyProps.qml new file mode 100644 index 0000000000..8a32dd131e --- /dev/null +++ b/tests/auto/qml/qmlformat/data/readOnlyProps.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +QtObject { + // Testing UiObjectBinding + readonly property Item item: Item { id: test; signal foo() } + // End comment + + // Testing UiArrayBinding + readonly property list array: [ Item { id: test1; signal foo() }, Item { id: test2; signal bar() } ] + + // Testing UiScriptBinding + readonly property int script: Math.sin(Math.PI) + + property bool normalProperty: true +} diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp index 95c8e88f21..3201fa5ace 100644 --- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp +++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp @@ -42,6 +42,7 @@ private Q_SLOTS: void testFormat(); void testFormatNoSort(); + void testReadOnlyProps(); #if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void testExample(); @@ -120,6 +121,11 @@ void TestQmlformat::initTestCase() m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/typeAnnotations.2.qml"; m_invalidFiles << "tests/auto/qml/qqmlparser/data/disallowedtypeannotations/qmlnestedfunction.qml"; + + // These files rely on exact formatting + m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon1.qml"; + m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon_error1.qml"; + m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon2.qml"; } QStringList TestQmlformat::findFiles(const QDir &d) @@ -178,6 +184,11 @@ void TestQmlformat::testFormatNoSort() QCOMPARE(runQmlformat(testFile("Example1.qml"), false, true), readTestFile("Example1.formatted.nosort.qml")); } +void TestQmlformat::testReadOnlyProps() +{ + QCOMPARE(runQmlformat(testFile("readOnlyProps.qml"), false, true), readTestFile("readOnlyProps.formatted.qml")); +} + #if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void TestQmlformat::testExample_data() { -- cgit v1.2.3 From c5f78add12b7d33926631b6df79599df18f65068 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 28 Jan 2020 16:26:49 +0100 Subject: Reduce Qt Declarative's use of QDateTime's locale-dependent APIs [ChangeLog][QtQml] Qt.formatDateTime, Qt.formatDate and Qt.formatTime now support formatting according to a locale and an optional locale format type. If locale dependent formatting is desired, this method should be used instead of the locale-related DateFormat enum members. Fixes: QTBUG-81631 Change-Id: I971231644ebbeaccbf54dd8f036adf4d31547301 Reviewed-by: Edward Welbourne --- tests/auto/qml/qqmlqt/data/formattingLocale.qml | 12 ++++++ tests/auto/qml/qqmlqt/tst_qqmlqt.cpp | 52 +++++++++++++++++++------ 2 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 tests/auto/qml/qqmlqt/data/formattingLocale.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmlqt/data/formattingLocale.qml b/tests/auto/qml/qqmlqt/data/formattingLocale.qml new file mode 100644 index 0000000000..9da349b101 --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/formattingLocale.qml @@ -0,0 +1,12 @@ +import QtQml 2.15 + +QtObject { + required property var myDateTime + required property var myDate + property var myTime + + property string dateTimeString: Qt.formatDateTime(myDateTime, Qt.locale("de_DE"), Locale.NarrowFormat) + property string dateString: Qt.formatDate(myDate, Qt.locale("de_DE")) + + function invalidUsage() { Qt.formatTime(myTime, null, "hello") } +} diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index 15ef31464b..1a54397f1a 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -91,6 +91,7 @@ private slots: void dateTimeFormatting_data(); void dateTimeFormattingVariants(); void dateTimeFormattingVariants_data(); + void dateTimeFormattingWithLocale(); void isQtObject(); void btoa(); void atob(); @@ -780,12 +781,12 @@ void tst_qqmlqt::dateTimeFormatting() QQmlComponent component(&eng, testFileUrl("formatting.qml")); QStringList warnings; - warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Invalid date format" - << component.url().toString() + ":36: Error: Qt.formatDate(): Invalid arguments" - << component.url().toString() + ":40: Error: Qt.formatTime(): Invalid time format" - << component.url().toString() + ":39: Error: Qt.formatTime(): Invalid arguments" - << component.url().toString() + ":43: Error: Qt.formatDateTime(): Invalid datetime format" - << component.url().toString() + ":42: Error: Qt.formatDateTime(): Invalid arguments"; + warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Bad second argument (must be either string, number or locale)" + << component.url().toString() + ":36: Error: Qt.formatDate(): Missing argument" + << component.url().toString() + ":40: Error: Qt.formatTime(): Bad second argument (must be either string, number or locale)" + << component.url().toString() + ":39: Error: Qt.formatTime(): Missing argument" + << component.url().toString() + ":43: Error: Qt.formatDateTime(): Bad second argument (must be either string, number or locale)" + << component.url().toString() + ":42: Error: Qt.formatDateTime(): Missing argument"; foreach (const QString &warning, warnings) QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); @@ -815,6 +816,8 @@ void tst_qqmlqt::dateTimeFormatting() void tst_qqmlqt::dateTimeFormatting_data() { + QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED + // Test intentionally uses deprecated enumerators from Qt::DateFormat QTest::addColumn("method"); QTest::addColumn("inputProperties"); QTest::addColumn("expectedResults"); @@ -844,6 +847,7 @@ void tst_qqmlqt::dateTimeFormatting_data() << (QStringList() << dateTime.toString(Qt::DefaultLocaleShortDate) << dateTime.toString(Qt::DefaultLocaleLongDate) << dateTime.toString("M/d/yy H:m:s a")); + QT_WARNING_POP } void tst_qqmlqt::dateTimeFormattingVariants() @@ -856,12 +860,12 @@ void tst_qqmlqt::dateTimeFormattingVariants() QQmlComponent component(&eng, testFileUrl("formatting.qml")); QStringList warnings; - warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Invalid date format" - << component.url().toString() + ":36: Error: Qt.formatDate(): Invalid arguments" - << component.url().toString() + ":40: Error: Qt.formatTime(): Invalid time format" - << component.url().toString() + ":39: Error: Qt.formatTime(): Invalid arguments" - << component.url().toString() + ":43: Error: Qt.formatDateTime(): Invalid datetime format" - << component.url().toString() + ":42: Error: Qt.formatDateTime(): Invalid arguments"; + warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Bad second argument (must be either string, number or locale)" + << component.url().toString() + ":36: Error: Qt.formatDate(): Missing argument" + << component.url().toString() + ":40: Error: Qt.formatTime(): Bad second argument (must be either string, number or locale)" + << component.url().toString() + ":39: Error: Qt.formatTime(): Missing argument" + << component.url().toString() + ":43: Error: Qt.formatDateTime(): Bad second argument (must be either string, number or locale)" + << component.url().toString() + ":42: Error: Qt.formatDateTime(): Missing argument"; foreach (const QString &warning, warnings) QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); @@ -882,6 +886,8 @@ void tst_qqmlqt::dateTimeFormattingVariants() void tst_qqmlqt::dateTimeFormattingVariants_data() { + QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED + // Test intentionally uses deprecated enumerators from Qt::DateFormat QTest::addColumn("method"); QTest::addColumn("variant"); QTest::addColumn("expectedResults"); @@ -922,6 +928,28 @@ void tst_qqmlqt::dateTimeFormattingVariants_data() QTest::newRow("formatDate, int") << "formatDate" << QVariant::fromValue(integer) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy")); QTest::newRow("formatDateTime, int") << "formatDateTime" << QVariant::fromValue(integer) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a")); QTest::newRow("formatTime, int") << "formatTime" << QVariant::fromValue(integer) << (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")); + QT_WARNING_POP +} + +void tst_qqmlqt::dateTimeFormattingWithLocale() +{ + QQmlEngine engine; + auto url = testFileUrl("formattingLocale.qml"); + QQmlComponent comp(&engine, url); + QDateTime dateTime = QDateTime::fromString("M1d1y9800:01:02", + "'M'M'd'd'y'yyhh:mm:ss"); + QDate date(1995, 5, 17); + QScopedPointer o(comp.createWithInitialProperties({ {"myDateTime", dateTime}, {"myDate", date} })); + QVERIFY(!o.isNull()); + + auto dateTimeString = o->property("dateTimeString").toString(); + QCOMPARE(dateTimeString, QLocale("de_DE").toString(dateTime, QLocale::NarrowFormat)); + auto dateString = o->property("dateString").toString(); + QCOMPARE(dateString, QLocale("de_DE").toString(date, QLocale::ShortFormat)); + + QString warningMsg = url.toString() + QLatin1String(":11: Error: Qt.formatTime(): Third argument must be a Locale format option"); + QTest::ignoreMessage(QtMsgType::QtWarningMsg, warningMsg.toUtf8().constData()); + QMetaObject::invokeMethod(o.get(), "invalidUsage"); } void tst_qqmlqt::isQtObject() -- cgit v1.2.3 From 01660fbb67c39c74b2e1eeae1e3d1b97c8886cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Tue, 3 Dec 2019 11:52:55 +0100 Subject: Fix some ListView bugs related to snapping when it had a header Most bugs were related to the PullBackHeader header positining mode, for instance the old code did not take into consideration that for the PullBackHeader it was sometimes not sufficient to scroll the view. The header also had to be scrolled independently from the view: We achieve this by hooking on to the same timeline that is used for scrolling the view. (This way, both animations are synchronized, and they start and end at the same time). Change-Id: I75708c0fd8d4741032c04ad9ee144d7a49cf3359 Fixes: QTBUG-76362 Reviewed-by: Shawn Rutledge --- .../quick/qquicklistview/data/headerSnapToItem.qml | 67 +++ .../quick/qquicklistview/tst_qquicklistview.cpp | 601 +++++++++++++++++++++ 2 files changed, 668 insertions(+) create mode 100644 tests/auto/quick/qquicklistview/data/headerSnapToItem.qml (limited to 'tests') diff --git a/tests/auto/quick/qquicklistview/data/headerSnapToItem.qml b/tests/auto/quick/qquicklistview/data/headerSnapToItem.qml new file mode 100644 index 0000000000..1e5a811630 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/headerSnapToItem.qml @@ -0,0 +1,67 @@ +import QtQuick 2.12 + +Rectangle { + + width: 240 + height: 320 + color: "#ffffff" + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: list.orientation == ListView.Vertical ? 240 : 20 + height: list.orientation == ListView.Vertical ? 20 : 240 + border.width: 1 + border.color: "black" + Text { + text: index + ":" + (list.orientation == ListView.Vertical ? parent.y : parent.x).toFixed(0) + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 200 + clip: true + snapMode: ListView.SnapToItem + headerPositioning: ListView.OverlayHeader + model: 30 + delegate: myDelegate + orientation: ListView.Vertical + verticalLayoutDirection: ListView.BottomToTop + + header: Rectangle { + width: list.orientation == Qt.Vertical ? 240 : 30 + height: list.orientation == Qt.Vertical ? 30 : 240 + objectName: "header"; + color: "green" + z: 11 + Text { + anchors.centerIn: parent + text: "header " + (list.orientation == ListView.Vertical ? parent.y : parent.x).toFixed(1) + } + } + } + + Rectangle { + color: "red" + opacity: 0.5 + width: txt.implicitWidth + 50 + height: txt.implicitHeight + anchors.bottom: parent.bottom + anchors.right: parent.right + + Text { + id: txt + anchors.centerIn: parent + text: "header position: " + (list.orientation == ListView.Vertical ? list.headerItem.y : list.headerItem.x).toFixed(1) + + "\ncontent position: " + (list.orientation == ListView.Vertical ? list.contentY : list.contentX).toFixed(1) + } + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 3687c9416e..20d71aa0d7 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -183,6 +184,8 @@ private slots: void creationContext(); void snapToItem_data(); void snapToItem(); + void headerSnapToItem_data(); + void headerSnapToItem(); void snapToItemWithSpacing_QTBUG_59852(); void snapOneItemResize_QTBUG_43555(); void snapOneItem_data(); @@ -5395,6 +5398,604 @@ void tst_QQuickListView::snapToItemWithSpacing_QTBUG_59852() releaseView(window); } +static void drag_helper(QWindow *window, QPoint *startPos, const QPoint &delta) +{ + QPoint pos = *startPos; + int dragDistance = delta.manhattanLength(); + Q_ASSERT(qAbs(delta.x()) >= 1 || qAbs(delta.y()) >= 1); + + const int stepSize = 8; + QPoint unitVector(0, 0); + if (delta.x()) + unitVector.setX(qBound(-1, delta.x(), 1)); + if (delta.y()) + unitVector.setY(qBound(-1, delta.y(), 1)); + QPoint dragStepSize = unitVector * stepSize; + int nDragSteps = qAbs(dragDistance/stepSize); + + for (int i = 0 ; i < nDragSteps; ++i) { + QTest::mouseMove(window, pos); + pos += dragStepSize; + } + // Move to the final position + pos = *startPos + delta; + QTest::mouseMove(window, pos); + *startPos = pos; +} + +static void dragtwice(QWindow *window, QPoint *startPos, const QPoint &delta1, const QPoint &delta2) +{ + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + QPoint &pos = *startPos; + QPoint unitVector(0, 0); + if (delta1.x()) + unitVector.setX(qBound(-1, delta1.x(), 1)); + if (delta1.y()) + unitVector.setY(qBound(-1, delta1.y(), 1)); + + // go just beyond the drag theshold + drag_helper(window, &pos, unitVector * (dragThreshold + 1)); + drag_helper(window, &pos, unitVector); + + // next drag will actually scroll the listview + if (delta1.manhattanLength() >= 1) + drag_helper(window, &pos, delta1); + if (delta2.manhattanLength() >= 1) + drag_helper(window, &pos, delta2); +} + +struct MyListView : public QQuickListView{ + qreal contentPosition() const + { + return (orientation() == QQuickListView::Horizontal ? contentX(): contentY()); + } + + qreal headerPosition() const + { + return (orientation() == QQuickListView::Horizontal ? headerItem()->x() : headerItem()->y()); + } +}; + +void tst_QQuickListView::headerSnapToItem() +{ + QFETCH(QQuickItemView::LayoutDirection, layoutDirection); + QFETCH(QQuickListView::HeaderPositioning, headerPositioning); + QFETCH(int, firstDragDistance); + QFETCH(int, secondDragDistance); + QFETCH(int, expectedContentPosition); + QFETCH(int, expectedHeaderPosition); + + QQuickView *window = getView(); + window->setSource(testFileUrl("headerSnapToItem.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + MyListView *listview = static_cast(findItem(window->rootObject(), "list")); + QVERIFY(listview != nullptr); + + const bool horizontal = layoutDirection < QQuickItemView::VerticalTopToBottom; + listview->setOrientation(horizontal ? QQuickListView::Horizontal : QQuickListView::Vertical); + + if (horizontal) + listview->setLayoutDirection(static_cast(layoutDirection)); + else + listview->setVerticalLayoutDirection(static_cast(layoutDirection)); + + listview->setHeaderPositioning(headerPositioning); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != nullptr); + QQuickItem *header = findItem(contentItem, "header"); + QVERIFY(header != nullptr); + QCOMPARE(header, listview->headerItem()); + + QPoint startPos = (QPointF(listview->width(), listview->height())/2).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, startPos, 200); + + QPoint firstDragDelta(0, firstDragDistance); + QPoint secondDragDelta = QPoint(0, secondDragDistance); + if (horizontal) { + firstDragDelta = firstDragDelta.transposed(); + secondDragDelta = secondDragDelta.transposed(); + } + + dragtwice(window, &startPos, firstDragDelta, secondDragDelta); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, startPos, 200); // Wait 200 ms before we release to avoid trigger a flick + + // wait for the "fixup" animation to finish + QTest::qWaitFor([&]() + { return !listview->isMoving();} + ); + + QCOMPARE(listview->contentPosition(), expectedContentPosition); + QCOMPARE(listview->headerPosition(), expectedHeaderPosition); +} + +void tst_QQuickListView::headerSnapToItem_data() +{ + QTest::addColumn("layoutDirection"); + QTest::addColumn("headerPositioning"); + QTest::addColumn("firstDragDistance"); + QTest::addColumn("secondDragDistance"); + QTest::addColumn("expectedContentPosition"); + QTest::addColumn("expectedHeaderPosition"); + + // -------------------- + // InlineHeader TopToBottom + QTest::newRow("InlineHeader TopToBottom -10") << QQuickItemView::VerticalTopToBottom + << QQuickListView::InlineHeader + << -10 << 0 + << -30 << -30; + + QTest::newRow("InlineHeader TopToBottom -14") << QQuickItemView::VerticalTopToBottom + << QQuickListView::InlineHeader + << -14 << 0 + << -30 << -30; + + QTest::newRow("InlineHeader TopToBottom -16") << QQuickItemView::VerticalTopToBottom + << QQuickListView::InlineHeader + << -16 << 0 + << 0 << -30; + + QTest::newRow("InlineHeader TopToBottom -30") << QQuickItemView::VerticalTopToBottom + << QQuickListView::InlineHeader + << -30 << 0 + << 0 << -30; + + QTest::newRow("InlineHeader TopToBottom -39") << QQuickItemView::VerticalTopToBottom + << QQuickListView::InlineHeader + << -39 << 0 + << 0 << -30; + + QTest::newRow("InlineHeader TopToBottom -41") << QQuickItemView::VerticalTopToBottom + << QQuickListView::InlineHeader + << -41 << 0 + << 20 << -30; + + QTest::newRow("InlineHeader TopToBottom -65+10") << QQuickItemView::VerticalTopToBottom + << QQuickListView::InlineHeader + << -65 << 10 + << 20 << -30; + + // -------------------- + // InlineHeader BottomToTop + QTest::newRow("InlineHeader BottomToTop +10") << QQuickItemView::VerticalBottomToTop + << QQuickListView::InlineHeader + << 10 << 0 + << -170 << 0; + + QTest::newRow("InlineHeader BottomToTop +14") << QQuickItemView::VerticalBottomToTop + << QQuickListView::InlineHeader + << 14 << 0 + << -170 << 0; + + QTest::newRow("InlineHeader BottomToTop +16") << QQuickItemView::VerticalBottomToTop + << QQuickListView::InlineHeader + << 16 << 0 + << -200 << 0; + + QTest::newRow("InlineHeader BottomToTop +30") << QQuickItemView::VerticalBottomToTop + << QQuickListView::InlineHeader + << 30 << 0 + << -200 << 0; + + QTest::newRow("InlineHeader BottomToTop +39") << QQuickItemView::VerticalBottomToTop + << QQuickListView::InlineHeader + << 39 << 0 + << -200 << 0; + + QTest::newRow("InlineHeader BottomToTop +41") << QQuickItemView::VerticalBottomToTop + << QQuickListView::InlineHeader + << 41 << 0 + << -220 << 0; + + QTest::newRow("InlineHeader BottomToTop +65-10") << QQuickItemView::VerticalBottomToTop + << QQuickListView::InlineHeader + << 65 << -10 + << -220 << 0; + + // -------------------- + // InlineHeader LeftToRight + QTest::newRow("InlineHeader LeftToRight -10") << QQuickItemView::LeftToRight + << QQuickListView::InlineHeader + << -10 << 0 + << -30 << -30; + + QTest::newRow("InlineHeader LeftToRight -14") << QQuickItemView::LeftToRight + << QQuickListView::InlineHeader + << -14 << 0 + << -30 << -30; + + QTest::newRow("InlineHeader LeftToRight -16") << QQuickItemView::LeftToRight + << QQuickListView::InlineHeader + << -16 << 0 + << 0 << -30; + + QTest::newRow("InlineHeader LeftToRight -30") << QQuickItemView::LeftToRight + << QQuickListView::InlineHeader + << -30 << 0 + << 0 << -30; + + QTest::newRow("InlineHeader LeftToRight -39") << QQuickItemView::LeftToRight + << QQuickListView::InlineHeader + << -39 << 0 + << 0 << -30; + + QTest::newRow("InlineHeader LeftToRight -41") << QQuickItemView::LeftToRight + << QQuickListView::InlineHeader + << -41 << 0 + << 20 << -30; + + QTest::newRow("InlineHeader LeftToRight -65+10") << QQuickItemView::LeftToRight + << QQuickListView::InlineHeader + << -65 << 10 + << 20 << -30; + + // -------------------- + // InlineHeader RightToLeft + QTest::newRow("InlineHeader RightToLeft +10") << QQuickItemView::RightToLeft + << QQuickListView::InlineHeader + << 10 << 0 + << -210 << 0; + + QTest::newRow("InlineHeader RightToLeft +14") << QQuickItemView::RightToLeft + << QQuickListView::InlineHeader + << 14 << 0 + << -210 << 0; + + QTest::newRow("InlineHeader RightToLeft +16") << QQuickItemView::RightToLeft + << QQuickListView::InlineHeader + << 16 << 0 + << -240 << 0; + + QTest::newRow("InlineHeader RightToLeft +30") << QQuickItemView::RightToLeft + << QQuickListView::InlineHeader + << 30 << 0 + << -240 << 0; + + QTest::newRow("InlineHeader RightToLeft +39") << QQuickItemView::RightToLeft + << QQuickListView::InlineHeader + << 39 << 0 + << -240 << 0; + + QTest::newRow("InlineHeader RightToLeft +41") << QQuickItemView::RightToLeft + << QQuickListView::InlineHeader + << 41 << 0 + << -260 << 0; + + QTest::newRow("InlineHeader RightToLeft +65-10") << QQuickItemView::RightToLeft + << QQuickListView::InlineHeader + << 65 << -10 + << -260 << 0; + + // -------------------- + // OverlayHeader TopToBottom + QTest::newRow("OverlayHeader TopToBottom +9") << QQuickItemView::VerticalTopToBottom + << QQuickListView::OverlayHeader + << 9 << 0 + << -30 << -30; + + QTest::newRow("OverlayHeader TopToBottom -9") << QQuickItemView::VerticalTopToBottom + << QQuickListView::OverlayHeader + << -9 << 0 + << -30 << -30; + + QTest::newRow("OverlayHeader TopToBottom -11") << QQuickItemView::VerticalTopToBottom + << QQuickListView::OverlayHeader + << -11 << 0 + << -10 << -10; + + QTest::newRow("OverlayHeader TopToBottom -29") << QQuickItemView::VerticalTopToBottom + << QQuickListView::OverlayHeader + << -29 << 0 + << -10 << -10; + + QTest::newRow("OverlayHeader TopToBottom -31") << QQuickItemView::VerticalTopToBottom + << QQuickListView::OverlayHeader + << -31 << 0 + << 10 << 10; + + // -------------------- + // OverlayHeader BottomToTop + QTest::newRow("OverlayHeader BottomToTop -9") << QQuickItemView::VerticalBottomToTop + << QQuickListView::OverlayHeader + << -9 << 0 + << -170 << 0; + + QTest::newRow("OverlayHeader BottomToTop +9") << QQuickItemView::VerticalBottomToTop + << QQuickListView::OverlayHeader + << 9 << 0 + << -170 << 0; + + QTest::newRow("OverlayHeader BottomToTop +11") << QQuickItemView::VerticalBottomToTop + << QQuickListView::OverlayHeader + << 11 << 0 + << -190 << -20; + + QTest::newRow("OverlayHeader BottomToTop +29") << QQuickItemView::VerticalBottomToTop + << QQuickListView::OverlayHeader + << 29 << 0 + << -190 << -20; + + QTest::newRow("OverlayHeader BottomToTop +31") << QQuickItemView::VerticalBottomToTop + << QQuickListView::OverlayHeader + << 31 << 0 + << -210 << -40; + + // -------------------- + // OverlayHeader LeftToRight + QTest::newRow("OverlayHeader LeftToRight +9") << QQuickItemView::LeftToRight + << QQuickListView::OverlayHeader + << 9 << 0 + << -30 << -30; + + QTest::newRow("OverlayHeader LeftToRight -9") << QQuickItemView::LeftToRight + << QQuickListView::OverlayHeader + << -9 << 0 + << -30 << -30; + + QTest::newRow("OverlayHeader LeftToRight -11") << QQuickItemView::LeftToRight + << QQuickListView::OverlayHeader + << -11 << 0 + << -10 << -10; + + QTest::newRow("OverlayHeader LeftToRight -29") << QQuickItemView::LeftToRight + << QQuickListView::OverlayHeader + << -29 << 0 + << -10 << -10; + + QTest::newRow("OverlayHeader LeftToRight -31") << QQuickItemView::LeftToRight + << QQuickListView::OverlayHeader + << -31 << 0 + << 10 << 10; + + // -------------------- + // OverlayHeader RightToLeft + QTest::newRow("OverlayHeader RightToLeft -9") << QQuickItemView::RightToLeft + << QQuickListView::OverlayHeader + << -9 << 0 + << -210 << 0; + + QTest::newRow("OverlayHeader RightToLeft +9") << QQuickItemView::RightToLeft + << QQuickListView::OverlayHeader + << 9 << 0 + << -210 << 0; + + QTest::newRow("OverlayHeader RightToLeft +11") << QQuickItemView::RightToLeft + << QQuickListView::OverlayHeader + << 11 << 0 + << -230 << -20; + + QTest::newRow("OverlayHeader RightToLeft +29") << QQuickItemView::RightToLeft + << QQuickListView::OverlayHeader + << 29 << 0 + << -230 << -20; + + QTest::newRow("OverlayHeader RightToLeft +31") << QQuickItemView::RightToLeft + << QQuickListView::OverlayHeader + << 31 << 0 + << -250 << -40; + + // -------------------- + // PullbackHeader TopToBottom + QTest::newRow("PullbackHeader TopToBottom -2") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -2 << 0 + << -30 << -30; + + QTest::newRow("PullbackHeader TopToBottom -10") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -10 << 0 + << -30 << -30; + + QTest::newRow("PullbackHeader TopToBottom -11") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -11 << 0 + << -10 << -10; + + QTest::newRow("PullbackHeader TopToBottom -14") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -14 << 0 + << -10 << -10; + + QTest::newRow("PullbackHeader TopToBottom -16") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -16 << 0 + << 0 << -30; + + QTest::newRow("PullbackHeader TopToBottom -20") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -20 << 0 + << 0 << -30; + + QTest::newRow("PullbackHeader TopToBottom -65+10") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -65 << 10 + << 20 << -10; + + QTest::newRow("PullbackHeader TopToBottom -65+20") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -65 << 20 + << 10 << 10; + + // Should move header even if contentY doesn't move (its aligned with top) + QTest::newRow("PullbackHeader TopToBottom -55+5") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -55 << 5 + << 20 << -10; + + // Should move header even if contentY doesn't move (it's aligned with header) + QTest::newRow("PullbackHeader TopToBottom -76+16") << QQuickItemView::VerticalTopToBottom + << QQuickListView::PullBackHeader + << -76 << 16 + << 30 << 30; + + // -------------------- + // PullbackHeader BottomToTop + QTest::newRow("PullbackHeader BottomToTop +2") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << +2 << 0 + << -170 << 0; + + QTest::newRow("PullbackHeader BottomToTop +9") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << +9 << 0 + << -170 << 0; + + QTest::newRow("PullbackHeader BottomToTop +11") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << +11 << 0 + << -190 << -20; + + QTest::newRow("PullbackHeader BottomToTop +14") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << +14 << 0 + << -190 << -20; + + QTest::newRow("PullbackHeader BottomToTop +16") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << +16 << 0 + << -200 << 0; + + QTest::newRow("PullbackHeader BottomToTop +20") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << +20 << 0 + << -200 << 0; + + QTest::newRow("PullbackHeader BottomToTop +65-10") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << +65 << -10 + << -220 << -20; + + QTest::newRow("PullbackHeader BottomToTop +65-20") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << +65 << -20 + << -210 << -40; + + // Should move header even if contentY doesn't move (it's aligned with top) + QTest::newRow("PullbackHeader BottomToTop +55-5") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << 55 << -5 + << -220 << -20; + + // Should move header even if contentY doesn't move (it's aligned with header) + QTest::newRow("PullbackHeader BottomToTop +76-16") << QQuickItemView::VerticalBottomToTop + << QQuickListView::PullBackHeader + << 76 << -16 + << -230 << -60; + + // -------------------- + // PullbackHeader LeftToRight + QTest::newRow("PullbackHeader LeftToRight -2") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -2 << 0 + << -30 << -30; + + QTest::newRow("PullbackHeader LeftToRight -10") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -10 << 0 + << -30 << -30; + + QTest::newRow("PullbackHeader LeftToRight -11") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -11 << 0 + << -10 << -10; + + QTest::newRow("PullbackHeader LeftToRight -14") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -14 << 0 + << -10 << -10; + + QTest::newRow("PullbackHeader LeftToRight -16") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -16 << 0 + << 0 << -30; + + QTest::newRow("PullbackHeader LeftToRight -20") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -20 << 0 + << 0 << -30; + + QTest::newRow("PullbackHeader LeftToRight -65+10") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -65 << 10 + << 20 << -10; + + QTest::newRow("PullbackHeader LeftToRight -65+20") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -65 << 20 + << 10 << 10; + + // Should move header even if contentX doesn't move (its aligned with top) + QTest::newRow("PullbackHeader LeftToRight -55+5") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -55 << 5 + << 20 << -10; + + // Should move header even if contentX doesn't move (it's aligned with header) + QTest::newRow("PullbackHeader LeftToRight -76+16") << QQuickItemView::LeftToRight + << QQuickListView::PullBackHeader + << -76 << 16 + << 30 << 30; + + // -------------------- + // PullbackHeader RightToLeft + QTest::newRow("PullbackHeader RightToLeft +2") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << +2 << 0 + << -210 << 0; + + QTest::newRow("PullbackHeader RightToLeft +9") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << +9 << 0 + << -210 << 0; + + QTest::newRow("PullbackHeader RightToLeft +11") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << +11 << 0 + << -230 << -20; + + QTest::newRow("PullbackHeader RightToLeft +14") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << +14 << 0 + << -230 << -20; + + QTest::newRow("PullbackHeader RightToLeft +16") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << +16 << 0 + << -240 << 0; + + QTest::newRow("PullbackHeader RightToLeft +20") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << +20 << 0 + << -240 << 0; + + QTest::newRow("PullbackHeader RightToLeft +65-10") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << +65 << -10 + << -260 << -20; + + QTest::newRow("PullbackHeader RightToLeft +65-20") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << +65 << -20 + << -250 << -40; + + // Should move header even if contentX doesn't move (it's aligned with top) + QTest::newRow("PullbackHeader RightToLeft +55-5") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << 55 << -5 + << -260 << -20; + + // Should move header even if contentX doesn't move (it's aligned with header) + QTest::newRow("PullbackHeader RightToLeft +76-16") << QQuickItemView::RightToLeft + << QQuickListView::PullBackHeader + << 76 << -16 + << -270 << -60; + +} + void tst_QQuickListView::snapOneItemResize_QTBUG_43555() { QScopedPointer window(createView()); -- cgit v1.2.3 From f7647d5adaaed4c651cb2e65c7ce66d7ef6639f1 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 23 Dec 2019 08:39:26 +0100 Subject: Add Image.sourceClipRect property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we set sourceSize, we expect to use that coordinate system in sourceClipRect too. Therefore we use QImageReader::setScaledClipRect(), not setClipRect(). [ChangeLog][QtQuick][Image] Image now has a sourceClipRect property to render a clipped image from a region of the sourceSize. Change-Id: If08277df772c2ab1063dd88572e49de41b97bca4 Reviewed-by: Jan Arve Sæther --- tests/manual/tableview/imagetiling/imageTiling.qml | 90 +++++++++++++++++++++ tests/manual/tableview/imagetiling/map.pdf | Bin 0 -> 31904 bytes tests/manual/tableview/imagetiling/map.png | Bin 0 -> 21101 bytes tests/manual/tableview/imagetiling/map.svgz | Bin 0 -> 27956 bytes 4 files changed, 90 insertions(+) create mode 100644 tests/manual/tableview/imagetiling/imageTiling.qml create mode 100644 tests/manual/tableview/imagetiling/map.pdf create mode 100644 tests/manual/tableview/imagetiling/map.png create mode 100644 tests/manual/tableview/imagetiling/map.svgz (limited to 'tests') diff --git a/tests/manual/tableview/imagetiling/imageTiling.qml b/tests/manual/tableview/imagetiling/imageTiling.qml new file mode 100644 index 0000000000..5c9cdb9888 --- /dev/null +++ b/tests/manual/tableview/imagetiling/imageTiling.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.15 +import Qt.labs.qmlmodels 1.0 + +TableView { + id: root + width: 1024 + height: 200 + property int tileSize: 1024 / 8 + rowSpacing: 1; columnSpacing: 1 + model: TableModel { + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + columns: [0, 1, 2, 3, 4, 5, 6, 7] + rows: [0, 1, 2, 3] + } + delegate: Image { + id: image +// source: "map.png" // unscaled because png doesn't support QImageIOHandler::ScaledClipRect +// source: "map.svgz" // tiles offset incorrectly: see QTBUG-81044 + source: "map.pdf" // ok if the qtpdf plugin is installed + fillMode: Image.Pad + sourceSize.width: 1024 + sourceClipRect: Qt.rect(model.column * tileSize, model.row * tileSize, tileSize, tileSize) + cache: true + asynchronous: true + Text { + text: image.sourceClipRect.width + "x" + image.sourceClipRect.height + + " " + image.sourceClipRect.x + "," + image.sourceClipRect.y + + "\nfrom " + image.sourceSize.toString() + // inconsistency: if we don't set sourceSize, it ends up being sourceClipRect.size + "\nimplicit " + image.implicitWidth + "x" + image.implicitHeight + } + } + columnWidthProvider: function (c) { return tileSize } // workaround for QTBUG-81045 + rowHeightProvider: function (r) { return tileSize } +} diff --git a/tests/manual/tableview/imagetiling/map.pdf b/tests/manual/tableview/imagetiling/map.pdf new file mode 100644 index 0000000000..31e7b5225e Binary files /dev/null and b/tests/manual/tableview/imagetiling/map.pdf differ diff --git a/tests/manual/tableview/imagetiling/map.png b/tests/manual/tableview/imagetiling/map.png new file mode 100644 index 0000000000..23a8342818 Binary files /dev/null and b/tests/manual/tableview/imagetiling/map.png differ diff --git a/tests/manual/tableview/imagetiling/map.svgz b/tests/manual/tableview/imagetiling/map.svgz new file mode 100644 index 0000000000..64d509c106 Binary files /dev/null and b/tests/manual/tableview/imagetiling/map.svgz differ -- cgit v1.2.3 From 276d00cff956cb54612ec425b7c40eb50a20d78a Mon Sep 17 00:00:00 2001 From: Pierre-Yves Siret Date: Tue, 28 Jan 2020 23:46:56 +0100 Subject: Add Behavior.targetProperty property [ChangeLog][Behavior] Behavior now have a targetProperty property to allow custom logic based on the target property's object or name. Fixes: QTBUG-70964 Change-Id: I866c10d36c7de181fff48da94c8e16cd73ce49b1 Reviewed-by: Paul Wicking Reviewed-by: Fabian Kosmale --- .../quick/qquickbehaviors/data/targetProperty.qml | 16 ++++++++++++++++ .../quick/qquickbehaviors/tst_qquickbehaviors.cpp | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/auto/quick/qquickbehaviors/data/targetProperty.qml (limited to 'tests') diff --git a/tests/auto/quick/qquickbehaviors/data/targetProperty.qml b/tests/auto/quick/qquickbehaviors/data/targetProperty.qml new file mode 100644 index 0000000000..18abd46010 --- /dev/null +++ b/tests/auto/quick/qquickbehaviors/data/targetProperty.qml @@ -0,0 +1,16 @@ +import QtQuick 2.15 + +Item { + readonly property QtObject xBehaviorObject: xBehavior.targetProperty.object + readonly property string xBehaviorName: xBehavior.targetProperty.name + readonly property QtObject emptyBehaviorObject: emptyBehavior.targetProperty.object + readonly property string emptyBehaviorName: emptyBehavior.targetProperty.name + Behavior on x { + id: xBehavior + objectName: "xBehavior" + } + Behavior { + id: emptyBehavior + objectName: "emptyBehavior" + } +} diff --git a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp index 64e32dcdfd..3b46019f64 100644 --- a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp +++ b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp @@ -75,6 +75,7 @@ private slots: void innerBehaviorOverwritten(); void oneWay(); void safeToDelete(); + void targetProperty(); }; void tst_qquickbehaviors::simpleBehavior() @@ -656,6 +657,27 @@ void tst_qquickbehaviors::safeToDelete() QVERIFY(c.create()); } +Q_DECLARE_METATYPE(QQmlProperty) +void tst_qquickbehaviors::targetProperty() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("targetProperty.qml")); + QScopedPointer item(qobject_cast(c.create())); + QVERIFY2(!item.isNull(), qPrintable(c.errorString())); + + QQuickBehavior* xBehavior = + qobject_cast(item->findChild("xBehavior")); + QCOMPARE(xBehavior->property("targetProperty").value(), QQmlProperty(item.data(), "x")); + QCOMPARE(item->property("xBehaviorObject").value(), item.data()); + QCOMPARE(item->property("xBehaviorName").toString(), "x"); + + QQuickBehavior* emptyBehavior = + qobject_cast(item->findChild("emptyBehavior")); + QCOMPARE(emptyBehavior->property("targetProperty").value().isValid(), false); + QCOMPARE(item->property("emptyBehaviorObject").value(), nullptr); + QCOMPARE(item->property("emptyBehaviorName").toString(), ""); +} + QTEST_MAIN(tst_qquickbehaviors) -- cgit v1.2.3 From a6e661d25bf7ebeb8f4e58925aa9375f5ca10ef3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 9 Dec 2019 13:44:31 +0100 Subject: Image ColorSpace bindings for Quick/QML Adds a ColorSpace type mapped to QColorSpace, and adds a property to Image nodes to read and change it, converting the image if necessary on read. Fixes: QTBUG-80616 Change-Id: Ie80c8bc045f66de01de3a5d2c4a9974f07d2871d Reviewed-by: Andy Nichols --- tests/auto/quick/qquickimage/data/ProPhoto.jpg | Bin 0 -> 30900 bytes tests/auto/quick/qquickimage/tst_qquickimage.cpp | 29 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/auto/quick/qquickimage/data/ProPhoto.jpg (limited to 'tests') diff --git a/tests/auto/quick/qquickimage/data/ProPhoto.jpg b/tests/auto/quick/qquickimage/data/ProPhoto.jpg new file mode 100644 index 0000000000..481d35ca8e Binary files /dev/null and b/tests/auto/quick/qquickimage/data/ProPhoto.jpg differ diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp index abc7cd86bd..bab1f1445d 100644 --- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp +++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp @@ -99,6 +99,7 @@ private slots: void urlInterceptor(); void multiFrame_data(); void multiFrame(); + void colorSpace(); private: QQmlEngine engine; @@ -1190,6 +1191,34 @@ void tst_qquickimage::multiFrame() QVERIFY(qBlue(color) < 0xc0); } +void tst_qquickimage::colorSpace() +{ + QString componentStr1 = "import QtQuick 2.15\n" + "Image { source: srcImage; }"; + QQmlComponent component1(&engine); + component1.setData(componentStr1.toLatin1(), QUrl::fromLocalFile("")); + engine.rootContext()->setContextProperty("srcImage", testFileUrl("ProPhoto.jpg")); + + QScopedPointer object1 { qobject_cast(component1.create())}; + QVERIFY(object1); + QTRY_COMPARE(object1->status(), QQuickImageBase::Ready); + QCOMPARE(object1->colorSpace(), QColorSpace(QColorSpace::ProPhotoRgb)); + + QString componentStr2 = "import QtQuick 2.15\n" + "Image {\n" + " source: srcImage;\n" + " colorSpace.namedColorSpace: ColorSpace.SRgb;\n" + "}"; + + QQmlComponent component2(&engine); + component2.setData(componentStr2.toLatin1(), QUrl::fromLocalFile("")); + + QScopedPointer object2 { qobject_cast(component2.create())}; + QVERIFY(object2); + QTRY_COMPARE(object2->status(), QQuickImageBase::Ready); + QCOMPARE(object2->colorSpace(), QColorSpace(QColorSpace::SRgb)); +} + QTEST_MAIN(tst_qquickimage) #include "tst_qquickimage.moc" -- cgit v1.2.3 From 1c44804600ad3dbeb60d1f5209ce9cf937d30ab3 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 16 Jan 2020 13:45:15 +0100 Subject: Add PointerHandler.cursorShape property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, QQuickItemPrivate::setHasCursorInChild() was unable to check the QQuickItemPrivate::hasCursor variable, because the function argument hasCursor was shadowing that, even though the comment "nope! sorry, I have a cursor myself" hints that the intention was to check that. So this change exposed a problem there, and we have to fix that too, in order to keep the tst_qquickwindow::cursor() test passing. [ChangeLog][Event Handlers] Pointer Handlers now have a cursorShape property to set the cursor when the handler is active and the mouse is hovering, and restore to the previous cursor when the mouse leaves. Fixes: QTBUG-68073 Change-Id: Ib5c66bd59c4691c4210ee5465e1c95e7bdcf5ae1 Reviewed-by: Jan Arve Sæther --- .../qquickdraghandler/data/draggables.qml | 5 ++- .../qquickdraghandler/tst_qquickdraghandler.cpp | 15 ++++++- .../qquickhoverhandler/data/lesHoverables.qml | 12 ++++-- .../qquickhoverhandler/tst_qquickhoverhandler.cpp | 46 ++++++++++++++++++++++ tests/auto/quick/qquickwindow/tst_qquickwindow.cpp | 4 ++ tests/manual/pointer/sidebar.qml | 7 +++- 6 files changed, 82 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml index 7b3601bea0..81fa20f3bb 100644 --- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml +++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the manual tests of the Qt Toolkit. @@ -26,7 +26,7 @@ ** ****************************************************************************/ -import QtQuick 2.12 +import QtQuick 2.15 Item { id: root @@ -47,6 +47,7 @@ Item { DragHandler { id: dragHandler objectName: "DragHandler " + (index + 1) + cursorShape: Qt.ClosedHandCursor } Text { diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp index 65c5ac9ef4..47cfd27817 100644 --- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp @@ -249,8 +249,11 @@ void tst_DragHandler::mouseDrag() QPointF ballCenter = ball->clipRect().center(); QPointF scenePressPos = ball->mapToScene(ballCenter); QPoint p1 = scenePressPos.toPoint(); - QTest::mousePress(window, static_cast(int(dragButton)), Qt::NoModifier, p1); + QTest::mousePress(window, static_cast(int(dragButton)), Qt::NoModifier, p1, 500); QVERIFY(!dragHandler->active()); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif if (shouldDrag) { QCOMPARE(dragHandler->centroid().position(), ballCenter); QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter); @@ -265,6 +268,9 @@ void tst_DragHandler::mouseDrag() QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0); QCOMPARE(centroidChangedSpy.count(), 2); QVERIFY(!dragHandler->active()); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif } p1 += QPoint(1, 0); QTest::mouseMove(window, p1); @@ -292,6 +298,9 @@ void tst_DragHandler::mouseDrag() QCOMPARE(dragHandler->translation().y(), 0.0); QVERIFY(dragHandler->centroid().velocity().x() > 0); QCOMPARE(centroidChangedSpy.count(), 4); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ClosedHandCursor); +#endif } QTest::mouseRelease(window, static_cast(int(dragButton)), Qt::NoModifier, p1); QTRY_VERIFY(!dragHandler->active()); @@ -300,6 +309,10 @@ void tst_DragHandler::mouseDrag() QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1); QCOMPARE(translationChangedSpy.count(), shouldDrag ? 1 : 0); QCOMPARE(centroidChangedSpy.count(), shouldDrag ? 5 : 0); +#if QT_CONFIG(cursor) + QTest::mouseMove(window, p1 + QPoint(1, 0)); // TODO after fixing QTBUG-53987, don't send mouseMove + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif } void tst_DragHandler::mouseDragThreshold_data() diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml index 011dc4e75f..38a19c57c5 100644 --- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -26,7 +26,7 @@ ** ****************************************************************************/ -import QtQuick 2.12 +import QtQuick 2.15 Rectangle { id: root @@ -52,6 +52,7 @@ Rectangle { id: buttonMA objectName: "buttonMA" hoverEnabled: true + cursorShape: Qt.UpArrowCursor anchors.fill: parent onClicked: console.log("clicked MA") } @@ -74,9 +75,12 @@ Rectangle { id: buttonHH objectName: "buttonHH" acceptedDevices: PointerDevice.AllDevices + cursorShape: tapHandler.pressed ? Qt.BusyCursor : Qt.PointingHandCursor } - TapHandler { } + TapHandler { + id: tapHandler + } Text { anchors.centerIn: parent @@ -127,6 +131,7 @@ Rectangle { HoverHandler { id: topSidebarHH objectName: "topSidebarHH" + cursorShape: Qt.OpenHandCursor } Loader { @@ -152,6 +157,7 @@ Rectangle { id: bottomSidebarMA objectName: "bottomSidebarMA" hoverEnabled: true + cursorShape: Qt.ClosedHandCursor anchors.fill: parent } diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp index 575139f851..61f2752dd2 100644 --- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp @@ -104,30 +104,45 @@ void tst_HoverHandler::hoverHandlerAndUnderlyingHoverHandler() QCOMPARE(sidebarHoveredSpy.count(), 0); QCOMPARE(buttonHH->isHovered(), false); QCOMPARE(buttonHoveredSpy.count(), 0); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif QTest::mouseMove(window, rightOfButton); QCOMPARE(topSidebarHH->isHovered(), true); QCOMPARE(sidebarHoveredSpy.count(), 1); QCOMPARE(buttonHH->isHovered(), false); QCOMPARE(buttonHoveredSpy.count(), 0); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::OpenHandCursor); +#endif QTest::mouseMove(window, buttonCenter); QCOMPARE(topSidebarHH->isHovered(), true); QCOMPARE(sidebarHoveredSpy.count(), 1); QCOMPARE(buttonHH->isHovered(), true); QCOMPARE(buttonHoveredSpy.count(), 1); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::PointingHandCursor); +#endif QTest::mouseMove(window, rightOfButton); QCOMPARE(topSidebarHH->isHovered(), true); QCOMPARE(sidebarHoveredSpy.count(), 1); QCOMPARE(buttonHH->isHovered(), false); QCOMPARE(buttonHoveredSpy.count(), 2); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::OpenHandCursor); +#endif QTest::mouseMove(window, outOfSidebar); QCOMPARE(topSidebarHH->isHovered(), false); QCOMPARE(sidebarHoveredSpy.count(), 2); QCOMPARE(buttonHH->isHovered(), false); QCOMPARE(buttonHoveredSpy.count(), 2); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif } void tst_HoverHandler::mouseAreaAndUnderlyingHoverHandler() @@ -153,30 +168,45 @@ void tst_HoverHandler::mouseAreaAndUnderlyingHoverHandler() QCOMPARE(sidebarHoveredSpy.count(), 0); QCOMPARE(buttonMA->hovered(), false); QCOMPARE(buttonHoveredSpy.count(), 0); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif QTest::mouseMove(window, rightOfButton); QCOMPARE(topSidebarHH->isHovered(), true); QCOMPARE(sidebarHoveredSpy.count(), 1); QCOMPARE(buttonMA->hovered(), false); QCOMPARE(buttonHoveredSpy.count(), 0); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::OpenHandCursor); +#endif QTest::mouseMove(window, buttonCenter); QCOMPARE(topSidebarHH->isHovered(), true); QCOMPARE(sidebarHoveredSpy.count(), 1); QCOMPARE(buttonMA->hovered(), true); QCOMPARE(buttonHoveredSpy.count(), 1); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::UpArrowCursor); +#endif QTest::mouseMove(window, rightOfButton); QCOMPARE(topSidebarHH->isHovered(), true); QCOMPARE(sidebarHoveredSpy.count(), 1); QCOMPARE(buttonMA->hovered(), false); QCOMPARE(buttonHoveredSpy.count(), 2); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::OpenHandCursor); +#endif QTest::mouseMove(window, outOfSidebar); QCOMPARE(topSidebarHH->isHovered(), false); QCOMPARE(sidebarHoveredSpy.count(), 2); QCOMPARE(buttonMA->hovered(), false); QCOMPARE(buttonHoveredSpy.count(), 2); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif } void tst_HoverHandler::hoverHandlerAndUnderlyingMouseArea() @@ -204,30 +234,45 @@ void tst_HoverHandler::hoverHandlerAndUnderlyingMouseArea() QCOMPARE(sidebarHoveredSpy.count(), 0); QCOMPARE(buttonHH->isHovered(), false); QCOMPARE(buttonHoveredSpy.count(), 0); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif QTest::mouseMove(window, rightOfButton); QCOMPARE(bottomSidebarMA->hovered(), true); QCOMPARE(sidebarHoveredSpy.count(), 1); QCOMPARE(buttonHH->isHovered(), false); QCOMPARE(buttonHoveredSpy.count(), 0); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ClosedHandCursor); +#endif QTest::mouseMove(window, buttonCenter); QCOMPARE(bottomSidebarMA->hovered(), false); QCOMPARE(sidebarHoveredSpy.count(), 2); QCOMPARE(buttonHH->isHovered(), true); QCOMPARE(buttonHoveredSpy.count(), 1); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::PointingHandCursor); +#endif QTest::mouseMove(window, rightOfButton); QCOMPARE(bottomSidebarMA->hovered(), true); QCOMPARE(sidebarHoveredSpy.count(), 3); QCOMPARE(buttonHH->isHovered(), false); QCOMPARE(buttonHoveredSpy.count(), 2); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ClosedHandCursor); +#endif QTest::mouseMove(window, outOfSidebar); QCOMPARE(bottomSidebarMA->hovered(), false); QCOMPARE(sidebarHoveredSpy.count(), 4); QCOMPARE(buttonHH->isHovered(), false); QCOMPARE(buttonHoveredSpy.count(), 2); +#if QT_CONFIG(cursor) + QCOMPARE(window->cursor().shape(), Qt::ArrowCursor); +#endif } void tst_HoverHandler::movingItemWithHoverHandler() @@ -255,6 +300,7 @@ void tst_HoverHandler::movingItemWithHoverHandler() QVERIFY(QTest::qWaitForWindowExposed(window)); QTRY_COMPARE(paddleHH->isHovered(), true); + // TODO check the cursor shape after fixing QTBUG-53987 paddle->setX(100); QTRY_COMPARE(paddleHH->isHovered(), false); diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index 5b6b11c746..bf58ce961c 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -1797,22 +1797,26 @@ void tst_qquickwindow::cursor() window.resize(320, 290); QQuickItem parentItem; + parentItem.setObjectName("parentItem"); parentItem.setPosition(QPointF(0, 0)); parentItem.setSize(QSizeF(180, 180)); parentItem.setParentItem(window.contentItem()); QQuickItem childItem; + childItem.setObjectName("childItem"); childItem.setPosition(QPointF(60, 90)); childItem.setSize(QSizeF(120, 120)); childItem.setParentItem(&parentItem); QQuickItem clippingItem; + clippingItem.setObjectName("clippingItem"); clippingItem.setPosition(QPointF(120, 120)); clippingItem.setSize(QSizeF(180, 180)); clippingItem.setClip(true); clippingItem.setParentItem(window.contentItem()); QQuickItem clippedItem; + clippedItem.setObjectName("clippedItem"); clippedItem.setPosition(QPointF(-30, -30)); clippedItem.setSize(QSizeF(120, 120)); clippedItem.setParentItem(&clippingItem); diff --git a/tests/manual/pointer/sidebar.qml b/tests/manual/pointer/sidebar.qml index 827dbd1980..b7370a4fb7 100644 --- a/tests/manual/pointer/sidebar.qml +++ b/tests/manual/pointer/sidebar.qml @@ -26,7 +26,7 @@ ** ****************************************************************************/ -import QtQuick 2.12 +import QtQuick 2.15 import "content" Rectangle { @@ -53,6 +53,7 @@ Rectangle { id: buttonMA objectName: "buttonMA" hoverEnabled: true + cursorShape: Qt.UpArrowCursor anchors.fill: parent onClicked: console.log("clicked MA") } @@ -75,9 +76,11 @@ Rectangle { id: buttonHH objectName: "buttonHH" acceptedDevices: PointerDevice.AllDevices + cursorShape: tapHandler.pressed ? Qt.BusyCursor : Qt.PointingHandCursor } TapHandler { + id: tapHandler onTapped: tapFlash.start() } @@ -148,6 +151,7 @@ Rectangle { HoverHandler { id: topSidebarHH objectName: "topSidebarHH" + cursorShape: Qt.OpenHandCursor } Loader { @@ -173,6 +177,7 @@ Rectangle { id: bottomSidebarMA objectName: "bottomSidebarMA" hoverEnabled: true + cursorShape: Qt.ClosedHandCursor anchors.fill: parent } -- cgit v1.2.3 From 65fa7e795dd67250b8d95f13ebd9924069864866 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Fri, 24 Jan 2020 11:14:13 +0100 Subject: Tests: make ConnectResult a Q_ENUM to get nice error message Change-Id: I0e22eb66109e61a5341388d37f5b596f4125ac99 Reviewed-by: Ulf Hermann --- tests/auto/qml/debugger/shared/debugutil_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h index 1c32590305..41a5663283 100644 --- a/tests/auto/qml/debugger/shared/debugutil_p.h +++ b/tests/auto/qml/debugger/shared/debugutil_p.h @@ -53,7 +53,6 @@ public: static QString clientStateString(const QQmlDebugClient *client); static QString connectionStateString(const QQmlDebugConnection *connection); -protected: enum ConnectResult { ConnectSuccess, ProcessFailed, @@ -64,6 +63,8 @@ protected: RestrictFailed }; + Q_ENUM(ConnectResult) +protected: ConnectResult connect(const QString &executable, const QString &services, const QString &extraArgs, bool block); -- cgit v1.2.3 From a87ad432a002614a5cca4d635ead5aedb97ba757 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Tue, 28 Jan 2020 14:21:10 +0100 Subject: add annotations to QML A QML Annotation is a Qml Object declaration prepended with @. The name of the annotation is restricted to a dot separated list of non keyword identifiers. Annotations can be put before an Object definition, or any object member declaration: bindings, property declarations, function declarations. This patch, aside parsing the annotations does absolutely nothing, the list of annotations is discarded and never touches the AST. [ChangeLog][QML] Add Qml Annotations Task-number: QTBUG-81714 Change-Id: I4d79559a0d1fb23acaf482d0ef8f7d106dbf099d Reviewed-by: Ulf Hermann --- .../auto/qml/qqmlparser/data/annotations/View1.qml | 76 ++++++++++++++++++++++ .../qml/qqmlparser/data/noannotations/View1.qml | 76 ++++++++++++++++++++++ tests/auto/qml/qqmlparser/tst_qqmlparser.cpp | 63 ++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 tests/auto/qml/qqmlparser/data/annotations/View1.qml create mode 100644 tests/auto/qml/qqmlparser/data/noannotations/View1.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmlparser/data/annotations/View1.qml b/tests/auto/qml/qqmlparser/data/annotations/View1.qml new file mode 100644 index 0000000000..2d3d7d2cfd --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/annotations/View1.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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$ +** +****************************************************************************/ + +//![2] +import QtQuick 2.0 +//![2] +import QtCharts 2.0 + +@Pippo{ atg1:3 } +@Annotation2{} +Item { + @Annotate{} + anchors.fill: parent + @AnnotateMore{ + property int x: 5 + } + @AnnotateALot{} + property variant othersSlice: 0 + + //![1] + ChartView { + id: chart + title: "Top-5 car brand shares in Finland" + anchors.fill: parent + legend.alignment: Qt.AlignBottom + antialiasing: true + +@ExtraAnnotation{ + signal pippo +} + PieSeries { + id: pieSeries + PieSlice { label: "Volkswagen"; value: 13.5 } + PieSlice { label: "Toyota"; value: 10.9 } + PieSlice { label: "Ford"; value: 8.6 } + PieSlice { label: "Skoda"; value: 8.2 } + PieSlice { label: "Volvo"; value: 6.8 } + } + } + +@SuperComplete{ +binding: late +} + Component.onCompleted: { + // You can also manipulate slices dynamically, like append a slice or set a slice exploded + othersSlice = pieSeries.append("Others", 52.0); + pieSeries.find("Volkswagen").exploded = true; + } + //![1] +} diff --git a/tests/auto/qml/qqmlparser/data/noannotations/View1.qml b/tests/auto/qml/qqmlparser/data/noannotations/View1.qml new file mode 100644 index 0000000000..945bce3a44 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/noannotations/View1.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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$ +** +****************************************************************************/ + +//![2] +import QtQuick 2.0 +//![2] +import QtCharts 2.0 + + + +Item { + + anchors.fill: parent + + + + + property variant othersSlice: 0 + + //![1] + ChartView { + id: chart + title: "Top-5 car brand shares in Finland" + anchors.fill: parent + legend.alignment: Qt.AlignBottom + antialiasing: true + + + + + PieSeries { + id: pieSeries + PieSlice { label: "Volkswagen"; value: 13.5 } + PieSlice { label: "Toyota"; value: 10.9 } + PieSlice { label: "Ford"; value: 8.6 } + PieSlice { label: "Skoda"; value: 8.2 } + PieSlice { label: "Volvo"; value: 6.8 } + } + } + + + + + Component.onCompleted: { + // You can also manipulate slices dynamically, like append a slice or set a slice exploded + othersSlice = pieSeries.append("Others", 52.0); + pieSeries.find("Volkswagen").exploded = true; + } + //![1] +} diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp index 76b56bd303..0b88358d4a 100644 --- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp +++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp @@ -65,6 +65,8 @@ private slots: void semicolonPartOfExpressionStatement(); void typeAssertion_data(); void typeAssertion(); + void annotations_data(); + void annotations(); private: QStringList excludedDirs; @@ -521,6 +523,67 @@ void tst_qqmlparser::typeAssertion() QVERIFY(parser.parse()); } +void tst_qqmlparser::annotations_data() +{ + QTest::addColumn("file"); + QTest::addColumn("refFile"); + + QString tests = dataDirectory() + "/annotations/"; + QString compare = dataDirectory() + "/noannotations/"; + + QStringList files; + files << findFiles(QDir(tests)); + + QStringList refFiles; + refFiles << findFiles(QDir(compare)); + + for (const QString &file: qAsConst(files)) { + auto fileNameStart = file.lastIndexOf(QDir::separator()); + QStringRef fileName(&file, fileNameStart, file.length()-fileNameStart); + auto ref=std::find_if(refFiles.constBegin(),refFiles.constEnd(), [fileName](const QString &s){ return s.endsWith(fileName); }); + if (ref != refFiles.constEnd()) + QTest::newRow(qPrintable(file)) << file << *ref; + else + QTest::newRow(qPrintable(file)) << file << QString(); + } +} + +void tst_qqmlparser::annotations() +{ + using namespace QQmlJS; + + QFETCH(QString, file); + QFETCH(QString, refFile); + + QString code; + QString refCode; + + QFile f(file); + if (f.open(QFile::ReadOnly)) + code = QString::fromUtf8(f.readAll()); + QFile refF(refFile); + if (!refFile.isEmpty() && refF.open(QFile::ReadOnly)) + refCode = QString::fromUtf8(refF.readAll()); + + const bool qmlMode = true; + + Engine engine; + Lexer lexer(&engine); + lexer.setCode(code, 1, qmlMode); + Parser parser(&engine); + QVERIFY(parser.parse()); + + if (!refCode.isEmpty()) { + Engine engine2; + Lexer lexer2(&engine2); + lexer2.setCode(refCode, 1, qmlMode); + Parser parser2(&engine2); + QVERIFY(parser2.parse()); + + // to do: compare for equality skipping annotations + } +} + QTEST_MAIN(tst_qqmlparser) #include "tst_qqmlparser.moc" -- cgit v1.2.3 From 85f15e2af40be1e9500fe600daba31839b904ef4 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 30 Jan 2020 10:51:34 +0100 Subject: Required properties: Allow retroactive require specification It is now possible to mark a property of a parent class as required in the child by writing required Change-Id: I9e9d58c7b5c00577b056e905b39744b2fa359ea0 Reviewed-by: Ulf Hermann --- tests/auto/qml/qmlformat/tst_qmlformat.cpp | 1 - tests/auto/qml/qmlmin/tst_qmlmin.cpp | 1 - .../auto/qml/qqmllanguage/data/NonRequiredBase.qml | 5 ++++ tests/auto/qml/qqmllanguage/data/RequiredBase.qml | 3 +++ .../qml/qqmllanguage/data/requiredProperties.3.qml | 6 +++++ .../qml/qqmllanguage/data/requiredProperties.4.qml | 5 ++++ .../qml/qqmllanguage/data/requiredProperties.5.qml | 1 + .../qml/qqmllanguage/data/requiredProperties.6.qml | 3 +++ .../qml/qqmllanguage/data/requiredProperties.7.qml | 5 ++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 30 ++++++++++++++++++++++ 10 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/auto/qml/qqmllanguage/data/NonRequiredBase.qml create mode 100644 tests/auto/qml/qqmllanguage/data/RequiredBase.qml create mode 100644 tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml create mode 100644 tests/auto/qml/qqmllanguage/data/requiredProperties.4.qml create mode 100644 tests/auto/qml/qqmllanguage/data/requiredProperties.5.qml create mode 100644 tests/auto/qml/qqmllanguage/data/requiredProperties.6.qml create mode 100644 tests/auto/qml/qqmllanguage/data/requiredProperties.7.qml (limited to 'tests') diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp index 3201fa5ace..b10eaf26f1 100644 --- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp +++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp @@ -113,7 +113,6 @@ void TestQmlformat::initTestCase() m_invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.2.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.3.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml"; - m_invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.qml"; diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp index e7498a8583..0501a8112a 100644 --- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp +++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp @@ -132,7 +132,6 @@ void tst_qmlmin::initTestCase() invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.2.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.3.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml"; // generatorFunction.qml is not invalid per se, but the minifier cannot handle yield statements invalidFiles << "tests/auto/qml/qqmlecmascript/data/generatorFunction.qml"; #endif diff --git a/tests/auto/qml/qqmllanguage/data/NonRequiredBase.qml b/tests/auto/qml/qqmllanguage/data/NonRequiredBase.qml new file mode 100644 index 0000000000..60d45c2b1e --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/NonRequiredBase.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +Item { + property int i +} diff --git a/tests/auto/qml/qqmllanguage/data/RequiredBase.qml b/tests/auto/qml/qqmllanguage/data/RequiredBase.qml new file mode 100644 index 0000000000..4effdbf1c7 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/RequiredBase.qml @@ -0,0 +1,3 @@ +NonRequiredBase { + required i +} diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml new file mode 100644 index 0000000000..2585cf361e --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml @@ -0,0 +1,6 @@ +import QtQuick 2.15 + +Item { + property int i; + required i; +} diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.4.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.4.qml new file mode 100644 index 0000000000..1126f845c9 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.4.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +Item { + required objectName +} diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.5.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.5.qml new file mode 100644 index 0000000000..c2d155b123 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.5.qml @@ -0,0 +1 @@ +RequiredBase {} diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.6.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.6.qml new file mode 100644 index 0000000000..e8802aef20 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.6.qml @@ -0,0 +1,3 @@ +RequiredBase { + i: 42 +} diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.7.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.7.qml new file mode 100644 index 0000000000..40987f5c56 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.7.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +Item { + required blub +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 5027c0825f..b4ad9bd7b3 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -1675,6 +1675,36 @@ void tst_qqmllanguage::requiredProperty() QQmlComponent component(&engine, testFileUrl("requiredProperties.2.qml")); QVERIFY(!component.errors().empty()); } + { + QQmlComponent component(&engine, testFileUrl("requiredProperties.4.qml")); + QScopedPointer object(component.create()); + QVERIFY(!component.errors().empty()); + QVERIFY(component.errorString().contains("Required property objectName was not initialized")); + } + { + QQmlComponent component(&engine, testFileUrl("requiredProperties.3.qml")); + QScopedPointer object(component.create()); + QVERIFY(!component.errors().empty()); + QVERIFY(component.errorString().contains("Required property i was not initialized")); + } + { + QQmlComponent component(&engine, testFileUrl("requiredProperties.5.qml")); + QScopedPointer object(component.create()); + QVERIFY(!component.errors().empty()); + QVERIFY(component.errorString().contains("Required property i was not initialized")); + } + { + QQmlComponent component(&engine, testFileUrl("requiredProperties.6.qml")); + VERIFY_ERRORS(0); + QScopedPointer object(component.create()); + QVERIFY(object); + } + { + QQmlComponent component(&engine, testFileUrl("requiredProperties.7.qml")); + QScopedPointer object(component.create()); + QVERIFY(!component.errors().empty()); + QVERIFY(component.errorString().contains("Property blub was marked as required but does not exist")); + } } class MyClassWithRequiredProperty : public QObject -- cgit v1.2.3 From ecdb4ed275a0869dc668d73d774735575d43a0a3 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 2 Jan 2020 14:42:12 +0100 Subject: Enable conversion from QJSValues containing arrays to container types We started to convert containers to QJSValues, so that we could use them as JavaScript arrays. Unfortunately, this would then lead to a type missmatch when those same values where to be stored in a property of the container type. This commit fixes this by converting them back to the original type. Fixes: QTBUG-80916 Change-Id: I30a3b03e17c34b171d4a6881dfd7801c13e94d80 Reviewed-by: Ulf Hermann --- .../data/sequenceConversion.write.error.qml | 2 +- .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 9 ++++---- .../qml/qqmllanguage/data/arrayToContainer.qml | 7 ++++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 27 ++++++++++++++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 tests/auto/qml/qqmllanguage/data/arrayToContainer.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml index 75beafd1ee..c2c8c1b52b 100644 --- a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml +++ b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml @@ -12,7 +12,7 @@ Item { function performTest() { // we have NOT registered QList as a type - var pointList = [ Qt.point(7,7), Qt.point(8,8), Qt.point(9,9) ]; + var pointList = [ Qt.point(7,7), "hello world", Qt.point(8,8), Qt.point(9,9) ]; msco.pointListProperty = pointList; // error. } } diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 370ef5f065..26232ac1a3 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -5792,13 +5792,12 @@ void tst_qqmlecmascript::sequenceConversionWrite() MySequenceConversionObject *seq = object->findChild("msco"); QVERIFY(seq != nullptr); - // we haven't registered QList as a sequence type, so writing shouldn't work. - QString warningOne = qmlFile.toString() + QLatin1String(":16: Error: Cannot assign QJSValue to QList"); - QTest::ignoreMessage(QtWarningMsg, warningOne.toLatin1().constData()); - + // Behavior change in 5.14: due to added auto-magical conversions, it is possible to assign to + // QList, even though it is not a registered sequence type + QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression("Could not convert array value at position 1 from QString to QPoint")); QMetaObject::invokeMethod(object, "performTest"); - QList pointList; pointList << QPoint(1, 2) << QPoint(3, 4) << QPoint(5, 6); // original values, shouldn't have changed + QList pointList; pointList << QPoint(7, 7) << QPoint(0,0) << QPoint(8, 8) << QPoint(9, 9); // original values, shouldn't have changed QCOMPARE(seq->pointListProperty(), pointList); delete object; diff --git a/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml b/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml new file mode 100644 index 0000000000..ee400eb41f --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml @@ -0,0 +1,7 @@ +import QtQml 2.14 +import qt.test 1.0 + +TestItem { + property var vector + positions: vector +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index fae74f1f25..4a8ce77f92 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -303,6 +303,8 @@ private slots: void typeWrapperToVariant(); + void arrayToContainer(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -5238,6 +5240,31 @@ void tst_qqmllanguage::typeWrapperToVariant() QVERIFY(target); } +class TestItem : public QObject +{ + Q_OBJECT + Q_PROPERTY( QVector positions MEMBER m_points ) + +public: + TestItem() = default; + QVector< QPointF > m_points; +}; + + +Q_DECLARE_METATYPE(QVector); +void tst_qqmllanguage::arrayToContainer() +{ + QQmlEngine engine; + qmlRegisterType("qt.test", 1, 0, "TestItem"); + QVector points { QPointF (2.0, 3.0) }; + engine.rootContext()->setContextProperty("test", QVariant::fromValue(points)); + QQmlComponent component(&engine, testFileUrl("arrayToContainer.qml")); + VERIFY_ERRORS(0); + QScopedPointer root(qobject_cast(component.createWithInitialProperties( {{"vector", QVariant::fromValue(points)}} ))); + QVERIFY(root); + QCOMPARE(root->m_points.at(0), QPointF (2.0, 3.0) ); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" -- cgit v1.2.3 From e3303da40b6af2d4b6d0d1512809a849085d207f Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 30 Jan 2020 08:02:40 +0100 Subject: Add autotest for Image.sourceClipRect property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It clips the heart.png image in various ways and tests a few pixel colors to verify the boundaries of the clipped portion. Change-Id: I1c65e522c99720e94a6e13020bd9bf9736e19b4e Reviewed-by: Jan Arve Sæther --- tests/auto/quick/qquickimage/data/image.qml | 5 ++ tests/auto/quick/qquickimage/tst_qquickimage.cpp | 69 ++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/auto/quick/qquickimage/data/image.qml (limited to 'tests') diff --git a/tests/auto/quick/qquickimage/data/image.qml b/tests/auto/quick/qquickimage/data/image.qml new file mode 100644 index 0000000000..09a577cc6f --- /dev/null +++ b/tests/auto/quick/qquickimage/data/image.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +Image { + source: "heart.png" +} diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp index bab1f1445d..f0b44743b9 100644 --- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp +++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp @@ -51,6 +51,7 @@ #include "../../shared/testhttpserver.h" #include "../shared/visualtestutil.h" +// #define DEBUG_WRITE_OUTPUT using namespace QQuickVisualTestUtil; @@ -89,6 +90,8 @@ private slots: void imageCrash_QTBUG_32513(); void sourceSize_data(); void sourceSize(); + void sourceClipRect_data(); + void sourceClipRect(); void progressAndStatusChanges(); void sourceSizeChanges(); void correctStatus(); @@ -880,6 +883,72 @@ void tst_qquickimage::sourceSizeChanges() delete img; } +void tst_qquickimage::sourceClipRect_data() +{ + QTest::addColumn("sourceClipRect"); + QTest::addColumn("sourceSize"); + QTest::addColumn>("redPixelLocations"); + QTest::addColumn>("bluePixelLocations"); + + QTest::newRow("unclipped") << QRectF() << QSize() + << (QList() << QPoint(80, 80) << QPoint(150, 256)) + << (QList() << QPoint(28, 28) << QPoint(215, 215)); + QTest::newRow("upperLeft") << QRectF(10, 10, 100, 100) << QSize() + << (QList() << QPoint(99, 99)) + << (QList() << QPoint(100, 100) << QPoint(28, 28)); + QTest::newRow("lowerRight") << QRectF(200, 200, 20, 20) << QSize() + << (QList() << QPoint(0, 0)) + << (QList() << QPoint(14, 14)); + QTest::newRow("miniMiddle") << QRectF(20, 20, 60, 60) << QSize(100, 100) + << (QList() << QPoint(59, 0) << QPoint(6, 12) << QPoint(42, 42)) + << (QList() << QPoint(54, 54) << QPoint(15, 59)); +} + +void tst_qquickimage::sourceClipRect() +{ + QFETCH(QRectF, sourceClipRect); + QFETCH(QSize, sourceSize); + QFETCH(QList, redPixelLocations); + QFETCH(QList, bluePixelLocations); + + QScopedPointer window(new QQuickView(nullptr)); + + window->setColor(Qt::blue); + window->setSource(testFileUrl("image.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickImage *image = qobject_cast(window->rootObject()); + QVERIFY(image); + + image->setSourceSize(sourceSize); + QCOMPARE(image->implicitWidth(), sourceSize.isValid() ? sourceSize.width() : 300); + QCOMPARE(image->implicitHeight(), sourceSize.isValid() ? sourceSize.height() : 300); + image->setSourceClipRect(sourceClipRect); + QCOMPARE(image->implicitWidth(), sourceClipRect.isNull() ? 300 : sourceClipRect.width()); + QCOMPARE(image->implicitHeight(), sourceClipRect.isNull() ? 300 : sourceClipRect.height()); + + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms"); + QImage contents = window->grabWindow(); + if (contents.width() < sourceClipRect.width()) + QSKIP("Skipping due to grabWindow not functional"); +#ifdef DEBUG_WRITE_OUTPUT + contents.save("/tmp/sourceClipRect_" + QLatin1String(QTest::currentDataTag()) + ".png"); +#endif + for (auto p : redPixelLocations) { + QRgb color = contents.pixel(p); + QVERIFY(qRed(color) > 0xc0); + QVERIFY(qBlue(color) < 0x0f); + } + for (auto p : bluePixelLocations){ + QRgb color = contents.pixel(p); + QVERIFY(qBlue(color) > 0xc0); + QVERIFY(qRed(color) < 0x0f); + } +} + void tst_qquickimage::progressAndStatusChanges() { TestHTTPServer server; -- cgit v1.2.3 From 44f24c43ad6af8784314d22f5261094a742458a3 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 31 Jan 2020 19:41:38 +0100 Subject: Prospective workaround for accidental c++11 build with 10.14 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When switching to macOS 10.14 and the xcode we install there, mysteriously qtbase switches from c++17 to c++11 when compiling the tests, which breaks this particular test as it includes qv4arraydata_p.h, which in turn requires C++14's std::aligned_storage_t. Once we enforce C++17 in qtbase this should not be needed anymore, but we can only enforce that once we've switched to macOS 10.14. Change-Id: Iaa2b55dfd2bfd23f908a211ca90255ef522bc6ff Reviewed-by: Lars Knoll Reviewed-by: Tor Arne Vestbø --- tests/auto/qml/ecmascripttests/qjstest/qjstest.pro | 2 ++ tests/auto/qml/ecmascripttests/testcase.pro | 2 ++ 2 files changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/qml/ecmascripttests/qjstest/qjstest.pro b/tests/auto/qml/ecmascripttests/qjstest/qjstest.pro index 6dec5f8f23..adead821e4 100644 --- a/tests/auto/qml/ecmascripttests/qjstest/qjstest.pro +++ b/tests/auto/qml/ecmascripttests/qjstest/qjstest.pro @@ -3,6 +3,8 @@ TARGET = qjstest QT += qml-private INCLUDEPATH += . +CONFIG += c++14 + DEFINES += QT_DEPRECATED_WARNINGS HEADERS += test262runner.h diff --git a/tests/auto/qml/ecmascripttests/testcase.pro b/tests/auto/qml/ecmascripttests/testcase.pro index 5bf7ecd696..9405095050 100644 --- a/tests/auto/qml/ecmascripttests/testcase.pro +++ b/tests/auto/qml/ecmascripttests/testcase.pro @@ -6,6 +6,8 @@ SOURCES += tst_ecmascripttests.cpp qjstest/test262runner.cpp HEADERS += qjstest/test262runner.h DEFINES += SRCDIR=\\\"$$PWD\\\" +CONFIG += c++14 + # The ES test suite takes approximately 5 mins to run, on a fairly # vanilla developer machine, so the default watchdog timer kills the # test some of the time. Fix by raising time-out to 400s when -- cgit v1.2.3 From 793ba7c0272725a377c1e27e69e84f3abadcbcf5 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 3 Feb 2020 12:37:54 +0100 Subject: Blacklist tst_qquickmousearea::nestedStopAtBounds on opensuse 15.0 This partially reverts commit 51e02fdc02c3cc2dbf9d2ba0b3fb709a6cd4e32e. Task-number: QTBUG-78153 Change-Id: I421fdc3acefd11cabfc192eb06c3cd92c0e76149 Reviewed-by: Fabian Kosmale Reviewed-by: Shawn Rutledge --- tests/auto/quick/qquickmousearea/BLACKLIST | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/auto/quick/qquickmousearea/BLACKLIST (limited to 'tests') diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST new file mode 100644 index 0000000000..f2cb00225b --- /dev/null +++ b/tests/auto/quick/qquickmousearea/BLACKLIST @@ -0,0 +1,4 @@ +# QTBUG-78153 +[nestedStopAtBounds] +opensuse-leap + -- cgit v1.2.3 From 789929f939a60462373beae37ab4373809095cff Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 22 Jan 2020 13:12:56 +0100 Subject: Use QTypeRevision for all versions and revisions In many places we carry major and minor versions or revisions that are loosely coupled to minor versions. As the Qt minor version resets now, we need to handle these things more systematically. In particular, we need to add a "major" part to revisions. QTypeRevision can express the current major/minor pairs more efficiently and can also be used to add a major version to revisions. This change does not change the semantics, yet, but only replaces the types. Change-Id: Ie58ba8114d7e4c6427f0f28716deee71995c0d24 Reviewed-by: Fabian Kosmale --- .../data/dumper/ExtendedType/plugins.qmltypes | 6 +-- tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp | 8 ++-- .../qqmlenginecleanup/tst_qqmlenginecleanup.cpp | 3 +- tests/auto/qml/qqmlimport/tst_qqmlimport.cpp | 4 +- tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp | 50 ++++++++++++++-------- .../qqmlpropertycache/tst_qqmlpropertycache.cpp | 5 ++- .../tst_qquickdesignersupport.cpp | 5 ++- tests/benchmarks/qml/creation/tst_creation.cpp | 2 +- 8 files changed, 54 insertions(+), 29 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes b/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes index d84eb0011a..5c5ae73ca5 100644 --- a/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes +++ b/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes @@ -27,9 +27,9 @@ Module { "dumper.ExtendedType/Type 1.0", "dumper.ExtendedType/Type 1.1" ] - exportMetaObjectRevisions: [0, 101] + exportMetaObjectRevisions: [0, 257] Property { name: "baseProperty"; type: "int" } - Property { name: "extendedProperty"; revision: 101; type: "int" } - Property { name: "data"; revision: 101; type: "QObject"; isList: true; isReadonly: true } + Property { name: "extendedProperty"; revision: 257; type: "int" } + Property { name: "data"; revision: 257; type: "QObject"; isList: true; isReadonly: true } } } diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp index bc4ba9437c..db79adac6c 100644 --- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp +++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp @@ -94,7 +94,8 @@ namespace { QString toString(const QQmlDirParser::Component &c) { return c.typeName + QLatin1Char('|') + c.fileName + QLatin1Char('|') - + QString::number(c.majorVersion) + QLatin1Char('|') + QString::number(c.minorVersion) + + QString::number(c.version.majorVersion()) + QLatin1Char('|') + + QString::number(c.version.minorVersion()) + QLatin1Char('|') + (c.internal ? "true" : "false"); } @@ -112,7 +113,8 @@ namespace { QString toString(const QQmlDirParser::Script &s) { return s.nameSpace + QLatin1Char('|') + s.fileName + QLatin1Char('|') - + QString::number(s.majorVersion) + '|' + QString::number(s.minorVersion); + + QString::number(s.version.majorVersion()) + '|' + + QString::number(s.version.minorVersion()); } QStringList toStringList(const QList &scripts) @@ -248,7 +250,7 @@ void tst_qqmldirparser::parse_data() << "unversioned-component/qmldir" << QStringList() << QStringList() - << (QStringList() << "foo|bar|-1|-1|false") + << (QStringList() << "foo|bar|255|255|false") << QStringList() << QStringList() << false; diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp index 690db30838..0e70933ec6 100644 --- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp +++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp @@ -77,7 +77,8 @@ void tst_qqmlenginecleanup::test_qmlClearTypeRegistrations() QUrl testFile = testFileUrl("types.qml"); const auto qmlTypeForTestType = []() { - return QQmlMetaType::qmlType(QStringLiteral("TestTypeCpp"), QStringLiteral("Test"), 2, 0); + return QQmlMetaType::qmlType(QStringLiteral("TestTypeCpp"), QStringLiteral("Test"), + QTypeRevision::fromVersion(2, 0)); }; QVERIFY(!qmlTypeForTestType().isValid()); diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp index 9c865b3f73..6e95ddfdea 100644 --- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp +++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp @@ -190,7 +190,9 @@ void tst_QQmlImport::completeQmldirPaths() QFETCH(int, minorVersion); QFETCH(QStringList, expectedPaths); - QCOMPARE(QQmlImports::completeQmldirPaths(uri, basePaths, majorVersion, minorVersion), expectedPaths); + QCOMPARE(QQmlImports::completeQmldirPaths( + uri, basePaths, QTypeRevision::fromVersion(majorVersion, minorVersion)), + expectedPaths); } class QmldirUrlInterceptor : public QQmlAbstractUrlInterceptor { diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index 296d1b14e0..c8e6e9c935 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -217,13 +217,14 @@ void tst_qqmlmetatype::qmlPropertyValueInterceptorCast() void tst_qqmlmetatype::qmlType() { - QQmlType type = QQmlMetaType::qmlType(QString("ParserStatusTestType"), QString("Test"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("ParserStatusTestType"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module() == QLatin1String("Test")); QVERIFY(type.elementName() == QLatin1String("ParserStatusTestType")); QCOMPARE(type.qmlTypeName(), QLatin1String("Test/ParserStatusTestType")); - type = QQmlMetaType::qmlType("Test/ParserStatusTestType", 1, 0); + type = QQmlMetaType::qmlType("Test/ParserStatusTestType", QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module() == QLatin1String("Test")); QVERIFY(type.elementName() == QLatin1String("ParserStatusTestType")); @@ -282,19 +283,22 @@ void tst_qqmlmetatype::defaultObject() void tst_qqmlmetatype::registrationType() { - QQmlType type = QQmlMetaType::qmlType(QString("TestType"), QString("Test"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("TestType"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); QVERIFY(!type.isComposite()); - type = QQmlMetaType::qmlType(QString("TestTypeSingleton"), QString("Test"), 1, 0); + type = QQmlMetaType::qmlType(QString("TestTypeSingleton"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); QVERIFY(!type.isComposite()); - type = QQmlMetaType::qmlType(QString("TestTypeComposite"), QString("Test"), 1, 0); + type = QQmlMetaType::qmlType(QString("TestTypeComposite"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -310,7 +314,8 @@ void tst_qqmlmetatype::compositeType() QScopedPointer obj(c.create()); QVERIFY(obj); - QQmlType type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module().isEmpty()); QCOMPARE(type.elementName(), QLatin1String("ImplicitType")); @@ -380,10 +385,12 @@ void tst_qqmlmetatype::unregisterCustomType() int controllerId = 0; { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -403,10 +410,12 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlMetaType::unregisterType(controllerId); { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -426,10 +435,12 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlMetaType::unregisterType(controllerId); { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -480,7 +491,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType("mytypes", 1, 0, "StaticProvider", createStaticProvider1); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -496,7 +508,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType("mytypes", 1, 0, "StaticProvider", createStaticProvider2); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -512,7 +525,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType("mytypes", 1, 0, "StaticProvider", createStaticProvider1); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -548,7 +562,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties() QQmlComponent c(&e); c.setData("import QtQuick 2.2\n Item { }", dummy); - const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); + const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", + QTypeRevision::fromVersion(2, 2)); QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), attachedType.metaObject()); @@ -568,7 +583,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties() "import QtQuick 2.2 \n" "Item { KeyNavigation.up: null }", dummy); - const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); + const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", + QTypeRevision::fromVersion(2, 2)); QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), attachedType.metaObject()); diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index c79fdc57b4..25a448a97f 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -167,8 +167,9 @@ void tst_qqmlpropertycache::revisionedProperties() QQmlRefPointer cacheWithoutVersion(new QQmlPropertyCache(metaObject), QQmlRefPointer::Adopt); - QQmlRefPointer cacheWithVersion(new QQmlPropertyCache(metaObject, 1), - QQmlRefPointer::Adopt); + QQmlRefPointer cacheWithVersion( + new QQmlPropertyCache(metaObject, QTypeRevision::fromEncodedVersion(1)), + QQmlRefPointer::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cacheWithoutVersion, "propertyE"))); diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp index b44977bd5a..062a8b5c9a 100644 --- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp +++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp @@ -76,7 +76,10 @@ void tst_qquickdesignersupport::customData() QVERIFY(rootItem); - QScopedPointer newItemScopedPointer(QQuickDesignerSupportItems::createPrimitive(QLatin1String("QtQuick/Item"), 2, 6, view->rootContext())); + QScopedPointer newItemScopedPointer(QQuickDesignerSupportItems::createPrimitive( + QLatin1String("QtQuick/Item"), + QTypeRevision::fromVersion(2, 6), + view->rootContext())); QObject *newItem = newItemScopedPointer.data(); QVERIFY(newItem); diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index ed2e52f869..2044360b3d 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -196,7 +196,7 @@ void tst_creation::qobject_10tree_cpp() void tst_creation::qobject_qmltype() { - QQmlType t = QQmlMetaType::qmlType("QtQuick/QtObject", 2, 0); + QQmlType t = QQmlMetaType::qmlType("QtQuick/QtObject", QTypeRevision::fromVersion(2, 0)); QBENCHMARK { QObject *obj = t.create(); -- cgit v1.2.3 From 32dffb917536c6fb4af2986abaa6b0c7f35daed7 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 23 Jan 2020 13:07:22 +0100 Subject: Further RHI adaptation of shaders in lancelot test scenes In the recent commit that added RHI shaders, a couple of the test scenes were overlooked. The attributes.qml test file is simply removed as it adds no significant test coverage. Change-Id: Ic3af7b4447da322323f67faa1cf93c160c5043e8 Reviewed-by: Laszlo Agocs --- .../data/shaders/gridmesh/attributes.qml | 65 ---------------------- .../data/shaders/source/switch_3.qml | 9 +-- 2 files changed, 1 insertion(+), 73 deletions(-) delete mode 100644 tests/manual/scenegraph_lancelot/data/shaders/gridmesh/attributes.qml (limited to 'tests') diff --git a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/attributes.qml b/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/attributes.qml deleted file mode 100644 index 17d9aadf95..0000000000 --- a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/attributes.qml +++ /dev/null @@ -1,65 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 320 - height: 480 - - Text { - id: text - font.pixelSize: 80 - text: "Shaderz!" - } - - ShaderEffectSource { - id: source - sourceItem: text - hideSource: true - smooth: true - } - Column { - ShaderEffect { - width: 320 - height: 160 - property variant source: source - vertexShader: " - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - varying highp vec2 qt_TexCoord0; - void main() { - gl_Position = qt_Matrix * qt_Vertex; - qt_TexCoord0 = qt_MultiTexCoord0; - }" - } - ShaderEffect { - width: 320 - height: 160 - property variant source: source - vertexShader: " - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - varying highp vec2 qt_TexCoord0; - void main() { - gl_Position = qt_Matrix * qt_Vertex; - qt_TexCoord0 = qt_MultiTexCoord0; - }" - } - ShaderEffect { - width: 320 - height: 160 - property variant source: source - vertexShader: " - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - varying highp vec2 qt_TexCoord0; - uniform highp float width; - uniform highp float height; - void main() { - gl_Position = qt_Matrix * qt_Vertex; - qt_TexCoord0 = qt_Vertex.xy / vec2(width, height); - }" - } - } -} diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml b/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml index 0d3c1fc4ee..c02dfba9e2 100644 --- a/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml +++ b/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml @@ -47,14 +47,7 @@ Item { property variant source: source - fragmentShader: " - uniform lowp sampler2D source; - varying highp vec2 qt_TexCoord0; - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = vec4(qt_TexCoord0.x, qt_TexCoord0.y, 1, 1) * texture2D(source, qt_TexCoord0).a; - } - " + fragmentShader: "qrc:shaders/gradient.frag" } -- cgit v1.2.3 From bda38eae465fdf7dc719966e1199eafc7eb7c27c Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Fri, 24 Jan 2020 11:17:44 +0100 Subject: Tests: rename connect -> connectTo avoids strange compiler errors if a QObject::connect is used Change-Id: Ib9f5fc4114a06f7f1d1a0b9a142a15ce19270cec Reviewed-by: Tim Jenssen --- .../tst_qdebugmessageservice.cpp | 2 +- .../qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp | 2 +- .../qqmlenginecontrol/tst_qqmlenginecontrol.cpp | 10 +++---- .../tst_qqmlenginedebuginspectorintegration.cpp | 2 +- .../debugger/qqmlinspector/tst_qqmlinspector.cpp | 2 +- .../qml/debugger/qqmlpreview/tst_qqmlpreview.cpp | 2 +- .../tst_qqmlprofilerservice.cpp | 32 +++++++++++----------- tests/auto/qml/debugger/shared/debugutil.cpp | 2 +- tests/auto/qml/debugger/shared/debugutil_p.h | 2 +- 9 files changed, 28 insertions(+), 28 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp index 1c1f785560..ec7ee15d34 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp +++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp @@ -135,7 +135,7 @@ QList tst_QDebugMessageService::createClients() void tst_QDebugMessageService::retrieveDebugOutput() { - QCOMPARE(QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", + QCOMPARE(QQmlDebugTest::connectTo(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", QString(), testFile(QMLFILE), true), ConnectSuccess); QTRY_VERIFY(m_client->logBuffer.size() >= 2); diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 5b6c43bc0c..3f424d16f2 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -180,7 +180,7 @@ QQmlDebugTest::ConnectResult tst_QQmlDebugJS::init(bool qmlscene, const QString const QString executable = qmlscene ? QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene" : debugJsServerPath("qqmldebugjs"); - return QQmlDebugTest::connect( + return QQmlDebugTest::connectTo( executable, restrictServices ? QStringLiteral("V8Debugger") : QString(), testFile(qmlFile), blockMode); } diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp index a8c43b1c75..c8915fb840 100644 --- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp +++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp @@ -66,7 +66,7 @@ class tst_QQmlEngineControl : public QQmlDebugTest Q_OBJECT private: - ConnectResult connect(const QString &testFile, bool restrictServices); + ConnectResult connectTo(const QString &testFile, bool restrictServices); QList createClients() override; void engine_data(); @@ -79,10 +79,10 @@ private slots: void stopEngine(); }; -QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connect(const QString &file, +QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connectTo(const QString &file, bool restrictServices) { - return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", + return QQmlDebugTest::connectTo(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", restrictServices ? QStringLiteral("EngineControl") : QString(), testFile(file), true); } @@ -109,7 +109,7 @@ void tst_QQmlEngineControl::startEngine_data() void tst_QQmlEngineControl::startEngine() { QFETCH(bool, restrictMode); - QCOMPARE(connect("test.qml", restrictMode), ConnectSuccess); + QCOMPARE(connectTo("test.qml", restrictMode), ConnectSuccess); QTRY_VERIFY(!m_client->blockedEngines().empty()); m_client->releaseEngine(m_client->blockedEngines().last()); @@ -130,7 +130,7 @@ void tst_QQmlEngineControl::stopEngine() { QFETCH(bool, restrictMode); - QCOMPARE(connect("exit.qml", restrictMode), ConnectSuccess); + QCOMPARE(connectTo("exit.qml", restrictMode), ConnectSuccess); QTRY_VERIFY(!m_client->blockedEngines().empty()); m_client->releaseEngine(m_client->blockedEngines().last()); diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp index 980e2be1f1..9830f1a9bd 100644 --- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp @@ -87,7 +87,7 @@ QQmlEngineDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRoot QQmlDebugTest::ConnectResult tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices) { - return QQmlDebugTest::connect( + return QQmlDebugTest::connectTo( QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", restrictServices ? QStringLiteral("QmlDebugger,QmlInspector") : QString(), testFile("qtquick2.qml"), true); diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp index 6685558bb5..b5f45f1eeb 100644 --- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp +++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp @@ -64,7 +64,7 @@ private slots: QQmlDebugTest::ConnectResult tst_QQmlInspector::startQmlProcess(const QString &qmlFile, bool restrictServices) { - return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", + return QQmlDebugTest::connectTo(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", restrictServices ? QStringLiteral("QmlInspector") : QString(), testFile(qmlFile), true); } diff --git a/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp index 15eb4012ac..bfec776614 100644 --- a/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp +++ b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp @@ -74,7 +74,7 @@ private slots: QQmlDebugTest::ConnectResult tst_QQmlPreview::startQmlProcess(const QString &qmlFile) { - return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", + return QQmlDebugTest::connectTo(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", QStringLiteral("QmlPreview"), testFile(qmlFile), true); } diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index 085eb7b87a..c2a774b42d 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -201,7 +201,7 @@ private: CheckType = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckFileEndsWith }; - ConnectResult connect(bool block, const QString &file, bool recordFromStart = true, + ConnectResult connectTo(bool block, const QString &file, bool recordFromStart = true, uint flushInterval = 0, bool restrictServices = true, const QString &executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"); @@ -246,7 +246,7 @@ private: #define VERIFY(type, position, expected, checks, numbers) \ QVERIFY(verify(type, position, expected, checks, numbers)) -QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect( +QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connectTo( bool block, const QString &file, bool recordFromStart, uint flushInterval, bool restrictServices, const QString &executable) { @@ -255,7 +255,7 @@ QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect( m_isComplete = false; // ### Still using qmlscene due to QTBUG-33377 - return QQmlDebugTest::connect( + return QQmlDebugTest::connectTo( executable, restrictServices ? "CanvasFrameRate,EngineControl,DebugMessages" : QString(), testFile(file), block); @@ -542,7 +542,7 @@ void tst_QQmlProfilerService::connect() QFETCH(bool, restrictMode); QFETCH(bool, traceEnabled); - QCOMPARE(connect(blockMode, "test.qml", traceEnabled, 0, restrictMode), ConnectSuccess); + QCOMPARE(connectTo(blockMode, "test.qml", traceEnabled, 0, restrictMode), ConnectSuccess); if (!traceEnabled) m_client->client->setRecording(true); @@ -556,7 +556,7 @@ void tst_QQmlProfilerService::connect() void tst_QQmlProfilerService::pixmapCacheData() { - QCOMPARE(connect(true, "pixmapCacheTest.qml"), ConnectSuccess); + QCOMPARE(connectTo(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 && @@ -594,7 +594,7 @@ void tst_QQmlProfilerService::pixmapCacheData() void tst_QQmlProfilerService::scenegraphData() { - QCOMPARE(connect(true, "scenegraphTest.qml"), ConnectSuccess); + QCOMPARE(connectTo(true, "scenegraphTest.qml"), ConnectSuccess); while (!m_process->output().contains(QLatin1String("tick"))) QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); @@ -654,7 +654,7 @@ void tst_QQmlProfilerService::scenegraphData() void tst_QQmlProfilerService::profileOnExit() { - QCOMPARE(connect(true, "exit.qml"), ConnectSuccess); + QCOMPARE(connectTo(true, "exit.qml"), ConnectSuccess); checkProcessTerminated(); checkTraceReceived(); @@ -663,7 +663,7 @@ void tst_QQmlProfilerService::profileOnExit() void tst_QQmlProfilerService::controlFromJS() { - QCOMPARE(connect(true, "controlFromJS.qml", false), ConnectSuccess); + QCOMPARE(connectTo(true, "controlFromJS.qml", false), ConnectSuccess); QTRY_VERIFY(m_client->numLoadedEventTypes() > 0); m_client->client->setRecording(false); @@ -673,7 +673,7 @@ void tst_QQmlProfilerService::controlFromJS() void tst_QQmlProfilerService::signalSourceLocation() { - QCOMPARE(connect(true, "signalSourceLocation.qml"), ConnectSuccess); + QCOMPARE(connectTo(true, "signalSourceLocation.qml"), ConnectSuccess); while (!(m_process->output().contains(QLatin1String("500")))) QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); @@ -694,7 +694,7 @@ void tst_QQmlProfilerService::signalSourceLocation() void tst_QQmlProfilerService::javascript() { - QCOMPARE(connect(true, "javascript.qml"), ConnectSuccess); + QCOMPARE(connectTo(true, "javascript.qml"), ConnectSuccess); while (!(m_process->output().contains(QLatin1String("done")))) QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); @@ -722,7 +722,7 @@ void tst_QQmlProfilerService::javascript() void tst_QQmlProfilerService::flushInterval() { - QCOMPARE(connect(true, "timer.qml", true, 1), ConnectSuccess); + QCOMPARE(connectTo(true, "timer.qml", true, 1), ConnectSuccess); // Make sure we get multiple messages QTRY_VERIFY(m_client->qmlMessages.length() > 0); @@ -736,7 +736,7 @@ void tst_QQmlProfilerService::flushInterval() void tst_QQmlProfilerService::translationBinding() { - QCOMPARE(connect(true, "qstr.qml"), ConnectSuccess); + QCOMPARE(connectTo(true, "qstr.qml"), ConnectSuccess); checkProcessTerminated(); checkTraceReceived(); @@ -752,7 +752,7 @@ void tst_QQmlProfilerService::translationBinding() void tst_QQmlProfilerService::memory() { - QCOMPARE(connect(true, "memory.qml"), ConnectSuccess); + QCOMPARE(connectTo(true, "memory.qml"), ConnectSuccess); checkProcessTerminated(); checkTraceReceived(); @@ -781,7 +781,7 @@ static bool hasCompileEvents(const QVector &types) void tst_QQmlProfilerService::compile() { // Flush interval so that we actually get the events before we stop recording. - connect(true, "test.qml", true, 100); + connectTo(true, "test.qml", true, 100); QVERIFY(m_client); @@ -820,7 +820,7 @@ void tst_QQmlProfilerService::compile() void tst_QQmlProfilerService::multiEngine() { - QCOMPARE(connect(true, "quit.qml", true, 0, false, debugJsServerPath("qqmlprofilerservice")), + QCOMPARE(connectTo(true, "quit.qml", true, 0, false, debugJsServerPath("qqmlprofilerservice")), ConnectSuccess); QSignalSpy spy(m_client->client, SIGNAL(complete(qint64))); @@ -837,7 +837,7 @@ void tst_QQmlProfilerService::multiEngine() void tst_QQmlProfilerService::batchOverflow() { // The trace client checks that the events are received in order. - QCOMPARE(connect(true, "batchOverflow.qml"), ConnectSuccess); + QCOMPARE(connectTo(true, "batchOverflow.qml"), ConnectSuccess); checkProcessTerminated(); checkTraceReceived(); checkJsHeap(); diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp index 68446b53a4..3787f34bc2 100644 --- a/tests/auto/qml/debugger/shared/debugutil.cpp +++ b/tests/auto/qml/debugger/shared/debugutil.cpp @@ -120,7 +120,7 @@ void QQmlDebugTestClient::messageReceived(const QByteArray &ba) emit serverMessage(ba); } -QQmlDebugTest::ConnectResult QQmlDebugTest::connect( +QQmlDebugTest::ConnectResult QQmlDebugTest::connectTo( const QString &executable, const QString &services, const QString &extraArgs, bool block) { diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h index 41a5663283..190909dc44 100644 --- a/tests/auto/qml/debugger/shared/debugutil_p.h +++ b/tests/auto/qml/debugger/shared/debugutil_p.h @@ -65,7 +65,7 @@ public: Q_ENUM(ConnectResult) protected: - ConnectResult connect(const QString &executable, const QString &services, + ConnectResult connectTo(const QString &executable, const QString &services, const QString &extraArgs, bool block); virtual QQmlDebugProcess *createProcess(const QString &executable); -- cgit v1.2.3 From a8bc011d459a4d080815a2675f2a0413c8bf09d2 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 4 Feb 2020 08:31:10 +0100 Subject: QV4: Handle value tyes in sameValue algorithm The sameValue(Zero) algorithm were implemented according to the JavaScript specification; however QML has the concept of value types. For those we need to check equality with the intrinsic isEqualTo method. This aligns sameValue(Zero) with strict equality in its treatment of value types. This fixes Array.includes for value types Fixes: QTBUG-81825 Change-Id: Idd3e09cbed94bca6ea44f5683610b87d184e432c Reviewed-by: Ulf Hermann --- .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tests') diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index ec0db16114..558647e17a 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -74,6 +74,7 @@ public: private slots: void initTestCase(); + void arrayIncludesValueType(); void assignBasicTypes(); void assignDate_data(); void assignDate(); @@ -414,6 +415,36 @@ void tst_qqmlecmascript::initTestCase() registerTypes(); } +void tst_qqmlecmascript::arrayIncludesValueType() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + // It is vital that QtQuick is imported below else we get a warning about + // QQml_colorProvider and tst_qqmlecmascript::signalParameterTypes fails due + // to some static variable being initialized with the wrong value + component.setData(R"( + import QtQuick 2.15 + import QtQml 2.15 + QtObject { + id: root + property color r: Qt.rgba(1, 0, 0) + property color g: Qt.rgba(0, 1, 0) + property color b: Qt.rgba(0, 0, 1) + property var colors: [r, g, b] + property bool success: false + + Component.onCompleted: { + root.success = root.colors.includes(root.g) + } + } + )", QUrl("testData")); + QScopedPointer o(component.create()); + QVERIFY(o); + auto success = o->property("success"); + QVERIFY(success.isValid()); + QVERIFY(success.toBool()); +} + void tst_qqmlecmascript::assignBasicTypes() { QQmlEngine engine; -- cgit v1.2.3 From 9dccec88e3394d9d2dc52812d9607f0bfa01a2d2 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Wed, 5 Feb 2020 08:50:37 +0100 Subject: Inline components: fix name resolution Inline components are an explicit component boundary, and therefore need some extra treatment. Change-Id: I03cc0d58f3565999f64675e8482ed3c3a325e8c0 Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmllanguage/data/SimpleItem.qml | 5 +++++ .../qml/qqmllanguage/data/inlineComponentWithAlias.qml | 17 +++++++++++++++++ .../qml/qqmllanguage/data/inlineComponentWithId.qml | 14 ++++++++++++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 3 +++ 4 files changed, 39 insertions(+) create mode 100644 tests/auto/qml/qqmllanguage/data/SimpleItem.qml create mode 100644 tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml create mode 100644 tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmllanguage/data/SimpleItem.qml b/tests/auto/qml/qqmllanguage/data/SimpleItem.qml new file mode 100644 index 0000000000..c7bce2bc78 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/SimpleItem.qml @@ -0,0 +1,5 @@ +import QtQuick 2.15 + +Item { + property int i: 42 +} diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml new file mode 100644 index 0000000000..ab125e9323 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml @@ -0,0 +1,17 @@ +import QtQuick 2.15 + +Item { + id: root + component IC: SimpleItem { + width: i + Rectangle { + id: rect + color: "lime" + } + property alias color: rect.color + } + width: 200 + IC { + objectName: "icInstance" + } +} diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml new file mode 100644 index 0000000000..c4093bad2f --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml @@ -0,0 +1,14 @@ +import QtQuick 2.15 + +Item { + id: root + component IC: SimpleItem { + id: root + width: root.i + property color color: "red" + } + width: 200 + IC { + objectName: "icInstance" + } +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index b4ad9bd7b3..5966831183 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -5547,6 +5547,9 @@ void tst_qqmllanguage::inlineComponent_data() QTest::newRow("Non-toplevel IC is found") << testFileUrl("inlineComponentUser5.qml") << QColorConstants::Svg::red << 24; QTest::newRow("Resolved in correct order") << testFileUrl("inlineComponentOrder.qml") << QColorConstants::Blue << 200; + + QTest::newRow("ID resolves correctly") << testFileUrl("inlineComponentWithId.qml") << QColorConstants::Svg::red << 42; + QTest::newRow("Alias resolves correctly") << testFileUrl("inlineComponentWithAlias.qml") << QColorConstants::Svg::lime << 42; } void tst_qqmllanguage::inlineComponentReferenceCycle_data() -- cgit v1.2.3 From 4975a33ba9aa357ba2bca93e292b1fbcfb34c24e Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Fri, 24 Jan 2020 11:26:06 +0100 Subject: QmlDebug: add new debugtranslationservice Users were asking for having the possibility to see where the translated text will not fit in the reserved/available space. This is more a preparation patch to get the right connectors to change the visualization of findings or maybe log this to a file. Task-number: QDS-1463 Change-Id: Ic0a7a930141d6eeb79964e51c0a165c69888cf5d Reviewed-by: Ulf Hermann --- tests/auto/qml/debugger/debugger.pro | 1 + .../qqmldebugtranslationservice/data/test.qml | 41 +++++++++++ .../qqmldebugtranslationservice.pro | 12 ++++ .../tst_qqmldebugtranslationservice.cpp | 80 ++++++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml create mode 100644 tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro create mode 100644 tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp (limited to 'tests') diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro index 5c328fbfcc..890e722aa3 100644 --- a/tests/auto/qml/debugger/debugger.pro +++ b/tests/auto/qml/debugger/debugger.pro @@ -4,6 +4,7 @@ SUBDIRS += qqmldebugjsserver PUBLICTESTS += \ qdebugmessageservice \ + qqmldebugtranslationservice \ qqmlenginedebugservice \ qqmldebugjs \ qqmlinspector \ diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml new file mode 100644 index 0000000000..234496577a --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 2.12 + +Item { + width: 360 + height: 360 + + Text { + text: qsTr("hello") + width: parent.width / 10 + elide: Text.ElideRight + } +} diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro b/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro new file mode 100644 index 0000000000..32e60e306d --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qdebugtranslationservice +QT += network testlib gui-private core-private qmldebug-private +macos:CONFIG -= app_bundle + +SOURCES += tst_qqmldebugtranslationservice.cpp + +include(../shared/debugutil.pri) + +TESTDATA = data/* + +OTHER_FILES += data/test.qml diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp b/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp new file mode 100644 index 0000000000..01ee805dee --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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$ +** +****************************************************************************/ + +//QQmlDebugTest +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +const char *QMLFILE = "test.qml"; + +class tst_QQmlDebugTranslationService : public QQmlDebugTest +{ + Q_OBJECT + +private slots: + void pluginConnection(); + +private: + QList createClients() override; + QPointer m_client; +}; + +QList tst_QQmlDebugTranslationService::createClients() +{ + m_client = new QQmlDebugTranslationClient(m_connection); + + QObject::connect(m_client, &QQmlDebugClient::stateChanged, m_client, [this](QQmlDebugClient::State newState) { + QCOMPARE(newState, m_client->state()); + }); + + return {m_client}; +} + +void tst_QQmlDebugTranslationService::pluginConnection() +{ + auto executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml"; + auto services = "DebugTranslation"; + auto extraArgs = testFile(QMLFILE); + auto block = true; + + auto result = QQmlDebugTest::connectTo(executable, services, extraArgs, block); + QCOMPARE(result, ConnectSuccess); +} + +QTEST_MAIN(tst_QQmlDebugTranslationService) + +#include "tst_qqmldebugtranslationservice.moc" -- cgit v1.2.3 From 6ba3dc8d489be0058d8ca6349ac19b0857247b17 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 4 Feb 2020 12:06:49 +0100 Subject: Models: Make sure we can use QList as required model We can use it as model passed via a context property as shown in the objectlistmodel example. We should also be able to pass it directly then. Change-Id: I55db74df969d8024553d9470f1afe4710e61b1bf Reviewed-by: Fabian Kosmale --- .../data/requiredObjectListModel.qml | 15 ++++++ .../quick/qquicklistview/tst_qquicklistview.cpp | 57 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml (limited to 'tests') diff --git a/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml b/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml new file mode 100644 index 0000000000..f6380ed5aa --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + required model + + delegate: Rectangle { + required color + required property string name + + height: 25 + width: 100 + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 45d16cc415..b141e235d5 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -294,6 +295,8 @@ private slots: void moveObjectModelItemToAnotherObjectModel(); void changeModelAndDestroyTheOldOne(); + void requiredObjectListModel(); + private: template void items(const QUrl &source); template void changed(const QUrl &source); @@ -10032,6 +10035,60 @@ void tst_QQuickListView::changeModelAndDestroyTheOldOne() // QTBUG-80203 // no crash } +class DataObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString color READ color CONSTANT) + +public: + DataObject(QObject *parent = nullptr) : QObject(parent) {} + DataObject(const QString &name, const QString &color, QObject *parent = nullptr) + : QObject(parent), m_name(name), m_color(color) {} + + QString name() const { return m_name; } + QString color() const { return m_color; } + +private: + QString m_name; + QString m_color; +}; + +void tst_QQuickListView::requiredObjectListModel() +{ + QList dataList = { + new DataObject("Item 1", "red", this), + new DataObject("Item 2", "green", this), + new DataObject("Item 3", "blue", this), + new DataObject("Item 4", "yellow", this) + }; + + const auto deleter = qScopeGuard([&](){ qDeleteAll(dataList); }); + Q_UNUSED(deleter); + + QQuickView view; + view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }}); + view.setSource(testFileUrl("requiredObjectListModel.qml")); + view.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + const auto *root = qobject_cast(view.rootObject()); + QVERIFY(root); + + QCOMPARE(root->count(), dataList.count()); + + for (int i = 0, end = dataList.count(); i != end; ++i) { + const auto *rect = qobject_cast(root->itemAtIndex(i)); + QVERIFY(rect); + const auto *data = qobject_cast(dataList.at(i)); + QVERIFY(data); + + QCOMPARE(rect->color(), QColor(data->color())); + QCOMPARE(rect->property("name").toString(), data->name()); + } +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" -- cgit v1.2.3 From 19cc92d170eaba83812be2abda15348ecfa2f072 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Fri, 7 Feb 2020 09:57:02 +0100 Subject: QV4Engine: Do not construct invalid QVariant If the provided typeHint is -1, it does not make sense to construct a QVariant of this type and to check whether it is appendable. Fixes: QTBUG-81945 Change-Id: I32cbb9e70e210a7eca8d55801c1783338d1173b7 Reviewed-by: Ulf Hermann --- tests/auto/qml/qjsvalue/tst_qjsvalue.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index 95f554776f..cab4686c37 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -1128,6 +1128,10 @@ void tst_QJSValue::toVariant() // array { + auto handler = qInstallMessageHandler([](QtMsgType type, const QMessageLogContext &, const QString &) { + if (type == QtMsgType::QtWarningMsg) + QFAIL("Converting QJSValue to QVariant should not cause error messages"); + }); QVariantList listIn; listIn << 123 << "hello"; QJSValue array = eng.toScriptValue(listIn); @@ -1145,8 +1149,9 @@ void tst_QJSValue::toVariant() QCOMPARE(array2.property("length").toInt(), array.property("length").toInt()); for (int i = 0; i < array.property("length").toInt(); ++i) QVERIFY(array2.property(i).strictlyEquals(array.property(i))); - } + qInstallMessageHandler(handler); + } } void tst_QJSValue::toQObject_nonQObject_data() -- cgit v1.2.3 From c915ac23d9a460070ab4e4f8417df9db461c537c Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Mon, 10 Feb 2020 16:25:47 +0100 Subject: QQmlEngine: Test that types are correctly removed Amends 4f0c9986069c690e8ed7a7d2b42dfbce5c492368 Change-Id: I10a0d7988e1f5a003ccc80faa5b5c9bda62359cd Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmlenginecleanup/data/MyItem.qml | 2 ++ tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 tests/auto/qml/qqmlenginecleanup/data/MyItem.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml b/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml new file mode 100644 index 0000000000..4bb8dfb486 --- /dev/null +++ b/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml @@ -0,0 +1,2 @@ +import QtQuick 2.12 +Item {} diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp index 690db30838..846ac842db 100644 --- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp +++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp @@ -45,6 +45,7 @@ private slots: void test_qmlClearTypeRegistrations(); void test_valueTypeProviderModule(); // QTBUG-43004 void test_customModuleCleanup(); + void test_qmlListCleared(); }; // A wrapper around QQmlComponent to ensure the temporary reference counts @@ -186,6 +187,18 @@ void tst_qqmlenginecleanup::test_customModuleCleanup() } } +void tst_qqmlenginecleanup::test_qmlListCleared() +{ + { + QQmlEngine engine; + auto url = testFileUrl("MyItem.qml"); + QQmlComponent comp(&engine, url); + QScopedPointer item {comp.create()}; + QCOMPARE(QQmlMetaType::qmlRegisteredListTypeCount(), 1); + } + QCOMPARE(QQmlMetaType::qmlRegisteredListTypeCount(), 0); +} + QTEST_MAIN(tst_qqmlenginecleanup) #include "tst_qqmlenginecleanup.moc" -- cgit v1.2.3 From 2f4c131805f4009f42abe991e0f92f096bbc55fd Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 11 Feb 2020 11:21:03 +0100 Subject: Fix QQmlProperty and Connections for properties starting with '_' We do a weird renaming for the change handler of properties starting with '_', now we do it at least in a consistent way. Fixes: QTBUG-82017 Change-Id: I1535a5ee462f3a344c972461f1fb954f039aa854 Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmlconnections/data/underscore.qml | 14 ++++++++++++++ .../auto/qml/qqmlconnections/tst_qqmlconnections.cpp | 15 +++++++++++++++ tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 tests/auto/qml/qqmlconnections/data/underscore.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmlconnections/data/underscore.qml b/tests/auto/qml/qqmlconnections/data/underscore.qml new file mode 100644 index 0000000000..0f73dc8f17 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/underscore.qml @@ -0,0 +1,14 @@ +import QtQuick 2.12 + +Item { + id: item + property bool success: false + property bool sanityCheck: false + property int __underscore_property: 0 + on__Underscore_propertyChanged: item.sanityCheck = true + + Connections { + target: item + on__Underscore_propertyChanged: item.success = true + } +} diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp index 07af519a3d..f144002875 100644 --- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp +++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp @@ -77,6 +77,8 @@ private slots: void noAcceleratedGlobalLookup_data() { prefixes(); } void noAcceleratedGlobalLookup(); + void bindToPropertyWithUnderscoreChangeHandler(); + private: QQmlEngine engine; void prefixes(); @@ -474,6 +476,19 @@ void tst_qqmlconnections::noAcceleratedGlobalLookup() QCOMPARE(val.toInt(), int(Proxy::EnumValue)); } +void tst_qqmlconnections::bindToPropertyWithUnderscoreChangeHandler() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("underscore.qml")); + QScopedPointer root {component.create()}; + QVERIFY(root); + QQmlProperty underscoreProperty(root.get(), "__underscore_property"); + QVERIFY(underscoreProperty.isValid()); + underscoreProperty.write(42); + QVERIFY(root->property("sanityCheck").toBool()); + QVERIFY(root->property("success").toBool()); +} + QTEST_MAIN(tst_qqmlconnections) #include "tst_qqmlconnections.moc" diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index a15c00ad62..864a47e998 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -158,6 +158,8 @@ private slots: void copy(); void nestedQQmlPropertyMap(); + + void underscorePropertyChangeHandler(); private: QQmlEngine engine; }; @@ -2230,6 +2232,24 @@ void tst_qqmlproperty::nestedQQmlPropertyMap() QCOMPARE(success.read().toString(), QLatin1String("success")); } +void tst_qqmlproperty::underscorePropertyChangeHandler() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(R"( + import QtQuick 2.12 + + Item { + property int __withUnderScore + } + )", QUrl::fromLocalFile(".")); + QScopedPointer root { component.create() }; + QVERIFY(root); + QQmlProperty changeHandler(root.get(), "on__WithUnderScoreChanged"); + QVERIFY(changeHandler.isValid()); + QVERIFY(changeHandler.isSignalProperty()); +} + QTEST_MAIN(tst_qqmlproperty) #include "tst_qqmlproperty.moc" -- cgit v1.2.3 From a363aa3df44da399d2aeb8785608501eae50e600 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 11 Feb 2020 14:44:28 +0100 Subject: QQmlCustomParser: Resolve import namespaces Also, don't use plain QObject for testing registrations with extensions and foreign types. This interacts with other tests. Change-Id: I43df8a4e5b22def5a87f508130f1c7b4833ecfb6 Fixes: QTBUG-81970 Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmllanguage/testtypes.h | 9 +++++-- tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 30 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 39502372e6..148179cb9c 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1440,17 +1440,22 @@ public: int base() const { return 43; } }; +class Local : public QObject +{ + Q_OBJECT +}; + class Foreign { Q_GADGET - QML_FOREIGN(QObject) + QML_FOREIGN(Local) QML_NAMED_ELEMENT(Foreign) }; class ForeignExtended { Q_GADGET - QML_FOREIGN(QObject) + QML_FOREIGN(Local) QML_NAMED_ELEMENT(ForeignExtended) QML_EXTENDED(Extension) }; diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 4f2e203ec2..2112e0cffb 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -325,6 +325,7 @@ private slots: void overrideSingleton(); void arrayToContainer(); + void qualifiedScopeInCustomParser(); private: QQmlEngine engine; @@ -5667,6 +5668,35 @@ void tst_qqmllanguage::arrayToContainer() QCOMPARE(root->m_points.at(0), QPointF (2.0, 3.0) ); } +class EnumTester : public QObject +{ + Q_OBJECT +public: + enum Types + { + FIRST = 0, + SECOND, + THIRD + }; + Q_ENUM(Types) +}; + +void tst_qqmllanguage::qualifiedScopeInCustomParser() +{ + qmlRegisterUncreatableType("scoped.custom.test", 1, 0, "EnumTester", + "Object only creatable in C++"); + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQml.Models 2.12\n" + "import scoped.custom.test 1.0 as BACKEND\n" + "ListModel {\n" + " ListElement { text: \"a\"; type: BACKEND.EnumTester.FIRST }\n" + "}\n", QUrl()); + QVERIFY(component.isReady()); + QScopedPointer obj(component.create()); + QVERIFY(!obj.isNull()); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" -- cgit v1.2.3 From c48b0902b56a62808e78b10d89435e85b840c8dc Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 11 Feb 2020 16:53:00 +0100 Subject: tst_qquickwindow: construct pointer events with proper devices In the QQuickPointerMouseEvent constructor, the device pointer became mandatory mainly because it's mandatory in QQuickSinglePointEvent, because we want to ensure that we distinguish mouse from tablet events. Change-Id: I3d314c6877493b8b5b6407f5eb5631f7083900a5 Reviewed-by: Shawn Rutledge --- tests/auto/quick/qquickwindow/tst_qquickwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index bf58ce961c..0bf83c267a 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -2860,7 +2860,7 @@ void tst_qquickwindow::pointerEventTypeAndPointCount() QList() << QTouchEvent::TouchPoint(1)); - QQuickPointerMouseEvent pme; + QQuickPointerMouseEvent pme(nullptr, QQuickPointerDevice::genericMouseDevice()); pme.reset(&me); QCOMPARE(pme.asMouseEvent(localPosition), &me); QVERIFY(pme.asPointerMouseEvent()); @@ -2872,7 +2872,7 @@ void tst_qquickwindow::pointerEventTypeAndPointCount() QCOMPARE(pme.asMouseEvent(localPosition)->localPos(), localPosition); QCOMPARE(pme.asMouseEvent(localPosition)->screenPos(), screenPosition); - QQuickPointerTouchEvent pte; + QQuickPointerTouchEvent pte(nullptr, QQuickPointerDevice::touchDevice(touchDevice)); pte.reset(&te); QCOMPARE(pte.asTouchEvent(), &te); QVERIFY(!pte.asPointerMouseEvent()); -- cgit v1.2.3 From 8e822e981d91e688799c8670f11dfdf6aaf9e0d1 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Sat, 14 Dec 2019 16:02:21 +0100 Subject: Deliver QTabletEvents to pointer handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At this time, there are not yet any specialized handlers to do anything specifically with tablet events; but we demonstrate how to use HoverHandler to detect the type of stylus in use, and how to use PointHandler to draw on a Canvas. Unfortunately, events of types TabletEnterProximity and TabletLeaveProximity are not delivered to the window, only to QGuiApplication. So HoverHandler can detect when the stylus is moved out of its parent Item (as long as it's still hovering over the tablet surface), but cannot detect when the stylus leaves the tablet completely. In Qt 5 that would require a custom application subclass (see qtbase/examples/widgets/widgets/tablet/tabletapplication.cpp). Fixes: QTBUG-79660 Change-Id: I81fdb99082dc41c0455085e6b6d3952402bf8742 Reviewed-by: Qt CI Bot Reviewed-by: Jan Arve Sæther --- .../qquickpointhandler/tst_qquickpointhandler.cpp | 60 +++++ tests/manual/pointer/main.qml | 3 +- tests/manual/pointer/qml.qrc | 5 + tests/manual/pointer/resources/cursor-airbrush.png | Bin 0 -> 823 bytes tests/manual/pointer/resources/cursor-eraser.png | Bin 0 -> 1454 bytes .../pointer/resources/cursor-felt-marker.png | Bin 0 -> 513 bytes tests/manual/pointer/resources/cursor-pencil.png | Bin 0 -> 1307 bytes tests/manual/pointer/tabletCanvasDrawing.qml | 242 +++++++++++++++++++++ 8 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 tests/manual/pointer/resources/cursor-airbrush.png create mode 100644 tests/manual/pointer/resources/cursor-eraser.png create mode 100644 tests/manual/pointer/resources/cursor-felt-marker.png create mode 100644 tests/manual/pointer/resources/cursor-pencil.png create mode 100644 tests/manual/pointer/tabletCanvasDrawing.qml (limited to 'tests') diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp index d0b3bc3d36..ca6463f365 100644 --- a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp @@ -55,6 +55,7 @@ private slots: void initTestCase(); void singleTouch(); + void tabletStylus(); void simultaneousMultiTouch(); void pressedMultipleButtons_data(); void pressedMultipleButtons(); @@ -136,6 +137,65 @@ void tst_PointHandler::singleTouch() QCOMPARE(translationSpy.count(), 3); } +void tst_PointHandler::tabletStylus() +{ + qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents, false); + QScopedPointer windowPtr; + createView(windowPtr, "pointTracker.qml"); + QQuickView * window = windowPtr.data(); + QQuickPointHandler *handler = window->rootObject()->findChild("pointHandler"); + QVERIFY(handler); + handler->setAcceptedDevices(QQuickPointerDevice::Stylus); + + QSignalSpy activeSpy(handler, SIGNAL(activeChanged())); + QSignalSpy pointSpy(handler, SIGNAL(pointChanged())); + QSignalSpy translationSpy(handler, SIGNAL(translationChanged())); + + QPoint point(100,100); + const qint64 stylusId = 1234567890; + + QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point), + QTabletEvent::Stylus, QTabletEvent::Pen, Qt::LeftButton, 0.5, 25, 35, 0.6, 12.3, 3, stylusId, Qt::NoModifier); + QTRY_COMPARE(handler->active(), true); + QCOMPARE(activeSpy.count(), 1); + QCOMPARE(pointSpy.count(), 1); + QCOMPARE(handler->point().position().toPoint(), point); + QCOMPARE(handler->point().scenePosition().toPoint(), point); + QCOMPARE(handler->point().pressedButtons(), Qt::LeftButton); + QCOMPARE(handler->point().pressure(), 0.5); + QCOMPARE(handler->point().rotation(), 12.3); + QCOMPARE(handler->point().uniqueId().numericId(), stylusId); + QCOMPARE(handler->translation(), QVector2D()); + QCOMPARE(translationSpy.count(), 1); + + point += QPoint(10, 10); + QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point), + QTabletEvent::Stylus, QTabletEvent::Pen, Qt::LeftButton, 0.45, 23, 33, 0.57, 15.6, 3.4, stylusId, Qt::NoModifier); + QTRY_COMPARE(pointSpy.count(), 2); + QCOMPARE(handler->active(), true); + QCOMPARE(activeSpy.count(), 1); + QCOMPARE(handler->point().position().toPoint(), point); + QCOMPARE(handler->point().scenePosition().toPoint(), point); + QCOMPARE(handler->point().pressPosition().toPoint(), QPoint(100, 100)); + QCOMPARE(handler->point().scenePressPosition().toPoint(), QPoint(100, 100)); + QCOMPARE(handler->point().pressedButtons(), Qt::LeftButton); + QCOMPARE(handler->point().pressure(), 0.45); + QCOMPARE(handler->point().rotation(), 15.6); + QCOMPARE(handler->point().uniqueId().numericId(), stylusId); + QVERIFY(handler->point().velocity().x() > 0); + QVERIFY(handler->point().velocity().y() > 0); + QCOMPARE(handler->translation(), QVector2D(10, 10)); + QCOMPARE(translationSpy.count(), 2); + + QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point), + QTabletEvent::Stylus, QTabletEvent::Pen, Qt::NoButton, 0, 0, 0, 0, 0, 0, stylusId, Qt::NoModifier); + QTRY_COMPARE(handler->active(), false); + QCOMPARE(activeSpy.count(), 2); + QCOMPARE(pointSpy.count(), 3); + QCOMPARE(handler->translation(), QVector2D()); + QCOMPARE(translationSpy.count(), 3); +} + void tst_PointHandler::simultaneousMultiTouch() { QScopedPointer windowPtr; diff --git a/tests/manual/pointer/main.qml b/tests/manual/pointer/main.qml index d382d8b23d..83e1d3b2ba 100644 --- a/tests/manual/pointer/main.qml +++ b/tests/manual/pointer/main.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the manual tests of the Qt Toolkit. @@ -57,6 +57,7 @@ Window { addExample("multibuttons", "TapHandler: gesturePolicy (99 red balloons)", Qt.resolvedUrl("multibuttons.qml")) addExample("flickable with Handlers", "Flickable with buttons, sliders etc. implemented in various ways", Qt.resolvedUrl("flickableWithHandlers.qml")) addExample("tap and drag", "Flickable with all possible combinations of TapHandler and DragHandler children", Qt.resolvedUrl("pointerDrag.qml")) + addExample("tablet canvas", "PointHandler and HoverHandler with a tablet: detect the stylus, and draw", Qt.resolvedUrl("tabletCanvasDrawing.qml")) } } Item { diff --git a/tests/manual/pointer/qml.qrc b/tests/manual/pointer/qml.qrc index 95bece180a..20956fcbac 100644 --- a/tests/manual/pointer/qml.qrc +++ b/tests/manual/pointer/qml.qrc @@ -13,6 +13,7 @@ pointerDrag.qml singlePointHandlerProperties.qml sidebar.qml + tabletCanvasDrawing.qml tapHandler.qml content/CheckBox.qml content/FakeFlickable.qml @@ -30,6 +31,10 @@ content/TouchpointFeedbackSprite.qml resources/arrowhead.png resources/balloon.png + resources/cursor-airbrush.png + resources/cursor-eraser.png + resources/cursor-felt-marker.png + resources/cursor-pencil.png resources/fighter.png resources/fingersprite.png resources/grabbing-location.svg diff --git a/tests/manual/pointer/resources/cursor-airbrush.png b/tests/manual/pointer/resources/cursor-airbrush.png new file mode 100644 index 0000000000..bea756ed6f Binary files /dev/null and b/tests/manual/pointer/resources/cursor-airbrush.png differ diff --git a/tests/manual/pointer/resources/cursor-eraser.png b/tests/manual/pointer/resources/cursor-eraser.png new file mode 100644 index 0000000000..e5488a89f2 Binary files /dev/null and b/tests/manual/pointer/resources/cursor-eraser.png differ diff --git a/tests/manual/pointer/resources/cursor-felt-marker.png b/tests/manual/pointer/resources/cursor-felt-marker.png new file mode 100644 index 0000000000..132f09aa39 Binary files /dev/null and b/tests/manual/pointer/resources/cursor-felt-marker.png differ diff --git a/tests/manual/pointer/resources/cursor-pencil.png b/tests/manual/pointer/resources/cursor-pencil.png new file mode 100644 index 0000000000..cc2f447d02 Binary files /dev/null and b/tests/manual/pointer/resources/cursor-pencil.png differ diff --git a/tests/manual/pointer/tabletCanvasDrawing.qml b/tests/manual/pointer/tabletCanvasDrawing.qml new file mode 100644 index 0000000000..c340dee5f4 --- /dev/null +++ b/tests/manual/pointer/tabletCanvasDrawing.qml @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import "content" + +Rectangle { + width: 1024 + height: 1024 + color: "#444" + + ColumnLayout { + x: -15; width: 80 + height: parent.height + Slider { + id: hueSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "hue" + Rectangle { + color: "beige" + width: 30 + height: 25 + anchors.bottom: parent.bottom + anchors.bottomMargin: 2 + anchors.horizontalCenter: parent.horizontalCenter + Rectangle { + border.color: "white" + color: canvas.drawingColor + anchors.fill: parent + } + } + } + Slider { + id: saturationSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "sat" + } + Slider { + id: lightnessSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "light" + } + } + + ColumnLayout { + x: parent.width - 65; width: 80 + height: parent.height + Slider { + id: widthSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "width" + } + Slider { + id: alphaSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "alpha" + } + } + + Rectangle { + id: rect + width: 640 + height: 480 + color: "beige" + anchors { + fill: parent + margins: 10 + leftMargin: 50 + rightMargin: 50 + } + + Canvas { + id: canvas + anchors.fill: parent + antialiasing: true + renderTarget: Canvas.FramebufferObject + property color drawingColor: Qt.hsla(hueSlider.value / 100.0, + saturationSlider.value / 100.0, + lightnessSlider.value / 100.0, + alphaSlider.value / 100.0) + property var points: [] + property var pressures: [] + property var pointerType: PointerDevice.Pen + onPaint: { + if (points.length < 2) + return + var ctx = canvas.getContext('2d'); + ctx.save() + ctx.strokeStyle = pointerType === PointerDevice.Pen ? drawingColor : "beige" + ctx.lineCap = "round" + if (pressures.length === points.length) { + for (var i = 1; i < points.length; i++) { + ctx.lineWidth = pressures[i] * widthSlider.value + ctx.beginPath() + ctx.moveTo(points[i - 1].x, points[i - 1].y) + ctx.lineTo(points[i].x, points[i].y) + ctx.stroke() + } + points = points.slice(points.length - 2, 1) + pressures = pressures.slice(pressures.length - 2, 1) + } else { + ctx.beginPath() + ctx.moveTo(points[0].x, points[0].y) + for (var i = 1; i < points.length; i++) + ctx.lineTo(points[i].x, points[i].y) + ctx.lineWidth = widthSlider + ctx.stroke() + points = points.slice(points.length - 2, 1) + pressures = [] + } + ctx.restore() + } + } + + PointHandler { + acceptedPointerTypes: PointerDevice.Pen + onActiveChanged: + if (active) { + canvas.pointerType = PointerDevice.Pen + } else { + canvas.points = [] + canvas.pressures = [] + } + onPointChanged: + if (active) { + canvas.points.push(point.position) + canvas.pressures.push(point.pressure) + canvas.requestPaint() + } + } + + PointHandler { + acceptedPointerTypes: PointerDevice.Eraser + onActiveChanged: + if (active) { + canvas.pointerType = PointerDevice.Eraser + } else { + canvas.points = [] + canvas.pressures = [] + } + onPointChanged: + if (active) { + canvas.points.push(point.position) + canvas.pressures.push(point.pressure) + canvas.requestPaint() + } + } + + HoverHandler { + id: stylusHandler + acceptedDevices: PointerDevice.Stylus + acceptedPointerTypes: PointerDevice.Pen + target: Image { + parent: rect + source: stylusHandler.point.rotation === 0 ? + "resources/cursor-pencil.png" : "resources/cursor-felt-marker.png" + visible: stylusHandler.hovered + rotation: stylusHandler.point.rotation + x: stylusHandler.point.position.x + y: stylusHandler.point.position.y + } + } + + HoverHandler { + id: airbrushHandler + acceptedDevices: PointerDevice.Airbrush + acceptedPointerTypes: PointerDevice.Pen + target: Image { + parent: rect + source: "resources/cursor-airbrush.png" + visible: airbrushHandler.hovered + x: airbrushHandler.point.position.x + y: airbrushHandler.point.position.y + } + } + + HoverHandler { + id: eraserHandler + acceptedPointerTypes: PointerDevice.Eraser + target: Image { + parent: rect + source: "resources/cursor-eraser.png" + visible: eraserHandler.hovered + x: eraserHandler.point.position.x + y: eraserHandler.point.position.y - 32 + } + } + } +} -- cgit v1.2.3 From df075ee964fa41f95a0dd1f691c1547dc0b018dc Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Wed, 12 Feb 2020 12:30:24 +0100 Subject: Blacklist tst_QQuickTextInput::setInputMask() on macOs Task-number: QTBUG-82058 Change-Id: Ida2a546044d4c85f3ec8037ff7e8f1fd2bd1f424 Reviewed-by: Ulf Hermann --- tests/auto/quick/qquicktextinput/BLACKLIST | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/quick/qquicktextinput/BLACKLIST b/tests/auto/quick/qquicktextinput/BLACKLIST index ada7c57c75..6cd24de9a9 100644 --- a/tests/auto/quick/qquicktextinput/BLACKLIST +++ b/tests/auto/quick/qquicktextinput/BLACKLIST @@ -1,3 +1,7 @@ # QTBUG-78162 [mouseSelectionMode] opensuse-leap + +# QTBUG-82058 +[setInputMask] +macos ci -- cgit v1.2.3 From 5b203bc4647e8e9d8d3c1091ba791c9589243420 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Wed, 12 Feb 2020 08:17:31 +0100 Subject: Blacklist tst_QQuickTextEdit::linkHover() on macOS Task-number: QTBUG-82052 Change-Id: I2718ab6004ba7a278b1917a6164566d6e541fbdc Reviewed-by: Simon Hausmann --- tests/auto/quick/qquicktextedit/BLACKLIST | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/quick/qquicktextedit/BLACKLIST b/tests/auto/quick/qquicktextedit/BLACKLIST index 36c7f0042f..b8147a0ef9 100644 --- a/tests/auto/quick/qquicktextedit/BLACKLIST +++ b/tests/auto/quick/qquicktextedit/BLACKLIST @@ -4,3 +4,7 @@ opensuse-leap # QTBUG-78846 [mouseSelectionMode] opensuse-leap + +# QTBUG-82052 +[linkHover] +macos ci -- cgit v1.2.3 From b9b860dc51eb11e2b6c8d95ce85f48057e542df6 Mon Sep 17 00:00:00 2001 From: Maximilian Goldstein Date: Thu, 6 Feb 2020 12:00:08 +0100 Subject: Blacklist flakey tst_QPauseAnimationJob::multipleSequentialGroups on macOS Task-number: QTBUG-81938 Change-Id: I9ced28d246161c87b5751699857dd0598121176e Reviewed-by: Simon Hausmann --- tests/auto/qml/animation/qpauseanimationjob/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/qml/animation/qpauseanimationjob/BLACKLIST (limited to 'tests') diff --git a/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST b/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST new file mode 100644 index 0000000000..33799b6528 --- /dev/null +++ b/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST @@ -0,0 +1,3 @@ +[multipleSequentialGroups] +macos ci + -- cgit v1.2.3 From c3f1b4ea25ccd7c036aa6d6c241c4cc3e6220d3e Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 10 Feb 2020 12:53:44 +0100 Subject: Mark simplePath as flakey test on macOS in the CI Task-number: QTBUG-82015 Change-Id: Iffde91ff903db1c767b7df76fa813d1d7c836f53 Reviewed-by: Simon Hausmann --- tests/auto/quick/qquickanimations/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/quick/qquickanimations/BLACKLIST (limited to 'tests') diff --git a/tests/auto/quick/qquickanimations/BLACKLIST b/tests/auto/quick/qquickanimations/BLACKLIST new file mode 100644 index 0000000000..a1b8557128 --- /dev/null +++ b/tests/auto/quick/qquickanimations/BLACKLIST @@ -0,0 +1,2 @@ +[simplePath] +macos ci -- cgit v1.2.3 From f73dad1c991aa5adff14e42812da70db9ac52018 Mon Sep 17 00:00:00 2001 From: Maximilian Goldstein Date: Wed, 5 Feb 2020 10:49:52 +0100 Subject: qtdeclarative: Disable movingItemWithHoverHandler on macOS The cursor cannot be moved on macOS >= 10.14. Task-number: QTBUG-76312 Task-number: QTBUG-81884 Change-Id: Iec73d572d2ccc0a4be8cc6c2c0b445329a200609 Reviewed-by: Simon Hausmann --- tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST (limited to 'tests') diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST new file mode 100644 index 0000000000..9bb35c4770 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST @@ -0,0 +1,3 @@ +[movingItemWithHoverHandler] +macos # Can't move cursor (QTBUG-76312) + -- cgit v1.2.3 From b9de07daebebe879fd793b278cad3b205f207c99 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 7 Feb 2020 09:31:39 +0100 Subject: Stabilize tst_QParallelAnimationGroupJob::deleteChildrenWithRunningGroup The point is not that the current loop has started after 80ms but that it starts at some point. The fixed waiting time makes us depend on scheduling. Change-Id: I36a5adef8563da66418a575d71fb79adff234d79 Reviewed-by: Fabian Kosmale --- .../qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp b/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp index a8bcadbc84..8c4c461813 100644 --- a/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp +++ b/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp @@ -432,8 +432,7 @@ void tst_QParallelAnimationGroupJob::deleteChildrenWithRunningGroup() QCOMPARE(group.state(), QAnimationGroupJob::Running); QCOMPARE(anim1->state(), QAnimationGroupJob::Running); - QTest::qWait(80); - QVERIFY(group.currentLoopTime() > 0); + QTRY_VERIFY(group.currentLoopTime() > 0); delete anim1; QVERIFY(!group.firstChild()); -- cgit v1.2.3 From d34e3445bd1482bf79f1fb6b2bf5a1c324e05c13 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 7 Feb 2020 11:11:18 +0100 Subject: Stabilize tst_qqmltimer::restart() Double the intervals. Some operating systems are sloppier with scheduling and we apparently trigger the timer a third time during the wait interval. We waited 600ms + 300ms = 900ms and expected the 500ms timer to hit only once before the restart. That was probably too tight. We also lower the second wait time by 100ms to allow for some more time skew, and check all intermediate states of the trigger counter. Change-Id: I2f83ffb0e05f1939d3525cd649322a4331986c3c Reviewed-by: Fabian Kosmale Reviewed-by: Maximilian Goldstein --- tests/auto/qml/qqmltimer/tst_qqmltimer.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp b/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp index 4e42d02514..0168663cf2 100644 --- a/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp +++ b/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp @@ -311,7 +311,7 @@ void tst_qqmltimer::restart() { QQmlEngine engine; QQmlComponent component(&engine); - component.setData(QByteArray("import QtQml 2.0\nTimer { interval: 500; repeat: true; running: true }"), QUrl::fromLocalFile("")); + component.setData(QByteArray("import QtQml 2.0\nTimer { interval: 1000; repeat: true; running: true }"), QUrl::fromLocalFile("")); QQmlTimer *timer = qobject_cast(component.create()); QVERIFY(timer != nullptr); @@ -319,14 +319,16 @@ void tst_qqmltimer::restart() connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); QCOMPARE(helper.count, 0); - consistentWait(600); + consistentWait(1200); QCOMPARE(helper.count, 1); - consistentWait(300); + consistentWait(500); + QCOMPARE(helper.count, 1); timer->restart(); + QCOMPARE(helper.count, 1); - consistentWait(700); + consistentWait(1400); QCOMPARE(helper.count, 2); QVERIFY(timer->isRunning()); -- cgit v1.2.3 From 5ec94281298af5dac8ce463e3ca02cf52595ce6e Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 10 Feb 2020 09:46:36 +0100 Subject: Blacklist tst_QQuickWheelHandler::singleHandler() on macOS Task-number: QTBUG-81993 Change-Id: I378e4873e9cf8e8805eaaf8cf0dd8e0afaf11108 Reviewed-by: Simon Hausmann --- tests/auto/quick/pointerhandlers/qquickwheelhandler/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/quick/pointerhandlers/qquickwheelhandler/BLACKLIST (limited to 'tests') diff --git a/tests/auto/quick/pointerhandlers/qquickwheelhandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickwheelhandler/BLACKLIST new file mode 100644 index 0000000000..2949d3371f --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickwheelhandler/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-81993 +[singleHandler] +macos ci -- cgit v1.2.3 From bc0e9b56744a4b796c14efd6ded9ebaa63567bdc Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 11 Feb 2020 11:50:49 +0100 Subject: Ignore flakey tst_qquickmousearea::pressAndHold Task-number: QTBUG-82043 Change-Id: I1490ef6875e46cee5c23a205ba19dc150e52ea18 Reviewed-by: Simon Hausmann --- tests/auto/quick/qquickmousearea/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/quick/qquickmousearea/BLACKLIST (limited to 'tests') diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST new file mode 100644 index 0000000000..6dbe3e11b6 --- /dev/null +++ b/tests/auto/quick/qquickmousearea/BLACKLIST @@ -0,0 +1,2 @@ +[pressAndHold] +macos ci -- cgit v1.2.3 From 899de66d41e4e9666187e107516ac714963e7b20 Mon Sep 17 00:00:00 2001 From: Maximilian Goldstein Date: Wed, 29 Jan 2020 12:22:28 +0100 Subject: qqmlxmlhttprequest: Disable local file access by default [ChangeLog][Important Behavior Changes] Local file accesses are now disabled by default for security reasons. To enable them set the environment variables QML_XHR_ALLOW_FILE_READ / QML_XHR_ALLOW_FILE_WRITE to 1 for reading and writing respectively. Change-Id: Idf225d6eb8f16b1716867101b8e768926242b7bf Reviewed-by: Fabian Kosmale --- .../qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp | 38 ++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp index ae794e76a9..2c08c33fc8 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp +++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp @@ -1133,15 +1133,16 @@ void tst_qqmlxmlhttprequest::sendFileRequest() #if QT_CONFIG(process) void tst_qqmlxmlhttprequest::sendFileRequestNotSet() { if (qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) { - // Test with no settings - // Should just result in warnings in Qt 5 - doFileRequest([](QObject* object, QTemporaryFile &writeFile) { - QTRY_COMPARE(object->property("readResult").toString(), testString); + // Test with no settings, neither reading nor writing should work + doFileRequest([](QObject *object, QTemporaryFile &writeFile) { + QTest::qWait(1000); - QTRY_VERIFY(object->property("writeDone").toBool()); + // Verify that the read has not yielded any value + QVERIFY(object->property("readResult").isNull()); + // Check that the file stays empty QVERIFY(writeFile.open()); - QCOMPARE(QString::fromUtf8(writeFile.readAll()), testString); + QCOMPARE(QString::fromUtf8(writeFile.readAll()), ""); writeFile.close(); }); return; @@ -1161,22 +1162,25 @@ void tst_qqmlxmlhttprequest::sendFileRequestNotSet() { // Check exit code QCOMPARE(child.exitCode(), 0); - // Check if all warnings were printed + // Check if all errors were printed QString output = QString::fromUtf8(child.readAllStandardOutput()); + // Due to differences in line endings on Windows, check for the error lines individually + const QStringList readingError = { + QLatin1String("XMLHttpRequest: Using GET on a local file is disabled by default."), + QLatin1String("Set QML_XHR_ALLOW_FILE_READ to 1 to enable this feature.") + }; - const QString readingWarning = QLatin1String( - "XMLHttpRequest: Using GET on a local file is dangerous " - "and will be disabled by default in a future Qt version." - "Set QML_XHR_ALLOW_FILE_READ to 1 if you wish to continue using this feature."); + const QStringList writingError = { + QLatin1String("XMLHttpRequest: Using PUT on a local file is disabled by default."), + QLatin1String("Set QML_XHR_ALLOW_FILE_WRITE to 1 to enable this feature.") + }; - const QString writingWarning = QLatin1String( - "XMLHttpRequest: Using PUT on a local file is dangerous " - "and will be disabled by default in a future Qt version." - "Set QML_XHR_ALLOW_FILE_WRITE to 1 if you wish to continue using this feature."); + for (const auto &readingErrorLine : readingError) + QVERIFY(output.contains(readingErrorLine)); - QVERIFY(output.contains(readingWarning)); - QVERIFY(output.contains(writingWarning)); + for (const auto &writingErrorLine : writingError) + QVERIFY(output.contains(writingErrorLine)); } #endif -- cgit v1.2.3 From 4df24385315c869b804e040a9089f9fa7a1fc57b Mon Sep 17 00:00:00 2001 From: Maximilian Goldstein Date: Thu, 30 Jan 2020 14:03:09 +0100 Subject: qmlformat: Enforce more of the coding conventions Now also enforces: - states and transitions being the last elements in an object - large bindings being the last bindings Change-Id: I8be1db4eb2bc9dd429dd5b9abab70a1362f47dfb Reviewed-by: Ulf Hermann --- .../auto/qml/qmlformat/data/largeBindings.formatted.qml | 9 +++++++++ tests/auto/qml/qmlformat/data/largeBindings.qml | 11 +++++++++++ .../qmlformat/data/statesAndTransitions.formatted.qml | 16 ++++++++++++++++ tests/auto/qml/qmlformat/data/statesAndTransitions.qml | 10 ++++++++++ tests/auto/qml/qmlformat/tst_qmlformat.cpp | 12 ++++++++++++ 5 files changed, 58 insertions(+) create mode 100644 tests/auto/qml/qmlformat/data/largeBindings.formatted.qml create mode 100644 tests/auto/qml/qmlformat/data/largeBindings.qml create mode 100644 tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml create mode 100644 tests/auto/qml/qmlformat/data/statesAndTransitions.qml (limited to 'tests') diff --git a/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml b/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml new file mode 100644 index 0000000000..d8e4ffb087 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml @@ -0,0 +1,9 @@ +QtObject { + small1: 3 + small2: foo + // THIS NEEDS TO BE LAST + largeBinding: { + var x = 300; + console.log(x); + } +} diff --git a/tests/auto/qml/qmlformat/data/largeBindings.qml b/tests/auto/qml/qmlformat/data/largeBindings.qml new file mode 100644 index 0000000000..a2249f6815 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/largeBindings.qml @@ -0,0 +1,11 @@ +QtObject +{ + // THIS NEEDS TO BE LAST + largeBinding: { + var x = 300; + console.log(x); + } + + small1: 3 + small2: foo +} diff --git a/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml b/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml new file mode 100644 index 0000000000..bd063ac498 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml @@ -0,0 +1,16 @@ +QtObject { + id: foo + + // This needs to be *before* states and transitions after formatting + Item { + } + + states: [ + State { + } + ] + transitions: [ + Transition { + } + ] +} diff --git a/tests/auto/qml/qmlformat/data/statesAndTransitions.qml b/tests/auto/qml/qmlformat/data/statesAndTransitions.qml new file mode 100644 index 0000000000..648bdce6b9 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/statesAndTransitions.qml @@ -0,0 +1,10 @@ +QtObject { + id: foo + + states: [ State {} ] + transitions: [ Transition {} ] + + // This needs to be *before* states and transitions after formatting + Item {} + +} diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp index b10eaf26f1..c7714304b8 100644 --- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp +++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp @@ -43,6 +43,8 @@ private Q_SLOTS: void testFormatNoSort(); void testReadOnlyProps(); + void testStatesAndTransitions(); + void testLargeBindings(); #if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void testExample(); @@ -188,6 +190,16 @@ void TestQmlformat::testReadOnlyProps() QCOMPARE(runQmlformat(testFile("readOnlyProps.qml"), false, true), readTestFile("readOnlyProps.formatted.qml")); } +void TestQmlformat::testStatesAndTransitions() +{ + QCOMPARE(runQmlformat(testFile("statesAndTransitions.qml"), false, true), readTestFile("statesAndTransitions.formatted.qml")); +} + +void TestQmlformat::testLargeBindings() +{ + QCOMPARE(runQmlformat(testFile("largeBindings.qml"), false, true), readTestFile("largeBindings.formatted.qml")); +} + #if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void TestQmlformat::testExample_data() { -- cgit v1.2.3 From 70120c931faa0c6139354c75fcf8d39b77ec3b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Fri, 22 Nov 2019 17:03:43 +0100 Subject: Fix a bug where a layout could crash or become non-responsive This happened because of that QQuickText is ill-behaving: When the width on a QQuickText with word wrap enabled is changed to something less than its implicitWidth, its implicitHeight is changed to reflect the height it needs in order to fit all lines. This will cause the layout to be invalidated, and rearranged again. However, at the same time it will also change its implicitWidth actually become wider than its initial implicitWidth (this seems to be a bug). So the next time it is rearranged it will actually be wide enough so that it doesn't need to wrap. This again will cause its implicitWidth and implicitHeight to change to reflect that only one line is needed, which again will cause it to rearrange, but since the item has a too small width for that it will again change the implicitHeight to reflect that it needs more lines..... This went on forever until there was a stack overflow. In addition it also caused an endless (that is, if it didn't stack overflow) updatePolish()/polish() loop (basically polish() was called from within updatePolish() continuously). To make the layout more robust for such "ill-behaving" items we have to add one recursion guard, and one polish-loop guard. Change-Id: I9f752ed320a100c8d0f0fd340347a556e63318e5 Task-number: QTBUG-73683 Reviewed-by: Richard Moe Gustavsen --- .../quick/qquicklayouts/data/tst_rowlayout.qml | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tests') diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml index 07af6a77ac..0732884c97 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml @@ -1100,5 +1100,36 @@ Item { waitForRendering(rootRect.layout) compare(rootRect.item1.width, 100) } + +//--------------------------- + Component { + id: rowlayoutWithTextItems_Component + RowLayout { + Text { + Layout.fillWidth: true + text: "OneWord" + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + } + Text { + Layout.fillWidth: true + text: "OneWord" + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + } + } + } + + // QTBUG-73683 + function test_rowlayoutWithTextItems() { + var layout = createTemporaryObject(rowlayoutWithTextItems_Component, container) + waitForRendering(layout) + for (var i = 0; i < 3; i++) { + ignoreWarning(/Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations./) + } + ignoreWarning(/Qt Quick Layouts: Polish loop detected. Aborting after two iterations./) + layout.width = layout.width - 2 // set the size to be smaller than its "minimum size" + waitForRendering(layout) // do not exit before all warnings have been received + + // DO NOT CRASH due to stack overflow (or loop endlessly due to updatePolish()/polish() loop) + } } } -- cgit v1.2.3 From 1a7ca47a7a92945e16006ddd00adea186535cdd5 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Wed, 12 Feb 2020 13:29:08 +0100 Subject: QQuickLoader: store status This allows us to emit the change signal only when the status has actually changed. Due to alignment restrictions, this does not even change the size of the class. Fixes: QTBUG-82002 Change-Id: I2192bf80e72b92108046780811c3acdab39af518 Reviewed-by: Ulf Hermann --- tests/auto/quick/qquickloader/data/statusChanged.qml | 16 ++++++++++++++++ tests/auto/quick/qquickloader/tst_qquickloader.cpp | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/auto/quick/qquickloader/data/statusChanged.qml (limited to 'tests') diff --git a/tests/auto/quick/qquickloader/data/statusChanged.qml b/tests/auto/quick/qquickloader/data/statusChanged.qml new file mode 100644 index 0000000000..fe46bc7b24 --- /dev/null +++ b/tests/auto/quick/qquickloader/data/statusChanged.qml @@ -0,0 +1,16 @@ +import QtQuick 2.12 +import QtQuick.Window 2.12 + +Window { + id: root + property int statusChangedCounter: 0 + property alias status: loader.status + visible: true; width: 640; height: 480 + Loader { + id: loader + anchors.fill: parent + asynchronous: true + source: "./RedRect.qml" + onStatusChanged: root.statusChangedCounter++ + } +} diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index d0a1a8a45b..7bd6f9466a 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -39,6 +39,7 @@ #include "testhttpserver.h" #include "../../shared/util.h" #include "../shared/geometrytestutil.h" +#include Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") @@ -128,6 +129,7 @@ private slots: void rootContext(); void sourceURLKeepComponent(); + void statusChangeOnlyEmittedOnce(); }; Q_DECLARE_METATYPE(QList) @@ -1446,6 +1448,18 @@ void tst_QQuickLoader::sourceURLKeepComponent() } +// QTBUG-82002 +void tst_QQuickLoader::statusChangeOnlyEmittedOnce() +{ + QQmlApplicationEngine engine; + auto url = testFileUrl("statusChanged.qml"); + engine.load(url); + auto root = engine.rootObjects().at(0); + QVERIFY(root); + QTRY_COMPARE(QQuickLoader::Status(root->property("status").toInt()), QQuickLoader::Ready); + QCOMPARE(root->property("statusChangedCounter").toInt(), 2); // 1xLoading + 1xReady*/ +} + QTEST_MAIN(tst_QQuickLoader) #include "tst_qquickloader.moc" -- cgit v1.2.3 From 074aa948000088e816f11eb5cc46abc8be40df96 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 11 Feb 2020 13:13:02 +0100 Subject: Check that we can find revisioned nested attached properties Task-number: QTBUG-81967 Change-Id: Iff4536a96fc0c225083fc1de7cf1f2d367186130 Reviewed-by: Simon Hausmann Reviewed-by: Fabian Kosmale Reviewed-by: Mitch Curtis --- tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 80 ++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'tests') diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index b4ad9bd7b3..1e382d7ee2 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -323,6 +323,7 @@ private slots: void listContainingDeletedObject(); void overrideSingleton(); + void revisionedPropertyOfAttachedObjectProperty(); private: QQmlEngine engine; @@ -5515,6 +5516,85 @@ void tst_qqmllanguage::overrideSingleton() check("uncreatable", "UncreatableSingleton"); } +class AttachedObject; +class InnerObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool revisionedProperty READ revisionedProperty WRITE setRevisionedProperty + NOTIFY revisionedPropertyChanged REVISION 2) + +public: + InnerObject(QObject *parent = nullptr) : QObject(parent) {} + + bool revisionedProperty() const { return m_revisionedProperty; } + void setRevisionedProperty(bool revisionedProperty) + { + if (revisionedProperty != m_revisionedProperty) { + m_revisionedProperty = revisionedProperty; + emit revisionedPropertyChanged(); + } + } + + static AttachedObject *qmlAttachedProperties(QObject *object); + +signals: + Q_REVISION(2) void revisionedPropertyChanged(); + +private: + bool m_revisionedProperty = false; +}; + +class AttachedObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(InnerObject *attached READ attached CONSTANT) + +public: + explicit AttachedObject(QObject *parent = nullptr) : + QObject(parent), + m_attached(new InnerObject(this)) + {} + + InnerObject *attached() const { return m_attached; } + +private: + InnerObject *m_attached; +}; + +class OuterObject : public QObject +{ + Q_OBJECT +public: + explicit OuterObject(QObject *parent = nullptr) : QObject(parent) {} +}; + +AttachedObject *InnerObject::qmlAttachedProperties(QObject *object) +{ + return new AttachedObject(object); +} + +QML_DECLARE_TYPE(InnerObject) +QML_DECLARE_TYPEINFO(InnerObject, QML_HAS_ATTACHED_PROPERTIES) + +void tst_qqmllanguage::revisionedPropertyOfAttachedObjectProperty() +{ + qmlRegisterAnonymousType("foo", 2); + qmlRegisterType("foo", 2, 0, "InnerObject"); + qmlRegisterType("foo", 2, 2, "InnerObject"); + qmlRegisterType("foo", 2, 2, "OuterObject"); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import foo 2.2\n" + "OuterObject {\n" + " InnerObject.attached.revisionedProperty: true\n" + "}", QUrl()); + + QVERIFY(component.isReady()); + QScopedPointer obj(component.create()); + QVERIFY(!obj.isNull()); +} + void tst_qqmllanguage::inlineComponent() { QFETCH(QUrl, componentUrl); -- cgit v1.2.3 From e192874c6c134f0e7e1f08795e277cbc80cd55d5 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 27 Jan 2020 17:33:56 +0100 Subject: Guard against invalid version specifiers in import statements Check that the version parsed is in the valid range for QTypeRevision and produce a compile error if not. Task-number: QTBUG-71278 Change-Id: I9a957a10f4254387f9868a8f3f1e231440bc2cd2 Reviewed-by: Fabian Kosmale --- tests/auto/qml/qqmlparser/tst_qqmlparser.cpp | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'tests') diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp index 0b88358d4a..981fe7407e 100644 --- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp +++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include class tst_qqmlparser : public QQmlDataTest @@ -67,6 +68,8 @@ private slots: void typeAssertion(); void annotations_data(); void annotations(); + void invalidImportVersion_data(); + void invalidImportVersion(); private: QStringList excludedDirs; @@ -584,6 +587,47 @@ void tst_qqmlparser::annotations() } } +void tst_qqmlparser::invalidImportVersion_data() +{ + QTest::addColumn("expression"); + + const QStringList segments = { + "0", "255", "500", "3030303030303030303030303" + }; + + for (const QString &major : segments) { + if (major != "0") { + QTest::addRow("%s", qPrintable(major)) + << QString::fromLatin1("import Foo %1").arg(major); + } + + for (const QString &minor : segments) { + if (major == "0" && minor == "0") + continue; + + QTest::addRow("%s.%s", qPrintable(major), qPrintable(minor)) + << QString::fromLatin1("import Foo %1.%2").arg(major).arg(minor); + } + } + + +} + +void tst_qqmlparser::invalidImportVersion() +{ + QFETCH(QString, expression); + + QQmlJS::Engine engine; + QQmlJS::Lexer lexer(&engine); + lexer.setCode(expression, 1); + QQmlJS::Parser parser(&engine); + QVERIFY(!parser.parse()); + + QRegularExpression regexp( + "^Invalid (major )?version. Version numbers must be >= 0 and < 255\\.$"); + QVERIFY(regexp.match(parser.errorMessage()).hasMatch()); +} + QTEST_MAIN(tst_qqmlparser) #include "tst_qqmlparser.moc" -- cgit v1.2.3 From 2fae1d7e8f0bd6619c560fed65ce8507664dacb9 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 12 Feb 2020 10:42:24 +0100 Subject: Allow dynamic and static registration of same URI in any order Previously, a static registration would not go through if a dynamic registration was carried out before the first type of the statically registered module was referenced. Change-Id: Icf6a2b78dff7d0e5b29138501e04723510d6a668 Reviewed-by: Fabian Kosmale --- .../qml/qqmlproperty/data/interfaceBinding2.qml | 27 ++++ tests/auto/qml/qqmlproperty/interfaces.h | 160 +++++++++++++++++++++ tests/auto/qml/qqmlproperty/qqmlproperty.pro | 8 +- tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 79 ++-------- 4 files changed, 209 insertions(+), 65 deletions(-) create mode 100644 tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml create mode 100644 tests/auto/qml/qqmlproperty/interfaces.h (limited to 'tests') diff --git a/tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml b/tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml new file mode 100644 index 0000000000..e7c5dc7344 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml @@ -0,0 +1,27 @@ +import QtQuick 2.12 +import io.qt.bugreports 2.0 +Item { + InterfaceConsumer2 { + objectName: "a1" + i: A2 { + property int i: 42 + } + } + + InterfaceConsumer2 { + objectName: "a2" + property A2 a: A2 { + property int i: 43 + } + i: a + } + + InterfaceConsumer2 { + objectName: "a3" + property A2 a: A2 { + id : aa + property int i: 44 + } + i: aa + } +} diff --git a/tests/auto/qml/qqmlproperty/interfaces.h b/tests/auto/qml/qqmlproperty/interfaces.h new file mode 100644 index 0000000000..191c3e84e8 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/interfaces.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 INTERFACES_H +#define INTERFACES_H + +#include + +struct Interface { +}; + +QT_BEGIN_NAMESPACE +#define MyInterface_iid "io.qt.bugreports.Interface" +Q_DECLARE_INTERFACE(Interface, MyInterface_iid); +QT_END_NAMESPACE + +class A : public QObject, Interface { + Q_OBJECT + Q_INTERFACES(Interface) +}; + +class B : public QObject, Interface { + Q_OBJECT + Q_INTERFACES(Interface) +}; + +class C : public QObject { + Q_OBJECT +}; + +struct Interface2 +{ + Q_GADGET +}; + +QT_BEGIN_NAMESPACE +#define MyInterface2_iid "io.qt.bugreports.Interface2" +Q_DECLARE_INTERFACE(Interface2, MyInterface2_iid); +QT_END_NAMESPACE + +class A2 : public QObject, Interface2 { + Q_OBJECT + QML_ELEMENT + Q_INTERFACES(Interface2) +}; + +class B2 : public QObject, Interface2 { + Q_OBJECT + QML_ELEMENT + Q_INTERFACES(Interface2) +}; + +class C2 : public QObject { + Q_OBJECT + QML_ELEMENT +}; + +class InterfaceConsumer : public QObject { + Q_OBJECT + Q_PROPERTY(Interface *i READ interface WRITE setInterface NOTIFY interfaceChanged) + Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged) + +public: + + Interface* interface() const + { + return m_interface; + } + void setInterface(Interface* interface) + { + QObject* object = reinterpret_cast(interface); + m_testValue = object->property("i").toInt(); + emit testValueChanged(); + if (m_interface == interface) + return; + + m_interface = interface; + emit interfaceChanged(); + } + + int testValue() { + return m_testValue; + } + +signals: + void interfaceChanged(); + void testValueChanged(); + +private: + Interface* m_interface = nullptr; + int m_testValue = 0; +}; + + +class InterfaceConsumer2 : public QObject +{ + Q_OBJECT + + Q_PROPERTY(Interface2 *i READ interface WRITE setInterface NOTIFY interfaceChanged) + Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged) + + QML_ELEMENT + +public: + + Interface2* interface() const + { + return m_interface; + } + void setInterface(Interface2* interface2) + { + QObject* object = reinterpret_cast(interface2); + m_testValue = object->property("i").toInt(); + emit testValueChanged(); + if (m_interface == interface2) + return; + + m_interface = interface2; + emit interfaceChanged(); + } + + int testValue() { + return m_testValue; + } + +signals: + void interfaceChanged(); + void testValueChanged(); + +private: + Interface2 *m_interface = nullptr; + int m_testValue = 0; +}; + +#endif // INTERFACES_H diff --git a/tests/auto/qml/qqmlproperty/qqmlproperty.pro b/tests/auto/qml/qqmlproperty/qqmlproperty.pro index b1bcf1f17d..4d42975369 100644 --- a/tests/auto/qml/qqmlproperty/qqmlproperty.pro +++ b/tests/auto/qml/qqmlproperty/qqmlproperty.pro @@ -1,7 +1,10 @@ -CONFIG += testcase +CONFIG += testcase qmltypes TARGET = tst_qqmlproperty macx:CONFIG -= app_bundle +QML_IMPORT_NAME = io.qt.bugreports +QML_IMPORT_VERSION = 2.0 + SOURCES += tst_qqmlproperty.cpp include (../../shared/util.pri) @@ -9,3 +12,6 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private testlib + +HEADERS += \ + interfaces.h diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index 83e173f379..1223c7cc07 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -25,6 +25,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + +#include "interfaces.h" #include #include #include @@ -2090,74 +2092,22 @@ void tst_qqmlproperty::nullPropertyBinding() QMetaObject::invokeMethod(root.get(), "tog"); } -struct Interface { -}; - -QT_BEGIN_NAMESPACE -#define MyInterface_iid "io.qt.bugreports.Interface" -Q_DECLARE_INTERFACE(Interface, MyInterface_iid); -QT_END_NAMESPACE - -class A : public QObject, Interface { - Q_OBJECT - Q_INTERFACES(Interface) -}; - -class B : public QObject, Interface { - Q_OBJECT - Q_INTERFACES(Interface) -}; - -class C : public QObject { - Q_OBJECT -}; - -class InterfaceConsumer : public QObject { - Q_OBJECT - Q_PROPERTY(Interface* i READ interface WRITE setInterface NOTIFY interfaceChanged) - Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged) - - -public: - - Interface* interface() const - { - return m_interface; - } - void setInterface(Interface* interface) - { - QObject* object = reinterpret_cast(interface); - m_testValue = object->property("i").toInt(); - emit testValueChanged(); - if (m_interface == interface) - return; - - m_interface = interface; - emit interfaceChanged(); - } - - int testValue() { - return m_testValue; - } - -signals: - void interfaceChanged(); - void testValueChanged(); - -private: - Interface* m_interface = nullptr; - int m_testValue = 0; -}; void tst_qqmlproperty::interfaceBinding() { + qmlRegisterInterface("Interface"); + qmlRegisterType("io.qt.bugreports", 1, 0, "A"); + qmlRegisterType("io.qt.bugreports", 1, 0, "B"); + qmlRegisterType("io.qt.bugreports", 1, 0, "C"); + qmlRegisterType("io.qt.bugreports", 1, 0, "InterfaceConsumer"); - qmlRegisterInterface("Interface"); - qmlRegisterType("io.qt.bugreports", 1, 0, "A"); - qmlRegisterType("io.qt.bugreports", 1, 0, "B"); - qmlRegisterType("io.qt.bugreports", 1, 0, "C"); - qmlRegisterType("io.qt.bugreports", 1, 0, "InterfaceConsumer"); + qmlRegisterInterface("Interface2"); - const QUrl url = testFileUrl("interfaceBinding.qml"); + const QVector urls = { + testFileUrl("interfaceBinding.qml"), + testFileUrl("interfaceBinding2.qml") + }; + + for (const QUrl &url : urls) { QQmlEngine engine; QQmlComponent component(&engine, url); QScopedPointer root(component.create()); @@ -2165,6 +2115,7 @@ void tst_qqmlproperty::interfaceBinding() QCOMPARE(root->findChild("a1")->property("testValue").toInt(), 42); QCOMPARE(root->findChild("a2")->property("testValue").toInt(), 43); QCOMPARE(root->findChild("a3")->property("testValue").toInt(), 44); + } } void tst_qqmlproperty::floatToStringPrecision_data() -- cgit v1.2.3 From a2b31f073530f61203fe0e9799ad158c4fe6b9f9 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 11 Feb 2020 19:15:59 +0100 Subject: Add a static variant of qmlRegisterInterface() qmlRegisterInterface() should not be called procedurally, for the same reason that qmlRegisterType() should not be called procedurally. Also, add URI and major version parameters to qmlRegisterInterface(), and deprecate the typeName parameter. We want to identify which import an interface belongs to. Task-number: QTBUG-68796 Change-Id: Iba3d66e5ce6219b30aadba34396f12fca92f35a7 Reviewed-by: Fabian Kosmale --- tests/auto/qml/qqmlproperty/interfaces.h | 1 + tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmlproperty/interfaces.h b/tests/auto/qml/qqmlproperty/interfaces.h index 191c3e84e8..2c06c5f594 100644 --- a/tests/auto/qml/qqmlproperty/interfaces.h +++ b/tests/auto/qml/qqmlproperty/interfaces.h @@ -56,6 +56,7 @@ class C : public QObject { struct Interface2 { Q_GADGET + QML_INTERFACE }; QT_BEGIN_NAMESPACE diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index 1223c7cc07..166437c8de 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -2100,8 +2100,6 @@ void tst_qqmlproperty::interfaceBinding() qmlRegisterType("io.qt.bugreports", 1, 0, "C"); qmlRegisterType("io.qt.bugreports", 1, 0, "InterfaceConsumer"); - qmlRegisterInterface("Interface2"); - const QVector urls = { testFileUrl("interfaceBinding.qml"), testFileUrl("interfaceBinding2.qml") -- cgit v1.2.3 From 8791fc19f04d51d1efc077205e39a11047e732b5 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Mon, 10 Feb 2020 13:15:37 +0100 Subject: Added AstDumper: better describe and compare AST trees This is just added to the test sources (via tests/auto/shared/astdump.pri) Fixes: QTBUG-81819 Change-Id: Icc70e6f7a6ded9e9957c6d4151f696be34c942e6 Reviewed-by: Fabian Kosmale Reviewed-by: Ulf Hermann --- tests/auto/qml/qqmlparser/qqmlparser.pro | 1 + tests/auto/qml/qqmlparser/tst_qqmlparser.cpp | 3 +- tests/auto/shared/astdump.pri | 7 + tests/auto/shared/qqmljsastdumper.cpp | 1065 ++++++++++++++++++++++++++ tests/auto/shared/qqmljsastdumper.h | 442 +++++++++++ 5 files changed, 1517 insertions(+), 1 deletion(-) create mode 100644 tests/auto/shared/astdump.pri create mode 100644 tests/auto/shared/qqmljsastdumper.cpp create mode 100644 tests/auto/shared/qqmljsastdumper.h (limited to 'tests') diff --git a/tests/auto/qml/qqmlparser/qqmlparser.pro b/tests/auto/qml/qqmlparser/qqmlparser.pro index d8e4b0dd06..7f117b3157 100644 --- a/tests/auto/qml/qqmlparser/qqmlparser.pro +++ b/tests/auto/qml/qqmlparser/qqmlparser.pro @@ -11,3 +11,4 @@ cross_compile: DEFINES += QTEST_CROSS_COMPILED TESTDATA = data/* include (../../shared/util.pri) +include (../../shared/astdump.pri) diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp index 0b88358d4a..c7d09f9d6e 100644 --- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp +++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp @@ -33,6 +33,7 @@ #include #include "../../shared/util.h" +#include "../../shared/qqmljsastdumper.h" #include #include @@ -580,7 +581,7 @@ void tst_qqmlparser::annotations() Parser parser2(&engine2); QVERIFY(parser2.parse()); - // to do: compare for equality skipping annotations + QCOMPARE(AstDumper::diff(parser.ast(), parser2.rootNode(), 3, DumperOptions::NoAnnotations | DumperOptions::NoLocations), QString()); } } diff --git a/tests/auto/shared/astdump.pri b/tests/auto/shared/astdump.pri new file mode 100644 index 0000000000..365b12fc51 --- /dev/null +++ b/tests/auto/shared/astdump.pri @@ -0,0 +1,7 @@ + +INCLUDEPATH += $$PWD +HEADERS += \ + $$PWD/qqmljsastdumper.h + +SOURCES += \ + $$PWD/qqmljsastdumper.cpp diff --git a/tests/auto/shared/qqmljsastdumper.cpp b/tests/auto/shared/qqmljsastdumper.cpp new file mode 100644 index 0000000000..7c7485fd1f --- /dev/null +++ b/tests/auto/shared/qqmljsastdumper.cpp @@ -0,0 +1,1065 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +**/ +#include "qqmljsastdumper.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace QQmlJS { +using namespace AST; +/*! +\internal +\enum QQmlJS::DumperOptions + +This enum type specifies the options for the AstDumper. +The values can be combined with the '|' operator, and checked using the '&' operator. + +\value None + Default dumping options +\value NoLocations + Does not dump SourceLocations, allowing one to compare equivalent AST + generated by code formatted differently +\value NoAnnotations + Does not dump annotations +\value DumpNode + Does dump a in preVisit/postVisit +*/ + +/*! +\internal +\class QQmlJS::AstDumper +\brief Dumps or compares AST in an xml like format, mostly for testing/debugging + +Initialize it with a lambda that dumps a string, and configure it with .setX methods. +If \l{indent} is set to a non zero value the xml is indented by that amount, and +\l{baseIndent} is the initial indent. +If \l{emitNode} is true the node tag is emitted in the preVisit/postVisit. +If \l{emitLocation} is true the SourceLocations are emitted. +If \l{emitAnnotations} is true annotations are emitted + +The implementation has unnecessary roundtrips to QString, but it is supposed to be used +for debugging purposes... + +Probably you will not use the visitor at all but rather the static method diff or +the qDebug() and ostream operator << that use the visitor... + +\fn AstDumper::diff(AST::Node *n1, AST::Node *n2, int nContext, DumperOptions opt, int indent) + +\brief compares the two AST::Node n1 and n2 and returns a string describing their first difference + +If there are no differences the empty string is returned, so .isEmpty() can be use to check +for no differences. +\l{nContext} decides how much context is printed out. + +*/ + + +QDebug operator<<(QDebug d, AST::Node *n) { + QDebug noQuote = d.noquote().nospace(); + AstDumper visitor([&noQuote](const QString &s){ noQuote << s; }); + Node::accept(n, &visitor); + return d; +} + + +std::ostream &operator<<(std::ostream &stream, AST::Node *n) { + AstDumper visitor([&stream](const QString &s){ stream << s.toStdString(); }); + Node::accept(n, &visitor); + return stream; +} + +bool operator & (DumperOptions lhs, DumperOptions rhs) { + return bool(static_cast(lhs) & static_cast(rhs)); +} + +DumperOptions operator | (DumperOptions lhs, DumperOptions rhs) { + return DumperOptions(static_cast(lhs) | static_cast(rhs)); +} + +QString AstDumper::diff(AST::Node *n1, AST::Node *n2, int nContext, DumperOptions opt, int indent) { + QString s1, s2; + QTextStream d1(&s1), d2(&s2); + AstDumper visitor1=AstDumper([&d1](const QString &s){ d1 << s; }, opt, indent); + AstDumper visitor2=AstDumper([&d2](const QString &s){ d2 << s; }, opt, indent); + Node::accept(n1, &visitor1); + Node::accept(n2, &visitor2); + d1.seek(0); + d2.seek(0); + std::vector preLines(nContext); + int nLine = 0; + bool same = true; + QString l1, l2; + while (same && !d1.atEnd() && !d2.atEnd()) { + l1=d1.readLine(); + l2=d2.readLine(); + if (l1 == l2) + preLines[nLine++ % nContext] = l1; + else + same = false; + } + QString res; + QTextStream ss(&res); + if (!same || !d1.atEnd() || !d2.atEnd()) { + for (int iline = qMin(nLine, nContext); iline > 0; --iline) { + ss << QLatin1String(" ") << preLines[(nLine - iline) % nContext] << QLatin1String("\n"); + } + int iline = 0; + if (!same) { + ss << QLatin1String("-") << l1 << QLatin1String("\n"); + ++iline; + } + if (same && nContext == 0) + nContext = 1; + for (;iline < nContext && !d1.atEnd(); iline ++) { + l1 = d1.readLine(); + ss << QLatin1String("-") << l1 << QLatin1String("\n"); + } + iline = 0; + if (!same) { + ss << QLatin1String("+") << l2 << QLatin1String("\n"); + ++iline; + } + for (;iline < nContext && !d2.atEnd(); iline ++) { + l2 = d2.readLine(); + ss << QLatin1String("+") << l2 << QLatin1String("\n"); + } + } + return res; +} + +QString AstDumper::printNode(Node *n, DumperOptions opt, int indent, int baseIndent) +{ + QString res; + QTextStream d(&res); + AstDumper visitor=AstDumper([&d](const QString &s){ d << s; }, opt, indent, baseIndent); + Node::accept(n, &visitor); + return res; +} + +AstDumper::AstDumper(const std::function &dumper, DumperOptions options, int indent, int baseIndent): + dumper(dumper), options(options), indent(indent), baseIndent(baseIndent) {} + +void AstDumper::start(const QString &str) { + dumper(QString::fromLatin1(" ").repeated(baseIndent)); + dumper(QLatin1String("<")); + dumper(str); + dumper(QLatin1String(">\n")); + baseIndent += indent; +} + +void AstDumper::start(const char *str) { + start(QLatin1String(str)); +} + +void AstDumper::stop(const QString &str) { + baseIndent -= indent; + dumper(QString::fromLatin1(" ").repeated(baseIndent)); + dumper(QLatin1String("\n")); +} + +void AstDumper::stop(const char *str) { + stop(QLatin1String(str)); +} + +QString AstDumper::qs(const QString &s) { + QString res(s); + return QLatin1String("\"") + res + .replace(QLatin1String("\\"), QLatin1String("\\\\")) + .replace(QLatin1String("\""), QLatin1String("\\\"")) + QLatin1String("\""); +} + +QString AstDumper::qs(const char *s) { + return qs(QLatin1String(s)); +} + +QString AstDumper::qs(const QStringRef &s) { + return qs(s.toString()); +} + +QString AstDumper::loc(const AST::SourceLocation &s) { + if (noLocations() || !s.isValid()) + return QLatin1String("\"\""); + else { + return QLatin1String("\"off:%1 len:%2 l:%3 c:%4\"").arg(QString::number(s.offset), QString::number(s.length), QString::number(s.startLine), QString::number(s.startColumn)); + } +} + +QString AstDumper::boolStr(bool v) { return (v ? qs("true"): qs("false")); } + +bool AstDumper::preVisit(Node *) { if (dumpNode()) start("Node"); return true; } + +void AstDumper::postVisit(Node *) { if (dumpNode()) stop("Node"); } + +bool AstDumper::visit(UiProgram *) { start("UiProgram"); return true; } + +bool AstDumper::visit(UiHeaderItemList *) { start("UiHeaderItemList"); return true; } + +bool AstDumper::visit(UiPragma *el) { + start(QLatin1String("UiPragma name=%1 pragmaToken=%2 semicolonToken=%3") + .arg(qs(el->name), loc(el->pragmaToken), loc(el->semicolonToken))); + return true; +} + +bool AstDumper::visit(UiImport *el) +{ + start(QLatin1String("UiImport fileName=%1 importId=%2 importToken=%3 fileNameToken=%4 asToken=%5 importIdToken=%6 semicolonToken=%7") + .arg(qs(el->fileName), qs(el->importId), loc(el->importToken), loc(el->fileNameToken), loc(el->asToken), loc(el->importIdToken), loc(el->semicolonToken))); + return true; +} + +bool AstDumper::visit(UiPublicMember *el) { + QString typeStr = ((el->type == UiPublicMember::Signal) ? QLatin1String("Signal") : + (el->type == UiPublicMember::Property) ? QLatin1String("Property") : QLatin1String("Unexpected(%1)").arg(el->type)); + start(QLatin1String("UiPublicMember type=%1 typeModifier=%2 name=%3 isDefaultMember=%4 isReadonlyMember=%5 isRequired=%6 " + "defaultToken=%7 readonlyToken=%8 propertyToken=%9 requiredToken=%10 typeModifierToken=%11 typeToken=%12 " + "identifierToken=%13 colonToken=%14 semicolonToken=%15") + .arg(qs(typeStr), qs(el->typeModifier), qs(el->name), + el->isDefaultMember, el->isReadonlyMember, el->isRequired, + loc(el->defaultToken), loc(el->readonlyToken), loc(el->propertyToken), + loc(el->requiredToken), loc(el->typeModifierToken), loc(el->typeToken), + loc(el->identifierToken), loc(el->colonToken), loc(el->semicolonToken) + )); + if (!noAnnotations()) // put annotations inside the node they refer to + Node::accept(el->annotations, this); + Node::accept(el->memberType, this); + return true; +} + +bool AstDumper::visit(AST::UiSourceElement *el) { + start(QLatin1String("UiSourceElement")); + if (!noAnnotations()) // put annotations inside the node they refer to + Node::accept(el->annotations, this); + return true; +} + +bool AstDumper::visit(AST::UiObjectDefinition *el) { + start("UiObjectDefinition"); + if (!noAnnotations()) // put annotations inside the node they refer to + Node::accept(el->annotations, this); + return true; +} + +bool AstDumper::visit(AST::UiObjectInitializer *el) { + start(QLatin1String("UiObjectInitializer lbraceToken=%1 rbraceToken=%2") + .arg(loc(el->lbraceToken), loc(el->rbraceToken))); + return true; +} + +bool AstDumper::visit(AST::UiObjectBinding *el) { + start(QLatin1String("UiObjectBinding colonToken=%1 hasOnToken=%2") + .arg(loc(el->colonToken), boolStr(el->hasOnToken))); + if (!noAnnotations()) // put annotations inside the node they refer to + Node::accept(el->annotations, this); + return true; +} + +bool AstDumper::visit(AST::UiScriptBinding *el) { + start(QLatin1String("UiScriptBinding colonToken=%1") + .arg(loc(el->colonToken))); + if (!noAnnotations()) // put annotations inside the node they refer to + Node::accept(el->annotations, this); + return true; +} + +bool AstDumper::visit(AST::UiArrayBinding *el) { + start(QLatin1String("UiArrayBinding colonToken=%1 lbracketToken=%2 rbracketToken=%3") + .arg(loc(el->colonToken), loc(el->lbracketToken), loc(el->rbracketToken))); + if (!noAnnotations()) // put annotations inside the node they refer to + Node::accept(el->annotations, this); + return true; +} + +bool AstDumper::visit(AST::UiParameterList *el) { + start(QLatin1String("UiArrayBinding name=%1 commaToken=%2 propertyTypeToken=%3 identifierToken=%4 colonToken=%5") + .arg(qs(el->name), loc(el->commaToken), loc(el->propertyTypeToken), loc(el->identifierToken), loc(el->colonToken))); + Node::accept(el->type, this); + return true; +} + +bool AstDumper::visit(AST::UiObjectMemberList *) { start("UiObjectMemberList"); return true; } + +bool AstDumper::visit(AST::UiArrayMemberList *el) { + start(QLatin1String("UiArrayMemberList commaToken=%1") + .arg(loc(el->commaToken))); + return true; +} + +bool AstDumper::visit(AST::UiQualifiedId *el) { + start(QLatin1String("UiQualifiedId name=%1 identifierToken=%2") + .arg(qs(el->name), loc(el->identifierToken))); + Node::accept(el->next, this); + return true; +} + +bool AstDumper::visit(AST::UiEnumDeclaration *el) { + start(QLatin1String("UiEnumDeclaration enumToken=%1 rbraceToken=%2 name=%3") + .arg(loc(el->enumToken), loc(el->rbraceToken), qs(el->name))); + if (!noAnnotations()) // put annotations inside the node they refer to + Node::accept(el->annotations, this); + return true; +} + +bool AstDumper::visit(AST::UiEnumMemberList *el) { + start(QLatin1String("UiEnumMemberList member=%1 value=%2 memberToken=%3 valueToken=%4") + .arg(qs(el->member), qs(QString::number(el->value)), loc(el->memberToken), loc(el->valueToken))); + return true; +} + +bool AstDumper::visit(AST::UiVersionSpecifier *el) { + start(QLatin1String("UiVersionSpecifier majorVersion=%1 minorVersion=%2 majorToken=%3 minorToken=%4") + .arg(qs(QString::number(el->majorVersion)), qs(QString::number(el->minorVersion)), loc(el->majorToken), loc(el->minorToken))); + return true; +} + +bool AstDumper::visit(AST::UiInlineComponent *el) { + start(QLatin1String("UiInlineComponent name=%1 componentToken=%2") + .arg(qs(el->name), loc(el->componentToken))); + if (!noAnnotations()) // put annotations inside the node they refer to + Node::accept(el->annotations, this); + return true; +} + +bool AstDumper::visit(UiRequired *el) +{ + start(QLatin1String("UiRequired name=%1 requiredToken=%2 semicolonToken=%3") + .arg(qs(el->name), loc(el->requiredToken), loc(el->semicolonToken))); + return true; +} + +void AstDumper::endVisit(AST::UiProgram *) { stop("UiProgram"); } + +void AstDumper::endVisit(AST::UiImport *el) { + Node::accept(el->version, this); + stop("UiImport"); +} + +void AstDumper::endVisit(AST::UiHeaderItemList *) { stop("UiHeaderItemList"); } + +void AstDumper::endVisit(AST::UiPragma *) { stop("UiPragma"); } + +void AstDumper::endVisit(AST::UiPublicMember *el) { + Node::accept(el->parameters, this); + stop("UiPublicMember"); +} + +void AstDumper::endVisit(AST::UiSourceElement *) { stop("UiSourceElement"); } +void AstDumper::endVisit(AST::UiObjectDefinition *) { stop("UiObjectDefinition"); } +void AstDumper::endVisit(AST::UiObjectInitializer *) { stop("UiObjectInitializer"); } +void AstDumper::endVisit(AST::UiObjectBinding *) { stop("UiObjectBinding"); } +void AstDumper::endVisit(AST::UiScriptBinding *) { stop("UiScriptBinding"); } +void AstDumper::endVisit(AST::UiArrayBinding *) { stop("UiArrayBinding"); } +void AstDumper::endVisit(AST::UiParameterList *el) { + stop("UiParameterList"); + Node::accept(el->next, this); // put other args at the same level as this one... +} +void AstDumper::endVisit(AST::UiObjectMemberList *) { stop("UiObjectMemberList"); } +void AstDumper::endVisit(AST::UiArrayMemberList *) { stop("UiArrayMemberList"); } +void AstDumper::endVisit(AST::UiQualifiedId *) { stop("UiQualifiedId"); } +void AstDumper::endVisit(AST::UiEnumDeclaration *) { stop("UiEnumDeclaration"); } +void AstDumper::endVisit(AST::UiEnumMemberList *el) { + stop("UiEnumMemberList"); + Node::accept(el->next, this); // put other enum members at the same level as this one... +} +void AstDumper::endVisit(AST::UiVersionSpecifier *) { stop("UiVersionSpecifier"); } +void AstDumper::endVisit(AST::UiInlineComponent *) { stop("UiInlineComponent"); } +void AstDumper::endVisit(UiRequired *) { stop("UiRequired"); } + +// QQmlJS +bool AstDumper::visit(AST::ThisExpression *el) { + start(QLatin1String("ThisExpression thisToken=%1") + .arg(loc(el->thisToken))); + return true; +} +void AstDumper::endVisit(AST::ThisExpression *) { stop("ThisExpression"); } + +bool AstDumper::visit(AST::IdentifierExpression *el) { + start(QLatin1String("IdentifierExpression name=%1 identiferToken=%2") + .arg(qs(el->name), loc(el->identifierToken))); + return true; +} +void AstDumper::endVisit(AST::IdentifierExpression *) { stop("IdentifierExpression"); } + +bool AstDumper::visit(AST::NullExpression *el) { + start(QLatin1String("NullExpression nullToken=%1") + .arg(loc(el->nullToken))); + return true; +} +void AstDumper::endVisit(AST::NullExpression *) { stop("NullExpression"); } + +bool AstDumper::visit(AST::TrueLiteral *el) { + start(QLatin1String("TrueLiteral trueToken=%1") + .arg(loc(el->trueToken))); + return true; +} +void AstDumper::endVisit(AST::TrueLiteral *) { stop("TrueLiteral"); } + +bool AstDumper::visit(AST::FalseLiteral *el) { + start(QLatin1String("FalseLiteral falseToken=%1") + .arg(loc(el->falseToken))); + return true; +} +void AstDumper::endVisit(AST::FalseLiteral *) { stop("FalseLiteral"); } + +bool AstDumper::visit(AST::SuperLiteral *el) { + start(QLatin1String("SuperLiteral superToken=%1") + .arg(loc(el->superToken))); + return true; +} +void AstDumper::endVisit(AST::SuperLiteral *) { stop("SuperLiteral"); } + +bool AstDumper::visit(AST::StringLiteral *el) { + start(QLatin1String("StringLiteral value=%1 literalToken=%2") + .arg(qs(el->value), loc(el->literalToken))); + return true; +} +void AstDumper::endVisit(AST::StringLiteral *) { stop("StringLiteral"); } + +bool AstDumper::visit(AST::TemplateLiteral *el) { + start(QLatin1String("TemplateLiteral value=%1 rawValue=%2 literalToken=%3") + .arg(qs(el->value), qs(el->rawValue), loc(el->literalToken))); + Node::accept(el->expression, this); + return true; +} +void AstDumper::endVisit(AST::TemplateLiteral *) { stop("TemplateLiteral"); } + +bool AstDumper::visit(AST::NumericLiteral *el) { + start(QLatin1String("NumericLiteral value=%1 literalToken=%2") + .arg(qs(QString::number(el->value)), loc(el->literalToken))); + return true; +} +void AstDumper::endVisit(AST::NumericLiteral *) { stop("NumericLiteral"); } + +bool AstDumper::visit(AST::RegExpLiteral *el) { + start(QLatin1String("RegExpLiteral pattern=%1 flags=%2 literalToken=%3") + .arg(qs(el->pattern), qs(QString::number(el->flags, 16)), loc(el->literalToken))); + return true; +} +void AstDumper::endVisit(AST::RegExpLiteral *) { stop("RegExpLiteral"); } + +bool AstDumper::visit(AST::ArrayPattern *el) { + start(QLatin1String("ArrayPattern lbracketToken=%1, commaToken=%2, rbracketToken=%3 parseMode=%4") + .arg(loc(el->lbracketToken),loc(el->commaToken),loc(el->rbracketToken), qs(QString::number(el->parseMode, 16)))); + return true; +} +void AstDumper::endVisit(AST::ArrayPattern *) { stop("ArrayPattern"); } + +bool AstDumper::visit(AST::ObjectPattern *el) { + start(QLatin1String("ObjectPattern lbraceToken=%1 rbraceToken=%2 parseMode=%3") + .arg(loc(el->lbraceToken), loc(el->rbraceToken), qs(QString::number(el->parseMode, 16)))); + return true; +} +void AstDumper::endVisit(AST::ObjectPattern *) { stop("ObjectPattern"); } + +bool AstDumper::visit(AST::PatternElementList *) { start("PatternElementList"); return true; } +void AstDumper::endVisit(AST::PatternElementList *) { stop("PatternElementList"); } + +bool AstDumper::visit(AST::PatternPropertyList *) { start("PatternPropertyList"); return true; } +void AstDumper::endVisit(AST::PatternPropertyList *) { stop("PatternPropertyList"); } + +bool AstDumper::visit(AST::PatternElement *el) { + start(QLatin1String("PatternElement identifierToken=%1 bindingIdentifier=%2 type=%3 scope=%4 isForDeclaration=%5") + .arg(loc(el->identifierToken), qs(el->bindingIdentifier), qs(QString::number(el->type, 16)), + qs(QString::number(static_cast(el->scope), 16)), boolStr(el->isForDeclaration))); + return true; +} +void AstDumper::endVisit(AST::PatternElement *) { stop("PatternElement"); } + +bool AstDumper::visit(AST::PatternProperty *el) { + start(QLatin1String("PatternProperty identifierToken=%1 bindingIdentifier=%2 type=%3 scope=%4 isForDeclaration=%5 colonToken=%6") + .arg(loc(el->identifierToken), qs(el->bindingIdentifier), qs(QString::number(el->type, 16)), + qs(QString::number(static_cast(el->scope), 16)), boolStr(el->isForDeclaration), loc(el->colonToken))); + return true; +} +void AstDumper::endVisit(AST::PatternProperty *) { stop("PatternProperty"); } + +bool AstDumper::visit(AST::Elision *el) { + start(QLatin1String("Elision commaToken=%1") + .arg(loc(el->commaToken))); + return true; +} +void AstDumper::endVisit(AST::Elision *el) { + stop("Elision"); + Node::accept(el->next, this); // emit other elisions at the same level +} + +bool AstDumper::visit(AST::NestedExpression *el) { + start(QLatin1String("NestedExpression lparenToken=%1 rparenToken=%2") + .arg(loc(el->lparenToken), loc(el->rparenToken))); + return true; +} +void AstDumper::endVisit(AST::NestedExpression *) { stop("NestedExpression"); } + +bool AstDumper::visit(AST::IdentifierPropertyName *el) { + start(QLatin1String("IdentifierPropertyName id=%1 propertyNameToken=%2") + .arg(qs(el->id), loc(el->propertyNameToken))); + return true; +} +void AstDumper::endVisit(AST::IdentifierPropertyName *) { stop("IdentifierPropertyName"); } + +bool AstDumper::visit(AST::StringLiteralPropertyName *el) { + start(QLatin1String("StringLiteralPropertyName id=%1 propertyNameToken=%2") + .arg(qs(el->id), loc(el->propertyNameToken))); + return true; +} +void AstDumper::endVisit(AST::StringLiteralPropertyName *) { stop("StringLiteralPropertyName"); } + +bool AstDumper::visit(AST::NumericLiteralPropertyName *el) { + start(QLatin1String("NumericLiteralPropertyName id=%1 propertyNameToken=%2") + .arg(qs(QString::number(el->id)),loc(el->propertyNameToken))); + return true; +} +void AstDumper::endVisit(AST::NumericLiteralPropertyName *) { stop("NumericLiteralPropertyName"); } + +bool AstDumper::visit(AST::ComputedPropertyName *) { + start(QLatin1String("ComputedPropertyName")); + return true; +} +void AstDumper::endVisit(AST::ComputedPropertyName *) { stop("ComputedPropertyName"); } + +bool AstDumper::visit(AST::ArrayMemberExpression *el) { + start(QLatin1String("ArrayMemberExpression lbraketToken=%1 rbraketToken=%2") + .arg(loc(el->lbracketToken), loc(el->rbracketToken))); + return true; +} +void AstDumper::endVisit(AST::ArrayMemberExpression *) { stop("ArrayMemberExpression"); } + +bool AstDumper::visit(AST::FieldMemberExpression *el) { + start(QLatin1String("FieldMemberExpression name=%1 dotToken=%2 identifierToken=%3") + .arg(qs(el->name), loc(el->dotToken), loc(el->identifierToken))); + return true; +} +void AstDumper::endVisit(AST::FieldMemberExpression *) { stop("FieldMemberExpression"); } + +bool AstDumper::visit(AST::TaggedTemplate *) { + start(QLatin1String("TaggedTemplate")); + return true; +} +void AstDumper::endVisit(AST::TaggedTemplate *) { stop("TaggedTemplate"); } + +bool AstDumper::visit(AST::NewMemberExpression *el) { + start(QLatin1String("NewMemberExpression newToken=%1 lparenToken=%2 rparenToken=%3") + .arg(loc(el->newToken), loc(el->lparenToken), loc(el->rparenToken))); + return true; +} +void AstDumper::endVisit(AST::NewMemberExpression *) { stop("NewMemberExpression"); } + +bool AstDumper::visit(AST::NewExpression *el) { + start(QLatin1String("NewExpression newToken=%1") + .arg(loc(el->newToken))); + return true; +} +void AstDumper::endVisit(AST::NewExpression *) { stop("NewExpression"); } + +bool AstDumper::visit(AST::CallExpression *el) { + start(QLatin1String("CallExpression lparenToken=%1 rparenToken=%2") + .arg(loc(el->lparenToken), loc(el->rparenToken))); + return true; +} +void AstDumper::endVisit(AST::CallExpression *) { stop("CallExpression"); } + +bool AstDumper::visit(AST::ArgumentList *el) { + start(QLatin1String("ArgumentList commaToken=%1 isSpreadElement=%2") + .arg(loc(el->commaToken), boolStr(el->isSpreadElement))); + return true; +} +void AstDumper::endVisit(AST::ArgumentList *) { stop("ArgumentList"); } + +bool AstDumper::visit(AST::PostIncrementExpression *el) { + start(QLatin1String("PostIncrementExpression incrementToken=%1") + .arg(loc(el->incrementToken))); + return true; +} +void AstDumper::endVisit(AST::PostIncrementExpression *) { stop("PostIncrementExpression"); } + +bool AstDumper::visit(AST::PostDecrementExpression *el) { + start(QLatin1String("PostDecrementExpression decrementToken=%1") + .arg(loc(el->decrementToken))); + return true; +} +void AstDumper::endVisit(AST::PostDecrementExpression *) { stop("PostDecrementExpression"); } + +bool AstDumper::visit(AST::DeleteExpression *el) { + start(QLatin1String("DeleteExpression deleteToken=%1") + .arg(loc(el->deleteToken))); + return true; +} +void AstDumper::endVisit(AST::DeleteExpression *) { stop("DeleteExpression"); } + +bool AstDumper::visit(AST::VoidExpression *el) { + start(QLatin1String("VoidExpression voidToken=%1") + .arg(loc(el->voidToken))); + return true; +} +void AstDumper::endVisit(AST::VoidExpression *) { stop("VoidExpression"); } + +bool AstDumper::visit(AST::TypeOfExpression *el) { + start(QLatin1String("TypeOfExpression typeofToken=%1") + .arg(loc(el->typeofToken))); + return true; +} +void AstDumper::endVisit(AST::TypeOfExpression *) { stop("TypeOfExpression"); } + +bool AstDumper::visit(AST::PreIncrementExpression *el) { + start(QLatin1String("PreIncrementExpression incrementToken=%1") + .arg(loc(el->incrementToken))); + return true; +} +void AstDumper::endVisit(AST::PreIncrementExpression *) { stop("PreIncrementExpression"); } + +bool AstDumper::visit(AST::PreDecrementExpression *el) { + start(QLatin1String("PreDecrementExpression decrementToken=%1") + .arg(loc(el->decrementToken))); + return true; +} +void AstDumper::endVisit(AST::PreDecrementExpression *) { stop("PreDecrementExpression"); } + +bool AstDumper::visit(AST::UnaryPlusExpression *el) { + start(QLatin1String("UnaryPlusExpression plusToken=%1") + .arg(loc(el->plusToken))); + return true; +} +void AstDumper::endVisit(AST::UnaryPlusExpression *) { stop("UnaryPlusExpression"); } + +bool AstDumper::visit(AST::UnaryMinusExpression *el) { + start(QLatin1String("UnaryMinusExpression minusToken=%1") + .arg(loc(el->minusToken))); + return true; +} +void AstDumper::endVisit(AST::UnaryMinusExpression *) { stop("UnaryMinusExpression"); } + +bool AstDumper::visit(AST::TildeExpression *el) { + start(QLatin1String("TildeExpression tildeToken=%1") + .arg(loc(el->tildeToken))); + return true; +} +void AstDumper::endVisit(AST::TildeExpression *) { stop("TildeExpression"); } + +bool AstDumper::visit(AST::NotExpression *el) { + start(QLatin1String("NotExpression notToken=%1") + .arg(loc(el->notToken))); + return true; +} +void AstDumper::endVisit(AST::NotExpression *) { stop("NotExpression"); } + +bool AstDumper::visit(AST::BinaryExpression *el) { + start(QLatin1String("BinaryExpression op=%1 operatorToken=%2") + .arg(qs(QString::number(el->op,16)), loc(el->operatorToken))); + return true; +} +void AstDumper::endVisit(AST::BinaryExpression *) { stop("BinaryExpression"); } + +bool AstDumper::visit(AST::ConditionalExpression *el) { + start(QLatin1String("ConditionalExpression questionToken=%1 colonToken=%2") + .arg(loc(el->questionToken), loc(el->colonToken))); + return true; +} +void AstDumper::endVisit(AST::ConditionalExpression *) { stop("ConditionalExpression"); } + +bool AstDumper::visit(AST::Expression *el) { + start(QLatin1String("Expression commaToken=%1") + .arg(loc(el->commaToken))); + return true; +} +void AstDumper::endVisit(AST::Expression *) { stop("Expression"); } + +bool AstDumper::visit(AST::Block *el) { + start(QLatin1String("Block lbraceToken=%1 rbraceToken=%2") + .arg(loc(el->lbraceToken), loc(el->rbraceToken))); + return true; +} +void AstDumper::endVisit(AST::Block *) { stop("Block"); } + +bool AstDumper::visit(AST::StatementList *) { + start(QLatin1String("StatementList")); + return true; +} +void AstDumper::endVisit(AST::StatementList *) { stop("StatementList"); } + +bool AstDumper::visit(AST::VariableStatement *el) { + start(QLatin1String("VariableStatement declarationKindToken=%1") + .arg(loc(el->declarationKindToken))); + return true; +} +void AstDumper::endVisit(AST::VariableStatement *) { stop("VariableStatement"); } + +bool AstDumper::visit(AST::VariableDeclarationList *el) { + start(QLatin1String("VariableDeclarationList commaToken=%1") + .arg(loc(el->commaToken))); + return true; +} +void AstDumper::endVisit(AST::VariableDeclarationList *) { stop("VariableDeclarationList"); } + +bool AstDumper::visit(AST::EmptyStatement *el) { + start(QLatin1String("EmptyStatement semicolonToken=%1") + .arg(loc(el->semicolonToken))); + return true; +} +void AstDumper::endVisit(AST::EmptyStatement *) { stop("EmptyStatement"); } + +bool AstDumper::visit(AST::ExpressionStatement *el) { + start(QLatin1String("ExpressionStatement semicolonToken=%1") + .arg(loc(el->semicolonToken))); + return true; +} +void AstDumper::endVisit(AST::ExpressionStatement *) { stop("ExpressionStatement"); } + +bool AstDumper::visit(AST::IfStatement *el) { + start(QLatin1String("IfStatement ifToken=%1 lparenToken=%2 rparenToken=%3 elseToken=%4") + .arg(loc(el->ifToken), loc(el->lparenToken), loc(el->rparenToken), loc(el->elseToken))); + return true; +} +void AstDumper::endVisit(AST::IfStatement *) { stop("IfStatement"); } + +bool AstDumper::visit(AST::DoWhileStatement *el) { + start(QLatin1String("DoWhileStatement doToken=%1 whileToken=%2 lparenToken=%3 rparenToken=%4 semicolonToken=%5") + .arg(loc(el->doToken), loc(el->whileToken), loc(el->lparenToken), loc(el->rparenToken), loc(el->semicolonToken))); + return true; +} +void AstDumper::endVisit(AST::DoWhileStatement *) { stop("DoWhileStatement"); } + +bool AstDumper::visit(AST::WhileStatement *el) { + start(QLatin1String("WhileStatement whileToken=%1 lparenToken=%2 rparenToken=%3") + .arg(loc(el->whileToken), loc(el->lparenToken), loc(el->rparenToken))); + return true; +} +void AstDumper::endVisit(AST::WhileStatement *) { stop("WhileStatement"); } + +bool AstDumper::visit(AST::ForStatement *el) { + start(QLatin1String("ForStatement forToken=%1 lparenToken=%2 firstSemicolonToken=%3 secondSemicolonToken=%4 rparenToken=%5") + .arg(loc(el->forToken), loc(el->lparenToken), loc(el->firstSemicolonToken), loc(el->secondSemicolonToken), loc(el->rparenToken))); + return true; +} +void AstDumper::endVisit(AST::ForStatement *) { stop("ForStatement"); } + +bool AstDumper::visit(AST::ForEachStatement *el) { + start(QLatin1String("ForEachStatement forToken=%1 lparenToken=%2 inOfToken=%3 rparenToken=%4 type=%5") + .arg(loc(el->forToken), loc(el->lparenToken), loc(el->inOfToken), loc(el->rparenToken), qs(QString::number(static_cast(el->type), 16)))); + return true; +} +void AstDumper::endVisit(AST::ForEachStatement *) { stop("ForEachStatement"); } + +bool AstDumper::visit(AST::ContinueStatement *el) { + start(QLatin1String("ContinueStatement label=%1 continueToken=%2 identifierToken=%3 semicolonToken=%4") + .arg(qs(el->label), loc(el->continueToken), loc(el->identifierToken), loc(el->semicolonToken))); + return true; +} +void AstDumper::endVisit(AST::ContinueStatement *) { stop("ContinueStatement"); } + +bool AstDumper::visit(AST::BreakStatement *el) { + start(QLatin1String("BreakStatement label=%1 breakToken=%2 identifierToken=%3 semicolonToken=%4") + .arg(qs(el->label), loc(el->breakToken), loc(el->identifierToken), loc(el->semicolonToken))); + return true; +} +void AstDumper::endVisit(AST::BreakStatement *) { stop("BreakStatement"); } + +bool AstDumper::visit(AST::ReturnStatement *el) { + start(QLatin1String("ReturnStatement returnToken=%1 semicolonToken=%2") + .arg(loc(el->returnToken), loc(el->semicolonToken))); + return true; +} +void AstDumper::endVisit(AST::ReturnStatement *) { stop("ReturnStatement"); } + +bool AstDumper::visit(AST::YieldExpression *el) { + start(QLatin1String("YieldExpression isYieldStar=%1 yieldToken=%2") + .arg(boolStr(el->isYieldStar), loc(el->yieldToken))); + return true; +} +void AstDumper::endVisit(AST::YieldExpression *) { stop("YieldExpression"); } + +bool AstDumper::visit(AST::WithStatement *el) { + start(QLatin1String("WithStatement withToken=%1 lparenToken=%2 rparenToken=%3") + .arg(loc(el->withToken), loc(el->lparenToken), loc(el->rparenToken))); + return true; +} +void AstDumper::endVisit(AST::WithStatement *) { stop("WithStatement"); } + +bool AstDumper::visit(AST::SwitchStatement *el) { + start(QLatin1String("SwitchStatement switchToken=%1 lparenToken=%2 rparenToken=%3") + .arg(loc(el->switchToken), loc(el->lparenToken), loc(el->rparenToken))); + return true; +} +void AstDumper::endVisit(AST::SwitchStatement *) { stop("SwitchStatement"); } + +bool AstDumper::visit(AST::CaseBlock *el) { + start(QLatin1String("CaseBlock lbraceToken=%1 rbraceToken=%2") + .arg(loc(el->lbraceToken), loc(el->rbraceToken))); + return true; +} +void AstDumper::endVisit(AST::CaseBlock *) { stop("CaseBlock"); } + +bool AstDumper::visit(AST::CaseClauses *) { + start(QLatin1String("CaseClauses")); + return true; +} +void AstDumper::endVisit(AST::CaseClauses *) { stop("CaseClauses"); } + +bool AstDumper::visit(AST::CaseClause *el) { + start(QLatin1String("CaseClause caseToken=%1 colonToken=%2") + .arg(loc(el->caseToken), loc(el->colonToken))); + return true; +} +void AstDumper::endVisit(AST::CaseClause *) { stop("CaseClause"); } + +bool AstDumper::visit(AST::DefaultClause *el) { + start(QLatin1String("DefaultClause defaultToken=%1 colonToken=%2") + .arg(loc(el->defaultToken), loc(el->colonToken))); + return true; +} +void AstDumper::endVisit(AST::DefaultClause *) { stop("DefaultClause"); } + +bool AstDumper::visit(AST::LabelledStatement *el) { + start(QLatin1String("LabelledStatement label=%1 identifierToken=%2 colonToken=%3") + .arg(qs(el->label), loc(el->identifierToken), loc(el->colonToken))); + return true; +} +void AstDumper::endVisit(AST::LabelledStatement *) { stop("LabelledStatement"); } + +bool AstDumper::visit(AST::ThrowStatement *el) { + start(QLatin1String("ThrowStatement throwToken=%1 semicolonToken=%2") + .arg(loc(el->throwToken), loc(el->semicolonToken))); + return true; +} +void AstDumper::endVisit(AST::ThrowStatement *) { stop("ThrowStatement"); } + +bool AstDumper::visit(AST::TryStatement *el) { + start(QLatin1String("TryStatement tryToken=%1") + .arg(loc(el->tryToken))); + return true; +} +void AstDumper::endVisit(AST::TryStatement *) { stop("TryStatement"); } + +bool AstDumper::visit(AST::Catch *el) { + start(QLatin1String("Catch catchToken=%1 lparenToken=%2 identifierToken=%3 rparenToken=%4") + .arg(loc(el->catchToken), loc(el->lparenToken), loc(el->identifierToken), loc(el->rparenToken))); + return true; +} +void AstDumper::endVisit(AST::Catch *) { stop("Catch"); } + +bool AstDumper::visit(AST::Finally *el) { + start(QLatin1String("Finally finallyToken=%1") + .arg(loc(el->finallyToken))); + return true; +} +void AstDumper::endVisit(AST::Finally *) { stop("Finally"); } + +bool AstDumper::visit(AST::FunctionDeclaration *el) { + start(QLatin1String("FunctionDeclaration name=%1 isArrowFunction=%2 isGenerator=%3 functionToken=%4 " + "identifierToken=%5 lparenToken=%6 rparenToken=%7 lbraceToken=%8 rbraceToken=%9") + .arg(qs(el->name), boolStr(el->isArrowFunction), boolStr(el->isGenerator), loc(el->functionToken), + loc(el->identifierToken), loc(el->lparenToken), loc(el->rparenToken), loc(el->lbraceToken), + loc(el->rbraceToken))); + return true; +} +void AstDumper::endVisit(AST::FunctionDeclaration *) { stop("FunctionDeclaration"); } + +bool AstDumper::visit(AST::FunctionExpression *el) { + start(QLatin1String("FunctionExpression name=%1 isArrowFunction=%2 isGenerator=%3 functionToken=%4 " + "identifierToken=%5 lparenToken=%6 rparenToken=%7 lbraceToken=%8 rbraceToken=%9") + .arg(qs(el->name), boolStr(el->isArrowFunction), boolStr(el->isGenerator), loc(el->functionToken), + loc(el->identifierToken), loc(el->lparenToken), loc(el->rparenToken), loc(el->lbraceToken), + loc(el->rbraceToken))); + return true; +} +void AstDumper::endVisit(AST::FunctionExpression *) { stop("FunctionExpression"); } + +bool AstDumper::visit(AST::FormalParameterList *) { + start(QLatin1String("FormalParameterList")); + return true; +} +void AstDumper::endVisit(AST::FormalParameterList *) { stop("FormalParameterList"); } + +bool AstDumper::visit(AST::ClassExpression *el) { + start(QLatin1String("ClassExpression name=%1 classToken=%2 identifierToken=%3 lbraceToken=%4 rbraceToken=%5") + .arg(qs(el->name), loc(el->classToken), loc(el->identifierToken), loc(el->lbraceToken), loc(el->rbraceToken))); + return true; +} +void AstDumper::endVisit(AST::ClassExpression *) { stop("ClassExpression"); } + +bool AstDumper::visit(AST::ClassDeclaration *el) { + start(QLatin1String("ClassDeclaration name=%1 classToken=%2 identifierToken=%3 lbraceToken=%4 rbraceToken=%5") + .arg(qs(el->name), loc(el->classToken), loc(el->identifierToken), loc(el->lbraceToken), loc(el->rbraceToken))); + return true; +} +void AstDumper::endVisit(AST::ClassDeclaration *) { stop("ClassDeclaration"); } + +bool AstDumper::visit(AST::ClassElementList *el) { + start(QLatin1String("ClassElementList isStatic=%1") + .arg(boolStr(el->isStatic))); + return true; +} +void AstDumper::endVisit(AST::ClassElementList *) { stop("ClassElementList"); } + +bool AstDumper::visit(AST::Program *) { + start(QLatin1String("Program")); + return true; +} +void AstDumper::endVisit(AST::Program *) { stop("Program"); } + +bool AstDumper::visit(AST::NameSpaceImport *el) { + start(QLatin1String("NameSpaceImport starToken=%1 importedBindingToken=%2 importedBinding=%3") + .arg(loc(el->starToken), loc(el->importedBindingToken), qs(el->importedBinding))); + return true; +} +void AstDumper::endVisit(AST::NameSpaceImport *) { stop("NameSpaceImport"); } + +bool AstDumper::visit(AST::ImportSpecifier *el) { + start(QLatin1String("ImportSpecifier identifierToken=%1 importedBindingToken=%2 identifier=%3 importedBinding=%4") + .arg(loc(el->identifierToken), loc(el->importedBindingToken), qs(el->identifier), qs(el->importedBinding))); + return true; +} +void AstDumper::endVisit(AST::ImportSpecifier *) { stop("ImportSpecifier"); } + +bool AstDumper::visit(AST::ImportsList *el) { + start(QLatin1String("ImportsList importSpecifierToken=%1") + .arg(loc(el->importSpecifierToken))); + return true; +} +void AstDumper::endVisit(AST::ImportsList *) { stop("ImportsList"); } + +bool AstDumper::visit(AST::NamedImports *el) { + start(QLatin1String("NamedImports leftBraceToken=%1 rightBraceToken=%2") + .arg(loc(el->leftBraceToken), loc(el->rightBraceToken))); + return true; +} +void AstDumper::endVisit(AST::NamedImports *) { stop("NamedImports"); } + +bool AstDumper::visit(AST::FromClause *el) { + start(QLatin1String("FromClause fromToken=%1 moduleSpecifierToken=%2 moduleSpecifier=%3") + .arg(loc(el->fromToken), loc(el->moduleSpecifierToken), qs(el->moduleSpecifier))); + return true; +} +void AstDumper::endVisit(AST::FromClause *) { stop("FromClause"); } + +bool AstDumper::visit(AST::ImportClause *el) { + start(QLatin1String("ImportClause importedDefaultBindingToken=%1 importedDefaultBinding=%2") + .arg(loc(el->importedDefaultBindingToken), qs(el->importedDefaultBinding))); + return true; +} +void AstDumper::endVisit(AST::ImportClause *) { stop("ImportClause"); } + +bool AstDumper::visit(AST::ImportDeclaration *el) { + start(QLatin1String("ImportDeclaration importToken=%1 moduleSpecifierToken=%2 moduleSpecifier=%3") + .arg(loc(el->importToken), loc(el->moduleSpecifierToken), qs(el->moduleSpecifier))); + return true; +} +void AstDumper::endVisit(AST::ImportDeclaration *) { stop("ImportDeclaration"); } + +bool AstDumper::visit(AST::ExportSpecifier *el) { + start(QLatin1String("ExportSpecifier identifierToken=%1 exportedIdentifierToken=%2 identifier=%3 exportedIdentifier=%4") + .arg(loc(el->identifierToken), loc(el->exportedIdentifierToken), qs(el->identifier), qs(el->exportedIdentifier))); + return true; +} +void AstDumper::endVisit(AST::ExportSpecifier *) { stop("ExportSpecifier"); } + +bool AstDumper::visit(AST::ExportsList *) { + start(QLatin1String("ExportsList")); + return true; +} +void AstDumper::endVisit(AST::ExportsList *) { stop("ExportsList"); } + +bool AstDumper::visit(AST::ExportClause *el) { + start(QLatin1String("ExportClause leftBraceToken=%1 rightBraceToken=%2") + .arg(loc(el->leftBraceToken), loc(el->rightBraceToken))); + return true; +} +void AstDumper::endVisit(AST::ExportClause *) { stop("ExportClause"); } + +bool AstDumper::visit(AST::ExportDeclaration *el) { + start(QLatin1String("ExportDeclaration exportToken=%1 exportAll=%2 exportDefault=%3") + .arg(loc(el->exportToken), boolStr(el->exportAll), boolStr(el->exportDefault))); + return true; +} +void AstDumper::endVisit(AST::ExportDeclaration *) { stop("ExportDeclaration"); } + +bool AstDumper::visit(AST::ESModule *) { + start(QLatin1String("ESModule")); + return true; +} +void AstDumper::endVisit(AST::ESModule *) { stop("ESModule"); } + +bool AstDumper::visit(AST::DebuggerStatement *el) { + start(QLatin1String("DebuggerStatement debuggerToken=%1 semicolonToken=%2") + .arg(loc(el->debuggerToken), loc(el->semicolonToken))); + return true; +} +void AstDumper::endVisit(AST::DebuggerStatement *) { stop("DebuggerStatement"); } + +bool AstDumper::visit(AST::Type *) { + start(QLatin1String("Type")); + return true; +} +void AstDumper::endVisit(AST::Type *) { stop("Type"); } + +bool AstDumper::visit(AST::TypeArgumentList *) { + start(QLatin1String("TypeArgumentList")); + return true; +} +void AstDumper::endVisit(AST::TypeArgumentList *) { stop("TypeArgumentList"); } + +bool AstDumper::visit(AST::TypeAnnotation *el) { + start(QLatin1String("TypeAnnotation colonToken=%1") + .arg(loc(el->colonToken))); + return true; +} +void AstDumper::endVisit(AST::TypeAnnotation *) { stop("TypeAnnotation"); } + +void AstDumper::throwRecursionDepthError() +{ + qDebug() << "Maximum statement or expression depth exceeded in AstDumper"; +} + +bool AstDumper::dumpNode() { + return options & DumperOptions::DumpNode; +} + +bool AstDumper::noLocations() { + return options & DumperOptions::NoLocations; +} + +bool AstDumper::noAnnotations() { + return options & DumperOptions::NoAnnotations; +} + +} // end namespace QQmlJS + +QT_END_NAMESPACE diff --git a/tests/auto/shared/qqmljsastdumper.h b/tests/auto/shared/qqmljsastdumper.h new file mode 100644 index 0000000000..919b80f38c --- /dev/null +++ b/tests/auto/shared/qqmljsastdumper.h @@ -0,0 +1,442 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +**/ +#ifndef ASTDUMPER_H +#define ASTDUMPER_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 +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QDebug; + +namespace QQmlJS { + +enum class DumperOptions { + None=0, + NoLocations=0x1, + NoAnnotations=0x2, + DumpNode=0x4 +}; +bool operator & (DumperOptions lhs, DumperOptions rhs); +DumperOptions operator | (DumperOptions lhs, DumperOptions rhs); + +// no export, currently just a supporting file... +class AstDumper: public AST::Visitor +{ +public: + static QString printNode2(AST::Node *); + + static QString diff(AST::Node *n1, AST::Node *n2, int nContext=3, DumperOptions opt=DumperOptions::None, int indent=0); + static QString printNode(AST::Node *n, DumperOptions opt=DumperOptions::None, int indent=1, int baseIndent=0); + + AstDumper(const std::function &dumper, DumperOptions options=DumperOptions::None, + int indent=1, int baseIndent=0); + + void start(const QString &str); + void start(const char *str); + void stop(const QString &str); + void stop(const char *str); + + QString qs(const QString &s); + QString qs(const char *s); + QString qs(const QStringRef &s); + + QString loc(const AST::SourceLocation &s); + + QString boolStr(bool v); + + bool preVisit(AST::Node *el) override; + void postVisit(AST::Node *el) override; + + // Ui + bool visit(AST::UiProgram *el) override; + bool visit(AST::UiHeaderItemList *) override; + bool visit(AST::UiPragma *el) override; + bool visit(AST::UiImport *el) override; + bool visit(AST::UiPublicMember *el) override; + bool visit(AST::UiSourceElement *) override; + bool visit(AST::UiObjectDefinition *) override; + bool visit(AST::UiObjectInitializer *) override; + bool visit(AST::UiObjectBinding *) override; + bool visit(AST::UiScriptBinding *) override; + bool visit(AST::UiArrayBinding *) override; + bool visit(AST::UiParameterList *) override; + bool visit(AST::UiObjectMemberList *) override; + bool visit(AST::UiArrayMemberList *) override; + bool visit(AST::UiQualifiedId *) override; + bool visit(AST::UiEnumDeclaration *) override; + bool visit(AST::UiEnumMemberList *) override; + bool visit(AST::UiVersionSpecifier *) override; + bool visit(AST::UiInlineComponent *) override; + bool visit(AST::UiRequired *) override; + + void endVisit(AST::UiProgram *) override; + void endVisit(AST::UiImport *) override; + void endVisit(AST::UiHeaderItemList *) override; + void endVisit(AST::UiPragma *) override; + void endVisit(AST::UiPublicMember *) override; + void endVisit(AST::UiSourceElement *) override; + void endVisit(AST::UiObjectDefinition *) override; + void endVisit(AST::UiObjectInitializer *) override; + void endVisit(AST::UiObjectBinding *) override; + void endVisit(AST::UiScriptBinding *) override; + void endVisit(AST::UiArrayBinding *) override; + void endVisit(AST::UiParameterList *) override; + void endVisit(AST::UiObjectMemberList *) override; + void endVisit(AST::UiArrayMemberList *) override; + void endVisit(AST::UiQualifiedId *) override; + void endVisit(AST::UiEnumDeclaration *) override; + void endVisit(AST::UiEnumMemberList *) override; + void endVisit(AST::UiVersionSpecifier *) override; + void endVisit(AST::UiInlineComponent *) override; + void endVisit(AST::UiRequired *) override; + + // QQmlJS + bool visit(AST::ThisExpression *) override; + void endVisit(AST::ThisExpression *) override; + + bool visit(AST::IdentifierExpression *) override; + void endVisit(AST::IdentifierExpression *) override; + + bool visit(AST::NullExpression *) override; + void endVisit(AST::NullExpression *) override; + + bool visit(AST::TrueLiteral *) override; + void endVisit(AST::TrueLiteral *) override; + + bool visit(AST::FalseLiteral *) override; + void endVisit(AST::FalseLiteral *) override; + + bool visit(AST::SuperLiteral *) override; + void endVisit(AST::SuperLiteral *) override; + + bool visit(AST::StringLiteral *) override; + void endVisit(AST::StringLiteral *) override; + + bool visit(AST::TemplateLiteral *) override; + void endVisit(AST::TemplateLiteral *) override; + + bool visit(AST::NumericLiteral *) override; + void endVisit(AST::NumericLiteral *) override; + + bool visit(AST::RegExpLiteral *) override; + void endVisit(AST::RegExpLiteral *) override; + + bool visit(AST::ArrayPattern *) override; + void endVisit(AST::ArrayPattern *) override; + + bool visit(AST::ObjectPattern *) override; + void endVisit(AST::ObjectPattern *) override; + + bool visit(AST::PatternElementList *) override; + void endVisit(AST::PatternElementList *) override; + + bool visit(AST::PatternPropertyList *) override; + void endVisit(AST::PatternPropertyList *) override; + + bool visit(AST::PatternElement *) override; + void endVisit(AST::PatternElement *) override; + + bool visit(AST::PatternProperty *) override; + void endVisit(AST::PatternProperty *) override; + + bool visit(AST::Elision *) override; + void endVisit(AST::Elision *) override; + + bool visit(AST::NestedExpression *) override; + void endVisit(AST::NestedExpression *) override; + + bool visit(AST::IdentifierPropertyName *) override; + void endVisit(AST::IdentifierPropertyName *) override; + + bool visit(AST::StringLiteralPropertyName *) override; + void endVisit(AST::StringLiteralPropertyName *) override; + + bool visit(AST::NumericLiteralPropertyName *) override; + void endVisit(AST::NumericLiteralPropertyName *) override; + + bool visit(AST::ComputedPropertyName *) override; + void endVisit(AST::ComputedPropertyName *) override; + + bool visit(AST::ArrayMemberExpression *) override; + void endVisit(AST::ArrayMemberExpression *) override; + + bool visit(AST::FieldMemberExpression *) override; + void endVisit(AST::FieldMemberExpression *) override; + + bool visit(AST::TaggedTemplate *) override; + void endVisit(AST::TaggedTemplate *) override; + + bool visit(AST::NewMemberExpression *) override; + void endVisit(AST::NewMemberExpression *) override; + + bool visit(AST::NewExpression *) override; + void endVisit(AST::NewExpression *) override; + + bool visit(AST::CallExpression *) override; + void endVisit(AST::CallExpression *) override; + + bool visit(AST::ArgumentList *) override; + void endVisit(AST::ArgumentList *) override; + + bool visit(AST::PostIncrementExpression *) override; + void endVisit(AST::PostIncrementExpression *) override; + + bool visit(AST::PostDecrementExpression *) override; + void endVisit(AST::PostDecrementExpression *) override; + + bool visit(AST::DeleteExpression *) override; + void endVisit(AST::DeleteExpression *) override; + + bool visit(AST::VoidExpression *) override; + void endVisit(AST::VoidExpression *) override; + + bool visit(AST::TypeOfExpression *) override; + void endVisit(AST::TypeOfExpression *) override; + + bool visit(AST::PreIncrementExpression *) override; + void endVisit(AST::PreIncrementExpression *) override; + + bool visit(AST::PreDecrementExpression *) override; + void endVisit(AST::PreDecrementExpression *) override; + + bool visit(AST::UnaryPlusExpression *) override; + void endVisit(AST::UnaryPlusExpression *) override; + + bool visit(AST::UnaryMinusExpression *) override; + void endVisit(AST::UnaryMinusExpression *) override; + + bool visit(AST::TildeExpression *) override; + void endVisit(AST::TildeExpression *) override; + + bool visit(AST::NotExpression *) override; + void endVisit(AST::NotExpression *) override; + + bool visit(AST::BinaryExpression *) override; + void endVisit(AST::BinaryExpression *) override; + + bool visit(AST::ConditionalExpression *) override; + void endVisit(AST::ConditionalExpression *) override; + + bool visit(AST::Expression *) override; + void endVisit(AST::Expression *) override; + + bool visit(AST::Block *) override; + void endVisit(AST::Block *) override; + + bool visit(AST::StatementList *) override; + void endVisit(AST::StatementList *) override; + + bool visit(AST::VariableStatement *) override; + void endVisit(AST::VariableStatement *) override; + + bool visit(AST::VariableDeclarationList *) override; + void endVisit(AST::VariableDeclarationList *) override; + + bool visit(AST::EmptyStatement *) override; + void endVisit(AST::EmptyStatement *) override; + + bool visit(AST::ExpressionStatement *) override; + void endVisit(AST::ExpressionStatement *) override; + + bool visit(AST::IfStatement *) override; + void endVisit(AST::IfStatement *) override; + + bool visit(AST::DoWhileStatement *) override; + void endVisit(AST::DoWhileStatement *) override; + + bool visit(AST::WhileStatement *) override; + void endVisit(AST::WhileStatement *) override; + + bool visit(AST::ForStatement *) override; + void endVisit(AST::ForStatement *) override; + + bool visit(AST::ForEachStatement *) override; + void endVisit(AST::ForEachStatement *) override; + + bool visit(AST::ContinueStatement *) override; + void endVisit(AST::ContinueStatement *) override; + + bool visit(AST::BreakStatement *) override; + void endVisit(AST::BreakStatement *) override; + + bool visit(AST::ReturnStatement *) override; + void endVisit(AST::ReturnStatement *) override; + + bool visit(AST::YieldExpression *) override; + void endVisit(AST::YieldExpression *) override; + + bool visit(AST::WithStatement *) override; + void endVisit(AST::WithStatement *) override; + + bool visit(AST::SwitchStatement *) override; + void endVisit(AST::SwitchStatement *) override; + + bool visit(AST::CaseBlock *) override; + void endVisit(AST::CaseBlock *) override; + + bool visit(AST::CaseClauses *) override; + void endVisit(AST::CaseClauses *) override; + + bool visit(AST::CaseClause *) override; + void endVisit(AST::CaseClause *) override; + + bool visit(AST::DefaultClause *) override; + void endVisit(AST::DefaultClause *) override; + + bool visit(AST::LabelledStatement *) override; + void endVisit(AST::LabelledStatement *) override; + + bool visit(AST::ThrowStatement *) override; + void endVisit(AST::ThrowStatement *) override; + + bool visit(AST::TryStatement *) override; + void endVisit(AST::TryStatement *) override; + + bool visit(AST::Catch *) override; + void endVisit(AST::Catch *) override; + + bool visit(AST::Finally *) override; + void endVisit(AST::Finally *) override; + + bool visit(AST::FunctionDeclaration *) override; + void endVisit(AST::FunctionDeclaration *) override; + + bool visit(AST::FunctionExpression *) override; + void endVisit(AST::FunctionExpression *) override; + + bool visit(AST::FormalParameterList *) override; + void endVisit(AST::FormalParameterList *) override; + + bool visit(AST::ClassExpression *) override; + void endVisit(AST::ClassExpression *) override; + + bool visit(AST::ClassDeclaration *) override; + void endVisit(AST::ClassDeclaration *) override; + + bool visit(AST::ClassElementList *) override; + void endVisit(AST::ClassElementList *) override; + + bool visit(AST::Program *) override; + void endVisit(AST::Program *) override; + + bool visit(AST::NameSpaceImport *) override; + void endVisit(AST::NameSpaceImport *) override; + + bool visit(AST::ImportSpecifier *) override; + void endVisit(AST::ImportSpecifier *) override; + + bool visit(AST::ImportsList *) override; + void endVisit(AST::ImportsList *) override; + + bool visit(AST::NamedImports *) override; + void endVisit(AST::NamedImports *) override; + + bool visit(AST::FromClause *) override; + void endVisit(AST::FromClause *) override; + + bool visit(AST::ImportClause *) override; + void endVisit(AST::ImportClause *) override; + + bool visit(AST::ImportDeclaration *) override; + void endVisit(AST::ImportDeclaration *) override; + + bool visit(AST::ExportSpecifier *) override; + void endVisit(AST::ExportSpecifier *) override; + + bool visit(AST::ExportsList *) override; + void endVisit(AST::ExportsList *) override; + + bool visit(AST::ExportClause *) override; + void endVisit(AST::ExportClause *) override; + + bool visit(AST::ExportDeclaration *) override; + void endVisit(AST::ExportDeclaration *) override; + + bool visit(AST::ESModule *) override; + void endVisit(AST::ESModule *) override; + + bool visit(AST::DebuggerStatement *) override; + void endVisit(AST::DebuggerStatement *) override; + + bool visit(AST::Type *) override; + void endVisit(AST::Type *) override; + + bool visit(AST::TypeArgumentList *) override; + void endVisit(AST::TypeArgumentList *) override; + + bool visit(AST::TypeAnnotation *) override; + void endVisit(AST::TypeAnnotation *) override; + + void throwRecursionDepthError() override; + +private: + // attributes + std::function dumper; + DumperOptions options = DumperOptions::None; + int indent = 0; + int baseIndent = 0; + bool dumpNode(); + bool noLocations(); + bool noAnnotations(); +}; + +QDebug operator<<(QDebug d, AST::Node *n); + +std::ostream &operator<<(std::ostream &stream, AST::Node *n); + +} // namespace AST + +QT_END_NAMESPACE + +#endif // ASTDUMPER_H -- cgit v1.2.3 From c2e756dc1962eeb3575f618b38272359d4fccc89 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Tue, 11 Feb 2020 16:22:12 +0100 Subject: Introduce BaseVisitor Base Visitor is an abstract visitor that has all visit methods abstract, subclassing this one gets an error if some visit method is not implemented (dumper and reformatter for example will gain from this. Change-Id: I3f8cfeb6fc0ef917acf725bbe1c293d761304287 Reviewed-by: Ulf Hermann --- tests/auto/shared/qqmljsastdumper.cpp | 7 +++++++ tests/auto/shared/qqmljsastdumper.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/shared/qqmljsastdumper.cpp b/tests/auto/shared/qqmljsastdumper.cpp index 7c7485fd1f..92d95be80a 100644 --- a/tests/auto/shared/qqmljsastdumper.cpp +++ b/tests/auto/shared/qqmljsastdumper.cpp @@ -366,6 +366,12 @@ bool AstDumper::visit(UiRequired *el) return true; } +bool AstDumper::visit(UiAnnotationList *) +{ + start(QLatin1String("UiAnnotationList")); + return true; +} + void AstDumper::endVisit(AST::UiProgram *) { stop("UiProgram"); } void AstDumper::endVisit(AST::UiImport *el) { @@ -403,6 +409,7 @@ void AstDumper::endVisit(AST::UiEnumMemberList *el) { void AstDumper::endVisit(AST::UiVersionSpecifier *) { stop("UiVersionSpecifier"); } void AstDumper::endVisit(AST::UiInlineComponent *) { stop("UiInlineComponent"); } void AstDumper::endVisit(UiRequired *) { stop("UiRequired"); } +void AstDumper::endVisit(UiAnnotationList *) { stop("UiAnnotationList"); } // QQmlJS bool AstDumper::visit(AST::ThisExpression *el) { diff --git a/tests/auto/shared/qqmljsastdumper.h b/tests/auto/shared/qqmljsastdumper.h index 919b80f38c..cd52e96220 100644 --- a/tests/auto/shared/qqmljsastdumper.h +++ b/tests/auto/shared/qqmljsastdumper.h @@ -71,7 +71,7 @@ bool operator & (DumperOptions lhs, DumperOptions rhs); DumperOptions operator | (DumperOptions lhs, DumperOptions rhs); // no export, currently just a supporting file... -class AstDumper: public AST::Visitor +class AstDumper: public AST::BaseVisitor { public: static QString printNode2(AST::Node *); -- cgit v1.2.3 From 41e8f8a7c6aa4a530abdbc52f8014c4563e85417 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Tue, 11 Feb 2020 16:13:36 +0100 Subject: Add UiAnnotation for annotation objects This is a partial patch that is fuilly fixed with the following one (big restructure) because it needs extra visit methods, and that leads to conflicts, but I think it gets lost if merged with the next one. Change-Id: I54331a47a5c7faaf78a97e580825d1feec5adf92 Reviewed-by: Ulf Hermann --- tests/auto/shared/qqmljsastdumper.cpp | 7 +++++++ tests/auto/shared/qqmljsastdumper.h | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'tests') diff --git a/tests/auto/shared/qqmljsastdumper.cpp b/tests/auto/shared/qqmljsastdumper.cpp index 92d95be80a..8a50e021f6 100644 --- a/tests/auto/shared/qqmljsastdumper.cpp +++ b/tests/auto/shared/qqmljsastdumper.cpp @@ -366,6 +366,12 @@ bool AstDumper::visit(UiRequired *el) return true; } +bool AstDumper::visit(UiAnnotation *) +{ + start(QLatin1String("UiAnnotation")); + return true; +} + bool AstDumper::visit(UiAnnotationList *) { start(QLatin1String("UiAnnotationList")); @@ -409,6 +415,7 @@ void AstDumper::endVisit(AST::UiEnumMemberList *el) { void AstDumper::endVisit(AST::UiVersionSpecifier *) { stop("UiVersionSpecifier"); } void AstDumper::endVisit(AST::UiInlineComponent *) { stop("UiInlineComponent"); } void AstDumper::endVisit(UiRequired *) { stop("UiRequired"); } +void AstDumper::endVisit(UiAnnotation *) { stop("UiAnnotation"); } void AstDumper::endVisit(UiAnnotationList *) { stop("UiAnnotationList"); } // QQmlJS diff --git a/tests/auto/shared/qqmljsastdumper.h b/tests/auto/shared/qqmljsastdumper.h index cd52e96220..d8d19e351d 100644 --- a/tests/auto/shared/qqmljsastdumper.h +++ b/tests/auto/shared/qqmljsastdumper.h @@ -119,6 +119,8 @@ public: bool visit(AST::UiVersionSpecifier *) override; bool visit(AST::UiInlineComponent *) override; bool visit(AST::UiRequired *) override; + bool visit(AST::UiAnnotation *) override; + bool visit(AST::UiAnnotationList *) override; void endVisit(AST::UiProgram *) override; void endVisit(AST::UiImport *) override; @@ -140,6 +142,8 @@ public: void endVisit(AST::UiVersionSpecifier *) override; void endVisit(AST::UiInlineComponent *) override; void endVisit(AST::UiRequired *) override; + void endVisit(AST::UiAnnotation *) override; + void endVisit(AST::UiAnnotationList *) override; // QQmlJS bool visit(AST::ThisExpression *) override; -- cgit v1.2.3 From 229e3220ef521dd4389808fd311ea5ae33ab0cae Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Tue, 11 Feb 2020 16:32:04 +0100 Subject: qmlformat: preserve annotations Change-Id: I22e72d91f6d422e93a7ebc642a8449cb490aec20 Reviewed-by: Ulf Hermann Reviewed-by: Maximilian Goldstein --- .../data/Annotations.formatted.nosort.qml | 106 +++++++++++++++++++++ .../qml/qmlformat/data/Annotations.formatted.qml | 106 +++++++++++++++++++++ tests/auto/qml/qmlformat/data/Annotations.qml | 76 +++++++++++++++ tests/auto/qml/qmlformat/tst_qmlformat.cpp | 12 +++ 4 files changed, 300 insertions(+) create mode 100644 tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml create mode 100644 tests/auto/qml/qmlformat/data/Annotations.formatted.qml create mode 100644 tests/auto/qml/qmlformat/data/Annotations.qml (limited to 'tests') diff --git a/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml b/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml new file mode 100644 index 0000000000..a05c2125dc --- /dev/null +++ b/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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$ +** +****************************************************************************/ + +//![2] +import QtQuick 2.0 +//![2] +import QtCharts 2.0 + +@Pippo { + atg1: 3 +} +@Annotation2 { +} +Item { + //![1] + + @AnnotateMore { + property int x: 5 + } + @AnnotateALot { + } + + property variant othersSlice: 0 + @Annotate { + } + + anchors.fill: parent + @SuperComplete { + binding: late + } + Component.onCompleted: { + // You can also manipulate slices dynamically, like append a slice or set a slice exploded + othersSlice = pieSeries.append("Others", 52); + pieSeries.find("Volkswagen").exploded = true; + } + //![1] + ChartView { + id: chart + + title: "Top-5 car brand shares in Finland" + anchors.fill: parent + legend.alignment: Qt.AlignBottom + antialiasing: true + + @ExtraAnnotation { + signal pippo() + } + PieSeries { + id: pieSeries + + PieSlice { + label: "Volkswagen" + value: 13.5 + } + + PieSlice { + label: "Toyota" + value: 10.9 + } + + PieSlice { + label: "Ford" + value: 8.6 + } + + PieSlice { + label: "Skoda" + value: 8.2 + } + + PieSlice { + label: "Volvo" + value: 6.8 + } + + } + + } + +} diff --git a/tests/auto/qml/qmlformat/data/Annotations.formatted.qml b/tests/auto/qml/qmlformat/data/Annotations.formatted.qml new file mode 100644 index 0000000000..a142d4cb74 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/Annotations.formatted.qml @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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$ +** +****************************************************************************/ + +//![2] +import QtCharts 2.0 +//![2] +import QtQuick 2.0 + +@Pippo { + atg1: 3 +} +@Annotation2 { +} +Item { + //![1] + + @AnnotateMore { + property int x: 5 + } + @AnnotateALot { + } + + property variant othersSlice: 0 + @Annotate { + } + + anchors.fill: parent + @SuperComplete { + binding: late + } + Component.onCompleted: { + // You can also manipulate slices dynamically, like append a slice or set a slice exploded + othersSlice = pieSeries.append("Others", 52); + pieSeries.find("Volkswagen").exploded = true; + } + //![1] + ChartView { + id: chart + + title: "Top-5 car brand shares in Finland" + anchors.fill: parent + legend.alignment: Qt.AlignBottom + antialiasing: true + + @ExtraAnnotation { + signal pippo() + } + PieSeries { + id: pieSeries + + PieSlice { + label: "Volkswagen" + value: 13.5 + } + + PieSlice { + label: "Toyota" + value: 10.9 + } + + PieSlice { + label: "Ford" + value: 8.6 + } + + PieSlice { + label: "Skoda" + value: 8.2 + } + + PieSlice { + label: "Volvo" + value: 6.8 + } + + } + + } + +} diff --git a/tests/auto/qml/qmlformat/data/Annotations.qml b/tests/auto/qml/qmlformat/data/Annotations.qml new file mode 100644 index 0000000000..2d3d7d2cfd --- /dev/null +++ b/tests/auto/qml/qmlformat/data/Annotations.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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$ +** +****************************************************************************/ + +//![2] +import QtQuick 2.0 +//![2] +import QtCharts 2.0 + +@Pippo{ atg1:3 } +@Annotation2{} +Item { + @Annotate{} + anchors.fill: parent + @AnnotateMore{ + property int x: 5 + } + @AnnotateALot{} + property variant othersSlice: 0 + + //![1] + ChartView { + id: chart + title: "Top-5 car brand shares in Finland" + anchors.fill: parent + legend.alignment: Qt.AlignBottom + antialiasing: true + +@ExtraAnnotation{ + signal pippo +} + PieSeries { + id: pieSeries + PieSlice { label: "Volkswagen"; value: 13.5 } + PieSlice { label: "Toyota"; value: 10.9 } + PieSlice { label: "Ford"; value: 8.6 } + PieSlice { label: "Skoda"; value: 8.2 } + PieSlice { label: "Volvo"; value: 6.8 } + } + } + +@SuperComplete{ +binding: late +} + Component.onCompleted: { + // You can also manipulate slices dynamically, like append a slice or set a slice exploded + othersSlice = pieSeries.append("Others", 52.0); + pieSeries.find("Volkswagen").exploded = true; + } + //![1] +} diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp index b10eaf26f1..47255d7745 100644 --- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp +++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp @@ -41,6 +41,8 @@ private Q_SLOTS: void testFormat(); void testFormatNoSort(); + void testAnnotations(); + void testAnnotationsNoSort(); void testReadOnlyProps(); @@ -183,6 +185,16 @@ void TestQmlformat::testFormatNoSort() QCOMPARE(runQmlformat(testFile("Example1.qml"), false, true), readTestFile("Example1.formatted.nosort.qml")); } +void TestQmlformat::testAnnotations() +{ + QCOMPARE(runQmlformat(testFile("Annotations.qml"), true, true), readTestFile("Annotations.formatted.qml")); +} + +void TestQmlformat::testAnnotationsNoSort() +{ + QCOMPARE(runQmlformat(testFile("Annotations.qml"), false, true), readTestFile("Annotations.formatted.nosort.qml")); +} + void TestQmlformat::testReadOnlyProps() { QCOMPARE(runQmlformat(testFile("readOnlyProps.qml"), false, true), readTestFile("readOnlyProps.formatted.qml")); -- cgit v1.2.3 From 164e559c8a7a34aa46ef7563a19100f81a1cade4 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 16 Jan 2020 15:00:36 +0100 Subject: Process major versions as part of Q_REVISION Retrieve the major version from the meta object revisions and use them to register types and generate qmltypes files. Change-Id: I35da8963457660d1a49ba9063574e1a68057a7ba Reviewed-by: Fabian Kosmale --- tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes | 6 +++--- tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes b/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes index 3a33590139..ce003fc535 100644 --- a/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes +++ b/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes @@ -15,9 +15,9 @@ Module { "dumper.Versions/Versions 1.0", "dumper.Versions/Versions 1.1" ] - exportMetaObjectRevisions: [0, 1] + exportMetaObjectRevisions: [0, 65281] Property { name: "foo"; type: "int" } - Property { name: "bar"; revision: 1; type: "int" } - Property { name: "baz"; revision: 2; type: "int" } + Property { name: "bar"; revision: 65281; type: "int" } + Property { name: "baz"; revision: 65282; type: "int" } } } diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index 25a448a97f..2e040eec18 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -168,7 +168,7 @@ void tst_qqmlpropertycache::revisionedProperties() QQmlRefPointer cacheWithoutVersion(new QQmlPropertyCache(metaObject), QQmlRefPointer::Adopt); QQmlRefPointer cacheWithVersion( - new QQmlPropertyCache(metaObject, QTypeRevision::fromEncodedVersion(1)), + new QQmlPropertyCache(metaObject, QTypeRevision::fromMinorVersion(1)), QQmlRefPointer::Adopt); QQmlPropertyData *data; -- cgit v1.2.3 From 751e92d50a23d1273af42a7a7836bb2eb336eced Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 13 Feb 2020 19:03:40 +0100 Subject: V4 Debugger: Properly set up context object for expressions We need to use the object in question as context object in order to access its properties. Otherwise we can only access the context properties and, incidentally, the root scope's properties. The latter is why the test didn't fail. Fixes: QTBUG-82150 Change-Id: I1f18f9e78dd61786310fd75e0695929522a4c90c Reviewed-by: Simon Hausmann --- tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml | 4 ++++ tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'tests') diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml index deba24cf91..a7231df48b 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml @@ -36,5 +36,9 @@ Item { } id: root property int a: 10 + + Item { + property int b: 11 + } } diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 3f424d16f2..91470e0651 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -896,6 +896,16 @@ void tst_QQmlDebugJS::evaluateInContext() QVERIFY(waitForClientSignal(SIGNAL(result()))); QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 20); + + auto childObjects = object.children; + QVERIFY(childObjects.count() > 0); // QQmlComponentAttached is also in there + QCOMPARE(childObjects[0].className, QString::fromLatin1("Item")); + + // "b" accessible in context of surrounding (child) object + m_client->evaluate(QLatin1String("b"), -1, childObjects[0].debugId); + QVERIFY(waitForClientSignal(SIGNAL(result()))); + + QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 11); } void tst_QQmlDebugJS::getScripts() -- cgit v1.2.3 From 7e7efc0dbbfdc396b3e890df59a56fe906f5bb11 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 18 Feb 2020 09:42:58 +0100 Subject: Blacklist tst_qquickmousearea::pressOneAndTapAnother on OpenSuse Task-number: QTBUG-82282 Change-Id: I4794bea023f45b3bdac2f19a68550c7116a49fa2 Reviewed-by: Fabian Kosmale --- tests/auto/quick/qquickmousearea/BLACKLIST | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST index f2cb00225b..6e0665271c 100644 --- a/tests/auto/quick/qquickmousearea/BLACKLIST +++ b/tests/auto/quick/qquickmousearea/BLACKLIST @@ -2,3 +2,7 @@ [nestedStopAtBounds] opensuse-leap +# QTBUG-82282 +[pressOneAndTapAnother] +opensuse-leap + -- cgit v1.2.3 From 872dc18e653b50c878699a78ca7cb9399cb47b62 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Mon, 3 Feb 2020 15:02:31 +0100 Subject: Quick: Don't qualify OpenGL includes (part two) 406f15ce0e only removed the "QtGui" prefix from some includes, but we are trying to move (almost) everything OpenGL related from QtGui. This removes prefixes for additional QOpenGL includes (QOpenGLShaderProgram, versioned opengl functions etc.). Task-number: QTBUG-74409 Change-Id: I91e1feac0676859f11de9b75301a0a4e81db50d9 Reviewed-by: Simon Hausmann --- tests/auto/quick/drawingmodes/tst_drawingmodes.cpp | 2 +- tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp | 4 ++-- .../quick/qquickframebufferobject/tst_qquickframebufferobject.cpp | 6 +++--- tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp | 2 +- tests/auto/quick/qquickitem/tst_qquickitem.cpp | 3 +++ tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp | 4 ++-- tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp | 2 +- tests/auto/quick/rendernode/tst_rendernode.cpp | 4 ++-- 8 files changed, 15 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp index 9bcc21c77d..39f4c3c70a 100644 --- a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp +++ b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include "../../shared/util.h" diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp index 9f616c56e2..47d6008c28 100644 --- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp +++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp @@ -34,8 +34,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp index 6aff66d61e..2327270b0f 100644 --- a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp +++ b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp @@ -30,9 +30,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp index 4da6da6043..aff081c4a8 100644 --- a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp +++ b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp @@ -36,7 +36,7 @@ #include "../../shared/util.h" #if QT_CONFIG(opengl) -#include +#include #include #endif diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index 8aab13e095..ac8c599cc9 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -34,6 +34,9 @@ #include "private/qquickfocusscope_p.h" #include "private/qquickitem_p.h" #include +#ifdef Q_OS_WIN +#include +#endif #include #include #include diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 2f90632841..b45aa5d61c 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -31,8 +31,8 @@ #include #include #include -#include -#include +#include +#include #include "../../shared/util.h" diff --git a/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp b/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp index 3bf61e8f17..a4cbaa453d 100644 --- a/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp +++ b/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include "../../shared/util.h" diff --git a/tests/auto/quick/rendernode/tst_rendernode.cpp b/tests/auto/quick/rendernode/tst_rendernode.cpp index e75e9e30b9..961531db6d 100644 --- a/tests/auto/quick/rendernode/tst_rendernode.cpp +++ b/tests/auto/quick/rendernode/tst_rendernode.cpp @@ -30,8 +30,8 @@ #include #include -#include -#include +#include +#include #include #include -- cgit v1.2.3 From d89dde522a67f6fb01f9879f45871efed5e35793 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 17 Feb 2020 14:50:09 +0100 Subject: Fix deprecation warning against QDateTime(QDate) Change-Id: Iaba4d9f1ea4b265326a8d1b07573b0f30b4d7428 Reviewed-by: Friedemann Kleint Reviewed-by: Qt CI Bot --- tests/auto/qml/qjsengine/tst_qjsengine.cpp | 8 ++++---- tests/auto/qml/qjsvalue/tst_qjsvalue.cpp | 12 ++++++------ tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 7b59087a72..aeb0303899 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -3342,7 +3342,7 @@ void tst_QJSEngine::dateRoundtripJSQtJS() #ifdef Q_OS_WIN QSKIP("This test fails on Windows due to a bug in QDateTime."); #endif - qint64 secs = QDateTime(QDate(2009, 1, 1)).toUTC().toSecsSinceEpoch(); + qint64 secs = QDate(2009, 1, 1).startOfDay(Qt::UTC).toSecsSinceEpoch(); QJSEngine eng; for (int i = 0; i < 8000; ++i) { QJSValue jsDate = eng.evaluate(QString::fromLatin1("new Date(%0)").arg(secs * 1000.0)); @@ -3359,7 +3359,7 @@ void tst_QJSEngine::dateRoundtripQtJSQt() #ifdef Q_OS_WIN QSKIP("This test fails on Windows due to a bug in QDateTime."); #endif - QDateTime qtDate = QDateTime(QDate(2009, 1, 1)); + QDateTime qtDate = QDate(2009, 1, 1).startOfDay(); QJSEngine eng; for (int i = 0; i < 8000; ++i) { QJSValue jsDate = eng.toScriptValue(qtDate); @@ -3375,7 +3375,7 @@ void tst_QJSEngine::dateConversionJSQt() #ifdef Q_OS_WIN QSKIP("This test fails on Windows due to a bug in QDateTime."); #endif - qint64 secs = QDateTime(QDate(2009, 1, 1)).toUTC().toSecsSinceEpoch(); + qint64 secs = QDate(2009, 1, 1).startOfDay(Qt::UTC).toSecsSinceEpoch(); QJSEngine eng; for (int i = 0; i < 8000; ++i) { QJSValue jsDate = eng.evaluate(QString::fromLatin1("new Date(%0)").arg(secs * 1000.0)); @@ -3391,7 +3391,7 @@ void tst_QJSEngine::dateConversionJSQt() void tst_QJSEngine::dateConversionQtJS() { - QDateTime qtDate = QDateTime(QDate(2009, 1, 1)); + QDateTime qtDate = QDate(2009, 1, 1).startOfDay(); QJSEngine eng; for (int i = 0; i < 8000; ++i) { QJSValue jsDate = eng.toScriptValue(qtDate); diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index b561e5f398..0d0bd2ae7e 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -1067,7 +1067,7 @@ void tst_QJSValue::toVariant() } { - QDateTime dateTime = QDateTime(QDate(1980, 10, 4)); + QDateTime dateTime = QDate(1980, 10, 4).startOfDay(); QJSValue dateObject = eng.toScriptValue(dateTime); QVariant var = dateObject.toVariant(); QCOMPARE(var, QVariant(dateTime)); @@ -1222,7 +1222,7 @@ void tst_QJSValue::toDateTime() QDateTime dt = eng.evaluate("new Date(0)").toDateTime(); QVERIFY(dt.isValid()); QCOMPARE(dt.timeSpec(), Qt::LocalTime); - QCOMPARE(dt.toUTC(), QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::UTC)); + QCOMPARE(dt.toUTC(), QDate(1970, 1, 1).startOfDay(Qt::UTC)); QVERIFY(!eng.evaluate("[]").toDateTime().isValid()); QVERIFY(!eng.evaluate("{}").toDateTime().isValid()); @@ -2145,8 +2145,8 @@ void tst_QJSValue::equals() QCOMPARE(str2.equals(QJSValue(321)), false); QCOMPARE(str2.equals(QJSValue()), false); - QJSValue date1 = eng.toScriptValue(QDateTime(QDate(2000, 1, 1))); - QJSValue date2 = eng.toScriptValue(QDateTime(QDate(1999, 1, 1))); + QJSValue date1 = eng.toScriptValue(QDate(2000, 1, 1).startOfDay()); + QJSValue date2 = eng.toScriptValue(QDate(1999, 1, 1).startOfDay()); QCOMPARE(date1.equals(date2), false); QCOMPARE(date1.equals(date1), true); QCOMPARE(date2.equals(date2), true); @@ -2278,8 +2278,8 @@ void tst_QJSValue::strictlyEquals() QCOMPARE(str2.strictlyEquals(QJSValue(321)), false); QVERIFY(!str2.strictlyEquals(QJSValue())); - QJSValue date1 = eng.toScriptValue(QDateTime(QDate(2000, 1, 1))); - QJSValue date2 = eng.toScriptValue(QDateTime(QDate(1999, 1, 1))); + QJSValue date1 = eng.toScriptValue(QDate(2000, 1, 1).startOfDay()); + QJSValue date2 = eng.toScriptValue(QDate(1999, 1, 1).startOfDay()); QCOMPARE(date1.strictlyEquals(date2), false); QCOMPARE(date1.strictlyEquals(date1), true); QCOMPARE(date2.strictlyEquals(date2), true); diff --git a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp index ea157a7d15..b21d2a908d 100644 --- a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp +++ b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp @@ -112,9 +112,9 @@ void tst_QQmlMetaObject::property_data() QTest::newRow("date") << "property.date.qml" << QByteArray("QDateTime") << int(QMetaType::QDateTime) << false // default - << QVariant(QDateTime(QDate(2012, 2, 7))) + << QVariant(QDate(2012, 2, 7).startOfDay()) << true // writable - << QVariant(QDateTime(QDate(2010, 7, 2))); + << QVariant(QDate(2010, 7, 2).startOfDay()); QTest::newRow("variant") << "property.variant.qml" << QByteArray("QVariant") << int(QMetaType::QVariant) << true // default -- cgit v1.2.3 From e33e250080dbbb01015daafc8a79b569806d9467 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 17 Jan 2020 10:46:54 +0100 Subject: Fix all import versions Bump all the *.15 versions to QT_VERSION and use QML_IMPORT_VERSION rather than IMPORT_VERSION. Change-Id: I5bfbc960d119a7386bdcedb9bdbfdbfa4486a187 Reviewed-by: Fabian Kosmale Reviewed-by: Mitch Curtis --- tests/auto/qml/qqmlengine/data/qtqmlModule.10.qml | 4 ++++ tests/auto/qml/qqmlengine/tst_qqmlengine.cpp | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 tests/auto/qml/qqmlengine/data/qtqmlModule.10.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmlengine/data/qtqmlModule.10.qml b/tests/auto/qml/qqmlengine/data/qtqmlModule.10.qml new file mode 100644 index 0000000000..3fc0cc217d --- /dev/null +++ b/tests/auto/qml/qqmlengine/data/qtqmlModule.10.qml @@ -0,0 +1,4 @@ +import QtQml 6.50 + +QtObject { +} diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index cfbbd2a94c..0081243a88 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -687,9 +687,9 @@ void tst_qqmlengine::qtqmlModule_data() << QString(testFileUrl("qtqmlModule.3.qml").toString() + QLatin1String(":1 module \"QtQml\" version 1.0 is not installed\n")) << QStringList(); - QTest::newRow("import QtQml of incorrect version (2.50)") + QTest::newRow("import QtQml of old version (2.50)") << testFileUrl("qtqmlModule.4.qml") - << QString(testFileUrl("qtqmlModule.4.qml").toString() + QLatin1String(":1 module \"QtQml\" version 2.50 is not installed\n")) + << QString() << QStringList(); QTest::newRow("QtQml 2.0 module provides Component, QtObject, Connections, Binding and Timer") @@ -716,6 +716,11 @@ void tst_qqmlengine::qtqmlModule_data() << testFileUrl("qtqmlModule.9.qml") << QString(testFileUrl("qtqmlModule.9.qml").toString() + QLatin1String(":4 Item is not a type\n")) << QStringList(); + + QTest::newRow("import QtQml of incorrect version (6.50)") + << testFileUrl("qtqmlModule.10.qml") + << QString(testFileUrl("qtqmlModule.10.qml").toString() + QLatin1String(":1 module \"QtQml\" version 6.50 is not installed\n")) + << QStringList(); } // Test that the engine registers the QtQml module -- cgit v1.2.3 From add46fd9055088e6aa458f21558234e267eb60ca Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 18 Feb 2020 09:20:13 +0100 Subject: ResolvedList: attempt read from correct meta object Fixes: QTBUG-82171 Change-Id: If14b10d703aa1b69cd697024ada2fae0453103d7 Reviewed-by: Ulf Hermann Reviewed-by: Aleix Pol Gonzalez --- tests/auto/qml/qqmllanguage/data/Action.qml | 21 +++++++++++++++++++++ .../qml/qqmllanguage/data/listPropertiesChild.qml | 7 +++++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 11 +++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/auto/qml/qqmllanguage/data/Action.qml create mode 100644 tests/auto/qml/qqmllanguage/data/listPropertiesChild.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmllanguage/data/Action.qml b/tests/auto/qml/qqmllanguage/data/Action.qml new file mode 100644 index 0000000000..4db2bacf6e --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/Action.qml @@ -0,0 +1,21 @@ +import QtQuick 2.12 + +QtObject { + id:root + property Item parent + property Item displayComponent: null + + property list children + + readonly property var visibleChildren: { + var visible = []; + var child; + for (var i in children) { + child = children[i]; + if (!child.hasOwnProperty("visible") || child.visible) { + visible.push(child) + } + } + return visible; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/listPropertiesChild.qml b/tests/auto/qml/qqmllanguage/data/listPropertiesChild.qml new file mode 100644 index 0000000000..b1635a9409 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/listPropertiesChild.qml @@ -0,0 +1,7 @@ +import QtQuick 2.12 + +Action +{ + id: action + property color color +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 2112e0cffb..bd23806e3a 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -123,6 +123,7 @@ private slots: void dynamicProperties(); void dynamicPropertiesNested(); void listProperties(); + void listPropertiesInheritanceNoCrash(); void badListItemType(); void dynamicObjectProperties(); void dynamicSignalsAndSlots(); @@ -1491,6 +1492,16 @@ void tst_qqmllanguage::listProperties() QCOMPARE(object->property("test").toInt(), 2); } +// Tests that initializing list properties of a base class does not crash +// (QTBUG-82171) +void tst_qqmllanguage::listPropertiesInheritanceNoCrash() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("listPropertiesChild.qml")); + QScopedPointer object(component.create()); // should not crash + QVERIFY(object != nullptr); +} + void tst_qqmllanguage::badListItemType() { QQmlComponent component(&engine, testFileUrl("badListItemType.qml")); -- cgit v1.2.3 From 9e5376327fb258e1c0207c2d6b6a2f9254f5b3ee Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Wed, 19 Feb 2020 17:17:59 +0300 Subject: Escape url.toString() before passing it to QRegularExpression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise the test fails when path contains special characters like ‘+’. Change-Id: I461d9755436148ce979284be31ef8d204235c8a4 Reviewed-by: Ulf Hermann --- tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp index 5e855efe1a..2bee283826 100644 --- a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp +++ b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp @@ -302,7 +302,8 @@ void tst_qqmlapplicationengine::failureToLoadTriggersWarningSignal() auto url = testFileUrl("invalid.qml"); qRegisterMetaType>(); QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QQmlApplicationEngine failed to load component"); - QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression(url.toString() + QLatin1Char('*'))); + QTest::ignoreMessage(QtMsgType::QtWarningMsg, + QRegularExpression(QRegularExpression::escape(url.toString()) + QLatin1Char('*'))); QQmlApplicationEngine test; QSignalSpy warningObserver(&test, &QQmlApplicationEngine::warnings); test.load(url); -- cgit v1.2.3 From 11ff5c314682258b6eb26e90847210662eb0f533 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 12 Feb 2020 17:49:31 +0100 Subject: Provide a way to statically register namespaces Previously, qmltyperegistrar would stumble over any QML_* macros in namespaces, as the namespaces could not be used as template arguments. However, namespaces are intended to be usable by QML as uncreatable "types". Now, qmltyperegistrar checks the namespace flag that moc records in the JSON output, and if that is given, registers an uncreatable metaobject instead of a type. Therefore you can use QML_ELEMENT and friends to register namespaces, just like you would register classes (except that they're implicitly uncreatable, of course). Task-number: QTBUG-68796 Change-Id: I186d7e9425471c32fb1a1f29c0c0b946afb2a9d2 Reviewed-by: Fabian Kosmale --- .../qml/qqmllanguage/data/cppstaticnamespace.2.qml | 5 +++ .../qml/qqmllanguage/data/cppstaticnamespace.qml | 6 ++++ tests/auto/qml/qqmllanguage/qqmllanguage.pro | 5 ++- tests/auto/qml/qqmllanguage/testtypes.h | 41 ++++++++++++++++++++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 31 ++++++++++------ 5 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml create mode 100644 tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml new file mode 100644 index 0000000000..3b37c29b18 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml @@ -0,0 +1,5 @@ +import StaticTest 1.0 + +MyStaticSecondNamespacedType { + list: [ MyStaticNamespacedType {} ] +} diff --git a/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml new file mode 100644 index 0000000000..2778baadb9 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml @@ -0,0 +1,6 @@ +import StaticTest 1.0 + +MyStaticNamespacedType { + myEnum: MyStaticNamespace.Key5 + property int intProperty: MyStaticNamespace.MyOtherNSEnum.OtherKey2 +} diff --git a/tests/auto/qml/qqmllanguage/qqmllanguage.pro b/tests/auto/qml/qqmllanguage/qqmllanguage.pro index 724a27320c..6c54525544 100644 --- a/tests/auto/qml/qqmllanguage/qqmllanguage.pro +++ b/tests/auto/qml/qqmllanguage/qqmllanguage.pro @@ -1,4 +1,7 @@ -CONFIG += testcase +CONFIG += testcase qmltypes +QML_IMPORT_NAME = StaticTest +QML_IMPORT_VERSION = 1.0 + TARGET = tst_qqmllanguage macx:CONFIG -= app_bundle diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 148179cb9c..8852bf7af9 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -750,6 +750,47 @@ private: bool m_ownRWObj; }; +namespace MyStaticNamespace { + Q_NAMESPACE + QML_ELEMENT + + enum MyNSEnum { + Key1 = 1, + Key2, + Key5 = 5 + }; + Q_ENUM_NS(MyNSEnum); + + enum class MyOtherNSEnum { + OtherKey1 = 1, + OtherKey2 + }; + Q_ENUM_NS(MyOtherNSEnum); + + + class MyNamespacedType : public QObject + { + Q_OBJECT + Q_PROPERTY(MyStaticNamespace::MyNSEnum myEnum MEMBER m_myEnum) + QML_NAMED_ELEMENT(MyStaticNamespacedType) + MyStaticNamespace::MyNSEnum m_myEnum = MyNSEnum::Key1; + }; + + class MySecondNamespacedType : public QObject + { + Q_OBJECT + Q_PROPERTY(QQmlListProperty list READ list) + QML_NAMED_ELEMENT(MyStaticSecondNamespacedType) + public: + QQmlListProperty list() + { + return QQmlListProperty(this, &m_list); + } + + private: + QList m_list; + }; +} namespace MyNamespace { Q_NAMESPACE diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index bd23806e3a..4d4056ba3f 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -1858,21 +1858,30 @@ void tst_qqmllanguage::valueTypes() void tst_qqmllanguage::cppnamespace() { - { - QQmlComponent component(&engine, testFileUrl("cppnamespace.qml")); + QScopedPointer object; + + auto create = [&](const char *file) { + QQmlComponent component(&engine, testFileUrl(file)); VERIFY_ERRORS(0); - QScopedPointer object(component.create()); + object.reset(component.create()); QVERIFY(object != nullptr); + }; - QCOMPARE(object->property("intProperty").toInt(), (int)MyNamespace::MyOtherNSEnum::OtherKey2); - } + auto createAndCheck = [&](const char *file) { + create(file); + return !QTest::currentTestFailed(); + }; - { - QQmlComponent component(&engine, testFileUrl("cppnamespace.2.qml")); - VERIFY_ERRORS(0); - QScopedPointer object(component.create()); - QVERIFY(object != nullptr); - } + QVERIFY(createAndCheck("cppnamespace.qml")); + QCOMPARE(object->property("intProperty").toInt(), + (int)MyNamespace::MyOtherNSEnum::OtherKey2); + + QVERIFY(createAndCheck("cppstaticnamespace.qml")); + QCOMPARE(object->property("intProperty").toInt(), + (int)MyStaticNamespace::MyOtherNSEnum::OtherKey2); + + QVERIFY(createAndCheck("cppnamespace.2.qml")); + QVERIFY(createAndCheck("cppstaticnamespace.2.qml")); } void tst_qqmllanguage::aliasProperties() -- cgit v1.2.3 From 685d2ca3c7a9f221ac12f6db61e02bab40371f5f Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 14 Feb 2020 13:56:59 +0100 Subject: Propagate the LanguageChange events from the QQuickWindow to the items Fixes: QTBUG-78141 Task-number: QTBUG-82020 Change-Id: Id47f8efe77cd3f6bfd330c8759059e19de5a86d2 Reviewed-by: Shawn Rutledge --- tests/auto/quick/qquickitem/data/hellotr_la.qm | Bin 0 -> 237 bytes tests/auto/quick/qquickitem/tst_qquickitem.cpp | 35 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/auto/quick/qquickitem/data/hellotr_la.qm (limited to 'tests') diff --git a/tests/auto/quick/qquickitem/data/hellotr_la.qm b/tests/auto/quick/qquickitem/data/hellotr_la.qm new file mode 100644 index 0000000000..25c0aad583 Binary files /dev/null and b/tests/auto/quick/qquickitem/data/hellotr_la.qm differ diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index 8aab13e095..b5e001a2b7 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -40,6 +40,7 @@ #include "../../shared/util.h" #include "../shared/viewtestutil.h" #include +#include #ifdef TEST_QTBUG_60123 #include @@ -70,6 +71,7 @@ public: ulong timestamp; QPoint lastWheelEventPos; QPoint lastWheelEventGlobalPos; + int languageChangeEventCount = 0; protected: virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; } virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; } @@ -86,6 +88,12 @@ protected: lastWheelEventPos = event->position().toPoint(); lastWheelEventGlobalPos = event->globalPosition().toPoint(); } + bool event(QEvent *e) override + { + if (e->type() == QEvent::LanguageChange) + languageChangeEventCount++; + return QQuickItem::event(e); + } }; class TestWindow: public QQuickWindow @@ -198,6 +206,7 @@ private slots: #endif void setParentCalledInOnWindowChanged(); + void receivesLanguageChangeEvent(); private: @@ -2155,6 +2164,32 @@ void tst_qquickitem::setParentCalledInOnWindowChanged() QVERIFY(ensureFocus(&view)); // should not crash } +void tst_qquickitem::receivesLanguageChangeEvent() +{ + QQuickWindow window; + window.setFramePosition(QPoint(100, 100)); + window.resize(200, 200); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QScopedPointer child1(new TestItem); + child1->setObjectName(QStringLiteral("child1")); + child1->setSize(QSizeF(200, 100)); + child1->setParentItem(window.contentItem()); + + QScopedPointer child2(new TestItem); + child2->setObjectName(QStringLiteral("child2")); + child2->setSize(QSizeF(50, 50)); + child2->setParentItem(child1.data()); + + QTranslator t; + QVERIFY(t.load("hellotr_la.qm", dataDirectory())); + QVERIFY(QCoreApplication::installTranslator(&t)); + + QTRY_COMPARE(child1->languageChangeEventCount, 1); + QCOMPARE(child2->languageChangeEventCount, 1); +} + QTEST_MAIN(tst_qquickitem) #include "tst_qquickitem.moc" -- cgit v1.2.3 From 8dd18850714b9a8e7a51891a2c48f8ca94ffe014 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 25 Feb 2020 13:32:55 +0100 Subject: Revision properties and methods added in 5.15 Change-Id: I00e3f9535e819d9d0d547c9d3cf50be469cf9339 Reviewed-by: Fabian Kosmale --- tests/auto/qml/qquickworkerscript/data/BaseWorker.qml | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/auto/qml/qquickworkerscript/data/BaseWorker.qml b/tests/auto/qml/qquickworkerscript/data/BaseWorker.qml index 59af114379..1d3420e186 100644 --- a/tests/auto/qml/qquickworkerscript/data/BaseWorker.qml +++ b/tests/auto/qml/qquickworkerscript/data/BaseWorker.qml @@ -1,4 +1,5 @@ import QtQuick 2.0 +import QtQml.WorkerScript 2.15 WorkerScript { id: worker -- cgit v1.2.3 From 639196d0939ab2ce4f42671682cdddc91fee58ac Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 27 Feb 2020 09:30:06 +0100 Subject: Robustify QQuickListView test We should check for the window's root item before accessing it. Change-Id: I196d9cb4d0e525ffb62b3fd347fd986033cab3dd Reviewed-by: Fabian Kosmale --- tests/auto/quick/qquicklistview/tst_qquicklistview.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index b141e235d5..49b68a8473 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -9867,6 +9867,7 @@ void tst_QQuickListView::reuse_checkThatItemsAreReused() window->resize(640, 480); window->show(); QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(window->rootObject() != nullptr); QQuickListView *listView = findItem(window->rootObject(), "list"); QTRY_VERIFY(listView != nullptr); -- cgit v1.2.3 From 8ab237edf170f5b0482dccf5169868e5c7c47771 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 27 Feb 2020 10:49:14 +0100 Subject: Restore offset/length in QQmlJS::DiagnosticMessage This is needed in a few places outside of declarative, so this change restores the loc member in DiagnosticMessage and moves QQmlJS::AST::SourceLocation into common's QQmlJS namespace/directory. QQmlError is unaffected and retains only line/column. Amends d4d197d06279f9257647628f7e1ccc9ec763a6bb Change-Id: Ifb9d344228e3c6e9e26fc4fe112686f9336ea2b2 Reviewed-by: Fabian Kosmale --- tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp | 8 ++++---- tests/auto/shared/qqmljsastdumper.cpp | 2 +- tests/auto/shared/qqmljsastdumper.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp index bc4ba9437c..7e96205743 100644 --- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp +++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp @@ -63,10 +63,10 @@ namespace { for (const QQmlJS::DiagnosticMessage &e : errors) { QString errorString = QLatin1String("qmldir"); - if (e.line > 0) { - errorString += QLatin1Char(':') + QString::number(e.line); - if (e.column > 0) - errorString += QLatin1Char(':') + QString::number(e.column); + if (e.loc.startLine > 0) { + errorString += QLatin1Char(':') + QString::number(e.loc.startLine); + if (e.loc.startColumn > 0) + errorString += QLatin1Char(':') + QString::number(e.loc.startColumn); } errorString += QLatin1String(": ") + e.message; diff --git a/tests/auto/shared/qqmljsastdumper.cpp b/tests/auto/shared/qqmljsastdumper.cpp index 8a50e021f6..5da6be6bd0 100644 --- a/tests/auto/shared/qqmljsastdumper.cpp +++ b/tests/auto/shared/qqmljsastdumper.cpp @@ -216,7 +216,7 @@ QString AstDumper::qs(const QStringRef &s) { return qs(s.toString()); } -QString AstDumper::loc(const AST::SourceLocation &s) { +QString AstDumper::loc(const SourceLocation &s) { if (noLocations() || !s.isValid()) return QLatin1String("\"\""); else { diff --git a/tests/auto/shared/qqmljsastdumper.h b/tests/auto/shared/qqmljsastdumper.h index d8d19e351d..5e46e516f0 100644 --- a/tests/auto/shared/qqmljsastdumper.h +++ b/tests/auto/shared/qqmljsastdumper.h @@ -91,7 +91,7 @@ public: QString qs(const char *s); QString qs(const QStringRef &s); - QString loc(const AST::SourceLocation &s); + QString loc(const SourceLocation &s); QString boolStr(bool v); -- cgit v1.2.3 From 744246b1129f6042c0264eb578a6e5c86e09f80a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 25 Feb 2020 16:10:40 +0100 Subject: Use Qt::SplitBehavior in preference to QString::SplitBehavior The Qt version was added in 5.14 "for use as eventual replacement for QString::SplitBehavior." Move another step cloaser to that goal. Change-Id: I3214ad6ccaca9dfd4a026589cabeb40cbf4a6298 Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 2a1457d818..4b0cbfa1aa 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -7304,7 +7304,7 @@ void tst_qqmlecmascript::forInLoop() QMetaObject::invokeMethod(object, "listProperty"); - QStringList r = object->property("listResult").toString().split("|", QString::SkipEmptyParts); + QStringList r = object->property("listResult").toString().split("|", Qt::SkipEmptyParts); QCOMPARE(r.size(), 3); QCOMPARE(r[0],QLatin1String("0=obj1")); QCOMPARE(r[1],QLatin1String("1=obj2")); -- cgit v1.2.3 From 254a56252874b63430701351dcd8c9bef8507353 Mon Sep 17 00:00:00 2001 From: Wang Chuan Date: Wed, 26 Feb 2020 21:14:50 +0800 Subject: QQuickItem: prevent endless loop in focus tab chain Since the commit a18ab2a3822e0d, we promote the [startItem] in focus tab chain when it is invisible to prevent endless loop. However the problem still happen if the [startItem] is equal to [firstFromItem] Fixes it by compare the [current] item with the original start item Fixes: QTBUG-81510 Change-Id: Iae0207f39e2b8c4fc6ed0cf36f0a855668accfba Reviewed-by: Mitch Curtis Reviewed-by: Liang Qi Reviewed-by: Shawn Rutledge --- .../qquickitem2/data/activeFocusOnTab_infiniteLoop2.qml | 12 ++++++++++++ tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 15 +++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop2.qml (limited to 'tests') diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop2.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop2.qml new file mode 100644 index 0000000000..042f408753 --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop2.qml @@ -0,0 +1,12 @@ +import QtQuick 2.14 + +Item { + width: 400 + height: 200 + Item { + objectName: "hiddenChild" + focus: true + activeFocusOnTab: true + visible: false + } +} diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 399535cfa6..767994ec7d 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -64,6 +64,7 @@ private slots: void activeFocusOnTab8(); void activeFocusOnTab9(); void activeFocusOnTab10(); + void activeFocusOnTab_infiniteLoop_data(); void activeFocusOnTab_infiniteLoop(); void nextItemInFocusChain(); @@ -1025,12 +1026,20 @@ void tst_QQuickItem::activeFocusOnTab10() delete window; } +void tst_QQuickItem::activeFocusOnTab_infiniteLoop_data() +{ + QTest::addColumn("source"); + QTest::newRow("infiniteLoop") << testFileUrl("activeFocusOnTab_infiniteLoop.qml"); // QTBUG-68271 + QTest::newRow("infiniteLoop2") << testFileUrl("activeFocusOnTab_infiniteLoop2.qml");// QTBUG-81510 +} + void tst_QQuickItem::activeFocusOnTab_infiniteLoop() { - // see QTBUG-68271 + QFETCH(QUrl, source); + // create a window where the currently focused item is not visible QScopedPointerwindow(new QQuickView()); - window->setSource(testFileUrl("activeFocusOnTab_infiniteLoop.qml")); + window->setSource(source); window->show(); auto *hiddenChild = findItem(window->rootObject(), "hiddenChild"); QVERIFY(hiddenChild); @@ -1039,6 +1048,8 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop() auto *item = hiddenChild->nextItemInFocusChain(); // focus is moved to the root object since there is no other candidate QCOMPARE(item, window->rootObject()); + item = hiddenChild->nextItemInFocusChain(false); + QCOMPARE(item, window->rootObject()); } void tst_QQuickItem::nextItemInFocusChain() -- cgit v1.2.3 From eacb1a08ee4dace7c12a6eed153b9ec69cf95966 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 28 Feb 2020 15:28:39 +0100 Subject: Stop using Qt::DateFormat's locale-dependent members They're going away on dev. Amended tests to match. Task-number: QTBUG-80441 Change-Id: I00540d2f7a796ae9c080a0fb9f144c145f00ad57 Reviewed-by: Simon Hausmann Reviewed-by: Qt CI Bot --- tests/auto/qml/qqmlqt/data/formatting.qml | 8 +- tests/auto/qml/qqmlqt/tst_qqmlqt.cpp | 136 ++++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 32 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmlqt/data/formatting.qml b/tests/auto/qml/qqmlqt/data/formatting.qml index f2d1e1b5c8..14af9ba88b 100644 --- a/tests/auto/qml/qqmlqt/data/formatting.qml +++ b/tests/auto/qml/qqmlqt/data/formatting.qml @@ -1,4 +1,4 @@ -import QtQuick 2.0 +import QtQuick 2.15 QtObject { property date dateFromString: "2008-12-24" @@ -8,7 +8,7 @@ QtObject { var v = eval(prop) return [ Qt.formatDate(v), - Qt.formatDate(v, Qt.DefaultLocaleLongDate), + Qt.formatDate(v, Qt.locale(), Locale.LongFormat), Qt.formatDate(v, "ddd MMMM d yy") ] } @@ -17,7 +17,7 @@ QtObject { var v = eval(prop) return [ Qt.formatTime(v), - Qt.formatTime(v, Qt.DefaultLocaleLongDate), + Qt.formatTime(v, Qt.locale(), Locale.LongFormat), Qt.formatTime(v, "H:m:s a"), Qt.formatTime(v, "hh:mm:ss.zzz") ] @@ -27,7 +27,7 @@ QtObject { var v = eval(prop) return [ Qt.formatDateTime(v), - Qt.formatDateTime(v, Qt.DefaultLocaleLongDate), + Qt.formatDateTime(v, Qt.locale(), Locale.LongFormat), Qt.formatDateTime(v, "M/d/yy H:m:s a") ] } diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index 4a2e6841e7..60ee2a4d1c 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -774,8 +774,6 @@ void tst_qqmlqt::dateTimeFormatting() void tst_qqmlqt::dateTimeFormatting_data() { - QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED - // Test intentionally uses deprecated enumerators from Qt::DateFormat QTest::addColumn("method"); QTest::addColumn("inputProperties"); QTest::addColumn("expectedResults"); @@ -787,25 +785,24 @@ void tst_qqmlqt::dateTimeFormatting_data() QTest::newRow("formatDate") << "formatDate" << (QStringList() << "dateFromString" << "jsdate" << "qdate" << "qdatetime") - << (QStringList() << date.toString(Qt::DefaultLocaleShortDate) - << date.toString(Qt::DefaultLocaleLongDate) + << (QStringList() << QLocale().toString(date, QLocale::ShortFormat) + << QLocale().toString(date, QLocale::LongFormat) << date.toString("ddd MMMM d yy")); QTest::newRow("formatTime") << "formatTime" << (QStringList() << "jsdate" << "qtime" << "qdatetime") - << (QStringList() << time.toString(Qt::DefaultLocaleShortDate) - << time.toString(Qt::DefaultLocaleLongDate) + << (QStringList() << QLocale().toString(time, QLocale::ShortFormat) + << QLocale().toString(time, QLocale::LongFormat) << time.toString("H:m:s a") << time.toString("hh:mm:ss.zzz")); QTest::newRow("formatDateTime") << "formatDateTime" << (QStringList() << "jsdate" << "qdatetime") - << (QStringList() << dateTime.toString(Qt::DefaultLocaleShortDate) - << dateTime.toString(Qt::DefaultLocaleLongDate) + << (QStringList() << QLocale().toString(dateTime, QLocale::ShortFormat) + << QLocale().toString(dateTime, QLocale::LongFormat) << dateTime.toString("M/d/yy H:m:s a")); - QT_WARNING_POP } void tst_qqmlqt::dateTimeFormattingVariants() @@ -844,8 +841,6 @@ void tst_qqmlqt::dateTimeFormattingVariants() void tst_qqmlqt::dateTimeFormattingVariants_data() { - QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED - // Test intentionally uses deprecated enumerators from Qt::DateFormat QTest::addColumn("method"); QTest::addColumn("variant"); QTest::addColumn("expectedResults"); @@ -854,39 +849,124 @@ void tst_qqmlqt::dateTimeFormattingVariants_data() QTime time(11, 16, 39, 755); temporary = QDateTime(QDate(1970,1,1), time); - 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")); + QTest::newRow("formatTime, qtime") + << "formatTime" << QVariant::fromValue(time) + << (QStringList() + << QLocale().toString(temporary.time(), QLocale::ShortFormat) + << QLocale().toString(temporary.time(), QLocale::LongFormat) + << temporary.time().toString("H:m:s a") + << temporary.time().toString("hh:mm:ss.zzz")); QDate date(2011,5,31); // 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")); + QTest::newRow("formatDate, qdate") + << "formatDate" << QVariant::fromValue(date) + << (QStringList() + << QLocale().toString(temporary.date(), QLocale::ShortFormat) + << QLocale().toString(temporary.date(), QLocale::LongFormat) + << temporary.date().toString("ddd MMMM d yy")); + QTest::newRow("formatDateTime, qdate") + << "formatDateTime" << QVariant::fromValue(date) + << (QStringList() + << QLocale().toString(temporary, QLocale::ShortFormat) + << QLocale().toString(temporary, QLocale::LongFormat) + << temporary.toString("M/d/yy H:m:s a")); + QTest::newRow("formatTime, qdate") + << "formatTime" << QVariant::fromValue(date) + << (QStringList() + << QLocale().toString(temporary.time(), QLocale::ShortFormat) + << QLocale().toString(temporary.time(), QLocale::LongFormat) + << temporary + .time().toString("H:m:s a") << temporary.time().toString("hh:mm:ss.zzz")); QDateTime dateTime(date, time); temporary = dateTime; - QTest::newRow("formatDate, qdatetime") << "formatDate" << QVariant::fromValue(dateTime) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy")); - QTest::newRow("formatDateTime, qdatetime") << "formatDateTime" << QVariant::fromValue(dateTime) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a")); - QTest::newRow("formatTime, qdatetime") << "formatTime" << QVariant::fromValue(dateTime) << (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")); + QTest::newRow("formatDate, qdatetime") + << "formatDate" << QVariant::fromValue(dateTime) + << (QStringList() + << QLocale().toString(temporary.date(), QLocale::ShortFormat) + << QLocale().toString(temporary.date(), QLocale::LongFormat) + << temporary.date().toString("ddd MMMM d yy")); + QTest::newRow("formatDateTime, qdatetime") + << "formatDateTime" << QVariant::fromValue(dateTime) + << (QStringList() + << QLocale().toString(temporary, QLocale::ShortFormat) + << QLocale().toString(temporary, QLocale::LongFormat) + << temporary.toString("M/d/yy H:m:s a")); + QTest::newRow("formatTime, qdatetime") + << "formatTime" << QVariant::fromValue(dateTime) + << (QStringList() + << QLocale().toString(temporary.time(), QLocale::ShortFormat) + << QLocale().toString(temporary.time(), QLocale::LongFormat) + << temporary.time().toString("H:m:s a") + << temporary.time().toString("hh:mm:ss.zzz")); QString string(QLatin1String("2011/05/31 11:16:39.755")); temporary = QDateTime::fromString(string, "yyyy/MM/dd HH:mm:ss.zzz"); - QTest::newRow("formatDate, qstring") << "formatDate" << QVariant::fromValue(string) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy")); - QTest::newRow("formatDateTime, qstring") << "formatDateTime" << QVariant::fromValue(string) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a")); - QTest::newRow("formatTime, qstring") << "formatTime" << QVariant::fromValue(string) << (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")); + QTest::newRow("formatDate, qstring") + << "formatDate" << QVariant::fromValue(string) + << (QStringList() + << QLocale().toString(temporary.date(), QLocale::ShortFormat) + << QLocale().toString(temporary.date(), QLocale::LongFormat) + << temporary.date().toString("ddd MMMM d yy")); + QTest::newRow("formatDateTime, qstring") + << "formatDateTime" << QVariant::fromValue(string) + << (QStringList() + << QLocale().toString(temporary, QLocale::ShortFormat) + << QLocale().toString(temporary, QLocale::LongFormat) + << temporary.toString("M/d/yy H:m:s a")); + QTest::newRow("formatTime, qstring") + << "formatTime" << QVariant::fromValue(string) + << (QStringList() + << QLocale().toString(temporary.time(), QLocale::ShortFormat) + << QLocale().toString(temporary.time(), QLocale::LongFormat) + << temporary.time().toString("H:m:s a") + << temporary.time().toString("hh:mm:ss.zzz")); QColor color(Qt::red); temporary = QVariant::fromValue(color).toDateTime(); - QTest::newRow("formatDate, qcolor") << "formatDate" << QVariant::fromValue(color) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy")); - QTest::newRow("formatDateTime, qcolor") << "formatDateTime" << QVariant::fromValue(color) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a")); - QTest::newRow("formatTime, qcolor") << "formatTime" << QVariant::fromValue(color) << (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")); + QTest::newRow("formatDate, qcolor") + << "formatDate" << QVariant::fromValue(color) + << (QStringList() + << QLocale().toString(temporary.date(), QLocale::ShortFormat) + << QLocale().toString(temporary.date(), QLocale::LongFormat) + << temporary.date().toString("ddd MMMM d yy")); + QTest::newRow("formatDateTime, qcolor") + << "formatDateTime" << QVariant::fromValue(color) + << (QStringList() + << QLocale().toString(temporary, QLocale::ShortFormat) + << QLocale().toString(temporary, QLocale::LongFormat) + << temporary.toString("M/d/yy H:m:s a")); + QTest::newRow("formatTime, qcolor") + << "formatTime" << QVariant::fromValue(color) + << (QStringList() + << QLocale().toString(temporary.time(), QLocale::ShortFormat) + << QLocale().toString(temporary.time(), QLocale::LongFormat) + << temporary.time().toString("H:m:s a") + << temporary.time().toString("hh:mm:ss.zzz")); int integer(4); temporary = QVariant::fromValue(integer).toDateTime(); - QTest::newRow("formatDate, int") << "formatDate" << QVariant::fromValue(integer) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy")); - QTest::newRow("formatDateTime, int") << "formatDateTime" << QVariant::fromValue(integer) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a")); - QTest::newRow("formatTime, int") << "formatTime" << QVariant::fromValue(integer) << (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")); - QT_WARNING_POP + QTest::newRow("formatDate, int") + << "formatDate" << QVariant::fromValue(integer) + << (QStringList() + << QLocale().toString(temporary.date(), QLocale::ShortFormat) + << QLocale().toString(temporary.date(), QLocale::LongFormat) + << temporary.date().toString("ddd MMMM d yy")); + QTest::newRow("formatDateTime, int") + << "formatDateTime" << QVariant::fromValue(integer) + << (QStringList() + << QLocale().toString(temporary, QLocale::ShortFormat) + << QLocale().toString(temporary, QLocale::LongFormat) + << temporary.toString("M/d/yy H:m:s a")); + QTest::newRow("formatTime, int") + << "formatTime" << QVariant::fromValue(integer) + << (QStringList() + << QLocale().toString(temporary.time(), QLocale::ShortFormat) + << QLocale().toString(temporary.time(), QLocale::LongFormat) + << temporary.time().toString("H:m:s a") + << temporary.time().toString("hh:mm:ss.zzz")); } void tst_qqmlqt::dateTimeFormattingWithLocale() -- cgit v1.2.3 From f3dccc334f01d088fcdf1c2016c8153fe6154b61 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 7 Jan 2020 11:37:01 +0100 Subject: Adapt to the the new QMetaType change Fixes: QTBUG-82453 Change-Id: I7e5682945a07c3af183becd3947a69568f139d16 Reviewed-by: Fabian Kosmale --- tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 6 +-- tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp | 48 ++++++++++++------------ 2 files changed, 27 insertions(+), 27 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 7e053a027d..c6076410b2 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -5439,7 +5439,7 @@ void tst_qqmllanguage::selfReference() const QMetaObject *metaObject = o->metaObject(); QMetaProperty selfProperty = metaObject->property(metaObject->indexOfProperty("self")); - QCOMPARE(selfProperty.userType(), compilationUnit->metaTypeId); + QCOMPARE(selfProperty.userType(), compilationUnit->metaTypeId.id()); QByteArray typeName = selfProperty.typeName(); QVERIFY(typeName.endsWith('*')); @@ -5448,7 +5448,7 @@ void tst_qqmllanguage::selfReference() QMetaMethod selfFunction = metaObject->method(metaObject->indexOfMethod("returnSelf()")); QVERIFY(selfFunction.isValid()); - QCOMPARE(selfFunction.returnType(), compilationUnit->metaTypeId); + QCOMPARE(selfFunction.returnType(), compilationUnit->metaTypeId.id()); QMetaMethod selfSignal; @@ -5462,7 +5462,7 @@ void tst_qqmllanguage::selfReference() QVERIFY(selfSignal.isValid()); QCOMPARE(selfSignal.parameterCount(), 1); - QCOMPARE(selfSignal.parameterType(0), compilationUnit->metaTypeId); + QCOMPARE(selfSignal.parameterType(0), compilationUnit->metaTypeId.id()); } void tst_qqmllanguage::selfReferencingSingleton() diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index c8e6e9c935..b69b466947 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -387,24 +387,24 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlEngine engine; QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), QTypeRevision::fromVersion(1, 0)); - QVERIFY(!type.isValid()); + QVERIFY2(!type.isValid(), "Type is not valid yet"); controllerId = qmlRegisterType("mytypes", 1, 0, "Controller"); type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), QTypeRevision::fromVersion(1, 0)); - QVERIFY(type.isValid()); - QVERIFY(!type.isInterface()); - QVERIFY(!type.isSingleton()); - QVERIFY(!type.isComposite()); + QVERIFY2(type.isValid(), "Type is valid now"); + QVERIFY2(!type.isInterface(), "Type is not an interface"); + QVERIFY2(!type.isSingleton(), "Type is not a singleton"); + QVERIFY2(!type.isComposite(), "Types is not a composite type"); QQmlComponent c(&engine, testFileUrl("testUnregisterCustomType.qml")); QScopedPointer obj(c.create()); - QVERIFY(obj); + QVERIFY2(obj, "obj is not null"); QObject *controller = obj->findChild("controller"); - QVERIFY(qobject_cast(controller)); + QVERIFY2(qobject_cast(controller), "child 'controller' could be found and is a Controller1*"); QVariant stringVal = controller->property("string"); QCOMPARE(stringVal.userType(), QVariant::String); QCOMPARE(stringVal.toString(), QStringLiteral("Controller #1")); QVariant enumVal = controller->property("enumVal"); - QCOMPARE(enumVal.userType(), QVariant::Int); + QVERIFY2(QMetaType(enumVal.userType()).flags() & QMetaType::IsEnumeration, "enumVal's type is enumeratoion"); QCOMPARE(enumVal.toInt(), 1); } QQmlMetaType::unregisterType(controllerId); @@ -412,24 +412,24 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlEngine engine; QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), QTypeRevision::fromVersion(1, 0)); - QVERIFY(!type.isValid()); + QVERIFY2(!type.isValid(), "Type is not valid anymore"); controllerId = qmlRegisterType("mytypes", 1, 0, "Controller"); type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), QTypeRevision::fromVersion(1, 0)); - QVERIFY(type.isValid()); - QVERIFY(!type.isInterface()); - QVERIFY(!type.isSingleton()); - QVERIFY(!type.isComposite()); + QVERIFY2(type.isValid(), "Type is valid again"); + QVERIFY2(!type.isInterface(), "Type is not an interface"); + QVERIFY2(!type.isSingleton(), "Type is not a singleton"); + QVERIFY2(!type.isComposite(), "Type is not a composite"); QQmlComponent c(&engine, testFileUrl("testUnregisterCustomType.qml")); QScopedPointer obj(c.create()); - QVERIFY(obj); + QVERIFY2(obj, "obj is not null"); QObject *controller = obj->findChild("controller"); - QVERIFY(qobject_cast(controller)); + QVERIFY2(qobject_cast(controller), "child 'controller' could be found and is a Controller2*"); QVariant stringVal = controller->property("string"); QCOMPARE(stringVal.userType(), QVariant::String); QCOMPARE(stringVal.toString(), QStringLiteral("Controller #2")); QVariant enumVal = controller->property("enumVal"); - QCOMPARE(enumVal.userType(), QVariant::Int); + QVERIFY2(QMetaType(enumVal.userType()).flags() & QMetaType::IsEnumeration, "enumVal's type is enumeratoion"); QCOMPARE(enumVal.toInt(), 111); } QQmlMetaType::unregisterType(controllerId); @@ -437,24 +437,24 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlEngine engine; QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), QTypeRevision::fromVersion(1, 0)); - QVERIFY(!type.isValid()); + QVERIFY2(!type.isValid(), "Type is not valid anymore"); controllerId = qmlRegisterType("mytypes", 1, 0, "Controller"); type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), QTypeRevision::fromVersion(1, 0)); - QVERIFY(type.isValid()); - QVERIFY(!type.isInterface()); - QVERIFY(!type.isSingleton()); - QVERIFY(!type.isComposite()); + QVERIFY2(type.isValid(), "Type is valid again"); + QVERIFY2(!type.isInterface(), "Type is not an interface"); + QVERIFY2(!type.isSingleton(), "Type is not a singleton"); + QVERIFY2(!type.isComposite(), "Type is not a composite"); QQmlComponent c(&engine, testFileUrl("testUnregisterCustomType.qml")); QScopedPointer obj(c.create()); - QVERIFY(obj); + QVERIFY2(obj, "obj is not null"); QObject *controller = obj->findChild("controller"); - QVERIFY(qobject_cast(controller)); + QVERIFY2(qobject_cast(controller), "child 'controller' could be found and is a Controller1*"); QVariant stringVal = controller->property("string"); QCOMPARE(stringVal.userType(), QVariant::String); QCOMPARE(stringVal.toString(), QStringLiteral("Controller #1")); QVariant enumVal = controller->property("enumVal"); - QCOMPARE(enumVal.userType(), QVariant::Int); + QVERIFY2(QMetaType(enumVal.userType()).flags() & QMetaType::IsEnumeration, "enumVal's type is enumeratoion"); QCOMPARE(enumVal.toInt(), 1); } } -- cgit v1.2.3 From f40e8aa17a35da0b402bbcd2ca7b8636502ed448 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Fri, 6 Mar 2020 08:45:34 +0100 Subject: Remove parts of sequence type test The tests makes assumptions which simply don't hold anymore, now that QProperty does automatic type registration, and the engine supports magic conversions via QSequentialIterable. Change-Id: I33e8eeca95757686e59da9db5ef5d92041364335 Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index fea5c836e3..a136235f90 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -5771,9 +5771,7 @@ void tst_qqmlecmascript::sequenceConversionRead() QVERIFY(seq != nullptr); // we haven't registered QList as a sequence type. - QString warningOne = QLatin1String("QMetaProperty::read: Unable to handle unregistered datatype 'QVector' for property 'MySequenceConversionObject::typeListProperty'"); - QString warningTwo = qmlFile.toString() + QLatin1String(":18: TypeError: Cannot read property 'length' of undefined"); - QTest::ignoreMessage(QtWarningMsg, warningOne.toLatin1().constData()); + QString warningTwo = qmlFile.toString() + QLatin1String(":18: Error: Cannot assign [undefined] to int"); QTest::ignoreMessage(QtWarningMsg, warningTwo.toLatin1().constData()); QMetaObject::invokeMethod(object, "performTest"); @@ -5781,10 +5779,6 @@ void tst_qqmlecmascript::sequenceConversionRead() // QList has not been registered as a sequence type. QCOMPARE(object->property("pointListLength").toInt(), 0); QVERIFY(!object->property("pointList").isValid()); - QTest::ignoreMessage(QtWarningMsg, "QMetaProperty::read: Unable to handle unregistered datatype 'QVector' for property 'MySequenceConversionObject::typeListProperty'"); - QQmlProperty seqProp(seq, "typeListProperty", &engine); - QVERIFY(!seqProp.read().isValid()); // not a valid/known sequence type - delete object; } } -- cgit v1.2.3 From 8e67e31a3b554f2932085e0d4692e84af4a63429 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 27 Feb 2020 08:01:14 +0100 Subject: painting benchmark: adapt to openglwidgets split Change-Id: I603635dfaaa455a5a66d7a791a36008f9fb9b770 Reviewed-by: Johan Helsing --- tests/benchmarks/qml/painting/painting.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/benchmarks/qml/painting/painting.pro b/tests/benchmarks/qml/painting/painting.pro index 633be76e30..9948df511a 100644 --- a/tests/benchmarks/qml/painting/painting.pro +++ b/tests/benchmarks/qml/painting/painting.pro @@ -1,7 +1,7 @@ requires(qtHaveModule(opengl)) requires(qtHaveModule(widgets)) -QT += opengl widgets +QT += opengl widgets openglwidgets CONFIG += console macx:CONFIG -= app_bundle -- cgit v1.2.3 From c9a8be0c5bc43c4fa01a1c74bdbb43e2ac3dcbcd Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 21 Feb 2020 14:36:04 +0100 Subject: Stabilize tst_QPauseAnimationJob::multipleSequentialGroups() Apparently macos also has bad timer resolution these days. It only manifests in one specific place, though. Fixes: QTBUG-81938 Change-Id: Ibe024cf491760cff38944b0e97026c895938ae0a Reviewed-by: Fabian Kosmale --- .../qml/animation/qpauseanimationjob/BLACKLIST | 3 --- .../qpauseanimationjob/tst_qpauseanimationjob.cpp | 30 +++++++++++----------- 2 files changed, 15 insertions(+), 18 deletions(-) delete mode 100644 tests/auto/qml/animation/qpauseanimationjob/BLACKLIST (limited to 'tests') diff --git a/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST b/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST deleted file mode 100644 index 33799b6528..0000000000 --- a/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -[multipleSequentialGroups] -macos ci - diff --git a/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp b/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp index 8f6b6a2ab7..1d644bf9b5 100644 --- a/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp +++ b/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp @@ -32,8 +32,8 @@ #include #include -#ifdef Q_OS_WIN -static const char winTimerError[] = "On windows, consistent timing is not working properly due to bad timer resolution"; +#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) +static const char timerError[] = "On some platforms, consistent timing is not working properly due to bad timer resolution"; #endif class TestablePauseAnimation : public QPauseAnimationJob @@ -144,7 +144,7 @@ void tst_QPauseAnimationJob::noTimerUpdates() #ifdef Q_OS_WIN if (animation.state() != QAbstractAnimationJob::Stopped) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(animation.state(), QAbstractAnimationJob::Stopped); @@ -152,7 +152,7 @@ void tst_QPauseAnimationJob::noTimerUpdates() #ifdef Q_OS_WIN if (animation.m_updateCurrentTimeCount != expectedLoopCount) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(animation.m_updateCurrentTimeCount, expectedLoopCount); } @@ -173,25 +173,25 @@ void tst_QPauseAnimationJob::multiplePauseAnimations() #ifdef Q_OS_WIN if (animation.state() != QAbstractAnimationJob::Stopped) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(animation.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (animation2.state() != QAbstractAnimationJob::Running) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(animation2.state(), QAbstractAnimationJob::Running); #ifdef Q_OS_WIN if (animation.m_updateCurrentTimeCount != 2) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(animation.m_updateCurrentTimeCount, 2); #ifdef Q_OS_WIN if (animation2.m_updateCurrentTimeCount != 2) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(animation2.m_updateCurrentTimeCount, 2); @@ -388,7 +388,7 @@ void tst_QPauseAnimationJob::multipleSequentialGroups() #ifdef Q_OS_WIN if (group.state() != QAbstractAnimationJob::Stopped) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); QCOMPARE(group.state(), QAbstractAnimationJob::Stopped); #else QTRY_COMPARE(group.state(), QAbstractAnimationJob::Stopped); @@ -396,31 +396,31 @@ void tst_QPauseAnimationJob::multipleSequentialGroups() #ifdef Q_OS_WIN if (subgroup1.state() != QAbstractAnimationJob::Stopped) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(subgroup1.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (subgroup2.state() != QAbstractAnimationJob::Stopped) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(subgroup2.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (subgroup3.state() != QAbstractAnimationJob::Stopped) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(subgroup3.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (subgroup4.state() != QAbstractAnimationJob::Stopped) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(subgroup4.state(), QAbstractAnimationJob::Stopped); -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) if (pause5.m_updateCurrentTimeCount != 4) - QEXPECT_FAIL("", winTimerError, Abort); + QEXPECT_FAIL("", timerError, Abort); #endif QCOMPARE(pause5.m_updateCurrentTimeCount, 4); } -- cgit v1.2.3 From c24c5baeda4101b0058689adf9200b77a722c3a2 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 10 Mar 2020 10:16:52 +0100 Subject: tst_qsequentialanimationgroupjob: Protect against erratic scheduling If the scheduling stalled the animation for more than 50ms at the wrong time, the test would fail. The same effect can be observed by manually delaying the execution using a break point. Change-Id: I4c8d999469b2586e9a5619be1573ec7eb0604013 Fixes: QTBUG-82782 Reviewed-by: Simon Hausmann --- .../tst_qsequentialanimationgroupjob.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/animation/qsequentialanimationgroupjob/tst_qsequentialanimationgroupjob.cpp b/tests/auto/qml/animation/qsequentialanimationgroupjob/tst_qsequentialanimationgroupjob.cpp index 57b0905a8a..add19273d9 100644 --- a/tests/auto/qml/animation/qsequentialanimationgroupjob/tst_qsequentialanimationgroupjob.cpp +++ b/tests/auto/qml/animation/qsequentialanimationgroupjob/tst_qsequentialanimationgroupjob.cpp @@ -1332,6 +1332,8 @@ void tst_QSequentialAnimationGroupJob::stopUncontrolledAnimations() void tst_QSequentialAnimationGroupJob::finishWithUncontrolledAnimation() { + const int targetDuration = 300; + //1st case: //first we test a group with one uncontrolled animation QSequentialAnimationGroupJob group; @@ -1346,7 +1348,7 @@ void tst_QSequentialAnimationGroupJob::finishWithUncontrolledAnimation() QCOMPARE(group.currentLoopTime(), 0); QCOMPARE(notTimeDriven.currentLoopTime(), 0); - QTest::qWait(300); //wait for the end of notTimeDriven + QTest::qWait(targetDuration); //wait for the end of notTimeDriven QTRY_COMPARE(notTimeDriven.state(), QAnimationGroupJob::Stopped); const int actualDuration = notTimeDriven.currentLoopTime(); QCOMPARE(group.state(), QAnimationGroupJob::Stopped); @@ -1361,10 +1363,15 @@ void tst_QSequentialAnimationGroupJob::finishWithUncontrolledAnimation() StateChangeListener animStateChangedSpy; anim.addAnimationChangeListener(&animStateChangedSpy, QAbstractAnimationJob::StateChange); - group.setCurrentTime(300); + group.setCurrentTime(targetDuration); QCOMPARE(group.state(), QAnimationGroupJob::Stopped); - QCOMPARE(notTimeDriven.currentLoopTime(), actualDuration); - QCOMPARE(group.currentAnimation(), static_cast(&anim)); + if (actualDuration > targetDuration) { + QCOMPARE(notTimeDriven.currentLoopTime(), targetDuration); + QCOMPARE(group.currentAnimation(), ¬TimeDriven); + } else { + QCOMPARE(notTimeDriven.currentLoopTime(), actualDuration); + QCOMPARE(group.currentAnimation(), &anim); + } //3rd case: //now let's add a perfectly defined animation at the end @@ -1377,13 +1384,13 @@ void tst_QSequentialAnimationGroupJob::finishWithUncontrolledAnimation() QCOMPARE(animStateChangedSpy.count(), 0); - QTest::qWait(300); //wait for the end of notTimeDriven + QTest::qWait(targetDuration); //wait for the end of notTimeDriven QTRY_COMPARE(notTimeDriven.state(), QAnimationGroupJob::Stopped); QCOMPARE(group.state(), QAnimationGroupJob::Running); QCOMPARE(anim.state(), QAnimationGroupJob::Running); QCOMPARE(group.currentAnimation(), static_cast(&anim)); QCOMPARE(animStateChangedSpy.count(), 1); - QTest::qWait(300); //wait for the end of anim + QTest::qWait(targetDuration); //wait for the end of anim QTRY_COMPARE(anim.state(), QAnimationGroupJob::Stopped); QCOMPARE(anim.currentLoopTime(), anim.duration()); -- cgit v1.2.3