diff options
Diffstat (limited to 'tests/auto/corelib/kernel/qcoreapplication')
3 files changed, 158 insertions, 101 deletions
diff --git a/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt b/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt index 24be474f90..8f9783088c 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt @@ -1,4 +1,11 @@ -# Generated from qcoreapplication.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +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() @@ -8,38 +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 - PUBLIC_LIBRARIES + 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 -#### 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" +if (ANDROID) + set_property(TARGET tst_qcoreapplication PROPERTY QT_ANDROID_VERSION_NAME ${target_version}) +endif() diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index fcfd3030d5..8f8ab33e64 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -1,38 +1,15 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** 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. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "tst_qcoreapplication.h" #include <QtCore/QtCore> #include <QTest> +#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> @@ -48,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; } }; @@ -123,7 +103,7 @@ void tst_QCoreApplication::getSetCheck() void tst_QCoreApplication::qAppName() { -#ifdef QT_GUI_LIB +#ifdef QT_QGUIAPPLICATIONTEST const char* appName = "tst_qguiapplication"; #else const char* appName = "tst_qcoreapplication"; @@ -199,7 +179,7 @@ void tst_QCoreApplication::argc() char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; TestApplication app(argc, argv); QCOMPARE(argc, 1); - QCOMPARE(app.arguments().count(), 1); + QCOMPARE(app.arguments().size(), 1); } { @@ -210,7 +190,7 @@ void tst_QCoreApplication::argc() const_cast<char*>("arg3") }; TestApplication app(argc, argv); QCOMPARE(argc, 4); - QCOMPARE(app.arguments().count(), 4); + QCOMPARE(app.arguments().size(), 4); } { @@ -218,7 +198,7 @@ void tst_QCoreApplication::argc() char **argv = 0; TestApplication app(argc, argv); QCOMPARE(argc, 0); - QCOMPARE(app.arguments().count(), 0); + QCOMPARE(app.arguments().size(), 0); } { @@ -227,7 +207,7 @@ void tst_QCoreApplication::argc() const_cast<char*>("-qmljsdebugger=port:3768,block") }; TestApplication app(argc, argv); QCOMPARE(argc, 1); - QCOMPARE(app.arguments().count(), 1); + QCOMPARE(app.arguments().size(), 1); } } @@ -538,16 +518,13 @@ void tst_QCoreApplication::applicationPid() QVERIFY(QCoreApplication::applicationPid() > 0); } -QT_BEGIN_NAMESPACE -Q_CORE_EXPORT uint qGlobalPostedEventsCount(); -QT_END_NAMESPACE - +#ifdef QT_BUILD_INTERNAL class GlobalPostedEventsCountObject : public QObject { Q_OBJECT public: - QList<int> globalPostedEventsCount; + QList<qsizetype> globalPostedEventsCount; bool event(QEvent *event) override { @@ -564,7 +541,7 @@ void tst_QCoreApplication::globalPostedEventsCount() TestApplication app(argc, argv); QCoreApplication::sendPostedEvents(); - QCOMPARE(qGlobalPostedEventsCount(), 0u); + QCOMPARE(qGlobalPostedEventsCount(), qsizetype(0)); GlobalPostedEventsCountObject x; QCoreApplication::postEvent(&x, new QEvent(QEvent::User)); @@ -572,19 +549,15 @@ void tst_QCoreApplication::globalPostedEventsCount() QCoreApplication::postEvent(&x, new QEvent(QEvent::User)); QCoreApplication::postEvent(&x, new QEvent(QEvent::User)); QCoreApplication::postEvent(&x, new QEvent(QEvent::User)); - QCOMPARE(qGlobalPostedEventsCount(), 5u); + QCOMPARE(qGlobalPostedEventsCount(), qsizetype(5)); QCoreApplication::sendPostedEvents(); - QCOMPARE(qGlobalPostedEventsCount(), 0u); - - QList<int> expected = QList<int>() - << 4 - << 3 - << 2 - << 1 - << 0; + QCOMPARE(qGlobalPostedEventsCount(), qsizetype(0)); + + const QList<qsizetype> expected = {4, 3, 2, 1, 0}; QCOMPARE(x.globalPostedEventsCount, expected); } +#endif // QT_BUILD_INTERNAL class ProcessEventsAlwaysSendsPostedEventsObject : public QObject { @@ -1052,7 +1025,7 @@ void tst_QCoreApplication::addRemoveLibPaths() TestApplication app(argc, argv); // If libraryPaths only contains currentDir, neither will be in libraryPaths now. - if (paths.length() != 1 && currentDir != paths[0]) { + if (paths.size() != 1 && currentDir != paths[0]) { // Check that modifications stay alive across the creation of an application. QVERIFY(QCoreApplication::libraryPaths().contains(currentDir)); QVERIFY(!QCoreApplication::libraryPaths().contains(paths[0])); @@ -1065,20 +1038,128 @@ 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) -#ifndef QT_GUI_LIB +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 655a879afa..1c25f63534 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -1,31 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** 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. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef TST_QCOREAPPLICATION_H #define TST_QCOREAPPLICATION_H @@ -47,7 +22,9 @@ private slots: void deliverInDefinedOrder(); #endif void applicationPid(); +#ifdef QT_BUILD_INTERNAL void globalPostedEventsCount(); +#endif void processEventsAlwaysSendsPostedEvents(); #ifdef Q_OS_WIN void sendPostedEventsInNativeLoop(); @@ -67,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 |