diff options
Diffstat (limited to 'tests/auto/corelib/kernel/qcoreapplication')
3 files changed, 129 insertions, 26 deletions
diff --git a/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt b/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt index d51f857a4a..8f9783088c 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt @@ -1,7 +1,11 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -# Generated from qcoreapplication.pro. +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qcoreapplication LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() if(NOT QT_FEATURE_private_tests) return() @@ -11,43 +15,25 @@ endif() ## tst_qcoreapplication Test: ##################################################################### -# special case begin if (WIN32) set(target_version "1.2.3.4") else() set(target_version "1.2.3") endif() -# special case end qt_internal_add_test(tst_qcoreapplication - VERSION ${target_version} # special case + VERSION ${target_version} SOURCES tst_qcoreapplication.cpp tst_qcoreapplication.h LIBRARIES Qt::CorePrivate ) -# special case begin if (APPLE) set_property(TARGET tst_qcoreapplication PROPERTY MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist") set_property(TARGET tst_qcoreapplication PROPERTY PROPERTY MACOSX_BUNDLE TRUE) endif() -# special case end if (ANDROID) set_property(TARGET tst_qcoreapplication PROPERTY QT_ANDROID_VERSION_NAME ${target_version}) endif() - - -#### Keys ignored in scope 1:.:.:qcoreapplication.pro:<TRUE>: -# QMAKE_INFO_PLIST = "$$PWD/Info.plist" -# _REQUIREMENTS = "qtConfig(private_tests)" - -## Scopes: -##################################################################### - -#### Keys ignored in scope 2:.:.:qcoreapplication.pro:WIN32: -# VERSION = "1.2.3.4" - -#### Keys ignored in scope 3:.:.:qcoreapplication.pro:else: -# VERSION = "1.2.3" diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 46d52c2340..8f8ab33e64 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "tst_qcoreapplication.h" @@ -9,6 +9,7 @@ #include <private/qabstracteventdispatcher_p.h> // for qGlobalPostedEventsCount() #include <private/qcoreapplication_p.h> +#include <private/qcoreevent_p.h> #include <private/qeventloop_p.h> #include <private/qthread_p.h> @@ -24,9 +25,12 @@ class EventSpy : public QObject public: QList<int> recordedEvents; - bool eventFilter(QObject *, QEvent *event) override + std::function<void(QObject *, QEvent *)> eventCallback; + bool eventFilter(QObject *target, QEvent *event) override { recordedEvents.append(event->type()); + if (eventCallback) + eventCallback(target, event); return false; } }; @@ -1034,19 +1038,127 @@ void tst_QCoreApplication::addRemoveLibPaths() } #endif +static bool theMainThreadIsSet() +{ + // QCoreApplicationPrivate::mainThread() has a Q_ASSERT we'd trigger + return QCoreApplicationPrivate::theMainThreadId.loadRelaxed() != nullptr; +} + +static bool theMainThreadWasUnset = !theMainThreadIsSet(); // global static +void tst_QCoreApplication::theMainThread() +{ + QVERIFY2(theMainThreadWasUnset, "Something set the theMainThread before main()"); + QVERIFY(theMainThreadIsSet()); // we have at LEAST one QObject alive: tst_QCoreApplication + + int argc = 1; + char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; + TestApplication app(argc, argv); + QVERIFY(QCoreApplicationPrivate::theMainThreadId.loadRelaxed()); + QVERIFY(QThread::isMainThread()); + QCOMPARE(app.thread(), thread()); + QCOMPARE(app.thread(), QThread::currentThread()); +} + static void createQObjectOnDestruction() { - // Make sure that we can create a QObject after the last QObject has been - // destroyed (especially after QCoreApplication has). - // + // Make sure that we can create a QObject (and thus have an associated + // QThread) after the last QObject has been destroyed (especially after + // QCoreApplication has). + +#if !defined(QT_QGUIAPPLICATIONTEST) && !defined(Q_OS_WIN) + // QCoreApplicationData's global static destructor has run and cleaned up + // the QAdoptedThread. + if (theMainThreadIsSet()) + qFatal("theMainThreadIsSet() returned true; some QObject must have leaked"); +#endif + // Before the fixes, this would cause a dangling pointer dereference. If // the problem comes back, it's possible that the following causes no // effect. QObject obj; obj.thread()->setProperty("testing", 1); + if (!theMainThreadIsSet()) + qFatal("theMainThreadIsSet() returned false"); + + // because we created a QObject after QCoreApplicationData was destroyed, + // the QAdoptedThread won't get cleaned up } Q_DESTRUCTOR_FUNCTION(createQObjectOnDestruction) +void tst_QCoreApplication::testDeleteLaterFromBeforeOutermostEventLoop() +{ + int argc = 0; + QCoreApplication app(argc, nullptr); + + EventSpy *spy = new EventSpy(); + QPointer<QObject> spyPointer = spy; + + app.installEventFilter(spy); + spy->eventCallback = [spy](QObject *, QEvent *event) { + if (event->type() == QEvent::User + 1) + spy->deleteLater(); + }; + + QCoreApplication::postEvent(&app, new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + QEventLoop loop; + QTimer::singleShot(0, &loop, &QEventLoop::quit); + loop.exec(); + QVERIFY(!spyPointer); +} + +void tst_QCoreApplication::setIndividualAttributes_data() +{ + QTest::addColumn<Qt::ApplicationAttribute>("attribute"); + + const QMetaEnum &metaEnum = Qt::staticMetaObject.enumerator(Qt::staticMetaObject.indexOfEnumerator("ApplicationAttribute")); + // - 1 to avoid AA_AttributeCount. + for (int i = 0; i < metaEnum.keyCount(); ++i) { + const auto attribute = static_cast<Qt::ApplicationAttribute>(metaEnum.value(i)); + if (attribute == Qt::AA_AttributeCount) + continue; + + QTest::addRow("%s", metaEnum.key(i)) << attribute; + } +} + +void tst_QCoreApplication::setIndividualAttributes() +{ + QFETCH(Qt::ApplicationAttribute, attribute); + + const auto originalValue = QCoreApplication::testAttribute(attribute); + auto cleanup = qScopeGuard([=]() { + QCoreApplication::setAttribute(attribute, originalValue); + }); + + QCoreApplication::setAttribute(attribute, true); + QVERIFY(QCoreApplication::testAttribute(attribute)); + + QCoreApplication::setAttribute(attribute, false); + QVERIFY(!QCoreApplication::testAttribute(attribute)); +} + +void tst_QCoreApplication::setMultipleAttributes() +{ + const auto originalDontUseNativeMenuWindowsValue = QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows); + const auto originalDisableSessionManagerValue = QCoreApplication::testAttribute(Qt::AA_DisableSessionManager); + auto cleanup = qScopeGuard([=]() { + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, originalDontUseNativeMenuWindowsValue); + QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, originalDisableSessionManagerValue); + }); + + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, true); + QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, true); + QVERIFY(QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows)); + QVERIFY(QCoreApplication::testAttribute(Qt::AA_DisableSessionManager)); + + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, false); + QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, false); + QVERIFY(!QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows)); + QVERIFY(!QCoreApplication::testAttribute(Qt::AA_DisableSessionManager)); +} + #ifndef QT_QGUIAPPLICATIONTEST QTEST_APPLESS_MAIN(tst_QCoreApplication) #endif diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h index 0894b64f33..1c25f63534 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -1,6 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef TST_QCOREAPPLICATION_H #define TST_QCOREAPPLICATION_H @@ -44,6 +44,11 @@ private slots: #if QT_CONFIG(library) void addRemoveLibPaths(); #endif + void theMainThread(); + void testDeleteLaterFromBeforeOutermostEventLoop(); + void setIndividualAttributes_data(); + void setIndividualAttributes(); + void setMultipleAttributes(); }; #endif // TST_QCOREAPPLICATION_H |