summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/global/qglobal/qglobal.pro1
-rw-r--r--tests/auto/corelib/global/qglobal/tst_qglobal.cpp40
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp154
-rw-r--r--tests/auto/corelib/itemmodels/itemmodels.pro2
-rw-r--r--tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro5
-rw-r--r--tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp823
-rw-r--r--tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp4
-rw-r--r--tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp4
-rw-r--r--tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp176
-rw-r--r--tests/auto/corelib/itemmodels/qtransposeproxymodel/qtransposeproxymodel.pro6
-rw-r--r--tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp915
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp14
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp1315
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp12
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro1
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp39
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/staticplugin.pro7
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst/tst.pro5
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp37
-rw-r--r--tests/auto/corelib/serialization/json/tst_qtjson.cpp170
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp140
-rw-r--r--tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp141
-rw-r--r--tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp30
-rw-r--r--tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp26
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp40
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp18
-rw-r--r--tests/auto/corelib/tools/qoffsetstringarray/qoffsetstringarray.pro6
-rw-r--r--tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp121
-rw-r--r--tests/auto/corelib/tools/tools.pro1
30 files changed, 3466 insertions, 790 deletions
diff --git a/tests/auto/corelib/global/qglobal/qglobal.pro b/tests/auto/corelib/global/qglobal/qglobal.pro
index a40cb9a288..b105769430 100644
--- a/tests/auto/corelib/global/qglobal/qglobal.pro
+++ b/tests/auto/corelib/global/qglobal/qglobal.pro
@@ -2,3 +2,4 @@ CONFIG += testcase
TARGET = tst_qglobal
QT = core testlib
SOURCES = tst_qglobal.cpp qglobal.c
+contains(QT_CONFIG, c++1z): CONFIG += c++1z
diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
index 78b954f373..56da047147 100644
--- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
+++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
@@ -126,6 +126,46 @@ void tst_QGlobal::for_each()
QCOMPARE(i, counter++);
}
QCOMPARE(counter, list.count());
+
+ // Should also work with an existing variable
+ int local;
+ counter = 0;
+ foreach (local, list) {
+ QCOMPARE(local, counter++);
+ }
+ QCOMPARE(counter, list.count());
+ QCOMPARE(local, counter - 1);
+
+ // Test the macro does not mess if/else conditions
+ counter = 0;
+ if (true)
+ foreach (int i, list)
+ QCOMPARE(i, counter++);
+ else
+ QFAIL("If/Else mismatch");
+ QCOMPARE(counter, list.count());
+
+ counter = 0;
+ if (false)
+ foreach (int i, list)
+ if (i) QFAIL("If/Else mismatch");
+ else QFAIL("If/Else mismatch");
+ else
+ foreach (int i, list)
+ if (false) { }
+ else QCOMPARE(i, counter++);
+ QCOMPARE(counter, list.count());
+
+ // break and continue
+ counter = 0;
+ foreach (int i, list) {
+ if (i == 0)
+ continue;
+ QCOMPARE(i, (counter++) + 1);
+ if (i == 3)
+ break;
+ }
+ QCOMPARE(counter, 3);
}
void tst_QGlobal::qassert()
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index 017eebe153..3e29475636 100644
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -95,6 +95,38 @@ inline bool qIsLikelyToBeNfs(const QString &path)
#endif
}
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+# ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE // MinGW
+# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x2)
+# endif
+
+static DWORD createSymbolicLink(const QString &symLinkName, const QString &target,
+ QString *errorMessage)
+{
+ DWORD result = ERROR_SUCCESS;
+ const QString nativeSymLinkName = QDir::toNativeSeparators(symLinkName);
+ const QString nativeTarget = QDir::toNativeSeparators(target);
+ DWORD flags = 0;
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 14972))
+ flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
+ if (QFileInfo(target).isDir())
+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+ if (CreateSymbolicLink(reinterpret_cast<const wchar_t*>(nativeSymLinkName.utf16()),
+ reinterpret_cast<const wchar_t*>(nativeTarget.utf16()), flags) == FALSE) {
+ result = GetLastError();
+ QTextStream(errorMessage) << "CreateSymbolicLink(" << nativeSymLinkName << ", "
+ << nativeTarget << ", 0x" << hex << flags << dec << ") failed with error " << result
+ << ": " << qt_error_string(int(result));
+ }
+ return result;
+}
+
+static QByteArray msgInsufficientPrivileges(const QString &errorMessage)
+{
+ return "Insufficient privileges (" + errorMessage.toLocal8Bit() + ')';
+}
+#endif // Q_OS_WIN && !Q_OS_WINRT
+
static QString seedAndTemplate()
{
QString base;
@@ -704,19 +736,14 @@ void tst_QFileInfo::canonicalFilePath()
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
{
- // CreateSymbolicLink can return TRUE & still fail to create the link,
- // the error code in that case is ERROR_PRIVILEGE_NOT_HELD (1314)
- SetLastError(0);
+ QString errorMessage;
const QString linkTarget = QStringLiteral("res");
- BOOL ret = CreateSymbolicLink((wchar_t*)linkTarget.utf16(), (wchar_t*)m_resourcesDir.utf16(), 1);
- DWORD dwErr = GetLastError();
- if (!ret)
- QSKIP("Symbolic links aren't supported by FS");
+ const DWORD dwErr = createSymbolicLink(linkTarget, m_resourcesDir, &errorMessage);
+ if (dwErr == ERROR_PRIVILEGE_NOT_HELD)
+ QSKIP(msgInsufficientPrivileges(errorMessage));
+ QVERIFY2(dwErr == ERROR_SUCCESS, qPrintable(errorMessage));
QString currentPath = QDir::currentPath();
- bool is_res_Current = QDir::setCurrent(linkTarget);
- if (!is_res_Current && dwErr == 1314)
- QSKIP("Not enough privilages to create Symbolic links");
- QCOMPARE(is_res_Current, true);
+ QVERIFY(QDir::setCurrent(linkTarget));
const QString actualCanonicalPath = QFileInfo("file1").canonicalFilePath();
QVERIFY(QDir::setCurrent(currentPath));
QCOMPARE(actualCanonicalPath, m_resourcesDir + QStringLiteral("/file1"));
@@ -1455,8 +1482,24 @@ void tst_QFileInfo::refresh()
}
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+
+struct NtfsTestResource {
+
+ enum Type { None, SymLink, Junction };
+
+ explicit NtfsTestResource(Type tp = None, const QString &s = QString(), const QString &t = QString())
+ : source(s), target(t), type(tp) {}
+
+ QString source;
+ QString target;
+ Type type;
+};
+
+Q_DECLARE_METATYPE(NtfsTestResource)
+
void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
{
+ QTest::addColumn<NtfsTestResource>("resource");
QTest::addColumn<QString>("path");
QTest::addColumn<bool>("isSymLink");
QTest::addColumn<QString>("linkTarget");
@@ -1479,32 +1522,20 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QString fileInSymlink(absSymlink);
fileInSymlink.append("\\file");
QFile file(fileInTarget);
- file.open(QIODevice::ReadWrite);
+ QVERIFY2(file.open(QIODevice::ReadWrite), qPrintable(file.errorString()));
file.close();
- DWORD err = ERROR_SUCCESS ;
- if (!pwd.exists("abs_symlink"))
- if (!CreateSymbolicLink((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1))
- err = GetLastError();
- if (err == ERROR_SUCCESS && !pwd.exists(relSymlink))
- if (!CreateSymbolicLink((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1))
- err = GetLastError();
- if (err != ERROR_SUCCESS) {
- wchar_t errstr[0x100];
- DWORD count = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
- 0, err, 0, errstr, 0x100, 0);
- QString error(QString::fromWCharArray(errstr, count));
- qWarning() << error;
- //we need at least one data set for the test not to assert fail when skipping _data function
- QDir target("target");
- QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath();
- QSKIP("link not supported by FS or insufficient privilege");
- }
QVERIFY2(file.exists(), msgDoesNotExist(file.fileName()).constData());
- QTest::newRow("absolute dir symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
- QTest::newRow("relative dir symlink") << relSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
- QTest::newRow("file in symlink dir") << fileInSymlink << false << "" << target.canonicalPath().append("/file");
+ QTest::newRow("absolute dir symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, absSymlink, absTarget)
+ << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
+ QTest::newRow("relative dir symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, relSymlink, relTarget)
+ << relSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
+ QTest::newRow("file in symlink dir")
+ << NtfsTestResource()
+ << fileInSymlink << false << "" << target.canonicalPath().append("/file");
}
{
//File symlinks
@@ -1517,33 +1548,41 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QString relSymlink = "rel_symlink.cpp";
QString relToRelTarget = QDir::toNativeSeparators(relativeDir.relativeFilePath(target.absoluteFilePath()));
QString relToRelSymlink = "relative/rel_symlink";
- QVERIFY(pwd.exists("abs_symlink.cpp") || CreateSymbolicLink((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x0));
- QVERIFY(pwd.exists(relSymlink) || CreateSymbolicLink((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x0));
- QVERIFY(pwd.exists(relToRelSymlink) || CreateSymbolicLink((wchar_t*)relToRelSymlink.utf16(), (wchar_t*)relToRelTarget.utf16(),0x0));
- QTest::newRow("absolute file symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
- QTest::newRow("relative file symlink") << relSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
- QTest::newRow("relative to relative file symlink") << relToRelSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
+
+ QTest::newRow("absolute file symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, absSymlink, absTarget)
+ << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
+ QTest::newRow("relative file symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, relSymlink, relTarget)
+ << relSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
+ QTest::newRow("relative to relative file symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, relToRelSymlink, relToRelTarget)
+ << relToRelSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
}
//Junctions
QString target = "target";
QString junction = "junction_pwd";
- FileSystem::createNtfsJunction(target, junction);
QFileInfo targetInfo(target);
- QTest::newRow("junction_pwd") << junction << false << QString() << QString();
+ QTest::newRow("junction_pwd")
+ << NtfsTestResource(NtfsTestResource::Junction, junction, target)
+ << junction << false << QString() << QString();
QFileInfo fileInJunction(targetInfo.absoluteFilePath().append("/file"));
QFile file(fileInJunction.absoluteFilePath());
- file.open(QIODevice::ReadWrite);
+ QVERIFY2(file.open(QIODevice::ReadWrite), qPrintable(file.errorString()));
file.close();
QVERIFY2(file.exists(), msgDoesNotExist(file.fileName()).constData());
- QTest::newRow("file in junction") << fileInJunction.absoluteFilePath() << false << "" << fileInJunction.canonicalFilePath();
+ QTest::newRow("file in junction")
+ << NtfsTestResource()
+ << fileInJunction.absoluteFilePath() << false << QString() << fileInJunction.canonicalFilePath();
target = QDir::rootPath();
junction = "junction_root";
- FileSystem::createNtfsJunction(target, junction);
targetInfo.setFile(target);
- QTest::newRow("junction_root") << junction << false << QString() << QString();
+ QTest::newRow("junction_root")
+ << NtfsTestResource(NtfsTestResource::Junction, junction, target)
+ << junction << false << QString() << QString();
//Mountpoint
wchar_t buffer[MAX_PATH];
@@ -1552,17 +1591,38 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QString rootVolume = QString::fromWCharArray(buffer);
junction = "mountpoint";
rootVolume.replace("\\\\?\\","\\??\\");
- FileSystem::createNtfsJunction(rootVolume, junction);
- QTest::newRow("mountpoint") << junction << false << QString() << QString();
+ QTest::newRow("mountpoint")
+ << NtfsTestResource(NtfsTestResource::Junction, junction, rootVolume)
+ << junction << false << QString() << QString();
}
void tst_QFileInfo::ntfsJunctionPointsAndSymlinks()
{
+ QFETCH(NtfsTestResource, resource);
QFETCH(QString, path);
QFETCH(bool, isSymLink);
QFETCH(QString, linkTarget);
QFETCH(QString, canonicalFilePath);
+ QString errorMessage;
+ DWORD creationResult = ERROR_SUCCESS;
+ switch (resource.type) {
+ case NtfsTestResource::None:
+ break;
+ case NtfsTestResource::SymLink:
+ creationResult = createSymbolicLink(resource.source, resource.target, &errorMessage);
+ break;
+ case NtfsTestResource::Junction:
+ creationResult = FileSystem::createNtfsJunction(resource.target, resource.source, &errorMessage);
+ if (creationResult == ERROR_NOT_SUPPORTED) // Special value indicating non-NTFS drive
+ QSKIP(qPrintable(errorMessage));
+ break;
+ }
+
+ if (creationResult == ERROR_PRIVILEGE_NOT_HELD)
+ QSKIP(msgInsufficientPrivileges(errorMessage));
+ QVERIFY2(creationResult == ERROR_SUCCESS, qPrintable(errorMessage));
+
QFileInfo fi(path);
const bool actualIsSymLink = fi.isSymLink();
const QString actualSymLinkTarget = isSymLink ? fi.symLinkTarget() : QString();
diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro
index cca350ad43..ffbda6ec40 100644
--- a/tests/auto/corelib/itemmodels/itemmodels.pro
+++ b/tests/auto/corelib/itemmodels/itemmodels.pro
@@ -5,9 +5,11 @@ SUBDIRS = qstringlistmodel
qtHaveModule(gui): SUBDIRS += \
qabstractitemmodel \
qabstractproxymodel \
+ qconcatenatetablesproxymodel \
qidentityproxymodel \
qitemselectionmodel \
qsortfilterproxymodel_recursive \
+ qtransposeproxymodel \
qtHaveModule(widgets) {
SUBDIRS += \
diff --git a/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro
new file mode 100644
index 0000000000..ee4ea28b5b
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+TARGET = tst_qconcatenatetablesproxymodel
+QT = core gui testlib
+
+SOURCES = tst_qconcatenatetablesproxymodel.cpp
diff --git a/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
new file mode 100644
index 0000000000..40617c1f7d
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
@@ -0,0 +1,823 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QSignalSpy>
+#include <QSortFilterProxyModel>
+#include <QTest>
+#include <QStandardItemModel>
+#include <QIdentityProxyModel>
+#include <QItemSelectionModel>
+#include <QMimeData>
+#include <QStringListModel>
+#include <QAbstractItemModelTester>
+
+#include <qconcatenatetablesproxymodel.h>
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+// Extracts a full row from a model as a string
+// Works best if every cell contains only one character
+static QString extractRowTexts(QAbstractItemModel *model, int row, const QModelIndex &parent = QModelIndex())
+{
+ QString result;
+ const int colCount = model->columnCount();
+ for (int col = 0; col < colCount; ++col) {
+ const QString txt = model->index(row, col, parent).data().toString();
+ result += txt.isEmpty() ? QStringLiteral(" ") : txt;
+ }
+ return result;
+}
+
+// Extracts a full column from a model as a string
+// Works best if every cell contains only one character
+static QString extractColumnTexts(QAbstractItemModel *model, int column, const QModelIndex &parent = QModelIndex())
+{
+ QString result;
+ const int rowCount = model->rowCount();
+ for (int row = 0; row < rowCount; ++row) {
+ const QString txt = model->index(row, column, parent).data().toString();
+ result += txt.isEmpty() ? QStringLiteral(" ") : txt;
+ }
+ return result;
+}
+
+static QString rowSpyToText(const QSignalSpy &spy)
+{
+ if (!spy.isValid())
+ return QStringLiteral("THE SIGNALSPY IS INVALID!");
+ QString str;
+ for (int i = 0; i < spy.count(); ++i) {
+ str += spy.at(i).at(1).toString() + QLatin1Char(',') + spy.at(i).at(2).toString();
+ if (i + 1 < spy.count())
+ str += QLatin1Char(';');
+ }
+ return str;
+}
+
+class tst_QConcatenateTablesProxyModel : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void init();
+ void shouldAggregateTwoModelsCorrectly();
+ void shouldAggregateThenRemoveTwoEmptyModelsCorrectly();
+ void shouldAggregateTwoEmptyModelsWhichThenGetFilled();
+ void shouldHandleDataChanged();
+ void shouldHandleSetData();
+ void shouldHandleSetItemData();
+ void shouldHandleRowInsertionAndRemoval();
+ void shouldAggregateAnotherModelThenRemoveModels();
+ void shouldUseSmallestColumnCount();
+ void shouldIncreaseColumnCountWhenRemovingFirstModel();
+ void shouldHandleColumnInsertionAndRemoval();
+ void shouldPropagateLayoutChanged();
+ void shouldReactToModelReset();
+ void shouldUpdateColumnsOnModelReset();
+ void shouldPropagateDropOnItem_data();
+ void shouldPropagateDropOnItem();
+ void shouldPropagateDropBetweenItems();
+ void shouldPropagateDropBetweenItemsAtModelBoundary();
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+
+private:
+ QStandardItemModel mod;
+ QStandardItemModel mod2;
+ QStandardItemModel mod3;
+};
+
+void tst_QConcatenateTablesProxyModel::init()
+{
+ // Prepare some source models to use later on
+ mod.clear();
+ mod.appendRow({ new QStandardItem(QStringLiteral("A")), new QStandardItem(QStringLiteral("B")), new QStandardItem(QStringLiteral("C")) });
+ mod.setHorizontalHeaderLabels(QStringList() << QStringLiteral("H1") << QStringLiteral("H2") << QStringLiteral("H3"));
+ mod.setVerticalHeaderLabels(QStringList() << QStringLiteral("One"));
+
+ mod2.clear();
+ mod2.appendRow({ new QStandardItem(QStringLiteral("D")), new QStandardItem(QStringLiteral("E")), new QStandardItem(QStringLiteral("F")) });
+ mod2.setHorizontalHeaderLabels(QStringList() << QStringLiteral("H1") << QStringLiteral("H2") << QStringLiteral("H3"));
+ mod2.setVerticalHeaderLabels(QStringList() << QStringLiteral("Two"));
+
+ mod3.clear();
+ mod3.appendRow({ new QStandardItem(QStringLiteral("1")), new QStandardItem(QStringLiteral("2")), new QStandardItem(QStringLiteral("3")) });
+ mod3.appendRow({ new QStandardItem(QStringLiteral("4")), new QStandardItem(QStringLiteral("5")), new QStandardItem(QStringLiteral("6")) });
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateTwoModelsCorrectly()
+{
+ // Given a combining proxy
+ QConcatenateTablesProxyModel pm;
+
+ // When adding two source models
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ // Then the proxy should show 2 rows
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // ... and correct headers
+ QCOMPARE(pm.headerData(0, Qt::Horizontal).toString(), QStringLiteral("H1"));
+ QCOMPARE(pm.headerData(1, Qt::Horizontal).toString(), QStringLiteral("H2"));
+ QCOMPARE(pm.headerData(2, Qt::Horizontal).toString(), QStringLiteral("H3"));
+ QCOMPARE(pm.headerData(0, Qt::Vertical).toString(), QStringLiteral("One"));
+ QCOMPARE(pm.headerData(1, Qt::Vertical).toString(), QStringLiteral("Two"));
+
+ QVERIFY(!pm.canFetchMore(QModelIndex()));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateThenRemoveTwoEmptyModelsCorrectly()
+{
+ // Given a combining proxy
+ QConcatenateTablesProxyModel pm;
+
+ // When adding two empty models
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QIdentityProxyModel i1, i2;
+ pm.addSourceModel(&i1);
+ pm.addSourceModel(&i2);
+
+ // Then the proxy should still be empty (and no signals emitted)
+ QCOMPARE(pm.rowCount(), 0);
+ QCOMPARE(pm.columnCount(), 0);
+ QCOMPARE(rowATBISpy.count(), 0);
+ QCOMPARE(rowInsertedSpy.count(), 0);
+
+ // When removing the empty models
+ pm.removeSourceModel(&i1);
+ pm.removeSourceModel(&i2);
+
+ // Then the proxy should still be empty (and no signals emitted)
+ QCOMPARE(pm.rowCount(), 0);
+ QCOMPARE(pm.columnCount(), 0);
+ QCOMPARE(rowATBRSpy.count(), 0);
+ QCOMPARE(rowRemovedSpy.count(), 0);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateTwoEmptyModelsWhichThenGetFilled()
+{
+ // Given a combining proxy with two empty models
+ QConcatenateTablesProxyModel pm;
+ QIdentityProxyModel i1, i2;
+ pm.addSourceModel(&i1);
+ pm.addSourceModel(&i2);
+
+ // When filling them afterwards
+ i1.setSourceModel(&mod);
+ i2.setSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ // Then the proxy should show 2 rows
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // ... and correct headers
+ QCOMPARE(pm.headerData(0, Qt::Horizontal).toString(), QStringLiteral("H1"));
+ QCOMPARE(pm.headerData(1, Qt::Horizontal).toString(), QStringLiteral("H2"));
+ QCOMPARE(pm.headerData(2, Qt::Horizontal).toString(), QStringLiteral("H3"));
+ QCOMPARE(pm.headerData(0, Qt::Vertical).toString(), QStringLiteral("One"));
+ QCOMPARE(pm.headerData(1, Qt::Vertical).toString(), QStringLiteral("Two"));
+
+ QVERIFY(!pm.canFetchMore(QModelIndex()));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleDataChanged()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When a cell in a source model changes
+ mod.item(0, 0)->setData("a", Qt::EditRole);
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("aBC"));
+
+ // Same test with the other model
+ mod2.item(0, 2)->setData("f", Qt::EditRole);
+
+ QCOMPARE(dataChangedSpy.count(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEf"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleSetData()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When changing a cell using setData
+ pm.setData(pm.index(0, 0), "a");
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("aBC"));
+
+ // Same test with the other model
+ pm.setData(pm.index(1, 2), "f");
+
+ QCOMPARE(dataChangedSpy.count(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEf"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleSetItemData()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When changing a cell using setData
+ pm.setItemData(pm.index(0, 0), QMap<int, QVariant>{ std::make_pair<int, QVariant>(Qt::DisplayRole, QStringLiteral("X")),
+ std::make_pair<int, QVariant>(Qt::UserRole, 88) });
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("XBC"));
+ QCOMPARE(pm.index(0, 0).data(Qt::UserRole).toInt(), 88);
+
+ // Same test with the other model
+ pm.setItemData(pm.index(1, 2), QMap<int, QVariant>{ std::make_pair<int, QVariant>(Qt::DisplayRole, QStringLiteral("Y")),
+ std::make_pair<int, QVariant>(Qt::UserRole, 89) });
+
+ QCOMPARE(dataChangedSpy.count(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEY"));
+ QCOMPARE(pm.index(1, 2).data(Qt::UserRole).toInt(), 89);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleRowInsertionAndRemoval()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+
+ // When a source model inserts a new row
+ QList<QStandardItem *> row;
+ row.append(new QStandardItem(QStringLiteral("1")));
+ row.append(new QStandardItem(QStringLiteral("2")));
+ row.append(new QStandardItem(QStringLiteral("3")));
+ mod2.insertRow(0, row);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(rowATBISpy), QStringLiteral("1,1"));
+ QCOMPARE(rowSpyToText(rowInsertedSpy), QStringLiteral("1,1"));
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When removing that row
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ mod2.removeRow(0);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // When removing the last row from mod2
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ mod2.removeRow(0);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateAnotherModelThenRemoveModels()
+{
+ // Given two models combined, and a third model
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+
+ // When adding the new source model
+ pm.addSourceModel(&mod3);
+
+ // Then the proxy should notify its users about the two rows inserted
+ QCOMPARE(rowSpyToText(rowATBISpy), QStringLiteral("2,3"));
+ QCOMPARE(rowSpyToText(rowInsertedSpy), QStringLiteral("2,3"));
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("456"));
+
+ // When removing that source model again
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ pm.removeSourceModel(&mod3);
+
+ // Then the proxy should notify its users about the row removed
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 2);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 3);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 2);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 3);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // When removing model 2
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ pm.removeSourceModel(&mod2);
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+
+ // When removing model 1
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ pm.removeSourceModel(&mod);
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 0);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 0);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 0);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 0);
+ QCOMPARE(pm.rowCount(), 0);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldUseSmallestColumnCount()
+{
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ mod2.setColumnCount(1);
+ pm.addSourceModel(&mod3);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(pm.columnCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("A"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("D"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("1"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("4"));
+
+ const QModelIndex indexA = pm.mapFromSource(mod.index(0, 0));
+ QVERIFY(indexA.isValid());
+ QCOMPARE(indexA, pm.index(0, 0));
+
+ const QModelIndex indexB = pm.mapFromSource(mod.index(0, 1));
+ QVERIFY(!indexB.isValid());
+
+ const QModelIndex indexD = pm.mapFromSource(mod2.index(0, 0));
+ QVERIFY(indexD.isValid());
+ QCOMPARE(indexD, pm.index(1, 0));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldIncreaseColumnCountWhenRemovingFirstModel()
+{
+ // Given a model with 2 columns and one with 3 columns
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+ mod.setColumnCount(2);
+ pm.addSourceModel(&mod2);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 2);
+
+ QSignalSpy colATBISpy(&pm, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy colInsertedSpy(&pm, SIGNAL(columnsInserted(QModelIndex,int,int)));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+
+ // When removing the first source model
+ pm.removeSourceModel(&mod);
+
+ // Then the proxy should notify its users about the row removed, and the column added
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(rowSpyToText(rowATBRSpy), QStringLiteral("0,0"));
+ QCOMPARE(rowSpyToText(rowRemovedSpy), QStringLiteral("0,0"));
+ QCOMPARE(rowSpyToText(colATBISpy), QStringLiteral("2,2"));
+ QCOMPARE(rowSpyToText(colInsertedSpy), QStringLiteral("2,2"));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("DEF"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleColumnInsertionAndRemoval()
+{
+ // Given two models combined, one with 2 columns and one with 3
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+ mod.setColumnCount(2);
+ pm.addSourceModel(&mod2);
+ QSignalSpy colATBISpy(&pm, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy colInsertedSpy(&pm, SIGNAL(columnsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+
+ // When the first source model inserts a new column
+ QCOMPARE(mod.columnCount(), 2);
+ mod.setColumnCount(3);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(colATBISpy), QStringLiteral("2,2"));
+ QCOMPARE(rowSpyToText(colInsertedSpy), QStringLiteral("2,2"));
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("AB "));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // And when removing two columns
+ mod.setColumnCount(1);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(colATBRSpy), QStringLiteral("1,2"));
+ QCOMPARE(rowSpyToText(colRemovedSpy), QStringLiteral("1,2"));
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("A"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("D"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateLayoutChanged()
+{
+ // Given two source models, the second one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+
+ // And a selection (row 1)
+ QItemSelectionModel selection(&pm);
+ selection.select(pm.index(1, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ const QModelIndexList lst = selection.selectedIndexes();
+ QCOMPARE(lst.count(), 3);
+ for (int col = 0; col < lst.count(); ++col) {
+ QCOMPARE(lst.at(col).row(), 1);
+ QCOMPARE(lst.at(col).column(), col);
+ }
+
+ QSignalSpy layoutATBCSpy(&pm, SIGNAL(layoutAboutToBeChanged()));
+ QSignalSpy layoutChangedSpy(&pm, SIGNAL(layoutChanged()));
+
+ // When changing the sorting in the QSFPM
+ qsfpm.sort(0, Qt::DescendingOrder);
+
+ // Then the proxy should emit the layoutChanged signals, and show re-sorted data
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(layoutATBCSpy.count(), 1);
+ QCOMPARE(layoutChangedSpy.count(), 1);
+
+ // And the selection should be updated accordingly (it became row 2)
+ const QModelIndexList lstAfter = selection.selectedIndexes();
+ QCOMPARE(lstAfter.count(), 3);
+ for (int col = 0; col < lstAfter.count(); ++col) {
+ QCOMPARE(lstAfter.at(col).row(), 2);
+ QCOMPARE(lstAfter.at(col).column(), col);
+ }
+}
+
+void tst_QConcatenateTablesProxyModel::shouldReactToModelReset()
+{
+ // Given two source models, the second one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+ QSignalSpy modelATBResetSpy(&pm, SIGNAL(modelAboutToBeReset()));
+ QSignalSpy modelResetSpy(&pm, SIGNAL(modelReset()));
+
+ // When changing the source model of the QSFPM
+ qsfpm.setSourceModel(&mod2);
+
+ // Then the proxy should emit the reset signals, and show the new data
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(rowATBRSpy.count(), 0);
+ QCOMPARE(rowRemovedSpy.count(), 0);
+ QCOMPARE(rowATBISpy.count(), 0);
+ QCOMPARE(rowInsertedSpy.count(), 0);
+ QCOMPARE(colATBRSpy.count(), 0);
+ QCOMPARE(colRemovedSpy.count(), 0);
+ QCOMPARE(modelATBResetSpy.count(), 1);
+ QCOMPARE(modelResetSpy.count(), 1);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldUpdateColumnsOnModelReset()
+{
+ // Given two source models, the first one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("ABC"));
+
+ // ... and a model with only 2 columns
+ QStandardItemModel mod2Columns;
+ mod2Columns.appendRow({ new QStandardItem(QStringLiteral("W")), new QStandardItem(QStringLiteral("X")) });
+
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+ QSignalSpy modelATBResetSpy(&pm, SIGNAL(modelAboutToBeReset()));
+ QSignalSpy modelResetSpy(&pm, SIGNAL(modelReset()));
+
+ // When changing the source model of the QSFPM
+ qsfpm.setSourceModel(&mod2Columns);
+
+ // Then the proxy should reset, and show the new data
+ QCOMPARE(modelATBResetSpy.count(), 1);
+ QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.count(), 0);
+ QCOMPARE(rowRemovedSpy.count(), 0);
+ QCOMPARE(rowATBISpy.count(), 0);
+ QCOMPARE(rowInsertedSpy.count(), 0);
+ QCOMPARE(colATBRSpy.count(), 0);
+ QCOMPARE(colRemovedSpy.count(), 0);
+
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("WX"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("AB"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropOnItem_data()
+{
+ QTest::addColumn<int>("sourceRow");
+ QTest::addColumn<int>("destRow");
+ QTest::addColumn<QString>("expectedResult");
+
+ QTest::newRow("0-3") << 0 << 3 << QStringLiteral("ABCA");
+ QTest::newRow("1-2") << 1 << 2 << QStringLiteral("ABBD");
+ QTest::newRow("2-1") << 2 << 1 << QStringLiteral("ACCD");
+ QTest::newRow("3-0") << 3 << 0 << QStringLiteral("DBCD");
+
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropOnItem()
+{
+ // Given two source models who handle drops
+
+ // Note: QStandardItemModel handles drop onto items by inserting child rows,
+ // which is good for QTreeView but not for QTableView or QConcatenateTablesProxyModel.
+ // So we use QStringListModel here instead.
+ QConcatenateTablesProxyModel pm;
+ QStringListModel model1({QStringLiteral("A"), QStringLiteral("B")});
+ QStringListModel model2({QStringLiteral("C"), QStringLiteral("D")});
+ pm.addSourceModel(&model1);
+ pm.addSourceModel(&model2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(extractColumnTexts(&pm, 0), QStringLiteral("ABCD"));
+
+ // When dragging one item
+ QFETCH(int, sourceRow);
+ QMimeData* mimeData = pm.mimeData({pm.index(sourceRow, 0)});
+ QVERIFY(mimeData);
+
+ // and dropping onto another item
+ QFETCH(int, destRow);
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, -1, -1, pm.index(destRow, 0)));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, -1, -1, pm.index(destRow, 0)));
+ delete mimeData;
+
+ // Then the result should be as expected
+ QFETCH(QString, expectedResult);
+ QCOMPARE(extractColumnTexts(&pm, 0), expectedResult);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropBetweenItems()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the last row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(2, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it before row 1
+ const int destRow = 1;
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("DEF"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropBetweenItemsAtModelBoundary()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the first row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(0, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it before row 2
+ const int destRow = 2;
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("DEF"));
+
+ // and it should be part of the second model
+ QCOMPARE(mod2.rowCount(), 2);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropAfterLastRow_data()
+{
+ QTest::addColumn<int>("destRow");
+
+ // Dropping after the last row is documented to be done with destRow == -1.
+ QTest::newRow("-1") << -1;
+ // However, sometimes QTreeView calls dropMimeData with destRow == rowCount...
+ // Not sure if that's a bug or not, but let's support it in the model, just in case.
+ QTest::newRow("3") << 3;
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropAfterLastRow()
+{
+ QFETCH(int, destRow);
+
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the second row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(1, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it after the last row
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted at the end
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("456"));
+
+}
+
+QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+#include "tst_qconcatenatetablesproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp b/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp
index 6ea7a38137..dbc7173028 100644
--- a/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp
+++ b/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp
@@ -251,7 +251,7 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model)
QString val = xval + QString::number(y) + QString::number(i);
QModelIndex index = model->index(x, y, parent);
model->setData(index, val);
- model->setData(index, blue, Qt::TextColorRole);
+ model->setData(index, blue, Qt::ForegroundRole);
}
}
*/
@@ -276,7 +276,7 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model)
QString val = xval + QString::number(y) + QString::number(i);
QModelIndex index = realModel->index(x, y, parent);
realModel->setData(index, val);
- realModel->setData(index, blue, Qt::TextColorRole);
+ realModel->setData(index, blue, Qt::ForegroundRole);
}
}
*/
diff --git a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
index 7cd220e684..da13b9f33f 100644
--- a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
@@ -576,12 +576,12 @@ void tst_QItemModel::data()
alignment == Qt::AlignJustify);
}
- QVariant colorVariant = currentModel->data(currentModel->index(0,0), Qt::BackgroundColorRole);
+ QVariant colorVariant = currentModel->data(currentModel->index(0,0), Qt::BackgroundRole);
if (colorVariant.isValid()) {
QVERIFY(colorVariant.canConvert<QColor>());
}
- colorVariant = currentModel->data(currentModel->index(0,0), Qt::TextColorRole);
+ colorVariant = currentModel->data(currentModel->index(0,0), Qt::ForegroundRole);
if (colorVariant.isValid()) {
QVERIFY(colorVariant.canConvert<QColor>());
}
diff --git a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
index 9a54c0a70d..16e5170a47 100644
--- a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
@@ -82,8 +82,116 @@ private slots:
void setData_emits_both_roles();
void supportedDragDropActions();
+
+ void moveRows_data();
+ void moveRows();
+ void moveRowsInvalid_data();
+ void moveRowsInvalid();
+
+ void itemData();
+ void setItemData();
};
+void tst_QStringListModel::moveRowsInvalid_data()
+{
+ QTest::addColumn<QStringListModel*>("baseModel");
+ QTest::addColumn<QModelIndex>("startParent");
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<QModelIndex>("destinationParent");
+ QTest::addColumn<int>("destination");
+
+ QStringListModel* tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("destination_equal_source") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << 1;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("count_equal_0") << tempModel << QModelIndex() << 0 << 0 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("move_child") << tempModel << tempModel->index(0, 0) << 0 << 1 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("move_to_child") << tempModel << QModelIndex() << 0 << 1 << tempModel->index(0, 0) << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("negative_count") << tempModel << QModelIndex() << 0 << -1 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("negative_source_row") << tempModel << QModelIndex() << -1 << 1 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("negative_destination_row") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << -1;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("source_row_equal_rowCount") << tempModel << QModelIndex() << tempModel->rowCount() << 1 << QModelIndex() << 1;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("destination_row_greater_rowCount") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << tempModel->rowCount() + 1;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("move_row_within_source_range") << tempModel << QModelIndex() << 0 << 3 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("destination_row_before_0") << tempModel << QModelIndex() << 1 << 1 << QModelIndex() << 0;
+}
+
+void tst_QStringListModel::moveRowsInvalid()
+{
+ QFETCH(QStringListModel* const, baseModel);
+ QFETCH(const QModelIndex, startParent);
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const QModelIndex, destinationParent);
+ QFETCH(const int, destination);
+
+ QSignalSpy rowMovedSpy(baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(rowMovedSpy.isValid());
+ QVERIFY(rowAboutMovedSpy.isValid());
+ QVERIFY(!baseModel->moveRows(startParent, startRow, count, destinationParent, destination));
+ QCOMPARE(rowMovedSpy.size(), 0);
+ QCOMPARE(rowAboutMovedSpy.size(), 0);
+ delete baseModel;
+}
+
+void tst_QStringListModel::moveRows_data()
+{
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("destination");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("1_Item_from_top_to_middle") << 0 << 1 << 3 << QStringList{"B", "C", "A", "D", "E", "F"};
+ QTest::newRow("1_Item_from_top_to_bottom") << 0 << 1 << 6 << QStringList{"B", "C", "D", "E", "F", "A"};
+ QTest::newRow("1_Item_from_middle_to_top") << 2 << 1 << 1 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("1_Item_from_bottom_to_middle") << 5 << 1 << 3 << QStringList{"A", "B", "F", "C", "D", "E"};
+ QTest::newRow("1_Item_from_bottom to_top") << 5 << 1 << 1 << QStringList{"F", "A", "B", "C", "D", "E"};
+ QTest::newRow("1_Item_from_middle_to_bottom") << 2 << 1 << 6 << QStringList{"A", "B", "D", "E", "F", "C"};
+ QTest::newRow("1_Item_from_middle_to_middle_before") << 2 << 1 << 1 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("1_Item_from_middle_to_middle_after") << 2 << 1 << 4 << QStringList{"A", "B", "D", "C", "E", "F"};
+
+ QTest::newRow("2_Items_from_top_to_middle") << 0 << 2 << 3 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("2_Items_from_top_to_bottom") << 0 << 2 << 6 << QStringList{"C", "D", "E", "F", "A", "B"};
+ QTest::newRow("2_Items_from_middle_to_top") << 2 << 2 << 1 << QStringList{"C", "D", "A", "B", "E", "F"};
+ QTest::newRow("2_Items_from_bottom_to_middle") << 4 << 2 << 3 << QStringList{"A", "B", "E", "F", "C", "D"};
+ QTest::newRow("2_Items_from_bottom_to_top") << 4 << 2 << 1 << QStringList{"E", "F", "A", "B", "C", "D"};
+ QTest::newRow("2_Items_from_middle_to_bottom") << 2 << 2 << 6 << QStringList{"A", "B", "E", "F", "C", "D"};
+ QTest::newRow("2_Items_from_middle_to_middle_before") << 3 << 2 << 2 << QStringList{"A", "D", "E", "B", "C", "F"};
+ QTest::newRow("2_Items_from_middle_to_middle_after") << 1 << 2 << 5 << QStringList{"A", "D", "E", "B", "C", "F"};
+}
+
+void tst_QStringListModel::moveRows()
+{
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const int, destination);
+ QFETCH(const QStringList, expected);
+ QStringListModel baseModel(QStringList{"A", "B", "C", "D", "E", "F"});
+ QSignalSpy rowMovedSpy(&baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(&baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(baseModel.moveRows(QModelIndex(), startRow, count, QModelIndex(), destination));
+ QCOMPARE(baseModel.stringList(), expected);
+ QCOMPARE(rowMovedSpy.size(), 1);
+ QCOMPARE(rowAboutMovedSpy.size(), 1);
+ for (const QList<QVariant> &signalArgs : {rowMovedSpy.first(), rowAboutMovedSpy.first()}){
+ QVERIFY(!signalArgs.at(0).value<QModelIndex>().isValid());
+ QCOMPARE(signalArgs.at(1).toInt(), startRow);
+ QCOMPARE(signalArgs.at(2).toInt(), startRow + count - 1);
+ QVERIFY(!signalArgs.at(3).value<QModelIndex>().isValid());
+ QCOMPARE(signalArgs.at(4).toInt(), destination);
+ }
+}
+
void tst_QStringListModel::rowsAboutToBeRemoved_rowsRemoved_data()
{
QTest::addColumn<QStringList>("input");
@@ -246,6 +354,74 @@ void tst_QStringListModel::setData_emits_both_roles()
expected);
}
+void tst_QStringListModel::itemData()
+{
+ QStringListModel testModel{ QStringList {
+ QStringLiteral("One"),
+ QStringLiteral("Two"),
+ QStringLiteral("Three"),
+ QStringLiteral("Four"),
+ QStringLiteral("Five")
+ }};
+ QMap<int, QVariant> compareMap;
+ QCOMPARE(testModel.itemData(QModelIndex()), compareMap);
+ compareMap.insert(Qt::DisplayRole, QStringLiteral("Two"));
+ compareMap.insert(Qt::EditRole, QStringLiteral("Two"));
+ QCOMPARE(testModel.itemData(testModel.index(1, 0)), compareMap);
+}
+
+void tst_QStringListModel::setItemData()
+{
+ QStringListModel testModel{ QStringList {
+ QStringLiteral("One"),
+ QStringLiteral("Two"),
+ QStringLiteral("Three"),
+ QStringLiteral("Four"),
+ QStringLiteral("Five")
+ }};
+ QSignalSpy dataChangedSpy(&testModel, &QAbstractItemModel::dataChanged);
+ QModelIndex changeIndex = testModel.index(1, 0);
+ const QVector<int> changeRoles{Qt::DisplayRole, Qt::EditRole};
+ const QString changedString("Changed");
+ QMap<int, QVariant> newItemData{std::make_pair<int>(Qt::DisplayRole, changedString)};
+ // invalid index does nothing and returns false
+ QVERIFY(!testModel.setItemData(QModelIndex(), newItemData));
+ // valid data is set, return value is true and dataChanged is emitted once
+ QVERIFY(testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), changedString);
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), changedString);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QVariantList dataChangedArguments = dataChangedSpy.takeFirst();
+ QCOMPARE(dataChangedArguments.at(0).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(1).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(2).value<QVector<int> >(), changeRoles);
+ // Unsupported roles do nothing return false
+ newItemData.clear();
+ newItemData.insert(Qt::UserRole, changedString);
+ QVERIFY(!testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(dataChangedSpy.size(), 0);
+ // If some but not all the roles are supported it returns false and does nothing
+ newItemData.insert(Qt::EditRole, changedString);
+ changeIndex = testModel.index(2, 0);
+ QVERIFY(!testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), QStringLiteral("Three"));
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), QStringLiteral("Three"));
+ QCOMPARE(dataChangedSpy.size(), 0);
+ // Qt::EditRole and Qt::DisplayRole are both set, Qt::EditRole takes precedence
+ newItemData.clear();
+ newItemData.insert(Qt::EditRole, changedString);
+ newItemData.insert(Qt::DisplayRole, QStringLiteral("Ignored"));
+ changeIndex = testModel.index(3, 0);
+ QVERIFY(testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), changedString);
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), changedString);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ dataChangedArguments = dataChangedSpy.takeFirst();
+ QCOMPARE(dataChangedArguments.at(0).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(1).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(2).value<QVector<int> >(), changeRoles);
+}
+
void tst_QStringListModel::supportedDragDropActions()
{
QStringListModel model;
diff --git a/tests/auto/corelib/itemmodels/qtransposeproxymodel/qtransposeproxymodel.pro b/tests/auto/corelib/itemmodels/qtransposeproxymodel/qtransposeproxymodel.pro
new file mode 100644
index 0000000000..3834add115
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qtransposeproxymodel/qtransposeproxymodel.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+TARGET = tst_qtransposeproxymodel
+QT = core gui testlib
+
+SOURCES = tst_qtransposeproxymodel.cpp
+
diff --git a/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp b/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp
new file mode 100644
index 0000000000..a30ac46571
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp
@@ -0,0 +1,915 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Luca Beldi <v.ronin@yahoo.it>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QTest>
+#include <QSignalSpy>
+#include <QStandardItemModel>
+#include <QStringListModel>
+#include <QAbstractItemModelTester>
+#include <random>
+
+#include <qtransposeproxymodel.h>
+
+class tst_QTransposeProxyModel : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void initTestCase();
+ void index();
+ void data();
+ void setData_data();
+ void setData();
+ void parent();
+ void mapToSource();
+ void mapFromSource();
+ void basicTest_data();
+ void basicTest();
+ void sort();
+ void insertRowBase_data();
+ void insertRowBase();
+ void insertColumnBase_data();
+ void insertColumnBase();
+ void insertColumnProxy_data();
+ void insertColumnProxy();
+ void insertRowProxy_data();
+ void insertRowProxy();
+ void removeRowBase_data();
+ void removeRowBase();
+ void removeColumnBase_data();
+ void removeColumnBase();
+ void removeColumnProxy_data();
+ void removeColumnProxy();
+ void removeRowProxy_data();
+ void removeRowProxy();
+ void headerData();
+ void setHeaderData();
+ void span();
+ void itemData();
+ void setItemData();
+ void moveRowsBase();
+ void moveColumnsProxy();
+private:
+ void testTransposed(
+ const QAbstractItemModel *const baseModel,
+ const QAbstractItemModel *const transposed,
+ const QModelIndex &baseParent = QModelIndex(),
+ const QModelIndex &transposedParent = QModelIndex()
+ );
+ QAbstractItemModel *createListModel(QObject *parent);
+ QAbstractItemModel *createTableModel(QObject *parent);
+ QAbstractItemModel *createTreeModel(QObject *parent);
+};
+
+QAbstractItemModel *tst_QTransposeProxyModel::createListModel(QObject *parent)
+{
+ QStringList sequence;
+ sequence.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ sequence.append(QString::number(i));
+ return new QStringListModel(sequence, parent);
+}
+
+QAbstractItemModel *tst_QTransposeProxyModel::createTableModel(QObject *parent)
+{
+ QAbstractItemModel *model = new QStandardItemModel(parent);
+ model->insertRows(0, 5);
+ model->insertColumns(0, 4);
+ for (int i = 0; i < model->rowCount(); ++i) {
+ for (int j = 0; j < model->columnCount(); ++j) {
+ model->setData(model->index(i, j), QStringLiteral("%1,%2").arg(i).arg(j), Qt::EditRole);
+ model->setData(model->index(i, j), i, Qt::UserRole);
+ model->setData(model->index(i, j), j, Qt::UserRole + 1);
+ }
+ }
+ return model;
+}
+
+QAbstractItemModel *tst_QTransposeProxyModel::createTreeModel(QObject *parent)
+{
+ QAbstractItemModel *model = new QStandardItemModel(parent);
+ model->insertRows(0, 5);
+ model->insertColumns(0, 4);
+ for (int i = 0; i < model->rowCount(); ++i) {
+ for (int j = 0; j < model->columnCount(); ++j) {
+ const QModelIndex parIdx = model->index(i, j);
+ model->setData(parIdx, QStringLiteral("%1,%2").arg(i).arg(j), Qt::EditRole);
+ model->setData(parIdx, i, Qt::UserRole);
+ model->setData(parIdx, j, Qt::UserRole + 1);
+ model->insertRows(0, 3, parIdx);
+ model->insertColumns(0, 2, parIdx);
+ for (int h = 0; h < model->rowCount(parIdx); ++h) {
+ for (int k = 0; k < model->columnCount(parIdx); ++k) {
+ const QModelIndex childIdx = model->index(h, k, parIdx);
+ model->setData(childIdx, QStringLiteral("%1,%2,%3,%4").arg(i).arg(j).arg(h).arg(k), Qt::EditRole);
+ model->setData(childIdx, i, Qt::UserRole);
+ model->setData(childIdx, j, Qt::UserRole + 1);
+ model->setData(childIdx, h, Qt::UserRole + 2);
+ model->setData(childIdx, k, Qt::UserRole + 3);
+ }
+ }
+ }
+ }
+ return model;
+}
+
+void tst_QTransposeProxyModel::testTransposed(
+ const QAbstractItemModel *const baseModel,
+ const QAbstractItemModel *const transposed,
+ const QModelIndex &baseParent,
+ const QModelIndex &transposedParent
+)
+{
+ QCOMPARE(transposed->hasChildren(transposedParent), baseModel->hasChildren(baseParent));
+ QCOMPARE(transposed->columnCount(transposedParent), baseModel->rowCount(baseParent));
+ QCOMPARE(transposed->rowCount(transposedParent), baseModel->columnCount(baseParent));
+ for (int i = 0, maxRow = baseModel->rowCount(baseParent); i < maxRow; ++i) {
+ for (int j = 0, maxCol = baseModel->columnCount(baseParent); j < maxCol; ++j) {
+ const QModelIndex baseIdx = baseModel->index(i, j, baseParent);
+ const QModelIndex transIdx = transposed->index(j, i, transposedParent);
+ QCOMPARE(transIdx.data(), baseIdx.data());
+ QCOMPARE(transIdx.data(Qt::UserRole), baseIdx.data(Qt::UserRole));
+ QCOMPARE(transIdx.data(Qt::UserRole + 1), baseIdx.data(Qt::UserRole + 1));
+ QCOMPARE(transIdx.data(Qt::UserRole + 2), baseIdx.data(Qt::UserRole + 2));
+ QCOMPARE(transIdx.data(Qt::UserRole + 3), baseIdx.data(Qt::UserRole + 3));
+ if (baseModel->hasChildren(baseIdx)) {
+ testTransposed(baseModel, transposed, baseIdx, transIdx);
+ }
+ }
+ }
+}
+
+void tst_QTransposeProxyModel::initTestCase()
+{
+ qRegisterMetaType<QList<QPersistentModelIndex> >();
+ qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
+}
+
+void tst_QTransposeProxyModel::index()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QVERIFY(!proxy.index(0, -1).isValid());
+ QVERIFY(!proxy.index(0, -1).isValid());
+ QVERIFY(!proxy.index(-1, -1).isValid());
+ QVERIFY(!proxy.index(0, proxy.columnCount()).isValid());
+ QVERIFY(!proxy.index(proxy.rowCount(), 0).isValid());
+ QVERIFY(!proxy.index(proxy.rowCount(), proxy.columnCount()).isValid());
+ QModelIndex tempIdx = proxy.index(0, 1);
+ QVERIFY(tempIdx.isValid());
+ QCOMPARE(tempIdx.row(), 0);
+ QCOMPARE(tempIdx.column(), 1);
+ tempIdx = proxy.index(0, 1, tempIdx);
+ QVERIFY(tempIdx.isValid());
+ QCOMPARE(tempIdx.row(), 0);
+ QCOMPARE(tempIdx.column(), 1);
+ delete model;
+}
+
+void tst_QTransposeProxyModel::data()
+{
+ QStringListModel model{QStringList{"A", "B"}};
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QCOMPARE(proxy.index(0, 1).data().toString(), QStringLiteral("B"));
+}
+
+void tst_QTransposeProxyModel::parent()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const QModelIndex parentIdx = proxy.index(0, 0);
+ const QModelIndex childIdx = proxy.index(0, 0, parentIdx);
+ QVERIFY(parentIdx.isValid());
+ QVERIFY(childIdx.isValid());
+ QCOMPARE(childIdx.parent(), parentIdx);
+ delete model;
+}
+
+void tst_QTransposeProxyModel::mapToSource()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QVERIFY(!proxy.mapToSource(QModelIndex()).isValid());
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 0)), model->index(0, 0));
+ QCOMPARE(proxy.mapToSource(proxy.index(1, 0)), model->index(0, 1));
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 1)), model->index(1, 0));
+ const QModelIndex proxyParent = proxy.index(1, 0);
+ const QModelIndex sourceParent = model->index(0, 1);
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 0, proxyParent)), model->index(0, 0, sourceParent));
+ QCOMPARE(proxy.mapToSource(proxy.index(1, 0, proxyParent)), model->index(0, 1, sourceParent));
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 1, proxyParent)), model->index(1, 0, sourceParent));
+ delete model;
+}
+
+void tst_QTransposeProxyModel::mapFromSource()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QVERIFY(!proxy.mapFromSource(QModelIndex()).isValid());
+ QCOMPARE(proxy.mapFromSource(model->index(0, 0)), proxy.index(0, 0));
+ QCOMPARE(proxy.mapFromSource(model->index(0, 1)), proxy.index(1, 0));
+ QCOMPARE(proxy.mapFromSource(model->index(1, 0)), proxy.index(0, 1));
+ const QModelIndex proxyParent = proxy.index(1, 0);
+ const QModelIndex sourceParent = model->index(0, 1);
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 0, proxyParent)), model->index(0, 0, sourceParent));
+ QCOMPARE(proxy.mapFromSource(model->index(1, 0, sourceParent)), proxy.index(0, 1, proxyParent));
+ QCOMPARE(proxy.mapFromSource(model->index(0, 1, sourceParent)), proxy.index(1, 0, proxyParent));
+ delete model;
+}
+
+void tst_QTransposeProxyModel::basicTest_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::newRow("List") << createListModel(this);
+ QTest::newRow("Table") << createTableModel(this);
+ QTest::newRow("Tree") << createTreeModel(this);
+}
+
+void tst_QTransposeProxyModel::basicTest()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ testTransposed(model, &proxy);
+ delete model;
+}
+
+void tst_QTransposeProxyModel::sort()
+{
+ QStringList sequence;
+ sequence.reserve(100);
+ for (int i = 0; i < 100; ++i)
+ sequence.append(QStringLiteral("%1").arg(i, 3, 10, QLatin1Char('0')));
+ std::shuffle(sequence.begin(), sequence.end(), std::mt19937(88));
+ const QString firstItemBeforeSort = sequence.first();
+ QStringListModel baseModel(sequence);
+ QTransposeProxyModel proxyModel;
+ new QAbstractItemModelTester(&proxyModel, &proxyModel);
+ proxyModel.setSourceModel(&baseModel);
+ QSignalSpy layoutChangedSpy(&proxyModel, &QAbstractItemModel::layoutChanged);
+ QVERIFY(layoutChangedSpy.isValid());
+ QSignalSpy layoutAboutToBeChangedSpy(&proxyModel, &QAbstractItemModel::layoutAboutToBeChanged);
+ QVERIFY(layoutAboutToBeChangedSpy.isValid());
+ QPersistentModelIndex firstIndexBeforeSort = proxyModel.index(0, 0);
+ baseModel.sort(0, Qt::AscendingOrder);
+ QCOMPARE(layoutChangedSpy.count(), 1);
+ QCOMPARE(layoutAboutToBeChangedSpy.count(), 1);
+ QCOMPARE(layoutChangedSpy.takeFirst().at(1).toInt(), int(QAbstractItemModel::HorizontalSortHint));
+ QCOMPARE(firstIndexBeforeSort.data().toString(), firstItemBeforeSort);
+ for (int i = 0; i < 100; ++i)
+ QCOMPARE(proxyModel.index(0, i).data().toInt(), i);
+}
+
+void tst_QTransposeProxyModel::removeColumnBase_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<QModelIndex>("parent");
+ QTest::newRow("Table") << createTableModel(this) << QModelIndex();
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex();
+ QAbstractItemModel *model = createTreeModel(this);
+ QTest::newRow("Tree_Child_Item") << model << model->index(0, 0);
+}
+
+void tst_QTransposeProxyModel::removeColumnBase()
+{
+ QFETCH(QAbstractItemModel * const, model);
+ QFETCH(const QModelIndex, parent);
+ QTransposeProxyModel proxy;
+ QSignalSpy rowRemoveSpy(&proxy, &QAbstractItemModel::rowsRemoved);
+ QVERIFY(rowRemoveSpy.isValid());
+ QSignalSpy rowAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::rowsAboutToBeRemoved);
+ QVERIFY(rowAboutToBeRemoveSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const int oldRowCount = proxy.rowCount(proxy.mapFromSource(parent));
+ const QVariant expectedNewVal = model->index(0, 2, parent).data();
+ QVERIFY(model->removeColumn(1, parent));
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(parent)), oldRowCount - 1);
+ QCOMPARE(proxy.index(1, 0, proxy.mapFromSource(parent)).data(), expectedNewVal);
+ QCOMPARE(rowRemoveSpy.count(), 1);
+ QCOMPARE(rowAboutToBeRemoveSpy.count(), 1);
+ for (const auto &spyArgs : {rowRemoveSpy.takeFirst(),
+ rowAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxy.mapFromSource(parent));
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::insertColumnBase_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<QModelIndex>("parent");
+ QTest::newRow("Table") << createTableModel(this) << QModelIndex();
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex();
+ QAbstractItemModel *model = createTreeModel(this);
+ QTest::newRow("Tree_Child_Item") << model << model->index(0, 0);
+}
+
+void tst_QTransposeProxyModel::insertColumnBase()
+{
+ QFETCH(QAbstractItemModel * const, model);
+ QFETCH(const QModelIndex, parent);
+ QTransposeProxyModel proxy;
+ QSignalSpy rowInsertSpy(&proxy, &QAbstractItemModel::rowsInserted);
+ QVERIFY(rowInsertSpy.isValid());
+ QSignalSpy rowAboutToBeInsertSpy(&proxy, &QAbstractItemModel::rowsAboutToBeInserted);
+ QVERIFY(rowAboutToBeInsertSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const int oldRowCount = proxy.rowCount(proxy.mapFromSource(parent));
+ QVERIFY(model->insertColumn(1, parent));
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(parent)), oldRowCount + 1);
+ QVERIFY(!proxy.index(1, 0, proxy.mapFromSource(parent)).data().isValid());
+ QCOMPARE(rowInsertSpy.count(), 1);
+ QCOMPARE(rowAboutToBeInsertSpy.count(), 1);
+ for (const auto &spyArgs : {rowInsertSpy.takeFirst(),
+ rowAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxy.mapFromSource(parent));
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::removeRowBase_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<QModelIndex>("parent");
+ QTest::newRow("List") << createListModel(this) << QModelIndex();
+ QTest::newRow("Table") << createTableModel(this) << QModelIndex();
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex();
+ QAbstractItemModel *model = createTreeModel(this);
+ QTest::newRow("Tree_Child_Item") << model << model->index(0, 0);
+}
+
+void tst_QTransposeProxyModel::removeRowBase()
+{
+ QFETCH(QAbstractItemModel * const, model);
+ QFETCH(const QModelIndex, parent);
+ QTransposeProxyModel proxy;
+ QSignalSpy columnsRemoveSpy(&proxy, &QAbstractItemModel::columnsRemoved);
+ QVERIFY(columnsRemoveSpy.isValid());
+ QSignalSpy columnsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeRemoved);
+ QVERIFY(columnsAboutToBeRemoveSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const int oldColCount = proxy.columnCount(proxy.mapFromSource(parent));
+ const QVariant expectedNewVal = model->index(2, 0, parent).data();
+ QVERIFY(model->removeRow(1, parent));
+ QCOMPARE(proxy.columnCount(proxy.mapFromSource(parent)), oldColCount - 1);
+ QCOMPARE(proxy.index(0, 1, proxy.mapFromSource(parent)).data(), expectedNewVal);
+ QCOMPARE(columnsRemoveSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeRemoveSpy.count(), 1);
+ for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(),
+ columnsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxy.mapFromSource(parent));
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::insertRowBase_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<QModelIndex>("parent");
+ QTest::newRow("List") << createListModel(this) << QModelIndex();
+ QTest::newRow("Table") << createTableModel(this) << QModelIndex();
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex();
+ QAbstractItemModel *model = createTreeModel(this);
+ QTest::newRow("Tree_Child_Item") << model << model->index(0, 0);
+}
+
+void tst_QTransposeProxyModel::insertRowBase()
+{
+ QFETCH(QAbstractItemModel * const, model);
+ QFETCH(const QModelIndex, parent);
+ QTransposeProxyModel proxy;
+ QSignalSpy columnsInsertSpy(&proxy, &QAbstractItemModel::columnsInserted);
+ QVERIFY(columnsInsertSpy.isValid());
+ QSignalSpy columnsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::columnsAboutToBeInserted);
+ QVERIFY(columnsAboutToBeInsertSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const int oldColCount = proxy.columnCount(proxy.mapFromSource(parent));
+ QVERIFY(model->insertRow(1, parent));
+ QCOMPARE(proxy.columnCount(proxy.mapFromSource(parent)), oldColCount + 1);
+ QVERIFY(proxy.index(0, 1, proxy.mapFromSource(parent)).data().isNull());
+ QCOMPARE(columnsInsertSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeInsertSpy.count(), 1);
+ for (const auto &spyArgs : {columnsInsertSpy.takeFirst(),
+ columnsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxy.mapFromSource(parent));
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::removeColumnProxy_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::newRow("List") << createListModel(this) << true;
+ QTest::newRow("Table") << createTableModel(this) << true;
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true;
+ QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false;
+}
+
+void tst_QTransposeProxyModel::removeColumnProxy()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy columnsRemoveSpy(&proxy, &QAbstractItemModel::columnsRemoved);
+ QVERIFY(columnsRemoveSpy.isValid());
+ QSignalSpy columnsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeRemoved);
+ QVERIFY(columnsAboutToBeRemoveSpy.isValid());
+ QSignalSpy rowsRemoveSpy(model, &QAbstractItemModel::rowsRemoved);
+ QVERIFY(rowsRemoveSpy.isValid());
+ QSignalSpy rowsAboutToBeRemoveSpy(model, &QAbstractItemModel::rowsAboutToBeRemoved);
+ QVERIFY(rowsAboutToBeRemoveSpy.isValid());
+ proxy.setSourceModel(model);
+ const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1);
+ const QModelIndex sourceParent = proxy.mapToSource(proxyParent);
+ const int oldColCount = proxy.columnCount(proxyParent);
+ const int oldRowCount = model->rowCount(sourceParent);
+ const QVariant expectedNewVal = proxy.index(0, 2, proxyParent).data();
+ QVERIFY(proxy.removeColumn(1, proxyParent));
+ QCOMPARE(proxy.columnCount(proxyParent), oldColCount - 1);
+ QCOMPARE(model->rowCount(sourceParent), oldRowCount - 1);
+ QCOMPARE(proxy.index(0, 1, proxyParent).data(), expectedNewVal);
+ QCOMPARE(model->index(1, 0, sourceParent).data(), expectedNewVal);
+ QCOMPARE(columnsRemoveSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeRemoveSpy.count(), 1);
+ QCOMPARE(rowsRemoveSpy.count(), 1);
+ QCOMPARE(rowsAboutToBeRemoveSpy.count(), 1);
+ for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(),
+ columnsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxyParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ for (const auto &spyArgs : {rowsRemoveSpy.takeFirst(),
+ rowsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), sourceParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::insertColumnProxy_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::newRow("List") << createListModel(this) << true;
+ QTest::newRow("Table") << createTableModel(this) << true;
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true;
+ QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false;
+}
+
+void tst_QTransposeProxyModel::insertColumnProxy()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy columnsInsertSpy(&proxy, &QAbstractItemModel::columnsInserted);
+ QVERIFY(columnsInsertSpy.isValid());
+ QSignalSpy columnsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::columnsAboutToBeInserted);
+ QVERIFY(columnsAboutToBeInsertSpy.isValid());
+ QSignalSpy rowsInsertSpy(model, &QAbstractItemModel::rowsInserted);
+ QVERIFY(rowsInsertSpy.isValid());
+ QSignalSpy rowsAboutToBeInsertSpy(model, &QAbstractItemModel::rowsAboutToBeInserted);
+ QVERIFY(rowsAboutToBeInsertSpy.isValid());
+ proxy.setSourceModel(model);
+ const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1);
+ const QModelIndex sourceParent = proxy.mapToSource(proxyParent);
+ const int oldColCount = proxy.columnCount(proxyParent);
+ const int oldRowCount = model->rowCount(sourceParent);
+ QVERIFY(proxy.insertColumn(1, proxyParent));
+ QCOMPARE(proxy.columnCount(proxyParent), oldColCount + 1);
+ QCOMPARE(model->rowCount(sourceParent), oldRowCount + 1);
+ QVERIFY(proxy.index(0, 1, proxyParent).data().isNull());
+ QVERIFY(model->index(1, 0, sourceParent).data().isNull());
+ QCOMPARE(columnsInsertSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeInsertSpy.count(), 1);
+ QCOMPARE(rowsInsertSpy.count(), 1);
+ QCOMPARE(rowsAboutToBeInsertSpy.count(), 1);
+ for (const auto &spyArgs : {columnsInsertSpy.takeFirst(),
+ columnsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxyParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ for (const auto &spyArgs : {rowsInsertSpy.takeFirst(),
+ rowsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), sourceParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::removeRowProxy_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::newRow("Table") << createTableModel(this) << true;
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true;
+ QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false;
+}
+
+void tst_QTransposeProxyModel::removeRowProxy()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy rowsRemoveSpy(&proxy, &QAbstractItemModel::rowsRemoved);
+ QVERIFY(rowsRemoveSpy.isValid());
+ QSignalSpy rowsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::rowsAboutToBeRemoved);
+ QVERIFY(rowsAboutToBeRemoveSpy.isValid());
+ QSignalSpy columnsRemoveSpy(model, &QAbstractItemModel::columnsRemoved);
+ QVERIFY(columnsRemoveSpy.isValid());
+ QSignalSpy columnsAboutToBeRemoveSpy(model, &QAbstractItemModel::columnsAboutToBeRemoved);
+ QVERIFY(columnsAboutToBeRemoveSpy.isValid());
+ proxy.setSourceModel(model);
+ const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1);
+ const QModelIndex sourceParent = proxy.mapToSource(proxyParent);
+ const int oldRowCount = proxy.rowCount(proxyParent);
+ const int oldColCount = model->columnCount(sourceParent);
+ const QVariant expectedNewVal = proxy.index(2, 0, proxyParent).data();
+ QVERIFY(proxy.removeRow(1, proxyParent));
+ QCOMPARE(proxy.rowCount(proxyParent), oldRowCount - 1);
+ QCOMPARE(model->columnCount(sourceParent), oldColCount - 1);
+ QCOMPARE(proxy.index(1, 0, proxyParent).data(), expectedNewVal);
+ QCOMPARE(model->index(0, 1, sourceParent).data(), expectedNewVal);
+ QCOMPARE(columnsRemoveSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeRemoveSpy.count(), 1);
+ QCOMPARE(rowsRemoveSpy.count(), 1);
+ QCOMPARE(rowsAboutToBeRemoveSpy.count(), 1);
+ for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(),
+ columnsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), sourceParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ for (const auto &spyArgs : {rowsRemoveSpy.takeFirst(),
+ rowsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxyParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::insertRowProxy_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::newRow("Table") << createTableModel(this) << true;
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true;
+ QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false;
+}
+
+void tst_QTransposeProxyModel::insertRowProxy()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy rowsInsertSpy(&proxy, &QAbstractItemModel::rowsInserted);
+ QVERIFY(rowsInsertSpy.isValid());
+ QSignalSpy rowsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::rowsAboutToBeInserted);
+ QVERIFY(rowsAboutToBeInsertSpy.isValid());
+ QSignalSpy columnsInsertSpy(model, &QAbstractItemModel::columnsInserted);
+ QVERIFY(columnsInsertSpy.isValid());
+ QSignalSpy columnsAboutToBeInsertSpy(model, &QAbstractItemModel::columnsAboutToBeInserted);
+ QVERIFY(columnsAboutToBeInsertSpy.isValid());
+ proxy.setSourceModel(model);
+ const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1);
+ const QModelIndex sourceParent = proxy.mapToSource(proxyParent);
+ const int oldRowCount = proxy.rowCount(proxyParent);
+ const int oldColCount = model->columnCount(sourceParent);
+ QVERIFY(proxy.insertRow(1, proxyParent));
+ QCOMPARE(proxy.rowCount(proxyParent), oldRowCount + 1);
+ QCOMPARE(model->columnCount(sourceParent), oldColCount + 1);
+ QVERIFY(proxy.index(1, 0, proxyParent).data().isNull());
+ QVERIFY(model->index(0, 1, sourceParent).data().isNull());
+ QCOMPARE(columnsInsertSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeInsertSpy.count(), 1);
+ QCOMPARE(rowsInsertSpy.count(), 1);
+ QCOMPARE(rowsAboutToBeInsertSpy.count(), 1);
+ for (const auto &spyArgs : {columnsInsertSpy.takeFirst(),
+ columnsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), sourceParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ for (const auto &spyArgs : {rowsInsertSpy.takeFirst(),
+ rowsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxyParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::headerData()
+{
+ QStandardItemModel model;
+ model.insertRows(0, 3);
+ model.insertColumns(0, 5);
+ for (int i = 0; i < model.rowCount(); ++i)
+ model.setHeaderData(i, Qt::Horizontal, QChar('A' + i));
+ for (int i = 1; i <= model.columnCount(); ++i)
+ model.setHeaderData(i, Qt::Vertical, i);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ for (int i = 0; i < model.rowCount(); ++i)
+ QCOMPARE(model.headerData(i, Qt::Horizontal), proxy.headerData(i, Qt::Vertical));
+ for (int i = 0; i < model.columnCount(); ++i)
+ QCOMPARE(model.headerData(i, Qt::Vertical), proxy.headerData(i, Qt::Horizontal));
+}
+
+void tst_QTransposeProxyModel::setHeaderData()
+{
+ QStandardItemModel model;
+ model.insertRows(0, 3);
+ model.insertColumns(0, 5);
+ for (int i = 0; i < model.rowCount(); ++i)
+ model.setHeaderData(i, Qt::Horizontal, QChar('A' + i));
+ for (int i = 1; i <= model.columnCount(); ++i)
+ model.setHeaderData(i, Qt::Vertical, i);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QVERIFY(proxy.setHeaderData(1, Qt::Horizontal, 99));
+ QCOMPARE(model.headerData(1, Qt::Vertical).toInt(), 99);
+ QVERIFY(proxy.setHeaderData(1, Qt::Vertical, QChar('Z')));
+ QCOMPARE(model.headerData(1, Qt::Horizontal).toChar(), QChar('Z'));
+}
+
+void tst_QTransposeProxyModel::span()
+{
+ class SpanModel : public QStandardItemModel
+ {
+ Q_DISABLE_COPY(SpanModel)
+ public:
+ SpanModel(int rows, int columns, QObject *parent = nullptr)
+ : QStandardItemModel(rows, columns, parent)
+ {}
+ QSize span(const QModelIndex &index) const override
+ {
+ Q_UNUSED(index)
+ return QSize(2, 1);
+ }
+ };
+ SpanModel model(3, 5);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QCOMPARE(proxy.span(proxy.index(0, 0)), QSize(1, 2));
+}
+
+void tst_QTransposeProxyModel::itemData()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QMap<int, QVariant> itmData = proxy.itemData(proxy.index(0, 1));
+ QCOMPARE(itmData.value(Qt::DisplayRole).toString(), QStringLiteral("1,0"));
+ QCOMPARE(itmData.value(Qt::UserRole).toInt(), 1);
+ QCOMPARE(itmData.value(Qt::UserRole + 1).toInt(), 0);
+ itmData = proxy.itemData(proxy.index(1, 2, proxy.index(0, 1)));
+ QCOMPARE(itmData.value(Qt::DisplayRole).toString(), QStringLiteral("1,0,2,1"));
+ QCOMPARE(itmData.value(Qt::UserRole).toInt(), 1);
+ QCOMPARE(itmData.value(Qt::UserRole + 1).toInt(), 0);
+ QCOMPARE(itmData.value(Qt::UserRole + 2).toInt(), 2);
+ QCOMPARE(itmData.value(Qt::UserRole + 3).toInt(), 1);
+ QVERIFY(proxy.itemData(QModelIndex()).isEmpty());
+ delete model;
+}
+
+void tst_QTransposeProxyModel::setItemData()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QSignalSpy sourceDataChangeSpy(model, &QAbstractItemModel::dataChanged);
+ QVERIFY(sourceDataChangeSpy.isValid());
+ QSignalSpy proxyDataChangeSpy(&proxy, &QAbstractItemModel::dataChanged);
+ QVERIFY(proxyDataChangeSpy.isValid());
+ const QMap<int, QVariant> itmData = {
+ std::make_pair<int, QVariant>(Qt::DisplayRole, QStringLiteral("Test")),
+ std::make_pair<int, QVariant>(Qt::UserRole, 88),
+ std::make_pair<int, QVariant>(Qt::UserRole + 1, 99),
+ };
+ QModelIndex idx = proxy.index(0, 1);
+ QVERIFY(proxy.setItemData(idx, itmData));
+ QCOMPARE(idx.data(Qt::DisplayRole).toString(), QStringLiteral("Test"));
+ QCOMPARE(idx.data(Qt::UserRole).toInt(), 88);
+ QCOMPARE(idx.data(Qt::UserRole + 1).toInt(), 99);
+ QCOMPARE(sourceDataChangeSpy.size(), 1);
+ QCOMPARE(proxyDataChangeSpy.size(), 1);
+ auto signalData = proxyDataChangeSpy.takeFirst();
+ QCOMPARE(signalData.at(0).value<QModelIndex>(), idx);
+ QCOMPARE(signalData.at(1).value<QModelIndex>(), idx);
+ const QVector<int> expectedRoles{Qt::DisplayRole, Qt::UserRole, Qt::EditRole, Qt::UserRole + 1};
+ QVector<int> receivedRoles = signalData.at(2).value<QVector<int> >();
+ QCOMPARE(receivedRoles.size(), expectedRoles.size());
+ for (int role : expectedRoles)
+ QVERIFY(receivedRoles.contains(role));
+ signalData = sourceDataChangeSpy.takeFirst();
+ QCOMPARE(signalData.at(0).value<QModelIndex>(), proxy.mapToSource(idx));
+ QCOMPARE(signalData.at(1).value<QModelIndex>(), proxy.mapToSource(idx));
+ receivedRoles = signalData.at(2).value<QVector<int> >();
+ QCOMPARE(receivedRoles.size(), expectedRoles.size());
+ for (int role : expectedRoles)
+ QVERIFY(receivedRoles.contains(role));
+ idx = proxy.index(1, 2, proxy.index(0, 1));
+ QVERIFY(proxy.setItemData(idx, itmData));
+ QCOMPARE(idx.data(Qt::DisplayRole).toString(), QStringLiteral("Test"));
+ QCOMPARE(idx.data(Qt::UserRole).toInt(), 88);
+ QCOMPARE(idx.data(Qt::UserRole + 1).toInt(), 99);
+ QCOMPARE(idx.data(Qt::UserRole + 2).toInt(), 2);
+ QCOMPARE(idx.data(Qt::UserRole + 3).toInt(), 1);
+ QCOMPARE(sourceDataChangeSpy.size(), 1);
+ QCOMPARE(proxyDataChangeSpy.size(), 1);
+ signalData = proxyDataChangeSpy.takeFirst();
+ QCOMPARE(signalData.at(0).value<QModelIndex>(), idx);
+ QCOMPARE(signalData.at(1).value<QModelIndex>(), idx);
+ receivedRoles = signalData.at(2).value<QVector<int> >();
+ QCOMPARE(receivedRoles.size(), expectedRoles.size());
+ for (int role : expectedRoles)
+ QVERIFY(receivedRoles.contains(role));
+ signalData = sourceDataChangeSpy.takeFirst();
+ QCOMPARE(signalData.at(0).value<QModelIndex>(), proxy.mapToSource(idx));
+ QCOMPARE(signalData.at(1).value<QModelIndex>(), proxy.mapToSource(idx));
+ receivedRoles = signalData.at(2).value<QVector<int> >();
+ QCOMPARE(receivedRoles.size(), expectedRoles.size());
+ for (int role : expectedRoles)
+ QVERIFY(receivedRoles.contains(role));
+ QVERIFY(!proxy.setItemData(QModelIndex(), itmData));
+ delete model;
+}
+
+void tst_QTransposeProxyModel::moveRowsBase()
+{
+ QStringListModel model{QStringList{"A", "B", "C", "D"}};
+ QTransposeProxyModel proxy;
+ QSignalSpy columnsMoveSpy(&proxy, &QAbstractItemModel::columnsMoved);
+ QVERIFY(columnsMoveSpy.isValid());
+ QSignalSpy columnsAboutToBeMoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeMoved);
+ QVERIFY(columnsAboutToBeMoveSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ const QStringList expectedNewVal = {"B", "A", "C", "D"};
+ QVERIFY(model.moveRows(QModelIndex(), 0, 1, QModelIndex(), 2));
+ for (int i = 0; i < expectedNewVal.size(); ++i)
+ QCOMPARE(proxy.index(0, i).data(), expectedNewVal.at(i));
+ QCOMPARE(columnsMoveSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeMoveSpy.count(), 1);
+ for (const auto &spyArgs : {columnsMoveSpy.takeFirst(),
+ columnsAboutToBeMoveSpy.takeFirst()}) {
+ QVERIFY(!spyArgs.at(0).value<QModelIndex>().isValid());
+ QCOMPARE(spyArgs.at(1).toInt(), 0);
+ QCOMPARE(spyArgs.at(2).toInt(), 0);
+ QVERIFY(!spyArgs.at(3).value<QModelIndex>().isValid());
+ QCOMPARE(spyArgs.at(4).toInt(), 2);
+ }
+}
+
+void tst_QTransposeProxyModel::moveColumnsProxy()
+{
+ QStringListModel model{QStringList{"A", "B", "C", "D"}};
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy columnsMoveSpy(&proxy, &QAbstractItemModel::columnsMoved);
+ QVERIFY(columnsMoveSpy.isValid());
+ QSignalSpy columnsAboutToBeMoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeMoved);
+ QVERIFY(columnsAboutToBeMoveSpy.isValid());
+ QSignalSpy rowsMoveSpy(&model, &QAbstractItemModel::rowsMoved);
+ QVERIFY(rowsMoveSpy.isValid());
+ QSignalSpy rowsAboutToBeMoveSpy(&model, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(rowsAboutToBeMoveSpy.isValid());
+ proxy.setSourceModel(&model);
+ const QStringList expectedNewVal = {"B", "A", "C", "D"};
+ QVERIFY(proxy.moveColumns(QModelIndex(), 0, 1, QModelIndex(), 2));
+ for (int i = 0; i < expectedNewVal.size(); ++i)
+ QCOMPARE(proxy.index(0, i).data(), expectedNewVal.at(i));
+ for (int i = 0; i < expectedNewVal.size(); ++i)
+ QCOMPARE(model.index(i, 0).data(), expectedNewVal.at(i));
+ QCOMPARE(columnsMoveSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeMoveSpy.count(), 1);
+ QCOMPARE(rowsMoveSpy.count(), 1);
+ QCOMPARE(rowsAboutToBeMoveSpy.count(), 1);
+ for (const auto &spyArgs : {columnsMoveSpy.takeFirst(),
+ columnsAboutToBeMoveSpy.takeFirst(),
+ rowsMoveSpy.takeFirst(),rowsAboutToBeMoveSpy.takeFirst()}) {
+ QVERIFY(!spyArgs.at(0).value<QModelIndex>().isValid());
+ QCOMPARE(spyArgs.at(1).toInt(), 0);
+ QCOMPARE(spyArgs.at(2).toInt(), 0);
+ QVERIFY(!spyArgs.at(3).value<QModelIndex>().isValid());
+ }
+}
+
+void tst_QTransposeProxyModel::setData_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::addColumn<bool>("viaProxy");
+ QTest::newRow("List_via_Base") << createListModel(this) << true << false;
+ QTest::newRow("Table_via_Base") << createTableModel(this) << true << false;
+ QTest::newRow("Tree_via_Base_Root_Item") << createTreeModel(this) << true << false;
+ QTest::newRow("Tree_via_Base_Child_Item") << createTreeModel(this) << false << false;
+ QTest::newRow("List_via_Proxy") << createListModel(this) << true << true;
+ QTest::newRow("Table_via_Proxy") << createTableModel(this) << true << true;
+ QTest::newRow("Tree_via_Proxy_Root_Item") << createTreeModel(this) << true << true;
+ QTest::newRow("Tree_via_Proxy_Child_Item") << createTreeModel(this) << false << true;
+}
+
+void tst_QTransposeProxyModel::setData()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QFETCH(bool, viaProxy);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QSignalSpy sourceDataChangeSpy(model, &QAbstractItemModel::dataChanged);
+ QVERIFY(sourceDataChangeSpy.isValid());
+ QSignalSpy proxyDataChangeSpy(&proxy, &QAbstractItemModel::dataChanged);
+ QVERIFY(proxyDataChangeSpy.isValid());
+ const QString testData = QStringLiteral("TestingSetData");
+ if (viaProxy) {
+ const QModelIndex parIdx = rootItem ? QModelIndex() : proxy.index(0, 1);
+ QVERIFY(proxy.setData(proxy.index(0, 1, parIdx), testData));
+ QCOMPARE(model->index(1, 0, proxy.mapToSource(parIdx)).data().toString(), testData);
+ } else {
+ const QModelIndex parIdx = rootItem ? QModelIndex() : model->index(1, 0);
+ QVERIFY(model->setData(model->index(1, 0, parIdx), testData));
+ QCOMPARE(proxy.index(0, 1, proxy.mapFromSource(parIdx)).data().toString(), testData);
+ }
+ QCOMPARE(sourceDataChangeSpy.size(), 1);
+ QCOMPARE(proxyDataChangeSpy.size(), 1);
+ delete model;
+}
+
+QTEST_GUILESS_MAIN(tst_QTransposeProxyModel)
+
+#include "tst_qtransposeproxymodel.moc"
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 5d9b5ca95c..0c328dff58 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -73,6 +73,7 @@ private slots:
void defined();
void threadSafety();
void namespaces();
+ void id();
void qMetaTypeId();
void properties();
void normalizedTypes();
@@ -475,6 +476,12 @@ void tst_QMetaType::namespaces()
QCOMPARE(QMetaType::typeName(qungTfuId), "TestSpace::QungTfu");
}
+void tst_QMetaType::id()
+{
+ QCOMPARE(QMetaType(QMetaType::QString).id(), QMetaType::QString);
+ QCOMPARE(QMetaType(::qMetaTypeId<TestSpace::Foo>()).id(), ::qMetaTypeId<TestSpace::Foo>());
+}
+
void tst_QMetaType::qMetaTypeId()
{
QCOMPARE(::qMetaTypeId<QString>(), int(QMetaType::QString));
@@ -1814,13 +1821,6 @@ DECLARE_NONSTREAMABLE(void)
DECLARE_NONSTREAMABLE(void*)
DECLARE_NONSTREAMABLE(QModelIndex)
DECLARE_NONSTREAMABLE(QPersistentModelIndex)
-DECLARE_NONSTREAMABLE(QJsonValue)
-DECLARE_NONSTREAMABLE(QJsonObject)
-DECLARE_NONSTREAMABLE(QJsonArray)
-DECLARE_NONSTREAMABLE(QJsonDocument)
-DECLARE_NONSTREAMABLE(QCborValue)
-DECLARE_NONSTREAMABLE(QCborArray)
-DECLARE_NONSTREAMABLE(QCborMap)
DECLARE_NONSTREAMABLE(QObject*)
DECLARE_NONSTREAMABLE(QWidget*)
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 06254091cd..68a92ebcc3 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -285,104 +285,100 @@ static void playWithObjects()
void tst_QObject::disconnect()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
- connect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
- connect( s, SIGNAL(signal2()), r1, SLOT(slot2()) );
- connect( s, SIGNAL(signal3()), r1, SLOT(slot3()) );
- connect( s, SIGNAL(signal4()), r1, SLOT(slot4()) );
+ connect(&s, SIGNAL(signal2()), &r1, SLOT(slot2()));
+ connect(&s, SIGNAL(signal3()), &r1, SLOT(slot3()));
+ connect(&s, SIGNAL(signal4()), &r1, SLOT(slot4()));
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
- QVERIFY(r1->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(r1.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// usual disconnect with all parameters given
- bool ret = QObject::disconnect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
+ bool ret = QObject::disconnect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
- s->emitSignal1();
+ s.emitSignal1();
- QVERIFY(!r1->called(1));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ r1.reset();
QVERIFY(ret);
- ret = QObject::disconnect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
+ ret = QObject::disconnect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
QVERIFY(!ret);
// disconnect all signals from s from all slots from r1
- QObject::disconnect( s, 0, r1, 0 );
+ QObject::disconnect(&s, 0, &r1, 0);
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(!r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(!r1.called(4));
+ r1.reset();
- connect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
- connect( s, SIGNAL(signal1()), r1, SLOT(slot2()) );
- connect( s, SIGNAL(signal1()), r1, SLOT(slot3()) );
- connect( s, SIGNAL(signal2()), r1, SLOT(slot4()) );
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot2()));
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot3()));
+ connect(&s, SIGNAL(signal2()), &r1, SLOT(slot4()));
// disconnect s's signal1() from all slots of r1
- QObject::disconnect( s, SIGNAL(signal1()), r1, 0 );
+ QObject::disconnect(&s, SIGNAL(signal1()), &r1, 0);
- s->emitSignal1();
- s->emitSignal2();
+ s.emitSignal1();
+ s.emitSignal2();
- QVERIFY(!r1->called(1));
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// make sure all is disconnected again
- QObject::disconnect( s, 0, r1, 0 );
+ QObject::disconnect(&s, 0, &r1, 0);
- connect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
- connect( s, SIGNAL(signal1()), r2, SLOT(slot1()) );
- connect( s, SIGNAL(signal2()), r1, SLOT(slot2()) );
- connect( s, SIGNAL(signal2()), r2, SLOT(slot2()) );
- connect( s, SIGNAL(signal3()), r1, SLOT(slot3()) );
- connect( s, SIGNAL(signal3()), r2, SLOT(slot3()) );
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
+ connect(&s, SIGNAL(signal1()), &r2, SLOT(slot1()));
+ connect(&s, SIGNAL(signal2()), &r1, SLOT(slot2()));
+ connect(&s, SIGNAL(signal2()), &r2, SLOT(slot2()));
+ connect(&s, SIGNAL(signal3()), &r1, SLOT(slot3()));
+ connect(&s, SIGNAL(signal3()), &r2, SLOT(slot3()));
// disconnect signal1() from all receivers
- QObject::disconnect( s, SIGNAL(signal1()), 0, 0 );
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
+ QObject::disconnect(&s, SIGNAL(signal1()), 0, 0);
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
- QVERIFY(!r1->called(1));
- QVERIFY(!r2->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r2.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
// disconnect all signals of s from all receivers
- QObject::disconnect( s, 0, 0, 0 );
+ QObject::disconnect(&s, 0, 0, 0);
- QVERIFY(!r1->called(2));
- QVERIFY(!r2->called(2));
- QVERIFY(!r1->called(2));
- QVERIFY(!r2->called(2));
-
- delete r2;
- delete r1;
- delete s;
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r2.called(2));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r2.called(2));
}
class AutoConnectSender : public QObject
@@ -798,192 +794,197 @@ void tst_QObject::connectDisconnectNotify_data()
void tst_QObject::connectDisconnectNotify()
{
- NotifyObject *s = new NotifyObject;
- NotifyObject *r = new NotifyObject;
+ NotifyObject s;
+ NotifyObject r;
QFETCH(QString, a_signal);
QFETCH(QString, a_slot);
// Obtaining meta methods
- int signalIndx = ((SenderObject*)s)->metaObject()->indexOfSignal(
+ int signalIndx = ((SenderObject &)s).metaObject()->indexOfSignal(
QMetaObject::normalizedSignature(a_signal.toLatin1().constData()+1).constData());
- int methodIndx = ((ReceiverObject*)r)->metaObject()->indexOfMethod(
+ int methodIndx = ((ReceiverObject &)r).metaObject()->indexOfMethod(
QMetaObject::normalizedSignature(a_slot.toLatin1().constData()+1).constData());
- QMetaMethod signal = ((SenderObject*)s)->metaObject()->method(signalIndx);
- QMetaMethod method = ((ReceiverObject*)r)->metaObject()->method(methodIndx);
+ QMetaMethod signal = ((SenderObject &)s).metaObject()->method(signalIndx);
+ QMetaMethod method = ((ReceiverObject &)r).metaObject()->method(methodIndx);
QVERIFY(signal.isValid());
QVERIFY(method.isValid());
// Test connectNotify
- QVERIFY(QObject::connect((SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1()));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ QVERIFY(QObject::connect((SenderObject *)&s, a_signal.toLatin1(),
+ (ReceiverObject *)&r, a_slot.toLatin1()));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify
- QVERIFY(QObject::disconnect((SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1()));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, a_signal.toLatin1(),
+ (ReceiverObject *)&r, a_slot.toLatin1()));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
// Reconnect
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1()));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, a_signal.toLatin1(),
+ (ReceiverObject *)&r, a_slot.toLatin1()));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify for a complete disconnect
- QVERIFY(((SenderObject*)s)->disconnect((ReceiverObject*)r));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod());
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(((SenderObject *)&s)->disconnect((ReceiverObject *)&r));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod());
+ QCOMPARE(s.connectedSignals.size(), 1);
// Test connectNotify when connecting by QMetaMethod
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, signal, (ReceiverObject*)r, method));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, signal, (ReceiverObject *)&r, method));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify when disconnecting by QMetaMethod
- QVERIFY(QObject::disconnect((SenderObject*)s, signal, (ReceiverObject*)r, method));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, signal, (ReceiverObject *)&r, method));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
// Reconnect
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1()));
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, a_signal.toLatin1(),
+ (ReceiverObject *)&r, a_slot.toLatin1()));
// Test disconnectNotify for a complete disconnect by QMetaMethod
- QVERIFY(QObject::disconnect((SenderObject*)s, QMetaMethod(), 0, QMetaMethod()));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod());
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, QMetaMethod(), 0, QMetaMethod()));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod());
+ QCOMPARE(s.connectedSignals.size(), 1);
// Test connectNotify when connecting by index
- s->clearNotifications();
- QVERIFY(QMetaObject::connect((SenderObject*)s, signalIndx, (ReceiverObject*)r, methodIndx));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ s.clearNotifications();
+ QVERIFY(QMetaObject::connect((SenderObject *)&s, signalIndx, (ReceiverObject *)&r, methodIndx));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify when disconnecting by index
- QVERIFY(QMetaObject::disconnect((SenderObject*)s, signalIndx, (ReceiverObject*)r, methodIndx));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
-
- delete s;
- delete r;
+ QVERIFY(QMetaObject::disconnect((SenderObject *)&s, signalIndx,
+ (ReceiverObject *)&r, methodIndx));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
}
static void connectDisconnectNotifyTestSlot() {}
void tst_QObject::connectDisconnectNotifyPMF()
{
- NotifyObject *s = new NotifyObject;
- NotifyObject *r = new NotifyObject;
+ NotifyObject s;
+ NotifyObject r;
QMetaMethod signal = QMetaMethod::fromSignal(&SenderObject::signal1);
// Test connectNotify
- QVERIFY(QObject::connect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, &ReceiverObject::slot1));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ QVERIFY(QObject::connect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, &ReceiverObject::slot1));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify
- QVERIFY(QObject::disconnect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, &ReceiverObject::slot1));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, &ReceiverObject::slot1));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
// Reconnect
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, &ReceiverObject::slot1));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, &ReceiverObject::slot1));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify with wildcard slot
- QVERIFY(QObject::disconnect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, 0));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, 0));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
// Reconnect
- s->clearNotifications();
- QMetaObject::Connection conn = connect((SenderObject*)s, &SenderObject::signal1,
- (ReceiverObject*)r, &ReceiverObject::slot1);
+ s.clearNotifications();
+ QMetaObject::Connection conn = connect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, &ReceiverObject::slot1);
QVERIFY(conn);
// Test disconnectNotify when disconnecting by QMetaObject::Connection
QVERIFY(QObject::disconnect(conn));
- QVERIFY(!s->disconnectedSignals.isEmpty());
+ QVERIFY(!s.disconnectedSignals.isEmpty());
// Test connectNotify when connecting by function pointer
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, &SenderObject::signal1, connectDisconnectNotifyTestSlot));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
-
- delete s;
- delete r;
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, &SenderObject::signal1,
+ connectDisconnectNotifyTestSlot));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
}
void tst_QObject::disconnectNotify_receiverDestroyed()
{
- NotifyObject *s = new NotifyObject;
- NotifyObject *r = new NotifyObject;
-
- QVERIFY(QObject::connect((SenderObject*)s, SIGNAL(signal1()), (ReceiverObject*)r, SLOT(slot1())));
-
- delete r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal1));
+ NotifyObject s;
- s->disconnectedSignals.clear();
- r = new NotifyObject;
+ {
+ NotifyObject r;
+ QVERIFY(QObject::connect((SenderObject *)&s, SIGNAL(signal1()),
+ (ReceiverObject *)&r, SLOT(slot1())));
+ }
+ QCOMPARE(s.disconnectedSignals.count(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal1));
- QVERIFY(QObject::connect((SenderObject*)s, SIGNAL(signal3()), (ReceiverObject*)r, SLOT(slot3())));
+ s.disconnectedSignals.clear();
- delete r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal3));
+ {
+ NotifyObject r;
+ QVERIFY(QObject::connect((SenderObject *)&s, SIGNAL(signal3()),
+ (ReceiverObject *)&r, SLOT(slot3())));
+ }
- s->disconnectedSignals.clear();
- r = new NotifyObject;
+ QCOMPARE(s.disconnectedSignals.count(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal3));
- QVERIFY(QObject::connect((SenderObject*)s, SIGNAL(destroyed()), (ReceiverObject*)r, SLOT(slot3())));
+ s.disconnectedSignals.clear();
- delete r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod::fromSignal(&QObject::destroyed));
+ {
+ NotifyObject r;
+ QVERIFY(QObject::connect((SenderObject *)&s, SIGNAL(destroyed()), (ReceiverObject *)&r, SLOT(slot3())));
+ }
- delete s;
+ QCOMPARE(s.disconnectedSignals.count(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod::fromSignal(&QObject::destroyed));
}
void tst_QObject::disconnectNotify_metaObjConnection()
{
- NotifyObject *s = new NotifyObject;
- NotifyObject *r = new NotifyObject;
-
- QMetaObject::Connection c = QObject::connect((SenderObject*)s, SIGNAL(signal1()),
- (ReceiverObject*)r, SLOT(slot1()));
- QVERIFY(c);
- QVERIFY(QObject::disconnect(c));
+ NotifyObject s;
+ {
+ NotifyObject r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal1));
+ QMetaObject::Connection c = QObject::connect((SenderObject *)&s, SIGNAL(signal1()),
+ (ReceiverObject *)&r, SLOT(slot1()));
+ QVERIFY(c);
+ QVERIFY(QObject::disconnect(c));
- delete r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
+ QCOMPARE(s.disconnectedSignals.count(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal1));
- delete s;
+ QCOMPARE(s.disconnectedSignals.count(), 1);
+ }
}
class ConnectByNameNotifySenderObject : public QObject
@@ -3463,130 +3464,131 @@ void tst_QObject::qobjectConstCast()
void tst_QObject::uniqConnection()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
- r1->reset();
- r2->reset();
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, SIGNAL(signal1()), r1, SLOT(slot1()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal1()), r2, SLOT(slot1()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal1()), r1, SLOT(slot3()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal3()), r1, SLOT(slot3()) , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()) , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, SIGNAL(signal1()), &r2, SLOT(slot1()) , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, SIGNAL(signal1()), &r1, SLOT(slot3()) , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, SIGNAL(signal3()), &r1, SLOT(slot3()) , Qt::UniqueConnection) );
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 2 );
- QCOMPARE( r1->count_slot4, 0 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
- QCOMPARE( r2->count_slot4, 0 );
- QCOMPARE( r1->sequence_slot1, 1 );
- QCOMPARE( r2->sequence_slot1, 2 );
- QCOMPARE( r1->sequence_slot3, 4 );
-
- r1->reset();
- r2->reset();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 2);
+ QCOMPARE(r1.count_slot4, 0);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+ QCOMPARE(r2.count_slot4, 0);
+ QCOMPARE(r1.sequence_slot1, 1);
+ QCOMPARE(r2.sequence_slot1, 2);
+ QCOMPARE(r1.sequence_slot3, 4);
+
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, SIGNAL(signal4()), r1, SLOT(slot4()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal4()), r2, SLOT(slot4()) , Qt::UniqueConnection) );
- QVERIFY(!connect( s, SIGNAL(signal4()), r2, SLOT(slot4()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal1()), r2, SLOT(slot4()) , Qt::UniqueConnection) );
- QVERIFY(!connect( s, SIGNAL(signal4()), r1, SLOT(slot4()) , Qt::UniqueConnection) );
+ QVERIFY( connect(&s, SIGNAL(signal4()), &r1, SLOT(slot4()) , Qt::UniqueConnection));
+ QVERIFY( connect(&s, SIGNAL(signal4()), &r2, SLOT(slot4()) , Qt::UniqueConnection));
+ QVERIFY(!connect(&s, SIGNAL(signal4()), &r2, SLOT(slot4()) , Qt::UniqueConnection));
+ QVERIFY( connect(&s, SIGNAL(signal1()), &r2, SLOT(slot4()) , Qt::UniqueConnection));
+ QVERIFY(!connect(&s, SIGNAL(signal4()), &r1, SLOT(slot4()) , Qt::UniqueConnection));
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 1 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 1 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 1);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 1);
+ QCOMPARE(r2.sequence_slot4, 2);
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- connect( s, SIGNAL(signal4()), r1, SLOT(slot4()) );
-
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 2 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 3 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ connect(&s, SIGNAL(signal4()), &r1, SLOT(slot4()));
- delete s;
- delete r1;
- delete r2;
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 2);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 3);
+ QCOMPARE(r2.sequence_slot4, 2);
}
void tst_QObject::uniqConnectionPtr()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
- r1->reset();
- r2->reset();
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal1, r2, &ReceiverObject::slot1 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot3 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal3, r1, &ReceiverObject::slot3 , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1 ,
+ Qt::UniqueConnection));
+ QVERIFY(connect(&s, &SenderObject::signal1, &r2, &ReceiverObject::slot1 ,
+ Qt::UniqueConnection));
+ QVERIFY(connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot3 ,
+ Qt::UniqueConnection));
+ QVERIFY(connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot3 ,
+ Qt::UniqueConnection));
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 2 );
- QCOMPARE( r1->count_slot4, 0 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
- QCOMPARE( r2->count_slot4, 0 );
- QCOMPARE( r1->sequence_slot1, 1 );
- QCOMPARE( r2->sequence_slot1, 2 );
- QCOMPARE( r1->sequence_slot3, 4 );
-
- r1->reset();
- r2->reset();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 2);
+ QCOMPARE(r1.count_slot4, 0);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+ QCOMPARE(r2.count_slot4, 0);
+ QCOMPARE(r1.sequence_slot1, 1);
+ QCOMPARE(r2.sequence_slot1, 2);
+ QCOMPARE(r1.sequence_slot3, 4);
+
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal4, r2, &ReceiverObject::slot4 , Qt::UniqueConnection) );
- QVERIFY(!connect( s, &SenderObject::signal4, r2, &ReceiverObject::slot4 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal1, r2, &ReceiverObject::slot4 , Qt::UniqueConnection) );
- QVERIFY(!connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 , Qt::UniqueConnection) );
+ QVERIFY( connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
+ QVERIFY( connect(&s, &SenderObject::signal4, &r2, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
+ QVERIFY(!connect(&s, &SenderObject::signal4, &r2, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
+ QVERIFY( connect(&s, &SenderObject::signal1, &r2, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
+ QVERIFY(!connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 1 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 1 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 1);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 1);
+ QCOMPARE(r2.sequence_slot4, 2);
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 );
+ connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4);
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 2 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 3 );
- QCOMPARE( r2->sequence_slot4, 2 );
-
- delete s;
- delete r1;
- delete r2;
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 2);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 3);
+ QCOMPARE(r2.sequence_slot4, 2);
}
void tst_QObject::interfaceIid()
@@ -3890,217 +3892,214 @@ void tst_QObject::isSignalConnectedAfterDisconnection()
void tst_QObject::qMetaObjectConnect()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
- r1->reset();
- r2->reset();
- ReceiverObject::sequence = 0;
-
- int signal1Index = s->metaObject()->indexOfSignal("signal1()");
- int signal3Index = s->metaObject()->indexOfSignal("signal3()");
- int slot1Index = r1->metaObject()->indexOfSlot("slot1()");
- int slot2Index = r1->metaObject()->indexOfSlot("slot2()");
- int slot3Index = r1->metaObject()->indexOfSlot("slot3()");
-
- QVERIFY(slot1Index > 0);
- QVERIFY(slot2Index > 0);
- QVERIFY(slot3Index > 0);
-
- QVERIFY( QMetaObject::connect( s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::connect( s, signal3Index, r2, slot3Index) );
- QVERIFY( QMetaObject::connect( s, -1, r2, slot2Index) );
-
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
-
- s->emitSignal1();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 1 );
- QCOMPARE( r2->count_slot3, 0 );
-
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 4 );
- QCOMPARE( r2->count_slot3, 1 );
-
- QVERIFY( QMetaObject::disconnect( s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::disconnect( s, signal3Index, r2, slot3Index) );
- QVERIFY( QMetaObject::disconnect( s, -1, r2, slot2Index) );
-
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 4 );
- QCOMPARE( r2->count_slot3, 1 );
-
- //some "dynamic" signal
- QVERIFY( QMetaObject::connect( s, s->metaObject()->methodOffset() + 20, r1, slot3Index) );
- QVERIFY( QMetaObject::connect( s, s->metaObject()->methodOffset() + 35, r2, slot1Index) );
- QVERIFY( QMetaObject::connect( s, -1, r1, slot2Index) );
-
- r1->reset();
- r2->reset();
-
- void *args[] = { 0 , 0 };
- QMetaObject::activate(s, s->metaObject()->methodOffset() + 20, args);
- QMetaObject::activate(s, s->metaObject()->methodOffset() + 48, args);
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 2 );
- QCOMPARE( r1->count_slot3, 1 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
-
- QMetaObject::activate(s, s->metaObject()->methodOffset() + 35, args);
- s->emitSignal1();
- s->emitSignal2();
-
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 5 );
- QCOMPARE( r1->count_slot3, 1 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
+ ReceiverObject r1;
+ ReceiverObject r2;
+ int slot1Index, slot2Index, slot3Index;
+ {
+ SenderObject s;
+ r1.reset();
+ r2.reset();
+ ReceiverObject::sequence = 0;
+
+ int signal1Index = s.metaObject()->indexOfSignal("signal1()");
+ int signal3Index = s.metaObject()->indexOfSignal("signal3()");
+ slot1Index = r1.metaObject()->indexOfSlot("slot1()");
+ slot2Index = r1.metaObject()->indexOfSlot("slot2()");
+ slot3Index = r1.metaObject()->indexOfSlot("slot3()");
+
+ QVERIFY(slot1Index > 0);
+ QVERIFY(slot2Index > 0);
+ QVERIFY(slot3Index > 0);
+
+ QVERIFY(QMetaObject::connect(&s, signal1Index, &r1, slot1Index));
+ QVERIFY(QMetaObject::connect(&s, signal3Index, &r2, slot3Index));
+ QVERIFY(QMetaObject::connect(&s, -1, &r2, slot2Index));
+
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+
+ s.emitSignal1();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 1);
+ QCOMPARE(r2.count_slot3, 0);
+
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 4);
+ QCOMPARE(r2.count_slot3, 1);
+
+ QVERIFY(QMetaObject::disconnect(&s, signal1Index, &r1, slot1Index));
+ QVERIFY(QMetaObject::disconnect(&s, signal3Index, &r2, slot3Index));
+ QVERIFY(QMetaObject::disconnect(&s, -1, &r2, slot2Index));
+
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 4);
+ QCOMPARE(r2.count_slot3, 1);
+
+ //some "dynamic" signal
+ QVERIFY(QMetaObject::connect(&s, s.metaObject()->methodOffset() + 20, &r1, slot3Index));
+ QVERIFY(QMetaObject::connect(&s, s.metaObject()->methodOffset() + 35, &r2, slot1Index));
+ QVERIFY(QMetaObject::connect(&s, -1, &r1, slot2Index));
+
+ r1.reset();
+ r2.reset();
+
+ void *args[] = { 0 , 0 };
+ QMetaObject::activate(&s, s.metaObject()->methodOffset() + 20, args);
+ QMetaObject::activate(&s, s.metaObject()->methodOffset() + 48, args);
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 2);
+ QCOMPARE(r1.count_slot3, 1);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+
+ QMetaObject::activate(&s, s.metaObject()->methodOffset() + 35, args);
+ s.emitSignal1();
+ s.emitSignal2();
+
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 5);
+ QCOMPARE(r1.count_slot3, 1);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+ }
- delete s;
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
#define SIGNAL_INDEX(S) obj1.metaObject()->indexOfSignal(QMetaObject::normalizedSignature(#S))
OverloadObject obj1;
QObject obj2, obj3;
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int)) , r1, slot1Index);
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *)) , r2, slot1Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int)) , &r1, slot1Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *)) ,
+ &r2, slot1Index);
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *, QObject *)) , r1, slot2Index);
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *)) , r2, slot2Index);
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int, int)) , r1, slot3Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *, QObject *)) ,
+ &r1, slot2Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *)) , &r2, slot2Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int, int)) , &r1, slot3Index);
emit obj1.sig(0.5); //connected to nothing
emit obj1.sig(1, 'a'); //connected to nothing
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
emit obj1.sig(1); //this signal is connected
emit obj1.sig(&obj2);
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 1 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 1 );
- QCOMPARE( r2->count_slot3, 0 );
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 1);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 1);
+ QCOMPARE(r2.count_slot3, 0);
emit obj1.sig(&obj2, &obj3); //this signal is connected
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 1 );
- QCOMPARE( r1->count_slot3, 1 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 1 );
- QCOMPARE( r2->count_slot3, 0 );
-
- delete r1;
- delete r2;
-
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 1);
+ QCOMPARE(r1.count_slot3, 1);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 1);
+ QCOMPARE(r2.count_slot3, 0);
}
void tst_QObject::qMetaObjectDisconnectOne()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
+ SenderObject s;
+ ReceiverObject r1;
- int signal1Index = s->metaObject()->indexOfSignal("signal1()");
- int signal3Index = s->metaObject()->indexOfSignal("signal3()");
- int slot1Index = r1->metaObject()->indexOfSlot("slot1()");
- int slot2Index = r1->metaObject()->indexOfSlot("slot2()");
+ int signal1Index = s.metaObject()->indexOfSignal("signal1()");
+ int signal3Index = s.metaObject()->indexOfSignal("signal3()");
+ int slot1Index = r1.metaObject()->indexOfSlot("slot1()");
+ int slot2Index = r1.metaObject()->indexOfSlot("slot2()");
QVERIFY(signal1Index > 0);
QVERIFY(signal3Index > 0);
QVERIFY(slot1Index > 0);
QVERIFY(slot2Index > 0);
- QVERIFY( QMetaObject::connect(s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) );
- QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) );
- QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) );
-
- r1->reset();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ QVERIFY(QMetaObject::connect(&s, signal1Index, &r1, slot1Index));
+ QVERIFY(QMetaObject::connect(&s, signal3Index, &r1, slot2Index));
+ QVERIFY(QMetaObject::connect(&s, signal3Index, &r1, slot2Index));
+ QVERIFY(QMetaObject::connect(&s, signal3Index, &r1, slot2Index));
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 3 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
- r1->reset();
- QVERIFY( QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) );
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 3);
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QVERIFY(QMetaObject::disconnectOne(&s, signal1Index, &r1, slot1Index));
+ QVERIFY(QMetaObject::disconnectOne(&s, signal3Index, &r1, slot2Index));
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 2 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- r1->reset();
- QVERIFY( false == QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) );
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 2);
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QVERIFY(!QMetaObject::disconnectOne(&s, signal1Index, &r1, slot1Index));
+ QVERIFY( QMetaObject::disconnectOne(&s, signal3Index, &r1, slot2Index));
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 1 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- r1->reset();
- QVERIFY( false == QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) );
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 1);
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QVERIFY(!QMetaObject::disconnectOne(&s, signal1Index, &r1, slot1Index));
+ QVERIFY( QMetaObject::disconnectOne(&s, signal3Index, &r1, slot2Index));
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- delete s;
- delete r1;
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
}
class ConfusingObject : public SenderObject
@@ -4222,106 +4221,95 @@ void tst_QObject::connectConstructorByMetaMethod()
void tst_QObject::disconnectByMetaMethod()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
-
- QMetaMethod signal1 = s->metaObject()->method(
- s->metaObject()->indexOfMethod("signal1()"));
- QMetaMethod signal2 = s->metaObject()->method(
- s->metaObject()->indexOfMethod("signal2()"));
- QMetaMethod signal3 = s->metaObject()->method(
- s->metaObject()->indexOfMethod("signal3()"));
-
- QMetaMethod slot1 = r1->metaObject()->method(
- r1->metaObject()->indexOfMethod("slot1()"));
- QMetaMethod slot2 = r1->metaObject()->method(
- r1->metaObject()->indexOfMethod("slot2()"));
- QMetaMethod slot3 = r1->metaObject()->method(
- r1->metaObject()->indexOfMethod("slot3()"));
- QMetaMethod slot4 = r1->metaObject()->method(
- r1->metaObject()->indexOfMethod("slot4()"));
-
- connect(s, signal1, r1, slot1);
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
- s->emitSignal1();
+ QMetaMethod signal1 = s.metaObject()->method(s.metaObject()->indexOfMethod("signal1()"));
+ QMetaMethod signal2 = s.metaObject()->method(s.metaObject()->indexOfMethod("signal2()"));
+ QMetaMethod signal3 = s.metaObject()->method(s.metaObject()->indexOfMethod("signal3()"));
+
+ QMetaMethod slot1 = r1.metaObject()->method(r1.metaObject()->indexOfMethod("slot1()"));
+ QMetaMethod slot2 = r1.metaObject()->method(r1.metaObject()->indexOfMethod("slot2()"));
+ QMetaMethod slot3 = r1.metaObject()->method(r1.metaObject()->indexOfMethod("slot3()"));
+ QMetaMethod slot4 = r1.metaObject()->method(r1.metaObject()->indexOfMethod("slot4()"));
+
+ connect(&s, signal1, &r1, slot1);
- QVERIFY(r1->called(1));
- r1->reset();
+ s.emitSignal1();
+
+ QVERIFY(r1.called(1));
+ r1.reset();
// usual disconnect with all parameters given
- bool ret = QObject::disconnect(s, signal1, r1, slot1);
+ bool ret = QObject::disconnect(&s, signal1, &r1, slot1);
- s->emitSignal1();
+ s.emitSignal1();
- QVERIFY(!r1->called(1));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ r1.reset();
QVERIFY(ret);
- ret = QObject::disconnect(s, signal1, r1, slot1);
+ ret = QObject::disconnect(&s, signal1, &r1, slot1);
QVERIFY(!ret);
- r1->reset();
+ r1.reset();
- connect( s, signal1, r1, slot1 );
- connect( s, signal1, r1, slot2 );
- connect( s, signal1, r1, slot3 );
- connect( s, signal2, r1, slot4 );
+ connect(&s, signal1, &r1, slot1);
+ connect(&s, signal1, &r1, slot2);
+ connect(&s, signal1, &r1, slot3);
+ connect(&s, signal2, &r1, slot4);
// disconnect s's signal1() from all slots of r1
- QObject::disconnect(s, signal1, r1, QMetaMethod());
+ QObject::disconnect(&s, signal1, &r1, QMetaMethod());
- s->emitSignal1();
- s->emitSignal2();
+ s.emitSignal1();
+ s.emitSignal2();
- QVERIFY(!r1->called(1));
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// make sure all is disconnected again
- QObject::disconnect(s, 0, r1, 0);
+ QObject::disconnect(&s, 0, &r1, 0);
- connect(s, signal1, r1, slot1);
- connect(s, signal1, r2, slot1);
- connect(s, signal2, r1, slot2);
- connect(s, signal2, r2, slot2);
- connect(s, signal3, r1, slot3);
- connect(s, signal3, r2, slot3);
+ connect(&s, signal1, &r1, slot1);
+ connect(&s, signal1, &r2, slot1);
+ connect(&s, signal2, &r1, slot2);
+ connect(&s, signal2, &r2, slot2);
+ connect(&s, signal3, &r1, slot3);
+ connect(&s, signal3, &r2, slot3);
// disconnect signal1() from all receivers
- QObject::disconnect(s, signal1, 0, QMetaMethod());
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
+ QObject::disconnect(&s, signal1, 0, QMetaMethod());
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
- QVERIFY(!r1->called(1));
- QVERIFY(!r2->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r2.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
// disconnect all signals of s from all receivers
- QObject::disconnect( s, 0, 0, 0 );
+ QObject::disconnect(&s, 0, 0, 0);
- connect( s, signal1, r1, slot1 );
- connect( s, signal1, r2, slot1 );
+ connect(&s, signal1, &r1, slot1);
+ connect(&s, signal1, &r2, slot1);
// disconnect all signals from slot1 of r1
- QObject::disconnect(s, QMetaMethod(), r1, slot1);
+ QObject::disconnect(&s, QMetaMethod(), &r1, slot1);
- s->emitSignal1();
-
- QVERIFY(!r1->called(1));
- QVERIFY(r2->called(1));
+ s.emitSignal1();
- delete r2;
- delete r1;
- delete s;
+ QVERIFY(!r1.called(1));
+ QVERIFY(r2.called(1));
}
void tst_QObject::disconnectNotSignalMetaMethod()
@@ -4459,63 +4447,64 @@ void tst_QObject::baseDestroyed()
void tst_QObject::pointerConnect()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
- r1->reset();
- r2->reset();
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
QTimer timer;
- QVERIFY( connect( s, &SenderObject::signal1 , r1, &ReceiverObject::slot1 ) );
- QVERIFY( connect( s, &SenderObject::signal1 , r2, &ReceiverObject::slot1 ) );
- QVERIFY( connect( s, &SenderObject::signal1 , r1, &ReceiverObject::slot3 ) );
- QVERIFY( connect( s, &SenderObject::signal3 , r1, &ReceiverObject::slot3 ) );
- QVERIFY2( connect( &timer, &QTimer::timeout, r1, &ReceiverObject::deleteLater ),
- "Signal connection failed most likely due to failing comparison of pointers to member functions caused by problems with -reduce-relocations on this platform.");
+ QVERIFY(connect(&s, &SenderObject::signal1 , &r1, &ReceiverObject::slot1));
+ QVERIFY(connect(&s, &SenderObject::signal1 , &r2, &ReceiverObject::slot1));
+ QVERIFY(connect(&s, &SenderObject::signal1 , &r1, &ReceiverObject::slot3));
+ QVERIFY(connect(&s, &SenderObject::signal3 , &r1, &ReceiverObject::slot3));
+ QVERIFY2(connect(&timer, &QTimer::timeout, &r1, &ReceiverObject::deleteLater),
+ "Signal connection failed most likely due to failing comparison of pointers to member "
+ "functions caused by problems with -reduce-relocations on this platform.");
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 2 );
- QCOMPARE( r1->count_slot4, 0 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
- QCOMPARE( r2->count_slot4, 0 );
- QCOMPARE( r1->sequence_slot1, 1 );
- QCOMPARE( r2->sequence_slot1, 2 );
- QCOMPARE( r1->sequence_slot3, 4 );
-
- r1->reset();
- r2->reset();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 2);
+ QCOMPARE(r1.count_slot4, 0);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+ QCOMPARE(r2.count_slot4, 0);
+ QCOMPARE(r1.sequence_slot1, 1);
+ QCOMPARE(r2.sequence_slot1, 2);
+ QCOMPARE(r1.sequence_slot3, 4);
+
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 ) );
- QVERIFY( connect( s, &SenderObject::signal4, r2, &ReceiverObject::slot4 ) );
- QVERIFY( connect( s, &SenderObject::signal1, r2, &ReceiverObject::slot4 ) );
+ QVERIFY(connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4));
+ QVERIFY(connect(&s, &SenderObject::signal4, &r2, &ReceiverObject::slot4));
+ QVERIFY(connect(&s, &SenderObject::signal1, &r2, &ReceiverObject::slot4));
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 1 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 1 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 1);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 1);
+ QCOMPARE(r2.sequence_slot4, 2);
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- connect( s, &SenderObject::signal4 , r1, &ReceiverObject::slot4 );
+ connect(&s, &SenderObject::signal4 , &r1, &ReceiverObject::slot4);
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 2 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 3 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 2);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 3);
+ QCOMPARE(r2.sequence_slot4, 2);
QMetaObject::Connection con;
QVERIFY(!con);
@@ -4523,116 +4512,107 @@ void tst_QObject::pointerConnect()
//connect a slot to a signal (== error)
QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in ReceiverObject");
- con = connect(r1, &ReceiverObject::slot4 , s, &SenderObject::signal4 );
+ con = connect(&r1, &ReceiverObject::slot4 , &s, &SenderObject::signal4);
QVERIFY(!con);
QVERIFY(!QObject::disconnect(con));
-
- delete s;
- delete r1;
- delete r2;
}
void tst_QObject::pointerDisconnect()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
- connect( s, &SenderObject::signal2, r1, &ReceiverObject::slot2 );
- connect( s, &SenderObject::signal3, r1, &ReceiverObject::slot3 );
- connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 );
+ connect(&s, &SenderObject::signal2, &r1, &ReceiverObject::slot2);
+ connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot3);
+ connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4);
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
- QVERIFY(r1->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(r1.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// usual disconnect with all parameters given
- bool ret = QObject::disconnect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
+ bool ret = QObject::disconnect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
- s->emitSignal1();
+ s.emitSignal1();
- QVERIFY(!r1->called(1));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ r1.reset();
QVERIFY(ret);
- ret = QObject::disconnect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
+ ret = QObject::disconnect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
QVERIFY(!ret);
// disconnect all signals from s from all slots from r1
- QObject::disconnect( s, 0, r1, 0 );
+ QObject::disconnect(&s, 0, &r1, 0);
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(!r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(!r1.called(4));
+ r1.reset();
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot2 );
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot3 );
- connect( s, &SenderObject::signal2, r1, &ReceiverObject::slot4 );
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot2);
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot3);
+ connect(&s, &SenderObject::signal2, &r1, &ReceiverObject::slot4);
// disconnect s's signal1() from all slots of r1
- QObject::disconnect( s, &SenderObject::signal1, r1, 0 );
+ QObject::disconnect(&s, &SenderObject::signal1, &r1, 0);
- s->emitSignal1();
- s->emitSignal2();
+ s.emitSignal1();
+ s.emitSignal2();
- QVERIFY(!r1->called(1));
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// make sure all is disconnected again
- QObject::disconnect( s, 0, r1, 0 );
+ QObject::disconnect(&s, 0, &r1, 0);
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
- connect( s, &SenderObject::signal1, r2, &ReceiverObject::slot1 );
- connect( s, &SenderObject::signal2, r1, &ReceiverObject::slot2 );
- connect( s, &SenderObject::signal2, r2, &ReceiverObject::slot2 );
- connect( s, &SenderObject::signal3, r1, &ReceiverObject::slot3 );
- connect( s, &SenderObject::signal3, r2, &ReceiverObject::slot3 );
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
+ connect(&s, &SenderObject::signal1, &r2, &ReceiverObject::slot1);
+ connect(&s, &SenderObject::signal2, &r1, &ReceiverObject::slot2);
+ connect(&s, &SenderObject::signal2, &r2, &ReceiverObject::slot2);
+ connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot3);
+ connect(&s, &SenderObject::signal3, &r2, &ReceiverObject::slot3);
// disconnect signal1() from all receivers
- QObject::disconnect( s, &SenderObject::signal1, 0, 0 );
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
+ QObject::disconnect(&s, &SenderObject::signal1, 0, 0);
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
- QVERIFY(!r1->called(1));
- QVERIFY(!r2->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r2.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
// disconnect all signals of s from all receivers
- QObject::disconnect( s, 0, 0, 0 );
-
- QVERIFY(!r1->called(2));
- QVERIFY(!r2->called(2));
- QVERIFY(!r1->called(2));
- QVERIFY(!r2->called(2));
-
- delete r2;
- delete r1;
- delete s;
+ QObject::disconnect(&s, 0, 0, 0);
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r2.called(2));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r2.called(2));
}
@@ -4756,35 +4736,32 @@ void tst_QObject::customTypesPointer()
void tst_QObject::connectCxx0x()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
+ SenderObject s;
+ ReceiverObject r1;
- QObject::connect(s, &SenderObject::signal1, r1, &ReceiverObject::slot1);
- QObject::connect(s, &SenderObject::signal3, r1, &ReceiverObject::slot2);
- QObject::connect(s, &SenderObject::signal3, r1, &ReceiverObject::slot2);
- QObject::connect(s, &SenderObject::signal3, r1, &ReceiverObject::slot2);
+ QObject::connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
+ QObject::connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot2);
+ QObject::connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot2);
+ QObject::connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot2);
- r1->reset();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 3 );
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 3);
// connect signal to signal
- QObject::connect(s, &SenderObject::signal2, s, &SenderObject::signal1);
+ QObject::connect(&s, &SenderObject::signal2, &s, &SenderObject::signal1);
- r1->reset();
- s->emitSignal2();
- QCOMPARE( r1->count_slot1, 1 );
-
- delete s;
- delete r1;
+ r1.reset();
+ s.emitSignal2();
+ QCOMPARE(r1.count_slot1, 1);
}
int receivedCount;
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
index 9df52887f7..fd3cc18af5 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
@@ -73,12 +73,12 @@ static inline QString testSuiteWarning()
str << "\nCannot find the shared-mime-info test suite\nstarting from: "
<< QDir::toNativeSeparators(QDir::currentPath()) << "\n"
"cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-8.zip\n"
- "unzip Release-1-8.zip\n";
+ "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n"
+ "unzip Release-1-10.zip\n";
#ifdef Q_OS_WIN
- str << "mkdir testfiles\nxcopy /s Release-1-8 s-m-i\n";
+ str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n";
#else
- str << "ln -s Release-1-8 s-m-i\n";
+ str << "ln -s Release-1-10 s-m-i\n";
#endif
return result;
}
@@ -611,7 +611,7 @@ void tst_QMimeDatabase::allMimeTypes()
QVERIFY(!lst.isEmpty());
// Hardcoding this is the only way to check both providers find the same number of mimetypes.
- QCOMPARE(lst.count(), 749);
+ QCOMPARE(lst.count(), 779);
foreach (const QMimeType &mime, lst) {
const QString name = mime.name();
@@ -640,7 +640,7 @@ void tst_QMimeDatabase::suffixes_data()
QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
QTest::newRow("mimetype with uncommon pattern") << "text/x-readme" << "README*" << QString();
QTest::newRow("mimetype with no patterns") << "application/x-ole-storage" << QString() << QString();
- QTest::newRow("default_mimetype") << "application/octet-stream" << "*.bin" << QString();
+ QTest::newRow("default_mimetype") << "application/octet-stream" << QString() << QString();
}
void tst_QMimeDatabase::suffixes()
diff --git a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
index 541e73636c..5efe68f4af 100644
--- a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
@@ -3,6 +3,7 @@ TEMPLATE = subdirs
tst.depends = lib theplugin
SUBDIRS = lib \
+ staticplugin \
theplugin \
tst
!android:!win32:!darwin {
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore b/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore
new file mode 100644
index 0000000000..26f7ecd506
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore
@@ -0,0 +1,3 @@
+*staticplugin.prl
+libstaticplugin.a
+staticplugin.lib
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp b/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp
new file mode 100644
index 0000000000..d891839b1e
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** 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 <QtPlugin>
+#include <QObject>
+
+class StaticPlugin : public QObject
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "SomeIID")
+public:
+ StaticPlugin() {}
+};
+
+#include "main.moc"
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/staticplugin.pro b/tests/auto/corelib/plugin/qpluginloader/staticplugin/staticplugin.pro
new file mode 100644
index 0000000000..ff65ab728c
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/staticplugin.pro
@@ -0,0 +1,7 @@
+TEMPLATE = lib
+CONFIG += plugin static
+SOURCES = main.cpp
+QT = core
+
+# Add extra metadata to the plugin
+QMAKE_MOC_OPTIONS += -M ExtraMetaData=StaticPlugin -M ExtraMetaData=foo
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
index c20e56ba4c..a3885f4134 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
@@ -8,9 +8,14 @@ HEADERS = ../theplugin/plugininterface.h
win32 {
CONFIG(debug, debug|release) {
TARGET = ../../debug/tst_qpluginloader
+ LIBS += -L../staticplugin/debug
} else {
TARGET = ../../release/tst_qpluginloader
+ LIBS += -L../staticplugin/release
}
+} else {
+ LIBS += -L../staticplugin
}
+LIBS += -lstaticplugin
TESTDATA += ../elftest ../machtest
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index c517c0809a..4316ea14ea 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -121,8 +121,11 @@ private slots:
void reloadPlugin();
void preloadedPlugin_data();
void preloadedPlugin();
+ void staticPlugins();
};
+Q_IMPORT_PLUGIN(StaticPlugin)
+
void tst_QPluginLoader::cleanup()
{
// check if the library/plugin was leaked
@@ -520,5 +523,37 @@ void tst_QPluginLoader::preloadedPlugin()
QVERIFY(lib.unload());
}
+void tst_QPluginLoader::staticPlugins()
+{
+ const QObjectList instances = QPluginLoader::staticInstances();
+ QVERIFY(instances.size());
+
+ bool found = false;
+ for (QObject *obj : instances) {
+ found = obj->metaObject()->className() == QLatin1String("StaticPlugin");
+ if (found)
+ break;
+ }
+ QVERIFY(found);
+
+ const auto plugins = QPluginLoader::staticPlugins();
+ QCOMPARE(plugins.size(), instances.size());
+
+ // find the metadata
+ QJsonObject metaData;
+ for (const auto &p : plugins) {
+ metaData = p.metaData();
+ found = metaData.value("className").toString() == QLatin1String("StaticPlugin");
+ if (found)
+ break;
+ }
+ QVERIFY(found);
+
+ QCOMPARE(metaData.value("version").toInt(), QT_VERSION);
+ QCOMPARE(metaData.value("IID").toString(), "SomeIID");
+ QCOMPARE(metaData.value("ExtraMetaData"), QJsonArray({ "StaticPlugin", "foo" }));
+}
+
+
QTEST_MAIN(tst_QPluginLoader)
#include "tst_qpluginloader.moc"
diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp
index 4651258ef3..083e78375a 100644
--- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp
@@ -153,6 +153,17 @@ private Q_SLOTS:
void implicitValueType();
void implicitDocumentType();
+ void streamSerializationQJsonDocument_data();
+ void streamSerializationQJsonDocument();
+ void streamSerializationQJsonArray_data();
+ void streamSerializationQJsonArray();
+ void streamSerializationQJsonObject_data();
+ void streamSerializationQJsonObject();
+ void streamSerializationQJsonValue_data();
+ void streamSerializationQJsonValue();
+ void streamSerializationQJsonValueEmpty();
+ void streamVariantSerialization();
+
private:
QString testDataDir;
};
@@ -3011,5 +3022,164 @@ void tst_QtJson::implicitDocumentType()
QCOMPARE(arrayDocument[-1].toInt(123), 123);
}
+void tst_QtJson::streamSerializationQJsonDocument_data()
+{
+ QTest::addColumn<QJsonDocument>("document");
+ QTest::newRow("empty") << QJsonDocument();
+ QTest::newRow("object") << QJsonDocument(QJsonObject{{"value", 42}});
+}
+
+void tst_QtJson::streamSerializationQJsonDocument()
+{
+ // Check interface only, implementation is tested through to and from
+ // json functions.
+ QByteArray buffer;
+ QFETCH(QJsonDocument, document);
+ QJsonDocument output;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << document;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output, document);
+}
+
+void tst_QtJson::streamSerializationQJsonArray_data()
+{
+ QTest::addColumn<QJsonArray>("array");
+ QTest::newRow("empty") << QJsonArray();
+ QTest::newRow("values") << QJsonArray{665, 666, 667};
+}
+
+void tst_QtJson::streamSerializationQJsonArray()
+{
+ // Check interface only, implementation is tested through to and from
+ // json functions.
+ QByteArray buffer;
+ QFETCH(QJsonArray, array);
+ QJsonArray output;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << array;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output, array);
+}
+
+void tst_QtJson::streamSerializationQJsonObject_data()
+{
+ QTest::addColumn<QJsonObject>("object");
+ QTest::newRow("empty") << QJsonObject();
+ QTest::newRow("non-empty") << QJsonObject{{"foo", 665}, {"bar", 666}};
+}
+
+void tst_QtJson::streamSerializationQJsonObject()
+{
+ // Check interface only, implementation is tested through to and from
+ // json functions.
+ QByteArray buffer;
+ QFETCH(QJsonObject, object);
+ QJsonObject output;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << object;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output, object);
+}
+
+void tst_QtJson::streamSerializationQJsonValue_data()
+{
+ QTest::addColumn<QJsonValue>("value");
+ QTest::newRow("double") << QJsonValue{665};
+ QTest::newRow("bool") << QJsonValue{true};
+ QTest::newRow("string") << QJsonValue{QStringLiteral("bum")};
+ QTest::newRow("array") << QJsonValue{QJsonArray{12,1,5,6,7}};
+ QTest::newRow("object") << QJsonValue{QJsonObject{{"foo", 665}, {"bar", 666}}};
+}
+
+void tst_QtJson::streamSerializationQJsonValue()
+{
+ QByteArray buffer;
+ QFETCH(QJsonValue, value);
+ QJsonValue output;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << value;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output, value);
+}
+
+void tst_QtJson::streamSerializationQJsonValueEmpty()
+{
+ QByteArray buffer;
+ {
+ QJsonValue undef{QJsonValue::Undefined};
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << undef;
+ QDataStream load(buffer);
+ QJsonValue output;
+ load >> output;
+ QVERIFY(output.isUndefined());
+ }
+ {
+ QJsonValue null{QJsonValue::Null};
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << null;
+ QDataStream load(buffer);
+ QJsonValue output;
+ load >> output;
+ QVERIFY(output.isNull());
+ }
+}
+
+void tst_QtJson::streamVariantSerialization()
+{
+ // Check interface only, implementation is tested through to and from
+ // json functions.
+ QByteArray buffer;
+ {
+ QJsonDocument objectDoc(QJsonArray{665, 666, 667});
+ QVariant output;
+ QVariant variant(objectDoc);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QJsonDocument);
+ QCOMPARE(output.toJsonDocument(), objectDoc);
+ }
+ {
+ QJsonArray array{665, 666, 667};
+ QVariant output;
+ QVariant variant(array);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QJsonArray);
+ QCOMPARE(output.toJsonArray(), array);
+ }
+ {
+ QJsonObject obj{{"foo", 42}};
+ QVariant output;
+ QVariant variant(obj);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QJsonObject);
+ QCOMPARE(output.toJsonObject(), obj);
+ }
+ {
+ QJsonValue value{42};
+ QVariant output;
+ QVariant variant(value);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QJsonValue);
+ QCOMPARE(output.toJsonValue(), value);
+ }
+}
+
QTEST_MAIN(tst_QtJson)
#include "tst_qtjson.moc"
diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
index 4b753eab6b..f69ce4120d 100644
--- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
@@ -97,6 +97,10 @@ private slots:
void validation();
void toDiagnosticNotation_data();
void toDiagnosticNotation();
+
+ void datastreamSerialization_data();
+ void datastreamSerialization();
+ void streamVariantSerialization();
};
// Get the validation data from TinyCBOR (see src/3rdparty/tinycbor/tests/parser/data.cpp)
@@ -380,11 +384,17 @@ void tst_QCborValue::arrayDefaultInitialization()
QVERIFY(v.isArray());
QVERIFY(!v.isMap());
QVERIFY(!v.isTag());
- QVERIFY(v[0].isUndefined());
QCborArray a2 = v.toArray();
QVERIFY(a2.isEmpty());
QCOMPARE(a2, a);
+ auto front = v[0];
+ QVERIFY(front.isUndefined());
+ front = 1;
+ QCOMPARE(v[0], 1);
+ QVERIFY(a2.isEmpty());
+ a2 = v.toArray();
+ QCOMPARE(a2.size(), 1);
}
void tst_QCborValue::mapDefaultInitialization()
@@ -421,7 +431,7 @@ void tst_QCborValue::mapDefaultInitialization()
QVERIFY(m == QCborMap{});
QVERIFY(QCborMap{} == m);
- QCborValue v(m);
+ const QCborValue v(m);
QVERIFY(v.isMap());
QVERIFY(!v.isArray());
QVERIFY(!v.isTag());
@@ -723,6 +733,31 @@ void tst_QCborValue::arrayMutation()
QCOMPARE(a.at(1), QCborValue(-1));
QCOMPARE(a2.at(1), QCborValue(nullptr));
QCOMPARE(++it, end);
+
+ // Array accessed via value:
+ QCborValue val(a);
+ val[2] = QCborArray{2, 3, 5, 7};
+ QCOMPARE(a.size(), 2); // Unchanged
+ QVERIFY(val.isArray());
+ QCOMPARE(val.toArray().size(), 3);
+ val[2][4] = 17;
+ QVERIFY(val.isArray());
+ QVERIFY(val[2].isArray());
+ QCOMPARE(val[2].toArray().size(), 5);
+ QCOMPARE(val[2][4], 17);
+ QCOMPARE(val.toArray().size(), 3);
+ val[3] = 42;
+ QVERIFY(val.isArray());
+ QCOMPARE(val.toArray().size(), 4);
+ QCOMPARE(val[3], 42);
+
+ // Coerce to map on string key:
+ const QLatin1String any("any");
+ val[any] = any;
+ QVERIFY(val.isMap());
+ QCOMPARE(val.toMap().size(), 5);
+ QVERIFY(val[2].isArray());
+ QCOMPARE(val[2].toArray().size(), 5);
}
void tst_QCborValue::mapMutation()
@@ -778,6 +813,30 @@ void tst_QCborValue::mapMutation()
QCOMPARE((m.end() - 1)->toInteger(), -1);
QVERIFY((m2.end() - 1)->isNull());
QCOMPARE(++it, end);
+
+ // Map accessed via value:
+ QCborValue val(m);
+ val[7] = QCborMap({{0, 2}, {1, 3}, {2, 5}});
+ QCOMPARE(m.size(), 2); // Unchanged
+ QVERIFY(val.isMap());
+ QCOMPARE(val.toMap().size(), 3);
+ val[7][3] = 11;
+ QVERIFY(val.isMap());
+ QVERIFY(val[7].isMap());
+ QCOMPARE(val[7].toMap().size(), 4);
+ val[14] = 42;
+ QVERIFY(val.isMap());
+ QCOMPARE(val.toMap().size(), 4);
+
+ const QLatin1String any("any");
+ const QString hello(QStringLiteral("Hello World"));
+ val[any][3][hello] = any;
+ QVERIFY(val.isMap());
+ QCOMPARE(val.toMap().size(), 5);
+ QVERIFY(val[any].isMap());
+ QCOMPARE(val[any].toMap().size(), 1);
+ QVERIFY(val[any][3].isMap());
+ QCOMPARE(val[any][3].toMap().size(), 1);
}
void tst_QCborValue::arrayPrepend()
@@ -1690,6 +1749,83 @@ void tst_QCborValue::toDiagnosticNotation()
QCOMPARE(result, expected);
}
+
+void tst_QCborValue::datastreamSerialization_data()
+{
+ addCommonCborData();
+}
+
+void tst_QCborValue::datastreamSerialization()
+{
+ QFETCH(QCborValue, v);
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << v;
+ QDataStream load(buffer);
+ QCborValue output;
+ load >> output;
+ QCOMPARE(output, v);
+ }
+ if (v.isArray()) {
+ QCborArray array = v.toArray();
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << array;
+ QDataStream load(buffer);
+ QCborValue output;
+ load >> output;
+ QCOMPARE(output, array);
+ } else if (v.isMap()) {
+ QCborMap map = v.toMap();
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << map;
+ QDataStream load(buffer);
+ QCborValue output;
+ load >> output;
+ QCOMPARE(output, map);
+ }
+}
+
+void tst_QCborValue::streamVariantSerialization()
+{
+ // Check interface only, implementation is tested through to and from
+ // cbor functions.
+ QByteArray buffer;
+ {
+ QCborArray array{665, 666, 667};
+ QVariant output;
+ QVariant variant = QVariant::fromValue(array);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QCborArray);
+ QCOMPARE(qvariant_cast<QCborArray>(output), array);
+ }
+ {
+ QCborMap obj{{"foo", 42}};
+ QVariant output;
+ QVariant variant = QVariant::fromValue(obj);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QCborMap);
+ QCOMPARE(qvariant_cast<QCborMap>(output), obj);
+ }
+ {
+ QCborValue value{42};
+ QVariant output;
+ QVariant variant = QVariant::fromValue(value);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QCborValue);
+ QCOMPARE(qvariant_cast<QCborValue>(output), value);
+ }
+}
+
QTEST_MAIN(tst_QCborValue)
#include "tst_qcborvalue.moc"
diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
index 011a0e1a85..d204727bbd 100644
--- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
+++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
@@ -135,6 +135,15 @@ private slots:
void stream_QByteArray2();
+ void stream_QJsonDocument();
+ void stream_QJsonArray();
+ void stream_QJsonObject();
+ void stream_QJsonValue();
+
+ void stream_QCborArray();
+ void stream_QCborMap();
+ void stream_QCborValue();
+
void setVersion_data();
void setVersion();
@@ -2095,6 +2104,138 @@ void tst_QDataStream::stream_QByteArray2()
}
}
+void tst_QDataStream::stream_QJsonDocument()
+{
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << QByteArrayLiteral("invalidJson");
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonDocument doc;
+ load >> doc;
+ QVERIFY(doc.isEmpty());
+ QVERIFY(load.status() != QDataStream::Ok);
+ QCOMPARE(load.status(), QDataStream::ReadCorruptData);
+ }
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QJsonDocument docSave(QJsonArray{1,2,3});
+ save << docSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonDocument docLoad;
+ load >> docLoad;
+ QCOMPARE(docLoad, docSave);
+ }
+}
+
+void tst_QDataStream::stream_QJsonArray()
+{
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << QByteArrayLiteral("invalidJson");
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonArray array;
+ load >> array;
+ QVERIFY(array.isEmpty());
+ QVERIFY(load.status() != QDataStream::Ok);
+ QCOMPARE(load.status(), QDataStream::ReadCorruptData);
+ }
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QJsonArray arraySave(QJsonArray{1,2,3});
+ save << arraySave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonArray arrayLoad;
+ load >> arrayLoad;
+ QCOMPARE(arrayLoad, arraySave);
+ }
+}
+
+void tst_QDataStream::stream_QJsonObject()
+{
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << QByteArrayLiteral("invalidJson");
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonObject object;
+ load >> object;
+ QVERIFY(object.isEmpty());
+ QVERIFY(load.status() != QDataStream::Ok);
+ QCOMPARE(load.status(), QDataStream::ReadCorruptData);
+ }
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QJsonObject objSave{{"foo", 1}, {"bar", 2}};
+ save << objSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonObject objLoad;
+ load >> objLoad;
+ QCOMPARE(objLoad, objSave);
+ }
+}
+
+void tst_QDataStream::stream_QJsonValue()
+{
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << quint8(42);
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonValue value;
+ load >> value;
+ QVERIFY(value.isUndefined());
+ QVERIFY(load.status() != QDataStream::Ok);
+ QCOMPARE(load.status(), QDataStream::ReadCorruptData);
+ }
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QJsonValue valueSave{42};
+ save << valueSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonValue valueLoad;
+ load >> valueLoad;
+ QCOMPARE(valueLoad, valueSave);
+ }
+}
+
+void tst_QDataStream::stream_QCborArray()
+{
+ QByteArray buffer;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QCborArray arraySave({1, 2, 3});
+ save << arraySave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QCborArray arrayLoad;
+ load >> arrayLoad;
+ QCOMPARE(arrayLoad, arraySave);
+}
+
+void tst_QDataStream::stream_QCborMap()
+{
+ QByteArray buffer;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QCborMap objSave{{"foo", 1}, {"bar", 2}};
+ save << objSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QCborMap objLoad;
+ load >> objLoad;
+ QCOMPARE(objLoad, objSave);
+}
+
+void tst_QDataStream::stream_QCborValue()
+{
+ QByteArray buffer;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QCborValue valueSave{42};
+ save << valueSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QCborValue valueLoad;
+ load >> valueLoad;
+ QCOMPARE(valueLoad, valueSave);
+}
+
void tst_QDataStream::setVersion_data()
{
QTest::addColumn<int>("vers");
diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
index 159fbd7b03..8bb35554c8 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -2665,28 +2665,30 @@ void tst_QTextStream::useCase2()
// ------------------------------------------------------------------------------
void tst_QTextStream::manipulators_data()
{
- QTest::addColumn<int>("flags");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<int>("alignFlag");
+ QTest::addColumn<int>("numberFlag");
QTest::addColumn<int>("width");
QTest::addColumn<double>("realNumber");
QTest::addColumn<int>("intNumber");
QTest::addColumn<QString>("textData");
QTest::addColumn<QByteArray>("result");
- QTest::newRow("no flags") << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
- QTest::newRow("rightadjust") << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray(" 5 5 five");
-
- // ### FIX
-// QTest::newRow("leftadjust") << int(QTextStream::left) << 10 << 5.0 << 5 << QString("five") << QByteArray("5 5 five ");
-// QTest::newRow("showpos") << int(QTextStream::showpos) << 10 << 5.0 << 5 << QString("five") << QByteArray(" +5 +5 five");
-// QTest::newRow("showpos2") << int(QTextStream::showpos) << 5 << 3.14 << -5 << QString("five") << QByteArray("+3.14 -5 five");
-// QTest::newRow("hex") << int(QTextStream::hex | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0x5 five");
-// QTest::newRow("hex uppercase") << int(QTextStream::hex | QTextStream::uppercase | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
+ QTest::newRow("no flags") << 10 << 0 << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
+ QTest::newRow("rightadjust") << 10 << int(QTextStream::AlignRight) << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray(" 5 5 five");
+ QTest::newRow("leftadjust") << 10 << int(QTextStream::AlignLeft) << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray("5 5 five ");
+ QTest::newRow("showpos") << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 10 << 5.0 << 5 << QString("five") << QByteArray(" +5 +5 five");
+ QTest::newRow("showpos2") << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 5 << 3.14 << -5 << QString("five") << QByteArray("+3.14 -5 five");
+ QTest::newRow("hex") << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0x5 five");
+ QTest::newRow("hex") << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase | QTextStream::UppercaseBase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
}
// ------------------------------------------------------------------------------
void tst_QTextStream::manipulators()
{
-// QFETCH(int, flags);
+ QFETCH(int, base);
+ QFETCH(int, alignFlag);
+ QFETCH(int, numberFlag);
QFETCH(int, width);
QFETCH(double, realNumber);
QFETCH(int, intNumber);
@@ -2700,14 +2702,16 @@ void tst_QTextStream::manipulators()
stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
stream.setAutoDetectUnicode(true);
-// stream.setFlags(flags);
+ stream.setIntegerBase(base);
+ stream.setFieldAlignment(QTextStream::FieldAlignment(alignFlag));
+ stream.setNumberFlags(QTextStream::NumberFlag(numberFlag));
stream.setFieldWidth(width);
stream << realNumber;
stream << intNumber;
stream << textData;
stream.flush();
- QCOMPARE(buffer.data().constData(), result.constData());
+ QCOMPARE(buffer.data(), result);
}
void tst_QTextStream::generateBOM()
diff --git a/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp b/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp
index 85b4c4bfb7..2d2c536453 100644
--- a/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp
+++ b/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp
@@ -49,6 +49,9 @@ private slots:
void operator_plus() const;
void operator_plus_data() const;
+ void indexOf_data() const;
+ void indexOf() const;
+
void initializerList() const;
};
@@ -259,6 +262,29 @@ void tst_QByteArrayList::operator_plus_data() const
<< ( QByteArrayList() << "a" << "" << "c" );
}
+void tst_QByteArrayList::indexOf_data() const
+{
+ QTest::addColumn<QByteArrayList>("list");
+ QTest::addColumn<QByteArray>("item");
+ QTest::addColumn<int>("expectedResult");
+
+ QTest::newRow("empty") << QByteArrayList() << QByteArray("a") << -1;
+ QTest::newRow("found_1") << ( QByteArrayList() << "a" ) << QByteArray("a") << 0;
+ QTest::newRow("not_found_1") << ( QByteArrayList() << "a" ) << QByteArray("b") << -1;
+ QTest::newRow("found_2") << ( QByteArrayList() << "hello" << "world" ) << QByteArray("world") << 1;
+ QTest::newRow("returns_first") << ( QByteArrayList() << "hello" << "world" << "hello" << "again" ) << QByteArray("hello") << 0;
+}
+
+void tst_QByteArrayList::indexOf() const
+{
+ QFETCH(QByteArrayList, list);
+ QFETCH(QByteArray, item);
+ QFETCH(int, expectedResult);
+
+ QCOMPARE(list.indexOf(item), expectedResult);
+ QCOMPARE(list.indexOf(item.constData()), expectedResult);
+}
+
void tst_QByteArrayList::initializerList() const
{
#ifdef Q_COMPILER_INITIALIZER_LISTS
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index 943805e228..56792f38fb 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -37,9 +37,6 @@
#ifdef Q_OS_WIN
# include <qt_windows.h>
-# if defined(Q_OS_WINRT)
-# define tzset()
-# endif
#endif
class tst_QDateTime : public QObject
@@ -145,9 +142,7 @@ private slots:
void isDaylightTime() const;
void daylightTransitions() const;
void timeZones() const;
-#if defined(Q_OS_UNIX)
void systemTimeZoneChange() const;
-#endif
void invalid() const;
@@ -174,7 +169,7 @@ private:
void reset(const QByteArray &zone)
{
qputenv("TZ", zone.constData());
- tzset();
+ qTzSet();
}
~TimeZoneRollback()
{
@@ -182,7 +177,7 @@ private:
qunsetenv("TZ");
else
qputenv("TZ", prior.constData());
- tzset();
+ qTzSet();
}
};
};
@@ -3412,33 +3407,10 @@ void tst_QDateTime::timeZones() const
QCOMPARE(future.offsetFromUtc(), 28800);
}
-#if defined(Q_OS_UNIX)
-// Currently disabled on Windows as adjusting the timezone
-// requires additional privileges that aren't normally
-// enabled for a process. This can be achieved by calling
-// AdjustTokenPrivileges() and then SetTimeZoneInformation(),
-// which will require linking to a different library to access that API.
-static void setTimeZone(const QByteArray &tz)
-{
- qputenv("TZ", tz);
- ::tzset();
-
-// following left for future reference, see comment above
-// #if defined(Q_OS_WIN32)
-// ::_tzset();
-// #endif
-}
-
void tst_QDateTime::systemTimeZoneChange() const
{
- struct ResetTZ {
- QByteArray original;
- ResetTZ() : original(qgetenv("TZ")) {}
- ~ResetTZ() { setTimeZone(original); }
- } scopedReset;
-
// Set the timezone to Brisbane time
- setTimeZone(QByteArray("AEST-10:00"));
+ TimeZoneRollback useZone(QByteArray("AEST-10:00"));
QDateTime localDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::LocalTime);
QDateTime utcDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::UTC);
@@ -3451,16 +3423,18 @@ void tst_QDateTime::systemTimeZoneChange() const
QVERIFY(tzDate.timeZone().isValid());
// Change to Indian time
- setTimeZone(QByteArray("IST-05:30"));
+ useZone.reset(QByteArray("IST-05:30"));
QCOMPARE(localDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::LocalTime));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT gets this wrong, QTBUG-71185", Continue);
+#endif
QVERIFY(localMsecs != localDate.toMSecsSinceEpoch());
QCOMPARE(utcDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::UTC));
QCOMPARE(utcDate.toMSecsSinceEpoch(), utcMsecs);
QCOMPARE(tzDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), QTimeZone("Australia/Brisbane")));
QCOMPARE(tzDate.toMSecsSinceEpoch(), tzMsecs);
}
-#endif
void tst_QDateTime::invalid() const
{
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index 5d344834e6..9bb0c6811d 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -1989,9 +1989,11 @@ static void setWinLocaleInfo(LCTYPE type, const QString &value)
# define LOCALE_SSHORTTIME 0x00000079
#endif
-class RestoreLocaleHelper {
+class RestoreLocaleHelper
+{
public:
- RestoreLocaleHelper() {
+ RestoreLocaleHelper()
+ {
m_decimal = getWinLocaleInfo(LOCALE_SDECIMAL);
m_thousand = getWinLocaleInfo(LOCALE_STHOUSAND);
m_sdate = getWinLocaleInfo(LOCALE_SSHORTDATE);
@@ -1999,7 +2001,8 @@ public:
m_time = getWinLocaleInfo(LOCALE_SSHORTTIME);
}
- ~RestoreLocaleHelper() {
+ ~RestoreLocaleHelper()
+ {
// restore these, or the user will get a surprise
setWinLocaleInfo(LOCALE_SDECIMAL, m_decimal);
setWinLocaleInfo(LOCALE_STHOUSAND, m_thousand);
@@ -2007,12 +2010,10 @@ public:
setWinLocaleInfo(LOCALE_SLONGDATE, m_ldate);
setWinLocaleInfo(LOCALE_SSHORTTIME, m_time);
- // make sure QLocale::system() gets updated
- QLocalePrivate::updateSystemPrivate();
+ QSystemLocale dummy; // to provoke a refresh of the system locale
}
QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
-
};
void tst_QLocale::windowsDefaultLocale()
@@ -2028,8 +2029,7 @@ void tst_QLocale::windowsDefaultLocale()
const QString shortTimeFormat = QStringLiteral("h^m^s");
setWinLocaleInfo(LOCALE_SSHORTTIME, shortTimeFormat);
- // make sure QLocale::system() gets updated
- QLocalePrivate::updateSystemPrivate();
+ QSystemLocale dummy; // to provoke a refresh of the system locale
QLocale locale = QLocale::system();
// make sure we are seeing the system's format strings
@@ -2770,9 +2770,11 @@ void tst_QLocale::textDirection_data()
case QLocale::Sabaean:
case QLocale::Samaritan:
case QLocale::Sindhi:
+ case QLocale::SouthernKurdish:
case QLocale::Syriac:
case QLocale::Uighur:
case QLocale::Urdu:
+ case QLocale::WesternBalochi:
case QLocale::Yiddish:
// false if there is no locale data for language:
rightToLeft = (QLocale(QLocale::Language(language)).language()
diff --git a/tests/auto/corelib/tools/qoffsetstringarray/qoffsetstringarray.pro b/tests/auto/corelib/tools/qoffsetstringarray/qoffsetstringarray.pro
new file mode 100644
index 0000000000..c8e6a8e05a
--- /dev/null
+++ b/tests/auto/corelib/tools/qoffsetstringarray/qoffsetstringarray.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+TARGET = tst_qoffsetstringarray
+QT = core testlib core-private
+CONFIG += c++11
+CONFIG += strict_c++
+SOURCES = $$PWD/tst_qoffsetstringarray.cpp
diff --git a/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp b/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp
new file mode 100644
index 0000000000..dfa0450b18
--- /dev/null
+++ b/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 <private/qoffsetstringarray_p.h>
+
+
+class tst_QOffsetStringArray : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void init();
+ void access();
+};
+
+
+constexpr const auto messages = qOffsetStringArray(
+ "level - 0",
+ "level - 1",
+ "level - 2",
+ "level - 3",
+ "level - 4",
+ ""
+);
+
+constexpr const auto messages257 = qOffsetStringArray(
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "end"
+);
+
+constexpr const auto messagesBigOffsets = qOffsetStringArray(
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90"
+);
+
+void tst_QOffsetStringArray::init()
+{
+ static_assert(messages.sizeString == 51, "message.sizeString");
+ static_assert(messages.sizeOffsets == 6, "message.sizeOffsets");
+ static_assert(std::is_same<decltype(messages)::Type, quint8>::value, "messages::Type != quint8");
+
+ static_assert(messages257.sizeOffsets == 257, "messages257.sizeOffsets");
+ static_assert(messages257.sizeString == 260, "messages257.sizeString");
+ static_assert(std::is_same<decltype(messages257)::Type, quint16>::value,
+ "messages257::Type != quint16");
+
+ static_assert(messagesBigOffsets.sizeOffsets == 4, "messagesBigOffsets.sizeOffsets");
+ static_assert(messagesBigOffsets.sizeString == 364, "messagesBigOffsets.sizeString");
+ static_assert(std::is_same<decltype(messagesBigOffsets)::Type, quint16>::value,
+ "messagesBigOffsets::Type != quint16");
+}
+
+void tst_QOffsetStringArray::access()
+{
+ QCOMPARE(messages[0], "level - 0");
+ QCOMPARE(messages[1], "level - 1");
+ QCOMPARE(messages[2], "level - 2");
+ QCOMPARE(messages[3], "level - 3");
+ QCOMPARE(messages[4], "level - 4");
+ QCOMPARE(messages[5], "");
+ QCOMPARE(messages[6], "");
+}
+
+
+QTEST_APPLESS_MAIN(tst_QOffsetStringArray)
+#include "tst_qoffsetstringarray.moc"
diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro
index f28cf21b8b..2a975e67d1 100644
--- a/tests/auto/corelib/tools/tools.pro
+++ b/tests/auto/corelib/tools/tools.pro
@@ -35,6 +35,7 @@ SUBDIRS=\
qmap_strictiterators \
qmargins \
qmessageauthenticationcode \
+ qoffsetstringarray \
qpair \
qpoint \
qpointf \