diff options
author | Liang Qi <liang.qi@qt.io> | 2019-01-22 10:35:09 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2019-01-22 11:20:29 +0100 |
commit | 1b4d2741f90d3f4daf79940b9c8713dda0fb7f3d (patch) | |
tree | 40cee4f6af7bf9a5fc87c43f024f417a5d09e18d /tests | |
parent | 536868fad50778ec5bf4c6c7269c721b05d8a2d5 (diff) | |
parent | 84e15a609b37a64baf82ed20f8d4f79474989226 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
.qmake.conf
tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
Change-Id: Ic1f5e219a255d0613f7654368a5ce3eccb8f0ee9
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 16 | ||||
-rw-r--r-- | tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp | 39 | ||||
-rw-r--r-- | tests/auto/quick/qquickapplication/tst_qquickapplication.cpp | 56 | ||||
-rw-r--r-- | tests/auto/quick/qquickpathview/tst_qquickpathview.cpp | 1 | ||||
-rw-r--r-- | tests/manual/tableview/storagemodel/main.qml | 74 | ||||
-rw-r--r-- | tests/manual/tableview/storagemodel/storagemodel.cpp | 82 | ||||
-rw-r--r-- | tests/manual/tableview/storagemodel/storagemodel.h | 25 |
7 files changed, 236 insertions, 57 deletions
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index b75f069fab..94494df4c0 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -1759,6 +1759,22 @@ void tst_QJSEngine::stacktrace() QJSValue result2 = eng.evaluate(script2, fileName); QVERIFY(!result2.isError()); QVERIFY(result2.isString()); + + { + QString script3 = QString::fromLatin1( + "'use strict'\n" + "function throwUp() { throw new Error('up') }\n" + "function indirectlyThrow() { return throwUp() }\n" + "indirectlyThrow()\n" + ); + QJSValue result3 = eng.evaluate(script3); + QVERIFY(result3.isError()); + QJSValue stack = result3.property("stack"); + QVERIFY(stack.isString()); + QString stackTrace = stack.toString(); + QVERIFY(!stackTrace.contains(QStringLiteral("indirectlyThrow"))); + QVERIFY(stackTrace.contains(QStringLiteral("elide"))); + } } void tst_QJSEngine::numberParsing_data() diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index e83dac48fb..7139a1c952 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -35,6 +35,7 @@ #include <private/qqmlmetatype_p.h> #include <private/qqmlpropertyvalueinterceptor_p.h> +#include <private/qqmlengine_p.h> #include <private/qhashedstring_p.h> #include "../../shared/util.h" @@ -64,6 +65,7 @@ private slots: void unregisterCustomSingletonType(); void normalizeUrls(); + void unregisterAttachedProperties(); }; class TestType : public QObject @@ -533,6 +535,43 @@ void tst_qqmlmetatype::normalizeUrls() QVERIFY(!QQmlMetaType::qmlType(url, /*includeNonFileImports=*/true).isValid()); } +void tst_qqmlmetatype::unregisterAttachedProperties() +{ + qmlClearTypeRegistrations(); + + const QUrl dummy("qrc:///doesnotexist.qml"); + { + QQmlEngine e; + QQmlComponent c(&e); + c.setData("import QtQuick 2.2\n Item { }", dummy); + + const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); + QCOMPARE(attachedType.attachedPropertiesId(QQmlEnginePrivate::get(&e)), + attachedType.index()); + + QVERIFY(c.create()); + } + + qmlClearTypeRegistrations(); + { + QQmlEngine e; + QQmlComponent c(&e); + + // The extra import shuffles the type IDs around, so that we + // get a different ID for the attached properties. If the attached + // properties aren't properly cleared, this will crash. + c.setData("import QtQml.StateMachine 1.0 \n" + "import QtQuick 2.2 \n" + "Item { KeyNavigation.up: null }", dummy); + + const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); + QCOMPARE(attachedType.attachedPropertiesId(QQmlEnginePrivate::get(&e)), + attachedType.index()); + + QVERIFY(c.create()); + } +} + QTEST_MAIN(tst_qqmlmetatype) #include "tst_qqmlmetatype.moc" diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp index 62027f59f4..3526eb98be 100644 --- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp +++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp @@ -88,31 +88,37 @@ void tst_qquickapplication::active() QQuickWindow window; item->setParentItem(window.contentItem()); - // not active - QVERIFY(!item->property("active").toBool()); - QVERIFY(!item->property("active2").toBool()); - - // active - window.show(); - window.requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(&window)); - QCOMPARE(QGuiApplication::focusWindow(), &window); - QVERIFY(item->property("active").toBool()); - QVERIFY(item->property("active2").toBool()); - - QWindowSystemInterface::handleWindowActivated(nullptr); - -#ifdef Q_OS_OSX - // OS X has the concept of "reactivation" - QTRY_VERIFY(QGuiApplication::focusWindow() != &window); - QVERIFY(item->property("active").toBool()); - QVERIFY(item->property("active2").toBool()); -#else - // not active again - QTRY_VERIFY(QGuiApplication::focusWindow() != &window); - QVERIFY(!item->property("active").toBool()); - QVERIFY(!item->property("active2").toBool()); -#endif + // If the platform plugin has the ApplicationState capability, app activation originate from it + // as a result of a system event. We therefore have to simulate these events here. + if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) { + + // Flush pending events, in case the platform have already queued real application state events + QWindowSystemInterface::flushWindowSystemEvents(); + + QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); + QWindowSystemInterface::flushWindowSystemEvents(); + QVERIFY(item->property("active").toBool()); + QVERIFY(item->property("active2").toBool()); + + QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); + QWindowSystemInterface::flushWindowSystemEvents(); + QVERIFY(!item->property("active").toBool()); + QVERIFY(!item->property("active2").toBool()); + } else { + // Otherwise, app activation is triggered by window activation. + window.show(); + window.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + QCOMPARE(QGuiApplication::focusWindow(), &window); + QVERIFY(item->property("active").toBool()); + QVERIFY(item->property("active2").toBool()); + + // not active again + QWindowSystemInterface::handleWindowActivated(nullptr); + QTRY_VERIFY(QGuiApplication::focusWindow() != &window); + QVERIFY(!item->property("active").toBool()); + QVERIFY(!item->property("active2").toBool()); + } } void tst_qquickapplication::state() diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 8d3abb7ce3..bf38d2d926 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -1372,6 +1372,7 @@ void tst_QQuickPathView::package() QSKIP("QTBUG-27170 view does not reliably receive polish without a running animation"); #endif + QQuickTest::qWaitForItemPolished(pathView); QQuickItem *item = findItem<QQuickItem>(pathView, "pathItem"); QVERIFY(item); QVERIFY(item->scale() != 1.0); diff --git a/tests/manual/tableview/storagemodel/main.qml b/tests/manual/tableview/storagemodel/main.qml index 2603fba0e2..725d7da7b0 100644 --- a/tests/manual/tableview/storagemodel/main.qml +++ b/tests/manual/tableview/storagemodel/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 QtQuick module of the Qt Toolkit. @@ -38,13 +38,14 @@ ****************************************************************************/ import QtQuick 2.12 -import QtQuick.Window 2.3 +import QtQuick.Window 2.12 +import Qt.labs.qmlmodels 1.0 import StorageModel 0.1 Window { id: window - width: 640 - height: 480 + width: 480 + height: 300 visible: true color: "darkgray" title: "Storage Volumes" @@ -57,17 +58,62 @@ Window { model: StorageModel { } columnSpacing: 1 rowSpacing: 1 - delegate: Rectangle { - id: tableDelegate - implicitWidth: displayText.implicitWidth + 8 - implicitHeight: displayText.implicitHeight + 14 + delegate: DelegateChooser { + role: "type" + DelegateChoice { + roleValue: "Value" + delegate: Rectangle { + color: "tomato" + implicitWidth: Math.max(100, label.implicitWidth + 8) + implicitHeight: label.implicitHeight + 4 - Text { - id: displayText - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.leftMargin: 4 - text: display + Rectangle { + x: parent.width - width + width: value * parent.width / valueMax + height: parent.height + color: "white" + } + + Text { + id: label + anchors.baseline: parent.bottom + anchors.baselineOffset: -4 + anchors.left: parent.left + anchors.leftMargin: 4 + text: valueDisplay + " of " + valueMaxDisplay + " " + heading + } + } + } + DelegateChoice { + roleValue: "Flag" + // We could use a checkbox here but that would be another component (e.g. from Controls) + delegate: Rectangle { + implicitWidth: checkBox.implicitWidth + 8 + implicitHeight: checkBox.implicitHeight + 4 + Text { + id: checkBox + anchors.baseline: parent.bottom + anchors.baselineOffset: -4 + anchors.left: parent.left + anchors.leftMargin: 4 + text: (checkState ? "☑ " : "☐ ") + heading + } + } + } + DelegateChoice { + // roleValue: "String" // default delegate + delegate: Rectangle { + implicitWidth: stringLabel.implicitWidth + 8 + implicitHeight: stringLabel.implicitHeight + 4 + Text { + id: stringLabel + anchors.baseline: parent.bottom + anchors.baselineOffset: -4 + anchors.left: parent.left + anchors.leftMargin: 4 + text: display + } + } } } } diff --git a/tests/manual/tableview/storagemodel/storagemodel.cpp b/tests/manual/tableview/storagemodel/storagemodel.cpp index b6b861a1a8..b43454b249 100644 --- a/tests/manual/tableview/storagemodel/storagemodel.cpp +++ b/tests/manual/tableview/storagemodel/storagemodel.cpp @@ -63,6 +63,20 @@ StorageModel::StorageModel(QObject *parent) : refresh(); } +QHash<int, QByteArray> StorageModel::roleNames() const { + static auto roles = QHash<int, QByteArray> { + { int(Role::Type), "type" }, + { int(Role::Heading), "heading" }, + { int(Role::Value), "value" }, + { int(Role::ValueMax), "valueMax" }, + { int(Role::ValueDisplay), "valueDisplay" }, + { int(Role::ValueMaxDisplay), "valueMaxDisplay" }, + { Qt::CheckStateRole, "checkState" }, + }; + static auto ret = roles.unite(QAbstractTableModel::roleNames());; + return ret; +} + void StorageModel::refresh() { beginResetModel(); @@ -92,7 +106,6 @@ Qt::ItemFlags StorageModel::flags(const QModelIndex &index) const { Qt::ItemFlags result = QAbstractTableModel::flags(index); switch (Column(index.column())) { - case Column::Available: case Column::IsReady: case Column::IsReadOnly: case Column::IsValid: @@ -109,7 +122,9 @@ QVariant StorageModel::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); - if (role == Qt::DisplayRole) { + switch (role) { + case Qt::DisplayRole: + case int(Role::ValueDisplay): { const QStorageInfo &volume = m_volumes.at(index.row()); switch (Column(index.column())) { case Column::RootPath: @@ -120,12 +135,8 @@ QVariant StorageModel::data(const QModelIndex &index, int role) const return volume.device(); case Column::FileSystemName: return volume.fileSystemType(); - case Column::Total: - return QLocale().formattedDataSize(volume.bytesTotal()); case Column::Free: return QLocale().formattedDataSize(volume.bytesFree()); - case Column::Available: - return QLocale().formattedDataSize(volume.bytesAvailable()); case Column::IsReady: return volume.isReady(); case Column::IsReadOnly: @@ -135,7 +146,8 @@ QVariant StorageModel::data(const QModelIndex &index, int role) const default: break; } - } else if (role == Qt::CheckStateRole) { + } break; + case Qt::CheckStateRole: { const QStorageInfo &volume = m_volumes.at(index.row()); switch (Column(index.column())) { case Column::IsReady: @@ -147,17 +159,16 @@ QVariant StorageModel::data(const QModelIndex &index, int role) const default: break; } - } else if (role == Qt::TextAlignmentRole) { + } break; + case Qt::TextAlignmentRole: switch (Column(index.column())) { - case Column::Total: case Column::Free: - case Column::Available: return Qt::AlignTrailing; default: break; } return Qt::AlignLeading; - } else if (role == Qt::ToolTipRole) { + case Qt::ToolTipRole: { QLocale locale; const QStorageInfo &volume = m_volumes.at(index.row()); return tr("Root path : %1\n" @@ -186,6 +197,51 @@ QVariant StorageModel::data(const QModelIndex &index, int role) const arg(volume.isValid() ? tr("true") : tr("false")). arg(volume.isRoot() ? tr("true") : tr("false")); } + case int(Role::Type): + switch (Column(index.column())) { + case Column::RootPath: + case Column::Name: + case Column::Device: + case Column::FileSystemName: + return QVariant::fromValue(Type::String); + break; + case Column::Free: + return QVariant::fromValue(Type::Value); + case Column::IsReady: + case Column::IsReadOnly: + case Column::IsValid: + return QVariant::fromValue(Type::Flag); + default: + break; + } + break; + case int(Role::Heading): + return headerData(index.column()); + case int(Role::Value): + switch (Column(index.column())) { + case Column::Free: + return m_volumes.at(index.row()).bytesFree(); + default: + break; + } + break; + case int(Role::ValueMax): + switch (Column(index.column())) { + case Column::Free: + return m_volumes.at(index.row()).bytesTotal(); + default: + break; + } + break; + case int(Role::ValueMaxDisplay): + switch (Column(index.column())) { + case Column::Free: + return QLocale().formattedDataSize(m_volumes.at(index.row()).bytesTotal()); + default: + break; + } + break; + } // switch (role) return QVariant(); } @@ -206,12 +262,8 @@ QVariant StorageModel::headerData(int section, Qt::Orientation orientation, int return tr("Device"); case Column::FileSystemName: return tr("File System"); - case Column::Total: - return tr("Total"); case Column::Free: return tr("Free"); - case Column::Available: - return tr("Available"); case Column::IsReady: return tr("Ready"); case Column::IsReadOnly: diff --git a/tests/manual/tableview/storagemodel/storagemodel.h b/tests/manual/tableview/storagemodel/storagemodel.h index 1f6f6f8b1f..6cbab3d850 100644 --- a/tests/manual/tableview/storagemodel/storagemodel.h +++ b/tests/manual/tableview/storagemodel/storagemodel.h @@ -65,23 +65,42 @@ public: Name, Device, FileSystemName, - Total, Free, - Available, IsReady, IsReadOnly, IsValid, Count }; + Q_ENUM(Column) + + enum class Role : int { + Type = Qt::UserRole + 1, + Heading, + Value, + ValueMax, // If we had ValueMin, it would always be zero in this example + ValueDisplay, + ValueMaxDisplay, + Count + }; + Q_ENUM(Role) + + enum class Type : int { + String, // use Qt::DisplayRole + Value, // use Role::Value and Role::ValueMax + Flag, // use Qt::CheckStateRole + Count + }; + Q_ENUM(Type) explicit StorageModel(QObject *parent = nullptr); int columnCount(const QModelIndex &parent) const override; int rowCount(const QModelIndex &parent) const override; + QHash<int, QByteArray> roleNames() const override; QVariant data(const QModelIndex &index, int role) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation = Qt::Horizontal, int role = Qt::DisplayRole) const override; public slots: void refresh(); |