diff options
Diffstat (limited to 'tests/auto')
45 files changed, 1084 insertions, 301 deletions
diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp index f997a40119..c3407bcc52 100644 --- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp +++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp @@ -670,7 +670,7 @@ void tst_QRandomGenerator::qualityReal() RandomGenerator rng(control); enum { - SampleSize = 160, + SampleSize = 16000, // Expected value: sample size times proportion of the range: PerfectOctile = SampleSize / 8, @@ -678,8 +678,8 @@ void tst_QRandomGenerator::qualityReal() // Variance is (1 - proportion of range) * expected; sqrt() for standard deviations. // Should usually be within twice that and almost never outside four times: - RangeHalf = 25, // floor(4 * sqrt((1 - 0.5) * PerfectHalf)) - RangeOctile = 16 // floor(4 * sqrt((1 - 0.125) * PerfectOctile)) + RangeHalf = 252, // floor(4 * sqrt((1 - 0.5) * PerfectHalf)) + RangeOctile = 167 // floor(4 * sqrt((1 - 0.125) * PerfectOctile)) }; double data[SampleSize]; diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index f0fd3768a7..bd2bba8a88 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2020 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -40,6 +40,12 @@ #include <QtCore/QDebug> #include <QtCore/QMetaType> #include <QtNetwork/QHostInfo> + +#include <qplatformdefs.h> +#ifdef Q_OS_UNIX +# include <private/qcore_unix_p.h> +#endif + #include <stdlib.h> typedef void (QProcess::*QProcessErrorSignal)(QProcess::ProcessError); @@ -57,6 +63,7 @@ private slots: void getSetCheck(); void constructing(); void simpleStart(); + void setupChildProcess(); void startWithOpen(); void startWithOldOpen(); void execute(); @@ -274,6 +281,51 @@ void tst_QProcess::simpleStart() QCOMPARE(qvariant_cast<QProcess::ProcessState>(spy.at(2).at(0)), QProcess::NotRunning); } +void tst_QProcess::setupChildProcess() +{ + /* This test exists because in Qt 5.15, the Unix version of QProcess has + * some code that depends on whether it's an actual QProcess or a + * derived class */ + static const char setupChildMessage[] = "Called from setupChildProcess()"; + class DerivedProcessClass : public QProcess { + public: + int fd; + DerivedProcessClass(int fd) : fd(fd) + { + } + + protected: + void setupChildProcess() override + { + QT_WRITE(fd, setupChildMessage, sizeof(setupChildMessage) - 1); + QT_CLOSE(fd); + } + }; + + int pipes[2] = { -1 , -1 }; +#ifdef Q_OS_UNIX + QVERIFY(qt_safe_pipe(pipes) == 0); +#endif + + DerivedProcessClass process(pipes[1]); + process.start("testProcessNormal/testProcessNormal"); + if (process.state() != QProcess::Starting) + QCOMPARE(process.state(), QProcess::Running); + QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString())); + +#ifdef Q_OS_UNIX + char buf[sizeof setupChildMessage] = {}; + qt_safe_close(pipes[1]); + QCOMPARE(qt_safe_read(pipes[0], buf, sizeof(buf)), qint64(sizeof(setupChildMessage) - 1)); + QCOMPARE(buf, setupChildMessage); + qt_safe_close(pipes[0]); +#endif + + QVERIFY2(process.waitForFinished(5000), qPrintable(process.errorString())); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QCOMPARE(process.exitCode(), 0); +} + void tst_QProcess::startWithOpen() { QProcess p; diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 1b3bc8a627..86465d25fb 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -4700,14 +4700,28 @@ void tst_QVariant::sequentialIterableEndianessSanityCheck() void tst_QVariant::sequentialIterableAppend() { - QVector<int> container {1, 2}; - auto variant = QVariant::fromValue(container); - QVERIFY(variant.canConvert<QtMetaTypePrivate::QSequentialIterableImpl>()); - auto asIterable = variant.value<QtMetaTypePrivate::QSequentialIterableImpl>(); - const int i = 3, j = 4; - asIterable.append(&i); - asIterable.append(&j); - QCOMPARE(variant.value<QVector<int>>(), QVector<int> ({1, 2, 3, 4})); + { + QVector<int> container {1, 2}; + auto variant = QVariant::fromValue(container); + QVERIFY(variant.canConvert<QtMetaTypePrivate::QSequentialIterableImpl>()); + auto asIterable = variant.value<QtMetaTypePrivate::QSequentialIterableImpl>(); + const int i = 3, j = 4; + asIterable.append(&i); + asIterable.append(&j); + QCOMPARE(variant.value<QVector<int>>(), QVector<int> ({1, 2, 3, 4})); + } + { + QSet<QByteArray> container { QByteArray{"hello"}, QByteArray{"world"} }; + auto variant = QVariant::fromValue(std::move(container)); + QVERIFY(variant.canConvert<QtMetaTypePrivate::QSequentialIterableImpl>()); + auto asIterable = variant.value<QtMetaTypePrivate::QSequentialIterableImpl>(); + QByteArray qba1 {"goodbye"}; + QByteArray qba2 { "moon" }; + asIterable.append( &qba1 ); + asIterable.append( &qba2); + QSet<QByteArray> reference { "hello", "world", "goodbye", "moon" }; + QCOMPARE(variant.value<QSet<QByteArray>>(), reference); + } } void tst_QVariant::preferDirectConversionOverInterfaces() diff --git a/tests/auto/corelib/serialization/cborlargedatavalidation.cpp b/tests/auto/corelib/serialization/cborlargedatavalidation.cpp new file mode 100644 index 0000000000..9abfe0f575 --- /dev/null +++ b/tests/auto/corelib/serialization/cborlargedatavalidation.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Intel Corporation. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <cbor.h> + +namespace { +// A QIODevice that supplies a fixed header followed by a large sequence of +// null bytes up until a pre-determined size. +class LargeIODevice final : public QIODevice +{ +public: + qint64 realSize; + QByteArray start; + + LargeIODevice(const QByteArray &start, qint64 size, QObject *parent = nullptr) + : QIODevice(parent), realSize(size), start(start) + {} + + qint64 size() const override { return realSize; } + bool isSequential() const override { return false; } + +protected: + qint64 readData(char *data, qint64 maxlen) override; + qint64 writeData(const char *, qint64) override { return -1; } +}; +}; + +qint64 LargeIODevice::readData(char *data, qint64 maxlen) +{ + qint64 p = pos(); + if (maxlen > realSize - p) + maxlen = realSize - p; + memset(data, '\0', maxlen); + + qint64 fromstart = start.size() - p; + if (fromstart > maxlen) + fromstart = maxlen; + else if (fromstart < 0) + fromstart = 0; + if (fromstart) + memcpy(data, start.constData() + p, fromstart); + return maxlen; +} + +void addValidationLargeData(qsizetype minInvalid, qsizetype maxInvalid) +{ + char toolong[2 + sizeof(qsizetype)] = { char(0x81) }; + for (qsizetype v = maxInvalid; v >= minInvalid; --v) { + // 0x5a for 32-bit, 0x5b for 64-bit + toolong[1] = sizeof(v) > 4 ? 0x5b : 0x5a; + qToBigEndian(v, toolong + 2); + + QTest::addRow("bytearray-too-big-for-qbytearray-%llx", v) + << QByteArray(toolong, sizeof(toolong)) << 0 << CborErrorDataTooLarge; + toolong[1] |= 0x20; + + // QCborStreamReader::readString copies to a QByteArray first + QTest::addRow("string-too-big-for-qbytearray-%llx", v) + << QByteArray(toolong, sizeof(toolong)) << 0 << CborErrorDataTooLarge; + } +} + +void addValidationHugeDevice(qsizetype byteArrayInvalid, qsizetype stringInvalid) +{ + qRegisterMetaType<QSharedPointer<QIODevice>>(); + QTest::addColumn<QSharedPointer<QIODevice>>("device"); + QTest::addColumn<CborError>("expectedError"); + + char buf[1 + sizeof(quint64)]; + auto device = [&buf](QCborStreamReader::Type t, quint64 size) { + buf[0] = quint8(t) | 0x1b; + qToBigEndian(size, buf + 1); + size += sizeof(buf); + QSharedPointer<QIODevice> p = + QSharedPointer<LargeIODevice>::create(QByteArray(buf, sizeof(buf)), size); + return p; + }; + + // do the exact limits + QTest::newRow("bytearray-just-too-big") + << device(QCborStreamReader::ByteArray, byteArrayInvalid) << CborErrorDataTooLarge; + QTest::newRow("string-just-too-big") + << device(QCborStreamReader::String, stringInvalid) << CborErrorDataTooLarge; + + auto addSize = [=](const char *sizename, qint64 size) { + if (byteArrayInvalid < size) + QTest::addRow("bytearray-%s", sizename) + << device(QCborStreamReader::ByteArray, size) << CborErrorDataTooLarge; + if (stringInvalid < size) + QTest::addRow("string-%s", sizename) + << device(QCborStreamReader::String, size) << CborErrorDataTooLarge; + }; + addSize("1GB", quint64(1) << 30); + addSize("2GB", quint64(1) << 31); + addSize("4GB", quint64(1) << 32); + addSize("max", std::numeric_limits<qint64>::max() - sizeof(buf)); +} diff --git a/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt b/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt index 198cca8435..d5f5aea5be 100644 --- a/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt +++ b/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt @@ -12,4 +12,6 @@ add_qt_test(tst_qcborstreamreader INCLUDE_DIRECTORIES ../../../../../src/3rdparty/tinycbor/src ../../../../../src/3rdparty/tinycbor/tests/parser + PUBLIC_LIBRARIES + Qt::CorePrivate ) diff --git a/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro b/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro index 5df331314a..b758de1a9e 100644 --- a/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro +++ b/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro @@ -1,4 +1,4 @@ -QT = core testlib +QT = core-private testlib TARGET = tst_qcborstreamreader CONFIG += testcase SOURCES += \ diff --git a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp index 28d29168fb..f969bb9074 100644 --- a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp +++ b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2020 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -40,6 +40,8 @@ #include <QtCore/qcborstream.h> #include <QtTest> +#include <QtCore/private/qbytearray_p.h> + class tst_QCborStreamReader : public QObject { Q_OBJECT @@ -73,6 +75,8 @@ private Q_SLOTS: void next(); void validation_data(); void validation(); + void hugeDeviceValidation_data(); + void hugeDeviceValidation(); void recursionLimit_data(); void recursionLimit(); @@ -902,16 +906,26 @@ void tst_QCborStreamReader::next() QVERIFY(doit("\xbf\x9f\1\xff\x9f" + data + "\xff\xff")); } +#include "../cborlargedatavalidation.cpp" + void tst_QCborStreamReader::validation_data() { + // Add QCborStreamReader-specific limitations due to use of QByteArray and + // QString, which are allocated by QArrayData::allocate(). + const qsizetype MaxInvalid = std::numeric_limits<QByteArray::size_type>::max(); + const qsizetype MinInvalid = MaxByteArraySize + 1; + addValidationColumns(); - addValidationData(); + addValidationData(MinInvalid); + addValidationLargeData(MinInvalid, MaxInvalid); } void tst_QCborStreamReader::validation() { QFETCH_GLOBAL(bool, useDevice); QFETCH(QByteArray, data); + QFETCH(CborError, expectedError); + QCborError error = { QCborError::Code(expectedError) }; QBuffer buffer(&data); QCborStreamReader reader(data); @@ -920,12 +934,39 @@ void tst_QCborStreamReader::validation() reader.setDevice(&buffer); } parse(reader, data); - QVERIFY(reader.lastError() != QCborError::NoError); + QCOMPARE(reader.lastError(), error); + + // next() should fail + reader.reset(); + QVERIFY(!reader.next()); + QCOMPARE(reader.lastError(), error); +} + +void tst_QCborStreamReader::hugeDeviceValidation_data() +{ + addValidationHugeDevice(MaxByteArraySize + 1, MaxStringSize + 1); +} + +void tst_QCborStreamReader::hugeDeviceValidation() +{ + QFETCH_GLOBAL(bool, useDevice); + if (!useDevice) + return; + + QFETCH(QSharedPointer<QIODevice>, device); + QFETCH(CborError, expectedError); + QCborError error = { QCborError::Code(expectedError) }; + + device->open(QIODevice::ReadOnly | QIODevice::Unbuffered); + QCborStreamReader reader(device.data()); + + QVERIFY(parseOne(reader).isEmpty()); + QCOMPARE(reader.lastError(), error); // next() should fail reader.reset(); QVERIFY(!reader.next()); - QVERIFY(reader.lastError() != QCborError::NoError); + QCOMPARE(reader.lastError(), error); } static const int Recursions = 3; diff --git a/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt b/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt index 66cb80c56a..0835ac9c50 100644 --- a/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt +++ b/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt @@ -12,4 +12,6 @@ add_qt_test(tst_qcborvalue INCLUDE_DIRECTORIES ../../../../../src/3rdparty/tinycbor/src ../../../../../src/3rdparty/tinycbor/tests/parser + PUBLIC_LIBRARIES + Qt::CorePrivate ) diff --git a/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro b/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro index 9dd67da1f0..4d01b290f5 100644 --- a/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro +++ b/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro @@ -1,4 +1,4 @@ -QT = core testlib +QT = core-private testlib TARGET = tst_qcborvalue CONFIG += testcase SOURCES += \ diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index d5a9012f9f..6d8161c1f9 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2020 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -40,6 +40,8 @@ #include <QtCore/qcborvalue.h> #include <QtTest> +#include <QtCore/private/qbytearray_p.h> + Q_DECLARE_METATYPE(QCborKnownTags) Q_DECLARE_METATYPE(QCborValue) Q_DECLARE_METATYPE(QCborValue::EncodingOptions) @@ -102,6 +104,10 @@ private slots: void fromCborStreamReaderIODevice(); void validation_data(); void validation(); + void hugeDeviceValidation_data(); + void hugeDeviceValidation(); + void recursionLimit_data(); + void recursionLimit(); void toDiagnosticNotation_data(); void toDiagnosticNotation(); @@ -1687,39 +1693,127 @@ void tst_QCborValue::fromCborStreamReaderIODevice() fromCbor_common(doCheck); } +#include "../cborlargedatavalidation.cpp" + void tst_QCborValue::validation_data() { + // Add QCborStreamReader-specific limitations due to use of QByteArray and + // QString, which are allocated by QArrayData::allocate(). + const qsizetype MaxInvalid = std::numeric_limits<QByteArray::size_type>::max(); + const qsizetype MinInvalid = MaxByteArraySize + 1; addValidationColumns(); - addValidationData(); + addValidationData(MinInvalid); + addValidationLargeData(MinInvalid, MaxInvalid); // These tests say we have arrays and maps with very large item counts. // They are meant to ensure we don't pre-allocate a lot of memory // unnecessarily and possibly crash the application. The actual number of // elements in the stream is only 2, so we should get an unexpected EOF - // error. QCborValue internally uses 16 bytes per element, so we get to - // 2 GB at 2^27 elements. - QTest::addRow("very-large-array-no-overflow") << raw("\x9a\x07\xff\xff\xff" "\0\0"); - QTest::addRow("very-large-array-overflow1") << raw("\x9a\x40\0\0\0" "\0\0"); - - // this makes sure we don't accidentally clip to 32-bit: sending 2^32+2 elements - QTest::addRow("very-large-array-overflow2") << raw("\x9b\0\0\0\1""\0\0\0\2" "\0\0"); + // error. QCborValue internally uses 16 bytes per element, so we get to 2 + // GB at 2^27 elements (32-bit) or, theoretically, 2^63 bytes at 2^59 + // elements (64-bit). + if (sizeof(QVector<int>::size_type) == sizeof(int)) { + // 32-bit sizes (Qt 5 and 32-bit platforms) + QTest::addRow("very-large-array-no-overflow") << raw("\x9a\x07\xff\xff\xff" "\0\0") << 0 << CborErrorUnexpectedEOF; + QTest::addRow("very-large-array-overflow1") << raw("\x9a\x40\0\0\0" "\0\0") << 0 << CborErrorUnexpectedEOF; + + // this makes sure we don't accidentally clip to 32-bit: sending 2^32+2 elements + QTest::addRow("very-large-array-overflow2") << raw("\x9b\0\0\0\1""\0\0\0\2" "\0\0") << 0 << CborErrorDataTooLarge; + } else { + // 64-bit Qt 6 + QTest::addRow("very-large-array-no-overflow") << raw("\x9b\x07\xff\xff\xff" "\xff\xff\xff\xff" "\0\0"); + QTest::addRow("very-large-array-overflow") << raw("\x9b\x40\0\0\0" "\0\0\0\0" "\0\0"); + } } void tst_QCborValue::validation() { QFETCH(QByteArray, data); + QFETCH(CborError, expectedError); + QCborError error = { QCborError::Code(expectedError) }; - QCborParserError error; - QCborValue decoded = QCborValue::fromCbor(data, &error); - QVERIFY(error.error != QCborError{}); + QCborParserError parserError; + QCborValue decoded = QCborValue::fromCbor(data, &parserError); + QCOMPARE(parserError.error, error); if (data.startsWith('\x81')) { // decode without the array prefix - decoded = QCborValue::fromCbor(data.mid(1), &error); - QVERIFY(error.error != QCborError{}); + char *ptr = const_cast<char *>(data.constData()); + QByteArray mid = QByteArray::fromRawData(ptr + 1, data.size() - 1); + decoded = QCborValue::fromCbor(mid, &parserError); + QCOMPARE(parserError.error, error); } } +void tst_QCborValue::hugeDeviceValidation_data() +{ + addValidationHugeDevice(MaxByteArraySize + 1, MaxStringSize + 1); +} + +void tst_QCborValue::hugeDeviceValidation() +{ + QFETCH(QSharedPointer<QIODevice>, device); + QFETCH(CborError, expectedError); + QCborError error = { QCborError::Code(expectedError) }; + + device->open(QIODevice::ReadOnly | QIODevice::Unbuffered); + QCborStreamReader reader(device.data()); + QCborValue decoded = QCborValue::fromCbor(reader); + QCOMPARE(reader.lastError(), error); +} + +void tst_QCborValue::recursionLimit_data() +{ + constexpr int RecursionAttempts = 4096; + QTest::addColumn<QByteArray>("data"); + QByteArray arrays(RecursionAttempts, char(0x81)); + QByteArray _arrays(RecursionAttempts, char(0x9f)); + QByteArray maps(RecursionAttempts, char(0xa1)); + QByteArray _maps(RecursionAttempts, char(0xbf)); + QByteArray tags(RecursionAttempts, char(0xc0)); + + QTest::newRow("array-nesting-too-deep") << arrays; + QTest::newRow("_array-nesting-too-deep") << _arrays; + QTest::newRow("map-nesting-too-deep") << maps; + QTest::newRow("_map-nesting-too-deep") << _maps; + QTest::newRow("tag-nesting-too-deep") << tags; + + QByteArray mixed(5 * RecursionAttempts, Qt::Uninitialized); + char *ptr = mixed.data(); + for (int i = 0; i < RecursionAttempts; ++i) { + quint8 type = qBound(quint8(QCborStreamReader::Array), quint8(i & 0x80), quint8(QCborStreamReader::Tag)); + quint8 additional_info = i & 0x1f; + if (additional_info == 0x1f) + (void)additional_info; // leave it + else if (additional_info > 0x1a) + additional_info = 0x1a; + else if (additional_info < 1) + additional_info = 1; + + *ptr++ = type | additional_info; + if (additional_info == 0x18) { + *ptr++ = uchar(i); + } else if (additional_info == 0x19) { + qToBigEndian(ushort(i), ptr); + ptr += 2; + } else if (additional_info == 0x1a) { + qToBigEndian(uint(i), ptr); + ptr += 4; + } + } + + QTest::newRow("mixed-nesting-too-deep") << mixed; +} + +void tst_QCborValue::recursionLimit() +{ + QFETCH(QByteArray, data); + + QCborParserError error; + QCborValue decoded = QCborValue::fromCbor(data, &error); + QCOMPARE(error.error, QCborError::NestingTooDeep); +} + void tst_QCborValue::toDiagnosticNotation_data() { QTest::addColumn<QCborValue>("v"); diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 6ed06ca237..2b06e60c44 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -514,7 +514,7 @@ static inline bool runSysApp(const QString &binary, errorMessage->clear(); QProcess process; process.setEnvironment(env); - process.start(binary); + process.start(binary, QStringList()); process.closeWriteChannel(); if (!process.waitForStarted()) { *errorMessage = QLatin1String("Cannot start '") + binary @@ -2589,12 +2589,12 @@ void tst_QLocale::currency() const QLocale en_US("en_US"); QCOMPARE(en_US.toCurrencyString(qulonglong(1234)), QString("$1,234")); - QCOMPARE(en_US.toCurrencyString(qlonglong(-1234)), QString("$-1,234")); + QCOMPARE(en_US.toCurrencyString(qlonglong(-1234)), QString("($1,234)")); QCOMPARE(en_US.toCurrencyString(double(1234.56)), QString("$1,234.56")); - QCOMPARE(en_US.toCurrencyString(double(-1234.56)), QString("$-1,234.56")); - QCOMPARE(en_US.toCurrencyString(double(-1234.5678)), QString("$-1,234.57")); - QCOMPARE(en_US.toCurrencyString(double(-1234.5678), NULL, 4), QString("$-1,234.5678")); - QCOMPARE(en_US.toCurrencyString(double(-1234.56), NULL, 4), QString("$-1,234.5600")); + QCOMPARE(en_US.toCurrencyString(double(-1234.56)), QString("($1,234.56)")); + QCOMPARE(en_US.toCurrencyString(double(-1234.5678)), QString("($1,234.57)")); + QCOMPARE(en_US.toCurrencyString(double(-1234.5678), NULL, 4), QString("($1,234.5678)")); + QCOMPARE(en_US.toCurrencyString(double(-1234.56), NULL, 4), QString("($1,234.5600)")); const QLocale ru_RU("ru_RU"); QCOMPARE(ru_RU.toCurrencyString(qulonglong(1234)), diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp index 2a9c1e1e41..898ac86874 100644 --- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp @@ -428,9 +428,9 @@ void tst_QEasingCurve::setCustomType() QCOMPARE(curve.valueForProgress(0.15), 0.1); QCOMPARE(curve.valueForProgress(0.20), 0.2); QCOMPARE(curve.valueForProgress(0.25), 0.2); - // QTBUG-69947, MinGW 7.3 returns 0.2 + // QTBUG-69947, MinGW 7.3, 8.1 x86 returns 0.2 #if defined(Q_CC_MINGW) -#if !defined(__GNUC__) || __GNUC__ != 7 || __GNUC_MINOR__ < 3 +#if !defined(__GNUC__) || defined(__MINGW64__) QCOMPARE(curve.valueForProgress(0.30), 0.3); #endif #endif diff --git a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp index 4bb4113845..226af2f805 100644 --- a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp +++ b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com> -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -101,8 +101,8 @@ void tst_QScopeGuard::construction() QScopeGuard fromNonVoidFunction(intFunc); QScopeGuard fromNoDiscardFunction(noDiscardFunc); #ifndef __apple_build_version__ - QScopeGuard fromStdFunction{std::function(func)}; - std::function stdFunction(func); + QScopeGuard fromStdFunction{std::function<void()>(func)}; + std::function<void()> stdFunction(func); QScopeGuard fromNamedStdFunction(stdFunction); #endif #else diff --git a/tests/auto/gui/kernel/CMakeLists.txt b/tests/auto/gui/kernel/CMakeLists.txt index ecac48d1c1..1cb38a7c9e 100644 --- a/tests/auto/gui/kernel/CMakeLists.txt +++ b/tests/auto/gui/kernel/CMakeLists.txt @@ -1,17 +1,18 @@ # Generated from kernel.pro. +if(QT_FEATURE_action) + add_subdirectory(qaction) + add_subdirectory(qactiongroup) +endif() add_subdirectory(qbackingstore) add_subdirectory(qcursor) add_subdirectory(qdrag) add_subdirectory(qevent) add_subdirectory(qfileopenevent) add_subdirectory(qguieventdispatcher) -add_subdirectory(qguimetatype) add_subdirectory(qguitimer) -add_subdirectory(qguivariant) add_subdirectory(qinputmethod) add_subdirectory(qkeyevent) -add_subdirectory(qkeysequence) add_subdirectory(qmouseevent) add_subdirectory(qpalette) add_subdirectory(qscreen) @@ -20,12 +21,22 @@ add_subdirectory(qwindow) add_subdirectory(qguiapplication) add_subdirectory(qpixelformat) add_subdirectory(qrasterwindow) +add_subdirectory(qaddpostroutine) if(NOT ANDROID AND NOT UIKIT) add_subdirectory(qclipboard) endif() if(TARGET Qt::Network) add_subdirectory(qguieventloop) endif() +if(QT_FEATURE_shortcut) + add_subdirectory(qguimetatype) + add_subdirectory(qguivariant) + add_subdirectory(qkeysequence) + add_subdirectory(qshortcut) +endif() +if(QT_FEATURE_highdpiscaling) + add_subdirectory(qhighdpiscaling) +endif() if(TARGET Qt::Widgets) add_subdirectory(qmouseevent_modal) add_subdirectory(qtouchevent) diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 5a935699c5..85bebbddc9 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -28,7 +28,8 @@ SUBDIRS=\ qguiapplication \ qpixelformat \ qopenglwindow \ - qrasterwindow + qrasterwindow \ + qaddpostroutine win32:!winrt:qtHaveModule(network): SUBDIRS += noqteventloop diff --git a/tests/auto/gui/kernel/qaction/CMakeLists.txt b/tests/auto/gui/kernel/qaction/CMakeLists.txt index c14444c123..bdd1a1d165 100644 --- a/tests/auto/gui/kernel/qaction/CMakeLists.txt +++ b/tests/auto/gui/kernel/qaction/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from qaction.pro. ##################################################################### -## tst_qaction Test: +## tst_qaction_kernel Test: ##################################################################### -add_qt_test(tst_qaction +add_qt_test(tst_qaction_kernel SOURCES tst_qaction.cpp PUBLIC_LIBRARIES diff --git a/tests/auto/gui/kernel/qaction/qaction.pro b/tests/auto/gui/kernel/qaction/qaction.pro index fae8d826f4..83e8296e68 100644 --- a/tests/auto/gui/kernel/qaction/qaction.pro +++ b/tests/auto/gui/kernel/qaction/qaction.pro @@ -1,4 +1,4 @@ CONFIG += testcase -TARGET = tst_qaction +TARGET = tst_qaction_kernel QT += gui-private core-private testlib SOURCES += tst_qaction.cpp diff --git a/tests/auto/gui/kernel/qactiongroup/CMakeLists.txt b/tests/auto/gui/kernel/qactiongroup/CMakeLists.txt index 6ef659ebc1..bcab5e05a2 100644 --- a/tests/auto/gui/kernel/qactiongroup/CMakeLists.txt +++ b/tests/auto/gui/kernel/qactiongroup/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from qactiongroup.pro. ##################################################################### -## tst_qactiongroup Test: +## tst_qactiongroup_kernel Test: ##################################################################### -add_qt_test(tst_qactiongroup +add_qt_test(tst_qactiongroup_kernel SOURCES tst_qactiongroup.cpp PUBLIC_LIBRARIES diff --git a/tests/auto/gui/kernel/qactiongroup/qactiongroup.pro b/tests/auto/gui/kernel/qactiongroup/qactiongroup.pro index 81ceb10429..a60109c63e 100644 --- a/tests/auto/gui/kernel/qactiongroup/qactiongroup.pro +++ b/tests/auto/gui/kernel/qactiongroup/qactiongroup.pro @@ -1,4 +1,4 @@ CONFIG += testcase -TARGET = tst_qactiongroup +TARGET = tst_qactiongroup_kernel QT += testlib SOURCES += tst_qactiongroup.cpp diff --git a/tests/auto/gui/kernel/qaddpostroutine/CMakeLists.txt b/tests/auto/gui/kernel/qaddpostroutine/CMakeLists.txt new file mode 100644 index 0000000000..4af9ebedd5 --- /dev/null +++ b/tests/auto/gui/kernel/qaddpostroutine/CMakeLists.txt @@ -0,0 +1,12 @@ +# Generated from qaddpostroutine.pro. + +##################################################################### +## tst_qaddpostroutine Test: +##################################################################### + +qt_add_test(tst_qaddpostroutine + SOURCES + tst_qaddpostroutine.cpp + PUBLIC_LIBRARIES + Qt::Gui +) diff --git a/tests/auto/gui/kernel/qaddpostroutine/qaddpostroutine.pro b/tests/auto/gui/kernel/qaddpostroutine/qaddpostroutine.pro new file mode 100644 index 0000000000..e67720b5d5 --- /dev/null +++ b/tests/auto/gui/kernel/qaddpostroutine/qaddpostroutine.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qaddpostroutine + +QT += testlib + +SOURCES += tst_qaddpostroutine.cpp + diff --git a/tests/auto/gui/kernel/qaddpostroutine/tst_qaddpostroutine.cpp b/tests/auto/gui/kernel/qaddpostroutine/tst_qaddpostroutine.cpp new file mode 100644 index 0000000000..500543d2e1 --- /dev/null +++ b/tests/auto/gui/kernel/qaddpostroutine/tst_qaddpostroutine.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QTimer> + +static bool done = false; + +static void cleanup() +{ + done = true; + QEventLoop loop; + QTimer::singleShot(100,&loop, &QEventLoop::quit); + loop.exec(); +} + +struct tst_qAddPostRoutine : public QObject +{ +public: + tst_qAddPostRoutine(); + ~tst_qAddPostRoutine(); +}; + +tst_qAddPostRoutine::tst_qAddPostRoutine() +{ + qAddPostRoutine(cleanup); +} + +tst_qAddPostRoutine::~tst_qAddPostRoutine() +{ + Q_ASSERT(done); +} +int main(int argc, char *argv[]) +{ + tst_qAddPostRoutine tc; + QGuiApplication app(argc, argv); + app.setAttribute(Qt::AA_Use96Dpi, true); + QTEST_SET_MAIN_SOURCE_PATH + return QTest::qExec(&tc, argc, argv); +} diff --git a/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp b/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp index bff9f7d0e0..e099b4dfc7 100644 --- a/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp +++ b/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp @@ -289,10 +289,10 @@ void tst_QClipboard::copyImage() image.fill(QColor(Qt::transparent)); image.setPixel(QPoint(1, 0), QColor(Qt::blue).rgba()); QGuiApplication::clipboard()->setImage(image); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS // The Pasteboard needs a moment to breathe (at least on older Macs). QTest::qWait(100); -#endif // Q_OS_OSX +#endif // Q_OS_MACOS // paster will perform hard-coded checks on the copied image. QByteArray errorMessage; QVERIFY2(runHelper(QStringLiteral("paster/paster"), diff --git a/tests/auto/gui/kernel/qhighdpiscaling/CMakeLists.txt b/tests/auto/gui/kernel/qhighdpiscaling/CMakeLists.txt new file mode 100644 index 0000000000..69cff9229f --- /dev/null +++ b/tests/auto/gui/kernel/qhighdpiscaling/CMakeLists.txt @@ -0,0 +1,14 @@ +# Generated from qhighdpiscaling.pro. + +##################################################################### +## tst_qhighdpiscaling Test: +##################################################################### + +qt_add_test(tst_qhighdpiscaling + SOURCES + tst_qhighdpiscaling.cpp + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate +) diff --git a/tests/auto/gui/kernel/qshortcut/CMakeLists.txt b/tests/auto/gui/kernel/qshortcut/CMakeLists.txt index 66ad66335e..fab20dceed 100644 --- a/tests/auto/gui/kernel/qshortcut/CMakeLists.txt +++ b/tests/auto/gui/kernel/qshortcut/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from qshortcut.pro. ##################################################################### -## tst_qshortcut Test: +## tst_qshortcut_kernel Test: ##################################################################### -add_qt_test(tst_qshortcut +add_qt_test(tst_qshortcut_kernel SOURCES tst_qshortcut.cpp PUBLIC_LIBRARIES diff --git a/tests/auto/gui/kernel/qshortcut/qshortcut.pro b/tests/auto/gui/kernel/qshortcut/qshortcut.pro index e7e37663e0..5dc016b099 100644 --- a/tests/auto/gui/kernel/qshortcut/qshortcut.pro +++ b/tests/auto/gui/kernel/qshortcut/qshortcut.pro @@ -1,4 +1,4 @@ CONFIG += testcase -TARGET = tst_qshortcut +TARGET = tst_qshortcut_kernel QT += testlib SOURCES += tst_qshortcut.cpp diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index 1ca60655a6..a92c948ade 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -512,9 +512,7 @@ void tst_Http2::goaway() request.setAttribute(QNetworkRequest::Http2AllowedAttribute, QVariant(true)); replies[i] = manager->get(request); QCOMPARE(replies[i]->error(), QNetworkReply::NoError); - void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) = - &QNetworkReply::errorOccurred; - connect(replies[i], errorSignal, this, &tst_Http2::replyFinishedWithError); + connect(replies[i], &QNetworkReply::errorOccurred, this, &tst_Http2::replyFinishedWithError); // Since we're using self-signed certificates, ignore SSL errors: replies[i]->ignoreSslErrors(); } diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index cc41260d59..4c4113d9d4 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -1090,12 +1090,21 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest() QProcess serverProcess; serverProcess.start(QLatin1String("clientserver/clientserver server 1 1"), QIODevice::ReadWrite | QIODevice::Text); - QVERIFY2(serverProcess.waitForStarted(3000), - qPrintable("Failed to start subprocess: " + serverProcess.errorString())); + + const auto serverProcessCleaner = qScopeGuard([&serverProcess] { + serverProcess.kill(); + serverProcess.waitForFinished(); + }); + + if (!serverProcess.waitForStarted(3000)) + QSKIP("Failed to start server as a subprocess"); // Wait until the server has started and reports success. - while (!serverProcess.canReadLine()) - QVERIFY(serverProcess.waitForReadyRead(3000)); + while (!serverProcess.canReadLine()) { + if (!serverProcess.waitForReadyRead(3000)) + QSKIP("No output from the server process, bailing out"); + } + QByteArray serverGreeting = serverProcess.readLine(); QVERIFY(serverGreeting != QByteArray("XXX\n")); int serverPort = serverGreeting.trimmed().toInt(); @@ -1105,12 +1114,21 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest() clientProcess.start(QString::fromLatin1("clientserver/clientserver connectedclient %1 %2") .arg(QLatin1String("127.0.0.1")).arg(serverPort), QIODevice::ReadWrite | QIODevice::Text); - QVERIFY2(clientProcess.waitForStarted(3000), - qPrintable("Failed to start subprocess: " + clientProcess.errorString())); - // Wait until the server has started and reports success. - while (!clientProcess.canReadLine()) - QVERIFY(clientProcess.waitForReadyRead(3000)); + const auto clientProcessCleaner = qScopeGuard([&clientProcess] { + clientProcess.kill(); + clientProcess.waitForFinished(); + }); + + if (!clientProcess.waitForStarted(3000)) + QSKIP("Client process did not start"); + + // Wait until the client has started and reports success. + while (!clientProcess.canReadLine()) { + if (!clientProcess.waitForReadyRead(3000)) + QSKIP("No output from the client process, bailing out"); + } + QByteArray clientGreeting = clientProcess.readLine(); QCOMPARE(clientGreeting, QByteArray("ok\n")); @@ -1135,11 +1153,6 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest() QCOMPARE(serverData.at(i * 3 + 2).trimmed().mid(8).toInt(), sdata.mid(4).trimmed().toInt() * 2); } - - clientProcess.kill(); - QVERIFY(clientProcess.waitForFinished()); - serverProcess.kill(); - QVERIFY(serverProcess.waitForFinished()); #endif } @@ -1151,12 +1164,21 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest() QProcess serverProcess; serverProcess.start(QLatin1String("clientserver/clientserver server 1 1"), QIODevice::ReadWrite | QIODevice::Text); - QVERIFY2(serverProcess.waitForStarted(3000), - qPrintable("Failed to start subprocess: " + serverProcess.errorString())); + + const auto serverProcessCleaner = qScopeGuard([&serverProcess] { + serverProcess.kill(); + serverProcess.waitForFinished(); + }); + + if (!serverProcess.waitForStarted(3000)) + QSKIP("Failed to start the server subprocess"); // Wait until the server has started and reports success. - while (!serverProcess.canReadLine()) - QVERIFY(serverProcess.waitForReadyRead(3000)); + while (!serverProcess.canReadLine()) { + if (!serverProcess.waitForReadyRead(3000)) + QSKIP("No output from the server, probably, it is not running"); + } + QByteArray serverGreeting = serverProcess.readLine(); QVERIFY(serverGreeting != QByteArray("XXX\n")); int serverPort = serverGreeting.trimmed().toInt(); @@ -1166,12 +1188,21 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest() clientProcess.start(QString::fromLatin1("clientserver/clientserver unconnectedclient %1 %2") .arg(QLatin1String("127.0.0.1")).arg(serverPort), QIODevice::ReadWrite | QIODevice::Text); - QVERIFY2(clientProcess.waitForStarted(3000), - qPrintable("Failed to start subprocess: " + clientProcess.errorString())); - // Wait until the server has started and reports success. - while (!clientProcess.canReadLine()) - QVERIFY(clientProcess.waitForReadyRead(3000)); + const auto clientProcessCleaner = qScopeGuard([&clientProcess] { + clientProcess.kill(); + clientProcess.waitForFinished(); + }); + + if (!clientProcess.waitForStarted(3000)) + QSKIP("Failed to start the client's subprocess"); + + // Wait until the client has started and reports success. + while (!clientProcess.canReadLine()) { + if (!clientProcess.waitForReadyRead(3000)) + QSKIP("The client subprocess produced not output, exiting."); + } + QByteArray clientGreeting = clientProcess.readLine(); QCOMPARE(clientGreeting, QByteArray("ok\n")); @@ -1197,11 +1228,6 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest() QCOMPARE(serverData.at(i * 3 + 2).trimmed().mid(8).toInt(), sdata.mid(4).trimmed().toInt() * 2); } - - clientProcess.kill(); - QVERIFY(clientProcess.waitForFinished()); - serverProcess.kill(); - QVERIFY(serverProcess.waitForFinished()); #endif } diff --git a/tests/auto/network/ssl/qocsp/tst_qocsp.cpp b/tests/auto/network/ssl/qocsp/tst_qocsp.cpp index 27476f451e..519ae5c720 100644 --- a/tests/auto/network/ssl/qocsp/tst_qocsp.cpp +++ b/tests/auto/network/ssl/qocsp/tst_qocsp.cpp @@ -409,7 +409,6 @@ private: static QString certDirPath; - void (QSslSocket::*socketErrorSignal)(QAbstractSocket::SocketError) = &QAbstractSocket::errorOccurred; void (QSslSocket::*tlsErrorsSignal)(const QList<QSslError> &) = &QSslSocket::sslErrors; void (QTestEventLoop::*exitLoopSlot)() = &QTestEventLoop::exitLoop; @@ -763,7 +762,7 @@ void tst_QOcsp::setupOcspClient(QSslSocket &clientSocket, const CertificateChain clientSocket.setSslConfiguration(clientConfig); clientSocket.setPeerVerifyName(name); - connect(&clientSocket, socketErrorSignal, &loop, exitLoopSlot); + connect(&clientSocket, &QAbstractSocket::errorOccurred, &loop, exitLoopSlot); connect(&clientSocket, tlsErrorsSignal, &loop, exitLoopSlot); connect(&clientSocket, &QSslSocket::encrypted, &loop, exitLoopSlot); } diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index c793a6a98b..8b5b4156bb 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -2535,8 +2535,7 @@ void tst_QSslSocket::closeWhileEmittingSocketError() clientSocket.setSslConfiguration(clientConfig); QSignalSpy socketErrorSpy(&clientSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError))); - void (QSslSocket::*errorSignal)(QAbstractSocket::SocketError) = &QSslSocket::errorOccurred; - connect(&clientSocket, errorSignal, &handshake, &BrokenPskHandshake::socketError); + connect(&clientSocket, &QSslSocket::errorOccurred, &handshake, &BrokenPskHandshake::socketError); clientSocket.connectToHostEncrypted(QStringLiteral("127.0.0.1"), handshake.serverPort()); // Make sure we have some data buffered so that close will try to flush: diff --git a/tests/auto/other/lancelot/scripts/linedashes.qps b/tests/auto/other/lancelot/scripts/linedashes.qps index ee7d18b156..78c791e68b 100644 --- a/tests/auto/other/lancelot/scripts/linedashes.qps +++ b/tests/auto/other/lancelot/scripts/linedashes.qps @@ -91,4 +91,42 @@ translate 100 0 repeat_block draw_lines setPen 0xffff0000 0 dashline squarecap translate 100 0 -repeat_block draw_lines
\ No newline at end of file +repeat_block draw_lines + +path_moveTo mypath 10 10 +path_lineTo mypath 87 10 +path_moveTo mypath 10 30 +path_lineTo mypath 87 30 +path_moveTo mypath 10 50 +path_lineTo mypath 87 50 + +resetMatrix +translate 0 150 + +begin_block distinctLines + +setPen black 0 SolidLine SquareCap +pen_setDashPattern [ 3 3 ] +drawPath mypath + +translate 100 0 +setPen black 5 SolidLine SquareCap +pen_setDashPattern [ 3 3 ] +drawPath mypath + +translate 100 0 +setPen black 0 SolidLine RoundCap +pen_setDashPattern [ 3 3 ] +drawPath mypath + +translate 100 0 +setPen black 5 SolidLine RoundCap +pen_setDashPattern [ 3 3 ] +drawPath mypath + +end_block distinctLines + +resetMatrix +translate 0 220 +setRenderHint Antialiasing true +repeat_block distinctLines diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index 1af3bade0e..10a3746e36 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -607,7 +607,7 @@ void tst_QDialog::snapToDefaultButton() + QPoint(100, 100), QSize(200, 200)); const QPoint startingPos = dialogGeometry.bottomRight() + QPoint(100, 100); QCursor::setPos(startingPos); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS // On OS X we use CGEventPost to move the cursor, it needs at least // some time before the event handled and the position really set. QTest::qWait(100); diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 76314564f1..543128915e 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -51,7 +51,7 @@ private slots: void about(); void detailsText(); void detailsButtonText(); - void expandDetails_QTBUG_32473(); + void expandDetailsWithoutMoving(); #ifndef Q_OS_MAC void shortcut(); @@ -499,7 +499,7 @@ void tst_QMessageBox::detailsButtonText() } } -void tst_QMessageBox::expandDetails_QTBUG_32473() +void tst_QMessageBox::expandDetailsWithoutMoving() // QTBUG-32473 { tst_ResizingMessageBox box; box.setDetailedText("bla"); @@ -516,18 +516,14 @@ void tst_QMessageBox::expandDetails_QTBUG_32473() auto moreButton = *it; QVERIFY(QTest::qWaitForWindowExposed(&box)); + QTRY_VERIFY2(!box.geometry().topLeft().isNull(), "window manager is expected to decorate and position the dialog"); QRect geom = box.geometry(); box.resized = false; + // now click the "more" button, and verify that the dialog resizes but does not move moreButton->click(); QTRY_VERIFY(box.resized); - // After we receive the expose event for a second widget, it's likely - // that the window manager is also done manipulating the first QMessageBox. - QWidget fleece; - fleece.show(); - QVERIFY(QTest::qWaitForWindowExposed(&fleece)); - if (geom.topLeft() == box.geometry().topLeft()) - QTest::qWait(500); - QCOMPARE(geom.topLeft(), box.geometry().topLeft()); + QVERIFY(box.geometry().height() > geom.height()); + QCOMPARE(box.geometry().topLeft(), geom.topLeft()); } void tst_QMessageBox::incorrectDefaultButton() diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 44b728a042..ba4c1473e8 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -153,6 +153,7 @@ private slots: void currentFollowsIndexWidget(); void checkFocusAfterActivationChanges_data(); void checkFocusAfterActivationChanges(); + void dragSelectAfterNewPress(); private: static QAbstractItemView *viewFromString(const QByteArray &viewType, QWidget *parent = nullptr) { @@ -2553,5 +2554,62 @@ void tst_QAbstractItemView::checkFocusAfterActivationChanges() QVERIFY(view->hasFocus()); } +void tst_QAbstractItemView::dragSelectAfterNewPress() +{ + QStandardItemModel model; + for (int i = 0; i < 10; ++i) { + QStandardItem *item = new QStandardItem(QString::number(i)); + model.setItem(i, 0, item); + } + + QListView view; + view.setFixedSize(160, 650); // Minimum width for windows with frame on Windows 8 + view.setSelectionMode(QListView::ExtendedSelection); + view.setModel(&model); + centerOnScreen(&view); + moveCursorAway(&view); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QModelIndex index0 = model.index(0, 0); + QModelIndex index2 = model.index(2, 0); + + view.setCurrentIndex(index0); + QCOMPARE(view.currentIndex(), index0); + + // Select item 0 using a single click + QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, + view.visualRect(index0).center()); + QCOMPARE(view.currentIndex(), index0); + + // Press to select item 2 + QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, + view.visualRect(index2).center()); + QCOMPARE(view.currentIndex(), index2); + + // Verify that the selection worked OK + QModelIndexList selected = view.selectionModel()->selectedIndexes(); + QCOMPARE(selected.count(), 3); + for (int i = 0; i < 2; ++i) + QVERIFY(selected.contains(model.index(i, 0))); + + QModelIndex index5 = model.index(5, 0); + const QPoint releasePos = view.visualRect(index5).center(); + // The mouse move event has to be created manually because the QTest framework does not + // contain a function for mouse moves with buttons pressed + QMouseEvent moveEvent2(QEvent::MouseMove, releasePos, Qt::NoButton, Qt::LeftButton, + Qt::ShiftModifier); + const bool moveEventReceived = qApp->notify(view.viewport(), &moveEvent2); + QVERIFY(moveEventReceived); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, releasePos); + QCOMPARE(view.currentIndex(), index5); + + // Verify that the selection worked OK + selected = view.selectionModel()->selectedIndexes(); + QCOMPARE(selected.count(), 6); + for (int i = 0; i < 5; ++i) + QVERIFY(selected.contains(model.index(i, 0))); +} + QTEST_MAIN(tst_QAbstractItemView) #include "tst_qabstractitemview.moc" diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 95501136cc..760dcac608 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -303,6 +303,12 @@ public: QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override { + if (onlyValidCalls) { + Q_ASSERT(row >= 0); + Q_ASSERT(column >= 0); + Q_ASSERT(row < rows); + Q_ASSERT(column < cols); + } if (row < 0 || column < 0 || (level(parent) > levels) || column >= cols || row >= rows) { return QModelIndex(); } @@ -411,6 +417,7 @@ public: mutable bool fetched = false; bool decorationsEnabled = false; bool statusTipsEnabled = false; + bool onlyValidCalls = false; }; // Testing get/set functions @@ -2459,6 +2466,7 @@ void tst_QTreeView::hiddenItems() void tst_QTreeView::spanningItems() { QtTestModel model(10, 10); + model.onlyValidCalls = true; QTreeView view; view.setModel(&model); view.show(); @@ -2498,6 +2506,8 @@ void tst_QTreeView::spanningItems() } } QCOMPARE(view.sizeHintForColumn(0), w); + + view.repaint(); // to check that this doesn't hit any assert } void tst_QTreeView::selectionOrderTest() diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 8a5eff3fac..9ab7e4e315 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -93,7 +93,11 @@ private slots: void quitOnLastWindowClosed(); void closeAllWindows(); void testDeleteLater(); - void testDeleteLaterProcessEvents(); + void testDeleteLaterProcessEvents1(); + void testDeleteLaterProcessEvents2(); + void testDeleteLaterProcessEvents3(); + void testDeleteLaterProcessEvents4(); + void testDeleteLaterProcessEvents5(); #if QT_CONFIG(library) void libraryPaths(); @@ -1225,6 +1229,11 @@ void DeleteLaterWidget::runTest() QCoreApplication::processEvents(); + // At this point, the event queue is empty. As we want a deferred + // deletion to occur before the timer event, we should provoke the + // event dispatcher for the next spin. + QCoreApplication::eventDispatcher()->interrupt(); + QVERIFY(!stillAlive); // verify at the end to make test terminate } @@ -1254,8 +1263,10 @@ void tst_QApplication::testDeleteLater() QObject *stillAlive = wgt->findChild<QObject*>("deleteLater"); QVERIFY(stillAlive); + wgt->show(); QCoreApplication::exec(); + QVERIFY(wgt->isHidden()); delete wgt; } @@ -1333,10 +1344,8 @@ public slots: } }; -void tst_QApplication::testDeleteLaterProcessEvents() +void tst_QApplication::testDeleteLaterProcessEvents1() { - int argc = 0; - // Calling processEvents() with no event dispatcher does nothing. QObject *object = new QObject; QPointer<QObject> p(object); @@ -1344,75 +1353,85 @@ void tst_QApplication::testDeleteLaterProcessEvents() QApplication::processEvents(); QVERIFY(p); delete object; +} - { - QApplication app(argc, nullptr); - // If you call processEvents() with an event dispatcher present, but - // outside any event loops, deferred deletes are not processed unless - // sendPostedEvents(0, DeferredDelete) is called. - object = new QObject; - p = object; - object->deleteLater(); - QCoreApplication::processEvents(); - QVERIFY(p); - QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); - QVERIFY(!p); - - // If you call deleteLater() on an object when there is no parent - // event loop, and then enter an event loop, the object will get - // deleted. - object = new QObject; - p = object; - object->deleteLater(); - QEventLoop loop; - QTimer::singleShot(1000, &loop, &QEventLoop::quit); - loop.exec(); - QVERIFY(!p); - } - { - // When an object is in an event loop, then calls deleteLater() and enters - // an event loop recursively, it should not die until the parent event - // loop continues. - QApplication app(argc, nullptr); - QEventLoop loop; - EventLoopNester *nester = new EventLoopNester; - p = nester; - QTimer::singleShot(3000, &loop, &QEventLoop::quit); - QTimer::singleShot(0, nester, &EventLoopNester::deleteLaterAndEnterLoop); - - loop.exec(); - QVERIFY(!p); - } - - { - // When the event loop that calls deleteLater() is exited - // immediately, the object should die when returning to the - // parent event loop - QApplication app(argc, nullptr); - QEventLoop loop; - EventLoopNester *nester = new EventLoopNester; - p = nester; - QTimer::singleShot(3000, &loop, &QEventLoop::quit); - QTimer::singleShot(0, nester, &EventLoopNester::deleteLaterAndExitLoop); +void tst_QApplication::testDeleteLaterProcessEvents2() +{ + int argc = 0; + QApplication app(argc, nullptr); + // If you call processEvents() with an event dispatcher present, but + // outside any event loops, deferred deletes are not processed unless + // sendPostedEvents(0, DeferredDelete) is called. + auto object = new QObject; + QPointer<QObject> p(object); + object->deleteLater(); + QCoreApplication::processEvents(); + QVERIFY(p); + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); + QVERIFY(!p); + + // If you call deleteLater() on an object when there is no parent + // event loop, and then enter an event loop, the object will get + // deleted. + QEventLoop loop; + object = new QObject; + connect(object, &QObject::destroyed, &loop, &QEventLoop::quit); + p = object; + object->deleteLater(); + QTimer::singleShot(1000, &loop, &QEventLoop::quit); + loop.exec(); + QVERIFY(!p); +} - loop.exec(); - QVERIFY(!p); - } +void tst_QApplication::testDeleteLaterProcessEvents3() +{ + int argc = 0; + // When an object is in an event loop, then calls deleteLater() and enters + // an event loop recursively, it should not die until the parent event + // loop continues. + QApplication app(argc, nullptr); + QEventLoop loop; + EventLoopNester *nester = new EventLoopNester; + QPointer<QObject> p(nester); + QTimer::singleShot(3000, &loop, &QEventLoop::quit); + QTimer::singleShot(0, nester, &EventLoopNester::deleteLaterAndEnterLoop); + + loop.exec(); + QVERIFY(!p); +} - { - // when the event loop that calls deleteLater() also calls - // processEvents() immediately afterwards, the object should - // not die until the parent loop continues - QApplication app(argc, nullptr); - QEventLoop loop; - EventLoopNester *nester = new EventLoopNester(); - p = nester; - QTimer::singleShot(3000, &loop, &QEventLoop::quit); - QTimer::singleShot(0, nester, &EventLoopNester::deleteLaterAndProcessEvents); +void tst_QApplication::testDeleteLaterProcessEvents4() +{ + int argc = 0; + // When the event loop that calls deleteLater() is exited + // immediately, the object should die when returning to the + // parent event loop + QApplication app(argc, nullptr); + QEventLoop loop; + EventLoopNester *nester = new EventLoopNester; + QPointer<QObject> p(nester); + QTimer::singleShot(3000, &loop, &QEventLoop::quit); + QTimer::singleShot(0, nester, &EventLoopNester::deleteLaterAndExitLoop); + + loop.exec(); + QVERIFY(!p); +} - loop.exec(); - QVERIFY(!p); - } +void tst_QApplication::testDeleteLaterProcessEvents5() +{ + // when the event loop that calls deleteLater() also calls + // processEvents() immediately afterwards, the object should + // not die until the parent loop continues + int argc = 0; + QApplication app(argc, nullptr); + QEventLoop loop; + EventLoopNester *nester = new EventLoopNester(); + QPointer<QObject> p(nester); + QTimer::singleShot(3000, &loop, &QEventLoop::quit); + QTimer::singleShot(0, nester, &EventLoopNester::deleteLaterAndProcessEvents); + + loop.exec(); + QVERIFY(!p); } /* diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 2483d7b5bb..5ffbbdd400 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -75,7 +75,7 @@ #include <qtimer.h> #include <QtWidgets/QDoubleSpinBox> -#if defined(Q_OS_OSX) +#if defined(Q_OS_MACOS) #include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile. #endif @@ -110,7 +110,7 @@ static HWND winHandleOf(const QWidget *w) # define Q_CHECK_PAINTEVENTS #endif -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS #include <Security/AuthSession.h> bool macHasAccessToWindowsServer() { @@ -216,7 +216,7 @@ private slots: void restoreVersion1Geometry(); void widgetAt(); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS void setMask(); #endif void optimizedResizeMove(); @@ -250,7 +250,7 @@ private slots: void update(); void isOpaque(); -#ifndef Q_OS_OSX +#ifndef Q_OS_MACOS void scroll(); void scrollNativeChildren(); #endif @@ -381,7 +381,7 @@ private slots: void taskQTBUG_7532_tabOrderWithFocusProxy(); void movedAndResizedAttributes(); void childAt(); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS void taskQTBUG_11373(); #endif void taskQTBUG_17333_ResizeInfiniteRecursion(); @@ -2301,7 +2301,7 @@ void tst_QWidget::activation() void tst_QWidget::windowState() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974"); #endif @@ -2514,7 +2514,7 @@ void tst_QWidget::showMaximized() void tst_QWidget::showFullScreen() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974"); #endif @@ -2834,14 +2834,14 @@ void tst_QWidget::showMinimizedKeepsFocus() window.showNormal(); QApplication::setActiveWindow(&window); QVERIFY(QTest::qWaitForWindowActive(&window)); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS if (!macHasAccessToWindowsServer()) QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); #elif defined(Q_OS_WINRT) QEXPECT_FAIL("", "Winrt fails here - QTBUG-68297", Continue); #endif QTRY_COMPARE(window.focusWidget(), firstchild); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS if (!macHasAccessToWindowsServer()) QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); #elif defined(Q_OS_WINRT) @@ -2904,7 +2904,7 @@ void tst_QWidget::reparent() // Qt/Embedded does it differently. void tst_QWidget::icon() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974"); #endif @@ -2970,7 +2970,7 @@ void tst_QWidget::hideWhenFocusWidgetIsChild() void tst_QWidget::normalGeometry() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974"); #endif @@ -3230,7 +3230,7 @@ public: void tst_QWidget::lostUpdatesOnHide() { -#ifndef Q_OS_OSX +#ifndef Q_OS_MACOS UpdateWidget widget; widget.setAttribute(Qt::WA_DontShowOnScreen); widget.setWindowTitle(QLatin1String(QTest::currentTestFunction())); @@ -3271,7 +3271,7 @@ void tst_QWidget::raise() parentPtr->show(); QVERIFY(QTest::qWaitForWindowExposed(parentPtr.data())); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS if (child1->internalWinId()) { QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events."); } @@ -3412,7 +3412,7 @@ void tst_QWidget::lower() void tst_QWidget::stackUnder() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974: Cocoa has no Z-Order for views, we hack it, but it results in paint events."); #endif @@ -3445,7 +3445,7 @@ void tst_QWidget::stackUnder() for (UpdateWidget *child : qAsConst(allChildren)) { int expectedPaintEvents = child == child4 ? 1 : 0; -#if defined(Q_OS_WIN) || defined(Q_OS_OSX) +#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) if (expectedPaintEvents == 1 && child->numPaintEvents == 2) QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue); #endif @@ -3479,7 +3479,7 @@ void tst_QWidget::stackUnder() for (UpdateWidget *child : qAsConst(allChildren)) { int expectedZOrderChangeEvents = child == child1 ? 1 : 0; if (child == child3) { -#ifndef Q_OS_OSX +#ifndef Q_OS_MACOS QEXPECT_FAIL(0, "See QTBUG-493", Continue); #endif QCOMPARE(child->numPaintEvents, 0); @@ -3579,7 +3579,7 @@ void tst_QWidget::testContentsPropagation() void tst_QWidget::saveRestoreGeometry() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974"); #endif @@ -3817,7 +3817,7 @@ void tst_QWidget::restoreVersion1Geometry() void tst_QWidget::widgetAt() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974"); #endif @@ -4020,7 +4020,7 @@ void tst_QWidget::testDeletionInEventHandlers() delete w; } -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS class MaskedPainter : public QWidget { public: @@ -4887,7 +4887,7 @@ void tst_QWidget::update() QCOMPARE(sibling.numPaintEvents, 1); QCOMPARE(sibling.paintedRegion, sibling.visibleRegion()); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS if (child.internalWinId()) // child is native QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue); #endif @@ -4904,7 +4904,7 @@ void tst_QWidget::update() } } -#ifndef Q_OS_OSX +#ifndef Q_OS_MACOS static inline bool isOpaque(QWidget *widget) { if (!widget) @@ -4915,7 +4915,7 @@ static inline bool isOpaque(QWidget *widget) void tst_QWidget::isOpaque() { -#ifndef Q_OS_OSX +#ifndef Q_OS_MACOS QWidget w; QVERIFY(::isOpaque(&w)); @@ -4987,7 +4987,7 @@ void tst_QWidget::isOpaque() #endif } -#ifndef Q_OS_OSX +#ifndef Q_OS_MACOS /* Test that scrolling of a widget invalidates the correct regions */ @@ -5431,7 +5431,7 @@ void tst_QWidget::windowMoveResize() widget.move(r.topLeft()); widget.resize(r.size()); QApplication::processEvents(); -#if defined(Q_OS_OSX) +#if defined(Q_OS_MACOS) if (r.width() == 0 && r.height() > 0) { widget.move(r.topLeft()); widget.resize(r.size()); @@ -5502,7 +5502,7 @@ void tst_QWidget::windowMoveResize() widget.move(r.topLeft()); widget.resize(r.size()); QApplication::processEvents(); -#if defined(Q_OS_OSX) +#if defined(Q_OS_MACOS) if (r.width() == 0 && r.height() > 0) { widget.move(r.topLeft()); widget.resize(r.size()); @@ -5689,7 +5689,7 @@ void tst_QWidget::moveChild() QTRY_COMPARE(pos, child.pos()); QTRY_COMPARE(parent.r, QRegion(oldGeometry) - child.geometry()); -#if !defined(Q_OS_OSX) +#if !defined(Q_OS_MACOS) // should be scrolled in backingstore QCOMPARE(child.r, QRegion()); #endif @@ -5739,7 +5739,7 @@ void tst_QWidget::showAndMoveChild() void tst_QWidget::subtractOpaqueSiblings() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974: Cocoa only has rect granularity."); #endif @@ -5816,7 +5816,7 @@ public slots: void tst_QWidget::multipleToplevelFocusCheck() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974"); #endif @@ -7584,7 +7584,7 @@ void tst_QWidget::render_systemClip() // rrrrrrrrrr // ... -#ifndef Q_OS_OSX +#ifndef Q_OS_MACOS for (int i = 0; i < image.height(); ++i) { for (int j = 0; j < image.width(); ++j) { if (i < 50 && j < i) @@ -8618,11 +8618,11 @@ void tst_QWidget::sendUpdateRequestImmediately() void tst_QWidget::doubleRepaint() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974"); #endif -#if defined(Q_OS_OSX) +#if defined(Q_OS_MACOS) if (!macHasAccessToWindowsServer()) QSKIP("Not having window server access causes the wrong number of repaints to be issues"); #endif @@ -9330,7 +9330,7 @@ void tst_QWidget::setClearAndResizeMask() child.setMask(childMask); QTRY_COMPARE(child.mask(), childMask); // and ensure that the child widget doesn't get any update. -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QCOMPARE(child.numPaintEvents, 1); @@ -9352,7 +9352,7 @@ void tst_QWidget::setClearAndResizeMask() // and ensure that that the child widget gets an update for the area outside the old mask. QTRY_COMPARE(child.numPaintEvents, 1); outsideOldMask = child.rect(); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (!child.internalWinId()) #endif @@ -9366,7 +9366,7 @@ void tst_QWidget::setClearAndResizeMask() // Mask child widget with a mask that is bigger than the rect child.setMask(QRegion(0, 0, 1000, 1000)); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(child.numPaintEvents, 1); @@ -9379,7 +9379,7 @@ void tst_QWidget::setClearAndResizeMask() // ...and the same applies when clearing the mask. child.clearMask(); QTest::qWait(100); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_VERIFY(child.numPaintEvents > 0); @@ -9409,7 +9409,7 @@ void tst_QWidget::setClearAndResizeMask() QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask())); QTest::qWait(200); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); @@ -9421,7 +9421,7 @@ void tst_QWidget::setClearAndResizeMask() const QRegion oldMask = resizeChild.mask(); QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask())); QTest::qWait(100); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); @@ -10265,7 +10265,7 @@ void tst_QWidget::childAt() QCOMPARE(parent.childAt(120, 120), grandChild); } -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS void tst_QWidget::taskQTBUG_11373() { @@ -11121,7 +11121,7 @@ public: // when mousing over it. void tst_QWidget::taskQTBUG_27643_enterEvents() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QTBUG-52974: this test can crash!"); #endif // Move the mouse cursor to a safe location so it won't interfere diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 0ae2e6626f..82527849b0 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -995,7 +995,7 @@ void tst_QStyleSheetStyle::focusColors() #ifndef QT_NO_CURSOR void tst_QStyleSheetStyle::hoverColors() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("This test is fragile on Mac, most likely due to QTBUG-33959."); #endif if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) diff --git a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp index 8bdd4b4783..5e71c1888d 100644 --- a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp +++ b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp @@ -82,8 +82,8 @@ public: currentPos = se->contentPos(); overshoot = se->overshootDistance(); - if (!qFuzzyCompare( overshoot.x() + 1.0, 1.0 ) || - !qFuzzyCompare( overshoot.y() + 1.0, 1.0 )) + if (!qFuzzyCompare(overshoot.x() + 1.0, 1.0) || + !qFuzzyCompare(overshoot.y() + 1.0, 1.0)) receivedOvershoot = true; return true; } @@ -116,8 +116,8 @@ public: ~tst_QScroller() { } private: - void kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); - void kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); + void kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); + void kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); private slots: void staticScrollers(); @@ -135,13 +135,13 @@ private: Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling. Tests some in between states but does not wait until scrolling is finished. */ -void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) +void tst_QScroller::kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) { sw->scrollPosition = from; sw->currentPos= from; QScroller *s1 = QScroller::scroller(sw); - QCOMPARE( s1->state(), QScroller::Inactive ); + QCOMPARE(s1->state(), QScroller::Inactive); QScrollerProperties sp1 = QScroller::scroller(sw)->scrollerProperties(); @@ -161,7 +161,7 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint (QList<QTouchEvent::TouchPoint>() << touchPoint)); QApplication::sendEvent(sw, &touchEvent1); - QCOMPARE( s1->state(), QScroller::Pressed ); + QCOMPARE(s1->state(), QScroller::Pressed); // send the touch update far enough to trigger a scroll QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second. @@ -175,13 +175,13 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint (QList<QTouchEvent::TouchPoint>() << touchPoint)); QApplication::sendEvent(sw, &touchEvent2); - QCOMPARE( s1->state(), QScroller::Dragging ); - QCOMPARE( sw->receivedPrepare, true ); + QCOMPARE(s1->state(), QScroller::Dragging); + QCOMPARE(sw->receivedPrepare, true); - QTRY_COMPARE( sw->receivedFirst, true ); - QCOMPARE( sw->receivedScroll, true ); - QCOMPARE( sw->receivedOvershoot, false ); + QTRY_COMPARE(sw->receivedFirst, true); + QCOMPARE(sw->receivedScroll, true); + QCOMPARE(sw->receivedOvershoot, false); // note that the scrolling goes in a different direction than the mouse move QPoint calculatedPos = from.toPoint() - touchUpdate - touchStart; @@ -204,13 +204,13 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling. This function does not have any in between tests, it does not expect the scroller to actually scroll. */ -void tst_QScroller::kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) +void tst_QScroller::kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) { sw->scrollPosition = from; sw->currentPos = from; QScroller *s1 = QScroller::scroller(sw); - QCOMPARE( s1->state(), QScroller::Inactive ); + QCOMPARE(s1->state(), QScroller::Inactive); QScrollerProperties sp1 = s1->scrollerProperties(); int fps = 60; @@ -348,52 +348,57 @@ void tst_QScroller::scrollerProperties() void tst_QScroller::scrollTo() { - { - tst_QScrollerWidget *sw = new tst_QScrollerWidget(); - sw->scrollArea = QRectF( 0, 0, 1000, 1000 ); - sw->scrollPosition = QPointF( 500, 500 ); - - QScroller *s1 = QScroller::scroller(sw); - QCOMPARE( s1->state(), QScroller::Inactive ); - - // a normal scroll - s1->scrollTo(QPointF(100,100), 100); - QTest::qWait(200); - - QCOMPARE( sw->receivedPrepare, true ); - QCOMPARE( sw->receivedScroll, true ); - QCOMPARE( sw->receivedFirst, true ); - QCOMPARE( sw->receivedLast, true ); - QCOMPARE( sw->receivedOvershoot, false ); - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 100 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 100 )); - - delete sw; - } + QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget); + sw->show(); + QApplication::setActiveWindow(sw.data()); + if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data())) + QSKIP("Failed to show and activate window"); + + sw->scrollArea = QRectF(0, 0, 1000, 1000); + sw->scrollPosition = QPointF(500, 500); + + QScroller *s1 = QScroller::scroller(sw.data()); + QCOMPARE(s1->state(), QScroller::Inactive); + + // a normal scroll + s1->scrollTo(QPointF(100,100), 100); + QTest::qWait(200); + + QTRY_COMPARE(sw->receivedPrepare, true); + QCOMPARE(sw->receivedScroll, true); + QCOMPARE(sw->receivedFirst, true); + QCOMPARE(sw->receivedLast, true); + QCOMPARE(sw->receivedOvershoot, false); + QTRY_VERIFY(qFuzzyCompare(sw->currentPos.x(), 100)); + QVERIFY(qFuzzyCompare(sw->currentPos.y(), 100)); } void tst_QScroller::scroll() { #if QT_CONFIG(gestures) && QT_CONFIG(scroller) // -- good case. normal scroll - tst_QScrollerWidget *sw = new tst_QScrollerWidget(); + QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget()); sw->scrollArea = QRectF(0, 0, 1000, 1000); - QScroller::grabGesture(sw, QScroller::TouchGesture); + QScroller::grabGesture(sw.data(), QScroller::TouchGesture); sw->setGeometry(100, 100, 400, 300); + sw->show(); + QApplication::setActiveWindow(sw.data()); + if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data())) + QSKIP("Failed to show and activate window"); - QScroller *s1 = QScroller::scroller(sw); - kineticScroll(sw, QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); + QScroller *s1 = QScroller::scroller(sw.data()); + kineticScroll(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); // now we should be scrolling - QTRY_COMPARE( s1->state(), QScroller::Scrolling ); + QTRY_COMPARE(s1->state(), QScroller::Scrolling); // wait until finished, check that no further first scroll is sent sw->receivedFirst = false; sw->receivedScroll = false; QTRY_VERIFY(s1->state() != QScroller::Scrolling); - QCOMPARE( sw->receivedFirst, false ); - QCOMPARE( sw->receivedScroll, true ); - QCOMPARE( sw->receivedLast, true ); + QCOMPARE(sw->receivedFirst, false); + QCOMPARE(sw->receivedScroll, true); + QCOMPARE(sw->receivedLast, true); QVERIFY(sw->currentPos.x() < 400); QVERIFY(sw->currentPos.y() < 400); @@ -401,26 +406,28 @@ void tst_QScroller::scroll() sw->reset(); sw->scrollArea = QRectF(0, 0, 0, 1000); - kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(100, 0), QPoint(200, 0)); + kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(100, 0), QPoint(200, 0)); QTRY_COMPARE(s1->state(), QScroller::Inactive); QCOMPARE(sw->currentPos.x(), 0.0); QCOMPARE(sw->currentPos.y(), 500.0); - - delete sw; #endif } void tst_QScroller::overshoot() { #if QT_CONFIG(gestures) && QT_CONFIG(scroller) - tst_QScrollerWidget *sw = new tst_QScrollerWidget(); + QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget); sw->scrollArea = QRectF(0, 0, 1000, 1000); - QScroller::grabGesture(sw, QScroller::TouchGesture); + QScroller::grabGesture(sw.data(), QScroller::TouchGesture); sw->setGeometry(100, 100, 400, 300); + sw->show(); + QApplication::setActiveWindow(sw.data()); + if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data())) + QSKIP("Failed to show and activate window"); - QScroller *s1 = QScroller::scroller(sw); + QScroller *s1 = QScroller::scroller(sw.data()); QScrollerProperties sp1 = s1->scrollerProperties(); sp1.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.5); @@ -431,14 +438,14 @@ void tst_QScroller::overshoot() sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable)); s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); QTRY_COMPARE(s1->state(), QScroller::Inactive); //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, true ); + QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); + QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); + QCOMPARE(sw->receivedOvershoot, true); // -- try to scroll with overshoot (when scrollable bad case) sw->reset(); @@ -446,14 +453,14 @@ void tst_QScroller::overshoot() sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable)); s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); QTRY_COMPARE(s1->state(), QScroller::Inactive); //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, false ); + QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); + QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); + QCOMPARE(sw->receivedOvershoot, false); // -- try to scroll with overshoot (always on) sw->reset(); @@ -461,15 +468,15 @@ void tst_QScroller::overshoot() sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); QTRY_COMPARE(s1->state(), QScroller::Inactive); //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, true ); + QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); + QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); + QCOMPARE(sw->receivedOvershoot, true); // -- try to scroll with overshoot (always off) sw->reset(); @@ -477,13 +484,13 @@ void tst_QScroller::overshoot() sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); QTRY_COMPARE(s1->state(), QScroller::Inactive); - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, false ); + QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); + QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); + QCOMPARE(sw->receivedOvershoot, false); // -- try to scroll with overshoot (always on but max overshoot = 0) sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0); @@ -493,39 +500,39 @@ void tst_QScroller::overshoot() sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); QTRY_COMPARE(s1->state(), QScroller::Inactive); - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, false ); - - delete sw; + QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); + QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); + QCOMPARE(sw->receivedOvershoot, false); #endif } void tst_QScroller::multipleWindows() { #if QT_CONFIG(gestures) && QT_CONFIG(scroller) - QScopedPointer<tst_QScrollerWidget> sw1(new tst_QScrollerWidget()); + QScopedPointer<tst_QScrollerWidget> sw1(new tst_QScrollerWidget); sw1->scrollArea = QRectF(0, 0, 1000, 1000); QScroller::grabGesture(sw1.data(), QScroller::TouchGesture); sw1->setGeometry(100, 100, 400, 300); + QScroller *s1 = QScroller::scroller(sw1.data()); kineticScroll(sw1.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); // now we should be scrolling - QTRY_COMPARE( s1->state(), QScroller::Scrolling ); + QTRY_COMPARE(s1->state(), QScroller::Scrolling); // That was fun! Do it again! QScopedPointer<tst_QScrollerWidget> sw2(new tst_QScrollerWidget()); sw2->scrollArea = QRectF(0, 0, 1000, 1000); QScroller::grabGesture(sw2.data(), QScroller::TouchGesture); sw2->setGeometry(100, 100, 400, 300); + QScroller *s2 = QScroller::scroller(sw2.data()); kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); // now we should be scrolling - QTRY_COMPARE( s2->state(), QScroller::Scrolling ); + QTRY_COMPARE(s2->state(), QScroller::Scrolling); // wait for both to stop QTRY_VERIFY(s1->state() != QScroller::Scrolling); diff --git a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp index 999cf4a941..e4f927750e 100644 --- a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp +++ b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp @@ -83,6 +83,7 @@ Q_OBJECT private slots: void arrowKeyNavigation(); + void keyNavigationPushButtons(); void exclusive(); void exclusiveWithActions(); void testSignals(); @@ -185,6 +186,73 @@ void tst_QButtonGroup::arrowKeyNavigation() QVERIFY(bt3.hasFocus()); } +/* + Test that tab and arrow key navigation through buttons + in an invisible button group works as expected. Tabbing + into the group should give focus to the checked button, + and arrow navigation should change the checked button and + move focus. +*/ +void tst_QButtonGroup::keyNavigationPushButtons() +{ + if (!qt_tab_all_widgets()) + QSKIP("This test requires full keyboard control to be enabled."); + + QDialog dlg(nullptr); + QLineEdit *le1 = new QLineEdit; + le1->setObjectName("le1"); + QPushButton *pb1 = new QPushButton("Exclusive 1"); + pb1->setObjectName("pb1"); + pb1->setCheckable(true); + pb1->setChecked(true); + QPushButton *pb2 = new QPushButton("Exclusive 2"); + pb2->setObjectName("pb2"); + pb2->setCheckable(true); + QPushButton *pb3 = new QPushButton("Exclusive 3"); + pb3->setObjectName("pb3"); + pb3->setCheckable(true); + QLineEdit *le2 = new QLineEdit; + le2->setObjectName("le2"); + + QVBoxLayout* layout = new QVBoxLayout(&dlg); + layout->addWidget(le1); + layout->addWidget(pb1); + layout->addWidget(pb2); + layout->addWidget(pb3); + layout->addWidget(le2); + + QButtonGroup *buttonGroup = new QButtonGroup; + buttonGroup->addButton(pb1); + buttonGroup->addButton(pb2); + buttonGroup->addButton(pb3); + + dlg.show(); + qApp->setActiveWindow(&dlg); + if (!QTest::qWaitForWindowActive(&dlg)) + QSKIP("Window activation failed, skipping test"); + + QVERIFY2(le1->hasFocus(), qPrintable(qApp->focusWidget()->objectName())); + QTest::keyClick(qApp->focusWidget(), Qt::Key_Tab); + QVERIFY2(pb1->hasFocus(), qPrintable(qApp->focusWidget()->objectName())); + QVERIFY2(pb1->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName())); + QTest::keyClick(qApp->focusWidget(), Qt::Key_Down); + QVERIFY2(pb2->hasFocus(), qPrintable(qApp->focusWidget()->objectName())); + QVERIFY2(pb2->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName())); + QTest::keyClick(qApp->focusWidget(), Qt::Key_Down); + QVERIFY2(pb3->hasFocus(), qPrintable(qApp->focusWidget()->objectName())); + QVERIFY2(pb3->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName())); + QTest::keyClick(qApp->focusWidget(), Qt::Key_Up); + QVERIFY2(pb2->hasFocus(), qPrintable(qApp->focusWidget()->objectName())); + QVERIFY2(pb2->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName())); + QTest::keyClick(qApp->focusWidget(), Qt::Key_Tab); + QVERIFY2(le2->hasFocus(), qPrintable(qApp->focusWidget()->objectName())); + QTest::keyClick(qApp->focusWidget(), Qt::Key_Backtab); + QVERIFY2(pb2->hasFocus(), qPrintable(qApp->focusWidget()->objectName())); + QVERIFY2(pb2->isChecked(), qPrintable(buttonGroup->checkedButton()->objectName())); + QTest::keyClick(qApp->focusWidget(), Qt::Key_Backtab); + QVERIFY2(le1->hasFocus(), qPrintable(qApp->focusWidget()->objectName())); +} + void tst_QButtonGroup::exclusiveWithActions() { QDialog dlg(0); diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index bd3c6d1f03..10430e1796 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -1208,7 +1208,7 @@ void tst_QComboBox::currentIndex() QVERIFY(testWidget->currentText().isEmpty()); // spy on currentIndexChanged - QSignalSpy indexChangedSpy(testWidget, SIGNAL(currentIndexChanged(int, QString))); + QSignalSpy indexChangedInt(testWidget, SIGNAL(currentIndexChanged(int))); // stuff items into it foreach(QString text, initialItems) { @@ -1232,12 +1232,12 @@ void tst_QComboBox::currentIndex() QCOMPARE(testWidget->currentText(), expectedCurrentText); // check that signal count is correct - QCOMPARE(indexChangedSpy.count(), expectedSignalCount); + QCOMPARE(indexChangedInt.count(), expectedSignalCount); // compare with last sent signal values - if (indexChangedSpy.count()) - QCOMPARE(indexChangedSpy.at(indexChangedSpy.count() - 1).at(0).toInt(), - testWidget->currentIndex()); + if (indexChangedInt.count()) + QCOMPARE(indexChangedInt.at(indexChangedInt.count() - 1).at(0).toInt(), + testWidget->currentIndex()); if (edit) { testWidget->setCurrentIndex(-1); @@ -2336,8 +2336,7 @@ public: { QStringList list; list << "one" << "two"; - connect(this, SIGNAL(currentIndexChanged(int, QString)), - this, SLOT(onCurrentIndexChanged(int))); + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); addItems(list); } public slots: diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp index 9659d89833..08c80c96ab 100644 --- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -195,6 +195,8 @@ private slots: void specialValueText(); void setRange_data(); void setRange(); + void editingRanged_data(); + void editingRanged(); void selectAndScrollWithKeys(); void backspaceKey(); @@ -1312,6 +1314,120 @@ void tst_QDateTimeEdit::setRange() } } +/* + Test that a user can input a date into a ranged QDateTimeEdit or QDateEdit + where a part of date is larger than the respective part of the maximum, or + smaller than the respective part of the minimum of the range. + + This test is expected to fail unless keyboard tracking of the edit is set + to off. Otherwise the changed-signal would be emitted with values outside + of the allowed range as the user types. +*/ +void tst_QDateTimeEdit::editingRanged_data() +{ + QTest::addColumn<QDate>("minDate"); + QTest::addColumn<QTime>("minTime"); + QTest::addColumn<QDate>("maxDate"); + QTest::addColumn<QTime>("maxTime"); + QTest::addColumn<QString>("userInput"); + QTest::addColumn<QDateTime>("expected"); + + QTest::addRow("trivial") + << QDate(2010, 1, 1) << QTime(9, 0) + << QDate(2011, 12, 31) << QTime(16, 0) + << QString::fromLatin1("311220101600") + << QDateTime(QDate(2010, 12, 31), QTime(16, 0)); + + QTest::addRow("data0") + << QDate(2010, 12, 30) << QTime(16, 0) + << QDate(2011, 1, 2) << QTime(9, 0) + << QString::fromLatin1("311220102359") + << QDateTime(QDate(2010, 12, 31), QTime(23, 59)); + + QTest::addRow("data1") + << QDate(2010, 12, 30) << QTime(16, 0) + << QDate(2011, 1, 2) << QTime(9, 0) + << QString::fromLatin1("010120111823") + << QDateTime(QDate(2011, 1, 1), QTime(18, 23)); + + QTest::addRow("Out of range") + << QDate(2010, 12, 30) << QTime(16, 0) + << QDate(2011, 1, 2) << QTime(9, 0) + << QString::fromLatin1("090920111823") + << QDateTime(QDate(2011, 1, 2), QTime(9, 0)); + + QTest::addRow("only date") + << QDate(2010, 12, 30) << QTime() + << QDate(2011, 1, 2) << QTime() + << QString::fromLatin1("01012011") + << QDateTime(QDate(2011, 1, 1), QTime()); +} + +void tst_QDateTimeEdit::editingRanged() +{ + QFETCH(QDate, minDate); + QFETCH(QTime, minTime); + QFETCH(QDate, maxDate); + QFETCH(QTime, maxTime); + QFETCH(QString, userInput); + QFETCH(QDateTime, expected); + + QDateTimeEdit *edit; + if (minTime.isValid()) { + edit = new QDateTimeEdit; + edit->setDisplayFormat("dd.MM.yyyy hh:mm"); + edit->setDateTimeRange(QDateTime(minDate, minTime), QDateTime(maxDate, maxTime)); + } else { + edit = new QDateEdit; + edit->setDisplayFormat("dd.MM.yyyy"); + edit->setDateRange(minDate, maxDate); + } + + int callCount = 0; + connect(edit, &QDateTimeEdit::dateTimeChanged, [&](const QDateTime &dateTime) { + ++callCount; + if (minTime.isValid()) { + QVERIFY(dateTime >= QDateTime(minDate, minTime)); + QVERIFY(dateTime <= QDateTime(maxDate, maxTime)); + } else { + QVERIFY(dateTime.date() >= minDate); + QVERIFY(dateTime.date() <= maxDate); + } + }); + + edit->show(); + QApplication::setActiveWindow(edit); + if (!QTest::qWaitForWindowActive(edit)) + QSKIP("Failed to make window active, aborting"); + edit->setFocus(); + + // with keyboard tracking, never get a signal with an out-of-range value + edit->setKeyboardTracking(true); + QTest::keyClicks(edit, userInput); + QTest::keyClick(edit, Qt::Key_Return); + QVERIFY(callCount > 0); + + // QDateTimeEdit blocks these dates from being entered - see QTBUG-65 + QEXPECT_FAIL("data0", "Can't enter this date", Continue); + QEXPECT_FAIL("data1", "Can't enter this date", Continue); + QEXPECT_FAIL("Out of range", "Can't enter this date", Continue); + QEXPECT_FAIL("only date", "Can't enter this date", Continue); + QCOMPARE(edit->dateTime(), expected); + + // reset + edit->clearFocus(); + edit->setFocus(); + callCount = 0; + + edit->setKeyboardTracking(false); + QTest::keyClicks(edit, userInput); + QTest::keyClick(edit, Qt::Key_Return); + QCOMPARE(edit->dateTime(), expected); + QCOMPARE(callCount, 1); + + delete edit; +} + void tst_QDateTimeEdit::wrappingTime_data() { QTest::addColumn<bool>("startWithMin"); diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index a89b3231ad..c07961f867 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -1267,7 +1267,7 @@ void tst_QMenu::QTBUG47515_widgetActionEnterLeave() if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) QSKIP("Window activation is not supported"); if (QGuiApplication::platformName() == QLatin1String("cocoa")) - QSKIP("See QTBUG-63031"); + QSKIP("This test is meaningless on macOS, for additional info see QTBUG-63031"); const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry(); QRect geometry(QPoint(), availableGeometry.size() / 3); diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 8cbe821a68..90e89ff1d5 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -1537,7 +1537,7 @@ void tst_QMenuBar::cornerWidgets() QFETCH(Qt::Corner, corner); -#if defined(Q_OS_OSX) +#if defined(Q_OS_MACOS) QSKIP("Test interferes with native menu bars on this platform"); #endif diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index 73423d958b..cb4fc201f6 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -579,7 +579,7 @@ bool verifyColor(const QWidget *widget, const QRect &clipArea, const QColor &col void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible() { -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS QSKIP("QScreen::grabWindow() doesn't work properly on OSX HighDPI screen: QTBUG-46803"); return; #endif |