BasisTest.cmake
Go to the documentation of this file.
00001 ############################################################################## 00002 # @file BasisTest.cmake 00003 # @brief CTest configuration. Include this module instead of CTest. 00004 # 00005 # @note This module is included by basis_project_initialize(). 00006 # 00007 # Copyright (c) 2011, 2012 University of Pennsylvania. All rights reserved.<br /> 00008 # See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file. 00009 # 00010 # Contact: SBIA Group <sbia-software at uphs.upenn.edu> 00011 # 00012 # @ingroup CMakeAPI 00013 ############################################################################## 00014 00015 # ============================================================================ 00016 # configuration 00017 # ============================================================================ 00018 00019 ## @brief Request build of tests. 00020 option (BUILD_TESTING "Request build of tests." OFF) 00021 00022 # include CTest module which enables testing, but prevent it from generating 00023 # any configuration file or adding targets yet as we want to adjust the 00024 # default CTest settings--in particular the site name--before 00025 set (RUN_FROM_DART 1) 00026 include (CTest) 00027 00028 # mark timeout option as advanced 00029 mark_as_advanced (DART_TESTING_TIMEOUT) 00030 00031 set (RUN_FROM_CTEST_OR_DART 1) 00032 include (CTestTargets) 00033 set (RUN_FROM_CTEST_OR_DART) 00034 00035 # custom CTest configuration 00036 if (EXISTS "${PROJECT_CONFIG_DIR}/CTestCustom.cmake.in") 00037 configure_file ( 00038 "${PROJECT_CONFIG_DIR}/CTestCustom.cmake.in" 00039 "${PROJECT_BINARY_DIR}/CTestCustom.cmake" 00040 @ONLY 00041 ) 00042 elseif (EXISTS "${PROJECT_CONFIG_DIR}/CTestCustom.cmake") 00043 configure_file ( 00044 "${PROJECT_CONFIG_DIR}/CTestCustom.cmake" 00045 "${PROJECT_BINARY_DIR}/CTestCustom.cmake" 00046 COPYONLY 00047 ) 00048 else () 00049 basis_get_relative_path (CONFIG_DIR "${PROJECT_SOURCE_DIR}" "${PROJECT_CONFIG_DIR}") 00050 if (EXISTS "${BASIS_TEMPLATE_DIR}/${CONFIG_DIR}/CTestCustom.cmake.in") 00051 # to avoid a Doxygen warning, we need to replace certain patterns used by 00052 # the basisproject tool to replace them with project related information 00053 # 00054 # Note: Do this only on the first pass, otherwise configure_file() will 00055 # retrigger CMake every time b/c the modification timestamp of the 00056 # source file is newer than the previously configured file. 00057 # The use of the "cmake -E copy_if_different" command could be used 00058 # here instead, but as we do not expect the CTestCustom.cmake.in 00059 # file of the BASIS project template to change, it is sufficient 00060 # to only check if we copied the template file already. 00061 if (NOT EXISTS "${PROJECT_BINARY_DIR}/CTestCustom.cmake.in") 00062 file (READ "${BASIS_TEMPLATE_DIR}/${CONFIG_DIR}/CTestCustom.cmake.in" _TEMPLATE) 00063 string (REGEX REPLACE "<year>" "" _TEMPLATE "${_TEMPLATE}") 00064 file (WRITE "${PROJECT_BINARY_DIR}/CTestCustom.cmake.in" "${_TEMPLATE}") 00065 unset (_TEMPLATE) 00066 endif () 00067 # configure the modified template file 00068 configure_file ( 00069 "${PROJECT_BINARY_DIR}/CTestCustom.cmake.in" 00070 "${PROJECT_BINARY_DIR}/CTestCustom.cmake" 00071 @ONLY 00072 ) 00073 endif () 00074 endif () 00075 00076 # ============================================================================ 00077 # constants 00078 # ============================================================================ 00079 00080 ## @brief Names of recognized properties on tests. 00081 # 00082 # Unfortunately, the @c ARGV and @c ARGN arguments of a CMake function() 00083 # or macro() does not preserve values which themselves are lists. Therefore, 00084 # it is not possible to distinguish between property names and their values 00085 # in the arguments passed to basis_set_tests_properties(). 00086 # To overcome this problem, this list specifies all the possible property names. 00087 # Everything else is considered to be a property value except the first argument 00088 # follwing right after the @c PROPERTIES keyword. Alternatively, 00089 # basis_set_property() can be used as here no disambiguity exists. 00090 # 00091 # @note Placeholders such as <CONFIG> are allowed. These are treated 00092 # as the regular expression "[^ ]+". See basis_list_to_regex(). 00093 # 00094 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#section_PropertiesonTests 00095 set (BASIS_PROPERTIES_ON_TESTS 00096 ATTACHED_FILES 00097 ATTACHED_FILES_ON_FAIL 00098 COST 00099 DEPENDS 00100 ENVIRONMENT 00101 FAIL_REGULAR_EXPRESSION 00102 LABELS 00103 MEASUREMENT 00104 PASS_REGULAR_EXPRESSION 00105 PROCESSORS 00106 REQUIRED_FILES 00107 RESOURCE_LOCK 00108 RUN_SERIAL 00109 TIMEOUT 00110 WILL_FAIL 00111 WORKING_DIRECTORY 00112 ) 00113 00114 # convert list into regular expression 00115 basis_list_to_regex (BASIS_PROPERTIES_ON_TESTS_RE ${BASIS_PROPERTIES_ON_TESTS}) 00116 00117 # ============================================================================ 00118 # utilities 00119 # ============================================================================ 00120 00121 ## @addtogroup CMakeUtilities 00122 # @{ 00123 00124 00125 # ---------------------------------------------------------------------------- 00126 ## @brief Disable testing if project does not implement any tests. 00127 # 00128 # This function checks if there are test/ subdirectories in the project and 00129 # disables and hides the BUILD_TESTING option if none are found. 00130 function (basis_disable_testing_if_no_tests) 00131 if (IS_DIRECTORY "${PROJECT_TESTING_DIR}") 00132 set (DISABLE_TESTING FALSE) 00133 else () 00134 set (DISABLE_TESTING TRUE) 00135 endif () 00136 if (DISABLE_TESTING) 00137 basis_get_relative_path (TESTING_DIR "${PROJECT_SOURCE_DIR}" "${PROJECT_TESTING_DIR}") 00138 foreach (M IN LISTS PROJECT_MODULES_ENABLED) 00139 if (IS_DIRECTORY "${MODULE_${M}_SOURCE_DIR}/${TESTING_DIR}") 00140 set (DISABLE_TESTING FALSE) 00141 break () 00142 endif () 00143 endforeach () 00144 endif () 00145 if (DISABLE_TESTING) 00146 set_property (CACHE BUILD_TESTING PROPERTY VALUE OFF) 00147 set_property (CACHE BUILD_TESTING PROPERTY TYPE INTERNAL) 00148 else () 00149 set_property (CACHE BUILD_TESTING PROPERTY TYPE BOOL) 00150 endif () 00151 endfunction () 00152 00153 # ---------------------------------------------------------------------------- 00154 ## @brief Set a property of the tests. 00155 # 00156 # This function replaces CMake's 00157 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_tests_properties"> 00158 # set_tests_properties()</a> command. 00159 # 00160 # @note Due to a bug in CMake (http://www.cmake.org/Bug/view.php?id=12303), 00161 # except of the first property given directly after the @c PROPERTIES keyword, 00162 # only properties listed in @c BASIS_PROPERTIES_ON_TESTS can be set. 00163 # 00164 # @param [in] ARGN List of arguments for 00165 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_tests_properties"> 00166 # set_tests_properties()</a>. 00167 # 00168 # @returns Sets the given properties of the specified test. 00169 # 00170 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_tests_properties 00171 # 00172 # @ingroup CMakeAPI 00173 function (basis_set_tests_properties) 00174 # convert test names to UIDs 00175 set (TEST_UIDS) 00176 list (GET ARGN 0 ARG) 00177 while (ARG AND NOT ARG MATCHES "^PROPERTIES$") 00178 basis_get_test_uid (TEST_UID "${ARG}") 00179 list (APPEND TEST_UIDS "${TEST_UID}") 00180 list (REMOVE_AT ARGN 0) 00181 list (GET ARGN 0 ARG) 00182 endwhile () 00183 if (NOT ARG MATCHES "^PROPERTIES$") 00184 message (FATAL_ERROR "Missing PROPERTIES argument!") 00185 elseif (NOT TEST_UIDS) 00186 message (FATAL_ERROR "No test specified!") 00187 endif () 00188 # remove PROPERTIES keyword 00189 list (REMOVE_AT ARGN 0) 00190 # set tests properties 00191 # 00192 # Note: By iterating over the properties, the empty property values 00193 # are correctly passed on to CMake's set_tests_properties() 00194 # command, while 00195 # set_tests_properties(${TEST_UIDS} PROPERTIES ${ARGN}) 00196 # (erroneously) discards the empty elements in ARGN. 00197 if (BASIS_DEBUG) 00198 message ("** basis_set_tests_properties:") 00199 message ("** Test(s) : ${TEST_UIDS}") 00200 message ("** Properties: [${ARGN}]") 00201 endif () 00202 list (LENGTH ARGN N) 00203 while (N GREATER 1) 00204 list (GET ARGN 0 PROPERTY) 00205 list (GET ARGN 1 VALUE) 00206 list (REMOVE_AT ARGN 0 1) 00207 list (LENGTH ARGN N) 00208 # The following loop is only required b/c CMake's ARGV and ARGN 00209 # lists do not support arguments which are themselves lists. 00210 # Therefore, we need a way to decide when the list of values for a 00211 # property is terminated. Hence, we only allow known properties 00212 # to be set, except for the first property where the name follows 00213 # directly after the PROPERTIES keyword. 00214 while (N GREATER 0) 00215 list (GET ARGN 0 ARG) 00216 if (ARG MATCHES "${BASIS_PROPERTIES_ON_TESTS_RE}") 00217 break () 00218 endif () 00219 list (APPEND VALUE "${ARG}") 00220 list (REMOVE_AT ARGN 0) 00221 list (LENGTH ARGN N) 00222 endwhile () 00223 # check property name 00224 if ("${PROPERTY}" STREQUAL "") 00225 message (FATAL_ERROR "Empty property name given!") 00226 endif () 00227 # map test names to test UIDs 00228 if (PROPERTY MATCHES "^DEPENDS$") 00229 set (UIDS) 00230 foreach (V IN LISTS VALUE) 00231 basis_get_test_uid (UID "${V}") 00232 list (APPEND UIDS "${UID}") 00233 endforeach () 00234 set (VALUE ${UIDS}) 00235 endif () 00236 # set target property 00237 if (BASIS_DEBUG) 00238 message ("** -> ${PROPERTY} = [${VALUE}]") 00239 endif () 00240 set_tests_properties (${TEST_UIDS} PROPERTIES ${PROPERTY} "${VALUE}") 00241 endwhile () 00242 # make sure that every property had a corresponding value 00243 if (NOT N EQUAL 0) 00244 message (FATAL_ERROR "No value given for test property ${ARGN}") 00245 endif () 00246 endfunction () 00247 00248 # ---------------------------------------------------------------------------- 00249 ## @brief Get a property of the test. 00250 # 00251 # This function replaces CMake's 00252 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:get_test_property"> 00253 # get_test_property()</a> command. 00254 # 00255 # @param [out] VAR Property value. 00256 # @param [in] TEST_NAME Name of test. 00257 # @param [in] ARGN Remaining arguments of 00258 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:get_test_property"> 00259 # get_test_property()</a>. 00260 # 00261 # @returns Sets @p VAR to the value of the requested property. 00262 # 00263 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:get_test_property 00264 # 00265 # @ingroup CMakeAPI 00266 function (basis_get_test_property VAR TEST_NAME) 00267 basis_get_test_uid (TEST_UID "${TEST_NAME}") 00268 get_test_property (VALUE "${TEST_UID}" ${ARGN}) 00269 set (${VAR} "${VALUE}" PARENT_SCOPE) 00270 endfunction () 00271 00272 # ---------------------------------------------------------------------------- 00273 ## @brief Create and add a test driver executable. 00274 # 00275 # @param [in] TESTDRIVER_NAME Name of the test driver. 00276 # @param [in] ARGN List of source files implementing tests. 00277 # 00278 # @ingroup CMakeAPI 00279 function (basis_add_test_driver TESTDRIVER_NAME) 00280 # parse arguments 00281 CMAKE_PARSE_ARGUMENTS ( 00282 ARGN 00283 "" 00284 "EXTRA_INCLUDE;FUNCTION" 00285 "" 00286 ${ARGN} 00287 ) 00288 if (ARGN_EXTRA_INCLUDE OR ARGN_FUNCTION) 00289 message (FATAL_ERROR "Invalid argument EXTRA_INCLUDE or FUNCTON! " 00290 "Use create_test_sourcelist() if you want to create " 00291 "a custom test driver.") 00292 endif () 00293 # choose test driver implementation depending on which packages are available 00294 set (TESTDRIVER_INCLUDE "basis/testdriver.h") 00295 set (TESTDRIVER_DEPENDS) 00296 if (ITK_FOUND) 00297 basis_include_directories (BEFORE ${ITK_INCLUDE_DIRS}) 00298 set (TESTDRIVER_LINK_DEPENDS ${ITK_LIBRARIES}) 00299 endif () 00300 if (WIN32) 00301 list (APPEND TESTDRIVER_LINK_DEPENDS Ws2_32) 00302 endif () 00303 # create test driver source code 00304 set (TESTDRIVER_SOURCE "${TESTDRIVER_NAME}") 00305 if (NOT TESTDRIVER_SOURCE MATCHES "\\.cxx") 00306 set (TESTDRIVER_SOURCE "${TESTDRIVER_SOURCE}.cxx") 00307 endif () 00308 set (CMAKE_TESTDRIVER_BEFORE_TESTMAIN " #include <basis/testdriver-before-test.inc>") 00309 set (CMAKE_TESTDRIVER_AFTER_TESTMAIN " #include <basis/testdriver-after-test.inc>") 00310 create_test_sourcelist ( 00311 TESTDRIVER_SOURCES 00312 ${TESTDRIVER_SOURCE} ${ARGN_UNPARSED_ARGUMENTS} 00313 EXTRA_INCLUDE "${TESTDRIVER_INCLUDE}" 00314 FUNCTION testdriversetup 00315 ) 00316 # add test driver executable 00317 basis_add_executable (${TESTDRIVER_NAME} ${TESTDRIVER_SOURCES}) 00318 basis_target_link_libraries (${TESTDRIVER_NAME} ${TESTDRIVER_LINK_DEPENDS}) 00319 if (ITK_FOUND) 00320 basis_set_target_properties ( 00321 ${TESTDRIVER_NAME} 00322 PROPERTIES 00323 COMPILE_DEFINITIONS 00324 TESTDRIVER_NAME=\"${TESTDRIVER_NAME}\" 00325 ITK_VERSION=\"${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH}\" 00326 ITK_VERSION_MAJOR=${ITK_VERSION_MAJOR} 00327 ) 00328 else () 00329 basis_set_target_properties ( 00330 ${TESTDRIVER_NAME} 00331 PROPERTIES 00332 COMPILE_DEFINITIONS 00333 TESTDRIVER_NAME=\"${TESTDRIVER_NAME}\" 00334 ) 00335 endif () 00336 endfunction () 00337 00338 # ---------------------------------------------------------------------------- 00339 ## @brief Add test. 00340 # 00341 # This command is used similar to CMake's 00342 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_test"> 00343 # add_test()</a> command. It adds a test to the 00344 # <a href="http://www.cmake.org/cmake/help/ctest-2-8-docs.html">CTest</a>-based 00345 # testing system. Unlike CMake's 00346 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_test"> 00347 # add_test()</a>, this command can, for convenience, implicitly add 00348 # the necessary executable build target to the build system. Therefore, 00349 # instead of the name of the executable command, specify the sources of the 00350 # test implementation. An executable build target is then added by this 00351 # function using basis_add_executable(), and the built executable is used 00352 # as test command. If the @p UNITTEST option is given, the necessary unit 00353 # testing libraries which are part of the BASIS installation are added as 00354 # link dependencies as well as the default implementation of the main() 00355 # function if none of the specified source files has the suffix 00356 # <tt>-main</tt> or <tt>_main</tt> in the file name. 00357 # 00358 # Generator expressions as supported by CMake's 00359 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_test"> 00360 # add_test()</a> command are also supported by basis_add_test() as arguments of 00361 # the test command. For the argument specifying the test command itself, however, 00362 # only the generator expression $<TARGET_FILE:tgt> is allowed. Alternatively, 00363 # for this special argument, the name of the executable target can be supplied 00364 # directly without the use of the $<TARGET_FILE:tgt> generator expression. 00365 # See documentation of basis_process_generator_expressions() for details on 00366 # the supported generator expressions. 00367 # 00368 # Example: 00369 # @code 00370 # basis_add_test (COMMAND $<TARGET_FILE:basis.testdriver> $<TARGET_FILE:myexe> ...) 00371 # basis_add_test (COMMAND basis.testdriver $<TARGET_FILE:myexe> ...) 00372 # @endcode 00373 # 00374 # @param [in] TEST_NAME Name of the test. If a source file is given 00375 # as first argument, the test name is derived 00376 # from the name of this source file and the source 00377 # file is added to the list of sources which implement 00378 # the test command. 00379 # @param [in] ARGN The following parameters are parsed: 00380 # @par 00381 # <table border="0"> 00382 # <tr> 00383 # @tp @b COMMAND cmd [arg1 [arg2 ...]] @endtp 00384 # <td>The command to execute and optionally its arguments. The command 00385 # can be the name of an executable target (including imported targets), 00386 # or the name or path of an executable. Alternatively, 00387 # a test can be build from sources and the build executable 00388 # used as command. In this case, specify the sources using the 00389 # @p SOURCES argument. The command name @c cmd if given is used as 00390 # output name of the built executable. If you do not want to 00391 # specify the name of the output executable explicitly, but have 00392 # it derived from the @p TEST_NAME, do not specify the @p COMMAND 00393 # option and use the @p ARGS option instead to only specify the 00394 # arguments of the test command.</td> 00395 # </tr> 00396 # <tr> 00397 # @tp @b ARGS arg1 [arg2 ...] @endtp 00398 # <td>Arguments of the test command. If this option is given, the 00399 # specified arguments are appended to the arguments specified 00400 # already as part of the @p COMMAND option, if any.</td> 00401 # </tr> 00402 # <tr> 00403 # @tp @b WORKING_DIRECTORY dir @endtp 00404 # <td>The working directory of the test command. The generator expression 00405 # $<TARGET_FILE_DIR:tgt> can be used to specify a working directory 00406 # which corresponds to the output directory of a given target file. 00407 # Default: @c TESTING_OUTPUT_DIR / @p TEST_NAME. </td> 00408 # </tr> 00409 # <tr> 00410 # @tp @b CONFIGURATIONS @endtp 00411 # <td>If a CONFIGURATIONS option is given then the test will be executed 00412 # only when testing under one of the named configurations.</td> 00413 # </tr> 00414 # <tr> 00415 # @tp @b SOURCES file1 [file2 ...] @endtp 00416 # <td>The source files of the test. Use the @p UNITTEST option to specify 00417 # that the sources are an implementation of a unit test. In this case, 00418 # the default implementation of the main() function is added to the 00419 # build of the test executable. However, if this list contains a 00420 # file with the suffix <tt>-main</tt> or <tt>_main</tt> in the name, 00421 # the default implementation of the main() function is not used. 00422 # See the documentation of the @p UNITTEST option for further details.</td> 00423 # </tr> 00424 # <tr> 00425 # @tp @b LINK_DEPENDS file1|target1 [file2|target2 ...] @endtp 00426 # <td>Link dependencies of test executable build from sources.</td> 00427 # </tr> 00428 # <tr> 00429 # @tp @b NO_DEFAULT_MAIN @endtp 00430 # <td>Force that the implementation of the default main() function 00431 # is not added to unit tests even if neither of the given source 00432 # files has the suffix <tt>-main</tt> or <tt>_main</tt> in the 00433 # file name.</td> 00434 # </tr> 00435 # <tr> 00436 # @tp @b UNITTEST @endtp 00437 # <td>Specifies that the test is a unit test. In this case, the test 00438 # implementation is linked to the default unit testing framework 00439 # for the used programming language which is part of the BASIS 00440 # installation.</td> 00441 # </tr> 00442 # <tr> 00443 # @tp @b WITH_EXT @endtp 00444 # <td>Do not strip extension if test name is derived from source file name.</td> 00445 # </tr> 00446 # <tr> 00447 # @tp @b ARGN @endtp 00448 # <td>All other arguments are passed on to basis_add_executable() if 00449 # an executable target for the test is added.</td> 00450 # </tr> 00451 # </table> 00452 # 00453 # @returns Adds build target for test executable if test source files 00454 # are given and/or adds a CTest test which executes the given 00455 # test command. 00456 # 00457 # @sa basis_process_generator_expressions() 00458 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_test 00459 # 00460 # @todo Make use of ExternalData module to fetch remote test data. 00461 # 00462 # @ingroup CMakeAPI 00463 function (basis_add_test TEST_NAME) 00464 basis_sanitize_for_regex (R "${PROJECT_TESTING_DIR}") 00465 if (NOT CMAKE_CURRENT_SOURCE_DIR MATCHES "^${R}") 00466 message (FATAL_ERROR "Tests can only be added inside ${PROJECT_TESTING_DIR}!") 00467 endif () 00468 00469 # -------------------------------------------------------------------------- 00470 # parse arguments 00471 CMAKE_PARSE_ARGUMENTS ( 00472 ARGN 00473 "UNITTEST;NO_DEFAULT_MAIN;WITH_EXT;CLEAN_WORKING_DIRECTORY_BEFORE_TEST;CLEAN_WORKING_DIRECTORY_AFTER_TEST" 00474 "WORKING_DIRECTORY" 00475 "CONFIGURATIONS;SOURCES;LINK_DEPENDS;COMMAND;ARGS" 00476 ${ARGN} 00477 ) 00478 00479 if (BASIS_DEBUG AND BASIS_VERBOSE) 00480 message ("** basis_add_test():") 00481 message ("** Test: ${TEST_NAME}") 00482 message ("** Command: ${ARGN_COMMAND}") 00483 message ("** Arguments: ${ARGN_ARGS}") 00484 endif () 00485 00486 list (LENGTH ARGN_COMMAND N) 00487 if (N GREATER 1) 00488 list (GET ARGN_COMMAND 0 CMD) 00489 list (REMOVE_AT ARGN_COMMAND 0) 00490 list (APPEND ARGN_ARGS ${ARGN_COMMAND}) 00491 set (ARGN_COMMAND "${CMD}") 00492 endif () 00493 00494 # -------------------------------------------------------------------------- 00495 # test name 00496 if (NOT ARGN_COMMAND AND NOT ARGN_SOURCES) 00497 get_filename_component (ARGN_SOURCES "${TEST_NAME}" ABSOLUTE) 00498 if (ARGN_WITH_EXT) 00499 basis_get_source_target_name (TEST_NAME "${TEST_NAME}" NAME) 00500 list (APPEND ARGN_UNPARSED_ARGUMENTS WITH_EXT) # pass on to basis_add_executable() 00501 else () 00502 basis_get_source_target_name (TEST_NAME "${TEST_NAME}" NAME_WE) 00503 endif () 00504 endif () 00505 00506 basis_check_test_name ("${TEST_NAME}") 00507 basis_make_test_uid (TEST_UID "${TEST_NAME}") 00508 00509 if (BASIS_DEBUG) 00510 message ("** basis_add_test():") 00511 message ("** Name: ${TEST_NAME}") 00512 message ("** Command: ${ARGN_COMMAND}") 00513 message ("** Arguments: ${ARGN_ARGS}") 00514 message ("** Sources: ${ARGN_SOURCES}") 00515 endif () 00516 00517 # -------------------------------------------------------------------------- 00518 # build test executable 00519 set (LANGUAGE) 00520 if (ARGN_SOURCES) 00521 if (ARGN_UNITTEST) 00522 basis_get_source_language (LANGUAGE ${ARGN_SOURCES}) 00523 if (NOT ARGN_NO_DEFAULT_MAIN) 00524 foreach (SOURCE ${ARGN_SOURCES}) 00525 if (SOURCE MATCHES "-main\\.|_main\\.") 00526 set (ARGN_NO_DEFAULT_MAIN 1) 00527 break () 00528 endif () 00529 endforeach () 00530 endif () 00531 if (LANGUAGE MATCHES "CXX") 00532 if (NOT ARGN_NO_DEFAULT_MAIN) 00533 list (APPEND ARGN_LINK_DEPENDS "${BASIS_TEST_MAIN_LIBRARY}") 00534 endif () 00535 list (APPEND ARGN_LINK_DEPENDS "${BASIS_TEST_LIBRARY}") 00536 list (APPEND ARGN_LINK_DEPENDS "${CMAKE_THREAD_LIBS_INIT}") 00537 endif () 00538 endif () 00539 00540 basis_add_executable (${TEST_NAME} ${ARGN_SOURCES} ${ARGN_UNPARSED_ARGUMENTS}) 00541 if (ARGN_LINK_DEPENDS) 00542 basis_target_link_libraries (${TEST_NAME} ${ARGN_LINK_DEPENDS}) 00543 endif () 00544 00545 if (ARGN_COMMAND) 00546 basis_set_target_properties (${TEST_NAME} PROPERTIES OUTPUT_NAME ${CMD}) 00547 endif () 00548 set (ARGN_COMMAND ${TEST_NAME}) 00549 00550 if (BASIS_DEBUG) 00551 message ("** Added test executable ${TEST_UID} (${TEST_NAME})") 00552 message ("** Sources: ${ARGN_SOURCES}") 00553 message ("** Link dependencies: ${ARGN_LINK_DEPENDS}") 00554 message ("** Options: ${ARGN_UNPARSED_ARGUMENTS}") 00555 endif () 00556 endif () 00557 00558 # -------------------------------------------------------------------------- 00559 # add test 00560 message (STATUS "Adding test ${TEST_UID}...") 00561 00562 if (NOT ARGN_WORKING_DIRECTORY) 00563 set (ARGN_WORKING_DIRECTORY "${TESTING_OUTPUT_DIR}/${TEST_NAME}") 00564 endif () 00565 if (ARGN_WORKING_DIRECTORY MATCHES "^\\$<(.*):(.*)>$") 00566 if (NOT "${CMAKE_MATCH_1}" STREQUAL "TARGET_FILE_DIR") 00567 message (FATAL_ERROR "Invalid generator expression used for working directory." 00568 " Only $<TARGET_FILE_DIR:tgt> can be used as argument" 00569 " of the WORKING_DIRECTORY option.") 00570 endif () 00571 basis_get_target_location (ARGN_WORKING_DIRECTORY "${CMAKE_MATCH_2}" PATH) 00572 else () 00573 if (NOT IS_DIRECTORY "${ARGN_WORKING_DIRECTORY}") 00574 file (MAKE_DIRECTORY "${ARGN_WORKING_DIRECTORY}") 00575 endif () 00576 endif () 00577 set (OPTS "WORKING_DIRECTORY" "${ARGN_WORKING_DIRECTORY}") 00578 if (ARGN_CONFIGURATIONS) 00579 list (APPEND OPTS "CONFIGURATIONS") 00580 foreach (CONFIG ${ARGN_CONFIGURATIONS}) 00581 list (APPEND OPTS "${CONFIG}") 00582 endforeach () 00583 endif () 00584 00585 if (ARGN_COMMAND MATCHES "^\\$<(.*):(.*)>$") 00586 if (NOT "${CMAKE_MATCH_1}" STREQUAL "TARGET_FILE") 00587 message (FATAL_ERROR "Invalid generator expression used for test command." 00588 " Only $<TARGET_FILE:tgt> can be used as first" 00589 " argument of the COMMAND option.") 00590 endif () 00591 basis_get_target_location (ARGN_COMMAND "${CMAKE_MATCH_2}" ABSOLUTE) 00592 else () 00593 basis_get_target_uid (COMMAND_UID "${ARGN_COMMAND}") 00594 if (TARGET "${COMMAND_UID}") 00595 basis_get_target_location (ARGN_COMMAND "${COMMAND_UID}" ABSOLUTE) 00596 endif () 00597 endif () 00598 00599 basis_process_generator_expressions (ARGN_ARGS ${ARGN_ARGS}) 00600 00601 if (BASIS_DEBUG) 00602 message ("** Add test ${TEST_UID}") 00603 message ("** Command: ${ARGN_COMMAND}") 00604 message ("** Arguments: ${ARGN_ARGS}") 00605 message ("** Working in: ${ARGN_WORKING_DIRECTORY}") 00606 endif () 00607 00608 add_test (NAME ${TEST_UID} COMMAND ${ARGN_COMMAND} ${ARGN_ARGS} ${OPTS}) 00609 00610 # especially in case of C++ unit tests, if the linkage of the tests is done 00611 # incorrectly, no tests are actually run and the unit test passes 00612 # therefore, add this fail regular expression to identify such issues 00613 set_tests_properties (${TEST_UID} PROPERTIES FAIL_REGULAR_EXPRESSION "(\\[ *PASSED *\\]|Ran) 0 tests|No tests were found!!!") 00614 00615 message (STATUS "Adding test ${TEST_UID}... - done") 00616 endfunction () 00617 00618 # ---------------------------------------------------------------------------- 00619 ## @brief Add tests of default options for given executable. 00620 # 00621 # @par Default options: 00622 # <table border="0"> 00623 # <tr> 00624 # @tp <b>--helpshort</b> @endtp 00625 # <td>Short help. The output has to match the regular expression 00626 # "[Uu]sage:\n\s*\<executable name\>", where <executable name> 00627 # is the name of the tested executable.</td> 00628 # </tr> 00629 # <tr> 00630 # @tp <b>--help, -h</b> @endtp 00631 # <td>Help screen. Simply tests if the option is accepted.</td> 00632 # </tr> 00633 # <tr> 00634 # @tp <b>--version</b> @endtp 00635 # <td>Version information. Output has to include the project version string.</td> 00636 # </tr> 00637 # <tr> 00638 # @tp <b>--verbose, -v</b> @endtp 00639 # <td>Increase verbosity of output messages. Simply tests if the option is accepted.</td> 00640 # </tr> 00641 # </table> 00642 # 00643 # @param [in] TARGET_NAME Name of executable or script target. 00644 # 00645 # @returns Adds tests for the default options of the specified executable. 00646 function (basis_add_tests_of_default_options TARGET_NAME) 00647 basis_get_target_uid (TARGET_UID "${TARGET_NAME}") 00648 00649 message (STATUS "Adding tests of default options for ${TARGET_UID}...") 00650 00651 if (NOT TARGET "${TARGET_UID}") 00652 message (FATAL_ERROR "Unknown target ${TARGET_UID}.") 00653 endif () 00654 00655 # get executable name 00656 get_target_property (PREFIX ${TARGET_UID} "PREFIX") 00657 get_target_property (OUTPUT_NAME ${TARGET_UID} "OUTPUT_NAME") 00658 get_target_property (SUFFIX ${TARGET_UID} "SUFFIX") 00659 00660 if (NOT OUTPUT_NAME) 00661 set (EXEC_NAME "${TARGET_UID}") 00662 endif () 00663 if (PREFIX) 00664 set (EXEC_NAME "${PREFIX}${EXEC_NAME}") 00665 endif () 00666 if (SUFFIX) 00667 set (EXEC_NAME "${EXEC_NAME}${SUFFIX}") 00668 endif () 00669 00670 # get absolute path to executable 00671 get_target_property (EXEC_DIR ${TARGET_UID} "RUNTIME_OUTPUT_DIRECTORY") 00672 00673 # executable command 00674 set (EXEC_CMD "${EXEC_DIR}/${EXEC_NAME}") 00675 00676 # test option: -v 00677 basis_add_test (${EXEC}VersionS "${EXEC_CMD}" "-v") 00678 00679 set_tests_properties ( 00680 ${EXEC}VersionS 00681 PROPERTIES 00682 PASS_REGULAR_EXPRESSION "${EXEC} ${PROJECT_VERSION}" 00683 ) 00684 00685 # test option: --version 00686 basis_add_test (${EXEC}VersionL "${EXEC_CMD}" "--version") 00687 00688 set_tests_properties ( 00689 ${EXEC}VersionL 00690 PROPERTIES 00691 PASS_REGULAR_EXPRESSION "${EXEC} ${PROJECT_VERSION}" 00692 ) 00693 00694 # test option: -h 00695 basis_add_test (${EXEC}HelpS "${EXEC_CMD}" "-h") 00696 00697 # test option: --help 00698 basis_add_test (${EXEC}HelpL "${EXEC_CMD}" "--help") 00699 00700 # test option: --helpshort 00701 basis_add_test (${EXEC}UsageL "${EXEC_CMD}" "--helpshort") 00702 00703 set_tests_properties ( 00704 ${EXEC}UsageL 00705 PROPERTIES 00706 PASS_REGULAR_EXPRESSION "[Uu]sage:(\n)( )*${EXEC_NAME}" 00707 ) 00708 00709 message (STATUS "Adding tests of default options for ${EXEC}... - done") 00710 endfunction () 00711 00712 00713 ## @} 00714 # end of Doxygen group