diff options
author | Liang Qi <liang.qi@qt.io> | 2017-04-20 11:19:14 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-04-20 12:31:27 +0200 |
commit | 7950b6b283549c98f1e0f981c84b68071a13b616 (patch) | |
tree | cf7281872045ebd57c68e10064ff0f400084aa13 /tests/auto | |
parent | 58d2927861d3e57cac4f6db599e209d2bfb17a2c (diff) | |
parent | 0794d61c822585530243f638687b8a75f0a15d0c (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')
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 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 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" |