summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-04-20 11:19:14 +0200
committerLiang Qi <liang.qi@qt.io>2017-04-20 12:31:27 +0200
commit7950b6b283549c98f1e0f981c84b68071a13b616 (patch)
treecf7281872045ebd57c68e10064ff0f400084aa13 /tests/auto
parent58d2927861d3e57cac4f6db599e209d2bfb17a2c (diff)
parent0794d61c822585530243f638687b8a75f0a15d0c (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: src/corelib/tools/qbytearray.h src/corelib/tools/qdatetime.h src/corelib/tools/qstring.h src/corelib/tools/qversionnumber.h src/plugins/platforms/android/qandroidplatformintegration.cpp tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp Change-Id: Iefd92a435e687a76cd593099e40d9a9620a1454d
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/corelib/global/qlogging/app/app.pro6
-rw-r--r--tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp28
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp52
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+mac/test5 (renamed from tests/auto/corelib/io/qfileselector/platforms/+mac/test2)0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+macos/test (renamed from tests/auto/corelib/io/qfileselector/platforms/+osx/test2)0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+macos/test20
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+osx/test40
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+macos/test0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/+macos/test0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/test40
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/test50
-rw-r--r--tests/auto/corelib/io/qfileselector/qfileselector.qrc10
-rw-r--r--tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp8
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp4
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp3
-rw-r--r--tests/auto/corelib/plugin/quuid/tst_quuid.cpp15
-rw-r--r--tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp118
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp50
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp4
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp14
-rw-r--r--tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp4
-rw-r--r--tests/auto/gui/qopengl/tst_qopengl.cpp1
-rw-r--r--tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp7
-rw-r--r--tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp22
-rw-r--r--tests/auto/other/qfocusevent/tst_qfocusevent.cpp8
-rw-r--r--tests/auto/other/toolsupport/tst_toolsupport.cpp6
-rw-r--r--tests/auto/tools/qmake/tst_qmake.cpp1
-rw-r--r--tests/auto/widgets/effects/qpixmapfilter/tst_qpixmapfilter.cpp5
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp27
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp222
30 files changed, 558 insertions, 57 deletions
diff --git a/tests/auto/corelib/global/qlogging/app/app.pro b/tests/auto/corelib/global/qlogging/app/app.pro
index 8ada04acdc..6fba1b6129 100644
--- a/tests/auto/corelib/global/qlogging/app/app.pro
+++ b/tests/auto/corelib/global/qlogging/app/app.pro
@@ -11,5 +11,7 @@ CONFIG += console
SOURCES += main.cpp
DEFINES += QT_MESSAGELOGCONTEXT
-gcc:!mingw:!haiku: QMAKE_LFLAGS += -rdynamic
-
+gcc:!mingw:!haiku {
+ QMAKE_LFLAGS += -rdynamic
+ contains(QT_ARCH, arm): QMAKE_CXXFLAGS += -funwind-tables
+}
diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp
index 5b03b35780..0068411b94 100644
--- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp
+++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp
@@ -77,6 +77,9 @@ private slots:
void stream_QDateTime_data();
void stream_QDateTime();
+ void stream_nullptr_t_data();
+ void stream_nullptr_t();
+
void stream_QFont_data();
void stream_QFont();
@@ -187,6 +190,7 @@ private:
void writeQBrush(QDataStream *s);
void writeQColor(QDataStream *s);
void writeQByteArray(QDataStream *s);
+ void writenullptr_t(QDataStream *s);
#ifndef QT_NO_CURSOR
void writeQCursor(QDataStream *s);
#endif
@@ -216,6 +220,7 @@ private:
void readQBrush(QDataStream *s);
void readQColor(QDataStream *s);
void readQByteArray(QDataStream *s);
+ void readnullptr_t(QDataStream *s);
#ifndef QT_NO_CURSOR
void readQCursor(QDataStream *s);
#endif
@@ -1008,6 +1013,11 @@ void tst_QDataStream::writeQByteArray(QDataStream *s)
*s << d4;
}
+void tst_QDataStream::writenullptr_t(QDataStream *s)
+{
+ *s << nullptr;
+}
+
void tst_QDataStream::readQByteArray(QDataStream *s)
{
QByteArray test(qByteArrayData(dataIndex(QTest::currentDataTag())));
@@ -1016,6 +1026,13 @@ void tst_QDataStream::readQByteArray(QDataStream *s)
QCOMPARE(d4, test);
}
+void tst_QDataStream::readnullptr_t(QDataStream *s)
+{
+ std::nullptr_t ptr;
+ *s >> ptr;
+ QCOMPARE(ptr, nullptr);
+}
+
// ************************************
#ifndef QT_NO_CURSOR
static QCursor qCursorData(int index)
@@ -1263,6 +1280,17 @@ void tst_QDataStream::stream_QDateTime()
STREAM_IMPL(QDateTime);
}
+void tst_QDataStream::stream_nullptr_t_data()
+{
+ stream_data(1); // there's only one value possible
+}
+
+void tst_QDataStream::stream_nullptr_t()
+{
+ using namespace std;
+ STREAM_IMPL(nullptr_t);
+}
+
void tst_QDataStream::writeQDateTime(QDataStream *s)
{
QDateTime dt(qDateTimeData(dataIndex(QTest::currentDataTag())));
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index 330ff9312d..946620d61f 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2017 Intel Corporation.
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
@@ -101,6 +102,7 @@ private slots:
void mkdirRmdir_data();
void mkdirRmdir();
+ void mkdirOnSymlink();
void makedirReturnCode();
@@ -387,6 +389,56 @@ void tst_QDir::mkdirRmdir()
QVERIFY(!fi.exists());
}
+void tst_QDir::mkdirOnSymlink()
+{
+#ifndef Q_OS_UNIX
+ QSKIP("Test only valid on an OS that supports symlinks");
+#else
+ // Create the structure:
+ // .
+ // ├── symlink -> two/three
+ // └── two
+ // └── three
+ // so when we mkdir("symlink/../four/five"), we end up with:
+ // .
+ // ├── symlink -> two/three
+ // └── two
+ // ├── four
+ // │ └── five
+ // └── three
+
+ QDir dir;
+ struct Clean {
+ QDir &dir;
+ Clean(QDir &dir) : dir(dir) {}
+ ~Clean() { doClean(); }
+ void doClean() {
+ dir.rmpath("two/three");
+ dir.rmpath("two/four/five");
+ // in case the test fails, don't leave junk behind
+ dir.rmpath("four/five");
+ QFile::remove("symlink");
+ }
+ };
+ Clean clean(dir);
+ clean.doClean();
+
+ // create our structure:
+ dir.mkpath("two/three");
+ ::symlink("two/three", "symlink");
+
+ // try it:
+ QString path = "symlink/../four/five";
+ QVERIFY(dir.mkpath(path));
+ QFileInfo fi(path);
+ QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
+
+ path = "two/four/five";
+ fi.setFile(path);
+ QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
+#endif
+}
+
void tst_QDir::makedirReturnCode()
{
QString dirName = QString::fromLatin1("makedirReturnCode");
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+mac/test2 b/tests/auto/corelib/io/qfileselector/platforms/+mac/test5
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+mac/test2
+++ b/tests/auto/corelib/io/qfileselector/platforms/+mac/test5
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+osx/test2 b/tests/auto/corelib/io/qfileselector/platforms/+macos/test
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+osx/test2
+++ b/tests/auto/corelib/io/qfileselector/platforms/+macos/test
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+macos/test2 b/tests/auto/corelib/io/qfileselector/platforms/+macos/test2
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileselector/platforms/+macos/test2
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+osx/test4 b/tests/auto/corelib/io/qfileselector/platforms/+osx/test4
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileselector/platforms/+osx/test4
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+macos/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+macos/test
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+macos/test
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/+macos/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/+macos/test
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/+macos/test
diff --git a/tests/auto/corelib/io/qfileselector/platforms/test4 b/tests/auto/corelib/io/qfileselector/platforms/test4
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileselector/platforms/test4
diff --git a/tests/auto/corelib/io/qfileselector/platforms/test5 b/tests/auto/corelib/io/qfileselector/platforms/test5
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileselector/platforms/test5
diff --git a/tests/auto/corelib/io/qfileselector/qfileselector.qrc b/tests/auto/corelib/io/qfileselector/qfileselector.qrc
index ab7a4d7f23..ea9b8270e0 100644
--- a/tests/auto/corelib/io/qfileselector/qfileselector.qrc
+++ b/tests/auto/corelib/io/qfileselector/qfileselector.qrc
@@ -15,6 +15,7 @@
<file>platforms/test</file>
<file>platforms/+unix/+android/test</file>
<file>platforms/+unix/+darwin/+mac/+ios/test</file>
+ <file>platforms/+unix/+darwin/+mac/+osx/+macos/test</file>
<file>platforms/+unix/+darwin/+mac/+osx/test</file>
<file>platforms/+unix/+darwin/+mac/test</file>
<file>platforms/+unix/+darwin/test</file>
@@ -27,6 +28,7 @@
<file>platforms/+windows/test</file>
<file>platforms/+android/test</file>
<file>platforms/+ios/test</file>
+ <file>platforms/+macos/test</file>
<file>platforms/+osx/test</file>
<file>platforms/+darwin/test</file>
<file>platforms/+mac/test</file>
@@ -39,7 +41,7 @@
<file>platforms/test2</file>
<file>platforms/+android/test2</file>
<file>platforms/+ios/test2</file>
- <file>platforms/+osx/test2</file>
+ <file>platforms/+macos/test2</file>
<file>platforms/+haiku/test2</file>
<file>platforms/+linux/test2</file>
<file>platforms/+wince/test2</file>
@@ -50,5 +52,11 @@
<file>platforms/test3</file>
<file>platforms/+windows/test3</file>
<file>platforms/+unix/test3</file>
+
+ <!-- platforms/test4 and 5: special cases for macOS -->
+ <file>platforms/test4</file>
+ <file>platforms/+osx/test4</file>
+ <file>platforms/test5</file>
+ <file>platforms/+mac/test5</file>
</qresource>
</RCC>
diff --git a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp
index 8c2886f337..c537e43802 100644
--- a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp
+++ b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp
@@ -126,6 +126,14 @@ void tst_QFileSelector::basicTest_data()
QTest::newRow("platform3") << QString(":/platforms/test3") << QStringList()
<< expectedPlatform3File;
+#ifdef Q_OS_MACOS
+ // special case for compatibility code
+ QTest::newRow("osx-compat") << QString(":/platforms/test4") << QStringList()
+ << ":/platforms/+osx/test4";
+ QTest::newRow("mac-compat") << QString(":/platforms/test5") << QStringList()
+ << ":/platforms/+mac/test5";
+#endif
+
QString resourceTestPath(":/extras/test");
QString custom1("custom1");
QTest::newRow("custom1-noselector") << resourceTestPath << QStringList()
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 28c5c53744..f0a4ef9b42 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -716,8 +716,8 @@ void tst_QMetaType::flags_data()
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
QTest::newRow(#RealType) << MetaTypeId \
- << bool(!QTypeInfo<RealType>::isStatic) \
- << bool(QTypeInfo<RealType>::isComplex) \
+ << bool(QTypeInfoQuery<RealType>::isRelocatable) \
+ << bool(QTypeInfoQuery<RealType>::isComplex) \
<< bool(QtPrivate::IsPointerToTypeDerivedFromQObject<RealType>::Value) \
<< bool(std::is_enum<RealType>::value);
QT_FOR_EACH_STATIC_CORE_CLASS(ADD_METATYPE_TEST_ROW)
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 6cb23023c7..ac1e1c6b45 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -1512,10 +1512,11 @@ void tst_QVariant::operator_eq_eq_data()
// ### many other combinations missing
{
- // QUuid can convert to QString, but not the opposite
QUuid uuid(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
QTest::newRow("uuidstring") << QVariant(uuid) << QVariant(uuid.toString()) << true;
QTest::newRow("stringuuid") << QVariant(uuid.toString()) << QVariant(uuid) << true;
+ QTest::newRow("uuidbytearray") << QVariant(uuid) << QVariant(uuid.toByteArray()) << true;
+ QTest::newRow("bytearrayuuid") << QVariant(uuid.toByteArray()) << QVariant(uuid) << true;
}
{
diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
index cb45336d4c..d3102c7ee5 100644
--- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
+++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
@@ -392,9 +392,16 @@ void tst_QUuid::qvariant_conversion()
QUuid uuid = QUuid::createUuid();
QVariant v = QVariant::fromValue(uuid);
+ // QUuid -> QString
QVERIFY(v.canConvert<QString>());
QCOMPARE(v.toString(), uuid.toString());
QCOMPARE(v.value<QString>(), uuid.toString());
+
+ // QUuid -> QByteArray
+ QVERIFY(v.canConvert<QByteArray>());
+ QCOMPARE(v.toByteArray(), uuid.toByteArray());
+ QCOMPARE(v.value<QByteArray>(), uuid.toByteArray());
+
QVERIFY(!v.canConvert<int>());
QVERIFY(!v.canConvert<QStringList>());
@@ -403,6 +410,14 @@ void tst_QUuid::qvariant_conversion()
QCOMPARE(sv.type(), QVariant::String);
QVERIFY(sv.canConvert<QUuid>());
QCOMPARE(sv.value<QUuid>(), uuid);
+
+ // QString -> QUuid
+ {
+ QVariant sv = QVariant::fromValue(uuid.toByteArray());
+ QCOMPARE(sv.type(), QVariant::ByteArray);
+ QVERIFY(sv.canConvert<QUuid>());
+ QCOMPARE(sv.value<QUuid>(), uuid);
+ }
}
void tst_QUuid::darwinTypes()
diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
index a8ea9ccf27..dbfcf57955 100644
--- a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
+++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
@@ -37,12 +37,23 @@
class tst_QHashFunctions : public QObject
{
Q_OBJECT
+public:
+ enum {
+ // random value
+ RandomSeed = 1045982819
+ };
+ uint seed;
+
+public slots:
+ void initTestCase();
+ void init();
+
private Q_SLOTS:
void consistent();
void qhash();
void qhash_of_empty_and_null_qstring();
void qhash_of_empty_and_null_qbytearray();
- void fp_qhash_of_zero_is_zero();
+ void fp_qhash_of_zero_is_seed();
void qthash_data();
void qthash();
void range();
@@ -62,12 +73,27 @@ void tst_QHashFunctions::consistent()
}
}
+void tst_QHashFunctions::initTestCase()
+{
+ Q_STATIC_ASSERT(int(RandomSeed) > 0);
+
+ QTest::addColumn<uint>("seedValue");
+ QTest::newRow("zero-seed") << 0U;
+ QTest::newRow("non-zero-seed") << uint(RandomSeed);
+}
+
+void tst_QHashFunctions::init()
+{
+ QFETCH_GLOBAL(uint, seedValue);
+ seed = seedValue;
+}
+
void tst_QHashFunctions::qhash()
{
{
QBitArray a1;
QBitArray a2;
- QVERIFY(qHash(a1) == 0);
+ QCOMPARE(qHash(a1, seed), seed);
a1.resize(1);
a1.setBit(0, true);
@@ -75,53 +101,53 @@ void tst_QHashFunctions::qhash()
a2.resize(1);
a2.setBit(0, false);
- uint h1 = qHash(a1);
- uint h2 = qHash(a2);
+ uint h1 = qHash(a1, seed);
+ uint h2 = qHash(a2, seed);
- QVERIFY(h1 != h2);
+ QVERIFY(h1 != h2); // not guaranteed
a2.setBit(0, true);
- QVERIFY(h1 == qHash(a2));
+ QVERIFY(h1 == qHash(a2, seed));
a1.fill(true, 8);
a1.resize(7);
- h1 = qHash(a1);
+ h1 = qHash(a1, seed);
a2.fill(true, 7);
- h2 = qHash(a2);
+ h2 = qHash(a2, seed);
QVERIFY(h1 == h2);
a2.setBit(0, false);
- uint h3 = qHash(a2);
- QVERIFY(h2 != h3);
+ uint h3 = qHash(a2, seed);
+ QVERIFY(h2 != h3); // not guaranteed
a2.setBit(0, true);
- QVERIFY(h2 == qHash(a2));
+ QVERIFY(h2 == qHash(a2, seed));
a2.setBit(6, false);
- uint h4 = qHash(a2);
- QVERIFY(h2 != h4);
+ uint h4 = qHash(a2, seed);
+ QVERIFY(h2 != h4); // not guaranteed
a2.setBit(6, true);
- QVERIFY(h2 == qHash(a2));
+ QVERIFY(h2 == qHash(a2, seed));
- QVERIFY(h3 != h4);
+ QVERIFY(h3 != h4); // not guaranteed
}
{
QPair<int, int> p12(1, 2);
QPair<int, int> p21(2, 1);
- QVERIFY(qHash(p12) == qHash(p12));
- QVERIFY(qHash(p21) == qHash(p21));
- QVERIFY(qHash(p12) != qHash(p21));
+ QVERIFY(qHash(p12, seed) == qHash(p12, seed));
+ QVERIFY(qHash(p21, seed) == qHash(p21, seed));
+ QVERIFY(qHash(p12, seed) != qHash(p21, seed)); // not guaranteed
QPair<int, int> pA(0x12345678, 0x12345678);
QPair<int, int> pB(0x12345675, 0x12345675);
- QVERIFY(qHash(pA) != qHash(pB));
+ QVERIFY(qHash(pA, seed) != qHash(pB, seed)); // not guaranteed
}
{
@@ -130,14 +156,14 @@ void tst_QHashFunctions::qhash()
using QT_PREPEND_NAMESPACE(qHash);
- QVERIFY(qHash(p12) == qHash(p12));
- QVERIFY(qHash(p21) == qHash(p21));
- QVERIFY(qHash(p12) != qHash(p21));
+ QVERIFY(qHash(p12, seed) == qHash(p12, seed));
+ QVERIFY(qHash(p21, seed) == qHash(p21, seed));
+ QVERIFY(qHash(p12, seed) != qHash(p21, seed)); // not guaranteed
std::pair<int, int> pA(0x12345678, 0x12345678);
std::pair<int, int> pB(0x12345675, 0x12345675);
- QVERIFY(qHash(pA) != qHash(pB));
+ QVERIFY(qHash(pA, seed) != qHash(pB, seed)); // not guaranteed
}
}
@@ -145,35 +171,35 @@ void tst_QHashFunctions::qhash_of_empty_and_null_qstring()
{
QString null, empty("");
QCOMPARE(null, empty);
- QCOMPARE(qHash(null), qHash(empty));
+ QCOMPARE(qHash(null, seed), qHash(empty, seed));
QStringRef nullRef, emptyRef(&empty);
QCOMPARE(nullRef, emptyRef);
- QCOMPARE(qHash(nullRef), qHash(emptyRef));
+ QCOMPARE(qHash(nullRef, seed), qHash(emptyRef, seed));
QStringView nullView, emptyView(empty);
QCOMPARE(nullView, emptyView);
- QCOMPARE(qHash(nullView), qHash(emptyView));
+ QCOMPARE(qHash(nullView, seed), qHash(emptyView, seed));
}
void tst_QHashFunctions::qhash_of_empty_and_null_qbytearray()
{
QByteArray null, empty("");
QCOMPARE(null, empty);
- QCOMPARE(qHash(null), qHash(empty));
+ QCOMPARE(qHash(null, seed), qHash(empty, seed));
}
-void tst_QHashFunctions::fp_qhash_of_zero_is_zero()
+void tst_QHashFunctions::fp_qhash_of_zero_is_seed()
{
- QCOMPARE(qHash(-0.0f), 0U);
- QCOMPARE(qHash( 0.0f), 0U);
+ QCOMPARE(qHash(-0.0f, seed), seed);
+ QCOMPARE(qHash( 0.0f, seed), seed);
- QCOMPARE(qHash(-0.0 ), 0U);
- QCOMPARE(qHash( 0.0 ), 0U);
+ QCOMPARE(qHash(-0.0 , seed), seed);
+ QCOMPARE(qHash( 0.0 , seed), seed);
#ifndef Q_OS_DARWIN
- QCOMPARE(qHash(-0.0L), 0U);
- QCOMPARE(qHash( 0.0L), 0U);
+ QCOMPARE(qHash(-0.0L, seed), seed);
+ QCOMPARE(qHash( 0.0L, seed), seed);
#endif
}
@@ -208,10 +234,10 @@ void tst_QHashFunctions::range()
static const size_t numInts = sizeof ints / sizeof *ints;
// empty range just gives the seed:
- QCOMPARE(qHashRange(ints, ints, 0xdeadbeefU), 0xdeadbeefU);
- // verify that order matters:
- QVERIFY(qHashRange(ints, ints + numInts) !=
- qHashRange(std::reverse_iterator<const int*>(ints + numInts), std::reverse_iterator<const int*>(ints)));
+ QCOMPARE(qHashRange(ints, ints, seed), seed);
+ // verify that order matters (test not guaranteed):
+ QVERIFY(qHashRange(ints, ints + numInts, seed) !=
+ qHashRange(std::reverse_iterator<const int*>(ints + numInts), std::reverse_iterator<const int*>(ints), seed));
{
// verify that the input iterator category suffices:
@@ -220,13 +246,13 @@ void tst_QHashFunctions::range()
std::copy(ints, ints + numInts, std::ostream_iterator<int>(sstream, " "));
sstream.seekg(0);
std::istream_iterator<int> it(sstream), end;
- QCOMPARE(qHashRange(ints, ints + numInts), qHashRange(it, end));
+ 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);
+ (void)qHashRange(hashables, hashables + numHashables, seed);
}
void tst_QHashFunctions::rangeCommutative()
@@ -235,10 +261,10 @@ void tst_QHashFunctions::rangeCommutative()
static const size_t numInts = sizeof ints / sizeof *ints;
// empty range just gives the seed:
- QCOMPARE(qHashRangeCommutative(ints, ints, 0xdeadbeefU), 0xdeadbeefU);
- // verify that order doesn't matter:
- QCOMPARE(qHashRangeCommutative(ints, ints + numInts),
- qHashRangeCommutative(std::reverse_iterator<int*>(ints + numInts), std::reverse_iterator<int*>(ints)));
+ QCOMPARE(qHashRangeCommutative(ints, ints, seed), seed);
+ // verify that order doesn't matter (test not guaranteed):
+ QCOMPARE(qHashRangeCommutative(ints, ints + numInts, seed),
+ qHashRangeCommutative(std::reverse_iterator<int*>(ints + numInts), std::reverse_iterator<int*>(ints), seed));
{
// verify that the input iterator category suffices:
@@ -246,13 +272,13 @@ void tst_QHashFunctions::rangeCommutative()
std::copy(ints, ints + numInts, std::ostream_iterator<int>(sstream, " "));
sstream.seekg(0);
std::istream_iterator<int> it(sstream), end;
- QCOMPARE(qHashRangeCommutative(ints, ints + numInts), qHashRangeCommutative(it, end));
+ 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);
+ (void)qHashRangeCommutative(hashables, hashables + numHashables, seed);
}
void tst_QHashFunctions::setGlobalQHashSeed()
diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
index d0a0feb125..7850478602 100644
--- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
@@ -97,6 +97,8 @@ private slots:
void qvariantCast();
void sharedFromThis();
+ void constructorThrow();
+
void threadStressTest_data();
void threadStressTest();
void validConstructs();
@@ -2594,6 +2596,54 @@ void tst_QSharedPointer::sharedFromThis()
QCOMPARE(Data::destructorCounter, destructions + 6);
}
+#ifndef QT_NO_EXCEPTIONS
+class ThrowData: public Data
+{
+public:
+ static int childDestructorCounter;
+ static int childGenerationCounter;
+
+ ThrowData()
+ {
+ childGenerationCounter++;
+ throw QStringLiteral("Dummy exception");
+ }
+
+ ~ThrowData()
+ {
+ childDestructorCounter++;
+ }
+};
+int ThrowData::childDestructorCounter = 0;
+int ThrowData::childGenerationCounter = 0;
+#endif // !QT_NO_EXCEPTIONS
+
+void tst_QSharedPointer::constructorThrow()
+{
+#ifndef QT_NO_EXCEPTIONS
+ int generation = Data::generationCounter;
+ int destructorCounter = Data::destructorCounter;
+
+ int childGeneration = ThrowData::childGenerationCounter;
+ int childDestructorCounter = ThrowData::childDestructorCounter;
+
+ QSharedPointer<ThrowData> ptr;
+ QVERIFY_EXCEPTION_THROWN(ptr = QSharedPointer<ThrowData>::create(), QString);
+ QVERIFY(ptr.isNull());
+ QCOMPARE(ThrowData::childGenerationCounter, childGeneration + 1);
+ // destructor should never be called, if a constructor throws
+ // an exception
+ QCOMPARE(ThrowData::childDestructorCounter, childDestructorCounter);
+
+ QCOMPARE(Data::generationCounter, generation + 1);
+ // but base class constructor doesn't throw, so base class destructor
+ // should be called
+ QCOMPARE(Data::destructorCounter, destructorCounter + 1);
+#else
+ QSKIP("Needs exceptions");
+#endif // !QT_NO_EXCEPTIONS
+}
+
namespace ReentrancyWhileDestructing {
struct IB
{
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index 4a82d952ab..70ccc72630 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -5850,7 +5850,7 @@ void tst_QString::fromUtf16_char16()
void tst_QString::unicodeStrings()
{
-#ifdef Q_COMPILER_UNICODE_STRINGS
+#ifdef Q_STDLIB_UNICODE_STRINGS
QString s1, s2;
static const std::u16string u16str1(u"Hello Unicode World");
static const std::u32string u32str1(U"Hello Unicode World");
@@ -5865,7 +5865,7 @@ void tst_QString::unicodeStrings()
s1 = QString::fromStdU32String(std::u32string(U"\u221212\U000020AC\U00010000"));
QCOMPARE(s1, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
#else
- QSKIP("Compiler does not support C++11 unicode strings");
+ QSKIP("Standard Library does not support C++11 unicode strings");
#endif
}
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 21481e374d..fac785ac86 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -211,6 +211,8 @@ private slots:
void reinterpretAsFormat2();
+ void complexTransform8bit();
+
#ifdef Q_OS_DARWIN
void toCGImage_data();
void toCGImage();
@@ -3366,6 +3368,18 @@ void tst_QImage::reinterpretAsFormat2()
}
}
+void tst_QImage::complexTransform8bit()
+{
+ QImage img1(100, 100, QImage::Format_RGB32);
+ img1.fill(Qt::green);
+ img1 = img1.convertToFormat(QImage::Format_Indexed8);
+ QImage img2 = img1.transformed(QTransform().rotate(45), Qt::SmoothTransformation);
+ // Currently the format is always QImage::Format_ARGB32_Premultiplied, but it
+ // doesn't have to be, and if it becomes indexed this test is no longer be valid.
+ QVERIFY(img2.format() > QImage::Format_Indexed8);
+ QCOMPARE(img2.colorCount(), 0);
+}
+
#ifdef Q_OS_DARWIN
void tst_QImage::toCGImage_data()
diff --git a/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
index aea97a916e..c2c04b69c5 100644
--- a/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
+++ b/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
@@ -1227,6 +1227,10 @@ void tst_QMatrixNxN::multiply4x4()
QMatrix4x4 m5;
m5 = m1 * m2;
QVERIFY(isSame(m5, (const float *)m3Values));
+
+ QMatrix4x4 m1xm1 = m1 * m1;
+ m1 *= m1;
+ QCOMPARE(m1, m1xm1);
}
// Test matrix multiplication for 4x3 matrices.
diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp
index 87d93e0827..6d9456fa69 100644
--- a/tests/auto/gui/qopengl/tst_qopengl.cpp
+++ b/tests/auto/gui/qopengl/tst_qopengl.cpp
@@ -389,6 +389,7 @@ static bool fuzzyComparePixels(const QRgb testPixel, const QRgb refPixel, const
static void fuzzyCompareImages(const QImage &testImage, const QImage &referenceImage, const char* file, int line)
{
+ QCOMPARE(testImage.devicePixelRatio(), referenceImage.devicePixelRatio());
QCOMPARE(testImage.width(), referenceImage.width());
QCOMPARE(testImage.height(), referenceImage.height());
diff --git a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
index 39f7beca6f..f8dfdbd3b0 100644
--- a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
+++ b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
@@ -100,6 +100,7 @@ class tst_QOpenGlConfig : public QObject
Q_OBJECT
private slots:
+ void initTestCase();
void testConfiguration();
void testGlConfiguration();
void testBugList();
@@ -162,6 +163,12 @@ static void dumpConfiguration(QTextStream &str)
}
}
+void tst_QOpenGlConfig::initTestCase()
+{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+ QSKIP("OpenGL is not supported on this platform.");
+}
+
void tst_QOpenGlConfig::testConfiguration()
{
QString result;
diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
index ef1ad76161..764b99646b 100644
--- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
+++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
@@ -134,6 +134,7 @@ private slots:
void clearResources();
void setPlainText();
+ void toPlainText_data();
void toPlainText();
void toRawText();
@@ -2391,10 +2392,27 @@ void tst_QTextDocument::setPlainText()
QCOMPARE(doc->toPlainText(), s);
}
+void tst_QTextDocument::toPlainText_data()
+{
+ QTest::addColumn<QString>("html");
+ QTest::addColumn<QString>("expectedPlainText");
+
+ QTest::newRow("nbsp") << "Hello&nbsp;World" << "Hello World";
+ QTest::newRow("empty_div") << "<div></div>hello" << "hello";
+ QTest::newRow("br_and_p") << "<p>first<br></p><p>second<br></p>" << "first\n\nsecond\n";
+ QTest::newRow("div") << "first<div>second<br>third</div>fourth" << "first\nsecond\nthird\nfourth"; // <div> and </div> become newlines...
+ QTest::newRow("br_text_end_of_div") << "<div><div>first<br>moretext</div>second<br></div>" << "first\nmoretext\nsecond\n"; // ... when there is text before <div>
+ QTest::newRow("br_end_of_div_like_gmail") << "<div><div><div>first<br></div>second<br></div>third<br></div>" << "first\nsecond\nthird\n"; // ... and when there is text before </div>
+ QTest::newRow("p_and_div") << "<div><div>first<p>second</p></div>third</div>" << "first\nsecond\nthird";
+}
+
void tst_QTextDocument::toPlainText()
{
- doc->setHtml("Hello&nbsp;World");
- QCOMPARE(doc->toPlainText(), QLatin1String("Hello World"));
+ QFETCH(QString, html);
+ QFETCH(QString, expectedPlainText);
+
+ doc->setHtml(html);
+ QCOMPARE(doc->toPlainText(), expectedPlainText);
}
void tst_QTextDocument::toRawText()
diff --git a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
index 5137ba0c57..5bf39b3953 100644
--- a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
+++ b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
@@ -340,6 +340,14 @@ void tst_QFocusEvent::checkReason_ActiveWindow()
#if defined(Q_OS_IRIX)
QEXPECT_FAIL("", "IRIX requires explicit activateWindow(), so this test does not make any sense.", Abort);
#endif
+
+ if (!QGuiApplication::platformName().compare(QLatin1String("offscreen"), Qt::CaseInsensitive)
+ || !QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive)) {
+ // Activate window of testFocusWidget, focus in that window goes to childFocusWidgetOne
+ QWARN("Platforms offscreen and minimal require explicit activateWindow()");
+ testFocusWidget->activateWindow();
+ }
+
QTRY_VERIFY(childFocusWidgetOne->focusInEventRecieved);
QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
diff --git a/tests/auto/other/toolsupport/tst_toolsupport.cpp b/tests/auto/other/toolsupport/tst_toolsupport.cpp
index f93c8f825b..a78bdc34f1 100644
--- a/tests/auto/other/toolsupport/tst_toolsupport.cpp
+++ b/tests/auto/other/toolsupport/tst_toolsupport.cpp
@@ -124,7 +124,13 @@ void tst_toolsupport::offsets_data()
{
QTestData &data = QTest::newRow("QFilePrivate::fileName")
<< pmm_to_offsetof(&QFilePrivate::fileName);
+#ifdef Q_PROCESSOR_X86
+ // x86 32-bit has weird alignment rules. Refer to QtPrivate::AlignOf in
+ // qglobal.h for more details.
data << 168 << 248;
+#else
+ data << 172 << 248;
+#endif
}
#endif
diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp
index eed1fe1a56..10aabcf196 100644
--- a/tests/auto/tools/qmake/tst_qmake.cpp
+++ b/tests/auto/tools/qmake/tst_qmake.cpp
@@ -286,6 +286,7 @@ void tst_qmake::install_files()
QVERIFY( test_compiler.make( workDir, "install" ));
QVERIFY( test_compiler.exists( workDir + "/dist", "foo", Exe, "1.0.0" ));
QVERIFY( test_compiler.exists( workDir + "/dist", "test.txt", Plain, "1.0.0" ));
+ QCOMPARE(QFileInfo(workDir + "/test.txt").lastModified(), QFileInfo(workDir + "/dist/test.txt").lastModified());
QVERIFY( test_compiler.make( workDir, "uninstall" ));
QVERIFY( test_compiler.makeDistClean( workDir ));
diff --git a/tests/auto/widgets/effects/qpixmapfilter/tst_qpixmapfilter.cpp b/tests/auto/widgets/effects/qpixmapfilter/tst_qpixmapfilter.cpp
index 08f4944d49..7d7c1e79a9 100644
--- a/tests/auto/widgets/effects/qpixmapfilter/tst_qpixmapfilter.cpp
+++ b/tests/auto/widgets/effects/qpixmapfilter/tst_qpixmapfilter.cpp
@@ -390,6 +390,7 @@ QT_END_NAMESPACE
void tst_QPixmapFilter::blurIndexed8()
{
QImage img(16, 32, QImage::Format_Indexed8);
+ img.setDevicePixelRatio(2);
img.setColorCount(256);
for (int i = 0; i < 256; ++i)
img.setColor(i, qRgb(i, i, i));
@@ -399,9 +400,13 @@ void tst_QPixmapFilter::blurIndexed8()
QImage original = img;
qt_blurImage(img, 10, true, false);
QCOMPARE(original.size(), img.size());
+ QVERIFY2(qFuzzyCompare(img.devicePixelRatioF(), qreal(2)),
+ QByteArray::number(img.devicePixelRatioF()).constData());
original = img;
qt_blurImage(img, 10, true, true);
+ QVERIFY2(qFuzzyCompare(img.devicePixelRatioF(), qreal(2)),
+ QByteArray::number(img.devicePixelRatioF()).constData());
QCOMPARE(original.size(), QSize(img.height(), img.width()));
}
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index 330ce3a836..139aaa7371 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -310,6 +310,7 @@ private slots:
void shortcutOverrideOnReadonlyLineEdit_data();
void shortcutOverrideOnReadonlyLineEdit();
+ void QTBUG59957_clearButtonLeftmostAction();
protected slots:
void editingFinished();
@@ -4612,5 +4613,31 @@ void tst_QLineEdit::shortcutOverrideOnReadonlyLineEdit()
QCOMPARE(spy.count(), activationCount);
}
+void tst_QLineEdit::QTBUG59957_clearButtonLeftmostAction()
+{
+#ifndef QT_BUILD_INTERNAL
+ QSKIP("This test requires a developer build");
+#else
+ QLineEdit lineEdit;
+ lineEdit.setClearButtonEnabled(true);
+
+ auto clearButton = lineEdit.findChild<QLineEditIconButton *>();
+ QVERIFY(clearButton);
+
+ QPixmap pixmap(16, 16);
+ lineEdit.addAction(QIcon(pixmap), QLineEdit::TrailingPosition);
+ lineEdit.addAction(QIcon(pixmap), QLineEdit::TrailingPosition);
+
+ lineEdit.show();
+
+ const auto buttons = lineEdit.findChildren<QLineEditIconButton *>();
+ for (const auto button : buttons) {
+ if (button == clearButton)
+ continue;
+ QVERIFY(clearButton->x() < button->x());
+ }
+#endif // QT_BUILD_INTERNAL
+}
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index 1a06973304..35f75dbeab 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -55,6 +55,20 @@ static inline void centerOnScreen(QWidget *w, const QSize &size)
w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset);
}
+struct MenuMetrics {
+ int fw;
+ int hmargin;
+ int vmargin;
+ int tearOffHeight;
+
+ MenuMetrics(const QMenu *menu) {
+ fw = menu->style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, menu);
+ hmargin = menu->style()->pixelMetric(QStyle::PM_MenuHMargin, nullptr, menu);
+ vmargin = menu->style()->pixelMetric(QStyle::PM_MenuVMargin, nullptr, menu);
+ tearOffHeight = menu->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, nullptr, menu);
+ }
+};
+
static inline void centerOnScreen(QWidget *w)
{
centerOnScreen(w, w->geometry().size());
@@ -116,6 +130,10 @@ private slots:
void QTBUG_56917_wideMenuSize();
void QTBUG_56917_wideMenuScreenNumber();
void QTBUG_56917_wideSubmenuScreenNumber();
+ void menuSize_Scrolling_data();
+ void menuSize_Scrolling();
+ void tearOffMenuNotDisplayed();
+
protected slots:
void onActivated(QAction*);
void onHighlighted(QAction*);
@@ -619,7 +637,10 @@ void tst_QMenu::tearOff()
QVERIFY(QTest::qWaitForWindowActive(menu.data()));
QVERIFY(!menu->isTearOffMenuVisible());
- QTest::mouseClick(menu.data(), Qt::LeftButton, 0, QPoint(3, 3), 10);
+ MenuMetrics mm(menu.data());
+ const int tearOffOffset = mm.fw + mm.vmargin + mm.tearOffHeight / 2;
+
+ QTest::mouseClick(menu.data(), Qt::LeftButton, 0, QPoint(10, tearOffOffset), 10);
QTRY_VERIFY(menu->isTearOffMenuVisible());
QPointer<QMenu> torn = getTornOffMenu();
QVERIFY(torn);
@@ -1408,5 +1429,204 @@ void tst_QMenu::QTBUG_56917_wideSubmenuScreenNumber()
}
}
+void tst_QMenu::menuSize_Scrolling_data()
+{
+ QTest::addColumn<int>("numItems");
+ QTest::addColumn<int>("topMargin");
+ QTest::addColumn<int>("bottomMargin");
+ QTest::addColumn<int>("leftMargin");
+ QTest::addColumn<int>("rightMargin");
+ QTest::addColumn<int>("topPadding");
+ QTest::addColumn<int>("bottomPadding");
+ QTest::addColumn<int>("leftPadding");
+ QTest::addColumn<int>("rightPadding");
+ QTest::addColumn<int>("border");
+ QTest::addColumn<bool>("scrollable");
+ QTest::addColumn<bool>("tearOff");
+
+ // test data
+ // a single column and non-scrollable menu with contents margins + border
+ QTest::newRow("data0") << 5 << 2 << 2 << 2 << 2 << 0 << 0 << 0 << 0 << 2 << false << false;
+ // a single column and non-scrollable menu with paddings + border
+ QTest::newRow("data1") << 5 << 0 << 0 << 0 << 0 << 2 << 2 << 2 << 2 << 2 << false << false;
+ // a single column and non-scrollable menu with contents margins + paddings + border
+ QTest::newRow("data2") << 5 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << false << false;
+ // a single column and non-scrollable menu with contents margins + paddings + border + tear-off
+ QTest::newRow("data3") << 5 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << false << true;
+ // a multi-column menu with contents margins + border
+ QTest::newRow("data4") << 80 << 2 << 2 << 2 << 2 << 0 << 0 << 0 << 0 << 2 << false << false;
+ // a multi-column menu with paddings + border
+ QTest::newRow("data5") << 80 << 0 << 0 << 0 << 0 << 2 << 2 << 2 << 2 << 2 << false << false;
+ // a multi-column menu with contents margins + paddings + border
+ QTest::newRow("data6") << 80 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << false << false;
+ // a multi-column menu with contents margins + paddings + border + tear-off
+ QTest::newRow("data7") << 80 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << false << true;
+ // a scrollable menu with contents margins + border
+ QTest::newRow("data8") << 80 << 2 << 2 << 2 << 2 << 0 << 0 << 0 << 0 << 2 << true << false;
+ // a scrollable menu with paddings + border
+ QTest::newRow("data9") << 80 << 0 << 0 << 0 << 0 << 2 << 2 << 2 << 2 << 2 << true << false;
+ // a scrollable menu with contents margins + paddings + border
+ QTest::newRow("data10") << 80 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << true << false;
+ // a scrollable menu with contents margins + paddings + border + tear-off
+ QTest::newRow("data11") << 80 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << true << true;
+}
+
+void tst_QMenu::menuSize_Scrolling()
+{
+ class TestMenu : public QMenu
+ {
+ public:
+ struct ContentsMargins
+ {
+ ContentsMargins(int l, int t, int r, int b)
+ : left(l), top(t), right(r), bottom(b) {}
+ int left;
+ int top;
+ int right;
+ int bottom;
+ };
+
+ struct MenuPaddings
+ {
+ MenuPaddings(int l, int t, int r, int b)
+ : left(l), top(t), right(r), bottom(b) {}
+ int left;
+ int top;
+ int right;
+ int bottom;
+ };
+
+ TestMenu(int numItems, const ContentsMargins &margins, const MenuPaddings &paddings,
+ int border, bool scrollable, bool tearOff)
+ : QMenu("Test Menu"),
+ m_numItems(numItems),
+ m_scrollable(scrollable),
+ m_tearOff(tearOff)
+ {
+ init(margins, paddings, border);
+ }
+
+ ~TestMenu() {}
+
+ private:
+ void showEvent(QShowEvent *e) Q_DECL_OVERRIDE
+ {
+ QVERIFY(actions().length() == m_numItems);
+
+ int hmargin = style()->pixelMetric(QStyle::PM_MenuHMargin, nullptr, this);
+ int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, this);
+ int leftMargin, topMargin, rightMargin, bottomMargin;
+ getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
+ QRect lastItem = actionGeometry(actions().at(actions().length() - 1));
+ QSize s = size();
+ QCOMPARE( s.width(), lastItem.right() + fw + hmargin + rightMargin + 1);
+ QMenu::showEvent(e);
+ }
+
+ void init(const ContentsMargins &margins, const MenuPaddings &paddings, int border)
+ {
+ setLayoutDirection(Qt::LeftToRight);
+
+ setTearOffEnabled(m_tearOff);
+ setContentsMargins(margins.left, margins.top, margins.right, margins.bottom);
+ QString cssStyle("QMenu {menu-scrollable: ");
+ cssStyle += (m_scrollable ? QString::number(1) : QString::number(0));
+ cssStyle += "; border: ";
+ cssStyle += QString::number(border);
+ cssStyle += "px solid black; padding: ";
+ cssStyle += QString::number(paddings.top);
+ cssStyle += "px ";
+ cssStyle += QString::number(paddings.right);
+ cssStyle += "px ";
+ cssStyle += QString::number(paddings.bottom);
+ cssStyle += "px ";
+ cssStyle += QString::number(paddings.left);
+ cssStyle += "px;}";
+ setStyleSheet(cssStyle);
+ for (int i = 1; i <= m_numItems; i++)
+ addAction("MenuItem " + QString::number(i));
+ }
+
+ private:
+ int m_numItems;
+ bool m_scrollable;
+ bool m_tearOff;
+ };
+
+ QFETCH(int, numItems);
+ QFETCH(int, topMargin);
+ QFETCH(int, bottomMargin);
+ QFETCH(int, leftMargin);
+ QFETCH(int, rightMargin);
+ QFETCH(int, topPadding);
+ QFETCH(int, bottomPadding);
+ QFETCH(int, leftPadding);
+ QFETCH(int, rightPadding);
+ QFETCH(int, border);
+ QFETCH(bool, scrollable);
+ QFETCH(bool, tearOff);
+
+ qApp->setAttribute(Qt::AA_DontUseNativeMenuBar);
+
+ TestMenu::ContentsMargins margins(leftMargin, topMargin, rightMargin, bottomMargin);
+ TestMenu::MenuPaddings paddings(leftPadding, topPadding, rightPadding, bottomPadding);
+ TestMenu menu(numItems, margins, paddings, border, scrollable, tearOff);
+ menu.popup(QPoint(0,0));
+ centerOnScreen(&menu);
+ QVERIFY(QTest::qWaitForWindowExposed(&menu));
+
+ QList<QAction *> actions = menu.actions();
+ QCOMPARE(actions.length(), numItems);
+
+ MenuMetrics mm(&menu);
+ QTest::keyClick(&menu, Qt::Key_Home);
+ QTRY_COMPARE(menu.actionGeometry(actions.first()).y(), mm.fw + mm.vmargin + topMargin + (tearOff ? mm.tearOffHeight : 0));
+ QCOMPARE(menu.actionGeometry(actions.first()).x(), mm.fw + mm.hmargin + leftMargin);
+
+ if (!scrollable)
+ return;
+
+ QTest::keyClick(&menu, Qt::Key_End);
+ QTRY_COMPARE(menu.actionGeometry(actions.last()).right(),
+ menu.width() - mm.fw - mm.hmargin - leftMargin - 1);
+ QCOMPARE(menu.actionGeometry(actions.last()).bottom(),
+ menu.height() - mm.fw - mm.vmargin - bottomMargin - 1);
+}
+
+void tst_QMenu::tearOffMenuNotDisplayed()
+{
+ QWidget widget;
+ QScopedPointer<QMenu> menu(new QMenu(&widget));
+ menu->setTearOffEnabled(true);
+ QVERIFY(menu->isTearOffEnabled());
+
+ menu->setStyleSheet("QMenu { menu-scrollable: 1 }");
+ for (int i = 0; i < 80; i++)
+ menu->addAction(QString::number(i));
+
+ widget.resize(300, 200);
+ centerOnScreen(&widget);
+ widget.show();
+ widget.activateWindow();
+ QVERIFY(QTest::qWaitForWindowActive(&widget));
+ menu->popup(widget.geometry().topRight() + QPoint(50, 0));
+ QVERIFY(QTest::qWaitForWindowActive(menu.data()));
+ QVERIFY(!menu->isTearOffMenuVisible());
+
+ MenuMetrics mm(menu.data());
+ const int tearOffOffset = mm.fw + mm.vmargin + mm.tearOffHeight / 2;
+
+ QTest::mouseClick(menu.data(), Qt::LeftButton, 0, QPoint(10, tearOffOffset), 10);
+ QTRY_VERIFY(menu->isTearOffMenuVisible());
+ QPointer<QMenu> torn = getTornOffMenu();
+ QVERIFY(torn);
+ QVERIFY(torn->isVisible());
+ QVERIFY(torn->minimumWidth() >=0 && torn->minimumWidth() < QWIDGETSIZE_MAX);
+
+ menu->hideTearOffMenu();
+ QVERIFY(!menu->isTearOffMenuVisible());
+ QVERIFY(!torn->isVisible());
+}
+
QTEST_MAIN(tst_QMenu)
#include "tst_qmenu.moc"