diff --git a/cmake/Modules/_CppUTestDiscovery.cmake b/cmake/Modules/_CppUTestDiscovery.cmake index c4e94003e..2b36a73ed 100644 --- a/cmake/Modules/_CppUTestDiscovery.cmake +++ b/cmake/Modules/_CppUTestDiscovery.cmake @@ -21,16 +21,27 @@ if(NOT EXISTS "${EXECUTABLE}") ) endif() -if(TESTS_DETAILED) - set(discovery_arg "-ln") - set(select_arg "-st") -else() - set(discovery_arg "-lg") - set(select_arg "-sg") -endif() +macro(add_test_to_script TEST_NAME TEST_LOCATION SELECT_ARG) + add_command( + add_test + "${TEST_NAME}" + ${EMULATOR} + "${EXECUTABLE}" + ${ARGS} + ${SELECT_ARG} + ${TEST_NAME} + ) + add_command( + set_tests_properties + "${TEST_NAME}" + PROPERTIES + DEF_SOURCE_LINE + "${TEST_LOCATION}" + ) +endmacro() execute_process( - COMMAND ${EMULATOR} "${EXECUTABLE}" ${discovery_arg} + COMMAND ${EMULATOR} "${EXECUTABLE}" -ll OUTPUT_VARIABLE discovered_tests RESULT_VARIABLE result ERROR_VARIABLE error @@ -41,17 +52,46 @@ if(NOT ${result} EQUAL 0) "${error}" ) endif() -separate_arguments(discovered_tests) -foreach(test_name IN LISTS discovered_tests) - add_command( - add_test - "${test_name}" - ${EMULATOR} - "${EXECUTABLE}" - ${ARGS} - ${select_arg} - ${test_name} - ) -endforeach() + +string(CONCAT LL_LINE_REGEX + "^([^.]*)" # test group + "\\." + "([^.]*)" # test name + "\\." + "(.*)" # file name (only this field is allowed to contain dots) + "\\." + "([^.]*)" # line number + "\n" +) +string(REGEX MATCHALL "[^\n]+\n" discovered_test_lines "${discovered_tests}") +if(TESTS_DETAILED) + foreach(line IN LISTS discovered_test_lines) + string(REGEX MATCH "${LL_LINE_REGEX}" __unused "${line}") + set(test_name "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}") + set(test_location "${CMAKE_MATCH_3}:${CMAKE_MATCH_4}") + add_test_to_script("${test_name}" "${test_location}" -st) + endforeach() +else() + foreach(line IN LISTS discovered_test_lines) + string(REGEX MATCH "${LL_LINE_REGEX}" __unused "${line}") + set(test_name "${CMAKE_MATCH_1}") + set(test_file "${CMAKE_MATCH_3}") + set(test_line "${CMAKE_MATCH_4}") + if (NOT _${test_name}_file) + # if the group spans two files, arbitrarily choose the first one encountered + set(_${test_name}_file "${test_file}") + set(_${test_name}_line "${test_line}") + elseif(test_file STREQUAL _${test_name}_file AND test_line LESS _${test_name}_line) + # line number will eventually be the first line of the first test in the group's file + set(_${test_name}_line ${test_line}) + endif() + list(APPEND groups_seen ${test_name}) + endforeach() + list(REMOVE_DUPLICATES groups_seen) + foreach(test_name IN LISTS groups_seen) + set(test_location "${_${test_name}_file}:${_${test_name}_line}") + add_test_to_script("${test_name}" "${test_location}" -sg) + endforeach() +endif() file(WRITE "${CTEST_FILE}" "${script}")