diff --git a/.github/workflows/github-cxx-qt-tests.yml b/.github/workflows/github-cxx-qt-tests.yml index a80d14663..8f68dffe2 100644 --- a/.github/workflows/github-cxx-qt-tests.yml +++ b/.github/workflows/github-cxx-qt-tests.yml @@ -88,10 +88,7 @@ jobs: - name: Windows 2022 (MSVC) Qt5 os: windows-2022 qt_version: 5 - # FIXME: many tests fail to link - # https://github.com/KDAB/cxx-qt/issues/111 - # cxx_qt_lib_cargo_tests fails to run with a missing DLL error. - ctest_args: --exclude-regex '^(demo_threading_cargo_tests|example_qml.*|qml.*tests|test.*|reuse_lint|cpp_clang_format|.*valgrind|cxx_qt_lib_cargo_tests)$' + ctest_args: --exclude-regex '^(reuse_lint|cpp_clang_format|.*valgrind)$' exe_suffix: .exe qt_qpa_platform: windows compiler_cache_path: C:\Users\runneradmin\AppData\Local\Mozilla\sccache\cache @@ -103,10 +100,7 @@ jobs: - name: Windows 2022 (MSVC) Qt6 os: windows-2022 qt_version: 6 - # FIXME: many tests fail to link - # https://github.com/KDAB/cxx-qt/issues/111 - # cxx_qt_lib_cargo_tests fails to run with a missing DLL error. - ctest_args: --exclude-regex '^(demo_threading_cargo_tests|example_qml.*|qml.*tests|test.*|reuse_lint|cpp_clang_format|.*valgrind|cxx_qt_lib_cargo_tests)$' + ctest_args: --exclude-regex '^(reuse_lint|cpp_clang_format|.*valgrind)$' exe_suffix: .exe qt_qpa_platform: windows compiler_cache_path: C:\Users\runneradmin\AppData\Local\Mozilla\sccache\cache diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c7610393..e2b124f0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,9 +138,6 @@ function(add_valgrind_test NAME_WITH_PREFIX BINARY WORKING_DIRECTORY) ) endfunction() -add_subdirectory(book) -add_subdirectory(examples) - # QMAKE environment variable is needed by qt-build-utils to ensure that Cargo # uses the same installation of Qt as CMake does. if(NOT USE_QT5) @@ -150,25 +147,86 @@ if(NOT Qt6_FOUND) find_package(Qt5 5.15 COMPONENTS Core Gui Test REQUIRED) endif() get_target_property(QMAKE Qt::qmake IMPORTED_LOCATION) -set(CARGO_ENV "QMAKE=${QMAKE}") +set(CARGO_ENV "QMAKE=set:${QMAKE}") +set(RUNTIME_ENV "") + +# On windows, Qt dll needs to be in the PATH for the tests to run +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + execute_process( + COMMAND ${QMAKE} -query QT_INSTALL_BINS + OUTPUT_VARIABLE QT_INSTALL_BINS + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + execute_process( + COMMAND ${QMAKE} -query QT_INSTALL_PLUGINS + OUTPUT_VARIABLE QT_INSTALL_PLUGINS + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + execute_process( + COMMAND ${QMAKE} -query QT_INSTALL_QML + OUTPUT_VARIABLE QT_INSTALL_QML + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + list( + APPEND + RUNTIME_ENV + "PATH=path_list_append:${QT_INSTALL_BINS}" + "QT_PLUGIN_PATH=path_list_append:${QT_INSTALL_PLUGINS}" + "QML_IMPORT_PATH=path_list_append:${QT_INSTALL_QML}" + "QML2_IMPORT_PATH=path_list_append:${QT_INSTALL_QML}" + ) + list(APPEND CARGO_ENV ${RUNTIME_ENV}) +endif() # Create helper method which adds relevent cargo tests for a given manifest function(add_test_cargo TEST_NAME_PREFIX MANIFEST_PATH ADD_DOCTESTS) # Add cargo as a test - add_test(NAME ${TEST_NAME_PREFIX}_cargo_tests COMMAND cargo test --all-features --all-targets --manifest-path ${MANIFEST_PATH}) - set_property(TEST ${TEST_NAME_PREFIX}_cargo_tests PROPERTY ENVIRONMENT ${CARGO_ENV}) + set(CARGO_TEST_NAME ${TEST_NAME_PREFIX}_cargo_tests) + add_test(NAME ${CARGO_TEST_NAME} + COMMAND cargo test --all-features --all-targets --manifest-path + ${MANIFEST_PATH} + ) + set_tests_properties( + ${CARGO_TEST_NAME} PROPERTIES ENVIRONMENT_MODIFICATION "${CARGO_ENV}" + ) + # Check if we should enable doc tests - if (${ADD_DOCTESTS} STREQUAL "DOCTESTS_ON") + if(${ADD_DOCTESTS} STREQUAL "DOCTESTS_ON") + set(CARGO_DOC_TEST_NAME ${TEST_NAME_PREFIX}_cargo_doc_tests) # Add cargo docs as a test - add_test(NAME ${TEST_NAME_PREFIX}_cargo_doc_tests COMMAND cargo test --all-features --doc --manifest-path ${MANIFEST_PATH}) - set_property(TEST ${TEST_NAME_PREFIX}_cargo_doc_tests PROPERTY ENVIRONMENT ${CARGO_ENV}) + add_test(NAME ${CARGO_DOC_TEST_NAME} + COMMAND cargo test --all-features --doc --manifest-path + ${MANIFEST_PATH} + ) + set_tests_properties( + ${CARGO_DOC_TEST_NAME} PROPERTIES ENVIRONMENT_MODIFICATION + "${CARGO_ENV}" + ) endif() + # Add clippy as a test - add_test(NAME ${TEST_NAME_PREFIX}_cargo_clippy COMMAND cargo clippy --all-features --all-targets --manifest-path ${MANIFEST_PATH} -- -D warnings) - set_property(TEST ${TEST_NAME_PREFIX}_cargo_clippy PROPERTY ENVIRONMENT ${CARGO_ENV}) + set(CARGO_CLIPPY_TEST_NAME ${TEST_NAME_PREFIX}_cargo_clippy) + add_test(NAME ${CARGO_CLIPPY_TEST_NAME} + COMMAND cargo clippy --all-features --all-targets --manifest-path + ${MANIFEST_PATH} -- -D warnings + ) + set_tests_properties( + ${CARGO_CLIPPY_TEST_NAME} PROPERTIES ENVIRONMENT_MODIFICATION + "${CARGO_ENV}" + ) + # Add rustfmt as a test - add_test(NAME ${TEST_NAME_PREFIX}_cargo_fmt COMMAND cargo fmt --manifest-path ${MANIFEST_PATH} -- --check) - set_property(TEST ${TEST_NAME_PREFIX}_cargo_fmt PROPERTY ENVIRONMENT ${CARGO_ENV}) + set(CARGO_FMT_TEST_NAME ${TEST_NAME_PREFIX}_cargo_fmt) + add_test(NAME ${CARGO_FMT_TEST_NAME} COMMAND cargo fmt --manifest-path + ${MANIFEST_PATH} -- --check + ) + set_tests_properties( + ${CARGO_FMT_TEST_NAME} PROPERTIES ENVIRONMENT_MODIFICATION + "${CARGO_ENV}" + ) endfunction() # Add cargo tests for all our manifests @@ -199,4 +257,6 @@ add_test(NAME cpp_clang_format COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/clang_format # Add test which checks all files have a valid license add_test(NAME reuse_lint COMMAND reuse lint) +add_subdirectory(book) +add_subdirectory(examples) add_subdirectory(tests) diff --git a/examples/qml_extension_plugin/tests/CMakeLists.txt b/examples/qml_extension_plugin/tests/CMakeLists.txt index 80bb1ac79..f1a85df47 100644 --- a/examples/qml_extension_plugin/tests/CMakeLists.txt +++ b/examples/qml_extension_plugin/tests/CMakeLists.txt @@ -19,12 +19,27 @@ target_link_libraries(${APP_NAME} Qt::QuickTest) add_dependencies(${APP_NAME} core_qmlplugin) -set(test_cmd "./${APP_NAME}" -import "${CMAKE_CURRENT_BINARY_DIR}/../qml" -input "${CMAKE_CURRENT_SOURCE_DIR}") -add_test(NAME ${APP_NAME} +set(test_cmd + "$" + -import + "${CMAKE_CURRENT_BINARY_DIR}/../qml" + -input + "${CMAKE_CURRENT_SOURCE_DIR}" + -plugins + "$" +) + +add_test( + NAME ${APP_NAME} COMMAND ${test_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) +# RUNTIME_ENV comes from the CMakeLists.txt at the root of this repository. +set_tests_properties( + ${APP_NAME} PROPERTIES ENVIRONMENT_MODIFICATION "${RUNTIME_ENV}" +) + # TODO: Remove valgrind_additional_suppressions, there is a currently unknown issue with Qt5, # which we can't precisely suppress, so we need to suppress all conditional checks in valgrind. if(Qt5_FOUND) diff --git a/examples/qml_features/CMakeLists.txt b/examples/qml_features/CMakeLists.txt index 463c41e0d..d80f3fa4c 100644 --- a/examples/qml_features/CMakeLists.txt +++ b/examples/qml_features/CMakeLists.txt @@ -64,46 +64,28 @@ qt_import_qml_plugins(${APP_NAME}) # Unit test # -# Copy QML unit test to build folder -# this is so that our test executable can find the QML files in the same folder -function(copy_qml_test TEST_NAME) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/tst_${TEST_NAME}.qml ${CMAKE_CURRENT_BINARY_DIR}/tests/tst_${TEST_NAME}.qml COPYONLY) -endfunction() - -copy_qml_test(containers) -copy_qml_test(custom_base_class) -copy_qml_test(invokables) -copy_qml_test(multiple_qobjects) -copy_qml_test(nested_qobjects) -copy_qml_test(properties) -copy_qml_test(serialisation) -copy_qml_test(signals) -copy_qml_test(singleton) -copy_qml_test(threading) -copy_qml_test(types) -copy_qml_test(uncreatable) - -add_executable(${APP_NAME}_test - tests/main.cpp +set(APP_TEST_NAME ${APP_NAME}_test) +add_executable(${APP_TEST_NAME} tests/main.cpp) +target_include_directories(${APP_TEST_NAME} PRIVATE cpp) +target_link_libraries( + ${APP_TEST_NAME} PRIVATE ${APP_NAME}_lib Qt::Test Qt::QuickTest ) -target_include_directories(${APP_NAME}_test PRIVATE cpp) -target_link_libraries(${APP_NAME}_test PRIVATE - ${APP_NAME}_lib - Qt::Test - Qt::QuickTest -) -qt_import_qml_plugins(${APP_NAME}_test) +qt_import_qml_plugins(${APP_TEST_NAME}) -if(WIN32) - set(EXE_SUFFIX ".exe") -else() - set(EXE_SUFFIX "") -endif() +set(TEST_CMD + $ -input ${CMAKE_CURRENT_SOURCE_DIR}/tests +) -add_test(NAME ${APP_NAME}_test COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tests/${APP_NAME}_test${EXE_SUFFIX} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests) +add_test( + NAME ${APP_TEST_NAME} + COMMAND ${TEST_CMD} +) -add_valgrind_test(${APP_NAME}_test ${CMAKE_CURRENT_BINARY_DIR}/tests/${APP_NAME}_test${EXE_SUFFIX} ${CMAKE_CURRENT_BINARY_DIR}/tests) +add_valgrind_test( + ${APP_TEST_NAME} "${TEST_CMD}" ${CMAKE_CURRENT_BINARY_DIR} +) -set_target_properties(${APP_NAME}_test PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests +# RUNTIME_ENV comes from the CMakeLists.txt at the root of this repository. +set_tests_properties( + ${APP_TEST_NAME} PROPERTIES ENVIRONMENT_MODIFICATION "${RUNTIME_ENV}" ) diff --git a/examples/qml_minimal/CMakeLists.txt b/examples/qml_minimal/CMakeLists.txt index 6e2913a6d..17835f694 100644 --- a/examples/qml_minimal/CMakeLists.txt +++ b/examples/qml_minimal/CMakeLists.txt @@ -103,29 +103,32 @@ else() endif() function(add_qml_test TEST_NAME) - # Copy QML unit test to build folder - # this is so that our tst_${TEST_NAME} executable can find the QML files - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/${TEST_NAME}/tst_${TEST_NAME}.qml ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}/tst_${TEST_NAME}.qml COPYONLY) - - add_executable("${APP_NAME}_${TEST_NAME}_test" "tests/${TEST_NAME}/tst_${TEST_NAME}.cpp") - target_link_libraries(${APP_NAME}_${TEST_NAME}_test PRIVATE + set(APP_TEST_NAME ${APP_NAME}_${TEST_NAME}_test) + add_executable(${APP_TEST_NAME} tests/${TEST_NAME}/tst_${TEST_NAME}.cpp) + target_link_libraries(${APP_TEST_NAME} PRIVATE ${APP_NAME}_lib Qt::QuickTest ) - qt_import_qml_plugins(${APP_NAME}_${TEST_NAME}_test) + qt_import_qml_plugins(${APP_TEST_NAME}) - if(WIN32) - set(EXE_SUFFIX ".exe") - else() - set(EXE_SUFFIX "") - endif() + set(TEST_CMD + $ -input + ${CMAKE_CURRENT_SOURCE_DIR}/tests/${TEST_NAME}/tst_${TEST_NAME}.qml + ) - add_test(NAME ${APP_NAME}_${TEST_NAME}_test COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}/${APP_NAME}_${TEST_NAME}_test${EXE_SUFFIX} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}) + add_test( + NAME ${APP_TEST_NAME} + COMMAND ${TEST_CMD} + ) - add_valgrind_test(${APP_NAME}_${TEST_NAME}_test ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}/${APP_NAME}_${TEST_NAME}_test${EXE_SUFFIX} ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}) + # RUNTIME_ENV comes from the CMakeLists.txt at the root of this repository. + set_tests_properties( + ${APP_NAME}_${TEST_NAME}_test PROPERTIES ENVIRONMENT_MODIFICATION + "${RUNTIME_ENV}" + ) - set_target_properties(${APP_NAME}_${TEST_NAME}_test PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} + add_valgrind_test( + ${APP_TEST_NAME} "${TEST_CMD}" ${CMAKE_CURRENT_BINARY_DIR} ) endfunction() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7afac849c..6e0f6e3f9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,21 +10,26 @@ add_subdirectory(qt_types_standalone) # Create helper method which adds relevent tests for the given acceptance test function(add_acceptance_tests TEST_NAME) set(NAME_WITH_PREFIX test_${TEST_NAME}) + set(TARGET_NAME tests_${TEST_NAME}) # Add all the normal tests used on the other modules - add_test_cargo(${NAME_WITH_PREFIX} "${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}/rust/Cargo.toml" DOCTESTS_OFF) + add_test_cargo( + ${NAME_WITH_PREFIX} + "${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}/rust/Cargo.toml" DOCTESTS_OFF + ) - # The executable itself is a test that needs to be run - if(WIN32) - set(EXE_SUFFIX ".exe") - else() - set(EXE_SUFFIX "") - endif() + set(CPP_TEST_NAME ${NAME_WITH_PREFIX}_cpp_tests) + add_test(NAME ${CPP_TEST_NAME} COMMAND $) - add_test(NAME ${NAME_WITH_PREFIX}_cpp_tests COMMAND "${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}/tests_${TEST_NAME}${EXE_SUFFIX}") + set_tests_properties( + ${CPP_TEST_NAME} PROPERTIES ENVIRONMENT_MODIFICATION "${RUNTIME_ENV}" + ) # Add valgrind test - add_valgrind_test(${NAME_WITH_PREFIX} "${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}/tests_${TEST_NAME}${EXE_SUFFIX}" "${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}") + add_valgrind_test( + ${NAME_WITH_PREFIX} $ + ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} + ) endfunction() # Add tests for all the acceptance tests diff --git a/tests/basic_cxx_only/cpp/cxx_test.cpp b/tests/basic_cxx_only/cpp/cxx_test.cpp new file mode 100644 index 000000000..5db66b6f6 --- /dev/null +++ b/tests/basic_cxx_only/cpp/cxx_test.cpp @@ -0,0 +1,25 @@ +// clang-format off +// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Andrew Hayzen +// SPDX-FileContributor: Gerhard de Clercq +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +#include "cxx_test.h" + +namespace { +int hidden_num = 100; +} + +int +get_cpp_number() +{ + return hidden_num; +} + +void +set_cpp_number(int num) +{ + hidden_num = num; +} diff --git a/tests/basic_cxx_only/cpp/cxx_test.h b/tests/basic_cxx_only/cpp/cxx_test.h index 33c050028..416763cd0 100644 --- a/tests/basic_cxx_only/cpp/cxx_test.h +++ b/tests/basic_cxx_only/cpp/cxx_test.h @@ -9,3 +9,6 @@ int get_cpp_number(); + +void +set_cpp_number(int num); diff --git a/tests/basic_cxx_only/cpp/main.cpp b/tests/basic_cxx_only/cpp/main.cpp index dbae5ca9b..6120a7cfa 100644 --- a/tests/basic_cxx_only/cpp/main.cpp +++ b/tests/basic_cxx_only/cpp/main.cpp @@ -8,14 +8,7 @@ #include #include "cxx-qt-gen/ffi.cxx.h" - -int hidden_num = 100; - -int -get_cpp_number() -{ - return hidden_num; -} +#include "cxx_test.h" class CxxTest : public QObject { @@ -26,7 +19,7 @@ private Q_SLOTS: void test_cxx_interaction() { QCOMPARE(get_numbers_sum(), 102); - hidden_num = 200; + set_cpp_number(200); QCOMPARE(get_numbers_sum(), 202); } }; diff --git a/tests/basic_cxx_only/rust/build.rs b/tests/basic_cxx_only/rust/build.rs index a485c6be4..f202489a1 100644 --- a/tests/basic_cxx_only/rust/build.rs +++ b/tests/basic_cxx_only/rust/build.rs @@ -10,6 +10,10 @@ fn main() { .file("src/lib.rs") .cc_builder(|cc| { cc.include("../cpp"); + // cxx_test.cpp need to be compiled by cargo rather than CMakeLists.txt, + // otherwise linking cargo tests fails because the symbols from those files are not found. + // This to make cargo only tests work. + cc.file("../cpp/cxx_test.cpp"); }) .build(); } diff --git a/tests/basic_cxx_only/rust/src/lib.rs b/tests/basic_cxx_only/rust/src/lib.rs index 89d2c0dd1..49f7d3834 100644 --- a/tests/basic_cxx_only/rust/src/lib.rs +++ b/tests/basic_cxx_only/rust/src/lib.rs @@ -19,3 +19,13 @@ mod ffi { fn get_numbers_sum() -> i32 { ffi::get_cpp_number() + 2 } + +#[cfg(test)] +mod tests { + use super::ffi::get_cpp_number; + + #[test] + fn test_get_numbers_sum() { + assert_eq!(get_cpp_number(), 100); + } +}