From 5a8d0fb80006469ec00a5a90f3e61a8d6addc84d Mon Sep 17 00:00:00 2001 From: Chris White Date: Sun, 20 Oct 2019 18:57:19 -0400 Subject: [PATCH] Fix multiline-result tests; escape backslashes Fixes: - editorconfig/editorconfig-core-test#28 - The warning at https://ci.appveyor.com/project/xuhdev/editorconfig-core-c/builds/28235086/job/u9ebs7f3b9u3gowk#L1660 Major changes: - Always use add_test(NAME ... COMMAND ...): This is for consistency - add_test(NAME ... COMMAND ...) escapes differently than add_test( ...). - Fix backslash escaping: Now that we are using the add_test(NAME ... COMMAND ...) form, backslash escaping works differently. In my tests, backslashes are not collapsed in that form. - Specify `-C Debug` on the `ctest` command line: This permits the Visual Studio generator to run tests. --- .editorconfig | 2 +- .gitignore | 5 ++++ CMakeLists.txt | 64 ++++++++++++++++++++++++++++++++--------- cli/CMakeLists.txt | 22 +++++++------- cmake/runandsort.cmake | 21 +++++++------- filetree/CMakeLists.txt | 5 ++-- glob/CMakeLists.txt | 2 +- meta/CMakeLists.txt | 8 ++++-- 8 files changed, 86 insertions(+), 43 deletions(-) diff --git a/.editorconfig b/.editorconfig index 6f73490..0a6dc95 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -[CMakeLists.txt] +[{CMakeLists.txt,*.cmake}] trim_trailing_whitespace = true indent_style = space indent_size = 4 diff --git a/.gitignore b/.gitignore index 310923b..6cad380 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,8 @@ CTestTestfile.cmake # Eclipse .project + +# Editor backup files +~* +*~ +*.swp diff --git a/CMakeLists.txt b/CMakeLists.txt index c4b771e..fa5bfe6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,9 @@ # POSSIBILITY OF SUCH DAMAGE. # +# New escape-sequence processing. +cmake_minimum_required(VERSION 3.5) +cmake_policy(VERSION 3.5.1) # Don't check any language compiler. This project is for EditorConfig Core # testing only. @@ -31,34 +34,43 @@ project(editorconfig-core-test NONE) # Where this file lives set(tests_cmakelists_dir "${CMAKE_CURRENT_LIST_DIR}") -#message(STATUS "Tests are in ${tests_cmakelists_dir}") +message(STATUS "Tests are in ${tests_cmakelists_dir}") # Only when we are using editorconfig-core-test independently should we check # cmake version, set EDITORCONFIG_CMD as cache string, and enable_testing() # here. if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) - cmake_minimum_required(VERSION 3.5) set(EDITORCONFIG_CMD "editorconfig" CACHE STRING "editorconfig command.") + set(EDITORCONFIG_CMD_IS_TARGET OFF CACHE BOOL + "EDITORCONFIG_CMD names a CMake target rather than an executable.") enable_testing() + message(STATUS "tests: Standalone testing enabled") +endif() + +if(${EDITORCONFIG_CMD_IS_TARGET}) + string(REGEX REPLACE "^=" "" EDITORCONFIG_CMD ${EDITORCONFIG_CMD}) + message(STATUS "tests: Using editorconfig target ${EDITORCONFIG_CMD}") +else() + message(STATUS "tests: Using editorconfig binary ${EDITORCONFIG_CMD}") endif() # The most common test function function(new_ec_test name ec_file src_file regex) - add_test(${name} ${EDITORCONFIG_CMD} -f ${ec_file} + add_test(NAME ${name} COMMAND ${EDITORCONFIG_CMD} -f ${ec_file} "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}") set_tests_properties(${name} PROPERTIES PASS_REGULAR_EXPRESSION "${regex}") endfunction() -# The tests that requires version specified +# A test that requires a version specified function(new_ec_test_version name ec_file src_file regex version) - add_test(${name} ${EDITORCONFIG_CMD} -b ${version} -f ${ec_file} + add_test(NAME ${name} COMMAND ${EDITORCONFIG_CMD} -b ${version} -f ${ec_file} "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}") set_tests_properties(${name} PROPERTIES PASS_REGULAR_EXPRESSION "${regex}") endfunction() -# The tests that requires the full path EditorConfig files +# A test that requires the full path to the EditorConfig files function(new_ec_test_full_ec_file_path name ec_file src_file regex) - add_test(${name} ${EDITORCONFIG_CMD} -f ${ec_file} "${src_file}") + add_test(NAME ${name} COMMAND ${EDITORCONFIG_CMD} -f ${ec_file} ${src_file}) set_tests_properties(${name} PROPERTIES PASS_REGULAR_EXPRESSION "${regex}") endfunction() @@ -67,18 +79,42 @@ endfunction() function(new_ec_test_multiline name ec_file src_file regex) #message(STATUS "Building multiline test ${name} with tests_cmakelists_dir ${tests_cmakelists_dir}") #message(STATUS "List dir ${CMAKE_CURRENT_LIST_DIR}, source dir ${CMAKE_CURRENT_SOURCE_DIR}") - add_test(${name} "cmake" - "-D" "EDITORCONFIG_CMD=${EDITORCONFIG_CMD}" - # Since variables aren't autpmatically passed to the inner cmake - "-D" "ECARGS:LIST=-f;${ec_file};${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" - # Note: the semicolons separate list elements. - "-P" "${tests_cmakelists_dir}/cmake/ec_sort.cmake") + if(${EDITORCONFIG_CMD_IS_TARGET}) + add_test(NAME ${name} COMMAND "cmake" + "-D" "EDITORCONFIG_CMD=$" + # Since variables aren't automatically passed to the inner cmake + "-D" "ECARGS:LIST=-f;${ec_file};${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" + # Note: the semicolons separate list elements. + "-P" "${tests_cmakelists_dir}/cmake/ec_sort.cmake") + else() + add_test(NAME ${name} COMMAND "cmake" + "-D" "EDITORCONFIG_CMD=${EDITORCONFIG_CMD}" + # Since variables aren't automatically passed to the inner cmake + "-D" "ECARGS:LIST=-f;${ec_file};${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" + # Note: the semicolons separate list elements. + "-P" "${tests_cmakelists_dir}/cmake/ec_sort.cmake") + endif() + set_tests_properties(${name} PROPERTIES PASS_REGULAR_EXPRESSION - "^[\n]*${regex}$") + "^[\r\n]*${regex}$") # Permit leading \n's because I can't always get rid of them using # only CMake-provided facilities. endfunction() +# Tests for other CLI arguments. Usage: +# new_ec_cli_test(NAME name MATCH pass_regex ARGS arguments...) +function(new_ec_cli_test) + # Parse args + set(one_value_keywords NAME MATCH) + set(multi_value_keywords ARGS) + cmake_parse_arguments(P + "" "${one_value_keywords}" "${multi_value_keywords}" ${ARGN}) + + # Add test + add_test(NAME ${P_NAME} COMMAND ${EDITORCONFIG_CMD} ${P_ARGS}) + set_tests_properties(${name} PROPERTIES PASS_REGULAR_EXPRESSION "${P_MATCH}") + +endfunction() # First, make sure the test harness works. add_subdirectory(meta) diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index cc22d84..573b0b5 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -27,26 +27,24 @@ # Tests for version switches # test --version option returns version information -add_test(test_long_version_switch ${EDITORCONFIG_CMD} --version) -set_tests_properties(test_long_version_switch PROPERTIES - PASS_REGULAR_EXPRESSION - "^EditorConfig.* Version [0-9]+\\.[0-9]+\\.[0-9]+(-[a-z]+)?[ \t\n\r]$") +new_ec_cli_test(NAME test_long_version_switch + ARGS --version + MATCH "^EditorConfig.* Version [0-9]+\\.[0-9]+\\.[0-9]+(-[a-z]+)?[ \t\n\r]$") # test -v option returns version information -add_test(test_short_version_switch ${EDITORCONFIG_CMD} -v) -set_tests_properties(test_short_version_switch PROPERTIES - PASS_REGULAR_EXPRESSION - "^EditorConfig.* Version [0-9]+\\.[0-9]+\\.[0-9]+(-[a-z]+)?[ \t\n\r]$") +new_ec_cli_test(NAME test_short_version_switch + ARGS -v + MATCH "^EditorConfig.* Version [0-9]+\\.[0-9]+\\.[0-9]+(-[a-z]+)?[ \t\n\r]$") # Test for multiple input files # when files are specified on command line. The files can appear in either # order in the output, but each file's output line must be grouped with its # file header. Handle this by listing both possibilities manually in the regex. -add_test(multiple_files_on_command_line ${EDITORCONFIG_CMD} -f cli.in +new_ec_cli_test(NAME multiple_files_on_command_line + ARGS -f cli.in "${CMAKE_CURRENT_SOURCE_DIR}/file1.c" - "${CMAKE_CURRENT_SOURCE_DIR}/file2.cpp") -set_tests_properties(multiple_files_on_command_line PROPERTIES - PASS_REGULAR_EXPRESSION + "${CMAKE_CURRENT_SOURCE_DIR}/file2.cpp" + MATCH "^(\\[${CMAKE_CURRENT_SOURCE_DIR}/file1.c\\][ \t]*[\n\r]+key1=value1[ \t]*[\n\r]+\\[${CMAKE_CURRENT_SOURCE_DIR}/file2.cpp\\][ \t]*[\n\r]+key2=value2)|(\\[${CMAKE_CURRENT_SOURCE_DIR}/file2.cpp\\][ \t]*[\n\r]+key2=value2[ \t]*[\n\r]+\\[${CMAKE_CURRENT_SOURCE_DIR}/file1.c\\][ \t]*[\n\r]+key1=value1)[ \t\n\r]*$" ) diff --git a/cmake/runandsort.cmake b/cmake/runandsort.cmake index 6c46794..5746fc8 100755 --- a/cmake/runandsort.cmake +++ b/cmake/runandsort.cmake @@ -68,12 +68,12 @@ function(run_and_sort) cmake_parse_arguments(P "${option_keywords}" "${one_value_keywords}" "${multi_value_keywords}" ${ARGN}) - #message(STATUS "Running ${P_CMDLINE}") + #message(STATUS "Running ${P_CMDLINE}") # DEBUG execute_process(COMMAND ${P_CMDLINE} RESULT_VARIABLE ep_retval OUTPUT_VARIABLE ep_stdout ERROR_VARIABLE ep_stderr -) + ) # Which one are we processing? if(${P_CAPTURE_STDERR}) @@ -82,8 +82,9 @@ function(run_and_sort) set(ep_out "${ep_stdout}") endif() - #message(STATUS "Got stdout =${ep_stdout}=") - #message(STATUS "Got stderr =${ep_stderr}=") + #message(STATUS "Got retval =${ep_retval}=") # DEBUG + #message(STATUS "Got stdout =${ep_stdout}=") # DEBUG + #message(STATUS "Got stderr =${ep_stderr}=") # DEBUG # Early bail on failure if(NOT("${ep_retval}" EQUAL "0")) @@ -102,30 +103,30 @@ function(run_and_sort) # Change all the semicolons in the output to \x01 string(ASCII 1 ONE) string(REPLACE ";" "${ONE}" ep_out "${ep_out}") - #message(STATUS "After escaping =${ep_out}=") + #message(STATUS "After escaping =${ep_out}=") # DEBUG # Normalize line endings, just in case string(REGEX REPLACE "\r|\n|\r\n" "\n" ep_out "${ep_out}") - #message(STATUS "After line-endings =${ep_out}=") + #message(STATUS "After line-endings =${ep_out}=") # DEBUG # Turn the string into a list string(REPLACE "\n" ";" ep_out "${ep_out}") - #message(STATUS "After listifying =${ep_out}=") + #message(STATUS "After listifying =${ep_out}=") # DEBUG # Sort the list list(SORT ep_out) # Back to individual lines string(REPLACE ";" "\n" ep_out "${ep_out}") - #message(STATUS "After back to lines =${ep_out}=") + #message(STATUS "After back to lines =${ep_out}=") # DEBUG # And back to semicolons. Note: I am not trying to reverse line endings. string(REPLACE "${ONE}" ";" ep_out "${ep_out}") - #message(STATUS "After unescaping =${ep_out}=") + #message(STATUS "After unescaping =${ep_out}=") # DEBUG # Out to the caller set(${P_RETVAL} "${ep_out}" PARENT_SCOPE) - #message(STATUS "Returned =${ep_out}=") + #message(STATUS "Returned =${ep_out}=") # DEBUG endfunction(run_and_sort) diff --git a/filetree/CMakeLists.txt b/filetree/CMakeLists.txt index 6e2018f..1d214ed 100644 --- a/filetree/CMakeLists.txt +++ b/filetree/CMakeLists.txt @@ -63,7 +63,8 @@ else(WIN32) set(path_separator_backslash_in_cmd_line_regex "^[ \t\n\r]*$") endif(WIN32) new_ec_test_full_ec_file_path(path_separator_backslash_in_cmd_line - path_separator.in "${CMAKE_CURRENT_SOURCE_DIR}\\\\path\\\\separator" + path_separator.in + "${CMAKE_CURRENT_SOURCE_DIR}\\path\\separator" ${path_separator_backslash_in_cmd_line_regex}) # Tests path separator match below top of path @@ -83,7 +84,7 @@ new_ec_test(windows_separator2 path_separator.in windows/separator2 "^[ \t\n\r]* # Globs with backslash in it but should be considered as file name on Non-Windows system if((NOT WIN32) AND (NOT CYGWIN)) - new_ec_test(backslash_not_on_windows path_separator.in "windows\\\\separator2" "^key4=value4[ \t\n\r]*$") + new_ec_test(backslash_not_on_windows path_separator.in "windows\\separator2" "^key4=value4[ \t\n\r]*$") endif() new_ec_test(path_with_special_chars path_with_special_chars.in "path_with_special_[chars/test.a" "^key=value[ \t\n\r]*$") diff --git a/glob/CMakeLists.txt b/glob/CMakeLists.txt index 98f10b9..aa8226d 100644 --- a/glob/CMakeLists.txt +++ b/glob/CMakeLists.txt @@ -179,7 +179,7 @@ new_ec_test(braces_escaped_brace3 braces.in f.txt "^closing=yes[ \t\n\r]*$") # escaped backslash new_ec_test(braces_escaped_backslash1 braces.in g.txt "^backslash=yes[ \t\n\r]*$") if((NOT WIN32) AND (NOT CYGWIN)) # this case is impossible on Windows. - new_ec_test(braces_escaped_backslash2 braces.in \\\\.txt "^backslash=yes[ \t\n\r]*$") + new_ec_test(braces_escaped_backslash2 braces.in "\\.txt" "^backslash=yes[ \t\n\r]*$") endif() new_ec_test(braces_escaped_backslash3 braces.in i.txt "^backslash=yes[ \t\n\r]*$") diff --git a/meta/CMakeLists.txt b/meta/CMakeLists.txt index 8c839c7..4115da1 100755 --- a/meta/CMakeLists.txt +++ b/meta/CMakeLists.txt @@ -37,9 +37,11 @@ message(STATUS "meta: Using editorconfig ${EDITORCONFIG_CMD}") # Test run_and_sort() add_test(meta_runandsort cmake -P "${tests_meta_cmakelists_dir}/sample.cmake") set_tests_properties(meta_runandsort PROPERTIES PASS_REGULAR_EXPRESSION - "^[\n]*0${L}a;b${L}b;c${L}b;e${L}b;f${L}c;b;a${L}d${L}$") + "^[\r\n]*0${L}a;b${L}b;c${L}b;e${L}b;f${L}c;b;a${L}d${L}$") # Have to permit leading \n's - I don't know how to get rid of them -# Test the new multiline macro on a simple case +# Test the new multiline macro on a simple case. The new_ec_test_multiline +# function adds /^[\r\n]*/ to the beginning of the provided regex, and +# /$/ to the end. new_ec_test_multiline(meta_multiline meta.in meta.c - "^[\n]*answer=42${L}$") + "answer=42${L}")