diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2018-08-21 02:32:49 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2018-08-21 02:32:50 +0200 |
commit | 5a03b75c50b2e34552c7ec3e1e15e7b2a0128bf7 (patch) | |
tree | 88e05cd6150e0b3cda4e8716668082c655007fb8 /tests | |
parent | 0e7724079f1eae283714ae12769d1372b8f85659 (diff) | |
parent | 6553921dd537e416da2f4d1441ab6d63059cda60 (diff) |
Merge dev into 5.12
Change-Id: I63f632b595f66d2fc93e9aa713500e3799e3df2a
Diffstat (limited to 'tests')
36 files changed, 701 insertions, 278 deletions
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index eac5b9976d..51d0d2879e 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -154,3 +154,4 @@ if (NOT CMAKE_VERSION VERSION_LESS 3.8) # /usr/bin/ld: CMakeFiles/mywidget.dir/moc_mywidget.cpp.o: previous definition here # Reason: SKIP_* properties were added in CMake 3.8 only expect_pass(test_QTBUG-63422) +endif() diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp index 89c93bf245..7043969c2f 100644 --- a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp +++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp @@ -134,7 +134,7 @@ void transformRegion_template(T (*transformOne)(T), void (*transformRegion)(cons auto checkBounds = [&](int from) { for ( ; from < Size; ++from) - QCOMPARE(dest[from], 0); + QCOMPARE(dest[from], T(0)); }; transformRegion(source, 1, dest); diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index afa15fe895..30f0e447ad 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -33,7 +33,6 @@ #include <qdebug.h> #include <qdir.h> #include <qfileinfo.h> -#include <qregexp.h> #include <qstringlist.h> #if defined(Q_OS_WIN) diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 7615ad4586..1aa8984b70 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2068,6 +2068,21 @@ void tst_QUrl::isValid() } { + QUrl url = QUrl::fromEncoded("foo://%f0%9f%93%99.example.la/g"); + QVERIFY(!url.isValid()); + QVERIFY(url.toString().isEmpty()); + QCOMPARE(url.path(), QString("/g")); + url.setHost("%f0%9f%93%99.example.la/"); + QVERIFY(!url.isValid()); + QVERIFY(url.toString().isEmpty()); + url.setHost("\xf0\x9f\x93\x99.example.la/"); + QVERIFY(!url.isValid()); + QVERIFY(url.toString().isEmpty()); + QVERIFY2(url.errorString().contains("Invalid hostname"), + qPrintable(url.errorString())); + } + + { QUrl url("http://example.com"); QVERIFY(url.isValid()); QVERIFY(!url.toString().isEmpty()); @@ -2798,7 +2813,9 @@ void tst_QUrl::hosts() { QFETCH(QString, url); - QTEST(QUrl(url).host(), "host"); + QUrl u(url); + QTEST(u.host(), "host"); + QVERIFY(u.isEmpty() || u.isValid()); } void tst_QUrl::hostFlags_data() diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro index a09f03a7b4..bcb6e604f8 100644 --- a/tests/auto/corelib/itemmodels/itemmodels.pro +++ b/tests/auto/corelib/itemmodels/itemmodels.pro @@ -11,7 +11,8 @@ qtHaveModule(gui): SUBDIRS += \ qtHaveModule(widgets) { SUBDIRS += \ - qsortfilterproxymodel + qsortfilterproxymodel_regexp \ + qsortfilterproxymodel_regularexpression qtHaveModule(sql): SUBDIRS += \ qitemmodel diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/.gitignore b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/.gitignore deleted file mode 100644 index d3672fe4ae..0000000000 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tst_qsortfilterproxymodel diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/qsortfilterproxymodel.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/qsortfilterproxymodel.pro deleted file mode 100644 index dfa8b9fa1b..0000000000 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/qsortfilterproxymodel.pro +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG += testcase -TARGET = tst_qsortfilterproxymodel - -QT += widgets testlib -mtdir = ../../../other/qabstractitemmodelutils - -INCLUDEPATH += $$PWD/$${mtdir} -SOURCES += tst_qsortfilterproxymodel.cpp $${mtdir}/dynamictreemodel.cpp -HEADERS += $${mtdir}/dynamictreemodel.h diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp index b3431bcc7a..94c3fa6e46 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include <QtTest/QtTest> +#include "tst_qsortfilterproxymodel.h" #include "dynamictreemodel.h" #include <QtCore/QCoreApplication> @@ -36,137 +37,6 @@ #include <qdebug.h> -typedef QList<int> IntList; -typedef QPair<int, int> IntPair; -typedef QList<IntPair> IntPairList; - -Q_DECLARE_METATYPE(QList<QPersistentModelIndex>) - -class tst_QSortFilterProxyModel : public QObject -{ - Q_OBJECT -public: - tst_QSortFilterProxyModel(); - -public slots: - void initTestCase(); - void cleanupTestCase(); - void cleanup(); - -private slots: - void getSetCheck(); - void sort_data(); - void sort(); - void sortHierarchy_data(); - void sortHierarchy(); - - void insertRows_data(); - void insertRows(); - void prependRow(); - void removeRows_data(); - void removeRows(); - void removeColumns_data(); - void removeColumns(); - void insertAfterSelect(); - void removeAfterSelect(); - void filter_data(); - void filter(); - void filterHierarchy_data(); - void filterHierarchy(); - void filterColumns_data(); - void filterColumns(); - - void filterTable(); - void filterCurrent(); - void filter_qtbug30662(); - - void changeSourceLayout(); - void changeSourceLayoutFilteredOut(); - void removeSourceRows_data(); - void removeSourceRows(); - void insertSourceRows_data(); - void insertSourceRows(); - void changeFilter_data(); - void changeFilter(); - void changeSourceData_data(); - void changeSourceData(); - void changeSourceDataKeepsStableSorting_qtbug1548(); - void changeSourceDataForwardsRoles_qtbug35440(); - void resortingDoesNotBreakTreeModels(); - void dynamicFilterWithoutSort(); - void sortFilterRole(); - void selectionFilteredOut(); - void match_data(); - void match(); - void insertIntoChildrenlessItem(); - void invalidateMappedChildren(); - void insertRowIntoFilteredParent(); - void filterOutParentAndFilterInChild(); - - void sourceInsertRows(); - void sourceModelDeletion(); - - void sortColumnTracking1(); - void sortColumnTracking2(); - - void sortStable(); - - void hiddenColumns(); - void insertRowsSort(); - void staticSorting(); - void dynamicSorting(); - void fetchMore(); - void hiddenChildren(); - void mapFromToSource(); - void removeRowsRecursive(); - void doubleProxySelectionSetSourceModel(); - void appearsAndSort(); - void unnecessaryDynamicSorting(); - void unnecessaryMapCreation(); - void resetInvalidate_data(); - void resetInvalidate(); - - void testMultipleProxiesWithSelection(); - void mapSelectionFromSource(); - void testResetInternalData(); - void filteredColumns(); - void headerDataChanged(); - - void testParentLayoutChanged(); - void moveSourceRows(); - - void hierarchyFilterInvalidation(); - void simpleFilterInvalidation(); - - void chainedProxyModelRoleNames(); - - void noMapAfterSourceDelete(); - void forwardDropApi(); - void canDropMimeData(); - void filterHint(); - - void sourceLayoutChangeLeavesValidPersistentIndexes(); - void rowMoveLeavesValidPersistentIndexes(); - - void emitLayoutChangedOnlyIfSortingChanged_data(); - void emitLayoutChangedOnlyIfSortingChanged(); - - void checkSetNewModel(); - - void removeIntervals_data(); - void removeIntervals(); - -protected: - void buildHierarchy(const QStringList &data, QAbstractItemModel *model); - void checkHierarchy(const QStringList &data, const QAbstractItemModel *model); - -private: - QStandardItemModel *m_model; - QSortFilterProxyModel *m_proxy; -}; - -Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint) - // Testing get/set functions void tst_QSortFilterProxyModel::getSetCheck() { @@ -204,7 +74,15 @@ void tst_QSortFilterProxyModel::cleanupTestCase() void tst_QSortFilterProxyModel::cleanup() { - m_proxy->setFilterRegExp(QRegExp()); + switch (m_filterType) { + case FilterType::RegExp: + m_proxy->setFilterRegExp(QRegExp()); + break; + case FilterType::RegularExpression: + m_proxy->setFilterRegularExpression(QRegularExpression()); + break; + } + m_proxy->sort(-1, Qt::AscendingOrder); m_model->clear(); m_model->insertColumns(0, 1); @@ -915,8 +793,9 @@ void tst_QSortFilterProxyModel::removeRows() if (sortOrder != -1) proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder)); + if (!filter.isEmpty()) - proxy.setFilterRegExp(QRegExp(filter)); + setupFilter(&proxy, filter); // remove the rows QCOMPARE(proxy.removeRows(position, count, QModelIndex()), success); @@ -938,14 +817,29 @@ class MyFilteredColumnProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - MyFilteredColumnProxyModel(QObject *parent = 0) - : QSortFilterProxyModel(parent) { } + MyFilteredColumnProxyModel(FilterType filterType, QObject *parent = 0) : + QSortFilterProxyModel(parent), + m_filterType(filterType) + { } + protected: bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const { QString key = sourceModel()->headerData(sourceColumn, Qt::Horizontal).toString(); - return key.contains(filterRegExp()); + bool result = false; + switch (m_filterType) { + case FilterType::RegExp: + result = key.contains(filterRegExp()); + break; + case FilterType::RegularExpression: + result = key.contains(filterRegularExpression()); + break; + } + return result; } + +private: + FilterType m_filterType; }; void tst_QSortFilterProxyModel::removeColumns_data() @@ -1154,10 +1048,10 @@ void tst_QSortFilterProxyModel::removeColumns() QFETCH(QStringList, expectedSource); QStandardItemModel model; - MyFilteredColumnProxyModel proxy; + MyFilteredColumnProxyModel proxy(m_filterType); proxy.setSourceModel(&model); if (!filter.isEmpty()) - proxy.setFilterRegExp(QRegExp(filter)); + setupFilter(&proxy, filter); // prepare model model.setHorizontalHeaderLabels(initial); @@ -1225,7 +1119,8 @@ void tst_QSortFilterProxyModel::filterColumns() QModelIndex index = m_model->index(0, col, QModelIndex()); m_model->setData(index, initial.at(col), Qt::DisplayRole); } - m_proxy->setFilterRegExp(pattern); + setupFilter(m_proxy, pattern); + m_proxy->setFilterKeyColumn(-1); // make sure the model is unchanged for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) { @@ -1291,6 +1186,7 @@ void tst_QSortFilterProxyModel::filter() QFETCH(QString, pattern); QFETCH(QStringList, initial); QFETCH(QStringList, expected); + // prepare model QVERIFY(m_model->insertRows(0, initial.count(), QModelIndex())); QCOMPARE(m_model->rowCount(QModelIndex()), initial.count()); @@ -1300,7 +1196,7 @@ void tst_QSortFilterProxyModel::filter() QModelIndex index = m_model->index(row, 0, QModelIndex()); m_model->setData(index, initial.at(row), Qt::DisplayRole); } - m_proxy->setFilterRegExp(pattern); + setupFilter(m_proxy, pattern); // make sure the proxy is unfiltered QCOMPARE(m_proxy->columnCount(QModelIndex()), 1); QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count()); @@ -1339,7 +1235,7 @@ void tst_QSortFilterProxyModel::filterHierarchy() QFETCH(QStringList, initial); QFETCH(QStringList, expected); buildHierarchy(initial, m_model); - m_proxy->setFilterRegExp(pattern); + setupFilter(m_proxy, pattern); checkHierarchy(initial, m_model); checkHierarchy(expected, m_proxy); } @@ -1404,6 +1300,18 @@ void tst_QSortFilterProxyModel::checkHierarchy(const QStringList &l, const QAbst } } +void tst_QSortFilterProxyModel::setupFilter(QSortFilterProxyModel *model, const QString& pattern) +{ + switch (m_filterType) { + case FilterType::RegExp: + model->setFilterRegExp(pattern); + break; + case FilterType::RegularExpression: + model->setFilterRegularExpression(pattern); + break; + } +} + class TestModel: public QAbstractTableModel { public: @@ -1422,7 +1330,7 @@ void tst_QSortFilterProxyModel::filterTable() TestModel model; QSortFilterProxyModel filter; filter.setSourceModel(&model); - filter.setFilterRegExp("9"); + setupFilter(&filter, QLatin1String("9")); for (int i = 0; i < filter.rowCount(); ++i) QVERIFY(filter.data(filter.index(i, 0)).toString().contains(QLatin1Char('9'))); @@ -1486,7 +1394,7 @@ void tst_QSortFilterProxyModel::filterCurrent() view.setCurrentIndex(proxy.index(0, 0)); QCOMPARE(spy.count(), 1); - proxy.setFilterRegExp(QRegExp("^B")); + setupFilter(&proxy, QLatin1String("^B")); QCOMPARE(spy.count(), 2); } @@ -1497,7 +1405,7 @@ void tst_QSortFilterProxyModel::filter_qtbug30662() proxy.setSourceModel(&model); // make sure the filter does not match any entry - proxy.setFilterRegExp(QRegExp("[0-9]+")); + setupFilter(&proxy, QLatin1String("[0-9]+")); QStringList slSource; slSource << "z" << "x" << "a" << "b"; @@ -1507,7 +1415,7 @@ void tst_QSortFilterProxyModel::filter_qtbug30662() model.setStringList(slSource); // without fix for QTBUG-30662 this will make all entries visible - but unsorted - proxy.setFilterRegExp(QRegExp("[a-z]+")); + setupFilter(&proxy, QLatin1String("[a-z]+")); QStringList slResult; for (int i = 0; i < proxy.rowCount(); ++i) @@ -1553,7 +1461,8 @@ void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut() QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved); // Filter everything out - proxy.setFilterRegExp(QRegExp("c")); + setupFilter(&proxy, QLatin1String("c")); + QCOMPARE(removeSpy.count(), 1); QCOMPARE(0, proxy.rowCount()); @@ -1562,7 +1471,8 @@ void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut() QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted); // Remove filter; we expect an insert - proxy.setFilterRegExp(QRegExp("")); + setupFilter(&proxy, ""); + QCOMPARE(insertSpy.count(), 1); QCOMPARE(beforeSortFilter, proxy.rowCount()); } @@ -1842,7 +1752,7 @@ void tst_QSortFilterProxyModel::changeFilter() QVERIFY(initialRemoveSpy.isValid()); QVERIFY(initialInsertSpy.isValid()); - proxy.setFilterRegExp(initialFilter); + setupFilter(&proxy, initialFilter); QCOMPARE(initialRemoveSpy.count(), initialRemoveIntervals.count()); QCOMPARE(initialInsertSpy.count(), 0); @@ -1866,7 +1776,7 @@ void tst_QSortFilterProxyModel::changeFilter() QVERIFY(finalRemoveSpy.isValid()); QVERIFY(finalInsertSpy.isValid()); - proxy.setFilterRegExp(finalFilter); + setupFilter(&proxy, finalFilter); QCOMPARE(finalRemoveSpy.count(), finalRemoveIntervals.count()); for (int i = 0; i < finalRemoveSpy.count(); ++i) { @@ -2060,7 +1970,7 @@ void tst_QSortFilterProxyModel::changeSourceData() proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder)); (void)proxy.rowCount(QModelIndex()); // force mapping - proxy.setFilterRegExp(filter); + setupFilter(&proxy, filter); QCOMPARE(proxy.rowCount(), expectedInitialProxyItems.count()); for (int i = 0; i < expectedInitialProxyItems.count(); ++i) { @@ -2253,7 +2163,8 @@ void tst_QSortFilterProxyModel::sortFilterRole() model.setData(index, sourceItems.at(i).second, Qt::UserRole); } - proxy.setFilterRegExp("2"); + setupFilter(&proxy, QLatin1String("2")); + QCOMPARE(proxy.rowCount(), 0); // Qt::DisplayRole is default role proxy.setFilterRole(Qt::UserRole); @@ -2262,7 +2173,8 @@ void tst_QSortFilterProxyModel::sortFilterRole() proxy.setFilterRole(Qt::DisplayRole); QCOMPARE(proxy.rowCount(), 0); - proxy.setFilterRegExp("1|2|3"); + setupFilter(&proxy, QLatin1String("1|2|3")); + QCOMPARE(proxy.rowCount(), 0); proxy.setFilterRole(Qt::UserRole); @@ -2273,7 +2185,8 @@ void tst_QSortFilterProxyModel::sortFilterRole() proxy.setSortRole(Qt::UserRole); proxy.setFilterRole(Qt::DisplayRole); - proxy.setFilterRegExp("a|c"); + setupFilter(&proxy, QLatin1String("a|c")); + QCOMPARE(proxy.rowCount(), orderedItems.count()); for (int i = 0; i < proxy.rowCount(); ++i) { QModelIndex index = proxy.index(i, 0, QModelIndex()); @@ -2297,7 +2210,8 @@ void tst_QSortFilterProxyModel::selectionFilteredOut() view.setCurrentIndex(proxy.index(0, 0)); QCOMPARE(spy.count(), 1); - proxy.setFilterRegExp(QRegExp("^B")); + + setupFilter(&proxy, QLatin1String("^B")); QCOMPARE(spy.count(), 2); } @@ -2383,7 +2297,7 @@ void tst_QSortFilterProxyModel::match() } proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder)); - proxy.setFilterRegExp(filter); + setupFilter(&proxy, filter); QModelIndex startIndex = proxy.index(proxyStartRow, 0); QModelIndexList indexes = proxy.match(startIndex, Qt::DisplayRole, what, @@ -2508,7 +2422,8 @@ void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild() QSortFilterProxyModel proxy; proxy.setSourceModel(&model); - proxy.setFilterRegExp("A|B"); + setupFilter(&proxy, QLatin1String("A|B")); + QStandardItem *itemA = new QStandardItem("A"); model.appendRow(itemA); // not filtered QStandardItem *itemB = new QStandardItem("B"); @@ -2522,7 +2437,7 @@ void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild() QVERIFY(removedSpy.isValid()); QVERIFY(insertedSpy.isValid()); - proxy.setFilterRegExp("C"); // A and B will be filtered out, C filtered in + setupFilter(&proxy, QLatin1String("C")); // A and B will be filtered out, C filtered in // we should now have been notified that the subtree represented by itemA has been removed QCOMPARE(removedSpy.count(), 1); @@ -2935,7 +2850,7 @@ void tst_QSortFilterProxyModel::hiddenChildren() itemA->appendRow(itemB); QStandardItem *itemC = new QStandardItem("C"); itemA->appendRow(itemC); - proxy.setFilterRegExp("VISIBLE"); + setupFilter(&proxy, QLatin1String("VISIBLE")); QCOMPARE(proxy.rowCount(QModelIndex()) , 1); QPersistentModelIndex indexA = proxy.index(0,0); @@ -2962,7 +2877,8 @@ void tst_QSortFilterProxyModel::hiddenChildren() QModelIndex indexC = proxy.index(0, 0, indexA); QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE")); - proxy.setFilterRegExp("C"); + setupFilter(&proxy, QLatin1String("C")); + QCOMPARE(proxy.rowCount(QModelIndex()), 0); itemC->setText("invisible"); itemA->setText("AC"); @@ -3284,7 +3200,8 @@ void tst_QSortFilterProxyModel::mapSelectionFromSource() QSortFilterProxyModel proxy; proxy.setDynamicSortFilter(true); - proxy.setFilterRegExp("d.*"); + setupFilter(&proxy, QLatin1String("d.*")); + proxy.setSourceModel(&model); // Only "delta" remains. @@ -3839,13 +3756,13 @@ void tst_QSortFilterProxyModel::moveSourceRows() filterProxy.setDynamicSortFilter(true); filterProxy.sort(0, Qt::AscendingOrder); filterProxy.setSourceModel(&proxy); - filterProxy.setFilterRegExp("6"); // One of the parents + setupFilter(&filterProxy, QLatin1String("6")); // One of the parents QSortFilterProxyModel filterBothProxy; filterBothProxy.setDynamicSortFilter(true); filterBothProxy.sort(0, Qt::AscendingOrder); filterBothProxy.setSourceModel(&proxy); - filterBothProxy.setFilterRegExp("5"); // The parents are 6 and 3. This filters both out. + setupFilter(&filterBothProxy, QLatin1String("5")); // The parents are 6 and 3. This filters both out. QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved); QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved); @@ -4243,7 +4160,7 @@ void tst_QSortFilterProxyModel::filterHint() QSortFilterProxyModel proxy2; proxy2.setSourceModel(&proxy1); proxy2.setFilterRole(Qt::DisplayRole); - proxy2.setFilterRegExp("^[^ ]*$"); + setupFilter(&proxy2, QLatin1String("^[^ ]*$")); proxy2.setDynamicSortFilter(true); QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged); @@ -4371,8 +4288,7 @@ void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes() QSortFilterProxyModel proxy1; proxy1.setSourceModel(&model); Q_SET_OBJECT_NAME(proxy1); - - proxy1.setFilterRegExp("1|2"); + setupFilter(&proxy1, QLatin1String("1|2")); // The current state of things: // model proxy @@ -4419,7 +4335,7 @@ void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes() proxy1.setSourceModel(&model); Q_SET_OBJECT_NAME(proxy1); - proxy1.setFilterRegExp("1|2"); + setupFilter(&proxy1, QLatin1String("1|2")); auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first(); auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first(); @@ -4653,7 +4569,7 @@ void tst_QSortFilterProxyModel::removeIntervals() if (sortOrder != -1) proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder)); if (!filter.isEmpty()) - proxy.setFilterRegExp(QRegExp(filter)); + setupFilter(&proxy, filter); (void)proxy.rowCount(QModelIndex()); // force mapping @@ -4746,5 +4662,4 @@ void tst_QSortFilterProxyModel::checkSetNewModel() QCoreApplication::processEvents(); } -QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h new file mode 100644 index 0000000000..92f0b35065 --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TST_QSORTFILTERPROXYMODEL_H +#define TST_QSORTFILTERPROXYMODEL_H + +#include <QtTest/QtTest> +#include "dynamictreemodel.h" + +#include <QtCore/QCoreApplication> +#include <QtGui/QStandardItem> +#include <QtWidgets/QTreeView> +#include <QtWidgets/QTableView> + +#include <qdebug.h> + +typedef QList<int> IntList; +typedef QPair<int, int> IntPair; +typedef QList<IntPair> IntPairList; + +enum class FilterType { + RegExp, + RegularExpression +}; + +Q_DECLARE_METATYPE(QList<QPersistentModelIndex>) + +class tst_QSortFilterProxyModel : public QObject +{ + Q_OBJECT + +public: + tst_QSortFilterProxyModel(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void cleanup(); + +private slots: + void getSetCheck(); + void sort_data(); + void sort(); + void sortHierarchy_data(); + void sortHierarchy(); + + void insertRows_data(); + void insertRows(); + void prependRow(); + void removeRows_data(); + void removeRows(); + void removeColumns_data(); + void removeColumns(); + void insertAfterSelect(); + void removeAfterSelect(); + void filter_data(); + void filter(); + void filterHierarchy_data(); + void filterHierarchy(); + void filterColumns_data(); + void filterColumns(); + + void filterTable(); + void filterCurrent(); + void filter_qtbug30662(); + + void changeSourceLayout(); + void changeSourceLayoutFilteredOut(); + void removeSourceRows_data(); + void removeSourceRows(); + void insertSourceRows_data(); + void insertSourceRows(); + void changeFilter_data(); + void changeFilter(); + void changeSourceData_data(); + void changeSourceData(); + void changeSourceDataKeepsStableSorting_qtbug1548(); + void changeSourceDataForwardsRoles_qtbug35440(); + void resortingDoesNotBreakTreeModels(); + void dynamicFilterWithoutSort(); + void sortFilterRole(); + void selectionFilteredOut(); + void match_data(); + void match(); + void insertIntoChildrenlessItem(); + void invalidateMappedChildren(); + void insertRowIntoFilteredParent(); + void filterOutParentAndFilterInChild(); + + void sourceInsertRows(); + void sourceModelDeletion(); + + void sortColumnTracking1(); + void sortColumnTracking2(); + + void sortStable(); + + void hiddenColumns(); + void insertRowsSort(); + void staticSorting(); + void dynamicSorting(); + void fetchMore(); + void hiddenChildren(); + void mapFromToSource(); + void removeRowsRecursive(); + void doubleProxySelectionSetSourceModel(); + void appearsAndSort(); + void unnecessaryDynamicSorting(); + void unnecessaryMapCreation(); + void resetInvalidate_data(); + void resetInvalidate(); + + void testMultipleProxiesWithSelection(); + void mapSelectionFromSource(); + void testResetInternalData(); + void filteredColumns(); + void headerDataChanged(); + + void testParentLayoutChanged(); + void moveSourceRows(); + + void hierarchyFilterInvalidation(); + void simpleFilterInvalidation(); + + void chainedProxyModelRoleNames(); + + void noMapAfterSourceDelete(); + void forwardDropApi(); + void canDropMimeData(); + void filterHint(); + + void sourceLayoutChangeLeavesValidPersistentIndexes(); + void rowMoveLeavesValidPersistentIndexes(); + + void emitLayoutChangedOnlyIfSortingChanged_data(); + void emitLayoutChangedOnlyIfSortingChanged(); + + void checkSetNewModel(); + + void removeIntervals_data(); + void removeIntervals(); + +protected: + void buildHierarchy(const QStringList &data, QAbstractItemModel *model); + void checkHierarchy(const QStringList &data, const QAbstractItemModel *model); + void setupFilter(QSortFilterProxyModel *model, const QString& pattern); + +protected: + FilterType m_filterType; + +private: + QStandardItemModel *m_model; + QSortFilterProxyModel *m_proxy; +}; + +Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint) + +#endif // TST_QSORTFILTERPROXYMODEL_H diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore new file mode 100644 index 0000000000..4fdaebc09d --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore @@ -0,0 +1 @@ +tst_qsortfilterproxymodel_regexp diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro new file mode 100644 index 0000000000..7c510930f4 --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro @@ -0,0 +1,16 @@ +CONFIG += testcase +TARGET = tst_qsortfilterproxymodel_regexp + +QT += widgets testlib +mtdir = ../../../other/qabstractitemmodelutils +qsfpmdir = ../qsortfilterproxymodel_common + +INCLUDEPATH += $$PWD/$${mtdir} $$PWD/$${qsfpmdir} +SOURCES += \ + tst_qsortfilterproxymodel_regexp.cpp \ + $${qsfpmdir}/tst_qsortfilterproxymodel.cpp \ + $${mtdir}/dynamictreemodel.cpp + +HEADERS += \ + $${qsfpmdir}/tst_qsortfilterproxymodel.h \ + $${mtdir}/dynamictreemodel.h diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp new file mode 100644 index 0000000000..e83738661e --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include "tst_qsortfilterproxymodel.h" + +class tst_QSortFilterProxyModelRegExp : public tst_QSortFilterProxyModel +{ + Q_OBJECT +public: + tst_QSortFilterProxyModelRegExp(); +private slots: + void tst_invalid(); +}; + +tst_QSortFilterProxyModelRegExp::tst_QSortFilterProxyModelRegExp() : + tst_QSortFilterProxyModel() +{ + m_filterType = FilterType::RegExp; +} + +void tst_QSortFilterProxyModelRegExp::tst_invalid() +{ + const QLatin1String pattern("test"); + QSortFilterProxyModel model; + model.setFilterRegExp(pattern); + QCOMPARE(model.filterRegExp(), QRegExp(pattern)); + model.setFilterRegularExpression(pattern); + QCOMPARE(model.filterRegExp(), QRegExp()); +} + +QTEST_MAIN(tst_QSortFilterProxyModelRegExp) +#include "tst_qsortfilterproxymodel_regexp.moc" diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore new file mode 100644 index 0000000000..286771e250 --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore @@ -0,0 +1 @@ +tst_qsortfilterproxymodel_regularexpression diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro new file mode 100644 index 0000000000..e993d07126 --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro @@ -0,0 +1,16 @@ +CONFIG += testcase +TARGET = tst_qsortfilterproxymodel_regularexpression + +QT += widgets testlib +mtdir = ../../../other/qabstractitemmodelutils +qsfpmdir = ../qsortfilterproxymodel_common + +INCLUDEPATH += $$PWD/$${mtdir} $${qsfpmdir} +SOURCES += \ + tst_qsortfilterproxymodel_regularexpression.cpp \ + $${qsfpmdir}/tst_qsortfilterproxymodel.cpp \ + $${mtdir}/dynamictreemodel.cpp + +HEADERS += \ + $${qsfpmdir}/tst_qsortfilterproxymodel.h \ + $${mtdir}/dynamictreemodel.h diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp new file mode 100644 index 0000000000..821e199bcb --- /dev/null +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include "tst_qsortfilterproxymodel.h" + +class tst_QSortFilterProxyModelRegularExpression : public tst_QSortFilterProxyModel +{ + Q_OBJECT +public: + tst_QSortFilterProxyModelRegularExpression(); +private slots: + void tst_invalid(); +}; + +tst_QSortFilterProxyModelRegularExpression::tst_QSortFilterProxyModelRegularExpression() : + tst_QSortFilterProxyModel() +{ + m_filterType = FilterType::RegularExpression; +} + +void tst_QSortFilterProxyModelRegularExpression::tst_invalid() +{ + const QLatin1String pattern("test"); + QSortFilterProxyModel model; + model.setFilterRegularExpression(pattern); + QCOMPARE(model.filterRegularExpression(), QRegularExpression(pattern)); + model.setFilterRegExp(pattern); + QCOMPARE(model.filterRegularExpression(), QRegularExpression()); +} + +QTEST_MAIN(tst_QSortFilterProxyModelRegularExpression) +#include "tst_qsortfilterproxymodel_regularexpression.moc" diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 5e9dbdd226..a53501b9dd 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -415,7 +415,7 @@ void tst_QCoreApplication::removePostedEvents() expected.clear(); } -#ifndef QT_NO_THREAD +#if QT_CONFIG(thread) class DeliverInDefinedOrderThread : public QThread { Q_OBJECT @@ -532,7 +532,7 @@ void tst_QCoreApplication::deliverInDefinedOrder() QObject::connect(&obj, SIGNAL(done()), &app, SLOT(quit())); app.exec(); } -#endif // QT_NO_QTHREAD +#endif // QT_CONFIG(thread) void tst_QCoreApplication::applicationPid() { diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h index b6c20a915f..105cca5174 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -43,7 +43,7 @@ private slots: void argc(); void postEvent(); void removePostedEvents(); -#ifndef QT_NO_THREAD +#if QT_CONFIG(thread) void deliverInDefinedOrder(); #endif void applicationPid(); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.foo b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.foo new file mode 100644 index 0000000000..ed5e761417 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.foo @@ -0,0 +1,3 @@ +<?foo> +<blah> +</blah> diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.xml b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.xml new file mode 100644 index 0000000000..27b5bd7e1f --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'> + <!-- The real life example would be that this mime type is a sub class of application/xml + which has a magic that matches <?xml . + XML files with an early appearing qnx tag are detected as + application/vnd.qnx.bar-descriptor. We want that XML files without the qnx tag to be + identified as application/xml, independent of the order in which the two are registered. --> + <mime-type type="application/vnd.qnx.bar-descriptor"> + <sub-class-of type="application/foo"/> + <glob pattern="*.foo"/> + <magic><!-- higher priority than the parent magic --> + <match value="<qnx>" type="string" offset="0:200"/> + </magic> + </mime-type> + <mime-type type="application/foo"> + <glob pattern="*.foo"/> + <magic priority="40"> + <match value="<?foo" type="string" offset="0"/> + </magic> + </mime-type> +</mime-info> diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy2.foo b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy2.foo new file mode 100644 index 0000000000..fd90ed04b3 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy2.foo @@ -0,0 +1,3 @@ +<?foo> +<qnx> +</qnx> diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc b/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc index 29666627a1..1002d0195d 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc +++ b/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc @@ -7,5 +7,8 @@ <file>invalid-magic1.xml</file> <file>invalid-magic2.xml</file> <file>invalid-magic3.xml</file> + <file>magic-and-hierarchy.xml</file> + <file>magic-and-hierarchy.foo</file> + <file>magic-and-hierarchy2.foo</file> </qresource> </RCC> diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 3144c3071c..597d51e7e0 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -52,6 +52,7 @@ static const char *const additionalMimeFiles[] = { "invalid-magic1.xml", "invalid-magic2.xml", "invalid-magic3.xml", + "magic-and-hierarchy.xml", 0 }; @@ -985,6 +986,12 @@ void tst_QMimeDatabase::installNewGlobalMimeType() qDebug() << objcsrc.globPatterns(); } + const QString fooTestFile = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy.foo"); + QCOMPARE(db.mimeTypeForFile(fooTestFile).name(), QString::fromLatin1("application/foo")); + + const QString fooTestFile2 = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy2.foo"); + QCOMPARE(db.mimeTypeForFile(fooTestFile2).name(), QString::fromLatin1("application/vnd.qnx.bar-descriptor")); + // Now test removing the mimetype definitions again for (int i = 0; i < m_additionalMimeFileNames.size(); ++i) QFile::remove(destDir + m_additionalMimeFileNames.at(i)); diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp b/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp index 9179750218..d27884197a 100644 --- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp +++ b/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp @@ -30,7 +30,6 @@ #include "qplatformdefs.h" #include "qthreadonce.h" -#ifndef QT_NO_THREAD #include "qmutex.h" Q_GLOBAL_STATIC_WITH_ARGS(QMutex, onceInitializationMutex, (QMutex::Recursive)) @@ -104,5 +103,3 @@ void QOnceControl::done() { extra &= ~MustRunCode; } - -#endif // QT_NO_THREAD diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.h b/tests/auto/corelib/thread/qthreadonce/qthreadonce.h index 71e830ca16..e5918b8fa5 100644 --- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.h +++ b/tests/auto/corelib/thread/qthreadonce/qthreadonce.h @@ -34,8 +34,6 @@ #include <QtCore/qatomic.h> -#ifndef QT_NO_THREAD - class QOnceControl { public: @@ -91,6 +89,4 @@ public: inline operator T*() { return value(); } }; -#endif // QT_NO_THREAD - #endif diff --git a/tests/auto/corelib/thread/thread.pro b/tests/auto/corelib/thread/thread.pro index d3c669859b..dc60e5a7f5 100644 --- a/tests/auto/corelib/thread/thread.pro +++ b/tests/auto/corelib/thread/thread.pro @@ -1,22 +1,25 @@ TEMPLATE=subdirs -SUBDIRS=\ - qatomicint \ - qatomicinteger \ - qatomicpointer \ - qresultstore \ - qfuture \ - qfuturesynchronizer \ - qmutex \ - qmutexlocker \ - qreadlocker \ - qreadwritelock \ - qsemaphore \ - qthread \ - qthreadonce \ - qthreadpool \ - qthreadstorage \ - qwaitcondition \ - qwritelocker + +qtHaveFeature(thread) { + SUBDIRS=\ + qatomicint \ + qatomicinteger \ + qatomicpointer \ + qresultstore \ + qfuture \ + qfuturesynchronizer \ + qmutex \ + qmutexlocker \ + qreadlocker \ + qreadwritelock \ + qsemaphore \ + qthread \ + qthreadonce \ + qthreadpool \ + qthreadstorage \ + qwaitcondition \ + qwritelocker +} qtHaveModule(concurrent) { SUBDIRS += \ diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 7efcd14d33..9e9ba03a60 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -78,6 +78,7 @@ private slots: #endif void ctor(); + void emptyCtor_data(); void emptyCtor(); void consistentC(); void matchingLocales(); @@ -157,6 +158,7 @@ private slots: private: QString m_decimal, m_thousand, m_sdate, m_ldate, m_time; QString m_sysapp; + QStringList cleanEnv; bool europeanTimeZone; }; @@ -189,6 +191,14 @@ void tst_QLocale::initTestCase() QVERIFY2(fi.exists() && fi.isExecutable(), qPrintable(QDir::toNativeSeparators(m_sysapp) + QStringLiteral(" does not exist or is not executable."))); + + // Get an environment free of any locale-related variables + cleanEnv.clear(); + foreach (QString const& entry, QProcess::systemEnvironment()) { + if (entry.startsWith("LANG=") || entry.startsWith("LC_") || entry.startsWith("LANGUAGE=")) + continue; + cleanEnv << entry; + } #endif // QT_CONFIG(process) } @@ -528,81 +538,107 @@ static inline bool runSysAppTest(const QString &binary, } #endif -void tst_QLocale::emptyCtor() +void tst_QLocale::emptyCtor_data() { #if !QT_CONFIG(process) QSKIP("No qprocess support", SkipAll); -#else +#endif #ifdef Q_OS_ANDROID QSKIP("This test crashes on Android"); #endif -#define TEST_CTOR(req_lc, exp_str) \ - { \ - /* Test constructor without arguments. Needs separate process */ \ - /* because of caching of the system locale. */ \ - QString errorMessage; \ - QVERIFY2(runSysAppTest(m_sysapp, env, QLatin1String(req_lc), QLatin1String(exp_str), &errorMessage), \ - qPrintable(errorMessage)); \ - } - // Get an environment free of any locale-related variables - QStringList env; - foreach (QString const& entry, QProcess::systemEnvironment()) { - if (entry.startsWith("LANG=") || entry.startsWith("LC_") || entry.startsWith("LANGUAGE=")) - continue; - env << entry; - } + QTest::addColumn<QString>("expected"); + +#define ADD_CTOR_TEST(give, expect) QTest::newRow(give) << QStringLiteral(expect); + + // For format and meaning, see: + // http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html + // Note that the accepted values for fields are implementation-dependent; + // the template is language[_territory][.codeset][@modifier] + + // Vanilla: + ADD_CTOR_TEST("C", "C"); + + // Standard forms: + ADD_CTOR_TEST("en", "en_US"); + ADD_CTOR_TEST("en_GB", "en_GB"); + ADD_CTOR_TEST("de", "de_DE"); + // Norsk has some quirks: + ADD_CTOR_TEST("no", "nb_NO"); + ADD_CTOR_TEST("nb", "nb_NO"); + ADD_CTOR_TEST("nn", "nn_NO"); + ADD_CTOR_TEST("no_NO", "nb_NO"); + ADD_CTOR_TEST("nb_NO", "nb_NO"); + ADD_CTOR_TEST("nn_NO", "nn_NO"); + + // Not too fussy about case: + ADD_CTOR_TEST("DE", "de_DE"); + ADD_CTOR_TEST("EN", "en_US"); + + // Invalid fields + ADD_CTOR_TEST("bla", "C"); + ADD_CTOR_TEST("zz", "C"); + ADD_CTOR_TEST("zz_zz", "C"); + ADD_CTOR_TEST("zz...", "C"); + ADD_CTOR_TEST("en.bla", "en_US"); +#if !(defined(Q_OS_DARWIN) && QT_HAS_FEATURE(address_sanitizer)) + // See QTBUG-69875 + ADD_CTOR_TEST("en@bla", "en_US"); +#endif + ADD_CTOR_TEST("en_blaaa", "en_US"); + ADD_CTOR_TEST("en_zz", "en_US"); + ADD_CTOR_TEST("en_GB.bla", "en_GB"); + ADD_CTOR_TEST("en_GB@.bla", "en_GB"); + ADD_CTOR_TEST("en_GB@bla", "en_GB"); + + // Empty optional fields, but with punctuators supplied + ADD_CTOR_TEST("en.", "en_US"); +#if !(defined(Q_OS_DARWIN) && QT_HAS_FEATURE(address_sanitizer)) + // See QTBUG-69875 + ADD_CTOR_TEST("en@", "en_US"); +#endif + ADD_CTOR_TEST("en.@", "en_US"); + ADD_CTOR_TEST("en_", "en_US"); + ADD_CTOR_TEST("en_.", "en_US"); + ADD_CTOR_TEST("en_.@", "en_US"); +#undef ADD_CTOR_TEST +#if QT_CONFIG(process) // for runSysApp // Get default locale. QString defaultLoc; QString errorMessage; - QVERIFY2(runSysApp(m_sysapp, env, &defaultLoc, &errorMessage), - qPrintable(errorMessage)); - - TEST_CTOR("C", "C") - TEST_CTOR("bla", "C") - TEST_CTOR("zz", "C") - TEST_CTOR("zz_zz", "C") - TEST_CTOR("zz...", "C") - TEST_CTOR("en", "en_US") - TEST_CTOR("en", "en_US") - TEST_CTOR("en.", "en_US") - TEST_CTOR("en@", "en_US") - TEST_CTOR("en.@", "en_US") - TEST_CTOR("en_", "en_US") - TEST_CTOR("en_.", "en_US") - TEST_CTOR("en_.@", "en_US") - TEST_CTOR("en.bla", "en_US") - TEST_CTOR("en@bla", "en_US") - TEST_CTOR("en_blaaa", "en_US") - TEST_CTOR("en_zz", "en_US") - TEST_CTOR("en_GB", "en_GB") - TEST_CTOR("en_GB.bla", "en_GB") - TEST_CTOR("en_GB@.bla", "en_GB") - TEST_CTOR("en_GB@bla", "en_GB") - TEST_CTOR("de", "de_DE") - - QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal); - TEST_CTOR("no", "nb_NO") - TEST_CTOR("nb", "nb_NO") - TEST_CTOR("nn", "nn_NO") - TEST_CTOR("no_NO", "nb_NO") - TEST_CTOR("nb_NO", "nb_NO") - TEST_CTOR("nn_NO", "nn_NO") + if (runSysApp(m_sysapp, cleanEnv, &defaultLoc, &errorMessage)) { +#define ADD_CTOR_TEST(give) QTest::newRow(give) << defaultLoc; + ADD_CTOR_TEST("en/"); + ADD_CTOR_TEST("asdfghj"); + ADD_CTOR_TEST("123456"); +#undef ADD_CTOR_TEST + } else { + qDebug() << "Skipping tests based on default locale" << qPrintable(errorMessage); + } +#endif // process +} - TEST_CTOR("DE", "de_DE"); - TEST_CTOR("EN", "en_US"); +void tst_QLocale::emptyCtor() +{ +#if QT_CONFIG(process) // for runSysAppTest + QLatin1String request(QTest::currentDataTag()); + QFETCH(QString, expected); - TEST_CTOR("en/", defaultLoc.toLatin1()) - TEST_CTOR("asdfghj", defaultLoc.toLatin1()); - TEST_CTOR("123456", defaultLoc.toLatin1()); + // Test constructor without arguments (see syslocaleapp/syslocaleapp.cpp) + // Needs separate process because of caching of the system locale. + QString errorMessage; + QVERIFY2(runSysAppTest(m_sysapp, cleanEnv, request, expected, &errorMessage), + qPrintable(errorMessage)); -#undef TEST_CTOR -#endif +#else + // This won't be called, as _data() skipped out early. +#endif // process } void tst_QLocale::legacyNames() { + QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal); QLocale::setDefault(QLocale(QLocale::C)); #define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \ diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp index 5130b7cfcd..f520e9742a 100644 --- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp @@ -2171,6 +2171,11 @@ void tst_QRegularExpression::wildcard_data() addRow(".???l", "test.html", 4); addRow("?", "test.html", 0); addRow("?m", "test.html", 6); + addRow("[*]", "test.html", -1); + addRow("[?]","test.html", -1); + addRow("[?]","test.h?ml", 6); + addRow("[[]","test.h[ml", 6); + addRow("[]]","test.h]ml", 6); addRow(".h[a-z]ml", "test.html", 4); addRow(".h[A-Z]ml", "test.html", -1); addRow(".h[A-Z]ml", "test.hTml", 4); @@ -2183,6 +2188,24 @@ void tst_QRegularExpression::wildcard_data() addRow(".h[][!]", "test.h]ml", 4); addRow(".h[][!]", "test.h[ml", 4); addRow(".h[][!]", "test.h!ml", 4); + + addRow("foo/*/bar", "Qt/foo/baz/bar", 3); + addRow("foo/(*)/bar", "Qt/foo/baz/bar", -1); + addRow("foo/(*)/bar", "Qt/foo/(baz)/bar", 3); + addRow("foo/?/bar", "Qt/foo/Q/bar", 3); + addRow("foo/?/bar", "Qt/foo/Qt/bar", -1); + addRow("foo/(?)/bar", "Qt/foo/Q/bar", -1); + addRow("foo/(?)/bar", "Qt/foo/(Q)/bar", 3); + +#ifdef Q_OS_WIN + addRow("foo\\*\\bar", "Qt\\foo\\baz\\bar", 3); + addRow("foo\\(*)\\bar", "Qt\\foo\\baz\\bar", -1); + addRow("foo\\(*)\\bar", "Qt\\foo\\(baz)\\bar", 3); + addRow("foo\\?\\bar", "Qt\\foo\\Q\\bar", 3); + addRow("foo\\?\\bar", "Qt\\foo\\Qt\\bar", -1); + addRow("foo\\(?)\\bar", "Qt\\foo\\Q\\bar", -1); + addRow("foo\\(?)\\bar", "Qt\\foo\\(Q)\\bar", 3); +#endif } void tst_QRegularExpression::wildcard() @@ -2191,9 +2214,7 @@ void tst_QRegularExpression::wildcard() QFETCH(QString, string); QFETCH(int, foundIndex); - QRegularExpression re; - re.setWildcardPattern(pattern); - + QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern)); QRegularExpressionMatch match = re.match(string); QCOMPARE(match.capturedStart(), foundIndex); @@ -2217,11 +2238,9 @@ void tst_QRegularExpression::testInvalidWildcard_data() void tst_QRegularExpression::testInvalidWildcard() { QFETCH(QString, pattern); - - QRegularExpression re; - re.setWildcardPattern(pattern); - QFETCH(bool, isValid); + + QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern)); QCOMPARE(re.isValid(), isValid); } diff --git a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp index a45539a041..d19aa9b54f 100644 --- a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp +++ b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp @@ -69,8 +69,20 @@ private slots: void sortChildren(); void subclassing(); void lessThan(); + void clearData(); }; +void tst_QStandardItem::clearData() +{ + QStandardItem item; + item.setData(QStringLiteral("Test"), Qt::EditRole); + item.setData(5, Qt::UserRole); + item.clearData(); + QCOMPARE(item.data(Qt::EditRole), QVariant()); + QCOMPARE(item.data(Qt::UserRole), QVariant()); + QCOMPARE(item.data(Qt::DisplayRole), QVariant()); +} + void tst_QStandardItem::ctor() { QStandardItem item; diff --git a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp index 9399ebce34..f6ed3e142d 100644 --- a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp +++ b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp @@ -98,6 +98,7 @@ private slots: void checkChildren(); void data(); void clear(); + void clearItemData(); void sort_data(); void sort(); void sortRole_data(); @@ -752,6 +753,27 @@ void tst_QStandardItemModel::data() } +void tst_QStandardItemModel::clearItemData() +{ + currentRoles.clear(); + QVERIFY(!m_model->clearItemData(QModelIndex())); + QCOMPARE(currentRoles, {}); + const QModelIndex idx = m_model->index(0, 0); + const QMap<int, QVariant> oldData = m_model->itemData(idx); + m_model->setData(idx, QLatin1String("initialitem"), Qt::DisplayRole); + m_model->setData(idx, QLatin1String("tooltip"), Qt::ToolTipRole); + m_model->setData(idx, 5, Qt::UserRole); + currentRoles.clear(); + QVERIFY(m_model->clearItemData(idx)); + QCOMPARE(idx.data(Qt::UserRole), QVariant()); + QCOMPARE(idx.data(Qt::ToolTipRole), QVariant()); + QCOMPARE(idx.data(Qt::DisplayRole), QVariant()); + QCOMPARE(idx.data(Qt::EditRole), QVariant()); + QCOMPARE(currentRoles, {}); + m_model->setItemData(idx, oldData); + currentRoles.clear(); +} + void tst_QStandardItemModel::clear() { QStandardItemModel model; diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index 4e3d1da8fe..9c477589f9 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -137,6 +137,7 @@ private slots: void nbspWithFormat(); void noModificationOfInputString(); void superscriptCrash_qtbug53911(); + void showLineAndParagraphSeparatorsCrash(); private: QFont testFont; @@ -2199,6 +2200,23 @@ void tst_QTextLayout::noModificationOfInputString() } } +void tst_QTextLayout::showLineAndParagraphSeparatorsCrash() +{ + QString s = QString(100000, QChar('a')) + QChar(QChar::LineSeparator); + { + QTextLayout layout; + layout.setText(s); + + QTextOption option; + option.setFlags(QTextOption::ShowLineAndParagraphSeparators); + layout.setTextOption(option); + + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + } +} + void tst_QTextLayout::superscriptCrash_qtbug53911() { static int fontSizes = 64; diff --git a/tests/auto/other/qfocusevent/qfocusevent.pro b/tests/auto/other/qfocusevent/qfocusevent.pro index 5f799291c6..95445f30fa 100644 --- a/tests/auto/other/qfocusevent/qfocusevent.pro +++ b/tests/auto/other/qfocusevent/qfocusevent.pro @@ -1,4 +1,4 @@ CONFIG += testcase TARGET = tst_qfocusevent -QT += widgets testlib +QT += widgets testlib gui-private SOURCES += tst_qfocusevent.cpp diff --git a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp index 1b02c9e8ab..260ba12a97 100644 --- a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp +++ b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp @@ -38,6 +38,9 @@ #include <QBoxLayout> #include <QSysInfo> +#include <qpa/qplatformintegration.h> +#include <private/qguiapplication_p.h> + QT_FORWARD_DECLARE_CLASS(QWidget) class FocusLineEdit : public QLineEdit @@ -92,13 +95,16 @@ private slots: void checkReason_ActiveWindow(); private: - QWidget* testFocusWidget; + QWidget* testFocusWidget = nullptr; FocusLineEdit* childFocusWidgetOne; FocusLineEdit* childFocusWidgetTwo; }; void tst_QFocusEvent::initTestCase() { + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) + QSKIP("QWindow::requestActivate() is not supported on this platform."); + testFocusWidget = new QWidget( 0 ); childFocusWidgetOne = new FocusLineEdit( testFocusWidget ); childFocusWidgetOne->setGeometry( 10, 10, 180, 20 ); diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index 125d7f0bc6..2adf85a044 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -55,7 +55,7 @@ TESTSERVER_COMPOSE_FILE = $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compos TESTSERVER_VERSION = $$system(docker-compose --version) TESTSERVER_IMAGES = $$system(docker images -aq "qt-test-server-*") -equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION)|!linux-g++ { +equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { # Make check with server "qt-test-server.qt-test-net" as a fallback message("testserver: qt-test-server.qt-test-net") } else { diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 5c9e0a46cf..049468fd7c 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -331,6 +331,12 @@ void tst_QMessageBox::escapeButton() closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox2); msgBox2.exec(); QVERIFY(msgBox2.clickedButton() == msgBox2.button(QMessageBox::No)); // auto detected (one No button only) + + QMessageBox msgBox3; + msgBox3.setDetailedText("Details"); + closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox3); + msgBox3.exec(); + QVERIFY(msgBox3.clickedButton() == msgBox3.button(QMessageBox::Ok)); // auto detected } void tst_QMessageBox::statics() diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index e30429b7e7..ae50b32164 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -2321,6 +2321,12 @@ void tst_QWidget::resizeEvent() void tst_QWidget::showMinimized() { + if (m_platform == QStringLiteral("wayland")) { + QSKIP("Wayland: Neither xdg_shell, wl_shell or ivi_application support " + "letting a client know whether it's minimized. So on these shells " + "Qt Wayland will always report that it's unmimized."); + } + QWidget plain; plain.move(100, 100); plain.resize(200, 200); @@ -9165,7 +9171,7 @@ void tst_QWidget::syntheticEnterLeave() void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave() { if (m_platform == QStringLiteral("wayland")) - QSKIP("Wayland: This fails. Figure out why."); + QSKIP("Wayland: Clients can't set cursor position on wayland."); class SELParent : public QWidget { public: diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index 5a51bab51f..37bb28dec9 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -1775,6 +1775,10 @@ void tst_QSpinBox::stepModifierPressAndHold() spin.setStyle(stepModifierStyle.data()); QSignalSpy spy(&spin, QOverload<int>::of(&SpinBox::valueChanged)); + // TODO: remove debug output when QTBUG-69492 is fixed + connect(&spin, QOverload<int>::of(&SpinBox::valueChanged), [=]() { + qDebug() << QTime::currentTime() << "valueChanged emitted"; + }); spin.show(); QVERIFY(QTest::qWaitForWindowActive(&spin)); @@ -1785,6 +1789,9 @@ void tst_QSpinBox::stepModifierPressAndHold() const QRect buttonRect = spin.style()->subControlRect( QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &spin); + // TODO: remove debug output when QTBUG-69492 is fixed + qDebug() << "QGuiApplication::focusWindow():" << QGuiApplication::focusWindow(); + qDebug() << "QGuiApplication::topLevelWindows():" << QGuiApplication::topLevelWindows(); QTest::mousePress(&spin, Qt::LeftButton, modifiers, buttonRect.center()); QTRY_VERIFY2(spy.length() >= 3, qPrintable(QString::fromLatin1( "Expected valueChanged() to be emitted 3 or more times, but it was only emitted %1 times").arg(spy.length()))); |