diff options
Diffstat (limited to 'tests/auto/widgets/dialogs')
43 files changed, 1251 insertions, 833 deletions
diff --git a/tests/auto/widgets/dialogs/.prev_CMakeLists.txt b/tests/auto/widgets/dialogs/.prev_CMakeLists.txt deleted file mode 100644 index 7bb279e271..0000000000 --- a/tests/auto/widgets/dialogs/.prev_CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Generated from dialogs.pro. - -add_subdirectory(qcolordialog) -add_subdirectory(qdialog) -add_subdirectory(qerrormessage) -add_subdirectory(qfiledialog2) -add_subdirectory(qfontdialog) -add_subdirectory(qinputdialog) -add_subdirectory(qprogressdialog) -add_subdirectory(qwizard) -if(NOT ANDROID) - add_subdirectory(qfiledialog) - add_subdirectory(qmessagebox) -endif() -if(QT_FEATURE_private_tests) - add_subdirectory(qsidebar) -endif() diff --git a/tests/auto/widgets/dialogs/CMakeLists.txt b/tests/auto/widgets/dialogs/CMakeLists.txt index c21c65dbe3..f46950b6bf 100644 --- a/tests/auto/widgets/dialogs/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/CMakeLists.txt @@ -1,4 +1,5 @@ -# Generated from dialogs.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(qcolordialog) add_subdirectory(qdialog) @@ -8,9 +9,9 @@ add_subdirectory(qfontdialog) add_subdirectory(qinputdialog) add_subdirectory(qprogressdialog) add_subdirectory(qwizard) -# QTBUG-87671 # special case +add_subdirectory(qfiledialog) +# QTBUG-101217, qmessagebox hangs on Android if(NOT ANDROID) - add_subdirectory(qfiledialog) add_subdirectory(qmessagebox) endif() if(QT_FEATURE_private_tests) diff --git a/tests/auto/widgets/dialogs/dialogs.pro b/tests/auto/widgets/dialogs/dialogs.pro deleted file mode 100644 index 6d6f6987f0..0000000000 --- a/tests/auto/widgets/dialogs/dialogs.pro +++ /dev/null @@ -1,24 +0,0 @@ -TEMPLATE=subdirs -SUBDIRS=\ - qcolordialog \ - qdialog \ - qerrormessage \ - qfiledialog \ - qfiledialog2 \ - qfontdialog \ - qinputdialog \ - qmessagebox \ - qprogressdialog \ - qsidebar \ - qwizard \ - -# QTBUG-87671 -android: SUBDIRS -= \ - qfiledialog \ - qmessagebox - -!qtConfig(private_tests): SUBDIRS -= \ - qsidebar \ - -mac:qinputdialog.CONFIG += no_check_target # QTBUG-25496 - diff --git a/tests/auto/widgets/dialogs/qcolordialog/CMakeLists.txt b/tests/auto/widgets/dialogs/qcolordialog/CMakeLists.txt index a25c02ad92..2cba18c0f0 100644 --- a/tests/auto/widgets/dialogs/qcolordialog/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qcolordialog/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qcolordialog.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qcolordialog Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qcolordialog LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qcolordialog SOURCES tst_qcolordialog.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui Qt::Widgets ) diff --git a/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro deleted file mode 100644 index 563db6e887..0000000000 --- a/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG += testcase -TARGET = tst_qcolordialog -QT += widgets testlib -SOURCES += tst_qcolordialog.cpp diff --git a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp index c329ca9f3e..5ae8eaf30d 100644 --- a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp +++ b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp @@ -1,35 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QTest> #include <QtGui/QtGui> #include <QtWidgets/QColorDialog> +#include <QtWidgets/QLineEdit> +#include <QSignalSpy> QT_FORWARD_DECLARE_CLASS(QtTestEventThread) @@ -50,6 +27,10 @@ private slots: void native_activeModalWidget(); void task247349_alpha(); void QTBUG_43548_initialColor(); + void hexColor_data(); + void hexColor(); + + void hideNativeByDestruction(); }; class TestNativeDialog : public QColorDialog @@ -102,7 +83,7 @@ void tst_QColorDialog::native_activeModalWidget() void tst_QColorDialog::postKeyReturn() { QWidgetList list = QApplication::topLevelWidgets(); - for (int i=0; i<list.count(); ++i) { + for (int i=0; i<list.size(); ++i) { QColorDialog *dialog = qobject_cast<QColorDialog *>(list[i]); if (dialog) { QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier ); @@ -151,5 +132,81 @@ void tst_QColorDialog::QTBUG_43548_initialColor() QCOMPARE(a, dialog.currentColor()); } +void tst_QColorDialog::hexColor_data() +{ + QTest::addColumn<const QString>("colorString"); + QTest::addColumn<const QString>("expectedHexColor"); + QTest::addColumn<const int>("expectedSignalCount"); + + QTest::newRow("White-#") << "#FFFFFE" << "#FFFFFE" << 1; + QTest::newRow("White") << "FFFFFD" << "#FFFFFD" << 1; + QTest::newRow("Blue-#") << "#77fffb" << "#77fffb" << 2; + QTest::newRow("Blue") << "77fffa" << "#77fffa" << 2; +} + +void tst_QColorDialog::hexColor() +{ + QColorDialog dialog; + dialog.setOption(QColorDialog::DontUseNativeDialog); + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + + QLineEdit *lineEdit = dialog.findChild<QLineEdit *>("qt_colorname_lineedit", + Qt::FindChildrenRecursively); + QVERIFY2(lineEdit, "QLineEdit for color not found. Adapt this test."); + QVERIFY(lineEdit); // eliminate compiler warning + + QFETCH(const QString, colorString); + QFETCH(const QString, expectedHexColor); + QFETCH(const int, expectedSignalCount); + + QSignalSpy spy(&dialog, &QColorDialog::currentColorChanged); + + // Delete existing color + lineEdit->activateWindow(); + QVERIFY(QTest::qWaitForWindowActive(lineEdit)); + for (int i = 0; i < 8; ++i) + QTest::keyEvent(QTest::KeyAction::Click, lineEdit, Qt::Key_Backspace); + QVERIFY(lineEdit->text().isEmpty()); + + // Enter new color + for (const QChar &key : colorString) + QTest::keyEvent(QTest::KeyAction::Click, lineEdit, key.toLatin1()); + QCOMPARE(lineEdit->text().toLower(), expectedHexColor.toLower()); + + // Consume all color change signals + QTRY_COMPARE(spy.count(), expectedSignalCount); + + const QColor color = qvariant_cast<QColor>(spy.last().at(0)); + QCOMPARE(color.name(QColor::HexRgb), expectedHexColor.toLower()); +} + +void tst_QColorDialog::hideNativeByDestruction() +{ + QWidget window; + QWidget *child = new QWidget(&window); + QPointer<QColorDialog> dialog = new QColorDialog(child); + // Make it application modal so that we don't end up with a sheet on macOS + dialog->setWindowModality(Qt::ApplicationModal); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + dialog->open(); + + // We test that the dialog opens and closes by watching the activation of the + // transient parent window. If it doesn't deactivate, then we have to skip. + const auto windowActive = [&window]{ return window.isActiveWindow(); }; + const auto windowInactive = [&window]{ return !window.isActiveWindow(); }; + if (!QTest::qWaitFor(windowInactive, 2000)) + QSKIP("Dialog didn't activate"); + + // This should destroy the dialog and close the native window + child->deleteLater(); + QTRY_VERIFY(!dialog); + // If the native window is still open, then the transient parent can't become + // active + window.activateWindow(); + QVERIFY(QTest::qWaitFor(windowActive)); +} + QTEST_MAIN(tst_QColorDialog) #include "tst_qcolordialog.moc" diff --git a/tests/auto/widgets/dialogs/qdialog/BLACKLIST b/tests/auto/widgets/dialogs/qdialog/BLACKLIST index 02eb64cb8b..ad86386895 100644 --- a/tests/auto/widgets/dialogs/qdialog/BLACKLIST +++ b/tests/auto/widgets/dialogs/qdialog/BLACKLIST @@ -2,6 +2,3 @@ macos [showFullScreen] macos ci -# QTBUG-87389 -[snapToDefaultButton] -android diff --git a/tests/auto/widgets/dialogs/qdialog/CMakeLists.txt b/tests/auto/widgets/dialogs/qdialog/CMakeLists.txt index 08c4222535..d69310541d 100644 --- a/tests/auto/widgets/dialogs/qdialog/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qdialog/CMakeLists.txt @@ -1,15 +1,23 @@ -# Generated from qdialog.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qdialog Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qdialog LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qdialog SOURCES tst_qdialog.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Widgets + Qt::WidgetsPrivate ) diff --git a/tests/auto/widgets/dialogs/qdialog/qdialog.pro b/tests/auto/widgets/dialogs/qdialog/qdialog.pro deleted file mode 100644 index 0a065b1a87..0000000000 --- a/tests/auto/widgets/dialogs/qdialog/qdialog.pro +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdialog -QT += widgets testlib gui-private core-private -SOURCES += tst_qdialog.cpp diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index cc613b8218..13f971f5f0 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -1,34 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../../../shared/highdpi.h" -#include <QtTest/QtTest> +#include <QTest> +#include <QTestEventLoop> #include <qdialog.h> #include <qapplication.h> @@ -36,7 +12,9 @@ #include <qpushbutton.h> #include <qstyle.h> #include <QVBoxLayout> +#include <QSignalSpy> #include <QSizeGrip> +#include <QTimer> #include <QGraphicsProxyWidget> #include <QGraphicsView> #include <QWindow> @@ -44,6 +22,8 @@ #include <qpa/qplatformtheme.h> #include <qpa/qplatformtheme_p.h> +#include <QtWidgets/private/qapplication_p.h> + QT_FORWARD_DECLARE_CLASS(QDialog) // work around function being protected @@ -67,6 +47,8 @@ private slots: void showMinimized(); void showFullScreen(); void showAsTool(); + void showWithoutActivating_data(); + void showWithoutActivating(); void toolDialogPosition(); void deleteMainDefault(); void deleteInExec(); @@ -79,6 +61,11 @@ private slots: void transientParent_data(); void transientParent(); void dialogInGraphicsView(); + void keepPositionOnClose(); + void virtualsOnClose(); + void deleteOnDone(); + void quitOnDone(); + void focusWidgetAfterOpen(); }; // Testing get/set functions @@ -148,7 +135,7 @@ void tst_QDialog::defaultButtons() pushThree->setAutoDefault(false); testWidget.show(); - QApplication::setActiveWindow(&testWidget); + QApplicationPrivate::setActiveWindow(&testWidget); QVERIFY(QTest::qWaitForWindowExposed(&testWidget)); push->setDefault(true); @@ -297,9 +284,12 @@ void tst_QDialog::showFullScreen() void tst_QDialog::showAsTool() { -#if defined(Q_OS_UNIX) - QSKIP("Qt/X11: Skipped since activeWindow() is not respected by all window managers"); -#endif + if (QStringList{"xcb", "offscreen"}.contains(QGuiApplication::platformName())) + QSKIP("activeWindow() is not respected by all Xcb window managers and the offscreen plugin"); + + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) + QSKIP("QWindow::requestActivate() is not supported."); + DummyDialog testWidget; testWidget.resize(200, 200); testWidget.setWindowTitle(QTest::currentTestFunction()); @@ -315,6 +305,33 @@ void tst_QDialog::showAsTool() } } +void tst_QDialog::showWithoutActivating_data() +{ + QTest::addColumn<bool>("showWithoutActivating"); + QTest::addColumn<int>("focusInCount"); + + QTest::addRow("showWithoutActivating") << true << 0; + QTest::addRow("showWithActivating") << false << 1; +} + +void tst_QDialog::showWithoutActivating() +{ + QFETCH(bool, showWithoutActivating); + QFETCH(int, focusInCount); + + struct Dialog : public QDialog + { + int focusInCount = 0; + protected: + void focusInEvent(QFocusEvent *) override { ++focusInCount; } + } dialog; + dialog.setAttribute(Qt::WA_ShowWithoutActivating, showWithoutActivating); + + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + QCOMPARE(dialog.focusInCount, focusInCount); +} + // Verify that pos() returns the same before and after show() // for a dialog with the Tool window type. void tst_QDialog::toolDialogPosition() @@ -467,6 +484,9 @@ void tst_QDialog::snapToDefaultButton() #else if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("This platform does not support setting the cursor position."); +#ifdef Q_OS_ANDROID + QSKIP("Android does not support cursor"); +#endif const QRect dialogGeometry(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(100, 100), QSize(200, 200)); @@ -542,5 +562,211 @@ void tst_QDialog::dialogInGraphicsView() } } +// QTBUG-79147 (Windows): Closing a dialog by clicking the 'X' in the title +// bar would offset the dialog position when shown next time. +void tst_QDialog::keepPositionOnClose() +{ + QDialog dialog; + dialog.setWindowTitle(QTest::currentTestFunction()); + const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry(); + dialog.resize(availableGeometry.size() / 4); + QPoint pos = availableGeometry.topLeft() + QPoint(100, 100); + dialog.move(pos); + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + pos = dialog.pos(); + dialog.close(); + dialog.windowHandle()->destroy(); // Emulate a click on close by destroying the window. + QTest::qWait(50); + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + QTest::qWait(50); + QCOMPARE(dialog.pos(), pos); +} + +/*! + Verify that the virtual functions related to closing a dialog are + called exactly once, no matter how the dialog gets closed. +*/ +void tst_QDialog::virtualsOnClose() +{ + class Dialog : public QDialog + { + public: + using QDialog::QDialog; + int closeEventCount = 0; + int acceptCount = 0; + int rejectCount = 0; + int doneCount = 0; + + void accept() override + { + ++acceptCount; + QDialog::accept(); + } + void reject() override + { + ++rejectCount; + QDialog::reject(); + } + void done(int result) override + { + ++doneCount; + QDialog::done(result); + } + + protected: + void closeEvent(QCloseEvent *e) override + { + ++closeEventCount; + QDialog::closeEvent(e); + } + }; + + { + Dialog dialog; + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + dialog.accept(); + // we used to only hide the dialog, and we still don't want a + // closeEvent call for application-triggered calls to QDialog::done + QCOMPARE(dialog.closeEventCount, 0); + QCOMPARE(dialog.acceptCount, 1); + QCOMPARE(dialog.rejectCount, 0); + QCOMPARE(dialog.doneCount, 1); + } + + { + Dialog dialog; + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + dialog.reject(); + QCOMPARE(dialog.closeEventCount, 0); + QCOMPARE(dialog.acceptCount, 0); + QCOMPARE(dialog.rejectCount, 1); + QCOMPARE(dialog.doneCount, 1); + } + + { + Dialog dialog; + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + dialog.close(); + QCOMPARE(dialog.closeEventCount, 1); + QCOMPARE(dialog.acceptCount, 0); + QCOMPARE(dialog.rejectCount, 1); + QCOMPARE(dialog.doneCount, 1); + } + + { + // user clicks close button in title bar + Dialog dialog; + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + QWindowSystemInterface::handleCloseEvent(dialog.windowHandle()); + QApplication::processEvents(); + QCOMPARE(dialog.closeEventCount, 1); + QCOMPARE(dialog.acceptCount, 0); + QCOMPARE(dialog.rejectCount, 1); + QCOMPARE(dialog.doneCount, 1); + } + + { + struct EventFilter : QObject { + EventFilter(Dialog *dialog) + { dialog->installEventFilter(this); } + int closeEventCount = 0; + bool eventFilter(QObject *r, QEvent *e) override + { + if (e->type() == QEvent::Close) { + ++closeEventCount; + } + return QObject::eventFilter(r, e); + } + }; + // dialog gets destroyed while shown + Dialog *dialog = new Dialog; + QSignalSpy rejectedSpy(dialog, &QDialog::rejected); + EventFilter filter(dialog); + + dialog->show(); + QVERIFY(QTest::qWaitForWindowExposed(dialog)); + delete dialog; + // Qt doesn't deliver events to QWidgets closed during destruction + QCOMPARE(filter.closeEventCount, 0); + // QDialog doesn't emit signals when closed by destruction + QCOMPARE(rejectedSpy.size(), 0); + } +} + +/*! + QDialog::done is documented to respect Qt::WA_DeleteOnClose. +*/ +void tst_QDialog::deleteOnDone() +{ + { + std::unique_ptr<QDialog> dialog(new QDialog); + QPointer<QDialog> watcher(dialog.get()); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + QVERIFY(QTest::qWaitForWindowExposed(dialog.get())); + + dialog->accept(); + QTRY_COMPARE(watcher.isNull(), true); + dialog.release(); // if we get here, the dialog is destroyed + } + + // it is still safe to delete the dialog explicitly as long as events + // have not yet been processed + { + std::unique_ptr<QDialog> dialog(new QDialog); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + QVERIFY(QTest::qWaitForWindowExposed(dialog.get())); + + dialog->accept(); + dialog.reset(); + QApplication::processEvents(); + } +} + +/*! + QDialog::done is documented to make QApplication emit lastWindowClosed if + the dialog was the last window. +*/ +void tst_QDialog::quitOnDone() +{ + QSignalSpy quitSpy(qApp, &QGuiApplication::lastWindowClosed); + + QDialog dialog; + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + + // QGuiApplication::lastWindowClosed is documented to only be emitted + // when we are in exec() + QTimer::singleShot(0, &dialog, &QDialog::accept); + // also quit with a timer in case the test fails + QTimer::singleShot(1000, QApplication::instance(), &QApplication::quit); + QApplication::exec(); + QCOMPARE(quitSpy.size(), 1); +} + +void tst_QDialog::focusWidgetAfterOpen() +{ + QDialog dialog; + dialog.setLayout(new QVBoxLayout); + + QPushButton *pb1 = new QPushButton; + QPushButton *pb2 = new QPushButton; + dialog.layout()->addWidget(pb1); + dialog.layout()->addWidget(pb2); + + pb2->setFocus(); + QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(pb2)); + + dialog.open(); + QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(pb2)); +} + QTEST_MAIN(tst_QDialog) #include "tst_qdialog.moc" diff --git a/tests/auto/widgets/dialogs/qerrormessage/CMakeLists.txt b/tests/auto/widgets/dialogs/qerrormessage/CMakeLists.txt index 2ea2f01cdd..a26401c417 100644 --- a/tests/auto/widgets/dialogs/qerrormessage/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qerrormessage/CMakeLists.txt @@ -1,16 +1,21 @@ -# Generated from qerrormessage.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qerrormessage Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qerrormessage LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qerrormessage SOURCES tst_qerrormessage.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui + Qt::GuiPrivate Qt::Widgets ) - -#### Keys ignored in scope 1:.:.:qerrormessage.pro:<TRUE>: -# TEMPLATE = "app" diff --git a/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro b/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro deleted file mode 100644 index b4cf05e347..0000000000 --- a/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro +++ /dev/null @@ -1,7 +0,0 @@ -CONFIG += testcase -TEMPLATE = app -TARGET = tst_qerrormessage - -QT += widgets testlib - -SOURCES += tst_qerrormessage.cpp diff --git a/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp b/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp index 49ecc7305d..53ade3cbc6 100644 --- a/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp +++ b/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp @@ -1,45 +1,43 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +#include <QTest> #include <QErrorMessage> #include <QDebug> #include <QCheckBox> +#include <qpa/qplatformtheme.h> +#include <private/qguiapplication_p.h> + class tst_QErrorMessage : public QObject { Q_OBJECT private slots: + void initTestCase_data(); + void init(); + void dontShowAgain(); void dontShowCategoryAgain(); + void baseClassSetVisible(); }; +void tst_QErrorMessage::initTestCase_data() +{ + QTest::addColumn<bool>("useNativeDialog"); + QTest::newRow("widget") << false; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + if (theme->usePlatformNativeDialog(QPlatformTheme::MessageDialog)) + QTest::newRow("native") << true; + } +} + +void tst_QErrorMessage::init() +{ + QFETCH_GLOBAL(bool, useNativeDialog); + qApp->setAttribute(Qt::AA_DontUseNativeDialogs, !useNativeDialog); +} + void tst_QErrorMessage::dontShowAgain() { QString plainString = QLatin1String("foo"); @@ -72,8 +70,7 @@ void tst_QErrorMessage::dontShowAgain() QVERIFY(errorMessageDialog.isVisible()); checkBox = errorMessageDialog.findChild<QCheckBox*>(); QVERIFY(checkBox); - QVERIFY(!checkBox->isChecked()); - checkBox->setChecked(true); + QVERIFY(checkBox->isChecked()); errorMessageDialog.close(); errorMessageDialog.showMessage(htmlString); @@ -141,5 +138,13 @@ void tst_QErrorMessage::dontShowCategoryAgain() QVERIFY(errorMessageDialog.isVisible()); } +void tst_QErrorMessage::baseClassSetVisible() +{ + QErrorMessage errorMessage; + errorMessage.QDialog::setVisible(true); + QCOMPARE(errorMessage.isVisible(), true); + errorMessage.close(); +} + QTEST_MAIN(tst_QErrorMessage) #include "tst_qerrormessage.moc" diff --git a/tests/auto/widgets/dialogs/qfiledialog/BLACKLIST b/tests/auto/widgets/dialogs/qfiledialog/BLACKLIST new file mode 100644 index 0000000000..38aa416115 --- /dev/null +++ b/tests/auto/widgets/dialogs/qfiledialog/BLACKLIST @@ -0,0 +1,10 @@ +[filesSelectedSignal] +android # QTBUG-101194 +[historyForward] +android # QTBUG-101194 +[historyBack] +android # QTBUG-101194 +[completer_data] +android # QTBUG-108329 +[completer] +android # QTBUG-101194 diff --git a/tests/auto/widgets/dialogs/qfiledialog/CMakeLists.txt b/tests/auto/widgets/dialogs/qfiledialog/CMakeLists.txt index 6515645c05..000d99cdcf 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qfiledialog/CMakeLists.txt @@ -1,15 +1,20 @@ -# Generated from qfiledialog.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qfiledialog Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfiledialog LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qfiledialog SOURCES tst_qfiledialog.cpp - DEFINES - SRCDIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/\\\" - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro b/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro deleted file mode 100644 index 1cdf10d29a..0000000000 --- a/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro +++ /dev/null @@ -1,11 +0,0 @@ -############################################################ -# Project file for autotest for file qfiledialog.h -############################################################ - -CONFIG += testcase -TARGET = tst_qfiledialog -QT += widgets widgets-private testlib -QT += core-private gui-private -SOURCES += tst_qfiledialog.cpp - -DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index e070f74ae5..6ebf255f31 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -1,33 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QTest> +#include <QStandardPaths> +#include <QSignalSpy> +#include <QTemporaryFile> #include <qcoreapplication.h> #include <qfile.h> @@ -35,7 +13,7 @@ #include <qsharedpointer.h> #include <qfiledialog.h> #include <qabstractitemdelegate.h> -#include <qitemdelegate.h> +#include <qstyleditemdelegate.h> #include <qlistview.h> #include <qcombobox.h> #include <qpushbutton.h> @@ -60,6 +38,8 @@ #include <QFileDialog> #include <QFileSystemModel> +#include <QtWidgets/private/qapplication_p.h> + #if defined(Q_OS_UNIX) #include <unistd.h> // for pathconf() on OS X #ifdef QT_BUILD_INTERNAL @@ -136,6 +116,7 @@ private slots: void clearLineEdit(); void enableChooseButton(); void selectedFilesWithoutWidgets(); + void selectedFileWithDefaultSuffix(); void trailingDotsAndSpaces(); #ifdef Q_OS_UNIX #ifdef QT_BUILD_INTERNAL @@ -147,9 +128,10 @@ private slots: void QTBUG49600_nativeIconProviderCrash(); void focusObjectDuringDestruction(); - // NOTE: Please keep widgetlessNativeDialog() as the LAST test! + // NOTE: Please keep widgetlessNativeDialog() and + // hideNativeByDestruction() as the LAST tests! // - // widgetlessNativeDialog() is the only test function that creates + // widgetlessNativeDialog() are the only test functions that create // a native file dialog instance. GTK+ versions prior 3.15.5 have // a nasty bug (https://bugzilla.gnome.org/show_bug.cgi?id=725164) // in GtkFileChooserWidget, which makes it leak its folder change @@ -160,6 +142,7 @@ private slots: // The crash has been fixed in GTK+ 3.15.5, but the RHEL 7.2 CI has // GTK+ 3.14.13 installed (QTBUG-55276). void widgetlessNativeDialog(); + void hideNativeByDestruction(); private: void cleanupSettingsFile(); @@ -227,7 +210,7 @@ void tst_QFiledialog::currentChangedSignal() QVERIFY(listView->model()->hasChildren(folder)); listView->setCurrentIndex(folder); - QCOMPARE(spyCurrentChanged.count(), 1); + QCOMPARE(spyCurrentChanged.size(), 1); } // only emitted from the views, sidebar, or lookin combo @@ -249,7 +232,7 @@ void tst_QFiledialog::directoryEnteredSignal() QVERIFY(secondItem.isValid()); sidebar->setCurrentIndex(secondItem); QTest::keyPress(sidebar->viewport(), Qt::Key_Return); - QCOMPARE(spyDirectoryEntered.count(), 1); + QCOMPARE(spyDirectoryEntered.size(), 1); spyDirectoryEntered.clear(); // lookInCombo @@ -258,7 +241,7 @@ void tst_QFiledialog::directoryEnteredSignal() QVERIFY(comboBox->view()->model()->index(1, 0).isValid()); comboBox->view()->setCurrentIndex(comboBox->view()->model()->index(1, 0)); QTest::keyPress(comboBox->view()->viewport(), Qt::Key_Return); - QCOMPARE(spyDirectoryEntered.count(), 1); + QCOMPARE(spyDirectoryEntered.size(), 1); spyDirectoryEntered.clear(); // view @@ -300,7 +283,7 @@ void tst_QFiledialog::filesSelectedSignal() { QFileDialog fd; fd.setViewMode(QFileDialog::List); - QDir testDir(SRCDIR); + QDir testDir(QT_TESTCASE_SOURCEDIR); fd.setDirectory(testDir); QFETCH(QFileDialog::FileMode, fileMode); fd.setFileMode(fileMode); @@ -335,7 +318,7 @@ void tst_QFiledialog::filesSelectedSignal() QVERIFY(button->isEnabled()); button->animateClick(); QTRY_COMPARE(fd.isVisible(), false); - QCOMPARE(spyFilesSelected.count(), 1); + QCOMPARE(spyFilesSelected.size(), 1); } // only emitted when the combo box is activated @@ -360,7 +343,7 @@ void tst_QFiledialog::filterSelectedSignal() QTest::keyPress(filters, Qt::Key_Down); - QCOMPARE(spyFilterSelected.count(), 1); + QCOMPARE(spyFilterSelected.size(), 1); } void tst_QFiledialog::args() @@ -401,14 +384,14 @@ void tst_QFiledialog::directory() #ifndef Q_OS_WIN QCOMPARE(tempPath, fd.directory().absolutePath()); #endif - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); // Check my way QList<QListView*> list = fd.findChildren<QListView*>("listView"); - QVERIFY(list.count() > 0); + QVERIFY(list.size() > 0); #ifdef Q_OS_WIN QCOMPARE(list.at(0)->rootIndex().data().toString().toLower(), temp.dirName().toLower()); #else @@ -439,7 +422,14 @@ void tst_QFiledialog::completer_data() QTest::newRow("goto root") << QString() << rootPath << -1; QTest::newRow("start at root") << rootPath << QString() << -1; - QFileInfoList list = QDir::root().entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + QDir dir = QDir::root(); +#ifdef Q_OS_ANDROID + const auto homePaths = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); + QVERIFY(!homePaths.isEmpty()); + dir = QDir(homePaths.first()); +#endif + + QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); QVERIFY(!list.isEmpty()); const QString folder = list.first().absoluteFilePath(); QTest::newRow("start at one below root r") << folder << "r" << -1; @@ -526,10 +516,9 @@ void tst_QFiledialog::completer() } // press 'keys' for the input - for (int i = 0; i < input.count(); ++i) + for (int i = 0; i < input.size(); ++i) QTest::keyPress(lineEdit, input[i].toLatin1()); - QStringList expectedFiles; if (expected == -1) { QString fullPath = startPath; if (!fullPath.endsWith(QLatin1Char('/'))) @@ -542,11 +531,11 @@ void tst_QFiledialog::completer() QFileInfo fi(fullPath); QDir x(fi.absolutePath()); - expectedFiles = x.entryList(model->filter()); + const QStringList expectedFiles = x.entryList(model->filter()); expected = 0; if (input.startsWith("..")) input.clear(); - foreach (const QString &expectedFile, expectedFiles) { + for (const QString &expectedFile : expectedFiles) { if (expectedFile.startsWith(input, caseSensitivity)) ++expected; } @@ -582,16 +571,16 @@ void tst_QFiledialog::completer_up() fd.show(); QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit"); QVERIFY(lineEdit); - QCOMPARE(spyFilesSelected.count(), 0); - int depth = QDir::currentPath().split('/').count(); + QCOMPARE(spyFilesSelected.size(), 0); + int depth = QDir::currentPath().split('/').size(); for (int i = 0; i <= depth * 3 + 1; ++i) { lineEdit->insert("../"); qApp->processEvents(); } - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); } void tst_QFiledialog::acceptMode() @@ -671,7 +660,7 @@ void tst_QFiledialog::filters() // effects QList<QComboBox*> views = fd.findChildren<QComboBox*>("fileTypeCombo"); - QCOMPARE(views.count(), 1); + QCOMPARE(views.size(), 1); QCOMPARE(views.at(0)->isVisible(), false); QStringList filters; @@ -686,15 +675,15 @@ void tst_QFiledialog::filters() QCOMPARE(fd.nameFilters(), filters); fd.setNameFilter("Image files (*.png *.xpm *.jpg);;Text files (*.txt);;Any files (*.*)"); QCOMPARE(fd.nameFilters(), filters); - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); // setting shouldn't emit any signals for (int i = views.at(0)->currentIndex(); i < views.at(0)->count(); ++i) views.at(0)->setCurrentIndex(i); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyFilterSelected.size(), 0); //Let check if filters with whitespaces QFileDialog fd2; @@ -733,7 +722,7 @@ void tst_QFiledialog::selectFilter() QCOMPARE(fd.selectedNameFilter(), filters.at(2)); fd.selectNameFilter(""); QCOMPARE(fd.selectedNameFilter(), filters.at(2)); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyFilterSelected.size(), 0); } void tst_QFiledialog::history() @@ -772,10 +761,10 @@ void tst_QFiledialog::history() badHistory << QDir::toNativeSeparators(QDir::current().absolutePath()); QCOMPARE(fd.history(), badHistory); - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); } void tst_QFiledialog::iconProvider() @@ -817,7 +806,7 @@ void tst_QFiledialog::itemDelegate() { QFileDialog fd; QVERIFY(fd.itemDelegate() != 0); - QItemDelegate *id = new QItemDelegate(&fd); + QStyledItemDelegate *id = new QStyledItemDelegate(&fd); fd.setItemDelegate(id); QCOMPARE(fd.itemDelegate(), (QAbstractItemDelegate *)id); } @@ -878,7 +867,7 @@ void tst_QFiledialog::selectFile() QVERIFY(model); fd->setDirectory(QDir::currentPath()); // default value - QCOMPARE(fd->selectedFiles().count(), 1); + QCOMPARE(fd->selectedFiles().size(), 1); QScopedPointer<QTemporaryFile> tempFile; if (file == QLatin1String("temp")) { @@ -888,7 +877,7 @@ void tst_QFiledialog::selectFile() } fd->selectFile(file); - QCOMPARE(fd->selectedFiles().count(), count); + QCOMPARE(fd->selectedFiles().size(), count); if (tempFile.isNull()) { QCOMPARE(model->index(fd->directory().path()), model->index(QDir::currentPath())); } else { @@ -936,7 +925,7 @@ void tst_QFiledialog::selectFiles() QString filesPath = fd.directory().absolutePath(); for (int i=0; i < 5; ++i) { QFile file(filesPath + QLatin1String("/qfiledialog_auto_test_not_pres_") + QString::number(i)); - file.open(QIODevice::WriteOnly); + QVERIFY(file.open(QIODevice::WriteOnly)); file.resize(1024); file.flush(); file.close(); @@ -945,29 +934,29 @@ void tst_QFiledialog::selectFiles() // Get a list of files in the view and then get the corresponding index's QStringList list = fd.directory().entryList(QDir::Files); QModelIndexList toSelect; - QVERIFY(list.count() > 1); + QVERIFY(list.size() > 1); QListView* listView = fd.findChild<QListView*>("listView"); QVERIFY(listView); - for (int i = 0; i < list.count(); ++i) { + for (int i = 0; i < list.size(); ++i) { fd.selectFile(fd.directory().path() + QLatin1Char('/') + list.at(i)); QTRY_VERIFY(!listView->selectionModel()->selectedRows().isEmpty()); toSelect.append(listView->selectionModel()->selectedRows().last()); } - QCOMPARE(spyFilesSelected.count(), 0); + QCOMPARE(spyFilesSelected.size(), 0); listView->selectionModel()->clear(); - QCOMPARE(spyFilesSelected.count(), 0); + QCOMPARE(spyFilesSelected.size(), 0); // select the indexes - for (int i = 0; i < toSelect.count(); ++i) { + for (int i = 0; i < toSelect.size(); ++i) { listView->selectionModel()->select(toSelect.at(i), QItemSelectionModel::Select | QItemSelectionModel::Rows); } - QCOMPARE(fd.selectedFiles().count(), toSelect.count()); - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(fd.selectedFiles().size(), toSelect.size()); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); } @@ -993,13 +982,13 @@ void tst_QFiledialog::viewMode() // find widgets QList<QTreeView*> treeView = fd.findChildren<QTreeView*>("treeView"); - QCOMPARE(treeView.count(), 1); + QCOMPARE(treeView.size(), 1); QList<QListView*> listView = fd.findChildren<QListView*>("listView"); - QCOMPARE(listView.count(), 1); + QCOMPARE(listView.size(), 1); QList<QToolButton*> listButton = fd.findChildren<QToolButton*>("listModeButton"); - QCOMPARE(listButton.count(), 1); + QCOMPARE(listButton.size(), 1); QList<QToolButton*> treeButton = fd.findChildren<QToolButton*>("detailModeButton"); - QCOMPARE(treeButton.count(), 1); + QCOMPARE(treeButton.size(), 1); // default value QCOMPARE(fd.viewMode(), QFileDialog::List); @@ -1128,7 +1117,6 @@ void tst_QFiledialog::focus() QFileDialog fd; fd.setDirectory(QDir::currentPath()); fd.show(); - QApplication::setActiveWindow(&fd); QVERIFY(QTest::qWaitForWindowActive(&fd)); QCOMPARE(fd.isVisible(), true); QCOMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd)); @@ -1138,7 +1126,7 @@ void tst_QFiledialog::focus() QCursor::setPos(fd.geometry().center()); QList<QWidget*> treeView = fd.findChildren<QWidget*>("fileNameEdit"); - QCOMPARE(treeView.count(), 1); + QCOMPARE(treeView.size(), 1); QVERIFY(treeView.at(0)); QTRY_COMPARE(treeView.at(0)->hasFocus(), true); QCOMPARE(treeView.at(0)->hasFocus(), true); @@ -1168,13 +1156,13 @@ void tst_QFiledialog::historyBack() QCOMPARE(backButton->isEnabled(), true); QCOMPARE(forwardButton->isEnabled(), false); fd.setDirectory(desktop); - QCOMPARE(spy.count(), 2); + QCOMPARE(spy.size(), 2); backButton->click(); qApp->processEvents(); QCOMPARE(backButton->isEnabled(), true); QCOMPARE(forwardButton->isEnabled(), true); - QCOMPARE(spy.count(), 3); + QCOMPARE(spy.size(), 3); QString currentPath = qvariant_cast<QString>(spy.last().first()); QCOMPARE(model->index(currentPath), model->index(temp)); @@ -1183,11 +1171,11 @@ void tst_QFiledialog::historyBack() QCOMPARE(currentPath, home); QCOMPARE(backButton->isEnabled(), false); QCOMPARE(forwardButton->isEnabled(), true); - QCOMPARE(spy.count(), 4); + QCOMPARE(spy.size(), 4); // nothing should change at this point backButton->click(); - QCOMPARE(spy.count(), 4); + QCOMPARE(spy.size(), 4); QCOMPARE(backButton->isEnabled(), false); QCOMPARE(forwardButton->isEnabled(), true); } @@ -1221,7 +1209,7 @@ void tst_QFiledialog::historyForward() QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(desktop)); QCOMPARE(backButton->isEnabled(), true); QCOMPARE(forwardButton->isEnabled(), false); - QCOMPARE(spy.count(), 4); + QCOMPARE(spy.size(), 4); backButton->click(); QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp)); @@ -1231,13 +1219,13 @@ void tst_QFiledialog::historyForward() QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(home)); QCOMPARE(backButton->isEnabled(), false); QCOMPARE(forwardButton->isEnabled(), true); - QCOMPARE(spy.count(), 6); + QCOMPARE(spy.size(), 6); forwardButton->click(); QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp)); backButton->click(); QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(home)); - QCOMPARE(spy.count(), 8); + QCOMPARE(spy.size(), 8); forwardButton->click(); QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp)); @@ -1448,6 +1436,10 @@ void tst_QFiledialog::widgetlessNativeDialog() { if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog)) QSKIP("This platform always uses widgets to realize its QFileDialog, instead of the native file dialog."); +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This keeps the window open. Figure out why."); +#endif QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, false); QFileDialog fd; fd.setWindowModality(Qt::ApplicationModal); @@ -1460,6 +1452,46 @@ void tst_QFiledialog::widgetlessNativeDialog() QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, true); } +void tst_QFiledialog::hideNativeByDestruction() +{ + if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog)) + QSKIP("This platform always uses widgets to realize its QFileDialog, instead of the native file dialog."); + +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This keeps the native window open. Figure out why."); +#endif + + QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, false); + auto resetAttribute = qScopeGuard([]{ + QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, true); + }); + + QWidget window; + QWidget *child = new QWidget(&window); + QPointer<QFileDialog> dialog = new QFileDialog(child); + // Make it application modal so that we don't end up with a sheet on macOS + dialog->setWindowModality(Qt::ApplicationModal); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + dialog->open(); + + // We test that the dialog opens and closes by watching the activation of the + // transient parent window. If it doesn't deactivate, then we have to skip. + const auto windowActive = [&window]{ return window.isActiveWindow(); }; + const auto windowInactive = [&window]{ return !window.isActiveWindow(); }; + if (!QTest::qWaitFor(windowInactive, 2000)) + QSKIP("Dialog didn't activate"); + + // This should destroy the dialog and close the native window + child->deleteLater(); + QTRY_VERIFY(!dialog); + // If the native window is still open, then the transient parent can't become + // active + window.activateWindow(); + QVERIFY(QTest::qWaitFor(windowActive, 2000)); +} + void tst_QFiledialog::selectedFilesWithoutWidgets() { // Test for a crash when widgets are not instantiated yet. @@ -1468,6 +1500,21 @@ void tst_QFiledialog::selectedFilesWithoutWidgets() QVERIFY(fd.selectedFiles().size() >= 0); } +void tst_QFiledialog::selectedFileWithDefaultSuffix() +{ + // QTBUG-59401: dot in file path should not prevent default suffix from being added + QTemporaryDir tempDir(QDir::tempPath() + "/abcXXXXXX.def"); + QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString())); + + QFileDialog fd; + fd.setDirectory(tempDir.path()); + fd.setDefaultSuffix(".txt"); + fd.selectFile("xxx"); + const auto selectedFiles = fd.selectedFiles(); + QCOMPARE(selectedFiles.size(), 1); + QVERIFY(selectedFiles.first().endsWith(".txt")); +} + void tst_QFiledialog::trailingDotsAndSpaces() { #ifndef Q_OS_WIN @@ -1549,6 +1596,10 @@ void tst_QFiledialog::rejectModalDialogs() { if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This freezes. Figure out why."); +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This freezes. Figure out why."); +#endif // QTBUG-38672 , static functions should return empty Urls DialogRejecter dr; @@ -1580,6 +1631,12 @@ void tst_QFiledialog::QTBUG49600_nativeIconProviderCrash() { if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog)) QSKIP("This platform always uses widgets to realize its QFileDialog, instead of the native file dialog."); + +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This hangs. Figure out why."); +#endif + QFileDialog fd; fd.iconProvider(); } @@ -1611,6 +1668,10 @@ void tst_QFiledialog::focusObjectDuringDestruction() { if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This freezes. Figure out why."); +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This freezes. Figure out why."); +#endif QTRY_VERIFY(QGuiApplication::topLevelWindows().isEmpty()); diff --git a/tests/auto/widgets/dialogs/qfiledialog2/CMakeLists.txt b/tests/auto/widgets/dialogs/qfiledialog2/CMakeLists.txt index 4fded21556..7db2168a20 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qfiledialog2/CMakeLists.txt @@ -1,15 +1,20 @@ -# Generated from qfiledialog2.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qfiledialog2 Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfiledialog2 LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qfiledialog2 SOURCES tst_qfiledialog2.cpp - DEFINES - SRCDIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/\\\" - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro deleted file mode 100644 index 1b35b2e4ac..0000000000 --- a/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG += testcase -TARGET = tst_qfiledialog2 - -QT += widgets widgets-private testlib -QT += core-private gui-private - -SOURCES += tst_qfiledialog2.cpp - -DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index efcf8719ca..c34c8559da 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -1,39 +1,16 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QTest> +#include <QTemporaryFile> +#include <QSignalSpy> +#include <QStandardPaths> #include <qcoreapplication.h> #include <qdebug.h> #include <qfiledialog.h> #include <qabstractitemdelegate.h> -#include <qitemdelegate.h> #include <qlistview.h> #include <qcombobox.h> #include <qpushbutton.h> @@ -57,9 +34,9 @@ #include <qpa/qplatformdialoghelper.h> #include <qpa/qplatformintegration.h> -#if defined(Q_OS_WIN) -#include "../../../network-settings.h" -#endif +#include "../../../../shared/filesystem.h" + +#include <QtWidgets/private/qapplication_p.h> #if defined QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE @@ -130,6 +107,10 @@ private slots: void dontShowCompleterOnRoot(); void nameFilterParsing_data(); void nameFilterParsing(); +#if QT_CONFIG(settings) + void settingsCompatibility_data(); + void settingsCompatibility(); +#endif private: void cleanupSettingsFile(); @@ -278,7 +259,7 @@ void tst_QFileDialog2::unc() { #if defined(Q_OS_WIN) // Only test UNC on Windows./ - QString dir("\\\\" + QtNetworkSettings::winServerName() + "\\testsharewritable"); + QString dir("\\\\" + QTest::uncServerName() + "\\testsharewritable"); #else QString dir(QDir::currentPath()); #endif @@ -330,7 +311,7 @@ static bool openContextMenu(QFileDialog &fd) MenuCloser closer(&fd); QObject::connect(&timer, &QTimer::timeout, &closer, &MenuCloser::close); timer.start(); - QContextMenuEvent cme(QContextMenuEvent::Mouse, QPoint(10, 10)); + QContextMenuEvent cme(QContextMenuEvent::Mouse, QPoint(10, 10), list->viewport()->mapToGlobal(QPoint(10, 10))); qApp->sendEvent(list->viewport(), &cme); // blocks until menu is closed again. return true; } @@ -470,6 +451,44 @@ void tst_QFileDialog2::task180459_lastDirectory() delete dlg; } +#if QT_CONFIG(settings) +void tst_QFileDialog2::settingsCompatibility_data() +{ + QTest::addColumn<QString>("qtVersion"); + QTest::addColumn<QDataStream::Version>("dsVersion"); + QTest::newRow("6.2.3") << "6.2.3" << QDataStream::Qt_6_0; + QTest::newRow("6.5") << "6.5" << QDataStream::Qt_5_0; + QTest::newRow("15.5.2") << "5.15.2" << QDataStream::Qt_5_15; + QTest::newRow("15.5.9") << "5.15.9" << QDataStream::Qt_5_15; +} + +void tst_QFileDialog2::settingsCompatibility() +{ + static const QByteArray ba32 = QByteArrayLiteral("\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xF7\x00\x00\x00\x04\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00""d\xFF\xFF\xFF\xFF\x00\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x01\t\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00""B\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00n\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\xE8\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00"); + static const QByteArray ba64 = QByteArrayLiteral("\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xF7\x00\x00\x00\x04\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00""d\xFF\xFF\xFF\xFF\x00\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x01\t\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00""B\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00n\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\xE8\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00"); + QFETCH(QString, qtVersion); + QFETCH(QDataStream::Version, dsVersion); + // Create a header view, convert template to target format and store it in settings + { + QSettings settings(QSettings::UserScope, "QtProject"); + settings.beginGroup("FileDialog"); + settings.setValue("sidebarWidth", 93); // random value + settings.setValue("shortcuts", QStringList({settings.fileName(), "/tmp"})); + settings.setValue("qtVersion", qtVersion); + settings.setValue("treeViewHeader", dsVersion < QDataStream::Qt_6_0 ? ba32 : ba64); + settings.endGroup(); + } + // Create a file dialog, read settings write them back + { + QFileDialog fd; + } + // Read back settings and compare byte array + QSettings settings(QSettings::UserScope, "QtProject"); + settings.beginGroup("FileDialog"); + const QByteArray savedState = settings.value("treeViewHeader").toByteArray(); + QCOMPARE(savedState, ba32); +} +#endif class FilterDirModel : public QSortFilterProxyModel @@ -649,7 +668,7 @@ void tst_QFileDialog2::task226366_lowerCaseHardDriveWindows() //i clear my previous selection in the completer QTest::keyClick(edit->completer()->popup(), Qt::Key_Down); edit->clear(); - QTest::keyClick(edit, (char)(Qt::Key_C | Qt::SHIFT)); + QTest::keyClick(edit, Qt::Key_C, Qt::ShiftModifier); QTest::qWait(200); QTest::keyClick(edit->completer()->popup(), Qt::Key_Down); QCOMPARE(edit->text(), QString("C:/")); @@ -662,13 +681,13 @@ void tst_QFileDialog2::completionOnLevelAfterRoot() #if defined(Q_OS_WIN) fd.setDirectory("C:/"); QDir current = fd.directory(); - QStringList entryList = current.entryList(QStringList(), QDir::Dirs); + const QStringList entryList = current.entryList(QStringList(), QDir::Dirs); // Find a suitable test dir under c:-root: // - At least 6 characters long // - Ascii, letters only // - No another dir with same start QString testDir; - foreach (const QString &entry, entryList) { + for (const QString &entry : entryList) { if (entry.size() > 5 && QString(entry.toLatin1()).compare(entry) == 0) { bool invalid = false; for (int i = 0; i < 5; i++) { @@ -678,7 +697,7 @@ void tst_QFileDialog2::completionOnLevelAfterRoot() } } if (!invalid) { - foreach (const QString &check, entryList) { + for (const QString &check : entryList) { if (check.startsWith(entry.left(5), Qt::CaseInsensitive) && check != entry) { invalid = true; break; @@ -693,6 +712,17 @@ void tst_QFileDialog2::completionOnLevelAfterRoot() } if (testDir.isEmpty()) QSKIP("This test requires to have a unique directory of at least six ascii characters under c:/"); +#elif defined(Q_OS_ANDROID) + // Android 11 and above doesn't allow accessing root filesystem as before, + // so let's opt int for the app's home. + const auto homePaths = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); + QVERIFY(!homePaths.isEmpty()); + fd.setFilter(QDir::Hidden | QDir::AllDirs | QDir::Files | QDir::System); + fd.setDirectory(homePaths.first()); + QDir(homePaths.first()).mkdir("etc"); + auto cleanup = qScopeGuard([&]() { + QDir(homePaths.first()).rmdir("etc"); + }); #else fd.setFilter(QDir::Hidden | QDir::AllDirs | QDir::Files | QDir::System); fd.setDirectory("/"); @@ -774,8 +804,8 @@ void tst_QFileDialog2::task235069_hideOnEscape() child->setFocus(); QTest::keyClick(child, Qt::Key_Escape); QCOMPARE(fd.isVisible(), false); - QCOMPARE(spyFinished.count(), 1); // QTBUG-7690 - QCOMPARE(spyRejected.count(), 1); // reject(), don't hide() + QCOMPARE(spyFinished.size(), 1); // QTBUG-7690 + QCOMPARE(spyRejected.size(), 1); // reject(), don't hide() } #ifdef QT_BUILD_INTERNAL @@ -822,7 +852,7 @@ void tst_QFileDialog2::task203703_returnProperSeparator() QVERIFY(button); QTest::keyClick(button, Qt::Key_Return); QString result = fd.selectedFiles().first(); - QVERIFY(result.at(result.count() - 1) != '/'); + QVERIFY(result.at(result.size() - 1) != '/'); QVERIFY(!result.contains('\\')); current.rmdir("aaaaaaaaaaaaaaaaaa"); } @@ -917,9 +947,9 @@ void tst_QFileDialog2::task239706_editableFilterCombo() d.show(); QVERIFY(QTest::qWaitForWindowExposed(&d)); - QList<QComboBox *> comboList = d.findChildren<QComboBox *>(); + const QList<QComboBox *> comboList = d.findChildren<QComboBox *>(); QComboBox *filterCombo = nullptr; - foreach (QComboBox *combo, comboList) { + for (QComboBox *combo : comboList) { if (combo->objectName() == QString("fileTypeCombo")) { filterCombo = combo; break; @@ -997,10 +1027,10 @@ public : void removeSelection() { QList<QModelIndex> idxs = selectionModel()->selectedIndexes(); QList<QPersistentModelIndex> indexes; - for (int i = 0; i < idxs.count(); i++) + for (int i = 0; i < idxs.size(); i++) indexes.append(idxs.at(i)); - for (int i = 0; i < indexes.count(); ++i) + for (int i = 0; i < indexes.size(); ++i) if (!indexes.at(i).data(Qt::UserRole + 1).toUrl().path().isEmpty()) model()->removeRow(indexes.at(i).row()); } @@ -1080,7 +1110,6 @@ void tst_QFileDialog2::task254490_selectFileMultipleTimes() QTemporaryFile *t; t = new QTemporaryFile; QVERIFY2(t->open(), qPrintable(t->errorString())); - t->open(); QFileDialog fd(0, "TestFileDialog"); fd.setDirectory(tempPath); @@ -1102,7 +1131,7 @@ void tst_QFileDialog2::task254490_selectFileMultipleTimes() QCOMPARE(lineEdit->text(),QLatin1String("new_file.txt")); QListView *list = fd.findChild<QListView*>("listView"); QVERIFY(list); - QCOMPARE(list->selectionModel()->selectedRows(0).count(), 0); + QCOMPARE(list->selectionModel()->selectedRows(0).size(), 0); t->deleteLater(); } @@ -1118,7 +1147,7 @@ void tst_QFileDialog2::task257579_sideBarWithNonCleanUrls() QFileDialog fd; fd.setSidebarUrls(QList<QUrl>() << QUrl::fromLocalFile(url)); QSidebar *sidebar = fd.findChild<QSidebar*>("sidebar"); - QCOMPARE(sidebar->urls().count(), 1); + QCOMPARE(sidebar->urls().size(), 1); QVERIFY(sidebar->urls().first().toLocalFile() != url); QCOMPARE(sidebar->urls().first().toLocalFile(), QDir::cleanPath(url)); @@ -1223,7 +1252,7 @@ void tst_QFileDialog2::QTBUG6558_showDirsOnly() //Create a file QFile tempFile(dirPath + "/plop.txt"); - tempFile.open(QIODevice::WriteOnly | QIODevice::Text); + QVERIFY(tempFile.open(QIODevice::WriteOnly | QIODevice::Text)); QTextStream out(&tempFile); out << "The magic number is: " << 49 << "\n"; tempFile.close(); @@ -1236,7 +1265,6 @@ void tst_QFileDialog2::QTBUG6558_showDirsOnly() fd.setOption(QFileDialog::ShowDirsOnly, true); fd.show(); - QApplication::setActiveWindow(&fd); QVERIFY(QTest::qWaitForWindowActive(&fd)); QCOMPARE(fd.isVisible(), true); QCOMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd)); @@ -1280,7 +1308,6 @@ void tst_QFileDialog2::QTBUG4842_selectFilterWithHideNameFilterDetails() fd.selectNameFilter(chosenFilterString); fd.show(); - QApplication::setActiveWindow(&fd); QVERIFY(QTest::qWaitForWindowActive(&fd)); QCOMPARE(fd.isVisible(), true); QCOMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd)); @@ -1296,7 +1323,6 @@ void tst_QFileDialog2::QTBUG4842_selectFilterWithHideNameFilterDetails() fd2.selectNameFilter(chosenFilterString); fd2.show(); - QApplication::setActiveWindow(&fd2); QVERIFY(QTest::qWaitForWindowActive(&fd2)); QCOMPARE(fd2.isVisible(), true); QCOMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd2)); @@ -1316,7 +1342,6 @@ void tst_QFileDialog2::dontShowCompleterOnRoot() fd.setAcceptMode(QFileDialog::AcceptSave); fd.show(); - QApplication::setActiveWindow(&fd); QVERIFY(QTest::qWaitForWindowActive(&fd)); QCOMPARE(fd.isVisible(), true); QCOMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd)); diff --git a/tests/auto/widgets/dialogs/qfontdialog/CMakeLists.txt b/tests/auto/widgets/dialogs/qfontdialog/CMakeLists.txt index 4e231cc6cc..b1bbf62cc7 100644 --- a/tests/auto/widgets/dialogs/qfontdialog/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qfontdialog/CMakeLists.txt @@ -1,19 +1,15 @@ -# Generated from qfontdialog.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qfontdialog Test: ##################################################################### -qt_internal_add_test(tst_qfontdialog - SOURCES - tst_qfontdialog.cpp - PUBLIC_LIBRARIES - Qt::CorePrivate - Qt::Gui - Qt::GuiPrivate - Qt::Widgets - Qt::WidgetsPrivate -) +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfontdialog LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() # Resources: set_source_files_properties("../../../shared/resources/test.ttf" @@ -27,13 +23,18 @@ set(testfonts_resource_files "../../../shared/resources/testfont.ttf" ) -qt_internal_add_resource(tst_qfontdialog "testfonts" - PREFIX - "/" - FILES - ${testfonts_resource_files} +qt_internal_add_test(tst_qfontdialog + SOURCES + tst_qfontdialog.cpp + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::Widgets + Qt::WidgetsPrivate + TESTDATA ${testfonts_resource_files} + BUILTIN_TESTDATA ) - ## Scopes: ##################################################################### diff --git a/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro b/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro deleted file mode 100644 index 320d6ee3b5..0000000000 --- a/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro +++ /dev/null @@ -1,16 +0,0 @@ -CONFIG += testcase -TARGET = tst_qfontdialog - -QT += widgets widgets-private testlib -QT += core-private gui-private - -SOURCES += tst_qfontdialog.cpp - -RESOURCES += testfonts.qrc - -osx { -# ### fixme -# OBJECTIVE_SOURCES += tst_qfontdialog_mac_helpers.mm -# LIBS += -framework AppKit -} - diff --git a/tests/auto/widgets/dialogs/qfontdialog/testfonts.qrc b/tests/auto/widgets/dialogs/qfontdialog/testfonts.qrc deleted file mode 100644 index cdfa287b39..0000000000 --- a/tests/auto/widgets/dialogs/qfontdialog/testfonts.qrc +++ /dev/null @@ -1,6 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file alias="test.ttf">../../../shared/resources/test.ttf</file> - <file alias="testfont.ttf">../../../shared/resources/testfont.ttf</file> - </qresource> -</RCC> diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp index ad6bf900fd..01f3e7ec95 100644 --- a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp @@ -1,33 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QTest> #include <qapplication.h> @@ -70,6 +45,7 @@ private slots: void qtbug_41513_stylesheetStyle(); #endif + void hideNativeByDestruction(); private: void runSlotWithFailsafeTimer(const char *member); @@ -101,7 +77,7 @@ void tst_QFontDialog::cleanup() void tst_QFontDialog::postKeyReturn() { QWidgetList list = QApplication::topLevelWidgets(); - for (int i=0; i<list.count(); ++i) { + for (int i=0; i<list.size(); ++i) { QFontDialog *dialog = qobject_cast<QFontDialog*>(list[i]); if (dialog) { QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier ); @@ -240,7 +216,7 @@ void tst_QFontDialog::testNonStandardFontSize() QList<int> standardSizesList = QFontDatabase::standardSizes(); int nonStandardFontSize; if (!standardSizesList.isEmpty()) { - nonStandardFontSize = standardSizesList.at(standardSizesList.count()-1); // get the maximum standard size. + nonStandardFontSize = standardSizesList.at(standardSizesList.size()-1); // get the maximum standard size. nonStandardFontSize += 1; // the increment of 1 to mock a non-standard font size. } else { QSKIP("QFontDatabase::standardSizes() is empty."); @@ -260,7 +236,34 @@ void tst_QFontDialog::testNonStandardFontSize() if (accepted) QCOMPARE(testFont.pointSize(), resultFont.pointSize()); else - QWARN("Fail using a non-standard font size."); + qWarning("Fail using a non-standard font size."); +} + +void tst_QFontDialog::hideNativeByDestruction() +{ + QWidget window; + QWidget *child = new QWidget(&window); + QPointer<QFontDialog> dialog = new QFontDialog(child); + // Make it application modal so that we don't end up with a sheet on macOS + dialog->setWindowModality(Qt::ApplicationModal); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + dialog->open(); + + // We test that the dialog opens and closes by watching the activation of the + // transient parent window. If it doesn't deactivate, then we have to skip. + const auto windowActive = [&window]{ return window.isActiveWindow(); }; + const auto windowInactive = [&window]{ return !window.isActiveWindow(); }; + if (!QTest::qWaitFor(windowInactive, 2000)) + QSKIP("Dialog didn't activate"); + + // This should destroy the dialog and close the native window + child->deleteLater(); + QTRY_VERIFY(!dialog); + // If the native window is still open, then the transient parent can't become + // active + window.activateWindow(); + QVERIFY(QTest::qWaitFor(windowActive)); } QTEST_MAIN(tst_QFontDialog) diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm deleted file mode 100644 index 00cc6a879f..0000000000 --- a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation 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 <AppKit/AppKit.h> - -void click_cocoa_button() -{ - QMacAutoReleasePool pool; - NSArray *windows = [NSApp windows]; - for (NSWindow *window in windows) { - // This is NOT how one should do RTTI, but since I don't want to leak the class too much... - if ([[window delegate] respondsToSelector:@selector(qtFont)]) { - NSArray *subviews = [[window contentView] subviews]; - for (NSView *view in subviews) { - if ([view isKindOfClass:[NSButton class]] - && [[static_cast<NSButton *>(view) title] isEqualTo:@"OK"]) { - [static_cast<NSButton *>(view) performClick:view]; - [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint - modifierFlags:0 timestamp:0. windowNumber:0 context:0 - subtype:SHRT_MAX data1:0 data2:0] atStart:NO]; - - break; - } - } - break; - } - } -} diff --git a/tests/auto/widgets/dialogs/qinputdialog/CMakeLists.txt b/tests/auto/widgets/dialogs/qinputdialog/CMakeLists.txt index cdb311a3c2..528493a66b 100644 --- a/tests/auto/widgets/dialogs/qinputdialog/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qinputdialog/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qinputdialog.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qinputdialog Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qinputdialog LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qinputdialog SOURCES tst_qinputdialog.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui Qt::WidgetsPrivate ) diff --git a/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro b/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro deleted file mode 100644 index 9cb14c5350..0000000000 --- a/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG += testcase -TARGET = tst_qinputdialog -QT += widgets-private testlib -SOURCES += tst_qinputdialog.cpp diff --git a/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp b/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp index 2a40af320b..136c789abd 100644 --- a/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp +++ b/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp @@ -1,39 +1,16 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QTest> #include <QString> #include <QSpinBox> #include <QPushButton> #include <QLineEdit> #include <QComboBox> #include <QDialogButtonBox> +#include <QTimer> + #include <qinputdialog.h> #include <QtWidgets/private/qdialog_p.h> diff --git a/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST b/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST deleted file mode 100644 index 8d8a7c2105..0000000000 --- a/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST +++ /dev/null @@ -1,4 +0,0 @@ -[defaultButton] -opensuse-leap -rhel-7.6 -ubuntu diff --git a/tests/auto/widgets/dialogs/qmessagebox/CMakeLists.txt b/tests/auto/widgets/dialogs/qmessagebox/CMakeLists.txt index 8b6b864cf7..53fd8a61c6 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qmessagebox/CMakeLists.txt @@ -1,18 +1,22 @@ -# Generated from qmessagebox.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qmessagebox Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qmessagebox LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qmessagebox SOURCES tst_qmessagebox.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Widgets ) - -#### Keys ignored in scope 1:.:.:qmessagebox.pro:<TRUE>: -# TEMPLATE = "app" diff --git a/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro b/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro deleted file mode 100644 index 91848fee24..0000000000 --- a/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro +++ /dev/null @@ -1,6 +0,0 @@ -TEMPLATE = app -TARGET = tst_qmessagebox -QT += gui-private core-private widgets testlib -CONFIG += testcase - -SOURCES += tst_qmessagebox.cpp diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 1d379acc46..26a6245164 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -1,40 +1,19 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QTest> #include <QMessageBox> #include <QDebug> -#include <QPair> +#include <QSet> #include <QList> #include <QPointer> #include <QTimer> #include <QApplication> #include <QPushButton> #include <QDialogButtonBox> +#include <QSignalSpy> + #include <qpa/qplatformtheme.h> #include <private/qguiapplication_p.h> @@ -43,9 +22,14 @@ class tst_QMessageBox : public QObject Q_OBJECT private slots: + void initTestCase_data(); + void init(); + void sanityTest(); + void baseClassSetVisible(); void defaultButton(); void escapeButton(); + void clickedButton(); void button(); void statics(); void about(); @@ -53,6 +37,9 @@ private slots: void detailsButtonText(); void expandDetailsWithoutMoving(); + void optionsEmptyByDefault(); + void changeNativeOption(); + #ifndef Q_OS_MAC void shortcut(); #endif @@ -70,6 +57,14 @@ private slots: void acceptedRejectedSignals(); void acceptedRejectedSignals_data(); + void overrideDone_data(); + void overrideDone(); + + void hideNativeByDestruction(); + + void explicitDoneAfterButtonClicked(); + void legacyApiReturnValue(); + void cleanup(); }; @@ -122,11 +117,20 @@ void ExecCloseHelper::timerEvent(QTimerEvent *te) return; QWidget *modalWidget = QApplication::activeModalWidget(); - if (!m_testCandidate && modalWidget) m_testCandidate = modalWidget; - if (m_testCandidate && m_testCandidate == modalWidget) { + QWidget *activeWindow = QApplication::activeWindow(); + if (!m_testCandidate && activeWindow) + m_testCandidate = activeWindow; + + if (!m_testCandidate) + return; + + bool shouldHelp = (m_testCandidate->isModal() && m_testCandidate == modalWidget) + || (!m_testCandidate->isModal() && m_testCandidate == activeWindow); + + if (shouldHelp) { if (m_key == CloseWindow) { m_testCandidate->close(); } else { @@ -139,6 +143,60 @@ void ExecCloseHelper::timerEvent(QTimerEvent *te) } } +void tst_QMessageBox::initTestCase_data() +{ + QTest::addColumn<bool>("useNativeDialog"); + QTest::newRow("widget") << false; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + if (theme->usePlatformNativeDialog(QPlatformTheme::MessageDialog)) + QTest::newRow("native") << true; + } +} + +void tst_QMessageBox::init() +{ + QFETCH_GLOBAL(bool, useNativeDialog); + qApp->setAttribute(Qt::AA_DontUseNativeDialogs, !useNativeDialog); +} + +class OverridingMessageBox : public QMessageBox +{ +public: + void done(int result) override { + doneResult = result; + QMessageBox::done(result); + } + std::optional<int> doneResult; +}; + +void tst_QMessageBox::overrideDone_data() +{ + QTest::addColumn<QMessageBox::StandardButton>("button"); + QTest::addColumn<int>("closeAction"); + QTest::addColumn<int>("result"); + + QTest::newRow("close") << QMessageBox::Help << int(ExecCloseHelper::CloseWindow) << 0; + QTest::newRow("yes") << QMessageBox::Yes << int(Qt::Key_Enter) << int(QMessageBox::Yes); + QTest::newRow("no") << QMessageBox::No << int(Qt::Key_Enter) << int(QMessageBox::No); +} + +void tst_QMessageBox::overrideDone() +{ + QFETCH(QMessageBox::StandardButton, button); + QFETCH(int, closeAction); + QFETCH(int, result); + + OverridingMessageBox messageBox; + messageBox.addButton(button); + messageBox.setDefaultButton(button); + ExecCloseHelper closeHelper; + closeHelper.start(closeAction, &messageBox); + messageBox.exec(); + QVERIFY(messageBox.doneResult.has_value()); + QCOMPARE(*messageBox.doneResult, result); + +} + void tst_QMessageBox::cleanup() { QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty()); // OS X requires TRY @@ -165,6 +223,15 @@ void tst_QMessageBox::sanityTest() msgBox.exec(); } +void tst_QMessageBox::baseClassSetVisible() +{ + QMessageBox msgBox; + msgBox.setText("Hello World"); + msgBox.QDialog::setVisible(true); + QCOMPARE(msgBox.isVisible(), true); + msgBox.close(); +} + void tst_QMessageBox::button() { QMessageBox msgBox; @@ -298,6 +365,28 @@ void tst_QMessageBox::escapeButton() QVERIFY(msgBox3.clickedButton() == msgBox3.button(QMessageBox::Ok)); // auto detected } +void tst_QMessageBox::clickedButton() +{ + QMessageBox msgBox; + msgBox.addButton(QMessageBox::Yes); + msgBox.addButton(QMessageBox::No); + msgBox.addButton(QMessageBox::Retry); + + QVERIFY(!msgBox.clickedButton()); + + for (int i = 0; i < 2; ++i) { + QAbstractButton *clickedButtonAfterExex = nullptr; + QTimer::singleShot(100, [&] { + clickedButtonAfterExex = msgBox.clickedButton(); + msgBox.close(); + }); + msgBox.exec(); + + QVERIFY(!clickedButtonAfterExex); + QVERIFY(msgBox.clickedButton()); + } +} + void tst_QMessageBox::statics() { QMessageBox::StandardButton (*statics[4])(QWidget *, const QString &, @@ -351,7 +440,7 @@ void tst_QMessageBox::shortcut() msgBox.addButton("&Maybe", QMessageBox::YesRole); ExecCloseHelper closeHelper; closeHelper.start(Qt::Key_M, &msgBox); - QCOMPARE(msgBox.exec(), 2); + QCOMPARE(msgBox.exec(), 4); } #endif @@ -384,69 +473,63 @@ void tst_QMessageBox::staticSourceCompat() int ret; // source compat tests for < 4.2 +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED +#define COMPARE(real, exp) do {\ + const auto pressed = static_cast<QMessageBox::StandardButton>(real);\ + const auto expected = static_cast<QMessageBox::StandardButton>(exp);\ + if (!QTest::qCompare(pressed, expected, #real, #exp, __FILE__, __LINE__)) \ + return; } while (false) + ExecCloseHelper closeHelper; closeHelper.start(Qt::Key_Enter); ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes, QMessageBox::No); - int expectedButton = int(QMessageBox::Yes); - if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - const int dialogButtonBoxLayout = theme->themeHint(QPlatformTheme::DialogButtonBoxLayout).toInt(); - if (dialogButtonBoxLayout == QDialogButtonBox::MacLayout - || dialogButtonBoxLayout == QDialogButtonBox::GnomeLayout) - expectedButton = int(QMessageBox::No); - } - QCOMPARE(ret, expectedButton); + COMPARE(ret, QMessageBox::No); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); - QCOMPARE(ret, int(QMessageBox::Yes)); + COMPARE(ret, int(QMessageBox::Yes)); QVERIFY(closeHelper.done()); +#if QT_DEPRECATED_SINCE(6, 2) + // The overloads below are valid only before 6.2 closeHelper.start(Qt::Key_Enter); ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default); - QCOMPARE(ret, int(QMessageBox::No)); + COMPARE(ret, int(QMessageBox::No)); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape); - QCOMPARE(ret, int(QMessageBox::Yes)); + COMPARE(ret, int(QMessageBox::Yes)); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Escape, QMessageBox::No | QMessageBox::Default); - QCOMPARE(ret, int(QMessageBox::No)); + COMPARE(ret, int(QMessageBox::No)); QVERIFY(closeHelper.done()); // the button text versions closeHelper.start(Qt::Key_Enter); ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 1); - QCOMPARE(ret, 1); + COMPARE(ret, 1); QVERIFY(closeHelper.done()); - - if (0) { // don't run these tests since the dialog won't close! - closeHelper.start(Qt::Key_Escape); - ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 1); - QCOMPARE(ret, -1); - QVERIFY(closeHelper.done()); - - closeHelper.start(Qt::Key_Escape); - ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 0, 1); - QCOMPARE(ret, 1); - QVERIFY(closeHelper.done()); - } +#endif // QT_DEPRECATED_SINCE(6, 2) +#undef COMPARE +QT_WARNING_POP } void tst_QMessageBox::instanceSourceCompat() { - QMessageBox mb("Application name here", - "Saving the file will overwrite the original file on the disk.\n" - "Do you really want to save?", - QMessageBox::Information, - QMessageBox::Yes | QMessageBox::Default, - QMessageBox::No, - QMessageBox::Cancel | QMessageBox::Escape); - mb.setButtonText(QMessageBox::Yes, "Save"); - mb.setButtonText(QMessageBox::No, "Discard"); + QMessageBox mb(QMessageBox::Information, + "Application name here", + "Saving the file will overwrite the original file on the disk.\n" + "Do you really want to save?", + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + mb.setDefaultButton(QMessageBox::Yes); + mb.setEscapeButton(QMessageBox::Cancel); + mb.button(QMessageBox::Yes)->setText("Save"); + mb.button(QMessageBox::No)->setText("Discard"); mb.addButton("&Revert", QMessageBox::RejectRole); mb.addButton("&Zoo", QMessageBox::ActionRole); @@ -458,14 +541,18 @@ void tst_QMessageBox::instanceSourceCompat() #ifndef Q_OS_MAC // mnemonics are not used on OS X closeHelper.start(QKeyCombination(Qt::ALT | Qt::Key_R).toCombined(), &mb); - QCOMPARE(mb.exec(), 0); + QCOMPARE(mb.exec(), 2); closeHelper.start(QKeyCombination(Qt::ALT | Qt::Key_Z).toCombined(), &mb); - QCOMPARE(mb.exec(), 1); + QCOMPARE(mb.exec(), 3); #endif } void tst_QMessageBox::detailsText() { + QFETCH_GLOBAL(bool, useNativeDialog); + if (useNativeDialog) + QSKIP("Native dialogs do not propagate expose events"); + QMessageBox box; QString text("This is the details text."); box.setDetailedText(text); @@ -479,6 +566,10 @@ void tst_QMessageBox::detailsText() void tst_QMessageBox::detailsButtonText() { + QFETCH_GLOBAL(bool, useNativeDialog); + if (useNativeDialog) + QSKIP("Native dialogs do not propagate expose events"); + QMessageBox box; box.setDetailedText("bla"); box.open(); @@ -500,6 +591,10 @@ void tst_QMessageBox::detailsButtonText() void tst_QMessageBox::expandDetailsWithoutMoving() // QTBUG-32473 { + QFETCH_GLOBAL(bool, useNativeDialog); + if (useNativeDialog) + QSKIP("Native dialogs do not propagate expose events"); + tst_ResizingMessageBox box; box.setDetailedText("bla"); box.show(); @@ -525,6 +620,20 @@ void tst_QMessageBox::expandDetailsWithoutMoving() // QTBUG-32473 QCOMPARE(box.geometry().topLeft(), geom.topLeft()); } +void tst_QMessageBox::optionsEmptyByDefault() +{ + QMessageBox b; + QCOMPARE(b.options(), QMessageBox::Options()); + QVERIFY(!b.testOption(QMessageBox::Option::DontUseNativeDialog)); +} + +void tst_QMessageBox::changeNativeOption() +{ + QMessageBox b; + b.setOption(QMessageBox::Option::DontUseNativeDialog); + QCOMPARE(b.options(), QMessageBox::Options(QMessageBox::Option::DontUseNativeDialog)); +} + void tst_QMessageBox::incorrectDefaultButton() { ExecCloseHelper closeHelper; @@ -539,12 +648,17 @@ void tst_QMessageBox::incorrectDefaultButton() QMessageBox::question(nullptr, "", "I've been hit!",QFlag(QMessageBox::Ok | QMessageBox::Cancel),QMessageBox::Save); QVERIFY(closeHelper.done()); +#if QT_DEPRECATED_SINCE(6, 2) closeHelper.start(Qt::Key_Escape); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED //do not crash here -> call old function of QMessageBox in this case QMessageBox::question(nullptr, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Ok); +QT_WARNING_POP QVERIFY(closeHelper.done()); +#endif } void tst_QMessageBox::updateSize() @@ -594,6 +708,10 @@ Q_DECLARE_METATYPE(RoleSet); void tst_QMessageBox::acceptedRejectedSignals() { + QFETCH_GLOBAL(bool, useNativeDialog); + if (useNativeDialog) + QSKIP("Native dialogs do not propagate expose events"); + QMessageBox messageBox(QMessageBox::Information, "Test window", "Test text"); QFETCH(ButtonsCreator, buttonsCreator); @@ -615,7 +733,7 @@ void tst_QMessageBox::acceptedRejectedSignals() button->click(); if (roles.contains(messageBox.buttonRole(button))) - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); else QVERIFY(spy.isEmpty()); } @@ -673,5 +791,94 @@ void tst_QMessageBox::acceptedRejectedSignals_data() addCustomButtonsData(); } +void tst_QMessageBox::hideNativeByDestruction() +{ + QWidget window; + QWidget *child = new QWidget(&window); + QPointer<QMessageBox> dialog = new QMessageBox(child); + // Make it application modal so that we don't end up with a sheet on macOS + dialog->setWindowModality(Qt::ApplicationModal); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + dialog->open(); + + // We test that the dialog opens and closes by watching the activation of the + // transient parent window. If it doesn't deactivate, then we have to skip. + const auto windowActive = [&window]{ return window.isActiveWindow(); }; + const auto windowInactive = [&window]{ return !window.isActiveWindow(); }; + if (!QTest::qWaitFor(windowInactive, 2000)) + QSKIP("Dialog didn't activate"); + + // This should destroy the dialog and close the native window + child->deleteLater(); + QTRY_VERIFY(!dialog); + // If the native window is still open, then the transient parent can't become + // active + window.activateWindow(); + QVERIFY(QTest::qWaitFor(windowActive)); +} + +void tst_QMessageBox::explicitDoneAfterButtonClicked() +{ + QMessageBox msgBox; + auto *standardButton = msgBox.addButton(QMessageBox::Ok); + auto *customButton = msgBox.addButton("Custom", QMessageBox::RejectRole); + + QSignalSpy acceptedSpy(&msgBox, &QDialog::accepted); + QSignalSpy rejectedSpy(&msgBox, &QDialog::rejected); + + msgBox.setDefaultButton(standardButton); + ExecCloseHelper closeHelper; + closeHelper.start(Qt::Key_Enter, &msgBox); + msgBox.exec(); + QCOMPARE(msgBox.clickedButton(), standardButton); + QCOMPARE(msgBox.result(), QMessageBox::Ok); + QCOMPARE(acceptedSpy.size(), 1); + QCOMPARE(rejectedSpy.size(), 0); + + msgBox.accept(); + QCOMPARE(msgBox.result(), QDialog::Accepted); + QCOMPARE(acceptedSpy.size(), 2); + QCOMPARE(rejectedSpy.size(), 0); + msgBox.reject(); + QCOMPARE(msgBox.result(), QDialog::Rejected); + QCOMPARE(acceptedSpy.size(), 2); + QCOMPARE(rejectedSpy.size(), 1); + + msgBox.setDefaultButton(customButton); + closeHelper.start(Qt::Key_Enter, &msgBox); + msgBox.exec(); + QCOMPARE(msgBox.clickedButton(), customButton); + QVERIFY(msgBox.result() != QDialog::Accepted); + QVERIFY(msgBox.result() != QDialog::Rejected); + QCOMPARE(acceptedSpy.size(), 2); + QCOMPARE(rejectedSpy.size(), 2); + + msgBox.accept(); + QCOMPARE(msgBox.result(), QDialog::Accepted); + QCOMPARE(acceptedSpy.size(), 3); + QCOMPARE(rejectedSpy.size(), 2); + msgBox.reject(); + QCOMPARE(msgBox.result(), QDialog::Rejected); + QCOMPARE(acceptedSpy.size(), 3); + QCOMPARE(rejectedSpy.size(), 3); +} + +void tst_QMessageBox::legacyApiReturnValue() +{ + ExecCloseHelper closeHelper; + for (int i = 0; i < 3; ++i) { + closeHelper.start(Qt::Key_Enter); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + QCOMPARE(QMessageBox::warning(nullptr, "Title", "Text", + "Button 0", "Button 1", "Button 2", i), i); + closeHelper.start(Qt::Key_Escape); + QCOMPARE(QMessageBox::warning(nullptr, "Title", "Text", + "Button 0", "Button 1", "Button 2", 0, i), i); +QT_WARNING_POP + } +} + QTEST_MAIN(tst_QMessageBox) #include "tst_qmessagebox.moc" diff --git a/tests/auto/widgets/dialogs/qprogressdialog/CMakeLists.txt b/tests/auto/widgets/dialogs/qprogressdialog/CMakeLists.txt index 5651cf8d26..4861f3af25 100644 --- a/tests/auto/widgets/dialogs/qprogressdialog/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qprogressdialog/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qprogressdialog.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qprogressdialog Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qprogressdialog LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qprogressdialog SOURCES tst_qprogressdialog.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui Qt::Widgets ) diff --git a/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro b/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro deleted file mode 100644 index 10aeaace71..0000000000 --- a/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro +++ /dev/null @@ -1,8 +0,0 @@ -############################################################ -# Project file for autotest for file qprogressdialog.h -############################################################ - -CONFIG += testcase -TARGET = tst_qprogressdialog -QT += widgets testlib -SOURCES += tst_qprogressdialog.cpp diff --git a/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp b/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp index 2149ee7c44..baf727d766 100644 --- a/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp +++ b/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp @@ -1,33 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QTest> #include <qapplication.h> #include <qdebug.h> @@ -51,6 +26,7 @@ private Q_SLOTS: void getSetCheck(); void task198202(); void QTBUG_31046(); + void QTBUG_19983(); void settingCustomWidgets(); void i18n(); void setValueReentrancyGuard(); @@ -108,7 +84,7 @@ void tst_QProgressDialog::autoShow() // in order to test for the setValue() behavior instead // See autoShowCtor() for the ctor timer check dlg.setValue(value); - QThread::msleep(delay); + QThread::sleep(std::chrono::milliseconds{delay}); dlg.setValue(min+1); QCOMPARE(dlg.isVisible(), expectedAutoShow); } @@ -117,7 +93,7 @@ void tst_QProgressDialog::autoShowCtor() { QProgressDialog dlg; QVERIFY(!dlg.isVisible()); - QThread::msleep(dlg.minimumDuration()); + QThread::sleep(std::chrono::milliseconds{dlg.minimumDuration()}); QTRY_VERIFY(dlg.isVisible()); } @@ -205,11 +181,34 @@ void tst_QProgressDialog::QTBUG_31046() { QProgressDialog dlg("", "", 50, 60); dlg.setValue(0); - QThread::msleep(200); + QThread::sleep(std::chrono::milliseconds{200}); dlg.setValue(50); QCOMPARE(50, dlg.value()); } +void tst_QProgressDialog::QTBUG_19983() +{ + QProgressDialog tempDlg; + tempDlg.setRange(0, 0); + tempDlg.setLabelText("This is a test."); + + QPushButton *btnOne = new QPushButton("Cancel", &tempDlg); + tempDlg.setCancelButton(btnOne); + tempDlg.show(); + QVERIFY(QTest::qWaitForWindowExposed(&tempDlg)); + const auto btnOneGeometry = btnOne->geometry(); + QVERIFY(QPoint(0,0) != btnOneGeometry.topLeft()); + + tempDlg.cancel(); + QVERIFY(!tempDlg.isVisible()); + + QPushButton *btnTwo = new QPushButton("Cancel", &tempDlg); + tempDlg.setCancelButton(btnTwo); + tempDlg.show(); + QVERIFY(QTest::qWaitForWindowExposed(&tempDlg)); + QCOMPARE(btnOneGeometry, btnTwo->geometry()); +} + void tst_QProgressDialog::settingCustomWidgets() { QPointer<QLabel> l = new QLabel; diff --git a/tests/auto/widgets/dialogs/qsidebar/CMakeLists.txt b/tests/auto/widgets/dialogs/qsidebar/CMakeLists.txt index 8d2fda708d..bf9513bb69 100644 --- a/tests/auto/widgets/dialogs/qsidebar/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qsidebar/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qsidebar.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qsidebar Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qsidebar LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qsidebar SOURCES tst_qsidebar.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::Widgets diff --git a/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro b/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro deleted file mode 100644 index 18e637199a..0000000000 --- a/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += testcase - -QT += core-private -QT += widgets widgets-private testlib -SOURCES += tst_qsidebar.cpp -TARGET = tst_qsidebar diff --git a/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp b/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp index 20866a0fa7..cdbf2011a4 100644 --- a/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp +++ b/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp @@ -1,33 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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> +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QTest> +#include <QSignalSpy> + #include <QtWidgets/private/qsidebar_p.h> #include <QtGui/private/qfilesystemmodel_p.h> #include <QtWidgets/qfileiconprovider.h> @@ -61,9 +38,9 @@ void tst_QSidebar::setUrls() QCOMPARE(model->rowCount(), 0); qsidebar.setUrls(urls); QCOMPARE(qsidebar.urls(), urls); - QCOMPARE(model->rowCount(), urls.count()); + QCOMPARE(model->rowCount(), urls.size()); qsidebar.setUrls(urls); - QCOMPARE(model->rowCount(), urls.count()); + QCOMPARE(model->rowCount(), urls.size()); } void tst_QSidebar::selectUrls() @@ -78,7 +55,7 @@ void tst_QSidebar::selectUrls() QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(QUrl))); qsidebar.selectUrl(urls.at(0)); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); } void tst_QSidebar::addUrls() @@ -91,7 +68,7 @@ void tst_QSidebar::addUrls() QAbstractItemModel *model = qsidebar.model(); QDir testDir = QDir::home(); -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) +#ifdef Q_OS_ANDROID // temp and home is the same directory on Android testDir.mkdir(QStringLiteral("test")); QVERIFY(testDir.cd(QStringLiteral("test"))); @@ -194,7 +171,7 @@ void tst_QSidebar::goToUrl() QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(QUrl))); QTest::mousePress(qsidebar.viewport(), Qt::LeftButton, {}, qsidebar.visualRect(qsidebar.model()->index(0, 0)).center()); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QCOMPARE((spy.value(0)).at(0).toUrl(), urls.first()); } diff --git a/tests/auto/widgets/dialogs/qwizard/CMakeLists.txt b/tests/auto/widgets/dialogs/qwizard/CMakeLists.txt index 81dc9e85b2..d863126560 100644 --- a/tests/auto/widgets/dialogs/qwizard/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qwizard/CMakeLists.txt @@ -1,17 +1,15 @@ -# Generated from qwizard.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qwizard Test: ##################################################################### -qt_internal_add_test(tst_qwizard - SOURCES - tst_qwizard.cpp - tst_qwizard_2.cpp - PUBLIC_LIBRARIES - Qt::Gui - Qt::Widgets -) +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qwizard LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() # Resources: set(qwizard_resource_files @@ -21,10 +19,15 @@ set(qwizard_resource_files "images/watermark.png" ) -qt_internal_add_resource(tst_qwizard "qwizard" - PREFIX - "/" - FILES - ${qwizard_resource_files} +qt_internal_add_test(tst_qwizard + SOURCES + tst_qwizard.cpp + tst_qwizard_2.cpp + LIBRARIES + Qt::Gui + Qt::Widgets + Qt::WidgetsPrivate + TESTDATA ${qwizard_resource_files} + BUILTIN_TESTDATA ) diff --git a/tests/auto/widgets/dialogs/qwizard/qwizard.pro b/tests/auto/widgets/dialogs/qwizard/qwizard.pro deleted file mode 100644 index c6e5bcea7a..0000000000 --- a/tests/auto/widgets/dialogs/qwizard/qwizard.pro +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG += testcase -TARGET = tst_qwizard -QT += widgets testlib -SOURCES += tst_qwizard.cpp tst_qwizard_2.cpp -RESOURCES = qwizard.qrc diff --git a/tests/auto/widgets/dialogs/qwizard/qwizard.qrc b/tests/auto/widgets/dialogs/qwizard/qwizard.qrc deleted file mode 100644 index 471da9def6..0000000000 --- a/tests/auto/widgets/dialogs/qwizard/qwizard.qrc +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource> - <file>images/background.png</file> - <file>images/banner.png</file> - <file>images/logo.png</file> - <file>images/watermark.png</file> -</qresource> -</RCC> diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp index b8d2a4617c..c0afed6919 100644 --- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp +++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp @@ -1,34 +1,9 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QFont> -#include <QtTest/QtTest> +#include <QTest> #include <QCheckBox> #include <QLabel> #include <QLineEdit> @@ -39,6 +14,12 @@ #include <QWizard> #include <QTreeWidget> #include <QScreen> +#include <QSignalSpy> +#include <QOperatingSystemVersion> + +#include <QtWidgets/private/qapplication_p.h> + +#include <memory> Q_DECLARE_METATYPE(QWizard::WizardButton); @@ -87,6 +68,7 @@ private slots: void sideWidget(); void objectNames_data(); void objectNames(); + void changePages(); // task-specific tests below me: void task177716_disableCommitButton(); @@ -418,7 +400,7 @@ void tst_QWizard::setPixmap() QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull()); - if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSHighSierra) + if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::MacOS) QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull()); else QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull()); @@ -426,7 +408,7 @@ void tst_QWizard::setPixmap() QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull()); QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull()); QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull()); - if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSHighSierra) + if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::MacOS) QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull()); else QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull()); @@ -544,7 +526,7 @@ void tst_QWizard::addPage() QCOMPARE(wizard.addPage(pages[i]), i); QCOMPARE(pages[i]->window(), (QWidget *)&wizard); QCOMPARE(wizard.startId(), 0); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QList<QVariant> arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), i); } @@ -557,37 +539,37 @@ void tst_QWizard::addPage() QVERIFY(!wizard.page(N + 1)); wizard.setPage(N + 50, new QWizardPage); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QList<QVariant> arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), N + 50); wizard.setPage(-3000, new QWizardPage); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), -3000); QWizardPage *pageX = new QWizardPage; QCOMPARE(wizard.addPage(pageX), N + 51); QCOMPARE(wizard.page(N + 51), pageX); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), N + 51); QCOMPARE(wizard.addPage(new QWizardPage), N + 52); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), N + 52); QTest::ignoreMessage(QtWarningMsg,"QWizard::setPage: Cannot insert null page"); wizard.addPage(0); // generates a warning - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); delete parent; } #define CHECK_VISITED(wizard, list) \ do { \ - QList<int> myList = list; \ + const QList<int> myList = list; \ QCOMPARE((wizard).visitedIds(), myList); \ - Q_FOREACH(int id, myList) \ + for (int id : myList) \ QVERIFY((wizard).hasVisitedPage(id)); \ } while (0) @@ -606,7 +588,7 @@ void tst_QWizard::setPage() page = new QWizardPage(parent); QTest::ignoreMessage(QtWarningMsg,"QWizard::setPage: Cannot insert page with ID -1"); wizard.setPage(-1, page); // gives a warning and does nothing - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); QVERIFY(!wizard.page(-2)); QVERIFY(!wizard.page(-1)); QVERIFY(!wizard.page(0)); @@ -618,7 +600,7 @@ void tst_QWizard::setPage() page = new QWizardPage(parent); wizard.setPage(0, page); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QList<QVariant> arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 0); QCOMPARE(page->window(), (QWidget *)&wizard); @@ -631,7 +613,7 @@ void tst_QWizard::setPage() page = new QWizardPage(parent); wizard.setPage(-2, page); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), -2); QCOMPARE(page->window(), (QWidget *)&wizard); @@ -652,7 +634,7 @@ void tst_QWizard::setPage() page = new QWizardPage(parent); wizard.setPage(2, page); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 2); QCOMPARE(wizard.page(2), page); @@ -671,7 +653,7 @@ void tst_QWizard::setPage() page = new QWizardPage(parent); wizard.setPage(-3, page); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), -3); QCOMPARE(wizard.page(-3), page); @@ -742,7 +724,7 @@ void tst_QWizard::setPage() QCOMPARE(wizard.nextId(), -2); CHECK_VISITED(wizard, QList<int>() << -3); } - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); delete parent; } @@ -1000,7 +982,7 @@ void tst_QWizard::setOption_IgnoreSubTitles() // Check that subtitles are shown when they should (i.e., // they're set and IgnoreSubTitles is off). - qApp->setActiveWindow(0); // ensure no focus rectangle around cancel button + QApplicationPrivate::setActiveWindow(0); // ensure no focus rectangle around cancel button QImage i11 = grabWidget(&wizard1); QImage i21 = grabWidget(&wizard2); QVERIFY(i11 != i21); @@ -1601,9 +1583,9 @@ class SetPage : public Operation QString describe() const override { return QLatin1String("set page ") + QString::number(page); } int page; public: - static QSharedPointer<SetPage> create(int page) + static std::shared_ptr<SetPage> create(int page) { - QSharedPointer<SetPage> o = QSharedPointer<SetPage>::create(); + std::shared_ptr<SetPage> o = std::make_shared<SetPage>(); o->page = page; return o; } @@ -1615,9 +1597,9 @@ class SetStyle : public Operation QString describe() const override { return QLatin1String("set style ") + QString::number(style); } QWizard::WizardStyle style; public: - static QSharedPointer<SetStyle> create(QWizard::WizardStyle style) + static std::shared_ptr<SetStyle> create(QWizard::WizardStyle style) { - QSharedPointer<SetStyle> o = QSharedPointer<SetStyle>::create(); + std::shared_ptr<SetStyle> o = std::make_shared<SetStyle>(); o->style = style; return o; } @@ -1630,9 +1612,9 @@ class SetOption : public Operation QWizard::WizardOption option; bool on; public: - static QSharedPointer<SetOption> create(QWizard::WizardOption option, bool on) + static std::shared_ptr<SetOption> create(QWizard::WizardOption option, bool on) { - QSharedPointer<SetOption> o = QSharedPointer<SetOption>::create(); + std::shared_ptr<SetOption> o = std::make_shared<SetOption>(); o->option = option; o->on = on; return o; @@ -1661,8 +1643,8 @@ class OptionInfo tags[QWizard::HaveCustomButton3] = "15/CB3"; for (int i = 0; i < 2; ++i) { - QMap<QWizard::WizardOption, QSharedPointer<Operation> > operations_; - foreach (QWizard::WizardOption option, tags.keys()) + QMap<QWizard::WizardOption, std::shared_ptr<Operation> > operations_; + for (const auto &[option, _] : std::as_const(tags).asKeyValueRange()) operations_[option] = SetOption::create(option, i == 1); operations << operations_; } @@ -1670,7 +1652,7 @@ class OptionInfo OptionInfo(OptionInfo const&); OptionInfo& operator=(OptionInfo const&); QMap<QWizard::WizardOption, QString> tags; - QList<QMap<QWizard::WizardOption, QSharedPointer<Operation> > > operations; + QList<QMap<QWizard::WizardOption, std::shared_ptr<Operation> > > operations; public: static OptionInfo &instance() { @@ -1679,7 +1661,7 @@ public: } QString tag(QWizard::WizardOption option) const { return tags.value(option); } - QSharedPointer<Operation> operation(QWizard::WizardOption option, bool on) const + std::shared_ptr<Operation> operation(QWizard::WizardOption option, bool on) const { return operations.at(on).value(option); } QList<QWizard::WizardOption> options() const { return tags.keys(); } }; @@ -1690,7 +1672,7 @@ QString SetOption::describe() const + QLatin1Char(on ? '1' : '0'); } -Q_DECLARE_METATYPE(QList<QSharedPointer<Operation>>) +Q_DECLARE_METATYPE(QList<std::shared_ptr<Operation>>) class TestGroup { @@ -1707,7 +1689,7 @@ public: combinations.clear(); } - QList<QSharedPointer<Operation>> &add() + QList<std::shared_ptr<Operation>> &add() { combinations.resize(combinations.size() + 1); return combinations.last(); @@ -1715,7 +1697,7 @@ public: void createTestRows() { - for (int i = 0; i < combinations.count(); ++i) { + for (int i = 0; i < combinations.size(); ++i) { QTest::newRow((name.toLatin1() + ", row " + QByteArray::number(i)).constData()) << (i == 0) << (type == Equality) << combinations.at(i); ++nRows_; @@ -1728,7 +1710,7 @@ private: QString name; Type type; int nRows_; - QList<QList<QSharedPointer<Operation>>> combinations; + QList<QList<std::shared_ptr<Operation>>> combinations; }; class IntroPage : public QWizardPage @@ -1805,16 +1787,16 @@ public: ~TestWizard() { - foreach (int id, pageIds) { + for (int id : std::as_const(pageIds)) { QWizardPage *page_to_delete = page(id); removePage(id); delete page_to_delete; } } - void applyOperations(const QList<QSharedPointer<Operation>> &operations) + void applyOperations(const QList<std::shared_ptr<Operation>> &operations) { - foreach (const QSharedPointer<Operation> &op, operations) { + for (const std::shared_ptr<Operation> &op : operations) { if (op) { op->apply(this); opsDescr += QLatin1Char('(') + op->describe() + QLatin1String(") "); @@ -1834,25 +1816,31 @@ public: class CombinationsTestData { TestGroup testGroup; - QList<QSharedPointer<Operation>> pageOps; - QList<QSharedPointer<Operation>> styleOps; - QMap<bool, QList<QSharedPointer<Operation>>> setAllOptions; + const std::shared_ptr<Operation> pageOps[3] = { + SetPage::create(0), + SetPage::create(1), + SetPage::create(2), + }; + const std::shared_ptr<Operation> styleOps[3] = { + SetStyle::create(QWizard::ClassicStyle), + SetStyle::create(QWizard::ModernStyle), + SetStyle::create(QWizard::MacStyle), + }; + QMap<bool, QList<std::shared_ptr<Operation>>> setAllOptions; public: CombinationsTestData() { QTest::addColumn<bool>("ref"); QTest::addColumn<bool>("testEquality"); - QTest::addColumn<QList<QSharedPointer<Operation>>>("operations"); - pageOps << SetPage::create(0) << SetPage::create(1) << SetPage::create(2); - styleOps << SetStyle::create(QWizard::ClassicStyle) << SetStyle::create(QWizard::ModernStyle) - << SetStyle::create(QWizard::MacStyle); -#define SETPAGE(page) pageOps.at(page) -#define SETSTYLE(style) styleOps.at(style) + QTest::addColumn<QList<std::shared_ptr<Operation>>>("operations"); +#define SETPAGE(page) pageOps[page] +#define SETSTYLE(style) styleOps[style] #define OPT(option, on) OptionInfo::instance().operation(option, on) #define CLROPT(option) OPT(option, false) #define SETOPT(option) OPT(option, true) - foreach (QWizard::WizardOption option, OptionInfo::instance().options()) { + const auto options = OptionInfo::instance().options(); + for (QWizard::WizardOption option : options) { setAllOptions[false] << CLROPT(option); setAllOptions[true] << SETOPT(option); } @@ -1909,7 +1897,7 @@ public: testGroup.createTestRows(); for (int i = 0; i < 2; ++i) { - QList<QSharedPointer<Operation>> setOptions = setAllOptions.value(i == 1); + QList<std::shared_ptr<Operation>> setOptions = setAllOptions.value(i == 1); testGroup.reset("testAll 3.1"); testGroup.add() << setOptions; @@ -1926,21 +1914,22 @@ public: testGroup.createTestRows(); } - foreach (const QSharedPointer<Operation> &pageOp, pageOps) { + for (const std::shared_ptr<Operation> &pageOp : pageOps) { testGroup.reset("testAll 4.1"); testGroup.add() << pageOp; testGroup.add() << pageOp << pageOp; testGroup.createTestRows(); for (int i = 0; i < 2; ++i) { - QList<QSharedPointer<Operation>> optionOps = setAllOptions.value(i == 1); + QList<std::shared_ptr<Operation>> optionOps = setAllOptions.value(i == 1); testGroup.reset("testAll 4.2"); testGroup.add() << optionOps << pageOp; testGroup.add() << pageOp << optionOps; testGroup.createTestRows(); - foreach (QWizard::WizardOption option, OptionInfo::instance().options()) { - QSharedPointer<Operation> optionOp = OPT(option, i == 1); + const auto options = OptionInfo::instance().options(); + for (QWizard::WizardOption option : options) { + std::shared_ptr<Operation> optionOp = OPT(option, i == 1); testGroup.reset("testAll 4.3"); testGroup.add() << optionOp << pageOp; testGroup.add() << pageOp << optionOp; @@ -1949,21 +1938,22 @@ public: } } - foreach (const QSharedPointer<Operation> &styleOp, styleOps) { + for (const std::shared_ptr<Operation> &styleOp : styleOps) { testGroup.reset("testAll 5.1"); testGroup.add() << styleOp; testGroup.add() << styleOp << styleOp; testGroup.createTestRows(); for (int i = 0; i < 2; ++i) { - QList<QSharedPointer<Operation>> optionOps = setAllOptions.value(i == 1); + QList<std::shared_ptr<Operation>> optionOps = setAllOptions.value(i == 1); testGroup.reset("testAll 5.2"); testGroup.add() << optionOps << styleOp; testGroup.add() << styleOp << optionOps; testGroup.createTestRows(); - foreach (QWizard::WizardOption option, OptionInfo::instance().options()) { - QSharedPointer<Operation> optionOp = OPT(option, i == 1); + const auto options = OptionInfo::instance().options(); + for (QWizard::WizardOption option : options) { + std::shared_ptr<Operation> optionOp = OPT(option, i == 1); testGroup.reset("testAll 5.3"); testGroup.add() << optionOp << styleOp; testGroup.add() << styleOp << optionOp; @@ -1972,8 +1962,8 @@ public: } } - foreach (const QSharedPointer<Operation> &pageOp, pageOps) { - foreach (const QSharedPointer<Operation> &styleOp, styleOps) { + for (const std::shared_ptr<Operation> &pageOp : pageOps) { + for (const std::shared_ptr<Operation> &styleOp : styleOps) { testGroup.reset("testAll 6.1"); testGroup.add() << pageOp; @@ -1991,7 +1981,7 @@ public: testGroup.createTestRows(); for (int i = 0; i < 2; ++i) { - QList<QSharedPointer<Operation>> optionOps = setAllOptions.value(i == 1); + QList<std::shared_ptr<Operation>> optionOps = setAllOptions.value(i == 1); testGroup.reset("testAll 6.4"); testGroup.add() << optionOps << pageOp << styleOp; testGroup.add() << pageOp << optionOps << styleOp; @@ -2001,8 +1991,9 @@ public: testGroup.add() << styleOp << pageOp << optionOps; testGroup.createTestRows(); - foreach (QWizard::WizardOption option, OptionInfo::instance().options()) { - QSharedPointer<Operation> optionOp = OPT(option, i == 1); + const auto options = OptionInfo::instance().options(); + for (QWizard::WizardOption option : options) { + std::shared_ptr<Operation> optionOp = OPT(option, i == 1); testGroup.reset("testAll 6.5"); testGroup.add() << optionOp << pageOp << styleOp; testGroup.add() << pageOp << optionOp << styleOp; @@ -2064,7 +2055,7 @@ void tst_QWizard::combinations() { QFETCH(bool, ref); QFETCH(bool, testEquality); - QFETCH(QList<QSharedPointer<Operation>>, operations); + QFETCH(const QList<std::shared_ptr<Operation>>, operations); TestWizard wizard; #if !defined(QT_NO_STYLE_WINDOWSVISTA) @@ -2133,7 +2124,7 @@ public: QList<WizardPage *> shown() const { QList<WizardPage *> result; - foreach (WizardPage *page, pages) + for (WizardPage *page : pages) if (page->shown()) result << page; return result; @@ -2151,19 +2142,19 @@ void tst_QWizard::showCurrentPageOnly() wizard.show(); - QCOMPARE(pages.shown().count(), 1); + QCOMPARE(pages.shown().size(), 1); QCOMPARE(pages.shown().first(), pages.all().first()); const int steps = 2; for (int i = 0; i < steps; ++i) wizard.next(); - QCOMPARE(pages.shown().count(), 1); + QCOMPARE(pages.shown().size(), 1); QCOMPARE(pages.shown().first(), pages.all().at(steps)); wizard.restart(); - QCOMPARE(pages.shown().count(), 1); + QCOMPARE(pages.shown().size(), 1); QCOMPARE(pages.shown().first(), pages.all().first()); } @@ -2295,36 +2286,36 @@ void tst_QWizard::removePage() wizard.restart(); QCOMPARE(wizard.pageIds().size(), 4); QCOMPARE(wizard.visitedIds().size(), 1); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); // Removing a non-existent page wizard.removePage(4); QCOMPARE(wizard.pageIds().size(), 4); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); // Removing and then reinserting a page QCOMPARE(wizard.pageIds().size(), 4); QVERIFY(wizard.pageIds().contains(2)); wizard.removePage(2); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QList<QVariant> arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 2); QCOMPARE(wizard.pageIds().size(), 3); QVERIFY(!wizard.pageIds().contains(2)); wizard.setPage(2, page2); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); QCOMPARE(wizard.pageIds().size(), 4); QVERIFY(wizard.pageIds().contains(2)); // Removing the same page twice wizard.removePage(2); // restore - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 2); QCOMPARE(wizard.pageIds().size(), 3); QVERIFY(!wizard.pageIds().contains(2)); wizard.removePage(2); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); QCOMPARE(wizard.pageIds().size(), 3); QVERIFY(!wizard.pageIds().contains(2)); @@ -2334,9 +2325,9 @@ void tst_QWizard::removePage() wizard.next(); QCOMPARE(wizard.visitedIds().size(), 2); QCOMPARE(wizard.currentPage(), page1); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); wizard.removePage(2); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 2); QCOMPARE(wizard.visitedIds().size(), 2); @@ -2347,11 +2338,11 @@ void tst_QWizard::removePage() wizard.setPage(2, page2); // restore wizard.restart(); wizard.next(); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); QCOMPARE(wizard.visitedIds().size(), 2); QCOMPARE(wizard.currentPage(), page1); wizard.removePage(0); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 0); QCOMPARE(wizard.visitedIds().size(), 1); @@ -2363,11 +2354,11 @@ void tst_QWizard::removePage() wizard.setPage(0, page0); // restore wizard.restart(); wizard.next(); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); QCOMPARE(wizard.visitedIds().size(), 2); QCOMPARE(wizard.currentPage(), page1); wizard.removePage(1); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 1); QCOMPARE(wizard.visitedIds().size(), 1); @@ -2377,7 +2368,7 @@ void tst_QWizard::removePage() // Remove the current page which is the first (and only) one in the history wizard.removePage(0); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 0); QCOMPARE(wizard.visitedIds().size(), 1); @@ -2387,7 +2378,7 @@ void tst_QWizard::removePage() QCOMPARE(wizard.currentPage(), page2); // wizard.removePage(2); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 2); QCOMPARE(wizard.visitedIds().size(), 1); @@ -2397,7 +2388,7 @@ void tst_QWizard::removePage() QCOMPARE(wizard.currentPage(), page3); // wizard.removePage(3); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).toInt(), 3); QVERIFY(wizard.visitedIds().empty()); @@ -2585,7 +2576,8 @@ void tst_QWizard::task161658_alignments() wizard.show(); QVERIFY(QTest::qWaitForWindowExposed(&wizard)); - foreach (QLabel *subtitleLabel, wizard.findChildren<QLabel *>()) { + const auto subtitleLabels = wizard.findChildren<QLabel *>(); + for (QLabel *subtitleLabel : subtitleLabels) { if (subtitleLabel->text().startsWith("SUBTITLE#")) { QCOMPARE(lineEdit1.mapToGlobal(lineEdit1.contentsRect().bottomRight()).x(), subtitleLabel->mapToGlobal(subtitleLabel->contentsRect().bottomRight()).x()); @@ -2718,6 +2710,45 @@ void tst_QWizard::taskQTBUG_46894_nextButtonShortcut() } } +/* setCurrentId(int) method was added in QTBUG99488 */ +void tst_QWizard::changePages() +{ + QWizard wizard; + + QList<QWizardPage*> pages; + for (int i = 0; i < 4; ++i) { + QWizardPage *page = new QWizardPage; + wizard.addPage(page); + pages.append(page); + } + + wizard.show(); + QVERIFY(QTest::qWaitForWindowExposed(&wizard)); + + // Verify default page + QCOMPARE(wizard.currentPage(), pages.at(0)); + + wizard.next(); + QVERIFY(wizard.currentId() == 1); + wizard.back(); + QVERIFY(wizard.currentId() == 0); + + // Test illegal page + QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QWizard::setCurrentId: No such page: 5"); + wizard.setCurrentId(5); + QCOMPARE(wizard.currentId(), 0); + + for (int i = 0; i < 4; ++i) { + wizard.setCurrentId(i); + QCOMPARE(wizard.currentPage(), pages.at(i)); + } + + for (int i = 3; i >= 0; --i) { + wizard.setCurrentId(i); + QCOMPARE(wizard.currentPage(), pages.at(i)); + } +} + #endif // QT_CONFIG(shortcut) QTEST_MAIN(tst_QWizard) diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard_2.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard_2.cpp index e090c0d851..8eef99ff38 100644 --- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard_2.cpp +++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard_2.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QComboBox> @@ -35,7 +10,7 @@ #include <QWizard> #include <QWizardPage> -#include <QtTest/QtTest> +#include <QTest> class taskQTBUG_25691 : public QWizard { |