summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-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.pro1
-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/qstringlistmodel/tst_qstringlistmodel.cpp176
-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/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.cpp81
-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/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
-rw-r--r--tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp46
-rw-r--r--tests/auto/gui/text/qcssparser/tst_qcssparser.cpp21
-rw-r--r--tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp4
-rw-r--r--tests/auto/network-settings.h10
-rw-r--r--tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp6
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp16
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp27
-rw-r--r--tests/auto/testserver.pri55
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp29
-rw-r--r--tests/auto/tools/rcc/data/sizes/data/data-0.txt0
-rw-r--r--tests/auto/tools/rcc/data/sizes/data/data-1.txt1
-rw-r--r--tests/auto/tools/rcc/data/sizes/data/data-2.txt1
-rw-r--r--tests/auto/tools/rcc/data/sizes/data/data-35.txt1
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-0.expected88
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-0.qrc5
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-1.expected89
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-1.qrc5
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected126
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-2-0-35-1.qrc8
-rw-r--r--tests/auto/tools/rcc/rcc.pro7
-rw-r--r--tests/auto/tools/rcc/tst_rcc.cpp47
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp4
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp4
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp133
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp1
-rw-r--r--tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp78
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp9
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp91
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp7
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp3
-rw-r--r--tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp47
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp76
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp11
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp62
-rw-r--r--tests/auto/widgets/widgets/qsplitter/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp45
-rw-r--r--tests/benchmarks/corelib/io/qfileinfo/main.cpp4
-rw-r--r--tests/benchmarks/corelib/mimetypes/qmimedatabase/main.cpp11
-rw-r--r--tests/benchmarks/widgets/itemviews/itemviews.pro3
-rw-r--r--tests/benchmarks/widgets/itemviews/qlistview/qlistview.pro7
-rw-r--r--tests/benchmarks/widgets/itemviews/qlistview/tst_qlistview.cpp68
-rw-r--r--tests/manual/widgets/itemviews/itemviews.pro8
-rw-r--r--tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/main.cpp88
-rw-r--r--tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro8
-rw-r--r--tests/shared/filesystem.h32
-rwxr-xr-xtests/testserver/danted/danted.sh19
-rw-r--r--tests/testserver/docker-compose-for-macOS.yml80
-rwxr-xr-xtests/testserver/vsftpd/vsftpd.sh2
72 files changed, 3850 insertions, 874 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..b27938e0c0 100644
--- a/tests/auto/corelib/itemmodels/itemmodels.pro
+++ b/tests/auto/corelib/itemmodels/itemmodels.pro
@@ -5,6 +5,7 @@ SUBDIRS = qstringlistmodel
qtHaveModule(gui): SUBDIRS += \
qabstractitemmodel \
qabstractproxymodel \
+ qconcatenatetablesproxymodel \
qidentityproxymodel \
qitemselectionmodel \
qsortfilterproxymodel_recursive \
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/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/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 effc82261b..936cbd3894 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/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..c609aa6621 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)
@@ -1690,6 +1694,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 edea4713a1..1c1631760b 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -2662,28 +2662,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);
@@ -2697,14 +2699,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/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 261689d401..ff36beadcb 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -1869,9 +1869,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);
@@ -1879,7 +1881,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);
@@ -1887,12 +1890,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()
@@ -1908,8 +1909,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
@@ -2650,9 +2650,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 \
diff --git a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp
index cca0e95c29..b2572188b9 100644
--- a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp
+++ b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp
@@ -49,6 +49,8 @@ private slots:
void construct();
void constructCopy_data();
void constructCopy();
+ void saveAndLoadBuiltin_data();
+ void saveAndLoadBuiltin();
};
#define FOR_EACH_GUI_METATYPE_BASE(F) \
@@ -442,5 +444,49 @@ FOR_EACH_GUI_METATYPE(RETURN_CONSTRUCT_COPY_FUNCTION)
TypeTestFunctionGetter::get(type)();
}
+template <typename T>
+struct StreamingTraits
+{
+ // Streamable by default, as currently all gui built-in types are streamable
+ enum { isStreamable = 1 };
+};
+
+void tst_QGuiMetaType::saveAndLoadBuiltin_data()
+{
+ QTest::addColumn<int>("type");
+ QTest::addColumn<bool>("isStreamable");
+
+#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
+ QTest::newRow(#RealType) << MetaTypeId << bool(StreamingTraits<RealType>::isStreamable);
+ QT_FOR_EACH_STATIC_GUI_CLASS(ADD_METATYPE_TEST_ROW)
+#undef ADD_METATYPE_TEST_ROW
+}
+
+void tst_QGuiMetaType::saveAndLoadBuiltin()
+{
+ QFETCH(int, type);
+ QFETCH(bool, isStreamable);
+
+ void *value = QMetaType::create(type);
+
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::ReadWrite);
+ QCOMPARE(QMetaType::save(stream, type, value), isStreamable);
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ if (isStreamable)
+ QVERIFY(QMetaType::load(stream, type, value));
+
+ stream.device()->seek(0);
+ stream.resetStatus();
+ QCOMPARE(QMetaType::load(stream, type, value), isStreamable);
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ if (isStreamable)
+ QVERIFY(QMetaType::load(stream, type, value));
+
+ QMetaType::destroy(type, value);
+}
+
QTEST_MAIN(tst_QGuiMetaType)
#include "tst_qguimetatype.moc"
diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
index cfd24a8701..7dbeb13aa7 100644
--- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
+++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
@@ -835,17 +835,32 @@ void tst_QCssParser::colorValue_data()
QTest::newRow("hexcolor") << "color: #12af0e" << QColor(0x12, 0xaf, 0x0e);
QTest::newRow("functional1") << "color: rgb(21, 45, 73)" << QColor(21, 45, 73);
QTest::newRow("functional2") << "color: rgb(100%, 0%, 100%)" << QColor(0xff, 0, 0xff);
+ QTest::newRow("rgb") << "color: rgb(10, 20, 30)" << QColor(10, 20, 30);
QTest::newRow("rgba") << "color: rgba(10, 20, 30, 40)" << QColor(10, 20, 30, 40);
QTest::newRow("rgbaf") << "color: rgba(10, 20, 30, 0.5)" << QColor(10, 20, 30, 127);
- QTest::newRow("rgb") << "color: rgb(10, 20, 30, 40)" << QColor(10, 20, 30, 40);
- QTest::newRow("hsl") << "color: hsv(10, 20, 30)" << QColor::fromHsv(10, 20, 30, 255);
- QTest::newRow("hsla") << "color: hsva(10, 20, 30, 40)" << QColor::fromHsv(10, 20, 30, 40);
+ QTest::newRow("hsv") << "color: hsv(10, 20, 30)" << QColor::fromHsv(10, 20, 30);
+ QTest::newRow("hsva") << "color: hsva(10, 20, 30, 40)" << QColor::fromHsv(10, 20, 30, 40);
+ // the percent and float values are well chosen to not get in trouble due to rounding errors
+ QTest::newRow("hsva-percent") << "color: hsva(100%, 20%, 40%, 60%)" << QColor::fromHsv(359, 51, 102, 153);
+ QTest::newRow("hsva-float") << "color: hsva(180, 20%, 40%, 0.6)" << QColor::fromHsvF(0.5, 0.2, 0.4, 0.6);
+ QTest::newRow("hsl") << "color: hsl(60, 100%, 50%)" << QColor::fromHsl(60., 255, 127);
+ QTest::newRow("hsla") << "color: hsla(240, 255, 127, 192)" << QColor::fromHsl(240, 255, 127, 192);
+ QTest::newRow("hsla-percent") << "color: hsla(100%, 80%, 40%, 0%)" << QColor::fromHsl(359, 204, 102, 0);
+ QTest::newRow("hsla-float") << "color: hsla(252, 40%, 60%, 0.2)" << QColor::fromHslF(0.7, 0.4, 0.6, 0.2);
QTest::newRow("invalid1") << "color: rgb(why, does, it, always, rain, on, me)" << QColor();
QTest::newRow("invalid2") << "color: rgba(i, meant, norway)" << QColor();
QTest::newRow("invalid3") << "color: rgb(21)" << QColor();
+ QTest::newRow("invalid4") << "color: rgbx(1, 2, 3)" << QColor();
+ QTest::newRow("invalid5") << "color: rgbax(1, 2, 3, 4)" << QColor();
+ QTest::newRow("invalid6") << "color: hsv(360, 0, 0)" << QColor();
+ QTest::newRow("invalid7") << "color: hsla(1, a, 1, 21)" << QColor();
QTest::newRow("role") << "color: palette(base)" << qApp->palette().color(QPalette::Base);
QTest::newRow("role2") << "color: palette( window-text ) " << qApp->palette().color(QPalette::WindowText);
QTest::newRow("transparent") << "color: transparent" << QColor(Qt::transparent);
+
+ // ### Qt6: no longer valid
+ QTest::newRow("rgb-invalid") << "color: rgb(10, 20, 30, 40)" << QColor(10, 20, 30, 40);
+ QTest::newRow("rgba-invalid") << "color: rgba(10, 20, 30)" << QColor(10, 20, 30, 255);
}
void tst_QCssParser::colorValue()
diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
index b7f014d0e2..1429e4cb7f 100644
--- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
+++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
@@ -491,10 +491,6 @@ void tst_QGlyphRun::drawMultiScriptText2()
drawGlyphs.save("drawMultiScriptText2_drawGlyphIndexes.png");
#endif
-#ifdef Q_OS_OSX
- if (drawGlyphs.toImage() != textLayoutDraw.toImage())
- QEXPECT_FAIL("", "See QTBUG-32690", Continue);
-#endif // Q_OS_OSX
QCOMPARE(drawGlyphs, textLayoutDraw);
}
diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h
index a3c318420f..4225ff11c7 100644
--- a/tests/auto/network-settings.h
+++ b/tests/auto/network-settings.h
@@ -176,7 +176,7 @@ public:
static QString ftpServerName()
{
-#ifdef QT_TEST_SERVER
+#ifdef QT_TEST_SERVER_NAME
return QString("vsftpd.") % serverDomainName();
#else
return serverName();
@@ -184,7 +184,7 @@ public:
}
static QString ftpProxyServerName()
{
-#ifdef QT_TEST_SERVER
+#ifdef QT_TEST_SERVER_NAME
return QString("ftp-proxy.") % serverDomainName();
#else
return serverName();
@@ -192,7 +192,7 @@ public:
}
static QString httpServerName()
{
-#ifdef QT_TEST_SERVER
+#ifdef QT_TEST_SERVER_NAME
return QString("apache2.") % serverDomainName();
#else
return serverName();
@@ -200,7 +200,7 @@ public:
}
static QString httpProxyServerName()
{
-#ifdef QT_TEST_SERVER
+#ifdef QT_TEST_SERVER_NAME
return QString("squid.") % serverDomainName();
#else
return serverName();
@@ -208,7 +208,7 @@ public:
}
static QString socksProxyServerName()
{
-#ifdef QT_TEST_SERVER
+#ifdef QT_TEST_SERVER_NAME
return QString("danted.") % serverDomainName();
#else
return serverName();
diff --git a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
index 8b49679042..6c3443a735 100644
--- a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
+++ b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
@@ -35,7 +35,9 @@
#include <QtNetwork/QNetworkCookieJar>
#include <QtNetwork/QNetworkCookie>
#include <QtNetwork/QNetworkRequest>
+#if QT_CONFIG(topleveldomain)
#include "private/qtldurl_p.h"
+#endif
class tst_QNetworkCookieJar: public QObject
{
@@ -47,7 +49,7 @@ private slots:
void setCookiesFromUrl();
void cookiesForUrl_data();
void cookiesForUrl();
-#ifdef QT_BUILD_INTERNAL
+#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(topleveldomain)
void effectiveTLDs_data();
void effectiveTLDs();
#endif
@@ -398,7 +400,7 @@ void tst_QNetworkCookieJar::cookiesForUrl()
}
// This test requires private API.
-#ifdef QT_BUILD_INTERNAL
+#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(topleveldomain)
void tst_QNetworkCookieJar::effectiveTLDs_data()
{
QTest::addColumn<QString>("domain");
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index b759aed074..72b5d06dd5 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -1345,10 +1345,10 @@ void tst_QSslSocket::protocolServerSide()
// to quit due to a socket error, and investigate the culprit.
if (server.socket->error() != QAbstractSocket::UnknownSocketError) {
QVERIFY(client.error() == QAbstractSocket::UnknownSocketError);
- QCOMPARE(int(server.socket->state()), int(expectedState));
+ QCOMPARE(server.socket->state(), expectedState);
} else if (client.error() != QAbstractSocket::UnknownSocketError) {
QVERIFY(server.socket->error() == QAbstractSocket::UnknownSocketError);
- QCOMPARE(int(client.state()), int(expectedState));
+ QCOMPARE(client.state(), expectedState);
}
QCOMPARE(client.isEncrypted(), works);
}
@@ -3271,10 +3271,10 @@ void tst_QSslSocket::verifyClientCertificate_data()
validCerts += QSslCertificate::fromPath(testDataDir + "certs/bogus-ca.crt");
QCOMPARE(validCerts.size(), 2);
- QTest::newRow("ValidClientCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << validCerts << validKey << true;
- QTest::newRow("ValidClientCert:QueryPeer") << QSslSocket::QueryPeer << validCerts << validKey << true;
- QTest::newRow("ValidClientCert:VerifyNone") << QSslSocket::VerifyNone << validCerts << validKey << true;
- QTest::newRow("ValidClientCert:VerifyPeer") << QSslSocket::VerifyPeer << validCerts << validKey << true;
+ QTest::newRow("ValidChainedClientCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << validCerts << validKey << true;
+ QTest::newRow("ValidChainedClientCert:QueryPeer") << QSslSocket::QueryPeer << validCerts << validKey << true;
+ QTest::newRow("ValidChainedClientCert:VerifyNone") << QSslSocket::VerifyNone << validCerts << validKey << true;
+ QTest::newRow("ValidChainedClientCert:VerifyPeer") << QSslSocket::VerifyPeer << validCerts << validKey << true;
}
void tst_QSslSocket::verifyClientCertificate()
@@ -3330,7 +3330,7 @@ void tst_QSslSocket::verifyClientCertificate()
// check server socket
QVERIFY(server.socket);
- QCOMPARE(int(server.socket->state()), int(expectedState));
+ QCOMPARE(server.socket->state(), expectedState);
QCOMPARE(server.socket->isEncrypted(), works);
if (peerVerifyMode == QSslSocket::VerifyNone || clientCerts.isEmpty()) {
@@ -3342,7 +3342,7 @@ void tst_QSslSocket::verifyClientCertificate()
}
// check client socket
- QCOMPARE(int(client.state()), int(expectedState));
+ QCOMPARE(client.state(), expectedState);
QCOMPARE(client.isEncrypted(), works);
}
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
index 8cf43e243b..bdfa957083 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
@@ -199,6 +199,9 @@ private slots:
void sqlite_openError();
+ void sqlite_check_json1_data() { generic_data("QSQLITE"); }
+ void sqlite_check_json1();
+
private:
void createTestTables(QSqlDatabase db);
void dropTestTables(QSqlDatabase db);
@@ -2350,6 +2353,30 @@ void tst_QSqlDatabase::sqlite_openError()
QCOMPARE(error.databaseText(), "unable to open database file");
}
+void tst_QSqlDatabase::sqlite_check_json1()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ if (dbType != QSqlDriver::SQLite)
+ QSKIP("SQLite3 specific test");
+
+ QSqlQuery q(db);
+ const QString json1("{\"id\":1}");
+ const QString tableName(qTableName("sqlite_check_json1", __FILE__, db));
+ tst_Databases::safeDropTable(db, tableName);
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(text TEXT)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES(json('%2'))").arg(tableName, json1)));
+ QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName)));
+ q.addBindValue("json('{\"id\":2}')");
+ QVERIFY_SQL(q, prepare(QString("SELECT * from %1 WHERE text = json('%2')").arg(tableName, json1)));
+ QVERIFY_SQL(q, exec());
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toString(), json1);
+ QFAIL_SQL(q, next());
+}
+
void tst_QSqlDatabase::cloneDatabase()
{
QFETCH(QString, dbName);
diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri
index b2f593235f..7dd32db0af 100644
--- a/tests/auto/testserver.pri
+++ b/tests/auto/testserver.pri
@@ -51,7 +51,6 @@
# 2. testserver_clean - Clean up server containers/images and tidy away related
# files.
-TESTSERVER_COMPOSE_FILE = $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml
TESTSERVER_VERSION = $$system(docker-compose --version)
equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) {
@@ -59,30 +58,59 @@ equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) {
message("testserver: qt-test-server.qt-test-net")
} else {
# Make check with test servers
- message("testserver:" $$TESTSERVER_VERSION)
+ equals(QMAKE_HOST.os, Darwin) {
+ # There is no docker bridge on macOS. It is impossible to ping a container.
+ # Docker docs recommends using port mapping to connect to a container;
+ # but it causes a port conflict if the user is running a service that
+ # binds the same port on the host. An alternative solution is to deploy
+ # the docker environment into VirtualBox using docker-machine.
+ TESTSERVER_COMPOSE_FILE = \
+ $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose-for-macOS.yml
+
+ # The connection configuration for the target machine
+ MACHINE_CONFIG = $(shell docker-machine config qt-test-server)
+
+ # The environment variables passed to the docker-compose file
+ TEST_ENV = 'MACHINE_IP=$(shell docker-machine ip qt-test-server)'
+ } else {
+ TESTSERVER_COMPOSE_FILE = $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml
+ DEFINES += QT_TEST_SERVER_NAME
+ }
# Ensure that the docker-compose file is provided. It is a configuration
# file which is mandatory for all docker-compose commands. You can get more
# detail from the description of TESTSERVER_COMPOSE_FILE above. There is
# also an example showing how to configure it manually.
FILE_PRETEST_MSG = "Project variable 'TESTSERVER_COMPOSE_FILE' is not set"
- testserver_pretest.commands = $(if $$TESTSERVER_COMPOSE_FILE,,$(error $$FILE_PRETEST_MSG))
+ testserver_pretest.commands = $(info "testserver:" $$TESTSERVER_VERSION)
+ testserver_pretest.commands += $(if $$TESTSERVER_COMPOSE_FILE,,$(error $$FILE_PRETEST_MSG))
+
+ # Make sure docker-machine is both created and running. The docker_machine
+ # script is used to deploy the docker environment into VirtualBox.
+ # Example: qt5/coin/provisioning/common/shared/testserver/docker_machine.sh
+ !isEmpty(MACHINE_CONFIG) {
+ MACHINE_LIST_CMD = docker-machine ls -q --filter "Name=^qt-test-server$"
+ MACHINE_LIST_MSG = "Docker machine qt-test-server not found"
+ testserver_pretest.commands += \
+ $(if $(shell $$MACHINE_LIST_CMD),,$(error $$MACHINE_LIST_MSG))
+
+ MACHINE_STATE_CMD = \
+ docker-machine ls -q --filter "State=Running" --filter "Name=^qt-test-server$"
+ MACHINE_START_CMD = docker-machine start qt-test-server
+ testserver_pretest.commands += \
+ $(if $(shell $$MACHINE_STATE_CMD),,$(shell $$MACHINE_START_CMD > /dev/null))
+ }
# Before starting the test servers, it requires the user to run the setup
# script (coin/provisioning/.../testserver/docker_testserver.sh) in advance.
- IMAGE_PRETEST_CMD = docker images -aq "qt-test-server-*"
+ IMAGE_PRETEST_CMD = docker $$MACHINE_CONFIG images -aq "qt-test-server-*"
IMAGE_PRETEST_MSG = "Docker image qt-test-server-* not found"
testserver_pretest.commands += $(if $(shell $$IMAGE_PRETEST_CMD),,$(error $$IMAGE_PRETEST_MSG))
# The domain name is relevant to https keycert (qnetworkreply/crts/qt-test-net-cacert.pem).
DNSDOMAIN = test-net.qt.local
- TEST_ENV += TESTSERVER_DOMAIN=$$DNSDOMAIN
DEFINES += QT_TEST_SERVER QT_TEST_SERVER_DOMAIN=$$shell_quote(\"$${DNSDOMAIN}\")
- # There is no docker bridge on macOS. It is impossible to ping a container.
- # Docker docs recommends using port mapping to connect to a container.
- equals(QMAKE_HOST.os, Darwin): TEST_ENV += TESTSERVER_BIND_LOCAL=1
-
# Rename the check target of testcase feature
check.target = check_network
testserver_test.target = check
@@ -91,18 +119,19 @@ equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) {
testserver_test.depends = testserver_pretest
# Bring up test servers and make sure the services are ready.
- testserver_test.commands = $$TEST_ENV docker-compose -f $$TESTSERVER_COMPOSE_FILE up -d \
- --force-recreate --timeout 1 $${QT_TEST_SERVER_LIST} &&
+ !isEmpty(TEST_ENV): testserver_test.commands = env $$TEST_ENV
+ testserver_test.commands += docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE up \
+ --detach --force-recreate --timeout 1 $${QT_TEST_SERVER_LIST} &&
# Check test cases with docker-based test servers.
testserver_test.commands += $(MAKE) check_network;
# Stop and remove test servers after testing.
- testserver_test.commands += $$TEST_ENV docker-compose -f $$TESTSERVER_COMPOSE_FILE down \
+ testserver_test.commands += docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE down \
--timeout 1
# Destroy test servers and tidy away related files.
- testserver_clean.commands = $$TEST_ENV docker-compose -f $$TESTSERVER_COMPOSE_FILE down \
+ testserver_clean.commands = docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE down \
--rmi all
QMAKE_EXTRA_TARGETS += testserver_pretest testserver_test testserver_clean
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index 92a94055a4..f1888aebab 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -682,6 +682,7 @@ private slots:
void finalClasses();
void explicitOverrideControl_data();
void explicitOverrideControl();
+ void overloadedAddressOperator();
void autoPropertyMetaTypeRegistration();
void autoMethodArgumentMetaTypeRegistration();
void autoSignalSpyMetaTypeRegistration();
@@ -2939,6 +2940,34 @@ void tst_Moc::explicitOverrideControl()
#endif
}
+class OverloadedAddressOperator : public QObject
+{
+ Q_OBJECT
+public:
+ void* operator&() { return nullptr; }
+signals:
+ void self(OverloadedAddressOperator&);
+public slots:
+ void assertSelf(OverloadedAddressOperator &o)
+ {
+ QCOMPARE(std::addressof(o), this);
+ testResult = (std::addressof(o) == this);
+ }
+public:
+ bool testResult = false;
+};
+
+void tst_Moc::overloadedAddressOperator()
+{
+ OverloadedAddressOperator o;
+ OverloadedAddressOperator *p = std::addressof(o);
+ QCOMPARE(&o, nullptr);
+ QVERIFY(p);
+ QObject::connect(p, &OverloadedAddressOperator::self, p, &OverloadedAddressOperator::assertSelf);
+ emit o.self(o);
+ QVERIFY(o.testResult);
+}
+
class CustomQObject : public QObject
{
Q_OBJECT
diff --git a/tests/auto/tools/rcc/data/sizes/data/data-0.txt b/tests/auto/tools/rcc/data/sizes/data/data-0.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/data/data-0.txt
diff --git a/tests/auto/tools/rcc/data/sizes/data/data-1.txt b/tests/auto/tools/rcc/data/sizes/data/data-1.txt
new file mode 100644
index 0000000000..b516b2c489
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/data/data-1.txt
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/tests/auto/tools/rcc/data/sizes/data/data-2.txt b/tests/auto/tools/rcc/data/sizes/data/data-2.txt
new file mode 100644
index 0000000000..a616ad491b
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/data/data-2.txt
@@ -0,0 +1 @@
+01 \ No newline at end of file
diff --git a/tests/auto/tools/rcc/data/sizes/data/data-35.txt b/tests/auto/tools/rcc/data/sizes/data/data-35.txt
new file mode 100644
index 0000000000..19a8036a15
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/data/data-35.txt
@@ -0,0 +1 @@
+0123456789 0123456789 0123456789 12 \ No newline at end of file
diff --git a/tests/auto/tools/rcc/data/sizes/size-0.expected b/tests/auto/tools/rcc/data/sizes/size-0.expected
new file mode 100644
index 0000000000..e862310153
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-0.expected
@@ -0,0 +1,88 @@
+/****************************************************************************
+** Resource object code
+**
+IGNORE: ** Created by: The Resource Compiler for Qt version 5.11.2
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+static const unsigned char qt_resource_data[] = {
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-0.txt
+ 0x0,0x0,0x0,0x0,
+
+
+};
+
+static const unsigned char qt_resource_name[] = {
+ // data
+ 0x0,0x4,
+ 0x0,0x6,0xa8,0xa1,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,
+ // data-0.txt
+ 0x0,0xa,
+ 0x4,0xe,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x30,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data/data-0.txt
+ 0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
+TIMESTAMP:data/data-0.txt
+
+};
+
+#ifdef QT_NAMESPACE
+# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
+# define QT_RCC_MANGLE_NAMESPACE0(x) x
+# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
+# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
+# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
+ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#else
+# define QT_RCC_PREPEND_NAMESPACE(name) name
+# define QT_RCC_MANGLE_NAMESPACE(name) name
+#endif
+
+#ifdef QT_NAMESPACE
+namespace QT_NAMESPACE {
+#endif
+
+bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+#ifdef QT_NAMESPACE
+}
+#endif
+
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)();
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)();
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+namespace {
+ struct initializer {
+ initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources)(); }
+ ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); }
+ } dummy;
+}
diff --git a/tests/auto/tools/rcc/data/sizes/size-0.qrc b/tests/auto/tools/rcc/data/sizes/size-0.qrc
new file mode 100644
index 0000000000..9f47732fe2
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-0.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>data/data-0.txt</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/tools/rcc/data/sizes/size-1.expected b/tests/auto/tools/rcc/data/sizes/size-1.expected
new file mode 100644
index 0000000000..9e5161272a
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-1.expected
@@ -0,0 +1,89 @@
+/****************************************************************************
+** Resource object code
+**
+IGNORE:** Created by: The Resource Compiler for Qt version 5.11.2
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+static const unsigned char qt_resource_data[] = {
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-1.txt
+ 0x0,0x0,0x0,0x1,
+ 0x40,
+
+
+};
+
+static const unsigned char qt_resource_name[] = {
+ // data
+ 0x0,0x4,
+ 0x0,0x6,0xa8,0xa1,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,
+ // data-1.txt
+ 0x0,0xa,
+ 0x4,0x11,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data/data-1.txt
+ 0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
+TIMESTAMP:data/data-1.txt
+
+};
+
+#ifdef QT_NAMESPACE
+# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
+# define QT_RCC_MANGLE_NAMESPACE0(x) x
+# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
+# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
+# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
+ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#else
+# define QT_RCC_PREPEND_NAMESPACE(name) name
+# define QT_RCC_MANGLE_NAMESPACE(name) name
+#endif
+
+#ifdef QT_NAMESPACE
+namespace QT_NAMESPACE {
+#endif
+
+bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+#ifdef QT_NAMESPACE
+}
+#endif
+
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)();
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)();
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+namespace {
+ struct initializer {
+ initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources)(); }
+ ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); }
+ } dummy;
+}
diff --git a/tests/auto/tools/rcc/data/sizes/size-1.qrc b/tests/auto/tools/rcc/data/sizes/size-1.qrc
new file mode 100644
index 0000000000..9fde9a1722
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-1.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>data/data-1.txt</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected
new file mode 100644
index 0000000000..0fc953351a
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected
@@ -0,0 +1,126 @@
+/****************************************************************************
+** Resource object code
+**
+IGNORE: ** Created by: The Resource Compiler for Qt version 5.11.2
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+static const unsigned char qt_resource_data[] = {
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-2.txt
+ 0x0,0x0,0x0,0x2,
+ 0x30,
+ 0x31,
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-35.txt
+ 0x0,0x0,0x0,0x23,
+ 0x30,
+ 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20,0x30,0x31,0x32,0x33,0x34,0x35,
+ 0x36,0x37,0x38,0x39,0x20,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20,
+ 0x31,0x32,
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-1.txt
+ 0x0,0x0,0x0,0x1,
+ 0x40,
+
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-0.txt
+ 0x0,0x0,0x0,0x0,
+
+
+};
+
+static const unsigned char qt_resource_name[] = {
+ // data
+ 0x0,0x4,
+ 0x0,0x6,0xa8,0xa1,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,
+ // data-2.txt
+ 0x0,0xa,
+ 0x4,0x8,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // data-35.txt
+ 0x0,0xb,
+ 0x0,0xb5,0x4f,0x74,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x33,0x0,0x35,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // data-1.txt
+ 0x0,0xa,
+ 0x4,0x11,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // data-0.txt
+ 0x0,0xa,
+ 0x4,0xe,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x30,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x2,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data/data-35.txt
+ 0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x6,
+TIMESTAMP:data/data-35.txt
+ // :/data/data-2.txt
+ 0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
+TIMESTAMP:data/data-2.txt
+ // :/data/data-0.txt
+ 0x0,0x0,0x0,0x5e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x32,
+TIMESTAMP:data/data-0.txt
+ // :/data/data-1.txt
+ 0x0,0x0,0x0,0x44,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2d,
+TIMESTAMP:data/data-1.txt
+
+};
+
+#ifdef QT_NAMESPACE
+# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
+# define QT_RCC_MANGLE_NAMESPACE0(x) x
+# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
+# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
+# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
+ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#else
+# define QT_RCC_PREPEND_NAMESPACE(name) name
+# define QT_RCC_MANGLE_NAMESPACE(name) name
+#endif
+
+#ifdef QT_NAMESPACE
+namespace QT_NAMESPACE {
+#endif
+
+bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+#ifdef QT_NAMESPACE
+}
+#endif
+
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)();
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)();
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+namespace {
+ struct initializer {
+ initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources)(); }
+ ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); }
+ } dummy;
+}
diff --git a/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.qrc b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.qrc
new file mode 100644
index 0000000000..039c9203ff
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>data/data-2.txt</file>
+ <file>data/data-0.txt</file>
+ <file>data/data-35.txt</file>
+ <file>data/data-1.txt</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/tools/rcc/rcc.pro b/tests/auto/tools/rcc/rcc.pro
index 264b8ecc66..3fdc4132a7 100644
--- a/tests/auto/tools/rcc/rcc.pro
+++ b/tests/auto/tools/rcc/rcc.pro
@@ -3,3 +3,10 @@ QT = core testlib
TARGET = tst_rcc
SOURCES += tst_rcc.cpp
+
+RESOURCES += \
+ $$PWD/data/images/images.qrc \
+ $$PWD/data/sizes/size-0.qrc \
+ $$PWD/data/sizes/size-2-0-35-1.qrc \
+ $$PWD/data/sizes/size-1.qrc
+
diff --git a/tests/auto/tools/rcc/tst_rcc.cpp b/tests/auto/tools/rcc/tst_rcc.cpp
index 54a2854ede..0876af6759 100644
--- a/tests/auto/tools/rcc/tst_rcc.cpp
+++ b/tests/auto/tools/rcc/tst_rcc.cpp
@@ -55,9 +55,13 @@ private slots:
void rcc_data();
void rcc();
+
void binary_data();
void binary();
+ void readback_data();
+ void readback();
+
void cleanupTestCase();
private:
@@ -126,6 +130,13 @@ void tst_rcc::rcc_data()
if (dataPath.isEmpty())
QFAIL("data path not found");
QTest::newRow("images") << dataPath << "images.qrc" << "images.expected";
+
+ QString sizesPath = QFINDTESTDATA("data/sizes/");
+ if (sizesPath.isEmpty())
+ QFAIL("data path not found");
+ QTest::newRow("size-0") << sizesPath << "size-0.qrc" << "size-0.expected";
+ QTest::newRow("size-1") << sizesPath << "size-1.qrc" << "size-1.expected";
+ QTest::newRow("size-2-0-35-1") << sizesPath << "size-2-0-35-1.qrc" << "size-2-0-35-1.expected";
}
void tst_rcc::rcc()
@@ -353,6 +364,42 @@ void tst_rcc::binary()
QLocale::setDefault(oldDefaultLocale);
}
+void tst_rcc::readback_data()
+{
+ QTest::addColumn<QString>("resourceName");
+ QTest::addColumn<QString>("fileSystemName");
+
+ QTest::newRow("data-0") << ":data/data-0.txt" << "sizes/data/data-0.txt";
+ QTest::newRow("data-1") << ":data/data-1.txt" << "sizes/data/data-1.txt";
+ QTest::newRow("data-2") << ":data/data-2.txt" << "sizes/data/data-2.txt";
+ QTest::newRow("data-35") << ":data/data-35.txt" << "sizes/data/data-35.txt";
+ QTest::newRow("circle") << ":images/circle.png" << "images/images/circle.png";
+ QTest::newRow("square") << ":images/square.png" << "images/images/square.png";
+ QTest::newRow("triangle") << ":images/subdir/triangle.png"
+ << "images/images/subdir/triangle.png";
+}
+
+void tst_rcc::readback()
+{
+ QFETCH(QString, resourceName);
+ QFETCH(QString, fileSystemName);
+
+ QString dataPath = QFINDTESTDATA("data/");
+ if (dataPath.isEmpty())
+ QFAIL("data path not found");
+
+ QFile resourceFile(resourceName);
+ QVERIFY(resourceFile.open(QIODevice::ReadOnly));
+ QByteArray resourceData = resourceFile.readAll();
+ resourceFile.close();
+
+ QFile fileSystemFile(dataPath + fileSystemName);
+ QVERIFY(fileSystemFile.open(QIODevice::ReadOnly));
+ QByteArray fileSystemData = fileSystemFile.readAll();
+ fileSystemFile.close();
+
+ QCOMPARE(resourceData, fileSystemData);
+}
void tst_rcc::cleanupTestCase()
{
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
index a8f6906056..adedace8b2 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
+++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
@@ -1215,7 +1215,7 @@ void tst_QItemDelegate::editorEvent()
option.checkState = Qt::CheckState(checkState);
const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1;
- QPoint pos = inCheck ? qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0) : QPoint(200,200);
+ QPoint pos = inCheck ? qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0) : QPoint(200,200);
QEvent *event = new QMouseEvent((QEvent::Type)type,
pos,
@@ -1371,7 +1371,7 @@ void tst_QItemDelegate::QTBUG4435_keepSelectionOnCheck()
option.features = QStyleOptionViewItem::HasDisplay | QStyleOptionViewItem::HasCheckIndicator;
option.checkState = Qt::CheckState(model.index(0, 0).data(Qt::CheckStateRole).toInt());
const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1;
- QPoint pos = qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option, 0).center()
+ QPoint pos = qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0).center()
+ QPoint(checkMargin, 0);
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, pos);
QTRY_VERIFY(view.selectionModel()->isColumnSelected(0, QModelIndex()));
diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
index 5227db64ec..433b9e55e1 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -873,6 +873,10 @@ void tst_QListView::setCurrentIndex()
}
}
}
+ while (model.rowCount()) {
+ view.setCurrentIndex(model.index(model.rowCount() - 1, 0));
+ model.removeRow(model.rowCount() - 1);
+ }
}
class PublicListView : public QListView
diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
index 98b44fe8aa..d8e14df353 100644
--- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
+++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
@@ -31,6 +31,7 @@
#include <QtGui/QtGui>
#include <QtWidgets/QtWidgets>
#include <qlist.h>
+#include <QSignalSpy>
#include <qlistwidget.h>
#include <private/qlistwidget_p.h>
@@ -116,6 +117,14 @@ private slots:
void QTBUG14363_completerWithAnyKeyPressedEditTriggers();
void mimeData();
void QTBUG50891_ensureSelectionModelSignalConnectionsAreSet();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ void clearItemData();
+#endif
+
+ void moveRows_data();
+ void moveRows();
+ void moveRowsInvalid_data();
+ void moveRowsInvalid();
protected slots:
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last)
@@ -148,6 +157,108 @@ private:
};
+void tst_QListWidget::moveRowsInvalid_data()
+{
+ QTest::addColumn<QListWidget*>("baseWidget");
+ QTest::addColumn<QModelIndex>("startParent");
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<QModelIndex>("destinationParent");
+ QTest::addColumn<int>("destination");
+
+ const auto createWidget = []() -> QListWidget* {
+ QListWidget* result = new QListWidget;
+ result->addItems(QStringList{"A", "B", "C", "D", "E", "F"});
+ return result;
+ };
+
+ QTest::addRow("destination_equal_source") << createWidget() << QModelIndex() << 0 << 1 << QModelIndex() << 1;
+ QTest::addRow("count_equal_0") << createWidget() << QModelIndex() << 0 << 0 << QModelIndex() << 2;
+ QListWidget* tempWidget = createWidget();
+ QTest::addRow("move_child") << tempWidget << tempWidget->model()->index(0, 0) << 0 << 1 << QModelIndex() << 2;
+ tempWidget = createWidget();
+ QTest::addRow("move_to_child") << tempWidget << QModelIndex() << 0 << 1 << tempWidget->model()->index(0, 0) << 2;
+ QTest::addRow("negative_count") << createWidget() << QModelIndex() << 0 << -1 << QModelIndex() << 2;
+ QTest::addRow("negative_source_row") << createWidget() << QModelIndex() << -1 << 1 << QModelIndex() << 2;
+ QTest::addRow("negative_destination_row") << createWidget() << QModelIndex() << 0 << 1 << QModelIndex() << -1;
+ QTest::addRow("source_row_equal_rowCount") << createWidget() << QModelIndex() << 6 << 1 << QModelIndex() << 1;
+ QTest::addRow("destination_row_greater_rowCount") << createWidget() << QModelIndex() << 0 << 1 << QModelIndex() << 6 + 1;
+ QTest::addRow("move_row_within_source_range") << createWidget() << QModelIndex() << 0 << 3 << QModelIndex() << 2;
+ QTest::addRow("destination_row_before_0") << createWidget() << QModelIndex() << 1 << 1 << QModelIndex() << 0;
+}
+
+void tst_QListWidget::moveRowsInvalid()
+{
+ QFETCH(QListWidget* const, baseWidget);
+ QFETCH(const QModelIndex, startParent);
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const QModelIndex, destinationParent);
+ QFETCH(const int, destination);
+ QAbstractItemModel *baseModel = baseWidget->model();
+ 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 baseWidget;
+}
+
+void tst_QListWidget::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_QListWidget::moveRows()
+{
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const int, destination);
+ QFETCH(const QStringList, expected);
+ QListWidget baseWidget;
+ baseWidget.addItems(QStringList{"A", "B", "C", "D", "E", "F"});
+ QAbstractItemModel *baseModel = baseWidget.model();
+ QSignalSpy rowMovedSpy(baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(baseModel->moveRows(QModelIndex(), startRow, count, QModelIndex(), destination));
+ QCOMPARE(baseModel->rowCount(), expected.size());
+ for (int i = 0; i < expected.size(); ++i)
+ QCOMPARE(baseModel->index(i, 0).data().toString(), expected.at(i));
+ 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);
+ }
+}
+
+
typedef QList<int> IntList;
tst_QListWidget::tst_QListWidget(): testWidget(0), rcParent(8), rcFirst(8,0), rcLast(8,0)
@@ -1743,5 +1854,27 @@ void tst_QListWidget::QTBUG50891_ensureSelectionModelSignalConnectionsAreSet()
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void tst_QListWidget::clearItemData()
+{
+ QListWidget list;
+ for (int i = 0 ; i < 4; ++i)
+ new QListWidgetItem(QString::number(i), &list);
+ QSignalSpy dataChangeSpy(list.model(), &QAbstractItemModel::dataChanged);
+ QVERIFY(dataChangeSpy.isValid());
+ QVERIFY(!list.model()->clearItemData(QModelIndex()));
+ QCOMPARE(dataChangeSpy.size(), 0);
+ QVERIFY(list.model()->clearItemData(list.model()->index(0, 0)));
+ QVERIFY(!list.model()->index(0, 0).data().isValid());
+ QCOMPARE(dataChangeSpy.size(), 1);
+ const QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
+ QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), list.model()->index(0, 0));
+ QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), list.model()->index(0, 0));
+ QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
+ QVERIFY(list.model()->clearItemData(list.model()->index(0, 0)));
+ QCOMPARE(dataChangeSpy.size(), 0);
+}
+#endif
+
QTEST_MAIN(tst_QListWidget)
#include "tst_qlistwidget.moc"
diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
index ab746dfee8..228d03350a 100644
--- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
@@ -2506,7 +2506,6 @@ void tst_QTableView::columnViewportPosition()
view.horizontalScrollBar()->setValue(horizontalScrollValue);
#ifdef Q_OS_WINRT
- QEXPECT_FAIL("column 1, scroll per item, 1", "Fails on WinRT - QTBUG-68297", Abort);
QEXPECT_FAIL("column 5, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort);
QEXPECT_FAIL("column 9, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort);
QEXPECT_FAIL("column 1, scroll per pixel 1", "Fails on WinRT - QTBUG-68297", Abort);
diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
index 4155ff1ec6..5f013a28d0 100644
--- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
@@ -83,12 +83,17 @@ private slots:
void setItemData();
void cellWidget();
void cellWidgetGeometry();
+ void sizeHint_data();
+ void sizeHint();
void task231094();
void task219380_removeLastRow();
void task262056_sortDuplicate();
void itemWithHeaderItems();
void mimeData();
void selectedRowAfterSorting();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ void clearItemData();
+#endif
private:
QTableWidget *testWidget;
@@ -1454,6 +1459,56 @@ void tst_QTableWidget::cellWidgetGeometry()
QCOMPARE(tw.visualItemRect(item).top(), le->geometry().top());
}
+void tst_QTableWidget::sizeHint_data()
+{
+ QTest::addColumn<int>("scrollBarPolicy");
+ QTest::addColumn<QSize>("viewSize");
+ QTest::newRow("ScrollBarAlwaysOn") << static_cast<int>(Qt::ScrollBarAlwaysOn) << QSize();
+ QTest::newRow("ScrollBarAlwaysOff") << static_cast<int>(Qt::ScrollBarAlwaysOff) << QSize();
+ // make sure the scrollbars are shown by resizing the view to 40x40
+ QTest::newRow("ScrollBarAsNeeded (40x40)") << static_cast<int>(Qt::ScrollBarAsNeeded) << QSize(40, 40);
+ QTest::newRow("ScrollBarAsNeeded (1000x1000)") << static_cast<int>(Qt::ScrollBarAsNeeded) << QSize(1000, 1000);
+}
+
+void tst_QTableWidget::sizeHint()
+{
+ QFETCH(int, scrollBarPolicy);
+ QFETCH(QSize, viewSize);
+
+ QTableWidget view(2, 2);
+ view.setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
+ view.setVerticalScrollBarPolicy(static_cast<Qt::ScrollBarPolicy>(scrollBarPolicy));
+ view.setHorizontalScrollBarPolicy(static_cast<Qt::ScrollBarPolicy>(scrollBarPolicy));
+ for (int r = 0 ; r < view.rowCount(); ++r)
+ for (int c = 0 ; c < view.columnCount(); ++c)
+ view.setItem(r, c, new QTableWidgetItem(QString("%1/%2").arg(r).arg(c)));
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ if (viewSize.isValid()) {
+ view.resize(viewSize);
+ view.setColumnWidth(0, 100);
+ view.setRowHeight(0, 100);
+ QTRY_COMPARE(view.size(), viewSize);
+ }
+
+ auto sizeHint = view.sizeHint();
+ view.hide();
+ QCOMPARE(view.sizeHint(), sizeHint);
+
+ view.horizontalHeader()->hide();
+ view.show();
+ sizeHint = view.sizeHint();
+ view.hide();
+ QCOMPARE(view.sizeHint(), sizeHint);
+
+ view.verticalHeader()->hide();
+ view.show();
+ sizeHint = view.sizeHint();
+ view.hide();
+ QCOMPARE(view.sizeHint(), sizeHint);
+}
+
void tst_QTableWidget::task231094()
{
QTableWidget tw(5, 3);
@@ -1617,5 +1672,28 @@ void tst_QTableWidget::selectedRowAfterSorting()
}
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void tst_QTableWidget::clearItemData()
+{
+ QTableWidget table(3,3);
+ for (int r = 0; r < 3; r++)
+ for (int c = 0; c < 3; c++)
+ table.setItem(r,c,new QTableWidgetItem(QStringLiteral("0")));
+ QSignalSpy dataChangeSpy(table.model(), &QAbstractItemModel::dataChanged);
+ QVERIFY(dataChangeSpy.isValid());
+ QVERIFY(!table.model()->clearItemData(QModelIndex()));
+ QCOMPARE(dataChangeSpy.size(), 0);
+ QVERIFY(table.model()->clearItemData(table.model()->index(0, 0)));
+ QVERIFY(!table.model()->index(0, 0).data().isValid());
+ QCOMPARE(dataChangeSpy.size(), 1);
+ const QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
+ QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), table.model()->index(0, 0));
+ QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), table.model()->index(0, 0));
+ QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
+ QVERIFY(table.model()->clearItemData(table.model()->index(0, 0)));
+ QCOMPARE(dataChangeSpy.size(), 0);
+}
+#endif
+
QTEST_MAIN(tst_QTableWidget)
#include "tst_qtablewidget.moc"
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 8f9afeea4d..f4a73b8b4a 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -2435,6 +2435,8 @@ void tst_QTreeView::selection()
for (int i = 0;i < 10; ++i)
m.setData(m.index(i, 0), i);
treeView.setModel(&m);
+ treeView.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&treeView));
treeView.setSelectionBehavior(QAbstractItemView::SelectRows);
treeView.setSelectionMode(QAbstractItemView::ExtendedSelection);
@@ -2446,6 +2448,13 @@ void tst_QTreeView::selection()
QTest::mousePress(treeView.viewport(), Qt::LeftButton, 0, treeView.visualRect(m.index(1, 0)).center());
QTest::keyPress(treeView.viewport(), Qt::Key_Down);
+ auto selectedRows = treeView.selectionModel()->selectedRows();
+ QCOMPARE(selectedRows.size(), 1);
+ QCOMPARE(selectedRows.first(), m.index(2, 0, QModelIndex()));
+ QTest::keyPress(treeView.viewport(), Qt::Key_5);
+ selectedRows = treeView.selectionModel()->selectedRows();
+ QCOMPARE(selectedRows.size(), 1);
+ QCOMPARE(selectedRows.first(), m.index(5, 0, QModelIndex()));
}
//From task 151686 QTreeView ExtendedSelection selects hidden rows
diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
index 8c93df9073..c5ccbc0d0b 100644
--- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
@@ -115,6 +115,8 @@ private slots:
void changeDataWithSorting();
void changeDataWithStableSorting_data();
void changeDataWithStableSorting();
+ void sizeHint_data();
+ void sizeHint();
void sortedIndexOfChild_data();
void sortedIndexOfChild();
@@ -161,6 +163,9 @@ private slots:
void getMimeDataWithInvalidItem();
void testVisualItemRect();
void reparentHiddenItem();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ void clearItemData();
+#endif
public slots:
void itemSelectionChanged();
@@ -2618,6 +2623,50 @@ void tst_QTreeWidget::changeDataWithStableSorting()
QCOMPARE(layoutChangedSpy.count(), reorderingExpected ? 1 : 0);
}
+void tst_QTreeWidget::sizeHint_data()
+{
+ QTest::addColumn<int>("scrollBarPolicy");
+ QTest::addColumn<QSize>("viewSize");
+ QTest::newRow("ScrollBarAlwaysOn") << static_cast<int>(Qt::ScrollBarAlwaysOn) << QSize();
+ QTest::newRow("ScrollBarAlwaysOff") << static_cast<int>(Qt::ScrollBarAlwaysOff) << QSize();
+ // make sure the scrollbars are shown by resizing the view to 40x40
+ QTest::newRow("ScrollBarAsNeeded (40x40)") << static_cast<int>(Qt::ScrollBarAsNeeded) << QSize(40, 40);
+ QTest::newRow("ScrollBarAsNeeded (1000x1000)") << static_cast<int>(Qt::ScrollBarAsNeeded) << QSize(1000, 1000);
+}
+
+void tst_QTreeWidget::sizeHint()
+{
+ QFETCH(int, scrollBarPolicy);
+ QFETCH(QSize, viewSize);
+
+ QTreeWidget view;
+ view.setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
+ view.setVerticalScrollBarPolicy(static_cast<Qt::ScrollBarPolicy>(scrollBarPolicy));
+ view.setHorizontalScrollBarPolicy(static_cast<Qt::ScrollBarPolicy>(scrollBarPolicy));
+ view.setColumnCount(2);
+ for (int i = 0 ; i < view.columnCount(); ++i)
+ view.addTopLevelItem(new QTreeWidgetItem(QStringList{"foo","bar"}));
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ if (viewSize.isValid()) {
+ view.resize(viewSize);
+ view.setColumnWidth(0, 100);
+ QTRY_COMPARE(view.size(), viewSize);
+ }
+
+ auto sizeHint = view.sizeHint();
+ view.hide();
+ QCOMPARE(view.sizeHint(), sizeHint);
+
+ view.header()->hide();
+ view.show();
+ sizeHint = view.sizeHint();
+ view.hide();
+ QCOMPARE(view.sizeHint(), sizeHint);
+}
+
void tst_QTreeWidget::itemOperatorLessThan()
{
QTreeWidget tw;
@@ -3004,7 +3053,7 @@ void tst_QTreeWidget::task191552_rtl()
opt.features = QStyleOptionViewItem::HasDisplay | QStyleOptionViewItem::HasCheckIndicator;
opt.checkState = Qt::Checked;
opt.widget = &tw;
- const QRect checkRect = tw.style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, &tw);
+ const QRect checkRect = tw.style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, &tw);
QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, checkRect.center());
QCOMPARE(item->checkState(0), Qt::Unchecked);
@@ -3218,7 +3267,7 @@ void tst_QTreeWidget::nonEditableTristate()
option.checkState = item->checkState(0);
const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1;
- QPoint pos = qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0);
+ QPoint pos = qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0);
QTest::mouseClick(tree->viewport(), Qt::LeftButton, Qt::NoModifier, pos);
QCOMPARE(int(item->checkState(0)), int(Qt::Checked));
@@ -3529,5 +3578,43 @@ void tst_QTreeWidget::reparentHiddenItem()
QVERIFY(grandChild->isHidden());
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void tst_QTreeWidget::clearItemData()
+{
+ QTreeWidget tree;
+ QAbstractItemModel* model = tree.model();
+ QVERIFY(model->insertColumn(0));
+ QVERIFY(model->insertRow(0));
+ const QModelIndex parentIdx = model->index(0, 0);
+ QVERIFY(model->insertColumn(0, parentIdx));
+ QVERIFY(model->insertRow(0, parentIdx));
+ const QModelIndex childIdx = model->index(0, 0, parentIdx);
+ model->setData(parentIdx, QStringLiteral("parent"));
+ model->setData(parentIdx, QStringLiteral("parent"), Qt::UserRole);
+ model->setData(childIdx, QStringLiteral("child"));
+ QSignalSpy dataChangeSpy(model, &QAbstractItemModel::dataChanged);
+ QVERIFY(dataChangeSpy.isValid());
+ QVERIFY(!model->clearItemData(QModelIndex()));
+ QCOMPARE(dataChangeSpy.size(), 0);
+ QVERIFY(model->clearItemData(parentIdx));
+ QVERIFY(!model->data(parentIdx).isValid());
+ QVERIFY(!model->data(parentIdx, Qt::UserRole).isValid());
+ QCOMPARE(dataChangeSpy.size(), 1);
+ QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
+ QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), parentIdx);
+ QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), parentIdx);
+ QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
+ QVERIFY(model->clearItemData(parentIdx));
+ QCOMPARE(dataChangeSpy.size(), 0);
+ QVERIFY(model->clearItemData(childIdx));
+ QVERIFY(!model->data(childIdx).isValid());
+ QCOMPARE(dataChangeSpy.size(), 1);
+ dataChangeArgs = dataChangeSpy.takeFirst();
+ QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), childIdx);
+ QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), childIdx);
+ QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
+}
+#endif
+
QTEST_MAIN(tst_QTreeWidget)
#include "tst_qtreewidget.moc"
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index d2a244b762..d06baed322 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -240,6 +240,7 @@ void tst_QApplication::staticSetup()
QVERIFY(style);
QApplication::setStyle(style);
+ bool palette_changed = false;
QPalette pal;
QApplication::setPalette(pal);
@@ -247,7 +248,11 @@ void tst_QApplication::staticSetup()
QApplication::setFont(font);*/
int argc = 0;
- QApplication app(argc, 0);
+ QApplication app(argc, nullptr);
+ QObject::connect(&app, &QApplication::paletteChanged, [&palette_changed]{ palette_changed = true; });
+ QVERIFY(!palette_changed);
+ qApp->setPalette(QPalette(Qt::red));
+ QVERIFY(palette_changed);
}
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 360e6986f6..67b326e7ee 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -7655,9 +7655,6 @@ void tst_QWidget::updateWhileMinimized()
// Restore window.
widget.showNormal();
- QTest::qWait(30);
- if (m_platform == QStringLiteral("xcb"))
- QSKIP("QTBUG-26424");
QTRY_COMPARE(widget.numPaintEvents, 1);
QCOMPARE(widget.paintedRegion, QRegion(0, 0, 50, 50));
}
diff --git a/tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp b/tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp
index 077e8de328..06522b2bd3 100644
--- a/tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp
+++ b/tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp
@@ -41,6 +41,8 @@ public:
private slots:
void metaObject();
+ void saveAndLoadBuiltin_data();
+ void saveAndLoadBuiltin();
};
class CustomWidget : public QWidget
@@ -68,5 +70,50 @@ void tst_QWidgetMetaType::metaObject()
QCOMPARE(QMetaType::metaObjectForType(qMetaTypeId<QSizePolicy>()), &QSizePolicy::staticMetaObject);
}
+template <typename T>
+struct StreamingTraits
+{
+ // Streamable by default, as currently all widgets built-in types are streamable
+ enum { isStreamable = 1 };
+};
+
+void tst_QWidgetMetaType::saveAndLoadBuiltin_data()
+{
+ QTest::addColumn<int>("type");
+ QTest::addColumn<bool>("isStreamable");
+
+#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
+ QTest::newRow(#RealType) << MetaTypeId << bool(StreamingTraits<RealType>::isStreamable);
+ QT_FOR_EACH_STATIC_WIDGETS_CLASS(ADD_METATYPE_TEST_ROW)
+#undef ADD_METATYPE_TEST_ROW
+}
+
+void tst_QWidgetMetaType::saveAndLoadBuiltin()
+{
+ QFETCH(int, type);
+ QFETCH(bool, isStreamable);
+
+ void *value = QMetaType::create(type);
+
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::ReadWrite);
+ QCOMPARE(QMetaType::save(stream, type, value), isStreamable);
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ if (isStreamable)
+ QVERIFY(QMetaType::load(stream, type, value));
+
+ stream.device()->seek(0);
+ stream.resetStatus();
+ QCOMPARE(QMetaType::load(stream, type, value), isStreamable);
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ if (isStreamable)
+ QVERIFY(QMetaType::load(stream, type, value));
+
+ QMetaType::destroy(type, value);
+}
+
+
QTEST_MAIN(tst_QWidgetMetaType)
#include "tst_qwidgetmetatype.moc"
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
index f5d9433f70..bfef9d2ac4 100644
--- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
+++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
@@ -159,7 +159,7 @@ void tst_QStyleSheetStyle::numinstances()
QCOMPARE(QStyleSheetStyle::numinstances, 0);
qApp->setStyleSheet("* { color: red; }");
QCOMPARE(QStyleSheetStyle::numinstances, 1);
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QCOMPARE(QStyleSheetStyle::numinstances, 0);
// set and unset application stylesheet+widget
@@ -168,9 +168,9 @@ void tst_QStyleSheetStyle::numinstances()
QCOMPARE(QStyleSheetStyle::numinstances, 2);
w.setStyle(style);
QCOMPARE(QStyleSheetStyle::numinstances, 2);
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QCOMPARE(QStyleSheetStyle::numinstances, 1);
- w.setStyleSheet("");
+ w.setStyleSheet(QString());
QCOMPARE(QStyleSheetStyle::numinstances, 0);
// set and unset widget stylesheet
@@ -179,7 +179,7 @@ void tst_QStyleSheetStyle::numinstances()
QCOMPARE(QStyleSheetStyle::numinstances, 1);
c.setStyle(style);
QCOMPARE(QStyleSheetStyle::numinstances, 2);
- w.setStyleSheet("");
+ w.setStyleSheet(QString());
QCOMPARE(QStyleSheetStyle::numinstances, 0);
}
@@ -192,9 +192,9 @@ void tst_QStyleSheetStyle::widgetsBeforeAppStyleSheet()
QCOMPARE(COLOR(w1), red);
w1.setStyleSheet("color: white");
QCOMPARE(COLOR(w1), white);
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QCOMPARE(COLOR(w1), white);
- w1.setStyleSheet("");
+ w1.setStyleSheet(QString());
QCOMPARE(COLOR(w1), APPCOLOR(w1));
}
@@ -217,17 +217,17 @@ void tst_QStyleSheetStyle::widgetsAfterAppStyleSheet()
QCOMPARE(COLOR(w1), white);
QCOMPARE(COLOR(spin), red);
QCOMPARE(COLOR(*spin.lineEdit()), red);
- w1.setStyleSheet("");
+ w1.setStyleSheet(QString());
QCOMPARE(COLOR(w1), red);
QCOMPARE(COLOR(spin), red);
QCOMPARE(COLOR(*spin.lineEdit()), red);
w1.setStyleSheet("color: white");
QCOMPARE(COLOR(w1), white);
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QCOMPARE(COLOR(w1), white);
QCOMPARE(COLOR(spin), APPCOLOR(spin));
QCOMPARE(COLOR(*spin.lineEdit()), APPCOLOR(*spin.lineEdit()));
- w1.setStyleSheet("");
+ w1.setStyleSheet(QString());
QCOMPARE(COLOR(w1), APPCOLOR(w1));
// QCOMPARE(FONTSIZE(w1), APPFONTSIZE(w1)); //### task 244261
QCOMPARE(FONTSIZE(spin), APPFONTSIZE(spin));
@@ -243,7 +243,7 @@ void tst_QStyleSheetStyle::applicationStyleSheet()
QCOMPARE(COLOR(w1), red);
qApp->setStyleSheet("* { color: white; }");
QCOMPARE(COLOR(w1), white);
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QCOMPARE(COLOR(w1), APPCOLOR(w1));
qApp->setStyleSheet("* { color: red }");
QCOMPARE(COLOR(w1), red);
@@ -254,21 +254,21 @@ void tst_QStyleSheetStyle::windowStyleSheet()
const QColor red(Qt::red);
const QColor white(Qt::white);
QPushButton w1;
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
w1.setStyleSheet("* { color: red; }");
QCOMPARE(COLOR(w1), red);
w1.setStyleSheet("* { color: white; }");
QCOMPARE(COLOR(w1), white);
- w1.setStyleSheet("");
+ w1.setStyleSheet(QString());
QCOMPARE(COLOR(w1), APPCOLOR(w1));
w1.setStyleSheet("* { color: red }");
QCOMPARE(COLOR(w1), red);
qApp->setStyleSheet("* { color: green }");
QCOMPARE(COLOR(w1), red);
- w1.setStyleSheet("");
+ w1.setStyleSheet(QString());
QCOMPARE(COLOR(w1), QColor("green"));
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QCOMPARE(COLOR(w1), APPCOLOR(w1));
}
@@ -281,7 +281,7 @@ void tst_QStyleSheetStyle::widgetStyleSheet()
QPushButton *pb = new QPushButton(&w1);
QPushButton &w2 = *pb;
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
w1.setStyleSheet("* { color: red }");
QCOMPARE(COLOR(w1), red);
QCOMPARE(COLOR(w2), red);
@@ -293,11 +293,11 @@ void tst_QStyleSheetStyle::widgetStyleSheet()
QCOMPARE(COLOR(w1), blue);
QCOMPARE(COLOR(w2), white);
- w1.setStyleSheet("");
+ w1.setStyleSheet(QString());
QCOMPARE(COLOR(w1), APPCOLOR(w1));
QCOMPARE(COLOR(w2), white);
- w2.setStyleSheet("");
+ w2.setStyleSheet(QString());
QCOMPARE(COLOR(w1), APPCOLOR(w1));
QCOMPARE(COLOR(w2), APPCOLOR(w2));
}
@@ -311,7 +311,7 @@ void tst_QStyleSheetStyle::reparentWithNoChildStyleSheet()
QPushButton *pb = new QPushButton(&p1);
QPushButton &c1 = *pb; // child with no stylesheet
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
p1.setStyleSheet("* { color: red }");
QCOMPARE(COLOR(c1), red);
c1.setParent(&p2);
@@ -333,7 +333,7 @@ void tst_QStyleSheetStyle::reparentWithChildStyleSheet()
{
const QColor gray("gray");
const QColor white(Qt::white);
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QPushButton p1, p2;
QPushButton *pb = new QPushButton(&p1);
QPushButton &c1 = *pb;
@@ -353,7 +353,7 @@ void tst_QStyleSheetStyle::repolish()
{
const QColor red(Qt::red);
const QColor white(Qt::white);
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QPushButton p1;
p1.setStyleSheet("color: red; background: white");
QCOMPARE(BACKGROUND(p1), white);
@@ -362,14 +362,14 @@ void tst_QStyleSheetStyle::repolish()
p1.setStyleSheet("color: red");
QCOMPARE(COLOR(p1), red);
QCOMPARE(BACKGROUND(p1), APPBACKGROUND(p1));
- p1.setStyleSheet("");
+ p1.setStyleSheet(QString());
QCOMPARE(COLOR(p1), APPCOLOR(p1));
QCOMPARE(BACKGROUND(p1), APPBACKGROUND(p1));
}
void tst_QStyleSheetStyle::widgetStyle()
{
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QWidget *window1 = new QWidget;
window1->setObjectName("window1");
@@ -429,7 +429,7 @@ void tst_QStyleSheetStyle::widgetStyle()
// Remove the stylesheet
proxy = (QStyleSheetStyle *)window1->style();
- window1->setStyleSheet("");
+ window1->setStyleSheet(QString());
QVERIFY(proxy.isNull()); // should have disappeared
QCOMPARE(window1->style(), style1.data()); // its restored
@@ -457,7 +457,7 @@ void tst_QStyleSheetStyle::widgetStyle()
QCOMPARE(proxy->baseStyle(), style1.data());
// Style Sheet propagation on a child widget with a custom style already set
- window2->setStyleSheet("");
+ window2->setStyleSheet(QString());
QCOMPARE(window2->style(), style2.data());
QCOMPARE(widget2->style(), style1.data());
widget2->setStyle(0);
@@ -470,9 +470,9 @@ void tst_QStyleSheetStyle::widgetStyle()
// clean everything out
window1->setStyle(0);
- window1->setStyleSheet("");
+ window1->setStyleSheet(QString());
window2->setStyle(0);
- window2->setStyleSheet("");
+ window2->setStyleSheet(QString());
qApp->setStyle(0);
qApp->setStyleSheet("may_insanity_prevail { }"); // app has stylesheet
@@ -489,14 +489,14 @@ void tst_QStyleSheetStyle::widgetStyle()
QCOMPARE(proxy->baseStyle(), newStyle); // magic ;) the widget still follows the application
QCOMPARE(static_cast<QStyle *>(proxy), widget1->style()); // child still follows...
- window1->setStyleSheet(""); // remove stylesheet
+ window1->setStyleSheet(QString()); // remove stylesheet
QCOMPARE(window1->style(), qApp->style()); // is this cool or what
QCOMPARE(widget1->style(), qApp->style()); // annoying child follows...
QScopedPointer<QStyle> wndStyle(QStyleFactory::create("Windows"));
window1->setStyle(wndStyle.data());
QCOMPARE(window1->style()->metaObject()->className(), "QStyleSheetStyle"); // auto wraps it
QCOMPARE(widget1->style(), window1->style()); // and auto propagates to child
- qApp->setStyleSheet(""); // remove the app stylesheet
+ qApp->setStyleSheet(QString()); // remove the app stylesheet
QCOMPARE(window1->style(), wndStyle.data()); // auto dewrap
QCOMPARE(widget1->style(), qApp->style()); // and child state is restored
window1->setStyle(0); // let sanity prevail
@@ -511,7 +511,7 @@ void tst_QStyleSheetStyle::widgetStyle()
void tst_QStyleSheetStyle::appStyle()
{
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
// qApp style can never be 0
QVERIFY(QApplication::style() != 0);
QPointer<QStyle> style1 = QStyleFactory::create("Windows");
@@ -544,11 +544,11 @@ void tst_QStyleSheetStyle::appStyle()
QCOMPARE(sss->baseStyle(), style1.data());
// Revert the stylesheet
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QVERIFY(sss.isNull()); // should have disappeared
QCOMPARE(QApplication::style(), style1.data());
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QCOMPARE(QApplication::style(), style1.data());
}
@@ -744,7 +744,7 @@ void tst_QStyleSheetStyle::fontPropagation()
window.setStyleSheet("* { font-size: 10pt }");
pb.setParent(&window);
QCOMPARE(FONTSIZE(pb), 10);
- window.setStyleSheet("");
+ window.setStyleSheet(QString());
QCOMPARE(FONTSIZE(pb), buttonFontSize);
QTabWidget tw;
@@ -757,7 +757,7 @@ void tst_QStyleSheetStyle::fontPropagation()
void tst_QStyleSheetStyle::onWidgetDestroyed()
{
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
QLabel *l = new QLabel;
l->setStyleSheet("QLabel { color: red }");
QPointer<QStyleSheetStyle> ss = (QStyleSheetStyle *) l->style();
@@ -778,14 +778,14 @@ void tst_QStyleSheetStyle::fontPrecedence()
font.setPointSize(16);
edit.setFont(font);
QCOMPARE(FONTSIZE(edit), 22);
- edit.setStyleSheet("");
+ edit.setStyleSheet(QString());
QCOMPARE(FONTSIZE(edit), 16);
font.setPointSize(18);
edit.setFont(font);
QCOMPARE(FONTSIZE(edit), 18);
edit.setStyleSheet("QLineEdit { font-size: 20pt; }");
QCOMPARE(FONTSIZE(edit), 20);
- edit.setStyleSheet("");
+ edit.setStyleSheet(QString());
QCOMPARE(FONTSIZE(edit), 18);
edit.hide();
@@ -1189,7 +1189,7 @@ void tst_QStyleSheetStyle::transparent()
QPushButton *p3=new QPushButton(&w);
p1->setStyleSheet("background:transparent");
p2->setStyleSheet("background-color:transparent");
- p3->setStyleSheet("background:rgb(0,0,0,0)");
+ p3->setStyleSheet("background:rgba(0,0,0,0)");
QCOMPARE(BACKGROUND(*p1) , QColor(0,0,0,0));
QCOMPARE(BACKGROUND(*p2) , QColor(0,0,0,0));
QCOMPARE(BACKGROUND(*p3) , QColor(0,0,0,0));
@@ -2051,7 +2051,7 @@ void tst_QStyleSheetStyle::styleSheetTargetAttribute()
QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), true);
QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
- qApp->setStyleSheet("");
+ qApp->setStyleSheet(QString());
gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
@@ -2066,7 +2066,7 @@ void tst_QStyleSheetStyle::unpolish()
w.setStyleSheet("QWidget { min-width: 100; }");
w.ensurePolished();
QCOMPARE(w.minimumWidth(), 100);
- w.setStyleSheet("");
+ w.setStyleSheet(QString());
QCOMPARE(w.minimumWidth(), 0);
}
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index a88fd8d19c..634e258250 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -1143,8 +1143,16 @@ void tst_QMenu::QTBUG7411_submenus_activate()
QTRY_VERIFY(sub1.isVisible());
}
+static bool isPlatformWayland()
+{
+ return !QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive);
+}
+
void tst_QMenu::QTBUG30595_rtl_submenu()
{
+ if (isPlatformWayland())
+ QSKIP("Creating xdg_popups on Wayland requires real input events. Positions would be off.");
+
QMenu menu("Test Menu");
menu.setLayoutDirection(Qt::RightToLeft);
QMenu sub("&sub");
@@ -1179,6 +1187,9 @@ void tst_QMenu::QTBUG20403_nested_popup_on_shortcut_trigger()
#ifndef Q_OS_MACOS
void tst_QMenu::click_while_dismissing_submenu()
{
+ if (isPlatformWayland())
+ QSKIP("Wayland: Creating (grabbing) popups requires real mouse events.");
+
QMenu menu("Test Menu");
QAction *action = menu.addAction("action");
QMenu sub("&sub");
diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
index cfa2ddc4cc..be19cbc9d1 100644
--- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
+++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
@@ -140,6 +140,11 @@ private slots:
void findBackwardWithRegExp();
void findWithRegExpReturnsFalseIfNoMoreResults();
#endif
+#if QT_CONFIG(regularexpression)
+ void findWithRegularExpression();
+ void findBackwardWithRegularExpression();
+ void findWithRegularExpressionReturnsFalseIfNoMoreResults();
+#endif
void layoutAfterMultiLineRemove();
void undoCommandRemovesAndReinsertsBlock();
void taskQTBUG_43562_lineCountCrash();
@@ -147,6 +152,9 @@ private slots:
void contextMenu();
#endif
void inputMethodCursorRect();
+#if QT_CONFIG(scrollbar)
+ void updateAfterChangeCenterOnScroll();
+#endif
private:
void createSelection();
@@ -1579,6 +1587,45 @@ void tst_QPlainTextEdit::findWithRegExpReturnsFalseIfNoMoreResults()
}
#endif
+#if QT_CONFIG(regularexpression)
+void tst_QPlainTextEdit::findWithRegularExpression()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QRegularExpression rx("\\w{2}xt");
+
+ bool found = ed->find(rx);
+
+ QVERIFY(found);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text"));
+}
+
+void tst_QPlainTextEdit::findBackwardWithRegularExpression()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QTextCursor cursor = ed->textCursor();
+ cursor.movePosition(QTextCursor::End);
+ ed->setTextCursor(cursor);
+ QRegularExpression rx("a\\w*t");
+
+ bool found = ed->find(rx, QTextDocument::FindBackward);
+
+ QVERIFY(found);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("arbit"));
+}
+
+void tst_QPlainTextEdit::findWithRegularExpressionReturnsFalseIfNoMoreResults()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QRegularExpression rx("t.xt");
+ ed->find(rx);
+
+ bool found = ed->find(rx);
+
+ QVERIFY(!found);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text"));
+}
+#endif
+
void tst_QPlainTextEdit::layoutAfterMultiLineRemove()
{
ed->setVisible(true); // The widget must be visible to reproduce this bug.
@@ -1727,5 +1774,20 @@ void tst_QPlainTextEdit::inputMethodCursorRect()
QCOMPARE(cursorRectV.toRect(), cursorRect.toRect());
}
+#if QT_CONFIG(scrollbar)
+// QTBUG-64730: Verify that the scrollbar is updated after center on scroll was set
+void tst_QPlainTextEdit::updateAfterChangeCenterOnScroll()
+{
+ ed->setPlainText("Line1\nLine2Line3\nLine3");
+ ed->show();
+ ed->setCenterOnScroll(true);
+ const int maxWithCenterOnScroll = ed->verticalScrollBar()->maximum();
+ ed->setCenterOnScroll(false);
+ const int maxWithoutCenterOnScroll = ed->verticalScrollBar()->maximum();
+ QVERIFY(maxWithCenterOnScroll > maxWithoutCenterOnScroll);
+}
+
+#endif
+
QTEST_MAIN(tst_QPlainTextEdit)
#include "tst_qplaintextedit.moc"
diff --git a/tests/auto/widgets/widgets/qsplitter/BLACKLIST b/tests/auto/widgets/widgets/qsplitter/BLACKLIST
deleted file mode 100644
index 1352805cd7..0000000000
--- a/tests/auto/widgets/widgets/qsplitter/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[replaceWidget:visible, not collapsed]
-xcb
diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
index 6a2ae4951b..5f5cd78215 100644
--- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
@@ -199,6 +199,12 @@ private slots:
void findWithRegExpReturnsFalseIfNoMoreResults();
#endif
+#if QT_CONFIG(regularexpression)
+ void findWithRegularExpression();
+ void findBackwardWithRegularExpression();
+ void findWithRegularExpressionReturnsFalseIfNoMoreResults();
+#endif
+
#if QT_CONFIG(wheelevent)
void wheelEvent();
#endif
@@ -2572,6 +2578,45 @@ void tst_QTextEdit::findWithRegExpReturnsFalseIfNoMoreResults()
}
#endif
+#if QT_CONFIG(regularexpression)
+void tst_QTextEdit::findWithRegularExpression()
+{
+ ed->setHtml(QStringLiteral("arbitrary te<span style=\"color:#ff0000\">xt</span>"));
+ QRegularExpression rx("\\w{2}xt");
+
+ bool found = ed->find(rx);
+
+ QVERIFY(found);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text"));
+}
+
+void tst_QTextEdit::findBackwardWithRegularExpression()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QTextCursor cursor = ed->textCursor();
+ cursor.movePosition(QTextCursor::End);
+ ed->setTextCursor(cursor);
+ QRegularExpression rx("a\\w*t");
+
+ bool found = ed->find(rx, QTextDocument::FindBackward);
+
+ QVERIFY(found);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("arbit"));
+}
+
+void tst_QTextEdit::findWithRegularExpressionReturnsFalseIfNoMoreResults()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QRegularExpression rx("t.xt");
+ ed->find(rx);
+
+ bool found = ed->find(rx);
+
+ QVERIFY(!found);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text"));
+}
+#endif
+
#if QT_CONFIG(wheelevent)
class TextEdit : public QTextEdit
diff --git a/tests/benchmarks/corelib/io/qfileinfo/main.cpp b/tests/benchmarks/corelib/io/qfileinfo/main.cpp
index 5180e7c29e..104c01d118 100644
--- a/tests/benchmarks/corelib/io/qfileinfo/main.cpp
+++ b/tests/benchmarks/corelib/io/qfileinfo/main.cpp
@@ -94,7 +94,9 @@ void qfileinfo::symLinkTargetPerformanceMounpoint()
QString rootVolume = QString::fromWCharArray(buffer);
QString mountpoint = "mountpoint";
rootVolume.replace("\\\\?\\","\\??\\");
- FileSystem::createNtfsJunction(rootVolume, mountpoint);
+ QString errorMessage;
+ QVERIFY2(FileSystem::createNtfsJunction(rootVolume, mountpoint, &errorMessage) == ERROR_SUCCESS,
+ qPrintable(errorMessage));
QFileInfo info(mountpoint);
info.setCaching(false);
diff --git a/tests/benchmarks/corelib/mimetypes/qmimedatabase/main.cpp b/tests/benchmarks/corelib/mimetypes/qmimedatabase/main.cpp
index 704119b921..1b432f3b3e 100644
--- a/tests/benchmarks/corelib/mimetypes/qmimedatabase/main.cpp
+++ b/tests/benchmarks/corelib/mimetypes/qmimedatabase/main.cpp
@@ -35,6 +35,7 @@ class tst_QMimeDatabase: public QObject
private slots:
void inheritsPerformance();
+ void benchMimeTypeForName();
};
void tst_QMimeDatabase::inheritsPerformance()
@@ -70,5 +71,15 @@ void tst_QMimeDatabase::inheritsPerformance()
// parsing XML, and then keeps being around 4.5 MB for all the in-memory hashes.
}
+void tst_QMimeDatabase::benchMimeTypeForName()
+{
+ QMimeDatabase db;
+
+ QBENCHMARK {
+ const auto s = db.mimeTypeForName(QStringLiteral("text/plain"));
+ QVERIFY(s.isValid());
+ }
+}
+
QTEST_MAIN(tst_QMimeDatabase)
#include "main.moc"
diff --git a/tests/benchmarks/widgets/itemviews/itemviews.pro b/tests/benchmarks/widgets/itemviews/itemviews.pro
index a23cdf7b97..0c3256f307 100644
--- a/tests/benchmarks/widgets/itemviews/itemviews.pro
+++ b/tests/benchmarks/widgets/itemviews/itemviews.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
SUBDIRS = \
qtableview \
- qheaderview
+ qheaderview \
+ qlistview
diff --git a/tests/benchmarks/widgets/itemviews/qlistview/qlistview.pro b/tests/benchmarks/widgets/itemviews/qlistview/qlistview.pro
new file mode 100644
index 0000000000..68537d09ea
--- /dev/null
+++ b/tests/benchmarks/widgets/itemviews/qlistview/qlistview.pro
@@ -0,0 +1,7 @@
+QT += widgets testlib
+
+TEMPLATE = app
+TARGET = tst_bench_qlistview
+
+SOURCES += tst_qlistview.cpp
+
diff --git a/tests/benchmarks/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/benchmarks/widgets/itemviews/qlistview/tst_qlistview.cpp
new file mode 100644
index 0000000000..01496743c2
--- /dev/null
+++ b/tests/benchmarks/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 <qtest.h>
+#include <QListView>
+#include <QStandardItemModel>
+
+
+class tst_QListView : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QListView() = default;
+ virtual ~tst_QListView() = default;
+
+private slots:
+ void benchSetCurrentIndex();
+};
+
+void tst_QListView::benchSetCurrentIndex()
+{
+ QStandardItemModel sm(50000, 1);
+ QListView lv;
+ lv.setModel(&sm);
+ const int rc = lv.model()->rowCount();
+ for (int i = 0; i < rc; i+= 100)
+ lv.setRowHidden(i, true);
+ lv.setCurrentIndex(lv.model()->index(0, 0, QModelIndex()));
+ lv.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&lv));
+
+ QBENCHMARK_ONCE {
+ while (lv.currentIndex().row() < rc - 20)
+ lv.setCurrentIndex(lv.model()->index(lv.currentIndex().row() + 17,
+ lv.currentIndex().column(),
+ QModelIndex()));
+ }
+}
+
+
+QTEST_MAIN(tst_QListView)
+#include "tst_qlistview.moc"
diff --git a/tests/manual/widgets/itemviews/itemviews.pro b/tests/manual/widgets/itemviews/itemviews.pro
index 53f658d54d..8884cc3aae 100644
--- a/tests/manual/widgets/itemviews/itemviews.pro
+++ b/tests/manual/widgets/itemviews/itemviews.pro
@@ -1,2 +1,8 @@
TEMPLATE = subdirs
-SUBDIRS = delegate qheaderview qtreeview qtreewidget tableview-span-navigation
+SUBDIRS = delegate \
+ qconcatenatetablesproxymodel \
+ qheaderview \
+ qtreeview \
+ qtreewidget \
+ tableview-span-navigation \
+
diff --git a/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/main.cpp b/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/main.cpp
new file mode 100644
index 0000000000..2c1825f29f
--- /dev/null
+++ b/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/main.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 QtGui module 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 <QApplication>
+#include <QConcatenateTablesProxyModel>
+#include <QStandardItemModel>
+#include <QTableView>
+#include <QTreeView>
+
+static void prepareModel(const QString &prefix, QStandardItemModel *model)
+{
+ for (int row = 0; row < model->rowCount(); ++row) {
+ for (int column = 0; column < model->columnCount(); ++column) {
+ QStandardItem *item = new QStandardItem(prefix + QString(" %1,%2").arg(row).arg(column));
+ item->setDragEnabled(true);
+ item->setDropEnabled(true);
+ model->setItem(row, column, item);
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QStandardItemModel firstModel(4, 4);
+ prepareModel("First", &firstModel);
+ QStandardItemModel secondModel(2, 2);
+
+ QConcatenateTablesProxyModel proxy;
+ proxy.addSourceModel(&firstModel);
+ proxy.addSourceModel(&secondModel);
+
+ prepareModel("Second", &secondModel);
+
+ QTableView tableView;
+ tableView.setWindowTitle("concat proxy, in QTableView");
+ tableView.setDragDropMode(QAbstractItemView::DragDrop);
+ tableView.setModel(&proxy);
+ tableView.show();
+
+ QTreeView treeView;
+ treeView.setWindowTitle("concat proxy, in QTreeView");
+ treeView.setDragDropMode(QAbstractItemView::DragDrop);
+ treeView.setModel(&proxy);
+ treeView.show();
+
+ // For comparison, views on top on QStandardItemModel
+
+ QTableView tableViewTest;
+ tableViewTest.setWindowTitle("first model, in QTableView");
+ tableViewTest.setDragDropMode(QAbstractItemView::DragDrop);
+ tableViewTest.setModel(&firstModel);
+ tableViewTest.show();
+
+ QTreeView treeViewTest;
+ treeViewTest.setWindowTitle("first model, in QTreeView");
+ treeViewTest.setDragDropMode(QAbstractItemView::DragDrop);
+ treeViewTest.setModel(&firstModel);
+ treeViewTest.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro b/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro
new file mode 100644
index 0000000000..19904212a7
--- /dev/null
+++ b/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro
@@ -0,0 +1,8 @@
+
+TEMPLATE = app
+TARGET = qconcatenatetablesproxymodel
+INCLUDEPATH += .
+
+QT += widgets
+
+SOURCES += main.cpp
diff --git a/tests/shared/filesystem.h b/tests/shared/filesystem.h
index 73d7d6523c..9f4527a992 100644
--- a/tests/shared/filesystem.h
+++ b/tests/shared/filesystem.h
@@ -80,7 +80,7 @@ public:
}
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
- static void createNtfsJunction(QString target, QString linkName)
+ static DWORD createNtfsJunction(QString target, QString linkName, QString *errorMessage)
{
typedef struct {
DWORD ReparseTag;
@@ -97,14 +97,22 @@ public:
DWORD returnedLength;
wchar_t fileSystem[MAX_PATH] = L"";
PREPARSE_MOUNTPOINT_DATA_BUFFER reparseInfo = (PREPARSE_MOUNTPOINT_DATA_BUFFER) reparseBuffer;
+ DWORD result = ERROR_SUCCESS;
QFileInfo junctionInfo(linkName);
linkName = QDir::toNativeSeparators(junctionInfo.absoluteFilePath());
-
- GetVolumeInformationW( (wchar_t*)linkName.left(3).utf16(), NULL, 0, NULL, NULL, NULL,
- fileSystem, sizeof(fileSystem)/sizeof(WCHAR));
- if(QString().fromWCharArray(fileSystem) != "NTFS")
- QSKIP("This seems not to be an NTFS volume. Junctions are not allowed.");
+ const QString drive = linkName.left(3);
+ if (GetVolumeInformationW(reinterpret_cast<const wchar_t *>(drive.utf16()),
+ NULL, 0, NULL, NULL, NULL,
+ fileSystem, sizeof(fileSystem)/sizeof(WCHAR)) == FALSE) {
+ result = GetLastError();
+ *errorMessage = "GetVolumeInformationW() failed: " + qt_error_string(int(result));
+ return result;
+ }
+ if (QString::fromWCharArray(fileSystem) != "NTFS") {
+ *errorMessage = "This seems not to be an NTFS volume. Junctions are not allowed.";
+ return ERROR_NOT_SUPPORTED;
+ }
if (!target.startsWith("\\??\\") && !target.startsWith("\\\\?\\")) {
QFileInfo targetInfo(target);
@@ -116,7 +124,11 @@ public:
QDir().mkdir(linkName);
hFile = CreateFileW( (wchar_t*)linkName.utf16(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL );
- QVERIFY(hFile != INVALID_HANDLE_VALUE );
+ if (hFile == INVALID_HANDLE_VALUE) {
+ result = GetLastError();
+ *errorMessage = "CreateFileW(" + linkName + ") failed: " + qt_error_string(int(result));
+ return result;
+ }
memset( reparseInfo, 0, sizeof( *reparseInfo ));
reparseInfo->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
@@ -128,8 +140,12 @@ public:
bool ioc = DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, reparseInfo,
reparseInfo->ReparseDataLength + REPARSE_MOUNTPOINT_HEADER_SIZE,
NULL, 0, &returnedLength, NULL);
+ if (!ioc) {
+ result = GetLastError();
+ *errorMessage = "DeviceIoControl() failed: " + qt_error_string(int(result));
+ }
CloseHandle( hFile );
- QVERIFY(ioc);
+ return result;
}
#endif
diff --git a/tests/testserver/danted/danted.sh b/tests/testserver/danted/danted.sh
index bf3d154f33..97e2142401 100755
--- a/tests/testserver/danted/danted.sh
+++ b/tests/testserver/danted/danted.sh
@@ -39,6 +39,25 @@ useradd -d /dev/null -s /bin/false qsockstest; echo "qsockstest:$PASS" | chpassw
# install configurations and test data
cp $TESTDATA/danted{,-authenticating}.conf /etc/
+# Use the input environment variables to overwrite the default value of internal interfaces.
+if [ "$danted_internal" -a "$danted_internal" != eth0 ]
+then sed -i "s,internal: eth0 port = 1080,internal: $danted_internal port = 1080," /etc/danted.conf
+fi
+
+if [ "$danted_auth_internal" -a "$danted_auth_internal" != eth0 ]
+then sed -i "s,internal: eth0 port = 1081,internal: $danted_auth_internal port = 1081," \
+ /etc/danted-authenticating.conf
+fi
+
+# Use the input environment variables to overwrite the default value of external interfaces.
+if [ "$danted_external" -a "$danted_external" != eth0 ]
+then sed -i "s,external: eth0,external: $danted_external," /etc/danted.conf
+fi
+
+if [ "$danted_auth_external" -a "$danted_auth_external" != eth0 ]
+then sed -i "s,external: eth0,external: $danted_auth_external," /etc/danted-authenticating.conf
+fi
+
# enable service with installed configurations
service danted start
service danted-authenticating start
diff --git a/tests/testserver/docker-compose-for-macOS.yml b/tests/testserver/docker-compose-for-macOS.yml
new file mode 100644
index 0000000000..f5d812511d
--- /dev/null
+++ b/tests/testserver/docker-compose-for-macOS.yml
@@ -0,0 +1,80 @@
+version: '3.4'
+
+# The tag of images is used by docker compose file to launch the corresponding
+# docker containers. The value of tag comes from the provisioning script
+# (coin/provisioning/.../testserver/docker_testserver.sh). The script gets SHA-1
+# of each server context as the tag of docker images. If one of the server
+# contexts gets changes, please make sure to update this compose file as well.
+# You can run command 'docker images' to list all the tags of test server images.
+# For example:
+# REPOSITORY TAG IMAGE ID
+# qt-test-server-apache2 cc9ea678b92bdda33acb9fa0159bb4ad0f3cd947 2ad5c8720317
+
+services:
+ apache2:
+ image: qt-test-server-apache2:cc9ea678b92bdda33acb9fa0159bb4ad0f3cd947
+ container_name: qt-test-server-apache2
+ domainname: test-net.qt.local
+ volumes:
+ - ./common:/common:ro
+ - ./apache2:/service:ro
+ entrypoint: common/startup.sh
+ command: [common/ssl.sh, service/apache2.sh]
+ network_mode: "host"
+
+ squid:
+ image: qt-test-server-squid:577d99307eea9a8cccfec944d25be2bce2fe99cc
+ container_name: qt-test-server-squid
+ domainname: test-net.qt.local
+ depends_on:
+ - apache2
+ volumes:
+ - ./common:/common:ro
+ - ./squid:/service:ro
+ entrypoint: common/startup.sh
+ command: service/squid.sh
+ network_mode: "host"
+
+ vsftpd:
+ image: qt-test-server-vsftpd:18896604c7e90b543e56d80c8a8aabdb65a590d0
+ container_name: qt-test-server-vsftpd
+ domainname: test-net.qt.local
+ volumes:
+ - ./common:/common:ro
+ - ./vsftpd:/service:ro
+ entrypoint: common/startup.sh
+ command: service/vsftpd.sh
+ network_mode: "host"
+
+ ftp-proxy:
+ image: qt-test-server-ftp-proxy:2c6c8f1ab6a364b540c43d705fb6f15a585cb2af
+ container_name: qt-test-server-ftp-proxy
+ domainname: test-net.qt.local
+ depends_on:
+ - vsftpd
+ volumes:
+ - ./common:/common:ro
+ - ./ftp-proxy:/service:ro
+ entrypoint: common/startup.sh
+ command: service/ftp-proxy.sh
+ network_mode: "host"
+
+ danted:
+ image: qt-test-server-danted:2d5eea7356dd0ba25f3c12d1cba00d70770da1b0
+ container_name: qt-test-server-danted
+ domainname: test-net.qt.local
+ depends_on:
+ - apache2
+ - vsftpd
+ - ftp-proxy
+ volumes:
+ - ./common:/common:ro
+ - ./danted:/service:ro
+ entrypoint: common/startup.sh
+ command: service/danted.sh
+ network_mode: "host"
+ environment:
+ - danted_internal=${MACHINE_IP:-eth0}
+ - danted_external=${MACHINE_IP:-eth0}
+ - danted_auth_internal=${MACHINE_IP:-eth0}
+ - danted_auth_external=${MACHINE_IP:-eth0}
diff --git a/tests/testserver/vsftpd/vsftpd.sh b/tests/testserver/vsftpd/vsftpd.sh
index 1ba1a8c347..845c576534 100755
--- a/tests/testserver/vsftpd/vsftpd.sh
+++ b/tests/testserver/vsftpd/vsftpd.sh
@@ -43,7 +43,7 @@ cp $TESTDATA/vsftpd.{conf,user_list} /etc/
# Resolve error message "vsftpd failed - probably invalid config" during boot
command='start-stop-daemon --start --background -m --oknodo --pidfile /var/run/vsftpd/vsftpd.pid'
command+=' --exec ${DAEMON}'
-sed -i "s,$command.*$,$command; sleep 1," /etc/init.d/vsftpd
+sed -i "s,$command.*$,$command; sleep 10," /etc/init.d/vsftpd
# Populate the FTP sites:
su $USER -c "cp -r $TESTDATA/ftp ~/ftp"