diff options
Diffstat (limited to 'tests/auto')
236 files changed, 5989 insertions, 629 deletions
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index 171e83a57a..1297db9b8a 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -66,6 +66,7 @@ if(QT_BUILD_WASM_BATCHED_TESTS) add_subdirectory(corelib/io/qbuffer) add_subdirectory(corelib/io/qabstractfileengine) add_subdirectory(corelib/io/qsettings) + add_subdirectory(corelib/io/qstandardpaths) add_subdirectory(corelib/io/qfileselector) add_subdirectory(corelib/io/qfile) add_subdirectory(corelib/serialization) diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 3331ad260d..86db954086 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -146,6 +146,21 @@ if(QT_BUILD_MINIMAL_ANDROID_MULTI_ABI_TESTS AND NOT NO_GUI) "-DTEST_ESCAPING_VALUE_ARG=${escaping_value}" "-DTEST_SPACES_VALUE_ARG=${spaces_value}" ) + + #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() + return() endif() @@ -399,8 +414,44 @@ endif() _qt_internal_test_expect_pass(test_config_expressions) _qt_internal_test_expect_pass(test_QTP0003) + if(NOT NO_GUI) _qt_internal_test_expect_pass(test_collecting_plugins) endif() _qt_internal_test_expect_pass(test_qt_manual_moc) + +# check if the os is opensuse. If it is, we need to skip tests due to CI problems +set(is_opensuse FALSE) +if(UNIX) + if(EXISTS "/etc/os-release") + file(STRINGS "/etc/os-release" os_release_content) + foreach(line IN LISTS os_release_content) + if(line MATCHES "openSUSE" OR line MATCHES "opensuse") + set(is_opensuse TRUE) + break() + endif() + endforeach() + endif() +endif() + +if(NOT QNX AND NOT WASM AND NOT (WIN32 AND QT_BUILD_MINIMAL_STATIC_TESTS) + AND NOT is_opensuse) + # Since our CI machines are slow, ctest --build-and-test buffers the output + # of the configure step of a test, and the fact that we run all the test + # logic in the configure step, we need to divide the tests into smaller + # chunks to avoid CI stdout timeout errors. + # See https://gitlab.kitware.com/cmake/cmake/-/issues/25790 + _qt_internal_test_expect_pass(test_qt_add_ui_common) + _qt_internal_test_expect_pass(test_qt_add_ui_1) + _qt_internal_test_expect_pass(test_qt_add_ui_2) + _qt_internal_test_expect_pass(test_qt_add_ui_3) + _qt_internal_test_expect_pass(test_qt_add_ui_4) + _qt_internal_test_expect_pass(test_qt_add_ui_5) + _qt_internal_test_expect_pass(test_qt_add_ui_6) + _qt_internal_test_expect_pass(test_qt_add_ui_7) + _qt_internal_test_expect_pass(test_qt_add_ui_8) + _qt_internal_test_expect_pass(test_qt_add_ui_9) + _qt_internal_test_expect_pass(test_qt_add_ui_10) +endif() + diff --git a/tests/auto/cmake/mockplugins/mock1plugin/qmock1plugin.cpp b/tests/auto/cmake/mockplugins/mock1plugin/qmock1plugin.cpp index 2ee817d80a..a2994c10e3 100644 --- a/tests/auto/cmake/mockplugins/mock1plugin/qmock1plugin.cpp +++ b/tests/auto/cmake/mockplugins/mock1plugin/qmock1plugin.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qmock1plugin.h" QT_BEGIN_NAMESPACE diff --git a/tests/auto/cmake/mockplugins/mock2plugin/qmock2plugin.cpp b/tests/auto/cmake/mockplugins/mock2plugin/qmock2plugin.cpp index 5b3280e884..8e10797997 100644 --- a/tests/auto/cmake/mockplugins/mock2plugin/qmock2plugin.cpp +++ b/tests/auto/cmake/mockplugins/mock2plugin/qmock2plugin.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qmock2plugin.h" QT_BEGIN_NAMESPACE diff --git a/tests/auto/cmake/mockplugins/mock3plugin/qmock3plugin.cpp b/tests/auto/cmake/mockplugins/mock3plugin/qmock3plugin.cpp index b38f854e4b..53090472e0 100644 --- a/tests/auto/cmake/mockplugins/mock3plugin/qmock3plugin.cpp +++ b/tests/auto/cmake/mockplugins/mock3plugin/qmock3plugin.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qmock3plugin.h" QT_BEGIN_NAMESPACE diff --git a/tests/auto/cmake/mockplugins/mock4plugin/qmock4plugin.cpp b/tests/auto/cmake/mockplugins/mock4plugin/qmock4plugin.cpp index 5deaf7f43f..f2a904182d 100644 --- a/tests/auto/cmake/mockplugins/mock4plugin/qmock4plugin.cpp +++ b/tests/auto/cmake/mockplugins/mock4plugin/qmock4plugin.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qmock4plugin.h" QT_BEGIN_NAMESPACE diff --git a/tests/auto/cmake/mockplugins/mock5plugin/qmock5plugin.cpp b/tests/auto/cmake/mockplugins/mock5plugin/qmock5plugin.cpp index c5b4620516..92ea47690f 100644 --- a/tests/auto/cmake/mockplugins/mock5plugin/qmock5plugin.cpp +++ b/tests/auto/cmake/mockplugins/mock5plugin/qmock5plugin.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qmock5plugin.h" QT_BEGIN_NAMESPACE diff --git a/tests/auto/cmake/mockplugins/mock6plugin/qmock6plugin.cpp b/tests/auto/cmake/mockplugins/mock6plugin/qmock6plugin.cpp index 4a0329c68a..9dd9e02f2a 100644 --- a/tests/auto/cmake/mockplugins/mock6plugin/qmock6plugin.cpp +++ b/tests/auto/cmake/mockplugins/mock6plugin/qmock6plugin.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qmock6plugin.h" QT_BEGIN_NAMESPACE diff --git a/tests/auto/cmake/test_android_aar/CMakeLists.txt b/tests/auto/cmake/test_android_aar/CMakeLists.txt new file mode 100644 index 0000000000..88cd5abf23 --- /dev/null +++ b/tests/auto/cmake/test_android_aar/CMakeLists.txt @@ -0,0 +1,54 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) + +project(test_android_aar) + +find_package(Qt6 COMPONENTS Core Gui REQUIRED) + +qt6_add_executable(test_aar main.cpp) + +# To support opening the project in QtCreator +if($CACHE{QT_USE_TARGET_ANDROID_BUILD_DIR}) + set(TARGET_ANDROID_BUILD_DIR ${CMAKE_BINARY_DIR}/android-build-test_aar) +else() + set(TARGET_ANDROID_BUILD_DIR ${CMAKE_BINARY_DIR}/android-build) +endif() + +# Add common libs for available ABIs that should be present in the aar package in a list +unset(aar_content_filepaths_to_verify) +foreach(abi IN LISTS QT_ANDROID_ABIS) + list(APPEND aar_content_filepaths_to_verify "jni/${abi}/libQt6Core_${abi}.so") + list(APPEND aar_content_filepaths_to_verify "jni/${abi}/libQt6Gui_${abi}.so") + list(APPEND aar_content_filepaths_to_verify + "jni/${abi}/libplugins_platforms_qtforandroid_${abi}.so") + list(APPEND aar_content_filepaths_to_verify "jni/${abi}/libtest_aar_${abi}.so") +endforeach() + +# Add a few ABI independent file that should be present in the aar package in a list +list(APPEND aar_content_filepaths_to_verify "libs/Qt6Android.jar") +list(APPEND aar_content_filepaths_to_verify "res/xml/qtprovider_paths.xml") +list(APPEND aar_content_filepaths_to_verify "AndroidManifest.xml") +list(JOIN aar_content_filepaths_to_verify "|" grep_pattern) + +# The overall number of lines we should expect to be filtered by grep regex +list(LENGTH aar_content_filepaths_to_verify expected_file_count) + +set(zipinfo_command "zipinfo -1 ${TARGET_ANDROID_BUILD_DIR}/test_aar.aar") + +# Runs zipinfo on the aar package, greps and outputs the number of matching lines +# and finally compares the expected number of lines with the output +add_custom_target(verify_aar + bash -c "${zipinfo_command} \ + | grep -Ecx '${grep_pattern}' \ + | grep -xq ${expected_file_count} \ + || { echo 'Error: The aar package is missing at least one file.'; exit 1; };" + COMMENT "Verifying aar package content" + VERBATIM +) + +# Build aar package before verification +add_dependencies(verify_aar aar) + +target_link_libraries(test_aar PRIVATE Qt::Core Qt::Gui) diff --git a/tests/auto/cmake/test_android_aar/main.cpp b/tests/auto/cmake/test_android_aar/main.cpp new file mode 100644 index 0000000000..90df9ee937 --- /dev/null +++ b/tests/auto/cmake/test_android_aar/main.cpp @@ -0,0 +1,4 @@ +// Copyright (C) 2024 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_interface/widget_test/main.cpp b/tests/auto/cmake/test_interface/widget_test/main.cpp index e6a8ab5fe9..0a47f43d84 100644 --- a/tests/auto/cmake/test_interface/widget_test/main.cpp +++ b/tests/auto/cmake/test_interface/widget_test/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QString> #include <QWidget> diff --git a/tests/auto/cmake/test_moc_macro_target/check_moc_parameters.cmake b/tests/auto/cmake/test_moc_macro_target/check_moc_parameters.cmake index 4ca8fab119..5388816c07 100644 --- a/tests/auto/cmake/test_moc_macro_target/check_moc_parameters.cmake +++ b/tests/auto/cmake/test_moc_macro_target/check_moc_parameters.cmake @@ -1,4 +1,6 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause function(check_parameters file_path) file(READ ${file_path} file_content) foreach(compile_option IN ITEMS "-DDEFINE_CMDLINE_SIGNAL" "-DMY_OPTION") diff --git a/tests/auto/cmake/test_qt_add_resources_rebuild/sample/CMakeLists.txt b/tests/auto/cmake/test_qt_add_resources_rebuild/sample/CMakeLists.txt index 0a40a948c6..1696eae261 100644 --- a/tests/auto/cmake/test_qt_add_resources_rebuild/sample/CMakeLists.txt +++ b/tests/auto/cmake/test_qt_add_resources_rebuild/sample/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(sample LANGUAGES CXX) diff --git a/tests/auto/cmake/test_qt_add_ui_1/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_1/CMakeLists.txt new file mode 100644 index 0000000000..882abecc0b --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_1/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + if(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case: ui_mainwindow.h is included as + # "sub1/sub2/sub3/sub4/../../../../src/ui_files/ui_mainwindow.h". + # Expect 1: Successful build without the double build issue. + # Expect 2: No build folder leakage and generation of the + # sub1/sub2/sub3/sub4 folder in ${hash_folder}/include + string(CONCAT test_ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + generate_hash_folder( "example" "${test_ui_file}" hash_folder) + string(CONCAT test_build_dir + "${CMAKE_CURRENT_BINARY_DIR}/UicBuildLeak_incPathGen" + "${config_path}-build") + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + string(CONCAT test_additional_args "-DMAINWINDOW_UI_PATH=sub1/sub2/" + "sub3/sub4/../../../../src/ui_files/") + string(CONCAT test_file_to_check "${test_build_dir}/.qt/${hash_folder}/" + "${config_arg}/src/ui_files/ui_mainwindow.h") + string(CONCAT test_folder_to_check "${test_build_dir}/.qt/" + "${hash_folder}/${config_arg}/sub1/sub2/sub3/sub4") + incremental_build_test( + TEST_NAME UicBuildLeak_incPathGen + SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + CONFIG "${config_arg}" + GENERATOR "${generator}" + ADDITIONAL_ARGS "${test_additional_args}" + FILE_TO_TOUCH "${test_ui_file}" + FILE_TO_CHECK "${test_file_to_check}" + FOLDER_TO_CHECK "${test_folder_to_check}" + ) + endforeach() +endforeach() + diff --git a/tests/auto/cmake/test_qt_add_ui_10/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_10/CMakeLists.txt new file mode 100644 index 0000000000..6b223fb281 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_10/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + # A CI test fails with the below condition. So, we are running the test + # only for the Debug configuration. + if ("${generator}" MATCHES "Xcode" AND + CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(configs "Debug") + elseif(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case: mainwindow.ui file is touched after the first build. The + # ui_mainwindow.h should be generated without the ${config_arg} folder. + # Expect 1: Successful build without the double build issue. + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "qt_add_ui_simple_no_config${config_path}-build") + string(CONCAT test_ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + string(CONCAT test_file_to_touch "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + generate_hash_folder( + "example" + "${test_ui_file}" + hash_folder) + incremental_build_test( + TEST_NAME qt6_add_ui_simple_no_config + SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + GENERATOR "${generator}" + CONFIG "${config_arg}" + ADDITIONAL_ARGS "-DUI_NO_CONFIG_OPTIONS=ON" + FILE_TO_TOUCH "${test_file_to_touch}" + FILE_TO_CHECK + "${test_build_dir}/.qt/${hash_folder}/ui_mainwindow.h" + ) + endforeach() +endforeach() diff --git a/tests/auto/cmake/test_qt_add_ui_2/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_2/CMakeLists.txt new file mode 100644 index 0000000000..dceb0c7a2e --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_2/CMakeLists.txt @@ -0,0 +1,60 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + # A CI test fails with the below condition. So, we are running the test + # only for the Debug configuration. + if ("${generator}" MATCHES "Xcode" AND + CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(configs "Debug") + elseif(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case: mainwindow.ui file is touched after the first build. + # Expect 1: Successful build without the double build issue. + set(test_build_dir + "${CMAKE_CURRENT_BINARY_DIR}/qt_add_ui_simple${config_path}-build") + string(CONCAT test_ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + string(CONCAT test_file_to_touch "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + generate_hash_folder( + "example" + "${test_ui_file}" + hash_folder) + incremental_build_test( + TEST_NAME qt6_add_ui_simple + SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + GENERATOR "${generator}" + CONFIG "${config_arg}" + FILE_TO_TOUCH "${test_file_to_touch}" + FILE_TO_CHECK + "${test_build_dir}/.qt/${hash_folder}/${config_arg}/ui_mainwindow.h" + ) + endforeach() +endforeach() diff --git a/tests/auto/cmake/test_qt_add_ui_3/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_3/CMakeLists.txt new file mode 100644 index 0000000000..81a9a38431 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_3/CMakeLists.txt @@ -0,0 +1,199 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + if(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case: Check whether api sets warning against AUTOUIC activation. + # Expect 1: Printing of the error message and failure of the build. + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_warning_test${config_path}-build") + run_cmake_configure(SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + GENERATOR "${generator}" + CLEAN_FIRST + ADDITIONAL_ARGS "-DCMAKE_AUTOUIC=ON" + OUTPUT_VARIABLE cmake_output + ERROR_VARIABLE cmake_error + RESULT_VARIABLE cmake_result) + if(NOT cmake_result EQUAL 0) + message(FATAL_ERROR "cmake_output: ${cmake_output}\ncmake_error: " + "${cmake_error}\nFAIL: \"uic_warning_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_warning_test${config_path}-" + "build failed to configure") + else() + message(STATUS "PASS: \"uic_warning_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_warning_test${config_path}-" + "build was configured successfully") + endif() + + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_warning_test${config_path}-build") + run_cmake_build( + BUILD_DIR "${test_build_dir}" + VERBOSE ON + CONFIG "${config_arg}" + OUTPUT_VARIABLE cmake_build_output + RESULT_VARIABLE cmake_build_result) + if(NOT cmake_build_result EQUAL 0) + message(STATUS "PASS: \"uic_warning_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_warning_test${config_path}" + "-build failed to build") + else() + message(FATAL_ERROR "FAIL: \"uic_warning_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_warning_test${config_path}-" + "build was built successfully") + endif() + expect_string_contains("${cmake_build_output}" "has \"AUTOUIC\" enabled" + SUCCESS_MESSAGE "\"uic_warning_test\" test in \ +${CMAKE_CURRENT_BINARY_DIR}/uic_warning_test${config_path}-build \ +has \"has AUTOUIC enabled\"" + FAILURE_MESSAGE "\"uic_warning_test\" test in \ +${CMAKE_CURRENT_BINARY_DIR}/uic_warning_test${config_path}-build \ +does not have \"has AUTOUIC enabled\"") + + + if("${generator}" MATCHES "Ninja") + # Test case: If INCLUDE_PREFIX is changed without changing the + # corresponding include path in the source file and Ninja generator + # is used, this casues the double build issue. + # Note: Only happens in Ninja generator. + # Expect 1: Failure of the build in the first build. + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_double_build_test${config_path}-build") + run_cmake_configure(SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + GENERATOR "${generator}" + CLEAN_FIRST + ADDITIONAL_ARGS "-DMAINWINDOW_UI_PATH=sub1/sub2/sub3/" + "-DDO_NOT_GENERATE_FILE=ON" + OUTPUT_VARIABLE cmake_output + ERROR_VARIABLE cmake_error + RESULT_VARIABLE cmake_result) + + if(NOT cmake_result EQUAL 0) + message(FATAL_ERROR "cmake_output: ${cmake_output}\ncmake_error" + ": ${cmake_error}\nFAIL: \"uic_double_build_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test" + "${config_path}-build failed to configure") + else() + message(STATUS "PASS: \"uic_double_build_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test" + "${config_path}-build was configured successfully") + endif() + + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_double_build_test${config_path}-build") + run_cmake_build( + BUILD_DIR "${test_build_dir}" + VERBOSE ON + CONFIG "${config_arg}" + OUTPUT_VARIABLE cmake_build_output + RESULT_VARIABLE cmake_build_result) + + if(NOT cmake_build_result EQUAL 0) + message(FATAL_ERROR "cmake_build_output: ${cmake_build_output}" + "FAIL: \"uic_double_build_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test" + "${config_path}-build failed to build in the first build") + else() + message(STATUS "PASS: \"uic_double_build_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test" + "${config_path}-build was built successfully in the first " + "build") + endif() + + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_double_build_test${config_path}-build") + run_cmake_configure(SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + GENERATOR "${generator}" + # We change the INCLUDE_PREFIX here. + ADDITIONAL_ARGS "-DMAINWINDOW_UI_PATH=sub1/sub2/sub/" + "-DDO_NOT_GENERATE_FILE=ON" + OUTPUT_VARIABLE cmake_output + ERROR_VARIABLE cmake_error + RESULT_VARIABLE cmake_result) + + if(NOT cmake_result EQUAL 0) + message(FATAL_ERROR "cmake_output: ${cmake_output}\ncmake_error" + ":${cmake_error}\nFAIL: \"uic_double_build_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test" + "${config_path}-build failed to configure in the second " + "build") + else() + message(STATUS "PASS: \"uic_double_build_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test" + "${config_path}-build was configured successfully in the " + "second build") + endif() + + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_double_build_test${config_path}-build") + run_cmake_build( + BUILD_DIR "${test_build_dir}" + VERBOSE ON + CONFIG "${config_arg}" + OUTPUT_VARIABLE cmake_build_output + ERROR_VARIABLE cmake_build_error + RESULT_VARIABLE cmake_build_result) + + if(NOT cmake_build_result EQUAL 0) + message(STATUS "PASS: \"uic_double_build_test\" test in" + "${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test" + "${config_path}-build failed to build in the first build " + "after changing INCLUDE_PREFIX") + else() + message(FATAL_ERROR "cmake_build_output: ${cmake_build_output}" + "\ncmake_build_error: ${cmake_build_error}\n" + "FAIL: \"uic_double_build_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test" + "${config_path}-build was built successfully in the first " + "build after changing INCLUDE_PREFIX") + endif() + + set(expected_fail_string "No such file or directory|file not found") + expect_string_contains(${cmake_build_output} + "${expected_fail_string}" + SUCCESS_MESSAGE "\"uic_double_build_test\" test in \ +${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test${config_path}\ +-build has \"ui_mainwindow.h: No such file or directory\" in \ +the first build after changing INCLUDE_PREFIX" + FAILURE_MESSAGE "\"uic_double_build_test\" test in \ +${CMAKE_CURRENT_BINARY_DIR}/uic_double_build_test${config_path}\ +-build does not have \"ui_mainwindow.h: No such file or \ +directory\" in the first build after changing INCLUDE_PREFIX") + + endif() + endforeach() +endforeach() + diff --git a/tests/auto/cmake/test_qt_add_ui_4/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_4/CMakeLists.txt new file mode 100644 index 0000000000..51c74352d6 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_4/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + # A CI test fails with the below condition. So, we are running the test + # only for the Debug configuration. + if ("${generator}" MATCHES "Xcode" AND + CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(configs "Debug") + elseif(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case: widget1.ui file is touched after the first build. + # Expect 1: Successful build without the double build issue. + # Expect 2: Only touched files to be built + set(test_build_dir + "${CMAKE_CURRENT_BINARY_DIR}/UicIncrementalBuild${config_path}-build") + string(CONCAT ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/UicIncrementalBuild/src/widget1.ui") + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/UicIncrementalBuild") + + generate_hash_folder( + "example" + "${ui_file}" + hash_folder) + string(CONCAT test_file_to_check "${test_build_dir}/.qt/${hash_folder}/" + "${config_arg}/src/ui_widget1.h") + incremental_build_test( + TEST_NAME UicIncrementalBuild + SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + CONFIG "${config_arg}" + GENERATOR "${generator}" + FILE_TO_TOUCH "${ui_file}" + FILE_TO_CHECK + "${test_file_to_check}" + FOLDER_TO_CHECK + "${test_build_dir}/.qt/${hash_folder}/${config_arg}/src" + CHECK_UNWANTED_BUILDS + ) + endforeach() +endforeach() diff --git a/tests/auto/cmake/test_qt_add_ui_5/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_5/CMakeLists.txt new file mode 100644 index 0000000000..7b29bcf52b --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_5/CMakeLists.txt @@ -0,0 +1,164 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + if(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + + if("${generator}" MATCHES "Ninja") + # Test case: Add a new ui file to CMakeLists.txt after the first + # build. + # Expect 1: Expect ${target}_autogen/prefix_info.cmake to be + # generated as expected. + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_prefix_info_cmake_test${config_path}-build") + run_cmake_configure(SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + GENERATOR "${generator}" + CLEAN_FIRST + ADDITIONAL_ARGS "-DMAINWINDOW_UI_PATH=sub1/sub2/sub3/" + OUTPUT_VARIABLE cmake_output + ERROR_VARIABLE cmake_error + RESULT_VARIABLE cmake_result) + + if(NOT cmake_result EQUAL 0) + message(FATAL_ERROR "cmake_output: ${cmake_output}\ncmake_error" + ":${cmake_error}\nFAIL: \"uic_prefix_info_cmake_test\" test" + " in ${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build failed to configure") + else() + message(STATUS "PASS: \"uic_prefix_info_cmake_test\" test in" + "${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build was configured successfully") + endif() + + string(CONCAT test_ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + generate_hash_folder("example" "${test_ui_file}" + hash_folder_mainwindow) + string(CONCAT expected_prefix_info_cmake_content + "include_guard()\nset(${hash_folder_mainwindow}_prefix \"" + "sub1/sub2/sub3\")") + # read the content of the prefix_info.cmake file + string(CONCAT "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_prefix_info_cmake_test${config_path}-build") + file(READ + "${test_build_dir}/example_autogen/prefix_info.cmake" + prefix_info_cmake_content) + + if("${prefix_info_cmake_content}" STREQUAL + "${expected_prefix_info_cmake_content}") + message(STATUS "PASS: \"uic_prefix_info_cmake_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build has the expected content in " + "prefix_info.cmake") + else() + message(FATAL_ERROR "FAIL: \"uic_prefix_info_cmake_test\" test " + "in ${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build does not have the expected content in" + " prefix_info.cmake") + endif() + + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_prefix_info_cmake_test${config_path}-build") + run_cmake_build( + BUILD_DIR "${test_build_dir}" + VERBOSE ON + CONFIG "${config_arg}" + OUTPUT_VARIABLE cmake_build_output + ERROR_VARIABLE cmake_build_error + RESULT_VARIABLE cmake_build_result) + + if(NOT cmake_build_result EQUAL 0) + message(FATAL_ERROR "cmake_build_output: ${cmake_build_output}" + "\ncmake_build_error: ${cmake_build_error}\n" + "FAIL: \"uic_prefix_info_cmake_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build failed to build in the first build") + else() + message(STATUS "PASS: \"uic_prefix_info_cmake_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build was built successfully in the first " + "build") + endif() + + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_prefix_info_cmake_test${config_path}-build") + run_cmake_configure(SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + GENERATOR "${generator}" + ADDITIONAL_ARGS "-DMAINWINDOW_UI_PATH=sub1/sub2/sub3/" + "-DNEW_UI_PATH=sub5/sub6/sub7/ " "-DADD_NEW_UI=ON" + OUTPUT_VARIABLE cmake_output + ERROR_VARIABLE cmake_error + RESULT_VARIABLE cmake_result) + + if(NOT cmake_result EQUAL 0) + message(FATAL_ERROR "cmake_output: ${cmake_output}\ncmake_error" + ": ${cmake_error}\nFAIL: \"uic_prefix_info_cmake_test\" " + "test in ${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_" + "test ${config_path}-build failed to configure in the" + "second build") + else() + message(STATUS "PASS: \"uic_prefix_info_cmake_test\" test in" + " ${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build was configured successfully in the " + "second build") + endif() + + string(CONCAT test_ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/subdir/mainwindow.ui") + generate_hash_folder("example" "${test_ui_file}" + hash_folder_subdir_mainwindow) + set(expected_prefix_info_cmake_content + "include_guard()\nset(${hash_folder_subdir_mainwindow}_prefix \ +\"sub5/sub6/sub7\")") + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "uic_prefix_info_cmake_test${config_path}-build") + file(READ + "${test_build_dir}/example_autogen/prefix_info.cmake" + prefix_info_cmake_content) + + if("${prefix_info_cmake_content}" STREQUAL + "${expected_prefix_info_cmake_content}") + message(STATUS "PASS: \"uic_prefix_info_cmake_test\" test in " + "${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build has the expected content in " + "prefix_info.cmake") + else() + message(FATAL_ERROR "FAIL: \"uic_prefix_info_cmake_test\" test " + "in ${CMAKE_CURRENT_BINARY_DIR}/uic_prefix_info_cmake_test" + "${config_path}-build does not have the expected content " + "in prefix_info.cmake") + endif() + endif() + endforeach() +endforeach() + diff --git a/tests/auto/cmake/test_qt_add_ui_6/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_6/CMakeLists.txt new file mode 100644 index 0000000000..2d57c6067d --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_6/CMakeLists.txt @@ -0,0 +1,64 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + # A CI test fails with the below condition. So, we are running the test + # only for the Debug configuration. + if ("${generator}" MATCHES "Xcode" AND + CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(configs "Debug") + elseif(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case: ui_mainwindow.h is included as + # "../../../../src/ui_files/ui_mainwindow.h". + # Test case: mainwindow1.ui file is touched after the first build. + # Expect 1: Successful build without the double build issue. + # Expect 2: No build folder leakage and generation of the "_/_/_/_/" + # folder in ${hash_folder}/include. + string(CONCAT test_ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../test_qt_add_ui_" + "common/uic_test/mainwindow.ui") + generate_hash_folder("example" "${test_ui_file}" hash_folder) + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/UicBuildLeak_" + "subFolderGen${config_path}-build") + string(CONCAT test_file_to_touch "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + string(CONCAT test_file_to_check "${test_build_dir}/.qt/${hash_folder}/" + "${config_arg}/src/ui_files/ui_mainwindow.h") + incremental_build_test( + TEST_NAME UicBuildLeak_subFolderGen + SOURCE_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/../test_qt_add_ui_common/uic_test" + BUILD_DIR "${test_build_dir}" + CONFIG "${config_arg}" + GENERATOR "${generator}" + ADDITIONAL_ARGS "-DMAINWINDOW_UI_PATH=../../../../src/ui_files/" + FILE_TO_TOUCH "${test_file_to_touch}" + FILE_TO_CHECK "${test_file_to_check}" + FOLDER_TO_CHECK + "${test_build_dir}/.qt/${hash_folder}/${config_arg}/_/_/_/_" + ) + endforeach() +endforeach() diff --git a/tests/auto/cmake/test_qt_add_ui_7/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_7/CMakeLists.txt new file mode 100644 index 0000000000..8278f13a72 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_7/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + # A CI test fails with the below condition. So, we are running the test + # only for the Debug configuration. + if ("${generator}" MATCHES "Xcode" AND + CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(configs "Debug") + elseif(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case 1: There are two widget1.ui files in different folders. + # Expect 1: Successful build without the double build issue. + # Expect 2: Only touched files to be built. + string(CONCAT ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.ui") + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/sub1/sub2/sub3/" + "sub4") + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "UicIncBuild_sameFileDiffFolder${config_path}-build") + string(CONCAT test_file_to_touch "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.ui") + generate_hash_folder( + "example" + "${ui_file}" + hash_folder) + incremental_build_test( + TEST_NAME UicIncBuild_sameFileDiffFolder + SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + CONFIG "${config_arg}" + GENERATOR "${generator}" + FILE_TO_TOUCH "${test_file_to_touch}" + CHECK_UNWANTED_BUILDS + ) + + endforeach() +endforeach() diff --git a/tests/auto/cmake/test_qt_add_ui_8/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_8/CMakeLists.txt new file mode 100644 index 0000000000..f8d0763d35 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_8/CMakeLists.txt @@ -0,0 +1,67 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + # A CI test fails with the below condition. So, we are running the test + # only for the Debug configuration. + if ("${generator}" MATCHES "Xcode" AND + CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(configs "Debug") + elseif(multi_config_out) + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case: ui_mainwindow.h is included as + # "sub1/sub2/sub3/../../../../../../../../../../../../../ui_mainwindow.h". + # Test case: mainwindow1.ui file is touched after the first build. + # Expect 1: Successful build without the double build issue. + # Expect 2: No build folder leakage and generation of the + # "_/_/_/_/_/_/_/_/_/_/sub1/sub2/sub3" folder in ${hash_folder}/include. + string(CONCAT test_ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + generate_hash_folder("example" "${test_ui_file}" hash_folder) + string(CONCAT test_build_dir "${CMAKE_CURRENT_BINARY_DIR}/" + "UicBuildLeak_subFolderGen_complex${config_path}-build") + string(CONCAT test_additional_args "-DMAINWINDOW_UI_PATH=sub1/sub2/sub3" + "/../../../../../../../../../../../../../") + string(CONCAT test_file_to_touch "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + string(CONCAT test_file_to_check "${test_build_dir}/.qt/${hash_folder}/" + "${config_arg}/ui_mainwindow.h") + string(CONCAT test_folder_to_check "${test_build_dir}/.qt/${hash_folder}/" + "${config_arg}/_/_/_/_/_/_/_/_/_/_/sub1/sub2/sub3") + incremental_build_test( + TEST_NAME UicBuildLeak_subFolderGen_complex + SOURCE_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/../test_qt_add_ui_common/uic_test" + BUILD_DIR "${test_build_dir}" + CONFIG "${config_arg}" + GENERATOR "${generator}" + ADDITIONAL_ARGS "${test_additional_args}" + FILE_TO_TOUCH "${test_file_to_touch}" + FILE_TO_CHECK "${test_file_to_check}" + FOLDER_TO_CHECK "${test_folder_to_check}" + ) + endforeach() +endforeach() diff --git a/tests/auto/cmake/test_qt_add_ui_9/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_9/CMakeLists.txt new file mode 100644 index 0000000000..9e28ddc927 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_9/CMakeLists.txt @@ -0,0 +1,66 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +include(../test_qt_add_ui_common/RunCMake.cmake) +include(../test_qt_add_ui_common/functions.cmake) + +get_generators(generators) + +foreach(generator IN ITEMS ${generators}) + message(STATUS "Running tests for generator: ${generator}") + is_multi_config(${generator} multi_config_out) + if(multi_config_out) + # Since our CI machines are slow, ctest --build-and-test buffers the + # output of the configure step of a test, and the fact that we run all + # the test logic in the configure step, we need to exclude Release + # to avoid CI stdout timeout errors. + # See https://gitlab.kitware.com/cmake/cmake/-/issues/25790 + set(configs "Debug" "Release") + else() + set(configs "single_config") + endif() + + foreach(config IN ITEMS ${configs}) + if("${config}" STREQUAL "single_config") + set(config_path "") + set(config_arg "") + else() + set(config_path "_${config}") + set(config_arg "${config}") + endif() + + # Test case: ui_mainwindow.h is included as + # "sub2/sub3/../../../src/ui_files/ui_mainwindow.h". + # Expect 1: Successful build without the double build issue. + # Expect 2: No build folder leakage and generation of + # _/sub2/sub3 in ${hash_folder}/include. + # Note: This test case is a mix of previous two test cases. + string(CONCAT test_ui_file "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test/mainwindow.ui") + generate_hash_folder("example" "${test_ui_file}" hash_folder) + set(test_build_dir + "${CMAKE_CURRENT_BINARY_DIR}/UicBuildLeak_mix${config_path}-build") + string(CONCAT test_additional_args "-DMAINWINDOW_UI_PATH=sub2/sub3/" + "../../../src/ui_files/") + string(CONCAT test_file_to_check "${test_build_dir}/.qt/${hash_folder}/" + "${config_arg}/src/ui_files/ui_mainwindow.h") + string(CONCAT test_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../" + "test_qt_add_ui_common/uic_test") + incremental_build_test( + TEST_NAME UicBuildLeak_mix + SOURCE_DIR "${test_source_dir}" + BUILD_DIR "${test_build_dir}" + CONFIG "${config_arg}" + GENERATOR "${generator}" + ADDITIONAL_ARGS "${test_additional_args}" + FILE_TO_TOUCH "${test_ui_file}" + FILE_TO_CHECK "${test_file_to_check}" + FOLDER_TO_CHECK + "${test_build_dir}/.qt/${hash_folder}/${config_arg}/_/sub2/sub3" + ) + endforeach() +endforeach() + diff --git a/tests/auto/cmake/test_qt_add_ui_common/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_common/CMakeLists.txt new file mode 100644 index 0000000000..628dc9373a --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(test) + +add_executable(test main.cpp) diff --git a/tests/auto/cmake/test_qt_add_ui_common/RunCMake.cmake b/tests/auto/cmake/test_qt_add_ui_common/RunCMake.cmake new file mode 100644 index 0000000000..6b39fe3398 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/RunCMake.cmake @@ -0,0 +1,157 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +function(run_cmake_configure) + set(options CLEAN_FIRST) + set(oneValueArgs SOURCE_DIR BUILD_DIR RESULT_VARIABLE OUTPUT_VARIABLE + ERROR_VARIABLE GENERATOR) + set(multiValueArgs ADDITIONAL_ARGS) + + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" + ${ARGN}) + + if(NOT arg_SOURCE_DIR) + message(FATAL_ERROR "SOURCE_DIR not specified") + endif() + + if(NOT arg_BUILD_DIR) + message(FATAL_ERROR "BUILD_DIR not specified") + endif() + + is_multi_config(arg_GENERATOR multi_config_out) + if (NOT ${multi_config_out}) + set(run_arg_config_arg -Darg_TYPE=Debug) + endif() + + set(test_project_source_dir ${arg_SOURCE_DIR}) + set(test_project_build_dir ${arg_BUILD_DIR}) + + # Make sure that file paths are 'real' paths + get_filename_component(test_project_source_dir "${test_project_source_dir}" + REALPATH) + get_filename_component(test_project_build_dir "${test_project_build_dir}" + REALPATH) + + if(arg_CLEAN_FIRST) + file(REMOVE_RECURSE "${test_project_build_dir}") + endif() + file(MAKE_DIRECTORY "${test_project_build_dir}") + + execute_process(COMMAND + "${CMAKE_COMMAND}" + -S "${test_project_source_dir}" + -B "${test_project_build_dir}" + -G "${arg_GENERATOR}" + "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" + ${run_arg_config_arg} + ${arg_ADDITIONAL_ARGS} + RESULT_VARIABLE cmake_result + OUTPUT_VARIABLE cmake_output + ERROR_VARIABLE cmake_error + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ECHO_OUTPUT_VARIABLE + ECHO_ERROR_VARIABLE + ) + + # set output variables + set(${arg_RESULT_VARIABLE} ${cmake_result} PARENT_SCOPE) + set(${arg_OUTPUT_VARIABLE} ${cmake_output} PARENT_SCOPE) + set(${arg_ERROR_VARIABLE} ${cmake_error} PARENT_SCOPE) +endfunction() + +function(run_cmake_build) + set(options VERBOSE) + set(oneValueArgs CONFIG BUILD_DIR RESULT_VARIABLE OUTPUT_VARIABLE + ERROR_VARIABLE) + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" + ${ARGN}) + + if(NOT arg_BUILD_DIR) + message(FATAL_ERROR "BUILD_DIR not specified") + endif() + + if (arg_VERBOSE OR arg_VERBOSE STREQUAL "") + set(arg_VERBOSE_ARG --verbose) + endif() + + if(arg_CONFIG) + set(arg_BUILD_CONFIG_ARG --config ${arg_CONFIG}) + endif() + + execute_process(COMMAND ${CMAKE_COMMAND} + --build ${arg_BUILD_DIR} + ${arg_VERBOSE_ARG} + ${arg_BUILD_CONFIG_ARG} + RESULT_VARIABLE cmake_result + OUTPUT_VARIABLE cmake_output + ERROR_VARIABLE cmake_error + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ECHO_OUTPUT_VARIABLE + ECHO_ERROR_VARIABLE) + + set(${arg_RESULT_VARIABLE} ${cmake_result} PARENT_SCOPE) + set(${arg_OUTPUT_VARIABLE} ${cmake_output} PARENT_SCOPE) + set(${arg_ERROR_VARIABLE} ${cmake_error} PARENT_SCOPE) +endfunction() + +function(is_multi_config generator output) + if ("${generator}" MATCHES "Visual Studio" OR "${generator}" MATCHES "Xcode" + OR "${generator}" MATCHES "Ninja Multi-Config") + set(${output} TRUE PARENT_SCOPE) + else() + set(${output} FALSE PARENT_SCOPE) + endif() +endfunction() + +# check if string includes substring +function(_internal_string_contains output string substring) + if("${string}" MATCHES "${substring}") + set(${output} TRUE PARENT_SCOPE) + else() + set(${output} FALSE PARENT_SCOPE) + endif() +endfunction() + +function(expect_string_contains string substring) + set(oneValueArgs SUCCESS_MESSAGE FAILURE_MESSAGE) + cmake_parse_arguments(expect_string_contains "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN}) + _internal_string_contains(result "${string}" "${substring}") + if("${result}" STREQUAL TRUE) + if (expect_string_contains_SUCCESS_MESSAGE) + message(STATUS "PASS: ${expect_string_contains_SUCCESS_MESSAGE}") + else() + message(STATUS "PASS: \"${string}\" contains \"${substring}\"") + endif() + else() + if (expect_string_contains_FAILURE_MESSAGE) + message(FATAL_ERROR + "FAIL: ${expect_string_contains_FAILURE_MESSAGE}") + else() + message(FATAL_ERROR "FAIL: \"${string}\" contains \"${substring}\"") + endif() + endif() +endfunction() + +function(expect_string_not_contains string substring) + set(oneValueArgs SUCCESS_MESSAGE FAILURE_MESSAGE) + cmake_parse_arguments(expect_string_not_contains + "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + _internal_string_contains(result ${string} ${substring}) + if(${result} STREQUAL FALSE) + if (expect_string_not_contains_SUCCESS_MESSAGE) + message(STATUS "PASS: ${expect_string_not_contains_SUCCESS_MESSAGE}") + else() + message(STATUS "PASS: \"${string}\" not contains \"${substring}\"") + endif() + else() + if (expect_string_not_contains_FAILURE_MESSAGE) + message(FATAL_ERROR + "FAIL: ${expect_string_not_contains_FAILURE_MESSAGE}") + else() + message(FATAL_ERROR "FAIL: \"${string}\" contains \"${substring}\"") + endif() + endif() +endfunction() diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicBuildFolderLeakageCommon/main.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicBuildFolderLeakageCommon/main.cpp new file mode 100644 index 0000000000..27296cb9a0 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicBuildFolderLeakageCommon/main.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QApplication> + +#include "mainwindow.h" + +int main(int argc, char* argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicBuildFolderLeakageCommon/mainwindow.h b/tests/auto/cmake/test_qt_add_ui_common/UicBuildFolderLeakageCommon/mainwindow.h new file mode 100644 index 0000000000..9aeaefbe08 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicBuildFolderLeakageCommon/mainwindow.h @@ -0,0 +1,26 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget* parent = nullptr); + ~MainWindow(); + +private: + Ui::MainWindow* ui; +}; +#endif // MAINWINDOW_H diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/main.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/main.cpp new file mode 100644 index 0000000000..27296cb9a0 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/main.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QApplication> + +#include "mainwindow.h" + +int main(int argc, char* argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/mainwindow.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/mainwindow.cpp new file mode 100644 index 0000000000..d4302325fb --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/mainwindow.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "mainwindow.h" + +#include <QVBoxLayout> + +#include "../../../../src/ui_files/ui_mainwindow.h" +#include "widget1.h" + +MainWindow::MainWindow(QWidget* parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + auto layout = new QVBoxLayout; + layout->addWidget(new Widget1); + + QWidget* w = new QWidget(this); + w->setLayout(layout); + + setCentralWidget(w); +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/mainwindow.h b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/mainwindow.h new file mode 100644 index 0000000000..46dc7690cc --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/mainwindow.h @@ -0,0 +1,25 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(QWidget* parent = nullptr); + ~MainWindow(); + +private: + Ui::MainWindow* ui; +}; +#endif // MAINWINDOW_H diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/ui_files/mainwindow.ui b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/ui_files/mainwindow.ui new file mode 100644 index 0000000000..828d7c1782 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/ui_files/mainwindow.ui @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout"/> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>22</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/ui_files/widget1.ui b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/ui_files/widget1.ui new file mode 100644 index 0000000000..db0c58d5df --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/ui_files/widget1.ui @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget1</class> + <widget class="QWidget" name="Widget1"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Input:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>OnTextChanged:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="OnTextChanged"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.cpp new file mode 100644 index 0000000000..2139ff2c84 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "widget1.h" + +#include "../../../../src/ui_files/ui_widget1.h" + +Widget1::Widget1(QWidget* parent) + : QWidget(parent) + , ui(new Ui::Widget1) +{ + ui->setupUi(this); + connect(ui->lineEdit, SIGNAL(textChanged(const QString&)), this, + SLOT(onTextChanged(const QString&))); +} + +Widget1::~Widget1() +{ + delete ui; +} + +void Widget1::onTextChanged(const QString& text) +{ + ui->OnTextChanged->setText(text); +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.h b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.h new file mode 100644 index 0000000000..f8a5ad57d5 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.h @@ -0,0 +1,28 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef WIDGET1_H +#define WIDGET1_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +namespace Ui { +class Widget1; +} +QT_END_NAMESPACE + +class Widget1 : public QWidget +{ + Q_OBJECT +public: + explicit Widget1(QWidget* parent = nullptr); + ~Widget1(); +public slots: + void onTextChanged(const QString& text); + +private: + Ui::Widget1* ui; +}; + +#endif // WIDGET1_H diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.ui b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.ui new file mode 100644 index 0000000000..db0c58d5df --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget1.ui @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget1</class> + <widget class="QWidget" name="Widget1"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Input:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>OnTextChanged:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="OnTextChanged"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget2.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget2.cpp new file mode 100644 index 0000000000..721f0c868f --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget2.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "widget2.h" + +#include "../../../../ui_widget1.h" + +Widget2::Widget2(QWidget* parent) + : QWidget(parent) + , ui(new Ui::Widget2) +{ + ui->setupUi(this); + connect(ui->lineEdit, SIGNAL(textChanged(const QString&)), this, + SLOT(onTextChanged(const QString&))); +} + +Widget2::~Widget2() +{ + delete ui; +} + +void Widget2::onTextChanged(const QString& text) +{ + ui->OnTextChanged->setText(text); +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget2.h b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget2.h new file mode 100644 index 0000000000..e448b12caf --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/src/widget2.h @@ -0,0 +1,29 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef WIDGET2_H +#define WIDGET2_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +namespace Ui { +class Widget2; +} +QT_END_NAMESPACE + +class Widget2 : public QWidget +{ + Q_OBJECT + +public: + explicit Widget2(QWidget* parent = nullptr); + ~Widget2(); +public slots: + void onTextChanged(const QString& text); + +private: + Ui::Widget2* ui; +}; + +#endif // WIDGET2_H diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/sub1/sub2/sub3/sub4/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/sub1/sub2/sub3/sub4/CMakeLists.txt new file mode 100644 index 0000000000..b8443c370d --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/sub1/sub2/sub3/sub4/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) + +project(UicIncrementalBuild_sameFileDifferentFolder LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Core Widgets Gui) + +set(CMAKE_AUTOMOC ON) + +qt_add_executable(example + ../../../../src/ui_files/mainwindow.ui + ../../../../src/ui_files/widget1.ui + ../../../../widget1.ui + ../../../../src/mainwindow.h + ../../../../src/widget1.h + ../../../../src/widget2.h + ../../../../src/main.cpp + ../../../../src/mainwindow.cpp + ../../../../src/widget1.cpp + ../../../../src/widget2.cpp +) + +target_link_libraries(example PRIVATE Qt6::Widgets + Qt6::Core + Qt6::Gui) + +qt6_add_ui(example + INCLUDE_PREFIX "../../../../src/ui_files" + SOURCES "../../../../src/ui_files/mainwindow.ui" + "../../../../src/ui_files/widget1.ui" + OPTIONS "$<$<CONFIG:Debug>:-a>") + +qt6_add_ui(example + INCLUDE_PREFIX "../../../../" + SOURCES "../../../../widget1.ui" + OPTIONS "$<$<CONFIG:Debug>:-a>") + diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/widget1.ui b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/widget1.ui new file mode 100644 index 0000000000..facf4678f2 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncBuild_sameFileDiffFolder/widget1.ui @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget2</class> + <widget class="QWidget" name="Widget2"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Input:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>OnTextChanged:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="OnTextChanged"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/CMakeLists.txt new file mode 100644 index 0000000000..81023c3382 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) + +project(UicIncrementalBuild LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) + +set(CMAKE_AUTOMOC ON) + +qt_add_executable(example + src/mainwindow.ui + src/widget1.ui + src/widget2.ui + src/mainwindow.h + src/widget1.h + src/widget2.h + src/main.cpp + src/mainwindow.cpp + src/widget1.cpp + src/widget2.cpp +) + +target_link_libraries(example PRIVATE Qt6::Widgets + Qt6::Core + Qt6::Gui) + +qt6_add_ui(example + INCLUDE_PREFIX "src" + SOURCES "src/mainwindow.ui" "src/widget1.ui" "src/widget2.ui" + OPTIONS "$<$<CONFIG:Debug>:-a>") + diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/main.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/main.cpp new file mode 100644 index 0000000000..27296cb9a0 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/main.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QApplication> + +#include "mainwindow.h" + +int main(int argc, char* argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.cpp new file mode 100644 index 0000000000..ef582f187c --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "mainwindow.h" + +#include <QVBoxLayout> + +#include "src/ui_mainwindow.h" +#include "widget1.h" + +MainWindow::MainWindow(QWidget* parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + auto layout = new QVBoxLayout; + layout->addWidget(new Widget1); + + QWidget* w = new QWidget(this); + w->setLayout(layout); + + setCentralWidget(w); +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.h b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.h new file mode 100644 index 0000000000..46dc7690cc --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.h @@ -0,0 +1,25 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(QWidget* parent = nullptr); + ~MainWindow(); + +private: + Ui::MainWindow* ui; +}; +#endif // MAINWINDOW_H diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.ui b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.ui new file mode 100644 index 0000000000..828d7c1782 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/mainwindow.ui @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout"/> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>22</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.cpp new file mode 100644 index 0000000000..4047ea4d9c --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "widget1.h" + +#include "src/ui_widget1.h" + +Widget1::Widget1(QWidget* parent) + : QWidget(parent) + , ui(new Ui::Widget1) +{ + ui->setupUi(this); + connect(ui->lineEdit, SIGNAL(textChanged(const QString&)), this, + SLOT(onTextChanged(const QString&))); +} + +Widget1::~Widget1() +{ + delete ui; +} + +void Widget1::onTextChanged(const QString& text) +{ + ui->OnTextChanged->setText(text); +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.h b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.h new file mode 100644 index 0000000000..f8a5ad57d5 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.h @@ -0,0 +1,28 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef WIDGET1_H +#define WIDGET1_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +namespace Ui { +class Widget1; +} +QT_END_NAMESPACE + +class Widget1 : public QWidget +{ + Q_OBJECT +public: + explicit Widget1(QWidget* parent = nullptr); + ~Widget1(); +public slots: + void onTextChanged(const QString& text); + +private: + Ui::Widget1* ui; +}; + +#endif // WIDGET1_H diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.ui b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.ui new file mode 100644 index 0000000000..db0c58d5df --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget1.ui @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget1</class> + <widget class="QWidget" name="Widget1"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Input:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>OnTextChanged:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="OnTextChanged"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.cpp b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.cpp new file mode 100644 index 0000000000..1dc28b0c8b --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "widget2.h" + +#include "src/ui_widget2.h" + +Widget2::Widget2(QWidget* parent) + : QWidget(parent) + , ui(new Ui::Widget2) +{ + ui->setupUi(this); + connect(ui->lineEdit, SIGNAL(textChanged(const QString&)), this, + SLOT(onTextChanged(const QString&))); +} + +Widget2::~Widget2() +{ + delete ui; +} + +void Widget2::onTextChanged(const QString& text) +{ + ui->OnTextChanged->setText(text); +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.h b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.h new file mode 100644 index 0000000000..e448b12caf --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.h @@ -0,0 +1,29 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef WIDGET2_H +#define WIDGET2_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +namespace Ui { +class Widget2; +} +QT_END_NAMESPACE + +class Widget2 : public QWidget +{ + Q_OBJECT + +public: + explicit Widget2(QWidget* parent = nullptr); + ~Widget2(); +public slots: + void onTextChanged(const QString& text); + +private: + Ui::Widget2* ui; +}; + +#endif // WIDGET2_H diff --git a/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.ui b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.ui new file mode 100644 index 0000000000..facf4678f2 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/UicIncrementalBuild/src/widget2.ui @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget2</class> + <widget class="QWidget" name="Widget2"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Input:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>OnTextChanged:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="OnTextChanged"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/cmake/test_qt_add_ui_common/functions.cmake b/tests/auto/cmake/test_qt_add_ui_common/functions.cmake new file mode 100644 index 0000000000..efb8b09774 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/functions.cmake @@ -0,0 +1,223 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +function(generate_hash_folder target_name infile out_folder) + get_filename_component(infile_abs "${infile}" ABSOLUTE) + string(SHA1 infile_hash "${target_name}${infile_abs}") + string(SUBSTRING "${infile_hash}" 0 6 short_hash) + set(${out_folder} "${short_hash}" PARENT_SCOPE) +endfunction() + +function(get_latest_vs_generator output) + execute_process(COMMAND ${CMAKE_COMMAND} -G + ERROR_VARIABLE CMAKE_GENERATORS_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCHALL "Visual Studio [0-9]+ [0-9]+" vs_generators + "${CMAKE_GENERATORS_ERROR}") + + if(NOT vs_generators) + message(FATAL_ERROR "No visual studio generators found") + endif() + + set(last_version "0") + set(last_generator "") + foreach(generator IN LISTS vs_generators) + string(REGEX MATCH "Visual Studio ([0-9]+) [0-9]+" unused "${generator}") + if("${CMAKE_MATCH_1}" VERSION_GREATER "${last_version}") + set(last_version "${CMAKE_MATCH_1}") + set(last_generator "${CMAKE_MATCH_0}") + endif() + endforeach() + set(${output} "${last_generator}" PARENT_SCOPE) +endfunction() + +function(check_unwanted_builds_after_first_build cmake_output test_name test_dir + generator) + set(unwanted_builds_success_message + "\"${test_name}\" in \"${test_dir}\" -> No unwanted builds") + set(unwanted_builds_failure_message + "\"${test_name}\" in \"${test_dir}\" -> Unwanted builds found") + if(${generator} MATCHES "Ninja") + expect_string_not_contains(${cmake_output} + "widget2.cpp.o.d|mainwindow.cpp.o.d" + SUCCESS_MESSAGE ${unwanted_builds_success_message} + FAILURE_MESSAGE ${unwanted_builds_failure_message}) + elseif(${generator} MATCHES "Make") + string(CONCAT not_expect_string + "Building CXX object UicIncrementalBuild/CMakeFiles" + "/example.dir/src/widget2.cpp.o|Building CXX object UicIncremental" + "Build/CMakeFiles/example.dir/src/mainwindow.cpp.o") + expect_string_not_contains(${cmake_output} "${not_expect_string}" + SUCCESS_MESSAGE ${unwanted_builds_success_message} + FAILURE_MESSAGE ${unwanted_builds_failure_message}) + elseif(${generator} MATCHES "Visual Studio") + expect_string_not_contains(${cmake_output} "widget2.cpp|mainwindow.cpp" + SUCCESS_MESSAGE ${unwanted_builds_success_message} + FAILURE_MESSAGE ${unwanted_builds_failure_message}) + elseif(${generator} MATCHES "Xcode") + expect_string_not_contains(${cmake_output} "widget2.cpp|mainwindow.cpp" + SUCCESS_MESSAGE ${unwanted_builds_success_message} + FAILURE_MESSAGE ${unwanted_builds_failure_message}) + endif() +endfunction() + +function(check_output_after_second_build cmake_output test_name + test_dir generator) + set(second_build_success_message + "\"${test_name}\" in \"${test_dir}\" -> Generation of UI files were not \ +triggered in the second build") + set(second_build_failure_message + "\"${test_name}\" in \"${test_dir}\" -> Generation of UI files were \ +triggered in the second build") + + if(${generator} MATCHES "Ninja") + expect_string_contains(${cmake_output} "ninja: no work to do." + SUCCESS_MESSAGE ${second_build_success_message} + FAILURE_MESSAGE ${second_build_failure_message}) + elseif(${generator} MATCHES "Visual Studio" OR ${generator} MATCHES "Xcode") + expect_string_not_contains(${cmake_output} "mainwindow" + SUCCESS_MESSAGE + ${second_build_success_message} + FAILURE_MESSAGE + ${second_build_failure_message}) + elseif(${generator} MATCHES "Makefiles") + expect_string_not_contains(${cmake_output} "mainwindow.cpp.o.d -o" + SUCCESS_MESSAGE ${second_build_success_message} + FAILURE_MESSAGE ${second_build_failure_message}) + endif() +endfunction() + +function(incremental_build_test) + set(options CHECK_UNWANTED_BUILDS) + set(oneValueArgs CONFIG TEST_NAME SOURCE_DIR BUILD_DIR FILE_TO_TOUCH + FILE_TO_CHECK FOLDER_TO_CHECK GENERATOR) + set(multiValueArgs ADDITIONAL_ARGS) + + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" + ${ARGN}) + + string(REPLACE ";" " " arg_ADDITIONAL_ARGS "${arg_ADDITIONAL_ARGS}") + if ("${arg_SOURCE_DIR}" STREQUAL "") + message(FATAL_ERROR "FAIL: \"${arg_TEST_NAME}\" test failed because " + "SOURCE_DIR is empty") + endif() + + if ("${arg_BUILD_DIR}" STREQUAL "") + message(FATAL_ERROR "FAIL: \"${arg_TEST_NAME}\" test failed because " + "BUILD_DIR is empty") + endif() + + if ("${arg_GENERATOR}" STREQUAL "") + message(FATAL_ERROR "FAIL: \"${arg_TEST_NAME}\" test failed because " + "GENERATOR is empty") + endif() + + run_cmake_configure(SOURCE_DIR "${arg_SOURCE_DIR}" + BUILD_DIR "${arg_BUILD_DIR}" + GENERATOR "${arg_GENERATOR}" + CLEAN_FIRST + ADDITIONAL_ARGS ${arg_ADDITIONAL_ARGS} + OUTPUT_VARIABLE cmake_output + ERROR_VARIABLE cmake_error + RESULT_VARIABLE cmake_result) + + if(${cmake_result} EQUAL 0) + message(STATUS + "PASS: \"${arg_TEST_NAME}\" test in ${arg_BUILD_DIR} was configured " + "successfully") + else() + message(FATAL_ERROR "cmake_output: ${cmake_output}\ncmake_error: " + "${cmake_error}\nFAIL: \"${arg_TEST_NAME}\" test in ${arg_BUILD_DIR}" + " failed to configure") + endif() + + if(NOT "${arg_CONFIG}" STREQUAL "single_config") + set(config_arg "${arg_CONFIG}") + endif() + + run_cmake_build(BUILD_DIR ${arg_BUILD_DIR} + VERBOSE ON + CONFIG ${config_arg} + OUTPUT_VARIABLE cmake_build_output + ERROR_VARIABLE cmake_build_error + RESULT_VARIABLE cmake_build_result) + + if(${cmake_build_result} EQUAL 0) + message(STATUS + "PASS: \"${arg_TEST_NAME}\" test in ${arg_BUILD_DIR} was built " + "successfully") + else() + message(FATAL_ERROR + "cmake_build_output: ${cmake_build_output}\ncmake_build_error: " + "${cmake_build_error}\nFAIL: \"${arg_TEST_NAME}\" test in " + "${arg_BUILD_DIR} failed to build") + endif() + + if(NOT "${arg_FILE_TO_CHECK}" STREQUAL "") + if(NOT EXISTS "${arg_FILE_TO_CHECK}") + message(FATAL_ERROR "FAIL: \"${arg_TEST_NAME}\" ${arg_FILE_TO_CHECK}" + " could not be found") + else() + message(STATUS "PASS: \"${arg_TEST_NAME}\" \"${arg_FILE_TO_CHECK}\" " + "was generated successfully") + endif() + endif() + + if(NOT "${arg_FOLDER_TO_CHECK}" STREQUAL "" AND NOT WIN32) + if(NOT EXISTS "${arg_FOLDER_TO_CHECK}") + message(FATAL_ERROR + "FAIL: \"${arg_TEST_NAME}\" Folder \"${arg_FOLDER_TO_CHECK}\" " + "does not exist") + else() + message(STATUS + "PASS: \"${arg_TEST_NAME}\" Folder \"${arg_FOLDER_TO_CHECK}\" " + "exists") + endif() + endif() + + if(NOT "${arg_FILE_TO_TOUCH}" STREQUAL "") + file(TOUCH "${arg_FILE_TO_TOUCH}") + endif() + + run_cmake_build(BUILD_DIR ${arg_BUILD_DIR} + VERBOSE ON + CONFIG ${arg_CONFIG} + OUTPUT_VARIABLE cmake_build_output) + if(${arg_CHECK_UNWANTED_BUILDS}) + check_unwanted_builds_after_first_build(${cmake_build_output} + ${arg_TEST_NAME} ${arg_BUILD_DIR} ${arg_GENERATOR}) + endif() + + run_cmake_build(BUILD_DIR ${arg_BUILD_DIR} + VERBOSE ON + CONFIG ${arg_CONFIG} + OUTPUT_VARIABLE cmake_build_output) + check_output_after_second_build(${cmake_build_output} + ${arg_TEST_NAME} ${arg_BUILD_DIR} ${arg_GENERATOR}) +endfunction() + +function(get_generators output) + if(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Linux") + set(generators "Unix Makefiles" "Ninja" "Ninja Multi-Config") + elseif(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows") + # CI fails with Clang and Visual Studio generators. + # That's why discard that combination. + if (NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND + NOT MINGW) + get_latest_vs_generator(latest_vs) + endif() + set(generators "Ninja" "Ninja Multi-Config" "${latest_vs}") + elseif(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Darwin") + # TODO: Add Xcode generator when + # https://gitlab.kitware.com/cmake/cmake/-/issues/25790 is fixed. + # Otherwise, adding Xcode generator might fail CI due to the timeout + # issue. + set(generators "Unix Makefiles" "Ninja" "Ninja Multi-Config") + else() + string(JOIN "" ERROR_MESSAGE + "FAIL: host OS not supported for this test." + "host : ${CMAKE_HOST_SYSTEM_NAME}") + message(FATAL_ERROR "${ERROR_MESSAGE}") + endif() + set(${output} "${generators}" PARENT_SCOPE) +endfunction() diff --git a/tests/auto/cmake/test_qt_add_ui_common/main.cpp b/tests/auto/cmake/test_qt_add_ui_common/main.cpp new file mode 100644 index 0000000000..c93c3fc6a0 --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/main.cpp @@ -0,0 +1,4 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +int main() { return 0; } diff --git a/tests/auto/cmake/test_qt_add_ui_common/uic_test/CMakeLists.txt b/tests/auto/cmake/test_qt_add_ui_common/uic_test/CMakeLists.txt new file mode 100644 index 0000000000..b05efd5e4d --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/uic_test/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) + +project(UicTest LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Core Widgets Gui) + +set(CMAKE_AUTOMOC ON) + +if (NOT DO_NOT_GENERATE_FILE) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mainwindow.cpp" + CONTENT " \ +#include \"${CMAKE_CURRENT_SOURCE_DIR}/../UicBuildFolderLeakageCommon/mainwindow.h\" \n \ +#include \"${MAINWINDOW_UI_PATH}ui_mainwindow.h\" \n \ +MainWindow::MainWindow(QWidget* parent) \n \ + : QMainWindow(parent) \n \ + , ui(new Ui::MainWindow) \n \ +{ \n \ + ui->setupUi(this); \n \ +} \n \ + \n \ +MainWindow::~MainWindow() \n \ +{ \n \ + delete ui; \n \ +} \n \ +") +endif() + +qt_add_executable(example + ../UicBuildFolderLeakageCommon/main.cpp + ../UicBuildFolderLeakageCommon/mainwindow.h + mainwindow.ui +) + +if (${DO_NOT_GENERATE_FILE}) + target_sources(example PRIVATE mainwindow.cpp) +else() + target_sources(example PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/mainwindow.cpp") +endif() + +target_link_libraries(example PRIVATE Qt6::Widgets + Qt6::Core + Qt6::Gui) + +if (NOT UI_NO_CONFIG_OPTIONS) + set(uic_options "$<$<CONFIG:Debug>:-a>") +endif() +qt6_add_ui(example + INCLUDE_PREFIX "${MAINWINDOW_UI_PATH}" + SOURCES "mainwindow.ui" + OPTIONS "${uic_options}") + +if(ADD_NEW_UI) + qt6_add_ui(example INCLUDE_PREFIX "${NEW_UI_PATH}" + SOURCES "subdir/mainwindow.ui" + OPTIONS "${uic_options}") +endif() + +# Enable AUTOUIC after qt6_add_ui() has been called +if (CMAKE_AUTOUIC) + set_property(TARGET example PROPERTY AUTOUIC ON) +endif() + diff --git a/tests/auto/cmake/test_qt_add_ui_common/uic_test/mainwindow.cpp b/tests/auto/cmake/test_qt_add_ui_common/uic_test/mainwindow.cpp new file mode 100644 index 0000000000..1c4b48b49e --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/uic_test/mainwindow.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "../UicBuildFolderLeakageCommon/mainwindow.h" +#include "sub1/sub2/sub3/ui_mainwindow.h" + +MainWindow::MainWindow(QWidget* parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/tests/auto/cmake/test_qt_add_ui_common/uic_test/mainwindow.ui b/tests/auto/cmake/test_qt_add_ui_common/uic_test/mainwindow.ui new file mode 100644 index 0000000000..4e57b05eac --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/uic_test/mainwindow.ui @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>PushButton</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>23</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/cmake/test_qt_add_ui_common/uic_test/subdir/mainwindow.ui b/tests/auto/cmake/test_qt_add_ui_common/uic_test/subdir/mainwindow.ui new file mode 100644 index 0000000000..4e57b05eac --- /dev/null +++ b/tests/auto/cmake/test_qt_add_ui_common/uic_test/subdir/mainwindow.ui @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>PushButton</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>23</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/corelib/global/CMakeLists.txt b/tests/auto/corelib/global/CMakeLists.txt index 7970116672..6072a18e81 100644 --- a/tests/auto/corelib/global/CMakeLists.txt +++ b/tests/auto/corelib/global/CMakeLists.txt @@ -16,6 +16,7 @@ if(NOT INTEGRITY) add_subdirectory(qnativeinterface) endif() add_subdirectory(qrandomgenerator) +add_subdirectory(qlibraryinfo) add_subdirectory(qlogging) add_subdirectory(qtendian) add_subdirectory(qglobalstatic) diff --git a/tests/auto/corelib/global/q20/CMakeLists.txt b/tests/auto/corelib/global/q20/CMakeLists.txt index bd28f8b999..141f94d9f7 100644 --- a/tests/auto/corelib/global/q20/CMakeLists.txt +++ b/tests/auto/corelib/global/q20/CMakeLists.txt @@ -1 +1,3 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(memory) diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp index f140c23ed0..cb114bc90b 100644 --- a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp +++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp @@ -597,4 +597,4 @@ void tst_QCompareHelpers::builtinOrder() } QTEST_MAIN(tst_QCompareHelpers) -#include "tst_qcomparehelpers.moc" +#include "moc_tst_qcomparehelpers.cpp" diff --git a/tests/auto/corelib/global/qlibraryinfo/CMakeLists.txt b/tests/auto/corelib/global/qlibraryinfo/CMakeLists.txt new file mode 100644 index 0000000000..d72e871967 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qlibraryinfo LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + + +qt_internal_add_test(tst_qlibraryinfo SOURCES tst_qlibraryinfo.cpp + LIBRARIES + Qt::CorePrivate + +) + +qt_add_resources(tst_qlibraryinfo "qtconffiles" + PREFIX "/" + FILES + empty.qt.conf + partial.qt.conf + list.qt.conf + merge.qt.conf +) diff --git a/tests/auto/corelib/global/qlibraryinfo/empty.qt.conf b/tests/auto/corelib/global/qlibraryinfo/empty.qt.conf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/empty.qt.conf diff --git a/tests/auto/corelib/global/qlibraryinfo/list.qt.conf b/tests/auto/corelib/global/qlibraryinfo/list.qt.conf new file mode 100644 index 0000000000..9271b414ca --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/list.qt.conf @@ -0,0 +1,2 @@ +[Paths] +Documentation = "/path/to/mydoc","/path/to/anotherdoc","relativePath" diff --git a/tests/auto/corelib/global/qlibraryinfo/merge.qt.conf b/tests/auto/corelib/global/qlibraryinfo/merge.qt.conf new file mode 100644 index 0000000000..a687dc4d71 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/merge.qt.conf @@ -0,0 +1,5 @@ +[Paths] +QmlImports = "/path/to/myqml" + +[Config] +MergeQtConf=true diff --git a/tests/auto/corelib/global/qlibraryinfo/partial.qt.conf b/tests/auto/corelib/global/qlibraryinfo/partial.qt.conf new file mode 100644 index 0000000000..bba214c2a6 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/partial.qt.conf @@ -0,0 +1,2 @@ +[Paths] +QmlImports = "/path/to/myqml" diff --git a/tests/auto/corelib/global/qlibraryinfo/tst_qlibraryinfo.cpp b/tests/auto/corelib/global/qlibraryinfo/tst_qlibraryinfo.cpp new file mode 100644 index 0000000000..b7d79c05f5 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/tst_qlibraryinfo.cpp @@ -0,0 +1,103 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QTest> +#include <QtCore/qlibraryinfo.h> +#include <QtCore/qscopeguard.h> +#include <QtCore/private/qlibraryinfo_p.h> + + +class tst_QLibraryInfo : public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanup(); + void path_data(); + void path(); + void paths(); + void merge(); +}; + +void tst_QLibraryInfo::initTestCase() +{ +#if !QT_CONFIG(settings) + QSKIP("QSettings support is required for the test to run."); +#endif +} + +void tst_QLibraryInfo::cleanup() +{ + QLibraryInfoPrivate::setQtconfManualPath(nullptr); + QLibraryInfoPrivate::reload(); +} + +void tst_QLibraryInfo::path_data() +{ + QTest::addColumn<QString>("qtConfPath"); + QTest::addColumn<QLibraryInfo::LibraryPath>("path"); + QTest::addColumn<QString>("expected"); + + // TODO: deal with bundle on macOs? + QString baseDir = QCoreApplication::applicationDirPath(); + + // empty means we fall-back to default entries + QTest::addRow("empty_qmlimports") << ":/empty.qt.conf" << QLibraryInfo::QmlImportsPath << (baseDir + "/qml"); + QTest::addRow("empty_Data") << ":/empty.qt.conf" << QLibraryInfo::DataPath << baseDir; + + // partial override; use given entry if provided, otherwise default + QTest::addRow("partial_qmlimports") << ":/partial.qt.conf" << QLibraryInfo::QmlImportsPath << "/path/to/myqml"; + QTest::addRow("partial_Data") << ":/partial.qt.conf" << QLibraryInfo::DataPath << baseDir; +} + +void tst_QLibraryInfo::path() +{ + QFETCH(QString, qtConfPath); + QFETCH(QLibraryInfo::LibraryPath, path); + QFETCH(QString, expected); + + QLibraryInfoPrivate::setQtconfManualPath(&qtConfPath); + QLibraryInfoPrivate::reload(); + QString value = QLibraryInfo::path(path); + QCOMPARE(value, expected); + + // check consistency with paths + auto values = QLibraryInfo::paths(path); + QVERIFY(!values.isEmpty()); + QCOMPARE(values.first(), expected); +} + +void tst_QLibraryInfo::paths() +{ + QString qtConfPath(u":/list.qt.conf"); + QLibraryInfoPrivate::setQtconfManualPath(&qtConfPath); + QLibraryInfoPrivate::reload(); + + QList<QString> values = QLibraryInfo::paths(QLibraryInfo::DocumentationPath); + QCOMPARE(values.length(), 3); + QCOMPARE(values[0], "/path/to/mydoc"); + QCOMPARE(values[1], "/path/to/anotherdoc"); + QString baseDir = QCoreApplication::applicationDirPath(); + QCOMPARE(values[2], baseDir + "/relativePath"); +} + +void tst_QLibraryInfo::merge() +{ + QString qtConfPath(u":/merge.qt.conf"); + QLibraryInfoPrivate::setQtconfManualPath(&qtConfPath); + QLibraryInfoPrivate::reload(); + + QString baseDir = QCoreApplication::applicationDirPath(); + QString docPath = QLibraryInfo::path(QLibraryInfo::DocumentationPath); + // we can't know where exactly the doc path points, but it should not point to ${baseDir}/doc, + // which would be the behavior without merge_qt_conf + QCOMPARE_NE(docPath, baseDir + "/doc"); + + QList<QString> values = QLibraryInfo::paths(QLibraryInfo::QmlImportsPath); + QCOMPARE(values.size(), 2); // custom entry + Qt default entry + QCOMPARE(values[0], "/path/to/myqml"); +} + +QTEST_GUILESS_MAIN(tst_QLibraryInfo) + +#include "tst_qlibraryinfo.moc" diff --git a/tests/auto/corelib/global/qlogging/CMakeLists.txt b/tests/auto/corelib/global/qlogging/CMakeLists.txt index b3c66aeb2e..f35c9c4192 100644 --- a/tests/auto/corelib/global/qlogging/CMakeLists.txt +++ b/tests/auto/corelib/global/qlogging/CMakeLists.txt @@ -23,7 +23,6 @@ set_target_properties(qlogging_helper PROPERTIES CXX_VISIBILITY_PRESET default) qt_internal_add_test(tst_qlogging SOURCES tst_qlogging.cpp DEFINES QT_MESSAGELOGCONTEXT - HELPER_BINARY="${CMAKE_CURRENT_BINARY_DIR}/qlogging_helper" ) add_dependencies(tst_qlogging qlogging_helper) diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 861e60e256..defe3ac421 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -986,11 +986,9 @@ QString tst_qmessagehandler::backtraceHelperPath() #ifdef Q_OS_ANDROID QString appExe(QCoreApplication::applicationDirPath() + QLatin1String("/lib" BACKTRACE_HELPER_NAME ".so")); -#elif defined(Q_OS_WEBOS) +#else QString appExe(QCoreApplication::applicationDirPath() + QLatin1String("/" BACKTRACE_HELPER_NAME)); -#else - QString appExe(QLatin1String(HELPER_BINARY)); #endif return appExe; } diff --git a/tests/auto/corelib/global/qxp/CMakeLists.txt b/tests/auto/corelib/global/qxp/CMakeLists.txt index 2178f446db..8292462d17 100644 --- a/tests/auto/corelib/global/qxp/CMakeLists.txt +++ b/tests/auto/corelib/global/qxp/CMakeLists.txt @@ -1,2 +1,4 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(function_ref) add_subdirectory(is_virtual_base_of) diff --git a/tests/auto/corelib/io/CMakeLists.txt b/tests/auto/corelib/io/CMakeLists.txt index 7fdf4b52b0..291dbfb413 100644 --- a/tests/auto/corelib/io/CMakeLists.txt +++ b/tests/auto/corelib/io/CMakeLists.txt @@ -25,7 +25,7 @@ add_subdirectory(qloggingcategory) add_subdirectory(qnodebug) add_subdirectory(qsavefile) add_subdirectory(qstandardpaths) -if(NOT QNX) +if(NOT QNX AND NOT VXWORKS) add_subdirectory(qstorageinfo) endif() add_subdirectory(qtemporarydir) diff --git a/tests/auto/corelib/io/largefile/tst_largefile.cpp b/tests/auto/corelib/io/largefile/tst_largefile.cpp index 6fa3569c4f..f5af3bde63 100644 --- a/tests/auto/corelib/io/largefile/tst_largefile.cpp +++ b/tests/auto/corelib/io/largefile/tst_largefile.cpp @@ -46,6 +46,10 @@ public: // This means that files are limited to 2 GB − 1 bytes. // Limit max size to 256MB maxSizeBits = 28; // 256 MiB + #elif defined(Q_OS_VXWORKS) + // VxWorks doesn't support sparse files, also, default /tmp directory is a RAM-disk which + // limits its capacity. + maxSizeBits = 28; // 256 MiB #elif defined (Q_OS_WASM) maxSizeBits = 28; // 256 MiB #elif defined(QT_LARGEFILE_SUPPORT) @@ -494,6 +498,7 @@ void tst_LargeFile::mapFile() // 32-bit: limited to 44-bit offsets (when sizeof(off_t) == 8) //Windows: memory-mapping beyond EOF is not allowed //wasm: as for linux +//VxWorks: memory-mapping beyond EOF is not allowed void tst_LargeFile::mapOffsetOverflow() { enum { @@ -506,6 +511,9 @@ void tst_LargeFile::mapOffsetOverflow() #elif (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && (Q_PROCESSOR_WORDSIZE == 4) Succeeds = true, MaxOffset = sizeof(QT_OFF_T) > 4 ? 43 : 30 +#elif defined(Q_OS_VXWORKS) + Succeeds = false, + MaxOffset = 8 * sizeof(QT_OFF_T) - 1 #else Succeeds = true, MaxOffset = 8 * sizeof(QT_OFF_T) - 1 diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index f7d531f61f..563e4c2a83 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -1217,9 +1217,16 @@ void tst_QFileInfo::setFileTimes() QCOMPARE(file.write(data), data.size()); QCOMPARE(file.size(), data.size()); - const QDateTime before = QDateTime::currentDateTimeUtc().addMSecs(-5000); + QDateTime before = QDateTime::currentDateTimeUtc().addMSecs(-5000); + QVERIFY(file.setFileTime(before, QFile::FileModificationTime)); const QDateTime mtime = file.fileTime(QFile::FileModificationTime).toUTC(); + if (mtime.time().msec() == 0) + { + const QTime beforeTime = before.time(); + const QTime beforeTimeWithMSCutOff{beforeTime.hour(), beforeTime.minute(), beforeTime.second(), 0}; + before.setTime(beforeTimeWithMSCutOff); + } QCOMPARE(mtime, before); } diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index a5b0087f9c..184eef3f15 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -26,14 +26,18 @@ using namespace std::chrono_literals; #if defined(Q_OS_QNX) -// Longer polling times on QNX, otherwise the tests fail on the CI +constexpr bool isQNX = true; +#else +constexpr bool isQNX = false; +#endif + +#if defined(Q_OS_QNX) || defined(Q_OS_VXWORKS) +// Longer polling times on QNX and VxWorks, otherwise the tests fail on the CI constexpr auto nativeEngineTimeout = 1s; constexpr auto pollingEngineTimeout = 1s; -constexpr bool isQNX = true; #else constexpr auto nativeEngineTimeout = 0ms; constexpr auto pollingEngineTimeout = 20ms; -constexpr bool isQNX = false; #endif /* All tests need to run in temporary directories not used diff --git a/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat b/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat index 900f7ae356..8567e16850 100755 --- a/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat +++ b/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 @echo off -echo Hello
\ No newline at end of file +echo Hello diff --git a/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat b/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat index 900f7ae356..8567e16850 100755 --- a/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat +++ b/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 @echo off -echo Hello
\ No newline at end of file +echo Hello diff --git a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp index 6a2a3daaa2..560d4196b2 100644 --- a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp +++ b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp @@ -257,6 +257,9 @@ void tst_QProcessEnvironment::caseSensitivity() void tst_QProcessEnvironment::systemEnvironment() { +#ifdef Q_OS_VXWORKS + QSKIP("VxWorks do not have PATH environment variable"); +#endif static const char envname[] = "THIS_ENVIRONMENT_VARIABLE_HOPEFULLY_DOESNT_EXIST"; QByteArray path = qgetenv("PATH"); QByteArray nonexistant = qgetenv(envname); diff --git a/tests/auto/corelib/io/qresourceengine/generateResources.sh b/tests/auto/corelib/io/qresourceengine/generateResources.sh index 9894f6bfb7..ab05f1c35a 100755 --- a/tests/auto/corelib/io/qresourceengine/generateResources.sh +++ b/tests/auto/corelib/io/qresourceengine/generateResources.sh @@ -1,4 +1,6 @@ #!/bin/sh +# Copyright (C) 2016 Intel Corporation. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 count=`awk '/ZERO_FILE_LEN/ { print $3 }' tst_qresourceengine.cpp` dd if=/dev/zero of=zero.txt bs=1 count=$count rcc --binary -o uncompressed.rcc --no-compress compressed.qrc diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp b/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp index 39a3a1e012..c7b0fe7ea1 100644 --- a/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp +++ b/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QObject> class PluginClass : public QObject diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc b/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc index f5e8c849a6..56972ea764 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc +++ b/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc @@ -9,10 +9,10 @@ <file>searchpath1/search_file.txt</file>
<file>searchpath2/search_file.txt</file>
<file>search_file.txt</file>
- </qresource>
- <qresource><file>test/testdir.txt</file>
+ <file>test/testdir.txt</file>
<file>otherdir/otherdir.txt</file>
<file alias="aliasdir/aliasdir.txt">test/testdir2.txt</file>
+ <file alias="uncompresseddir/uncompressed.txt" compression-algorithm="none">aliasdir/compressme.txt</file>
<file>test/test</file>
</qresource>
<qresource lang="ko">
@@ -21,7 +21,7 @@ <qresource lang="de_CH">
<file alias="aliasdir/aliasdir.txt" compress="9" threshold="30">aliasdir/compressme.txt</file>
</qresource>
- <qresource lang="de">
+ <qresource lang="de" compression-algorithm="none">
<file alias="aliasdir/aliasdir.txt">test/german.txt</file>
</qresource>
<qresource prefix="withoutslashes">
diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index fc9b9ee201..f0dab35f81 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -45,6 +45,7 @@ private slots: private: const QString m_runtimeResourceRcc; + QByteArray m_runtimeResourceData; }; @@ -73,15 +74,27 @@ void tst_QResourceEngine::initTestCase() #endif QVERIFY(!m_runtimeResourceRcc.isEmpty()); + + QFile resourceFile(m_runtimeResourceRcc); + QVERIFY2(resourceFile.open(QIODevice::ReadOnly), qPrintable(resourceFile.errorString())); + + // register once with the file name, which will attempt to use mmap() + // (uses QDynamicFileResourceRoot) QVERIFY(QResource::registerResource(m_runtimeResourceRcc)); - QVERIFY(QResource::registerResource(m_runtimeResourceRcc, "/secondary_root/")); + + // and register a second time with a gifted memory block + // (uses QDynamicBufferResourceRoot) + m_runtimeResourceData = resourceFile.readAll(); + auto resourcePtr = reinterpret_cast<const uchar *>(m_runtimeResourceData.constData()); + QVERIFY(QResource::registerResource(resourcePtr, "/secondary_root/")); } void tst_QResourceEngine::cleanupTestCase() { // make sure we don't leak memory QVERIFY(QResource::unregisterResource(m_runtimeResourceRcc)); - QVERIFY(QResource::unregisterResource(m_runtimeResourceRcc, "/secondary_root/")); + auto resourcePtr = reinterpret_cast<const uchar *>(m_runtimeResourceData.constData()); + QVERIFY(QResource::unregisterResource(resourcePtr, "/secondary_root/")); } void tst_QResourceEngine::compressedResource_data() @@ -180,6 +193,7 @@ void tst_QResourceEngine::checkStructure_data() #if defined(BUILTIN_TESTDATA) << QLatin1String("testqrc") #endif + << QLatin1String("uncompresseddir") << QLatin1String("withoutslashes"); QTest::newRow("root dir") << QString(":/") @@ -212,56 +226,56 @@ void tst_QResourceEngine::checkStructure_data() for(int i = 0; i < roots.size(); ++i) { const QString root = roots.at(i); - QTest::addRow("%s prefix dir", qPrintable(root)) << QString(root + "test/abc/123/+++") + QTest::addRow("prefix dir on %s", qPrintable(root)) << QString(root + "test/abc/123/+++") << QByteArray() << (QStringList() << QLatin1String("currentdir.txt") << QLatin1String("currentdir2.txt") << QLatin1String("parentdir.txt")) << (QStringList() << QLatin1String("subdir")) << QLocale::c() << qlonglong(0); - QTest::addRow("%s parent to prefix", qPrintable(root)) << QString(root + "test/abc/123") + QTest::addRow("parent to prefix on %s", qPrintable(root)) << QString(root + "test/abc/123") << QByteArray() << QStringList() << (QStringList() << QLatin1String("+++")) << QLocale::c() << qlonglong(0); - QTest::addRow("%s two parents prefix", qPrintable(root)) << QString(root + "test/abc") + QTest::addRow("two parents prefix on %s", qPrintable(root)) << QString(root + "test/abc") << QByteArray() << QStringList() << QStringList(QLatin1String("123")) << QLocale::c() << qlonglong(0); - QTest::addRow("%s test dir ", qPrintable(root)) << QString(root + "test") + QTest::addRow("test dir on %s", qPrintable(root)) << QString(root + "test") << QByteArray() << (QStringList() << QLatin1String("testdir.txt")) << (QStringList() << QLatin1String("abc") << QLatin1String("test")) << QLocale::c() << qlonglong(0); - QTest::addRow("%s prefix no slashes", qPrintable(root)) << QString(root + "withoutslashes") + QTest::addRow("prefix no slashes on %s", qPrintable(root)) << QString(root + "withoutslashes") << QByteArray() << QStringList("blahblah.txt") << QStringList() << QLocale::c() << qlonglong(0); - QTest::addRow("%s other dir", qPrintable(root)) << QString(root + "otherdir") + QTest::addRow("other dir on %s", qPrintable(root)) << QString(root + "otherdir") << QByteArray() << QStringList(QLatin1String("otherdir.txt")) << QStringList() << QLocale::c() << qlonglong(0); - QTest::addRow("%s alias dir", qPrintable(root)) << QString(root + "aliasdir") + QTest::addRow("alias dir on %s", qPrintable(root)) << QString(root + "aliasdir") << QByteArray() << QStringList(QLatin1String("aliasdir.txt")) << QStringList() << QLocale::c() << qlonglong(0); - QTest::addRow("%s second test dir", qPrintable(root)) << QString(root + "test/test") + QTest::addRow("second test dir on %s", qPrintable(root)) << QString(root + "test/test") << QByteArray() << (QStringList() << QLatin1String("test1.txt") << QLatin1String("test2.txt")) << QStringList() @@ -269,7 +283,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(0); info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test1.txt")); - QTest::addRow("%s test1 text", qPrintable(root)) << QString(root + "test/test/test1.txt") + QTest::addRow("test1 text on %s", qPrintable(root)) << QString(root + "test/test/test1.txt") << QByteArray("abc\n") << QStringList() << QStringList() @@ -277,7 +291,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/blahblah.txt")); - QTest::addRow("%s text no slashes", qPrintable(root)) << QString(root + "withoutslashes/blahblah.txt") + QTest::addRow("text no slashes on %s", qPrintable(root)) << QString(root + "withoutslashes/blahblah.txt") << QByteArray("qwerty\n") << QStringList() << QStringList() @@ -286,7 +300,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test2.txt")); - QTest::addRow("%s test2 text", qPrintable(root)) << QString(root + "test/test/test2.txt") + QTest::addRow("test2 text on %s", qPrintable(root)) << QString(root + "test/test/test2.txt") << QByteArray("def\n") << QStringList() << QStringList() @@ -294,7 +308,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/currentdir.txt")); - QTest::addRow("%s currentdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir.txt") + QTest::addRow("currentdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir.txt") << QByteArray("\"This is the current dir\"\n") << QStringList() << QStringList() @@ -302,7 +316,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/currentdir2.txt")); - QTest::addRow("%s currentdir text2", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir2.txt") + QTest::addRow("currentdir text2 on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir2.txt") << QByteArray("\"This is also the current dir\"\n") << QStringList() << QStringList() @@ -310,7 +324,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("parentdir.txt")); - QTest::addRow("%s parentdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/parentdir.txt") + QTest::addRow("parentdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/parentdir.txt") << QByteArray("abcdefgihklmnopqrstuvwxyz \n") << QStringList() << QStringList() @@ -318,7 +332,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/subdir/subdir.txt")); - QTest::addRow("%s subdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/subdir/subdir.txt") + QTest::addRow("subdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/subdir/subdir.txt") << QByteArray("\"This is in the sub directory\"\n") << QStringList() << QStringList() @@ -326,7 +340,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir.txt")); - QTest::addRow("%s testdir text", qPrintable(root)) << QString(root + "test/testdir.txt") + QTest::addRow("testdir text on %s", qPrintable(root)) << QString(root + "test/testdir.txt") << QByteArray("\"This is in the test directory\"\n") << QStringList() << QStringList() @@ -334,7 +348,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/otherdir/otherdir.txt")); - QTest::addRow("%s otherdir text", qPrintable(root)) << QString(root + "otherdir/otherdir.txt") + QTest::addRow("otherdir text on %s", qPrintable(root)) << QString(root + "otherdir/otherdir.txt") << QByteArray("\"This is the other dir\"\n") << QStringList() << QStringList() @@ -342,7 +356,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir2.txt")); - QTest::addRow("%s alias text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("alias text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is another file in this directory\"\n") << QStringList() << QStringList() @@ -350,7 +364,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt")); - QTest::addRow("%s korean text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("korean text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is a korean text file\"\n") << QStringList() << QStringList() @@ -358,7 +372,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt")); - QTest::addRow("%s korean text 2", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("korean text 2 on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is a korean text file\"\n") << QStringList() << QStringList() @@ -366,7 +380,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt")); - QTest::addRow("%s german text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("german text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("Deutsch\n") << QStringList() << QStringList() @@ -374,7 +388,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt")); - QTest::addRow("%s german text 2", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("german text 2 on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("Deutsch\n") << QStringList() << QStringList() @@ -384,8 +398,16 @@ void tst_QResourceEngine::checkStructure_data() QFile file(QFINDTESTDATA("testqrc/aliasdir/compressme.txt")); QVERIFY(file.open(QFile::ReadOnly)); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/compressme.txt")); - QTest::addRow("%s compressed text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") - << file.readAll() + QByteArray compressmeContents = file.readAll(); + QTest::addRow("compressed text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + << compressmeContents + << QStringList() + << QStringList() + << QLocale("de_CH") + << qlonglong(info.size()); + + QTest::addRow("non-compressed text on %s", qPrintable(root)) << QString(root + "uncompresseddir/uncompressed.txt") + << compressmeContents << QStringList() << QStringList() << QLocale("de_CH") @@ -463,6 +485,18 @@ void tst_QResourceEngine::checkStructure() // check that it is still valid after closing the file file.close(); QCOMPARE(ba, contents); + + // memory should be writable because we used MapPrivateOption + *ptr = '\0'; + + // but shouldn't affect the actual file or a new mapping + QFile file2(pathName); + QVERIFY(file2.open(QFile::ReadOnly)); + QCOMPARE(file2.readAll(), contents); + ptr = file2.map(0, file.size(), QFile::MapPrivateOption); + QVERIFY2(ptr, qPrintable(file2.errorString())); + QByteArrayView bav(reinterpret_cast<const char *>(ptr), file.size()); + QCOMPARE(bav, contents); } QLocale::setDefault(QLocale::system()); } diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 4bb7042790..84d0a505a4 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -430,7 +430,7 @@ void tst_qstandardpaths::testAppConfigLocation() #endif } -#ifndef Q_OS_WIN +#if !defined(Q_OS_WIN) && !defined(Q_OS_WASM) // Find "sh" on Unix. // It may exist twice, in /bin/sh and /usr/bin/sh, in that case use the PATH order. static inline QFileInfo findSh() @@ -484,6 +484,7 @@ void tst_qstandardpaths::testFindExecutable_data() << QString() << logo << logoPath; } #else +# ifndef Q_OS_WASM const QFileInfo shFi = findSh(); Q_ASSERT(shFi.exists()); const QString shPath = shFi.absoluteFilePath(); @@ -493,6 +494,7 @@ void tst_qstandardpaths::testFindExecutable_data() << QString() << shPath << shPath; QTest::newRow("unix-sh-relativepath") << QString(shFi.absolutePath()) << QString::fromLatin1("./sh") << shPath; +#endif /* !WASM */ #endif QTest::newRow("idontexist") << QString() << QString::fromLatin1("idontexist") << QString(); @@ -524,6 +526,9 @@ void tst_qstandardpaths::testFindExecutable() void tst_qstandardpaths::testFindExecutableLinkToDirectory() { +#ifdef Q_OS_WASM + QSKIP("No applicationdir on wasm"); +#else // link to directory const QString target = QDir::tempPath() + QDir::separator() + QLatin1String("link.lnk"); QFile::remove(target); @@ -531,6 +536,7 @@ void tst_qstandardpaths::testFindExecutableLinkToDirectory() QVERIFY(appFile.link(target)); QVERIFY(QStandardPaths::findExecutable(target).isEmpty()); QFile::remove(target); +#endif } using RuntimeDirSetup = std::optional<QString> (*)(QDir &); diff --git a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp index 6a6339a8ec..5242988fd1 100644 --- a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp +++ b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp @@ -262,7 +262,9 @@ void tst_QStorageInfo::freeSpaceUpdate() FlushFileBuffers(HANDLE(_get_osfhandle(file.handle()))); #elif _POSIX_VERSION >= 200112L fsync(file.handle()); +# ifndef Q_OS_VXWORKS sync(); +# endif // Q_OS_VXWORKS #endif }; diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index bd454fb695..2024968435 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -3776,13 +3776,13 @@ void tst_QUrl::setComponents_data() << PrettyDecoded << QString() << "foo:/path"; QTest::newRow("host-empty") << QUrl("foo://example.com/path") << int(Host) << "" << Tolerant << true - << PrettyDecoded << QString() << "foo:///path"; + << PrettyDecoded << "" << "foo:///path"; QTest::newRow("authority-null") << QUrl("foo://example.com/path") << int(Authority) << QString() << Tolerant << true << PrettyDecoded << QString() << "foo:/path"; QTest::newRow("authority-empty") << QUrl("foo://example.com/path") << int(Authority) << "" << Tolerant << true - << PrettyDecoded << QString() << "foo:///path"; + << PrettyDecoded << "" << "foo:///path"; QTest::newRow("query-null") << QUrl("http://example.com/?q=foo") << int(Query) << QString() << Tolerant << true << PrettyDecoded << QString() << "http://example.com/"; @@ -3840,10 +3840,10 @@ void tst_QUrl::setComponents_data() << PrettyDecoded << QString() << QString(); QTest::newRow("invalid-authority-1") << QUrl("http://example.com") << int(Authority) << "-not-valid-" << Tolerant << false - << PrettyDecoded << QString() << QString(); + << PrettyDecoded << "" << QString(); QTest::newRow("invalid-authority-2") << QUrl("http://example.com") << int(Authority) << "%31%30.%30.%30.%31" << Strict << false - << PrettyDecoded << QString() << QString(); + << PrettyDecoded << "" << QString(); QTest::newRow("invalid-path-0") << QUrl("http://example.com") << int(Path) << "{}" << Strict << false diff --git a/tests/auto/corelib/itemmodels/CMakeLists.txt b/tests/auto/corelib/itemmodels/CMakeLists.txt index 90211669d9..c0cd04df12 100644 --- a/tests/auto/corelib/itemmodels/CMakeLists.txt +++ b/tests/auto/corelib/itemmodels/CMakeLists.txt @@ -4,15 +4,17 @@ add_subdirectory(qstringlistmodel) if(TARGET Qt::Gui) add_subdirectory(qabstractitemmodel) - add_subdirectory(qabstractproxymodel) - add_subdirectory(qconcatenatetablesproxymodel) - add_subdirectory(qidentityproxymodel) + if(QT_FEATURE_proxymodel) + add_subdirectory(qabstractproxymodel) + add_subdirectory(qconcatenatetablesproxymodel) + add_subdirectory(qidentityproxymodel) + add_subdirectory(qsortfilterproxymodel_recursive) + add_subdirectory(qsortfilterproxymodel_regularexpression) + add_subdirectory(qtransposeproxymodel) + endif() add_subdirectory(qitemselectionmodel) - add_subdirectory(qsortfilterproxymodel_recursive) - add_subdirectory(qsortfilterproxymodel_regularexpression) - add_subdirectory(qtransposeproxymodel) endif() -if(TARGET Qt::Widgets) +if(TARGET Qt::Widgets AND QT_FEATURE_proxymodel) add_subdirectory(qsortfilterproxymodel) endif() if(TARGET Qt::Sql AND TARGET Qt::Widgets) diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp index 36eb9320a4..c48b79b260 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -6,7 +6,9 @@ #include <QtTest/private/qcomparisontesthelper_p.h> #include <QtCore/QCoreApplication> +#if QT_CONFIG(sortfilterproxymodel) #include <QtCore/QSortFilterProxyModel> +#endif #include <QtCore/QStringListModel> #include <QtGui/QStandardItemModel> @@ -80,9 +82,11 @@ private slots: void testMoveWithinOwnRange_data(); void testMoveWithinOwnRange(); +#if QT_CONFIG(sortfilterproxymodel) void testMoveThroughProxy(); void testReset(); +#endif void testDataChanged(); @@ -989,9 +993,9 @@ void tst_QAbstractItemModel::complexChangesWithPersistent() void tst_QAbstractItemModel::modelIndexComparisons() { - QTestPrivate::testEqualityOperatorsCompile<QModelIndex>(); - QTestPrivate::testEqualityOperatorsCompile<QPersistentModelIndex>(); - QTestPrivate::testEqualityOperatorsCompile<QPersistentModelIndex, QModelIndex>(); + QTestPrivate::testAllComparisonOperatorsCompile<QModelIndex>(); + QTestPrivate::testAllComparisonOperatorsCompile<QPersistentModelIndex>(); + QTestPrivate::testAllComparisonOperatorsCompile<QPersistentModelIndex, QModelIndex>(); QtTestModel model(3, 3); @@ -999,13 +1003,28 @@ void tst_QAbstractItemModel::modelIndexComparisons() QModelIndex mi22 = model.index(2, 2); QPersistentModelIndex pmi11 = mi11; QPersistentModelIndex pmi22 = mi22; + QPersistentModelIndex pmiU; QT_TEST_EQUALITY_OPS(mi11, mi11, true); QT_TEST_EQUALITY_OPS(mi11, mi22, false); + QT_TEST_ALL_COMPARISON_OPS(mi11, mi11, Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(mi11, mi22, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(mi22, mi11, Qt::strong_ordering::greater); QT_TEST_EQUALITY_OPS(pmi11, pmi11, true); QT_TEST_EQUALITY_OPS(pmi11, pmi22, false); QT_TEST_EQUALITY_OPS(pmi11, mi11, true); QT_TEST_EQUALITY_OPS(pmi11, mi22, false); + + QT_TEST_ALL_COMPARISON_OPS(pmi11, pmi11, Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(pmi11, pmi22, Qt::strong_ordering::less); + // Disengaged QPMIs are sorted randomly (based on address of their Private) + // So all we can check here is QPMIs with d == nullptr, which should reliably + // come before any others. + QT_TEST_ALL_COMPARISON_OPS(pmiU, pmiU, Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(pmi11, pmiU, Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(pmi11, mi11, Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(pmi11, mi22, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(pmiU, mi11, Qt::strong_ordering::less); } void tst_QAbstractItemModel::testMoveSameParentDown_data() @@ -1239,6 +1258,7 @@ void tst_QAbstractItemModel::testMoveSameParentUp() } } +#if QT_CONFIG(sortfilterproxymodel) void tst_QAbstractItemModel::testMoveThroughProxy() { QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this); @@ -1257,6 +1277,7 @@ void tst_QAbstractItemModel::testMoveThroughProxy() moveCommand->setDestRow(0); moveCommand->doCommand(); } +#endif void tst_QAbstractItemModel::testMoveToGrandParent_data() { @@ -1804,6 +1825,7 @@ void tst_QAbstractItemModel::testMoveWithinOwnRange() QCOMPARE(afterSpy.size(), 0); } +#if QT_CONFIG(proxymodel) class ListenerObject : public QObject { Q_OBJECT @@ -1822,7 +1844,7 @@ private: QList<QPersistentModelIndex> m_persistentIndexes; QModelIndexList m_nonPersistentIndexes; }; - +#endif class ModelWithCustomRole : public QStringListModel { @@ -1836,6 +1858,7 @@ public: } }; +#if QT_CONFIG(proxymodel) ListenerObject::ListenerObject(QAbstractProxyModel *parent) : QObject(parent), m_model(parent) { @@ -1876,7 +1899,9 @@ void ListenerObject::slotReset() QVERIFY(!idx.isValid()); } } +#endif +#if QT_CONFIG(sortfilterproxymodel) void tst_QAbstractItemModel::testReset() { QSignalSpy beforeResetSpy(m_model, &DynamicTreeModel::modelAboutToBeReset); @@ -1931,6 +1956,7 @@ void tst_QAbstractItemModel::testReset() // After being reset the proxy must be queried again. QCOMPARE(nullProxy->roleNames().value(Qt::UserRole + 1), QByteArray()); } +#endif class CustomRoleModel : public QStringListModel { diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp index 45f7a6c08d..08233a1f7b 100644 --- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -57,8 +57,10 @@ private slots: void merge(); void isRowSelected(); void childrenDeselectionSignal(); +#if QT_CONFIG(proxymodel) void layoutChangedWithAllSelected1(); void layoutChangedWithAllSelected2(); +#endif void layoutChangedTreeSelection(); void deselectRemovedMiddleRange(); void setModel(); @@ -75,7 +77,9 @@ private slots: void QTBUG48402(); void QTBUG58851_data(); +#if QT_CONFIG(proxymodel) void QTBUG58851(); +#endif void QTBUG18001_data(); void QTBUG18001(); @@ -2260,6 +2264,7 @@ void tst_QItemSelectionModel::childrenDeselectionSignal() QVERIFY(selectionModel.selection().contains(sel2)); } +#if QT_CONFIG(proxymodel) void tst_QItemSelectionModel::layoutChangedWithAllSelected1() { QStringListModel model( QStringList() << "foo" << "bar" << "foo2"); @@ -2338,6 +2343,7 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected2() for (const auto &index : indexList) QVERIFY(selection.isSelected(index)); } +#endif // This test is a regression test for QTBUG-2804. void tst_QItemSelectionModel::layoutChangedTreeSelection() @@ -2752,6 +2758,7 @@ void tst_QItemSelectionModel::QTBUG58851_data() << IntPair(2, 3)); } +#if QT_CONFIG(proxymodel) void tst_QItemSelectionModel::QTBUG58851() { using IntPair = std::pair<int, int>; @@ -2796,6 +2803,7 @@ void tst_QItemSelectionModel::QTBUG58851() QVERIFY(selections.isSelected(i)); } } +#endif void tst_QItemSelectionModel::QTBUG18001_data() { @@ -2973,7 +2981,7 @@ void tst_QItemSelectionModel::destroyModel() selectionModel->setCurrentIndex(itemModel->index(1, 0), QItemSelectionModel::Select); QVERIFY(selectionModel->currentIndex().isValid()); - QTest::failOnWarning(QRegularExpression(".*")); + QTest::failOnWarning(); itemModel.reset(); QVERIFY(!selectionModel->currentIndex().isValid()); QVERIFY(selectionModel->selection().isEmpty()); diff --git a/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt b/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt index 9a40a2f905..eccde38df2 100644 --- a/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qelapsedtimer SOURCES tst_qelapsedtimer.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp b/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp index 7623fd2e43..7a2b12b2eb 100644 --- a/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp +++ b/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp @@ -5,6 +5,7 @@ #include <QtCore/QString> #include <QtCore/QElapsedTimer> #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QTimer> static const int minResolution = 100; // the minimum resolution for the tests @@ -22,6 +23,7 @@ class tst_QElapsedTimer : public QObject Q_OBJECT private Q_SLOTS: + void compareCompiles(); void statics(); void validity(); void basics(); @@ -29,6 +31,11 @@ private Q_SLOTS: void msecsTo(); }; +void tst_QElapsedTimer::compareCompiles() +{ + QTestPrivate::testAllComparisonOperatorsCompile<QElapsedTimer>(); +} + void tst_QElapsedTimer::statics() { // these have been required since Qt 6.6 @@ -77,6 +84,7 @@ void tst_QElapsedTimer::basics() QVERIFY(!(t1 < t1)); QCOMPARE(t1.msecsTo(t1), qint64(0)); QCOMPARE(t1.secsTo(t1), qint64(0)); + QT_TEST_ALL_COMPARISON_OPS(t1, t1, Qt::strong_ordering::equal); quint64 value1 = t1.msecsSinceReference(); qDebug() << "value1:" << value1 << "t1:" << t1; @@ -141,10 +149,16 @@ void tst_QElapsedTimer::msecsTo() QTest::qSleep(minResolution); QElapsedTimer t2; t2.start(); - - QVERIFY(t1 != t2); - QVERIFY(!(t1 == t2)); - QVERIFY(t1 < t2); + QTest::qSleep(minResolution); + QElapsedTimer t3; + t3.start(); + + QT_TEST_EQUALITY_OPS(t1, t2, false); + QT_TEST_EQUALITY_OPS(QElapsedTimer(), QElapsedTimer(), true); + QT_TEST_EQUALITY_OPS(QElapsedTimer(), t2, false); + QT_TEST_ALL_COMPARISON_OPS(t1, t2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(t3, t2, Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(t3, QElapsedTimer(), Qt::strong_ordering::greater); auto diff = t1.msecsTo(t2); QVERIFY2(diff > 0, QString("difference t1 and t2 is %1").arg(diff).toLatin1()); diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index ee13c32353..182ec6daae 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -3,11 +3,15 @@ #include <QTest> #include <QSignalSpy> +#if QT_CONFIG(sortfilterproxymodel) #include <QSortFilterProxyModel> +#endif #include <qobject.h> #include <qmetaobject.h> +#if QT_CONFIG(proxymodel) #include <qabstractproxymodel.h> +#endif #include <private/qmetaobject_p.h> Q_DECLARE_METATYPE(const QMetaObject *) @@ -1906,6 +1910,7 @@ void tst_QMetaObject::invokeBlockingQueuedPointer() void tst_QMetaObject::qtMetaObjectInheritance() { QVERIFY(!QObject::staticMetaObject.superClass()); +#if QT_CONFIG(sortfilterproxymodel) QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("Qt::CaseSensitivity"), -1); QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("CaseSensitivity"), -1); int indexOfSortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.indexOfProperty("sortCaseSensitivity"); @@ -1913,6 +1918,7 @@ void tst_QMetaObject::qtMetaObjectInheritance() QMetaProperty sortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.property(indexOfSortCaseSensitivity); QVERIFY(sortCaseSensitivity.isValid()); QCOMPARE(sortCaseSensitivity.enumerator().name(), "CaseSensitivity"); +#endif } struct MyType @@ -2515,7 +2521,9 @@ void tst_QMetaObject::metaType() { QCOMPARE(QObject::staticMetaObject.metaType(), QMetaType::fromType<QObject>()); QCOMPARE(MyGadget::staticMetaObject.metaType(), QMetaType::fromType<MyGadget>()); +#if QT_CONFIG(proxymodel) QCOMPARE(QAbstractProxyModel::staticMetaObject.metaType(), QMetaType::fromType<QAbstractProxyModel>()); +#endif auto qtNameSpaceMetaType = Qt::staticMetaObject.metaType(); QVERIFY2(!qtNameSpaceMetaType.isValid(), qtNameSpaceMetaType.name()); } diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp index c8053ca43a..3bf6211a53 100644 --- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp +++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp @@ -170,11 +170,55 @@ public: {} }; +enum FreeEnum { + FreeEnumValue1, + FreeEnumValue2 +}; + +namespace MySpace { + enum NamespacedEnum { + NamespacedEnumValue1, + NamespacedEnumValue2 + }; +}; + +namespace MyQtSpace { + Q_NAMESPACE + enum NamespacedEnum { + NamespacedEnumValue1, + NamespacedEnumValue2 + }; + Q_DECLARE_FLAGS(NamespacedFlags, NamespacedEnum) + Q_FLAG_NS(NamespacedFlags) +}; + +namespace SeparateEnumNamespace { + Q_NAMESPACE + enum Enum { + Value1, + Value2 + }; + Q_ENUM_NS(Enum) +}; +namespace SeparateFlagsNamespace { + Q_NAMESPACE + Q_DECLARE_FLAGS(Flags, SeparateEnumNamespace::Enum) + Q_FLAG_NS(Flags) +} + class EnumFlagsTester : public QObject { Q_OBJECT Q_PROPERTY(TestEnum enumProperty READ enumProperty WRITE setEnumProperty) Q_PROPERTY(TestFlags flagProperty READ flagProperty WRITE setFlagProperty) + + Q_PROPERTY(FreeEnum freeEnumProperty READ freeEnumProperty WRITE setFreeEnumProperty) + Q_PROPERTY(MySpace::NamespacedEnum namespacedEnumProperty READ namespacedEnumProperty WRITE setNamespacedEnumProperty) + Q_PROPERTY(MyQtSpace::NamespacedEnum qtNamespacedEnumProperty READ qtNamespacedEnumProperty WRITE setQtNamespacedEnumProperty) + Q_PROPERTY(MyQtSpace::NamespacedFlags qtNamespacedFlagProperty READ qtNamespacedFlagProperty WRITE setQtNamespacedFlagProperty) + + Q_PROPERTY(SeparateEnumNamespace::Enum sepEnum READ sepEnum WRITE setSepEnum) + Q_PROPERTY(SeparateFlagsNamespace::Flags sepFlags READ sepFlags WRITE setSepFlags) public: enum TestEnum { e1, e2 }; Q_ENUM(TestEnum) @@ -190,9 +234,35 @@ public: TestFlags flagProperty() const { return m_flags; } void setFlagProperty(TestFlags f) { m_flags = f; } + FreeEnum freeEnumProperty() const { return m_freeEnum; } + void setFreeEnumProperty(FreeEnum e) { m_freeEnum = e; } + + MySpace::NamespacedEnum namespacedEnumProperty() const { return m_namespacedEnum; } + void setNamespacedEnumProperty(MySpace::NamespacedEnum e) { m_namespacedEnum = e; } + + MyQtSpace::NamespacedEnum qtNamespacedEnumProperty() const { return m_qtNamespaceEnum; } + void setQtNamespacedEnumProperty(MyQtSpace::NamespacedEnum e) { m_qtNamespaceEnum = e; } + + MyQtSpace::NamespacedFlags qtNamespacedFlagProperty() const { return m_qtNamespaceFlags; } + void setQtNamespacedFlagProperty(MyQtSpace::NamespacedFlags f) { m_qtNamespaceFlags = f; } + + SeparateEnumNamespace::Enum sepEnum() const { return m_sepEnum; } + void setSepEnum(SeparateEnumNamespace::Enum e) { m_sepEnum = e; } + + SeparateFlagsNamespace::Flags sepFlags() const { return m_sepFlags; } + void setSepFlags(SeparateFlagsNamespace::Flags f) { m_sepFlags = f; } + private: TestEnum m_enum = e1; TestFlags m_flags; + + FreeEnum m_freeEnum = FreeEnum::FreeEnumValue1; + MySpace::NamespacedEnum m_namespacedEnum = MySpace::NamespacedEnumValue1; + MyQtSpace::NamespacedEnum m_qtNamespaceEnum = MyQtSpace::NamespacedEnumValue1; + MyQtSpace::NamespacedFlags m_qtNamespaceFlags; + + SeparateEnumNamespace::Enum m_sepEnum = SeparateEnumNamespace::Value1; + SeparateFlagsNamespace::Flags m_sepFlags; }; Q_DECLARE_OPERATORS_FOR_FLAGS(EnumFlagsTester::TestFlags) @@ -265,7 +335,7 @@ void tst_QMetaProperty::conversion() void tst_QMetaProperty::enumsFlags() { // QTBUG-83689, verify that enumerations and flags can be assigned from int, - // which is important for Qt Designer. + // which is important for Qt Widgets Designer. EnumFlagsTester t; auto mo = t.metaObject(); @@ -276,6 +346,7 @@ void tst_QMetaProperty::enumsFlags() QVERIFY(enumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); QVERIFY(enumProperty.write(&t, QVariant(int(EnumFlagsTester::e2)))); QCOMPARE(t.enumProperty(), EnumFlagsTester::e2); + QVERIFY(enumProperty.enumerator().isValid()); // OK: Q_ENUM const int flagsIndex = mo->indexOfProperty("flagProperty"); QVERIFY(flagsIndex >= 0); @@ -283,6 +354,55 @@ void tst_QMetaProperty::enumsFlags() QVERIFY(flagsProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); QVERIFY(flagsProperty.write(&t, QVariant(int(EnumFlagsTester::flag2)))); QCOMPARE(t.flagProperty(), EnumFlagsTester::flag2); + QVERIFY(!flagsProperty.enumerator().isValid()); // Not using Q_FLAG + + const int freeEnumIndex = mo->indexOfProperty("freeEnumProperty"); + QVERIFY(freeEnumIndex >= 0); + auto freeEnumProperty = mo->property(freeEnumIndex); + QVERIFY(freeEnumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(freeEnumProperty.write(&t, QVariant(FreeEnumValue2))); + QCOMPARE(t.freeEnumProperty(), FreeEnumValue2); + QVERIFY(!freeEnumProperty.enumerator().isValid()); // Not using Q_ENUM + + const int namespacedEnumIndex = mo->indexOfProperty("namespacedEnumProperty"); + QVERIFY(namespacedEnumIndex >= 0); + auto namespacedEnumProperty = mo->property(namespacedEnumIndex); + QVERIFY(namespacedEnumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(namespacedEnumProperty.write(&t, QVariant(MySpace::NamespacedEnumValue2))); + QCOMPARE(t.namespacedEnumProperty(), MySpace::NamespacedEnumValue2); + QVERIFY(!namespacedEnumProperty.enumerator().isValid()); // Not using Q_NAMESPACE/Q_ENUM_NS + + const int qtNamespacedEnumIndex = mo->indexOfProperty("qtNamespacedEnumProperty"); + QVERIFY(qtNamespacedEnumIndex >= 0); + auto qtNamespacedEnumProperty = mo->property(qtNamespacedEnumIndex); + QVERIFY(qtNamespacedEnumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(qtNamespacedEnumProperty.write(&t, QVariant(MyQtSpace::NamespacedEnumValue2))); + QCOMPARE(t.qtNamespacedEnumProperty(), MyQtSpace::NamespacedEnumValue2); + QVERIFY(qtNamespacedEnumProperty.enumerator().isValid()); // OK: Q_ENUM_NS + + const int qtNamespacedFlagIndex = mo->indexOfProperty("qtNamespacedFlagProperty"); + QVERIFY(qtNamespacedFlagIndex >= 0); + auto qtNamespacedFlagProperty = mo->property(qtNamespacedFlagIndex); + QVERIFY(qtNamespacedFlagProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(qtNamespacedFlagProperty.write(&t, QVariant(MyQtSpace::NamespacedFlags(MyQtSpace::NamespacedEnumValue2)))); + QCOMPARE(t.qtNamespacedFlagProperty(), MyQtSpace::NamespacedFlags(MyQtSpace::NamespacedEnumValue2)); + QVERIFY(qtNamespacedFlagProperty.enumerator().isValid()); // OK: Q_FLAG + + const int sepEnumIndex = mo->indexOfProperty("sepEnum"); + QVERIFY(sepEnumIndex >= 0); + auto sepEnumProperty = mo->property(sepEnumIndex); + QVERIFY(sepEnumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(sepEnumProperty.write(&t, QVariant(SeparateEnumNamespace::Value2))); + QCOMPARE(t.sepEnum(), SeparateEnumNamespace::Value2); + QVERIFY(sepEnumProperty.enumerator().isValid()); // OK: Q_ENUM_NS + + const int sepFlagsIndex = mo->indexOfProperty("sepFlags"); + QVERIFY(sepFlagsIndex >= 0); + auto sepFlagsProperty = mo->property(sepFlagsIndex); + QVERIFY(sepFlagsProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(sepFlagsProperty.write(&t, QVariant(SeparateEnumNamespace::Value1))); + QCOMPARE(t.sepFlags(), SeparateEnumNamespace::Value1); + QVERIFY(!sepFlagsProperty.enumerator().isValid()); // NOK: the meta object is empty } diff --git a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt index b93d961109..65bec3e187 100644 --- a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt @@ -51,6 +51,7 @@ qt_internal_add_test(tst_qmetatype ../../../other/qvariant_common LIBRARIES Qt::CorePrivate + Qt::TestPrivate Qt::Gui qmetatype_lib1 qmetatype_lib2 diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h index 1694e49491..bcd2fe2def 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h @@ -111,6 +111,7 @@ private slots: void customDebugStream(); void unknownType(); void fromType(); + void compareCompiles(); void operatorEq_data(); void operatorEq(); void operatorEq2_data(); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp index 68bcb53056..661c1f6072 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp @@ -5,6 +5,7 @@ #include "tst_qmetatype_libs.h" #include <QtCore/private/qmetaobjectbuilder_p.h> +#include <QtTest/private/qcomparisontesthelper_p.h> void tst_QMetaType::constRefs() { @@ -418,6 +419,11 @@ struct CharTemplate } y; }; +void tst_QMetaType::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QMetaType>(); +} + void tst_QMetaType::operatorEq_data() { QTest::addColumn<QMetaType>("typeA"); @@ -447,10 +453,7 @@ void tst_QMetaType::operatorEq() QFETCH(QMetaType, typeB); QFETCH(bool, eq); - QCOMPARE(typeA == typeB, eq); - QCOMPARE(typeB == typeA, eq); - QCOMPARE(typeA != typeB, !eq); - QCOMPARE(typeB != typeA, !eq); + QT_TEST_EQUALITY_OPS(typeA, typeB, eq); #if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY) // for built-in types or locally-defined types, this must also hold true @@ -487,10 +490,10 @@ FOR_EACH_CORE_METATYPE(GET_METATYPE_FROM_TYPE) QCOMPARE(fromId2.id(), type); // confirm that they're all equal - QCOMPARE(fromId1, fromId2); - QCOMPARE(fromType1, fromType2); - QCOMPARE(fromType1, fromId1); - QCOMPARE(fromType2, fromId2); + QT_TEST_EQUALITY_OPS(fromId1, fromId2, true); + QT_TEST_EQUALITY_OPS(fromType1, fromType2, true); + QT_TEST_EQUALITY_OPS(fromType1, fromId1, true); + QT_TEST_EQUALITY_OPS(fromType2, fromId2, true); #if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY) // for built-in types (other than void), this must be true @@ -541,7 +544,7 @@ void tst_QMetaType::operatorEqAcrossLibs() // DO THIS FIRST: // if this isn't a built-in type, then the QMetaTypeInterface::typeId is // initially set to 0 - QCOMPARE(lib1Type, lib2Type); + QT_TEST_EQUALITY_OPS(lib1Type, lib2Type, true); int actualTypeId = localType.id(); bool builtinTypeExpected = builtinTypeId != QMetaType::UnknownType; @@ -559,8 +562,8 @@ void tst_QMetaType::operatorEqAcrossLibs() QCOMPARE(lib2Type.id(), actualTypeId); QCOMPARE(QByteArray(lib1Type.name()), QByteArray(localType.name())); QCOMPARE(QByteArray(lib2Type.name()), QByteArray(localType.name())); - QCOMPARE(lib1Type, localType); - QCOMPARE(lib2Type, localType); + QT_TEST_EQUALITY_OPS(lib1Type, localType, true); + QT_TEST_EQUALITY_OPS(lib2Type, localType, true); #if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY) if (actualTypeId < QMetaType::FirstGuiType && actualTypeId != QMetaType::Void) { diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 23d41cafb2..a8e2c7bda3 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -544,6 +544,9 @@ void tst_QVariant::isNull() var3 = QVariant(QMetaType::fromType<QString>()); QVERIFY( var3.isNull() ); + var3.setValue(QString()); + QVERIFY( !var3.isNull() ); + QVariant var4( 0 ); QVERIFY( !var4.isNull() ); diff --git a/tests/auto/corelib/platform/android/tst_android.cpp b/tests/auto/corelib/platform/android/tst_android.cpp index 07b939969c..76811a31ad 100644 --- a/tests/auto/corelib/platform/android/tst_android.cpp +++ b/tests/auto/corelib/platform/android/tst_android.cpp @@ -353,6 +353,9 @@ void tst_Android::orientationChange() QFETCH(Qt::ScreenOrientation, expected); QFETCH(QSize, screenSize); + if (QNativeInterface::QAndroidApplication::sdkVersion() == __ANDROID_API_P__) + QSKIP("Android 9 orientation changes callbacks are buggy (QTBUG-124890)."); + // For QTBUG-94459 to check that the widget size are consistent after orientation changes QWidget widget; widget.show(); diff --git a/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp b/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp index 5ad961ee66..3c609238fc 100644 --- a/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp +++ b/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp @@ -69,6 +69,7 @@ struct QComObjectTraits<IDirect> }; } // namespace QtPrivate +QT_END_NAMESPACE class tst_QComObject : public QObject { @@ -263,6 +264,4 @@ void tst_QComObject::Release_decrementsReferenceCountByOne() QTEST_MAIN(tst_QComObject) # include "tst_qcomobject.moc" -QT_END_NAMESPACE - #endif // Q_OS_WIN diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt index 6cb69fc46d..daf922b42c 100644 --- a/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause set_directory_properties(PROPERTIES _qt_good_targets "" _qt_stub_targets "" diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp b/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp index 24bac391fb..eed7228a29 100644 --- a/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp @@ -1 +1,3 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only void dummy() {} diff --git a/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt b/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt index 1e1e820b14..ec6c1979f7 100644 --- a/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt +++ b/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt @@ -9,6 +9,8 @@ qt_internal_add_test(tst_quuid OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../" SOURCES ../tst_quuid.cpp + LIBRARIES + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp index c5ce490b61..08a5b826e9 100644 --- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp +++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp @@ -3,6 +3,7 @@ #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #if QT_CONFIG(process) #include <QProcess> #endif @@ -17,6 +18,7 @@ class tst_QUuid : public QObject private slots: void initTestCase(); + void compareCompiles(); void fromChar(); void toString(); void fromString_data(); @@ -89,20 +91,28 @@ void tst_QUuid::initTestCase() uuidD = QUuid(0x21f7f8de, 0x8051, 0x5b89, 0x86, 0x80, 0x01, 0x95, 0xef, 0x79, 0x8b, 0x6a); } +void tst_QUuid::compareCompiles() +{ + QTestPrivate::testAllComparisonOperatorsCompile<QUuid>(); +#if defined(Q_OS_WIN) + QTestPrivate::testEqualityOperatorsCompile<QUuid, GUID>(); +#endif +} + void tst_QUuid::fromChar() { - QCOMPARE(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); - QCOMPARE(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); - QCOMPARE(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5")); - QCOMPARE(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5")); - QCOMPARE(QUuid(), QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c")); - QCOMPARE(QUuid(), QUuid("{fc69b59e-cc34")); - QCOMPARE(QUuid(), QUuid("fc69b59e-cc34-")); - QCOMPARE(QUuid(), QUuid("fc69b59e-cc34")); - QCOMPARE(QUuid(), QUuid("cc34")); - QCOMPARE(QUuid(), QUuid(nullptr)); - - QCOMPARE(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); + QT_TEST_EQUALITY_OPS(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5}"), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5"), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("{fc69b59e-cc34"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("fc69b59e-cc34-"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("fc69b59e-cc34"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("cc34"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid(nullptr), true); + + QT_TEST_EQUALITY_OPS(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")), true); } void tst_QUuid::toString() @@ -162,21 +172,21 @@ void tst_QUuid::fromString() const auto inputL1 = input.toLatin1(); const auto inputU8 = input.toUtf8(); - QCOMPARE(expected, QUuid(input)); - QCOMPARE(expected, QUuid(inputU8)); - QCOMPARE(expected, QUuid(inputL1)); + QT_TEST_EQUALITY_OPS(expected, QUuid(input), true); + QT_TEST_EQUALITY_OPS(expected, QUuid(inputU8), true); + QT_TEST_EQUALITY_OPS(expected, QUuid(inputL1), true); - QCOMPARE(expected, QUuid::fromString(input)); + QT_TEST_EQUALITY_OPS(expected, QUuid::fromString(input), true); // for QLatin1String, construct one whose data() is not NUL-terminated: const auto longerInputL1 = inputL1 + '5'; // the '5' makes the premature end check incorrectly succeed const auto inputL1S = QLatin1String(longerInputL1.data(), inputL1.size()); - QCOMPARE(expected, QUuid::fromString(inputL1S)); + QT_TEST_EQUALITY_OPS(expected, QUuid::fromString(inputL1S), true); // for QUtf8StringView, too: const auto longerInputU8 = inputU8 + '5'; // the '5' makes the premature end check incorrectly succeed const auto inputU8S = QUtf8StringView(longerInputU8.data(), inputU8.size()); - QCOMPARE(expected, QUuid::fromString(inputU8S)); + QT_TEST_EQUALITY_OPS(expected, QUuid::fromString(inputU8S), true); } void tst_QUuid::toByteArray() @@ -196,27 +206,30 @@ void tst_QUuid::toByteArray() void tst_QUuid::fromByteArray() { - QCOMPARE(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); - QCOMPARE(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); - QCOMPARE(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); - QCOMPARE(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); - QCOMPARE(QUuid(), QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c"))); + QT_TEST_EQUALITY_OPS(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5}")), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5")), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5")), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c")), true); - QCOMPARE(uuidB, QUuid(QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); + QT_TEST_EQUALITY_OPS(uuidB, QUuid(QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")), true); } void tst_QUuid::toRfc4122() { QCOMPARE(uuidA.toRfc4122(), QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5")); - QCOMPARE(uuidB.toRfc4122(), QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")); } void tst_QUuid::fromRfc4122() { - QCOMPARE(uuidA, QUuid::fromRfc4122(QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5"))); + QT_TEST_EQUALITY_OPS( + uuidA, + QUuid::fromRfc4122(QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5")), true); - QCOMPARE(uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b"))); + QT_TEST_EQUALITY_OPS( + uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")), + true); } void tst_QUuid::id128() @@ -234,15 +247,15 @@ void tst_QUuid::id128() 0xba, 0x47, 0xec, 0x7e, 0x99, 0x03, 0x9a, 0x7b, } }; - QCOMPARE(QUuid(bytesA), uuidA); - QCOMPARE(QUuid(bytesB), uuidB); + QT_TEST_EQUALITY_OPS(QUuid(bytesA), uuidA, true); + QT_TEST_EQUALITY_OPS(QUuid(bytesB), uuidB, true); QVERIFY(memcmp(uuidA.toBytes().data, bytesA.data, sizeof(QUuid::Id128Bytes)) == 0); QVERIFY(memcmp(uuidB.toBytes().data, bytesB.data, sizeof(QUuid::Id128Bytes)) == 0); QUuid::Id128Bytes leBytesA = {}; for (int i = 0; i < 16; i++) leBytesA.data[15 - i] = bytesA.data[i]; - QCOMPARE(QUuid(leBytesA, QSysInfo::LittleEndian), uuidA); + QT_TEST_EQUALITY_OPS(QUuid(leBytesA, QSysInfo::LittleEndian), uuidA, true); QVERIFY(memcmp(uuidA.toBytes(QSysInfo::LittleEndian).data, leBytesA.data, sizeof(leBytesA)) == 0); // check the new q{To,From}{Big,Little}Endian() overloads @@ -271,16 +284,16 @@ void tst_QUuid::uint128() constexpr QUuid uuid = QUuid::fromUInt128(be); static_assert(uuid.toUInt128() == be, "Round-trip through QUuid failed"); - QCOMPARE(uuid, uuidA); + QT_TEST_EQUALITY_OPS(uuid, uuidA, true); QCOMPARE(uuid.toUInt128(), be); quint128 le = qFromBigEndian(be); QCOMPARE(uuid.toUInt128(QSysInfo::LittleEndian), le); - QCOMPARE(QUuid::fromUInt128(le, QSysInfo::LittleEndian), uuidA); + QT_TEST_EQUALITY_OPS(QUuid::fromUInt128(le, QSysInfo::LittleEndian), uuidA, true); QUuid::Id128Bytes bytes = { .data128 = { qToBigEndian(u) } }; QUuid uuid2(bytes); - QCOMPARE(uuid2, uuid); + QT_TEST_EQUALITY_OPS(uuid2, uuid, true); // verify that toBytes() and toUInt128() provide bytewise similar result constexpr quint128 val = uuid.toUInt128(); @@ -294,11 +307,11 @@ void tst_QUuid::uint128() void tst_QUuid::createUuidV3OrV5() { //"www.widgets.com" is also from RFC4122 - QCOMPARE(uuidC, QUuid::createUuidV3(uuidNS, QByteArray("www.widgets.com"))); - QCOMPARE(uuidC, QUuid::createUuidV3(uuidNS, QString("www.widgets.com"))); + QT_TEST_EQUALITY_OPS(uuidC, QUuid::createUuidV3(uuidNS, QByteArray("www.widgets.com")), true); + QT_TEST_EQUALITY_OPS(uuidC, QUuid::createUuidV3(uuidNS, QString("www.widgets.com")), true); - QCOMPARE(uuidD, QUuid::createUuidV5(uuidNS, QByteArray("www.widgets.com"))); - QCOMPARE(uuidD, QUuid::createUuidV5(uuidNS, QString("www.widgets.com"))); + QT_TEST_EQUALITY_OPS(uuidD, QUuid::createUuidV5(uuidNS, QByteArray("www.widgets.com")), true); + QT_TEST_EQUALITY_OPS(uuidD, QUuid::createUuidV5(uuidNS, QString("www.widgets.com")), true); } void tst_QUuid::check_QDataStream() @@ -314,7 +327,7 @@ void tst_QUuid::check_QDataStream() QDataStream in(&ar,QIODevice::ReadOnly); in.setByteOrder(QDataStream::BigEndian); in >> tmp; - QCOMPARE(uuidA, tmp); + QT_TEST_EQUALITY_OPS(uuidA, tmp, true); } { QDataStream out(&ar,QIODevice::WriteOnly); @@ -325,7 +338,7 @@ void tst_QUuid::check_QDataStream() QDataStream in(&ar,QIODevice::ReadOnly); in.setByteOrder(QDataStream::LittleEndian); in >> tmp; - QCOMPARE(uuidA, tmp); + QT_TEST_EQUALITY_OPS(uuidA, tmp, true); } } @@ -340,14 +353,14 @@ void tst_QUuid::isNull() void tst_QUuid::equal() { - QVERIFY( !(uuidA == uuidB) ); + QT_TEST_EQUALITY_OPS(uuidA, uuidB, false); QUuid copy(uuidA); - QCOMPARE(uuidA, copy); + QT_TEST_EQUALITY_OPS(uuidA, copy, true); QUuid assigned; assigned = uuidA; - QCOMPARE(uuidA, assigned); + QT_TEST_EQUALITY_OPS(uuidA, assigned, true); } @@ -384,10 +397,12 @@ void tst_QUuid::less() QVERIFY( uuidB <= uuidA); QVERIFY(!(uuidA < uuidB) ); QVERIFY(!(uuidA <= uuidB)); + QT_TEST_ALL_COMPARISON_OPS(uuidB, uuidA, Qt::strong_ordering::less); QUuid null_uuid; QVERIFY(null_uuid < uuidA); // Null uuid is always less than a valid one QVERIFY(null_uuid <= uuidA); + QT_TEST_ALL_COMPARISON_OPS(null_uuid, uuidA, Qt::strong_ordering::less); QVERIFY(null_uuid <= null_uuid); QVERIFY(uuidA <= uuidA); @@ -400,6 +415,7 @@ void tst_QUuid::more() QVERIFY( uuidA >= uuidB); QVERIFY(!(uuidB > uuidA)); QVERIFY(!(uuidB >= uuidA)); + QT_TEST_ALL_COMPARISON_OPS(uuidA, uuidB, Qt::strong_ordering::greater); QUuid null_uuid; QVERIFY(!(null_uuid > uuidA)); // Null uuid is always less than a valid one @@ -407,6 +423,7 @@ void tst_QUuid::more() QVERIFY(null_uuid >= null_uuid); QVERIFY(uuidA >= uuidA); + QT_TEST_ALL_COMPARISON_OPS(uuidA, uuidA, Qt::strong_ordering::equal); } @@ -512,7 +529,7 @@ void tst_QUuid::qvariant() QUuid uuid2 = v.value<QUuid>(); QVERIFY(!uuid2.isNull()); - QCOMPARE(uuid, uuid2); + QT_TEST_EQUALITY_OPS(uuid, uuid2, true); } void tst_QUuid::qvariant_conversion() @@ -544,7 +561,7 @@ void tst_QUuid::qvariant_conversion() QVariant sv = QVariant::fromValue(uuid.toByteArray()); QCOMPARE(sv.metaType(), QMetaType(QMetaType::QByteArray)); QVERIFY(sv.canConvert<QUuid>()); - QCOMPARE(sv.value<QUuid>(), uuid); + QT_TEST_EQUALITY_OPS(sv.value<QUuid>(), uuid, true); } } diff --git a/tests/auto/corelib/serialization/CMakeLists.txt b/tests/auto/corelib/serialization/CMakeLists.txt index 3792336255..45965114cc 100644 --- a/tests/auto/corelib/serialization/CMakeLists.txt +++ b/tests/auto/corelib/serialization/CMakeLists.txt @@ -3,7 +3,9 @@ add_subdirectory(json) add_subdirectory(qcborstreamreader) -add_subdirectory(qcborstreamwriter) +if(QT_FEATURE_cborstreamwriter) + add_subdirectory(qcborstreamwriter) +endif() if(NOT WASM) add_subdirectory(qcborvalue) endif() diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 23b25834b9..e480b033e1 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -7,7 +7,9 @@ #include <QBuffer> #include <QCborStreamReader> +#if QT_CONFIG(cborstreamwriter) #include <QCborStreamWriter> +#endif #include <QDateTime> #include <QtEndian> #include <QTimeZone> @@ -86,9 +88,11 @@ private slots: void comparisonMap(); void toCbor_data(); +#if QT_CONFIG(cborstreamwriter) void toCbor(); void toCborStreamWriter_data() { toCbor_data(); } void toCborStreamWriter(); +#endif void fromCbor_data(); void fromCbor(); void fromCborStreamReaderByteArray_data() { fromCbor_data(); } @@ -2311,6 +2315,7 @@ void tst_QCborValue::toCbor_data() QTest::newRow("UseInteger:-2^65") << QCborValue(-2 * 18446744073709551616.0) << raw("\xfb\xc4\0\0\0""\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers); } +#if QT_CONFIG(cborstreamwriter) void tst_QCborValue::toCbor() { QFETCH(QCborValue, v); @@ -2350,6 +2355,7 @@ void tst_QCborValue::toCborStreamWriter() QCOMPARE(buffer.pos(), result.size()); QCOMPARE(output, result); } +#endif void tst_QCborValue::fromCbor_data() { @@ -2667,12 +2673,14 @@ void tst_QCborValue::extendedTypeValidation() QCOMPARE(error.offset, data.size()); QT_TEST_EQUALITY_OPS(decoded, expected, true); +#if QT_CONFIG(cborstreamwriter) QByteArray encoded = decoded.toCbor(); #if QT_VERSION < QT_VERSION_CHECK(6,0,0) // behavior change, see qdatetime.cpp:fromIsoTimeString QEXPECT_FAIL("DateTime:Null-at-19", "QDateTime parsing fixed, but only in 6.0", Abort); #endif QCOMPARE(encoded, data); +#endif } void tst_QCborValue::hugeDeviceValidation_data() @@ -3000,7 +3008,9 @@ template <typename ValueRef> static void cborValueRef_template() else QCOMPARE(ref.toVariant(), v.toVariant()); QCOMPARE(ref.toJsonValue(), v.toJsonValue()); +#if QT_CONFIG(cborstreamwriter) QCOMPARE(ref.toCbor(), v.toCbor()); +#endif QCOMPARE(ref.toDiagnosticNotation(), v.toDiagnosticNotation()); } @@ -3160,6 +3170,7 @@ void tst_QCborValue::datastreamSerialization_data() void tst_QCborValue::datastreamSerialization() { +#if QT_CONFIG(cborstreamwriter) QFETCH(QCborValue, v); QByteArray buffer; { @@ -3187,6 +3198,7 @@ void tst_QCborValue::datastreamSerialization() load >> output; QCOMPARE(output, map); } +#endif } void tst_QCborValue::streamVariantSerialization() diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index 77ca884897..9a227c782d 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -143,9 +143,11 @@ private slots: void stream_QJsonObject(); void stream_QJsonValue(); +#if QT_CONFIG(cborstreamwriter) void stream_QCborArray(); void stream_QCborMap(); void stream_QCborValue(); +#endif void setVersion_data(); void setVersion(); @@ -2326,6 +2328,7 @@ void tst_QDataStream::stream_QJsonValue() } } +#if QT_CONFIG(cborstreamwriter) void tst_QDataStream::stream_QCborArray() { QByteArray buffer; @@ -2361,6 +2364,7 @@ void tst_QDataStream::stream_QCborValue() load >> valueLoad; QCOMPARE(valueLoad, valueSave); } +#endif void tst_QDataStream::setVersion_data() { @@ -3254,11 +3258,13 @@ void tst_QDataStream::streamRealDataTypes() // Generate QPicture from pixmap. QPixmap pm(open_xpm); QVERIFY(!pm.isNull()); +#ifndef QT_NO_PICTURE QPicture picture; picture.setBoundingRect(QRect(QPoint(0, 0), pm.size())); QPainter painter(&picture); painter.drawPixmap(0, 0, pm); painter.end(); +#endif // Generate path QPainterPath path; @@ -3296,7 +3302,9 @@ void tst_QDataStream::streamRealDataTypes() stream << QPointF(3, 5) << QRectF(-1, -2, 3, 4) << (QPolygonF() << QPointF(0, 0) << QPointF(1, 2)); stream << QTransform().rotate(90).scale(2, 2).asAffineMatrix(); stream << path; +#ifndef QT_NO_PICTURE stream << picture; +#endif stream << QTextLength(QTextLength::VariableLength, 1.5); stream << color; stream << radialBrush << conicalBrush; @@ -3310,7 +3318,9 @@ void tst_QDataStream::streamRealDataTypes() QPolygonF polygon {{3, 4}, {5, 6}}; QTransform transform; QPainterPath p = otherPath; +#ifndef QT_NO_PICTURE QPicture pict; +#endif QTextLength textLength(QTextLength::FixedLength, 2.5); QColor col(128, 128, 127); QBrush rGrad(Qt::CrossPattern); @@ -3363,6 +3373,7 @@ void tst_QDataStream::streamRealDataTypes() QCOMPARE(transform, QTransform().rotate(90).scale(2, 2)); stream >> p; QCOMPARE(p, path); +#ifndef QT_NO_PICTURE if (i == 1) { stream >> pict; @@ -3376,6 +3387,7 @@ void tst_QDataStream::streamRealDataTypes() QCOMPARE(pictA, pictB); } +#endif stream >> textLength; QCOMPARE(textLength, QTextLength(QTextLength::VariableLength, 1.5)); stream >> col; diff --git a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt index c78a81c7bd..8922ae2267 100644 --- a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt +++ b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt @@ -15,3 +15,10 @@ qt_internal_add_test(tst_qbytearrayview SOURCES tst_qbytearrayview.cpp ) + +if(QT_FEATURE_sanitize_undefined) + qt_internal_extend_target(tst_qbytearrayview + DEFINES + QT_SANITIZE_UNDEFINED # GCC (in)famously doesn't provide a predefined macro for this + ) +endif() diff --git a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp index 894f0430dd..702e1840da 100644 --- a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp +++ b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp @@ -262,10 +262,9 @@ void tst_QByteArrayView::constExpr() const static_assert(!bv2.empty()); static_assert(bv2.size() == 5); } -#if !defined(Q_CC_GNU) || defined(Q_CC_CLANG) +#if !defined(Q_CC_GNU_ONLY) || !defined(QT_SANITIZE_UNDEFINED) // Below checks are disabled because of a compilation issue with GCC and // -fsanitize=undefined. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962. - // Note: Q_CC_GNU is also defined for Clang, so we need to check that too. { static constexpr char hello[] = "Hello"; constexpr QByteArrayView bv(hello); @@ -307,6 +306,9 @@ void tst_QByteArrayView::constExpr() const static_assert(bv.back() == 'o'); static_assert(bv.last() == 'o'); + constexpr auto bv2 = QByteArrayView::fromArray(hello); + QCOMPARE_EQ(bv, bv2); + constexpr std::string_view sv = bv; static_assert(bv.size() == sv.size()); #ifdef AMBIGUOUS_CALL // QTBUG-108805 @@ -416,7 +418,7 @@ void tst_QByteArrayView::fromArray() const { static constexpr char hello[] = "Hello\0abc\0\0."; - constexpr QByteArrayView bv = QByteArrayView::fromArray(hello); + const QByteArrayView bv = QByteArrayView::fromArray(hello); QCOMPARE(bv.size(), 13); QVERIFY(!bv.empty()); QVERIFY(!bv.isEmpty()); diff --git a/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp b/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp index 82e12bdfca..ba098fd23c 100644 --- a/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp +++ b/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp @@ -25,6 +25,7 @@ class tst_QLatin1StringMatcher : public QObject private slots: void overloads(); void staticOverloads(); + void staticOverloads_QStringViewHaystack(); void interface(); void indexIn(); void haystacksWithMoreThan4GiBWork(); @@ -44,6 +45,12 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("Hellohello"_L1), 5); QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), -1); + QCOMPARE(m.indexIn(u"Hellohello"), 5); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), -1); } { QLatin1StringMatcher m("Hello"_L1, Qt::CaseSensitive); @@ -53,6 +60,12 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("Hellohello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), -1); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m("hello"_L1, Qt::CaseInsensitive); @@ -63,6 +76,13 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m("Hello"_L1, Qt::CaseInsensitive); @@ -73,6 +93,13 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m(hello, Qt::CaseSensitive); @@ -81,6 +108,11 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn(hello, 1), -1); QCOMPARE(m.indexIn(hello2, 1), hello.size()); QCOMPARE(m.indexIn(hello2, 6), -1); + + QCOMPARE(m.indexIn(QString::fromLatin1(hello)), 0); + QCOMPARE(m.indexIn(QString::fromLatin1(hello), 1), -1); + QCOMPARE(m.indexIn(QString::fromLatin1(hello2), 1), hello.size()); + QCOMPARE(m.indexIn(QString::fromLatin1(hello2), 6), -1); } } @@ -206,6 +238,129 @@ void tst_QLatin1StringMatcher::staticOverloads() #endif } +void tst_QLatin1StringMatcher::staticOverloads_QStringViewHaystack() +{ +#ifdef QT_STATIC_BOYER_MOORE_NOT_SUPPORTED + QSKIP("Test is only valid on an OS that supports static latin1 string matcher"); +#else + constexpr QStringView hello = u"hello"; + QString hello2B = QStringView(hello).toString().repeated(2); + hello2B += QStringView(u"🍉"); + QStringView hello2(hello2B); + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 5); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); // from is 1 + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 5); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("Hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 5); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉"), 6), -1); + QCOMPARE(m.indexIn(QStringView(u"He🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hel🍉")), 0); + QCOMPARE(m.indexIn(hello), -1); + QCOMPARE(m.indexIn(hello2, 2), -1); // from is 2 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 5); + static_assert(m.indexIn(QStringView(u"helloHello🍉"), 6) == -1); + static_assert(m.indexIn(QStringView(u"He🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == -1); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("Hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("b\xF8"); + QCOMPARE(m.indexIn(QStringView(u"B\xD8")), 0); + QCOMPARE(m.indexIn(QStringView(u"B\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xD8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8lle")), 0); + QCOMPARE(m.indexIn(QStringView(u"m\xF8lle")), -1); + QCOMPARE(m.indexIn(QStringView(u"Si b\xF8")), 3); + } + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("b\xF8"); + QCOMPARE(m.indexIn(QStringView(u"B\xD8")), -1); + QCOMPARE(m.indexIn(QStringView(u"B\xF8")), -1); + QCOMPARE(m.indexIn(QStringView(u"b\xD8")), -1); + QCOMPARE(m.indexIn(QStringView(u"b\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8lle")), 0); + QCOMPARE(m.indexIn(QStringView(u"m\xF8lle")), -1); + QCOMPARE(m.indexIn(QStringView(u"Si b\xF8")), 3); + } +#endif +} + void tst_QLatin1StringMatcher::interface() { QLatin1StringView needle = "abc123"_L1; @@ -387,25 +542,35 @@ void tst_QLatin1StringMatcher::haystacksWithMoreThan4GiBWork() QCOMPARE(large.size(), BaseSize + needle.size()); qDebug("created dataset in %lld ms", timer.elapsed()); - using MaybeThread = std::thread; - - // - // WHEN: trying to match an occurrence past the 4GiB mark - // - - qsizetype dynamicResult; - - auto t = MaybeThread{ [&] { - QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); - dynamicResult = m.indexIn(QLatin1StringView(large)); - } }; - t.join(); + { + // + // WHEN: trying to match an occurrence past the 4GiB mark + // + qsizetype dynamicResult; + auto t = std::thread{ [&] { + QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); + dynamicResult = m.indexIn(QLatin1StringView(large)); + } }; + t.join(); + + // + // THEN: the result index is not truncated + // + + QCOMPARE(dynamicResult, qsizetype(BaseSize)); + } - // - // THEN: the result index is not trucated - // + { + qsizetype dynamicResult; + auto t = std::thread{ [&] { + QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); + dynamicResult = m.indexIn(QStringView(QString::fromLatin1(large))); + } }; + t.join(); + + QCOMPARE(dynamicResult, qsizetype(BaseSize)); + } - QCOMPARE(dynamicResult, qsizetype(BaseSize)); #else QSKIP("This test is 64-bit only."); #endif diff --git a/tests/auto/corelib/text/qlocale/CMakeLists.txt b/tests/auto/corelib/text/qlocale/CMakeLists.txt index 3e6693d12b..a91dd44ea5 100644 --- a/tests/auto/corelib/text/qlocale/CMakeLists.txt +++ b/tests/auto/corelib/text/qlocale/CMakeLists.txt @@ -8,4 +8,6 @@ if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) endif() add_subdirectory(test) -add_subdirectory(syslocaleapp) +if(QT_FEATURE_jalalicalendar) + add_subdirectory(syslocaleapp) +endif() diff --git a/tests/auto/corelib/text/qlocale/test/CMakeLists.txt b/tests/auto/corelib/text/qlocale/test/CMakeLists.txt index 54ab71ea81..fc3e1488cd 100644 --- a/tests/auto/corelib/text/qlocale/test/CMakeLists.txt +++ b/tests/auto/corelib/text/qlocale/test/CMakeLists.txt @@ -11,6 +11,7 @@ qt_internal_add_test(tst_qlocale ../tst_qlocale.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 5767c27436..eb2d73b9b2 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QLocale> #include <QDateTime> @@ -40,6 +41,7 @@ public: private slots: void initTestCase(); + void compareCompiles(); #if defined(Q_OS_WIN) void windowsDefaultLocale(); #endif @@ -189,6 +191,11 @@ tst_QLocale::tst_QLocale() qRegisterMetaType<QLocale::FormatType>("QLocale::FormatType"); } +void tst_QLocale::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QLocale>(); +} + void tst_QLocale::initTestCase() { #ifdef Q_OS_ANDROID @@ -741,8 +748,8 @@ void tst_QLocale::legacyNames() void tst_QLocale::consistentC() { const QLocale c(QLocale::C); - QCOMPARE(c, QLocale::c()); - QCOMPARE(c, QLocale(QLocale::C, QLocale::AnyScript, QLocale::AnyTerritory)); + QT_TEST_EQUALITY_OPS(c, QLocale::c(), true); + QT_TEST_EQUALITY_OPS(c, QLocale(QLocale::C, QLocale::AnyScript, QLocale::AnyTerritory), true); QVERIFY(QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyTerritory).contains(c)); } @@ -751,6 +758,7 @@ void tst_QLocale::matchingLocales() { const QLocale c(QLocale::C); const QLocale ru_RU(QLocale::Russian, QLocale::Russia); + QT_TEST_EQUALITY_OPS(c, ru_RU, false); QList<QLocale> locales = QLocale::matchingLocales(QLocale::C, QLocale::AnyScript, QLocale::AnyTerritory); QCOMPARE(locales.size(), 1); @@ -1618,6 +1626,11 @@ void tst_QLocale::infNaN() { // TODO: QTBUG-95460 -- could support localized forms of inf/NaN const QLocale c(QLocale::C); + + QT_TEST_EQUALITY_OPS(QLocale(), QLocale(QLocale::C), false); + QT_TEST_EQUALITY_OPS(QLocale(), QLocale(), true); + QT_TEST_EQUALITY_OPS(QLocale(QLocale::C), c, true); + QCOMPARE(c.toString(qQNaN()), u"nan"); QCOMPARE(c.toString(qQNaN(), 'e'), u"nan"); QCOMPARE(c.toString(qQNaN(), 'f'), u"nan"); @@ -2966,6 +2979,7 @@ void tst_QLocale::numberOptions() QVERIFY(ok); locale.toDouble(QString("12.400"), &ok); QVERIFY(!ok); + QT_TEST_EQUALITY_OPS(locale, locale2, false); } void tst_QLocale::negativeNumbers() @@ -3030,6 +3044,7 @@ void tst_QLocale::negativeNumbers() i = farsi.toInt(u"\u200e+\u06f4\u06f0\u06f3"_s, &ok); QVERIFY(ok); QCOMPARE(i, 403); + QT_TEST_EQUALITY_OPS(egypt, farsi, false); } #include <private/qlocale_p.h> @@ -3288,6 +3303,11 @@ void tst_QLocale::dateFormat() const QLocale ir("ga_IE"); QCOMPARE(ir.dateFormat(QLocale::ShortFormat), QLatin1String("dd/MM/yyyy")); + QT_TEST_EQUALITY_OPS(c, no, false); + QT_TEST_EQUALITY_OPS(ca, ja, false); + QT_TEST_EQUALITY_OPS(ca, ir, false); + QT_TEST_EQUALITY_OPS(ir, ja, false); + const auto sys = QLocale::system(); // QTBUG-92018, ru_RU on MS const QDate date(2021, 3, 17); QCOMPARE(sys.toString(date, sys.dateFormat(QLocale::LongFormat)), sys.toString(date)); @@ -3345,6 +3365,11 @@ void tst_QLocale::timeFormat() const QLocale tw("zh_TW"); QCOMPARE(tw.timeFormat(QLocale::ShortFormat), "Aph:mm"_L1); QCOMPARE(tw.timeFormat(QLocale::LongFormat), "Aph:mm:ss [tttt]"_L1); + + QT_TEST_EQUALITY_OPS(c, no, false); + QT_TEST_EQUALITY_OPS(id, no, false); + QT_TEST_EQUALITY_OPS(c, cat, false); + QT_TEST_EQUALITY_OPS(bra, no, false); } void tst_QLocale::dateTimeFormat() @@ -3357,6 +3382,8 @@ void tst_QLocale::dateTimeFormat() QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy HH:mm")); QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy HH:mm")); QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), "dddd d. MMMM yyyy HH:mm:ss tttt"_L1); + + QT_TEST_EQUALITY_OPS(c, no, false); } void tst_QLocale::monthName() @@ -3616,6 +3643,7 @@ void tst_QLocale::currency() const QLocale system = QLocale::system(); QVERIFY(system.toCurrencyString(1, QLatin1String("FOO")).contains(QLatin1String("FOO"))); + QT_TEST_EQUALITY_OPS(system, es_CR, false); } void tst_QLocale::quoteString() @@ -3630,6 +3658,7 @@ void tst_QLocale::quoteString() QCOMPARE(de_CH.quoteString(someText), QString::fromUtf8("\xe2\x80\x9e" "text" "\xe2\x80\x9c")); QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation), QString::fromUtf8("\xe2\x80\x9a" "text" "\xe2\x80\x98")); + QT_TEST_EQUALITY_OPS(de_CH, c, false); } void tst_QLocale::uiLanguages_data() @@ -4011,6 +4040,7 @@ void tst_QLocale::bcp47Name() QTest::ignoreMessage(QtWarningMsg, "QLocale::bcp47Name(): " "Using non-ASCII separator '\u00ff' (ff) is unsupported"); QCOMPARE(locale.bcp47Name(QLocale::TagSeparator{'\xff'}), QString()); + QT_TEST_EQUALITY_OPS(locale, QLocale(QLatin1String(QTest::currentDataTag())), true); } #ifndef QT_NO_SYSTEMLOCALE @@ -4148,12 +4178,14 @@ void tst_QLocale::mySystemLocale() qDebug("\n\t%s", qPrintable(QLocale::system().uiLanguages().join(u"\n\t"))); }); QCOMPARE(QLocale::system().uiLanguages(), uiLanguages); + QCOMPARE(QLocale::system().uiLanguages(QLocale::TagSeparator::Underscore), + uiLanguages.replaceInStrings(u"-", u"_")); reporter.dismiss(); } // Verify MySystemLocale tidy-up restored prior state: - QCOMPARE(QLocale(), originalLocale); - QCOMPARE(QLocale::system(), originalSystemLocale); + QT_TEST_EQUALITY_OPS(QLocale(), originalLocale, true); + QT_TEST_EQUALITY_OPS(QLocale::system(), originalSystemLocale, true); } # endif // QT_BUILD_INTERNAL diff --git a/tests/auto/corelib/text/qregularexpression/CMakeLists.txt b/tests/auto/corelib/text/qregularexpression/CMakeLists.txt index b1d3ed0a8d..a7a7fe298f 100644 --- a/tests/auto/corelib/text/qregularexpression/CMakeLists.txt +++ b/tests/auto/corelib/text/qregularexpression/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qregularexpression SOURCES tst_qregularexpression.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp index 72c49d2a9c..d0ce414095 100644 --- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qstring.h> #include <qlist.h> #include <qstringlist.h> @@ -27,6 +28,7 @@ public: static void initMain(); private slots: + void compareCompiles(); void defaultConstructors(); void moveSemantics(); void moveSemanticsMatch(); @@ -460,6 +462,11 @@ void tst_QRegularExpression::initMain() } } +void tst_QRegularExpression::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QRegularExpression>(); +} + void tst_QRegularExpression::defaultConstructors() { QRegularExpression re; @@ -564,12 +571,12 @@ void tst_QRegularExpression::moveSemanticsMatchIterator() QRegularExpressionMatchIterator it1 = re.globalMatch("some test"); QVERIFY(it1.isValid()); QVERIFY(it1.hasNext()); - QCOMPARE(it1.regularExpression(), re); + QT_TEST_EQUALITY_OPS(it1.regularExpression(), re, true); QRegularExpressionMatchIterator it2(std::move(it1)); QVERIFY(it2.isValid()); QVERIFY(it2.hasNext()); - QCOMPARE(it2.regularExpression(), re); + QT_TEST_EQUALITY_OPS(it2.regularExpression(), re, true); consistencyCheck(it2); if (QTest::currentTestFailed()) return; @@ -578,13 +585,13 @@ void tst_QRegularExpression::moveSemanticsMatchIterator() QRegularExpressionMatchIterator it3 = re2.globalMatch("123test456"); QVERIFY(it3.isValid()); QVERIFY(it3.hasNext()); - QCOMPARE(it3.regularExpression(), re2); + QT_TEST_EQUALITY_OPS(it3.regularExpression(), re2, true); // check that (move)assigning to the moved-from object is ok it1 = std::move(it3); QVERIFY(it1.isValid()); QVERIFY(it1.hasNext()); - QCOMPARE(it1.regularExpression(), re2); + QT_TEST_EQUALITY_OPS(it1.regularExpression(), re2, true); consistencyCheck(it1); if (QTest::currentTestFailed()) return; @@ -1680,38 +1687,23 @@ void tst_QRegularExpression::serialize() static void verifyEquality(const QRegularExpression &re1, const QRegularExpression &re2) { - QVERIFY(re1 == re2); - QVERIFY(re2 == re1); + QT_TEST_EQUALITY_OPS(re1, re2, true); QCOMPARE(qHash(re1), qHash(re2)); - QVERIFY(!(re1 != re2)); - QVERIFY(!(re2 != re1)); QRegularExpression re3(re1); - QVERIFY(re1 == re3); - QVERIFY(re3 == re1); QCOMPARE(qHash(re1), qHash(re3)); - QVERIFY(!(re1 != re3)); - QVERIFY(!(re3 != re1)); + QT_TEST_EQUALITY_OPS(re1, re3, true); - QVERIFY(re2 == re3); - QVERIFY(re3 == re2); QCOMPARE(qHash(re2), qHash(re3)); - QVERIFY(!(re2 != re3)); - QVERIFY(!(re3 != re2)); + QT_TEST_EQUALITY_OPS(re2, re3, true); re3 = re2; - QVERIFY(re1 == re3); - QVERIFY(re3 == re1); QCOMPARE(qHash(re1), qHash(re3)); - QVERIFY(!(re1 != re3)); - QVERIFY(!(re3 != re1)); + QT_TEST_EQUALITY_OPS(re1, re3, true); - QVERIFY(re2 == re3); - QVERIFY(re3 == re2); QCOMPARE(qHash(re2), qHash(re3)); - QVERIFY(!(re2 != re3)); - QVERIFY(!(re3 != re2)); + QT_TEST_EQUALITY_OPS(re2, re3, true); } void tst_QRegularExpression::operatoreq_data() diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index d56a9ebd20..64370e97d7 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -6647,10 +6647,19 @@ void tst_QString::arg() // number overloads QCOMPARE( s4.arg(0), QLatin1String("[0]") ); QCOMPARE( s4.arg(-1), QLatin1String("[-1]") ); + QCOMPARE( s4.arg(0U), QLatin1String("[0]")); + QCOMPARE( s4.arg(short(-4200)), QLatin1String("[-4200]")); + QCOMPARE( s4.arg(ushort(42000)), QLatin1String("[42000]")); QCOMPARE( s4.arg(4294967295UL), QLatin1String("[4294967295]") ); // ULONG_MAX 32 QCOMPARE( s4.arg(Q_INT64_C(9223372036854775807)), // LLONG_MAX QLatin1String("[9223372036854775807]") ); + // char-ish overloads + QCOMPARE(s4.arg('\xE4'), QStringView(u"[ä]")); + QEXPECT_FAIL("", "QTBUG-125588", Continue); + QCOMPARE(s4.arg(u'ø'), QStringView(u"[ø]")); + //QCOMPARE(s4.arg(u8'a'), QLatin1String("[a]")); + QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: , foo"); QCOMPARE(QString().arg(foo), QString()); QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"\" , 0"); diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 35a734cf02..77ca8f221b 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -1112,6 +1112,10 @@ auto overload_s_v(QStringView s) { return s; } auto overload_sr_v(QString &&s) { return std::move(s); } auto overload_sr_v(QStringView s) { return s; } +Q_WEAK_OVERLOAD +auto overload_s_bav(const QString &s) { return s; } +auto overload_s_bav(QByteArrayView s) { return s; } + } // unnamed namespace template<typename T> @@ -1174,6 +1178,15 @@ void tst_QStringApiSymmetry::overload() overload_sr_v(CT()); } } + + if constexpr (std::is_convertible_v<T, QString> || std::is_convertible_v<T, QByteArrayView>) { + overload_s_bav(t); + overload_s_bav(ct); + if constexpr (!std::is_array_v<T>) { + overload_s_bav(T()); + overload_s_bav(CT()); + } + } QT_WARNING_POP } diff --git a/tests/auto/corelib/text/qstringview/CMakeLists.txt b/tests/auto/corelib/text/qstringview/CMakeLists.txt index ba5f540838..b541cdd0ed 100644 --- a/tests/auto/corelib/text/qstringview/CMakeLists.txt +++ b/tests/auto/corelib/text/qstringview/CMakeLists.txt @@ -18,5 +18,12 @@ qt_internal_add_test(tst_qstringview Qt::CorePrivate ) +if(QT_FEATURE_sanitize_undefined) + qt_internal_extend_target(tst_qstringview + DEFINES + QT_SANITIZE_UNDEFINED # GCC (in)famously doesn't provide a predefined macro for this + ) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp index df3ef94371..3f87ffc9fc 100644 --- a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp @@ -359,6 +359,30 @@ void tst_QStringView::constExpr() const static_assert(sv3.isEmpty()); static_assert(sv3.size() == 0); } +#if !defined(Q_CC_GNU_ONLY) || !defined(QT_SANITIZE_UNDEFINED) + // Below checks are disabled because of a compilation issue with GCC and + // -fsanitize=undefined. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962. + { + static constexpr char16_t hello[] = u"Hello"; + constexpr QStringView sv(hello); + static_assert(sv.size() == 5); + static_assert(!sv.empty()); + static_assert(!sv.isEmpty()); + static_assert(!sv.isNull()); + static_assert(*sv.utf16() == 'H'); + static_assert(sv[0] == QLatin1Char('H')); + static_assert(sv.at(0) == QLatin1Char('H')); + static_assert(sv.front() == QLatin1Char('H')); + static_assert(sv.first() == QLatin1Char('H')); + static_assert(sv[4] == QLatin1Char('o')); + static_assert(sv.at(4) == QLatin1Char('o')); + static_assert(sv.back() == QLatin1Char('o')); + static_assert(sv.last() == QLatin1Char('o')); + + constexpr auto sv2 = QStringView::fromArray(hello); + QCOMPARE_EQ(sv, sv2.chopped(1)); + } +#endif // -fsanitize=undefined } void tst_QStringView::basics() const @@ -430,7 +454,7 @@ void tst_QStringView::fromArray() const { static constexpr char16_t hello[] = u"Hello\0abc\0\0."; - constexpr QStringView sv = QStringView::fromArray(hello); + const QStringView sv = QStringView::fromArray(hello); QCOMPARE(sv.size(), 13); QVERIFY(!sv.empty()); QVERIFY(!sv.isEmpty()); diff --git a/tests/auto/corelib/thread/CMakeLists.txt b/tests/auto/corelib/thread/CMakeLists.txt index 68110b652b..d25d0205f5 100644 --- a/tests/auto/corelib/thread/CMakeLists.txt +++ b/tests/auto/corelib/thread/CMakeLists.txt @@ -17,11 +17,20 @@ if(QT_FEATURE_thread) add_subdirectory(qatomicint) add_subdirectory(qatomicinteger) add_subdirectory(qatomicpointer) - add_subdirectory(qresultstore) - if(QT_FEATURE_concurrent AND NOT INTEGRITY) - add_subdirectory(qfuture) + if(QT_FEATURE_future) + if(QT_FEATURE_concurrent AND NOT INTEGRITY) + add_subdirectory(qfuture) + endif() + add_subdirectory(qresultstore) + add_subdirectory(qfuturesynchronizer) + if(NOT INTEGRITY) + add_subdirectory(qpromise) + endif() + # QTBUG-87431 + if(TARGET Qt::Concurrent AND NOT INTEGRITY) + add_subdirectory(qfuturewatcher) + endif() endif() - add_subdirectory(qfuturesynchronizer) add_subdirectory(qmutex) add_subdirectory(qmutexlocker) add_subdirectory(qreadlocker) @@ -36,12 +45,5 @@ if(QT_FEATURE_thread) add_subdirectory(qthreadstorage) add_subdirectory(qwaitcondition) add_subdirectory(qwritelocker) - if(NOT INTEGRITY) - add_subdirectory(qpromise) - endif() endif() -# QTBUG-87431 -if(TARGET Qt::Concurrent AND NOT INTEGRITY) - add_subdirectory(qfuturewatcher) -endif() diff --git a/tests/auto/corelib/thread/qfuture/CMakeLists.txt b/tests/auto/corelib/thread/qfuture/CMakeLists.txt index aa989f3df1..ba5730d5cf 100644 --- a/tests/auto/corelib/thread/qfuture/CMakeLists.txt +++ b/tests/auto/corelib/thread/qfuture/CMakeLists.txt @@ -16,6 +16,7 @@ qt_internal_add_test(tst_qfuture tst_qfuture.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) qt_internal_extend_target(tst_qfuture CONDITION MSVC diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 3fc796514d..4cb29c514a 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -17,6 +17,7 @@ #include <private/qobject_p.h> #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qfuture.h> #include <qfuturewatcher.h> #include <qresultstore.h> @@ -161,6 +162,7 @@ class tst_QFuture: public QObject { Q_OBJECT private slots: + void compareCompiles(); void resultStore(); void future(); void futureToVoid(); @@ -273,6 +275,12 @@ private: QtPrivate::ResultStoreBase &store; }; +void tst_QFuture::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QFuture<int>::const_iterator>(); + QTestPrivate::testEqualityOperatorsCompile<QFuture<QString>::const_iterator>(); +} + void tst_QFuture::resultStore() { int int0 = 0; @@ -1359,16 +1367,16 @@ void tst_QFuture::iterators() QFuture<int>::const_iterator i1 = f.begin(), i2 = i1 + 1; QFuture<int>::const_iterator c1 = i1, c2 = c1 + 1; - QCOMPARE(i1, i1); - QCOMPARE(i1, c1); - QCOMPARE(c1, i1); - QCOMPARE(c1, c1); - QCOMPARE(i2, i2); - QCOMPARE(i2, c2); - QCOMPARE(c2, i2); - QCOMPARE(c2, c2); - QCOMPARE(1 + i1, i1 + 1); - QCOMPARE(1 + c1, c1 + 1); + QT_TEST_EQUALITY_OPS(i1, i1, true); + QT_TEST_EQUALITY_OPS(i1, c1, true); + QT_TEST_EQUALITY_OPS(c1, i1, true); + QT_TEST_EQUALITY_OPS(c1, c1, true); + QT_TEST_EQUALITY_OPS(i2, i2, true); + QT_TEST_EQUALITY_OPS(i2, c2, true); + QT_TEST_EQUALITY_OPS(c2, i2, true); + QT_TEST_EQUALITY_OPS(c2, c2, true); + QT_TEST_EQUALITY_OPS(1 + i1, i1 + 1, true); + QT_TEST_EQUALITY_OPS(1 + c1, c1 + 1, true); QVERIFY(i1 != i2); QVERIFY(i1 != c2); diff --git a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt index 0f9d8d9e52..5abfc14ac6 100644 --- a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt +++ b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt @@ -16,4 +16,5 @@ qt_internal_add_test(tst_qresultstore tst_qresultstore.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) diff --git a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp index 265b2cd1f6..722184a72a 100644 --- a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp +++ b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> - +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qresultstore.h> using namespace QtPrivate; @@ -23,6 +23,7 @@ class tst_QtConcurrentResultStore : public QObject public slots: void init(); private slots: + void compareCompiles(); void construction(); void iterators(); void addResult(); @@ -52,6 +53,11 @@ void tst_QtConcurrentResultStore::init() vec1 = QList<int> { 4, 5 }; } +void tst_QtConcurrentResultStore::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<ResultIteratorBase>(); +} + void tst_QtConcurrentResultStore::construction() { ResultStoreBase store; @@ -74,17 +80,20 @@ void tst_QtConcurrentResultStore::iterators() storebase.addResult(1, &int1); // ResultStoreBase does not take ownership, only ResultStore<> does. ResultIteratorBase it = storebase.begin(); QCOMPARE(it.resultIndex(), 0); - QCOMPARE(it, storebase.begin()); + QT_TEST_EQUALITY_OPS(it, storebase.begin(), true); QVERIFY(it != storebase.end()); ++it; QCOMPARE(it.resultIndex(), 1); QVERIFY(it != storebase.begin()); QVERIFY(it != storebase.end()); + QT_TEST_EQUALITY_OPS(it, storebase.begin(), false); + QT_TEST_EQUALITY_OPS(it, storebase.end(), false); ++it; QVERIFY(it != storebase.begin()); QCOMPARE(it, storebase.end()); + QT_TEST_EQUALITY_OPS(it, storebase.end(), true); } } @@ -147,8 +156,8 @@ void tst_QtConcurrentResultStore::addResults() store.addResults(-1, &vec1); ResultIteratorBase it = store.begin(); QCOMPARE(it.resultIndex(), 0); - QCOMPARE(it, store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), true); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 1); @@ -162,7 +171,7 @@ void tst_QtConcurrentResultStore::addResults() QCOMPARE(it.resultIndex(), 3); ++it; - QCOMPARE(it, store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), true); QList<int> empty; const auto countBefore = store.count(); @@ -184,22 +193,22 @@ void tst_QtConcurrentResultStore::resultIndex() ResultIteratorBase it = store.begin(); QCOMPARE(it.resultIndex(), 0); - QVERIFY(it == store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), true); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 1); - QVERIFY(it != store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), false); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 2); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 3); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; - QVERIFY(it == store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), true); QCOMPARE(store.resultAt(0).value<int>(), int0); QCOMPARE(store.resultAt(1).value<int>(), vec0[0]); diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index b163235d81..18c8d5fbd5 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -1299,8 +1299,16 @@ public: } void registerSocketNotifier(QSocketNotifier *) override {} void unregisterSocketNotifier(QSocketNotifier *) override {} - void registerTimer(Qt::TimerId, Duration, Qt::TimerType, QObject *) override {} - bool unregisterTimer(Qt::TimerId) override { return false; } + void registerTimer(Qt::TimerId id, Duration, Qt::TimerType, QObject *) override + { + if (registeredTimerId <= Qt::TimerId::Invalid) + registeredTimerId = id; + } + bool unregisterTimer(Qt::TimerId id) override + { + Qt::TimerId oldId = std::exchange(registeredTimerId, Qt::TimerId::Invalid); + return id == oldId; + } bool unregisterTimers(QObject *) override { return false; } QList<TimerInfoV2> timersForObject(QObject *) const override { return {}; } Duration remainingTime(Qt::TimerId) const override { return 0s; } @@ -1313,25 +1321,47 @@ public: #endif QBasicAtomicInt visited; // bool + Qt::TimerId registeredTimerId = Qt::TimerId::Invalid; }; -class ThreadObj : public QObject +struct ThreadLocalContent { - Q_OBJECT -public slots: - void visit() { - emit visited(); + static inline const QMetaObject *atStart; + static inline const QMetaObject *atEnd; + QSemaphore *sem; + QBasicTimer timer; + + ThreadLocalContent(QObject *obj, QSemaphore *sem) + : sem(sem) + { + ensureEventDispatcher(); + atStart = QAbstractEventDispatcher::instance()->metaObject(); + timer.start(10s, obj); + } + ~ThreadLocalContent() + { + ensureEventDispatcher(); + atEnd = QAbstractEventDispatcher::instance()->metaObject(); + timer.stop(); + sem->release(); + } + + void ensureEventDispatcher() + { + // QEventLoop's constructor has a call to QThreadData::ensureEventDispatcher() + QEventLoop dummy; } -signals: - void visited(); }; void tst_QThread::customEventDispatcher() { + ThreadLocalContent::atStart = ThreadLocalContent::atEnd = nullptr; + QThread thr; // there should be no ED yet QVERIFY(!thr.eventDispatcher()); DummyEventDispatcher *ed = new DummyEventDispatcher; + QPointer<DummyEventDispatcher> weak_ed(ed); thr.setEventDispatcher(ed); // the new ED should be set QCOMPARE(thr.eventDispatcher(), ed); @@ -1340,25 +1370,39 @@ void tst_QThread::customEventDispatcher() thr.start(); // start() should not overwrite the ED QCOMPARE(thr.eventDispatcher(), ed); + QVERIFY(!weak_ed.isNull()); - ThreadObj obj; + QObject obj; obj.moveToThread(&thr); // move was successful? QCOMPARE(obj.thread(), &thr); - QEventLoop loop; - connect(&obj, SIGNAL(visited()), &loop, SLOT(quit()), Qt::QueuedConnection); - QMetaObject::invokeMethod(&obj, "visit", Qt::QueuedConnection); - loop.exec(); + + QSemaphore threadLocalSemaphore; + QMetaObject::invokeMethod(&obj, [&]() { +#ifndef Q_OS_WIN + // On Windows, the thread_locals are unsequenced between DLLs, so this + // could run after QThreadPrivate::finish() + static thread_local +#endif + ThreadLocalContent d(&obj, &threadLocalSemaphore); + }, Qt::BlockingQueuedConnection); + // test that the ED has really been used QVERIFY(ed->visited.loadRelaxed()); + // and it's ours + QCOMPARE(ThreadLocalContent::atStart->className(), "DummyEventDispatcher"); - QPointer<DummyEventDispatcher> weak_ed(ed); QVERIFY(!weak_ed.isNull()); thr.quit(); + // wait for thread to be stopped QVERIFY(thr.wait(30000)); + QVERIFY(threadLocalSemaphore.tryAcquire(1, 30s)); + // test that ED has been deleted QVERIFY(weak_ed.isNull()); + // test that ED was ours + QCOMPARE(ThreadLocalContent::atEnd->className(), "DummyEventDispatcher"); } class Job : public QObject diff --git a/tests/auto/corelib/time/CMakeLists.txt b/tests/auto/corelib/time/CMakeLists.txt index f2dfbfa527..1fb95e9245 100644 --- a/tests/auto/corelib/time/CMakeLists.txt +++ b/tests/auto/corelib/time/CMakeLists.txt @@ -4,6 +4,10 @@ add_subdirectory(qcalendar) add_subdirectory(qdate) add_subdirectory(qdatetime) -add_subdirectory(qdatetimeparser) +if(QT_FEATURE_datetimeparser) + add_subdirectory(qdatetimeparser) +endif() add_subdirectory(qtime) -add_subdirectory(qtimezone) +if(QT_FEATURE_timezone) + add_subdirectory(qtimezone) +endif() diff --git a/tests/auto/corelib/time/qdate/tst_qdate.cpp b/tests/auto/corelib/time/qdate/tst_qdate.cpp index cacdad307f..5b715e8c55 100644 --- a/tests/auto/corelib/time/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/time/qdate/tst_qdate.cpp @@ -1179,7 +1179,7 @@ void tst_QDate::operator_insert_extract() QCOMPARE(deserialised, date); } -#if QT_CONFIG(datetimeparser) +#if QT_CONFIG(datestring) void tst_QDate::fromStringDateFormat_data() { QTest::addColumn<QString>("dateStr"); @@ -1303,6 +1303,7 @@ void tst_QDate::fromStringDateFormat() QCOMPARE(QDate::fromString(dateStr, dateFormat), expectedDate); } +# if QT_CONFIG(datetimeparser) void tst_QDate::fromStringFormat_data() { QTest::addColumn<QString>("string"); @@ -1490,7 +1491,6 @@ void tst_QDate::fromStringFormat() } #endif // datetimeparser -#if QT_CONFIG(datestring) void tst_QDate::toStringFormat_data() { QTest::addColumn<QDate>("t"); diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp index a350ffeb04..7f6bc96aa6 100644 --- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp @@ -584,7 +584,7 @@ void tst_QTimeZone::utcOffsetId_data() #define ROW(name, valid, offset) \ QTest::newRow(name) << QByteArray(name) << valid << offset - // See qtbase/util/locale_database/cldr2qtimezone.py for source + // See qtbase/util/locale_database/zonedata.py for source // CLDR v35.1 IDs: ROW("UTC", true, 0); ROW("UTC-14:00", true, -50400); @@ -1280,7 +1280,7 @@ void tst_QTimeZone::utcTest() void tst_QTimeZone::icuTest() { -#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu) +#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu) && !defined(Q_OS_UNIX) // Known datetimes qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch(); qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch(); @@ -1323,7 +1323,7 @@ void tst_QTimeZone::icuTest() if (QTest::currentTestFailed()) return; testEpochTranPrivate(QIcuTimeZonePrivate("America/Toronto")); -#endif // icu +#endif // ICU not on Unix } void tst_QTimeZone::tzTest() @@ -1527,7 +1527,7 @@ void tst_QTimeZone::tzTest() QDateTime dt(QDate(2016, 3, 28), QTime(0, 0), UTC); QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07")); } -#endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN +#endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN && !Q_OS_ANDROID } void tst_QTimeZone::macTest() diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp index c08afd67c4..fe1a9b828a 100644 --- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp +++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp @@ -20,6 +20,8 @@ private slots: void repeated_result(); void intermediary_result_data(); void intermediary_result(); + void static_hash_data() { intermediary_result_data(); } + void static_hash(); void sha1(); void sha3_data(); void sha3(); @@ -29,9 +31,9 @@ private slots: void blake2(); void files_data(); void files(); - void hashLength_data(); + void hashLength_data() { all_methods(true); } void hashLength(); - void addDataAcceptsNullByteArrayView_data() { hashLength_data(); } + void addDataAcceptsNullByteArrayView_data() { all_methods(false); } void addDataAcceptsNullByteArrayView(); void move(); void swap(); @@ -40,6 +42,7 @@ private slots: void moreThan4GiBOfData(); void keccakBufferOverflow(); private: + void all_methods(bool includingNumAlgorithms) const; void ensureLargeData(); std::vector<char> large; }; @@ -197,6 +200,17 @@ void tst_QCryptographicHash::intermediary_result() hash.reset(); } +void tst_QCryptographicHash::static_hash() +{ + QFETCH(const int, algo); + QFETCH(const QByteArray, first); + QFETCH(const QByteArray, hash_first); + + const auto _algo = QCryptographicHash::Algorithm(algo); + + QCOMPARE(QCryptographicHash::hash(first, _algo), hash_first); +} + void tst_QCryptographicHash::sha1() { @@ -474,12 +488,14 @@ void tst_QCryptographicHash::files() } } -void tst_QCryptographicHash::hashLength_data() +void tst_QCryptographicHash::all_methods(bool inclNumAlgos) const { QTest::addColumn<QCryptographicHash::Algorithm>("algorithm"); auto metaEnum = QMetaEnum::fromType<QCryptographicHash::Algorithm>(); for (int i = 0, value = metaEnum.value(i); value != -1; value = metaEnum.value(++i)) { auto algorithm = QCryptographicHash::Algorithm(value); + if (!inclNumAlgos && algorithm == QCryptographicHash::Algorithm::NumAlgorithms) + continue; QTest::addRow("%s", metaEnum.key(i)) << algorithm; } } diff --git a/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt b/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt index 3f76f8a38f..2569e0c7a9 100644 --- a/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt +++ b/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qeasingcurve SOURCES tst_qeasingcurve.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp index fc8c1a3e5c..0a933a1e2b 100644 --- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <private/qcomparisontesthelper_p.h> #include <qeasingcurve.h> @@ -16,6 +17,7 @@ private slots: void valueForProgress_data(); void valueForProgress(); void setCustomType(); + void comparisonCompiles(); void operators(); void properties(); void metaTypes(); @@ -420,6 +422,11 @@ void tst_QEasingCurve::setCustomType() QCOMPARE(curve.valueForProgress(0.99), 0.99); } +void tst_QEasingCurve::comparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QEasingCurve>(); +} + void tst_QEasingCurve::operators() { { // member-swap() @@ -447,28 +454,28 @@ void tst_QEasingCurve::operators() curve2 = curve; curve2.setOvershoot(qreal(1.70158)); QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 == curve); + QT_TEST_EQUALITY_OPS(curve2, curve, true); curve.setOvershoot(3.0); - QVERIFY(curve2 != curve); + QT_TEST_EQUALITY_OPS(curve2, curve, false); curve2.setOvershoot(3.0); - QVERIFY(curve2 == curve); + QT_TEST_EQUALITY_OPS(curve2, curve, true); curve2.setType(QEasingCurve::Linear); QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 != curve); + QT_TEST_EQUALITY_OPS(curve2, curve, false); curve2.setType(QEasingCurve::InBack); QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 == curve); + QT_TEST_EQUALITY_OPS(curve2, curve, true); QEasingCurve curve3; QEasingCurve curve4; curve4.setAmplitude(curve4.amplitude()); QEasingCurve curve5; curve5.setAmplitude(0.12345); - QVERIFY(curve3 == curve4); // default value and not assigned - QVERIFY(curve3 != curve5); // unassinged and other value - QVERIFY(curve4 != curve5); + QT_TEST_EQUALITY_OPS(curve3, curve4, true); // default value and not assigned + QT_TEST_EQUALITY_OPS(curve3, curve5, false); // unassinged and other value + QT_TEST_EQUALITY_OPS(curve4, curve5, false); } class tst_QEasingProperties : public QObject @@ -890,7 +897,7 @@ void tst_QEasingCurve::streamInOut() dsw << orig; dsr >> copy; - QCOMPARE(copy == orig, equality); + QT_TEST_EQUALITY_OPS(copy, orig, equality); } QTEST_MAIN(tst_QEasingCurve) diff --git a/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp b/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp index 99fc7c5772..e004a560a2 100644 --- a/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp +++ b/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp @@ -21,7 +21,7 @@ private Q_SLOTS: void deterministicSeed(); void reseeding(); void quality(); -#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && QT_DEPRECATED_SINCE(6,6) void compatibilityApi(); void deterministicSeed_compat(); #endif @@ -157,7 +157,7 @@ void tst_QHashSeed::quality() "seedsToMinus1 = " + QByteArray::number(seedsToMinus1)); } -#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && QT_DEPRECATED_SINCE(6,6) QT_WARNING_DISABLE_DEPRECATED void tst_QHashSeed::compatibilityApi() { diff --git a/tests/auto/corelib/tools/qline/CMakeLists.txt b/tests/auto/corelib/tools/qline/CMakeLists.txt index 17a3a1bcef..7d9fdf51a9 100644 --- a/tests/auto/corelib/tools/qline/CMakeLists.txt +++ b/tests/auto/corelib/tools/qline/CMakeLists.txt @@ -14,6 +14,8 @@ endif() qt_internal_add_test(tst_qline SOURCES tst_qline.cpp + LIBRARIES + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/tools/qline/tst_qline.cpp b/tests/auto/corelib/tools/qline/tst_qline.cpp index 51f1f8ac79..10069e821b 100644 --- a/tests/auto/corelib/tools/qline/tst_qline.cpp +++ b/tests/auto/corelib/tools/qline/tst_qline.cpp @@ -4,6 +4,7 @@ #include <QTest> #include <qline.h> #include <qmath.h> +#include <private/qcomparisontesthelper_p.h> #include <array> @@ -11,6 +12,16 @@ class tst_QLine : public QObject { Q_OBJECT private slots: + void testComparisonCompiles(); + void testComparison_data(); + void testComparison(); + + void testFuzzyCompare_data(); + void testFuzzyCompare(); + + void testIsNull_data(); + void testIsNull(); + void testIntersection(); void testIntersection_data(); @@ -41,6 +52,120 @@ private slots: }; const qreal epsilon = sizeof(qreal) == sizeof(double) ? 1e-8 : 1e-4; +constexpr static qreal qreal_min = std::numeric_limits<qreal>::min(); + +void tst_QLine::testComparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QLine>(); + QTestPrivate::testEqualityOperatorsCompile<QLineF>(); + QTestPrivate::testEqualityOperatorsCompile<QLineF, QLine>(); +} + +void tst_QLine::testComparison_data() +{ + QTest::addColumn<double>("xa1"); + QTest::addColumn<double>("ya1"); + QTest::addColumn<double>("xa2"); + QTest::addColumn<double>("ya2"); + QTest::addColumn<double>("xb1"); + QTest::addColumn<double>("yb1"); + QTest::addColumn<double>("xb2"); + QTest::addColumn<double>("yb2"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + QTest::addColumn<bool>("mixedResult"); + + auto row = [&](double xa1, double ya1, double xa2, double ya2, + double xb1, double yb1, double xb2, double yb2, + bool result, bool floatResult, bool mixedResult) + { + QString str; + QDebug dbg(&str); + dbg.nospace() << "[(" << xa1 << ", " << ya1 << "); (" << xa2 << ", " << ya2 << ")] vs [(" + << xb1 << ", " << yb1 << "); (" << xb2 << ", " << yb2 << ")]"; + QTest::addRow("%s", str.toLatin1().constData()) + << xa1 << ya1 << xa2 << ya2 << xb1 << yb1 << xb2 << yb2 + << result << floatResult << mixedResult; + }; + + row(-1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, true, true, true); + row(-1.1, -0.9, 1.1, 0.9, -1.0, -1.0, 1.0, 1.0, true, false, false); + row(-1.0, -1.0, 1.0, 1.0, -0.9, -1.1, 0.9, 1.1, true, false, true); + row(-qreal_min, -1.0, 1.0, qreal_min, 0.0, -1.1, 0.9, 0.0, true, false, true); +} + +void tst_QLine::testComparison() +{ + QFETCH(double, xa1); + QFETCH(double, ya1); + QFETCH(double, xa2); + QFETCH(double, ya2); + QFETCH(double, xb1); + QFETCH(double, yb1); + QFETCH(double, xb2); + QFETCH(double, yb2); + QFETCH(bool, result); + QFETCH(bool, floatResult); + QFETCH(bool, mixedResult); + + const QLineF l1f(xa1, ya1, xa2, ya2); + const QLine l1 = l1f.toLine(); + + const QLineF l2f(xb1, yb1, xb2, yb2); + const QLine l2 = l2f.toLine(); + + QT_TEST_EQUALITY_OPS(l1, l2, result); + QT_TEST_EQUALITY_OPS(l1f, l2f, floatResult); + QT_TEST_EQUALITY_OPS(l1f, l2, mixedResult); +} + +void tst_QLine::testFuzzyCompare_data() +{ + testComparison_data(); +} + +void tst_QLine::testFuzzyCompare() +{ + QFETCH(double, xa1); + QFETCH(double, ya1); + QFETCH(double, xa2); + QFETCH(double, ya2); + QFETCH(double, xb1); + QFETCH(double, yb1); + QFETCH(double, xb2); + QFETCH(double, yb2); + QFETCH(bool, floatResult); + + const QLineF l1f(xa1, ya1, xa2, ya2); + const QLineF l2f(xb1, yb1, xb2, yb2); + + QCOMPARE_EQ(qFuzzyCompare(l1f, l2f), floatResult); +} + +void tst_QLine::testIsNull_data() +{ + QTest::addColumn<QLineF>("lineF"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + + QTest::newRow("non-null") << QLineF(1.0, 1.0, 2.0, 2.0) << false << false; + QTest::newRow("null") << QLineF(1.0, 1.0, 1.0, 1.0) << true << true; + QTest::newRow("null_int_non-null_float") << QLineF(1.0, 1.0, 1.1, 1.1) << true << false; + QTest::newRow("with_qreal_min") << QLineF(-qreal_min, qreal_min, 0.0, 0.0) << true << true; +} + +void tst_QLine::testIsNull() +{ + QFETCH(QLineF, lineF); + QFETCH(bool, result); + QFETCH(bool, floatResult); + + const QLine line = lineF.toLine(); + + QCOMPARE_EQ(line.isNull(), result); + QCOMPARE_EQ(lineF.isNull(), floatResult); + QCOMPARE_EQ(qFuzzyIsNull(lineF), floatResult); +} void tst_QLine::testSet() { diff --git a/tests/auto/corelib/tools/qmargins/CMakeLists.txt b/tests/auto/corelib/tools/qmargins/CMakeLists.txt index 2e0ea797ff..b0adf63f40 100644 --- a/tests/auto/corelib/tools/qmargins/CMakeLists.txt +++ b/tests/auto/corelib/tools/qmargins/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qmargins SOURCES tst_qmargins.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp index 2611f62f01..dc0b0e4085 100644 --- a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp +++ b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp @@ -32,15 +32,28 @@ CHECK(const &&); #include <QTest> #include <qmargins.h> +#include <private/qcomparisontesthelper_p.h> #include <array> Q_DECLARE_METATYPE(QMargins) +constexpr static qreal qreal_min = std::numeric_limits<qreal>::min(); + class tst_QMargins : public QObject { Q_OBJECT private slots: + void comparisonCompiles(); + void comparison_data(); + void comparison(); + + void fuzzyComparison_data(); + void fuzzyComparison(); + + void isNull_data(); + void isNull(); + void getSetCheck(); #ifndef QT_NO_DATASTREAM void dataStreamCheck(); @@ -65,6 +78,92 @@ private slots: void toMarginsF(); }; +void tst_QMargins::comparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QMargins>(); + QTestPrivate::testEqualityOperatorsCompile<QMarginsF>(); + QTestPrivate::testEqualityOperatorsCompile<QMarginsF, QMargins>(); +} + +void tst_QMargins::comparison_data() +{ + QTest::addColumn<QMarginsF>("lhs"); + QTest::addColumn<QMarginsF>("rhs"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + QTest::addColumn<bool>("mixedResult"); + + auto row = [](const QMarginsF &lhs, const QMarginsF &rhs, bool res, bool fRes, bool mRes) { + QString str; + QDebug dbg(&str); + dbg.nospace() << "(" << lhs.left() << ", " << lhs.top() << ", " << lhs.right() << ", " + << lhs.bottom() << ") vs (" << rhs.left() << ", " << rhs.top() << ", " + << rhs.right() << ", " << rhs.bottom() << ")"; + QTest::addRow("%s", str.toLatin1().constData()) << lhs << rhs << res << fRes << mRes; + }; + + row(QMarginsF(0.0, 0.0, 0.0, 0.0), QMarginsF(0.0, 0.0, 0.0, 0.0), true, true, true); + row(QMarginsF(qreal_min, -qreal_min, -qreal_min, qreal_min), QMarginsF(0.0, 0.0, 0.0, 0.0), true, true, true); + row(QMarginsF(1.0, 2.0, 3.0, 4.0), QMarginsF(1.1, 2.1, 2.9, 3.9), true, false, true); + row(QMarginsF(1.5, 2.5, 3.0, 4.0), QMarginsF(1.1, 2.1, 2.9, 3.9), false, false, false); +} + +void tst_QMargins::comparison() +{ + QFETCH(const QMarginsF, lhs); + QFETCH(const QMarginsF, rhs); + QFETCH(const bool, result); + QFETCH(const bool, floatResult); + QFETCH(const bool, mixedResult); + + QT_TEST_EQUALITY_OPS(lhs, rhs, floatResult); + + const QMargins lhsInt = lhs.toMargins(); + const QMargins rhsInt = rhs.toMargins(); + QT_TEST_EQUALITY_OPS(lhsInt, rhsInt, result); + + QT_TEST_EQUALITY_OPS(lhs, rhsInt, mixedResult); +} + +void tst_QMargins::fuzzyComparison_data() +{ + comparison_data(); +} + +void tst_QMargins::fuzzyComparison() +{ + QFETCH(const QMarginsF, lhs); + QFETCH(const QMarginsF, rhs); + QFETCH(const bool, floatResult); + + QCOMPARE_EQ(qFuzzyCompare(lhs, rhs), floatResult); +} + +void tst_QMargins::isNull_data() +{ + QTest::addColumn<QMarginsF>("margins"); + QTest::addColumn<bool>("result"); + + QTest::newRow("null") << QMarginsF(0.0, 0.0, 0.0, 0.0) << true; + QTest::newRow("non_null_left") << QMarginsF(1.0, 0.0, 0.0, 0.0) << false; + QTest::newRow("non_null_top") << QMarginsF(0.0, 0.5, 0.0, 0.0) << false; + QTest::newRow("non_null_right") << QMarginsF(0.0, 0.0, -2.0, 0.0) << false; + QTest::newRow("non_null_bottom") << QMarginsF(0.0, 0.0, 0.0, -0.6) << false; + QTest::newRow("almost_null") << QMarginsF(qreal_min, -qreal_min, qreal_min, -qreal_min) << true; +} + +void tst_QMargins::isNull() +{ + QFETCH(const QMarginsF, margins); + QFETCH(const bool, result); + + QCOMPARE_EQ(margins.isNull(), result); + QCOMPARE_EQ(qFuzzyIsNull(margins), result); + + const QMargins marginsInt = margins.toMargins(); + QCOMPARE_EQ(marginsInt.isNull(), result); +} + // Testing get/set functions void tst_QMargins::getSetCheck() { diff --git a/tests/auto/corelib/tools/qpoint/CMakeLists.txt b/tests/auto/corelib/tools/qpoint/CMakeLists.txt index f1402d8815..82ece1fc15 100644 --- a/tests/auto/corelib/tools/qpoint/CMakeLists.txt +++ b/tests/auto/corelib/tools/qpoint/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qpoint SOURCES tst_qpoint.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp b/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp index 7fea787131..4763c1bf07 100644 --- a/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp +++ b/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp @@ -5,6 +5,7 @@ #ifdef QVARIANT_H # error "This test requires qpoint.h to not include qvariant.h" #endif +#include <private/qcomparisontesthelper_p.h> // don't assume <type_traits> template <typename T, typename U> @@ -71,6 +72,7 @@ private slots: void operator_unary_minus_data(); void operator_unary_minus(); + void operatorsCompile(); void operator_eq_data(); void operator_eq(); @@ -155,6 +157,8 @@ void tst_QPoint::toPointF() QFETCH(const QPointF, result); QCOMPARE(input.toPointF(), result); + // test also mixed-type comparison + QT_TEST_EQUALITY_OPS(input, result, true); } void tst_QPoint::transposed() @@ -350,6 +354,12 @@ void tst_QPoint::operator_unary_minus() QCOMPARE(-point, expected); } +void tst_QPoint::operatorsCompile() +{ + // Mixed-type comparison is tested in tst_QPointF. + QTestPrivate::testEqualityOperatorsCompile<QPoint>(); +} + void tst_QPoint::operator_eq_data() { QTest::addColumn<QPoint>("point1"); @@ -371,12 +381,9 @@ void tst_QPoint::operator_eq() QFETCH(QPoint, point2); QFETCH(bool, expectEqual); - bool equal = point1 == point2; - QCOMPARE(equal, expectEqual); - bool notEqual = point1 != point2; - QCOMPARE(notEqual, !expectEqual); + QT_TEST_EQUALITY_OPS(point1, point2, expectEqual); - if (equal) + if (expectEqual) QCOMPARE(qHash(point1), qHash(point2)); } diff --git a/tests/auto/corelib/tools/qpointf/CMakeLists.txt b/tests/auto/corelib/tools/qpointf/CMakeLists.txt index 16e5a9036a..28cbe185b2 100644 --- a/tests/auto/corelib/tools/qpointf/CMakeLists.txt +++ b/tests/auto/corelib/tools/qpointf/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qpointf SOURCES tst_qpointf.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp b/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp index 392c22c70a..ebbac4ec7c 100644 --- a/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp +++ b/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp @@ -5,6 +5,7 @@ #ifdef QVARIANT_H # error "This test requires qpoint.h to not include qvariant.h" #endif +#include <private/qcomparisontesthelper_p.h> // don't assume <type_traits> template <typename T, typename U> @@ -71,9 +72,13 @@ private slots: void operator_unary_minus_data(); void operator_unary_minus(); + void operatorsCompile(); void operator_eq_data(); void operator_eq(); + void fuzzyCompare_data(); + void fuzzyCompare(); + void toPoint_data(); void toPoint(); @@ -101,15 +106,19 @@ void tst_QPointF::isNull() { QPointF point(0, 0); QVERIFY(point.isNull()); + QVERIFY(qFuzzyIsNull(point)); ++point.rx(); QVERIFY(!point.isNull()); + QVERIFY(!qFuzzyIsNull(point)); point.rx() -= 2; QVERIFY(!point.isNull()); + QVERIFY(!qFuzzyIsNull(point)); QPointF nullNegativeZero(qreal(-0.0), qreal(-0.0)); QCOMPARE(nullNegativeZero.x(), (qreal)-0.0f); QCOMPARE(nullNegativeZero.y(), (qreal)-0.0f); QVERIFY(nullNegativeZero.isNull()); + QVERIFY(qFuzzyIsNull(nullNegativeZero)); } void tst_QPointF::manhattanLength_data() @@ -345,21 +354,29 @@ void tst_QPointF::operator_unary_minus() QCOMPARE(-point, expected); } +void tst_QPointF::operatorsCompile() +{ + QTestPrivate::testEqualityOperatorsCompile<QPointF>(); + QTestPrivate::testEqualityOperatorsCompile<QPointF, QPoint>(); +} + void tst_QPointF::operator_eq_data() { QTest::addColumn<QPointF>("point1"); QTest::addColumn<QPointF>("point2"); QTest::addColumn<bool>("expectEqual"); - - QTest::newRow("(0, 0) == (0, 0)") << QPointF(0, 0) << QPointF(0, 0) << true; - QTest::newRow("(-1, 0) == (-1, 0)") << QPointF(-1, 0) << QPointF(-1, 0) << true; - QTest::newRow("(-1, 0) != (0, 0)") << QPointF(-1, 0) << QPointF(0, 0) << false; - QTest::newRow("(-1, 0) != (0, -1)") << QPointF(-1, 0) << QPointF(0, -1) << false; - QTest::newRow("(-1.125, 0.25) == (-1.125, 0.25)") << QPointF(-1.125, 0.25) << QPointF(-1.125, 0.25) << true; + QTest::addColumn<bool>("expectIntEqual"); + + QTest::newRow("(0, 0) == (0, 0)") << QPointF(0, 0) << QPointF(0, 0) << true << true; + QTest::newRow("(-1, 0) == (-1, 0)") << QPointF(-1, 0) << QPointF(-1, 0) << true << true; + QTest::newRow("(-1, 0) != (0, 0)") << QPointF(-1, 0) << QPointF(0, 0) << false << false; + QTest::newRow("(-1, 0) != (0, -1)") << QPointF(-1, 0) << QPointF(0, -1) << false << false; + QTest::newRow("(-1.125, 0.25) == (-1.125, 0.25)") + << QPointF(-1.125, 0.25) << QPointF(-1.125, 0.25) << true << false; QTest::newRow("(QREAL_MIN, QREAL_MIN) == (QREAL_MIN, QREAL_MIN)") - << QPointF(QREAL_MIN, QREAL_MIN) << QPointF(QREAL_MIN, QREAL_MIN) << true; + << QPointF(QREAL_MIN, QREAL_MIN) << QPointF(QREAL_MIN, QREAL_MIN) << true << true; QTest::newRow("(QREAL_MAX, QREAL_MAX) == (QREAL_MAX, QREAL_MAX)") - << QPointF(QREAL_MAX, QREAL_MAX) << QPointF(QREAL_MAX, QREAL_MAX) << true; + << QPointF(QREAL_MAX, QREAL_MAX) << QPointF(QREAL_MAX, QREAL_MAX) << true << false; } void tst_QPointF::operator_eq() @@ -367,11 +384,26 @@ void tst_QPointF::operator_eq() QFETCH(QPointF, point1); QFETCH(QPointF, point2); QFETCH(bool, expectEqual); + QFETCH(bool, expectIntEqual); + + QT_TEST_EQUALITY_OPS(point1, point2, expectEqual); + + const QPoint intPoint2 = point2.toPoint(); + QT_TEST_EQUALITY_OPS(point1, intPoint2, expectIntEqual); +} + +void tst_QPointF::fuzzyCompare_data() +{ + operator_eq_data(); +} + +void tst_QPointF::fuzzyCompare() +{ + QFETCH(QPointF, point1); + QFETCH(QPointF, point2); + QFETCH(bool, expectEqual); - bool equal = point1 == point2; - QCOMPARE(equal, expectEqual); - bool notEqual = point1 != point2; - QCOMPARE(notEqual, !expectEqual); + QCOMPARE_EQ(qFuzzyCompare(point1, point2), expectEqual); } void tst_QPointF::toPoint_data() diff --git a/tests/auto/corelib/tools/qrect/CMakeLists.txt b/tests/auto/corelib/tools/qrect/CMakeLists.txt index a02e1c33a5..c98c836379 100644 --- a/tests/auto/corelib/tools/qrect/CMakeLists.txt +++ b/tests/auto/corelib/tools/qrect/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qrect SOURCES tst_qrect.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qrect/tst_qrect.cpp b/tests/auto/corelib/tools/qrect/tst_qrect.cpp index 0f3dd1a0ef..c7c8b3a560 100644 --- a/tests/auto/corelib/tools/qrect/tst_qrect.cpp +++ b/tests/auto/corelib/tools/qrect/tst_qrect.cpp @@ -7,6 +7,8 @@ #include <limits.h> #include <qdebug.h> +#include <private/qcomparisontesthelper_p.h> + #include <array> class tst_QRect : public QObject @@ -33,8 +35,14 @@ public: static QPoint getQPointCase( QPointCases p ); private slots: + void comparisonCompiles(); + void comparison_data(); + void comparison(); + void fuzzyComparison_data(); + void fuzzyComparison(); void isNull_data(); void isNull(); + void fuzzyIsNull(); void newIsEmpty_data(); void newIsEmpty(); void newIsValid_data(); @@ -160,6 +168,8 @@ private slots: #define LARGE 1000000000 static bool isLarge(int x) { return x > LARGE || x < -LARGE; } +static constexpr qreal qreal_min = std::numeric_limits<qreal>::min(); + QRect tst_QRect::getQRectCase( QRectCases c ) { // Should return the best variety of possible QRects, if a @@ -242,6 +252,80 @@ QPoint tst_QRect::getQPointCase( QPointCases p ) } } +void tst_QRect::comparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QRect>(); + QTestPrivate::testEqualityOperatorsCompile<QRectF>(); + QTestPrivate::testEqualityOperatorsCompile<QRectF, QRect>(); +} + +void tst_QRect::comparison_data() +{ + QTest::addColumn<QRectF>("lhsF"); + QTest::addColumn<QRectF>("rhsF"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + QTest::addColumn<bool>("mixedResult"); + + QTest::newRow("Invalid_vs_Invalid") << getQRectCase(InvalidQRect).toRectF() + << getQRectCase(InvalidQRect).toRectF() + << true << true << true; + + QTest::newRow("Null_vs_Null") << getQRectCase(NullQRect).toRectF() + << getQRectCase(NullQRect).toRectF() + << true << true << true; + + QTest::newRow("Empty_vs_Empty") << getQRectCase(EmptyQRect).toRectF() + << getQRectCase(EmptyQRect).toRectF() + << true << true << true; + + QTest::newRow("NegativeSize_vs_NegativeSize") << getQRectCase(NegativeSizeQRect).toRectF() + << getQRectCase(NegativeSizeQRect).toRectF() + << true << true << true; + + QTest::newRow("Invalid_vs_Null") << getQRectCase(InvalidQRect).toRectF() + << getQRectCase(NullQRect).toRectF() + << false << false << false; + + QTest::newRow("NearlySimilar") << QRectF(QPointF(1.1, 9.9), QPointF(9.9, 1.1)) + << QRectF(QPointF(1., 10.), QPointF(10., 1.)) + << true << false << true; + + QTest::newRow("WithQREAL_MIN") << QRectF(QPointF(0., -10.), QPointF(-1., 0.)) + << QRectF(QPointF(-qreal_min, -10.), QPointF(-1., qreal_min)) + << true << true << true; +} + +void tst_QRect::comparison() +{ + QFETCH(const QRectF, lhsF); + QFETCH(const QRectF, rhsF); + QFETCH(const bool, result); + QFETCH(const bool, floatResult); + QFETCH(const bool, mixedResult); + + const QRect lhs = lhsF.toRect(); + const QRect rhs = rhsF.toRect(); + + QT_TEST_EQUALITY_OPS(lhs, rhs, result); + QT_TEST_EQUALITY_OPS(lhsF, rhsF, floatResult); + QT_TEST_EQUALITY_OPS(lhs, rhsF, mixedResult); +} + +void tst_QRect::fuzzyComparison_data() +{ + comparison_data(); +} + +void tst_QRect::fuzzyComparison() +{ + QFETCH(const QRectF, lhsF); + QFETCH(const QRectF, rhsF); + QFETCH(const bool, floatResult); + + QCOMPARE_EQ(qFuzzyCompare(lhsF, rhsF), floatResult); +} + void tst_QRect::isNull_data() { QTest::addColumn<QRect>("r"); @@ -271,6 +355,14 @@ void tst_QRect::isNull() QVERIFY( rf.isNull() == isNull ); } +void tst_QRect::fuzzyIsNull() +{ + QRectF rf(QPointF(-qreal_min, qreal_min), QPointF(qreal_min, -qreal_min)); + + QVERIFY(!rf.isNull()); // QRectF::isNull() does strict comparison + QVERIFY(qFuzzyIsNull(rf)); +} + void tst_QRect::newIsEmpty_data() { QTest::addColumn<QRect>("r"); diff --git a/tests/auto/corelib/tools/qsize/CMakeLists.txt b/tests/auto/corelib/tools/qsize/CMakeLists.txt index 91de696ddd..4a4c96b52c 100644 --- a/tests/auto/corelib/tools/qsize/CMakeLists.txt +++ b/tests/auto/corelib/tools/qsize/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qsize SOURCES tst_qsize.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qsize/tst_qsize.cpp b/tests/auto/corelib/tools/qsize/tst_qsize.cpp index c9699c5e76..d379275dd8 100644 --- a/tests/auto/corelib/tools/qsize/tst_qsize.cpp +++ b/tests/auto/corelib/tools/qsize/tst_qsize.cpp @@ -24,6 +24,7 @@ CHECK(const &&); #undef CHECK #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qsize.h> #include <array> @@ -34,6 +35,10 @@ class tst_QSize : public QObject { Q_OBJECT private slots: + void compareCompiles(); + void compare_data(); + void compare(); + void getSetCheck(); void scale(); @@ -55,6 +60,38 @@ private slots: void structuredBinding(); }; +void tst_QSize::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QSize>(); +} + +void tst_QSize::compare_data() +{ + QTest::addColumn<QSize>("lhs"); + QTest::addColumn<QSize>("rhs"); + QTest::addColumn<bool>("result"); + + auto row = [](QSize lhs, QSize rhs, bool res) { + QTest::addRow("(%d, %d) vs (%d, %d)", lhs.width(), lhs.height(), rhs.width(), rhs.height()) + << lhs << rhs << res; + }; + + row(QSize(0, 0), QSize(0, 0), true); + row(QSize(1, 0), QSize(0, 1), false); + row(QSize(-1, -1), QSize(-1, -1), true); + row(QSize(-1, -1), QSize(1, 1), false); + row(QSize(INT_MIN, INT_MAX), QSize(INT_MAX, INT_MIN), false); +} + +void tst_QSize::compare() +{ + QFETCH(QSize, lhs); + QFETCH(QSize, rhs); + QFETCH(bool, result); + + QT_TEST_EQUALITY_OPS(lhs, rhs, result); +} + // Testing get/set functions void tst_QSize::getSetCheck() { diff --git a/tests/auto/corelib/tools/qsizef/CMakeLists.txt b/tests/auto/corelib/tools/qsizef/CMakeLists.txt index 9adaafe2ea..d8a1c7f46e 100644 --- a/tests/auto/corelib/tools/qsizef/CMakeLists.txt +++ b/tests/auto/corelib/tools/qsizef/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qsizef SOURCES tst_qsizef.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp b/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp index ee33fa13b6..bb087e89de 100644 --- a/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp +++ b/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp @@ -24,17 +24,30 @@ CHECK(const &&); #undef CHECK #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qsize.h> Q_DECLARE_METATYPE(QMarginsF) +static constexpr qreal qreal_min = std::numeric_limits<qreal>::min(); + class tst_QSizeF : public QObject { Q_OBJECT private slots: + void compareCompiles(); + void compare_data(); + void compare(); + + void fuzzyCompare_data(); + void fuzzyCompare(); + void isNull_data(); void isNull(); + void fuzzyIsNull_data(); + void fuzzyIsNull(); + void scale(); void expandedTo(); @@ -52,6 +65,61 @@ private slots: void structuredBinding(); }; +void tst_QSizeF::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QSizeF>(); + QTestPrivate::testEqualityOperatorsCompile<QSizeF, QSize>(); +} + +void tst_QSizeF::compare_data() +{ + QTest::addColumn<QSizeF>("lhs"); + QTest::addColumn<QSizeF>("rhs"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("mixedResult"); + + auto row = [&](QSizeF lhs, QSizeF rhs, bool res, bool mixedRes) { + QString str; + QDebug dbg(&str); + dbg.nospace() << "(" << lhs.width() << ", " << lhs.height() << ") vs " + << "(" << rhs.width() << ", " << rhs.height() << ")"; + QTest::addRow("%s", str.toLatin1().constData()) << lhs << rhs << res << mixedRes; + }; + + row(QSizeF(0.0, 0.0), QSizeF(0.0, 0.0), true, true); + row(QSizeF(1.0, 2.0), QSizeF(1.0, 2.0), true, true); + row(QSizeF(1.0, -1.0), QSizeF(-1.0, 1.0), false, false); + row(QSizeF(0.1, 1.1), QSizeF(0.1, 1.1), true, false); + row(QSizeF(qreal_min, 0.0), QSizeF(0.0, -qreal_min), true, true); +} + +void tst_QSizeF::compare() +{ + QFETCH(QSizeF, lhs); + QFETCH(QSizeF, rhs); + QFETCH(bool, result); + QFETCH(bool, mixedResult); + + QT_TEST_EQUALITY_OPS(lhs, rhs, result); + + const QSize rhsFixed = rhs.toSize(); + QT_TEST_EQUALITY_OPS(lhs, rhsFixed, mixedResult); +} + +void tst_QSizeF::fuzzyCompare_data() +{ + compare_data(); +} + +void tst_QSizeF::fuzzyCompare() +{ + QFETCH(QSizeF, lhs); + QFETCH(QSizeF, rhs); + QFETCH(bool, result); + + QCOMPARE_EQ(qFuzzyCompare(lhs, rhs), result); +} + void tst_QSizeF::isNull_data() { QTest::addColumn<qreal>("width"); @@ -66,6 +134,7 @@ void tst_QSizeF::isNull_data() QTest::newRow("0, -0.1") << qreal(0) << qreal(-0.1) << false; QTest::newRow("0.1, 0") << qreal(0.1) << qreal(0) << false; QTest::newRow("0, 0.1") << qreal(0) << qreal(0.1) << false; + QTest::newRow("qreal_min, -qreal_min") << qreal_min << -qreal_min << false; } void tst_QSizeF::isNull() @@ -80,6 +149,33 @@ void tst_QSizeF::isNull() QCOMPARE(size.isNull(), isNull); } +void tst_QSizeF::fuzzyIsNull_data() +{ + QTest::addColumn<qreal>("width"); + QTest::addColumn<qreal>("height"); + QTest::addColumn<bool>("fuzzyNull"); + + QTest::newRow("0, 0") << qreal(0.0) << qreal(0.0) << true; + QTest::newRow("-0, -0") << qreal(-0.0) << qreal(-0.0) << true; + QTest::newRow("0, -0") << qreal(0) << qreal(-0.0) << true; + QTest::newRow("-0, 0") << qreal(-0.0) << qreal(0) << true; + QTest::newRow("-0.1, 0") << qreal(-0.1) << qreal(0) << false; + QTest::newRow("0, -0.1") << qreal(0) << qreal(-0.1) << false; + QTest::newRow("0.1, 0") << qreal(0.1) << qreal(0) << false; + QTest::newRow("0, 0.1") << qreal(0) << qreal(0.1) << false; + QTest::newRow("qreal_min, -qreal_min") << qreal_min << -qreal_min << true; +} + +void tst_QSizeF::fuzzyIsNull() +{ + QFETCH(qreal, width); + QFETCH(qreal, height); + QFETCH(bool, fuzzyNull); + + QSizeF size(width, height); + QCOMPARE(qFuzzyIsNull(size), fuzzyNull); +} + void tst_QSizeF::scale() { QSizeF t1(10.4, 12.8); t1.scale(60.6, 60.6, Qt::IgnoreAspectRatio); diff --git a/tests/auto/corelib/tools/qspan/tst_qspan.cpp b/tests/auto/corelib/tools/qspan/tst_qspan.cpp index 91d2ecf739..c7456ac7f2 100644 --- a/tests/auto/corelib/tools/qspan/tst_qspan.cpp +++ b/tests/auto/corelib/tools/qspan/tst_qspan.cpp @@ -141,6 +141,9 @@ private: void from_variable_size_container_impl(C &&c) const; }; +template <typename T> +const void *as_const_void(T *p) noexcept { return static_cast<const void *>(p); } + #define RETURN_IF_FAILED() \ do { if (QTest::currentTestFailed()) return; } while (false) @@ -149,7 +152,7 @@ void tst_QSpan::onlyZeroExtentSpansHaveDefaultCtors() const static_assert(std::is_nothrow_default_constructible_v<QSpan<int, 0>>); static_assert(std::is_nothrow_default_constructible_v<QSpan<const int, 0>>); static_assert(std::is_nothrow_default_constructible_v<QSpan<int>>); - static_assert(std::is_nothrow_default_constructible_v<QSpan<const int, 0>>); + static_assert(std::is_nothrow_default_constructible_v<QSpan<const int>>); QSpan<int, 0> si; check_null_span(si); @@ -173,7 +176,7 @@ void tst_QSpan::onlyZeroExtentSpansHaveDefaultCtors() const void tst_QSpan::zeroExtentSpansMaintainADataPointer() const { - int i; + int i = 0; QSpan<int, 0> si{&i, 0}; QCOMPARE(si.data(), &i); check_empty_span_incl_subspans(si); @@ -334,6 +337,8 @@ void tst_QSpan::from_container_impl(C &&c) const const auto c_data = QSpanPrivate::adl_data(c); using V = std::remove_reference_t<QSpanPrivate::range_reference_t<C>>; + constexpr auto ExpectedBytesExtent + = ExpectedExtent == q20::dynamic_extent ? q20::dynamic_extent : ExpectedExtent * sizeof(V); { QSpan si = c; // CTAD static_assert(std::is_same_v<decltype(si), QSpan<V, ExpectedExtent>>); @@ -344,6 +349,20 @@ void tst_QSpan::from_container_impl(C &&c) const check_nonempty_span(si, c_size); RETURN_IF_FAILED(); + auto bi = as_bytes(si); + static_assert(std::is_same_v<decltype(bi), QSpan<const std::byte, ExpectedBytesExtent>>); + QCOMPARE_EQ(bi.size(), si.size_bytes()); + QCOMPARE_EQ(as_const_void(bi.data()), + as_const_void(si.data())); + + if constexpr (!std::is_const_v<V>) { // e.g. std::initializer_list<int> + auto wbi = as_writable_bytes(si); + static_assert(std::is_same_v<decltype(wbi), QSpan<std::byte, ExpectedBytesExtent>>); + QCOMPARE_EQ(wbi.size(), si.size_bytes()); + QCOMPARE_EQ(as_const_void(wbi.data()), + as_const_void(si.data())); + } + QSpan<const int> sci = c; QCOMPARE_EQ(sci.size(), c_size); @@ -351,6 +370,12 @@ void tst_QSpan::from_container_impl(C &&c) const check_nonempty_span(sci, c_size); RETURN_IF_FAILED(); + + auto bci = as_bytes(sci); + static_assert(std::is_same_v<decltype(bci), QSpan<const std::byte>>); + QCOMPARE_EQ(bci.size(), sci.size_bytes()); + QCOMPARE_EQ(as_const_void(bci.data()), + as_const_void(sci.data())); } { QSpan sci = std::as_const(c); // CTAD @@ -361,6 +386,12 @@ void tst_QSpan::from_container_impl(C &&c) const check_nonempty_span(sci, c_size); RETURN_IF_FAILED(); + + auto bci = as_bytes(sci); + static_assert(std::is_same_v<decltype(bci), QSpan<const std::byte, ExpectedBytesExtent>>); + QCOMPARE_EQ(bci.size(), sci.size_bytes()); + QCOMPARE_EQ(as_const_void(bci.data()), + as_const_void(sci.data())); } } diff --git a/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt b/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt index 8f6ed66841..5b9fa60c64 100644 --- a/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt +++ b/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt @@ -14,6 +14,8 @@ endif() qt_internal_add_test(tst_qversionnumber SOURCES tst_qversionnumber.cpp + LIBRARIES + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp index da9dcc9366..5ccf56c1d1 100644 --- a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp +++ b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QtCore/qversionnumber.h> #include <QtCore/qlibraryinfo.h> @@ -16,24 +17,15 @@ private: private slots: void initTestCase(); + void compareCompiles(); void constructorDefault(); void constructorVersioned_data(); void constructorVersioned(); void constructorExplicit(); void constructorCopy_data(); void constructorCopy(); - void compareGreater_data(); - void compareGreater(); - void compareGreaterEqual_data(); - void compareGreaterEqual(); - void compareLess_data(); - void compareLess(); - void compareLessEqual_data(); - void compareLessEqual(); - void compareEqual_data(); - void compareEqual(); - void compareNotEqual_data(); - void compareNotEqual(); + void comparisonOperators_data(); + void comparisonOperators(); void compare_data(); void compare(); void isPrefixOf_data(); @@ -121,74 +113,69 @@ void tst_QVersionNumber::comparisonData() { QTest::addColumn<QVersionNumber>("lhs"); QTest::addColumn<QVersionNumber>("rhs"); - QTest::addColumn<bool>("equal"); - QTest::addColumn<bool>("notEqual"); - QTest::addColumn<bool>("lessThan"); - QTest::addColumn<bool>("lessThanOrEqual"); - QTest::addColumn<bool>("greaterThan"); - QTest::addColumn<bool>("greaterThanOrEqual"); + QTest::addColumn<Qt::strong_ordering>("ordering"); QTest::addColumn<int>("compareResult"); QTest::addColumn<bool>("isPrefix"); QTest::addColumn<QVersionNumber>("common"); - // LHS RHS == != < <= > >= compareResult isPrefixOf commonPrefix - QTest::newRow("null, null") << QVersionNumber() << QVersionNumber() << true << false << false << true << false << true << 0 << true << QVersionNumber(); - QTest::newRow("null, 0") << QVersionNumber() << QVersionNumber(0) << false << true << true << true << false << false << -1 << true << QVersionNumber(); - QTest::newRow("0, null") << QVersionNumber(0) << QVersionNumber() << false << true << false << false << true << true << 1 << false << QVersionNumber(); - QTest::newRow("0, 0") << QVersionNumber(0) << QVersionNumber(0) << true << false << false << true << false << true << 0 << true << QVersionNumber(0); - QTest::newRow("1.0, 1.0") << QVersionNumber(1, 0) << QVersionNumber(1, 0) << true << false << false << true << false << true << 0 << true << QVersionNumber(1, 0); - QTest::newRow("1, 1.0") << QVersionNumber(1) << QVersionNumber(1, 0) << false << true << true << true << false << false << -1 << true << QVersionNumber(1); - QTest::newRow("1.0, 1") << QVersionNumber(1, 0) << QVersionNumber(1) << false << true << false << false << true << true << 1 << false << QVersionNumber(1); - - QTest::newRow("0.1.2, 0.1") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1) << false << true << false << false << true << true << 2 << false << QVersionNumber(0, 1); - QTest::newRow("0.1, 0.1.2") << QVersionNumber(0, 1) << QVersionNumber(0, 1, 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(0, 1); - QTest::newRow("0.1.2, 0.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1, 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(0, 1, 2); - QTest::newRow("0.1.2, 1.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(1, 1, 2) << false << true << true << true << false << false << -1 << false << QVersionNumber(); - QTest::newRow("1.1.2, 0.1.2") << QVersionNumber(1, 1, 2) << QVersionNumber(0, 1, 2) << false << true << false << false << true << true << 1 << false << QVersionNumber(); - QTest::newRow("1, -1") << QVersionNumber(1) << QVersionNumber(-1) << false << true << false << false << true << true << 2 << false << QVersionNumber(); - QTest::newRow("-1, 1") << QVersionNumber(-1) << QVersionNumber(1) << false << true << true << true << false << false << -2 << false << QVersionNumber(); - QTest::newRow("0.1, 0.-1") << QVersionNumber(0, 1) << QVersionNumber(0, -1) << false << true << false << false << true << true << 2 << false << QVersionNumber(0); - QTest::newRow("0.-1, 0.1") << QVersionNumber(0, -1) << QVersionNumber(0, 1) << false << true << true << true << false << false << -2 << false << QVersionNumber(0); - QTest::newRow("0.-1, 0") << QVersionNumber(0, -1) << QVersionNumber(0) << false << true << true << true << false << false << -1 << false << QVersionNumber(0); - QTest::newRow("0, 0.-1") << QVersionNumber(0) << QVersionNumber(0, -1) << false << true << false << false << true << true << 1 << true << QVersionNumber(0); - - QTest::newRow("0.127.2, 0.127") << QVersionNumber(0, 127, 2) << QVersionNumber(0, 127) << false << true << false << false << true << true << 2 << false << QVersionNumber(0, 127); - QTest::newRow("0.127, 0.127.2") << QVersionNumber(0, 127) << QVersionNumber(0, 127, 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(0, 127); - QTest::newRow("0.127.2, 0.127.2") << QVersionNumber(0, 127, 2) << QVersionNumber(0, 127, 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(0, 127, 2); - QTest::newRow("0.127.2, 127.127.2") << QVersionNumber(0, 127, 2) << QVersionNumber(127, 127, 2) << false << true << true << true << false << false << -127 << false << QVersionNumber(); - QTest::newRow("127.127.2, 0.127.2") << QVersionNumber(127, 127, 2) << QVersionNumber(0, 127, 2) << false << true << false << false << true << true << 127 << false << QVersionNumber(); - QTest::newRow("127, -128") << QVersionNumber(127) << QVersionNumber(-128) << false << true << false << false << true << true << 255 << false << QVersionNumber(); - QTest::newRow("-128, 127") << QVersionNumber(-128) << QVersionNumber(127) << false << true << true << true << false << false << -255 << false << QVersionNumber(); - QTest::newRow("0.127, 0.-128") << QVersionNumber(0, 127) << QVersionNumber(0, -128) << false << true << false << false << true << true << 255 << false << QVersionNumber(0); - QTest::newRow("0.-128, 0.127") << QVersionNumber(0, -128) << QVersionNumber(0, 127) << false << true << true << true << false << false << -255 << false << QVersionNumber(0); - QTest::newRow("0.-128, 0") << QVersionNumber(0, -128) << QVersionNumber(0) << false << true << true << true << false << false << -128 << false << QVersionNumber(0); - QTest::newRow("0, 0.-128") << QVersionNumber(0) << QVersionNumber(0, -128) << false << true << false << false << true << true << 128 << true << QVersionNumber(0); - - QTest::newRow("0.128.2, 0.128") << QVersionNumber(0, 128, 2) << QVersionNumber(0, 128) << false << true << false << false << true << true << 2 << false << QVersionNumber(0, 128); - QTest::newRow("0.128, 0.128.2") << QVersionNumber(0, 128) << QVersionNumber(0, 128, 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(0, 128); - QTest::newRow("0.128.2, 0.128.2") << QVersionNumber(0, 128, 2) << QVersionNumber(0, 128, 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(0, 128, 2); - QTest::newRow("0.128.2, 128.128.2") << QVersionNumber(0, 128, 2) << QVersionNumber(128, 128, 2) << false << true << true << true << false << false << -128 << false << QVersionNumber(); - QTest::newRow("128.128.2, 0.128.2") << QVersionNumber(128, 128, 2) << QVersionNumber(0, 128, 2) << false << true << false << false << true << true << 128 << false << QVersionNumber(); - QTest::newRow("128, -129") << QVersionNumber(128) << QVersionNumber(-129) << false << true << false << false << true << true << 257 << false << QVersionNumber(); - QTest::newRow("-129, 128") << QVersionNumber(-129) << QVersionNumber(128) << false << true << true << true << false << false << -257 << false << QVersionNumber(); - QTest::newRow("0.128, 0.-129") << QVersionNumber(0, 128) << QVersionNumber(0, -129) << false << true << false << false << true << true << 257 << false << QVersionNumber(0); - QTest::newRow("0.-129, 0.128") << QVersionNumber(0, -129) << QVersionNumber(0, 128) << false << true << true << true << false << false << -257 << false << QVersionNumber(0); - QTest::newRow("0.-129, 0") << QVersionNumber(0, -129) << QVersionNumber(0) << false << true << true << true << false << false << -129 << false << QVersionNumber(0); - QTest::newRow("0, 0.-129") << QVersionNumber(0) << QVersionNumber(0, -129) << false << true << false << false << true << true << 129 << true << QVersionNumber(0); + // LHS RHS ordering compareResult isPrefixOf commonPrefix + QTest::newRow("null, null") << QVersionNumber() << QVersionNumber() << Qt::strong_ordering::equal << 0 << true << QVersionNumber(); + QTest::newRow("null, 0") << QVersionNumber() << QVersionNumber(0) << Qt::strong_ordering::less << -1 << true << QVersionNumber(); + QTest::newRow("0, null") << QVersionNumber(0) << QVersionNumber() << Qt::strong_ordering::greater << 1 << false << QVersionNumber(); + QTest::newRow("0, 0") << QVersionNumber(0) << QVersionNumber(0) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(0); + QTest::newRow("1.0, 1.0") << QVersionNumber(1, 0) << QVersionNumber(1, 0) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(1, 0); + QTest::newRow("1, 1.0") << QVersionNumber(1) << QVersionNumber(1, 0) << Qt::strong_ordering::less << -1 << true << QVersionNumber(1); + QTest::newRow("1.0, 1") << QVersionNumber(1, 0) << QVersionNumber(1) << Qt::strong_ordering::greater << 1 << false << QVersionNumber(1); + + QTest::newRow("0.1.2, 0.1") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(0, 1); + QTest::newRow("0.1, 0.1.2") << QVersionNumber(0, 1) << QVersionNumber(0, 1, 2) << Qt::strong_ordering::less << -2 << true << QVersionNumber(0, 1); + QTest::newRow("0.1.2, 0.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1, 2) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(0, 1, 2); + QTest::newRow("0.1.2, 1.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(1, 1, 2) << Qt::strong_ordering::less << -1 << false << QVersionNumber(); + QTest::newRow("1.1.2, 0.1.2") << QVersionNumber(1, 1, 2) << QVersionNumber(0, 1, 2) << Qt::strong_ordering::greater << 1 << false << QVersionNumber(); + QTest::newRow("1, -1") << QVersionNumber(1) << QVersionNumber(-1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(); + QTest::newRow("-1, 1") << QVersionNumber(-1) << QVersionNumber(1) << Qt::strong_ordering::less << -2 << false << QVersionNumber(); + QTest::newRow("0.1, 0.-1") << QVersionNumber(0, 1) << QVersionNumber(0, -1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(0); + QTest::newRow("0.-1, 0.1") << QVersionNumber(0, -1) << QVersionNumber(0, 1) << Qt::strong_ordering::less << -2 << false << QVersionNumber(0); + QTest::newRow("0.-1, 0") << QVersionNumber(0, -1) << QVersionNumber(0) << Qt::strong_ordering::less << -1 << false << QVersionNumber(0); + QTest::newRow("0, 0.-1") << QVersionNumber(0) << QVersionNumber(0, -1) << Qt::strong_ordering::greater << 1 << true << QVersionNumber(0); + + QTest::newRow("0.127.2, 0.127") << QVersionNumber(0, 127, 2) << QVersionNumber(0, 127) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(0, 127); + QTest::newRow("0.127, 0.127.2") << QVersionNumber(0, 127) << QVersionNumber(0, 127, 2) << Qt::strong_ordering::less << -2 << true << QVersionNumber(0, 127); + QTest::newRow("0.127.2, 0.127.2") << QVersionNumber(0, 127, 2) << QVersionNumber(0, 127, 2) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(0, 127, 2); + QTest::newRow("0.127.2, 127.127.2") << QVersionNumber(0, 127, 2) << QVersionNumber(127, 127, 2) << Qt::strong_ordering::less << -127 << false << QVersionNumber(); + QTest::newRow("127.127.2, 0.127.2") << QVersionNumber(127, 127, 2) << QVersionNumber(0, 127, 2) << Qt::strong_ordering::greater << 127 << false << QVersionNumber(); + QTest::newRow("127, -128") << QVersionNumber(127) << QVersionNumber(-128) << Qt::strong_ordering::greater << 255 << false << QVersionNumber(); + QTest::newRow("-128, 127") << QVersionNumber(-128) << QVersionNumber(127) << Qt::strong_ordering::less << -255 << false << QVersionNumber(); + QTest::newRow("0.127, 0.-128") << QVersionNumber(0, 127) << QVersionNumber(0, -128) << Qt::strong_ordering::greater << 255 << false << QVersionNumber(0); + QTest::newRow("0.-128, 0.127") << QVersionNumber(0, -128) << QVersionNumber(0, 127) << Qt::strong_ordering::less << -255 << false << QVersionNumber(0); + QTest::newRow("0.-128, 0") << QVersionNumber(0, -128) << QVersionNumber(0) << Qt::strong_ordering::less << -128 << false << QVersionNumber(0); + QTest::newRow("0, 0.-128") << QVersionNumber(0) << QVersionNumber(0, -128) << Qt::strong_ordering::greater << 128 << true << QVersionNumber(0); + + QTest::newRow("0.128.2, 0.128") << QVersionNumber(0, 128, 2) << QVersionNumber(0, 128) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(0, 128); + QTest::newRow("0.128, 0.128.2") << QVersionNumber(0, 128) << QVersionNumber(0, 128, 2) << Qt::strong_ordering::less << -2 << true << QVersionNumber(0, 128); + QTest::newRow("0.128.2, 0.128.2") << QVersionNumber(0, 128, 2) << QVersionNumber(0, 128, 2) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(0, 128, 2); + QTest::newRow("0.128.2, 128.128.2") << QVersionNumber(0, 128, 2) << QVersionNumber(128, 128, 2) << Qt::strong_ordering::less << -128 << false << QVersionNumber(); + QTest::newRow("128.128.2, 0.128.2") << QVersionNumber(128, 128, 2) << QVersionNumber(0, 128, 2) << Qt::strong_ordering::greater << 128 << false << QVersionNumber(); + QTest::newRow("128, -129") << QVersionNumber(128) << QVersionNumber(-129) << Qt::strong_ordering::greater << 257 << false << QVersionNumber(); + QTest::newRow("-129, 128") << QVersionNumber(-129) << QVersionNumber(128) << Qt::strong_ordering::less << -257 << false << QVersionNumber(); + QTest::newRow("0.128, 0.-129") << QVersionNumber(0, 128) << QVersionNumber(0, -129) << Qt::strong_ordering::greater << 257 << false << QVersionNumber(0); + QTest::newRow("0.-129, 0.128") << QVersionNumber(0, -129) << QVersionNumber(0, 128) << Qt::strong_ordering::less << -257 << false << QVersionNumber(0); + QTest::newRow("0.-129, 0") << QVersionNumber(0, -129) << QVersionNumber(0) << Qt::strong_ordering::less << -129 << false << QVersionNumber(0); + QTest::newRow("0, 0.-129") << QVersionNumber(0) << QVersionNumber(0, -129) << Qt::strong_ordering::greater << 129 << true << QVersionNumber(0); const QList<int> common = QList<int>({ 0, 1, 2, 3, 4, 5, 6 }); using namespace UglyOperator; - QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1) << false << true << false << false << true << true << 2 << false << QVersionNumber(common + 0 + 1); - QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + 1 + 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(common + 0 + 1); - QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1 + 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(common + 0 + 1 + 2); - QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.1.1.2") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 1 + 1 + 2) << false << true << true << true << false << false << -1 << false << QVersionNumber(common); - QTest::newRow("0.1.2.3.4.5.6.1.1.2, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 1 + 1 + 2) << QVersionNumber(common + 0 + 1 + 2) << false << true << false << false << true << true << 1 << false << QVersionNumber(common); - QTest::newRow("0.1.2.3.4.5.6.1, 0.1.2.3.4.5.6.-1") << QVersionNumber(common + 1) << QVersionNumber(common + -1) << false << true << false << false << true << true << 2 << false << QVersionNumber(common); - QTest::newRow("0.1.2.3.4.5.6.-1, 0.1.2.3.4.5.6.1") << QVersionNumber(common + -1) << QVersionNumber(common + 1) << false << true << true << true << false << false << -2 << false << QVersionNumber(common); - QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.-1") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + -1) << false << true << false << false << true << true << 2 << false << QVersionNumber(common + 0); - QTest::newRow("0.1.2.3.4.5.6.0.-1, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + -1) << QVersionNumber(common + 0 + 1) << false << true << true << true << false << false << -2 << false << QVersionNumber(common + 0); - QTest::newRow("0.1.2.3.4.5.6.0.-1, 0.1.2.3.4.5.6.0") << QVersionNumber(common + 0 + -1) << QVersionNumber(common + 0) << false << true << true << true << false << false << -1 << false << QVersionNumber(common + 0); - QTest::newRow("0.1.2.3.4.5.6.0, 0.1.2.3.4.5.6.0.-1") << QVersionNumber(common + 0) << QVersionNumber(common + 0 + -1) << false << true << false << false << true << true << 1 << true << QVersionNumber(common + 0); + QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(common + 0 + 1); + QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + 1 + 2) << Qt::strong_ordering::less << -2 << true << QVersionNumber(common + 0 + 1); + QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1 + 2) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(common + 0 + 1 + 2); + QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.1.1.2") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 1 + 1 + 2) << Qt::strong_ordering::less << -1 << false << QVersionNumber(common); + QTest::newRow("0.1.2.3.4.5.6.1.1.2, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 1 + 1 + 2) << QVersionNumber(common + 0 + 1 + 2) << Qt::strong_ordering::greater << 1 << false << QVersionNumber(common); + QTest::newRow("0.1.2.3.4.5.6.1, 0.1.2.3.4.5.6.-1") << QVersionNumber(common + 1) << QVersionNumber(common + -1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(common); + QTest::newRow("0.1.2.3.4.5.6.-1, 0.1.2.3.4.5.6.1") << QVersionNumber(common + -1) << QVersionNumber(common + 1) << Qt::strong_ordering::less << -2 << false << QVersionNumber(common); + QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.-1") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + -1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(common + 0); + QTest::newRow("0.1.2.3.4.5.6.0.-1, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + -1) << QVersionNumber(common + 0 + 1) << Qt::strong_ordering::less << -2 << false << QVersionNumber(common + 0); + QTest::newRow("0.1.2.3.4.5.6.0.-1, 0.1.2.3.4.5.6.0") << QVersionNumber(common + 0 + -1) << QVersionNumber(common + 0) << Qt::strong_ordering::less << -1 << false << QVersionNumber(common + 0); + QTest::newRow("0.1.2.3.4.5.6.0, 0.1.2.3.4.5.6.0.-1") << QVersionNumber(common + 0) << QVersionNumber(common + 0 + -1) << Qt::strong_ordering::greater << 1 << true << QVersionNumber(common + 0); } void tst_QVersionNumber::initTestCase() @@ -196,6 +183,11 @@ void tst_QVersionNumber::initTestCase() qRegisterMetaType<QList<int>>(); } +void tst_QVersionNumber::compareCompiles() +{ + QTestPrivate::testAllComparisonOperatorsCompile<QVersionNumber>(); +} + void tst_QVersionNumber::constructorDefault() { QVersionNumber version; @@ -270,88 +262,18 @@ void tst_QVersionNumber::constructorCopy() QCOMPARE(version.segments(), expectedVersion.segments()); } -void tst_QVersionNumber::compareGreater_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareGreater() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, greaterThan); - - QCOMPARE(lhs > rhs, greaterThan); -} - -void tst_QVersionNumber::compareGreaterEqual_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareGreaterEqual() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, greaterThanOrEqual); - - QCOMPARE(lhs >= rhs, greaterThanOrEqual); -} - -void tst_QVersionNumber::compareLess_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareLess() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, lessThan); - - QCOMPARE(lhs < rhs, lessThan); -} - -void tst_QVersionNumber::compareLessEqual_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareLessEqual() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, lessThanOrEqual); - - QCOMPARE(lhs <= rhs, lessThanOrEqual); -} - -void tst_QVersionNumber::compareEqual_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareEqual() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, equal); - - QCOMPARE(lhs == rhs, equal); -} - -void tst_QVersionNumber::compareNotEqual_data() +void tst_QVersionNumber::comparisonOperators_data() { comparisonData(); } -void tst_QVersionNumber::compareNotEqual() +void tst_QVersionNumber::comparisonOperators() { QFETCH(QVersionNumber, lhs); QFETCH(QVersionNumber, rhs); - QFETCH(bool, notEqual); + QFETCH(Qt::strong_ordering, ordering); - QCOMPARE(lhs != rhs, notEqual); + QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, ordering); } void tst_QVersionNumber::compare_data() @@ -394,7 +316,7 @@ void tst_QVersionNumber::commonPrefix() QFETCH(QVersionNumber, common); QVersionNumber calculatedPrefix = QVersionNumber::commonPrefix(lhs, rhs); - QCOMPARE(calculatedPrefix, common); + QT_TEST_EQUALITY_OPS(calculatedPrefix, common, true); QCOMPARE(calculatedPrefix.segments(), common.segments()); } @@ -530,18 +452,18 @@ void tst_QVersionNumber::fromString_extra() // when passing explicit nullptr: { auto v = QVersionNumber::fromString("1.2.3-rc1", nullptr); - QCOMPARE(v, QVersionNumber({1, 2, 3})); + QT_TEST_EQUALITY_OPS(v, QVersionNumber({1, 2, 3}), true); } { auto v = QVersionNumber::fromString("1.2.3-rc1", 0); - QCOMPARE(v, QVersionNumber({1, 2, 3})); + QT_TEST_EQUALITY_OPS(v, QVersionNumber({1, 2, 3}), true); } // check the UTF16->L1 conversion isn't doing something weird { qsizetype i = -1; auto v = QVersionNumber::fromString(u"1.0ı", &i); // LATIN SMALL LETTER DOTLESS I - QCOMPARE(v, QVersionNumber(1, 0)); + QT_TEST_EQUALITY_OPS(v, QVersionNumber(1, 0), true); QCOMPARE(i, 3); } } @@ -652,14 +574,14 @@ void tst_QVersionNumber::moveSemantics() { QVersionNumber v1(1, 2, 3); QVersionNumber v2 = std::move(v1); - QCOMPARE(v2, QVersionNumber(1, 2, 3)); + QT_TEST_EQUALITY_OPS(v2, QVersionNumber(1, 2, 3), true); } // QVersionNumber &operator=(QVersionNumber &&) { QVersionNumber v1(1, 2, 3); QVersionNumber v2; v2 = std::move(v1); - QCOMPARE(v2, QVersionNumber(1, 2, 3)); + QT_TEST_EQUALITY_OPS(v2, QVersionNumber(1, 2, 3), true); } // QVersionNumber(QList<int> &&) { @@ -668,7 +590,7 @@ void tst_QVersionNumber::moveSemantics() QVersionNumber v2(std::move(segments)); QVERIFY(!v1.isNull()); QVERIFY(!v2.isNull()); - QCOMPARE(v1, v2); + QT_TEST_EQUALITY_OPS(v1, v2, true); } #ifdef Q_COMPILER_REF_QUALIFIERS // normalized() diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp index 504d1a4fea..ab750dff33 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp @@ -1422,7 +1422,7 @@ void tst_QDBusConnection::connectionLimit() QProcess daemon; daemon.start("dbus-daemon", - QStringList() << "--config-file" << QFINDTESTDATA("tst_qdbusconnection.conf") + QStringList() << "--config-file" << QFINDTESTDATA("../qdbusconnection/tst_qdbusconnection.conf") << "--nofork" << "--print-address"); QVERIFY2(daemon.waitForReadyRead(2000), diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index e7a8273115..355a65bc59 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -161,7 +161,9 @@ void basicStringTypes_data() { QTest::newRow("string") << QVariant("ping") << "s" << "\"ping\""; QTest::newRow("objectpath") << QVariant::fromValue(QDBusObjectPath("/org/kde")) << "o" << "[ObjectPath: /org/kde]"; + QTest::newRow("emptysignature") << QVariant::fromValue(QDBusSignature(QString())) << "g" << "[Signature: ]"; QTest::newRow("signature") << QVariant::fromValue(QDBusSignature("g")) << "g" << "[Signature: g]"; + QTest::newRow("multisignature") << QVariant::fromValue(QDBusSignature("bit")) << "g" << "[Signature: bit]"; QTest::newRow("emptystring") << QVariant("") << "s" << "\"\""; QTest::newRow("nullstring") << QVariant(QString()) << "s" << "\"\""; } @@ -907,7 +909,7 @@ void tst_QDBusMarshall::sendSignalErrors() QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal to service \"\" path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid object path passed in arguments"); QVERIFY(!con.send(msg)); - QDBusSignature sig; + QDBusSignature sig(QChar(0)); msg.setArguments(QVariantList() << QVariant::fromValue(sig)); QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal to service \"\" path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid signature passed in arguments"); QVERIFY(!con.send(msg)); @@ -992,7 +994,7 @@ void tst_QDBusMarshall::sendCallErrors_data() << ""; QTest::newRow("invalid-signature-arg") << serviceName << objectPath << interfaceName << "ping" - << (QVariantList() << QVariant::fromValue(QDBusSignature())) + << (QVariantList() << QVariant::fromValue(QDBusSignature(QChar(0)))) << "org.freedesktop.DBus.Error.Failed" << "Marshalling failed: Invalid signature passed in arguments" << ""; diff --git a/tests/auto/dbus/qdbustype/tst_qdbustype.cpp b/tests/auto/dbus/qdbustype/tst_qdbustype.cpp index f4ad4cb77a..63cb7d4a65 100644 --- a/tests/auto/dbus/qdbustype/tst_qdbustype.cpp +++ b/tests/auto/dbus/qdbustype/tst_qdbustype.cpp @@ -206,6 +206,7 @@ void tst_QDBusType::isValidBasicType() void tst_QDBusType::isValidSingleSignature_data() { addColumns(); + QTest::newRow("empty") << "" << false; addSingleSignatures(); addNakedDictEntry(); } @@ -222,6 +223,7 @@ void tst_QDBusType::isValidSingleSignature() void tst_QDBusType::isValidArray_data() { addColumns(); + QTest::newRow("empty") << "" << false; addSingleSignatures(); } @@ -241,7 +243,10 @@ void tst_QDBusType::isValidArray() void tst_QDBusType::isValidSignature_data() { - isValidSingleSignature_data(); + addColumns(); + QTest::newRow("empty") << "" << true; + addSingleSignatures(); + addNakedDictEntry(); } void tst_QDBusType::isValidSignature() @@ -250,8 +255,10 @@ void tst_QDBusType::isValidSignature() QFETCH(bool, result); data.append(data); - if (data.at(0).unicode()) - QCOMPARE(bool(q_dbus_signature_validate(data.toLatin1(), 0)), result); + if (!data.isEmpty() && data.at(0).unicode()) { + // libdbus-1 API can't deal with string containing NULs + QCOMPARE(bool(q_dbus_signature_validate(data.toLatin1(), nullptr)), result); + } QCOMPARE(QDBusUtil::isValidSignature(data), result); } diff --git a/tests/auto/gui/image/CMakeLists.txt b/tests/auto/gui/image/CMakeLists.txt index 9cc6d4d2bf..3535d5f01e 100644 --- a/tests/auto/gui/image/CMakeLists.txt +++ b/tests/auto/gui/image/CMakeLists.txt @@ -12,8 +12,12 @@ add_subdirectory(qpixmap) add_subdirectory(qimage) add_subdirectory(qimageiohandler) add_subdirectory(qimagewriter) -add_subdirectory(qmovie) -add_subdirectory(qpicture) +if(QT_FEATURE_movie) + add_subdirectory(qmovie) +endif() +if(QT_FEATURE_picture) + add_subdirectory(qpicture) +endif() add_subdirectory(qiconhighdpi) if(QT_FEATURE_private_tests) add_subdirectory(qpixmapcache) diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 1d0cdfcc4e..9d3311c13c 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -15,6 +15,7 @@ #include <stdio.h> #include <qpainter.h> +#include <private/qcmyk_p.h> #include <private/qimage_p.h> #include <private/qdrawhelper_p.h> @@ -110,6 +111,8 @@ private slots: void smoothScaleFormats(); void smoothScaleNoConversion_data(); void smoothScaleNoConversion(); + void smoothScale_CMYK_data(); + void smoothScale_CMYK(); void transformed_data(); void transformed(); @@ -2091,6 +2094,76 @@ void tst_QImage::smoothScaleNoConversion() QVERIFY(img.hasAlphaChannel()); } +void tst_QImage::smoothScale_CMYK_data() +{ + QTest::addColumn<int>("size"); + + const int sizes[] = { 2, 3, 4, 6, 7, 8, 10, 16, 20, 32, 40, 64, 100, 101, 128 }; + for (int size : sizes) + QTest::addRow("%d x %d", size, size) << size; +} + +void tst_QImage::smoothScale_CMYK() +{ + QFETCH(int, size); + QImage img(size, size, QImage::Format_CMYK8888); + QCmyk32 expected(31, 63, 127, 127); + img.fill(expected.toUint()); + + auto getCmykPixel = [](const QImage &image, int x, int y) { + Q_ASSERT(image.format() == QImage::Format_CMYK8888); + const uint *line = reinterpret_cast<const uint *>(image.scanLine(y)); + const uint pixel = line[x]; + return QCmyk32::fromCmyk32(pixel); + }; + + // scale x down, y down + QImage scaled = img.scaled(QSize(1, 1), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + QCmyk32 pixel = getCmykPixel(scaled, 0, 0); + QCOMPARE(pixel, expected); + + // scale x down, y up + scaled = img.scaled(QSize(1, size * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int y = 0; y < scaled.height(); ++y) { + pixel = getCmykPixel(scaled, 0, y); + QCOMPARE(pixel, expected); + } + + // scale x up, y down + scaled = img.scaled(QSize(size * 2, 1), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int x = 0; x < scaled.width(); ++x) { + pixel = getCmykPixel(scaled, x, 0); + QCOMPARE(pixel, expected); + } + + // scale x up + scaled = img.scaled(QSize(size, size * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int y = 0; y < scaled.height(); ++y) { + for (int x = 0; x < scaled.width(); ++x) { + pixel = getCmykPixel(scaled, x, y); + QCOMPARE(pixel, expected); + } + } + + // scale y up + scaled = img.scaled(QSize(size * 2, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int y = 0; y < scaled.height(); ++y) { + for (int x = 0; x < scaled.width(); ++x) { + pixel = getCmykPixel(scaled, x, y); + QCOMPARE(pixel, expected); + } + } + + // scale x up, y up + scaled = img.scaled(QSize(size * 2, size * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int y = 0; y < scaled.height(); ++y) { + for (int x = 0; x < scaled.width(); ++x) { + pixel = getCmykPixel(scaled, x, y); + QCOMPARE(pixel, expected); + } + } +} + static int count(const QImage &img, int x, int y, int dx, int dy, QRgb pixel) { int i = 0; @@ -3863,10 +3936,12 @@ void tst_QImage::metadataPassthrough() QCOMPARE(alphaMask.dotsPerMeterY(), a.dotsPerMeterY()); QCOMPARE(alphaMask.devicePixelRatio(), a.devicePixelRatio()); +#ifndef QT_NO_IMAGE_HEURISTIC_MASK QImage heuristicMask = a.createHeuristicMask(); QCOMPARE(heuristicMask.dotsPerMeterX(), a.dotsPerMeterX()); QCOMPARE(heuristicMask.dotsPerMeterY(), a.dotsPerMeterY()); QCOMPARE(heuristicMask.devicePixelRatio(), a.devicePixelRatio()); +#endif QImage maskFromColor = a.createMaskFromColor(qRgb(0, 0, 0)); QCOMPARE(maskFromColor.dotsPerMeterX(), a.dotsPerMeterX()); diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index 137439d98b..d8c553b521 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -1176,8 +1176,10 @@ void tst_QPixmap::dprPassthrough() pm.convertFromImage(img); QCOMPARE(pm.devicePixelRatio(), dpr); +#ifndef QT_NO_IMAGE_HEURISTIC_MASK QBitmap heuristicMask = src.createHeuristicMask(); QCOMPARE(heuristicMask.devicePixelRatio(), dpr); +#endif QBitmap maskFromColor = src.createMaskFromColor(Qt::white); QCOMPARE(maskFromColor.devicePixelRatio(), dpr); diff --git a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp index 70fb2b39d3..093367c759 100644 --- a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp +++ b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp @@ -112,13 +112,17 @@ void tst_QStandardItem::getSetData() item.setToolTip(toolTip); QCOMPARE(item.toolTip(), toolTip); +#ifndef QT_NO_STATUSTIP QString statusTip = QLatin1String("statusTip ") + iS; item.setStatusTip(statusTip); QCOMPARE(item.statusTip(), statusTip); +#endif +#if QT_CONFIG(whatsthis) QString whatsThis = QLatin1String("whatsThis ") + iS; item.setWhatsThis(whatsThis); QCOMPARE(item.whatsThis(), whatsThis); +#endif QSize sizeHint(64*i, 48*i); item.setSizeHint(sizeHint); @@ -157,8 +161,12 @@ void tst_QStandardItem::getSetData() QCOMPARE(item.text(), text); QCOMPARE(item.icon(), icon); QCOMPARE(item.toolTip(), toolTip); +#ifndef QT_NO_STATUSTIP QCOMPARE(item.statusTip(), statusTip); +#endif +#if QT_CONFIG(whatsthis) QCOMPARE(item.whatsThis(), whatsThis); +#endif QCOMPARE(item.sizeHint(), sizeHint); QCOMPARE(item.font(), font); QCOMPARE(item.textAlignment(), textAlignment); @@ -171,8 +179,12 @@ void tst_QStandardItem::getSetData() QCOMPARE(qvariant_cast<QString>(item.data(Qt::DisplayRole)), text); QCOMPARE(qvariant_cast<QIcon>(item.data(Qt::DecorationRole)), icon); QCOMPARE(qvariant_cast<QString>(item.data(Qt::ToolTipRole)), toolTip); +#ifndef QT_NO_STATUSTIP QCOMPARE(qvariant_cast<QString>(item.data(Qt::StatusTipRole)), statusTip); +#endif +#if QT_CONFIG(whatsthis) QCOMPARE(qvariant_cast<QString>(item.data(Qt::WhatsThisRole)), whatsThis); +#endif QCOMPARE(qvariant_cast<QSize>(item.data(Qt::SizeHintRole)), sizeHint); QCOMPARE(qvariant_cast<QFont>(item.data(Qt::FontRole)), font); QCOMPARE(qvariant_cast<int>(item.data(Qt::TextAlignmentRole)), int(textAlignment)); @@ -844,7 +856,9 @@ void tst_QStandardItem::streamItem() item.setText(QLatin1String("text")); item.setToolTip(QLatin1String("toolTip")); item.setStatusTip(QLatin1String("statusTip")); +#if QT_CONFIG(whatsthis) item.setWhatsThis(QLatin1String("whatsThis")); +#endif item.setSizeHint(QSize(64, 48)); item.setFont(QFont()); item.setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); @@ -866,7 +880,9 @@ void tst_QStandardItem::streamItem() QCOMPARE(streamedItem.text(), item.text()); QCOMPARE(streamedItem.toolTip(), item.toolTip()); QCOMPARE(streamedItem.statusTip(), item.statusTip()); +#if QT_CONFIG(whatsthis) QCOMPARE(streamedItem.whatsThis(), item.whatsThis()); +#endif QCOMPARE(streamedItem.sizeHint(), item.sizeHint()); QCOMPARE(streamedItem.font(), item.font()); QCOMPARE(streamedItem.textAlignment(), item.textAlignment()); @@ -905,7 +921,9 @@ void tst_QStandardItem::clone() item.setText(QLatin1String("text")); item.setToolTip(QLatin1String("toolTip")); item.setStatusTip(QLatin1String("statusTip")); +#if QT_CONFIG(whatsthis) item.setWhatsThis(QLatin1String("whatsThis")); +#endif item.setSizeHint(QSize(64, 48)); item.setFont(QFont()); item.setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); @@ -920,7 +938,9 @@ void tst_QStandardItem::clone() QCOMPARE(clone->text(), item.text()); QCOMPARE(clone->toolTip(), item.toolTip()); QCOMPARE(clone->statusTip(), item.statusTip()); +#if QT_CONFIG(whatsthis) QCOMPARE(clone->whatsThis(), item.whatsThis()); +#endif QCOMPARE(clone->sizeHint(), item.sizeHint()); QCOMPARE(clone->font(), item.font()); QCOMPARE(clone->textAlignment(), item.textAlignment()); diff --git a/tests/auto/gui/kernel/qevent/tst_qevent.cpp b/tests/auto/gui/kernel/qevent/tst_qevent.cpp index 6960f99af2..8e8169b16c 100644 --- a/tests/auto/gui/kernel/qevent/tst_qevent.cpp +++ b/tests/auto/gui/kernel/qevent/tst_qevent.cpp @@ -6,7 +6,52 @@ #include <QtGui/qguiapplication.h> #include <QtGui/qevent.h> +#if QT_CONFIG(future) #include <QtCore/private/qfutureinterface_p.h> +#endif + + +#if QT_CONFIG(future) +#define X_QFutureCallOutEvent(X) X(QFutureCallOutEvent, ()) +#else +#define X_QFutureCallOutEvent(X) +#endif + +#if QT_CONFIG(wheelevent) +#define X_QWheelEvent(X) X(QWheelEvent, ({}, {}, {}, {}, {}, {}, {}, {})) +#else +#define X_QWheelEvent(X) +#endif + +#if QT_CONFIG(tabletevent) +#define X_QTabletEvent(X) X(QTabletEvent, (QEvent::None, QPointingDevice::primaryPointingDevice(), {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {})) +#else +#define X_QTabletEvent(X) +#endif + +#if QT_CONFIG(gestures) +#define X_QNativeGestureEvent(X) X(QNativeGestureEvent, ({}, QPointingDevice::primaryPointingDevice(), 0, {}, {}, {}, {}, {})) +#else +#define X_QNativeGestureEvent(X) +#endif + +#if QT_CONFIG(whatsthis) +#define X_QWhatsThisClickedEvent(X) X(QWhatsThisClickedEvent, ({})) +#else +#define X_QWhatsThisClickedEvent(X) +#endif + +#if QT_CONFIG(action) +#define X_QActionEvent(X) X(QActionEvent, (0, nullptr)) +#else +#define X_QActionEvent(X) +#endif + +#if QT_CONFIG(shortcut) +#define X_QShortcutEvent(X) X(QShortcutEvent, ({}, 0)) +#else +#define X_QShortcutEvent(X) +#endif #define FOR_EACH_CORE_EVENT(X) \ /* qcoreevent.h */ \ @@ -15,7 +60,7 @@ X(QChildEvent, (QEvent::ChildAdded, nullptr)) \ X(QDynamicPropertyChangeEvent, ("size")) \ /* qfutureinterface_p.h */ \ - X(QFutureCallOutEvent, ()) \ + X_QFutureCallOutEvent(X) \ /* end */ #define FOR_EACH_GUI_EVENT(X) \ @@ -27,9 +72,9 @@ X(QEnterEvent, ({}, {}, {})) \ X(QMouseEvent, (QEvent::None, {}, {}, {}, {}, {}, {}, {}, QPointingDevice::primaryPointingDevice())) \ X(QHoverEvent, (QEvent::None, {}, {}, QPointF{})) \ - X(QWheelEvent, ({}, {}, {}, {}, {}, {}, {}, {})) \ - X(QTabletEvent, (QEvent::None, QPointingDevice::primaryPointingDevice(), {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {})) \ - X(QNativeGestureEvent, ({}, QPointingDevice::primaryPointingDevice(), 0, {}, {}, {}, {}, {})) \ + X_QWheelEvent(X) \ + X_QTabletEvent(X) \ + X_QNativeGestureEvent(X) \ X(QKeyEvent, (QEvent::None, 0, {})) \ X(QFocusEvent, (QEvent::None)) \ X(QPaintEvent, (QRect{0, 0, 100, 100})) \ @@ -50,11 +95,11 @@ X(QDragLeaveEvent, ()) \ X(QHelpEvent, ({}, {}, {})) \ X(QStatusTipEvent, ({})) \ - X(QWhatsThisClickedEvent, ({})) \ - X(QActionEvent, (0, nullptr)) \ + X_QWhatsThisClickedEvent(X) \ + X_QActionEvent(X) \ X(QFileOpenEvent, (QString{})) \ X(QToolBarChangeEvent, (false)) \ - X(QShortcutEvent, ({}, 0)) \ + X_QShortcutEvent(X) \ X(QWindowStateChangeEvent, ({})) \ X(QTouchEvent, (QEvent::None)) \ X(QScrollPrepareEvent, ({})) \ diff --git a/tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp index 526abd6ea3..fdb1b333ef 100644 --- a/tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_foreignwindow.cpp @@ -172,6 +172,9 @@ void tst_ForeignWindow::destroyWhenParentIsDestroyed() // Reparenting into a window will result in creating it QVERIFY(parentWindow.handle()); + parentWindow.show(); + QVERIFY(QTest::qWaitForWindowExposed(&parentWindow)); + // Destroying the parent window of the foreign window results // in destroying the foreign window as well, as the foreign // window no longer has a parent it can be embedded in. @@ -184,6 +187,9 @@ void tst_ForeignWindow::destroyWhenParentIsDestroyed() foreignWindow->create(); QVERIFY(foreignWindow->handle()); QTRY_COMPARE(nativeWindow.parentWinId(), parentWindow.winId()); + + parentWindow.show(); + QVERIFY(QTest::qWaitForWindowExposed(&parentWindow)); } #include <tst_foreignwindow.moc> diff --git a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp index 7505d463ed..48f792b9ed 100644 --- a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp +++ b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp @@ -71,6 +71,8 @@ private slots: void setWhitePoint(); void grayColorSpace(); void grayColorSpaceEffectivelySRgb(); + + void scaleAlphaValue(); }; tst_QColorSpace::tst_QColorSpace() @@ -1030,5 +1032,14 @@ void tst_QColorSpace::grayColorSpaceEffectivelySRgb() QCOMPARE(rgbImage1, rgbImage2); } +void tst_QColorSpace::scaleAlphaValue() +{ + QImage image(1, 1, QImage::Format_ARGB32); + image.setPixel(0, 0, qRgba(255, 255, 255, 125)); + image.setColorSpace(QColorSpace::SRgb); + image.convertToColorSpace(QColorSpace::SRgbLinear, QImage::Format_RGBA64); + QCOMPARE(reinterpret_cast<const QRgba64 *>(image.constBits())->alpha(), 257 * 125); +} + QTEST_MAIN(tst_QColorSpace) #include "tst_qcolorspace.moc" diff --git a/tests/auto/gui/painting/qregion/tst_qregion.cpp b/tests/auto/gui/painting/qregion/tst_qregion.cpp index 3d60e62fc1..934725844a 100644 --- a/tests/auto/gui/painting/qregion/tst_qregion.cpp +++ b/tests/auto/gui/painting/qregion/tst_qregion.cpp @@ -138,12 +138,15 @@ void tst_QRegion::rects() QRegion region(rect); QVERIFY(region.isEmpty()); QCOMPARE(region.begin(), region.end()); + QVERIFY(region.rects().isEmpty()); } { QRect rect(10, -20, 30, 40); QRegion region(rect); QCOMPARE(region.end(), region.begin() + 1); QCOMPARE(*region.begin(), rect); + QCOMPARE(region.rects().size(), 1); + QCOMPARE(region.rects()[0], rect); } { QRect r(QPoint(10, 10), QPoint(40, 40)); @@ -190,6 +193,7 @@ void tst_QRegion::setRects() QCOMPARE(region, QRegion()); QCOMPARE(region.begin(), region.end()); QVERIFY(!region.boundingRect().isValid()); + QVERIFY(region.rects().isEmpty()); } { QRegion region; @@ -197,12 +201,15 @@ void tst_QRegion::setRects() region.setRects(&rect, 1); QCOMPARE(region.begin(), region.end()); QVERIFY(!region.boundingRect().isValid()); + QVERIFY(region.rects().isEmpty()); } { QRegion region; QRect rect(10, -20, 30, 40); region.setRects(&rect, 1); QCOMPARE(region.end(), region.begin() + 1); + QCOMPARE(region.rects().size(), 1); + QCOMPARE(region.rects()[0], rect); QCOMPARE(*region.begin(), rect); } } @@ -316,10 +323,12 @@ void tst_QRegion::emptyPolygonRegion() QRegion r(pa); QTEST(r.isEmpty(), "isEmpty"); QTEST(int(std::distance(r.begin(), r.end())), "numRects"); - QList<QRect> rects; - std::copy(r.begin(), r.end(), std::back_inserter(rects)); + QList<QRect> rects{r.begin(), r.end()}; QTEST(int(rects.size()), "numRects"); QTEST(rects, "rects"); + const auto span = r.rects(); + rects.assign(span.begin(), span.end()); + QTEST(rects, "rects"); } @@ -862,6 +871,7 @@ void tst_QRegion::isEmpty() QCOMPARE(region, QRegion()); QCOMPARE(region.rectCount(), 0); QCOMPARE(region.boundingRect(), QRect()); + QVERIFY(region.rects().isEmpty()); } void tst_QRegion::regionFromPath() @@ -877,6 +887,10 @@ void tst_QRegion::regionFromPath() QCOMPARE(rgn.begin()[0], QRect(0, 0, 10, 10)); QCOMPARE(rgn.begin()[1], QRect(0, 100, 100, 1000)); + QCOMPARE(rgn.rects().size(), 2); + QCOMPARE(rgn.rects()[0], QRect(0, 0, 10, 10)); + QCOMPARE(rgn.rects()[1], QRect(0, 100, 100, 1000)); + QCOMPARE(rgn.boundingRect(), QRect(0, 0, 100, 1100)); } @@ -893,6 +907,12 @@ void tst_QRegion::regionFromPath() QCOMPARE(rgn.begin()[2], QRect(90, 10, 10, 80)); QCOMPARE(rgn.begin()[3], QRect(0, 90, 100, 10)); + QCOMPARE(rgn.rects().size(), 4); + QCOMPARE(rgn.rects()[0], QRect(0, 0, 100, 10)); + QCOMPARE(rgn.rects()[1], QRect(0, 10, 10, 80)); + QCOMPARE(rgn.rects()[2], QRect(90, 10, 10, 80)); + QCOMPARE(rgn.rects()[3], QRect(0, 90, 100, 10)); + QCOMPARE(rgn.boundingRect(), QRect(0, 0, 100, 100)); } } diff --git a/tests/auto/gui/text/CMakeLists.txt b/tests/auto/gui/text/CMakeLists.txt index bad13de7dc..30b35fb10a 100644 --- a/tests/auto/gui/text/CMakeLists.txt +++ b/tests/auto/gui/text/CMakeLists.txt @@ -11,7 +11,9 @@ add_subdirectory(qstatictext) add_subdirectory(qsyntaxhighlighter) add_subdirectory(qtextblock) add_subdirectory(qtextcursor) -add_subdirectory(qtextdocumentfragment) +if(QT_FEATURE_texthtmlparser) + add_subdirectory(qtextdocumentfragment) +endif() add_subdirectory(qtextdocumentlayout) add_subdirectory(qtextformat) add_subdirectory(qtextimagehandler) diff --git a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp index 2ae2ccda0a..3d0fab4603 100644 --- a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp +++ b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp @@ -22,9 +22,11 @@ public: private slots: void getSetCheck(); void maximumBlockCount(); +#ifndef QT_NO_TEXTHTMLPARSER void anchorAt(); void imageAt(); void formatAt(); +#endif }; tst_QAbstractTextDocumentLayout::tst_QAbstractTextDocumentLayout() @@ -119,6 +121,7 @@ void tst_QAbstractTextDocumentLayout::maximumBlockCount() QCOMPARE(layout.blockCount, 10); } +#ifndef QT_NO_TEXTHTMLPARSER void tst_QAbstractTextDocumentLayout::anchorAt() { QTextDocument doc; @@ -204,6 +207,7 @@ void tst_QAbstractTextDocumentLayout::formatAt() QVERIFY(!format.toCharFormat().fontItalic()); QVERIFY(!format.isImageFormat()); } +#endif QTEST_MAIN(tst_QAbstractTextDocumentLayout) #include "tst_qabstracttextdocumentlayout.moc" diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp index a438d7ebc8..203fe003a0 100644 --- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp +++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp @@ -56,6 +56,10 @@ private slots: void quotedAndUnquotedIdentifiers(); void whitespaceValues_data(); void whitespaceValues(); + void strokeLineCapValues_data(); + void strokeLineCapValues(); + void strokeLineJoinValues_data(); + void strokeLineJoinValues(); }; void tst_QCssParser::scanner_data() @@ -1759,6 +1763,57 @@ void tst_QCssParser::whitespaceValues() QCOMPARE(rule.declarations.at(0).d->values.first().toString(), value); } +void tst_QCssParser::strokeLineCapValues_data() +{ + QTest::addColumn<QString>("value"); + + QTest::newRow("flatcap") << "flatcap"; + QTest::newRow("roundcap") << "roundcap"; + QTest::newRow("squarecap") << "squarecap"; +} + +void tst_QCssParser::strokeLineCapValues() +{ + QFETCH(QString, value); + QCss::Parser parser(QString("foo { -qt-stroke-linecap: %1 }").arg(value)); + QCss::StyleSheet sheet; + QVERIFY(parser.parse(&sheet)); + + QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? + sheet.styleRules.at(0) : *sheet.nameIndex.begin(); + QCOMPARE(rule.declarations.size(), 1); + + QCOMPARE(rule.declarations.at(0).d->property, QLatin1String("-qt-stroke-linecap")); + QCOMPARE(rule.declarations.at(0).d->values.first().type, QCss::Value::KnownIdentifier); + QCOMPARE(rule.declarations.at(0).d->values.first().toString(), value); +} + +void tst_QCssParser::strokeLineJoinValues_data() +{ + QTest::addColumn<QString>("value"); + + QTest::newRow("beveljoin") << "beveljoin"; + QTest::newRow("miterjoin") << "miterjoin"; + QTest::newRow("roundjoin") << "roundjoin"; + QTest::newRow("svgmiterjoin") << "svgmiterjoin"; +} + +void tst_QCssParser::strokeLineJoinValues() +{ + QFETCH(QString, value); + QCss::Parser parser(QString("foo { -qt-stroke-linejoin: %1 }").arg(value)); + QCss::StyleSheet sheet; + QVERIFY(parser.parse(&sheet)); + + QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? + sheet.styleRules.at(0) : *sheet.nameIndex.begin(); + QCOMPARE(rule.declarations.size(), 1); + + QCOMPARE(rule.declarations.at(0).d->property, QLatin1String("-qt-stroke-linejoin")); + QCOMPARE(rule.declarations.at(0).d->values.first().type, QCss::Value::KnownIdentifier); + QCOMPARE(rule.declarations.at(0).d->values.first().toString(), value); +} + QTEST_MAIN(tst_QCssParser) #include "tst_qcssparser.moc" diff --git a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt index 18b96ded5d..0cb6e8d7c8 100644 --- a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt +++ b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt @@ -47,6 +47,8 @@ set(testdata_resource_files "../../../shared/resources/testfont_open.otf" "../../../shared/resources/testfont_variable.ttf" "LED_REAL.TTF" + "QtTestLimitedFont-Regular.ttf" + "QtTestFallbackFont-Regular.ttf" ) qt_internal_add_resource(tst_qfontdatabase "testdata" diff --git a/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf b/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf Binary files differnew file mode 100644 index 0000000000..ae21fec9a5 --- /dev/null +++ b/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf diff --git a/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf b/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf Binary files differnew file mode 100644 index 0000000000..2891f8aeff --- /dev/null +++ b/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index 849e7432d1..8733f64d97 100644 --- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp @@ -78,6 +78,8 @@ private: QString m_testFontCondensed; QString m_testFontItalic; QString m_testFontVariable; + QString m_limitedFont; + QString m_fallbackFont; }; tst_QFontDatabase::tst_QFontDatabase() @@ -91,11 +93,15 @@ void tst_QFontDatabase::initTestCase() m_testFontCondensed = QFINDTESTDATA("testfont_condensed.ttf"); m_testFontItalic = QFINDTESTDATA("testfont_italic.ttf"); m_testFontVariable = QFINDTESTDATA("testfont_variable.ttf"); + m_limitedFont = QFINDTESTDATA("QtTestLimitedFont-Regular.ttf"); + m_fallbackFont = QFINDTESTDATA("QtTestFallbackFont-Regular.ttf"); QVERIFY(!m_ledFont.isEmpty()); QVERIFY(!m_testFont.isEmpty()); QVERIFY(!m_testFontCondensed.isEmpty()); QVERIFY(!m_testFontItalic.isEmpty()); QVERIFY(!m_testFontVariable.isEmpty()); + QVERIFY(!m_limitedFont.isEmpty()); + QVERIFY(!m_fallbackFont.isEmpty()); } void tst_QFontDatabase::styles_data() @@ -391,8 +397,14 @@ void tst_QFontDatabase::condensedFontWidthNoFontMerging() void tst_QFontDatabase::condensedFontWidth() { - QFontDatabase::addApplicationFont(m_testFont); - QFontDatabase::addApplicationFont(m_testFontCondensed); + int testFontId = QFontDatabase::addApplicationFont(m_testFont); + int testFontCondensedId = QFontDatabase::addApplicationFont(m_testFontCondensed); + auto cleanup = qScopeGuard([&testFontId, &testFontCondensedId] { + if (testFontId >= 0) + QFontDatabase::removeApplicationFont(testFontId); + if (testFontCondensedId >= 0) + QFontDatabase::removeApplicationFont(testFontCondensedId); + }); QVERIFY(QFontDatabase::hasFamily("QtBidiTestFont")); if (!QFontDatabase::hasFamily("QtBidiTestFontCondensed")) @@ -410,10 +422,16 @@ void tst_QFontDatabase::condensedFontWidth() void tst_QFontDatabase::condensedFontMatching() { QFontDatabase::removeAllApplicationFonts(); - QFontDatabase::addApplicationFont(m_testFontCondensed); + int testFontCondensedId = QFontDatabase::addApplicationFont(m_testFontCondensed); if (!QFontDatabase::hasFamily("QtBidiTestFont")) QSKIP("This platform doesn't support preferred font family names (QTBUG-53478)"); - QFontDatabase::addApplicationFont(m_testFont); + int testFontId = QFontDatabase::addApplicationFont(m_testFont); + auto cleanup = qScopeGuard([&testFontId, &testFontCondensedId] { + if (testFontId >= 0) + QFontDatabase::removeApplicationFont(testFontId); + if (testFontCondensedId >= 0) + QFontDatabase::removeApplicationFont(testFontCondensedId); + }); // Test we correctly get the condensed font using different font matching methods: QFont tfcByStretch("QtBidiTestFont"); @@ -561,11 +579,17 @@ void tst_QFontDatabase::addApplicationFontFallback() { int ledId = -1; int id = -1; - auto cleanup = qScopeGuard([&id, &ledId] { + int limitedId = -1; + int fallbackId = -1; + auto cleanup = qScopeGuard([&id, &ledId, &limitedId, &fallbackId] { if (id >= 0) QFontDatabase::removeApplicationFont(id); if (ledId >= 0) QFontDatabase::removeApplicationFont(ledId); + if (limitedId >= 0) + QFontDatabase::removeApplicationFont(limitedId); + if (fallbackId >= 0) + QFontDatabase::removeApplicationFont(fallbackId); }); const QChar hebrewChar(0x05D0); // Hebrew 'aleph' @@ -633,6 +657,107 @@ void tst_QFontDatabase::addApplicationFontFallback() QCOMPARE(hebrewFontNow, defaultHebrewFont); } + limitedId = QFontDatabase::addApplicationFont(m_limitedFont); + QVERIFY(limitedId >= 0); + + fallbackId = QFontDatabase::addApplicationFont(m_fallbackFont); + QVERIFY(fallbackId >= 0); + + QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Common, u"QtTestFallbackFont"_s); + + // The fallback for Common will be used also for Latin, because Latin and Common are + // considered the same script by the font matching engine. + { + QTextLayout layout; + layout.setText(u"A'B,"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QVERIFY(glyphRuns.size() > 1); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s + || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s); + } + } + + // When the text only consists of common script characters, the fallback font will also be used. + { + QTextLayout layout; + layout.setText(u"',"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s + || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s); + } + } + + QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Common, u"QtTestFallbackFont"_s)); + QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Latin, u"QtTestFallbackFont"_s); + + // Latin fallback works just the same as Common fallback + { + QTextLayout layout; + layout.setText(u"A'B,"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s + || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s); + } + } + + // When the common character is placed next to a Cyrillic characters, it gets adapted to this, + // so the fallback font will not be selected, even if it supports the character in question + { + QTextLayout layout; + layout.setText(u"A'Б,"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() != u"QtTestFallbackFont"_s); + } + } + + QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Cyrillic, u"QtTestFallbackFont"_s); + + // When we set the fallback font for Cyrillic as well, it gets selected + { + QTextLayout layout; + layout.setText(u"A'Б,"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s + || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s); + } + } + + QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Cyrillic, u"QtTestFallbackFont"_s)); + QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Latin, u"QtTestFallbackFont"_s)); } QTEST_MAIN(tst_QFontDatabase) diff --git a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp index 6984cd1bd2..8f5cacae4a 100644 --- a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp +++ b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp @@ -39,7 +39,9 @@ private slots: void navigation7(); void navigation8(); void navigation9(); +#ifndef QT_NO_TEXTHTMLPARSER void navigation10(); +#endif void movePositionEndOfLine(); void insertBlock(); void insertWithBlockSeparator1(); @@ -431,6 +433,7 @@ void tst_QTextCursor::navigation9() QCOMPARE(cursor.position(), 15); } +#ifndef QT_NO_TEXTHTMLPARSER void tst_QTextCursor::navigation10() { doc->setHtml("<html><p>just a simple paragraph.</p>" @@ -542,6 +545,7 @@ void tst_QTextCursor::navigation10() QVERIFY(ok); QCOMPARE(cursor.position(), 1); // a } +#endif void tst_QTextCursor::insertBlock() { diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 335ee06e2f..600b45575f 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -4053,20 +4053,107 @@ void tst_QTextDocument::restoreStrokeFromHtml() QTextDocument document; QTextCursor textCursor(&document); QTextCharFormat textOutline; - textOutline.setTextOutline(QPen(Qt::red, 2.3)); - textCursor.insertText("Outlined text", textOutline); + + // Set stroke color and width + { + QPen pen(Qt::red, 2.3, Qt::SolidLine); + textOutline.setTextOutline(pen); + textCursor.insertText("Outlined text", textOutline); + } + + // Set Cap and Join styles + { + QPen pen; + pen.setCapStyle(Qt::FlatCap); + pen.setJoinStyle(Qt::RoundJoin); + textOutline.setTextOutline(pen); + textCursor.insertBlock(); + textCursor.insertText("Cap and Join Style", textOutline); + } + + // Set Miter limit + { + QPen pen; + pen.setJoinStyle(Qt::MiterJoin); + pen.setMiterLimit(4); + textOutline.setTextOutline(pen); + textCursor.insertBlock(); + textCursor.insertText("Miter Limit", textOutline); + } + + // Set Dash Array and Dash Offset + { + QPen pen; + QList<qreal> pattern; + const int dash = 2; + const int gap = 4; + pattern << dash << gap << dash << gap << dash << gap; + pen.setDashPattern(pattern); + pen.setDashOffset(3); + textOutline.setTextOutline(pen); + textCursor.insertBlock(); + textCursor.insertText("Dash Pattern", textOutline); + } + { QTextDocument otherDocument; otherDocument.setHtml(document.toHtml()); - QCOMPARE(otherDocument.blockCount(), 1); - QTextBlock block = otherDocument.firstBlock(); - QTextFragment fragment = block.begin().fragment(); - QCOMPARE(fragment.text(), QStringLiteral("Outlined text")); - QTextCharFormat fmt = fragment.charFormat(); - QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline)); - QPen pen = fmt.textOutline(); - QCOMPARE(pen.color(), QColor(Qt::red)); - QCOMPARE(pen.widthF(), 2.3); + QCOMPARE(otherDocument.blockCount(), document.blockCount()); + + QTextBlock block; + QTextFragment fragment; + QTextCharFormat fmt; + QPen pen; + + { + block = otherDocument.findBlockByNumber(0); + fragment = block.begin().fragment(); + QCOMPARE(fragment.text(), QStringLiteral("Outlined text")); + fmt = fragment.charFormat(); + QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline)); + pen = fmt.textOutline(); + QCOMPARE(pen.color(), QColor(Qt::red)); + QCOMPARE(pen.widthF(), 2.3); + } + + { + block = otherDocument.findBlockByNumber(1); + qDebug() << block.text(); + fragment = block.begin().fragment(); + QCOMPARE(fragment.text(), QStringLiteral("Cap and Join Style")); + fmt = fragment.charFormat(); + QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline)); + pen = fmt.textOutline(); + QCOMPARE(pen.capStyle(), Qt::FlatCap); + QCOMPARE(pen.joinStyle(), Qt::RoundJoin); + } + + { + block = otherDocument.findBlockByNumber(2); + fragment = block.begin().fragment(); + QCOMPARE(fragment.text(), QStringLiteral("Miter Limit")); + fmt = fragment.charFormat(); + QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline)); + pen = fmt.textOutline(); + QCOMPARE(pen.joinStyle(), Qt::MiterJoin); + QCOMPARE(pen.miterLimit(), 4); + } + + + { + block = otherDocument.findBlockByNumber(3); + fragment = block.begin().fragment(); + QCOMPARE(fragment.text(), QStringLiteral("Dash Pattern")); + fmt = fragment.charFormat(); + QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline)); + pen = fmt.textOutline(); + QCOMPARE(pen.dashOffset(), 3); + QList<qreal> pattern; + const int dash = 2; + const int gap = 4; + pattern << dash << gap << dash << gap << dash << gap; + QCOMPARE(pen.dashPattern(), pattern); + } } } diff --git a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp index 2a279682ca..2ae31849bf 100644 --- a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp +++ b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp @@ -24,18 +24,24 @@ private slots: void cleanupTestCase(); void defaultPageSizeHandling(); void idealWidth(); +#ifndef QT_NO_TEXTHTMLPARSER void lineSeparatorFollowingTable(); +#endif #ifndef QT_NO_WIDGETS void wrapAtWordBoundaryOrAnywhere(); #endif void inlineImage(); +#ifndef QT_NO_TEXTHTMLPARSER void clippedTableCell(); +#endif void floatingTablePageBreak(); void imageAtRightAlignedTab(); void blockVisibility(); +#ifndef QT_NO_TEXTHTMLPARSER void testHitTest(); void largeImage(); +#endif private: QTextDocument *doc; @@ -99,6 +105,7 @@ void tst_QTextDocumentLayout::idealWidth() QVERIFY(doc->idealWidth() > 0); } +#ifndef QT_NO_TEXTHTMLPARSER // none of the QTextLine items in the document should intersect with the margin rect void tst_QTextDocumentLayout::lineSeparatorFollowingTable() { @@ -145,6 +152,7 @@ void tst_QTextDocumentLayout::lineSeparatorFollowingTable() } } } +#endif #ifndef QT_NO_WIDGETS void tst_QTextDocumentLayout::wrapAtWordBoundaryOrAnywhere() @@ -184,6 +192,7 @@ void tst_QTextDocumentLayout::inlineImage() QCOMPARE(doc->pageCount(), 1); } +#ifndef QT_NO_TEXTHTMLPARSER void tst_QTextDocumentLayout::clippedTableCell() { const char *html = @@ -224,6 +233,7 @@ void tst_QTextDocumentLayout::clippedTableCell() expected.save("expected.png"); QCOMPARE(img, expected); } +#endif void tst_QTextDocumentLayout::floatingTablePageBreak() { @@ -323,6 +333,7 @@ void tst_QTextDocumentLayout::blockVisibility() QCOMPARE(doc->size(), halfSize); } +#ifndef QT_NO_TEXTHTMLPARSER void tst_QTextDocumentLayout::largeImage() { auto img = QImage(400, 500, QImage::Format_ARGB32_Premultiplied); @@ -416,6 +427,7 @@ void tst_QTextDocumentLayout::testHitTest() QVERIFY(positionY - topMargin <= y); } } +#endif QTEST_MAIN(tst_QTextDocumentLayout) #include "tst_qtextdocumentlayout.moc" diff --git a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp index d20a2f1ea5..6c6145561d 100644 --- a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp +++ b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp @@ -7,7 +7,9 @@ #include <qcoreapplication.h> #include <qdebug.h> +#if QT_CONFIG(settings) #include <qsettings.h> +#endif #include <qtextformat.h> #include <private/qtextformat_p.h> #include <qtextdocument.h> @@ -27,7 +29,9 @@ Q_OBJECT private slots: void getSetCheck(); void defaultAlignment(); +#if QT_CONFIG(settings) void testQTextCharFormat() const; +#endif void testUnderlinePropertyPrecedence(); void toFormat(); void resolveFont(); @@ -47,6 +51,7 @@ private slots: #endif }; +#if QT_CONFIG(settings) /*! \internal This (used to) trigger a crash in: @@ -61,6 +66,7 @@ void tst_QTextFormat::testQTextCharFormat() const settings.value("test", test); } +#endif // Testing get/set functions void tst_QTextFormat::getSetCheck() diff --git a/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp b/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp index 5311aa6f2b..0048623d0e 100644 --- a/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp +++ b/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp @@ -6,6 +6,10 @@ #include <QPainter> #include <private/qtextimagehandler_p.h> +using namespace Qt::StringLiterals; + +// #define DEBUG_WRITE_HTML + class tst_QTextImageHandler : public QObject { Q_OBJECT @@ -18,7 +22,11 @@ private slots: void cleanup(); void cleanupTestCase(); void loadAtNImages_data(); +#ifndef QT_NO_TEXTHTMLPARSER void loadAtNImages(); + void maxWidth_data(); + void maxWidth(); +#endif }; tst_QTextImageHandler::tst_QTextImageHandler() @@ -47,6 +55,7 @@ void tst_QTextImageHandler::loadAtNImages_data() QTest::addRow("qrc_url") << "qrc:/data/image.png"; } +#ifndef QT_NO_TEXTHTMLPARSER void tst_QTextImageHandler::loadAtNImages() { QFETCH(QString, imageFile); @@ -58,7 +67,7 @@ void tst_QTextImageHandler::loadAtNImages() const auto it = std::find_if(formats.begin(), formats.end(), [](const auto &format){ return format.objectType() == QTextFormat::ImageObject; }); - QVERIFY(it != formats.end()); + QCOMPARE_NE(it, formats.end()); const QTextImageFormat format = (*it).toImageFormat(); QTextImageHandler handler; @@ -75,5 +84,64 @@ void tst_QTextImageHandler::loadAtNImages() } } +void tst_QTextImageHandler::maxWidth_data() +{ + QTest::addColumn<QString>("imageFile"); + QTest::addColumn<QSizeF>("pageSize"); + QTest::addColumn<QTextLength>("maxWidth"); + QTest::addColumn<QSizeF>("expectedSize"); + + QTest::addRow("constrained-percentage") << QFINDTESTDATA("data/image.png") << QSizeF(16, 16) << QTextLength(QTextLength::PercentageLength, 100) << QSizeF(12, 12); + QTest::addRow("not-constrained-percentage") << QFINDTESTDATA("data/image.png") << QSizeF(200, 200) << QTextLength(QTextLength::PercentageLength, 100) << QSizeF(16, 16); + QTest::addRow("constrained-fixed") << QFINDTESTDATA("data/image.png") << QSizeF(16, 16) << QTextLength(QTextLength::FixedLength, 5) << QSizeF(5, 5); + QTest::addRow("not-constrained-fixed") << QFINDTESTDATA("data/image.png") << QSizeF(200, 200) << QTextLength(QTextLength::FixedLength, 5) << QSizeF(5, 5); + QTest::addRow("not-constrained-default") << QFINDTESTDATA("data/image.png") << QSizeF(200, 200) << QTextLength(QTextLength::VariableLength, 5) << QSizeF(16, 16); +} + +void tst_QTextImageHandler::maxWidth() +{ + QFETCH(QString, imageFile); + QFETCH(QSizeF, pageSize); + QFETCH(QTextLength, maxWidth); + QFETCH(QSizeF, expectedSize); + + QTextDocument doc; + doc.setPageSize(pageSize); + doc.setDocumentMargin(2); + QTextCursor c(&doc); + QString style; + if (maxWidth.type() == QTextLength::PercentageLength) + style = " style=\"max-width:"_L1 + QString::number(maxWidth.rawValue()) + "%;\""_L1; + else if (maxWidth.type() == QTextLength::FixedLength) + style = " style=\"max-width:"_L1 + QString::number(maxWidth.rawValue()) + "px;\""_L1; + const QString html = "<img src=\"" + imageFile + u'\"' + style + "\">"; + c.insertHtml(html); + +#ifdef DEBUG_WRITE_HTML + { + QFile out("/tmp/" + QLatin1String(QTest::currentDataTag()) + ".html"); + out.open(QFile::WriteOnly); + out.write(html.toLatin1()); + out.close(); + } + { + QFile out("/tmp/" + QLatin1String(QTest::currentDataTag()) + "_rewrite.html"); + out.open(QFile::WriteOnly); + out.write(doc.toHtml().toLatin1()); + out.close(); + } +#endif + const auto formats = doc.allFormats(); + const auto it = std::find_if(formats.begin(), formats.end(), [](const auto &format){ + return format.objectType() == QTextFormat::ImageObject; + }); + QCOMPARE_NE(it, formats.end()); + const QTextImageFormat format = (*it).toImageFormat(); + QTextImageHandler handler; + + QCOMPARE(handler.intrinsicSize(&doc, 0, format), expectedSize); +} +#endif + QTEST_MAIN(tst_QTextImageHandler) #include "tst_qtextimagehandler.moc" diff --git a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp b/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp index 28eae93f6a..10d44f6d70 100644 --- a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp +++ b/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp @@ -140,6 +140,7 @@ void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport() QCOMPARE(list->count(), 28); +#ifndef QT_NO_TEXTHTMLPARSER QString htmlExport = doc->toHtml(); QTextDocument importDoc; importDoc.setHtml(htmlExport); @@ -152,6 +153,7 @@ void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport() QCOMPARE(importCursor.currentList()->itemNumber(importCursor.block()), 27); QCOMPARE(importCursor.currentList()->itemText(importCursor.block()), QLatin1String("\"ab#")); QCOMPARE(importCursor.currentList()->format().indent(), 10); +#endif } void tst_QTextList::autoNumberingRTL() diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/example.md b/tests/auto/gui/text/qtextmarkdownwriter/data/example.md index 15b30598e6..8fdad207ae 100644 --- a/tests/auto/gui/text/qtextmarkdownwriter/data/example.md +++ b/tests/auto/gui/text/qtextmarkdownwriter/data/example.md @@ -40,7 +40,7 @@ numerals in the same list structure: 1. Introduction 2. Qt Tools 1) Qt Assistant - 2) Qt Designer + 2) Qt Widgets Designer 1. Form Editor 2. Component Architecture 3) Qt Linguist @@ -70,7 +70,7 @@ column spans, text formatting within cells, and size constraints for columns. |-------------|------------------------------------|---------------------------|-------------------------| |9:00 - 11:00 |Introduction to Qt ||| |11:00 - 13:00|Using qmake |Object-oriented Programming|Layouts in Qt | -|13:00 - 15:00|Qt Designer Tutorial |Extreme Programming |Writing Custom Styles | +|13:00 - 15:00|Qt Widgets Designer Tutorial |Extreme Programming |Writing Custom Styles | |15:00 - 17:00|Qt Linguist and Internationalization|Test-Driven Development | | *Try adding text to the cells in the table and experiment with the alignment of diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp index d0e1e1cd74..a7e319ef62 100644 --- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp +++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp @@ -1236,6 +1236,7 @@ void tst_QTextTable::checkBorderAttributes() QFETCH(QBrush, leftBorderBrush); QFETCH(QBrush, rightBorderBrush); +#ifndef QT_NO_TEXTHTMLPARSER QTextDocument doc; doc.setHtml(html); QTextCursor cursor(doc.firstBlock()); @@ -1261,6 +1262,7 @@ void tst_QTextTable::checkBorderAttributes() QCOMPARE(cellFormat.brushProperty(QTextFormat::TableCellRightBorderBrush), rightBorderBrush); } } +#endif } void tst_QTextTable::checkTableBorderAttributes_data() @@ -1317,6 +1319,7 @@ void tst_QTextTable::checkTableBorderAttributes() QFETCH(QTextFrameFormat::BorderStyle, tableBorderStyle); QFETCH(QBrush, tableBorderBrush); +#ifndef QT_NO_TEXTHTMLPARSER QTextDocument doc; doc.setHtml(html); QTextCursor cursor(doc.firstBlock()); @@ -1327,6 +1330,7 @@ void tst_QTextTable::checkTableBorderAttributes() QCOMPARE(currentTable->format().border(), tableBorderWidth); QCOMPARE(currentTable->format().borderStyle(), tableBorderStyle); QCOMPARE(currentTable->format().borderBrush(), tableBorderBrush); +#endif } #ifndef QT_NO_WIDGETS @@ -1385,6 +1389,7 @@ void tst_QTextTable::columnWidthWithImage() QFETCH(QString, rightHtml); QFETCH(QSize, imageSize); +#ifndef QT_NO_TEXTHTMLPARSER QTextDocument doc; doc.setHtml(tableTemplate.arg(leftHtml).arg(rightHtml)); QTextEdit textEdit; @@ -1404,6 +1409,7 @@ void tst_QTextTable::columnWidthWithImage() const QRectF rightRect = currentTable->document()->documentLayout()->blockBoundingRect(block); QCOMPARE(leftRect.size().toSize(), imageSize); QVERIFY(rightRect.left() > leftRect.right()); +#endif } #endif diff --git a/tests/auto/gui/util/CMakeLists.txt b/tests/auto/gui/util/CMakeLists.txt index 830a9ff2f0..1efdf85b97 100644 --- a/tests/auto/gui/util/CMakeLists.txt +++ b/tests/auto/gui/util/CMakeLists.txt @@ -1,10 +1,16 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -add_subdirectory(qdesktopservices) +if(QT_FEATURE_desktopservices) + add_subdirectory(qdesktopservices) +endif() add_subdirectory(qdoublevalidator) add_subdirectory(qintvalidator) add_subdirectory(qregularexpressionvalidator) add_subdirectory(qtexturefilereader) -add_subdirectory(qundogroup) -add_subdirectory(qundostack) +if(QT_FEATURE_undogroup) + add_subdirectory(qundogroup) +endif() +if(QT_FEATURE_undocommand) + add_subdirectory(qundostack) +endif() diff --git a/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp b/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp index e08b299209..e75626eda7 100644 --- a/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp +++ b/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp @@ -42,10 +42,6 @@ public slots: } }; -#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) -# define CAN_IMPLICITLY_UNSET -#endif - void tst_qdesktopservices::handlers() { MyUrlHandler fooHandler; @@ -53,12 +49,10 @@ void tst_qdesktopservices::handlers() QDesktopServices::setUrlHandler(QString("foo"), &fooHandler, "handle"); QDesktopServices::setUrlHandler(QString("bar"), &barHandler, "handle"); -#ifndef CAN_IMPLICITLY_UNSET const auto unsetHandlers = qScopeGuard([] { QDesktopServices::unsetUrlHandler(u"bar"_s); QDesktopServices::unsetUrlHandler(u"foo"_s); }); -#endif QUrl fooUrl("foo://blub/meh"); QUrl barUrl("bar://hmm/hmmmm"); @@ -68,15 +62,6 @@ void tst_qdesktopservices::handlers() QCOMPARE(fooHandler.lastHandledUrl.toString(), fooUrl.toString()); QCOMPARE(barHandler.lastHandledUrl.toString(), barUrl.toString()); - -#ifdef CAN_IMPLICITLY_UNSET - for (int i = 0; i < 2; ++i) - QTest::ignoreMessage(QtWarningMsg, - "Please call QDesktopServices::unsetUrlHandler() before destroying a " - "registered URL handler object.\n" - "Support for destroying a registered URL handler object is deprecated, " - "and will be removed in Qt 6.6."); -#endif } QTEST_MAIN(tst_qdesktopservices) diff --git a/tests/auto/network/access/CMakeLists.txt b/tests/auto/network/access/CMakeLists.txt index 13703cf89c..d1130f832e 100644 --- a/tests/auto/network/access/CMakeLists.txt +++ b/tests/auto/network/access/CMakeLists.txt @@ -2,16 +2,21 @@ # SPDX-License-Identifier: BSD-3-Clause add_subdirectory(qhttpheaders) -add_subdirectory(qnetworkdiskcache) +if(QT_FEATURE_networkdiskcache) + add_subdirectory(qnetworkdiskcache) +endif() add_subdirectory(qnetworkcookiejar) add_subdirectory(qnetworkaccessmanager) add_subdirectory(qnetworkcookie) add_subdirectory(qnetworkrequest) -add_subdirectory(qnetworkrequestfactory) add_subdirectory(qnetworkreply) add_subdirectory(qnetworkcachemetadata) add_subdirectory(qabstractnetworkcache) -add_subdirectory(qrestaccessmanager) +if(QT_FEATURE_http) + add_subdirectory(qnetworkreply_local) + add_subdirectory(qnetworkrequestfactory) + add_subdirectory(qrestaccessmanager) +endif() if(QT_FEATURE_private_tests) add_subdirectory(qhttp2connection) add_subdirectory(qhttpheaderparser) diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index d9e82330b2..396a6f2fda 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -1277,7 +1277,7 @@ void tst_Http2::unsupportedAuthenticateChallenge() bool authenticationRequested = false; connect(manager.get(), &QNetworkAccessManager::authenticationRequired, reply.get(), - [&](QNetworkReply *, QAuthenticator *auth) { + [&](QNetworkReply *, QAuthenticator *) { authenticationRequested = true; }); diff --git a/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index 9bdef9bbe1..95f067a66e 100644 --- a/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -50,6 +50,7 @@ private: }; +#if QT_CONFIG(networkdiskcache) class NetworkDiskCache : public QNetworkDiskCache { Q_OBJECT @@ -72,6 +73,7 @@ public: QTemporaryDir tempDir; bool gotData; }; +#endif tst_QAbstractNetworkCache::tst_QAbstractNetworkCache() @@ -254,10 +256,12 @@ void tst_QAbstractNetworkCache::runTest() QFETCH(bool, fetchFromCache); QNetworkAccessManager manager; +#if QT_CONFIG(networkdiskcache) NetworkDiskCache *diskCache = new NetworkDiskCache(&manager); QVERIFY2(diskCache->tempDir.isValid(), qPrintable(diskCache->tempDir.errorString())); manager.setCache(diskCache); QCOMPARE(diskCache->gotData, false); +#endif QUrl realUrl = url.contains("://") ? url : TESTFILE + url; QNetworkRequest request(realUrl); @@ -266,7 +270,9 @@ void tst_QAbstractNetworkCache::runTest() QNetworkReply *reply = manager.get(request); QSignalSpy downloaded1(reply, SIGNAL(finished())); QTRY_COMPARE(downloaded1.size(), 1); +#if QT_CONFIG(networkdiskcache) QCOMPARE(diskCache->gotData, false); +#endif QByteArray goodData = reply->readAll(); request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, cacheLoadControl); @@ -293,7 +299,9 @@ void tst_QAbstractNetworkCache::runTest() std::sort(rawHeaderList.begin(), rawHeaderList.end()); std::sort(rawHeaderList2.begin(), rawHeaderList2.end()); } +#if QT_CONFIG(networkdiskcache) QCOMPARE(diskCache->gotData, fetchFromCache); +#endif } void tst_QAbstractNetworkCache::checkSynchronous() @@ -305,10 +313,12 @@ void tst_QAbstractNetworkCache::checkSynchronous() QFETCH(bool, fetchFromCache); QNetworkAccessManager manager; +#if QT_CONFIG(networkdiskcache) NetworkDiskCache *diskCache = new NetworkDiskCache(&manager); QVERIFY2(diskCache->tempDir.isValid(), qPrintable(diskCache->tempDir.errorString())); manager.setCache(diskCache); QCOMPARE(diskCache->gotData, false); +#endif QUrl realUrl = url.contains("://") ? url : TESTFILE + url; QNetworkRequest request(realUrl); @@ -320,7 +330,9 @@ void tst_QAbstractNetworkCache::checkSynchronous() // prime the cache QNetworkReply *reply = manager.get(request); QVERIFY(reply->isFinished()); // synchronous +#if QT_CONFIG(networkdiskcache) QCOMPARE(diskCache->gotData, false); +#endif QByteArray goodData = reply->readAll(); request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, cacheLoadControl); @@ -348,15 +360,19 @@ void tst_QAbstractNetworkCache::checkSynchronous() std::sort(rawHeaderList.begin(), rawHeaderList.end()); std::sort(rawHeaderList2.begin(), rawHeaderList2.end()); } +#if QT_CONFIG(networkdiskcache) QCOMPARE(diskCache->gotData, fetchFromCache); +#endif } void tst_QAbstractNetworkCache::deleteCache() { QNetworkAccessManager manager; +#if QT_CONFIG(networkdiskcache) NetworkDiskCache *diskCache = new NetworkDiskCache(&manager); QVERIFY2(diskCache->tempDir.isValid(), qPrintable(diskCache->tempDir.errorString())); manager.setCache(diskCache); +#endif QString url = "httpcachetest_cachecontrol.cgi?max-age=1000"; QNetworkRequest request(QUrl(TESTFILE + url)); diff --git a/tests/auto/network/access/qnetworkcachemetadata/tst_qnetworkcachemetadata.cpp b/tests/auto/network/access/qnetworkcachemetadata/tst_qnetworkcachemetadata.cpp index f811943dea..d49195efc6 100644 --- a/tests/auto/network/access/qnetworkcachemetadata/tst_qnetworkcachemetadata.cpp +++ b/tests/auto/network/access/qnetworkcachemetadata/tst_qnetworkcachemetadata.cpp @@ -29,6 +29,8 @@ private slots: void operatorEqualEqual(); void rawHeaders_data(); void rawHeaders(); + void headers_data(); + void headers(); void saveToDisk_data(); void saveToDisk(); void url_data(); @@ -114,6 +116,12 @@ void tst_QNetworkCacheMetaData::isValid_data() QNetworkCacheMetaData data5; data5.setSaveToDisk(false); QTest::newRow("valid-5") << data5 << true; + + QNetworkCacheMetaData data6; + QHttpHeaders httpHeaders; + httpHeaders.append("name", "value"); + data6.setHeaders(httpHeaders); + QTest::newRow("valid-6") << data6 << true; } // public bool isValid() const @@ -153,6 +161,9 @@ void tst_QNetworkCacheMetaData::operatorEqual_data() QNetworkCacheMetaData::RawHeaderList headers; headers.append(QNetworkCacheMetaData::RawHeader("foo", "Bar")); data.setRawHeaders(headers); + QHttpHeaders httpHeaders; + httpHeaders.append("name", "value"); + data.setHeaders(httpHeaders); data.setLastModified(QDateTime::currentDateTime()); data.setExpirationDate(QDateTime::currentDateTime()); data.setSaveToDisk(false); @@ -212,6 +223,18 @@ void tst_QNetworkCacheMetaData::operatorEqualEqual_data() QTest::newRow("valid-5-4") << data5 << data2 << false; QTest::newRow("valid-5-5") << data5 << data3 << false; QTest::newRow("valid-5-6") << data5 << data4 << false; + + QNetworkCacheMetaData data6; + QHttpHeaders httpHeaders; + httpHeaders.append("name", "value"); + data6.setHeaders(httpHeaders); + QTest::newRow("valid-6-1") << data6 << QNetworkCacheMetaData() << false; + QTest::newRow("valid-6-2") << data6 << data6 << true; + QTest::newRow("valid-6-3") << data6 << data1 << false; + QTest::newRow("valid-6-4") << data6 << data2 << false; + QTest::newRow("valid-6-5") << data6 << data3 << false; + QTest::newRow("valid-6-6") << data6 << data4 << false; + QTest::newRow("valid-6-7") << data6 << data5 << false; } // public bool operator==(QNetworkCacheMetaData const& other) const @@ -231,7 +254,11 @@ void tst_QNetworkCacheMetaData::rawHeaders_data() QTest::newRow("null") << QNetworkCacheMetaData::RawHeaderList(); QNetworkCacheMetaData::RawHeaderList headers; headers.append(QNetworkCacheMetaData::RawHeader("foo", "Bar")); - QTest::newRow("valie") << headers; + QTest::newRow("valid") << headers; + headers.append(QNetworkCacheMetaData::RawHeader("n1", "V1, v2, v3")); + headers.append(QNetworkCacheMetaData::RawHeader("n2", "V2")); + headers.append(QNetworkCacheMetaData::RawHeader("set-cookie", "v1\nV2\nV3")); + QTest::newRow("valid-2") << headers; } // public QNetworkCacheMetaData::RawHeaderList rawHeaders() const @@ -245,6 +272,25 @@ void tst_QNetworkCacheMetaData::rawHeaders() QCOMPARE(data.rawHeaders(), rawHeaders); } +void tst_QNetworkCacheMetaData::headers_data() +{ + QTest::addColumn<QHttpHeaders>("httpHeaders"); + QTest::newRow("null") << QHttpHeaders(); + QHttpHeaders headers; + headers.append("foo", "Bar"); + QTest::newRow("valid") << headers; +} + +void tst_QNetworkCacheMetaData::headers() +{ + QFETCH(QHttpHeaders, httpHeaders); + + SubQNetworkCacheMetaData data; + + data.setHeaders(httpHeaders); + QCOMPARE(data.headers().toListOfPairs(), httpHeaders.toListOfPairs()); +} + void tst_QNetworkCacheMetaData::saveToDisk_data() { QTest::addColumn<bool>("saveToDisk"); @@ -289,6 +335,9 @@ void tst_QNetworkCacheMetaData::stream() QNetworkCacheMetaData::RawHeaderList headers; headers.append(QNetworkCacheMetaData::RawHeader("foo", "Bar")); data.setRawHeaders(headers); + QHttpHeaders httpHeaders; + httpHeaders.append("name", "value"); + data.setHeaders(httpHeaders); data.setLastModified(QDateTime::currentDateTime()); data.setExpirationDate(QDateTime::currentDateTime()); data.setSaveToDisk(false); diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index a4a05b18f5..a26d2c809b 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -35,8 +35,10 @@ #include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpSocket> +#if QT_CONFIG(localserver) #include <QtNetwork/QLocalSocket> #include <QtNetwork/QLocalServer> +#endif #include <QtNetwork/QHostInfo> #include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkRequest> @@ -44,14 +46,18 @@ #include <QtNetwork/QAbstractNetworkCache> #include <QtNetwork/qauthenticator.h> #include <QtNetwork/qnetworkaccessmanager.h> +#if QT_CONFIG(networkdiskcache) #include <QtNetwork/qnetworkdiskcache.h> +#endif #include <QtNetwork/qnetworkrequest.h> #include <QtNetwork/qnetworkreply.h> -#include <QtNetwork/QHttp1Configuration> #include <QtNetwork/qnetworkcookie.h> #include <QtNetwork/QNetworkCookieJar> +#if QT_CONFIG(http) #include <QtNetwork/QHttpPart> #include <QtNetwork/QHttpMultiPart> +#include <QtNetwork/QHttp1Configuration> +#endif #include <QtNetwork/QNetworkProxyQuery> #if QT_CONFIG(ssl) #include <QtNetwork/qsslerror.h> @@ -129,14 +135,14 @@ class tst_QNetworkReply: public QObject static QString tempRedirectReplyStr() { QString s = "HTTP/1.1 307 Temporary Redirect\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: %1\r\n" "\r\n"; return s; } static QString movedReplyStr() { QString s = "HTTP/1.1 301 Moved Permanently\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: %1\r\n" "\r\n"; return s; @@ -144,7 +150,7 @@ class tst_QNetworkReply: public QObject static QString foundReplyStr() { QString s = "HTTP/1.1 302 Found\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: %1\r\n" "\r\n"; return s; @@ -152,7 +158,7 @@ class tst_QNetworkReply: public QObject static QString permRedirectReplyStr() { QString s = "HTTP/1.1 308 Permanent Redirect\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: %1\r\n" "\r\n"; return s; @@ -194,8 +200,10 @@ public: ~tst_QNetworkReply(); QString runSimpleRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QNetworkReplyPtr &reply, const QByteArray &data = QByteArray()); +#if QT_CONFIG(http) QString runMultipartRequest(const QNetworkRequest &request, QNetworkReplyPtr &reply, QHttpMultiPart *multiPart, const QByteArray &verb); +#endif QString runCustomRequest(const QNetworkRequest &request, QNetworkReplyPtr &reply, const QByteArray &verb, QIODevice *data); @@ -261,17 +269,21 @@ private Q_SLOTS: void putToHttp(); void putToHttpSynchronous_data(); void putToHttpSynchronous(); +#if QT_CONFIG(http) void putToHttpMultipart_data(); void putToHttpMultipart(); +#endif void putWithoutBody(); void putWithoutBody_data(); void postToHttp_data(); void postToHttp(); void postToHttpSynchronous_data(); void postToHttpSynchronous(); +#if QT_CONFIG(http) void postToHttpMultipart_data(); void postToHttpMultipart(); void multipartSkipIndices(); // QTBUG-32534 +#endif void postWithoutBody_data(); void postWithoutBody(); #if QT_CONFIG(ssl) @@ -342,8 +354,10 @@ private Q_SLOTS: void ioPutToFileFromFile(); void ioPutToFileFromSocket_data(); void ioPutToFileFromSocket(); +#if QT_CONFIG(localserver) void ioPutToFileFromLocalSocket_data(); void ioPutToFileFromLocalSocket(); +#endif void ioPutToFileFromProcess_data(); void ioPutToFileFromProcess(); void ioPutToFtpFromFile_data(); @@ -449,7 +463,9 @@ private Q_SLOTS: void ioGetFromHttpWithoutContentLength(); void ioGetFromHttpBrokenChunkedEncoding(); +#if QT_CONFIG(http) void qtbug12908compressedHttpReply(); +#endif void compressedHttpReplyBrokenGzip(); void getFromUnreachableIp(); @@ -468,7 +484,9 @@ private Q_SLOTS: void qtbug27161httpHeaderMayBeDamaged_data(); void qtbug27161httpHeaderMayBeDamaged(); +#if QT_CONFIG(networkdiskcache) void qtbug28035browserDoesNotLoadQtProjectOrgCorrectly(); +#endif void qtbug45581WrongReplyStatusCode(); @@ -484,8 +502,10 @@ private Q_SLOTS: void varyingCacheExpiry_data(); void varyingCacheExpiry(); +#if QT_CONFIG(http) void amountOfHttp1ConnectionsQtbug25280_data(); void amountOfHttp1ConnectionsQtbug25280(); +#endif void dontInsertPartialContentIntoTheCache(); @@ -521,12 +541,16 @@ private Q_SLOTS: void ioHttpCookiesDuringRedirect(); void ioHttpRedirect_data(); void ioHttpRedirect(); +#if QT_CONFIG(networkdiskcache) void ioHttpRedirectWithCache(); +#endif void ioHttpRedirectFromLocalToRemote(); void ioHttpRedirectPostPut_data(); void ioHttpRedirectPostPut(); +#if QT_CONFIG(http) void ioHttpRedirectMultipartPost_data(); void ioHttpRedirectMultipartPost(); +#endif void ioHttpRedirectDelete(); void ioHttpRedirectCustom(); void ioHttpRedirectWithUploadDevice_data(); @@ -540,16 +564,20 @@ private Q_SLOTS: void autoDeleteReplies_data(); void autoDeleteReplies(); +#if QT_CONFIG(http) || defined (Q_OS_WASM) void requestWithTimeout_data(); void requestWithTimeout(); +#endif void moreActivitySignals_data(); void moreActivitySignals(); void contentEncoding_data(); void contentEncoding(); +#if QT_CONFIG(http) void contentEncodingBigPayload_data(); void contentEncodingBigPayload(); +#endif void cacheWithContentEncoding_data(); void cacheWithContentEncoding(); void downloadProgressWithContentEncoding_data(); @@ -560,8 +588,13 @@ private Q_SLOTS: void notFoundWithCompression_data(); void notFoundWithCompression(); +#if QT_CONFIG(http) + void qhttpPartDebug_data(); + void qhttpPartDebug(); + void qtbug68821proxyError_data(); void qtbug68821proxyError(); +#endif void abortAndError(); @@ -1437,6 +1470,7 @@ void tst_QNetworkReply::storeSslConfiguration() } #endif +#if QT_CONFIG(http) QString tst_QNetworkReply::runMultipartRequest(const QNetworkRequest &request, QNetworkReplyPtr &reply, QHttpMultiPart *multiPart, @@ -1468,6 +1502,7 @@ QString tst_QNetworkReply::runMultipartRequest(const QNetworkRequest &request, } return QString(); } +#endif QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, @@ -2753,7 +2788,7 @@ void tst_QNetworkReply::postToHttp() QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi"); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply; QFETCH(QByteArray, data); @@ -2780,7 +2815,7 @@ void tst_QNetworkReply::postToHttpSynchronous() QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi"); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); request.setAttribute( QNetworkRequest::SynchronousRequestAttribute, @@ -2802,6 +2837,7 @@ void tst_QNetworkReply::postToHttpSynchronous() QCOMPARE(uploadedData, md5sum.toHex()); } +#if QT_CONFIG(http) void tst_QNetworkReply::postToHttpMultipart_data() { QTest::addColumn<QUrl>("url"); @@ -2841,8 +2877,8 @@ void tst_QNetworkReply::postToHttpMultipart_data() QHttpMultiPart *customMultiPart = new QHttpMultiPart; customMultiPart->append(textPart); - expectedData = "header: Content-Type, value: 'text/plain'\n" - "header: Content-Disposition, value: 'form-data; name=\"text\"'\n" + expectedData = "header: content-type, value: 'text/plain'\n" + "header: content-disposition, value: 'form-data; name=\"text\"'\n" "content: 7 bytes\n" "\n"; QTest::newRow("text-custom") << url << customMultiPart << expectedData << QByteArray("custom"); @@ -2878,18 +2914,18 @@ void tst_QNetworkReply::postToHttpMultipart_data() multiPart3->append(textPart); multiPart3->append(textPart2); multiPart3->append(textPart3); - expectedData = "header: Content-Type, value: 'text/plain'\n" - "header: Content-Disposition, value: 'form-data; name=\"text\"'\n" + expectedData = "header: content-type, value: 'text/plain'\n" + "header: content-disposition, value: 'form-data; name=\"text\"'\n" "content: 7 bytes\n" "\n" - "header: Content-Type, value: 'text/plain'\n" - "header: myRawHeader, value: 'myValue'\n" - "header: Content-Disposition, value: 'form-data; name=\"text2\"'\n" + "header: content-type, value: 'text/plain'\n" + "header: myrawheader, value: 'myValue'\n" + "header: content-disposition, value: 'form-data; name=\"text2\"'\n" "content: some more bytes\n" "\n" - "header: Content-Type, value: 'text/plain'\n" - "header: Content-Disposition, value: 'form-data; name=\"text3\"'\n" - "header: Content-Location, value: 'http://my.test.location.tld'\n" + "header: content-type, value: 'text/plain'\n" + "header: content-disposition, value: 'form-data; name=\"text3\"'\n" + "header: content-location, value: 'http://my.test.location.tld'\n" "content: even more bytes\n\n"; QTest::newRow("text-text-text") << url << multiPart3 << expectedData << QByteArray("alternative"); @@ -3111,6 +3147,7 @@ void tst_QNetworkReply::multipartSkipIndices() // QTBUG-32534 } multiPart->deleteLater(); } +#endif void tst_QNetworkReply::postWithoutBody_data() { @@ -3153,6 +3190,7 @@ void tst_QNetworkReply::postWithoutBody() QCOMPARE(server.foundContentLength, client_data); } +#if QT_CONFIG(http) void tst_QNetworkReply::putToHttpMultipart_data() { postToHttpMultipart_data(); @@ -3197,6 +3235,7 @@ void tst_QNetworkReply::putToHttpMultipart() // QEXPECT_FAIL("nested", "the server does not understand nested multipart messages", Continue); // see above QCOMPARE(replyData, expectedReplyData); } +#endif #if QT_CONFIG(ssl) void tst_QNetworkReply::putToHttps_data() @@ -3308,7 +3347,7 @@ void tst_QNetworkReply::postToHttps() QSslConfiguration conf; conf.setCaCertificates(certs); request.setSslConfiguration(conf); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply; QFETCH(QByteArray, data); @@ -3342,7 +3381,7 @@ void tst_QNetworkReply::postToHttpsSynchronous() QSslConfiguration conf; conf.setCaCertificates(certs); request.setSslConfiguration(conf); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); request.setAttribute( QNetworkRequest::SynchronousRequestAttribute, @@ -3364,6 +3403,7 @@ void tst_QNetworkReply::postToHttpsSynchronous() QCOMPARE(uploadedData, md5sum.toHex()); } +#if QT_CONFIG(http) void tst_QNetworkReply::postToHttpsMultipart_data() { if (isSecureTransport) @@ -3414,7 +3454,7 @@ void tst_QNetworkReply::postToHttpsMultipart() expectedReplyData.prepend("content type: multipart/" + contentType + "; boundary=\"" + multiPart->boundary() + "\"\n"); QCOMPARE(replyData, expectedReplyData); } - +#endif #endif // QT_CONFIG(ssl) void tst_QNetworkReply::deleteFromHttp_data() @@ -4458,7 +4498,7 @@ void tst_QNetworkReply::ioGetFromHttpWithCache_data() QByteArray reply200 = "HTTP/1.0 200\r\n" "Connection: keep-alive\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "Cache-control: no-store\r\n" "Content-length: 8\r\n" "\r\n" @@ -4593,7 +4633,7 @@ void tst_QNetworkReply::ioGetFromHttpWithCache_data() QByteArray reply206 = "HTTP/1.0 206\r\n" "Connection: keep-alive\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "Cache-control: no-cache\r\n" "Content-Range: bytes 2-6/8\r\n" "Content-length: 4\r\n" @@ -4996,6 +5036,7 @@ void tst_QNetworkReply::ioPutToFileFromSocket() QCOMPARE(contents, data); } +#if QT_CONFIG(localserver) void tst_QNetworkReply::ioPutToFileFromLocalSocket_data() { putToFile_data(); @@ -5039,6 +5080,7 @@ void tst_QNetworkReply::ioPutToFileFromLocalSocket() QByteArray contents = file.readAll(); QCOMPARE(contents, data); } +#endif // Currently no stdin/out supported for Windows CE. void tst_QNetworkReply::ioPutToFileFromProcess_data() @@ -5202,7 +5244,7 @@ void tst_QNetworkReply::ioPostToHttpFromFile() QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi"); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply(manager.post(request, &sourceFile)); @@ -5279,7 +5321,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocket() socketpair.endPoints[0]->write(data); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); manager.setProxy(proxy); QNetworkReplyPtr reply(manager.post(request, socketpair.endPoints[1])); @@ -5353,7 +5395,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous() QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi"); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); request.setAttribute( QNetworkRequest::SynchronousRequestAttribute, true); @@ -5384,7 +5426,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileToEnd() QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply(manager.post(request, &sourceFile)); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), @@ -5410,7 +5452,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileFiveBytes() QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); // only send 5 bytes request.setHeader(QNetworkRequest::ContentLengthHeader, 5); QVERIFY(request.header(QNetworkRequest::ContentLengthHeader).isValid()); @@ -5441,7 +5483,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfQBufferFiveBytes() QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply(manager.post(request, &uploadBuffer)); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), @@ -5469,7 +5511,7 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag() QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); // disallow buffering request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true); request.setHeader(QNetworkRequest::ContentLengthHeader, data.size()); @@ -5554,7 +5596,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() QUrl url = QUrl(QLatin1String("https://127.0.0.1:") + QString::number(server.serverPort()) + QLatin1Char('/')); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply(manager.post(request, sourceFile)); QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); @@ -5708,7 +5750,7 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() // create the request QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply(manager.post(request, &sourceFile)); QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -5776,7 +5818,7 @@ void tst_QNetworkReply::emitAllUploadProgressSignals() QUrl url = QUrl(QLatin1String("http://127.0.0.1:") + QString::number(server.serverPort()) + QLatin1Char('/')); QNetworkRequest normalRequest(url); - normalRequest.setRawHeader("Content-Type", "application/octet-stream"); + normalRequest.setRawHeader("content-type", "application/octet-stream"); QNetworkRequest catchAllSignalsRequest(normalRequest); catchAllSignalsRequest.setAttribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute, true); @@ -5827,7 +5869,7 @@ void tst_QNetworkReply::ioPostToHttpEmptyUploadProgress() // create the request QUrl url = QUrl(QLatin1String("http://127.0.0.1:") + QString::number(server.serverPort()) + QLatin1Char('/')); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply(manager.post(request, &buffer)); QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -5873,7 +5915,11 @@ void tst_QNetworkReply::lastModifiedHeaderForFile() QVERIFY2(waitForFinish(reply) == Success, msgWaitForFinished(reply)); QDateTime header = reply->header(QNetworkRequest::LastModifiedHeader).toDateTime(); - QCOMPARE(header, fileInfo.lastModified()); + QDateTime expected = fileInfo.lastModified(); + // remove msecs, HTTP dates don't support it + expected = expected.addMSecs(-expected.time().msec()); + + QCOMPARE(header.toUTC(), expected.toUTC()); } void tst_QNetworkReply::lastModifiedHeaderForHttp() @@ -6179,7 +6225,7 @@ void tst_QNetworkReply::receiveCookiesFromHttp() QByteArray data = cookieString.toLatin1() + '\n'; QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/set-cookie.cgi"); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); QNetworkReplyPtr reply; RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::PostOperation, request, reply, data)); @@ -6207,7 +6253,7 @@ void tst_QNetworkReply::receiveCookiesFromHttpSynchronous() QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/set-cookie.cgi"); QNetworkRequest request(url); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); request.setAttribute( QNetworkRequest::SynchronousRequestAttribute, true); @@ -7485,6 +7531,7 @@ void tst_QNetworkReply::ioGetFromHttpBrokenChunkedEncoding() QCOMPARE(reply->error(), QNetworkReply::NoError); } +#if QT_CONFIG(http) // TODO: // Prepare a gzip that has one chunk that expands to the size mentioned in the bugreport. // Then have a custom HTTP server that waits after this chunk so the returning gets @@ -7513,6 +7560,7 @@ void tst_QNetworkReply::qtbug12908compressedHttpReply() QCOMPARE(reply->size(), qint64(16384)); QCOMPARE(reply->readAll(), QByteArray(16384, '\0')); } +#endif void tst_QNetworkReply::compressedHttpReplyBrokenGzip() { @@ -8039,11 +8087,12 @@ void tst_QNetworkReply::qtbug27161httpHeaderMayBeDamaged(){ QCOMPARE(reply->readAll(), QByteArray("ABC")); } +#if QT_CONFIG(networkdiskcache) void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() { QByteArray getReply = "HTTP/1.1 200\r\n" "Connection: keep-alive\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "Cache-control: max-age = 6000\r\n" "\r\n" "GET"; @@ -8051,7 +8100,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() { QByteArray postReply = "HTTP/1.1 200\r\n" "Connection: keep-alive\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "Cache-control: max-age = 6000\r\n" "Content-length: 4\r\n" "\r\n" @@ -8060,7 +8109,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() { QByteArray putReply = "HTTP/1.1 201\r\n" "Connection: keep-alive\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "Cache-control: max-age = 6000\r\n" "\r\n"; @@ -8098,7 +8147,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() { server.clearHeaderParserState(); server.setDataToTransmit(postReply); - request.setRawHeader("Content-Type", "text/plain"); + request.setRawHeader("content-type", "text/plain"); reply.reset(manager.post(request, postData)); QVERIFY2(waitForFinish(reply) == Success, msgWaitForFinished(reply)); @@ -8163,6 +8212,7 @@ void tst_QNetworkReply::qtbug28035browserDoesNotLoadQtProjectOrgCorrectly() { QCOMPARE(reply->readAll(), QByteArray("GET")); QCOMPARE(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), true); } +#endif void tst_QNetworkReply::qtbug45581WrongReplyStatusCode() { @@ -8548,6 +8598,7 @@ public: } }; +#if QT_CONFIG(http) void tst_QNetworkReply::amountOfHttp1ConnectionsQtbug25280_data() { QTest::addColumn<int>("amount"); @@ -8588,13 +8639,14 @@ void tst_QNetworkReply::amountOfHttp1ConnectionsQtbug25280() } QCOMPARE(server.receivedSockets.size(), amount); } +#endif void tst_QNetworkReply::dontInsertPartialContentIntoTheCache() { QByteArray reply206 = "HTTP/1.0 206\r\n" "Connection: keep-alive\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "Cache-control: no-cache\r\n" "Content-Range: bytes 2-6/8\r\n" "Content-length: 4\r\n" @@ -8651,7 +8703,7 @@ void tst_QNetworkReply::synchronousAuthenticationCache() "WWW-Authenticate: Basic realm=\"QNetworkAccessManager Test Realm\"\r\n" "Content-Length: 4\r\n" "Connection: close\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "\r\n" "auth"; QRegularExpression rx("authorization: Basic ([^\r\n]*)\r\n"); @@ -8660,7 +8712,7 @@ void tst_QNetworkReply::synchronousAuthenticationCache() if (QByteArray::fromBase64(match.captured(1).toLatin1()) == "login:password") { dataToTransmit = "HTTP/1.0 200 OK\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "Content-Length: 2\r\n" "\r\n" "OK"; @@ -9030,7 +9082,7 @@ void tst_QNetworkReply::ioHttpRedirectErrors_data() QTest::addColumn<QNetworkReply::NetworkError>("error"); QString tempRedirectReply = QString("HTTP/1.1 307 Temporary Redirect\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: http://localhost:%1\r\n\r\n"); QTest::newRow("too-many-redirects") << "http://localhost" << tempRedirectReply << QNetworkReply::TooManyRedirectsError; @@ -9338,7 +9390,7 @@ void tst_QNetworkReply::ioHttpRedirect() targetUrl.setPort(target.serverPort()); QString redirectReply = QStringLiteral("HTTP/1.1 %1\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: %2\r\n" "\r\n").arg(status, targetUrl.toString()); MiniHttpServer redirectServer(redirectReply.toLatin1(), false); @@ -9356,6 +9408,7 @@ void tst_QNetworkReply::ioHttpRedirect() QVERIFY(validateRedirectedResponseHeaders(reply)); } +#if QT_CONFIG(networkdiskcache) /* Test that, if we load a redirect from cache, we don't treat the request to the destination of the redirect as a redirect. @@ -9366,7 +9419,7 @@ void tst_QNetworkReply::ioHttpRedirectWithCache() { // Disallow caching the result so that the second request must also send the request QByteArray http200ResponseNoCache = "HTTP/1.1 200 OK\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "Cache-Control: no-cache\r\n" "\r\nHello"; @@ -9376,7 +9429,7 @@ void tst_QNetworkReply::ioHttpRedirectWithCache() // A cache-able redirect reply QString redirectReply = QStringLiteral("HTTP/1.1 308\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: %1\r\n" "Cache-Control: max-age=3600\r\n" "\r\nYou're being redirected").arg(targetUrl.toString()); @@ -9413,6 +9466,7 @@ void tst_QNetworkReply::ioHttpRedirectWithCache() QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); QVERIFY(validateRedirectedResponseHeaders(reply)); } +#endif void tst_QNetworkReply::ioHttpRedirectFromLocalToRemote() { @@ -9488,7 +9542,7 @@ void tst_QNetworkReply::ioHttpRedirectPostPut() QUrl targetUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi"); QString redirectReply = QStringLiteral("HTTP/1.1 %1\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: %2\r\n" "\r\n").arg(status, targetUrl.toString()); MiniHttpServer redirectServer(redirectReply.toLatin1()); @@ -9507,6 +9561,7 @@ void tst_QNetworkReply::ioHttpRedirectPostPut() QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex()); } +#if QT_CONFIG(http) void tst_QNetworkReply::ioHttpRedirectMultipartPost_data() { postToHttpMultipart_data(); @@ -9567,6 +9622,7 @@ void tst_QNetworkReply::ioHttpRedirectMultipartPost() // QEXPECT_FAIL("nested", "the server does not understand nested multipart messages", Continue); // see above QCOMPARE(replyData, expectedReplyData); } +#endif void tst_QNetworkReply::ioHttpRedirectDelete() { @@ -9642,7 +9698,7 @@ void tst_QNetworkReply::ioHttpRedirectWithUploadDevice() targetUrl.setPort(target.serverPort()); QString redirectReply = QStringLiteral("HTTP/1.1 %1\r\n" - "Content-Type: text/plain\r\n" + "content-type: text/plain\r\n" "location: %2\r\n" "\r\n").arg(status, targetUrl.toString()); MiniHttpServer redirectServer(redirectReply.toLatin1()); @@ -9676,8 +9732,8 @@ void tst_QNetworkReply::ioHttpRedirectWithUploadDevice() // we shouldn't send Content-Length with not content (esp. for GET) QVERIFY2(!target.receivedData.contains("Content-Length"), "Target server should not have received a Content-Length header"); - QVERIFY2(!target.receivedData.contains("Content-Type"), - "Target server should not have received a Content-Type header"); + QVERIFY2(!target.receivedData.contains("content-type"), + "Target server should not have received a content-type header"); } } @@ -10008,6 +10064,7 @@ void tst_QNetworkReply::autoDeleteReplies() } } +#if QT_CONFIG(http) || defined (Q_OS_WASM) void tst_QNetworkReply::requestWithTimeout_data() { using Operation = QNetworkAccessManager::Operation; @@ -10045,7 +10102,7 @@ void tst_QNetworkReply::requestWithTimeout() server.stopTransfer = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - request.setRawHeader("Content-Type", "application/octet-stream"); + request.setRawHeader("content-type", "application/octet-stream"); if (reqInt > 0) request.setTransferTimeout(reqInt); if (reqChrono > 0ms) @@ -10067,6 +10124,7 @@ void tst_QNetworkReply::requestWithTimeout() QCOMPARE(spy.size(), 1); QCOMPARE(reply->error(), QNetworkReply::OperationCanceledError); } +#endif void tst_QNetworkReply::moreActivitySignals_data() { @@ -10097,7 +10155,7 @@ void tst_QNetworkReply::moreActivitySignals() QNetworkRequest request(url); QNetworkReplyPtr reply; if (postWithData) { - request.setRawHeader("Content-Type", "text/plain"); + request.setRawHeader("content-type", "text/plain"); reply.reset(manager.post(request, "Hello, world!")); } else { reply.reset(manager.get(request)); @@ -10118,7 +10176,7 @@ void tst_QNetworkReply::moreActivitySignals() // Second request will not send socketStartedConnecting because of keep-alive, so don't check it. QNetworkReplyPtr secondreply; if (postWithData) { - request.setRawHeader("Content-Type", "text/plain"); + request.setRawHeader("content-type", "text/plain"); secondreply.reset(manager.post(request, "Hello, world!")); } else { secondreply.reset(manager.get(request)); @@ -10239,6 +10297,7 @@ void tst_QNetworkReply::contentEncoding() } } +#if QT_CONFIG(http) void tst_QNetworkReply::contentEncodingBigPayload_data() { QTest::addColumn<QByteArray>("encoding"); @@ -10297,6 +10356,7 @@ void tst_QNetworkReply::contentEncodingBigPayload() } QCOMPARE(total, expectedSize); } +#endif void tst_QNetworkReply::cacheWithContentEncoding_data() { @@ -10479,6 +10539,60 @@ void tst_QNetworkReply::notFoundWithCompression() QCOMPARE(reply->readAll(), expected); } +#if QT_CONFIG(http) +void tst_QNetworkReply::qhttpPartDebug_data() +{ + QTest::addColumn<QByteArray>("header_data"); + QTest::addColumn<QByteArray>("raw_header_data"); + QTest::addColumn<QList<QByteArray>>("expected_header_values"); + QTest::addColumn<bool>("overwrite"); + + QTest::newRow("header-data-set") << "form-data; name=\"prompt\""_ba << ""_ba + << (QList<QByteArray>() << "form-data; name=\"prompt\""_ba) << false; + QTest::newRow("raw-header-data-set") << ""_ba << "thisismykeyherebutnotreally"_ba + << (QList<QByteArray>() << "thisismykeyherebutnotreally"_ba) << false; + QTest::newRow("both-set") << "form-data; name=\"prompt\""_ba + << "thisismykeyherebutnotreally"_ba + << (QList<QByteArray>() + << "form-data; name=\"prompt\""_ba + << "thisismykeyherebutnotreally"_ba) << false; + QTest::newRow("overwrite") << "form-data; name=\"prompt\""_ba + << "thisismykeyherebutnotreally"_ba + << (QList<QByteArray>() + << "thisismykeyherebutnotreally"_ba + << "thisismykeyherebutnotreally"_ba) << true; +} + +void tst_QNetworkReply::qhttpPartDebug() +{ + QFETCH(const QByteArray, header_data); + QFETCH(const QByteArray, raw_header_data); + QFETCH(const QList<QByteArray>, expected_header_values); + QFETCH(bool, overwrite); + + QHttpPart httpPart; + + if (!header_data.isEmpty()) + httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, header_data); + + if (!raw_header_data.isEmpty()) + httpPart.setRawHeader("Authorization", raw_header_data); + + if (overwrite) + httpPart.setRawHeader("Content-Disposition", raw_header_data); + + QByteArray msg; + { + QBuffer buf(&msg); + QVERIFY(buf.open(QIODevice::WriteOnly)); + QDebug debug(&buf); + debug << httpPart; + } + + for (const auto &value : expected_header_values) + QVERIFY2(msg.contains(value), "Missing header value: " + value); +} + void tst_QNetworkReply::qtbug68821proxyError_data() { QTest::addColumn<QString>("proxyHost"); @@ -10527,6 +10641,7 @@ void tst_QNetworkReply::qtbug68821proxyError() QCOMPARE(spy.count(), 1); QCOMPARE(spy.at(0).at(0), error); } +#endif void tst_QNetworkReply::abortAndError() { diff --git a/tests/auto/network/access/qnetworkreply_local/CMakeLists.txt b/tests/auto/network/access/qnetworkreply_local/CMakeLists.txt new file mode 100644 index 0000000000..13a60afb13 --- /dev/null +++ b/tests/auto/network/access/qnetworkreply_local/CMakeLists.txt @@ -0,0 +1,9 @@ +qt_internal_add_test(tst_qnetworkreply_local + SOURCES + minihttpserver.h + tst_qnetworkreply_local.cpp + LIBRARIES + Qt::CorePrivate + Qt::NetworkPrivate + BUNDLE_ANDROID_OPENSSL_LIBS +) diff --git a/tests/auto/network/access/qnetworkreply_local/minihttpserver.h b/tests/auto/network/access/qnetworkreply_local/minihttpserver.h new file mode 100644 index 0000000000..eb0697a6f8 --- /dev/null +++ b/tests/auto/network/access/qnetworkreply_local/minihttpserver.h @@ -0,0 +1,246 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef MINIHTTPSERVER_H +#define MINIHTTPSERVER_H + +#include <QtNetwork/qtnetworkglobal.h> + +#include <QtNetwork/qtcpserver.h> +#include <QtNetwork/qtcpsocket.h> +#include <QtNetwork/qlocalsocket.h> +#if QT_CONFIG(ssl) +# include <QtNetwork/qsslsocket.h> +#endif +#if QT_CONFIG(localserver) +# include <QtNetwork/qlocalserver.h> +#endif + +#include <QtCore/qpointer.h> +#include <QtCore/qhash.h> + +#include <utility> + +static inline QByteArray default200Response() +{ + return QByteArrayLiteral("HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 12\r\n" + "\r\n" + "Hello World!"); +} +class MiniHttpServerV2 : public QObject +{ + Q_OBJECT + +public: + struct State; + +#if QT_CONFIG(localserver) + void bind(QLocalServer *server) + { + Q_ASSERT(!localServer); + localServer = server; + connect(server, &QLocalServer::newConnection, this, + &MiniHttpServerV2::incomingLocalConnection); + } +#endif + + void bind(QTcpServer *server) + { + Q_ASSERT(!tcpServer); + tcpServer = server; + connect(server, &QTcpServer::pendingConnectionAvailable, this, + &MiniHttpServerV2::incomingConnection); + } + + void setDataToTransmit(QByteArray data) { dataToTransmit = std::move(data); } + + void clearServerState() + { + auto copy = std::exchange(clientStates, {}); + for (auto [socket, _] : copy.asKeyValueRange()) { + if (auto *tcpSocket = qobject_cast<QTcpSocket *>(socket)) + tcpSocket->disconnectFromHost(); + else if (auto *localSocket = qobject_cast<QLocalSocket *>(socket)) + localSocket->disconnectFromServer(); + else + Q_UNREACHABLE_RETURN(); + socket->deleteLater(); + } + } + + bool hasPendingConnections() const + { + return +#if QT_CONFIG(localserver) + (localServer && localServer->hasPendingConnections()) || +#endif + (tcpServer && tcpServer->hasPendingConnections()); + } + + QString addressForScheme(QStringView scheme) const + { + using namespace Qt::StringLiterals; + if (scheme.startsWith("unix"_L1) || scheme.startsWith("local"_L1)) { +#if QT_CONFIG(localserver) + if (localServer) + return localServer->serverName(); +#endif + } else if (scheme == "http"_L1) { + if (tcpServer) + return "%1:%2"_L1.arg(tcpServer->serverAddress().toString(), + QString::number(tcpServer->serverPort())); + } + return {}; + } + + QList<State> peerStates() const { return clientStates.values(); } + +protected: +#if QT_CONFIG(localserver) + void incomingLocalConnection() + { + auto *socket = localServer->nextPendingConnection(); + connectSocketSignals(socket); + } +#endif + + void incomingConnection() + { + auto *socket = tcpServer->nextPendingConnection(); + connectSocketSignals(socket); + } + + void reply(QIODevice *socket) + { + Q_ASSERT(socket); + if (dataToTransmit.isEmpty()) { + emit socket->bytesWritten(0); // emulate having written the data + return; + } + if (!stopTransfer) + socket->write(dataToTransmit); + } + +private: + void connectSocketSignals(QIODevice *socket) + { + connect(socket, &QIODevice::readyRead, this, [this, socket]() { readyReadSlot(socket); }); + connect(socket, &QIODevice::bytesWritten, this, + [this, socket]() { bytesWrittenSlot(socket); }); +#if QT_CONFIG(ssl) + if (auto *sslSocket = qobject_cast<QSslSocket *>(socket)) + connect(sslSocket, &QSslSocket::sslErrors, this, &MiniHttpServerV2::slotSslErrors); +#endif + + if (auto *tcpSocket = qobject_cast<QTcpSocket *>(socket)) { + connect(tcpSocket, &QAbstractSocket::errorOccurred, this, &MiniHttpServerV2::slotError); + } else if (auto *localSocket = qobject_cast<QLocalSocket *>(socket)) { + connect(localSocket, &QLocalSocket::errorOccurred, this, + [this](QLocalSocket::LocalSocketError error) { + slotError(QAbstractSocket::SocketError(error)); + }); + } else { + Q_UNREACHABLE_RETURN(); + } + } + + void parseContentLength(State &st, QByteArrayView header) + { + qsizetype index = header.indexOf("\r\ncontent-length:"); + if (index == -1) + return; + st.foundContentLength = true; + + index += sizeof("\r\ncontent-length:") - 1; + const auto *end = std::find(header.cbegin() + index, header.cend(), '\r'); + QByteArrayView num = header.mid(index, std::distance(header.cbegin() + index, end)); + bool ok = false; + st.contentLength = num.toInt(&ok); + if (!ok) + st.contentLength = -1; + } + +private slots: +#if QT_CONFIG(ssl) + void slotSslErrors(const QList<QSslError> &errors) + { + QTcpSocket *currentClient = qobject_cast<QTcpSocket *>(sender()); + Q_ASSERT(currentClient); + qDebug() << "slotSslErrors" << currentClient->errorString() << errors; + } +#endif + void slotError(QAbstractSocket::SocketError err) + { + QTcpSocket *currentClient = qobject_cast<QTcpSocket *>(sender()); + Q_ASSERT(currentClient); + qDebug() << "slotError" << err << currentClient->errorString(); + } + +public slots: + + void readyReadSlot(QIODevice *socket) + { + if (stopTransfer) + return; + State &st = clientStates[socket]; + st.receivedData += socket->readAll(); + const qsizetype doubleEndlPos = st.receivedData.indexOf("\r\n\r\n"); + + if (doubleEndlPos != -1) { + const qsizetype endOfHeader = doubleEndlPos + 4; + st.contentRead = st.receivedData.size() - endOfHeader; + + if (!st.checkedContentLength) { + parseContentLength(st, QByteArrayView(st.receivedData).first(endOfHeader)); + st.checkedContentLength = true; + } + + if (st.contentRead < st.contentLength) + return; + + // multiple requests incoming, remove the bytes of the current one + if (multiple) + st.receivedData.remove(0, endOfHeader); + + reply(socket); + } + } + + void bytesWrittenSlot(QIODevice *socket) + { + // Disconnect and delete in next cycle (else Windows clients will fail with + // RemoteHostClosedError). + if (doClose && socket->bytesToWrite() == 0) { + disconnect(socket, nullptr, this, nullptr); + socket->deleteLater(); + } + } + +private: + QByteArray dataToTransmit = default200Response(); + + QTcpServer *tcpServer = nullptr; +#if QT_CONFIG(localserver) + QLocalServer *localServer = nullptr; +#endif + + QHash<QIODevice *, State> clientStates; + +public: + struct State + { + QByteArray receivedData; + qsizetype contentLength = 0; + qsizetype contentRead = 0; + bool checkedContentLength = false; + bool foundContentLength = false; + }; + + bool doClose = true; + bool multiple = false; + bool stopTransfer = false; +}; + +#endif // MINIHTTPSERVER_H diff --git a/tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp b/tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp new file mode 100644 index 0000000000..6d78c81593 --- /dev/null +++ b/tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp @@ -0,0 +1,177 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QtNetwork/qtnetworkglobal.h> + +#include <QtTest/qtest.h> + +#include <QtNetwork/qnetworkreply.h> +#include <QtNetwork/qnetworkaccessmanager.h> + +#include "minihttpserver.h" + +using namespace Qt::StringLiterals; + +/* + The tests here are meant to be self-contained, using servers in the same + process if needed. This enables externals to more easily run the tests too. +*/ +class tst_QNetworkReply_local : public QObject +{ + Q_OBJECT +private slots: + void initTestCase_data(); + + void get(); + void post(); + +#if QT_CONFIG(localserver) + void fullServerName_data(); + void fullServerName(); +#endif +}; + +void tst_QNetworkReply_local::initTestCase_data() +{ + QTest::addColumn<QString>("scheme"); + + QTest::newRow("http") << "http"; +#if QT_CONFIG(localserver) + QTest::newRow("unix") << "unix+http"; + QTest::newRow("local") << "local+http"; // equivalent to unix, but test that it works +#endif +} + +static std::unique_ptr<MiniHttpServerV2> getServerForCurrentScheme() +{ + auto server = std::make_unique<MiniHttpServerV2>(); + QFETCH_GLOBAL(QString, scheme); + if (scheme.startsWith("unix"_L1) || scheme.startsWith("local"_L1)) { +#if QT_CONFIG(localserver) + QLocalServer *localServer = new QLocalServer(server.get()); + localServer->listen(u"qt_networkreply_test_"_s + % QLatin1StringView(QTest::currentTestFunction()) + % QString::number(QCoreApplication::applicationPid())); + server->bind(localServer); +#endif + } else if (scheme == "http") { + QTcpServer *tcpServer = new QTcpServer(server.get()); + tcpServer->listen(QHostAddress::LocalHost, 0); + server->bind(tcpServer); + } + return server; +} + +static QUrl getUrlForCurrentScheme(MiniHttpServerV2 *server) +{ + QFETCH_GLOBAL(QString, scheme); + const QString address = server->addressForScheme(scheme); + const QString urlString = QLatin1StringView("%1://%2").arg(scheme, address); + return { urlString }; +} + +void tst_QNetworkReply_local::get() +{ + std::unique_ptr<MiniHttpServerV2> server = getServerForCurrentScheme(); + const QUrl url = getUrlForCurrentScheme(server.get()); + + QNetworkAccessManager manager; + std::unique_ptr<QNetworkReply> reply(manager.get(QNetworkRequest(url))); + + const bool res = QTest::qWaitFor([reply = reply.get()] { return reply->isFinished(); }); + QVERIFY(res); + + QCOMPARE(reply->readAll(), QByteArray("Hello World!")); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); +} + +void tst_QNetworkReply_local::post() +{ + std::unique_ptr<MiniHttpServerV2> server = getServerForCurrentScheme(); + const QUrl url = getUrlForCurrentScheme(server.get()); + + QNetworkAccessManager manager; + const QByteArray payload = "Hello from the other side!"_ba; + QNetworkRequest req(url); + req.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain"); + std::unique_ptr<QNetworkReply> reply(manager.post(req, payload)); + + const bool res = QTest::qWaitFor([reply = reply.get()] { return reply->isFinished(); }); + QVERIFY(res); + + QCOMPARE(reply->readAll(), QByteArray("Hello World!")); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + + auto states = server->peerStates(); + QCOMPARE(states.size(), 1); + + const auto &firstRequest = states.at(0); + + QVERIFY(firstRequest.checkedContentLength); + QCOMPARE(firstRequest.contentLength, payload.size()); + QCOMPARE_GT(firstRequest.receivedData.size(), payload.size() + 4); + QCOMPARE(firstRequest.receivedData.last(payload.size() + 4), "\r\n\r\n" + payload); +} + +#if QT_CONFIG(localserver) +void tst_QNetworkReply_local::fullServerName_data() +{ +#if defined(Q_OS_ANDROID) || defined(QT_PLATFORM_UIKIT) + QSKIP("While partially supported, the test as-is doesn't make sense on this platform."); +#else + + QTest::addColumn<QString>("hostAndPath"); + + QTest::newRow("dummy-host") << u"://irrelevant/test"_s; + QTest::newRow("no-host") << u":///test"_s; +#endif +} + +void tst_QNetworkReply_local::fullServerName() +{ + QFETCH_GLOBAL(QString, scheme); + if (!scheme.startsWith("unix"_L1) && !scheme.startsWith("local"_L1)) + return; // only relevant for local sockets + + MiniHttpServerV2 server; + QLocalServer localServer; + + QString path; +#ifdef Q_OS_WIN + path = uR"(\\.\pipe\qt_networkreply_test_fullServerName)"_s + % QString::number(QCoreApplication::applicationPid()); +#else + path = u"/tmp/qt_networkreply_test_fullServerName"_s + % QString::number(QCoreApplication::applicationPid()) % u".sock"_s; +#endif + + QVERIFY(localServer.listen(path)); + server.bind(&localServer); + + QFETCH(QString, hostAndPath); + QUrl url(scheme % hostAndPath); + QNetworkRequest req(url); + req.setAttribute(QNetworkRequest::FullLocalServerNameAttribute, path); + + QNetworkAccessManager manager; + std::unique_ptr<QNetworkReply> reply(manager.get(req)); + + const bool res = QTest::qWaitFor([reply = reply.get()] { return reply->isFinished(); }); + QVERIFY(res); + + QCOMPARE(reply->readAll(), QByteArray("Hello World!")); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + + const QByteArray receivedData = server.peerStates().at(0).receivedData; + const QByteArray expectedGet = "GET " % url.path().toUtf8() % " HTTP/1.1\r\n"; + QVERIFY(receivedData.startsWith(expectedGet)); + + const QByteArray expectedHost = "host: " % url.host().toUtf8() % "\r\n"; + QVERIFY(receivedData.contains(expectedHost)); +} +#endif + +QTEST_MAIN(tst_QNetworkReply_local) + +#include "tst_qnetworkreply_local.moc" +#include "moc_minihttpserver.cpp" diff --git a/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp b/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp index ed978e6b0f..0b6d6f339b 100644 --- a/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp +++ b/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp @@ -3,6 +3,8 @@ #include <QTest> +#include <QtNetwork/QHttp1Configuration> +#include <QtNetwork/QHttp2Configuration> #include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkCookie> @@ -33,6 +35,8 @@ private slots: void originatingObject(); void setHeaders_data(); void setHeaders(); + void operatorEqual_data(); + void operatorEqual(); void removeHeader(); }; @@ -349,7 +353,7 @@ void tst_QNetworkRequest::rawHeaderParsing_data() << true << "Content-Type" << "text/html"; QTest::newRow("Content-Length") << QNetworkRequest::ContentLengthHeader << QVariant(qint64(1)) - << true << "Content-Length" << " 1 "; + << true << "Content-Length" << "1"; QTest::newRow("Location") << QNetworkRequest::LocationHeader << QVariant(QUrl("http://foo/with space")) << true << "Location" << "http://foo/with%20space"; @@ -581,5 +585,128 @@ void tst_QNetworkRequest::setHeaders() QCOMPARE(r2.headers().toListOfPairs(), h.toListOfPairs()); } +void tst_QNetworkRequest::operatorEqual_data() +{ + QTest::addColumn<QNetworkRequest>("a"); + QTest::addColumn<QNetworkRequest>("b"); + QTest::addColumn<bool>("expectedToMatch"); + QTest::newRow("null") << QNetworkRequest() << QNetworkRequest() << true; + + QNetworkRequest data1; + data1.setUrl(QUrl("http://qt-project.org")); + QTest::newRow("url-1-1") << data1 << QNetworkRequest() << false; + QTest::newRow("url-1-2") << data1 << data1 << true; + + QNetworkRequest data2; + QHttpHeaders headers; + headers.append("name1", "value1"); + data2.setHeaders(headers); + QTest::newRow("headers-2-1") << data2 << QNetworkRequest() << false; + QTest::newRow("headers-2-2") << data2 << data2 << true; + QTest::newRow("headers-2-3") << data2 << data1 << false; + + QNetworkRequest data3; + data3.setPeerVerifyName("peerName"); + QTest::newRow("peerName-3-1") << data3 << QNetworkRequest() << false; + QTest::newRow("peerName-3-2") << data3 << data3 << true; + QTest::newRow("peerName-3-3") << data3 << data1 << false; + QTest::newRow("peerName-3-4") << data3 << data2 << false; + + QNetworkRequest data4; + data4.setAttribute(QNetworkRequest::Http2AllowedAttribute, true); + QTest::newRow("attribute-4-1") << data4 << QNetworkRequest() << false; + QTest::newRow("attribute-4-2") << data4 << data4 << true; + QTest::newRow("attribute-4-3") << data4 << data1 << false; + QTest::newRow("attribute-4-4") << data4 << data2 << false; + QTest::newRow("attribute-4-5") << data4 << data3 << false; + + QNetworkRequest data5; + data5.setPriority(QNetworkRequest::Priority::HighPriority); + QTest::newRow("priority-5-1") << data5 << QNetworkRequest() << false; + QTest::newRow("priority-5-2") << data5 << data5 << true; + QTest::newRow("priority-5-3") << data5 << data1 << false; + QTest::newRow("priority-5-4") << data5 << data2 << false; + QTest::newRow("priority-5-5") << data5 << data3 << false; + QTest::newRow("priority-5-6") << data5 << data4 << false; + + QNetworkRequest data6; + data6.setMaximumRedirectsAllowed(3); + QTest::newRow("maxRedirects-6-1") << data6 << QNetworkRequest() << false; + QTest::newRow("maxRedirects-6-2") << data6 << data6 << true; + QTest::newRow("maxRedirects-6-3") << data6 << data1 << false; + QTest::newRow("maxRedirects-6-4") << data6 << data2 << false; + QTest::newRow("maxRedirects-6-5") << data6 << data3 << false; + QTest::newRow("maxRedirects-6-6") << data6 << data4 << false; + QTest::newRow("maxRedirects-6-7") << data6 << data5 << false; + +#if QT_CONFIG(http) + QNetworkRequest data7; + QHttp1Configuration http1Configuration; + http1Configuration.setNumberOfConnectionsPerHost(5); + data7.setHttp1Configuration(http1Configuration); + QTest::newRow("http1Config-7-1") << data7 << QNetworkRequest() << false; + QTest::newRow("http1Config-7-2") << data7 << data7 << true; + QTest::newRow("http1Config-7-3") << data7 << data1 << false; + QTest::newRow("http1Config-7-4") << data7 << data2 << false; + QTest::newRow("http1Config-7-5") << data7 << data3 << false; + QTest::newRow("http1Config-7-6") << data7 << data4 << false; + QTest::newRow("http1Config-7-7") << data7 << data5 << false; + QTest::newRow("http1Config-7-8") << data7 << data6 << false; + + QNetworkRequest data8; + QHttp2Configuration http2Configuration; + http2Configuration.setMaxFrameSize(16386); + data8.setHttp2Configuration(http2Configuration); + QTest::newRow("http2Config-8-1") << data8 << QNetworkRequest() << false; + QTest::newRow("http2Config-8-2") << data8 << data8 << true; + QTest::newRow("http2Config-8-3") << data8 << data1 << false; + QTest::newRow("http2Config-8-4") << data8 << data2 << false; + QTest::newRow("http2Config-8-5") << data8 << data3 << false; + QTest::newRow("http2Config-8-6") << data8 << data4 << false; + QTest::newRow("http2Config-8-7") << data8 << data5 << false; + QTest::newRow("http2Config-8-8") << data8 << data6 << false; + QTest::newRow("http2Config-8-9") << data8 << data7 << false; + + QNetworkRequest data9; + data9.setDecompressedSafetyCheckThreshold(-1); + QTest::newRow("threshold-9-1") << data9 << QNetworkRequest() << false; + QTest::newRow("threshold-9-2") << data9 << data9 << true; + QTest::newRow("threshold-9-3") << data9 << data1 << false; + QTest::newRow("threshold-9-4") << data9 << data2 << false; + QTest::newRow("threshold-9-5") << data9 << data3 << false; + QTest::newRow("threshold-9-6") << data9 << data4 << false; + QTest::newRow("threshold-9-7") << data9 << data5 << false; + QTest::newRow("threshold-9-8") << data9 << data6 << false; + QTest::newRow("threshold-9-9") << data9 << data7 << false; + QTest::newRow("threshold-9-10") << data9 << data8 << false; +#endif + +#if QT_CONFIG(http) || defined (Q_OS_WASM) + QNetworkRequest data10; + data10.setTransferTimeout(50000); + QTest::newRow("timeout-10-1") << data10 << QNetworkRequest() << false; + QTest::newRow("timeout-10-2") << data10 << data10 << true; + QTest::newRow("timeout-10-3") << data10 << data1 << false; + QTest::newRow("timeout-10-4") << data10 << data2 << false; + QTest::newRow("timeout-10-5") << data10 << data3 << false; + QTest::newRow("timeout-10-6") << data10 << data4 << false; + QTest::newRow("timeout-10-7") << data10 << data5 << false; + QTest::newRow("timeout-10-8") << data10 << data6 << false; + QTest::newRow("timeout-10-9") << data10 << data7 << false; + QTest::newRow("timeout-10-10") << data10 << data8 << false; + QTest::newRow("timeout-10-11") << data10 << data9 << false; +#endif +} + +// public bool operator==(const QNetworkRequest &other) const +void tst_QNetworkRequest::operatorEqual() +{ + QFETCH(QNetworkRequest, a); + QFETCH(QNetworkRequest, b); + QFETCH(bool, expectedToMatch); + + QCOMPARE(a == b, expectedToMatch); +} + QTEST_MAIN(tst_QNetworkRequest) #include "tst_qnetworkrequest.moc" diff --git a/tests/auto/network/access/qrestaccessmanager/tst_qrestaccessmanager.cpp b/tests/auto/network/access/qrestaccessmanager/tst_qrestaccessmanager.cpp index 814a9b27f4..d6bdda76ca 100644 --- a/tests/auto/network/access/qrestaccessmanager/tst_qrestaccessmanager.cpp +++ b/tests/auto/network/access/qrestaccessmanager/tst_qrestaccessmanager.cpp @@ -3,7 +3,9 @@ #include "httptestserver_p.h" +#if QT_CONFIG(http) #include <QtNetwork/qhttpmultipart.h> +#endif #include <QtNetwork/qrestaccessmanager.h> #include <QtNetwork/qauthenticator.h> #include <QtNetwork/qnetworkreply.h> @@ -33,7 +35,9 @@ private slots: void initialization(); void destruction(); void callbacks(); +#if QT_CONFIG(http) void requests(); +#endif void reply(); void errors(); void body(); @@ -90,6 +94,7 @@ void tst_QRestAccessManager::reply() networkReply = nullptr; \ } +#if QT_CONFIG(http) void tst_QRestAccessManager::requests() { // A basic test for each HTTP method against the local testserver. @@ -268,6 +273,7 @@ void tst_QRestAccessManager::requests() //manager.sendCustomRequest(request, this, [](){}); // No verb && no data //manager.sendCustomRequest(request, "FOOBAR", this, [](){}); // No verb || no data } +#endif void tst_QRestAccessManager::memberHandler(QRestReply &reply) { @@ -768,7 +774,7 @@ void tst_QRestAccessManager::text() // Successful UTF-32 with spec-wise allowed extra trailing content in the Content-Type header value serverSideResponse.headers.removeAll(Header::ContentType); serverSideResponse.headers.append(Header::ContentType, - "text/plain; charset = \"UTF-32\";extraparameter=bar"_ba); + "text(this is a \\)comment)/ (this (too)) plain; charset = \"UTF-32\";extraparameter=bar"_ba); serverSideResponse.body = encUTF32(sourceString); VERIFY_TEXT_REPLY_OK; diff --git a/tests/auto/network/kernel/CMakeLists.txt b/tests/auto/network/kernel/CMakeLists.txt index b42a9724b3..df87e9d58e 100644 --- a/tests/auto/network/kernel/CMakeLists.txt +++ b/tests/auto/network/kernel/CMakeLists.txt @@ -6,12 +6,16 @@ if(QT_FEATURE_dnslookup AND (QT_FEATURE_libresolv OR WIN32)) add_subdirectory(qdnslookup_appless) endif() if(QT_FEATURE_networkinterface) + add_subdirectory(qnetworkaddressentry) add_subdirectory(qnetworkproxyfactory) add_subdirectory(qnetworkinterface) endif() -add_subdirectory(qnetworkproxy) -add_subdirectory(qnetworkdatagram) -add_subdirectory(qnetworkaddressentry) +if(QT_FEATURE_networkproxy) + add_subdirectory(qnetworkproxy) +endif() +if(QT_FEATURE_udpsocket) + add_subdirectory(qnetworkdatagram) +endif() add_subdirectory(qhostaddress) if(QT_FEATURE_private_tests AND NOT MACOS AND NOT INTEGRITY) add_subdirectory(qhostinfo) diff --git a/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp b/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp index f71e94862c..af3a74a498 100644 --- a/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp +++ b/tests/auto/network/kernel/qdnslookup/tst_qdnslookup.cpp @@ -13,6 +13,13 @@ #include <QtNetwork/QNetworkDatagram> #include <QtNetwork/QUdpSocket> +#if QT_CONFIG(networkproxy) +# include <QtNetwork/QNetworkProxyFactory> +#endif +#if QT_CONFIG(ssl) +# include <QtNetwork/QSslSocket> +#endif + #ifdef Q_OS_UNIX # include <QtCore/QFile> #else @@ -37,8 +44,11 @@ class tst_QDnsLookup: public QObject QStringList domainNameListAlternatives(const QString &input); std::unique_ptr<QDnsLookup> lookupCommon(QDnsLookup::Type type, const QString &domain, - const QHostAddress &server = {}, quint16 port = 53); + const QHostAddress &server = {}, quint16 port = 0, + QDnsLookup::Protocol protocol = QDnsLookup::Standard); QStringList formatReply(const QDnsLookup *lookup) const; + + void setNameserver_helper(QDnsLookup::Protocol protocol); public slots: void initTestCase(); @@ -57,6 +67,8 @@ private slots: void setNameserverLoopback(); void setNameserver_data(); void setNameserver(); + void dnsOverTls_data(); + void dnsOverTls(); void bindingsAndProperties(); void automatedBindings(); }; @@ -74,9 +86,11 @@ static const char preparedDnsQuery[] = "\x00\x00\x06\x00\x01" // <root domain> IN SOA ; -static QList<QHostAddress> systemNameservers() +static QList<QHostAddress> systemNameservers(QDnsLookup::Protocol protocol) { QList<QHostAddress> result; + if (protocol != QDnsLookup::Standard) + return result; #ifdef Q_OS_WIN ULONG infosize = 0; @@ -113,7 +127,7 @@ static QList<QHostAddress> systemNameservers() return result; } -static QList<QHostAddress> globalPublicNameservers() +static QList<QHostAddress> globalPublicNameservers(QDnsLookup::Protocol proto) { const char *const candidates[] = { // Google's dns.google @@ -128,6 +142,56 @@ static QList<QHostAddress> globalPublicNameservers() //"9.9.9.9", "2620:fe::9", }; + auto udpSendAndReceive = [](const QHostAddress &addr, QByteArray &data) { + QUdpSocket socket; + socket.connectToHost(addr, 53); + if (socket.waitForConnected(1)) + socket.write(data); + + if (!socket.waitForReadyRead(1000)) + return socket.errorString(); + + QNetworkDatagram dgram = socket.receiveDatagram(); + if (!dgram.isValid()) + return socket.errorString(); + + data = dgram.data(); + return QString(); + }; + + auto tlsSendAndReceive = [](const QHostAddress &addr, QByteArray &data) { +#if QT_CONFIG(ssl) + QSslSocket socket; + QDeadlineTimer timeout(2000); + socket.connectToHostEncrypted(addr.toString(), 853); + if (!socket.waitForEncrypted(2000)) + return socket.errorString(); + + quint16 size = qToBigEndian<quint16>(data.size()); + socket.write(reinterpret_cast<char *>(&size), sizeof(size)); + socket.write(data); + + if (!socket.waitForReadyRead(timeout.remainingTime())) + return socket.errorString(); + if (socket.bytesAvailable() < 2) + return u"protocol error"_s; + + socket.read(reinterpret_cast<char *>(&size), sizeof(size)); + size = qFromBigEndian(size); + + while (socket.bytesAvailable() < size) { + int remaining = timeout.remainingTime(); + if (remaining < 0 || !socket.waitForReadyRead(remaining)) + return socket.errorString(); + } + + data = socket.readAll(); + return QString(); +#else + return u"SSL/TLS support not compiled in"_s; +#endif + }; + QList<QHostAddress> result; QRandomGenerator &rng = *QRandomGenerator::system(); for (auto name : candidates) { @@ -138,23 +202,18 @@ static QList<QHostAddress> globalPublicNameservers() char *ptr = data.data(); qToBigEndian(id, ptr); - QUdpSocket socket; - socket.connectToHost(addr, 53); - if (socket.waitForConnected(1)) - socket.write(data); - - if (!socket.waitForReadyRead(1000)) { - qDebug() << addr << "discarded:" << socket.errorString(); - continue; - } - - QNetworkDatagram dgram = socket.receiveDatagram(); - if (!dgram.isValid()) { - qDebug() << addr << "discarded:" << socket.errorString(); + QString errorString = [&] { + switch (proto) { + case QDnsLookup::Standard: return udpSendAndReceive(addr, data); + case QDnsLookup::DnsOverTls: return tlsSendAndReceive(addr, data); + } + Q_UNREACHABLE(); + }(); + if (!errorString.isEmpty()) { + qDebug() << addr << "discarded:" << errorString; continue; } - data = dgram.data(); ptr = data.data(); if (data.size() < HeaderSize) { qDebug() << addr << "discarded: reply too small"; @@ -181,6 +240,11 @@ void tst_QDnsLookup::initTestCase() { if (qgetenv("QTEST_ENVIRONMENT") == "ci") dnsServersMustWork = true; + +#if QT_CONFIG(networkproxy) + // for DNS-over-TLS + QNetworkProxyFactory::setUseSystemConfiguration(true); +#endif } QString tst_QDnsLookup::domainName(const QString &input) @@ -221,9 +285,10 @@ QStringList tst_QDnsLookup::domainNameListAlternatives(const QString &input) std::unique_ptr<QDnsLookup> tst_QDnsLookup::lookupCommon(QDnsLookup::Type type, const QString &domain, - const QHostAddress &server, quint16 port) + const QHostAddress &server, quint16 port, + QDnsLookup::Protocol protocol) { - auto lookup = std::make_unique<QDnsLookup>(type, domainName(domain), server, port); + auto lookup = std::make_unique<QDnsLookup>(type, domainName(domain), protocol, server, port); QObject::connect(lookup.get(), &QDnsLookup::finished, &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); lookup->lookup(); @@ -309,6 +374,14 @@ QStringList tst_QDnsLookup::formatReply(const QDnsLookup *lookup) const result.append(std::move(entry)); } + for (const QDnsTlsAssociationRecord &rr : lookup->tlsAssociationRecords()) { + QString entry = u"TLSA %1 %2 %3 %4"_s.arg(int(rr.usage())).arg(int(rr.selector())) + .arg(int(rr.matchType())).arg(rr.value().toHex().toUpper()); + if (rr.name() != domain) + entry = "TLSA unexpected label to "_L1 + rr.name(); + result.append(std::move(entry)); + } + result.sort(); return result; } @@ -439,6 +512,10 @@ void tst_QDnsLookup::lookup_data() "SRV 2 50 7 aaaa-single;" "SRV 3 50 7 a-multi"; + QTest::newRow("tlsa") << QDnsLookup::Type::TLSA << "_25._tcp.multi" + << "TLSA 3 1 1 0123456789ABCDEFFEDCBA9876543210" + "0123456789ABCDEFFEDCBA9876543210"; + QTest::newRow("txt-single") << QDnsLookup::TXT << "txt-single" << "TXT \"Hello\""; QTest::newRow("txt-multi-onerr") << QDnsLookup::TXT << "txt-multi-onerr" @@ -457,8 +534,12 @@ void tst_QDnsLookup::lookup() if (!lookup) return; - QCOMPARE(lookup->error(), QDnsLookup::NoError); +#ifdef Q_OS_WIN + if (QTest::currentDataTag() == "tlsa"_L1) + QSKIP("WinDNS doesn't work properly with TLSA records and we don't know why"); +#endif QCOMPARE(lookup->errorString(), QString()); + QCOMPARE(lookup->error(), QDnsLookup::NoError); QCOMPARE(lookup->type(), type); QCOMPARE(lookup->name(), domainName(domain)); @@ -591,31 +672,59 @@ void tst_QDnsLookup::setNameserverLoopback() QCOMPARE(lookup.error(), QDnsLookup::NotFoundError); } -void tst_QDnsLookup::setNameserver_data() +template <QDnsLookup::Protocol Protocol> +static void setNameserver_data_helper(const QByteArray &protoName) { - static QList<QHostAddress> servers = systemNameservers() + globalPublicNameservers(); + if (!QDnsLookup::isProtocolSupported(Protocol)) + QSKIP(protoName + " not supported"); + + static QList<QHostAddress> servers = systemNameservers(Protocol) + + globalPublicNameservers(Protocol); QTest::addColumn<QHostAddress>("server"); if (servers.isEmpty()) { - QSKIP("No reachable DNS servers were found"); + QSKIP("No reachable " + protoName + " servers were found"); } else { for (const QHostAddress &h : std::as_const(servers)) QTest::addRow("%s", qUtf8Printable(h.toString())) << h; } } -void tst_QDnsLookup::setNameserver() +void tst_QDnsLookup::setNameserver_data() +{ + setNameserver_data_helper<QDnsLookup::Standard>("DNS"); +} + +void tst_QDnsLookup::setNameserver_helper(QDnsLookup::Protocol protocol) { QFETCH(QHostAddress, server); + QElapsedTimer timer; + timer.start(); std::unique_ptr<QDnsLookup> lookup = - lookupCommon(QDnsLookup::Type::A, "a-single", server); + lookupCommon(QDnsLookup::Type::A, "a-single", server, 0, protocol); if (!lookup) return; + qDebug() << "Lookup took" << timer.elapsed() << "ms"; QCOMPARE(lookup->error(), QDnsLookup::NoError); QString result = formatReply(lookup.get()).join(';'); QCOMPARE(result, "A 192.0.2.1"); } +void tst_QDnsLookup::setNameserver() +{ + setNameserver_helper(QDnsLookup::Standard); +} + +void tst_QDnsLookup::dnsOverTls_data() +{ + setNameserver_data_helper<QDnsLookup::DnsOverTls>("DNS-over-TLS"); +} + +void tst_QDnsLookup::dnsOverTls() +{ + setNameserver_helper(QDnsLookup::DnsOverTls); +} + void tst_QDnsLookup::bindingsAndProperties() { QDnsLookup lookup; diff --git a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp index 141ca25021..e5bbf3467c 100644 --- a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp +++ b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp @@ -197,6 +197,14 @@ void tst_QNetworkInterface::localAddress_data() } else if (!ipv6 || entry.prefixLength() != 64) { continue; } else { +#ifdef Q_OS_ANDROID + // Android seem to not allow IPv6 connection from interfaces other than wlan, + // if it's connected, and wlan is connected by default on Android emulators, + // so prefer selecting wlan in this test. + const QString scopeId = addr.scopeId(); + if (!scopeId.isEmpty() && !scopeId.startsWith("wlan")) + continue; +#endif // add a random node in this IPv6 network quint64 randomid = qFromBigEndian(Q_UINT64_C(0x8f41f072e5733caa)); QIPv6Address ip6 = addr.toIPv6Address(); diff --git a/tests/auto/network/socket/CMakeLists.txt b/tests/auto/network/socket/CMakeLists.txt index c3f8e8f87f..7136017f39 100644 --- a/tests/auto/network/socket/CMakeLists.txt +++ b/tests/auto/network/socket/CMakeLists.txt @@ -7,14 +7,20 @@ if(QT_FEATURE_private_tests) add_subdirectory(qsocks5socketengine) add_subdirectory(platformsocketengine) endif() -add_subdirectory(qudpsocket) +if(QT_FEATURE_udpsocket) + add_subdirectory(qudpsocket) +endif() add_subdirectory(qabstractsocket) -if(NOT ANDROID) +if(QT_FEATURE_localserver AND NOT ANDROID) # QTBUG-87387 add_subdirectory(qlocalsocket) +endif() + +if(QT_FEATURE_networkinterface AND NOT ANDROID) # QTBUG-87388 add_subdirectory(qtcpserver) endif() + if(QT_FEATURE_sctp) add_subdirectory(qsctpsocket) endif() diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 1ecd871ceb..30ffb50d23 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -1664,6 +1664,9 @@ void tst_QLocalSocket::asyncDisconnectNotify() void tst_QLocalSocket::verifySocketOptions_data() { #ifdef Q_OS_LINUX + if (::geteuid() == 0) + QSKIP("Running this test as root doesn't make sense"); + QTest::addColumn<QString>("service"); QTest::addColumn<QLocalServer::SocketOption>("opts"); QTest::addColumn<QFile::Permissions>("perms"); diff --git a/tests/auto/other/CMakeLists.txt b/tests/auto/other/CMakeLists.txt index 16f96cd5f4..e261ea234d 100644 --- a/tests/auto/other/CMakeLists.txt +++ b/tests/auto/other/CMakeLists.txt @@ -1,9 +1,6 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -if(NOT CMAKE_CROSSCOMPILING) - # add_subdirectory(atwrapper) <- does not exist -endif() if(TARGET Qt::Widgets) add_subdirectory(gestures) add_subdirectory(languagechange) diff --git a/tests/auto/other/android_deployment_settings/CMakeLists.txt b/tests/auto/other/android_deployment_settings/CMakeLists.txt index f2ba135328..9ef457189a 100644 --- a/tests/auto/other/android_deployment_settings/CMakeLists.txt +++ b/tests/auto/other/android_deployment_settings/CMakeLists.txt @@ -30,6 +30,7 @@ set_target_properties(${target} PROPERTIES QT_ANDROID_SDK_BUILD_TOOLS_REVISION "23.0.2" QT_ANDROID_MIN_SDK_VERSION "1" QT_ANDROID_TARGET_SDK_VERSION "2" + QT_ANDROID_PACKAGE_NAME "org.qtproject.android_deployment_settings_test" QT_ANDROID_DEPLOYMENT_DEPENDENCIES "dep1.so;dep2.so;dep3.so" QT_ANDROID_DEPLOYMENT_SETTINGS_FILE "attempt_to_rewrite.json" QT_ANDROID_EXTRA_LIBS @@ -53,6 +54,7 @@ set_target_properties(${target} PROPERTIES QT_ANDROID_SDK_BUILD_TOOLS_REVISION "23.0.2" QT_ANDROID_MIN_SDK_VERSION "1" QT_ANDROID_TARGET_SDK_VERSION "2" + QT_ANDROID_PACKAGE_NAME "org.qtproject.android_deployment_settings_test" QT_ANDROID_DEPLOYMENT_DEPENDENCIES "dep1.so;dep2.so;dep3.so" QT_ANDROID_EXTRA_LIBS "some/path/to/lib1.so;some/path\\to/lib2.so;some\\path\\to\\lib3.so;some/path/to/lib4.so" 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 d68d08b58e..f8428aaf43 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 @@ -76,6 +76,8 @@ void tst_android_deployment_settings::DeploymentSettings_data() << "1"; QTest::newRow("android-target-sdk-version") << "android-target-sdk-version" << "2"; + QTest::newRow("android-package-name") << "android-package-name" + << "org.qtproject.android_deployment_settings_test"; } void tst_android_deployment_settings::DeploymentSettings() diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 5fd695e2e6..cab88e2fc0 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -966,6 +966,13 @@ void tst_QAccessibility::mainWindowTest() QCOMPARE(iface->text(QAccessible::Name), name); QCOMPARE(iface->role(), QAccessible::Window); QVERIFY(iface->state().active); + + QTestAccessibility::clearEvents(); + QLatin1String newName = QLatin1String("Main window with updated title"); + mw->setWindowTitle(newName); + QCOMPARE(iface->text(QAccessible::Name), QLatin1String(newName)); + QAccessibleEvent event(mw, QAccessible::NameChanged); + QVERIFY(QTestAccessibility::containsEvent(&event)); } QTestAccessibility::clearEvents(); diff --git a/tests/auto/other/qvariant_common/tst_qvariant_common.h b/tests/auto/other/qvariant_common/tst_qvariant_common.h index 553c396e47..4007cc7db8 100644 --- a/tests/auto/other/qvariant_common/tst_qvariant_common.h +++ b/tests/auto/other/qvariant_common/tst_qvariant_common.h @@ -119,6 +119,13 @@ protected: QFETCH(bool, UIntCast); \ QFETCH(bool, ULongLongCast); +#if QT_CONFIG(shortcut) +#define QMETATYPE_QKEYSEQUENCE \ + QCOMPARE(val.canConvert(QMetaType(QMetaType::QKeySequence)), KeySequenceCast); +#else +#define QMETATYPE_QKEYSEQUENCE +#endif + #define TST_QVARIANT_CANCONVERT_COMPARE_DATA \ QCOMPARE(val.canConvert(QMetaType(QMetaType::QBitArray)), BitArrayCast); \ QCOMPARE(val.canConvert(QMetaType(QMetaType::QBitmap)), BitmapCast); \ @@ -135,7 +142,7 @@ protected: QCOMPARE(val.canConvert(QMetaType(QMetaType::QImage)), ImageCast); \ QCOMPARE(val.canConvert(QMetaType(QMetaType::Int)), IntCast); \ QCOMPARE(val.canConvert(QMetaType(QMetaType::UnknownType)), InvalidCast); \ - QCOMPARE(val.canConvert(QMetaType(QMetaType::QKeySequence)), KeySequenceCast); \ + QMETATYPE_QKEYSEQUENCE \ QCOMPARE(val.canConvert(QMetaType(QMetaType::QVariantList)), ListCast); \ QCOMPARE(val.canConvert(QMetaType(QMetaType::LongLong)), LongLongCast); \ QCOMPARE(val.canConvert(QMetaType(QMetaType::QVariantMap)), MapCast); \ diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h index f81fe5548b..5a10bde814 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h +++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h @@ -518,7 +518,10 @@ protected: void cleanup() { QSqlQuery q(m_db); - q.exec("DROP PROCEDURE IF EXISTS " + m_procName); + if (m_db.driverName() == "QIBASE") + q.exec("DROP PROCEDURE " + m_procName); + else + q.exec("DROP PROCEDURE IF EXISTS " + m_procName); } private: QSqlDatabase m_db; diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 56fb5cd05f..92bedfab06 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -256,6 +256,9 @@ private slots: void ibaseDateTimeWithTZ(); void ibaseTimeStampTzArray_data() { generic_data("QIBASE"); } void ibaseTimeStampTzArray(); + void ibaseInt128_data() { generic_data("QIBASE"); } + void ibaseInt128(); + void psqlJsonOperator_data() { generic_data("QPSQL"); } void psqlJsonOperator(); @@ -1875,52 +1878,54 @@ void tst_QSqlQuery::oci_rawField() // Test whether we can fetch values with more than DOUBLE precision // note that SQLite highest precision is that of a double, although // you can define field with higher precision: +// Test whether we can fetch values with more than DOUBLE precision +// note that SQLite highest precision is that of a double, although +// you can define field with higher precision: void tst_QSqlQuery::precision() { QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); - if (dbType == QSqlDriver::Interbase) - QSKIP("DB unable to store high precision"); const auto tidier = qScopeGuard([db, oldPrecision = db.driver()->numericalPrecisionPolicy()]() { db.driver()->setNumericalPrecisionPolicy(oldPrecision); }); + int digits = 21; + int decimals = 20; + std::array<QLatin1String, 2> precStrings = { "1.2345678901234567891"_L1, + "-1.2345678901234567891"_L1 }; + if (dbType == QSqlDriver::SQLite) { + // SQLite 3.45 does not return more, even when speicfied + digits = 17; + decimals = 16; + precStrings = { "1.2345678901234567"_L1, "-1.2345678901234567"_L1 }; + } else if (dbType == QSqlDriver::Sybase) + decimals = 18; db.driver()->setNumericalPrecisionPolicy(QSql::HighPrecision); TableScope ts(db, "qtest_precision", __FILE__); - static const QLatin1String precStr("1.2345678901234567891"); - - { - // need a new scope for SQLITE - QSqlQuery q(db); - QVERIFY_SQL(q, exec(QLatin1String(tst_Databases::isMSAccess(db) - ? "CREATE TABLE %1 (col1 number)" - : "CREATE TABLE %1 (col1 numeric(21, 20))") - .arg(ts.tableName()))); - - QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (col1) VALUES (%2)") - .arg(ts.tableName(), precStr))); + QSqlQuery q(db); + QString stmt = "CREATE TABLE %1 (col1 numeric("_L1 + QString::number(digits) + ", "_L1 + + QString::number(decimals) + "))"_L1; + if (tst_Databases::isMSAccess(db)) + stmt = "CREATE TABLE %1 (col1 number)"_L1; + QVERIFY_SQL(q, exec(stmt.arg(ts.tableName()))); + for (const auto &precStr : precStrings) { + QVERIFY_SQL(q, exec("DELETE FROM %1"_L1.arg(ts.tableName()))); + QVERIFY_SQL(q, exec("INSERT INTO %1 (col1) VALUES (%2)"_L1.arg(ts.tableName(), precStr))); QVERIFY_SQL(q, exec("SELECT * FROM " + ts.tableName())); QVERIFY(q.next()); const QString val = q.value(0).toString(); if (!val.startsWith(precStr)) { int i = 0; - while (i < val.size() && precStr[i] != 0 && precStr[i] == val[i].toLatin1()) + while (i < val.size() && precStr[i] != 0 && precStr[i] == val[i]) ++i; - - // TDS has crappy precisions by default - if (dbType == QSqlDriver::Sybase) { - if (i < 18) - qWarning("TDS didn't return the right precision"); - } else { - qWarning() << tst_Databases::dbToString(db) << "didn't return the right precision (" - << i << "out of 21)," << val; - } + qWarning() << tst_Databases::dbToString(db) << "didn't return the right precision (" + << i << "out of " << digits << ")," << val; } - } // SQLITE scope + } } void tst_QSqlQuery::nullResult() @@ -5034,6 +5039,54 @@ void tst_QSqlQuery::ibaseTimeStampTzArray() #endif // QT_CONFIG(timezone) } +void tst_QSqlQuery::ibaseInt128() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + TableScope ts(db, "int128test", __FILE__); + db.setNumericalPrecisionPolicy(QSql::HighPrecision); + QSqlQuery q(db); + if (!q.exec("CREATE TABLE " + ts.tableName() + " (id INT PRIMARY KEY, price NUMERIC(20, 4))")) + QSKIP("Need at least Firebird 4 for this test - skipping"); + + QVERIFY_SQL(q, exec("INSERT INTO " + ts.tableName() + "(id,price) values(1,40001.1234)")); + QVERIFY_SQL(q, prepare("INSERT INTO " + ts.tableName() + "(id,price) values(2,:amount)")); + q.bindValue(":amount", 12345.67890); + QVERIFY_SQL(q, exec()); + { + QSqlQuery q2(db); + q2.setNumericalPrecisionPolicy(QSql::LowPrecisionDouble); + QVERIFY_SQL(q2, exec("SELECT price FROM " + ts.tableName() + " ORDER BY id")); + QVERIFY_SQL(q2, next()); + QCOMPARE(q2.value(0).metaType().id(), QMetaType::Double); + QCOMPARE(q2.value(0).toDouble(), 40001.1234); + QVERIFY_SQL(q2, next()); + QCOMPARE(q2.value(0).metaType().id(), QMetaType::Double); + QCOMPARE(q2.value(0).toDouble(), 12345.6789); + QVERIFY_SQL(q2, exec("SELECT sum(price) FROM " + ts.tableName())); + QVERIFY_SQL(q2, next()); + QCOMPARE(q2.value(0).metaType().id(), QMetaType::Double); + QCOMPARE(q2.value(0).toDouble(), 52346.8023); + } + { + QSqlQuery q2(db); + q2.setNumericalPrecisionPolicy(QSql::HighPrecision); + QVERIFY_SQL(q2, exec("SELECT price FROM " + ts.tableName() + " ORDER BY id")); + QVERIFY_SQL(q2, next()); + QCOMPARE(q2.value(0).metaType().id(), QMetaType::QString); + QCOMPARE(q2.value(0).toString(), "40001.1234"); + QVERIFY_SQL(q2, next()); + QCOMPARE(q2.value(0).metaType().id(), QMetaType::QString); + QCOMPARE(q2.value(0).toString(), "12345.6789"); + QVERIFY_SQL(q2, exec("SELECT sum(price) FROM " + ts.tableName())); + QVERIFY_SQL(q2, next()); + QCOMPARE(q2.value(0).metaType().id(), QMetaType::QString); + QCOMPARE(q2.value(0).toString(), "52346.8023"); + } +} + void tst_QSqlQuery::ibase_executeBlock() { QFETCH(QString, dbName); diff --git a/tests/auto/testlib/selftests/eventloop/CMakeLists.txt b/tests/auto/testlib/selftests/eventloop/CMakeLists.txt index 46b794f895..afaf766f69 100644 --- a/tests/auto/testlib/selftests/eventloop/CMakeLists.txt +++ b/tests/auto/testlib/selftests/eventloop/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## eventloop Binary: ##################################################################### diff --git a/tests/auto/testlib/selftests/failcleanup/CMakeLists.txt b/tests/auto/testlib/selftests/failcleanup/CMakeLists.txt index 0b582ffdc3..10805ba6f7 100644 --- a/tests/auto/testlib/selftests/failcleanup/CMakeLists.txt +++ b/tests/auto/testlib/selftests/failcleanup/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2022 The Qt Company Ltd. +# Copyright (C) 2024 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause ##################################################################### diff --git a/tests/auto/testlib/selftests/failcleanuptestcase/CMakeLists.txt b/tests/auto/testlib/selftests/failcleanuptestcase/CMakeLists.txt index 1a1417f76c..cb11a577f6 100644 --- a/tests/auto/testlib/selftests/failcleanuptestcase/CMakeLists.txt +++ b/tests/auto/testlib/selftests/failcleanuptestcase/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## failcleanuptestcase Binary: ##################################################################### diff --git a/tests/auto/testlib/selftests/skipblacklisted/CMakeLists.txt b/tests/auto/testlib/selftests/skipblacklisted/CMakeLists.txt index cc1a2ff469..0cdcf2c063 100644 --- a/tests/auto/testlib/selftests/skipblacklisted/CMakeLists.txt +++ b/tests/auto/testlib/selftests/skipblacklisted/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## skipblacklisted Binary: ##################################################################### diff --git a/tests/auto/testlib/selftests/skipcleanuptestcase/CMakeLists.txt b/tests/auto/testlib/selftests/skipcleanuptestcase/CMakeLists.txt index 88aae42acd..5c531b46b5 100644 --- a/tests/auto/testlib/selftests/skipcleanuptestcase/CMakeLists.txt +++ b/tests/auto/testlib/selftests/skipcleanuptestcase/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## skipcleanuptestcase Binary: ##################################################################### diff --git a/tests/auto/tools/moc/enum_inc.h b/tests/auto/tools/moc/enum_inc.h index 7d7b6ae9f3..2b355b7a19 100644 --- a/tests/auto/tools/moc/enum_inc.h +++ b/tests/auto/tools/moc/enum_inc.h @@ -1,2 +1,4 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only parcel = 42, part = 12, diff --git a/tests/auto/tools/moc/forwarddeclaredparam.h b/tests/auto/tools/moc/forwarddeclaredparam.h index 176f0c3356..94caae8a5b 100644 --- a/tests/auto/tools/moc/forwarddeclaredparam.h +++ b/tests/auto/tools/moc/forwarddeclaredparam.h @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef FORWARDDECLAREDPARAM_H #define FORWARDDECLAREDPARAM_H struct ForwardDeclaredParam {}; diff --git a/tests/auto/tools/moc/os9-newlines.h b/tests/auto/tools/moc/os9-newlines.h index 82bddd117d..2da70f6a89 100644 --- a/tests/auto/tools/moc/os9-newlines.h +++ b/tests/auto/tools/moc/os9-newlines.h @@ -1 +1 @@ -// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QObject>
class Os9Newlines : public QObject
{
Q_OBJECT
public Q_SLOTS:
inline void testSlot() {}
};
\ No newline at end of file +// REUSE-IgnoreStart
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
// REUSE-IgnoreEnd
#include <QObject>
class Os9Newlines : public QObject
{
Q_OBJECT
public Q_SLOTS:
inline void testSlot() {}
};
\ No newline at end of file diff --git a/tests/auto/tools/moc/subdir/extradefines.h b/tests/auto/tools/moc/subdir/extradefines.h index e7888ce80d..efad23be6f 100644 --- a/tests/auto/tools/moc/subdir/extradefines.h +++ b/tests/auto/tools/moc/subdir/extradefines.h @@ -1 +1,3 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #define FOO 1 diff --git a/tests/auto/tools/qmake/testdata/conflicting_targets/main.cpp b/tests/auto/tools/qmake/testdata/conflicting_targets/main.cpp index 39de28135a..866a063753 100644 --- a/tests/auto/tools/qmake/testdata/conflicting_targets/main.cpp +++ b/tests/auto/tools/qmake/testdata/conflicting_targets/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 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/tools/qmake/testdata/findDeps/needed.cpp b/tests/auto/tools/qmake/testdata/findDeps/needed.cpp index 698d0aaa12..726382cf10 100644 --- a/tests/auto/tools/qmake/testdata/findDeps/needed.cpp +++ b/tests/auto/tools/qmake/testdata/findDeps/needed.cpp @@ -1 +1,3 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only extern int needed(void) { return 1; } diff --git a/tests/auto/tools/qmake/testdata/findMocs/digitseparated.h b/tests/auto/tools/qmake/testdata/findMocs/digitseparated.h index ddedac26e3..10cf31a8a5 100644 --- a/tests/auto/tools/qmake/testdata/findMocs/digitseparated.h +++ b/tests/auto/tools/qmake/testdata/findMocs/digitseparated.h @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QObject> class AfterDigitSeparator : public QObject diff --git a/tests/auto/tools/qmake/testdata/include_pwd/anotherheader.h b/tests/auto/tools/qmake/testdata/include_pwd/anotherheader.h index a3a63e26bf..228a8861b7 100644 --- a/tests/auto/tools/qmake/testdata/include_pwd/anotherheader.h +++ b/tests/auto/tools/qmake/testdata/include_pwd/anotherheader.h @@ -1,2 +1,4 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only /* This file should be included indirectly through main.cpp */ diff --git a/tests/auto/tools/qmake/testdata/include_pwd/main.cpp b/tests/auto/tools/qmake/testdata/include_pwd/main.cpp index c98935f87d..b55f0525ea 100644 --- a/tests/auto/tools/qmake/testdata/include_pwd/main.cpp +++ b/tests/auto/tools/qmake/testdata/include_pwd/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "someheader.h" int main() diff --git a/tests/auto/tools/qmake/testdata/include_pwd/somedirectory/someheader.h b/tests/auto/tools/qmake/testdata/include_pwd/somedirectory/someheader.h index f977346945..9a26fb7c1e 100644 --- a/tests/auto/tools/qmake/testdata/include_pwd/somedirectory/someheader.h +++ b/tests/auto/tools/qmake/testdata/include_pwd/somedirectory/someheader.h @@ -1 +1,3 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "anotherheader.h" diff --git a/tests/auto/tools/qmake/testdata/quotedfilenames/include folder/header.h b/tests/auto/tools/qmake/testdata/quotedfilenames/include folder/header.h index 595c0cac3c..b65da1d85c 100644 --- a/tests/auto/tools/qmake/testdata/quotedfilenames/include folder/header.h +++ b/tests/auto/tools/qmake/testdata/quotedfilenames/include folder/header.h @@ -1 +1,3 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only /* a random header file */ diff --git a/tests/auto/tools/qmake/testdata/windows_resources/main.cpp b/tests/auto/tools/qmake/testdata/windows_resources/main.cpp index 237c8ce181..6c1d24751e 100644 --- a/tests/auto/tools/qmake/testdata/windows_resources/main.cpp +++ b/tests/auto/tools/qmake/testdata/windows_resources/main.cpp @@ -1 +1,3 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only int main() {} diff --git a/tests/auto/tools/qt_cmake_create/testdata/cpp_project/main.cpp b/tests/auto/tools/qt_cmake_create/testdata/cpp_project/main.cpp index ae659d5ed4..3526286e5e 100644 --- a/tests/auto/tools/qt_cmake_create/testdata/cpp_project/main.cpp +++ b/tests/auto/tools/qt_cmake_create/testdata/cpp_project/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <iostream> int main(int, char *[]) diff --git a/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.cpp b/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.cpp index 13c7014d8c..844e67e2c4 100644 --- a/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.cpp +++ b/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QGuiApplication> #include <QQmlApplicationEngine> diff --git a/tests/auto/tools/qt_cmake_create/testdata/qrc_project/main.cpp b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/main.cpp index cd8ed8f57b..72f63e3077 100644 --- a/tests/auto/tools/qt_cmake_create/testdata/qrc_project/main.cpp +++ b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QFile> #include <QDebug> diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_project/main.cpp b/tests/auto/tools/qt_cmake_create/testdata/ui_project/main.cpp index b0a4ec2647..2e74e1c140 100644 --- a/tests/auto/tools/qt_cmake_create/testdata/ui_project/main.cpp +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_project/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "widget.h" #include <QApplication> diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.cpp b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.cpp index 815d5f8c4b..65c5eae0c9 100644 --- a/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.cpp +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "widget.h" #include "ui_widget.h" @@ -12,4 +14,3 @@ Widget::~Widget() { delete ui; } - diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.h b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.h index 1fe2322b13..9110f2a20b 100644 --- a/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.h +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.h @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef WIDGET_H #define WIDGET_H diff --git a/tests/auto/wasm/fetchapi/tst_fetchapi.cpp b/tests/auto/wasm/fetchapi/tst_fetchapi.cpp index 3dcd8dd916..e37316b2db 100644 --- a/tests/auto/wasm/fetchapi/tst_fetchapi.cpp +++ b/tests/auto/wasm/fetchapi/tst_fetchapi.cpp @@ -69,11 +69,9 @@ void tst_FetchApi::sendRequestOnMainThread() void tst_FetchApi::sendRequestOnBackgroundThread() { - QSKIP("Skip this test until we fix fetching from background threads."); QEventLoop mainEventLoop; BackgroundThread *backgroundThread = new BackgroundThread(); connect(backgroundThread, &BackgroundThread::finished, &mainEventLoop, &QEventLoop::quit); - connect(backgroundThread, &BackgroundThread::finished, backgroundThread, &QObject::deleteLater); backgroundThread->start(); mainEventLoop.exec(); diff --git a/tests/auto/wasm/selenium/CMakeLists.txt b/tests/auto/wasm/selenium/CMakeLists.txt index 335b6d23d9..445030878e 100644 --- a/tests/auto/wasm/selenium/CMakeLists.txt +++ b/tests/auto/wasm/selenium/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 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_qwasmwindow_harness LANGUAGES CXX) diff --git a/tests/auto/wasm/selenium/run.bat b/tests/auto/wasm/selenium/run.bat index 031e0b13ab..56305c72c3 100644 --- a/tests/auto/wasm/selenium/run.bat +++ b/tests/auto/wasm/selenium/run.bat @@ -1,3 +1,5 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 :: :: The highest version of python that can be used is 3.11 :: Download from here: https://www.python.org/downloads/release/python-3118/ diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index c91a0803ee..fad75ec045 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -2976,11 +2976,6 @@ static QSizeF wfh(Qt::SizeHint /*which*/, const QSizeF &constraint) return result; } -bool qFuzzyCompare(const QSizeF &a, const QSizeF &b) -{ - return qFuzzyCompare(a.width(), b.width()) && qFuzzyCompare(a.height(), b.height()); -} - void tst_QGraphicsGridLayout::heightForWidth() { QGraphicsWidget *widget = new QGraphicsWidget; diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index e39437d8c7..ee1a8c530a 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -2062,7 +2062,6 @@ void tst_QGraphicsProxyWidget::setFocus_simpleWidget() window.setLayout(layout); window.show(); - QApplicationPrivate::setActiveWindow(&window); window.activateWindow(); QVERIFY(QTest::qWaitForWindowActive(&window)); QCOMPARE(QApplication::activeWindow(), &window); @@ -2134,7 +2133,6 @@ void tst_QGraphicsProxyWidget::setFocus_simpleTwoWidgets() window.setLayout(layout); window.show(); - QApplicationPrivate::setActiveWindow(&window); window.activateWindow(); QVERIFY(QTest::qWaitForWindowActive(&window)); QCOMPARE(QApplication::activeWindow(), &window); @@ -2213,7 +2211,6 @@ void tst_QGraphicsProxyWidget::setFocus_complexTwoWidgets() window.setLayout(layout); window.show(); - QApplicationPrivate::setActiveWindow(&window); window.activateWindow(); QVERIFY(QTest::qWaitForWindowActive(&window)); QCOMPARE(QApplication::activeWindow(), &window); @@ -2458,7 +2455,6 @@ void tst_QGraphicsProxyWidget::tooltip_basic() QGraphicsView view(&scene); view.setFixedSize(200, 200); view.show(); - QApplicationPrivate::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); { QHelpEvent helpEvent(QEvent::ToolTip, view.viewport()->rect().topLeft(), @@ -2994,7 +2990,6 @@ void tst_QGraphicsProxyWidget::actionsContextMenu() view.resize(200, 200); view.move(QGuiApplication::primaryScreen()->geometry().center() - QPoint(100, 100)); view.show(); - QApplicationPrivate::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); view.setFocus(); QTRY_VERIFY(view.hasFocus()); @@ -3076,7 +3071,6 @@ void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget() QGraphicsScene scene; QGraphicsView view(&scene); view.show(); - QApplicationPrivate::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); QGraphicsProxyWidget *proxy = scene.addWidget(widgetGuard.release()); diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index b71a7a0a31..2eb2d84504 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -23,6 +23,7 @@ #include <QtGui/QFontDatabase> #include <QtGui/QClipboard> +#include <QtGui/QStyleHints> #include <QtWidgets/QApplication> #include <QtWidgets/QMessageBox> @@ -119,6 +120,7 @@ private slots: void style(); void applicationPalettePolish(); + void setColorScheme(); void allWidgets(); void topLevelWidgets(); @@ -311,10 +313,8 @@ void tst_QApplication::alert() QApplication::alert(&widget, -1); QApplication::alert(&widget, 250); widget2.activateWindow(); - QApplicationPrivate::setActiveWindow(&widget2); QApplication::alert(&widget, 0); widget.activateWindow(); - QApplicationPrivate::setActiveWindow(&widget); QApplication::alert(&widget, 200); } @@ -1624,7 +1624,6 @@ void tst_QApplication::focusWidget() QTextEdit te; te.show(); - QApplicationPrivate::setActiveWindow(&te); QVERIFY(QTest::qWaitForWindowActive(&te)); const auto focusWidget = QApplication::focusWidget(); @@ -1640,7 +1639,6 @@ void tst_QApplication::focusWidget() QTextEdit te(&w); w.show(); - QApplicationPrivate::setActiveWindow(&w); QVERIFY(QTest::qWaitForWindowActive(&w)); const auto focusWidget = QApplication::focusWidget(); @@ -2055,6 +2053,122 @@ void tst_QApplication::applicationPalettePolish() } } +void tst_QApplication::setColorScheme() +{ + int argc = 1; + QApplication app(argc, &argv0); + + if (QStringList{"minimal", "offscreen", "wayland", "xcb", "wasm", "webassembly"} + .contains(QGuiApplication::platformName(), Qt::CaseInsensitive)) { + QSKIP("Setting the colorScheme is not implemented on this platform."); + } + qDebug() << "Testing setColorScheme on platform" << QGuiApplication::platformName(); + + if (QByteArrayView(app.style()->metaObject()->className()) == "QWindowsVistaStyle") + QSKIP("Setting the colorScheme is not supported with the Windows Vista style."); + + const Qt::ColorScheme defaultColorScheme = QApplication::styleHints()->colorScheme(); + // if we implement setColorScheme, then we must be able to read it + QVERIFY(defaultColorScheme != Qt::ColorScheme::Unknown); + const Qt::ColorScheme newColorScheme = defaultColorScheme == Qt::ColorScheme::Light + ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light; + + class TopLevelWidget : public QWidget + { + QList<QEvent::Type> events; + public: + TopLevelWidget() + { + setObjectName("colorScheme TopLevelWidget"); + } + + void clearEvents() + { + events.clear(); + } + qsizetype eventCount(QEvent::Type type) const + { + return events.count(type); + } + protected: + bool event(QEvent *event) override + { + switch (event->type()) { + case QEvent::ApplicationPaletteChange: + case QEvent::PaletteChange: + case QEvent::ThemeChange: + events << event->type(); + break; + default: + break; + } + + return QWidget::event(event); + } + } topLevelWidget; + topLevelWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevelWidget)); + + QSignalSpy colorSchemeChangedSpy(app.styleHints(), &QStyleHints::colorSchemeChanged); + + // always start with a clean list + topLevelWidget.clearEvents(); + const QPalette defaultPalette = topLevelWidget.palette(); + + bool oldPaletteWhenSchemeChanged = false; + connect(app.styleHints(), &QStyleHints::colorSchemeChanged, this, + [defaultPalette, &topLevelWidget, &oldPaletteWhenSchemeChanged]{ + oldPaletteWhenSchemeChanged = defaultPalette == topLevelWidget.palette(); + }); + + app.styleHints()->setColorScheme(newColorScheme); + QTRY_COMPARE(colorSchemeChangedSpy.count(), 1); + // We have not yet updated the palette when we emit the colorSchemeChanged + // signal, so the toplevel widget should still use the previous palette + QVERIFY(oldPaletteWhenSchemeChanged); + QCOMPARE(topLevelWidget.eventCount(QEvent::ThemeChange), 1); + // We can't guarantee that there is only one ApplicationPaletteChange, + // and they might arrive asynchronously in response to ThemeChange + QTRY_COMPARE_GE(topLevelWidget.eventCount(QEvent::ApplicationPaletteChange), 1); + // But we can guarantee a single PaletteChange event for the widget + QCOMPARE(topLevelWidget.eventCount(QEvent::PaletteChange), 1); + // The palette should have changed + QCOMPARE_NE(topLevelWidget.palette(), defaultPalette); + + topLevelWidget.clearEvents(); + colorSchemeChangedSpy.clear(); + + // verify that a widget shown with a color scheme override in place respect that + QWidget newWidget; + newWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&newWidget)); + QCOMPARE(newWidget.palette(), topLevelWidget.palette()); + + // Setting to Unknown should follow the system preference again + app.styleHints()->setColorScheme(Qt::ColorScheme::Unknown); + QTRY_COMPARE(colorSchemeChangedSpy.count(), 1); + QCOMPARE(app.styleHints()->colorScheme(), defaultColorScheme); + QTRY_COMPARE(topLevelWidget.eventCount(QEvent::PaletteChange), 1); + + auto debugPalette = qScopeGuard([defaultPalette, &topLevelWidget]{ + qDebug() << "Inspecting palettes for differences"; + const QPalette palette = topLevelWidget.palette(); + for (int g = 0; g < QPalette::NColorGroups; ++g) { + for (int r = 0; r < QPalette::NColorRoles; ++r) { + const auto group = static_cast<QPalette::ColorGroup>(g); + const auto role = static_cast<QPalette::ColorRole>(r); + qDebug() << "...Checking" << group << role; + const auto actualBrush = palette.brush(group, role); + const auto expectedBrush = defaultPalette.brush(group, role); + if (palette.brush(group, role) != defaultPalette.brush(group, role)) + qWarning() << "...Difference in" << group << role << actualBrush << expectedBrush; + } + } + }); + QCOMPARE(topLevelWidget.palette(), defaultPalette); + debugPalette.dismiss(); +} + void tst_QApplication::allWidgets() { int argc = 1; diff --git a/tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp b/tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp index ca002a1375..c73b9725b2 100644 --- a/tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp +++ b/tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp @@ -289,7 +289,6 @@ void tst_QStackedLayout::keepFocusAfterSetCurrent() stackLayout->setCurrentIndex(0); testWidget->show(); - QApplicationPrivate::setActiveWindow(testWidget); QVERIFY(QTest::qWaitForWindowActive(testWidget)); edit1->setFocus(); diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 94bf9fff5c..666cb70da9 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -319,6 +319,7 @@ private slots: void renderTargetOffset(); void renderInvisible(); void renderWithPainter(); + void renderRTL(); void render_task188133(); void render_task211796(); void render_task217815(); @@ -476,6 +477,10 @@ private slots: void reparentWindowHandles_data(); void reparentWindowHandles(); +#ifndef QT_NO_CONTEXTMENU + void contextMenuTrigger(); +#endif + private: const QString m_platform; QSize m_testWidgetSize; @@ -1897,6 +1902,7 @@ void tst_QWidget::focusChainOnReparent() } QWidget window2; + child22->setParent(child21); child2->setParent(&window2); QWidget *expectedNewChain[5] = {&window2, child2, child21, child22, &window2}; @@ -8474,6 +8480,47 @@ void tst_QWidget::renderWithPainter() QCOMPARE(painter.renderHints(), oldRenderHints); } +void tst_QWidget::renderRTL() +{ + QFont f; + f.setStyleStrategy(QFont::NoAntialias); + const QScopedPointer<QStyle> style(QStyleFactory::create(QLatin1String("Windows"))); + + QMenu menu; + menu.setMinimumWidth(200); + menu.setFont(f); + menu.setStyle(style.data()); + menu.addAction("I"); + menu.show(); + menu.setLayoutDirection(Qt::LeftToRight); + QVERIFY(QTest::qWaitForWindowExposed(&menu)); + + QImage imageLTR(menu.size(), QImage::Format_ARGB32); + menu.render(&imageLTR); + //imageLTR.save("/tmp/rendered_1.png"); + + menu.setLayoutDirection(Qt::RightToLeft); + QImage imageRTL(menu.size(), QImage::Format_ARGB32); + menu.render(&imageRTL); + imageRTL = imageRTL.mirrored(true, false); + //imageRTL.save("/tmp/rendered_2.png"); + + QCOMPARE(imageLTR.height(), imageRTL.height()); + QCOMPARE(imageLTR.width(), imageRTL.width()); + static constexpr auto border = 4; + for (int h = border; h < imageRTL.height() - border; ++h) { + // there should be no difference on the right (aka no text) + for (int w = imageRTL.width() / 2; w < imageRTL.width() - border; ++w) { + auto pixLTR = imageLTR.pixel(w, h); + auto pixRTL = imageRTL.pixel(w, h); + if (pixLTR != pixRTL) + qDebug() << "Pixel do not match at" << w << h << ":" + << Qt::hex << pixLTR << "<->" << pixRTL; + QCOMPARE(pixLTR, pixRTL); + } + } +} + void tst_QWidget::render_task188133() { QMainWindow mainWindow; @@ -11107,6 +11154,10 @@ void tst_QWidget::hoverPosition() QVERIFY(QTest::qWaitForWindowExposed(&root)); const QPoint middle(50, 50); + // wait until we got the correct global pos + QPoint expectedGlobalPos = root.geometry().topLeft() + QPoint(100, 100) + middle; + if (!QTest::qWaitFor([&]{ return expectedGlobalPos == h.mapToGlobal(middle); })) + QSKIP("Can't move cursor"); QPoint curpos = h.mapToGlobal(middle); QCursor::setPos(curpos); if (!QTest::qWaitFor([curpos]{ return QCursor::pos() == curpos; })) @@ -13998,5 +14049,41 @@ void tst_QWidget::reparentWindowHandles() } } +#ifndef QT_NO_CONTEXTMENU +void tst_QWidget::contextMenuTrigger() +{ + class ContextMenuWidget : public QWidget + { + public: + int events = 0; + + protected: + void contextMenuEvent(QContextMenuEvent *) override { ++events; } + }; + + const Qt::ContextMenuTrigger wasTrigger = QGuiApplication::styleHints()->contextMenuTrigger(); + auto restoreTriggerGuard = qScopeGuard([wasTrigger]{ + QGuiApplication::styleHints()->setContextMenuTrigger(wasTrigger); + }); + + ContextMenuWidget widget; + widget.show(); + QVERIFY(!qApp->topLevelWindows().empty()); + auto *window = qApp->topLevelWindows()[0]; + QVERIFY(window); + QCOMPARE(widget.events, 0); + QGuiApplication::styleHints()->setContextMenuTrigger(Qt::ContextMenuTrigger::Press); + QTest::mousePress(window, Qt::RightButton); + QCOMPARE(widget.events, 1); + QTest::mouseRelease(window, Qt::RightButton); + QCOMPARE(widget.events, 1); + QGuiApplication::styleHints()->setContextMenuTrigger(Qt::ContextMenuTrigger::Release); + QTest::mousePress(window, Qt::RightButton); + QCOMPARE(widget.events, 1); + QTest::mouseRelease(window, Qt::RightButton); + QCOMPARE(widget.events, 2); +} +#endif + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index 63a432578e..88a7057d2e 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -96,6 +96,20 @@ private: QPointer<QDockWidget> &d1, QPointer<QDockWidget> &d2, QList<int> &path1, QList<int> &path2) const; +#if defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID) || defined(Q_OS_QNX) +#define qCreateFloatingTabs(mainWindow, centralWidget, d1, d2, path1, path2)\ + mainWindow = nullptr;\ + Q_UNUSED(path1);\ + Q_UNUSED(path2);\ + QSKIP("Platform not supported"); +#else +#define qCreateFloatingTabs(mainWindow, centralWidget, d1, d2, path1, path2)\ + createFloatingTabs(mainWindow, centralWidget, d1, d2, path1, path2);\ + std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);\ + if (!platformSupportingRaise)\ + QSKIP("Platform not supporting raise(). Floating tab based tests will fail.") +#endif + static inline QPoint dragPoint(QDockWidget* dockWidget); static inline QPoint home1(QMainWindow* MainWindow) { return MainWindow->mapToGlobal(MainWindow->rect().topLeft() + QPoint(0.1 * MainWindow->width(), 0.1 * MainWindow->height())); } @@ -447,6 +461,23 @@ void tst_QDockWidget::setFloating() dw.setFloating(dw.isFloating()); QCOMPARE(spy.size(), 0); spy.clear(); + +#if defined(QT_BUILD_INTERNAL) && !defined(Q_OS_WIN) + // Check that setFloating() reparents the dock widget to the main window, + // in case it has a QDockWidgetGroupWindow parent + QPointer<QDockWidget> d1; + QPointer<QDockWidget> d2; + QPointer<QWidget> cent; + QMainWindow* mainWindow; + QList<int> path1; + QList<int> path2; + qCreateFloatingTabs(mainWindow, cent, d1, d2, path1, path2); + QVERIFY(qobject_cast<QDockWidgetGroupWindow *>(d1->parentWidget())); + QVERIFY(qobject_cast<QDockWidgetGroupWindow *>(d2->parentWidget())); + d1->setFloating(true); + QTRY_COMPARE(mainWindow, d1->parentWidget()); + QTRY_COMPARE(mainWindow, d2->parentWidget()); +#endif // defined(QT_BUILD_INTERNAL) && !defined(Q_OS_WIN) } void tst_QDockWidget::allowedAreas() @@ -716,6 +747,9 @@ void tst_QDockWidget::updateTabBarOnVisibilityChanged() QCOMPARE(tabBar->currentIndex(), 0); QCOMPARE(mw.tabifiedDockWidgets(dw2), {dw3}); + + mw.removeDockWidget(dw3); + QCOMPARE(mw.tabifiedDockWidgets(dw2).count(), 0); } Q_DECLARE_METATYPE(Qt::DockWidgetArea) @@ -1396,7 +1430,7 @@ void tst_QDockWidget::createFloatingTabs(QMainWindow* &mainWindow, QPointer<QWid // Test will fail if platform doesn't support raise. mainWindow->windowHandle()->handle()->raise(); if (!platformSupportingRaise) - QSKIP("Platform not supporting raise(). Floating tab based tests will fail."); + return; // remember paths to d1 and d2 QMainWindowLayout* layout = qobject_cast<QMainWindowLayout *>(mainWindow->layout()); @@ -1440,8 +1474,7 @@ void tst_QDockWidget::floatingTabs() QMainWindow* mainWindow; QList<int> path1; QList<int> path2; - createFloatingTabs(mainWindow, cent, d1, d2, path1, path2); - std::unique_ptr<QMainWindow> up_mainWindow(mainWindow); + qCreateFloatingTabs(mainWindow, cent, d1, d2, path1, path2); QCOMPARE(mainWindow->tabifiedDockWidgets(d1), {d2}); QCOMPARE(mainWindow->tabifiedDockWidgets(d2), {d1}); @@ -1494,9 +1527,13 @@ void tst_QDockWidget::floatingTabs() QTest::mouseClick(floatButton, Qt::LeftButton, Qt::KeyboardModifiers(), pos1); QTest::qWait(waitingTime); - // d1 must be floating again, while d2 is still in its GroupWindow + // d1 and d2 must be floating again QTRY_VERIFY(d1->isFloating()); - QTRY_VERIFY(!d2->isFloating()); + QTRY_VERIFY(d2->isFloating()); + + // d2 was the active tab, so d1 was not visible + QTRY_VERIFY(d1->isVisible()); + QTRY_VERIFY(d2->isVisible()); // Plug back into dock areas qCDebug(lcTestDockWidget) << "*** test plugging back to dock areas ***"; @@ -1559,8 +1596,7 @@ void tst_QDockWidget::deleteFloatingTabWithSingleDockWidget() QMainWindow* mainWindow; QList<int> path1; QList<int> path2; - createFloatingTabs(mainWindow, cent, d1, d2, path1, path2); - std::unique_ptr<QMainWindow> up_mainWindow(mainWindow); + qCreateFloatingTabs(mainWindow, cent, d1, d2, path1, path2); switch (removalReason) { case ChildRemovalReason::Destroyed: @@ -1695,6 +1731,9 @@ void tst_QDockWidget::closeAndDelete() if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Test skipped on Wayland."); #ifdef QT_BUILD_INTERNAL + if (QSysInfo::productType() == "rhel") + QSKIP("Memory leak on RHEL 9.2 QTBUG-124559", TestFailMode::Abort); + // Create a mainwindow with a central widget and two dock widgets QPointer<QDockWidget> d1; QPointer<QDockWidget> d2; @@ -1989,6 +2028,7 @@ void tst_QDockWidget::saveAndRestore() QCOMPARE(d1->isFloating(), isFloating1); QCOMPARE(d2->isFloating(), isFloating2); +#undef qCreateFloatingTabs #endif // QT_BUILD_INTERNAL } diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp index 28752cd40d..999b5cac07 100644 --- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp @@ -1154,7 +1154,6 @@ void tst_QDoubleSpinBox::taskQTBUG_5008_textFromValueAndValidate() spinbox.show(); spinbox.activateWindow(); spinbox.setFocus(); - QApplicationPrivate::setActiveWindow(&spinbox); QVERIFY(QTest::qWaitForWindowActive(&spinbox)); QCOMPARE(static_cast<QWidget *>(&spinbox), QApplication::activeWindow()); QTRY_VERIFY(spinbox.hasFocus()); diff --git a/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp index 0d716cce97..b178707e7a 100644 --- a/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp +++ b/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp @@ -462,7 +462,6 @@ void tst_QGroupBox::propagateFocus() QGroupBox box; QLineEdit lineEdit(&box); box.show(); - QApplicationPrivate::setActiveWindow(&box); QVERIFY(QTest::qWaitForWindowActive(&box)); box.setFocus(); QTRY_COMPARE(qApp->focusWidget(), static_cast<QWidget*>(&lineEdit)); diff --git a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp index 92ce1f5419..73360ae21d 100644 --- a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp +++ b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp @@ -339,7 +339,6 @@ void tst_QPushButton::setAccel() // The shortcut will not be activated unless the button is in a active // window and has focus - QApplicationPrivate::setActiveWindow(testWidget); testWidget->setFocus(); QVERIFY(QTest::qWaitForWindowActive(testWidget)); QTest::keyClick(testWidget, 'A', Qt::AltModifier); diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index dfb0f71139..27343edcde 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -927,7 +927,6 @@ void tst_QSpinBox::editingFinished() layout->addWidget(box2); testFocusWidget.show(); - QApplicationPrivate::setActiveWindow(&testFocusWidget); QVERIFY(QTest::qWaitForWindowActive(&testFocusWidget)); box->activateWindow(); box->setFocus(); @@ -1106,7 +1105,6 @@ void tst_QSpinBox::specialValue() spin.setValue(50); topWidget.show(); //make sure we have the focus (even if editingFinished fails) - QApplicationPrivate::setActiveWindow(&topWidget); topWidget.activateWindow(); QVERIFY(QTest::qWaitForWindowActive(&topWidget)); spin.setFocus(); @@ -1210,7 +1208,6 @@ void tst_QSpinBox::taskQTBUG_5008_textFromValueAndValidate() spinbox.show(); spinbox.activateWindow(); spinbox.setFocus(); - QApplicationPrivate::setActiveWindow(&spinbox); QVERIFY(QTest::qWaitForWindowActive(&spinbox)); QVERIFY(spinbox.hasFocus()); QTRY_COMPARE(static_cast<QWidget *>(&spinbox), QApplication::activeWindow()); diff --git a/tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp b/tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp index 0a1b140867..3c28ad324a 100644 --- a/tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp +++ b/tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp @@ -159,7 +159,6 @@ void tst_QStackedWidget::dynamicPages() le11->setFocus(); // set focus to second widget in the page sw->resize(200, 200); sw->show(); - QApplicationPrivate::setActiveWindow(sw); QVERIFY(QTest::qWaitForWindowActive(sw)); QTRY_COMPARE(QApplication::focusWidget(), le11); diff --git a/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp b/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp index 5d66f5922a..6dfab07fed 100644 --- a/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp +++ b/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp @@ -19,7 +19,6 @@ class TestBrowser : public QTextBrowser public: inline TestBrowser() { show(); - QApplicationPrivate::setActiveWindow(this); activateWindow(); setFocus(); QVERIFY(QTest::qWaitForWindowActive(this)); diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 0136e5b5de..ddf2bcfa85 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -2545,7 +2545,6 @@ void tst_QTextEdit::inputMethodEvent() // test that input method gets chance to commit preedit when removing focus ed->setText(""); - QApplicationPrivate::setActiveWindow(ed); QTRY_VERIFY(QApplication::focusWindow()); QCOMPARE(qApp->focusObject(), ed); diff --git a/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp b/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp index 6336b792ed..8b8c74b1e7 100644 --- a/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp +++ b/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp @@ -1022,7 +1022,6 @@ void tst_QToolBar::accel() QSignalSpy spy(action, SIGNAL(triggered(bool))); mw.show(); - QApplicationPrivate::setActiveWindow(&mw); QVERIFY(QTest::qWaitForWindowActive(&mw)); QTest::keyClick(&mw, Qt::Key_T, Qt::AltModifier); diff --git a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp index 20472861d9..b77a9c0eec 100644 --- a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp +++ b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp @@ -182,7 +182,6 @@ void tst_QToolButton::task176137_autoRepeatOfAction() label->move(0, 50); mainWidget.show(); - QApplicationPrivate::setActiveWindow(&mainWidget); QVERIFY(QTest::qWaitForWindowActive(&mainWidget)); QSignalSpy spy(&action,SIGNAL(triggered())); diff --git a/tests/auto/xml/CMakeLists.txt b/tests/auto/xml/CMakeLists.txt index 4b8cc88d78..92ac1870f6 100644 --- a/tests/auto/xml/CMakeLists.txt +++ b/tests/auto/xml/CMakeLists.txt @@ -1 +1,3 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(dom) |