diff --git a/README.md b/README.md index cc59e52..ae56c1c 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ mock_message() message(ERROR "some error message") end_mock_message() -assert_message(STATUS "some status message") -assert_message(ERROR "some error message") +assert(MESSAGE STATUS "some status message") +assert(MESSAGE ERROR "some error message") ``` ## License diff --git a/cmake/Assertion.cmake b/cmake/Assertion.cmake index 88039f7..f37ec9d 100644 --- a/cmake/Assertion.cmake +++ b/cmake/Assertion.cmake @@ -10,60 +10,86 @@ include_guard(GLOBAL) # # Refer to the documentation of the 'if' function for supported conditions to # perform the assertion. +# +# Aside from the assertions specified in the documentation of the 'if' function, +# this function also supports mocked message assertion by calling +# 'assert(MESSAGE )', where 'MODE' is the message mode +# and 'EXPECTED_MESSAGE' is the expected message. function(assert) list(LENGTH ARGN ARGUMENTS_LENGTH) if(ARGUMENTS_LENGTH GREATER 0) set(ARGUMENTS ${ARGN}) - # Determines whether the given arguments start with 'NOT'. - list(GET ARGUMENTS 0 ARGUMENTS_0) - if(ARGUMENTS_0 STREQUAL NOT) - list(REMOVE_AT ARGUMENTS 0) - set(BOOLEAN_WORD " false") - set(NOT_WORD " not") - else() - set(ARGUMENT_NOT NOT) - set(BOOLEAN_WORD " true") - endif() + list(GET ARGUMENTS 0 ASSERTION) + if(ASSERTION STREQUAL MESSAGE) + list(LENGTH ARGUMENTS ARGUMENTS_LENGTH) + if(ARGUMENTS_LENGTH LESS 3) + message(FATAL_ERROR "usage: assert(MESSAGE )") + endif() + list(GET ARGUMENTS 1 MODE) + list(GET ARGUMENTS 2 EXPECTED_MESSAGE) - list(LENGTH ARGUMENTS ARGUMENTS_LENGTH) - if(ARGUMENTS_LENGTH EQUAL 2) - list(GET ARGUMENTS 0 OPERATOR) - list(GET ARGUMENTS 1 VALUE) + list(POP_FRONT ${MODE}_MESSAGES MESSAGE) + if(NOT MESSAGE STREQUAL EXPECTED_MESSAGE) + string(TOLOWER "${MODE}" MODE) + string(REPLACE "_" " " MODE "${MODE}") + message(FATAL_ERROR "expected ${MODE} message '${MESSAGE}' to be equal to '${EXPECTED_MESSAGE}'") + endif() - if(OPERATOR STREQUAL DEFINED) - set(MESSAGE "expected variable '${VALUE}'${NOT_WORD} to be defined") - elseif(OPERATOR STREQUAL EXISTS) - set(MESSAGE "expected path '${VALUE}'${NOT_WORD} to exist") - elseif(OPERATOR STREQUAL IS_DIRECTORY) - set(MESSAGE "expected path '${VALUE}'${NOT_WORD} to be a directory") + if(DEFINED ${MODE}_MESSAGES) + set(${MODE}_MESSAGES "${${MODE}_MESSAGES}" PARENT_SCOPE) + endif() + else() + # Determines whether the given arguments start with 'NOT'. + list(GET ARGUMENTS 0 ARGUMENTS_0) + if(ARGUMENTS_0 STREQUAL NOT) + list(REMOVE_AT ARGUMENTS 0) + set(BOOLEAN_WORD " false") + set(NOT_WORD " not") + else() + set(ARGUMENT_NOT NOT) + set(BOOLEAN_WORD " true") endif() - elseif(ARGUMENTS_LENGTH EQUAL 3) - list(GET ARGUMENTS 0 LEFT_VALUE) - list(GET ARGUMENTS 1 OPERATOR) - list(GET ARGUMENTS 2 RIGHT_VALUE) - if(OPERATOR STREQUAL MATCHES) - if(DEFINED "${LEFT_VALUE}") - set(LEFT_VALUE "${${LEFT_VALUE}}") - endif() - set(MESSAGE "expected string '${LEFT_VALUE}'${NOT_WORD} to match '${RIGHT_VALUE}'") - elseif(OPERATOR STREQUAL STREQUAL) - if(DEFINED "${LEFT_VALUE}") - set(LEFT_VALUE "${${LEFT_VALUE}}") + list(LENGTH ARGUMENTS ARGUMENTS_LENGTH) + if(ARGUMENTS_LENGTH EQUAL 2) + list(GET ARGUMENTS 0 OPERATOR) + list(GET ARGUMENTS 1 VALUE) + + if(OPERATOR STREQUAL DEFINED) + set(MESSAGE "expected variable '${VALUE}'${NOT_WORD} to be defined") + elseif(OPERATOR STREQUAL EXISTS) + set(MESSAGE "expected path '${VALUE}'${NOT_WORD} to exist") + elseif(OPERATOR STREQUAL IS_DIRECTORY) + set(MESSAGE "expected path '${VALUE}'${NOT_WORD} to be a directory") endif() - if(DEFINED "${RIGHT_VALUE}") - set(RIGHT_VALUE "${${RIGHT_VALUE}}") + elseif(ARGUMENTS_LENGTH EQUAL 3) + list(GET ARGUMENTS 0 LEFT_VALUE) + list(GET ARGUMENTS 1 OPERATOR) + list(GET ARGUMENTS 2 RIGHT_VALUE) + + if(OPERATOR STREQUAL MATCHES) + if(DEFINED "${LEFT_VALUE}") + set(LEFT_VALUE "${${LEFT_VALUE}}") + endif() + set(MESSAGE "expected string '${LEFT_VALUE}'${NOT_WORD} to match '${RIGHT_VALUE}'") + elseif(OPERATOR STREQUAL STREQUAL) + if(DEFINED "${LEFT_VALUE}") + set(LEFT_VALUE "${${LEFT_VALUE}}") + endif() + if(DEFINED "${RIGHT_VALUE}") + set(RIGHT_VALUE "${${RIGHT_VALUE}}") + endif() + set(MESSAGE "expected string '${LEFT_VALUE}'${NOT_WORD} to be equal to '${RIGHT_VALUE}'") endif() - set(MESSAGE "expected string '${LEFT_VALUE}'${NOT_WORD} to be equal to '${RIGHT_VALUE}'") endif() - endif() - if(${ARGUMENT_NOT} ${ARGUMENTS}) - if(DEFINED MESSAGE) - message(FATAL_ERROR "${MESSAGE}") - else() - message(FATAL_ERROR "expected '${ARGUMENTS}' to resolve to${BOOLEAN_WORD}") + if(${ARGUMENT_NOT} ${ARGUMENTS}) + if(DEFINED MESSAGE) + message(FATAL_ERROR "${MESSAGE}") + else() + message(FATAL_ERROR "expected '${ARGUMENTS}' to resolve to${BOOLEAN_WORD}") + endif() endif() endif() endif() @@ -106,31 +132,6 @@ function(end_mock_message) set_property(GLOBAL PROPERTY message_mocked OFF) endfunction() -# Asserts whether the 'message' function was called with the expected -# arguments. -# -# This function asserts whether a message with the specified mode was called -# with the expected message content. -# -# This function can only assert calls to the mocked 'message' function, which -# is enabled by calling the 'mock_message' function. -# -# Arguments: -# - MODE: The message mode. -# - EXPECTED_MESSAGE: The expected message content. -function(assert_message MODE EXPECTED_MESSAGE) - list(POP_FRONT ${MODE}_MESSAGES MESSAGE) - if(NOT MESSAGE STREQUAL EXPECTED_MESSAGE) - string(TOLOWER "${MODE}" MODE) - string(REPLACE "_" " " MODE "${MODE}") - message(FATAL_ERROR "expected ${MODE} message '${MESSAGE}' to be equal to '${EXPECTED_MESSAGE}'") - endif() - - if(DEFINED ${MODE}_MESSAGES) - set(${MODE}_MESSAGES "${${MODE}_MESSAGES}" PARENT_SCOPE) - endif() -endfunction() - # Asserts whether the given command successfully executes a process. # # Arguments: diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fa4267f..c5cb2f8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,8 +18,8 @@ add_cmake_test( "Directory path assertions" "Regular expression match assertions" "String equality assertions" + "Message assertions" "Mock message" - "Assert messages" "Assert successful process execution" "Assert failed process execution" "Assert matching process execution output" diff --git a/test/cmake/AssertionTest.cmake b/test/cmake/AssertionTest.cmake index 3392937..e9452f0 100644 --- a/test/cmake/AssertionTest.cmake +++ b/test/cmake/AssertionTest.cmake @@ -9,12 +9,12 @@ function("Boolean assertions") mock_message() assert(FALSE) end_mock_message() - assert_message(FATAL_ERROR "expected 'FALSE' to resolve to true") + assert(MESSAGE FATAL_ERROR "expected 'FALSE' to resolve to true") mock_message() assert(NOT TRUE) end_mock_message() - assert_message(FATAL_ERROR "expected 'TRUE' to resolve to false") + assert(MESSAGE FATAL_ERROR "expected 'TRUE' to resolve to false") endfunction() function("Variable existence assertions") @@ -27,12 +27,12 @@ function("Variable existence assertions") mock_message() assert(DEFINED NON_EXISTING_VARIABLE) end_mock_message() - assert_message(FATAL_ERROR "expected variable 'NON_EXISTING_VARIABLE' to be defined") + assert(MESSAGE FATAL_ERROR "expected variable 'NON_EXISTING_VARIABLE' to be defined") mock_message() assert(NOT DEFINED EXISTING_VARIABLE) end_mock_message() - assert_message(FATAL_ERROR "expected variable 'EXISTING_VARIABLE' not to be defined") + assert(MESSAGE FATAL_ERROR "expected variable 'EXISTING_VARIABLE' not to be defined") endfunction() function("Path existence assertions") @@ -45,12 +45,12 @@ function("Path existence assertions") mock_message() assert(EXISTS non_existing_file) end_mock_message() - assert_message(FATAL_ERROR "expected path 'non_existing_file' to exist") + assert(MESSAGE FATAL_ERROR "expected path 'non_existing_file' to exist") mock_message() assert(NOT EXISTS some_file) end_mock_message() - assert_message(FATAL_ERROR "expected path 'some_file' not to exist") + assert(MESSAGE FATAL_ERROR "expected path 'some_file' not to exist") endfunction() function("Directory path assertions") @@ -63,12 +63,12 @@ function("Directory path assertions") mock_message() assert(IS_DIRECTORY some_file) end_mock_message() - assert_message(FATAL_ERROR "expected path 'some_file' to be a directory") + assert(MESSAGE FATAL_ERROR "expected path 'some_file' to be a directory") mock_message() assert(NOT IS_DIRECTORY some_directory) end_mock_message() - assert_message(FATAL_ERROR "expected path 'some_directory' not to be a directory") + assert(MESSAGE FATAL_ERROR "expected path 'some_directory' not to be a directory") endfunction() function("Regular expression match assertions") @@ -81,12 +81,12 @@ function("Regular expression match assertions") mock_message() assert(NOT "${VALUE}" MATCHES "so.*ing") end_mock_message() - assert_message(FATAL_ERROR "expected string 'some string' not to match 'so.*ing'") + assert(MESSAGE FATAL_ERROR "expected string 'some string' not to match 'so.*ing'") mock_message() assert("${VALUE}" MATCHES "so.*other.*ing") end_mock_message() - assert_message(FATAL_ERROR "expected string 'some string' to match 'so.*other.*ing'") + assert(MESSAGE FATAL_ERROR "expected string 'some string' to match 'so.*other.*ing'") endforeach() endfunction() @@ -107,14 +107,14 @@ function("String equality assertions") mock_message() assert("${LEFT_VALUE}" STREQUAL "${RIGHT_VALUE}") end_mock_message() - assert_message(FATAL_ERROR "expected string 'some string' to be equal to 'some other string'") + assert(MESSAGE FATAL_ERROR "expected string 'some string' to be equal to 'some other string'") endforeach() foreach(RIGHT_VALUE STRING_VAR "${STRING_VAR}") mock_message() assert(NOT "${LEFT_VALUE}" STREQUAL "${RIGHT_VALUE}") end_mock_message() - assert_message(FATAL_ERROR "expected string 'some string' not to be equal to 'some string'") + assert(MESSAGE FATAL_ERROR "expected string 'some string' not to be equal to 'some string'") endforeach() endforeach() endfunction() @@ -127,6 +127,27 @@ function(call_sample_messages) message(ERROR "some other error message") endfunction() +function("Message assertions") + mock_message() + call_sample_messages() + end_mock_message() + + assert(MESSAGE WARNING "some warning message") + assert(MESSAGE WARNING "some other warning message") + assert(MESSAGE ERROR "some error message") + assert(MESSAGE FATAL_ERROR "some fatal error message") + + mock_message() + assert(MESSAGE ERROR "some other error message") + end_mock_message() + assert(MESSAGE FATAL_ERROR "expected error message '' to be equal to 'some other error message'") + + mock_message() + assert(MESSAGE SOME_MODE) + end_mock_message() + assert(MESSAGE FATAL_ERROR "usage: assert(MESSAGE )") +endfunction() + function("Mock message") mock_message() call_sample_messages() @@ -144,36 +165,20 @@ function("Mock message") assert("${FATAL_ERROR_MESSAGES}" STREQUAL "some fatal error message") endfunction() -function("Assert messages") - mock_message() - call_sample_messages() - end_mock_message() - - assert_message(WARNING "some warning message") - assert_message(WARNING "some other warning message") - assert_message(ERROR "some error message") - assert_message(FATAL_ERROR "some fatal error message") - - mock_message() - assert_message(ERROR "some other error message") - end_mock_message() - assert_message(FATAL_ERROR "expected error message '' to be equal to 'some other error message'") -endfunction() - function("Assert successful process execution") assert_execute_process("${CMAKE_COMMAND}" -E true) mock_message() assert_not_execute_process("${CMAKE_COMMAND}" -E true) end_mock_message() - assert_message(FATAL_ERROR "expected command '${CMAKE_COMMAND} -E true' to fail (exit code: 0)") + assert(MESSAGE FATAL_ERROR "expected command '${CMAKE_COMMAND} -E true' to fail (exit code: 0)") endfunction() function("Assert failed process execution") mock_message() assert_execute_process("${CMAKE_COMMAND}" -E false) end_mock_message() - assert_message(FATAL_ERROR "expected command '${CMAKE_COMMAND} -E false' not to fail (exit code: 1)") + assert(MESSAGE FATAL_ERROR "expected command '${CMAKE_COMMAND} -E false' not to fail (exit code: 1)") assert_not_execute_process("${CMAKE_COMMAND}" -E false) endfunction() @@ -197,7 +202,7 @@ function("Assert non-matching process execution output") EXPECTED_OUTPUT "Hi.*!" ) end_mock_message() - assert_message(FATAL_ERROR "expected the output of command '${CMAKE_COMMAND} -E echo Hello world!' to match 'Hi.*!'") + assert(MESSAGE FATAL_ERROR "expected the output of command '${CMAKE_COMMAND} -E echo Hello world!' to match 'Hi.*!'") mock_message() assert_not_execute_process( @@ -205,7 +210,7 @@ function("Assert non-matching process execution output") EXPECTED_OUTPUT "CMake Error:.*Unavailable commands:" ) end_mock_message() - assert_message(FATAL_ERROR "expected the output of command '${CMAKE_COMMAND} -E invalid' to match 'CMake Error:.*Unavailable commands:'") + assert(MESSAGE FATAL_ERROR "expected the output of command '${CMAKE_COMMAND} -E invalid' to match 'CMake Error:.*Unavailable commands:'") endfunction() cmake_language(CALL "${TEST_COMMAND}")