diff options
Diffstat (limited to 'tests/auto')
44 files changed, 2000 insertions, 735 deletions
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index ee18151e4a..e1a999abfb 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -1384,18 +1384,6 @@ void tst_QUrl::compat_constructor_01_data() void tst_QUrl::compat_constructor_01() { - /* The following should work as expected: - * - * QUrlOperator op; - * op.copy( QString( "Makefile" ), - * QString("ftp://rms:grmpf12@nibbler/home/rms/tmp"), - * false ); - * - * as well as the following: - * - * QUrlOperator op; - * op.copy(QString("ftp://ftp.qt-project.org/qt/INSTALL"), "."); - */ QFETCH( QString, urlStr ); { @@ -1425,11 +1413,6 @@ void tst_QUrl::compat_constructor_02_data() void tst_QUrl::compat_constructor_02() { - /* The following should work as expected: - * - * QUrlOperator op( "ftp://ftp.qt-project.org/qt" ); - * op.copy(QString("INSTALL"), "."); - */ QFETCH( QString, urlStr ); QFETCH( QString, fileName ); diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro index 7e0e3a0944..3552f30632 100644 --- a/tests/auto/corelib/itemmodels/itemmodels.pro +++ b/tests/auto/corelib/itemmodels/itemmodels.pro @@ -7,6 +7,7 @@ qtHaveModule(gui): SUBDIRS += \ qabstractproxymodel \ qidentityproxymodel \ qitemselectionmodel \ + qsortfilterproxymodel_recursive \ qtHaveModule(widgets): SUBDIRS += \ qitemmodel \ diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 7b6c470dc4..6444b76a3a 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -3994,14 +3994,14 @@ class DropOnOddRows : public QAbstractListModel public: DropOnOddRows(QObject *parent = 0) : QAbstractListModel(parent) {} - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { if (role == Qt::DisplayRole) return (index.row() % 2 == 0) ? "A" : "B"; return QVariant(); } - int rowCount(const QModelIndex &parent = QModelIndex()) const + int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return 10; @@ -4026,7 +4026,7 @@ public: } - QModelIndex mapToSource(const QModelIndex &proxyIndex) const + QModelIndex mapToSource(const QModelIndex &proxyIndex) const override { Q_ASSERT(sourceModel()); return QSortFilterProxyModel::mapToSource(proxyIndex); diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/.gitignore b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/.gitignore new file mode 100644 index 0000000000..2007aaabbd --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/.gitignore @@ -0,0 +1 @@ +tst_qsortfilterproxymodel_recursive diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/qsortfilterproxymodel_recursive.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/qsortfilterproxymodel_recursive.pro new file mode 100644 index 0000000000..a8b793dbc6 --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/qsortfilterproxymodel_recursive.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +CONFIG += parallel_test +TARGET = tst_qsortfilterproxymodel_recursive + +QT += testlib + +SOURCES += tst_qsortfilterproxymodel_recursive.cpp +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp new file mode 100644 index 0000000000..54c79e0893 --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp @@ -0,0 +1,727 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, authors Filipe Azevedo <filipe.azevedo@kdab.com> and David Faure <david.faure@kdab.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTest> +#include <QSignalSpy> + +#include <QtCore/QSortFilterProxyModel> +#include <QtGui/QStandardItem> + +Q_DECLARE_METATYPE(QModelIndex) + +class ModelSignalSpy : public QObject { + Q_OBJECT +public: + explicit ModelSignalSpy(QAbstractItemModel &model) { + connect(&model, &QAbstractItemModel::rowsInserted, this, &ModelSignalSpy::onRowsInserted); + connect(&model, &QAbstractItemModel::rowsRemoved, this, &ModelSignalSpy::onRowsRemoved); + connect(&model, &QAbstractItemModel::rowsAboutToBeInserted, this, &ModelSignalSpy::onRowsAboutToBeInserted); + connect(&model, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ModelSignalSpy::onRowsAboutToBeRemoved); + connect(&model, &QAbstractItemModel::rowsMoved, this, &ModelSignalSpy::onRowsMoved); + connect(&model, &QAbstractItemModel::dataChanged, this, &ModelSignalSpy::onDataChanged); + connect(&model, &QAbstractItemModel::layoutChanged, this, &ModelSignalSpy::onLayoutChanged); + connect(&model, &QAbstractItemModel::modelReset, this, &ModelSignalSpy::onModelReset); + } + + QStringList mSignals; + +private Q_SLOTS: + void onRowsInserted(QModelIndex p, int start, int end) { + mSignals << QLatin1String("rowsInserted(") + textForRowSpy(p, start, end) + ')'; + } + void onRowsRemoved(QModelIndex p, int start, int end) { + mSignals << QLatin1String("rowsRemoved(") + textForRowSpy(p, start, end) + ')'; + } + void onRowsAboutToBeInserted(QModelIndex p, int start, int end) { + mSignals << QLatin1String("rowsAboutToBeInserted(") + textForRowSpy(p, start, end) + ')'; + } + void onRowsAboutToBeRemoved(QModelIndex p, int start, int end) { + mSignals << QLatin1String("rowsAboutToBeRemoved(") + textForRowSpy(p, start, end) + ')'; + } + void onRowsMoved(QModelIndex,int,int,QModelIndex,int) { + mSignals << QStringLiteral("rowsMoved"); + } + void onDataChanged(const QModelIndex &from, const QModelIndex& ) { + mSignals << QStringLiteral("dataChanged(%1)").arg(from.data().toString()); + } + void onLayoutChanged() { + mSignals << QStringLiteral("layoutChanged"); + } + void onModelReset() { + mSignals << QStringLiteral("modelReset"); + } +private: + QString textForRowSpy(const QModelIndex &parent, int start, int end) + { + QString txt = parent.data().toString(); + if (!txt.isEmpty()) + txt += QLatin1Char('.'); + txt += QString::number(start+1); + if (start != end) + txt += QLatin1Char('-') + QString::number(end+1); + return txt; + } +}; + +class TestModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + TestModel(QAbstractItemModel *sourceModel) + : QSortFilterProxyModel() + { + setRecursiveFiltering(true); + setSourceModel(sourceModel); + } + + virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override + { + return sourceModel()->index(sourceRow, 0, sourceParent).data(Qt::UserRole +1).toBool() + && QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); + } +}; + +// Represents this tree +// - A +// - - B +// - - - C +// - - - D +// - - E +// as a single string, englobing children in brackets, like this: +// [A[B[C D] E]] +// In addition, items that match the filtering (data(UserRole+1) == true) have a * after their value. +static QString treeAsString(const QAbstractItemModel &model, const QModelIndex &parent = QModelIndex()) +{ + QString ret; + const int rowCount = model.rowCount(parent); + if (rowCount > 0) { + ret += QLatin1Char('['); + for (int row = 0 ; row < rowCount; ++row) { + if (row > 0) { + ret += ' '; + } + const QModelIndex child = model.index(row, 0, parent); + ret += child.data().toString(); + if (child.data(Qt::UserRole+1).toBool()) + ret += QLatin1Char('*'); + ret += treeAsString(model, child); + } + ret += QLatin1Char(']'); + } + return ret; +} + +// Fill a tree model based on a string representation (see treeAsString) +static void fillModel(QStandardItemModel &model, const QString &str) +{ + QCOMPARE(str.count('['), str.count(']')); + QStandardItem *item = 0; + QString data; + for ( int i = 0 ; i < str.length() ; ++i ) { + const QChar ch = str.at(i); + if ((ch == '[' || ch == ']' || ch == ' ') && !data.isEmpty()) { + if (data.endsWith('*')) { + item->setData(true, Qt::UserRole + 1); + data.chop(1); + } + item->setText(data); + data.clear(); + } + if (ch == '[') { + // Create new child + QStandardItem *child = new QStandardItem; + if (item) + item->appendRow(child); + else + model.appendRow(child); + item = child; + } else if (ch == ']') { + // Go up to parent + item = item->parent(); + } else if (ch == ' ') { + // Create new sibling + QStandardItem *child = new QStandardItem; + QStandardItem *parent = item->parent(); + if (parent) + parent->appendRow(child); + else + model.appendRow(child); + item = child; + } else { + data += ch; + } + } +} + +class tst_QSortFilterProxyModel_Recursive : public QObject +{ + Q_OBJECT +private: +private Q_SLOTS: + void testInitialFiltering_data() + { + QTest::addColumn<QString>("sourceStr"); + QTest::addColumn<QString>("proxyStr"); + + QTest::newRow("empty") << "[]" << ""; + QTest::newRow("no") << "[1]" << ""; + QTest::newRow("yes") << "[1*]" << "[1*]"; + QTest::newRow("second") << "[1 2*]" << "[2*]"; + QTest::newRow("child_yes") << "[1 2[2.1*]]" << "[2[2.1*]]"; + QTest::newRow("grandchild_yes") << "[1 2[2.1[2.1.1*]]]" << "[2[2.1[2.1.1*]]]"; + // 1, 3.1 and 4.2.1 match, so their parents are in the model + QTest::newRow("more") << "[1* 2[2.1] 3[3.1*] 4[4.1 4.2[4.2.1*]]]" << "[1* 3[3.1*] 4[4.2[4.2.1*]]]"; + } + + void testInitialFiltering() + { + QFETCH(QString, sourceStr); + QFETCH(QString, proxyStr); + + QStandardItemModel model; + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), proxyStr); + } + + // Test changing a role that is unrelated to the filtering. + void testUnrelatedDataChange() + { + QStandardItemModel model; + const QString sourceStr = QStringLiteral("[1[1.1[1.1.1*]]]"); + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), sourceStr); + + ModelSignalSpy spy(proxy); + QStandardItem *item_1_1_1 = model.item(0)->child(0)->child(0); + + // When changing the text on the item + item_1_1_1->setText(QStringLiteral("ME")); + + QCOMPARE(treeAsString(proxy), QStringLiteral("[1[1.1[ME*]]]")); + + QCOMPARE(spy.mSignals, QStringList() + << QStringLiteral("dataChanged(ME)") + << QStringLiteral("dataChanged(1.1)") + << QStringLiteral("dataChanged(1)")); + } + + // Test changing a role that is unrelated to the filtering, in a hidden item. + void testHiddenDataChange() + { + QStandardItemModel model; + const QString sourceStr = QStringLiteral("[1[1.1[1.1.1]]]"); + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), QString()); + + ModelSignalSpy spy(proxy); + QStandardItem *item_1_1_1 = model.item(0)->child(0)->child(0); + + // When changing the text on a hidden item + item_1_1_1->setText(QStringLiteral("ME")); + + QCOMPARE(treeAsString(proxy), QString()); + QCOMPARE(spy.mSignals, QStringList()); + } + + // Test that we properly react to a data-changed signal in a descendant and include all required rows + void testDataChangeIn_data() + { + QTest::addColumn<QString>("sourceStr"); + QTest::addColumn<QString>("initialProxyStr"); + QTest::addColumn<QString>("add"); // set the flag on this item + QTest::addColumn<QString>("expectedProxyStr"); + QTest::addColumn<QStringList>("expectedSignals"); + + QTest::newRow("toplevel") << "[1]" << "" << "1" << "[1*]" + << (QStringList() << QStringLiteral("rowsAboutToBeInserted(1)") << QStringLiteral("rowsInserted(1)")); + QTest::newRow("show_parents") << "[1[1.1[1.1.1]]]" << "" << "1.1.1" << "[1[1.1[1.1.1*]]]" + << (QStringList() << QStringLiteral("rowsAboutToBeInserted(1)") << QStringLiteral("rowsInserted(1)")); + + const QStringList insert_1_1_1 = QStringList() + << QStringLiteral("rowsAboutToBeInserted(1.1.1)") + << QStringLiteral("rowsInserted(1.1.1)") + << QStringLiteral("dataChanged(1.1)") + << QStringLiteral("dataChanged(1)") + ; + QTest::newRow("parent_visible") << "[1[1.1*[1.1.1]]]" << "[1[1.1*]]" << "1.1.1" << "[1[1.1*[1.1.1*]]]" + << insert_1_1_1; + + QTest::newRow("sibling_visible") << "[1[1.1[1.1.1 1.1.2*]]]" << "[1[1.1[1.1.2*]]]" << "1.1.1" << "[1[1.1[1.1.1* 1.1.2*]]]" + << insert_1_1_1; + + QTest::newRow("visible_cousin") << "[1[1.1[1.1.1 1.1.2[1.1.2.1*]]]]" << "[1[1.1[1.1.2[1.1.2.1*]]]]" << "1.1.1" << "[1[1.1[1.1.1* 1.1.2[1.1.2.1*]]]]" + << insert_1_1_1; + + QTest::newRow("show_parent") << "[1[1.1[1.1.1 1.1.2] 1.2*]]" << "[1[1.2*]]" << "1.1.1" << "[1[1.1[1.1.1*] 1.2*]]" + << (QStringList() + << QStringLiteral("rowsAboutToBeInserted(1.1)") + << QStringLiteral("rowsInserted(1.1)") + << QStringLiteral("dataChanged(1)")); + + QTest::newRow("with_children") << "[1[1.1[1.1.1[1.1.1.1*]]] 2*]" << "[1[1.1[1.1.1[1.1.1.1*]]] 2*]" << "1.1.1" << "[1[1.1[1.1.1*[1.1.1.1*]]] 2*]" + << (QStringList() + << QStringLiteral("dataChanged(1.1.1)") + << QStringLiteral("dataChanged(1.1)") + << QStringLiteral("dataChanged(1)")); + + } + + void testDataChangeIn() + { + QFETCH(QString, sourceStr); + QFETCH(QString, initialProxyStr); + QFETCH(QString, add); + QFETCH(QString, expectedProxyStr); + QFETCH(QStringList, expectedSignals); + + QStandardItemModel model; + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), initialProxyStr); + + ModelSignalSpy spy(proxy); + // When changing the data on the designated item to show this row + QStandardItem *itemToChange = itemByText(model, add); + QVERIFY(!itemToChange->data().toBool()); + itemToChange->setData(true); + + // The proxy should update as expected + QCOMPARE(treeAsString(proxy), expectedProxyStr); + + //qDebug() << spy.mSignals; + QCOMPARE(spy.mSignals, expectedSignals); + } + + void testDataChangeOut_data() + { + QTest::addColumn<QString>("sourceStr"); + QTest::addColumn<QString>("initialProxyStr"); + QTest::addColumn<QString>("remove"); // unset the flag on this item + QTest::addColumn<QString>("expectedProxyStr"); + QTest::addColumn<QStringList>("expectedSignals"); + + const QStringList remove1_1_1 = (QStringList() + << QStringLiteral("rowsAboutToBeRemoved(1.1.1)") + << QStringLiteral("rowsRemoved(1.1.1)") + << QStringLiteral("dataChanged(1.1)") + << QStringLiteral("dataChanged(1)")); + + QTest::newRow("toplevel") << "[1*]" << "[1*]" << "1" << "" + << (QStringList() << QStringLiteral("rowsAboutToBeRemoved(1)") << QStringLiteral("rowsRemoved(1)")); + + QTest::newRow("hide_parent") << "[1[1.1[1.1.1*]]]" << "[1[1.1[1.1.1*]]]" << "1.1.1" << "" << + (QStringList() + << QStringLiteral("rowsAboutToBeRemoved(1.1.1)") + << QStringLiteral("rowsRemoved(1.1.1)") + << QStringLiteral("rowsAboutToBeRemoved(1.1)") + << QStringLiteral("rowsRemoved(1.1)") + << QStringLiteral("rowsAboutToBeRemoved(1)") + << QStringLiteral("rowsRemoved(1)")); + + QTest::newRow("parent_visible") << "[1[1.1*[1.1.1*]]]" << "[1[1.1*[1.1.1*]]]" << "1.1.1" << "[1[1.1*]]" + << remove1_1_1; + + QTest::newRow("visible") << "[1[1.1[1.1.1* 1.1.2*]]]" << "[1[1.1[1.1.1* 1.1.2*]]]" << "1.1.1" << "[1[1.1[1.1.2*]]]" + << remove1_1_1; + QTest::newRow("visible_cousin") << "[1[1.1[1.1.1* 1.1.2[1.1.2.1*]]]]" << "[1[1.1[1.1.1* 1.1.2[1.1.2.1*]]]]" << "1.1.1" << "[1[1.1[1.1.2[1.1.2.1*]]]]" + << remove1_1_1; + + // The following tests trigger the removal of an ascendant. + QTest::newRow("remove_parent") << "[1[1.1[1.1.1* 1.1.2] 1.2*]]" << "[1[1.1[1.1.1*] 1.2*]]" << "1.1.1" << "[1[1.2*]]" + << (QStringList() + << QStringLiteral("rowsAboutToBeRemoved(1.1.1)") + << QStringLiteral("rowsRemoved(1.1.1)") + << QStringLiteral("rowsAboutToBeRemoved(1.1)") + << QStringLiteral("rowsRemoved(1.1)") + << QStringLiteral("dataChanged(1)")); + + QTest::newRow("with_children") << "[1[1.1[1.1.1*[1.1.1.1*]]] 2*]" << "[1[1.1[1.1.1*[1.1.1.1*]]] 2*]" << "1.1.1" << "[1[1.1[1.1.1[1.1.1.1*]]] 2*]" + << (QStringList() + << QStringLiteral("dataChanged(1.1.1)") + << QStringLiteral("dataChanged(1.1)") + << QStringLiteral("dataChanged(1)")); + + QTest::newRow("last_visible") << "[1[1.1[1.1.1* 1.1.2]]]" << "[1[1.1[1.1.1*]]]" << "1.1.1" << "" + << (QStringList() + << QStringLiteral("rowsAboutToBeRemoved(1.1.1)") + << QStringLiteral("rowsRemoved(1.1.1)") + << QStringLiteral("rowsAboutToBeRemoved(1.1)") + << QStringLiteral("rowsRemoved(1.1)") + << QStringLiteral("rowsAboutToBeRemoved(1)") + << QStringLiteral("rowsRemoved(1)")); + + } + + void testDataChangeOut() + { + QFETCH(QString, sourceStr); + QFETCH(QString, initialProxyStr); + QFETCH(QString, remove); + QFETCH(QString, expectedProxyStr); + QFETCH(QStringList, expectedSignals); + + QStandardItemModel model; + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), initialProxyStr); + + ModelSignalSpy spy(proxy); + + // When changing the data on the designated item to exclude this row again + QStandardItem *itemToChange = itemByText(model, remove); + QVERIFY(itemToChange->data().toBool()); + itemToChange->setData(false); + + // The proxy should update as expected + QCOMPARE(treeAsString(proxy), expectedProxyStr); + + //qDebug() << spy.mSignals; + QCOMPARE(spy.mSignals, expectedSignals); + } + + void testInsert() + { + QStandardItemModel model; + const QString sourceStr = QStringLiteral("[1[1.1[1.1.1]]]"); + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), QString()); + + ModelSignalSpy spy(proxy); + QStandardItem *item_1_1_1 = model.item(0)->child(0)->child(0); + QStandardItem *item_1_1_1_1 = new QStandardItem(QStringLiteral("1.1.1.1")); + item_1_1_1_1->setData(true); + item_1_1_1->appendRow(item_1_1_1_1); + QCOMPARE(treeAsString(proxy), QStringLiteral("[1[1.1[1.1.1[1.1.1.1*]]]]")); + + QCOMPARE(spy.mSignals, QStringList() << QStringLiteral("rowsAboutToBeInserted(1)") + << QStringLiteral("rowsInserted(1)")); + } + + // Start from [1[1.1[1.1.1 1.1.2[1.1.2.1*]]]] + // where 1.1.1 is hidden but 1.1 is shown, we want to insert a shown child in 1.1.1. + // The proxy ensures dataChanged is called on 1.1, + // so that 1.1.1 and 1.1.1.1 are included in the model. + void testInsertCousin() + { + QStandardItemModel model; + const QString sourceStr = QStringLiteral("[1[1.1[1.1.1 1.1.2[1.1.2.1*]]]]"); + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), QStringLiteral("[1[1.1[1.1.2[1.1.2.1*]]]]")); + + ModelSignalSpy spy(proxy); + { + QStandardItem *item_1_1_1_1 = new QStandardItem(QStringLiteral("1.1.1.1")); + item_1_1_1_1->setData(true); + QStandardItem *item_1_1_1 = model.item(0)->child(0)->child(0); + item_1_1_1->appendRow(item_1_1_1_1); + } + + QCOMPARE(treeAsString(proxy), QStringLiteral("[1[1.1[1.1.1[1.1.1.1*] 1.1.2[1.1.2.1*]]]]")); + //qDebug() << spy.mSignals; + QCOMPARE(spy.mSignals, QStringList() + << QStringLiteral("rowsAboutToBeInserted(1.1.1)") + << QStringLiteral("rowsInserted(1.1.1)") + << QStringLiteral("dataChanged(1.1)") + << QStringLiteral("dataChanged(1)")); + } + + void testInsertWithChildren() + { + QStandardItemModel model; + const QString sourceStr = QStringLiteral("[1[1.1]]"); + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), QString()); + + ModelSignalSpy spy(proxy); + { + QStandardItem *item_1_1_1 = new QStandardItem(QStringLiteral("1.1.1")); + QStandardItem *item_1_1_1_1 = new QStandardItem(QStringLiteral("1.1.1.1")); + item_1_1_1_1->setData(true); + item_1_1_1->appendRow(item_1_1_1_1); + + QStandardItem *item_1_1 = model.item(0)->child(0); + item_1_1->appendRow(item_1_1_1); + } + + QCOMPARE(treeAsString(proxy), QStringLiteral("[1[1.1[1.1.1[1.1.1.1*]]]]")); + QCOMPARE(spy.mSignals, QStringList() + << QStringLiteral("rowsAboutToBeInserted(1)") + << QStringLiteral("rowsInserted(1)")); + } + + void testInsertIntoVisibleWithChildren() + { + QStandardItemModel model; + const QString sourceStr = QStringLiteral("[1[1.1[1.1.1*]]]"); + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), sourceStr); + + ModelSignalSpy spy(proxy); + { + QStandardItem *item_1_1_2 = new QStandardItem(QStringLiteral("1.1.2")); + QStandardItem *item_1_1_2_1 = new QStandardItem(QStringLiteral("1.1.2.1")); + item_1_1_2_1->setData(true); + item_1_1_2->appendRow(item_1_1_2_1); + + QStandardItem *item_1_1 = model.item(0)->child(0); + item_1_1->appendRow(item_1_1_2); + } + + QCOMPARE(treeAsString(proxy), QStringLiteral("[1[1.1[1.1.1* 1.1.2[1.1.2.1*]]]]")); + QCOMPARE(spy.mSignals, QStringList() + << QStringLiteral("rowsAboutToBeInserted(1.1.2)") + << QStringLiteral("rowsInserted(1.1.2)")); + } + + void testInsertBefore() + { + QStandardItemModel model; + const QString sourceStr = "[1[1.1[1.1.2*]]]"; + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), sourceStr); + + ModelSignalSpy spy(proxy); + { + QStandardItem *item_1_1_1 = new QStandardItem("1.1.1"); + + QStandardItem *item_1_1 = model.item(0)->child(0); + item_1_1->insertRow(0, item_1_1_1); + } + + QCOMPARE(treeAsString(proxy), QString("[1[1.1[1.1.2*]]]")); + QCOMPARE(spy.mSignals, QStringList()); + } + + void testInsertHidden() // inserting filtered-out rows shouldn't emit anything + { + QStandardItemModel model; + const QString sourceStr = QStringLiteral("[1[1.1]]"); + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), QString()); + + ModelSignalSpy spy(proxy); + { + QStandardItem *item_1_1_1 = new QStandardItem(QStringLiteral("1.1.1")); + QStandardItem *item_1_1_1_1 = new QStandardItem(QStringLiteral("1.1.1.1")); + item_1_1_1->appendRow(item_1_1_1_1); + + QStandardItem *item_1_1 = model.item(0)->child(0); + item_1_1->appendRow(item_1_1_1); + } + + QCOMPARE(treeAsString(proxy), QString()); + QCOMPARE(spy.mSignals, QStringList()); + } + + void testConsecutiveInserts_data() + { + testInitialFiltering_data(); + } + + void testConsecutiveInserts() + { + QFETCH(QString, sourceStr); + QFETCH(QString, proxyStr); + + QStandardItemModel model; + TestModel proxy(&model); // this time the proxy listens to the model while we fill it + + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + QCOMPARE(treeAsString(proxy), proxyStr); + } + + void testRemove_data() + { + QTest::addColumn<QString>("sourceStr"); + QTest::addColumn<QString>("initialProxyStr"); + QTest::addColumn<QString>("remove"); // remove this item + QTest::addColumn<QString>("expectedProxyStr"); + QTest::addColumn<QStringList>("expectedSignals"); + + const QStringList remove1_1_1 = (QStringList() << QStringLiteral("rowsAboutToBeRemoved(1.1.1)") << QStringLiteral("rowsRemoved(1.1.1)")); + + QTest::newRow("toplevel") << "[1* 2* 3*]" << "[1* 2* 3*]" << "1" << "[2* 3*]" + << (QStringList() << QStringLiteral("rowsAboutToBeRemoved(1)") << QStringLiteral("rowsRemoved(1)")); + + QTest::newRow("remove_hidden") << "[1 2* 3*]" << "[2* 3*]" << "1" << "[2* 3*]" << QStringList(); + + QTest::newRow("parent_hidden") << "[1[1.1[1.1.1]]]" << "" << "1.1.1" << "" << QStringList(); + + QTest::newRow("child_hidden") << "[1[1.1*[1.1.1]]]" << "[1[1.1*]]" << "1.1.1" << "[1[1.1*]]" << QStringList(); + + QTest::newRow("parent_visible") << "[1[1.1*[1.1.1*]]]" << "[1[1.1*[1.1.1*]]]" << "1.1.1" << "[1[1.1*]]" + << remove1_1_1; + + QTest::newRow("visible") << "[1[1.1[1.1.1* 1.1.2*]]]" << "[1[1.1[1.1.1* 1.1.2*]]]" << "1.1.1" << "[1[1.1[1.1.2*]]]" + << remove1_1_1; + QTest::newRow("visible_cousin") << "[1[1.1[1.1.1* 1.1.2[1.1.2.1*]]]]" << "[1[1.1[1.1.1* 1.1.2[1.1.2.1*]]]]" << "1.1.1" << "[1[1.1[1.1.2[1.1.2.1*]]]]" + << remove1_1_1; + + // The following tests trigger the removal of an ascendant. + // We could optimize the rows{AboutToBe,}Removed(1.1.1) away... + + QTest::newRow("remove_parent") << "[1[1.1[1.1.1* 1.1.2] 1.2*]]" << "[1[1.1[1.1.1*] 1.2*]]" << "1.1.1" << "[1[1.2*]]" + << (QStringList() + << QStringLiteral("rowsAboutToBeRemoved(1.1.1)") + << QStringLiteral("rowsRemoved(1.1.1)") + << QStringLiteral("rowsAboutToBeRemoved(1.1)") + << QStringLiteral("rowsRemoved(1.1)") + << QStringLiteral("dataChanged(1)")); + + QTest::newRow("with_children") << "[1[1.1[1.1.1[1.1.1.1*]]] 2*]" << "[1[1.1[1.1.1[1.1.1.1*]]] 2*]" << "1.1.1" << "[2*]" + << (QStringList() + << QStringLiteral("rowsAboutToBeRemoved(1.1.1)") + << QStringLiteral("rowsRemoved(1.1.1)") + << QStringLiteral("rowsAboutToBeRemoved(1)") + << QStringLiteral("rowsRemoved(1)")); + + QTest::newRow("last_visible") << "[1[1.1[1.1.1* 1.1.2]]]" << "[1[1.1[1.1.1*]]]" << "1.1.1" << "" + << (QStringList() + << QStringLiteral("rowsAboutToBeRemoved(1.1.1)") + << QStringLiteral("rowsRemoved(1.1.1)") + << QStringLiteral("rowsAboutToBeRemoved(1)") + << QStringLiteral("rowsRemoved(1)")); + + + } + + void testRemove() + { + QFETCH(QString, sourceStr); + QFETCH(QString, initialProxyStr); + QFETCH(QString, remove); + QFETCH(QString, expectedProxyStr); + QFETCH(QStringList, expectedSignals); + + QStandardItemModel model; + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), initialProxyStr); + + ModelSignalSpy spy(proxy); + QStandardItem *itemToRemove = itemByText(model, remove); + QVERIFY(itemToRemove); + if (itemToRemove->parent()) + itemToRemove->parent()->removeRow(itemToRemove->row()); + else + model.removeRow(itemToRemove->row()); + QCOMPARE(treeAsString(proxy), expectedProxyStr); + + //qDebug() << spy.mSignals; + QCOMPARE(spy.mSignals, expectedSignals); + } + + void testStandardFiltering_data() + { + QTest::addColumn<QString>("sourceStr"); + QTest::addColumn<QString>("initialProxyStr"); + QTest::addColumn<QString>("filter"); + QTest::addColumn<QString>("expectedProxyStr"); + + QTest::newRow("select_child") << "[1[1.1[1.1.1* 1.1.2*]]]" << "[1[1.1[1.1.1* 1.1.2*]]]" + << "1.1.2" << "[1[1.1[1.1.2*]]]"; + + QTest::newRow("filter_all_out") << "[1[1.1[1.1.1*]]]" << "[1[1.1[1.1.1*]]]" + << "test" << ""; + + QTest::newRow("select_parent") << "[1[1.1[1.1.1*[child*] 1.1.2*]]]" << "[1[1.1[1.1.1*[child*] 1.1.2*]]]" + << "1.1.1" << "[1[1.1[1.1.1*]]]"; + + } + + void testStandardFiltering() + { + QFETCH(QString, sourceStr); + QFETCH(QString, initialProxyStr); + QFETCH(QString, filter); + QFETCH(QString, expectedProxyStr); + + QStandardItemModel model; + fillModel(model, sourceStr); + QCOMPARE(treeAsString(model), sourceStr); + + TestModel proxy(&model); + QCOMPARE(treeAsString(proxy), initialProxyStr); + + ModelSignalSpy spy(proxy); + + //qDebug() << "setFilterFixedString"; + proxy.setFilterFixedString(filter); + + QCOMPARE(treeAsString(proxy), expectedProxyStr); + + } + +private: + QStandardItem *itemByText(const QStandardItemModel& model, const QString &text) const { + QModelIndexList list = model.match(model.index(0, 0), Qt::DisplayRole, text, 1, Qt::MatchRecursive); + return list.isEmpty() ? 0 : model.itemFromIndex(list.first()); + } +}; + +QTEST_GUILESS_MAIN(tst_QSortFilterProxyModel_Recursive) +#include "tst_qsortfilterproxymodel_recursive.moc" diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index f693d14029..78833d08bd 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -155,7 +155,9 @@ void tst_QMetaType::defined() QCOMPARE(int(QMetaTypeId2<int*>::Defined), 0); QCOMPARE(int(QMetaTypeId2<CustomQObject::CustomQEnum>::Defined), 1); QCOMPARE(int(QMetaTypeId2<CustomGadget>::Defined), 1); + QCOMPARE(int(QMetaTypeId2<CustomGadget*>::Defined), 1); QVERIFY(!QMetaTypeId2<GadgetDerived>::Defined); + QVERIFY(!QMetaTypeId2<GadgetDerived*>::Defined); QVERIFY(int(QMetaTypeId2<CustomQObject*>::Defined)); QVERIFY(!QMetaTypeId2<CustomQObject>::Defined); QVERIFY(!QMetaTypeId2<CustomNonQObject>::Defined); @@ -397,6 +399,7 @@ void tst_QMetaType::typeName_data() QTest::newRow("CustomQObject*") << ::qMetaTypeId<CustomQObject*>() << QString::fromLatin1("CustomQObject*"); QTest::newRow("CustomGadget") << ::qMetaTypeId<CustomGadget>() << QString::fromLatin1("CustomGadget"); + QTest::newRow("CustomGadget*") << ::qMetaTypeId<CustomGadget*>() << QString::fromLatin1("CustomGadget*"); QTest::newRow("CustomQObject::CustomQEnum") << ::qMetaTypeId<CustomQObject::CustomQEnum>() << QString::fromLatin1("CustomQObject::CustomQEnum"); QTest::newRow("Qt::ArrowType") << ::qMetaTypeId<Qt::ArrowType>() << QString::fromLatin1("Qt::ArrowType"); } @@ -1679,6 +1682,7 @@ public: }; Q_DECLARE_METATYPE(MyGadget); +Q_DECLARE_METATYPE(MyGadget*); Q_DECLARE_METATYPE(const QMetaObject *); Q_DECLARE_METATYPE(Qt::ScrollBarPolicy); Q_DECLARE_METATYPE(MyGadget::MyEnum); @@ -1688,16 +1692,18 @@ void tst_QMetaType::metaObject_data() QTest::addColumn<int>("type"); QTest::addColumn<const QMetaObject*>("result"); QTest::addColumn<bool>("isGadget"); + QTest::addColumn<bool>("isGadgetPtr"); QTest::addColumn<bool>("isQObjectPtr"); - QTest::newRow("QObject") << int(QMetaType::QObjectStar) << &QObject::staticMetaObject << false << true; - QTest::newRow("QFile*") << ::qMetaTypeId<QFile*>() << &QFile::staticMetaObject << false << true; - QTest::newRow("MyObject*") << ::qMetaTypeId<MyObject*>() << &MyObject::staticMetaObject << false << true; - QTest::newRow("int") << int(QMetaType::Int) << static_cast<const QMetaObject *>(0) << false << false; - QTest::newRow("QEasingCurve") << ::qMetaTypeId<QEasingCurve>() << &QEasingCurve::staticMetaObject << true << false; - QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false; - QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false; - QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false; + QTest::newRow("QObject") << int(QMetaType::QObjectStar) << &QObject::staticMetaObject << false << false << true; + QTest::newRow("QFile*") << ::qMetaTypeId<QFile*>() << &QFile::staticMetaObject << false << false << true; + QTest::newRow("MyObject*") << ::qMetaTypeId<MyObject*>() << &MyObject::staticMetaObject << false << false << true; + QTest::newRow("int") << int(QMetaType::Int) << static_cast<const QMetaObject *>(0) << false << false << false; + QTest::newRow("QEasingCurve") << ::qMetaTypeId<QEasingCurve>() << &QEasingCurve::staticMetaObject << true << false << false; + QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false << false; + QTest::newRow("MyGadget*") << ::qMetaTypeId<MyGadget*>() << &MyGadget::staticMetaObject << false << true << false; + QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false << false; + QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false << false; } @@ -1706,12 +1712,14 @@ void tst_QMetaType::metaObject() QFETCH(int, type); QFETCH(const QMetaObject *, result); QFETCH(bool, isGadget); + QFETCH(bool, isGadgetPtr); QFETCH(bool, isQObjectPtr); QCOMPARE(QMetaType::metaObjectForType(type), result); QMetaType mt(type); QCOMPARE(mt.metaObject(), result); QCOMPARE(!!(mt.flags() & QMetaType::IsGadget), isGadget); + QCOMPARE(!!(mt.flags() & QMetaType::PointerToGadget), isGadgetPtr); QCOMPARE(!!(mt.flags() & QMetaType::PointerToQObject), isQObjectPtr); } diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index a546cad225..37b052bf1d 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -1205,8 +1205,6 @@ void tst_QFuture::pause() Interface.reportFinished(); } -const int resultCount = 1000; - class ResultObject : public QObject { Q_OBJECT diff --git a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp index 2970b2e118..ba470a77c9 100644 --- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp +++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp @@ -42,6 +42,7 @@ private slots: void tryAcquireWithTimeout(); void tryAcquireWithTimeoutStarvation(); void producerConsumer(); + void raii(); }; static QSemaphore *semaphore = 0; @@ -417,5 +418,54 @@ void tst_QSemaphore::producerConsumer() consumer.wait(); } +void tst_QSemaphore::raii() +{ + QSemaphore sem; + + QCOMPARE(sem.available(), 0); + + // basic operation: + { + QSemaphoreReleaser r0; + const QSemaphoreReleaser r1(sem); + const QSemaphoreReleaser r2(sem, 2); + + QCOMPARE(r0.semaphore(), nullptr); + QCOMPARE(r1.semaphore(), &sem); + QCOMPARE(r2.semaphore(), &sem); + } + + QCOMPARE(sem.available(), 3); + + // cancel: + { + const QSemaphoreReleaser r1(sem); + QSemaphoreReleaser r2(sem, 2); + + QCOMPARE(r2.cancel(), &sem); + QCOMPARE(r2.semaphore(), nullptr); + } + + QCOMPARE(sem.available(), 4); + + // move-assignment: + { + const QSemaphoreReleaser r1(sem); + QSemaphoreReleaser r2(sem, 2); + + QCOMPARE(sem.available(), 4); + + r2 = QSemaphoreReleaser(); + + QCOMPARE(sem.available(), 6); + + r2 = QSemaphoreReleaser(sem, 42); + + QCOMPARE(sem.available(), 6); + } + + QCOMPARE(sem.available(), 49); +} + QTEST_MAIN(tst_QSemaphore) #include "tst_qsemaphore.moc" diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index fdc4ecb5c8..1dcd642023 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -961,21 +961,6 @@ void tst_QThreadPool::cancel() QSemaphore sem(0); QSemaphore startedThreads(0); - class SemaphoreReleaser - { - QSemaphore &sem; - int n; - Q_DISABLE_COPY(SemaphoreReleaser) - public: - explicit SemaphoreReleaser(QSemaphore &sem, int n) - : sem(sem), n(n) {} - - ~SemaphoreReleaser() - { - sem.release(n); - } - }; - class BlockingRunnable : public QRunnable { public: @@ -1014,7 +999,7 @@ void tst_QThreadPool::cancel() // ensure that the QThreadPool doesn't deadlock if any of the checks fail // and cause an early return: - const SemaphoreReleaser semReleaser(sem, runs); + const QSemaphoreReleaser semReleaser(sem, runs); count.store(0); QAtomicInt dtorCounter = 0; @@ -1048,21 +1033,6 @@ void tst_QThreadPool::tryTake() QSemaphore sem(0); QSemaphore startedThreads(0); - class SemaphoreReleaser - { - QSemaphore &sem; - int n; - Q_DISABLE_COPY(SemaphoreReleaser) - public: - explicit SemaphoreReleaser(QSemaphore &sem, int n) - : sem(sem), n(n) {} - - ~SemaphoreReleaser() - { - sem.release(n); - } - }; - class BlockingRunnable : public QRunnable { public: @@ -1101,7 +1071,7 @@ void tst_QThreadPool::tryTake() // ensure that the QThreadPool doesn't deadlock if any of the checks fail // and cause an early return: - const SemaphoreReleaser semReleaser(sem, Runs); + const QSemaphoreReleaser semReleaser(sem, Runs); count.store(0); QAtomicInt dtorCounter = 0; diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp index 13898ace7b..dede56b4bf 100644 --- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp +++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp @@ -36,6 +36,8 @@ class tst_QChar : public QObject { Q_OBJECT private slots: + void fromChar16_t(); + void fromWchar_t(); void operator_eqeq_int(); void operators_data(); void operators(); @@ -75,6 +77,30 @@ private slots: QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED +void tst_QChar::fromChar16_t() +{ +#if !defined(Q_OS_WIN) || defined(Q_COMPILER_UNICODE_STRINGS) + QChar aUmlaut = u'\u00E4'; // German small letter a-umlaut + QCOMPARE(aUmlaut, QChar(0xE4)); + QChar replacementCharacter = u'\uFFFD'; + QCOMPARE(replacementCharacter, QChar(QChar::ReplacementCharacter)); +#else + QSKIP("This test requires C++11 char16_t support enabled in the compiler."); +#endif +} + +void tst_QChar::fromWchar_t() +{ +#if defined(Q_OS_WIN) + QChar aUmlaut = L'\u00E4'; // German small letter a-umlaut + QCOMPARE(aUmlaut, QChar(0xE4)); + QChar replacementCharacter = L'\uFFFD'; + QCOMPARE(replacementCharacter, QChar(QChar::ReplacementCharacter)); +#else + QSKIP("This is a Windows-only test."); +#endif +} + void tst_QChar::operator_eqeq_int() { { diff --git a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp b/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp index a68671d899..c8373b6ae9 100644 --- a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp +++ b/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp @@ -48,6 +48,7 @@ private Q_SLOTS: void midLeftRight(); void nullString(); void emptyString(); + void iterators(); void relationalOperators_data(); void relationalOperators(); }; @@ -155,6 +156,22 @@ void tst_QLatin1String::emptyString() } } +void tst_QLatin1String::iterators() +{ + QLatin1String hello("hello"); + QLatin1String olleh("olleh"); + + QVERIFY(std::equal(hello.begin(), hello.end(), + olleh.rbegin())); + QVERIFY(std::equal(hello.rbegin(), hello.rend(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size()))); + + QVERIFY(std::equal(hello.cbegin(), hello.cend(), + olleh.rbegin())); + QVERIFY(std::equal(hello.crbegin(), hello.crend(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size()))); +} + void tst_QLatin1String::relationalOperators_data() { QTest::addColumn<QLatin1StringContainer>("lhs"); diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 03436375dd..3f118d04ce 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -6067,14 +6067,6 @@ void tst_QString::compare_data() lower += QChar(QChar::lowSurrogate(0x10428)); QTest::newRow("data8") << upper << lower << -1 << 0; - QTest::newRow("vectorized-boundaries-7") << QString("1234567") << QString("abcdefg") << -1 << -1; - QTest::newRow("vectorized-boundaries-8") << QString("12345678") << QString("abcdefgh") << -1 << -1; - QTest::newRow("vectorized-boundaries-9") << QString("123456789") << QString("abcdefghi") << -1 << -1; - - QTest::newRow("vectorized-boundaries-15") << QString("123456789012345") << QString("abcdefghiklmnop") << -1 << -1; - QTest::newRow("vectorized-boundaries-16") << QString("1234567890123456") << QString("abcdefghiklmnopq") << -1 << -1; - QTest::newRow("vectorized-boundaries-17") << QString("12345678901234567") << QString("abcdefghiklmnopqr") << -1 << -1; - // embedded nulls // These don't work as of now. It's OK that these don't work since \0 is not a valid unicode /*QTest::newRow("data10") << QString(QByteArray("\0", 1)) << QString(QByteArray("\0", 1)) << 0 << 0; @@ -6083,6 +6075,44 @@ void tst_QString::compare_data() QTest::newRow("data13") << QString("ab\0c") << QString(QByteArray("ab\0c", 4)) << 0 << 0; QTest::newRow("data14") << QString(QByteArray("ab\0c", 4)) << QString("abc") << -1 << -1; QTest::newRow("data15") << QString("abc") << QString(QByteArray("ab\0c", 4)) << 1 << 1;*/ + + // All tests below (generated by the 3 for-loops) are meant to excercise the vectorized versions + // of ucstrncmp. + + QString in1, in2; + for (int i = 0; i < 70; ++i) { + in1 += QString::number(i % 10); + in2 += QString::number((70 - i + 1) % 10); + } + Q_ASSERT(in1.length() == in2.length()); + Q_ASSERT(in1 != in2); + Q_ASSERT(in1.at(0) < in2.at(0)); + for (int i = 0; i < in1.length(); ++i) { + Q_ASSERT(in1.at(i) != in2.at(i)); + } + + for (int i = 1; i <= 65; ++i) { + QString inp1 = in1.left(i); + QString inp2 = in2.left(i); + QTest::addRow("all-different-%d", i) << inp1 << inp2 << -1 << -1; + } + + for (int i = 1; i <= 65; ++i) { + QString start(i - 1, 'a'); + + QString in = start + QLatin1Char('a'); + QTest::addRow("all-same-%d", i) << in << in << 0 << 0; + + QString in2 = start + QLatin1Char('b'); + QTest::addRow("last-different-%d", i) << in << in2 << -1 << -1; + } + + for (int i = 0; i < 16; ++i) { + QString in1(16, 'a'); + QString in2 = in1; + in2[i] = 'b'; + QTest::addRow("all-same-except-char-%d", i) << in1 << in2 << -1 << -1; + } } static bool isLatin(const QString &s) diff --git a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp index 9d9b47b61e..36f479ca01 100644 --- a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -160,6 +160,45 @@ private Q_SLOTS: //void compare_const_char_star_const_char_star_data() { compare_data(); } //void compare_const_char_star_const_char_star() { compare_impl<const char *, const char *>(); } +private: + void mid_data(); + template <typename String> void mid_impl(); + + void left_data(); + template <typename String> void left_impl(); + + void right_data(); + template <typename String> void right_impl(); + +private Q_SLOTS: + + void mid_QString_data() { mid_data(); } + void mid_QString() { mid_impl<QString>(); } + void mid_QStringRef_data() { mid_data(); } + void mid_QStringRef() { mid_impl<QStringRef>(); } + void mid_QLatin1String_data() { mid_data(); } + void mid_QLatin1String() { mid_impl<QLatin1String>(); } + void mid_QByteArray_data() { mid_data(); } + void mid_QByteArray() { mid_impl<QByteArray>(); } + + void left_QString_data() { left_data(); } + void left_QString() { left_impl<QString>(); } + void left_QStringRef_data() { left_data(); } + void left_QStringRef() { left_impl<QStringRef>(); } + void left_QLatin1String_data() { left_data(); } + void left_QLatin1String() { left_impl<QLatin1String>(); } + void left_QByteArray_data() { left_data(); } + void left_QByteArray() { left_impl<QByteArray>(); } + + void right_QString_data() { right_data(); } + void right_QString() { right_impl<QString>(); } + void right_QStringRef_data() { right_data(); } + void right_QStringRef() { right_impl<QStringRef>(); } + void right_QLatin1String_data() { right_data(); } + void right_QLatin1String() { right_impl<QLatin1String>(); } + void right_QByteArray_data() { right_data(); } + void right_QByteArray() { right_impl<QByteArray>(); } + // // UTF-16-only checks: // @@ -300,6 +339,178 @@ void tst_QStringApiSymmetry::compare_impl() const #undef CHECK } +static QString empty = QLatin1String(""); +// the tests below rely on the fact that these objects' names match their contents: +static QString a = QStringLiteral("a"); +static QString b = QStringLiteral("b"); +static QString c = QStringLiteral("c"); +static QString ab = QStringLiteral("ab"); +static QString bc = QStringLiteral("bc"); +static QString abc = QStringLiteral("abc"); + +void tst_QStringApiSymmetry::mid_data() +{ + QTest::addColumn<QStringRef>("unicode"); + QTest::addColumn<QLatin1String>("latin1"); + QTest::addColumn<int>("pos"); + QTest::addColumn<int>("n"); + QTest::addColumn<QStringRef>("result"); + QTest::addColumn<QStringRef>("result2"); + + QTest::addRow("null") << QStringRef() << QLatin1String() << 0 << 0 << QStringRef() << QStringRef(); + QTest::addRow("empty") << QStringRef(&empty) << QLatin1String("") << 0 << 0 << QStringRef(&empty) << QStringRef(&empty); + + // Some classes' mid() implementations have a wide contract, others a narrow one + // so only test valid arguents here: +#define ROW(base, p, n, r1, r2) \ + QTest::addRow("%s%d%d", #base, p, n) << QStringRef(&base) << QLatin1String(#base) << p << n << QStringRef(&r1) << QStringRef(&r2) + + ROW(a, 0, 0, a, empty); + ROW(a, 0, 1, a, a); + ROW(a, 1, 0, empty, empty); + + ROW(ab, 0, 0, ab, empty); + ROW(ab, 0, 1, ab, a); + ROW(ab, 0, 2, ab, ab); + ROW(ab, 1, 0, b, empty); + ROW(ab, 1, 1, b, b); + ROW(ab, 2, 0, empty, empty); + + ROW(abc, 0, 0, abc, empty); + ROW(abc, 0, 1, abc, a); + ROW(abc, 0, 2, abc, ab); + ROW(abc, 0, 3, abc, abc); + ROW(abc, 1, 0, bc, empty); + ROW(abc, 1, 1, bc, b); + ROW(abc, 1, 2, bc, bc); + ROW(abc, 2, 0, c, empty); + ROW(abc, 2, 1, c, c); + ROW(abc, 3, 0, empty, empty); +#undef ROW +} + +template <typename String> +void tst_QStringApiSymmetry::mid_impl() +{ + QFETCH(const QStringRef, unicode); + QFETCH(const QLatin1String, latin1); + QFETCH(const int, pos); + QFETCH(const int, n); + QFETCH(const QStringRef, result); + QFETCH(const QStringRef, result2); + + const auto utf8 = unicode.toUtf8(); + + const auto s = make<String>(unicode, latin1, utf8); + + const auto mid = s.mid(pos); + const auto mid2 = s.mid(pos, n); + + QVERIFY(mid == result); + QCOMPARE(mid.isNull(), result.isNull()); + QCOMPARE(mid.isEmpty(), result.isEmpty()); + + QVERIFY(mid2 == result2); + QCOMPARE(mid2.isNull(), result2.isNull()); + QCOMPARE(mid2.isEmpty(), result2.isEmpty()); +} + +void tst_QStringApiSymmetry::left_data() +{ + QTest::addColumn<QStringRef>("unicode"); + QTest::addColumn<QLatin1String>("latin1"); + QTest::addColumn<int>("n"); + QTest::addColumn<QStringRef>("result"); + + QTest::addRow("null") << QStringRef() << QLatin1String() << 0 << QStringRef(); + QTest::addRow("empty") << QStringRef(&empty) << QLatin1String("") << 0 << QStringRef(&empty); + + // Some classes' left() implementations have a wide contract, others a narrow one + // so only test valid arguents here: +#define ROW(base, n, res) \ + QTest::addRow("%s%d", #base, n) << QStringRef(&base) << QLatin1String(#base) << n << QStringRef(&res); + + ROW(a, 0, empty); + ROW(a, 1, a); + + ROW(ab, 0, empty); + ROW(ab, 1, a); + ROW(ab, 2, ab); + + ROW(abc, 0, empty); + ROW(abc, 1, a); + ROW(abc, 2, ab); + ROW(abc, 3, abc); +#undef ROW +} + +template <typename String> +void tst_QStringApiSymmetry::left_impl() +{ + QFETCH(const QStringRef, unicode); + QFETCH(const QLatin1String, latin1); + QFETCH(const int, n); + QFETCH(const QStringRef, result); + + const auto utf8 = unicode.toUtf8(); + + const auto s = make<String>(unicode, latin1, utf8); + + const auto left = s.left(n); + + QVERIFY(left == result); + QCOMPARE(left.isNull(), result.isNull()); + QCOMPARE(left.isEmpty(), result.isEmpty()); +} + +void tst_QStringApiSymmetry::right_data() +{ + QTest::addColumn<QStringRef>("unicode"); + QTest::addColumn<QLatin1String>("latin1"); + QTest::addColumn<int>("n"); + QTest::addColumn<QStringRef>("result"); + + QTest::addRow("null") << QStringRef() << QLatin1String() << 0 << QStringRef(); + QTest::addRow("empty") << QStringRef(&empty) << QLatin1String("") << 0 << QStringRef(&empty); + + // Some classes' right() implementations have a wide contract, others a narrow one + // so only test valid arguents here: +#define ROW(base, n, res) \ + QTest::addRow("%s%d", #base, n) << QStringRef(&base) << QLatin1String(#base) << n << QStringRef(&res); + + ROW(a, 0, empty); + ROW(a, 1, a); + + ROW(ab, 0, empty); + ROW(ab, 1, b); + ROW(ab, 2, ab); + + ROW(abc, 0, empty); + ROW(abc, 1, c); + ROW(abc, 2, bc); + ROW(abc, 3, abc); +#undef ROW +} + +template <typename String> +void tst_QStringApiSymmetry::right_impl() +{ + QFETCH(const QStringRef, unicode); + QFETCH(const QLatin1String, latin1); + QFETCH(const int, n); + QFETCH(const QStringRef, result); + + const auto utf8 = unicode.toUtf8(); + + const auto s = make<String>(unicode, latin1, utf8); + + const auto right = s.right(n); + + QVERIFY(right == result); + QCOMPARE(right.isNull(), result.isNull()); + QCOMPARE(right.isEmpty(), result.isEmpty()); +} + // // // UTF-16-only checks: diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp index 0806ad1318..3971353cbb 100644 --- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp +++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp @@ -30,8 +30,6 @@ #include <qvarlengtharray.h> #include <qvariant.h> -const int N = 1; - class tst_QVarLengthArray : public QObject { Q_OBJECT diff --git a/tests/auto/gui/gui.pro b/tests/auto/gui/gui.pro index 2fd3024afe..d7cda11513 100644 --- a/tests/auto/gui/gui.pro +++ b/tests/auto/gui/gui.pro @@ -9,8 +9,11 @@ SUBDIRS = \ painting \ qopenglconfig \ qopengl \ + qvulkan \ text \ util \ itemmodels \ !qtConfig(opengl): SUBDIRS -= qopengl qopenglconfig + +!qtConfig(vulkan): SUBDIRS -= qvulkan diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp index d628fad705..ecf8c033b5 100644 --- a/tests/auto/gui/image/qicon/tst_qicon.cpp +++ b/tests/auto/gui/image/qicon/tst_qicon.cpp @@ -530,16 +530,6 @@ void tst_QIcon::streamAvailableSizes() } } - -static inline bool operator<(const QSize &lhs, const QSize &rhs) -{ - if (lhs.width() < rhs.width()) - return true; - else if (lhs.width() == lhs.width()) - return lhs.height() < lhs.height(); - return false; -} - #ifndef QT_NO_WIDGETS void tst_QIcon::task184901_badCache() { diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index d5c624833c..2381fd9246 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -77,6 +77,9 @@ private slots: void saveWithNoFormat(); void saveToTemporaryFile(); + + void writeEmpty(); + private: QTemporaryDir m_temporaryDir; QString prefix; @@ -529,5 +532,18 @@ void tst_QImageWriter::saveToTemporaryFile() } } +void tst_QImageWriter::writeEmpty() +{ + // check writing a null QImage errors gracefully + QTemporaryDir dir; + QVERIFY2(dir.isValid(), qPrintable(dir.errorString())); + QString fileName(dir.path() + QLatin1String("/testimage.bmp")); + QVERIFY(!QFileInfo(fileName).exists()); + QImageWriter writer(fileName); + QVERIFY(!writer.write(QImage())); + QCOMPARE(writer.error(), QImageWriter::InvalidImageError); + QVERIFY(!QFileInfo(fileName).exists()); +} + QTEST_MAIN(tst_QImageWriter) #include "tst_qimagewriter.moc" diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp index 6394a956bd..f8b6bf064a 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -36,14 +36,18 @@ #include <QLibraryInfo> #ifdef Q_OS_MAC -#ifdef Q_OS_OSX -#include <Carbon/Carbon.h> -#endif struct MacSpecialKey { int key; ushort macSymbol; }; +// Unicode code points for the glyphs associated with these keys +// Defined by Carbon headers but not anywhere in Cocoa +static const int kShiftUnicode = 0x21E7; +static const int kControlUnicode = 0x2303; +static const int kOptionUnicode = 0x2325; +static const int kCommandUnicode = 0x2318; + static const int NumEntries = 21; static const MacSpecialKey entries[NumEntries] = { { Qt::Key_Escape, 0x238B }, @@ -61,12 +65,10 @@ static const MacSpecialKey entries[NumEntries] = { { Qt::Key_Down, 0x2193 }, { Qt::Key_PageUp, 0x21DE }, { Qt::Key_PageDown, 0x21DF }, -#ifdef Q_OS_OSX { Qt::Key_Shift, kShiftUnicode }, { Qt::Key_Control, kCommandUnicode }, { Qt::Key_Meta, kControlUnicode }, { Qt::Key_Alt, kOptionUnicode }, -#endif { Qt::Key_CapsLock, 0x21EA }, }; diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 3562bc63f4..7f72fb04f2 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -397,51 +397,6 @@ void tst_QPainter::cleanupTestCase() QFile::remove(QLatin1String("foo.png")); } -static const char* const maskSource_data[] = { -"16 13 6 1", -". c None", -"d c #000000", -"# c #999999", -"c c #cccccc", -"b c #ffff00", -"a c #ffffff", -"...#####........", -"..#aaaaa#.......", -".#abcbcba######.", -".#acbcbcaaaaaa#d", -".#abcbcbcbcbcb#d", -"#############b#d", -"#aaaaaaaaaa##c#d", -"#abcbcbcbcbbd##d", -".#abcbcbcbcbcd#d", -".#acbcbcbcbcbd#d", -"..#acbcbcbcbb#dd", -"..#############d", -"...ddddddddddddd"}; - -static const char* const maskResult_data[] = { -"16 13 6 1", -". c #ff0000", -"d c #000000", -"# c #999999", -"c c #cccccc", -"b c #ffff00", -"a c #ffffff", -"...#####........", -"..#aaaaa#.......", -".#abcbcba######.", -".#acbcbcaaaaaa#d", -".#abcbcbcbcbcb#d", -"#############b#d", -"#aaaaaaaaaa##c#d", -"#abcbcbcbcbbd##d", -".#abcbcbcbcbcd#d", -".#acbcbcbcbcbd#d", -"..#acbcbcbcbb#dd", -"..#############d", -"...ddddddddddddd"}; - - #ifndef QT_NO_WIDGETS void tst_QPainter::drawPixmap_comp_data() { diff --git a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp index a79526c434..46420b49c5 100644 --- a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp +++ b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp @@ -118,127 +118,96 @@ void tst_QWMatrix::mapping_data() #define M_PI 3.14159265897932384626433832795f #endif + const auto rotate = [](qreal degrees) { + const qreal rad = M_PI * degrees / 180.; + return QMatrix(std::cos(rad), -std::sin(rad), + std::sin(rad), std::cos(rad), 0, 0); + }; + // rotations - float deg = 0.; - QTest::newRow( "rot 0 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 a" ) << rotate(0.) << QRect( 0, 0, 30, 40 ) << QPolygon ( QRect( 0, 0, 30, 40 ) ); - deg = 0.00001f; - QTest::newRow( "rot 0 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 b" ) << rotate(0.00001f) << QRect( 0, 0, 30, 40 ) << QPolygon ( QRect( 0, 0, 30, 40 ) ); - deg = 0.; - QTest::newRow( "rot 0 c" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 c" ) << rotate(0.) << QRect( 10, 20, 30, 40 ) << QPolygon ( QRect( 10, 20, 30, 40 ) ); - deg = 0.00001f; - QTest::newRow( "rot 0 d" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 d" ) << rotate(0.00001f) << QRect( 10, 20, 30, 40 ) << QPolygon ( QRect( 10, 20, 30, 40 ) ); #if 0 - // rotations - deg = 90.; - QTest::newRow( "rotscale 90 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + const auto rotScale = [](qreal degrees, qreal scale) { + const qreal rad = M_PI * degrees / 180.; + return QMatrix(scale * std::cos(rad), -scale * std::sin(rad), + scale * std::sin(rad), scale * std::cos(rad), 0, 0); + }; + // rotations with scaling + QTest::newRow( "rotscale 90 a" ) << rotScale(90., 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -299, 400, 300 ) ); - deg = 90.00001; - QTest::newRow( "rotscale 90 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 b" ) << rotScale(90.00001, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -299, 400, 300 ) ); - deg = 90.; - QTest::newRow( "rotscale 90 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 c" ) << rotScale(90., 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 200, -399, 400, 300 ) ); - deg = 90.00001; - QTest::newRow( "rotscale 90 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 d" ) << rotScale(90.00001, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 200, -399, 400, 300 ) ); - deg = 180.; - QTest::newRow( "rotscale 180 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 a" ) << rotScale(180., 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -299, -399, 300, 400 ) ); - deg = 180.000001; - QTest::newRow( "rotscale 180 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 b" ) << rotScale(180.000001, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -299, -399, 300, 400 ) ); - deg = 180.; - QTest::newRow( "rotscale 180 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 c" ) << rotScale(180., 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -399, -599, 300, 400 ) ); - deg = 180.000001; - QTest::newRow( "rotscale 180 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 d" ) << rotScale(180.000001, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -399, -599, 300, 400 ) ); - deg = 270.; - QTest::newRow( "rotscale 270 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 a" ) << rotScale(270., 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -399, 00, 400, 300 ) ); - deg = 270.0000001; - QTest::newRow( "rotscale 270 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 b" ) << rotScale(270.0000001, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -399, 00, 400, 300 ) ); - deg = 270.; - QTest::newRow( "rotscale 270 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 c" ) << rotScale(270., 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -599, 100, 400, 300 ) ); - deg = 270.000001; - QTest::newRow( "rotscale 270 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 d" ) << rotScale(270.000001, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -599, 100, 400, 300 ) ); // rotations that are not multiples of 90 degrees. mapRect returns the bounding rect here. - deg = 45; - QTest::newRow( "rot 45 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 a" ) << rotate(45) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( 0, -7, 14, 14 ) ); - QTest::newRow( "rot 45 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 b" ) << rotate(45) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 21, -14, 49, 49 ) ); - QTest::newRow( "rot 45 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 c" ) << rotScale(45, 10) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( 0, -70, 141, 141 ) ); - QTest::newRow( "rot 45 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 d" ) << rotScale(45, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 212, -141, 495, 495 ) ); - deg = -45; - QTest::newRow( "rot -45 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 a" ) << rotate(-45) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( -7, 0, 14, 14 ) ); - QTest::newRow( "rot -45 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 b" ) << rotate(-45) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -35, 21, 49, 49 ) ); - QTest::newRow( "rot -45 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 c" ) << rotScale(-45, 10) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( -70, 0, 141, 141 ) ); - QTest::newRow( "rot -45 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 d" ) << rotScale(-45, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -353, 212, 495, 495 ) ); #endif diff --git a/tests/auto/gui/qvulkan/qvulkan.pro b/tests/auto/gui/qvulkan/qvulkan.pro new file mode 100644 index 0000000000..0db990a2d6 --- /dev/null +++ b/tests/auto/gui/qvulkan/qvulkan.pro @@ -0,0 +1,9 @@ +############################################################ +# Project file for autotest for gui/vulkan functionality +############################################################ + +CONFIG += testcase +TARGET = tst_qvulkan +QT += gui-private core-private testlib + +SOURCES += tst_qvulkan.cpp diff --git a/tests/auto/gui/qvulkan/tst_qvulkan.cpp b/tests/auto/gui/qvulkan/tst_qvulkan.cpp new file mode 100644 index 0000000000..2803b84e8c --- /dev/null +++ b/tests/auto/gui/qvulkan/tst_qvulkan.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QVulkanInstance> +#include <QtGui/QVulkanFunctions> +#include <QtGui/QWindow> + +#include <QtTest/QtTest> + +#include <QSignalSpy> + +class tst_QVulkan : public QObject +{ + Q_OBJECT + +private slots: + void vulkanInstance(); + void vulkanCheckSupported(); + void vulkanWindow(); + void vulkanVersionRequest(); +}; + +void tst_QVulkan::vulkanInstance() +{ + QVulkanInstance inst; + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + QVERIFY(inst.isValid()); + QVERIFY(inst.vkInstance() != VK_NULL_HANDLE); + QVERIFY(inst.functions()); + QVERIFY(!inst.flags().testFlag(QVulkanInstance::NoDebugOutputRedirect)); + + inst.destroy(); + + QVERIFY(!inst.isValid()); + QVERIFY(inst.handle() == nullptr); + + inst.setFlags(QVulkanInstance::NoDebugOutputRedirect); + // pass a bogus layer and extension + inst.setExtensions(QByteArrayList() << "abcdefg" << "notanextension"); + inst.setLayers(QByteArrayList() << "notalayer"); + QVERIFY(inst.create()); + + QVERIFY(inst.isValid()); + QVERIFY(inst.vkInstance() != VK_NULL_HANDLE); + QVERIFY(inst.handle() != nullptr); + QVERIFY(inst.functions()); + QVERIFY(inst.flags().testFlag(QVulkanInstance::NoDebugOutputRedirect)); + QVERIFY(!inst.extensions().contains("abcdefg")); + QVERIFY(!inst.extensions().contains("notanextension")); + QVERIFY(!inst.extensions().contains("notalayer")); + // at least the surface extensions should be there however + QVERIFY(inst.extensions().contains("VK_KHR_surface")); + + QVERIFY(inst.getInstanceProcAddr("vkGetDeviceQueue")); +} + +void tst_QVulkan::vulkanCheckSupported() +{ + // Test the early calls to supportedLayers/extensions that need the library + // and some basics, but do not initialize the instance. + QVulkanInstance inst; + QVERIFY(!inst.isValid()); + + QVulkanInfoVector<QVulkanLayer> vl = inst.supportedLayers(); + qDebug() << vl; + QVERIFY(!inst.isValid()); + + QVulkanInfoVector<QVulkanExtension> ve = inst.supportedExtensions(); + qDebug() << ve; + QVERIFY(!inst.isValid()); + + if (inst.create()) { // skip the rest when Vulkan is not supported at all + QVERIFY(!ve.isEmpty()); + QVERIFY(ve == inst.supportedExtensions()); + } +} + +void tst_QVulkan::vulkanWindow() +{ + QVulkanInstance inst; + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + QWindow w; + w.setSurfaceType(QSurface::VulkanSurface); + w.setVulkanInstance(&inst); + w.resize(1024, 768); + w.show(); + QTest::qWaitForWindowExposed(&w); + + QCOMPARE(w.vulkanInstance(), &inst); + + VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(&w); + QVERIFY(surface != VK_NULL_HANDLE); + + // exercise supportsPresent (and QVulkanFunctions) a bit + QVulkanFunctions *f = inst.functions(); + VkPhysicalDevice physDev; + uint32_t count = 1; + VkResult err = f->vkEnumeratePhysicalDevices(inst.vkInstance(), &count, &physDev); + if (err != VK_SUCCESS) + QSKIP("No physical devices; skip"); + + VkPhysicalDeviceProperties physDevProps; + f->vkGetPhysicalDeviceProperties(physDev, &physDevProps); + qDebug("Device name: %s Driver version: %d.%d.%d", physDevProps.deviceName, + VK_VERSION_MAJOR(physDevProps.driverVersion), VK_VERSION_MINOR(physDevProps.driverVersion), + VK_VERSION_PATCH(physDevProps.driverVersion)); + + bool supports = inst.supportsPresent(physDev, 0, &w); + qDebug("queue family 0 supports presenting to window = %d", supports); +} + +void tst_QVulkan::vulkanVersionRequest() +{ + QVulkanInstance inst; + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + // Now that we know Vulkan is functional, check the requested apiVersion is + // passed to vkCreateInstance as expected. + + inst.destroy(); + + inst.setApiVersion(QVersionNumber(10, 0, 0)); + QVERIFY(!inst.create()); + QCOMPARE(inst.errorCode(), VK_ERROR_INCOMPATIBLE_DRIVER); +} + +QTEST_MAIN(tst_QVulkan) + +#include "tst_qvulkan.moc" diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 4eb26d17fe..ba02af1d47 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -1096,6 +1096,9 @@ public: QString m_interFile; QString ciphers; +signals: + void socketError(QAbstractSocket::SocketError); + protected: void incomingConnection(qintptr socketDescriptor) { @@ -1105,6 +1108,7 @@ protected: socket->setProtocol(protocol); if (ignoreSslErrors) connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(socketError(QAbstractSocket::SocketError))); QFile file(m_keyFile); QVERIFY(file.open(QIODevice::ReadOnly)); @@ -1240,6 +1244,37 @@ void tst_QSslSocket::protocolServerSide_data() #if !defined(OPENSSL_NO_SSL3) QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true; #endif + +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) + QTest::newRow("tls1.0orlater-ssl2") << QSsl::TlsV1_0OrLater << QSsl::SslV2 << false; +#endif +#if !defined(OPENSSL_NO_SSL3) + QTest::newRow("tls1.0orlater-ssl3") << QSsl::TlsV1_0OrLater << QSsl::SslV3 << false; +#endif + QTest::newRow("tls1.0orlater-tls1.0") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_0 << true; + QTest::newRow("tls1.0orlater-tls1.1") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_1 << true; + QTest::newRow("tls1.0orlater-tls1.2") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_2 << true; + +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) + QTest::newRow("tls1.1orlater-ssl2") << QSsl::TlsV1_1OrLater << QSsl::SslV2 << false; +#endif +#if !defined(OPENSSL_NO_SSL3) + QTest::newRow("tls1.1orlater-ssl3") << QSsl::TlsV1_1OrLater << QSsl::SslV3 << false; +#endif + QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false; + QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true; + QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true; + +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) + QTest::newRow("tls1.2orlater-ssl2") << QSsl::TlsV1_2OrLater << QSsl::SslV2 << false; +#endif +#if !defined(OPENSSL_NO_SSL3) + QTest::newRow("tls1.2orlater-ssl3") << QSsl::TlsV1_2OrLater << QSsl::SslV3 << false; +#endif + QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false; + QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false; + QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true; + QTest::newRow("any-tls1.0") << QSsl::AnyProtocol << QSsl::TlsV1_0 << true; QTest::newRow("any-tls1ssl3") << QSsl::AnyProtocol << QSsl::TlsV1SslV3 << true; QTest::newRow("any-secure") << QSsl::AnyProtocol << QSsl::SecureProtocols << true; @@ -1262,6 +1297,7 @@ void tst_QSslSocket::protocolServerSide() QVERIFY(server.listen()); QEventLoop loop; + connect(&server, SIGNAL(socketError(QAbstractSocket::SocketError)), &loop, SLOT(quit())); QTimer::singleShot(5000, &loop, SLOT(quit())); QSslSocket client; @@ -1279,7 +1315,15 @@ void tst_QSslSocket::protocolServerSide() QFETCH(bool, works); QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState; - QCOMPARE(int(client.state()), int(expectedState)); + // Determine whether the client or the server caused the event loop + // to quit due to a socket error, and investigate the culprit. + if (server.socket->error() != QAbstractSocket::UnknownSocketError) { + QVERIFY(client.error() == QAbstractSocket::UnknownSocketError); + QCOMPARE(int(server.socket->state()), int(expectedState)); + } else if (client.error() != QAbstractSocket::UnknownSocketError) { + QVERIFY(server.socket->error() == QAbstractSocket::UnknownSocketError); + QCOMPARE(int(client.state()), int(expectedState)); + } QCOMPARE(client.isEncrypted(), works); } diff --git a/tests/auto/other/macnativeevents/macnativeevents.pro b/tests/auto/other/macnativeevents/macnativeevents.pro index 48ad04bbff..0611377d0b 100644 --- a/tests/auto/other/macnativeevents/macnativeevents.pro +++ b/tests/auto/other/macnativeevents/macnativeevents.pro @@ -1,9 +1,8 @@ CONFIG += testcase TARGET = tst_macnativeevents -LIBS += -framework Carbon QT += widgets testlib HEADERS += qnativeevents.h nativeeventlist.h expectedeventlist.h -SOURCES += qnativeevents.cpp qnativeevents_mac.cpp +SOURCES += qnativeevents.cpp qnativeevents_mac.cpp SOURCES += expectedeventlist.cpp nativeeventlist.cpp SOURCES += tst_macnativeevents.cpp diff --git a/tests/auto/other/macnativeevents/qnativeevents.cpp b/tests/auto/other/macnativeevents/qnativeevents.cpp index 758c0a94b8..f04b33151a 100644 --- a/tests/auto/other/macnativeevents/qnativeevents.cpp +++ b/tests/auto/other/macnativeevents/qnativeevents.cpp @@ -72,7 +72,7 @@ void QNativeInput::nativeEvent(QNativeEvent *event) } } -Qt::Native::Status QNativeInput::sendNativeEvent(const QNativeEvent &event, int pid) +Qt::Native::Status QNativeInput::sendNativeEvent(const QNativeEvent &event) { switch (event.id()){ case QNativeMouseMoveEvent::eventId: @@ -84,7 +84,7 @@ Qt::Native::Status QNativeInput::sendNativeEvent(const QNativeEvent &event, int case QNativeMouseWheelEvent::eventId: return sendNativeMouseWheelEvent(static_cast<const QNativeMouseWheelEvent &>(event)); case QNativeKeyEvent::eventId: - return sendNativeKeyEvent(static_cast<const QNativeKeyEvent &>(event), pid); + return sendNativeKeyEvent(static_cast<const QNativeKeyEvent &>(event)); case QNativeModifierEvent::eventId: return sendNativeModifierEvent(static_cast<const QNativeModifierEvent &>(event)); case QNativeEvent::eventId: diff --git a/tests/auto/other/macnativeevents/qnativeevents.h b/tests/auto/other/macnativeevents/qnativeevents.h index 605d6d196e..2e30d849f2 100644 --- a/tests/auto/other/macnativeevents/qnativeevents.h +++ b/tests/auto/other/macnativeevents/qnativeevents.h @@ -204,10 +204,10 @@ class QNativeInput static Qt::Native::Status sendNativeMouseMoveEvent(const QNativeMouseMoveEvent &event); static Qt::Native::Status sendNativeMouseDragEvent(const QNativeMouseDragEvent &event); static Qt::Native::Status sendNativeMouseWheelEvent(const QNativeMouseWheelEvent &event); - static Qt::Native::Status sendNativeKeyEvent(const QNativeKeyEvent &event, int pid = 0); + static Qt::Native::Status sendNativeKeyEvent(const QNativeKeyEvent &event); static Qt::Native::Status sendNativeModifierEvent(const QNativeModifierEvent &event); // sendNativeEvent will NOT differ from OS to OS. - static Qt::Native::Status sendNativeEvent(const QNativeEvent &event, int pid = 0); + static Qt::Native::Status sendNativeEvent(const QNativeEvent &event); // The following methods will differ in implementation from OS to OS: Qt::Native::Status subscribeForNativeEvents(); diff --git a/tests/auto/other/macnativeevents/qnativeevents_mac.cpp b/tests/auto/other/macnativeevents/qnativeevents_mac.cpp index 6671813188..6d7fbbecc1 100644 --- a/tests/auto/other/macnativeevents/qnativeevents_mac.cpp +++ b/tests/auto/other/macnativeevents/qnativeevents_mac.cpp @@ -27,7 +27,7 @@ ****************************************************************************/ #include "qnativeevents.h" -#include <Carbon/Carbon.h> +#include <CoreGraphics/CoreGraphics.h> #include <QtCore> // ************************************************************ @@ -176,28 +176,18 @@ static CGEventRef EventHandler_Quartz(CGEventTapProxy proxy, CGEventType type, C return inEvent; } -Qt::Native::Status insertEventHandler_Quartz(QNativeInput *nativeInput, int pid = 0) +Qt::Native::Status insertEventHandler_Quartz(QNativeInput *nativeInput) { uid_t uid = geteuid(); if (uid != 0) qWarning("MacNativeEvents: You must be root to listen for key events!"); - CFMachPortRef port; - if (!pid){ - port = CGEventTapCreate(kCGHIDEventTap, - kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, - kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); - } else { - ProcessSerialNumber psn; - GetProcessForPID(pid, &psn); - port = CGEventTapCreateForPSN(&psn, - kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, - kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); - } + CFMachPortRef port = CGEventTapCreate(kCGHIDEventTap, + kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, + kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); CFRunLoopSourceRef eventSrc = CFMachPortCreateRunLoopSource(NULL, port, 0); - CFRunLoopAddSource((CFRunLoopRef) GetCFRunLoopFromEventLoop(GetMainEventLoop()), - eventSrc, kCFRunLoopCommonModes); + CFRunLoopAddSource(CFRunLoopGetMain(), eventSrc, kCFRunLoopCommonModes); return Qt::Native::Success; } @@ -207,19 +197,6 @@ Qt::Native::Status removeEventHandler_Quartz() return Qt::Native::Success; // ToDo: } -Qt::Native::Status sendNativeKeyEventToProcess_Quartz(const QNativeKeyEvent &event, int pid) -{ - ProcessSerialNumber psn; - GetProcessForPID(pid, &psn); - - CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, event.press); - setModifiersFromQNativeEvent(e, event); - SetFrontProcess(&psn); - CGEventPostToPSN(&psn, e); - CFRelease(e); - return Qt::Native::Success; -} - Qt::Native::Status sendNativeKeyEvent_Quartz(const QNativeKeyEvent &event) { CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, event.press); @@ -344,12 +321,9 @@ Qt::Native::Status QNativeInput::sendNativeMouseWheelEvent(const QNativeMouseWhe return sendNativeMouseWheelEvent_Quartz(event); } -Qt::Native::Status QNativeInput::sendNativeKeyEvent(const QNativeKeyEvent &event, int pid) +Qt::Native::Status QNativeInput::sendNativeKeyEvent(const QNativeKeyEvent &event) { - if (!pid) - return sendNativeKeyEvent_Quartz(event); - else - return sendNativeKeyEventToProcess_Quartz(event, pid); + return sendNativeKeyEvent_Quartz(event); } Qt::Native::Status QNativeInput::sendNativeModifierEvent(const QNativeModifierEvent &event) diff --git a/tests/auto/other/macnativeevents/tst_macnativeevents.cpp b/tests/auto/other/macnativeevents/tst_macnativeevents.cpp index 5edff7aabe..e8970e6f24 100644 --- a/tests/auto/other/macnativeevents/tst_macnativeevents.cpp +++ b/tests/auto/other/macnativeevents/tst_macnativeevents.cpp @@ -35,10 +35,14 @@ #include "qnativeevents.h" #include "nativeeventlist.h" #include "expectedeventlist.h" -#include <Carbon/Carbon.h> QT_USE_NAMESPACE +// Unicode code points for the glyphs associated with these keys +// Defined by Carbon headers but not anywhere in Cocoa +static const int kControlUnicode = 0x2303; +static const int kCommandUnicode = 0x2318; + class tst_MacNativeEvents : public QObject { Q_OBJECT diff --git a/tests/auto/other/modeltest/dynamictreemodel.cpp b/tests/auto/other/modeltest/dynamictreemodel.cpp index 1f6463db8a..fc979bce2d 100644 --- a/tests/auto/other/modeltest/dynamictreemodel.cpp +++ b/tests/auto/other/modeltest/dynamictreemodel.cpp @@ -33,9 +33,8 @@ #include <QtCore/QTimer> #include <QtCore/QDebug> - -DynamicTreeModel::DynamicTreeModel(QObject *parent) - : QAbstractItemModel(parent), +DynamicTreeModel::DynamicTreeModel(QObject *parent) : + QAbstractItemModel(parent), nextId(1) { } @@ -45,186 +44,172 @@ QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &pare // if (column != 0) // return QModelIndex(); + if (column < 0 || row < 0) + return QModelIndex(); - if ( column < 0 || row < 0 ) - return QModelIndex(); - - QList<QList<qint64> > childIdColumns = m_childItems.value(parent.internalId()); + QList<QList<qint64> > childIdColumns = m_childItems.value(parent.internalId()); - const qint64 grandParent = findParentId(parent.internalId()); - if (grandParent >= 0) { - QList<QList<qint64> > parentTable = m_childItems.value(grandParent); - if (parent.column() >= parentTable.size()) - qFatal("%s: parent.column() must be less than parentTable.size()", Q_FUNC_INFO); - QList<qint64> parentSiblings = parentTable.at(parent.column()); - if (parent.row() >= parentSiblings.size()) - qFatal("%s: parent.row() must be less than parentSiblings.size()", Q_FUNC_INFO); - } - - if (childIdColumns.size() == 0) - return QModelIndex(); + const qint64 grandParent = findParentId(parent.internalId()); + if (grandParent >= 0) { + QList<QList<qint64> > parentTable = m_childItems.value(grandParent); + if (parent.column() >= parentTable.size()) + qFatal("%s: parent.column() must be less than parentTable.size()", Q_FUNC_INFO); + QList<qint64> parentSiblings = parentTable.at(parent.column()); + if (parent.row() >= parentSiblings.size()) + qFatal("%s: parent.row() must be less than parentSiblings.size()", Q_FUNC_INFO); + } - if (column >= childIdColumns.size()) - return QModelIndex(); + if (childIdColumns.size() == 0) + return QModelIndex(); - QList<qint64> rowIds = childIdColumns.at(column); + if (column >= childIdColumns.size()) + return QModelIndex(); - if ( row >= rowIds.size()) - return QModelIndex(); + QList<qint64> rowIds = childIdColumns.at(column); - qint64 id = rowIds.at(row); + if (row >= rowIds.size()) + return QModelIndex(); - return createIndex(row, column, reinterpret_cast<void *>(id)); + qint64 id = rowIds.at(row); + return createIndex(row, column, reinterpret_cast<void *>(id)); } qint64 DynamicTreeModel::findParentId(qint64 searchId) const { - if (searchId <= 0) - return -1; - - QHashIterator<qint64, QList<QList<qint64> > > i(m_childItems); - while (i.hasNext()) - { - i.next(); - QListIterator<QList<qint64> > j(i.value()); - while (j.hasNext()) - { - QList<qint64> l = j.next(); - if (l.contains(searchId)) - { - return i.key(); - } + if (searchId <= 0) + return -1; + + QHashIterator<qint64, QList<QList<qint64> > > i(m_childItems); + while (i.hasNext()) { + i.next(); + QListIterator<QList<qint64> > j(i.value()); + while (j.hasNext()) { + QList<qint64> l = j.next(); + if (l.contains(searchId)) + return i.key(); + } } - } - return -1; + return -1; } QModelIndex DynamicTreeModel::parent(const QModelIndex &index) const { - if (!index.isValid()) - return QModelIndex(); + if (!index.isValid()) + return QModelIndex(); - qint64 searchId = index.internalId(); - qint64 parentId = findParentId(searchId); - // Will never happen for valid index, but what the hey... - if (parentId <= 0) - return QModelIndex(); + qint64 searchId = index.internalId(); + qint64 parentId = findParentId(searchId); + // Will never happen for valid index, but what the hey... + if (parentId <= 0) + return QModelIndex(); - qint64 grandParentId = findParentId(parentId); - if (grandParentId < 0) - grandParentId = 0; + qint64 grandParentId = findParentId(parentId); + if (grandParentId < 0) + grandParentId = 0; - int column = 0; - QList<qint64> childList = m_childItems.value(grandParentId).at(column); + int column = 0; + QList<qint64> childList = m_childItems.value(grandParentId).at(column); - int row = childList.indexOf(parentId); - - return createIndex(row, column, reinterpret_cast<void *>(parentId)); + int row = childList.indexOf(parentId); + return createIndex(row, column, reinterpret_cast<void *>(parentId)); } -int DynamicTreeModel::rowCount(const QModelIndex &index ) const +int DynamicTreeModel::rowCount(const QModelIndex &index) const { - QList<QList<qint64> > cols = m_childItems.value(index.internalId()); + QList<QList<qint64> > cols = m_childItems.value(index.internalId()); - if (cols.size() == 0 ) - return 0; + if (cols.size() == 0) + return 0; - if (index.column() > 0) - return 0; + if (index.column() > 0) + return 0; - return cols.at(0).size(); + return cols.at(0).size(); } -int DynamicTreeModel::columnCount(const QModelIndex &index ) const +int DynamicTreeModel::columnCount(const QModelIndex &index) const { // Q_UNUSED(index); - return m_childItems.value(index.internalId()).size(); + return m_childItems.value(index.internalId()).size(); } QVariant DynamicTreeModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); + if (!index.isValid()) + return QVariant(); - if (Qt::DisplayRole == role) - { - return m_items.value(index.internalId()); - } - return QVariant(); + if (Qt::DisplayRole == role) + return m_items.value(index.internalId()); + return QVariant(); } void DynamicTreeModel::clear() { - beginResetModel(); - m_items.clear(); - m_childItems.clear(); - nextId = 1; - endResetModel(); + beginResetModel(); + m_items.clear(); + m_childItems.clear(); + nextId = 1; + endResetModel(); } - -ModelChangeCommand::ModelChangeCommand( DynamicTreeModel *model, QObject *parent ) - : QObject(parent), m_model(model), m_numCols(1), m_startRow(-1), m_endRow(-1) +ModelChangeCommand::ModelChangeCommand(DynamicTreeModel *model, QObject *parent) : + QObject(parent), + m_model(model), + m_numCols(1), + m_startRow(-1), + m_endRow(-1) { - } QModelIndex ModelChangeCommand::findIndex(QList<int> rows) { - const int col = 0; - QModelIndex parent = QModelIndex(); - QListIterator<int> i(rows); - while (i.hasNext()) - { - parent = m_model->index(i.next(), col, parent); - if (!parent.isValid()) - qFatal("%s: parent must be valid", Q_FUNC_INFO); - } - return parent; + const int col = 0; + QModelIndex parent = QModelIndex(); + QListIterator<int> i(rows); + while (i.hasNext()) { + parent = m_model->index(i.next(), col, parent); + if (!parent.isValid()) + qFatal("%s: parent must be valid", Q_FUNC_INFO); + } + return parent; } -ModelInsertCommand::ModelInsertCommand(DynamicTreeModel *model, QObject *parent ) - : ModelChangeCommand(model, parent) +ModelInsertCommand::ModelInsertCommand(DynamicTreeModel *model, QObject *parent) : + ModelChangeCommand(model, parent) { - } void ModelInsertCommand::doCommand() { - QModelIndex parent = findIndex(m_rowNumbers); - m_model->beginInsertRows(parent, m_startRow, m_endRow); - qint64 parentId = parent.internalId(); - for (int row = m_startRow; row <= m_endRow; row++) - { - for(int col = 0; col < m_numCols; col++ ) - { - if (m_model->m_childItems[parentId].size() <= col) - { - m_model->m_childItems[parentId].append(QList<qint64>()); - } + QModelIndex parent = findIndex(m_rowNumbers); + m_model->beginInsertRows(parent, m_startRow, m_endRow); + qint64 parentId = parent.internalId(); + for (int row = m_startRow; row <= m_endRow; row++) { + for (int col = 0; col < m_numCols; col++) { + if (m_model->m_childItems[parentId].size() <= col) + m_model->m_childItems[parentId].append(QList<qint64>()); // QString name = QUuid::createUuid().toString(); - qint64 id = m_model->newId(); - QString name = QString::number(id); - - m_model->m_items.insert(id, name); - m_model->m_childItems[parentId][col].insert(row, id); + qint64 id = m_model->newId(); + QString name = QString::number(id); + m_model->m_items.insert(id, name); + m_model->m_childItems[parentId][col].insert(row, id); + } } - } - m_model->endInsertRows(); + m_model->endInsertRows(); } - -ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent) - : ModelChangeCommand(model, parent) +ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent) : + ModelChangeCommand(model, parent) { - } -bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) + +bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, + const QModelIndex &destParent, int destRow) { - return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow); + return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow); } void ModelMoveCommand::doCommand() @@ -233,33 +218,26 @@ void ModelMoveCommand::doCommand() QModelIndex destParent = findIndex(m_destRowNumbers); if (!emitPreSignal(srcParent, m_startRow, m_endRow, destParent, m_destRow)) - { return; - } - for (int column = 0; column < m_numCols; ++column) - { - QList<qint64> l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 ); + for (int column = 0; column < m_numCols; ++column) { + QList<qint64> l = m_model->m_childItems.value(srcParent.internalId())[column].mid( + m_startRow, m_endRow - m_startRow + 1); - for (int i = m_startRow; i <= m_endRow ; i++) - { + for (int i = m_startRow; i <= m_endRow; i++) m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow); - } int d; - if (m_destRow < m_startRow) + if (m_destRow < m_startRow) { d = m_destRow; - else - { + } else { if (srcParent == destParent) d = m_destRow - (m_endRow - m_startRow + 1); else d = m_destRow - (m_endRow - m_startRow) + 1; } - foreach(const qint64 id, l) - { + foreach (const qint64 id, l) m_model->m_childItems[destParent.internalId()][column].insert(d++, id); - } } emitPostSignal(); @@ -270,18 +248,17 @@ void ModelMoveCommand::emitPostSignal() m_model->endMoveRows(); } -ModelResetCommand::ModelResetCommand(DynamicTreeModel* model, QObject* parent) - : ModelMoveCommand(model, parent) +ModelResetCommand::ModelResetCommand(DynamicTreeModel *model, QObject *parent) : + ModelMoveCommand(model, parent) { - } ModelResetCommand::~ModelResetCommand() { - } -bool ModelResetCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +bool ModelResetCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, + const QModelIndex &destParent, int destRow) { Q_UNUSED(srcParent); Q_UNUSED(srcStart); @@ -298,18 +275,17 @@ void ModelResetCommand::emitPostSignal() m_model->endResetModel(); } -ModelResetCommandFixed::ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent) - : ModelMoveCommand(model, parent) +ModelResetCommandFixed::ModelResetCommandFixed(DynamicTreeModel *model, QObject *parent) : + ModelMoveCommand(model, parent) { - } ModelResetCommandFixed::~ModelResetCommandFixed() { - } -bool ModelResetCommandFixed::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +bool ModelResetCommandFixed::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, + const QModelIndex &destParent, int destRow) { Q_UNUSED(srcParent); Q_UNUSED(srcStart); @@ -326,10 +302,10 @@ void ModelResetCommandFixed::emitPostSignal() m_model->endResetModel(); } -ModelChangeChildrenLayoutsCommand::ModelChangeChildrenLayoutsCommand(DynamicTreeModel* model, QObject* parent) - : ModelChangeCommand(model, parent) +ModelChangeChildrenLayoutsCommand::ModelChangeChildrenLayoutsCommand(DynamicTreeModel *model, + QObject *parent) : + ModelChangeCommand(model, parent) { - } void ModelChangeChildrenLayoutsCommand::doCommand() @@ -346,17 +322,16 @@ void ModelChangeChildrenLayoutsCommand::doCommand() int rowSize1 = -1; int rowSize2 = -1; - for (int column = 0; column < m_numCols; ++column) - { + for (int column = 0; column < m_numCols; ++column) { { - QList<qint64> &l = m_model->m_childItems[parent1.internalId()][column]; - rowSize1 = l.size(); - l.prepend(l.takeLast()); + QList<qint64> &l = m_model->m_childItems[parent1.internalId()][column]; + rowSize1 = l.size(); + l.prepend(l.takeLast()); } { - QList<qint64> &l = m_model->m_childItems[parent2.internalId()][column]; - rowSize2 = l.size(); - l.append(l.takeFirst()); + QList<qint64> &l = m_model->m_childItems[parent2.internalId()][column]; + rowSize2 = l.size(); + l.append(l.takeFirst()); } } @@ -373,15 +348,23 @@ void ModelChangeChildrenLayoutsCommand::doCommand() foreach (const QModelIndex &idx, persistent) { if (idx.parent() == parent1) { if (idx.row() == rowSize1 - 1) { - m_model->changePersistentIndex(idx, m_model->createIndex(0, idx.column(), idx.internalPointer())); + m_model->changePersistentIndex(idx, + m_model->createIndex(0, idx.column(), + idx.internalPointer())); } else { - m_model->changePersistentIndex(idx, m_model->createIndex(idx.row() + 1, idx.column(), idx.internalPointer())); + m_model->changePersistentIndex(idx, + m_model->createIndex(idx.row() + 1, idx.column(), + idx.internalPointer())); } } else if (idx.parent() == parent2) { if (idx.row() == 0) { - m_model->changePersistentIndex(idx, m_model->createIndex(rowSize2 - 1, idx.column(), idx.internalPointer())); + m_model->changePersistentIndex(idx, + m_model->createIndex(rowSize2 - 1, idx.column(), + idx.internalPointer())); } else { - m_model->changePersistentIndex(idx, m_model->createIndex(idx.row() - 1, idx.column(), idx.internalPointer())); + m_model->changePersistentIndex(idx, + m_model->createIndex(idx.row() - 1, idx.column(), + idx.internalPointer())); } } } diff --git a/tests/auto/other/modeltest/dynamictreemodel.h b/tests/auto/other/modeltest/dynamictreemodel.h index e31c4569fd..709751dd27 100644 --- a/tests/auto/other/modeltest/dynamictreemodel.h +++ b/tests/auto/other/modeltest/dynamictreemodel.h @@ -34,119 +34,142 @@ #include <QtCore/QHash> #include <QtCore/QList> - class DynamicTreeModel : public QAbstractItemModel { - Q_OBJECT + Q_OBJECT public: - DynamicTreeModel(QObject *parent = 0); + DynamicTreeModel(QObject *parent = 0); - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index) const; - int rowCount(const QModelIndex &index = QModelIndex()) const; - int columnCount(const QModelIndex &index = QModelIndex()) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &index = QModelIndex()) const; + int columnCount(const QModelIndex &index = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - void clear(); + void clear(); protected slots: - /** - Finds the parent id of the string with id @p searchId. + /** + Finds the parent id of the string with id @p searchId. - Returns -1 if not found. - */ - qint64 findParentId(qint64 searchId) const; + Returns -1 if not found. + */ + qint64 findParentId(qint64 searchId) const; private: - QHash<qint64, QString> m_items; - QHash<qint64, QList<QList<qint64> > > m_childItems; - qint64 nextId; - qint64 newId() { return nextId++; }; - - QModelIndex m_nextParentIndex; - int m_nextRow; - - int m_depth; - int maxDepth; - - friend class ModelInsertCommand; - friend class ModelMoveCommand; - friend class ModelResetCommand; - friend class ModelResetCommandFixed; - friend class ModelChangeChildrenLayoutsCommand; - + QHash<qint64, QString> m_items; + QHash<qint64, QList<QList<qint64> > > m_childItems; + qint64 nextId; + qint64 newId() + { + return nextId++; + } + + QModelIndex m_nextParentIndex; + int m_nextRow; + + int m_depth; + int maxDepth; + + friend class ModelInsertCommand; + friend class ModelMoveCommand; + friend class ModelResetCommand; + friend class ModelResetCommandFixed; + friend class ModelChangeChildrenLayoutsCommand; }; - class ModelChangeCommand : public QObject { - Q_OBJECT + Q_OBJECT public: - ModelChangeCommand( DynamicTreeModel *model, QObject *parent = 0 ); + ModelChangeCommand(DynamicTreeModel *model, QObject *parent = 0); - virtual ~ModelChangeCommand() {} + virtual ~ModelChangeCommand() + { + } - void setAncestorRowNumbers(QList<int> rowNumbers) { m_rowNumbers = rowNumbers; } + void setAncestorRowNumbers(QList<int> rowNumbers) + { + m_rowNumbers = rowNumbers; + } - QModelIndex findIndex(QList<int> rows); + QModelIndex findIndex(QList<int> rows); - void setStartRow(int row) { m_startRow = row; } + void setStartRow(int row) + { + m_startRow = row; + } - void setEndRow(int row) { m_endRow = row; } + void setEndRow(int row) + { + m_endRow = row; + } - void setNumCols(int cols) { m_numCols = cols; } + void setNumCols(int cols) + { + m_numCols = cols; + } - virtual void doCommand() = 0; + virtual void doCommand() = 0; protected: - DynamicTreeModel* m_model; - QList<int> m_rowNumbers; - int m_numCols; - int m_startRow; - int m_endRow; - + DynamicTreeModel *m_model; + QList<int> m_rowNumbers; + int m_numCols; + int m_startRow; + int m_endRow; }; -typedef QList<ModelChangeCommand*> ModelChangeCommandList; +typedef QList<ModelChangeCommand *> ModelChangeCommandList; class ModelInsertCommand : public ModelChangeCommand { - Q_OBJECT + Q_OBJECT public: - ModelInsertCommand(DynamicTreeModel *model, QObject *parent = 0 ); - virtual ~ModelInsertCommand() {} + ModelInsertCommand(DynamicTreeModel *model, QObject *parent = 0); + virtual ~ModelInsertCommand() + { + } - virtual void doCommand(); + virtual void doCommand(); }; - class ModelMoveCommand : public ModelChangeCommand { - Q_OBJECT + Q_OBJECT public: - ModelMoveCommand(DynamicTreeModel *model, QObject *parent); + ModelMoveCommand(DynamicTreeModel *model, QObject *parent); - virtual ~ModelMoveCommand() {} + virtual ~ModelMoveCommand() + { + } - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, + const QModelIndex &destParent, int destRow); - virtual void doCommand(); + virtual void doCommand(); - virtual void emitPostSignal(); + virtual void emitPostSignal(); - void setDestAncestors( QList<int> rows ) { m_destRowNumbers = rows; } + void setDestAncestors(QList<int> rows) + { + m_destRowNumbers = rows; + } - void setDestRow(int row) { m_destRow = row; } + void setDestRow(int row) + { + m_destRow = row; + } protected: - QList<int> m_destRowNumbers; - int m_destRow; + QList<int> m_destRowNumbers; + int m_destRow; }; /** @@ -154,15 +177,15 @@ protected: */ class ModelResetCommand : public ModelMoveCommand { - Q_OBJECT + Q_OBJECT public: - ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0); + ModelResetCommand(DynamicTreeModel *model, QObject *parent = 0); - virtual ~ModelResetCommand(); - - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - virtual void emitPostSignal(); + virtual ~ModelResetCommand(); + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, + const QModelIndex &destParent, int destRow); + virtual void emitPostSignal(); }; /** @@ -170,32 +193,37 @@ public: */ class ModelResetCommandFixed : public ModelMoveCommand { - Q_OBJECT + Q_OBJECT public: - ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent = 0); - - virtual ~ModelResetCommandFixed(); + ModelResetCommandFixed(DynamicTreeModel *model, QObject *parent = 0); - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - virtual void emitPostSignal(); + virtual ~ModelResetCommandFixed(); + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, + const QModelIndex &destParent, int destRow); + virtual void emitPostSignal(); }; class ModelChangeChildrenLayoutsCommand : public ModelChangeCommand { - Q_OBJECT + Q_OBJECT public: - ModelChangeChildrenLayoutsCommand(DynamicTreeModel *model, QObject *parent); + ModelChangeChildrenLayoutsCommand(DynamicTreeModel *model, QObject *parent); - virtual ~ModelChangeChildrenLayoutsCommand() {} + virtual ~ModelChangeChildrenLayoutsCommand() + { + } - virtual void doCommand(); + virtual void doCommand(); - void setSecondAncestorRowNumbers( QList<int> rows ) { m_secondRowNumbers = rows; } + void setSecondAncestorRowNumbers(QList<int> rows) + { + m_secondRowNumbers = rows; + } protected: - QList<int> m_secondRowNumbers; - int m_destRow; + QList<int> m_secondRowNumbers; + int m_destRow; }; #endif diff --git a/tests/auto/other/modeltest/modeltest.cpp b/tests/auto/other/modeltest/modeltest.cpp index 4da00bda4d..611f9e904b 100644 --- a/tests/auto/other/modeltest/modeltest.cpp +++ b/tests/auto/other/modeltest/modeltest.cpp @@ -34,60 +34,62 @@ /*! Connect to all of the models signals. Whenever anything happens recheck everything. */ -ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject ( parent ), model ( _model ), fetchingMore ( false ) +ModelTest::ModelTest(QAbstractItemModel *_model, QObject *parent) : QObject(parent), + model(_model), + fetchingMore(false) { if (!model) qFatal("%s: model must not be null", Q_FUNC_INFO); connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), - this, SLOT(runAllTests()) ); - connect(model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(runAllTests()) ); - connect(model, SIGNAL(layoutChanged()), this, SLOT(runAllTests()) ); - connect(model, SIGNAL(modelReset()), this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); + connect(model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(runAllTests())); + connect(model, SIGNAL(layoutChanged()), this, SLOT(runAllTests())); + connect(model, SIGNAL(modelReset()), this, SLOT(runAllTests())); connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(runAllTests()) ); + this, SLOT(runAllTests())); // Special checks for changes connect(model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(layoutAboutToBeChanged()) ); + this, SLOT(layoutAboutToBeChanged())); connect(model, SIGNAL(layoutChanged()), - this, SLOT(layoutChanged()) ); + this, SLOT(layoutChanged())); connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int)) ); + this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int))); connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)) ); + this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(rowsInserted(QModelIndex,int,int)) ); + this, SLOT(rowsInserted(QModelIndex,int,int))); connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(rowsRemoved(QModelIndex,int,int)) ); + this, SLOT(rowsRemoved(QModelIndex,int,int))); connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(dataChanged(QModelIndex,QModelIndex)) ); + this, SLOT(dataChanged(QModelIndex,QModelIndex))); connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), - this, SLOT(headerDataChanged(Qt::Orientation,int,int)) ); + this, SLOT(headerDataChanged(Qt::Orientation,int,int))); runAllTests(); } void ModelTest::runAllTests() { - if ( fetchingMore ) + if (fetchingMore) return; nonDestructiveBasicTest(); rowCount(); @@ -105,31 +107,31 @@ void ModelTest::runAllTests() void ModelTest::nonDestructiveBasicTest() { QVERIFY(!model->buddy(QModelIndex()).isValid()); - model->canFetchMore ( QModelIndex() ); - QVERIFY( model->columnCount ( QModelIndex() ) >= 0 ); + model->canFetchMore(QModelIndex()); + QVERIFY(model->columnCount(QModelIndex()) >= 0); QCOMPARE(model->data(QModelIndex()), QVariant()); fetchingMore = true; - model->fetchMore ( QModelIndex() ); + model->fetchMore(QModelIndex()); fetchingMore = false; - Qt::ItemFlags flags = model->flags ( QModelIndex() ); - QVERIFY( flags == Qt::ItemIsDropEnabled || flags == 0 ); - model->hasChildren ( QModelIndex() ); - model->hasIndex ( 0, 0 ); - model->headerData ( 0, Qt::Horizontal ); - model->index ( 0, 0 ); - model->itemData ( QModelIndex() ); + Qt::ItemFlags flags = model->flags(QModelIndex()); + QVERIFY(flags == Qt::ItemIsDropEnabled || flags == 0); + model->hasChildren(QModelIndex()); + model->hasIndex(0, 0); + model->headerData(0, Qt::Horizontal); + model->index(0, 0); + model->itemData(QModelIndex()); QVariant cache; - model->match ( QModelIndex(), -1, cache ); + model->match(QModelIndex(), -1, cache); model->mimeTypes(); QVERIFY(!model->parent(QModelIndex()).isValid()); - QVERIFY( model->rowCount() >= 0 ); + QVERIFY(model->rowCount() >= 0); QVariant variant; - model->setData ( QModelIndex(), variant, -1 ); - model->setHeaderData ( -1, Qt::Horizontal, QVariant() ); - model->setHeaderData ( 999999, Qt::Horizontal, QVariant() ); + model->setData(QModelIndex(), variant, -1); + model->setHeaderData(-1, Qt::Horizontal, QVariant()); + model->setHeaderData(999999, Qt::Horizontal, QVariant()); QMap<int, QVariant> roles; - model->sibling ( 0, 0, QModelIndex() ); - model->span ( QModelIndex() ); + model->sibling(0, 0, QModelIndex()); + model->span(QModelIndex()); model->supportedDropActions(); } @@ -142,19 +144,19 @@ void ModelTest::rowCount() { // qDebug() << "rc"; // check top row - QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); - int rows = model->rowCount ( topIndex ); - QVERIFY( rows >= 0 ); - if ( rows > 0 ) - QVERIFY( model->hasChildren ( topIndex ) ); - - QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex ); - if ( secondLevelIndex.isValid() ) { // not the top level + QModelIndex topIndex = model->index(0, 0, QModelIndex()); + int rows = model->rowCount(topIndex); + QVERIFY(rows >= 0); + if (rows > 0) + QVERIFY(model->hasChildren(topIndex)); + + QModelIndex secondLevelIndex = model->index(0, 0, topIndex); + if (secondLevelIndex.isValid()) { // not the top level // check a row count where parent is valid - rows = model->rowCount ( secondLevelIndex ); - QVERIFY( rows >= 0 ); - if ( rows > 0 ) - QVERIFY( model->hasChildren ( secondLevelIndex ) ); + rows = model->rowCount(secondLevelIndex); + QVERIFY(rows >= 0); + if (rows > 0) + QVERIFY(model->hasChildren(secondLevelIndex)); } // The models rowCount() is tested more extensively in checkChildren(), @@ -167,13 +169,13 @@ void ModelTest::rowCount() void ModelTest::columnCount() { // check top row - QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); - QVERIFY( model->columnCount ( topIndex ) >= 0 ); + QModelIndex topIndex = model->index(0, 0, QModelIndex()); + QVERIFY(model->columnCount(topIndex) >= 0); // check a column count where parent is valid - QModelIndex childIndex = model->index ( 0, 0, topIndex ); - if ( childIndex.isValid() ) - QVERIFY( model->columnCount ( childIndex ) >= 0 ); + QModelIndex childIndex = model->index(0, 0, topIndex); + if (childIndex.isValid()) + QVERIFY(model->columnCount(childIndex) >= 0); // columnCount() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -186,19 +188,19 @@ void ModelTest::hasIndex() { // qDebug() << "hi"; // Make sure that invalid values returns an invalid index - QVERIFY( !model->hasIndex ( -2, -2 ) ); - QVERIFY( !model->hasIndex ( -2, 0 ) ); - QVERIFY( !model->hasIndex ( 0, -2 ) ); + QVERIFY(!model->hasIndex(-2, -2)); + QVERIFY(!model->hasIndex(-2, 0)); + QVERIFY(!model->hasIndex(0, -2)); int rows = model->rowCount(); int columns = model->columnCount(); // check out of bounds - QVERIFY( !model->hasIndex ( rows, columns ) ); - QVERIFY( !model->hasIndex ( rows + 1, columns + 1 ) ); + QVERIFY(!model->hasIndex(rows, columns)); + QVERIFY(!model->hasIndex(rows + 1, columns + 1)); - if ( rows > 0 ) - QVERIFY( model->hasIndex ( 0, 0 ) ); + if (rows > 0) + QVERIFY(model->hasIndex(0, 0)); // hasIndex() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -218,7 +220,7 @@ void ModelTest::index() int rows = model->rowCount(); int columns = model->columnCount(); - if ( rows == 0 ) + if (rows == 0) return; // Catch off by one errors @@ -226,8 +228,8 @@ void ModelTest::index() QVERIFY(model->index(0, 0).isValid()); // Make sure that the same index is *always* returned - QModelIndex a = model->index ( 0, 0 ); - QModelIndex b = model->index ( 0, 0 ); + QModelIndex a = model->index(0, 0); + QModelIndex b = model->index(0, 0); QCOMPARE(a, b); // index() is tested more extensively in checkChildren(), @@ -244,7 +246,7 @@ void ModelTest::parent() // when asked for the parent of an invalid index. QVERIFY(!model->parent(QModelIndex()).isValid()); - if ( model->rowCount() == 0 ) + if (model->rowCount() == 0) return; // Column 0 | Column 1 | @@ -254,29 +256,29 @@ void ModelTest::parent() // Common error test #1, make sure that a top level index has a parent // that is a invalid QModelIndex. - QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); + QModelIndex topIndex = model->index(0, 0, QModelIndex()); QVERIFY(!model->parent(topIndex).isValid()); // Common error test #2, make sure that a second level index has a parent // that is the first level index. - if ( model->rowCount ( topIndex ) > 0 ) { - QModelIndex childIndex = model->index ( 0, 0, topIndex ); + if (model->rowCount(topIndex) > 0) { + QModelIndex childIndex = model->index(0, 0, topIndex); QCOMPARE(model->parent(childIndex), topIndex); } // Common error test #3, the second column should NOT have the same children // as the first column in a row. // Usually the second column shouldn't have children. - QModelIndex topIndex1 = model->index ( 0, 1, QModelIndex() ); - if ( model->rowCount ( topIndex1 ) > 0 ) { - QModelIndex childIndex = model->index ( 0, 0, topIndex ); - QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 ); - QVERIFY( childIndex != childIndex1 ); + QModelIndex topIndex1 = model->index(0, 1, QModelIndex()); + if (model->rowCount(topIndex1) > 0) { + QModelIndex childIndex = model->index(0, 0, topIndex); + QModelIndex childIndex1 = model->index(0, 0, topIndex1); + QVERIFY(childIndex != childIndex1); } // Full test, walk n levels deep through the model making sure that all // parent's children correctly specify their parent. - checkChildren ( QModelIndex() ); + checkChildren(QModelIndex()); } /*! @@ -293,73 +295,75 @@ void ModelTest::parent() found the basic bugs because it is easier to figure out the problem in those tests then this one. */ -void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) +void ModelTest::checkChildren(const QModelIndex &parent, int currentDepth) { // First just try walking back up the tree. QModelIndex p = parent; - while ( p.isValid() ) + while (p.isValid()) p = p.parent(); // For models that are dynamically populated - if ( model->canFetchMore ( parent ) ) { + if (model->canFetchMore(parent)) { fetchingMore = true; - model->fetchMore ( parent ); + model->fetchMore(parent); fetchingMore = false; } - int rows = model->rowCount ( parent ); - int columns = model->columnCount ( parent ); + int rows = model->rowCount(parent); + int columns = model->columnCount(parent); - if ( rows > 0 ) - QVERIFY( model->hasChildren ( parent ) ); + if (rows > 0) + QVERIFY(model->hasChildren(parent)); // Some further testing against rows(), columns(), and hasChildren() - QVERIFY( rows >= 0 ); - QVERIFY( columns >= 0 ); - if ( rows > 0 ) - QVERIFY( model->hasChildren ( parent ) ); + QVERIFY(rows >= 0); + QVERIFY(columns >= 0); + if (rows > 0) + QVERIFY(model->hasChildren(parent)); //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows // << "columns:" << columns << "parent column:" << parent.column(); - const QModelIndex topLeftChild = model->index( 0, 0, parent ); + const QModelIndex topLeftChild = model->index(0, 0, parent); - QVERIFY( !model->hasIndex ( rows + 1, 0, parent ) ); - for ( int r = 0; r < rows; ++r ) { - if ( model->canFetchMore ( parent ) ) { + QVERIFY(!model->hasIndex(rows + 1, 0, parent)); + for (int r = 0; r < rows; ++r) { + if (model->canFetchMore(parent)) { fetchingMore = true; - model->fetchMore ( parent ); + model->fetchMore(parent); fetchingMore = false; } - QVERIFY( !model->hasIndex ( r, columns + 1, parent ) ); - for ( int c = 0; c < columns; ++c ) { - QVERIFY( model->hasIndex ( r, c, parent ) ); - QModelIndex index = model->index ( r, c, parent ); + QVERIFY(!model->hasIndex(r, columns + 1, parent)); + for (int c = 0; c < columns; ++c) { + QVERIFY(model->hasIndex(r, c, parent)); + QModelIndex index = model->index(r, c, parent); // rowCount() and columnCount() said that it existed... + if (!index.isValid()) + qWarning() << "Got invalid index at row=" << r << "col=" << c << "parent=" << parent; QVERIFY(index.isValid()); // index() should always return the same index when called twice in a row - QModelIndex modifiedIndex = model->index ( r, c, parent ); + QModelIndex modifiedIndex = model->index(r, c, parent); QCOMPARE(index, modifiedIndex); // Make sure we get the same index if we request it twice in a row - QModelIndex a = model->index ( r, c, parent ); - QModelIndex b = model->index ( r, c, parent ); + QModelIndex a = model->index(r, c, parent); + QModelIndex b = model->index(r, c, parent); QCOMPARE(a, b); { - const QModelIndex sibling = model->sibling( r, c, topLeftChild ); + const QModelIndex sibling = model->sibling(r, c, topLeftChild); QCOMPARE(index, sibling); } { - const QModelIndex sibling = topLeftChild.sibling( r, c ); + const QModelIndex sibling = topLeftChild.sibling(r, c); QCOMPARE(index, sibling); } // Some basic checking on the index that is returned QCOMPARE(index.model(), model); - QCOMPARE( index.row(), r ); - QCOMPARE( index.column(), c ); + QCOMPARE(index.row(), r); + QCOMPARE(index.column(), c); // While you can technically return a QVariant usually this is a sign // of a bug in data(). Disable if this really is ok in your model. // QVERIFY( model->data ( index, Qt::DisplayRole ).isValid() ); @@ -377,16 +381,16 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) } // Check that we can get back our real parent. - QCOMPARE( model->parent ( index ), parent ); + QCOMPARE(model->parent(index), parent); // recursively go down the children - if ( model->hasChildren ( index ) && currentDepth < 10 ) { + if (model->hasChildren(index) && currentDepth < 10) { //qDebug() << r << c << "has children" << model->rowCount(index); - checkChildren ( index, ++currentDepth ); + checkChildren(index, ++currentDepth); }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/ // make sure that after testing the children that the index doesn't change. - QModelIndex newerIndex = model->index ( r, c, parent ); + QModelIndex newerIndex = model->index(r, c, parent); QCOMPARE(index, newerIndex); } } @@ -398,68 +402,61 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) void ModelTest::data() { // Invalid index should return an invalid qvariant - QVERIFY( !model->data ( QModelIndex() ).isValid() ); + QVERIFY(!model->data(QModelIndex()).isValid()); - if ( model->rowCount() == 0 ) + if (model->rowCount() == 0) return; // A valid index should have a valid QVariant data - QVERIFY( model->index ( 0, 0 ).isValid() ); + QVERIFY(model->index(0, 0).isValid()); // shouldn't be able to set data on an invalid index - QVERIFY( !model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) ); + QVERIFY(!model->setData(QModelIndex(), QLatin1String("foo"), Qt::DisplayRole)); // General Purpose roles that should return a QString - QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole ); - if ( variant.isValid() ) { - QVERIFY( variant.canConvert<QString>() ); - } - variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole ); - if ( variant.isValid() ) { - QVERIFY( variant.canConvert<QString>() ); - } - variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole ); - if ( variant.isValid() ) { - QVERIFY( variant.canConvert<QString>() ); - } + QVariant variant = model->data(model->index(0, 0), Qt::ToolTipRole); + if (variant.isValid()) + QVERIFY(variant.canConvert<QString>()); + variant = model->data(model->index(0, 0), Qt::StatusTipRole); + if (variant.isValid()) + QVERIFY(variant.canConvert<QString>()); + variant = model->data(model->index(0, 0), Qt::WhatsThisRole); + if (variant.isValid()) + QVERIFY(variant.canConvert<QString>()); // General Purpose roles that should return a QSize - variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole ); - if ( variant.isValid() ) { - QVERIFY( variant.canConvert<QSize>() ); - } + variant = model->data(model->index(0, 0), Qt::SizeHintRole); + if (variant.isValid()) + QVERIFY(variant.canConvert<QSize>()); // General Purpose roles that should return a QFont - QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole ); - if ( fontVariant.isValid() ) { - QVERIFY( fontVariant.canConvert<QFont>() ); - } + QVariant fontVariant = model->data(model->index(0, 0), Qt::FontRole); + if (fontVariant.isValid()) + QVERIFY(fontVariant.canConvert<QFont>()); // Check that the alignment is one we know about - QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole ); - if ( textAlignmentVariant.isValid() ) { + QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole); + if (textAlignmentVariant.isValid()) { Qt::Alignment alignment = textAlignmentVariant.value<Qt::Alignment>(); - QCOMPARE( alignment, ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) ); + QCOMPARE(alignment, (alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask))); } // General Purpose roles that should return a QColor - QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole ); - if ( colorVariant.isValid() ) { - QVERIFY( colorVariant.canConvert<QColor>() ); - } + QVariant colorVariant = model->data(model->index(0, 0), Qt::BackgroundColorRole); + if (colorVariant.isValid()) + QVERIFY(colorVariant.canConvert<QColor>()); - colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole ); - if ( colorVariant.isValid() ) { - QVERIFY( colorVariant.canConvert<QColor>() ); - } + colorVariant = model->data(model->index(0, 0), Qt::TextColorRole); + if (colorVariant.isValid()) + QVERIFY(colorVariant.canConvert<QColor>()); // Check that the "check state" is one we know about. - QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole ); - if ( checkStateVariant.isValid() ) { + QVariant checkStateVariant = model->data(model->index(0, 0), Qt::CheckStateRole); + if (checkStateVariant.isValid()) { int state = checkStateVariant.toInt(); - QVERIFY( state == Qt::Unchecked || - state == Qt::PartiallyChecked || - state == Qt::Checked ); + QVERIFY(state == Qt::Unchecked + || state == Qt::PartiallyChecked + || state == Qt::Checked); } } @@ -468,7 +465,7 @@ void ModelTest::data() \sa rowsInserted() */ -void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, int /* end */) +void ModelTest::rowsAboutToBeInserted(const QModelIndex &parent, int start, int /* end */) { // Q_UNUSED(end); // qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).toString() @@ -476,10 +473,10 @@ void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, in // qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) ); Changing c; c.parent = parent; - c.oldSize = model->rowCount ( parent ); - c.last = model->data ( model->index ( start - 1, 0, parent ) ); - c.next = model->data ( model->index ( start, 0, parent ) ); - insert.push ( c ); + c.oldSize = model->rowCount(parent); + c.last = model->data(model->index(start - 1, 0, parent)); + c.next = model->data(model->index(start, 0, parent)); + insert.push(c); } /*! @@ -487,10 +484,10 @@ void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, in \sa rowsAboutToBeInserted() */ -void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) +void ModelTest::rowsInserted(const QModelIndex &parent, int start, int end) { Changing c = insert.pop(); - QCOMPARE(c.parent, parent); + QCOMPARE(parent, c.parent); // qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize // << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent ); @@ -500,30 +497,30 @@ void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) // } // qDebug(); - QCOMPARE(c.oldSize + (end - start + 1), model->rowCount(parent)); - QCOMPARE(c.last, model->data(model->index(start - 1, 0, c.parent))); + QCOMPARE(model->rowCount(parent), c.oldSize + (end - start + 1)); + QCOMPARE(model->data(model->index(start - 1, 0, c.parent)), c.last); if (c.next != model->data(model->index(end + 1, 0, c.parent))) { qDebug() << start << end; - for (int i=0; i < model->rowCount(); ++i) + for (int i = 0; i < model->rowCount(); ++i) qDebug() << model->index(i, 0).data().toString(); qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent)); } - QCOMPARE(c.next, model->data(model->index(end + 1, 0, c.parent))); + QCOMPARE(model->data(model->index(end + 1, 0, c.parent)), c.next); } void ModelTest::layoutAboutToBeChanged() { - for ( int i = 0; i < qBound ( 0, model->rowCount(), 100 ); ++i ) - changing.append ( QPersistentModelIndex ( model->index ( i, 0 ) ) ); + for (int i = 0; i < qBound(0, model->rowCount(), 100); ++i) + changing.append(QPersistentModelIndex(model->index(i, 0))); } void ModelTest::layoutChanged() { - for ( int i = 0; i < changing.count(); ++i ) { + for (int i = 0; i < changing.count(); ++i) { QPersistentModelIndex p = changing[i]; - QCOMPARE(QModelIndex(p), model->index(p.row(), p.column(), p.parent())); + QCOMPARE(model->index(p.row(), p.column(), p.parent()), QModelIndex(p)); } changing.clear(); } @@ -533,15 +530,15 @@ void ModelTest::layoutChanged() \sa rowsRemoved() */ -void ModelTest::rowsAboutToBeRemoved ( const QModelIndex &parent, int start, int end ) +void ModelTest::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { -qDebug() << "ratbr" << parent << start << end; + qDebug() << "ratbr" << parent << start << end; Changing c; c.parent = parent; - c.oldSize = model->rowCount ( parent ); - c.last = model->data ( model->index ( start - 1, 0, parent ) ); - c.next = model->data ( model->index ( end + 1, 0, parent ) ); - remove.push ( c ); + c.oldSize = model->rowCount(parent); + c.last = model->data(model->index(start - 1, 0, parent)); + c.next = model->data(model->index(end + 1, 0, parent)); + remove.push(c); } /*! @@ -549,14 +546,14 @@ qDebug() << "ratbr" << parent << start << end; \sa rowsAboutToBeRemoved() */ -void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end ) +void ModelTest::rowsRemoved(const QModelIndex &parent, int start, int end) { - qDebug() << "rr" << parent << start << end; + qDebug() << "rr" << parent << start << end; Changing c = remove.pop(); - QCOMPARE(c.parent, parent); - QCOMPARE(c.oldSize - (end - start + 1), model->rowCount(parent)); - QCOMPARE(c.last, model->data(model->index(start - 1, 0, c.parent))); - QCOMPARE(c.next, model->data(model->index(start, 0, c.parent))); + QCOMPARE(parent, c.parent); + QCOMPARE(model->rowCount(parent), c.oldSize - (end - start + 1)); + QCOMPARE(model->data(model->index(start - 1, 0, c.parent)), c.last); + QCOMPARE(model->data(model->index(start, 0, c.parent)), c.next); } void ModelTest::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) @@ -582,4 +579,3 @@ void ModelTest::headerDataChanged(Qt::Orientation orientation, int start, int en QVERIFY(start < itemCount); QVERIFY(end < itemCount); } - diff --git a/tests/auto/other/modeltest/modeltest.h b/tests/auto/other/modeltest/modeltest.h index 735a422729..4676bf4434 100644 --- a/tests/auto/other/modeltest/modeltest.h +++ b/tests/auto/other/modeltest/modeltest.h @@ -26,7 +26,6 @@ ** ****************************************************************************/ - #ifndef MODELTEST_H #define MODELTEST_H @@ -36,48 +35,48 @@ class ModelTest : public QObject { - Q_OBJECT + Q_OBJECT public: - ModelTest( QAbstractItemModel *model, QObject *parent = 0 ); + ModelTest(QAbstractItemModel *model, QObject *parent = 0); private Q_SLOTS: - void nonDestructiveBasicTest(); - void rowCount(); - void columnCount(); - void hasIndex(); - void index(); - void parent(); - void data(); + void nonDestructiveBasicTest(); + void rowCount(); + void columnCount(); + void hasIndex(); + void index(); + void parent(); + void data(); protected Q_SLOTS: - void runAllTests(); - void layoutAboutToBeChanged(); - void layoutChanged(); - void rowsAboutToBeInserted( const QModelIndex &parent, int start, int end ); - void rowsInserted( const QModelIndex & parent, int start, int end ); - void rowsAboutToBeRemoved( const QModelIndex &parent, int start, int end ); - void rowsRemoved( const QModelIndex & parent, int start, int end ); - void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - void headerDataChanged(Qt::Orientation orientation, int start, int end); + void runAllTests(); + void layoutAboutToBeChanged(); + void layoutChanged(); + void rowsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void rowsInserted(const QModelIndex &parent, int start, int end); + void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void rowsRemoved(const QModelIndex &parent, int start, int end); + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void headerDataChanged(Qt::Orientation orientation, int start, int end); private: - void checkChildren( const QModelIndex &parent, int currentDepth = 0 ); + void checkChildren(const QModelIndex &parent, int currentDepth = 0); - QAbstractItemModel *model; + QAbstractItemModel *model; - struct Changing { - QModelIndex parent; - int oldSize; - QVariant last; - QVariant next; - }; - QStack<Changing> insert; - QStack<Changing> remove; + struct Changing { + QModelIndex parent; + int oldSize; + QVariant last; + QVariant next; + }; + QStack<Changing> insert; + QStack<Changing> remove; - bool fetchingMore; + bool fetchingMore; - QList<QPersistentModelIndex> changing; + QList<QPersistentModelIndex> changing; }; #endif diff --git a/tests/auto/other/modeltest/tst_modeltest.cpp b/tests/auto/other/modeltest/tst_modeltest.cpp index f81fefe9d1..e2d002844b 100644 --- a/tests/auto/other/modeltest/tst_modeltest.cpp +++ b/tests/auto/other/modeltest/tst_modeltest.cpp @@ -26,7 +26,6 @@ ** ****************************************************************************/ - #include <QtTest/QtTest> #include <QtGui/QtGui> #include <QtWidgets/QtWidgets> @@ -34,7 +33,6 @@ #include "modeltest.h" #include "dynamictreemodel.h" - class tst_ModelTest : public QObject { Q_OBJECT @@ -63,7 +61,7 @@ void tst_ModelTest::stringListModel() proxy.setSourceModel(&model); model.setStringList(QStringList() << "2" << "3" << "1"); - model.setStringList(QStringList() << "a" << "e" << "plop" << "b" << "c" ); + model.setStringList(QStringList() << "a" << "e" << "plop" << "b" << "c"); proxy.setDynamicSortFilter(true); proxy.setFilterRegExp(QRegExp("[^b]")); @@ -76,9 +74,8 @@ void tst_ModelTest::treeWidgetModel() ModelTest t1(widget.model()); QTreeWidgetItem *root = new QTreeWidgetItem(&widget, QStringList("root")); - for (int i = 0; i < 20; ++i) { + for (int i = 0; i < 20; ++i) new QTreeWidgetItem(root, QStringList(QString::number(i))); - } QTreeWidgetItem *remove = root->child(2); root->removeChild(remove); QTreeWidgetItem *parent = new QTreeWidgetItem(&widget, QStringList("parent")); @@ -90,10 +87,9 @@ void tst_ModelTest::treeWidgetModel() void tst_ModelTest::standardItemModel() { - QStandardItemModel model(10,10); + QStandardItemModel model(10, 10); QSortFilterProxyModel proxy; - ModelTest t1(&model); ModelTest t2(&proxy); @@ -105,8 +101,8 @@ void tst_ModelTest::standardItemModel() model.insertColumns(2, 5); model.removeColumns(4, 5); - model.insertRows(0,5, model.index(1,1)); - model.insertColumns(0,5, model.index(1,3)); + model.insertRows(0, 5, model.index(1, 1)); + model.insertColumns(0, 5, model.index(1, 3)); } void tst_ModelTest::testInsertThroughProxy() @@ -148,7 +144,9 @@ class AccessibleProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - AccessibleProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {} + AccessibleProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) + { + } QModelIndexList persistent() { @@ -160,14 +158,16 @@ class ObservingObject : public QObject { Q_OBJECT public: - ObservingObject(AccessibleProxyModel *proxy, QObject *parent = 0) - : QObject(parent) - , m_proxy(proxy) - , storePersistentFailureCount(0) - , checkPersistentFailureCount(0) + ObservingObject(AccessibleProxyModel *proxy, QObject *parent = 0) : + QObject(parent), + m_proxy(proxy), + storePersistentFailureCount(0), + checkPersistentFailureCount(0) { - connect(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(storePersistent())); - connect(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(checkPersistent())); + connect(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), + SLOT(storePersistent())); + connect(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + SLOT(checkPersistent())); } public slots: @@ -195,7 +195,7 @@ public slots: void storePersistent() { // This method is called from rowsAboutToBeMoved. Persistent indexes should be valid - foreach(const QModelIndex &idx, m_persistentProxyIndexes) + foreach (const QModelIndex &idx, m_persistentProxyIndexes) if (!idx.isValid()) { qWarning("%s: persistentProxyIndexes contains invalid index", Q_FUNC_INFO); ++storePersistentFailureCount; @@ -233,7 +233,7 @@ public slots: } private: - AccessibleProxyModel *m_proxy; + AccessibleProxyModel *m_proxy; QList<QPersistentModelIndex> m_persistentSourceIndexes; QList<QPersistentModelIndex> m_persistentProxyIndexes; public: @@ -296,6 +296,5 @@ void tst_ModelTest::testResetThroughProxy() QCOMPARE(observer.checkPersistentFailureCount, 0); } - QTEST_MAIN(tst_ModelTest) #include "tst_modeltest.moc" diff --git a/tests/auto/other/qaccessibility/accessiblewidgets.h b/tests/auto/other/qaccessibility/accessiblewidgets.h index 35b1ec890b..62aa38ff6c 100644 --- a/tests/auto/other/qaccessibility/accessiblewidgets.h +++ b/tests/auto/other/qaccessibility/accessiblewidgets.h @@ -98,7 +98,7 @@ public: return 0; } CustomTextWidgetIface(CustomTextWidget *w): QAccessibleWidget(w) {} - void *interface_cast(QAccessible::InterfaceType t) { + void *interface_cast(QAccessible::InterfaceType t) override { if (t == QAccessible::TextInterface) return static_cast<QAccessibleTextInterface*>(this); return 0; @@ -112,19 +112,19 @@ public: return QAccessibleWidget::text(t); } - QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const + QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const override { if (offset == -2) offset = textWidget()->cursorPosition; return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset); } - QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const + QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const override { if (offset == -2) offset = textWidget()->cursorPosition; return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset); } - QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const + QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const override { if (offset == -2) offset = textWidget()->cursorPosition; diff --git a/tests/auto/other/qaccessibilitymac/qaccessibilitymac.pro b/tests/auto/other/qaccessibilitymac/qaccessibilitymac.pro index ceed81c914..e55757775e 100644 --- a/tests/auto/other/qaccessibilitymac/qaccessibilitymac.pro +++ b/tests/auto/other/qaccessibilitymac/qaccessibilitymac.pro @@ -1,6 +1,5 @@ CONFIG += testcase TARGET = tst_qaccessibilitymac -# LIBS += -framework Carbon QT += widgets testlib HEADERS += tst_qaccessibilitymac_helpers.h diff --git a/tests/auto/shared/platformclipboard.h b/tests/auto/shared/platformclipboard.h index c5f1a64dce..15801f6add 100644 --- a/tests/auto/shared/platformclipboard.h +++ b/tests/auto/shared/platformclipboard.h @@ -31,22 +31,12 @@ #include <qglobal.h> -#ifdef Q_OS_OSX -#include <Carbon/Carbon.h> -#endif - struct PlatformClipboard { static inline bool isAvailable() { #if defined(QT_NO_CLIPBOARD) return false; -#elif defined(Q_OS_OSX) - PasteboardRef pasteboard; - OSStatus status = PasteboardCreate(0, &pasteboard); - if (status == noErr) - CFRelease(pasteboard); - return status == noErr; #else return true; #endif diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index d7772f5c34..58648045a3 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -188,6 +188,9 @@ private slots: void sqlite_enable_cache_mode_data() { generic_data("QSQLITE"); } void sqlite_enable_cache_mode(); + void sqlite_enableRegexp_data() { generic_data("QSQLITE"); } + void sqlite_enableRegexp(); + private: void createTestTables(QSqlDatabase db); void dropTestTables(QSqlDatabase db); @@ -2259,5 +2262,33 @@ void tst_QSqlDatabase::sqlite_enable_cache_mode() db2.close(); } +void tst_QSqlDatabase::sqlite_enableRegexp() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + if (db.driverName().startsWith("QSQLITE2")) + QSKIP("SQLite3 specific test"); + + db.close(); + db.setConnectOptions("QSQLITE_ENABLE_REGEXP"); + QVERIFY_SQL(db, open()); + + QSqlQuery q(db); + const QString tableName(qTableName("uint_test", __FILE__, db)); + QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(text TEXT)").arg(tableName))); + QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName))); + q.addBindValue("a0"); + QVERIFY_SQL(q, exec()); + q.addBindValue("a1"); + QVERIFY_SQL(q, exec()); + + QVERIFY_SQL(q, exec(QString("SELECT text FROM %1 WHERE text REGEXP 'a[^0]' " + "ORDER BY text").arg(tableName))); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toString(), QString("a1")); + QFAIL_SQL(q, next()); +} + QTEST_MAIN(tst_QSqlDatabase) #include "tst_qsqldatabase.moc" diff --git a/tests/auto/tools/uic/tst_uic.cpp b/tests/auto/tools/uic/tst_uic.cpp index cf43cb02d3..85668c96d4 100644 --- a/tests/auto/tools/uic/tst_uic.cpp +++ b/tests/auto/tools/uic/tst_uic.cpp @@ -34,6 +34,7 @@ #include <QtCore/QByteArray> #include <QtCore/QLibraryInfo> #include <QtCore/QTemporaryDir> +#include <QtCore/QRegularExpression> #include <QtCore/QStandardPaths> class tst_uic : public QObject @@ -63,12 +64,12 @@ private: const QString m_command; QString m_baseline; QTemporaryDir m_generated; - QRegExp m_versionRegexp; + QRegularExpression m_versionRegexp; }; tst_uic::tst_uic() : m_command(QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/uic")) - , m_versionRegexp(QLatin1String("Created by: Qt User Interface Compiler version [.\\d]{5,5}")) + , m_versionRegexp(QLatin1String("\\*\\* Created by: Qt User Interface Compiler version \\d{1,2}\\.\\d{1,2}\\.\\d{1,2}")) { } diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro index 499ca65516..0e95d454cf 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.pro +++ b/tests/auto/widgets/kernel/qwidget/qwidget.pro @@ -12,7 +12,7 @@ aix-g++*:QMAKE_CXXFLAGS+=-fpermissive CONFIG += x11inc mac { - LIBS += -framework Security -framework AppKit -framework Carbon + LIBS += -framework Security -framework AppKit OBJECTIVE_SOURCES += tst_qwidget_mac_helpers.mm } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 5715505fd6..cd1df49f8c 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -1781,9 +1781,11 @@ void tst_QWidget::windowState() QCOMPARE(widget1.pos(), pos); QCOMPARE(widget1.size(), size); -#define VERIFY_STATE(s) QCOMPARE(int(widget1.windowState() & stateMask), int(s)) +#define VERIFY_STATE(s) \ + QCOMPARE(int(widget1.windowState() & stateMask), int(s)); \ + QCOMPARE(int(widget1.windowHandle()->windowStates() & stateMask), int(s)) - const int stateMask = Qt::WindowMaximized|Qt::WindowMinimized|Qt::WindowFullScreen; + const auto stateMask = Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen; widget1.setWindowState(Qt::WindowMaximized); QTest::qWait(100); diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 6aaac6d135..97d7d78153 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -99,6 +99,9 @@ private slots: void tst_eventfilter_on_toplevel(); void QTBUG_50561_QCocoaBackingStore_paintDevice_crash(); + + void setWindowState_data(); + void setWindowState(); }; void tst_QWidget_window::initTestCase() @@ -861,5 +864,56 @@ void tst_QWidget_window::QTBUG_50561_QCocoaBackingStore_paintDevice_crash() w.close(); } +void tst_QWidget_window::setWindowState_data() +{ + QString platformName = QGuiApplication::platformName().toLower(); + + QTest::addColumn<Qt::WindowStates>("state"); + QTest::newRow("0") << Qt::WindowStates(); + QTest::newRow("Qt::WindowMaximized") << Qt::WindowStates(Qt::WindowMaximized); + QTest::newRow("Qt::WindowMinimized") << Qt::WindowStates(Qt::WindowMinimized); + QTest::newRow("Qt::WindowFullScreen") << Qt::WindowStates(Qt::WindowFullScreen); + + if (platformName != "xcb" && platformName != "windows" && !platformName.startsWith("wayland") + && platformName != "offscreen") + return; // Combination of states is not preserved on all platforms. + if (platformName == "xcb" && qgetenv("XDG_CURRENT_DESKTOP") != "KDE" + && qgetenv("XDG_CURRENT_DESKTOP") != "Unity") + return; // Not all window managers support state combinations. + + QTest::newRow("Qt::WindowMaximized|Qt::WindowMinimized") + << (Qt::WindowMaximized | Qt::WindowMinimized); + QTest::newRow("Qt::WindowFullScreen|Qt::WindowMinimized") + << (Qt::WindowFullScreen | Qt::WindowMinimized); + QTest::newRow("Qt::WindowMaximized|Qt::WindowFullScreen") + << (Qt::WindowMaximized | Qt::WindowFullScreen); + QTest::newRow("Qt::WindowMaximized|Qt::WindowFullScreen|Qt::WindowMinimized") + << (Qt::WindowMaximized | Qt::WindowFullScreen | Qt::WindowMinimized); +} + +void tst_QWidget_window::setWindowState() +{ + QFETCH(Qt::WindowStates, state); + + // This tests make sure that the states are preserved when the window is shown. + + QWidget w; + w.setWindowState(state); + QCOMPARE(w.windowState(), state); + w.show(); + QCOMPARE(w.windowState(), state); + QCOMPARE(w.windowHandle()->windowStates(), state); + QTest::qWaitForWindowExposed(&w); + QTRY_COMPARE(w.windowState(), state); + QCOMPARE(w.windowHandle()->windowStates(), state); + + // Minimizing keeps other states + w.showMinimized(); + QCOMPARE(w.windowState(), state | Qt::WindowMinimized); + QTest::qWait(100); + QCOMPARE(w.windowState(), state | Qt::WindowMinimized); + QCOMPARE(w.windowHandle()->windowStates(), state | Qt::WindowMinimized); +} + QTEST_MAIN(tst_QWidget_window) #include "tst_qwidget_window.moc" diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index f13291d0a9..778ff1d932 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -64,6 +64,7 @@ void tst_QOpenGLWidget::create() { QScopedPointer<QOpenGLWidget> w(new QOpenGLWidget); QVERIFY(!w->isValid()); + QVERIFY(w->textureFormat() == 0); QSignalSpy frameSwappedSpy(w.data(), SIGNAL(frameSwapped())); w->show(); QTest::qWaitForWindowExposed(w.data()); @@ -73,6 +74,7 @@ void tst_QOpenGLWidget::create() QVERIFY(w->context()); QCOMPARE(w->context()->format(), w->format()); QVERIFY(w->defaultFramebufferObject() != 0); + QVERIFY(w->textureFormat() != 0); } class ClearWidget : public QOpenGLWidget, protected QOpenGLFunctions diff --git a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp index 205ef34958..9f64335930 100644 --- a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp +++ b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp @@ -45,6 +45,7 @@ private slots: void destroyIndeterminate(); void text(); void format(); + void setValueRepaint_data(); void setValueRepaint(); #ifndef Q_OS_MAC void setMinMaxRepaint(); @@ -191,21 +192,49 @@ void tst_QProgressBar::format() QCOMPARE(bar.text(), QString()); } +void tst_QProgressBar::setValueRepaint_data() +{ + QTest::addColumn<int>("min"); + QTest::addColumn<int>("max"); + QTest::addColumn<int>("increment"); + + auto add = [](int min, int max, int increment) { + QTest::addRow("%d-%d@%d", min, max, increment) << min << max << increment; + }; + + add(0, 10, 1); + + auto add_set = [=](int min, int max, int increment) { + // check corner cases, and adjacent values (to circumvent explicit checks for corner cases) + add(min, max, increment); + add(min + 1, max, increment); + add(min, max - 1, increment); + add(min + 1, max - 1, increment); + }; + + add_set(INT_MIN, INT_MAX, INT_MAX / 50 + 1); + add_set(0, INT_MAX, INT_MAX / 100 + 1); + add_set(INT_MIN, 0, INT_MAX / 100 + 1); +} + void tst_QProgressBar::setValueRepaint() { + QFETCH(int, min); + QFETCH(int, max); + QFETCH(int, increment); + ProgressBar pbar; - pbar.setMinimum(0); - pbar.setMaximum(10); + pbar.setMinimum(min); + pbar.setMaximum(max); pbar.setFormat("%v"); pbar.move(300, 300); pbar.show(); QVERIFY(QTest::qWaitForWindowExposed(&pbar)); QApplication::processEvents(); - for (int i = pbar.minimum(); i < pbar.maximum(); ++i) { + for (qint64 i = min; i < max; i += increment) { pbar.repainted = false; - pbar.setValue(i); - QTest::qWait(50); + pbar.setValue(int(i)); QTRY_VERIFY(pbar.repainted); } } |