diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-02-17 01:01:00 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-02-17 10:21:59 +0100 |
commit | 3e758800b4daf8fbc870a2ff5d54fce9d4402ce8 (patch) | |
tree | ba237b9da1c7dfd08bf13e71c5dbd6b3c2e77633 /tests/auto/qml | |
parent | 925a0e499a5dbdb180fd9969a79abf96006ce4fd (diff) | |
parent | 55546991e24ca6799709cbe0171b9ab87216c35f (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
src/imports/qtqml/plugin.cpp
src/qml/qml/qqml.h
src/qml/qml/qqmlmetatype.cpp
src/qml/qml/qqmlmetatype_p.h
src/qml/qml/qqmltypeloader.cpp
src/qml/types/qqmlbind.cpp
src/quick/items/qquickitemsmodule.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
Change-Id: I52548938a582cb6510271ed4bc3a9aa0c3c11df6
Diffstat (limited to 'tests/auto/qml')
29 files changed, 877 insertions, 77 deletions
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/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() 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 <debugutil_p.h> +#include <qqmldebugprocess_p.h> + +#include <private/qqmldebugclient_p.h> +#include <private/qqmldebugtranslationclient_p.h> +#include <private/qqmldebugconnection_p.h> +#include <private/qpacket_p.h> + +#include <QtCore/qstring.h> +#include <QtCore/qlibraryinfo.h> +#include <QtTest/qtest.h> + +const char *QMLFILE = "test.qml"; + +class tst_QQmlDebugTranslationService : public QQmlDebugTest +{ + Q_OBJECT + +private slots: + void pluginConnection(); + +private: + QList<QQmlDebugClient *> createClients() override; + QPointer<QQmlDebugTranslationClient> m_client; +}; + +QList<QQmlDebugClient *> 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" diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index d6e85f973f..b561e5f398 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() 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 c7714304b8..21d5ae46a9 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(); void testStatesAndTransitions(); @@ -185,6 +187,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")); 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<QObject> 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/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<QPoint> 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 a05933d071..61dc393998 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<QObject> o(component.create()); + QVERIFY(o); + auto success = o->property("success"); + QVERIFY(success.isValid()); + QVERIFY(success.toBool()); +} + void tst_qqmlecmascript::assignBasicTypes() { QQmlEngine engine; @@ -5792,13 +5823,12 @@ void tst_qqmlecmascript::sequenceConversionWrite() MySequenceConversionObject *seq = object->findChild<MySequenceConversionObject*>("msco"); QVERIFY(seq != nullptr); - // we haven't registered QList<QPoint> as a sequence type, so writing shouldn't work. - QString warningOne = qmlFile.toString() + QLatin1String(":16: Error: Cannot assign QJSValue to QVector<QPoint>"); - QTest::ignoreMessage(QtWarningMsg, warningOne.toLatin1().constData()); - + // Behavior change in 5.14: due to added auto-magical conversions, it is possible to assign to + // QList<QPoint>, 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<QPoint> pointList; pointList << QPoint(1, 2) << QPoint(3, 4) << QPoint(5, 6); // original values, shouldn't have changed + QList<QPoint> 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/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 0e70933ec6..26b2b839ea 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 @@ -187,6 +188,18 @@ void tst_qqmlenginecleanup::test_customModuleCleanup() } } +void tst_qqmlenginecleanup::test_qmlListCleared() +{ + { + QQmlEngine engine; + auto url = testFileUrl("MyItem.qml"); + QQmlComponent comp(&engine, url); + QScopedPointer<QObject> item {comp.create()}; + QCOMPARE(QQmlMetaType::qmlRegisteredListTypeCount(), 1); + } + QCOMPARE(QQmlMetaType::qmlRegisteredListTypeCount(), 0); +} + QTEST_MAIN(tst_qqmlenginecleanup) #include "tst_qqmlenginecleanup.moc" 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/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/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/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 1e382d7ee2..d4760fa7e9 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -325,6 +325,9 @@ private slots: void overrideSingleton(); void revisionedPropertyOfAttachedObjectProperty(); + void arrayToContainer(); + void qualifiedScopeInCustomParser(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -5627,6 +5630,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() @@ -5717,6 +5723,60 @@ void tst_qqmllanguage::nonExistingInlineComponent() QCOMPARE(error.column(), column); } +class TestItem : public QObject +{ + Q_OBJECT + Q_PROPERTY( QVector<QPointF> positions MEMBER m_points ) + +public: + TestItem() = default; + QVector< QPointF > m_points; +}; + + +Q_DECLARE_METATYPE(QVector<QPointF>); +void tst_qqmllanguage::arrayToContainer() +{ + QQmlEngine engine; + qmlRegisterType<TestItem>("qt.test", 1, 0, "TestItem"); + QVector<QPointF> points { QPointF (2.0, 3.0) }; + engine.rootContext()->setContextProperty("test", QVariant::fromValue(points)); + QQmlComponent component(&engine, testFileUrl("arrayToContainer.qml")); + VERIFY_ERRORS(0); + QScopedPointer<TestItem> root(qobject_cast<TestItem *>(component.createWithInitialProperties( {{"vector", QVariant::fromValue(points)}} ))); + QVERIFY(root); + 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<EnumTester>("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<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" 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 981fe7407e..8483bd1f95 100644 --- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp +++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp @@ -33,6 +33,7 @@ #include <private/qqmljsast_p.h> #include "../../shared/util.h" +#include "../../shared/qqmljsastdumper.h" #include <qtest.h> #include <QDir> @@ -583,7 +584,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/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..2c06c5f594 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/interfaces.h @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** 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 <QtQml/qqml.h> + +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 + QML_INTERFACE +}; + +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<QObject*>(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<QObject*>(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..8a96fc52c5 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 <qtest.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> @@ -160,6 +162,8 @@ private slots: void bindingToAlias(); void nestedQQmlPropertyMap(); + + void underscorePropertyChangeHandler(); private: QQmlEngine engine; }; @@ -2090,74 +2094,20 @@ 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<QObject*>(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>("Interface"); - qmlRegisterType<A>("io.qt.bugreports", 1, 0, "A"); - qmlRegisterType<B>("io.qt.bugreports", 1, 0, "B"); - qmlRegisterType<C>("io.qt.bugreports", 1, 0, "C"); - qmlRegisterType<InterfaceConsumer>("io.qt.bugreports", 1, 0, "InterfaceConsumer"); - - const QUrl url = testFileUrl("interfaceBinding.qml"); + qmlRegisterInterface<Interface>("Interface"); + qmlRegisterType<A>("io.qt.bugreports", 1, 0, "A"); + qmlRegisterType<B>("io.qt.bugreports", 1, 0, "B"); + qmlRegisterType<C>("io.qt.bugreports", 1, 0, "C"); + qmlRegisterType<InterfaceConsumer>("io.qt.bugreports", 1, 0, "InterfaceConsumer"); + + const QVector<QUrl> urls = { + testFileUrl("interfaceBinding.qml"), + testFileUrl("interfaceBinding2.qml") + }; + + for (const QUrl &url : urls) { QQmlEngine engine; QQmlComponent component(&engine, url); QScopedPointer<QObject> root(component.create()); @@ -2165,6 +2115,7 @@ void tst_qqmlproperty::interfaceBinding() QCOMPARE(root->findChild<QObject*>("a1")->property("testValue").toInt(), 42); QCOMPARE(root->findChild<QObject*>("a2")->property("testValue").toInt(), 43); QCOMPARE(root->findChild<QObject*>("a3")->property("testValue").toInt(), 44); + } } void tst_qqmlproperty::floatToStringPrecision_data() @@ -2241,6 +2192,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<QObject> 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" |