diff options
Diffstat (limited to 'tests/auto/integration/multiapp')
-rw-r--r-- | tests/auto/integration/multiapp/CMakeLists.txt | 21 | ||||
-rw-r--r-- | tests/auto/integration/multiapp/double-drop.wav | bin | 0 -> 20626 bytes | |||
-rw-r--r-- | tests/auto/integration/multiapp/tst_multiapp.cpp | 161 |
3 files changed, 182 insertions, 0 deletions
diff --git a/tests/auto/integration/multiapp/CMakeLists.txt b/tests/auto/integration/multiapp/CMakeLists.txt new file mode 100644 index 000000000..8a297cafc --- /dev/null +++ b/tests/auto/integration/multiapp/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_multiapp + SOURCES + tst_multiapp.cpp + LIBRARIES + Qt::Core + Qt::MultimediaPrivate +) + +set(resources_resource_files + "double-drop.wav" +) + +qt_add_resources(tst_multiapp "resources" + PREFIX + "/" + FILES + ${resources_resource_files} +) diff --git a/tests/auto/integration/multiapp/double-drop.wav b/tests/auto/integration/multiapp/double-drop.wav Binary files differnew file mode 100644 index 000000000..bd9a507c7 --- /dev/null +++ b/tests/auto/integration/multiapp/double-drop.wav diff --git a/tests/auto/integration/multiapp/tst_multiapp.cpp b/tests/auto/integration/multiapp/tst_multiapp.cpp new file mode 100644 index 000000000..793a56e9d --- /dev/null +++ b/tests/auto/integration/multiapp/tst_multiapp.cpp @@ -0,0 +1,161 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QtTest/QtTest> +#include <QtCore/qdebug.h> +#include <QtCore/qprocess.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qstring.h> +#include <QtCore/qmetaobject.h> +#include <QtMultimedia/qsoundeffect.h> +#include <QtMultimedia/qmediadevices.h> +#include <QtMultimedia/qaudiodevice.h> + +using namespace Qt::StringLiterals; + +QT_USE_NAMESPACE + +namespace { +bool executeTestOutOfProcess(const QString &testName); +void playSound(); +} // namespace + +class tst_multiapp : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase() + { +#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) + QSKIP("Out-of-process testing does not behave correctly on mobile OS"); +#endif + } + +private slots: + void mediaDevices_doesNotCrash_whenRecreatingApplication() + { + QVERIFY(executeTestOutOfProcess( + "mediaDevices_doesNotCrash_whenRecreatingApplication_impl"_L1)); + } + + bool mediaDevices_doesNotCrash_whenRecreatingApplication_impl(int argc, char ** argv) + { + { + QCoreApplication app{ argc, argv }; + QMediaDevices::defaultAudioOutput(); + } + { + QCoreApplication app{ argc, argv }; + QMediaDevices::defaultAudioOutput(); + } + + return true; + } + + void soundEffect_doesNotCrash_whenRecreatingApplication() + { + QVERIFY(executeTestOutOfProcess( + "soundEffect_doesNotCrash_whenRecreatingApplication_impl"_L1)); + } + + bool soundEffect_doesNotCrash_whenRecreatingApplication_impl(int argc, char **argv) + { + Q_ASSERT(!qApp); + + // Play a sound twice under two different application objects + // This verifies that QSoundEffect works in use cases where + // client application recreates Qt application instances, + // for example when the client application loads plugins + // implemented using Qt. + { + QCoreApplication app{ argc, argv }; + playSound(); + } + { + QCoreApplication app{ argc, argv }; + playSound(); + } + + return true; + } + +}; + +namespace { + +void playSound() +{ + const QUrl url{ "qrc:double-drop.wav"_L1 }; + + QSoundEffect effect; + effect.setSource(url); + effect.play(); + + QObject::connect(&effect, &QSoundEffect::playingChanged, qApp, [&]() { + if (!effect.isPlaying()) + qApp->quit(); + }); + + // In some CI configurations, we do not have any audio devices. We must therefore + // close the qApp on error signal instead of on playingChanged. + QObject::connect(&effect, &QSoundEffect::statusChanged, qApp, [&]() { + if (effect.status() == QSoundEffect::Status::Error) { + qDebug() << "Failed to play sound effect"; + qApp->quit(); + } + }); + + qApp->exec(); +} + +bool executeTestOutOfProcess(const QString &testName) +{ + const QStringList args{ "--run-test"_L1, testName }; + const QString processName = QCoreApplication::applicationFilePath(); + const int status = QProcess::execute(processName, args); + return status == 0; +} + +} // namespace + +// This main function executes tests like normal qTest, and adds support +// for executing specific test functions when called out of process. In this +// case we don't create a QApplication, because the intent is to test how features +// behave when no QApplication exists. +int main(int argc, char *argv[]) +{ + QCommandLineParser cmd; + const QCommandLineOption runTest{ QStringList{ "run-test" }, "Executes a named test", + "runTest" }; + cmd.addOption(runTest); + cmd.parse({ argv, argv + argc }); + + if (cmd.isSet(runTest)) { + // We are requested to run a test case in a separate process without a Qt application + const QString testName = cmd.value(runTest); + + bool returnValue = false; + tst_multiapp tc; + + // Call the requested function on the test class + const bool invokeResult = + QMetaObject::invokeMethod(&tc, testName.toLatin1(), Qt::DirectConnection, + qReturnArg(returnValue), argc, argv); + + return (invokeResult && returnValue) ? 0 : 1; + } + + // If no special arguments are set, enter the regular QTest main routine + // The below lines are the same that QTEST_GUILESS_MAIN would stamp out, + // except the `int main(...)` + TESTLIB_SELFCOVERAGE_START("tst_multiapp") + QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<tst_multiapp>(); + QCoreApplication app(argc, argv); + app.setAttribute(Qt::AA_Use96Dpi, true); + tst_multiapp tc; + QTEST_SET_MAIN_SOURCE_PATH + return QTest::qExec(&tc, argc, argv); +} + +#include "tst_multiapp.moc" |