CatchAddTests.cmake: Refactor into callable method

Move test discovery logic into new catch_discover_tests_impl method
and make CatchAddTests aware of whether it is being launched in
CMake's script mode.

When launched in script mode, catch_discover_tests_impl is called
passing arguments obtained from the definitions passed into the call
to cmake. This preserves the existing behavior assumed by Catch.cmake.

Looking ahead, it also allows CatchAddTests to be included in
generated files and call catch_discover_tests_impl to perform test
discovery at test runtime with the new PRE_TEST discovery mode
introduced later.
This commit is contained in:
Holger Kaelberer 2023-04-11 09:43:44 +02:00 committed by Martin Hořeňovský
parent 9a2a4eadc0
commit 4e8399d835

View File

@ -1,28 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
set(prefix "${TEST_PREFIX}")
set(suffix "${TEST_SUFFIX}")
set(spec ${TEST_SPEC})
set(extra_args ${TEST_EXTRA_ARGS})
set(properties ${TEST_PROPERTIES})
set(reporter ${TEST_REPORTER})
set(output_dir ${TEST_OUTPUT_DIR})
set(output_prefix ${TEST_OUTPUT_PREFIX})
set(output_suffix ${TEST_OUTPUT_SUFFIX})
set(dl_paths ${TEST_DL_PATHS})
set(script)
set(suite)
set(tests)
if(WIN32)
set(dl_paths_variable_name PATH)
elseif(APPLE)
set(dl_paths_variable_name DYLD_LIBRARY_PATH)
else()
set(dl_paths_variable_name LD_LIBRARY_PATH)
endif()
function(add_command NAME)
set(_args "")
# use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments
@ -38,36 +16,68 @@ function(add_command NAME)
set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
endfunction()
# Run test executable to get list of available tests
if(NOT EXISTS "${TEST_EXECUTABLE}")
message(FATAL_ERROR
"Specified test executable '${TEST_EXECUTABLE}' does not exist"
)
endif()
function(catch_discover_tests_impl)
if(dl_paths)
cmake_parse_arguments(
""
""
"TEST_EXECUTABLE;TEST_WORKING_DIR;TEST_DL_PATHS;TEST_OUTPUT_DIR;TEST_OUTPUT_PREFIX;TEST_OUTPUT_SUFFIX;TEST_PREFIX;TEST_REPORTER;TEST_SPEC;TEST_SUFFIX;TEST_LIST;CTEST_FILE"
"TEST_EXTRA_ARGS;TEST_PROPERTIES;TEST_EXECUTOR"
${ARGN}
)
set(prefix "${_TEST_PREFIX}")
set(suffix "${_TEST_SUFFIX}")
set(spec ${_TEST_SPEC})
set(extra_args ${_TEST_EXTRA_ARGS})
set(properties ${_TEST_PROPERTIES})
set(reporter ${_TEST_REPORTER})
set(output_dir ${_TEST_OUTPUT_DIR})
set(output_prefix ${_TEST_OUTPUT_PREFIX})
set(output_suffix ${_TEST_OUTPUT_SUFFIX})
set(dl_paths ${_TEST_DL_PATHS})
set(script)
set(suite)
set(tests)
if(WIN32)
set(dl_paths_variable_name PATH)
elseif(APPLE)
set(dl_paths_variable_name DYLD_LIBRARY_PATH)
else()
set(dl_paths_variable_name LD_LIBRARY_PATH)
endif()
# Run test executable to get list of available tests
if(NOT EXISTS "${_TEST_EXECUTABLE}")
message(FATAL_ERROR
"Specified test executable '${_TEST_EXECUTABLE}' does not exist"
)
endif()
if(dl_paths)
cmake_path(CONVERT "${dl_paths}" TO_NATIVE_PATH_LIST paths)
set(ENV{${dl_paths_variable_name}} "${paths}")
endif()
endif()
execute_process(
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-tests --verbosity quiet
execute_process(
COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" ${spec} --list-tests --verbosity quiet
OUTPUT_VARIABLE output
RESULT_VARIABLE result
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
)
if(NOT ${result} EQUAL 0)
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
)
if(NOT ${result} EQUAL 0)
message(FATAL_ERROR
"Error running test executable '${TEST_EXECUTABLE}':\n"
"Error running test executable '${_TEST_EXECUTABLE}':\n"
" Result: ${result}\n"
" Output: ${output}\n"
)
endif()
endif()
string(REPLACE "\n" ";" output "${output}")
string(REPLACE "\n" ";" output "${output}")
# Prepare reporter
if(reporter)
# Prepare reporter
if(reporter)
set(reporter_arg "--reporter ${reporter}")
# Run test executable to check whether reporter is available
@ -90,25 +100,25 @@ if(reporter)
" Output: ${reporter_check_output}\n"
)
endif()
endif()
endif()
# Prepare output dir
if(output_dir AND NOT IS_ABSOLUTE ${output_dir})
set(output_dir "${TEST_WORKING_DIR}/${output_dir}")
# Prepare output dir
if(output_dir AND NOT IS_ABSOLUTE ${output_dir})
set(output_dir "${_TEST_WORKING_DIR}/${output_dir}")
if(NOT EXISTS ${output_dir})
file(MAKE_DIRECTORY ${output_dir})
endif()
endif()
endif()
if(dl_paths)
if(dl_paths)
foreach(path ${dl_paths})
cmake_path(NATIVE_PATH path native_path)
list(APPEND environment_modifications "${dl_paths_variable_name}=path_list_prepend:${native_path}")
endforeach()
endif()
endif()
# Parse output
foreach(line ${output})
# Parse output
foreach(line ${output})
set(test ${line})
# Escape characters in test case names that would be parsed by Catch2
set(test_name ${test})
@ -124,8 +134,8 @@ foreach(line ${output})
# ...and add to script
add_command(add_test
"${prefix}${test}${suffix}"
${TEST_EXECUTOR}
"${TEST_EXECUTABLE}"
${_TEST_EXECUTOR}
"${_TEST_EXECUTABLE}"
"${test_name}"
${extra_args}
"${reporter_arg}"
@ -134,7 +144,7 @@ foreach(line ${output})
add_command(set_tests_properties
"${prefix}${test}${suffix}"
PROPERTIES
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
${properties}
)
@ -146,11 +156,32 @@ foreach(line ${output})
endif()
list(APPEND tests "${prefix}${test}${suffix}")
endforeach()
endforeach()
# Create a list of all discovered tests, which users may use to e.g. set
# properties on the tests
add_command(set ${TEST_LIST} ${tests})
# Create a list of all discovered tests, which users may use to e.g. set
# properties on the tests
add_command(set ${_TEST_LIST} ${tests})
# Write CTest script
file(WRITE "${CTEST_FILE}" "${script}")
# Write CTest script
file(WRITE "${_CTEST_FILE}" "${script}")
endfunction()
if(CMAKE_SCRIPT_MODE_FILE)
catch_discover_tests_impl(
TEST_EXECUTABLE ${TEST_EXECUTABLE}
TEST_EXECUTOR ${TEST_EXECUTOR}
TEST_WORKING_DIR ${TEST_WORKING_DIR}
TEST_SPEC ${TEST_SPEC}
TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS}
TEST_PROPERTIES ${TEST_PROPERTIES}
TEST_PREFIX ${TEST_PREFIX}
TEST_SUFFIX ${TEST_SUFFIX}
TEST_LIST ${TEST_LIST}
TEST_REPORTER ${TEST_REPORTER}
TEST_OUTPUT_DIR ${TEST_OUTPUT_DIR}
TEST_OUTPUT_PREFIX ${TEST_OUTPUT_PREFIX}
TEST_OUTPUT_SUFFIX ${TEST_OUTPUT_SUFFIX}
TEST_DL_PATHS ${TEST_DL_PATHS}
CTEST_FILE ${CTEST_FILE}
)
endif()