summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2022-11-11 09:29:17 +0200
committerTarja Sundqvist <tarja.sundqvist@qt.io>2022-11-11 09:29:17 +0200
commit4ee4fc18b4067b90efa46ca9baba74f53b54d9ec (patch)
treecc68622c9b85992d99a8373ab55471ee821a4ebf /tests/auto
parentab28ff2207e8f33754c79793089dbf943d67736d (diff)
parentebb49c66aaf22ed55d62ff7bc3690fce00b7d8ba (diff)
Merge remote-tracking branch 'origin/tqtc/lts-5.15.8' into tqtc/lts-5.15-opensourcev5.15.8-lts-lgpl
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp34
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h1
-rw-r--r--tests/auto/corelib/kernel/qtimer/BLACKLIST3
-rw-r--r--tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro10
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_arm64.pro3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro41
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro9
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp15
-rw-r--r--tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp26
-rw-r--r--tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp52
-rw-r--r--tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp36
-rw-r--r--tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp66
-rw-r--r--tests/auto/corelib/tools/qvector/tst_qvector.cpp108
-rw-r--r--tests/auto/gui/image/qpixmap/tst_qpixmap.cpp14
-rw-r--r--tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp8
-rw-r--r--tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp60
-rw-r--r--tests/auto/gui/text/qtextlayout/BLACKLIST3
-rw-r--r--tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp59
-rw-r--r--tests/auto/gui/text/qtexttable/tst_qtexttable.cpp89
-rw-r--r--tests/auto/network/access/qdecompresshelper/BLACKLIST2
-rw-r--r--tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp30
-rw-r--r--tests/auto/network/socket/qtcpserver/BLACKLIST3
-rw-r--r--tests/auto/network/socket/qtcpsocket/BLACKLIST2
-rw-r--r--tests/auto/network/socket/qudpsocket/BLACKLIST4
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp3
-rw-r--r--tests/auto/opengl/qgl/tst_qgl.cpp5
-rw-r--r--tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm21
-rw-r--r--tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp8
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp39
-rw-r--r--tests/auto/widgets/kernel/qwidget/BLACKLIST2
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp205
-rw-r--r--tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp39
-rw-r--r--tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp13
35 files changed, 924 insertions, 95 deletions
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
index 6f608854ae..a6e1f49be2 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
@@ -2220,6 +2220,40 @@ void tst_QSortFilterProxyModel::changeSourceDataProxySendDataChanged_qtbug87781(
QCOMPARE(afterDataChangedSpy.size(), 1);
}
+void tst_QSortFilterProxyModel::changeSourceDataTreeModel()
+{
+ QStandardItemModel treeModel;
+ QSortFilterProxyModel treeProxyModelBefore;
+ QSortFilterProxyModel treeProxyModelAfter;
+
+ QSignalSpy treeBaseDataChangedSpy(&treeModel, &QStandardItemModel::dataChanged);
+ QSignalSpy treeBeforeDataChangedSpy(&treeProxyModelBefore, &QSortFilterProxyModel::dataChanged);
+ QSignalSpy treeAfterDataChangedSpy(&treeProxyModelAfter, &QSortFilterProxyModel::dataChanged);
+
+ QVERIFY(treeBaseDataChangedSpy.isValid());
+ QVERIFY(treeBeforeDataChangedSpy.isValid());
+ QVERIFY(treeAfterDataChangedSpy.isValid());
+
+ treeProxyModelBefore.setSourceModel(&treeModel);
+ QStandardItem treeNode1("data1");
+ QStandardItem treeNode11("data11");
+ QStandardItem treeNode111("data111");
+
+ treeNode1.appendRow(&treeNode11);
+ treeNode11.appendRow(&treeNode111);
+ treeModel.appendRow(&treeNode1);
+ treeProxyModelAfter.setSourceModel(&treeModel);
+
+ QCOMPARE(treeBaseDataChangedSpy.size(), 0);
+ QCOMPARE(treeBeforeDataChangedSpy.size(), 0);
+ QCOMPARE(treeAfterDataChangedSpy.size(), 0);
+
+ treeNode111.setData(QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(treeBaseDataChangedSpy.size(), 1);
+ QCOMPARE(treeBeforeDataChangedSpy.size(), 1);
+ QCOMPARE(treeAfterDataChangedSpy.size(), 1);
+}
+
void tst_QSortFilterProxyModel::changeSourceDataProxyFilterSingleColumn()
{
enum modelRow { Row0, Row1, RowCount };
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
index 7bf87a86c2..97862e804b 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
@@ -91,6 +91,7 @@ private slots:
void changeSourceDataKeepsStableSorting_qtbug1548();
void changeSourceDataForwardsRoles_qtbug35440();
void changeSourceDataProxySendDataChanged_qtbug87781();
+ void changeSourceDataTreeModel();
void changeSourceDataProxyFilterSingleColumn();
void changeSourceDataProxyFilterMultipleColumns();
void resortingDoesNotBreakTreeModels();
diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST
new file mode 100644
index 0000000000..2af0df9432
--- /dev/null
+++ b/tests/auto/corelib/kernel/qtimer/BLACKLIST
@@ -0,0 +1,3 @@
+[zeroTimer]
+ubuntu-20.04
+
diff --git a/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp b/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
index aa85a7c35b..0ad0fc7076 100644
--- a/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
+++ b/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
@@ -228,6 +228,9 @@ static qsizetype locateMetadata(const uchar *data, qsizetype len)
void tst_QPlugin::scanInvalidPlugin()
{
+#if defined(Q_OS_MACOS) && defined(Q_PROCESSOR_ARM)
+ QSKIP("This test crashes on ARM macOS");
+#endif
const auto fileNames = dir.entryList({"*invalid*"}, QDir::Files);
QString invalidPluginName;
if (fileNames.isEmpty())
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
index 795dd89895..7cfb7920c0 100644
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
@@ -1,15 +1,11 @@
TEMPLATE = subdirs
SUBDIRS = \
- machtest_i386.pro \
+ machtest_arm64.pro \
machtest_x86_64.pro \
- machtest_ppc64.pro \
machtest_fat.pro
machtest_fat-pro.depends = \
- machtest_i386.pro \
- machtest_x86_64.pro \
- machtest_ppc64.pro
-
-machtest_ppc64-pro.depends = \
+ machtest_arm64.pro \
machtest_x86_64.pro
+
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_arm64.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_arm64.pro
new file mode 100644
index 0000000000..c2856a8af0
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_arm64.pro
@@ -0,0 +1,3 @@
+QMAKE_APPLE_DEVICE_ARCHS = arm64
+include(machtest.pri)
+
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro
index 9c34a873bc..57c6654984 100644
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro
@@ -7,41 +7,42 @@ load(qt)
# Generate a fat binary with three architectures
fat_all.target = good.fat.all.dylib
fat_all.commands = lipo -create -output $@ \
- -arch ppc64 good.ppc64.dylib \
- -arch i386 good.i386.dylib \
+ -arch arm64 good.arm64.dylib \
-arch x86_64 good.x86_64.dylib
-fat_all.depends += good.i386.dylib good.x86_64.dylib good.ppc64.dylib
+fat_all.depends += good.arm64.dylib good.x86_64.dylib
-fat_no_i386.target = good.fat.no-i386.dylib
-fat_no_i386.commands = lipo -create -output $@ -arch x86_64 good.x86_64.dylib -arch ppc64 good.ppc64.dylib
-fat_no_i386.depends += good.x86_64.dylib good.ppc64.dylib
+fat_no_arm64.target = good.fat.no-arm64.dylib
+fat_no_arm64.commands = lipo -create -output $@ -arch x86_64 good.x86_64.dylib
+fat_no_arm64.depends += good.x86_64.dylib
fat_no_x86_64.target = good.fat.no-x86_64.dylib
-fat_no_x86_64.commands = lipo -create -output $@ -arch i386 good.i386.dylib -arch ppc64 good.ppc64.dylib
-fat_no_x86_64.depends += good.i386.dylib good.ppc64.dylib
+fat_no_x86_64.commands = lipo -create -output $@ -arch arm64 good.arm64.dylib
+fat_no_x86_64.depends += good.arm64.dylib
-stub_i386.commands = $$QMAKE_CXX -shared -arch i386 -o stub.i386.dylib $$PWD/stub.cpp
-stub_i386.depends += $$PWD/stub.cpp
+stub_flags = -L$$system(xcrun --show-sdk-path)/usr/lib/ -stdlib=libc++
-stub_x86_64.commands = $$QMAKE_CXX -shared -arch x86_64 -o stub.x86_64.dylib $$PWD/stub.cpp
+stub_arm64.commands = $$QMAKE_CXX $$stub_flags -shared -arch arm64 -o stub.arm64.dylib $$PWD/stub.cpp
+stub_arm64.depends += $$PWD/stub.cpp
+
+stub_x86_64.commands = $$QMAKE_CXX $$stub_flags -shared -arch x86_64 -o stub.x86_64.dylib $$PWD/stub.cpp
stub_x86_64.depends += $$PWD/stub.cpp
-fat_stub_i386.target = good.fat.stub-i386.dylib
-fat_stub_i386.commands = lipo -create -output $@ -arch ppc64 good.ppc64.dylib -arch i386 stub.i386.dylib
-fat_stub_i386.depends += stub_i386 good.x86_64.dylib good.ppc64.dylib
+fat_stub_arm64.target = good.fat.stub-arm64.dylib
+fat_stub_arm64.commands = lipo -create -output $@ -arch arm64 stub.arm64.dylib
+fat_stub_arm64.depends += stub_arm64 good.x86_64.dylib
fat_stub_x86_64.target = good.fat.stub-x86_64.dylib
-fat_stub_x86_64.commands = lipo -create -output $@ -arch ppc64 good.ppc64.dylib -arch x86_64 stub.x86_64.dylib
-fat_stub_x86_64.depends += stub_x86_64 good.i386.dylib good.ppc64.dylib
+fat_stub_x86_64.commands = lipo -create -output $@ -arch x86_64 stub.x86_64.dylib
+fat_stub_x86_64.depends += stub_x86_64 good.arm64.dylib
bad.commands = $$PWD/generate-bad.pl
bad.depends += $$PWD/generate-bad.pl
-MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_i386 \
- fat_stub_i386 fat_stub_x86_64 bad stub_i386 stub_x86_64
+MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_arm64 \
+ fat_stub_arm64 fat_stub_x86_64 bad stub_arm64 stub_x86_64
all.depends += $$MYTARGETS
QMAKE_EXTRA_TARGETS += $$MYTARGETS all
-QMAKE_CLEAN += $$fat_all.target $$fat_no_i386.target $$fat_no_x86_64.target \
- $$fat_stub_i386.target $$fat_stub_x86_64.target \
+QMAKE_CLEAN += $$fat_all.target $$fat_no_arm64.target $$fat_no_x86_64.target \
+ $$fat_stub_arm64.target $$fat_stub_x86_64.target \
"bad*.dylib"
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro
deleted file mode 100644
index bfb2e0930c..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-QMAKE_APPLE_DEVICE_ARCHS = i386
-include(machtest.pri)
-
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro
deleted file mode 100644
index a73f97ccc6..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-QMAKE_APPLE_DEVICE_ARCHS = ppc64
-include(machtest.pri)
-
-OTHER_FILES += ppcconverter.pl
-
-# Current macOS toolchains have no compiler for PPC anymore
-# So we fake it by converting an x86-64 binary to (little-endian!) PPC64
-goodlib.commands = $$PWD/ppcconverter.pl $< $@
-goodlib.depends = good.x86_64.dylib $$PWD/ppcconverter.pl
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index 8d548f5260..ce8057372c 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -341,22 +341,19 @@ void tst_QPluginLoader::loadMachO_data()
# ifdef Q_PROCESSOR_X86_64
QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::QtMetaDataSection);
- QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.arm64.dylib") << int(QMachOParser::NotSuitable);
QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::QtMetaDataSection);
-# elif defined(Q_PROCESSOR_X86_32)
- QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::QtMetaDataSection);
+ QTest::newRow("machtest/good.fat.no-arm64.dylib") << int(QMachOParser::QtMetaDataSection);
+# elif defined(Q_PROCESSOR_ARM)
+ QTest::newRow("machtest/good.arm64.dylib") << int(QMachOParser::QtMetaDataSection);
QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.no-arm64.dylib") << int(QMachOParser::NotSuitable);
QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::QtMetaDataSection);
# endif
-# ifndef Q_PROCESSOR_POWER_64
- QTest::newRow("machtest/good.ppc64.dylib") << int(QMachOParser::NotSuitable);
-# endif
QTest::newRow("machtest/good.fat.all.dylib") << int(QMachOParser::QtMetaDataSection);
QTest::newRow("machtest/good.fat.stub-x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.stub-i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.stub-arm64.dylib") << int(QMachOParser::NotSuitable);
QDir d(QFINDTESTDATA("machtest"));
QStringList badlist = d.entryList(QStringList() << "bad*.dylib");
diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp
index 88f8ea0bbb..b24243b98e 100644
--- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp
+++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp
@@ -80,6 +80,7 @@ private slots:
void threadSafety_data();
void threadSafety();
+ void returnsViewsIntoOriginalString();
void wildcard_data();
void wildcard();
void testInvalidWildcard_data();
@@ -2188,6 +2189,31 @@ void tst_QRegularExpression::threadSafety()
}
}
+void tst_QRegularExpression::returnsViewsIntoOriginalString()
+{
+ // https://bugreports.qt.io/browse/QTBUG-98653
+
+ auto to_void = [](const QChar *p) -> const void* { return p; };
+
+ // GIVEN
+ // a QString with dynamically-allocated data:
+ const QString string = QLatin1String("A\nA\nB\nB\n\nC\nC"); // NOT QStringLiteral!
+ const auto stringDataAddress = to_void(string.data());
+
+ // and a view over said QString:
+ QStringView view(string);
+ const auto viewDataAddress = to_void(view.data());
+ QCOMPARE(stringDataAddress, viewDataAddress);
+
+ // WHEN
+ // we call view.split() with a temporary QRegularExpression object
+ const auto split = view.split(QRegularExpression( "(\r\n|\n|\r)" ), Qt::KeepEmptyParts);
+
+ // THEN
+ // the returned views should point into the underlying string:
+ QCOMPARE(to_void(split.front().data()), stringDataAddress);
+}
+
void tst_QRegularExpression::wildcard_data()
{
QTest::addColumn<QString>("pattern");
diff --git a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
index 2c7c8f6514..11f181a955 100644
--- a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
+++ b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
@@ -40,8 +40,10 @@
#include <algorithm>
#include <functional>
#include <vector> // for reference
+#include <iostream>
#include <list>
#include <set>
+#include <sstream>
#include <map>
// MSVC has these containers from the Standard Library, but it lacks
@@ -64,6 +66,28 @@
#include <unordered_map>
#endif
+QT_BEGIN_NAMESPACE
+std::ostream &operator<<(std::ostream &os, const QChar &c)
+{
+ Q_ASSERT(c == QLatin1Char{c.toLatin1()});
+ return os << c.toLatin1();
+}
+std::istream &operator>>(std::istream &os, QChar &c)
+{
+ char cL1;
+ os >> cL1;
+ c = QLatin1Char{cL1};
+ return os;
+}
+QT_END_NAMESPACE
+
+namespace {
+template <typename T>
+struct is_qlist : std::false_type {};
+template <typename T>
+struct is_qlist<QList<T>> : std::true_type {};
+}
+
struct Movable
{
explicit Movable(int i = 0) Q_DECL_NOTHROW
@@ -85,6 +109,11 @@ struct Movable
int i;
static int instanceCount;
+
+ friend std::ostream &operator<<(std::ostream &os, const Movable &m)
+ { return os << m.i; }
+ friend std::istream &operator>>(std::istream &os, Movable &m)
+ { return os >> m.i; }
};
int Movable::instanceCount = 0;
@@ -124,6 +153,11 @@ struct Complex
int i;
static int instanceCount;
+
+ friend std::ostream &operator<<(std::ostream &os, const Complex &c)
+ { return os << c.i; }
+ friend std::istream &operator>>(std::istream &os, Complex &c)
+ { return os >> c.i; }
};
int Complex::instanceCount = 0;
@@ -550,12 +584,30 @@ void tst_ContainerApiSymmetry::ranged_ctor_non_associative_impl() const
// from itself
const Container c4(reference.begin(), reference.end());
+ // from stringsteam (= pure input_iterator)
+ const Container c5 = [&] {
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) // QTBUG-99036
+ if constexpr (is_qlist<Container>::value) {
+ return c4;
+ } else
+#endif
+ {
+ std::stringstream ss;
+ for (auto &v : values1)
+ ss << v << ' ';
+ ss.seekg(0);
+ return Container(std::istream_iterator<V>{ss},
+ std::istream_iterator<V>{});
+ }
+ }();
+
QCOMPARE(c1, reference);
QCOMPARE(c2a, reference);
QCOMPARE(c2b, reference);
QCOMPARE(c3a, reference);
QCOMPARE(c3b, reference);
QCOMPARE(c4, reference);
+ QCOMPARE(c5, reference);
}
diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
index f76f3aa0c6..4eb8a97051 100644
--- a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
+++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
@@ -230,8 +230,14 @@ namespace SomeNamespace {
struct Hashable { int i; };
inline uint qHash(Hashable h, uint seed = 0)
{ return QT_PREPEND_NAMESPACE(qHash)(h.i, seed); }
-}
+ struct AdlHashable {
+ int i;
+ private:
+ friend size_t qHash(AdlHashable h, size_t seed = 0)
+ { return QT_PREPEND_NAMESPACE(qHash)(h.i, seed); }
+ };
+}
void tst_QHashFunctions::range()
{
static const int ints[] = {0, 1, 2, 3, 4, 5};
@@ -253,10 +259,16 @@ void tst_QHashFunctions::range()
QCOMPARE(qHashRange(ints, ints + numInts, seed), qHashRange(it, end, seed));
}
- SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
- static const size_t numHashables = sizeof hashables / sizeof *hashables;
- // compile check: is qHash() found using ADL?
- (void)qHashRange(hashables, hashables + numHashables, seed);
+ {
+ SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found using ADL?
+ [[maybe_unused]] auto r = qHashRange(std::begin(hashables), std::end(hashables), seed);
+ }
+ {
+ SomeNamespace::AdlHashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found as a hidden friend?
+ [[maybe_unused]] auto r = qHashRange(std::begin(hashables), std::end(hashables), seed);
+ }
}
void tst_QHashFunctions::rangeCommutative()
@@ -279,10 +291,16 @@ void tst_QHashFunctions::rangeCommutative()
QCOMPARE(qHashRangeCommutative(ints, ints + numInts, seed), qHashRangeCommutative(it, end, seed));
}
- SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
- static const size_t numHashables = sizeof hashables / sizeof *hashables;
- // compile check: is qHash() found using ADL?
- (void)qHashRangeCommutative(hashables, hashables + numHashables, seed);
+ {
+ SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found using ADL?
+ [[maybe_unused]] auto r = qHashRangeCommutative(std::begin(hashables), std::end(hashables), seed);
+ }
+ {
+ SomeNamespace::AdlHashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found as a hidden friend?
+ [[maybe_unused]] auto r = qHashRangeCommutative(std::begin(hashables), std::end(hashables), seed);
+ }
}
void tst_QHashFunctions::stdHash()
diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
index 5443cf120b..0174885cf3 100644
--- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
+++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
@@ -29,6 +29,7 @@
#include <QtTest/QTest>
#include <qvarlengtharray.h>
#include <qvariant.h>
+#include <qscopedvaluerollback.h>
#include <memory>
@@ -36,10 +37,13 @@ class tst_QVarLengthArray : public QObject
{
Q_OBJECT
private slots:
+ void defaultConstructor_int() { defaultConstructor<int>(); }
+ void defaultConstructor_QString() { defaultConstructor<QString>(); }
void append();
void removeLast();
void oldTests();
void appendCausingRealloc();
+ void appendIsStronglyExceptionSafe();
void resize();
void realloc();
void reverseIterators();
@@ -61,6 +65,8 @@ private slots:
void implicitDefaultCtor();
private:
+ template <typename T>
+ void defaultConstructor();
template<typename T>
void initializeList();
};
@@ -80,6 +86,23 @@ struct Tracker
int Tracker::count = 0;
+template <typename T>
+void tst_QVarLengthArray::defaultConstructor()
+{
+ {
+ QVarLengthArray<T, 123> vla;
+ QCOMPARE(vla.size(), 0);
+ QVERIFY(vla.empty());
+ QVERIFY(vla.isEmpty());
+ QCOMPARE(vla.begin(), vla.end());
+ QCOMPARE(vla.capacity(), 123);
+ }
+ {
+ QVarLengthArray<T> vla;
+ QCOMPARE(vla.capacity(), 256); // notice, should we change the default
+ }
+}
+
void tst_QVarLengthArray::append()
{
QVarLengthArray<QString, 2> v;
@@ -245,6 +268,49 @@ void tst_QVarLengthArray::appendCausingRealloc()
d.append(i);
}
+void tst_QVarLengthArray::appendIsStronglyExceptionSafe()
+{
+#ifdef QT_NO_EXCEPTIONS
+ QSKIP("This test requires exception support enabled in the compiler.");
+#else
+ static bool throwOnCopyNow = false;
+ static bool throwOnMoveNow = false;
+ struct Thrower {
+ Thrower() = default;
+ Thrower(const Thrower &)
+ {
+ if (throwOnCopyNow)
+ throw 1;
+ }
+ Thrower &operator=(const Thrower &) = default;
+ Thrower(Thrower &&)
+ {
+ if (throwOnMoveNow)
+ throw 1;
+ }
+ Thrower &operator=(Thrower &&) = default;
+ ~Thrower() = default;
+ };
+
+ {
+ // ### TODO: QVLA isn't exception-safe when throwing during reallocation,
+ // ### so check with size() < capacity() for now
+ QVarLengthArray<Thrower, 2> vla(1);
+ {
+ Thrower t;
+ const QScopedValueRollback<bool> rb(throwOnCopyNow, true);
+ QVERIFY_EXCEPTION_THROWN(vla.push_back(t), int);
+ QCOMPARE(vla.size(), 1);
+ }
+ {
+ const QScopedValueRollback<bool> rb(throwOnMoveNow, true);
+ QVERIFY_EXCEPTION_THROWN(vla.push_back({}), int);
+ QCOMPARE(vla.size(), 1);
+ }
+ }
+#endif
+}
+
void tst_QVarLengthArray::resize()
{
//MOVABLE
diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
index 08d5a8cd50..01409bd188 100644
--- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp
+++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
@@ -183,6 +183,94 @@ inline uint qHash(const Custom &key, uint seed = 0) { return qHash(key.i, seed);
Q_DECLARE_METATYPE(Custom);
+// Similar to Custom but not default-constructible and has move constructor and assignment
+struct NonDefaultConstructible {
+ NonDefaultConstructible() = delete;
+ NonDefaultConstructible(char input)
+ : i(input)
+ , that(this)
+ , state(Constructed)
+ {
+ counter.fetchAndAddRelaxed(1);
+ }
+ NonDefaultConstructible(const NonDefaultConstructible &other)
+ : i(other.i)
+ , that(this)
+ , state(Constructed)
+ {
+ check(&other);
+ counter.fetchAndAddRelaxed(1);
+ }
+ NonDefaultConstructible(NonDefaultConstructible &&other)
+ : i(other.i)
+ , that(this)
+ , state(Constructed)
+ {
+ check(&other);
+ other.state = MovedFrom;
+ counter.fetchAndAddRelaxed(1);
+ }
+ ~NonDefaultConstructible()
+ {
+ check(this, true);
+ i = 0;
+ counter.fetchAndAddRelaxed(-1);
+ state = Destructed;
+ }
+
+ bool operator==(const NonDefaultConstructible &other) const
+ {
+ check(&other);
+ check(this);
+ return i == other.i;
+ }
+
+ bool operator<(const NonDefaultConstructible &other) const
+ {
+ check(&other);
+ check(this);
+ return i < other.i;
+ }
+
+ NonDefaultConstructible &operator=(const NonDefaultConstructible &other)
+ {
+ check(&other);
+ check(this, true);
+ i = other.i;
+ state = Constructed;
+ return *this;
+ }
+
+ NonDefaultConstructible &operator=(NonDefaultConstructible &&other)
+ {
+ check(&other);
+ check(this, true);
+ i = other.i;
+ state = Constructed;
+ other.state = MovedFrom;
+ return *this;
+ }
+ static QAtomicInt counter;
+
+ char i; // used to identify origin of an instance
+private:
+ NonDefaultConstructible *that; // used to catch copying using mem{cpy,move}()
+
+ enum State { Constructed = 106, Destructed = 110, MovedFrom = 120 };
+ State state;
+
+ static void check(const NonDefaultConstructible *c, bool movedOk = false)
+ {
+ // check if c object has been moved incorrectly
+ QCOMPARE(c, c->that);
+ if (!movedOk || c->state != MovedFrom)
+ QCOMPARE(c->state, Constructed);
+ }
+};
+QAtomicInt NonDefaultConstructible::counter = 0;
+
+inline uint qHash(const NonDefaultConstructible &key, uint seed = 0) { return qHash(key.i, seed); }
+
// tests depends on the fact that:
Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic);
Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex);
@@ -190,6 +278,8 @@ Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic);
Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex);
Q_STATIC_ASSERT(QTypeInfo<Custom>::isStatic);
Q_STATIC_ASSERT(QTypeInfo<Custom>::isComplex);
+Q_STATIC_ASSERT(QTypeInfo<NonDefaultConstructible>::isStatic);
+Q_STATIC_ASSERT(QTypeInfo<NonDefaultConstructible>::isComplex);
class tst_QVector : public QObject
@@ -263,6 +353,7 @@ private slots:
void insertInt() const;
void insertMovable() const;
void insertCustom() const;
+ void insertNonDefaultConstructible() const;
void isEmpty() const;
void last() const;
void lastIndexOf() const;
@@ -273,6 +364,7 @@ private slots:
void prependInt() const;
void prependMovable() const;
void prependCustom() const;
+ void prependNonDefaultConstructible() const;
void qhashInt() const { qhash<int>(); }
void qhashMovable() const { qhash<Movable>(); }
void qhashCustom() const { qhash<Custom>(); }
@@ -390,6 +482,10 @@ template<>
const Movable SimpleValue<Movable>::Values[] = { 110, 105, 101, 114, 111, 98 };
template<>
const Custom SimpleValue<Custom>::Values[] = { 110, 105, 101, 114, 111, 98 };
+template<>
+const NonDefaultConstructible SimpleValue<NonDefaultConstructible>::Values[] =
+ { 110, 105, 101, 114, 111, 98 };
+
// Make some macros for the tests to use in order to be slightly more readable...
#define T_FOO SimpleValue<T>::at(0)
@@ -1592,6 +1688,11 @@ void tst_QVector::insertCustom() const
insert<Custom>();
}
+void tst_QVector::insertNonDefaultConstructible() const
+{
+ insert<NonDefaultConstructible>();
+}
+
void tst_QVector::isEmpty() const
{
QVector<QString> myvec;
@@ -1831,6 +1932,13 @@ void tst_QVector::prependCustom() const
QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
+void tst_QVector::prependNonDefaultConstructible() const
+{
+ const int instancesCount = NonDefaultConstructible::counter.loadAcquire();
+ prepend<NonDefaultConstructible>();
+ QCOMPARE(instancesCount, NonDefaultConstructible::counter.loadAcquire());
+}
+
void tst_QVector::removeAllWithAlias() const
{
QVector<QString> strings;
diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
index 1d77f70919..417514607f 100644
--- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
@@ -120,6 +120,7 @@ private slots:
void copy();
void deepCopyPreservesDpr();
+ void fillPreservesDpr();
void dprPassthrough();
void depthOfNullObjects();
@@ -1156,6 +1157,19 @@ void tst_QPixmap::deepCopyPreservesDpr()
QCOMPARE(dest.devicePixelRatio(), dpr);
}
+// Check that the DPR is preserved after doing a fill after an
+// assigned copy of the QPixmap
+void tst_QPixmap::fillPreservesDpr()
+{
+ const qreal dpr = 2;
+ QPixmap src(32, 32);
+ src.setDevicePixelRatio(dpr);
+ src.fill(Qt::red);
+ QPixmap dest = src;
+ dest.fill(Qt::blue);
+ QCOMPARE(dest.devicePixelRatio(), dpr);
+}
+
void tst_QPixmap::dprPassthrough()
{
const qreal dpr = 2;
diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
index edbb090e42..15e0ecadaa 100644
--- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
@@ -33,6 +33,8 @@
#include <qfontmetrics.h>
#include <qtextlayout.h>
#include <private/qrawfont_p.h>
+#include <private/qfont_p.h>
+#include <private/qfontengine_p.h>
#include <qpa/qplatformfontdatabase.h>
Q_LOGGING_CATEGORY(lcTests, "qt.text.tests")
@@ -411,7 +413,11 @@ void tst_QFontDatabase::condensedFontMatching()
tfcByStyleName.setStyleName("Condensed");
#ifdef Q_OS_WIN
- QEXPECT_FAIL("","No matching of sub-family by stretch on Windows", Continue);
+ QFont f;
+ f.setStyleStrategy(QFont::NoFontMerging);
+ QFontPrivate *font_d = QFontPrivate::get(f);
+ if (font_d->engineForScript(QChar::Script_Common)->type() != QFontEngine::Freetype)
+ QEXPECT_FAIL("","No matching of sub-family by stretch on Windows", Continue);
#endif
#ifdef Q_OS_ANDROID
diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
index 7bc9fe47c5..a61824b51c 100644
--- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
+++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
@@ -197,6 +197,9 @@ private slots:
void clearUndoRedoStacks();
void mergeFontFamilies();
+ void contentsChangeIndices_data();
+ void contentsChangeIndices();
+
private:
void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
void buildRegExpData();
@@ -3716,5 +3719,62 @@ void tst_QTextDocument::clearUndoRedoStacks()
}
+void tst_QTextDocument::contentsChangeIndices_data()
+{
+ QTest::addColumn<QString>("html");
+ // adding list entries change the entire block, so change position is
+ // not the same as the cursor position if this value is >= 0
+ QTest::addColumn<int>("expectedBegin");
+
+ QTest::addRow("text") << "Test" << -1;
+ QTest::addRow("unnumbered list") << "<ul><li>Test</li></ul>" << 0;
+ QTest::addRow("numbered list") << "<ol><li>Test</li></ol>" << 0;
+ QTest::addRow("table") << "<table><tr><td>Test</td></tr></table>" << -1;
+}
+
+void tst_QTextDocument::contentsChangeIndices()
+{
+ QFETCH(QString, html);
+ QFETCH(int, expectedBegin);
+
+ QTextDocument doc;
+ QTestDocumentLayout *layout = new QTestDocumentLayout(&doc);
+ doc.setDocumentLayout(layout);
+ doc.setHtml(QString("<html><body>%1</body></html>").arg(html));
+
+ int documentLength = 0;
+ int cursorLength = 0;
+ int changeBegin = 0;
+ int changeRemoved = 0;
+ int changeAdded = 0;
+ connect(&doc, &QTextDocument::contentsChange, this, [&](int pos, int removed, int added){
+ documentLength = doc.characterCount();
+
+ QTextCursor cursor(&doc);
+ cursor.movePosition(QTextCursor::End);
+ // includes end-of-paragraph character
+ cursorLength = cursor.position() + 1;
+
+ changeBegin = pos;
+ changeRemoved = removed;
+ changeAdded = added;
+ });
+
+ QTextCursor cursor(&doc);
+ cursor.movePosition(QTextCursor::End);
+ if (expectedBegin < 0)
+ expectedBegin = cursor.position();
+ cursor.insertBlock();
+
+ const int changeEnd = changeBegin + changeAdded;
+
+ QVERIFY(documentLength > 0);
+ QCOMPARE(documentLength, cursorLength);
+ QVERIFY(documentLength >= changeEnd);
+ QCOMPARE(changeBegin, expectedBegin);
+ QCOMPARE(changeAdded - changeRemoved, 1);
+}
+
+
QTEST_MAIN(tst_QTextDocument)
#include "tst_qtextdocument.moc"
diff --git a/tests/auto/gui/text/qtextlayout/BLACKLIST b/tests/auto/gui/text/qtextlayout/BLACKLIST
new file mode 100644
index 0000000000..c05b0de4eb
--- /dev/null
+++ b/tests/auto/gui/text/qtextlayout/BLACKLIST
@@ -0,0 +1,3 @@
+[softHyphens]
+winrt
+
diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
index 2feca77f40..f3bb5eaffb 100644
--- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
@@ -141,6 +141,7 @@ private slots:
void showLineAndParagraphSeparatorsCrash();
void koreanWordWrap();
void tooManyDirectionalCharctersCrash_qtbug77819();
+ void softHyphens_data();
void softHyphens();
void min_maximumWidth();
@@ -2429,22 +2430,45 @@ void tst_QTextLayout::tooManyDirectionalCharctersCrash_qtbug77819()
tl.endLayout();
}
+void tst_QTextLayout::softHyphens_data()
+{
+ QTest::addColumn<int>("fontSize");
+
+ QTest::newRow("12") << 12;
+ QTest::newRow("14") << 14;
+ QTest::newRow("16") << 16;
+}
+
void tst_QTextLayout::softHyphens()
{
+ QFETCH(int, fontSize);
QString text = QStringLiteral("xxxx\u00ad") + QStringLiteral("xxxx\u00ad");
QFont font;
- font.setPixelSize(14);
+ font.setPixelSize(fontSize);
font.setHintingPreference(QFont::PreferNoHinting);
- const float xAdvance = QFontMetricsF(font).horizontalAdvance(QChar('x'));
- const float shyAdvance = QFontMetricsF(font).horizontalAdvance(QChar::SoftHyphen);
- if (xAdvance < (shyAdvance + 1.0f))
- QSKIP("Default font not suitable for this test.");
+ const float xAdvance = QFontMetricsF(font).horizontalAdvance(QChar::fromLatin1('x'));
+ float shyWidth = 0.0f;
QTextLayout layout(text, font);
QTextOption option;
option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
layout.setTextOption(option);
-
+ {
+ // Calculate the effective width of a line-ending hyphen
+ // This calculation is currently done to work-around odditities on
+ // macOS 11 (see QTBUG-90698).
+ QTextLayout test(QStringLiteral("x\u00ad"), font);
+ // Note: This only works because Qt show the soft-hyphen when ending a text.
+ // This _could_ be considered a bug and the test would need to be changed
+ // if we stop doing that.
+ test.beginLayout();
+ QTextLine line = test.createLine();
+ line.setLineWidth(10 * xAdvance);
+ line.setPosition(QPoint(0, 0));
+ shyWidth = line.naturalTextWidth() - xAdvance;
+ test.endLayout();
+ }
+ qreal linefit;
// Loose fit
// xxxx- |
// xxxx- |
@@ -2453,21 +2477,22 @@ void tst_QTextLayout::softHyphens()
int y = 0;
layout.beginLayout();
QTextLine line = layout.createLine();
- line.setLineWidth(qCeil(5 * xAdvance) + 1);
+ line.setLineWidth(qCeil(5 * xAdvance + shyWidth) + 1);
line.setPosition(QPoint(0, y));
QCOMPARE(line.textStart(), pos);
QCOMPARE(line.textLength(), 5);
- QVERIFY(qAbs(line.naturalTextWidth() - (4 * xAdvance + shyAdvance)) <= 1);
+ linefit = line.naturalTextWidth();
+ QVERIFY(qAbs(linefit - qCeil(4 * xAdvance + shyWidth)) <= 1.0);
pos += line.textLength();
y += qRound(line.ascent() + line.descent());
line = layout.createLine();
- line.setLineWidth(qCeil(5 * xAdvance) + 1);
+ line.setLineWidth(qCeil(5 * xAdvance + shyWidth) + 1);
line.setPosition(QPoint(0, y));
QCOMPARE(line.textStart(), pos);
QCOMPARE(line.textLength(), 5);
- QVERIFY(qAbs(line.naturalTextWidth() - (4 * xAdvance + shyAdvance)) <= 1);
+ QVERIFY(qAbs(line.naturalTextWidth() - linefit) <= 1.0);
layout.endLayout();
}
@@ -2479,21 +2504,21 @@ void tst_QTextLayout::softHyphens()
int y = 0;
layout.beginLayout();
QTextLine line = layout.createLine();
- line.setLineWidth(qCeil(4 * xAdvance + shyAdvance) + 1);
+ line.setLineWidth(qCeil(linefit) + 1);
line.setPosition(QPoint(0, y));
QCOMPARE(line.textStart(), pos);
QCOMPARE(line.textLength(), 5);
- QVERIFY(qAbs(line.naturalTextWidth() - (4 * xAdvance + shyAdvance)) <= 1);
+ QVERIFY(qAbs(line.naturalTextWidth() - linefit) <= 1.0);
pos += line.textLength();
y += qRound(line.ascent() + line.descent());
line = layout.createLine();
- line.setLineWidth(qCeil(4 * xAdvance + shyAdvance) + 1);
+ line.setLineWidth(qCeil(linefit) + 1);
line.setPosition(QPoint(0, y));
QCOMPARE(line.textStart(), pos);
QCOMPARE(line.textLength(), 5);
- QVERIFY(qAbs(line.naturalTextWidth() - (4 * xAdvance + shyAdvance)) <= 1);
+ QVERIFY(qAbs(line.naturalTextWidth() - linefit) <= 1.0);
layout.endLayout();
}
@@ -2510,7 +2535,7 @@ void tst_QTextLayout::softHyphens()
line.setPosition(QPoint(0, y));
QCOMPARE(line.textStart(), pos);
QCOMPARE(line.textLength(), 4);
- QVERIFY(qAbs(line.naturalTextWidth() - 4 * xAdvance) <= 1);
+ QVERIFY(qAbs(line.naturalTextWidth() - qCeil(4 * xAdvance)) <= 1.0);
pos += line.textLength();
y += qRound(line.ascent() + line.descent());
@@ -2520,7 +2545,7 @@ void tst_QTextLayout::softHyphens()
line.setPosition(QPoint(0, y));
QCOMPARE(line.textStart(), pos);
QCOMPARE(line.textLength(), 5);
- QVERIFY(qAbs(line.naturalTextWidth() - 4 * xAdvance) <= 1);
+ QVERIFY(qAbs(line.naturalTextWidth() - qCeil(4 * xAdvance)) <= 1.0);
pos += line.textLength();
y += qRound(line.ascent() + line.descent());
@@ -2530,7 +2555,7 @@ void tst_QTextLayout::softHyphens()
line.setPosition(QPoint(0, y));
QCOMPARE(line.textStart(), pos);
QCOMPARE(line.textLength(), 1);
- QVERIFY(qAbs(line.naturalTextWidth() - shyAdvance) <= 1);
+ QVERIFY(qAbs(line.naturalTextWidth() - shyWidth) <= 1.0);
layout.endLayout();
}
}
diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
index 474079037b..7d4921203c 100644
--- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
+++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
@@ -29,7 +29,7 @@
#include <QtTest/QtTest>
-
+#include <qbuffer.h>
#include <qtextdocument.h>
#include <qtextdocumentfragment.h>
#include <qtexttable.h>
@@ -44,6 +44,7 @@
#include <QPainter>
#include <QPaintEngine>
#endif
+#include <private/qtextdocumentlayout_p.h>
#include <private/qpagedpaintdevice_p.h>
typedef QList<int> IntList;
@@ -100,6 +101,13 @@ private slots:
void checkBorderAttributes_data();
void checkBorderAttributes();
+#ifndef QT_NO_WIDGETS
+ void columnWidthWithSpans();
+
+ void columnWidthWithImage_data();
+ void columnWidthWithImage();
+#endif
+
private:
QTextTable *create2x2Table();
QTextTable *create4x4Table();
@@ -1278,5 +1286,84 @@ void tst_QTextTable::checkBorderAttributes()
}
}
+#ifndef QT_NO_WIDGETS
+void tst_QTextTable::columnWidthWithSpans()
+{
+ cleanup();
+ init();
+ QTextTable *table = cursor.insertTable(4, 4);
+ QTextEdit textEdit;
+ textEdit.setDocument(doc);
+ textEdit.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&textEdit));
+
+ for (int i = 0; i < table->columns(); ++i)
+ table->cellAt(0, i).firstCursorPosition().insertText(QString("Header %1").arg(i));
+
+ QTextBlock block = table->cellAt(0, 0).firstCursorPosition().block();
+ const QRectF beforeRect = table->document()->documentLayout()->blockBoundingRect(block);
+ table->mergeCells(1, 0, 1, table->columns());
+ block = table->cellAt(0, 0).firstCursorPosition().block();
+ const QRectF afterRect = table->document()->documentLayout()->blockBoundingRect(block);
+ QCOMPARE(afterRect, beforeRect);
+}
+
+void tst_QTextTable::columnWidthWithImage_data()
+{
+ const auto imageHtml = [](int width, int height) {
+ QImage image(width, height, QImage::Format_RGB32);
+ image.fill(Qt::red);
+ QByteArray imageBytes;
+ QBuffer buffer(&imageBytes);
+ buffer.open(QIODevice::WriteOnly);
+ image.save(&buffer, "png");
+ return QString("<td><img src='data:image/png;base64,%1'/></td>")
+ .arg(QString::fromLatin1(imageBytes.toBase64()));
+ };
+
+ QTest::addColumn<QString>("leftHtml");
+ QTest::addColumn<QString>("rightHtml");
+ QTest::addColumn<QSize>("imageSize");
+ QTest::addRow("image")
+ << imageHtml(500, 32) << "<td></td>" << QSize(500, 32);
+ QTest::addRow("image, text")
+ << imageHtml(32, 32) << "<td>abc</td>" << QSize(32, 32);
+ QTest::addRow("image, 100%% text")
+ << imageHtml(32, 32) << "<td style='background-color: grey' width='100%'>abc</td>"
+ << QSize(32, 32);
+ QTest::addRow("image, image")
+ << imageHtml(256, 32) << imageHtml(256, 32) << QSize(256, 32);
+}
+
+void tst_QTextTable::columnWidthWithImage()
+{
+ const QString tableTemplate = "<table><tr>%1 %2</tr></table>";
+
+ QFETCH(QString, leftHtml);
+ QFETCH(QString, rightHtml);
+ QFETCH(QSize, imageSize);
+
+ QTextDocument doc;
+ doc.setHtml(tableTemplate.arg(leftHtml).arg(rightHtml));
+ QTextEdit textEdit;
+ textEdit.setDocument(&doc);
+ textEdit.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&textEdit));
+
+ QTextCursor cursor(doc.firstBlock());
+ cursor.movePosition(QTextCursor::Right);
+
+ QTextTable *currentTable = cursor.currentTable();
+ QVERIFY(currentTable);
+
+ QTextBlock block = currentTable->cellAt(0, 0).firstCursorPosition().block();
+ const QRectF leftRect = currentTable->document()->documentLayout()->blockBoundingRect(block);
+ block = currentTable->cellAt(0, 1).firstCursorPosition().block();
+ const QRectF rightRect = currentTable->document()->documentLayout()->blockBoundingRect(block);
+ QCOMPARE(leftRect.size().toSize(), imageSize);
+ QVERIFY(rightRect.left() > leftRect.right());
+}
+#endif
+
QTEST_MAIN(tst_QTextTable)
#include "tst_qtexttable.moc"
diff --git a/tests/auto/network/access/qdecompresshelper/BLACKLIST b/tests/auto/network/access/qdecompresshelper/BLACKLIST
new file mode 100644
index 0000000000..d189fd9e00
--- /dev/null
+++ b/tests/auto/network/access/qdecompresshelper/BLACKLIST
@@ -0,0 +1,2 @@
+[bigZlib]
+macos arm
diff --git a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp
index cec05f8806..6ae53e2ccd 100644
--- a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp
+++ b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp
@@ -48,6 +48,8 @@ private Q_SLOTS:
void ntlmAuth_data();
void ntlmAuth();
+ void sha256AndMd5Digest();
+
void equalityOperators();
};
@@ -149,6 +151,34 @@ void tst_QAuthenticator::ntlmAuth()
QVERIFY(priv->calculateResponse("GET", "/", "").startsWith("NTLM "));
}
+// We don't (currently) support SHA256. So, when presented with the option of MD5 or SHA256,
+// we should always pick MD5.
+void tst_QAuthenticator::sha256AndMd5Digest()
+{
+ QByteArray md5 = "Digest realm=\"\", nonce=\"\", algorithm=MD5, qop=\"auth\"";
+ QByteArray sha256 = "Digest realm=\"\", nonce=\"\", algorithm=SHA-256, qop=\"auth\"";
+
+ QAuthenticator auth;
+ auth.setUser("unimportant");
+ auth.setPassword("unimportant");
+
+ QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth);
+
+ QCOMPARE(priv->phase, QAuthenticatorPrivate::Start);
+ QList<QPair<QByteArray, QByteArray>> headers;
+ // Put sha256 first, so that its parsed first...
+ headers.push_back({"WWW-Authenticate", sha256});
+ headers.push_back({"WWW-Authenticate", md5});
+ priv->parseHttpResponse(headers, false, QString());
+
+ QByteArray response = priv->calculateResponse("GET", "/index", {});
+ QCOMPARE(priv->phase, QAuthenticatorPrivate::Done);
+
+ QVERIFY(!response.isEmpty());
+ QVERIFY(!response.contains("algorithm=SHA-256"));
+ QVERIFY(response.contains("algorithm=MD5"));
+}
+
void tst_QAuthenticator::equalityOperators()
{
QAuthenticator s1, s2;
diff --git a/tests/auto/network/socket/qtcpserver/BLACKLIST b/tests/auto/network/socket/qtcpserver/BLACKLIST
index e268468bdb..c6d4d49908 100644
--- a/tests/auto/network/socket/qtcpserver/BLACKLIST
+++ b/tests/auto/network/socket/qtcpserver/BLACKLIST
@@ -14,3 +14,6 @@ windows-10
windows-7sp1
windows-10
+[linkLocal]
+macos arm
+
diff --git a/tests/auto/network/socket/qtcpsocket/BLACKLIST b/tests/auto/network/socket/qtcpsocket/BLACKLIST
index 129e9f0b4e..fb57715a49 100644
--- a/tests/auto/network/socket/qtcpsocket/BLACKLIST
+++ b/tests/auto/network/socket/qtcpsocket/BLACKLIST
@@ -2,3 +2,5 @@
windows
# QTBUG-66247
+[bind]
+macos arm
diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST
index 40e06ca10a..690d814a2c 100644
--- a/tests/auto/network/socket/qudpsocket/BLACKLIST
+++ b/tests/auto/network/socket/qudpsocket/BLACKLIST
@@ -7,3 +7,7 @@ opensuse-leap
opensuse-42.3
[readyReadForEmptyDatagram]
linux
+[multicast]
+macos arm
+[linkLocalIPv6]
+macos arm
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index a40ec30622..0dc211dc7d 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -1623,6 +1623,9 @@ void tst_QSslSocket::setSocketDescriptor()
void tst_QSslSocket::setSslConfiguration_data()
{
+#if QT_CONFIG(securetransport)
+ QSKIP("Skipping the cases with certificate, SecureTransport does not like old certificate on the test server");
+#endif // securetransport
QTest::addColumn<QSslConfiguration>("configuration");
QTest::addColumn<bool>("works");
diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp
index 7c43c52236..c5441770f3 100644
--- a/tests/auto/opengl/qgl/tst_qgl.cpp
+++ b/tests/auto/opengl/qgl/tst_qgl.cpp
@@ -44,6 +44,7 @@
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
#include <QVBoxLayout>
+#include <QOperatingSystemVersion>
#ifdef QT_BUILD_INTERNAL
#include <qpa/qplatformpixmap.h>
@@ -2537,6 +2538,10 @@ public:
void tst_QGL::closeAndThenShow()
{
+#ifdef Q_OS_MACOS
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSBigSur)
+ QSKIP("Test is crashing flaky on macos-11.0 - QTBUG-96271");
+#endif
QWidget *w = new QWidget;
w->resize(640, 480);
QVBoxLayout *layout = new QVBoxLayout(w);
diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
index d97a0db939..174d86a941 100644
--- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
+++ b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
@@ -86,6 +86,7 @@ QDebug operator<<(QDebug dbg, AXErrorTag err)
return false; \
} \
+#define TRY_EXPECT(cond) EXPECT(QTest::qWaitFor([&]{ return (cond); }))
@interface TestAXObject : NSObject
{
@@ -546,21 +547,17 @@ bool notifications(QWidget *w)
EXPECT(notificationList.length() == 0);
le2->setFocus();
- QCoreApplication::processEvents();
- EXPECT(notificationList.length() == 1);
- EXPECT(notificationList.at(0) == QAccessible::Focus);
+ TRY_EXPECT(notificationList.length() == 1);
+ TRY_EXPECT(notificationList.at(0) == QAccessible::Focus);
le1->setFocus();
- QCoreApplication::processEvents();
- EXPECT(notificationList.length() == 2);
- EXPECT(notificationList.at(1) == QAccessible::Focus);
+ TRY_EXPECT(notificationList.length() == 2);
+ TRY_EXPECT(notificationList.at(1) == QAccessible::Focus);
le1->setText("hello");
- QCoreApplication::processEvents();
- EXPECT(notificationList.length() == 3);
- EXPECT(notificationList.at(2) == QAccessible::ValueChanged);
+ TRY_EXPECT(notificationList.length() == 3);
+ TRY_EXPECT(notificationList.at(2) == QAccessible::ValueChanged);
le1->setText("foo");
- QCoreApplication::processEvents();
- EXPECT(notificationList.length() == 4);
- EXPECT(notificationList.at(3) == QAccessible::ValueChanged);
+ TRY_EXPECT(notificationList.length() == 4);
+ TRY_EXPECT(notificationList.at(3) == QAccessible::ValueChanged);
return true;
}
diff --git a/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp b/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
index 9fc490417c..fc12738604 100644
--- a/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
+++ b/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
@@ -112,12 +112,16 @@ void tst_VerifyExceptionThrown::testCorrectMyExceptions() const
void tst_VerifyExceptionThrown::testFailInt() const
{
- QVERIFY_EXCEPTION_THROWN(throw int(5), double);
+ try {
+ QVERIFY_EXCEPTION_THROWN(throw int(5), double);
+ } catch (int) {}
}
void tst_VerifyExceptionThrown::testFailStdString() const
{
- QVERIFY_EXCEPTION_THROWN(throw std::string("some string"), char*);
+ try {
+ QVERIFY_EXCEPTION_THROWN(throw std::string("some string"), char*);
+ } catch (const std::string &) {}
}
void tst_VerifyExceptionThrown::testFailStdRuntimeError() const
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index 29158faf95..56448c1723 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -47,6 +47,7 @@
#include <QStringListModel>
#include <QStyledItemDelegate>
#include <QTableWidget>
+#include <QTimer>
#include <QTreeWidget>
#include <QTest>
#include <QVBoxLayout>
@@ -152,6 +153,8 @@ private slots:
void dragSelectAfterNewPress();
void dragWithSecondClick_data();
void dragWithSecondClick();
+ void clickAfterDoubleClick();
+
private:
static QAbstractItemView *viewFromString(const QByteArray &viewType, QWidget *parent = nullptr)
{
@@ -2606,5 +2609,41 @@ void tst_QAbstractItemView::dragWithSecondClick()
QTest::mouseRelease(view->viewport(), Qt::LeftButton, Qt::NoModifier, dragTo);
}
+void tst_QAbstractItemView::clickAfterDoubleClick()
+{
+ QTableWidget view(5, 5);
+ view.horizontalHeader()->hide();
+ view.verticalHeader()->hide();
+ view.setEditTriggers(QAbstractItemView::NoEditTriggers);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ const QModelIndex index = view.model()->index(1, 1);
+ QVERIFY(index.isValid());
+ const QPoint clickPoint = view.visualRect(index).center();
+
+ // must use the QWindow overloads so that modality is respected
+ QWindow *window = view.window()->windowHandle();
+ int clickCount = 0;
+
+ connect(&view, &QAbstractItemView::doubleClicked, [&]{
+ QDialog dialog(&view);
+ dialog.setModal(true);
+ QTimer::singleShot(0, [&]{ dialog.close(); });
+ dialog.exec();
+ });
+ connect(&view, &QAbstractItemView::clicked, [&]{
+ ++clickCount;
+ });
+
+ QTest::mouseClick(window, Qt::LeftButton, {}, clickPoint);
+ QCOMPARE(clickCount, 1);
+ // generates a click followed by a double click; double click opens
+ // dialog that eats second release
+ QTest::mouseDClick(window, Qt::LeftButton, {}, clickPoint);
+ QCOMPARE(clickCount, 2);
+ QTest::mouseClick(window, Qt::LeftButton, {}, clickPoint);
+ QCOMPARE(clickCount, 3);
+}
+
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"
diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST
index ec38d565e4..1f1e3804fc 100644
--- a/tests/auto/widgets/kernel/qwidget/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST
@@ -25,6 +25,8 @@ macos
osx
[optimizedResize_topLevel]
osx
+[render_windowOpacity]
+macos arm
[render_systemClip]
osx
[showMinimizedKeepsFocus]
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 1a72ca298f..2b11aec902 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -186,6 +186,7 @@ private slots:
void defaultTabOrder();
void reverseTabOrder();
void tabOrderWithProxy();
+ void tabOrderWithProxyDisabled();
void tabOrderWithCompoundWidgets();
void tabOrderWithCompoundWidgetsNoFocusPolicy();
void tabOrderNoChange();
@@ -366,6 +367,8 @@ private slots:
void focusWidget_task254563();
void rectOutsideCoordinatesLimit_task144779();
void setGraphicsEffect();
+ void render_graphicsEffect_data();
+ void render_graphicsEffect();
#ifdef QT_BUILD_INTERNAL
void destroyBackingStore();
@@ -2006,6 +2009,57 @@ void tst_QWidget::tabOrderWithProxy()
QVERIFY(firstEdit->hasFocus());
}
+void tst_QWidget::tabOrderWithProxyDisabled()
+{
+ Container container;
+ container.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
+
+ QLineEdit lineEdit1;
+ lineEdit1.setObjectName("lineEdit1");
+
+ QWidget containingWidget;
+ containingWidget.setFocusPolicy(Qt::StrongFocus);
+ auto *containingLayout = new QVBoxLayout;
+ QLineEdit lineEdit2;
+ lineEdit2.setObjectName("lineEdit2");
+ QLineEdit lineEdit3;
+ lineEdit3.setObjectName("lineEdit3");
+ containingLayout->addWidget(&lineEdit2);
+ containingLayout->addWidget(&lineEdit3);
+ containingWidget.setLayout(containingLayout);
+ containingWidget.setFocusProxy(&lineEdit2);
+ lineEdit2.setEnabled(false);
+
+ container.box->addWidget(&lineEdit1);
+ container.box->addWidget(&containingWidget);
+
+ container.show();
+ container.activateWindow();
+
+ QApplication::setActiveWindow(&container);
+ if (!QTest::qWaitForWindowActive(&container))
+ QSKIP("Window failed to activate, skipping test");
+
+ QVERIFY2(lineEdit1.hasFocus(),
+ qPrintable(QApplication::focusWidget()->objectName()));
+ container.tab();
+ QVERIFY2(!lineEdit2.hasFocus(),
+ qPrintable(QApplication::focusWidget()->objectName()));
+ QVERIFY2(lineEdit3.hasFocus(),
+ qPrintable(QApplication::focusWidget()->objectName()));
+ container.tab();
+ QVERIFY2(lineEdit1.hasFocus(),
+ qPrintable(QApplication::focusWidget()->objectName()));
+ container.backTab();
+ QVERIFY2(lineEdit3.hasFocus(),
+ qPrintable(QApplication::focusWidget()->objectName()));
+ container.backTab();
+ QVERIFY2(!lineEdit2.hasFocus(),
+ qPrintable(QApplication::focusWidget()->objectName()));
+ QVERIFY2(lineEdit1.hasFocus(),
+ qPrintable(QApplication::focusWidget()->objectName()));
+}
+
void tst_QWidget::tabOrderWithCompoundWidgets()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
@@ -10096,6 +10150,157 @@ void tst_QWidget::setGraphicsEffect()
QVERIFY(!blurEffect);
}
+
+class TestGraphicsEffect : public QGraphicsEffect
+{
+public:
+ TestGraphicsEffect(QObject *parent = nullptr)
+ : QGraphicsEffect(parent)
+ {
+ m_pattern = QPixmap(10, 10);
+ m_pattern.fill(Qt::lightGray);
+ QPainter p(&m_pattern);
+ p.fillRect(QRectF(0, 0, 5, 5), QBrush(Qt::darkGray));
+ p.fillRect(QRectF(5, 5, 5, 5), QBrush(Qt::darkGray));
+ }
+ void setExtent(int extent)
+ {
+ m_extent = extent;
+ }
+ QRectF boundingRectFor(const QRectF &sr) const override
+ {
+ return QRectF(sr.x() - m_extent, sr.y() - m_extent,
+ sr.width() + 2 * m_extent, sr.height() + 2 * m_extent);
+ }
+protected:
+ void draw(QPainter *painter) override
+ {
+ QBrush brush;
+ brush.setTexture(m_pattern);
+ brush.setStyle(Qt::TexturePattern);
+ QPaintDevice *p = painter->device();
+ painter->fillRect(QRect(-m_extent, -m_extent,
+ p->width() + m_extent, p->height() + m_extent), brush);
+ }
+ QPixmap m_pattern;
+ int m_extent = 0;
+};
+
+static QImage fillExpected1()
+{
+ QImage expected(QSize(40, 40), QImage::Format_RGB32);
+ QPainter p(&expected);
+ p.fillRect(QRect{{0, 0}, expected.size()}, QBrush(Qt::gray));
+ p.fillRect(QRect(10, 10, 10, 10), QBrush(Qt::red));
+ p.fillRect(QRect(20, 20, 10, 10), QBrush(Qt::blue));
+ return expected;
+}
+static QImage fillExpected2()
+{
+ QImage expected = fillExpected1();
+ QPainter p(&expected);
+ p.fillRect(QRect(10, 10, 5, 5), QBrush(Qt::darkGray));
+ p.fillRect(QRect(15, 15, 5, 5), QBrush(Qt::darkGray));
+ p.fillRect(QRect(15, 10, 5, 5), QBrush(Qt::lightGray));
+ p.fillRect(QRect(10, 15, 5, 5), QBrush(Qt::lightGray));
+ return expected;
+}
+static QImage fillExpected3()
+{
+ QImage expected(QSize(40, 40), QImage::Format_RGB32);
+ QPixmap pattern;
+ pattern = QPixmap(10, 10);
+ pattern.fill(Qt::lightGray);
+ QPainter p(&pattern);
+ p.fillRect(QRectF(0, 0, 5, 5), QBrush(Qt::darkGray));
+ p.fillRect(QRectF(5, 5, 5, 5), QBrush(Qt::darkGray));
+ QBrush brush;
+ brush.setTexture(pattern);
+ brush.setStyle(Qt::TexturePattern);
+ QPainter p2(&expected);
+ p2.fillRect(QRect{{0, 0}, expected.size()}, brush);
+ return expected;
+}
+static QImage fillExpected4()
+{
+ QImage expected = fillExpected1();
+ QPixmap pattern;
+ pattern = QPixmap(10, 10);
+ pattern.fill(Qt::lightGray);
+ QPainter p(&pattern);
+ p.fillRect(QRectF(0, 0, 5, 5), QBrush(Qt::darkGray));
+ p.fillRect(QRectF(5, 5, 5, 5), QBrush(Qt::darkGray));
+ QBrush brush;
+ brush.setTexture(pattern);
+ brush.setStyle(Qt::TexturePattern);
+ QPainter p2(&expected);
+ p2.fillRect(QRect{{15, 15}, QSize{20, 20}}, brush);
+ return expected;
+}
+
+void tst_QWidget::render_graphicsEffect_data()
+{
+ QTest::addColumn<QImage>("expected");
+ QTest::addColumn<bool>("topLevelEffect");
+ QTest::addColumn<bool>("child1Effect");
+ QTest::addColumn<bool>("child2Effect");
+ QTest::addColumn<int>("extent");
+
+ QTest::addRow("no_effect") << fillExpected1() << false << false << false << 0;
+ QTest::addRow("first_child_effect") << fillExpected2() << false << true << false << 0;
+ QTest::addRow("top_level_effect") << fillExpected3() << true << false << false << 0;
+ QTest::addRow("effect_with_extent") << fillExpected4() << false << false << true << 5;
+}
+
+void tst_QWidget::render_graphicsEffect()
+{
+ QFETCH(QImage, expected);
+ QFETCH(bool, topLevelEffect);
+ QFETCH(bool, child1Effect);
+ QFETCH(bool, child2Effect);
+ QFETCH(int, extent);
+
+ QScopedPointer<QWidget> topLevel(new QWidget);
+ topLevel->setPalette(Qt::gray);
+ topLevel->resize(40, 40);
+ topLevel->setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1String("::")
+ + QLatin1String(QTest::currentDataTag()));
+
+ // Render widget with 2 child widgets
+ QImage image(topLevel->size(), QImage::Format_RGB32);
+ image.fill(QColor(Qt::gray).rgb());
+
+ QPainter painter(&image);
+
+ QWidget *childWidget1(new QWidget(topLevel.data()));
+ childWidget1->setAutoFillBackground(true);
+ childWidget1->setPalette(Qt::red);
+ childWidget1->resize(10, 10);
+ childWidget1->move(10, 10);
+ QWidget *childWidget2(new QWidget(topLevel.data()));
+ childWidget2->setAutoFillBackground(true);
+ childWidget2->setPalette(Qt::blue);
+ childWidget2->resize(10, 10);
+ childWidget2->move(20, 20);
+
+ TestGraphicsEffect *graphicsEffect(new TestGraphicsEffect(topLevel.data()));
+ if (topLevelEffect)
+ topLevel->setGraphicsEffect(graphicsEffect);
+ if (child1Effect)
+ childWidget1->setGraphicsEffect(graphicsEffect);
+ if (child2Effect)
+ childWidget2->setGraphicsEffect(graphicsEffect);
+ graphicsEffect->setExtent(extent);
+
+ // Render without effect
+ topLevel->render(&painter);
+#ifdef RENDER_DEBUG
+ image.save("render_GraphicsEffect" + QTest::currentDataTag() + ".png");
+ expected.save("render_GraphicsEffect_expected" + QTest::currentDataTag() + ".png");
+#endif
+ QCOMPARE(image, expected);
+}
+
void tst_QWidget::activateWindow()
{
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
diff --git a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp
index 01ecfb2ca9..ec1013a078 100644
--- a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp
+++ b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp
@@ -37,6 +37,7 @@
#include <qlabel.h>
#include <qwidget.h>
#include <qdialog.h>
+#include <qscroller.h>
class tst_QAbstractScrollArea : public QObject
{
@@ -57,6 +58,7 @@ private slots:
void task214488_layoutDirection();
void margins();
+ void resizeWithOvershoot();
};
tst_QAbstractScrollArea::tst_QAbstractScrollArea()
@@ -398,5 +400,42 @@ void tst_QAbstractScrollArea::margins()
QCOMPARE(area.viewportMargins(), margins);
}
+void tst_QAbstractScrollArea::resizeWithOvershoot()
+{
+ QWidget window;
+
+ QScrollArea scrollArea(&window);
+ scrollArea.setWidget([]{
+ QWidget *widget = new QWidget;
+ widget->setFixedSize(QSize(0, 200));
+ return widget;
+ }());
+ scrollArea.setGeometry(0, 20, 100, 100);
+
+ QScroller::grabGesture(&scrollArea, QScroller::LeftMouseButtonGesture);
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ const QPoint originAtRest = scrollArea.viewport()->pos();
+
+ QPoint center = scrollArea.viewport()->mapToGlobal(scrollArea.viewport()->rect().center());
+ center = window.windowHandle()->mapFromGlobal(center);
+ QTest::mousePress(window.windowHandle(), Qt::LeftButton, {}, center);
+ QTest::mouseMove(window.windowHandle(), center + QPoint(0, 50));
+ QTRY_COMPARE(scrollArea.viewport()->pos(), originAtRest + QPoint(0, 25));
+ QPoint overshootPosition = scrollArea.viewport()->pos();
+
+ // trigger a layout of the scroll area while there's overshoot
+ scrollArea.setGeometry(0, 0, 100, 120);
+ QCOMPARE(scrollArea.viewport()->pos(), overshootPosition);
+ QTest::mouseRelease(window.windowHandle(), Qt::LeftButton, {}, center + QPoint(0, 50));
+ QTRY_COMPARE(scrollArea.viewport()->pos(), originAtRest);
+ // Process a few more events and verify that the scroll area
+ // doesn't overcompensate for the overshoot.
+ QApplication::processEvents();
+ QTRY_COMPARE(scrollArea.viewport()->pos(), originAtRest);
+}
+
QTEST_MAIN(tst_QAbstractScrollArea)
#include "tst_qabstractscrollarea.moc"
diff --git a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
index bd3ea5686a..75f595e959 100644
--- a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
+++ b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
@@ -261,15 +261,18 @@ void tst_QFontComboBox::writingSystem()
// protected void currentFontChanged(QFont const& f)
void tst_QFontComboBox::currentFontChanged()
{
- SubQFontComboBox box;
- QSignalSpy spy0(&box, SIGNAL(currentFontChanged(QFont)));
+ // The absence of this file does not affect the test results
+ QFontDatabase::addApplicationFont("ArianaVioleta-dz2K.ttf");
+
+ SubQFontComboBox *box = new SubQFontComboBox;
+ QSignalSpy spy0(box, SIGNAL(currentFontChanged(QFont)));
- if (box.model()->rowCount() > 2) {
- QTest::keyPress(&box, Qt::Key_Down);
+ if (box->model()->rowCount() > 2) {
+ QTest::keyPress(box, Qt::Key_Down);
QCOMPARE(spy0.count(), 1);
QFont f( "Sans Serif" );
- box.setCurrentFont(f);
+ box->setCurrentFont(f);
QCOMPARE(spy0.count(), 2);
} else
qWarning("Not enough fonts installed on test system. Consider adding some");