summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/cmake/CMakeLists.txt104
-rw-r--r--tests/auto/cmake/test_android_signing/CMakeLists.txt53
-rw-r--r--tests/auto/cmake/test_android_signing/main.cpp4
-rw-r--r--tests/auto/cmake/test_android_signing/verify_signature.cmake25
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp5
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp32
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp29
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp49
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp4
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp28
-rw-r--r--tests/auto/corelib/platform/CMakeLists.txt4
-rw-r--r--tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle2
-rw-r--r--tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp76
-rw-r--r--tests/auto/corelib/text/qlocale/tst_qlocale.cpp22
-rw-r--r--tests/auto/corelib/text/qstring/tst_qstring.cpp24
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp12
-rw-r--r--tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp89
-rw-r--r--tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp5
-rw-r--r--tests/auto/dbus/qdbusconnection/CMakeLists.txt12
-rw-r--r--tests/auto/dbus/qdbusconnection/qdbusdelayeddeliveryreenablehelper.cpp56
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp30
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h2
-rw-r--r--tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp36
-rw-r--r--tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp3
-rw-r--r--tests/auto/gui/kernel/qwindow/BLACKLIST1
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp8
-rw-r--r--tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp23
-rw-r--r--tests/auto/gui/qopengl/tst_qopengl.cpp3
-rw-r--r--tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp3
-rw-r--r--tests/auto/gui/text/qfont/BLACKLIST3
-rw-r--r--tests/auto/network/kernel/qnetworkinterface/BLACKLIST5
-rw-r--r--tests/auto/other/android/CMakeLists.txt8
-rw-r--r--tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp10
-rw-r--r--tests/auto/other/android/dynamic_feature/CMakeLists.txt33
-rw-r--r--tests/auto/other/android/dynamic_feature/feature/CMakeLists.txt8
-rw-r--r--tests/auto/other/android/dynamic_feature/feature/qtlogo.pngbin0 -> 1214 bytes
-rw-r--r--tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoader.java175
-rw-r--r--tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoaderListener.java92
-rw-r--r--tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoaderListenerCallback.java26
-rw-r--r--tests/auto/other/android/dynamic_feature/storeloader/storeloader.cpp227
-rw-r--r--tests/auto/other/android/dynamic_feature/storeloader/storeloader.h65
-rw-r--r--tests/auto/other/android/dynamic_feature/tst_android_dynamic_feature.cpp37
-rw-r--r--tests/auto/other/android/package_source_dir/CMakeLists.txt54
-rw-r--r--tests/auto/other/android/package_source_dir/custom_android_manifest/AndroidManifest.xml51
-rw-r--r--tests/auto/other/android/package_source_dir/custom_android_manifest_bundle/app/AndroidManifest.xml51
-rw-r--r--tests/auto/other/android/package_source_dir/partial_template/app/AndroidManifest.xml51
-rw-r--r--tests/auto/other/android/package_source_dir/partial_template/app/build.gradle.in54
-rw-r--r--tests/auto/other/android/package_source_dir/tst_android_package_source_dir.cpp47
-rw-r--r--tests/auto/other/android/permissions/CMakeLists.txt23
-rw-r--r--tests/auto/other/android/permissions/tst_android_permissions.cpp80
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp14
-rw-r--r--tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp61
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.junitxml14
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.lightxml26
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.tap30
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.teamcity10
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.txt10
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.xml26
-rw-r--r--tests/auto/testlib/selftests/expected_threewaycompare.junitxml36
-rw-r--r--tests/auto/testlib/selftests/expected_threewaycompare.lightxml36
-rw-r--r--tests/auto/testlib/selftests/expected_threewaycompare.tap36
-rw-r--r--tests/auto/testlib/selftests/expected_threewaycompare.teamcity18
-rw-r--r--tests/auto/testlib/selftests/expected_threewaycompare.txt36
-rw-r--r--tests/auto/testlib/selftests/expected_threewaycompare.xml36
-rw-r--r--tests/auto/testlib/selftests/mouse/tst_mouse.cpp4
-rw-r--r--tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp2
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp2
-rw-r--r--tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist1
-rw-r--r--tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro2
-rw-r--r--tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp4
-rw-r--r--tests/auto/tools/qmake/testdata/windows_resources/REUSE.toml2
-rw-r--r--tests/auto/tools/qmake/tst_qmake.cpp18
-rw-r--r--tests/auto/tools/uic/baseline/REUSE.toml2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp3
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp16
-rw-r--r--tests/auto/widgets/kernel/qapplication/BLACKLIST3
-rw-r--r--tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp224
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp34
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp35
-rw-r--r--tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp6
-rw-r--r--tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp2
-rw-r--r--tests/benchmarks/corelib/CMakeLists.txt1
-rw-r--r--tests/benchmarks/corelib/platform/CMakeLists.txt6
-rw-r--r--tests/benchmarks/corelib/platform/androiditemmodel/CMakeLists.txt24
-rw-r--r--tests/benchmarks/corelib/platform/androiditemmodel/testdata/src/org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel.java56
-rw-r--r--tests/benchmarks/corelib/platform/androiditemmodel/tst_bench_androiditemmodel.cpp144
-rw-r--r--tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp2
88 files changed, 2451 insertions, 376 deletions
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
index 7c4f33cddb6..f4789d115a6 100644
--- a/tests/auto/cmake/CMakeLists.txt
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -70,7 +70,7 @@ enable_testing()
# doesn't seem to be the case.
# Until this is figured out, disable the tests when cross-compiling to Linux.
if(UNIX AND NOT APPLE AND NOT WIN32 AND CMAKE_CROSSCOMPILING AND NOT QT_ENABLE_CMAKE_BOOT2QT_TESTS
- AND NOT QT_BUILD_MINIMAL_ANDROID_MULTI_ABI_TESTS)
+ AND NOT QT_BUILD_MINIMAL_ANDROID_MULTI_ABI_TESTS AND NOT ANDROID)
message(STATUS "Running CMake tests is disabled when cross-compiling to Linux / Boot2Qt.")
return()
endif()
@@ -83,6 +83,12 @@ if(WIN32 AND CMAKE_CROSSCOMPILING)
return()
endif()
+if(TARGET Qt6::Core)
+ # Tests are built as part of the qtbase build tree.
+ # Setup paths so that the Qt packages are found, similar to examples.
+ qt_internal_set_up_build_dir_package_paths()
+endif()
+
set(required_packages Core Network Xml Sql Test TestInternalsPrivate)
set(optional_packages DBus Gui Widgets PrintSupport OpenGL Concurrent)
@@ -117,53 +123,73 @@ endif()
include("${_Qt6CTestMacros}")
-# Test only multi-abi specific functionality when QT_BUILD_MINIMAL_ANDROID_MULTI_ABI_TESTS is ON.
-# Qt::Gui is the prerequisite for all Android tests.
-if(QT_BUILD_MINIMAL_ANDROID_MULTI_ABI_TESTS AND NOT NO_GUI)
- unset(multi_abi_vars)
- foreach(abi IN LISTS QT_ANDROID_ABIS)
- list(APPEND multi_abi_vars "-DQT_PATH_ANDROID_ABI_${abi}=${QT_PATH_ANDROID_ABI_${abi}}")
- endforeach()
- if(QT_ANDROID_BUILD_ALL_ABIS)
- list(APPEND multi_abi_vars "-DQT_ANDROID_BUILD_ALL_ABIS=${QT_ANDROID_BUILD_ALL_ABIS}")
+
+if(ANDROID)
+ # Qt::Gui is the prerequisite for all Android tests.
+ if(NO_GUI)
+ return()
endif()
- list(APPEND multi_abi_vars "-DQT_HOST_PATH=${QT_HOST_PATH}")
+ set(common_android_vars "-DQT_HOST_PATH=${QT_HOST_PATH}")
- set(multi_abi_forward_vars
- TEST_SINGLE_VALUE_ARG
- TEST_SPACES_VALUE_ARG
- TEST_LIST_VALUE_ARG
- TEST_ESCAPING_VALUE_ARG
+ _qt_internal_test_expect_pass(test_android_signing
+ BUILD_OPTIONS "${common_android_vars}"
+ BINARY ${CMAKE_CTEST_COMMAND}
+ BINARY_ARGS -V
)
- string(REPLACE ";" "[[;]]" multi_abi_forward_vars "${multi_abi_forward_vars}")
-
- set(single_value "TestValue")
- set(list_value "TestValue[[;]]TestValue2[[;]]TestValue3")
- set(escaping_value "TestValue\\\\[[;]]TestValue2\\\\[[;]]TestValue3")
- set(spaces_value "TestValue TestValue2 TestValue3")
- _qt_internal_test_expect_pass(test_android_multi_abi_forward_vars
- BUILD_OPTIONS
- ${multi_abi_vars}
- "-DQT_ANDROID_MULTI_ABI_FORWARD_VARS=${multi_abi_forward_vars}"
- "-DTEST_SINGLE_VALUE_ARG=${single_value}"
- "-DTEST_LIST_VALUE_ARG=${list_value}"
- "-DTEST_ESCAPING_VALUE_ARG=${escaping_value}"
- "-DTEST_SPACES_VALUE_ARG=${spaces_value}"
+ set_property(TEST test_android_signing APPEND PROPERTY ENVIRONMENT
+ "QT_ANDROID_KEYSTORE_PATH=${CMAKE_CURRENT_BINARY_DIR}/test_android_signing/qttest.jks"
+ "QT_ANDROID_KEYSTORE_ALIAS=qttest"
+ "QT_ANDROID_KEYSTORE_STORE_PASS=qttest"
+ "QT_ANDROID_KEYSTORE_KEY_PASS=qttest"
)
- #Run test_android_aar only if the host is Unix and zipinfo is available
- find_program(ZIPINFO_EXECUTABLE zipinfo)
- if(CMAKE_HOST_UNIX AND ZIPINFO_EXECUTABLE)
- _qt_internal_test_expect_pass(test_android_aar
+ # Test only multi-abi specific functionality when QT_BUILD_MINIMAL_ANDROID_MULTI_ABI_TESTS is
+ # ON.
+ if(QT_BUILD_MINIMAL_ANDROID_MULTI_ABI_TESTS)
+ set(multi_abi_vars "${common_android_vars}")
+ foreach(abi IN LISTS QT_ANDROID_ABIS)
+ list(APPEND multi_abi_vars "-DQT_PATH_ANDROID_ABI_${abi}=${QT_PATH_ANDROID_ABI_${abi}}")
+ endforeach()
+ if(QT_ANDROID_BUILD_ALL_ABIS)
+ list(APPEND multi_abi_vars "-DQT_ANDROID_BUILD_ALL_ABIS=${QT_ANDROID_BUILD_ALL_ABIS}")
+ endif()
+
+ set(multi_abi_forward_vars
+ TEST_SINGLE_VALUE_ARG
+ TEST_SPACES_VALUE_ARG
+ TEST_LIST_VALUE_ARG
+ TEST_ESCAPING_VALUE_ARG
+ )
+ string(REPLACE ";" "[[;]]" multi_abi_forward_vars "${multi_abi_forward_vars}")
+
+ set(single_value "TestValue")
+ set(list_value "TestValue[[;]]TestValue2[[;]]TestValue3")
+ set(escaping_value "TestValue\\\\[[;]]TestValue2\\\\[[;]]TestValue3")
+ set(spaces_value "TestValue TestValue2 TestValue3")
+ _qt_internal_test_expect_pass(test_android_multi_abi_forward_vars
BUILD_OPTIONS
${multi_abi_vars}
- --build-target verify_aar
+ "-DQT_ANDROID_MULTI_ABI_FORWARD_VARS=${multi_abi_forward_vars}"
+ "-DTEST_SINGLE_VALUE_ARG=${single_value}"
+ "-DTEST_LIST_VALUE_ARG=${list_value}"
+ "-DTEST_ESCAPING_VALUE_ARG=${escaping_value}"
+ "-DTEST_SPACES_VALUE_ARG=${spaces_value}"
)
- else()
- message(WARNING
- "Skipping test_android_aar CMake build test because \
- the host is not Unix or zipinfo is not found")
+
+ #Run test_android_aar only if the host is Unix and zipinfo is available
+ find_program(ZIPINFO_EXECUTABLE zipinfo)
+ if(CMAKE_HOST_UNIX AND ZIPINFO_EXECUTABLE)
+ _qt_internal_test_expect_pass(test_android_aar
+ BUILD_OPTIONS
+ ${multi_abi_vars}
+ --build-target verify_aar
+ )
+ else()
+ message(WARNING
+ "Skipping test_android_aar CMake build test because \
+ the host is not Unix or zipinfo is not found")
+ endif()
endif()
return()
diff --git a/tests/auto/cmake/test_android_signing/CMakeLists.txt b/tests/auto/cmake/test_android_signing/CMakeLists.txt
new file mode 100644
index 00000000000..b2d67676a69
--- /dev/null
+++ b/tests/auto/cmake/test_android_signing/CMakeLists.txt
@@ -0,0 +1,53 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.20)
+
+project(test_android_signing)
+
+enable_testing()
+
+find_program(keytool NAMES keytool)
+
+if(NOT keytool)
+ message("Skipping test_android_signing: keytool not found.")
+ return()
+endif()
+
+if("$ENV{QT_ANDROID_KEYSTORE_PATH}" STREQUAL ""
+ OR "$ENV{QT_ANDROID_KEYSTORE_STORE_PASS}" STREQUAL ""
+ OR "$ENV{QT_ANDROID_KEYSTORE_ALIAS}" STREQUAL ""
+ OR "$ENV{QT_ANDROID_KEYSTORE_KEY_PASS}" STREQUAL "")
+ message(FATAL_ERROR "Environment variables QT_ANDROID_KEYSTORE_PATH,"
+ " QT_ANDROID_KEYSTORE_STORE_PASS, QT_ANDROID_KEYSTORE_ALIAS, and"
+ " QT_ANDROID_KEYSTORE_KEY_PASS must be set to run this test.")
+endif()
+
+find_package(Qt6 COMPONENTS Core Gui REQUIRED)
+
+set(QT_ANDROID_SIGN_AAB ON)
+set(QT_ANDROID_SIGN_APK ON)
+
+execute_process(COMMAND ${keytool}
+ -genkey -alias "$ENV{QT_ANDROID_KEYSTORE_ALIAS}" -keyalg RSA
+ -keystore "$ENV{QT_ANDROID_KEYSTORE_PATH}"
+ -noprompt
+ -dname "CN=qttest, OU=ID, O=Qt, L=Qt, S=Test, C=DE"
+ -storepass "$ENV{QT_ANDROID_KEYSTORE_STORE_PASS}"
+ -keypass "$ENV{QT_ANDROID_KEYSTORE_KEY_PASS}"
+ RESULT_VARIABLE keytool_result
+)
+
+
+qt6_add_executable(test_android_signing main.cpp)
+
+target_link_libraries(test_android_signing PRIVATE
+ Qt6::Core
+ Qt6::Gui
+)
+
+add_test(NAME test_android_signing_verify_signature
+ COMMAND "${CMAKE_COMMAND}" "-DKEYTOOL_PATH=${keytool}"
+ "-DAPK_FILE=${CMAKE_CURRENT_BINARY_DIR}/android-build/test_android_signing.apk"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/verify_signature.cmake"
+)
diff --git a/tests/auto/cmake/test_android_signing/main.cpp b/tests/auto/cmake/test_android_signing/main.cpp
new file mode 100644
index 00000000000..2112a0de739
--- /dev/null
+++ b/tests/auto/cmake/test_android_signing/main.cpp
@@ -0,0 +1,4 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+int main(int, char *[]) { return 0; }
diff --git a/tests/auto/cmake/test_android_signing/verify_signature.cmake b/tests/auto/cmake/test_android_signing/verify_signature.cmake
new file mode 100644
index 00000000000..d4405a30201
--- /dev/null
+++ b/tests/auto/cmake/test_android_signing/verify_signature.cmake
@@ -0,0 +1,25 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT KEYTOOL_PATH)
+ message(FATAL_ERROR "KEYTOOL_PATH is missing.")
+endif()
+
+if(NOT APK_FILE)
+ message(FATAL_ERROR "APK_FILE is missing.")
+endif()
+
+execute_process(
+ COMMAND ${KEYTOOL_PATH} -printcert -jarfile ${APK_FILE}
+ RESULT_VARIABLE keytool_result
+ OUTPUT_VARIABLE keytool_output
+ ERROR_VARIABLE keytool_error
+)
+
+if(NOT keytool_result EQUAL 0)
+ message(FATAL_ERROR "Keytool command failed with error: ${keytool_error}")
+endif()
+
+if(NOT keytool_output MATCHES ".+Certificate #1:.+")
+ message(FATAL_ERROR "APK is not signed.")
+endif()
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index 1e423f21bec..0ea2be1b147 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -430,7 +430,7 @@ void tst_QDir::mkdirRmdir()
void tst_QDir::mkdirOnSymlink()
{
-#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS) || defined(Q_OS_INTEGRITY) || defined(Q_OS_WASM)
+#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS) || defined(Q_OS_INTEGRITY)
QSKIP("Test only valid on an OS that supports symlinks");
#else
// Create the structure:
@@ -477,9 +477,6 @@ void tst_QDir::mkdirOnSymlink()
#if defined(Q_OS_QNX)
QSKIP("Fails on QNX QTBUG-98561");
#endif
-#if defined (Q_OS_WASM)
- QEXPECT_FAIL("", "fails on wasm, see bug: QTBUG-127766", Continue);
-#endif
QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
#endif
}
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 781f64a31ab..66c3db2e2f0 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -228,6 +228,7 @@ private slots:
void getCharFF();
void remove_and_exists();
void removeOpenFile();
+ void removedFileDoesntExist();
void fullDisk();
void writeLargeDataBlock_data();
void writeLargeDataBlock();
@@ -2526,6 +2527,37 @@ void tst_QFile::removeOpenFile()
}
}
+void tst_QFile::removedFileDoesntExist()
+{
+#ifdef Q_OS_WIN
+ QSKIP("Not relevant for Windows - can't remove still-open files");
+#endif
+ QFile::remove("remove_unclosed.txt");
+ QFile f("remove_unclosed.txt");
+ QVERIFY(!f.exists());
+ bool opened = f.open(QIODevice::ReadWrite | QIODevice::Unbuffered);
+ QVERIFY(opened);
+ f.write("blah blah blah");
+
+ QVERIFY(f.exists());
+
+ // delete by path, not using f.remove() (that's tested above)
+ QVERIFY(QFile::remove(f.fileName()));
+ QVERIFY(!QFile::exists(f.fileName()));
+ QVERIFY(!f.exists());
+
+#ifdef Q_OS_LINUX
+ QString procPath = u"/proc/self/fd/"_s;
+ if (QFile::exists(procPath)) {
+ // reopen the deleted file
+ procPath += QString::number(f.handle());
+ QFile f2(procPath);
+ QVERIFY(f2.open(QIODevice::ReadOnly));
+ QVERIFY(!f2.exists());
+ }
+#endif
+}
+
void tst_QFile::fullDisk()
{
QFile file("/dev/full");
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index 761f0552eec..e2190477441 100644
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -141,6 +141,7 @@ private slots:
void exists_data();
void exists();
+ void deletedFileLinuxProcExists();
void absolutePath_data();
void absolutePath();
@@ -615,6 +616,34 @@ void tst_QFileInfo::exists()
QVERIFY(!exists);
}
+void tst_QFileInfo::deletedFileLinuxProcExists()
+{
+#ifdef Q_OS_LINUX
+ static const char msg[] = "Hello, World\n";
+ QFileInfo fi("/proc/self/fd/");
+ if (!fi.isDir())
+ QSKIP("/proc appears not to be mounted");
+
+ QFile f("removed_file.txt");
+ QVERIFY(f.open(QIODevice::ReadWrite | QIODevice::Unbuffered));
+ f.write(msg, strlen(msg));
+
+ fi.setFile(fi.filePath() + QString::number(f.handle()));
+ QVERIFY(fi.exists());
+ QCOMPARE(fi.size(), strlen(msg));
+
+ QFile::remove("removed_file.txt");
+ fi.refresh();
+ QVERIFY(fi.exists());
+
+ fi.refresh();
+ QCOMPARE(fi.size(), strlen(msg)); // this stats, so may change flags
+ QVERIFY(fi.exists());
+#else
+ QSKIP("Linux-only test");
+#endif
+}
+
void tst_QFileInfo::absolutePath_data()
{
QTest::addColumn<QString>("file");
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
index e57cc732ee2..820a7b4bdb5 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -7,7 +7,6 @@
#include <qfile.h>
#include <qdatetime.h>
#include <qdir.h>
-#include <qset.h>
#include <qstandardpaths.h>
#include <qstring.h>
#include <qtemporarydir.h>
@@ -15,6 +14,9 @@
#include <QtTest/private/qtesthelpers_p.h>
+#include <QtCore/private/qduplicatetracker_p.h>
+#include <QtCore/qscopeguard.h>
+
#if defined(Q_OS_WIN)
# include <shlwapi.h>
# include <qt_windows.h>
@@ -549,18 +551,20 @@ void tst_QTemporaryFile::openOnRootDrives()
void tst_QTemporaryFile::stressTest()
{
- const int iterations = 1000;
+ constexpr int iterations = 1000;
+
+ QDuplicateTracker<QString, iterations> names;
+
+ const auto remover = qScopeGuard([&] {
+ for (const QString &s : std::as_const(names))
+ QFile::remove(s);
+ });
- QSet<QString> names;
for (int i = 0; i < iterations; ++i) {
QTemporaryFile file;
file.setAutoRemove(false);
QVERIFY2(file.open(), qPrintable(file.errorString()));
- QVERIFY(!names.contains(file.fileName()));
- names.insert(file.fileName());
- }
- for (QSet<QString>::const_iterator it = names.constBegin(); it != names.constEnd(); ++it) {
- QFile::remove(*it);
+ QVERIFY(!names.hasSeen(file.fileName()));
}
}
@@ -821,37 +825,26 @@ void tst_QTemporaryFile::autoRemoveAfterFailedRename()
#if defined(Q_OS_VXWORKS)
QSKIP("QTBUG-130066");
#endif
- struct CleanOnReturn
- {
- ~CleanOnReturn()
- {
+
+ QString tempName;
+ auto cleaner = qScopeGuard([&] {
if (!tempName.isEmpty())
QFile::remove(tempName);
- }
-
- void reset()
- {
- tempName.clear();
- }
-
- QString tempName;
- };
-
- CleanOnReturn cleaner;
+ });
{
QTemporaryFile file;
QVERIFY( file.open() );
- cleaner.tempName = file.fileName();
+ tempName = file.fileName();
- QVERIFY( QFile::exists(cleaner.tempName) );
+ QVERIFY(QFile::exists(tempName));
QVERIFY( !QFileInfo("i-do-not-exist").isDir() );
QVERIFY( !file.rename("i-do-not-exist/file.txt") );
- QVERIFY( QFile::exists(cleaner.tempName) );
+ QVERIFY(QFile::exists(tempName));
}
- QVERIFY( !QFile::exists(cleaner.tempName) );
- cleaner.reset();
+ QVERIFY(!QFile::exists(tempName));
+ cleaner.dismiss(); // would fail: file is known to no longer exist
}
void tst_QTemporaryFile::createNativeFile_data()
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index 282c7f2e360..71389abc976 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -513,6 +513,7 @@ void tst_QUrl::comparison2()
QCOMPARE(url1.toString(), url2.toString());
QCOMPARE(url1, url2);
QCOMPARE(qHash(url1), qHash(url2));
+ QCOMPARE(qHash(url1, 1), qHash(url2, 1));
} else if (ordering < 0) {
QCOMPARE_LT(url1.toString(), url2.toString());
QCOMPARE_NE(url1, url2);
@@ -1387,12 +1388,14 @@ void tst_QUrl::toString_constructed()
QUrl parsed(asString);
QCOMPARE(url, parsed);
QCOMPARE(qHash(url), qHash(parsed));
+ QCOMPARE(qHash(url, 1), qHash(parsed, 1));
}
// clear it and ensure no memory of the previous state remains
url.setUrl(QString());
QCOMPARE(url, QUrl());
QCOMPARE(qHash(url), qHash(QUrl()));
+ QCOMPARE(qHash(url, 1), qHash(QUrl(), 1));
}
void tst_QUrl::toDisplayString_PreferLocalFile_data()
@@ -4265,6 +4268,7 @@ void tst_QUrl::setComponents()
QUrl recreated(toString);
QCOMPARE(copy, recreated);
QCOMPARE(qHash(copy), qHash(recreated));
+ QCOMPARE(qHash(copy, 1), qHash(recreated, 1));
} else {
QVERIFY(copy.toString().isEmpty());
}
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
index b1e2e8164af..a5f23014b94 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
@@ -708,6 +708,24 @@ void tst_QMetaObjectBuilder::property()
prop2.setEnumOrFlag(false); \
prop2.setConstant(false); \
prop2.setFinal(false); \
+ prop2.setBindable(false); \
+ prop2.setRequired(false); \
+ } while (0)
+#define SET_ALL_FLAGS() \
+ do { \
+ prop2.setReadable(true); \
+ prop2.setWritable(true); \
+ prop2.setResettable(true); \
+ prop2.setDesignable(true); \
+ prop2.setScriptable(true); \
+ prop2.setStored(true); \
+ prop2.setUser(true); \
+ prop2.setStdCppSet(true); \
+ prop2.setEnumOrFlag(true); \
+ prop2.setConstant(true); \
+ prop2.setFinal(true); \
+ prop2.setBindable(true); \
+ prop2.setRequired(true); \
} while (0)
#define COUNT_FLAGS() \
((prop2.isReadable() ? 1 : 0) + \
@@ -720,15 +738,19 @@ void tst_QMetaObjectBuilder::property()
(prop2.hasStdCppSet() ? 1 : 0) + \
(prop2.isEnumOrFlag() ? 1 : 0) + \
(prop2.isConstant() ? 1 : 0) + \
- (prop2.isFinal() ? 1 : 0))
+ (prop2.isFinal() ? 1 : 0) + \
+ (prop2.isBindable() ? 1 : 0) + \
+ (prop2.isRequired() ? 1 : 0))
#define CHECK_FLAG(setFunc,isFunc) \
do { \
+ ++flagCounter; \
CLEAR_FLAGS(); \
QCOMPARE(COUNT_FLAGS(), 0); \
prop2.setFunc(true); \
QVERIFY(prop2.isFunc()); \
QCOMPARE(COUNT_FLAGS(), 1); \
} while (0)
+ int flagCounter = 0;
CHECK_FLAG(setReadable, isReadable);
CHECK_FLAG(setWritable, isWritable);
CHECK_FLAG(setResettable, isResettable);
@@ -739,7 +761,11 @@ void tst_QMetaObjectBuilder::property()
CHECK_FLAG(setStdCppSet, hasStdCppSet);
CHECK_FLAG(setEnumOrFlag, isEnumOrFlag);
CHECK_FLAG(setConstant, isConstant);
+ CHECK_FLAG(setBindable, isBindable);
CHECK_FLAG(setFinal, isFinal);
+ CHECK_FLAG(setRequired, isRequired);
+ SET_ALL_FLAGS();
+ QCOMPARE(COUNT_FLAGS(), flagCounter);
// Check that nothing else changed.
QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties));
diff --git a/tests/auto/corelib/platform/CMakeLists.txt b/tests/auto/corelib/platform/CMakeLists.txt
index 3a66ec2eae6..9810947e3c6 100644
--- a/tests/auto/corelib/platform/CMakeLists.txt
+++ b/tests/auto/corelib/platform/CMakeLists.txt
@@ -5,7 +5,9 @@ if(ANDROID)
add_subdirectory(android)
add_subdirectory(android_appless)
add_subdirectory(androiditemmodel)
- add_subdirectory(android_legacy_packaging)
+ if(NOT QT_USE_ANDROID_MODERN_BUNDLE)
+ add_subdirectory(android_legacy_packaging)
+ endif()
endif()
if(WIN32)
add_subdirectory(windows)
diff --git a/tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle b/tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle
index cbdd833e2ae..1d796d9b6b9 100644
--- a/tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle
+++ b/tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle
@@ -70,8 +70,8 @@ android {
abortOnError = false
}
- // Do not compress Qt binary resources file
aaptOptions {
+ // Do not compress Qt binary resources file
noCompress 'rcc'
}
diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
index 6dd8a6d07f9..65714036e2d 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -23,6 +23,8 @@
#include "../../../network-settings.h"
#include <QtTest/private/qemulationdetector_p.h>
+using namespace Qt::StringLiterals;
+
QT_BEGIN_NAMESPACE
template<> struct QMetaTypeId<QIODevice::OpenModeFlag>
{ enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
@@ -1379,17 +1381,14 @@ void tst_QTextStream::pos2()
// ------------------------------------------------------------------------------
void tst_QTextStream::pos3LargeFile()
{
- if (QTestPrivate::isRunningArmOnX86())
- QSKIP("Running QTextStream::pos() in tight loop is too slow on emulator");
-
+ // NOTE: The unusual spacing is to ensure non-1-character whitespace.
+ constexpr auto lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n"_L1;
{
QFile file(testFileName);
QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
QTextStream out( &file );
- // NOTE: The unusual spacing is to ensure non-1-character whitespace.
- QString lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n";
- // Approximate 50kb text file
- const int NbLines = (50*1024) / lineString.size() + 1;
+ // Approximately 5kb text file (more is too slow (QTBUG-138435))
+ const int NbLines = (5 * 1024) / lineString.size() + 1;
for (int line = 0; line < NbLines; ++line)
QVERIFY(out << lineString);
// File is automatically flushed and closed on destruction.
@@ -1397,11 +1396,18 @@ void tst_QTextStream::pos3LargeFile()
QFile file(testFileName);
QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream in( &file );
- const int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
- int value;
+ constexpr int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ qint64 expectedLineEnd = 0;
+#ifdef Q_OS_WIN // CRLF platform
+ constexpr int crlfAdjustment = 1;
+#else
+ constexpr int crlfAdjustment = 0;
+#endif
+ const auto expectedLineLength = lineString.size() + crlfAdjustment;
+ QCOMPARE(in.pos(), 0);
while (true) {
- in.pos();
- for ( int i = 0; i < 10; ++i ) {
+ for (size_t i = 0; i < std::size(testValues); ++i) {
+ int value = -42;
if (!(in >> value)) {
// End case, i == 0 && eof reached.
QCOMPARE(i, 0);
@@ -1410,6 +1416,9 @@ void tst_QTextStream::pos3LargeFile()
}
QCOMPARE(value, testValues[i]);
}
+ expectedLineEnd += expectedLineLength;
+ // Final space and newline are not consumed until next read.
+ QCOMPARE(in.pos(), expectedLineEnd - 2 - crlfAdjustment);
}
}
@@ -3000,14 +3009,41 @@ void tst_QTextStream::int_write_with_locale_data()
QTest::addColumn<int>("numberFlags");
QTest::addColumn<int>("input");
QTest::addColumn<QString>("output");
+ QTest::addColumn<int>("fieldWidth");
+ QTest::addColumn<QTextStream::FieldAlignment>("fieldAlignment");
+
+ const auto alignDefault = QTextStream().fieldAlignment();
+ constexpr int forceSign = QTextStream::ForceSign;
- QTest::newRow("C -123") << QString("C") << 0 << -123 << QString("-123");
- QTest::newRow("C +123") << QString("C") << (int)QTextStream::ForceSign << 123 << QString("+123");
- QTest::newRow("C 12345") << QString("C") << 0 << 12345 << QString("12345");
+ QTest::newRow("C -123") << u"C"_s << 0 << -123 << u"-123"_s << 0 << alignDefault;
+ QTest::newRow("C +123") << u"C"_s << forceSign << 123 << u"+123"_s << 0 << alignDefault;
+ QTest::newRow("C 12345") << u"C"_s << 0 << 12345 << u"12345"_s << 0 << alignDefault;
- QTest::newRow("de_DE -123") << QString("de_DE") << 0 << -123 << QString("-123");
- QTest::newRow("de_DE +123") << QString("de_DE") << (int)QTextStream::ForceSign << 123 << QString("+123");
- QTest::newRow("de_DE 12345") << QString("de_DE") << 0 << 12345 << QString("12.345");
+ QTest::newRow("de_DE -123") << u"de_DE"_s << 0 << -123 << u"-123"_s << 0 << alignDefault;
+ QTest::newRow("de_DE +123") << u"de_DE"_s << forceSign << 123 << u"+123"_s << 0 << alignDefault;
+ QTest::newRow("de_DE 12345") << u"de_DE"_s << 0 << 12345 << u"12.345"_s << 0 << alignDefault;
+
+ constexpr auto alignAccountingStyle = QTextStream::FieldAlignment::AlignAccountingStyle;
+
+ {
+ const QLocale loc("ar_EG"_L1);
+ // Arabic as spoken in Egypt has a two-code-point negativeSign():
+ const auto minus = loc.negativeSign();
+ QCOMPARE(minus.size(), 2);
+ // ditto positiveSign():
+ const auto plus = loc.positiveSign();
+ QCOMPARE(plus.size(), 2);
+
+ QTest::addRow("ar_EG -123") << u"ar_EG"_s << 0 << -123
+ << (minus + u" ١٢٣")
+ << 10 << alignAccountingStyle;
+ QTest::newRow("ar_EG +123") << u"ar_EG"_s << forceSign << 123
+ << (plus + u" ١٢٣")
+ << 10 << alignAccountingStyle;
+ QTest::newRow("ar_EG 12345") << u"ar_EG"_s << 0 << 12345
+ << u" ١٢٬٣٤٥"_s
+ << 10 << alignAccountingStyle;
+ }
}
void tst_QTextStream::int_write_with_locale()
@@ -3016,12 +3052,18 @@ void tst_QTextStream::int_write_with_locale()
QFETCH(int, numberFlags);
QFETCH(int, input);
QFETCH(QString, output);
+ QFETCH(const int, fieldWidth);
+ QFETCH(const QTextStream::FieldAlignment, fieldAlignment);
QString result;
QTextStream stream(&result);
stream.setLocale(QLocale(locale));
+ stream.setFieldAlignment(fieldAlignment);
if (numberFlags)
stream.setNumberFlags(QTextStream::NumberFlags(numberFlags));
+ if (fieldWidth)
+ stream.setFieldWidth(fieldWidth);
+
QVERIFY(stream << input);
QCOMPARE(result, output);
}
diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
index 3756937c94a..50e17728cf3 100644
--- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
@@ -78,6 +78,9 @@ private slots:
void negativeZero_data();
void negativeZero();
+ void signsNeverCompareEqualToNullCharacter_data() { testNames_data(); }
+ void signsNeverCompareEqualToNullCharacter();
+
void dayOfWeek();
void dayOfWeek_data();
void formatDate();
@@ -2114,6 +2117,19 @@ void tst_QLocale::negativeZero()
QCOMPARE(locale.toString(std::copysign(0.0, -1.0)), expect);
}
+void tst_QLocale::signsNeverCompareEqualToNullCharacter() // otherwise QTextStream has a problem
+{
+ QFETCH(QLocale::Language, language);
+ QFETCH(const QLocale::Territory, country);
+
+ if (language == QLocale::AnyLanguage && country == QLocale::AnyTerritory)
+ language = QLocale::C;
+
+ const QLocale loc(language, country);
+ QCOMPARE_NE(loc.negativeSign(), QChar());
+ QCOMPARE_NE(loc.positiveSign(), QChar());
+}
+
void tst_QLocale::dayOfWeek_data()
{
QTest::addColumn<QDate>("date");
@@ -2470,7 +2486,8 @@ void tst_QLocale::formatTimeZone()
// Time definitely in Standard Time
const QStringList knownCETus = {
u"GMT+1"_s, // ICU
- u"CET"_s // Standard abbreviation
+ u"CET"_s, // Standard abbreviation
+ u"UTC+0100"_s, // used by Emscripten
};
const QString cet = enUS.toString(QDate(2013, 1, 1).startOfDay(), u"t");
QVERIFY2(knownCETus.contains(cet), cet.isEmpty() ? "[empty]" : qPrintable(cet));
@@ -2478,7 +2495,8 @@ void tst_QLocale::formatTimeZone()
// Time definitely in Daylight Time
const QStringList knownCESTus = {
u"GMT+2"_s, // ICU
- u"CEST"_s // Standard abbreviation
+ u"CEST"_s, // Standard abbreviation
+ u"UTC+0200"_s, // used by Emscripten
};
const QString cest = enUS.toString(QDate(2013, 6, 1).startOfDay(), u"t");
QVERIFY2(knownCESTus.contains(cest), cest.isEmpty() ? "[empty]" : qPrintable(cest));
diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp
index 2cd1398e7f9..c7f4c35f413 100644
--- a/tests/auto/corelib/text/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp
@@ -22,8 +22,9 @@
#include <qstringmatcher.h>
#include <qbytearraymatcher.h>
#include <qvariant.h>
-
#include <qlocale.h>
+#include <QtCore/qxptype_traits.h>
+
#include <locale.h>
#include <qhash.h>
#include <private/qtools_p.h>
@@ -623,6 +624,7 @@ private slots:
void fromUcs4();
void toUcs4();
void arg();
+ void arg_negative_tests();
void number();
void number_double_data();
void number_double();
@@ -6981,6 +6983,26 @@ void tst_QString::arg()
u"\u0660\u0660\u0661\u0662\u0663\u066c\u0664\u0665\u0666\u066c\u0667\u0668\u0669"); // ٠٠١٢٣٬٤٥٦٬٧٨٩
}
+template <typename S, typename...Ts>
+using arg_compile_test = decltype(std::declval<S>().arg(std::declval<Ts>()...));
+template <typename S, typename...Ts>
+constexpr bool arg_compiles_v = qxp::is_detected_v<arg_compile_test, S, Ts...>;
+
+void tst_QString::arg_negative_tests()
+{
+ static_assert(!arg_compiles_v<QString&, QObject*>);
+ // QLatin1StringView::arg() is unconstrained...
+ // static_assert(!arg_compiles_v<QLatin1StringView&, QObject*>);
+
+ // integral type called like an FP overload:
+ static_assert(!arg_compiles_v<QString&, int, int, char, int, QChar>);
+ static_assert(!arg_compiles_v<QString&, long, int, char, int, char16_t>);
+
+ // strong enums don't match:
+ enum class Strong {};
+ static_assert(!arg_compiles_v<QString&, Strong>);
+}
+
void tst_QString::number()
{
QCOMPARE(QString::number(int(0)), QLatin1String("0"));
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index 87d48d56e6b..5804aeeb1e5 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -73,22 +73,22 @@ void tst_QArrayData::referenceCounting()
// Reference counting initialized to 1 (owned)
QArrayData array = { Q_BASIC_ATOMIC_INITIALIZER(1), {}, 0 };
- QCOMPARE(array.m_ref.loadRelaxed(), 1);
+ QCOMPARE(array.ref_.loadRelaxed(), 1);
QVERIFY(array.ref());
- QCOMPARE(array.m_ref.loadRelaxed(), 2);
+ QCOMPARE(array.ref_.loadRelaxed(), 2);
QVERIFY(array.deref());
- QCOMPARE(array.m_ref.loadRelaxed(), 1);
+ QCOMPARE(array.ref_.loadRelaxed(), 1);
QVERIFY(array.ref());
- QCOMPARE(array.m_ref.loadRelaxed(), 2);
+ QCOMPARE(array.ref_.loadRelaxed(), 2);
QVERIFY(array.deref());
- QCOMPARE(array.m_ref.loadRelaxed(), 1);
+ QCOMPARE(array.ref_.loadRelaxed(), 1);
QVERIFY(!array.deref());
- QCOMPARE(array.m_ref.loadRelaxed(), 0);
+ QCOMPARE(array.ref_.loadRelaxed(), 0);
// Now would be a good time to free/release allocated data
}
diff --git a/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp b/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp
index 89bd1d7ff61..b53362b43e9 100644
--- a/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp
+++ b/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp
@@ -5,6 +5,10 @@
#include <QTest>
+#include <chrono>
+
+using namespace std::chrono_literals;
+
class tst_QAtomicScopedValueRollback : public QObject
{
Q_OBJECT
@@ -15,6 +19,7 @@ private Q_SLOTS:
void rollbackToPreviousCommit();
void exceptions();
void earlyExitScope();
+ void mixedTypes();
private:
void earlyExitScope_helper(int exitpoint, std::atomic<int> &member);
};
@@ -132,6 +137,90 @@ void tst_QAtomicScopedValueRollback::earlyExitScope()
}
}
+template <typename T>
+struct Wrap {
+#if __cpp_deduction_guides < 201907L // no CTAD for aggregates
+ Q_IMPLICIT Wrap(T &t) : t{t} {}
+ Q_IMPLICIT Wrap(T &&t) : t{std::move(t)} {}
+#endif
+ T t;
+ Q_IMPLICIT operator T() const { return t; }
+};
+
+void tst_QAtomicScopedValueRollback::mixedTypes()
+{
+ const auto relaxed = std::memory_order_relaxed;
+ {
+ std::atomic a{10'000ms};
+ {
+ QAtomicScopedValueRollback rb(a, 5s);
+ QCOMPARE(a.load(relaxed), 5s);
+ }
+ QCOMPARE(a.load(relaxed), 10s);
+ {
+ QAtomicScopedValueRollback rb(a, 5s, relaxed);
+ QCOMPARE(a.load(relaxed), 5s);
+ }
+ QCOMPARE(a.load(relaxed), 10s);
+ }
+ {
+ QBasicAtomicInteger a{10'000};
+ {
+ QAtomicScopedValueRollback rb(a, Wrap{5'000});
+ QCOMPARE(a.loadRelaxed(), 5'000);
+ }
+ QCOMPARE(a.loadRelaxed(), 10'000);
+ {
+ QAtomicScopedValueRollback rb(a, Wrap{5'000}, relaxed);
+ QCOMPARE(a.loadRelaxed(), 5'000);
+ }
+ QCOMPARE(a.loadRelaxed(), 10'000);
+ }
+ {
+ QAtomicInteger a{10'000};
+ {
+ QAtomicScopedValueRollback rb(a, Wrap{5'000});
+ QCOMPARE(a.loadRelaxed(), 5'000);
+ }
+ QCOMPARE(a.loadRelaxed(), 10'000);
+ {
+ QAtomicScopedValueRollback rb(a, Wrap{5'000}, relaxed);
+ QCOMPARE(a.loadRelaxed(), 5'000);
+ }
+ QCOMPARE(a.loadRelaxed(), 10'000);
+ }
+ {
+ int i = 10'000;
+ int j = 5'000;
+ QBasicAtomicPointer a{&i};
+ {
+ QAtomicScopedValueRollback rb(a, Wrap{&j});
+ QCOMPARE(a.loadRelaxed(), &j);
+ }
+ QCOMPARE(a.loadRelaxed(), &i);
+ {
+ QAtomicScopedValueRollback rb(a, Wrap{&j}, relaxed);
+ QCOMPARE(a.loadRelaxed(), &j);
+ }
+ QCOMPARE(a.loadRelaxed(), &i);
+ }
+ {
+ int i = 10'000;
+ int j = 5'000;
+ QAtomicPointer a{&i};
+ {
+ QAtomicScopedValueRollback rb(a, Wrap{&j});
+ QCOMPARE(a.loadRelaxed(), &j);
+ }
+ QCOMPARE(a.loadRelaxed(), &i);
+ {
+ QAtomicScopedValueRollback rb(a, Wrap{&j}, relaxed);
+ QCOMPARE(a.loadRelaxed(), &j);
+ }
+ QCOMPARE(a.loadRelaxed(), &i);
+ }
+}
+
static void operator*=(std::atomic<int> &lhs, int rhs)
{
int expected = lhs.load();
diff --git a/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp b/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp
index eecc8b52d28..bd95174c932 100644
--- a/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp
+++ b/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp
@@ -120,6 +120,11 @@ void tst_QDuplicateTracker::appendTo()
QList<int> b;
tracker.appendTo(b);
+ // iteration order is append order:
+ QVERIFY(std::equal(b.cbegin(), b.cend(),
+ tracker.cbegin(), tracker.cend()));
+ QVERIFY(std::equal(b.cbegin(), b.cend(),
+ tracker.begin(), tracker.end()));
std::sort(b.begin(), b.end());
QCOMPARE(b, QList<int>({ 0, 1 }));
diff --git a/tests/auto/dbus/qdbusconnection/CMakeLists.txt b/tests/auto/dbus/qdbusconnection/CMakeLists.txt
index 56ae21f2911..cbbe76a7dc7 100644
--- a/tests/auto/dbus/qdbusconnection/CMakeLists.txt
+++ b/tests/auto/dbus/qdbusconnection/CMakeLists.txt
@@ -19,3 +19,15 @@ qt_internal_add_test(tst_qdbusconnection
TESTDATA
tst_qdbusconnection.conf
)
+
+qt_internal_add_executable(qdbusdelayeddeliveryreenablehelper
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ qdbusdelayeddeliveryreenablehelper.cpp
+ LIBRARIES
+ Qt::DBus
+)
+
+add_dependencies(tst_qdbusconnection
+ qdbusdelayeddeliveryreenablehelper
+)
diff --git a/tests/auto/dbus/qdbusconnection/qdbusdelayeddeliveryreenablehelper.cpp b/tests/auto/dbus/qdbusconnection/qdbusdelayeddeliveryreenablehelper.cpp
new file mode 100644
index 00000000000..cd916d5b639
--- /dev/null
+++ b/tests/auto/dbus/qdbusconnection/qdbusdelayeddeliveryreenablehelper.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2025 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QTimer>
+#include <QtCore/QCoreApplication>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMessage>
+
+#include <stdio.h>
+
+using namespace Qt::StringLiterals;
+using namespace std::chrono_literals;
+
+static QString myInterface()
+{
+ return u"local.qdbusdelayeddeliveryreenablehelper"_s;
+}
+
+static void makeSynchronousCall(QDBusConnection &conn)
+{
+ QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus.Peer", "Ping");
+ conn.call(msg);
+}
+
+static void emitSignal(QDBusConnection &conn)
+{
+ QDBusMessage msg = QDBusMessage::createSignal("/", myInterface(), "quit");
+ conn.send(msg);
+}
+
+int main(int argc, char **argv)
+{
+ // Open a connection to the bus *before* QCoreApplication exists;
+ // this will put the connection in delayed delivery mode
+ QDBusConnection session = QDBusConnection::sessionBus();
+ if (!session.isConnected()) {
+ fprintf(stderr, "Session bus did not connect!");
+ return 1;
+ }
+ makeSynchronousCall(session);
+
+ QCoreApplication app(argc, argv);
+ QTimer::singleShot(15s, qApp, [] {
+ fprintf(stderr, "Did not receive signal.\n");
+ qApp->exit(1);
+ });
+
+ // connect a remote, wildcard signal to qApp->quit()
+ session.connect(QString(), QString(), myInterface(), "quit", &app, SLOT(quit()));
+
+ // send ourselves the signal to quit, via D-Bus
+ emitSignal(session);
+
+ return app.exec();
+}
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
index ab750dff330..fe9214c5513 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
@@ -13,11 +13,6 @@
#include <QDBusInterface>
#include <QDBusConnectionInterface>
-#ifdef Q_OS_UNIX
-# include <sys/types.h>
-# include <signal.h>
-#endif
-
void MyObject::method(const QDBusMessage &msg)
{
path = msg.path();
@@ -1473,6 +1468,31 @@ void tst_QDBusConnection::parentClassSignal()
QTRY_COMPARE(recv.signalsReceived, 2);
}
+// see also tst_qdbusconnection_delayed
+void tst_QDBusConnection::delayedDeliveryReenabledAfterUsedInMainThread()
+{
+#if !QT_CONFIG(process)
+ QSKIP("Test requires QProcess");
+#elif defined(HAS_HOOKSETUPFUNCTION)
+ QSKIP("No difference to run by tst_QDBusConnection");
+#else
+# if defined(Q_OS_WIN)
+# define EXE ".exe"
+# else
+# define EXE ""
+# endif
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
+ QProcess process;
+ process.start(QFINDTESTDATA("qdbusdelayeddeliveryreenablehelper" EXE));
+ QVERIFY2(process.waitForFinished(25000), qPrintable(process.errorString()));
+ QCOMPARE(process.readAllStandardError(), QString());
+ QCOMPARE(process.exitCode(), 0);
+# undef EXE
+#endif
+}
+
QString MyObject::path;
QString MyObjectWithoutInterface::path;
QString MyObjectWithoutInterface::interface;
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
index 4137859414c..dc37e3157b4 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
@@ -126,6 +126,8 @@ private slots:
void parentClassSignal();
+ void delayedDeliveryReenabledAfterUsedInMainThread();
+
public:
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
bool callMethod(const QDBusConnection &conn, const QString &path);
diff --git a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp
index 36cf8ac8fd8..18fe43fbcea 100644
--- a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp
+++ b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp
@@ -35,6 +35,8 @@ private slots:
void write();
void icoMask_data();
void icoMask();
+ void origBitDepth_data();
+ void origBitDepth();
private:
QString m_IconPath;
@@ -354,6 +356,40 @@ void tst_QIcoImageFormat::icoMask()
QCOMPARE(inImage, outImage);
}
+void tst_QIcoImageFormat::origBitDepth_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QList<int>>("origBitDepths");
+
+ QTest::newRow("35FLOPPY") << "35FLOPPY.ICO" << QList<int>{4};
+ QTest::newRow("abcardWindow") << "abcardWindow.ico" << QList<int>{8};
+ QTest::newRow("AddPerf") << "AddPerfMon.ico" << QList<int>{4};
+ QTest::newRow("App") << "App.ico" << QList<int>{4};
+ QTest::newRow("Obj_N2_Internal_Mem") << "Obj_N2_Internal_Mem.ico" << QList<int>{4, 8, 32};
+ QTest::newRow("Qt") << "Qt.ico" << QList<int>{32};
+ QTest::newRow("semitransparent") << "semitransparent.ico" << QList<int>{4};
+ QTest::newRow("Status_Play") << "Status_Play.ico" << QList<int>{4, 8, 32};
+ QTest::newRow("TIMER01") << "TIMER01.ICO" << QList<int>{4};
+ QTest::newRow("trolltechlogo_tiny") << "trolltechlogo_tiny.ico" << QList<int>{8};
+ QTest::newRow("WORLD") << "WORLD.ico" << QList<int>{8, 4, 4};
+ QTest::newRow("yellow") << "yellow.cur" << QList<int>{32};
+}
+
+void tst_QIcoImageFormat::origBitDepth()
+{
+ QFETCH(QString, file);
+ QFETCH(QList<int>, origBitDepths);
+
+ QImage image;
+ QImageReader reader(m_IconPath + QLatin1String("/valid/") + file);
+
+ for (int depth : origBitDepths) {
+ reader.read(&image);
+ QCOMPARE(image.text("_q_icoOrigDepth").toInt(), depth);
+ reader.jumpToNextImage();
+ }
+}
+
QTEST_MAIN(tst_QIcoImageFormat)
#include "tst_qicoimageformat.moc"
diff --git a/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp b/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp
index 6019261f792..06a1ffb2960 100644
--- a/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp
+++ b/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp
@@ -26,9 +26,6 @@ private slots:
void tst_QOpenGLWindow::initTestCase()
{
-#if !QT_CONFIG(run_opengl_tests)
- QSKIP("Skip test as run-opengl-tests feature is off.");
-#endif
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
QSKIP("OpenGL is not supported on this platform.");
}
diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST
index a92d89c6123..4f994fb3059 100644
--- a/tests/auto/gui/kernel/qwindow/BLACKLIST
+++ b/tests/auto/gui/kernel/qwindow/BLACKLIST
@@ -25,6 +25,5 @@ android
windows-10
windows-11
android
-rhel
[windowExposedAfterReparent]
xcb ubuntu-24.04 # QTBUG-129023
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index 39051276371..66bb0fa84d8 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -11,6 +11,7 @@
#include <QtGui/QPainter>
#include <QTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include <QSignalSpy>
#include <QEvent>
#include <QStyleHints>
@@ -1237,6 +1238,7 @@ void tst_QWindow::testInputEvents()
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.showNormal();
QTRY_VERIFY(window.isActive());
+ QVERIFY(QTestPrivate::ensurePositionTopLeft(&window));
QTest::keyClick(&window, Qt::Key_A, Qt::NoModifier);
QCoreApplication::processEvents();
@@ -3264,12 +3266,14 @@ void tst_QWindow::windowExposedAfterReparent()
QVERIFY(QTest::qWaitForWindowExposed(&parent));
QVERIFY(QTest::qWaitForWindowExposed(&child));
+ // Close the child before reparenting it to ensure it is correctly converted
+ // to a toplevel window by the window manager.
+ child.close();
child.setParent(nullptr);
- QCoreApplication::processEvents();
+ child.show();
QVERIFY(QTest::qWaitForWindowExposed(&child));
child.setParent(&parent);
- QCoreApplication::processEvents();
QVERIFY(QTest::qWaitForWindowExposed(&child));
}
diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp
index bd4a230b78a..d4dc6544a0e 100644
--- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp
+++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp
@@ -894,6 +894,13 @@ void tst_QQuaternion::fromAxes()
QQuaternion result = QQuaternion::fromAxisAndAngle(QVector3D(x1, y1, z1), angle);
+ {
+ const auto axes = result.toAxes();
+ QVERIFY(myFuzzyCompare(axes.x, xAxis));
+ QVERIFY(myFuzzyCompare(axes.y, yAxis));
+ QVERIFY(myFuzzyCompare(axes.z, zAxis));
+ }
+
QVector3D axes[3];
result.getAxes(&axes[0], &axes[1], &axes[2]);
QVERIFY(myFuzzyCompare(axes[0], xAxis));
@@ -985,8 +992,7 @@ void tst_QQuaternion::fromDirection_data()
// othonormal up and dir
for (QQuaternion q : orientations) {
- QVector3D xAxis, yAxis, zAxis;
- q.getAxes(&xAxis, &yAxis, &zAxis);
+ const auto [xAxis, yAxis, zAxis] = q.toAxes();
QTest::addRow("ortho dirs: (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f)",
xAxis.x(), xAxis.y(), xAxis.z(),
@@ -1007,8 +1013,7 @@ void tst_QQuaternion::fromDirection_data()
// invalid up
for (QQuaternion q : orientations) {
- QVector3D xAxis, yAxis, zAxis;
- q.getAxes(&xAxis, &yAxis, &zAxis);
+ const auto [xAxis, yAxis, zAxis] = q.toAxes();
QTest::addRow("bad dirs: (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f)",
xAxis.x(), xAxis.y(), xAxis.z(),
@@ -1029,16 +1034,14 @@ void tst_QQuaternion::fromDirection()
QQuaternion result = QQuaternion::fromDirection(direction, up);
QVERIFY(myFuzzyCompare(result, result.normalized()));
- QVector3D xAxis, yAxis, zAxis;
- result.getAxes(&xAxis, &yAxis, &zAxis);
-
- QVERIFY(myFuzzyCompare(zAxis, expectedZ));
+ const auto axes = result.toAxes();
+ QVERIFY(myFuzzyCompare(axes.z, expectedZ));
const QVector3D expectedX = QVector3D::crossProduct(expectedY, expectedZ);
if (!qFuzzyIsNull(expectedX.lengthSquared())) {
- QVERIFY(myFuzzyCompare(xAxis, expectedX));
- QVERIFY(myFuzzyCompare(yAxis, expectedY));
+ QVERIFY(myFuzzyCompare(axes.x, expectedX));
+ QVERIFY(myFuzzyCompare(axes.y, expectedY));
}
}
diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp
index b9b4c3aa11c..36ff1d1f2e9 100644
--- a/tests/auto/gui/qopengl/tst_qopengl.cpp
+++ b/tests/auto/gui/qopengl/tst_qopengl.cpp
@@ -185,9 +185,6 @@ static QSurface *createSurface(int surfaceClass)
void tst_QOpenGL::initTestCase()
{
-#if !QT_CONFIG(run_opengl_tests)
- QSKIP("Skip test as run-opengl-tests feature is off.");
-#endif
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
QSKIP("OpenGL is not supported on this platform.");
}
diff --git a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
index f597dac53d7..423f9419daf 100644
--- a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
+++ b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
@@ -139,9 +139,6 @@ static void dumpConfiguration(QTextStream &str)
void tst_QOpenGlConfig::initTestCase()
{
-#if !QT_CONFIG(run_opengl_tests)
- QSKIP("Skip test as run-opengl-tests feature is off.");
-#endif
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
QSKIP("OpenGL is not supported on this platform.");
}
diff --git a/tests/auto/gui/text/qfont/BLACKLIST b/tests/auto/gui/text/qfont/BLACKLIST
index 2d2440255ae..3f63b678bb5 100644
--- a/tests/auto/gui/text/qfont/BLACKLIST
+++ b/tests/auto/gui/text/qfont/BLACKLIST
@@ -1,12 +1,9 @@
[defaultFamily:cursive]
centos
b2qt
-rhel
[defaultFamily:fantasy]
centos
b2qt
-rhel
-
# QTBUG-130738
[familyNameWithCommaQuote:weird]
vxworks
diff --git a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST b/tests/auto/network/kernel/qnetworkinterface/BLACKLIST
deleted file mode 100644
index e9f4678e8ef..00000000000
--- a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST
+++ /dev/null
@@ -1,5 +0,0 @@
-# QTBUG-130070
-[localAddress:enet0-fe80::8f41:f072:e573:3caa%enet0]
-vxworks
-[localAddress:localhost-ipv6]
-vxworks
diff --git a/tests/auto/other/android/CMakeLists.txt b/tests/auto/other/android/CMakeLists.txt
index bcbf5b657d7..0eb2d00b46a 100644
--- a/tests/auto/other/android/CMakeLists.txt
+++ b/tests/auto/other/android/CMakeLists.txt
@@ -2,3 +2,11 @@
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(deployment_settings)
+add_subdirectory(permissions)
+
+if(QT_USE_TARGET_ANDROID_BUILD_DIR)
+ add_subdirectory(package_source_dir)
+ if(QT_USE_ANDROID_MODERN_BUNDLE)
+ add_subdirectory(dynamic_feature)
+ endif()
+endif()
diff --git a/tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp b/tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp
index 1687ed9de92..9297958ba31 100644
--- a/tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp
+++ b/tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp
@@ -83,10 +83,12 @@ void tst_android_deployment_settings::DeploymentSettings_data()
<< "org.qtproject.android_deployment_settings_test";
QTest::newRow("android-app-name") << "android-app-name"
<< "Android Deployment Settings Test";
- QTest::newRow("permissions") << "permissions"
- << "[{\"name\":\"PERMISSION_WITH_ATTRIBUTES\","
- "\"extras\":\"android:minSdkVersion='32' android:maxSdkVersion='34' \"},"
- "{\"name\":\"PERMISSION_WITHOUT_ATTRIBUTES\"}]";
+ QTest::newRow("permissions")
+ << "permissions"
+ << "[{\"maxSdkVersion\":\"34\",\"minSdkVersion\":\"32\",\"name\":\"PERMISSION_WITH_"
+ "ATTRIBUTES\"},{\"name\":\"PERMISSION_WITHOUT_ATTRIBUTES\"},{\"name\":\"android."
+ "permission.WRITE_EXTERNAL_STORAGE\"},{\"name\":\"android."
+ "permission.INTERNET\"}]";
}
void tst_android_deployment_settings::DeploymentSettings()
diff --git a/tests/auto/other/android/dynamic_feature/CMakeLists.txt b/tests/auto/other/android/dynamic_feature/CMakeLists.txt
new file mode 100644
index 00000000000..b12c2af4dc7
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_android_dynamic_feature LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(feature)
+
+qt_internal_add_test(tst_android_dynamic_feature
+ SOURCES
+ tst_android_dynamic_feature.cpp
+ storeloader/storeloader.h
+ storeloader/storeloader.cpp
+ INCLUDE_DIRECTORIES
+ storeloader
+ LIBRARIES
+ Qt6::Test
+ Qt6::Gui
+ Qt6::CorePrivate
+)
+
+set_property(TARGET tst_android_dynamic_feature PROPERTY
+ QT_ANDROID_PACKAGE_NAME "org.qtproject.example.android_dynamic_feature")
+set_property(TARGET tst_android_dynamic_feature APPEND PROPERTY
+ _qt_android_gradle_java_source_dirs "${CMAKE_CURRENT_SOURCE_DIR}/storeloader/java")
+
+qt6_add_android_dynamic_features(tst_android_dynamic_feature FEATURE_TARGETS
+ tst_android_dynamic_feature_resources)
diff --git a/tests/auto/other/android/dynamic_feature/feature/CMakeLists.txt b/tests/auto/other/android/dynamic_feature/feature/CMakeLists.txt
new file mode 100644
index 00000000000..bfe29cc0f5e
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/feature/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.16)
+
+qt6_add_library(tst_android_dynamic_feature_resources SHARED)
+qt6_add_resources(tst_android_dynamic_feature_resources "dynamic_resources"
+ PREFIX "/dynamic_resources"
+ FILES "qtlogo.png")
+
+target_link_libraries(tst_android_dynamic_feature_resources PRIVATE Qt6::Core)
diff --git a/tests/auto/other/android/dynamic_feature/feature/qtlogo.png b/tests/auto/other/android/dynamic_feature/feature/qtlogo.png
new file mode 100644
index 00000000000..b63f1384b11
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/feature/qtlogo.png
Binary files differ
diff --git a/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoader.java b/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoader.java
new file mode 100644
index 00000000000..5a72351c802
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoader.java
@@ -0,0 +1,175 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+package org.qtproject.example.android_dynamic_feature;
+
+import com.google.android.play.core.splitcompat.SplitCompat;
+import com.google.android.play.core.splitinstall.SplitInstallManager;
+import com.google.android.play.core.splitinstall.SplitInstallManagerFactory;
+import com.google.android.play.core.splitinstall.SplitInstallRequest;
+import com.google.android.play.core.splitinstall.SplitInstallHelper;
+import com.google.android.play.core.splitinstall.testing.FakeSplitInstallManagerFactory;
+import android.content.pm.PackageManager.NameNotFoundException;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.io.File;
+import android.util.Log;
+import android.content.Context;
+import android.os.Build;
+
+/**
+ * Android implementation of store loader.
+ */
+public class StoreLoader implements StoreLoaderListenerCallback
+{
+ private static final String TAG = "StoreLoader";
+ private final SplitInstallManager m_splitInstallManager;
+ private HashMap<String, StoreLoaderListener> m_listeners =
+ new HashMap();
+ private Context m_context;
+ private String m_moduleName;
+
+ public static native void stateChangedNative(String callId, int state);
+ public static native void errorOccurredNative(String callId, int errorCode,
+ String errorMessage);
+ public static native void userConfirmationRequestedNative(String callId, int errorCode,
+ String errorMessage);
+ public static native void downloadProgressChangedNative(String callId, long bytes, long total);
+ public static native void finishedNative(String callId);
+
+ public StoreLoader(Context context) {
+ m_context = context;
+
+ SplitCompat.install(context);
+
+ m_splitInstallManager = SplitInstallManagerFactory.create(context);
+ if (m_splitInstallManager == null)
+ Log.e(TAG,"Constructor: Did not get splitInstallManager");
+ }
+
+ /**
+ * Loads Feature Delivery module from a play store.
+ */
+ public void installModuleFromStore(String moduleName, String callId) {
+ Log.d(TAG, "installModuleFromStore: " + moduleName + " " + callId);
+ m_moduleName = moduleName;
+
+ registerListener(callId);
+
+ SplitInstallRequest request =
+ SplitInstallRequest.newBuilder().addModule(m_moduleName).build();
+ if (request == null)
+ Log.e(TAG, "Null request");
+
+ if (m_splitInstallManager == null)
+ Log.e(TAG, "Null m_splitInstallManager");
+
+ m_splitInstallManager.startInstall(request)
+ .addOnSuccessListener(sessionId -> {
+ Log.d(TAG, "Install start call succesfull");
+ StoreLoaderListener listener = m_listeners.get(callId);
+ if (listener != null) {
+ if (!listener.isCancelled())
+ listener.setSessionId(sessionId);
+ else
+ m_splitInstallManager.cancelInstall(sessionId);
+ } else {
+ Log.d(TAG, "Listener for callId '" + callId + "' is not found");
+ }
+ });
+ }
+
+ public void onStateChanged(String callId, int state) {
+ stateChangedNative(callId, state);
+ if (state == StoreLoaderListenerCallback.LOADED ||
+ state == StoreLoaderListenerCallback.CANCELED) {
+ finished(callId);
+ }
+ }
+
+ public void onErrorOccurred(String callId, int errorCode, String errorMessage) {
+ onStateChanged(callId, ERROR);
+
+ Log.e(TAG, "Error occurred " + errorCode + " " + errorMessage);
+ errorOccurredNative(callId, errorCode, errorMessage);
+ finished(callId);
+ }
+
+ public void onUserConfirmationRequested(String callId, int errorCode, String errorMessage) {
+ Log.d(TAG, "Requires user confirmation " + errorCode);
+ userConfirmationRequestedNative(callId, errorCode, errorMessage);
+ }
+
+ public void onDownloadProgressChanged(String callId, long bytes, long total) {
+ Log.d(TAG, "Downloading " + bytes + "/" + total);
+ downloadProgressChangedNative(callId, bytes, total);
+ }
+
+ public void onLoadLibrary(String callId) {
+ Log.d(TAG, "Load library for the module " + m_moduleName);
+
+ stateChangedNative(callId, StoreLoaderListenerCallback.LOADING);
+ // update context.
+ try {
+ m_context = m_context.createPackageContext(m_context.getPackageName(), 0);
+ } catch (NameNotFoundException ignored) {
+ Log.e(TAG, "Could not get package name");
+ }
+ // install splitcompat for new context.
+ SplitCompat.install(m_context);
+ // try to load new library
+ boolean isLoaded = false;
+ for (String abi : Build.SUPPORTED_ABIS) {
+ String fullLibraryName = m_moduleName + "_" + abi;
+ try {
+ System.loadLibrary(fullLibraryName);
+ isLoaded = true;
+ break;
+ } catch (Exception e) {
+ Log.d(TAG, "Exception occurred when loading the library " + fullLibraryName + ":" +
+ e.getClass().getCanonicalName());
+ }
+ }
+
+ if (isLoaded)
+ onStateChanged(callId, StoreLoaderListenerCallback.LOADED);
+ else
+ onErrorOccurred(callId, -1, "Error loading library. Check logcat for details.");
+
+ }
+
+ public void cancelInstall(String callId) {
+ StoreLoaderListener listener = m_listeners.get(callId);
+ if (listener == null) {
+ Log.e(TAG, "The listener for callId " + callId + " is not found");
+ return;
+ }
+
+ if (listener.getSessionId() < 0)
+ listener.postponeCancel();
+ else
+ m_splitInstallManager.cancelInstall(listener.getSessionId());
+ }
+
+ private void finished(String callId) {
+ unregisterListener(callId);
+ finishedNative(callId);
+ }
+
+ private void registerListener(String callId) {
+ Log.d(TAG, "registerListener");
+ StoreLoaderListener listener = new StoreLoaderListener(this, callId);
+ if (listener != null) {
+ m_listeners.put(callId, listener);
+ m_splitInstallManager.registerListener(listener);
+ }
+ }
+
+ private void unregisterListener(String callId) {
+ Log.d(TAG, "unregisterListener");
+ StoreLoaderListener listener = m_listeners.remove(callId);
+ if (listener != null)
+ m_splitInstallManager.unregisterListener(listener);
+ }
+}
diff --git a/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoaderListener.java b/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoaderListener.java
new file mode 100644
index 00000000000..3e83a0fa7f9
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoaderListener.java
@@ -0,0 +1,92 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+package org.qtproject.example.android_dynamic_feature;
+
+import com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener;
+import com.google.android.play.core.splitinstall.SplitInstallSessionState;
+import com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus;
+
+import android.util.Log;
+
+public class StoreLoaderListener implements SplitInstallStateUpdatedListener {
+
+ private final StoreLoaderListenerCallback m_callback;
+ private final String m_callId;
+ private int m_installSessionId = -1;
+ private static final String TAG = "StoreLoaderListener";
+ private int m_currentStatus = SplitInstallSessionStatus.UNKNOWN;
+ private boolean m_postponeCancel = false;
+
+ public StoreLoaderListener(StoreLoaderListenerCallback callback, String callId) {
+ m_callback = callback;
+ m_callId = callId;
+ }
+
+ public void setSessionId(int sessionId) { m_installSessionId = sessionId; }
+ public int getSessionId() { return m_installSessionId; }
+
+ public void postponeCancel() { m_postponeCancel = true; }
+ public boolean isCancelled() { return m_postponeCancel; }
+
+ @Override
+ public void onStateUpdate(SplitInstallSessionState state) {
+ Log.d(TAG,
+ "onStateUpdate, status: " + state.status() + " session id: " + state.sessionId());
+ if (state.sessionId() != m_installSessionId) {
+ // Not mine
+ return;
+ }
+
+ switch (state.status()) {
+ case SplitInstallSessionStatus.DOWNLOADING:
+ Log.d(TAG,
+ "SplitInstallSessionState: DOWNLOADING " + state.bytesDownloaded() + "/"
+ + state.totalBytesToDownload());
+ if (m_currentStatus != SplitInstallSessionStatus.DOWNLOADING)
+ m_callback.onStateChanged(m_callId, StoreLoaderListenerCallback.DOWNLOADING);
+
+ m_callback.onDownloadProgressChanged(m_callId, state.bytesDownloaded(),
+ state.totalBytesToDownload());
+ break;
+ case SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION:
+ Log.d(TAG, "SplitInstallSessionState: REQUIRES_USER_CONFIRMATION");
+ m_callback.onStateChanged(m_callId,
+ StoreLoaderListenerCallback.REQUIRES_USER_CONFIRMATION);
+
+ m_callback.onUserConfirmationRequested(m_callId, state.errorCode(), "" /*noop for now*/);
+ break;
+ case SplitInstallSessionStatus.INSTALLED:
+ Log.d(TAG, "SplitInstallSessionState: INSTALLED");
+ m_callback.onStateChanged(m_callId, StoreLoaderListenerCallback.INSTALLED);
+ m_callback.onLoadLibrary(m_callId);
+ break;
+ case SplitInstallSessionStatus.INSTALLING:
+ Log.d(TAG, "SplitInstallSessionState: INSTALLING");
+ m_callback.onStateChanged(m_callId, StoreLoaderListenerCallback.INSTALLING);
+ break;
+ case SplitInstallSessionStatus.FAILED:
+ Log.d(TAG,
+ "SplitInstallSessionState: FAILED with error code: " + state.errorCode());
+ m_callback.onErrorOccurred(m_callId, state.errorCode(), "" /*noop for now*/);
+ break;
+ case SplitInstallSessionStatus.PENDING:
+ Log.d(TAG, "SplitInstallSessionState: PENDING");
+ m_callback.onStateChanged(m_callId, StoreLoaderListenerCallback.PENDING);
+ break;
+ case SplitInstallSessionStatus.DOWNLOADED:
+ Log.d(TAG, "SplitInstallSessionState: DOWNLOADED");
+ m_callback.onStateChanged(m_callId, StoreLoaderListenerCallback.DOWNLOADED);
+ break;
+ case SplitInstallSessionStatus.CANCELED:
+ Log.d(TAG, "SplitInstallSessionState: CANCELED");
+ m_callback.onStateChanged(m_callId, StoreLoaderListenerCallback.CANCELED);
+ break;
+ case SplitInstallSessionStatus.CANCELING:
+ Log.d(TAG, "SplitInstallSessionState: CANCELING");
+ m_callback.onStateChanged(m_callId, StoreLoaderListenerCallback.CANCELING);
+ break;
+ }
+ m_currentStatus = state.status();
+ }
+}
diff --git a/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoaderListenerCallback.java b/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoaderListenerCallback.java
new file mode 100644
index 00000000000..99c7327e328
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/storeloader/java/src/main/java/org/qtproject/example/android_dynamic_feature/StoreLoaderListenerCallback.java
@@ -0,0 +1,26 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+package org.qtproject.example.android_dynamic_feature;
+
+public interface StoreLoaderListenerCallback {
+ public static final int UNKNOWN = 0; // Unused but native part has and uses one.
+ public static final int INITIALIZED = 1;
+ public static final int PENDING = 2;
+ public static final int DOWNLOADING = 3;
+ public static final int DOWNLOADED = 4;
+ public static final int REQUIRES_USER_CONFIRMATION = 5;
+ public static final int CANCELING = 6;
+ public static final int CANCELED = 7;
+ public static final int INSTALLING = 8;
+ public static final int INSTALLED = 9;
+ public static final int LOADING = 10;
+ public static final int LOADED = 11;
+ public static final int ERROR = 12;
+
+ public void onStateChanged(String callId, int state);
+ public void onErrorOccurred(String callId, int errorCode, String errorMessage);
+ public void onUserConfirmationRequested(String callId, int errorCode, String errorMessage);
+ public void onDownloadProgressChanged(String callId, long bytes, long total);
+ public void onLoadLibrary(String callId);
+}
diff --git a/tests/auto/other/android/dynamic_feature/storeloader/storeloader.cpp b/tests/auto/other/android/dynamic_feature/storeloader/storeloader.cpp
new file mode 100644
index 00000000000..7abce59b79e
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/storeloader/storeloader.cpp
@@ -0,0 +1,227 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include "storeloader.h"
+
+#include <QtCore/private/qobject_p.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qjniobject.h>
+#include <QtCore/qlogging.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/quuid.h>
+
+#include <jni.h>
+
+Q_DECLARE_JNI_CLASS(StoreLoader,
+ "org/qtproject/example/android_dynamic_feature/StoreLoader");
+
+class StoreLoaderHandlerPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(StoreLoaderHandler)
+public:
+ void setState(StoreLoader::State state)
+ {
+ if (m_state == state)
+ return;
+ Q_Q(StoreLoaderHandler);
+ m_state = state;
+ q->stateChanged(m_state);
+ }
+
+ const QString &callId() const & noexcept { return m_callId; }
+
+private:
+ StoreLoader::State m_state = StoreLoader::State::Unknown;
+ QString m_callId = QUuid::createUuid().toString();
+};
+
+namespace QtPrivate {
+QString asString(const jstring &s)
+{
+ return QJniObject(s).toString();
+}
+} // namespace QtPrivate
+
+namespace {
+
+class StoreLoaderImpl
+{
+public:
+ StoreLoaderImpl();
+ bool registerNatives() const;
+
+ void addHandler(StoreLoaderHandler *handler);
+ StoreLoaderHandler *findHandler(const jstring &callId);
+ void removeHandler(const jstring &callId);
+
+ QtJniTypes::StoreLoader loader = nullptr;
+
+private:
+ QHash<QString, QPointer<StoreLoaderHandler>> m_handlers;
+ QMutex m_lock;
+};
+
+Q_GLOBAL_STATIC(StoreLoaderImpl, loaderInstance)
+
+void stateChangedNative(JNIEnv *, jobject, jstring callId, int state)
+{
+ qDebug("State changed %s.", qPrintable(callId));
+
+ if (auto *handler = loaderInstance->findHandler(callId))
+ emit handler->stateChanged(static_cast<StoreLoader::State>(state));
+}
+
+void errorOccurredNative(JNIEnv *, jobject, jstring callId, int errorCode, jstring errorMessage)
+{
+ qDebug("Error occurred %s %d %s.", qPrintable(callId), errorCode, qPrintable(errorMessage));
+ auto *handler = loaderInstance->findHandler(callId);
+ if (!handler)
+ return;
+
+ emit handler->errorOccured(errorCode, QJniObject(errorMessage).toString());
+}
+
+void userConfirmationRequestedNative(JNIEnv *, jobject, jstring callId, int errorCode,
+ jstring errorMessage)
+{
+ qDebug("User confirmation requested %s %d %s.", qPrintable(callId), errorCode,
+ qPrintable(errorMessage));
+ auto *handler = loaderInstance->findHandler(callId);
+ if (!handler)
+ return;
+
+ emit handler->confirmationRequest(errorCode, QJniObject(errorMessage).toString());
+}
+
+void downloadProgressChangedNative(JNIEnv *, jobject, jstring callId, long bytes, long total)
+{
+ qDebug("Download progress changed %ld/%ld.", bytes, total);
+ auto *handler = loaderInstance->findHandler(callId);
+ if (!handler)
+ return;
+
+ emit handler->downloadProgress(bytes, total);
+}
+
+void finishedNative(JNIEnv *, jobject, jstring callId)
+{
+ auto *handler = loaderInstance->findHandler(callId);
+ if (!handler)
+ return;
+
+ emit handler->finished();
+}
+
+} // namespace
+
+Q_DECLARE_JNI_NATIVE_METHOD(stateChangedNative)
+Q_DECLARE_JNI_NATIVE_METHOD(errorOccurredNative)
+Q_DECLARE_JNI_NATIVE_METHOD(userConfirmationRequestedNative)
+Q_DECLARE_JNI_NATIVE_METHOD(downloadProgressChangedNative)
+Q_DECLARE_JNI_NATIVE_METHOD(finishedNative)
+
+StoreLoaderImpl::StoreLoaderImpl()
+{
+ loader = QJniObject::construct<QtJniTypes::StoreLoader, QtJniTypes::Context>(
+ QNativeInterface::QAndroidApplication::context());
+}
+
+bool StoreLoaderImpl::registerNatives() const
+{
+ static bool result = [] {
+ return QtJniTypes::StoreLoader::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(stateChangedNative),
+ Q_JNI_NATIVE_METHOD(errorOccurredNative),
+ Q_JNI_NATIVE_METHOD(userConfirmationRequestedNative),
+ Q_JNI_NATIVE_METHOD(downloadProgressChangedNative),
+ Q_JNI_NATIVE_METHOD(finishedNative),
+ });
+ }();
+
+ if (!result)
+ qCritical("Unable to register native methods.");
+
+ return result;
+}
+
+void StoreLoaderImpl::addHandler(StoreLoaderHandler *handler)
+{
+ Q_ASSERT(handler);
+
+ QMutexLocker lock(&m_lock);
+ const auto &callId = handler->callId();
+ Q_ASSERT_X(m_handlers.constFind(callId) != m_handlers.constEnd(), "StoreLoaderImpl::addHandler",
+ qPrintable(QString("Handler with callId %1 already exists.").arg(callId)));
+
+ m_handlers[callId] = QPointer(handler);
+}
+
+
+StoreLoaderHandler *StoreLoaderImpl::findHandler(const jstring &callId)
+{
+ QMutexLocker lock(&m_lock);
+ const auto it = m_handlers.constFind(QJniObject(callId).toString());
+ if (it == m_handlers.constEnd()) {
+ qCritical("The handler for the call %s was not found.", qPrintable(callId));
+ return nullptr;
+ }
+
+ if (it.value().isNull()) {
+ qCritical("The handler for the call %s expired.", qPrintable(callId));
+ m_handlers.erase(it);
+ }
+
+ return it.value().get();
+}
+
+void StoreLoaderImpl::removeHandler(const jstring &callId)
+{
+ QMutexLocker lock(&m_lock);
+ m_handlers.remove(QJniObject(callId).toString());
+}
+
+std::unique_ptr<StoreLoaderHandler>
+StoreLoader::loadModule(const QString &moduleName)
+{
+ if (moduleName.isEmpty())
+ return {};
+
+ if (!loaderInstance->registerNatives())
+ return {};
+
+ if (!loaderInstance->loader.isValid()) {
+ qCritical("StoreLoader not constructed");
+ return {};
+ }
+
+ auto handlerPtr = std::make_unique<StoreLoaderHandler>(
+ nullptr, StoreLoaderHandler::PrivateConstructor{});
+ loaderInstance->addHandler(handlerPtr.get());
+
+ const auto &callId = handlerPtr->callId();
+ qDebug("Loading module %s, callId: %s.", qPrintable(moduleName), qPrintable(callId));
+
+ loaderInstance->loader.callMethod<void>("installModuleFromStore", moduleName, callId);
+ return handlerPtr;
+}
+
+StoreLoaderHandler::StoreLoaderHandler(QObject *parent, PrivateConstructor)
+ : QObject(*new StoreLoaderHandlerPrivate(), parent)
+{
+}
+
+StoreLoaderHandler::~StoreLoaderHandler() = default;
+
+const QString &StoreLoaderHandler::callId() const & noexcept
+{
+ Q_D(const StoreLoaderHandler);
+ return d->callId();
+}
+
+void StoreLoaderHandler::cancel()
+{
+ Q_D(StoreLoaderHandler);
+ loaderInstance->loader.callMethod<void>("cancelInstall", d->callId());
+}
+
+#include "moc_storeloader.cpp"
diff --git a/tests/auto/other/android/dynamic_feature/storeloader/storeloader.h b/tests/auto/other/android/dynamic_feature/storeloader/storeloader.h
new file mode 100644
index 00000000000..be4e103207e
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/storeloader/storeloader.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef STORELOADER_H
+#define STORELOADER_H
+
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qobject.h>
+
+#include <memory>
+
+class StoreLoaderHandler;
+
+namespace StoreLoader {
+ Q_NAMESPACE
+enum class State {
+ Unknown,
+ Initialized,
+ Pending,
+ Downloading,
+ Downloaded,
+ RequiresUserConfirmation,
+ Canceling,
+ Canceled,
+ Installing,
+ Installed,
+ Loading,
+ Loaded,
+ Error,
+};
+Q_ENUM_NS(State)
+
+std::unique_ptr<StoreLoaderHandler> loadModule(const QString &moduleName);
+}; // namespace StoreLoader
+
+class StoreLoaderHandlerPrivate;
+
+class StoreLoaderHandler : public QObject
+{
+ Q_OBJECT
+ QT_DEFINE_TAG_STRUCT(PrivateConstructor);
+
+public:
+ explicit StoreLoaderHandler(QObject *parent, PrivateConstructor);
+ ~StoreLoaderHandler() override;
+
+ const QString &callId() const & noexcept;
+
+ void cancel();
+signals:
+ void stateChanged(StoreLoader::State state);
+ void downloadProgress(qsizetype bytes, qsizetype total);
+ void errorOccured(int errorCode, const QString &errorString);
+ void confirmationRequest(int errorCode, const QString &errorString);
+ void finished();
+
+private:
+ Q_DISABLE_COPY_MOVE(StoreLoaderHandler)
+ Q_DECLARE_PRIVATE(StoreLoaderHandler)
+
+ friend std::unique_ptr<StoreLoaderHandler>
+ StoreLoader::loadModule(const QString &);
+};
+
+#endif // STORELOADER_H
diff --git a/tests/auto/other/android/dynamic_feature/tst_android_dynamic_feature.cpp b/tests/auto/other/android/dynamic_feature/tst_android_dynamic_feature.cpp
new file mode 100644
index 00000000000..739a645c5d5
--- /dev/null
+++ b/tests/auto/other/android/dynamic_feature/tst_android_dynamic_feature.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <storeloader.h>
+
+#include <QtTest/QTest>
+#include <QtTest/QSignalSpy>
+
+#include <QtCore/QVariant>
+
+using namespace Qt::Literals::StringLiterals;
+
+class QtDynamicFeatureTest : public QObject
+{
+ Q_OBJECT
+public:
+ QtDynamicFeatureTest(){}
+
+private Q_SLOTS:
+ void loadResourcesFeature();
+};
+
+void QtDynamicFeatureTest::loadResourcesFeature()
+{
+ QVERIFY(!QFile::exists(":/dynamic_resources/qtlogo.png"));
+
+ auto handler = StoreLoader::loadModule("tst_android_dynamic_feature_resources"_L1);
+
+ QSignalSpy spy(handler.get(), &StoreLoaderHandler::finished);
+
+ QVERIFY(spy.wait(20000));
+ QVERIFY(QFile::exists(":/dynamic_resources/qtlogo.png"));
+}
+
+QTEST_MAIN(QtDynamicFeatureTest)
+
+#include "tst_android_dynamic_feature.moc"
diff --git a/tests/auto/other/android/package_source_dir/CMakeLists.txt b/tests/auto/other/android/package_source_dir/CMakeLists.txt
new file mode 100644
index 00000000000..360aa50d87d
--- /dev/null
+++ b/tests/auto/other/android/package_source_dir/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Copyright (C) 2025 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_android_package_source_dir LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Package name is generated and written to AndroidManifest.xml
+qt_internal_add_test(tst_package_source_dir_not_defined
+ SOURCES
+ tst_android_package_source_dir.cpp
+ DEFINES
+ EXPECTED_APP_NAME="tst_package_source_dir_not_defined"
+)
+
+# Package name from user-provided AndroidManifest.xml
+qt_internal_add_test(tst_package_source_dir_custom_android_manifest
+ SOURCES
+ tst_android_package_source_dir.cpp
+ DEFINES
+ EXPECTED_APP_NAME="tst_package_source_dir_custom_android_manifest_my"
+)
+
+if(QT_USE_ANDROID_MODERN_BUNDLE)
+ set_target_properties(tst_package_source_dir_custom_android_manifest
+ PROPERTIES
+ QT_ANDROID_PACKAGE_SOURCE_DIR
+ "${CMAKE_CURRENT_SOURCE_DIR}/custom_android_manifest_bundle"
+ )
+else()
+ set_target_properties(tst_package_source_dir_custom_android_manifest
+ PROPERTIES
+ QT_ANDROID_PACKAGE_SOURCE_DIR
+ "${CMAKE_CURRENT_SOURCE_DIR}/custom_android_manifest"
+ )
+endif()
+
+if(QT_USE_ANDROID_MODERN_BUNDLE)
+ # Partial gradle template is only supported by QT_USE_ANDROID_MODERN_BUNDLE
+ #
+ # Package name from user-provided gradle.build.in
+ qt_internal_add_test(tst_package_source_dir_partial_template
+ SOURCES
+ tst_android_package_source_dir.cpp
+ DEFINES
+ EXPECTED_APP_NAME="tst_package_source_dir_partial_template_my"
+ )
+ set_target_properties(tst_package_source_dir_partial_template
+ PROPERTIES
+ QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/partial_template"
+ )
+endif()
diff --git a/tests/auto/other/android/package_source_dir/custom_android_manifest/AndroidManifest.xml b/tests/auto/other/android/package_source_dir/custom_android_manifest/AndroidManifest.xml
new file mode 100644
index 00000000000..4f53295e979
--- /dev/null
+++ b/tests/auto/other/android/package_source_dir/custom_android_manifest/AndroidManifest.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.qtproject.example.tst_package_source_dir_custom_android_manifest"
+ android:installLocation="auto"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <supports-screens
+ android:anyDensity="true"
+ android:largeScreens="true"
+ android:normalScreens="true"
+ android:smallScreens="true" />
+ <application
+ android:name="org.qtproject.qt.android.bindings.QtApplication"
+ android:hardwareAccelerated="true"
+ android:label="tst_package_source_dir_custom_android_manifest_my"
+ android:requestLegacyExternalStorage="true"
+ android:allowBackup="true"
+ android:fullBackupOnly="false">
+ <activity
+ android:name="org.qtproject.qt.android.bindings.QtActivity"
+ android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
+ android:launchMode="singleTop"
+ android:screenOrientation="unspecified"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.app.lib_name"
+ android:value="tst_package_source_dir_custom_android_manifest" />
+
+ <meta-data
+ android:name="android.app.arguments"
+ android:value="" />
+ </activity>
+
+ <provider
+ android:name="androidx.core.content.FileProvider"
+ android:authorities="${applicationId}.qtprovider"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/qtprovider_paths"/>
+ </provider>
+ </application>
+</manifest>
diff --git a/tests/auto/other/android/package_source_dir/custom_android_manifest_bundle/app/AndroidManifest.xml b/tests/auto/other/android/package_source_dir/custom_android_manifest_bundle/app/AndroidManifest.xml
new file mode 100644
index 00000000000..4f53295e979
--- /dev/null
+++ b/tests/auto/other/android/package_source_dir/custom_android_manifest_bundle/app/AndroidManifest.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.qtproject.example.tst_package_source_dir_custom_android_manifest"
+ android:installLocation="auto"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <supports-screens
+ android:anyDensity="true"
+ android:largeScreens="true"
+ android:normalScreens="true"
+ android:smallScreens="true" />
+ <application
+ android:name="org.qtproject.qt.android.bindings.QtApplication"
+ android:hardwareAccelerated="true"
+ android:label="tst_package_source_dir_custom_android_manifest_my"
+ android:requestLegacyExternalStorage="true"
+ android:allowBackup="true"
+ android:fullBackupOnly="false">
+ <activity
+ android:name="org.qtproject.qt.android.bindings.QtActivity"
+ android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
+ android:launchMode="singleTop"
+ android:screenOrientation="unspecified"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.app.lib_name"
+ android:value="tst_package_source_dir_custom_android_manifest" />
+
+ <meta-data
+ android:name="android.app.arguments"
+ android:value="" />
+ </activity>
+
+ <provider
+ android:name="androidx.core.content.FileProvider"
+ android:authorities="${applicationId}.qtprovider"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/qtprovider_paths"/>
+ </provider>
+ </application>
+</manifest>
diff --git a/tests/auto/other/android/package_source_dir/partial_template/app/AndroidManifest.xml b/tests/auto/other/android/package_source_dir/partial_template/app/AndroidManifest.xml
new file mode 100644
index 00000000000..838d239e5f4
--- /dev/null
+++ b/tests/auto/other/android/package_source_dir/partial_template/app/AndroidManifest.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.qtproject.example.tst_package_source_dir_partial_template"
+ android:installLocation="auto"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <supports-screens
+ android:anyDensity="true"
+ android:largeScreens="true"
+ android:normalScreens="true"
+ android:smallScreens="true" />
+ <application
+ android:name="org.qtproject.qt.android.bindings.QtApplication"
+ android:hardwareAccelerated="true"
+ android:label="${appName}"
+ android:requestLegacyExternalStorage="true"
+ android:allowBackup="true"
+ android:fullBackupOnly="false">
+ <activity
+ android:name="org.qtproject.qt.android.bindings.QtActivity"
+ android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
+ android:launchMode="singleTop"
+ android:screenOrientation="unspecified"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.app.lib_name"
+ android:value="tst_package_source_dir_partial_template" />
+
+ <meta-data
+ android:name="android.app.arguments"
+ android:value="" />
+ </activity>
+
+ <provider
+ android:name="androidx.core.content.FileProvider"
+ android:authorities="${applicationId}.qtprovider"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/qtprovider_paths"/>
+ </provider>
+ </application>
+</manifest>
diff --git a/tests/auto/other/android/package_source_dir/partial_template/app/build.gradle.in b/tests/auto/other/android/package_source_dir/partial_template/app/build.gradle.in
new file mode 100644
index 00000000000..538f1ca6217
--- /dev/null
+++ b/tests/auto/other/android/package_source_dir/partial_template/app/build.gradle.in
@@ -0,0 +1,54 @@
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:8.6.0'
+ }
+}
+
+apply plugin: '@GRADLE_PLUGIN_TYPE@'
+
+dependencies {
+ @GRADLE_DEPENDENCIES@
+}
+
+android {
+ namespace '@PACKAGE_NAME@'
+ compileSdkVersion '@ANDROID_COMPILE_SDK_VERSION@'
+ buildToolsVersion '@ANDROID_BUILD_TOOLS_VERSION@'
+ ndkVersion '@ANDROID_NDK_REVISION@'
+
+ defaultConfig {
+ @DEFAULT_CONFIG_VALUES@
+ manifestPlaceholders = [ appName:"tst_package_source_dir_partial_template_my" ]
+ }
+
+ sourceSets {
+ main {
+@SOURCE_SETS@
+ }
+ }
+
+ tasks.withType(JavaCompile) {
+ options.incremental = true
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ lintOptions {
+ abortOnError false
+ }
+
+ aaptOptions {
+ // Do not compress Qt binary resources file
+ noCompress 'rcc'
+ }
+
+ @ANDROID_DEPLOYMENT_EXTRAS@
+}
diff --git a/tests/auto/other/android/package_source_dir/tst_android_package_source_dir.cpp b/tests/auto/other/android/package_source_dir/tst_android_package_source_dir.cpp
new file mode 100644
index 00000000000..d74d388371f
--- /dev/null
+++ b/tests/auto/other/android/package_source_dir/tst_android_package_source_dir.cpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QCoreApplication>
+#include <QJniObject>
+#include <QTest>
+#include <QDebug>
+
+using namespace QNativeInterface;
+
+Q_DECLARE_JNI_CLASS(ApplicationInfo, "android/content/pm/ApplicationInfo")
+Q_DECLARE_JNI_CLASS(PackageManager, "android/content/pm/PackageManager")
+Q_DECLARE_JNI_CLASS(CharSequence, "java/lang/CharSequence")
+
+class tst_android_package_source_dir : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void applicationName();
+
+private:
+};
+
+void tst_android_package_source_dir::applicationName()
+{
+ QJniObject appCtx = QAndroidApplication::context();
+ QVERIFY(appCtx.isValid());
+
+ const auto appInfo = appCtx.callMethod<QtJniTypes::ApplicationInfo>("getApplicationInfo");
+ QVERIFY(appInfo.isValid());
+
+ const auto packageManager = appCtx.callMethod<QtJniTypes::PackageManager>("getPackageManager");
+ QVERIFY(packageManager.isValid());
+
+ const auto appNameLabel =
+ appInfo.callMethod<QtJniTypes::CharSequence>("loadLabel", packageManager);
+ QVERIFY(appNameLabel.isValid());
+
+ const auto appName = appNameLabel.callMethod<jstring>("toString").toString();
+
+ QCOMPARE_EQ(appName, QString::fromLatin1(EXPECTED_APP_NAME));
+}
+
+QTEST_MAIN(tst_android_package_source_dir);
+
+#include "tst_android_package_source_dir.moc"
diff --git a/tests/auto/other/android/permissions/CMakeLists.txt b/tests/auto/other/android/permissions/CMakeLists.txt
new file mode 100644
index 00000000000..0424c674e1b
--- /dev/null
+++ b/tests/auto/other/android/permissions/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2025 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_android_permissions LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_android_permissions
+ SOURCES
+ tst_android_permissions.cpp
+)
+
+qt_add_android_permission(tst_android_permissions
+ NAME android.permission.ACCESS_COARSE_LOCATION
+)
+
+qt_add_android_permission(tst_android_permissions
+ NAME android.permission.ACCESS_FINE_LOCATION
+ ATTRIBUTES
+ maxSdkVersion 31
+)
diff --git a/tests/auto/other/android/permissions/tst_android_permissions.cpp b/tests/auto/other/android/permissions/tst_android_permissions.cpp
new file mode 100644
index 00000000000..5d7a255d3ac
--- /dev/null
+++ b/tests/auto/other/android/permissions/tst_android_permissions.cpp
@@ -0,0 +1,80 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QCoreApplication>
+#include <QJniObject>
+#include <QSet>
+#include <QString>
+#include <QTest>
+
+constexpr int GET_PERMISSIONS(0x00001000);
+
+using namespace QNativeInterface;
+using namespace Qt::StringLiterals;
+
+Q_DECLARE_JNI_CLASS(PackageManager, "android/content/pm/PackageManager")
+Q_DECLARE_JNI_CLASS(PackageInfo, "android/content/pm/PackageInfo")
+
+class tst_android_permissions : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void checkExpectedDefaults();
+ void checkNonExisting();
+ void checkNonDefaultPermissions();
+
+private:
+ QJniArray<QString> m_requestedPermissions;
+};
+
+void tst_android_permissions::initTestCase()
+{
+ QJniObject appCtx = QAndroidApplication::context();
+ QVERIFY(appCtx.isValid());
+
+ const auto packageName = appCtx.callMethod<QString>("getPackageName");
+ const auto packageManager = appCtx.callMethod<QtJniTypes::PackageManager>("getPackageManager");
+ QVERIFY(packageManager.isValid());
+
+ const auto packageInfo = QJniObject(packageManager.callMethod<QtJniTypes::PackageInfo>(
+ "getPackageInfo", packageName, jint(GET_PERMISSIONS)));
+ QVERIFY(packageInfo.isValid());
+
+ m_requestedPermissions = packageInfo.getField<QJniArray<QString>>("requestedPermissions");
+ QVERIFY(m_requestedPermissions.isValid());
+}
+
+void tst_android_permissions::checkExpectedDefaults()
+{
+ QSet<QString> expectedDefaults{ { "android.permission.INTERNET"_L1 },
+ { "android.permission.WRITE_EXTERNAL_STORAGE"_L1 },
+ { "android.permission.READ_EXTERNAL_STORAGE"_L1 } };
+
+ for (const auto &permission : m_requestedPermissions)
+ expectedDefaults.remove(permission);
+
+ QVERIFY(expectedDefaults.empty());
+}
+
+void tst_android_permissions::checkNonExisting()
+{
+ for (const auto &permission : m_requestedPermissions)
+ QCOMPARE_NE(permission, "android.permission.BLUETOOTH_SCAN");
+}
+
+void tst_android_permissions::checkNonDefaultPermissions()
+{
+ bool hasNonDefaultPermissions = false;
+ for (const auto &permission : m_requestedPermissions) {
+ if (permission == "android.permission.ACCESS_COARSE_LOCATION")
+ hasNonDefaultPermissions = true;
+ }
+
+ QVERIFY(hasNonDefaultPermissions);
+}
+
+QTEST_MAIN(tst_android_permissions);
+
+#include "tst_android_permissions.moc"
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 011852c28e4..7926c7a73aa 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -3701,7 +3701,7 @@ void tst_QAccessibility::dockWidgetTest()
// 1 close button
// 2 float button
QVERIFY(accDock1);
- QCOMPARE(accDock1->role(), QAccessible::Window);
+ QCOMPARE(accDock1->role(), QAccessible::Pane);
QCOMPARE(accDock1->text(QAccessible::Name), dock1->windowTitle());
QCOMPARE(accDock1->childCount(), 3);
@@ -3731,7 +3731,7 @@ void tst_QAccessibility::dockWidgetTest()
QVERIFY(!dock1Float->state().invisible);
QVERIFY(accDock2);
- QCOMPARE(accDock2->role(), QAccessible::Window);
+ QCOMPARE(accDock2->role(), QAccessible::Pane);
QCOMPARE(accDock2->text(QAccessible::Name), dock2->windowTitle());
QCOMPARE(accDock2->childCount(), 3);
@@ -3779,7 +3779,7 @@ void tst_QAccessibility::dockWidgetTest()
QAccessibleInterface *accDock3 = accMainWindow->child(4);
QVERIFY(accDock3);
- QCOMPARE(accDock3->role(), QAccessible::Window);
+ QCOMPARE(accDock3->role(), QAccessible::Pane);
QCOMPARE(accDock3->text(QAccessible::Name), dock3->windowTitle());
QCOMPARE(accDock3->childCount(), 2);
QAccessibleInterface *titleWidget = accDock3->child(1);
@@ -3788,6 +3788,14 @@ void tst_QAccessibility::dockWidgetTest()
QAccessibleInterface *dock3Widget = accDock3->child(0);
QCOMPARE(dock3Widget->text(QAccessible::Name), pb3->text());
+ // check role is changed to QAccessible::Window when dock window is undocked
+ // and a corresponding event is sent
+ QTestAccessibility::clearEvents();
+ dock3->setFloating(true);
+ QCOMPARE(accDock3->role(), QAccessible::Window);
+ QAccessibleEvent roleChangedEvent(dock3, QAccessible::RoleChanged);
+ QVERIFY(QTestAccessibility::containsEvent(&roleChangedEvent));
+
QTestAccessibility::clearEvents();
#endif // QT_CONFIG(dockwidget)
}
diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
index e10dd6da885..8787cc54bf6 100644
--- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
+#include <QtCore/qatomicscopedvaluerollback.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QTimer>
#ifdef QT_GUI_LIB
@@ -15,6 +16,8 @@
#endif
#include <QSet>
#include <vector>
+
+using namespace std::chrono_literals;
using namespace Qt::StringLiterals;
/* XPM test data for QPixmap, QImage tests (use drag cursors as example) */
@@ -105,6 +108,9 @@ public:
enum class MyClassEnum { MyClassEnumValue1, MyClassEnumValue2 };
Q_ENUM(MyClassEnum)
+private:
+ void defaultTryTimeoutData();
+
private slots:
void compare_unregistered_enums();
void compare_registered_enums();
@@ -152,6 +158,10 @@ private slots:
void tryVerify();
void tryVerify2();
void verifyExplicitOperatorBool();
+ void defaultTryVerifyTimeout_data();
+ void defaultTryVerifyTimeout();
+ void defaultTryCompareTimeout_data();
+ void defaultTryCompareTimeout();
};
enum MyUnregisteredEnum { MyUnregisteredEnumValue1, MyUnregisteredEnumValue2 };
@@ -841,5 +851,56 @@ void tst_Cmptest::verifyExplicitOperatorBool()
QVERIFY(!val2);
}
+void tst_Cmptest::defaultTryTimeoutData()
+{
+ QTest::addColumn<std::chrono::milliseconds>("timeout");
+ QTest::addRow("times-out") << 1ms;
+ QTest::addRow("ample-time") << 1000ms;
+}
+
+void tst_Cmptest::defaultTryVerifyTimeout_data()
+{
+ defaultTryTimeoutData();
+}
+
+void tst_Cmptest::defaultTryVerifyTimeout()
+{
+ QFETCH(const std::chrono::milliseconds, timeout);
+
+ // Check that the default is what expect.
+ QCOMPARE(QTest::defaultTryTimeout.load(std::memory_order_relaxed), 5s);
+
+ {
+ DeferredFlag trueEventually;
+ const auto innerScope = QAtomicScopedValueRollback(QTest::defaultTryTimeout, timeout, std::memory_order_relaxed);
+ QEXPECT_FAIL("times-out", "The timeout (std::chrono::milliseconds) is deliberately too short", Continue);
+ QTRY_VERIFY(trueEventually);
+ }
+
+ // innerScope has now been destroyed, so the timeout should be back to its default.
+ QCOMPARE(QTest::defaultTryTimeout.load(std::memory_order_relaxed), 5s);
+}
+
+void tst_Cmptest::defaultTryCompareTimeout_data()
+{
+ defaultTryTimeoutData();
+}
+
+void tst_Cmptest::defaultTryCompareTimeout()
+{
+ QFETCH(const std::chrono::milliseconds, timeout);
+
+ DeferredFlag trueAlready(true);
+ {
+ DeferredFlag trueEventually;
+ const auto innerScope = QAtomicScopedValueRollback(QTest::defaultTryTimeout, timeout, std::memory_order_relaxed);
+ QEXPECT_FAIL("times-out", "The timeout (std::chrono::milliseconds) is deliberately too short", Continue);
+ QTRY_COMPARE(trueEventually, trueAlready);
+ }
+
+ // innerScope has now been destroyed, so the timeout should be back to its default.
+ QCOMPARE(QTest::defaultTryTimeout.load(std::memory_order_relaxed), 5s);
+}
+
QTEST_MAIN(tst_Cmptest)
#include "tst_cmptest.moc"
diff --git a/tests/auto/testlib/selftests/expected_cmptest.junitxml b/tests/auto/testlib/selftests/expected_cmptest.junitxml
index ce6a1c0c76e..232b86117af 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.junitxml
+++ b/tests/auto/testlib/selftests/expected_cmptest.junitxml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<testsuite name="tst_Cmptest" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="74" failures="51" errors="0" skipped="0" time="@TEST_DURATION@">
+<testsuite name="tst_Cmptest" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="78" failures="51" errors="0" skipped="0" time="@TEST_DURATION@">
<properties>
<property name="QTestVersion" value="@INSERT_QT_VERSION_HERE@"/>
<property name="QtVersion" value="@INSERT_QT_VERSION_HERE@"/>
@@ -321,5 +321,17 @@
<failure type="fail" message="&apos;!c&apos; returned FALSE. (Should time out and fail)"/>
</testcase>
<testcase name="verifyExplicitOperatorBool" classname="tst_Cmptest" time="@TEST_DURATION@"/>
+ <testcase name="defaultTryVerifyTimeout(times&#x002D;out)" classname="tst_Cmptest" time="@TEST_DURATION@">
+ <system-out>
+ <![CDATA[The timeout (std::chrono::milliseconds) is deliberately too short]]>
+ </system-out>
+ </testcase>
+ <testcase name="defaultTryVerifyTimeout(ample&#x002D;time)" classname="tst_Cmptest" time="@TEST_DURATION@"/>
+ <testcase name="defaultTryCompareTimeout(times&#x002D;out)" classname="tst_Cmptest" time="@TEST_DURATION@">
+ <system-out>
+ <![CDATA[The timeout (std::chrono::milliseconds) is deliberately too short]]>
+ </system-out>
+ </testcase>
+ <testcase name="defaultTryCompareTimeout(ample&#x002D;time)" classname="tst_Cmptest" time="@TEST_DURATION@"/>
<testcase name="cleanupTestCase" classname="tst_Cmptest" time="@TEST_DURATION@"/>
</testsuite>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml
index 9919dde3241..b31bc2aef7d 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.lightxml
+++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml
@@ -486,6 +486,32 @@
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
+ <TestFunction name="defaultTryVerifyTimeout">
+ <Incident type="xfail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[times-out]]></DataTag>
+ <Description><![CDATA[The timeout (std::chrono::milliseconds) is deliberately too short]]></Description>
+ </Incident>
+ <Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[times-out]]></DataTag>
+ </Incident>
+ <Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[ample-time]]></DataTag>
+ </Incident>
+ <Duration msecs="0"/>
+ </TestFunction>
+ <TestFunction name="defaultTryCompareTimeout">
+ <Incident type="xfail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[times-out]]></DataTag>
+ <Description><![CDATA[The timeout (std::chrono::milliseconds) is deliberately too short]]></Description>
+ </Incident>
+ <Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[times-out]]></DataTag>
+ </Incident>
+ <Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[ample-time]]></DataTag>
+ </Incident>
+ <Duration msecs="0"/>
+ </TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.tap b/tests/auto/testlib/selftests/expected_cmptest.tap
index 77118713717..180567f2112 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.tap
+++ b/tests/auto/testlib/selftests/expected_cmptest.tap
@@ -719,8 +719,30 @@ not ok 72 - tryVerify2()
line: 0
...
ok 73 - verifyExplicitOperatorBool()
-ok 74 - cleanupTestCase()
-1..74
-# tests 74
-# pass 23
+not ok 74 - defaultTryVerifyTimeout(times-out) # TODO The timeout (std::chrono::milliseconds) is deliberately too short
+ ---
+ extensions:
+ messages:
+ - severity: xfail
+ message: The timeout (std::chrono::milliseconds) is deliberately too short
+ at: tst_Cmptest::defaultTryVerifyTimeout() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:0)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 0
+ ...
+ok 75 - defaultTryVerifyTimeout(ample-time)
+not ok 76 - defaultTryCompareTimeout(times-out) # TODO The timeout (std::chrono::milliseconds) is deliberately too short
+ ---
+ extensions:
+ messages:
+ - severity: xfail
+ message: The timeout (std::chrono::milliseconds) is deliberately too short
+ at: tst_Cmptest::defaultTryCompareTimeout() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:0)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 0
+ ...
+ok 77 - defaultTryCompareTimeout(ample-time)
+ok 78 - cleanupTestCase()
+1..78
+# tests 78
+# pass 27
# fail 51
diff --git a/tests/auto/testlib/selftests/expected_cmptest.teamcity b/tests/auto/testlib/selftests/expected_cmptest.teamcity
index c48262e0376..f88e44f3ee2 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.teamcity
+++ b/tests/auto/testlib/selftests/expected_cmptest.teamcity
@@ -216,6 +216,16 @@
##teamcity[testFinished name='tryVerify2()' flowId='tst_Cmptest']
##teamcity[testStarted name='verifyExplicitOperatorBool()' flowId='tst_Cmptest']
##teamcity[testFinished name='verifyExplicitOperatorBool()' flowId='tst_Cmptest']
+##teamcity[testStarted name='defaultTryVerifyTimeout(times-out)' flowId='tst_Cmptest']
+##teamcity[testStdOut name='defaultTryVerifyTimeout(times-out)' out='XFAIL |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]: The timeout (std::chrono::milliseconds) is deliberately too short' flowId='tst_Cmptest']
+##teamcity[testFinished name='defaultTryVerifyTimeout(times-out)' flowId='tst_Cmptest']
+##teamcity[testStarted name='defaultTryVerifyTimeout(ample-time)' flowId='tst_Cmptest']
+##teamcity[testFinished name='defaultTryVerifyTimeout(ample-time)' flowId='tst_Cmptest']
+##teamcity[testStarted name='defaultTryCompareTimeout(times-out)' flowId='tst_Cmptest']
+##teamcity[testStdOut name='defaultTryCompareTimeout(times-out)' out='XFAIL |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]: The timeout (std::chrono::milliseconds) is deliberately too short' flowId='tst_Cmptest']
+##teamcity[testFinished name='defaultTryCompareTimeout(times-out)' flowId='tst_Cmptest']
+##teamcity[testStarted name='defaultTryCompareTimeout(ample-time)' flowId='tst_Cmptest']
+##teamcity[testFinished name='defaultTryCompareTimeout(ample-time)' flowId='tst_Cmptest']
##teamcity[testStarted name='cleanupTestCase()' flowId='tst_Cmptest']
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Cmptest']
##teamcity[testSuiteFinished name='tst_Cmptest' flowId='tst_Cmptest']
diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt
index efb305654f4..4c4b340a5ca 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.txt
+++ b/tests/auto/testlib/selftests/expected_cmptest.txt
@@ -252,6 +252,14 @@ FAIL! : tst_Cmptest::tryVerify() '!c' returned FALSE. ()
FAIL! : tst_Cmptest::tryVerify2() '!c' returned FALSE. (Should time out and fail)
Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
PASS : tst_Cmptest::verifyExplicitOperatorBool()
+XFAIL : tst_Cmptest::defaultTryVerifyTimeout(times-out) The timeout (std::chrono::milliseconds) is deliberately too short
+ Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
+PASS : tst_Cmptest::defaultTryVerifyTimeout(times-out)
+PASS : tst_Cmptest::defaultTryVerifyTimeout(ample-time)
+XFAIL : tst_Cmptest::defaultTryCompareTimeout(times-out) The timeout (std::chrono::milliseconds) is deliberately too short
+ Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
+PASS : tst_Cmptest::defaultTryCompareTimeout(times-out)
+PASS : tst_Cmptest::defaultTryCompareTimeout(ample-time)
PASS : tst_Cmptest::cleanupTestCase()
-Totals: 23 passed, 51 failed, 0 skipped, 0 blacklisted, 0ms
+Totals: 27 passed, 51 failed, 0 skipped, 0 blacklisted, 0ms
********* Finished testing of tst_Cmptest *********
diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml
index f6ed03b0e9f..5ec93c5ce7e 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.xml
+++ b/tests/auto/testlib/selftests/expected_cmptest.xml
@@ -488,6 +488,32 @@
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
+ <TestFunction name="defaultTryVerifyTimeout">
+ <Incident type="xfail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[times-out]]></DataTag>
+ <Description><![CDATA[The timeout (std::chrono::milliseconds) is deliberately too short]]></Description>
+ </Incident>
+ <Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[times-out]]></DataTag>
+ </Incident>
+ <Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[ample-time]]></DataTag>
+ </Incident>
+ <Duration msecs="0"/>
+ </TestFunction>
+ <TestFunction name="defaultTryCompareTimeout">
+ <Incident type="xfail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[times-out]]></DataTag>
+ <Description><![CDATA[The timeout (std::chrono::milliseconds) is deliberately too short]]></Description>
+ </Incident>
+ <Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[times-out]]></DataTag>
+ </Incident>
+ <Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[ample-time]]></DataTag>
+ </Incident>
+ <Duration msecs="0"/>
+ </TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.junitxml b/tests/auto/testlib/selftests/expected_threewaycompare.junitxml
index e10872ef1ba..37551ecd23d 100644
--- a/tests/auto/testlib/selftests/expected_threewaycompare.junitxml
+++ b/tests/auto/testlib/selftests/expected_threewaycompare.junitxml
@@ -25,8 +25,8 @@
</testcase>
<testcase name="compareFloats(Qt::partial_ordering::equivalent)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (lhs): 1
- Right (rhs): 1
+ <![CDATA[ Left (lhs): 1 (0x1p+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::less]]>
</failure>
@@ -34,24 +34,24 @@
<testcase name="compareFloats(Qt::partial_ordering::less)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"/>
<testcase name="compareFloats(Qt::partial_ordering::greater)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (lhs): 1.1
- Right (rhs): 1
+ <![CDATA[ Left (lhs): 1.1 (0x1.19999ap+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): Qt::partial_ordering::less]]>
</failure>
</testcase>
<testcase name="compareDoubles(Qt::partial_ordering::equivalent)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (lhs): 0
- Right (rhs): 0
+ <![CDATA[ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0 (0x0p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::greater]]>
</failure>
</testcase>
<testcase name="compareDoubles(Qt::partial_ordering::less)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (lhs): 0
- Right (rhs): 0.1
+ <![CDATA[ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0.1 (0x1.999999999999ap-4)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): Qt::partial_ordering::greater]]>
</failure>
@@ -161,16 +161,16 @@
</testcase>
<testcase name="stdCompareFloats(std::partial_ordering::equivalent)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (lhs): 2
- Right (rhs): 2
+ <![CDATA[ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 2 (0x1p+1)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::less]]>
</failure>
</testcase>
<testcase name="stdCompareFloats(std::partial_ordering::less)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (lhs): 2
- Right (rhs): 1.1
+ <![CDATA[ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 1.1 (0x1.19999ap+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): std::partial_ordering::less]]>
</failure>
@@ -178,16 +178,16 @@
<testcase name="stdCompareFloats(std::partial_ordering::greater)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"/>
<testcase name="stdCompareDoubles(std::partial_ordering::equivalent)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (lhs): 0.15
- Right (rhs): 0.15
+ <![CDATA[ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.15 (0x1.3333333333333p-3)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::greater]]>
</failure>
</testcase>
<testcase name="stdCompareDoubles(std::partial_ordering::less)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (lhs): 0.15
- Right (rhs): 0.25
+ <![CDATA[ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.25 (0x1p-2)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): std::partial_ordering::greater]]>
</failure>
@@ -288,8 +288,8 @@
</testcase>
<testcase name="checkWeakComparison" classname="tst_ThreeWayCompare" time="@TEST_DURATION@">
<failure type="fail" message="The result of operator&lt;=&gt;() is not what was expected">
- <![CDATA[ Left (june) : 2012/06/20 14:33:02.500[CEST]
- Right (juneLater): 2012/06/20 14:33:02.501[CEST]
+ <![CDATA[ Left (june) : 2012/06/20 14:33:02.500[UTC]
+ Right (juneLater): 2012/06/20 14:33:02.501[UTC]
Actual (june <=> juneLater) : std::weak_ordering::less
Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater]]>
</failure>
diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.lightxml b/tests/auto/testlib/selftests/expected_threewaycompare.lightxml
index 75679c5e374..082255a2c41 100644
--- a/tests/auto/testlib/selftests/expected_threewaycompare.lightxml
+++ b/tests/auto/testlib/selftests/expected_threewaycompare.lightxml
@@ -33,8 +33,8 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[Qt::partial_ordering::equivalent]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 1
- Right (rhs): 1
+ Left (lhs): 1 (0x1p+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::less]]></Description>
</Incident>
@@ -44,8 +44,8 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[Qt::partial_ordering::greater]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 1.1
- Right (rhs): 1
+ Left (lhs): 1.1 (0x1.19999ap+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): Qt::partial_ordering::less]]></Description>
</Incident>
@@ -55,16 +55,16 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[Qt::partial_ordering::equivalent]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 0
- Right (rhs): 0
+ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0 (0x0p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::greater]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[Qt::partial_ordering::less]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 0
- Right (rhs): 0.1
+ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0.1 (0x1.999999999999ap-4)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): Qt::partial_ordering::greater]]></Description>
</Incident>
@@ -209,16 +209,16 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[std::partial_ordering::equivalent]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 2
- Right (rhs): 2
+ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 2 (0x1p+1)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::less]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[std::partial_ordering::less]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 2
- Right (rhs): 1.1
+ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 1.1 (0x1.19999ap+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): std::partial_ordering::less]]></Description>
</Incident>
@@ -231,16 +231,16 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[std::partial_ordering::equivalent]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 0.15
- Right (rhs): 0.15
+ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.15 (0x1.3333333333333p-3)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::greater]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[std::partial_ordering::less]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 0.15
- Right (rhs): 0.25
+ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.25 (0x1p-2)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): std::partial_ordering::greater]]></Description>
</Incident>
@@ -372,8 +372,8 @@
<TestFunction name="checkWeakComparison">
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (june) : 2012/06/20 14:33:02.500[CEST]
- Right (juneLater): 2012/06/20 14:33:02.501[CEST]
+ Left (june) : 2012/06/20 14:33:02.500[UTC]
+ Right (juneLater): 2012/06/20 14:33:02.501[UTC]
Actual (june <=> juneLater) : std::weak_ordering::less
Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater]]></Description>
</Incident>
diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.tap b/tests/auto/testlib/selftests/expected_threewaycompare.tap
index daeae42c06f..5d464e0e648 100644
--- a/tests/auto/testlib/selftests/expected_threewaycompare.tap
+++ b/tests/auto/testlib/selftests/expected_threewaycompare.tap
@@ -27,8 +27,8 @@ not ok 4 - compareInts(Qt::strong_ordering::greater)
not ok 5 - compareFloats(Qt::partial_ordering::equivalent)
---
# The result of operator<=>() is not what was expected
- Left (lhs): 1
- Right (rhs): 1
+ Left (lhs): 1 (0x1p+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::less
at: tst_ThreeWayCompare::compareFloats() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
@@ -39,8 +39,8 @@ ok 6 - compareFloats(Qt::partial_ordering::less)
not ok 7 - compareFloats(Qt::partial_ordering::greater)
---
# The result of operator<=>() is not what was expected
- Left (lhs): 1.1
- Right (rhs): 1
+ Left (lhs): 1.1 (0x1.19999ap+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): Qt::partial_ordering::less
at: tst_ThreeWayCompare::compareFloats() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
@@ -50,8 +50,8 @@ not ok 7 - compareFloats(Qt::partial_ordering::greater)
not ok 8 - compareDoubles(Qt::partial_ordering::equivalent)
---
# The result of operator<=>() is not what was expected
- Left (lhs): 0
- Right (rhs): 0
+ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0 (0x0p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::greater
at: tst_ThreeWayCompare::compareDoubles() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
@@ -61,8 +61,8 @@ not ok 8 - compareDoubles(Qt::partial_ordering::equivalent)
not ok 9 - compareDoubles(Qt::partial_ordering::less)
---
# The result of operator<=>() is not what was expected
- Left (lhs): 0
- Right (rhs): 0.1
+ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0.1 (0x1.999999999999ap-4)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): Qt::partial_ordering::greater
at: tst_ThreeWayCompare::compareDoubles() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
@@ -211,8 +211,8 @@ not ok 28 - stdCompareInts(std::strong_ordering::greater)
not ok 29 - stdCompareFloats(std::partial_ordering::equivalent)
---
# The result of operator<=>() is not what was expected
- Left (lhs): 2
- Right (rhs): 2
+ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 2 (0x1p+1)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::less
at: tst_ThreeWayCompare::stdCompareFloats() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
@@ -222,8 +222,8 @@ not ok 29 - stdCompareFloats(std::partial_ordering::equivalent)
not ok 30 - stdCompareFloats(std::partial_ordering::less)
---
# The result of operator<=>() is not what was expected
- Left (lhs): 2
- Right (rhs): 1.1
+ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 1.1 (0x1.19999ap+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): std::partial_ordering::less
at: tst_ThreeWayCompare::stdCompareFloats() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
@@ -234,8 +234,8 @@ ok 31 - stdCompareFloats(std::partial_ordering::greater)
not ok 32 - stdCompareDoubles(std::partial_ordering::equivalent)
---
# The result of operator<=>() is not what was expected
- Left (lhs): 0.15
- Right (rhs): 0.15
+ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.15 (0x1.3333333333333p-3)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::greater
at: tst_ThreeWayCompare::stdCompareDoubles() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
@@ -245,8 +245,8 @@ not ok 32 - stdCompareDoubles(std::partial_ordering::equivalent)
not ok 33 - stdCompareDoubles(std::partial_ordering::less)
---
# The result of operator<=>() is not what was expected
- Left (lhs): 0.15
- Right (rhs): 0.25
+ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.25 (0x1p-2)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): std::partial_ordering::greater
at: tst_ThreeWayCompare::stdCompareDoubles() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
@@ -383,8 +383,8 @@ not ok 50 - checkComparisonForTemporaryObjects()
not ok 51 - checkWeakComparison()
---
# The result of operator<=>() is not what was expected
- Left (june) : 2012/06/20 14:33:02.500[CEST]
- Right (juneLater): 2012/06/20 14:33:02.501[CEST]
+ Left (june) : 2012/06/20 14:33:02.500[UTC]
+ Right (juneLater): 2012/06/20 14:33:02.501[UTC]
Actual (june <=> juneLater) : std::weak_ordering::less
Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater
at: tst_ThreeWayCompare::checkWeakComparison() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0)
diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.teamcity b/tests/auto/testlib/selftests/expected_threewaycompare.teamcity
index 2eed5bdb422..6b92880418e 100644
--- a/tests/auto/testlib/selftests/expected_threewaycompare.teamcity
+++ b/tests/auto/testlib/selftests/expected_threewaycompare.teamcity
@@ -10,18 +10,18 @@
##teamcity[testFailed name='compareInts(Qt::strong_ordering::greater)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2|n Right (rhs): 1|n Actual (lhs <=> rhs) : std::strong_ordering::greater|n Expected (expectedOrder): Qt::strong_ordering::equal' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='compareInts(Qt::strong_ordering::greater)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='compareFloats(Qt::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='compareFloats(Qt::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 1|n Right (rhs): 1|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): Qt::partial_ordering::less' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='compareFloats(Qt::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 1 (0x1p+0)|n Right (rhs): 1 (0x1p+0)|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): Qt::partial_ordering::less' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='compareFloats(Qt::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='compareFloats(Qt::partial_ordering::less)' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='compareFloats(Qt::partial_ordering::less)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='compareFloats(Qt::partial_ordering::greater)' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='compareFloats(Qt::partial_ordering::greater)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 1.1|n Right (rhs): 1|n Actual (lhs <=> rhs) : std::partial_ordering::greater|n Expected (expectedOrder): Qt::partial_ordering::less' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='compareFloats(Qt::partial_ordering::greater)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 1.1 (0x1.19999ap+0)|n Right (rhs): 1 (0x1p+0)|n Actual (lhs <=> rhs) : std::partial_ordering::greater|n Expected (expectedOrder): Qt::partial_ordering::less' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='compareFloats(Qt::partial_ordering::greater)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='compareDoubles(Qt::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='compareDoubles(Qt::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0|n Right (rhs): 0|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): Qt::partial_ordering::greater' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='compareDoubles(Qt::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0 (0x0p+0)|n Right (rhs): 0 (0x0p+0)|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): Qt::partial_ordering::greater' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='compareDoubles(Qt::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='compareDoubles(Qt::partial_ordering::less)' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='compareDoubles(Qt::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0|n Right (rhs): 0.1|n Actual (lhs <=> rhs) : std::partial_ordering::less|n Expected (expectedOrder): Qt::partial_ordering::greater' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='compareDoubles(Qt::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0 (0x0p+0)|n Right (rhs): 0.1 (0x1.999999999999ap-4)|n Actual (lhs <=> rhs) : std::partial_ordering::less|n Expected (expectedOrder): Qt::partial_ordering::greater' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='compareDoubles(Qt::partial_ordering::less)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='compareDoubles(Qt::partial_ordering::greater)' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='compareDoubles(Qt::partial_ordering::greater)' flowId='tst_ThreeWayCompare']
@@ -74,18 +74,18 @@
##teamcity[testFailed name='stdCompareInts(std::strong_ordering::greater)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): -2|n Right (rhs): 1|n Actual (lhs <=> rhs) : std::strong_ordering::less|n Expected (expectedOrder): std::strong_ordering::equal' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='stdCompareInts(std::strong_ordering::greater)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='stdCompareFloats(std::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='stdCompareFloats(std::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2|n Right (rhs): 2|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): std::partial_ordering::less' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='stdCompareFloats(std::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2 (0x1p+1)|n Right (rhs): 2 (0x1p+1)|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): std::partial_ordering::less' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='stdCompareFloats(std::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='stdCompareFloats(std::partial_ordering::less)' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='stdCompareFloats(std::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2|n Right (rhs): 1.1|n Actual (lhs <=> rhs) : std::partial_ordering::greater|n Expected (expectedOrder): std::partial_ordering::less' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='stdCompareFloats(std::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2 (0x1p+1)|n Right (rhs): 1.1 (0x1.19999ap+0)|n Actual (lhs <=> rhs) : std::partial_ordering::greater|n Expected (expectedOrder): std::partial_ordering::less' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='stdCompareFloats(std::partial_ordering::less)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='stdCompareFloats(std::partial_ordering::greater)' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='stdCompareFloats(std::partial_ordering::greater)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='stdCompareDoubles(std::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='stdCompareDoubles(std::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0.15|n Right (rhs): 0.15|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): std::partial_ordering::greater' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='stdCompareDoubles(std::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0.15 (0x1.3333333333333p-3)|n Right (rhs): 0.15 (0x1.3333333333333p-3)|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): std::partial_ordering::greater' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='stdCompareDoubles(std::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='stdCompareDoubles(std::partial_ordering::less)' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='stdCompareDoubles(std::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0.15|n Right (rhs): 0.25|n Actual (lhs <=> rhs) : std::partial_ordering::less|n Expected (expectedOrder): std::partial_ordering::greater' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='stdCompareDoubles(std::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0.15 (0x1.3333333333333p-3)|n Right (rhs): 0.25 (0x1p-2)|n Actual (lhs <=> rhs) : std::partial_ordering::less|n Expected (expectedOrder): std::partial_ordering::greater' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='stdCompareDoubles(std::partial_ordering::less)' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='stdCompareDoubles(std::partial_ordering::greater)' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='stdCompareDoubles(std::partial_ordering::greater)' flowId='tst_ThreeWayCompare']
@@ -133,7 +133,7 @@
##teamcity[testFailed name='checkComparisonForTemporaryObjects()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (getClassForValue(0).getValuePointer()): MyClass(2) on memory address with index 0|n Right (getClassForValue(1).getValuePointer()): MyClass(1) on memory address with index 1|n Actual (getClassForValue(0).getValuePointer() <=> getClassForValue(1).getValuePointer()): std::strong_ordering::less|n Expected (std::strong_ordering::equal) : std::strong_ordering::equal' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='checkComparisonForTemporaryObjects()' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='checkWeakComparison()' flowId='tst_ThreeWayCompare']
-##teamcity[testFailed name='checkWeakComparison()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (june) : 2012/06/20 14:33:02.500|[CEST|]|n Right (juneLater): 2012/06/20 14:33:02.501|[CEST|]|n Actual (june <=> juneLater) : std::weak_ordering::less|n Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater' flowId='tst_ThreeWayCompare']
+##teamcity[testFailed name='checkWeakComparison()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (june) : 2012/06/20 14:33:02.500|[UTC|]|n Right (juneLater): 2012/06/20 14:33:02.501|[UTC|]|n Actual (june <=> juneLater) : std::weak_ordering::less|n Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='checkWeakComparison()' flowId='tst_ThreeWayCompare']
##teamcity[testStarted name='cleanupTestCase()' flowId='tst_ThreeWayCompare']
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_ThreeWayCompare']
diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.txt b/tests/auto/testlib/selftests/expected_threewaycompare.txt
index 896cec72819..45496e4420c 100644
--- a/tests/auto/testlib/selftests/expected_threewaycompare.txt
+++ b/tests/auto/testlib/selftests/expected_threewaycompare.txt
@@ -15,27 +15,27 @@ FAIL! : tst_ThreeWayCompare::compareInts(Qt::strong_ordering::greater) The resu
Expected (expectedOrder): Qt::strong_ordering::equal
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
FAIL! : tst_ThreeWayCompare::compareFloats(Qt::partial_ordering::equivalent) The result of operator<=>() is not what was expected
- Left (lhs): 1
- Right (rhs): 1
+ Left (lhs): 1 (0x1p+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::less
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
PASS : tst_ThreeWayCompare::compareFloats(Qt::partial_ordering::less)
FAIL! : tst_ThreeWayCompare::compareFloats(Qt::partial_ordering::greater) The result of operator<=>() is not what was expected
- Left (lhs): 1.1
- Right (rhs): 1
+ Left (lhs): 1.1 (0x1.19999ap+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): Qt::partial_ordering::less
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
FAIL! : tst_ThreeWayCompare::compareDoubles(Qt::partial_ordering::equivalent) The result of operator<=>() is not what was expected
- Left (lhs): 0
- Right (rhs): 0
+ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0 (0x0p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::greater
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
FAIL! : tst_ThreeWayCompare::compareDoubles(Qt::partial_ordering::less) The result of operator<=>() is not what was expected
- Left (lhs): 0
- Right (rhs): 0.1
+ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0.1 (0x1.999999999999ap-4)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): Qt::partial_ordering::greater
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
@@ -119,27 +119,27 @@ FAIL! : tst_ThreeWayCompare::stdCompareInts(std::strong_ordering::greater) The
Expected (expectedOrder): std::strong_ordering::equal
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
FAIL! : tst_ThreeWayCompare::stdCompareFloats(std::partial_ordering::equivalent) The result of operator<=>() is not what was expected
- Left (lhs): 2
- Right (rhs): 2
+ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 2 (0x1p+1)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::less
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
FAIL! : tst_ThreeWayCompare::stdCompareFloats(std::partial_ordering::less) The result of operator<=>() is not what was expected
- Left (lhs): 2
- Right (rhs): 1.1
+ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 1.1 (0x1.19999ap+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): std::partial_ordering::less
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
PASS : tst_ThreeWayCompare::stdCompareFloats(std::partial_ordering::greater)
FAIL! : tst_ThreeWayCompare::stdCompareDoubles(std::partial_ordering::equivalent) The result of operator<=>() is not what was expected
- Left (lhs): 0.15
- Right (rhs): 0.15
+ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.15 (0x1.3333333333333p-3)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::greater
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
FAIL! : tst_ThreeWayCompare::stdCompareDoubles(std::partial_ordering::less) The result of operator<=>() is not what was expected
- Left (lhs): 0.15
- Right (rhs): 0.25
+ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.25 (0x1p-2)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): std::partial_ordering::greater
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
@@ -216,8 +216,8 @@ FAIL! : tst_ThreeWayCompare::checkComparisonForTemporaryObjects() The result of
Expected (std::strong_ordering::equal) : std::strong_ordering::equal
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
FAIL! : tst_ThreeWayCompare::checkWeakComparison() The result of operator<=>() is not what was expected
- Left (june) : 2012/06/20 14:33:02.500[CEST]
- Right (juneLater): 2012/06/20 14:33:02.501[CEST]
+ Left (june) : 2012/06/20 14:33:02.500[UTC]
+ Right (juneLater): 2012/06/20 14:33:02.501[UTC]
Actual (june <=> juneLater) : std::weak_ordering::less
Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater
Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)]
diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.xml b/tests/auto/testlib/selftests/expected_threewaycompare.xml
index 5e8f1f93bac..a3f4d38ee5a 100644
--- a/tests/auto/testlib/selftests/expected_threewaycompare.xml
+++ b/tests/auto/testlib/selftests/expected_threewaycompare.xml
@@ -35,8 +35,8 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[Qt::partial_ordering::equivalent]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 1
- Right (rhs): 1
+ Left (lhs): 1 (0x1p+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::less]]></Description>
</Incident>
@@ -46,8 +46,8 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[Qt::partial_ordering::greater]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 1.1
- Right (rhs): 1
+ Left (lhs): 1.1 (0x1.19999ap+0)
+ Right (rhs): 1 (0x1p+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): Qt::partial_ordering::less]]></Description>
</Incident>
@@ -57,16 +57,16 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[Qt::partial_ordering::equivalent]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 0
- Right (rhs): 0
+ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0 (0x0p+0)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): Qt::partial_ordering::greater]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[Qt::partial_ordering::less]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 0
- Right (rhs): 0.1
+ Left (lhs): 0 (0x0p+0)
+ Right (rhs): 0.1 (0x1.999999999999ap-4)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): Qt::partial_ordering::greater]]></Description>
</Incident>
@@ -211,16 +211,16 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[std::partial_ordering::equivalent]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 2
- Right (rhs): 2
+ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 2 (0x1p+1)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::less]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[std::partial_ordering::less]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 2
- Right (rhs): 1.1
+ Left (lhs): 2 (0x1p+1)
+ Right (rhs): 1.1 (0x1.19999ap+0)
Actual (lhs <=> rhs) : std::partial_ordering::greater
Expected (expectedOrder): std::partial_ordering::less]]></Description>
</Incident>
@@ -233,16 +233,16 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[std::partial_ordering::equivalent]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 0.15
- Right (rhs): 0.15
+ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.15 (0x1.3333333333333p-3)
Actual (lhs <=> rhs) : std::partial_ordering::equivalent
Expected (expectedOrder): std::partial_ordering::greater]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<DataTag><![CDATA[std::partial_ordering::less]]></DataTag>
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (lhs): 0.15
- Right (rhs): 0.25
+ Left (lhs): 0.15 (0x1.3333333333333p-3)
+ Right (rhs): 0.25 (0x1p-2)
Actual (lhs <=> rhs) : std::partial_ordering::less
Expected (expectedOrder): std::partial_ordering::greater]]></Description>
</Incident>
@@ -374,8 +374,8 @@
<TestFunction name="checkWeakComparison">
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0">
<Description><![CDATA[The result of operator<=>() is not what was expected
- Left (june) : 2012/06/20 14:33:02.500[CEST]
- Right (juneLater): 2012/06/20 14:33:02.501[CEST]
+ Left (june) : 2012/06/20 14:33:02.500[UTC]
+ Right (juneLater): 2012/06/20 14:33:02.501[UTC]
Actual (june <=> juneLater) : std::weak_ordering::less
Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater]]></Description>
</Incident>
diff --git a/tests/auto/testlib/selftests/mouse/tst_mouse.cpp b/tests/auto/testlib/selftests/mouse/tst_mouse.cpp
index 4af55adde91..ae8fa54dcea 100644
--- a/tests/auto/testlib/selftests/mouse/tst_mouse.cpp
+++ b/tests/auto/testlib/selftests/mouse/tst_mouse.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include <QtGui/QWindow>
#include <QtGui/QCursor>
#include <QtGui/private/qguiapplication_p.h>
@@ -256,8 +257,9 @@ void tst_Mouse::doubleClick()
{
MouseWindow w;
w.show();
- w.setGeometry(100, 100, 200, 200);
+ w.resize(200, 200);
QVERIFY(QTest::qWaitForWindowActive(&w));
+ QVERIFY(QTestPrivate::ensurePositionTopLeft(&w));
// click
QPoint point(10, 10);
diff --git a/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp b/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp
index bcc544d33a1..4a290f9f2fb 100644
--- a/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp
+++ b/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp
@@ -231,7 +231,7 @@ void tst_ThreeWayCompare::checkWeakComparison()
QCOMPARE_3WAY(example_left, example_right, std::weak_ordering::less);
- QDateTime june(QDate(2012, 6, 20), QTime(14, 33, 2, 500));
+ QDateTime june(QDate(2012, 6, 20), QTime(14, 33, 2, 500), QTimeZone::UTC);
QDateTime juneLater = june.addMSecs(1);
QCOMPARE_3WAY(june, juneLater, Qt::weak_ordering::greater);
#endif
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index ab88dd78111..217122100a0 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -7,7 +7,7 @@
https://developercommunity.visualstudio.com/t/Regression:-c-compilation-failure-in-c/10926790
*/
#include <QtCore/qcompilerdetection.h>
-#if defined(Q_CC_MSVC_ONLY) && (_MSC_FULL_VER >= 194435209) && (_MSC_FULL_VER < 194500000)
+#if defined(Q_CC_MSVC_ONLY) && (_MSC_FULL_VER >= 194435208) && (_MSC_FULL_VER < 194500000)
# define MSVC_ENUM_BUG
#endif
diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist b/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist
new file mode 100644
index 00000000000..5468597e2b4
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist
@@ -0,0 +1 @@
+<invalid>
diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro b/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro
new file mode 100644
index 00000000000..0230f9c6736
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro
@@ -0,0 +1,2 @@
+SOURCES += main.cpp
+QMAKE_INFO_PLIST = Info.plist
diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp b/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp
new file mode 100644
index 00000000000..905869dfa38
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/tests/auto/tools/qmake/testdata/windows_resources/REUSE.toml b/tests/auto/tools/qmake/testdata/windows_resources/REUSE.toml
index 8d05566c678..65bfc74258c 100644
--- a/tests/auto/tools/qmake/testdata/windows_resources/REUSE.toml
+++ b/tests/auto/tools/qmake/testdata/windows_resources/REUSE.toml
@@ -3,5 +3,5 @@ version = 1
[[annotations]]
path = ["version.inc"]
precedence = "override"
-SPDX-FileCopyrightText = "Copyright (C) 2019 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only"
diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp
index 278cf4ad232..080f0abbdaa 100644
--- a/tests/auto/tools/qmake/tst_qmake.cpp
+++ b/tests/auto/tools/qmake/tst_qmake.cpp
@@ -47,6 +47,7 @@ private slots:
void rawString();
#if defined(Q_OS_DARWIN)
void bundle_spaces();
+ void invalid_info_plist();
#elif defined(Q_OS_WIN)
void windowsResources();
#endif
@@ -534,6 +535,23 @@ void tst_qmake::bundle_spaces()
QVERIFY( test_compiler.removeMakefile(workDir) );
}
+void tst_qmake::invalid_info_plist()
+{
+ QString workDir = base_path + "/testdata/invalid-info-plist";
+
+ // We set up alternate arguments here, to make sure we're testing Mac
+ // Bundles. We need to actually run make to check whether the failing
+ // plutil invocation breaks the build.
+
+ test_compiler.setArguments(QStringList(),
+ QStringList() << "-spec" << "macx-clang");
+
+ QVERIFY( test_compiler.qmake(workDir, "invalid-info-plist") );
+
+ // Make fails: plutil fails to parse the Info.plist file
+ QVERIFY( test_compiler.make(workDir, QString(), true) );
+}
+
#elif defined(Q_OS_WIN) // defined(Q_OS_DARWIN)
void tst_qmake::windowsResources()
diff --git a/tests/auto/tools/uic/baseline/REUSE.toml b/tests/auto/tools/uic/baseline/REUSE.toml
index 30f460c00b0..c147a71dca5 100644
--- a/tests/auto/tools/uic/baseline/REUSE.toml
+++ b/tests/auto/tools/uic/baseline/REUSE.toml
@@ -3,5 +3,5 @@ version = 1
[[annotations]]
path = ["Widget.ui"]
precedence = "override"
-SPDX-FileCopyrightText = "Copyright (C) 2016 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only"
diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST
index aca3147b2d6..fde971443d4 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST
+++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST
@@ -1,3 +1,2 @@
[layoutDirection]
ubuntu-22.04
-ubuntu-24.04
diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
index 3e5ff5ce640..df19ea1568e 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
@@ -657,9 +657,6 @@ void tst_QGraphicsView::viewport()
#if QT_CONFIG(opengl)
void tst_QGraphicsView::openGLViewport()
{
-#if !QT_CONFIG(run_opengl_tests)
- QSKIP("Skip test as run-opengl-tests feature is off.");
-#endif
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
QSKIP("QOpenGL is not supported on this platform.");
if (isPlatformEGLFS())
diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
index 03be7aa0fe9..b651668cabd 100644
--- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
@@ -213,6 +213,7 @@ private slots:
void storeRestoreLowMemoryMode();
void setSectionResizeModeWithSectionWillTakeMemory();
void setModelWithAutoSizeWillSwitchToMemoryMode();
+ void tableViewResizeSectionsWillSwitchToMemoryMode();
void setDefaultSectionSizeRespectsColumnWidth();
@@ -3559,12 +3560,17 @@ struct TableViewWithBasicModel : public QTableView
emptyState = verticalHeader()->saveState();
setModel(&m);
header = verticalHeader();
+ horizontal_header = horizontalHeader();
}
bool hasLowMemoryUsage() const {
return emptyState.size() == header->saveState().size();
}
+ bool horizontalLowMememorUsage() const {
+ return emptyState.size() == horizontal_header->saveState().size();
+ }
+
bool hasHigherMemoryUsage() const {
const int delta = 1000;
return header->saveState().size() > delta + emptyState.size();
@@ -3572,6 +3578,7 @@ struct TableViewWithBasicModel : public QTableView
BasicModel m;
QHeaderView *header;
+ QHeaderView *horizontal_header;
QByteArray emptyState;
};
@@ -3770,6 +3777,15 @@ void tst_QHeaderView::setModelWithAutoSizeWillSwitchToMemoryMode()
QCOMPARE_GT(nonEmptyState.size(), emptyState.size() + delta);
}
+void tst_QHeaderView::tableViewResizeSectionsWillSwitchToMemoryMode()
+{
+ TableViewWithBasicModel tv;
+ QVERIFY(tv.horizontalLowMememorUsage());
+ tv.horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
+ tv.resizeColumnsToContents();
+ QVERIFY(!tv.horizontalLowMememorUsage());
+}
+
void tst_QHeaderView::setDefaultSectionSizeRespectsColumnWidth()
{
QTreeWidget tree;
diff --git a/tests/auto/widgets/kernel/qapplication/BLACKLIST b/tests/auto/widgets/kernel/qapplication/BLACKLIST
deleted file mode 100644
index c68c7d6b149..00000000000
--- a/tests/auto/widgets/kernel/qapplication/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-[touchEventPropagation]
-# QTBUG-66745
-opensuse-leap
diff --git a/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp b/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp
index c460eb1db8c..f418d5ead14 100644
--- a/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp
+++ b/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp
@@ -655,121 +655,122 @@ void tst_QWidgetRepaintManager::evaluateRhi()
#if QT_CONFIG(opengl)
-#if QT_CONFIG(run_opengl_tests)
- {
- // Non-native child RHI widget enables RHI for top level regular widget
- QWidget topLevel;
- RhiWidget rhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
- topLevel.show();
- QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
- QCOMPARE(topLevel.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
- QVERIFY(QWidgetPrivate::get(&topLevel)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&topLevel)->rhi());
- // Only the native widget that actually flushes will report usesRhiFlush
- QVERIFY(!QWidgetPrivate::get(&rhiWidget)->usesRhiFlush);
- // But it should have an RHI it can use
- QVERIFY(QWidgetPrivate::get(&rhiWidget)->rhi());
- }
-
- {
- // Native child RHI widget does not enable RHI for top level
- QWidget topLevel;
- RhiWidget nativeRhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
- nativeRhiWidget.setAttribute(Qt::WA_NativeWindow);
- topLevel.show();
- QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
- QCOMPARE(nativeRhiWidget.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
- QVERIFY(QWidgetPrivate::get(&nativeRhiWidget)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&nativeRhiWidget)->rhi());
- QCOMPARE(topLevel.windowHandle()->surfaceType(), defaultSurfaceType);
- QVERIFY(!QWidgetPrivate::get(&topLevel)->usesRhiFlush);
-
- if (!usesRhiBackingStore)
- QVERIFY(!QWidgetPrivate::get(&topLevel)->rhi());
- }
-
- {
- // Non-native RHI child of native child enables RHI for native child,
- // but not top level.
- QWidget topLevel;
- QWidget nativeChild(&topLevel);
- nativeChild.setAttribute(Qt::WA_NativeWindow);
- RhiWidget rhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &nativeChild);
- topLevel.show();
- QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
-
- QCOMPARE(nativeChild.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
- QVERIFY(QWidgetPrivate::get(&nativeChild)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&nativeChild)->rhi());
- QVERIFY(!QWidgetPrivate::get(&rhiWidget)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&rhiWidget)->rhi());
- QCOMPARE(topLevel.windowHandle()->surfaceType(), defaultSurfaceType);
- QVERIFY(!QWidgetPrivate::get(&topLevel)->usesRhiFlush);
- if (!usesRhiBackingStore)
- QVERIFY(!QWidgetPrivate::get(&topLevel)->rhi());
- }
-
- {
- // Native child RHI widget does not prevent RHI for top level
- // if non-native RHI child widget is also present.
- QWidget topLevel;
- RhiWidget rhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
- RhiWidget nativeRhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
- nativeRhiWidget.setAttribute(Qt::WA_NativeWindow);
- topLevel.show();
- QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
- QCOMPARE(nativeRhiWidget.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
- QVERIFY(QWidgetPrivate::get(&nativeRhiWidget)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&nativeRhiWidget)->rhi());
- QVERIFY(!QWidgetPrivate::get(&rhiWidget)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&rhiWidget)->rhi());
- QCOMPARE(topLevel.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
- QVERIFY(QWidgetPrivate::get(&topLevel)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&topLevel)->rhi());
- }
+ {
+ // Non-native child RHI widget enables RHI for top level regular widget
+ QWidget topLevel;
+ RhiWidget rhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ QCOMPARE(topLevel.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
+ QVERIFY(QWidgetPrivate::get(&topLevel)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&topLevel)->rhi());
+ // Only the native widget that actually flushes will report usesRhiFlush
+ QVERIFY(!QWidgetPrivate::get(&rhiWidget)->usesRhiFlush);
+ // But it should have an RHI it can use
+ QVERIFY(QWidgetPrivate::get(&rhiWidget)->rhi());
+ }
- {
- // Reparenting into a window that already matches the required
- // surface type should still mark the parent as flushing with RHI.
- QWidget topLevel;
+ {
+ // Native child RHI widget does not enable RHI for top level
+ QWidget topLevel;
+ RhiWidget nativeRhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
+ nativeRhiWidget.setAttribute(Qt::WA_NativeWindow);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ QCOMPARE(nativeRhiWidget.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
+ QVERIFY(QWidgetPrivate::get(&nativeRhiWidget)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&nativeRhiWidget)->rhi());
+ QCOMPARE(topLevel.windowHandle()->surfaceType(), defaultSurfaceType);
+ QVERIFY(!QWidgetPrivate::get(&topLevel)->usesRhiFlush);
+
+ if (!usesRhiBackingStore)
+ QVERIFY(!QWidgetPrivate::get(&topLevel)->rhi());
+ }
- RhiWidget rhiWidget(QPlatformBackingStoreRhiConfig::Null);
- rhiWidget.show();
- QVERIFY(QTest::qWaitForWindowExposed(&rhiWidget));
- QVERIFY(QWidgetPrivate::get(&rhiWidget)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&rhiWidget)->rhi());
+ {
+ // Non-native RHI child of native child enables RHI for native child,
+ // but not top level.
+ QWidget topLevel;
+ QWidget nativeChild(&topLevel);
+ nativeChild.setAttribute(Qt::WA_NativeWindow);
+ RhiWidget rhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &nativeChild);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ QCOMPARE(nativeChild.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
+ QVERIFY(QWidgetPrivate::get(&nativeChild)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&nativeChild)->rhi());
+ QVERIFY(!QWidgetPrivate::get(&rhiWidget)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&rhiWidget)->rhi());
+ QCOMPARE(topLevel.windowHandle()->surfaceType(), defaultSurfaceType);
+ QVERIFY(!QWidgetPrivate::get(&topLevel)->usesRhiFlush);
+ if (!usesRhiBackingStore)
+ QVERIFY(!QWidgetPrivate::get(&topLevel)->rhi());
+ }
- topLevel.show();
- QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
- rhiWidget.setParent(&topLevel);
- QVERIFY(QWidgetPrivate::get(&topLevel)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&topLevel)->rhi());
- }
+ {
+ // Native child RHI widget does not prevent RHI for top level
+ // if non-native RHI child widget is also present.
+ QWidget topLevel;
+ RhiWidget rhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
+ RhiWidget nativeRhiWidget(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
+ nativeRhiWidget.setAttribute(Qt::WA_NativeWindow);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ QCOMPARE(nativeRhiWidget.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
+ QVERIFY(QWidgetPrivate::get(&nativeRhiWidget)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&nativeRhiWidget)->rhi());
+ QVERIFY(!QWidgetPrivate::get(&rhiWidget)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&rhiWidget)->rhi());
+ QCOMPARE(topLevel.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
+ QVERIFY(QWidgetPrivate::get(&topLevel)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&topLevel)->rhi());
+ }
- {
- // Non-native RHI child of native child enables RHI for native child,
- // but does not prevent top level from flushing with RHI.
- QWidget topLevel;
- QWidget nativeChild(&topLevel);
- nativeChild.setAttribute(Qt::WA_NativeWindow);
- RhiWidget rhiGranchild(QPlatformBackingStoreRhiConfig::OpenGL, &nativeChild);
- RhiWidget rhiChild(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
- topLevel.show();
- QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ {
+ // Reparenting into a window that already matches the required
+ // surface type should still mark the parent as flushing with RHI.
+ QWidget topLevel;
+
+ RhiWidget rhiWidget(QPlatformBackingStoreRhiConfig::Null);
+ rhiWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&rhiWidget));
+ QVERIFY(QWidgetPrivate::get(&rhiWidget)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&rhiWidget)->rhi());
+
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ rhiWidget.setParent(&topLevel);
+ QVERIFY(QWidgetPrivate::get(&topLevel)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&topLevel)->rhi());
+ }
- QCOMPARE(nativeChild.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
- QVERIFY(QWidgetPrivate::get(&nativeChild)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&nativeChild)->rhi());
- QVERIFY(!QWidgetPrivate::get(&rhiGranchild)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&rhiGranchild)->rhi());
- QCOMPARE(topLevel.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
- QVERIFY(QWidgetPrivate::get(&topLevel)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&topLevel)->rhi());
- QVERIFY(!QWidgetPrivate::get(&rhiChild)->usesRhiFlush);
- QVERIFY(QWidgetPrivate::get(&rhiChild)->rhi());
+ {
+ // Non-native RHI child of native child enables RHI for native child,
+ // but does not prevent top level from flushing with RHI.
+ QWidget topLevel;
+ QWidget nativeChild(&topLevel);
+ nativeChild.setAttribute(Qt::WA_NativeWindow);
+ RhiWidget rhiGranchild(QPlatformBackingStoreRhiConfig::OpenGL, &nativeChild);
+ RhiWidget rhiChild(QPlatformBackingStoreRhiConfig::OpenGL, &topLevel);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ QCOMPARE(nativeChild.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
+ QVERIFY(QWidgetPrivate::get(&nativeChild)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&nativeChild)->rhi());
+ QVERIFY(!QWidgetPrivate::get(&rhiGranchild)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&rhiGranchild)->rhi());
+ QCOMPARE(topLevel.windowHandle()->surfaceType(), QSurface::OpenGLSurface);
+ QVERIFY(QWidgetPrivate::get(&topLevel)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&topLevel)->rhi());
+ QVERIFY(!QWidgetPrivate::get(&rhiChild)->usesRhiFlush);
+ QVERIFY(QWidgetPrivate::get(&rhiChild)->rhi());
+ }
}
-#endif // QT_CONFIG(run_opengl_tests)
#if QT_CONFIG(metal)
QRhiMetalInitParams metalParams;
@@ -805,10 +806,6 @@ void tst_QWidgetRepaintManager::evaluateRhi()
void tst_QWidgetRepaintManager::rhiRecreateMaintainsWindowProperties()
{
-#if !QT_CONFIG(run_opengl_tests)
- QSKIP("Skip test as run-opengl-tests feature is off.");
-#endif
-
const auto *integration = QGuiApplicationPrivate::platformIntegration();
if (!integration->hasCapability(QPlatformIntegration::RhiBasedRendering))
QSKIP("Platform does not support RHI based rendering");
@@ -817,6 +814,9 @@ void tst_QWidgetRepaintManager::rhiRecreateMaintainsWindowProperties()
QSKIP("Platform does not support OpenGL RHI based rendering");
#endif
+ if (!integration->hasCapability(QPlatformIntegration::OpenGL))
+ QSKIP("OpenGL is not supported on this platform.");
+
// Reparenting Rhi widget into a window causes the window to be
// recreated, but after recreation the window properties such as
// window position must remain the same
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index 1b3afa0a4dc..cbe554f997f 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -8,10 +8,12 @@
#include <QPushButton>
#include <QMainWindow>
#include <QMenuBar>
+#include <QPlainTextEdit>
#include <QToolBar>
#include <QToolButton>
#include <QStatusBar>
#include <QListWidget>
+#include <QVBoxLayout>
#include <QWidgetAction>
#include <QScreen>
#include <QSpinBox>
@@ -96,6 +98,8 @@ private slots:
void QTBUG_89082_actionTipsHide();
void QTBUG8122_widgetActionCrashOnClose();
void widgetActionTriggerClosesMenu();
+ void widgetActionContextMenu();
+
void transientParent();
void QTBUG_10735_crashWithDialog();
@@ -1590,6 +1594,36 @@ void tst_QMenu::widgetActionTriggerClosesMenu()
QCOMPARE(actionTriggered, &widgetAction);
}
+void tst_QMenu::widgetActionContextMenu() // QTBUG-134757
+{
+ QPushButton openButton("open");
+ QMenu *menu = new QMenu(&openButton);
+ QVBoxLayout *layout = new QVBoxLayout;
+ QWidgetAction widgetAction(menu);
+ QWidget menuWidget(menu);
+ QPlainTextEdit edit;
+ openButton.setMenu(menu);
+ menuWidget.setLayout(layout);
+ widgetAction.setDefaultWidget(&menuWidget);
+ menu->addAction(&widgetAction);
+ layout->addWidget(&edit);
+
+ openButton.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&openButton));
+
+ // Click the QPushButton to open its menu
+ QTest::mouseClick(&openButton, Qt::LeftButton);
+ QVERIFY(QTest::qWaitForWindowExposed(&menuWidget));
+ QWindow *popupWindow = edit.window()->windowHandle();
+ QVERIFY(popupWindow);
+ QCOMPARE(QApplication::activePopupWidget(), menu);
+
+ // Right-click the QPlainTextEdit to open its context menu
+ QTest::mouseClick(popupWindow, Qt::RightButton);
+ QVERIFY(qobject_cast<QMenu *>(QApplication::activePopupWidget()));
+ QCOMPARE_NE(QApplication::activePopupWidget(), menu);
+}
+
void tst_QMenu::transientParent()
{
QMainWindow window;
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
index 609a0847862..f4baf6b1714 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -1233,12 +1233,41 @@ void tst_QMenuBar::taskQTBUG4965_escapeEaten()
}
#endif
+#ifdef Q_OS_LINUX
+class ResizeCounter : public QObject
+{
+public:
+ explicit ResizeCounter(QMenuBar *bar)
+ {
+ Q_ASSERT(bar);
+ bar->installEventFilter(this);
+ }
+
+ int resizeCount() const { return m_resizeCount; }
+
+protected:
+ bool eventFilter(QObject *o, QEvent *event) override
+ {
+ Q_UNUSED(o);
+ if (event->type() == QEvent::Resize)
+ ++m_resizeCount;
+ return false;
+ }
+
+private:
+ int m_resizeCount = 0;
+};
+#endif
+
void tst_QMenuBar::taskQTBUG11823_crashwithInvisibleActions()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
QMenuBar menubar;
+#ifdef Q_OS_LINUX
+ ResizeCounter counter(&menubar);
+#endif
menubar.setNativeMenuBar(false); //we can't check the geometry of native menubars
QAction * m = menubar.addAction( "&m" );
@@ -1247,6 +1276,12 @@ void tst_QMenuBar::taskQTBUG11823_crashwithInvisibleActions()
centerOnScreen(&menubar);
menubar.show();
QVERIFY(QTest::qWaitForWindowActive(&menubar));
+
+#ifdef Q_OS_LINUX
+ if (QSysInfo::productType().contains("opensuse"))
+ QVERIFY(QTest::qWaitFor([&]{ return counter.resizeCount() == 2;}));
+#endif
+
menubar.setActiveAction(m);
QCOMPARE(menubar.activeAction(), m);
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Right);
diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
index b2cdd6b72c2..c5df30dd7d1 100644
--- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
+++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
@@ -63,12 +63,12 @@ private slots:
void tst_QOpenGLWidget::initTestCase()
{
-#if !QT_CONFIG(run_opengl_tests)
- QSKIP("Skip test as run-opengl-tests feature is off.");
-#endif
// See QOpenGLWidget constructor
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::RasterGLSurface))
QSKIP("QOpenGLWidget is not supported on this platform.");
+
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+ QSKIP("OpenGL is not supported on this platform.");
}
void tst_QOpenGLWidget::create()
diff --git a/tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp b/tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp
index da4fee72f65..457df2159b1 100644
--- a/tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp
+++ b/tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp
@@ -64,7 +64,7 @@ void tst_QRhiWidget::testData()
QTest::newRow("Null") << QRhiWidget::Api::Null;
#endif
-#if QT_CONFIG(opengl) && QT_CONFIG(run_opengl_tests)
+#if QT_CONFIG(opengl)
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
QTest::newRow("OpenGL") << QRhiWidget::Api::OpenGL;
#endif
diff --git a/tests/benchmarks/corelib/CMakeLists.txt b/tests/benchmarks/corelib/CMakeLists.txt
index 890cbcfc6b8..42e1d2cb96d 100644
--- a/tests/benchmarks/corelib/CMakeLists.txt
+++ b/tests/benchmarks/corelib/CMakeLists.txt
@@ -14,3 +14,4 @@ add_subdirectory(time)
add_subdirectory(tools)
add_subdirectory(plugin)
add_subdirectory(serialization)
+add_subdirectory(platform)
diff --git a/tests/benchmarks/corelib/platform/CMakeLists.txt b/tests/benchmarks/corelib/platform/CMakeLists.txt
new file mode 100644
index 00000000000..68844c1c8f7
--- /dev/null
+++ b/tests/benchmarks/corelib/platform/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(ANDROID)
+ add_subdirectory(androiditemmodel)
+endif()
diff --git a/tests/benchmarks/corelib/platform/androiditemmodel/CMakeLists.txt b/tests/benchmarks/corelib/platform/androiditemmodel/CMakeLists.txt
new file mode 100644
index 00000000000..b72d0564c1a
--- /dev/null
+++ b/tests/benchmarks/corelib/platform/androiditemmodel/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_androiditemmodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_bench_androiditemmodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_bench_androiditemmodel
+ SOURCES
+ tst_bench_androiditemmodel.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::CorePrivate
+)
+
+set_property(TARGET tst_androiditemmodel PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR}/testdata
+)
diff --git a/tests/benchmarks/corelib/platform/androiditemmodel/testdata/src/org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel.java b/tests/benchmarks/corelib/platform/androiditemmodel/testdata/src/org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel.java
new file mode 100644
index 00000000000..79b07b3fd04
--- /dev/null
+++ b/tests/benchmarks/corelib/platform/androiditemmodel/testdata/src/org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel.java
@@ -0,0 +1,56 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+package org.qtproject.qt.android.benchmark;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.qtproject.qt.android.QtAbstractItemModel;
+import org.qtproject.qt.android.QtModelIndex;
+
+public class BenchQtAbstractItemModel
+ extends QtAbstractItemModel
+{
+ int m_rows = 1;
+ int m_cols = 1;
+
+ @Override
+ public int columnCount(QtModelIndex parent)
+ {
+ return m_cols;
+ }
+
+ @Override
+ public Object data(QtModelIndex index, int role)
+ {
+ return null;
+ }
+
+ @Override
+ public QtModelIndex index(int row, int column, QtModelIndex parent)
+ {
+ return createIndex(row, column, 0);
+ }
+
+ @Override
+ public QtModelIndex parent(QtModelIndex qtModelIndex)
+ {
+ return new QtModelIndex();
+ }
+
+ @Override
+ public int rowCount(QtModelIndex parent)
+ {
+ return m_rows;
+ }
+
+ @Override
+ public HashMap<Integer, String> roleNames()
+ {
+ final HashMap<Integer, String> roles = new HashMap<Integer, String>();
+ roles.put(0, "integerRole");
+ return roles;
+ }
+}
diff --git a/tests/benchmarks/corelib/platform/androiditemmodel/tst_bench_androiditemmodel.cpp b/tests/benchmarks/corelib/platform/androiditemmodel/tst_bench_androiditemmodel.cpp
new file mode 100644
index 00000000000..c7079e147a7
--- /dev/null
+++ b/tests/benchmarks/corelib/platform/androiditemmodel/tst_bench_androiditemmodel.cpp
@@ -0,0 +1,144 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtTest/QTest>
+
+#include <QtCore/private/qandroiditemmodelproxy_p.h>
+#include <QtCore/private/qandroidmodelindexproxy_p.h>
+#include <QtCore/private/qandroidtypes_p.h>
+
+#include <QGuiApplication>
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qjniobject.h>
+#include <QtCore/qjnitypes.h>
+#include <QtCore/qstring.h>
+#include <QSignalSpy>
+#include <memory>
+
+using namespace Qt::Literals;
+
+Q_DECLARE_JNI_CLASS(BenchQtAbstractItemModel,
+ "org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel")
+
+class BenchNativeAbstractItemModel : public QAbstractItemModel {
+ Q_OBJECT
+ int m_rows = 1;
+ int m_cols = 1;
+
+ public:
+
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override {
+ return m_cols;
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override {
+ return m_rows;
+ }
+
+ QVariant data(const QModelIndex &index, int role) const override {
+ return QVariant();
+ }
+
+ QModelIndex index(int row, int column, const QModelIndex &parent) const override {
+ return createIndex(row, column, quintptr(0));
+ }
+
+ QModelIndex parent(const QModelIndex &index) const override
+ {
+ return QModelIndex();
+ }
+
+ QHash<int, QByteArray> roleNames() const override {
+ static QHash<int, QByteArray> roles = {
+ {0, "integerRole"}
+ };
+ return roles;
+ }
+
+};
+
+class tst_BenchAndroidItemModel : public QObject
+{
+ Q_OBJECT
+ QtJniTypes::BenchQtAbstractItemModel m_jModel;
+ std::unique_ptr<QAbstractItemModel> qProxy;
+ std::unique_ptr<QAbstractItemModel> nativeModel;
+
+private slots:
+ void init();
+
+ void proxiedData();
+ void nativeData();
+
+ void proxiedRowCount();
+ void nativeRowCount();
+
+ void proxiedColumnCount();
+ void nativeColumnCount();
+
+ void proxiedIndex();
+ void nativeIndex();
+};
+
+void tst_BenchAndroidItemModel::init()
+{
+ m_jModel = QJniObject::construct<QtJniTypes::BenchQtAbstractItemModel>();
+ QVERIFY(m_jModel.isValid());
+ qProxy = std::unique_ptr<QAbstractItemModel>(QAndroidItemModelProxy::createNativeProxy(jModel));
+ nativeModel = std::make_unique<BenchNativeAbstractItemModel>();
+ QVERIFY(qProxy);
+}
+
+void tst_BenchAndroidItemModel::proxiedData()
+{
+ QCOMPARE(qProxy->rowCount(), 1);
+ QCOMPARE(qProxy->columnCount(), 1);
+
+ QModelIndex idx = qProxy->index(0, 0, QModelIndex());
+
+ QBENCHMARK { qProxy->data(idx, 0); }
+}
+
+void tst_BenchAndroidItemModel::nativeData()
+{
+ QCOMPARE(nativeModel->rowCount(), 1);
+ QCOMPARE(nativeModel->columnCount(), 1);
+
+ QModelIndex idx = nativeModel->index(0, 0, QModelIndex());
+
+ QBENCHMARK { nativeModel->data(idx, 0); }
+}
+
+void tst_BenchAndroidItemModel::proxiedRowCount()
+{
+ QBENCHMARK { qProxy->rowCount(QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::nativeRowCount()
+{
+ QBENCHMARK { nativeModel->rowCount(QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::proxiedColumnCount()
+{
+ QBENCHMARK { qProxy->columnCount(QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::nativeColumnCount()
+{
+ QBENCHMARK { nativeModel->columnCount(QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::proxiedIndex()
+{
+ QBENCHMARK { qProxy->index(0, 0, QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::nativeIndex()
+{
+ QBENCHMARK { nativeModel->index(0, 0, QModelIndex()); }
+}
+
+#include "tst_bench_androiditemmodel.moc"
+
+QTEST_MAIN(tst_BenchAndroidItemModel)
diff --git a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
index 59f1f00cc59..1fd6e0a0c4f 100644
--- a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
+++ b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
@@ -7,7 +7,7 @@
using namespace emscripten;
-const int timerTimeout = 10;
+const std::chrono::milliseconds timerTimeout{10};
// Test QWasmSuspendResumeControl suspend/resume and event processing,
// via QWasmTimer native timer events.