From 5fb6ca819495c833099ad5976eb52ceb8e1f8150 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 4 Jun 2016 14:35:46 +0200 Subject: [PATCH 1/5] tests/example/: Make search for template.lua explicit Previously, while recursively scanning the directory tree, the code in here also scanned for template.lua files and remembered the latest one it found. This commit adds a function which finds the right template.lua for a given file name, making this search explicit and easier to understand. Signed-off-by: Uli Schlachter --- tests/examples/CMakeLists.txt | 40 ++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/tests/examples/CMakeLists.txt b/tests/examples/CMakeLists.txt index 253a5924..3c746657 100644 --- a/tests/examples/CMakeLists.txt +++ b/tests/examples/CMakeLists.txt @@ -106,13 +106,26 @@ function(escape_code path escaped_content pre_header post_header) set(${post_header} ${example_post_header} PARENT_SCOPE) endfunction() -# Execute a lua file. -function(run_test test_path namespace template escaped_content) +# Find the template.lua that is closest to the given file. For example, if a +# template.lua is present in the same directory, its path will be returned. If +# one is present in the parent directory, that path is returned etc. +function(find_template result_variable file) + get_filename_component(path "${file}" DIRECTORY) - # A template is required to know how to handle the output. - if (template STREQUAL " ") - message(FATAL_ERROR "No template found for " ${test_path} ", bye") - endif() + while(NOT EXISTS "${path}/template.lua") + set(last_path "${path}") + get_filename_component(path "${path}" DIRECTORY) + if(last_path STREQUAL path) + message(FATAL_ERROR "Failed to find template.lua for ${file}") + endif() + endwhile() + + set(${result_variable} "${path}/template.lua" PARENT_SCOPE) +endfunction() + +# Execute a lua file. +function(run_test test_path namespace escaped_content) + find_template(template "${test_path}") # Get the file name without the extension get_filename_component(${test_path} TEST_FILE_NAME NAME) @@ -199,14 +212,7 @@ endfunction() # Recursive helper function to avoid adding CMakeLists.txt and add_subdirectory # in every sub-directories. -function(digg path namespace template) - - # Check if there is a template for this directory, else use the - # last known one. - if(EXISTS ${path}/template.lua) - message(STATUS "Testing code based on ${namespace}") - set(template ${path}/template.lua) - endif() +function(digg path namespace) # Get the directory content file(GLOB ex_files RELATIVE "${path}" @@ -216,7 +222,7 @@ function(digg path namespace template) if(IS_DIRECTORY ${path}/${ex_file_name} AND (NOT ${ex_file_name} STREQUAL "shims")) - digg("${path}/${ex_file_name}" "${namespace}_${ex_file_name}" ${template}) + digg("${path}/${ex_file_name}" "${namespace}_${ex_file_name}") elseif(${ex_file_name} MATCHES ".lua" AND NOT ${ex_file_name} MATCHES "template.lua") @@ -224,7 +230,7 @@ function(digg path namespace template) # Get the file name without the extension string(REGEX REPLACE "\\.lua" "" TEST_FILE_NAME ${ex_file_name}) - run_test("${path}/${ex_file_name}" "${namespace}" ${template} ESCAPED_CODE_EXAMPLE) + run_test("${path}/${ex_file_name}" "${namespace}" ESCAPED_CODE_EXAMPLE) # Set the test name set(TEST_NAME DOC${namespace}_${TEST_FILE_NAME}_EXAMPLE) @@ -245,7 +251,7 @@ endfunction() # the test. In parallel, build a namespace for the global variables. Those # variables will be inserted into the lua source code itself once the examples # are validated. -digg("${SOURCE_DIR}/tests/examples" "" " ") +digg("${SOURCE_DIR}/tests/examples" "") # This is ugly, but CMake variable scope system totally ignore 50 years of # computer science evolution and only support function local variables. From 77f867ff57cb230da6a268c81c520718d84066b5 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 4 Jun 2016 14:50:41 +0200 Subject: [PATCH 2/5] tests/example/: Explcitly compute namespace The namespace of e.g. "tests/examples/awful/mouse/coords.lua" is "_awful_mouse". This is purely based on the path of the file. Previously, this was computed while recursively scanning the directory tree. This commit instead moves this to an extra function that handles this task. Signed-off-by: Uli Schlachter --- tests/examples/CMakeLists.txt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/examples/CMakeLists.txt b/tests/examples/CMakeLists.txt index 3c746657..18166bc5 100644 --- a/tests/examples/CMakeLists.txt +++ b/tests/examples/CMakeLists.txt @@ -123,6 +123,16 @@ function(find_template result_variable file) set(${result_variable} "${path}/template.lua" PARENT_SCOPE) endfunction() +# Get the namespace of a file +function(get_namespace result_variable file) + get_filename_component(path "${file}" DIRECTORY) + string(LENGTH "${SOURCE_DIR}/tests/examples" prefix_length) + string(REPLACE "/" "_" namespace "${path}") + string(SUBSTRING "${namespace}" "${prefix_length}" -1 namespace) + + set(${result_variable} "${namespace}" PARENT_SCOPE) +endfunction() + # Execute a lua file. function(run_test test_path namespace escaped_content) find_template(template "${test_path}") @@ -212,7 +222,7 @@ endfunction() # Recursive helper function to avoid adding CMakeLists.txt and add_subdirectory # in every sub-directories. -function(digg path namespace) +function(digg path) # Get the directory content file(GLOB ex_files RELATIVE "${path}" @@ -222,7 +232,7 @@ function(digg path namespace) if(IS_DIRECTORY ${path}/${ex_file_name} AND (NOT ${ex_file_name} STREQUAL "shims")) - digg("${path}/${ex_file_name}" "${namespace}_${ex_file_name}") + digg("${path}/${ex_file_name}") elseif(${ex_file_name} MATCHES ".lua" AND NOT ${ex_file_name} MATCHES "template.lua") @@ -230,6 +240,8 @@ function(digg path namespace) # Get the file name without the extension string(REGEX REPLACE "\\.lua" "" TEST_FILE_NAME ${ex_file_name}) + get_namespace(namespace "${path}/${ex_file_name}") + run_test("${path}/${ex_file_name}" "${namespace}" ESCAPED_CODE_EXAMPLE) # Set the test name @@ -251,7 +263,7 @@ endfunction() # the test. In parallel, build a namespace for the global variables. Those # variables will be inserted into the lua source code itself once the examples # are validated. -digg("${SOURCE_DIR}/tests/examples" "") +digg("${SOURCE_DIR}/tests/examples") # This is ugly, but CMake variable scope system totally ignore 50 years of # computer science evolution and only support function local variables. From a7d6699d5d6a4db2d8ba9cdeb33f5603463bf901 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 4 Jun 2016 15:01:30 +0200 Subject: [PATCH 3/5] tests/example/: Replace recursion with iteration Instead of recursively walking the directory tree, this commit makes the code us GLOB_RECURSE to find all files and then handles them on after another. Signed-off-by: Uli Schlachter --- tests/examples/CMakeLists.txt | 57 ++++++++++++----------------------- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/tests/examples/CMakeLists.txt b/tests/examples/CMakeLists.txt index 18166bc5..825c36ab 100644 --- a/tests/examples/CMakeLists.txt +++ b/tests/examples/CMakeLists.txt @@ -220,50 +220,33 @@ function(run_test test_path namespace escaped_content) endfunction() -# Recursive helper function to avoid adding CMakeLists.txt and add_subdirectory -# in every sub-directories. -function(digg path) +# Find and run all test files +file(GLOB_RECURSE test_files LIST_DIRECTORIES false + "${SOURCE_DIR}/tests/examples/*.lua") +foreach(file ${test_files}) + if ((NOT "${file}" MATCHES ".*/shims/.*") + AND (NOT "${file}" MATCHES ".*/template.lua")) - # Get the directory content - file(GLOB ex_files RELATIVE "${path}" - "${path}/*") + # Get the file name without the extension + get_filename_component(TEST_FILE_NAME ${file} NAME_WE) - foreach(ex_file_name ${ex_files}) - if(IS_DIRECTORY ${path}/${ex_file_name} - AND (NOT ${ex_file_name} STREQUAL "shims")) + get_namespace(namespace "${file}") - digg("${path}/${ex_file_name}") + run_test("${file}" "${namespace}" ESCAPED_CODE_EXAMPLE) - elseif(${ex_file_name} MATCHES ".lua" - AND NOT ${ex_file_name} MATCHES "template.lua") + # Set the test name + set(TEST_NAME DOC${namespace}_${TEST_FILE_NAME}_EXAMPLE) - # Get the file name without the extension - string(REGEX REPLACE "\\.lua" "" TEST_FILE_NAME ${ex_file_name}) + # Anything called @DOC_`namespace`_EXAMPLE@ + # in the Lua or C sources will be replaced by the content if that + # variable during the pre-processing + set(ENV{${TEST_NAME}} "${ESCAPED_CODE_EXAMPLE}" CACHE INTERNAL FORCE) - get_namespace(namespace "${path}/${ex_file_name}") + # Update the test list + set(ENV{EXAMPLE_LIST} "$ENV{EXAMPLE_LIST};${TEST_NAME}") - run_test("${path}/${ex_file_name}" "${namespace}" ESCAPED_CODE_EXAMPLE) - - # Set the test name - set(TEST_NAME DOC${namespace}_${TEST_FILE_NAME}_EXAMPLE) - - # Anything called @DOC_`namespace`_EXAMPLE@ - # in the Lua or C sources will be replaced by the content if that - # variable during the pre-processing - set(ENV{${TEST_NAME}} "${ESCAPED_CODE_EXAMPLE}" CACHE INTERNAL FORCE) - - # Update the test list - set(ENV{EXAMPLE_LIST} "$ENV{EXAMPLE_LIST};${TEST_NAME}") - - endif() - endforeach() -endfunction() - -# Start at the top level then recursively explore the sub-directories to locate -# the test. In parallel, build a namespace for the global variables. Those -# variables will be inserted into the lua source code itself once the examples -# are validated. -digg("${SOURCE_DIR}/tests/examples") + endif() +endforeach() # This is ugly, but CMake variable scope system totally ignore 50 years of # computer science evolution and only support function local variables. From ca074dc689a2d36de3162587ed384e04ce8d5424 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 4 Jun 2016 15:10:34 +0200 Subject: [PATCH 4/5] tests/example/: Remove environment hack Now that tests are no longer scanned for recursively, the hack of passing values back and forth via the environment is no longer needed and can be removed. While at it, this also exchanges the "useless use of regex" for an explicit string replacement. Signed-off-by: Uli Schlachter --- tests/examples/CMakeLists.txt | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/tests/examples/CMakeLists.txt b/tests/examples/CMakeLists.txt index 825c36ab..9e347785 100644 --- a/tests/examples/CMakeLists.txt +++ b/tests/examples/CMakeLists.txt @@ -240,24 +240,10 @@ foreach(file ${test_files}) # Anything called @DOC_`namespace`_EXAMPLE@ # in the Lua or C sources will be replaced by the content if that # variable during the pre-processing - set(ENV{${TEST_NAME}} "${ESCAPED_CODE_EXAMPLE}" CACHE INTERNAL FORCE) - - # Update the test list - set(ENV{EXAMPLE_LIST} "$ENV{EXAMPLE_LIST};${TEST_NAME}") + # While at it, replace \" created by CMake by ', " wont work in + string(REPLACE "\"" "'" ${TEST_NAME} ${ESCAPED_CODE_EXAMPLE}) endif() endforeach() -# This is ugly, but CMake variable scope system totally ignore 50 years of -# computer science evolution and only support function local variables. -# PARENT_SCOPE is useless in recursive methods and the CMake pre-processor -# can't access ENV variables. So the only (insane) way is to set tons of ENV -# variables, keep track of them in yet another one and set them in the global -# scope once in the "top level" CMakeLists section (it cannot be done from -# functions). -foreach(vari $ENV{EXAMPLE_LIST}) - # While at it, replace \" created by CMake by ', " wont work in - string(REGEX REPLACE "\\\"" "'" ${vari} $ENV{${vari}}) -endforeach() - message(STATUS "All test passed!") From 7488f80be74d44ade983e88398060324b84dad4d Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 4 Jun 2016 15:14:56 +0200 Subject: [PATCH 5/5] tests/example/: Print status messages Running the tests sadly takes much to long. Since I don't have a good idea what to do about this (I'd like to run all tests in a single Lua process, but that doesn't seem to be possible easily), instead let's just make it more explicit what is being done. This commit prints a message for each test that is being run. Signed-off-by: Uli Schlachter --- tests/examples/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/examples/CMakeLists.txt b/tests/examples/CMakeLists.txt index 9e347785..7458e7ca 100644 --- a/tests/examples/CMakeLists.txt +++ b/tests/examples/CMakeLists.txt @@ -227,6 +227,9 @@ foreach(file ${test_files}) if ((NOT "${file}" MATCHES ".*/shims/.*") AND (NOT "${file}" MATCHES ".*/template.lua")) + file(RELATIVE_PATH relative_file "${SOURCE_DIR}" "${file}") + message(STATUS "Running ${relative_file}...") + # Get the file name without the extension get_filename_component(TEST_FILE_NAME ${file} NAME_WE)