From e5e542efa8ddeb84f259ad74090d9280dbe91d9b Mon Sep 17 00:00:00 2001 From: Alfi Maulana Date: Tue, 2 Jul 2024 21:13:23 +0700 Subject: [PATCH] feat: add `fail` macro --- CMakeLists.txt | 5 ++ cmake/Assertion.cmake | 150 +++++++++++++++++++----------------------- test/Fail.cmake | 7 ++ 3 files changed, 79 insertions(+), 83 deletions(-) create mode 100644 test/Fail.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ecc90c..0da438a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,11 @@ if(ASSERT_ENABLE_TESTS) COMMAND "${CMAKE_COMMAND}" -P "${ASSERTION_LIST_FILE}" -- ${CMAKE_CURRENT_SOURCE_DIR}/test/IncludeOtherModules.cmake) + add_test( + NAME "failure invocation" + COMMAND "${CMAKE_COMMAND}" -P "${ASSERTION_LIST_FILE}" + -- ${CMAKE_CURRENT_SOURCE_DIR}/test/Fail.cmake) + add_test( NAME "condition assertions" COMMAND "${CMAKE_COMMAND}" -P "${ASSERTION_LIST_FILE}" diff --git a/cmake/Assertion.cmake b/cmake/Assertion.cmake index c1c4e9d..781cab1 100644 --- a/cmake/Assertion.cmake +++ b/cmake/Assertion.cmake @@ -31,6 +31,19 @@ macro(_assert_internal_format_message OUT_VAR FIRST_LINE) endforeach() endmacro() +# Throws a formatted fatal error message. +# +# fail(...) +# +# This macro throws a fatal error message formatted from the given lines. +# +# Refer to the `_assert_internal_format_message` macro for more information on +# how the fatal error message is formatted. +macro(fail FIRST_LINE) + _assert_internal_format_message(MESSAGE "${FIRST_LINE}" ${ARGN}) + message(FATAL_ERROR "${MESSAGE}") +endmacro() + # Asserts the given condition. # # assert() @@ -45,117 +58,102 @@ function(assert) if(${ARG_UNPARSED_ARGUMENTS}) # Do nothing if the assertion succeeds. else() - string(REPLACE ";" " " ARGS "${ARG_UNPARSED_ARGUMENTS}") - _assert_internal_format_message( - MESSAGE "expected:" ARGS "to resolve to true") - if(ARGC EQUAL 2) if(NOT ARGV0 STREQUAL NOT) if(ARGV0 STREQUAL DEFINED) - _assert_internal_format_message( - MESSAGE "expected variable:" ARGV1 "to be defined") + fail("expected variable:" ARGV1 "to be defined") elseif(ARGV0 STREQUAL EXISTS) - _assert_internal_format_message( - MESSAGE "expected path:" ARGV1 "to exist") + fail("expected path:" ARGV1 "to exist") elseif(ARGV0 STREQUAL IS_DIRECTORY) - _assert_internal_format_message( - MESSAGE "expected path:" ARGV1 "to be a directory") + fail("expected path:" ARGV1 "to be a directory") + else() + set(ARGS "${ARGV0} ${ARGV1}") + fail("expected:" ARGS "to resolve to true") endif() + else() + set(ARGS "${ARGV0} ${ARGV1}") + fail("expected:" ARGS "to resolve to true") endif() elseif(ARGC EQUAL 3) if(ARGV0 STREQUAL NOT) if(ARGV1 STREQUAL DEFINED) - _assert_internal_format_message( - MESSAGE "expected variable:" ARGV2 "not to be defined") + fail("expected variable:" ARGV2 "not to be defined") elseif(ARGV1 STREQUAL EXISTS) - _assert_internal_format_message( - MESSAGE "expected path:" ARGV2 "not to exist") + fail("expected path:" ARGV2 "not to exist") elseif(ARGV1 STREQUAL IS_DIRECTORY) - _assert_internal_format_message( - MESSAGE "expected path:" ARGV2 "not to be a directory") + fail("expected path:" ARGV2 "not to be a directory") + else() + set(ARGS "${ARGV0} ${ARGV1} ${ARGV2}") + fail("expected:" ARGS "to resolve to true") endif() else() if(ARGV1 STREQUAL MATCHES) if(DEFINED "${ARGV0}") - _assert_internal_format_message( - MESSAGE "expected string:" "${ARGV0}" - "of variable:" ARGV0 - "to match:" ARGV2) + fail("expected string:" "${ARGV0}" "of variable:" ARGV0 + "to match:" ARGV2) else() - _assert_internal_format_message( - MESSAGE "expected string:" ARGV0 "to match:" ARGV2) + fail("expected string:" ARGV0 "to match:" ARGV2) endif() elseif(ARGV1 STREQUAL STREQUAL) if(DEFINED "${ARGV0}") if(DEFINED "${ARGV2}") - _assert_internal_format_message( - MESSAGE "expected string:" "${ARGV0}" - "of variable:" ARGV0 - "to be equal to string:" "${ARGV2}" - "of variable:" ARGV2) + fail("expected string:" "${ARGV0}" "of variable:" ARGV0 + "to be equal to string:" "${ARGV2}" "of variable:" ARGV2) else() - _assert_internal_format_message( - MESSAGE "expected string:" "${ARGV0}" - "of variable:" ARGV0 - "to be equal to:" ARGV2) + fail("expected string:" "${ARGV0}" "of variable:" ARGV0 + "to be equal to:" ARGV2) endif() else() if(DEFINED "${ARGV2}") - _assert_internal_format_message( - MESSAGE "expected string:" ARGV0 - "to be equal to string:" "${ARGV2}" - "of variable:" ARGV2) + fail("expected string:" ARGV0 + "to be equal to string:" "${ARGV2}" "of variable:" ARGV2) else() - _assert_internal_format_message( - MESSAGE "expected string:" ARGV0 - "to be equal to:" ARGV2) + fail("expected string:" ARGV0 "to be equal to:" ARGV2) endif() endif() + else() + set(ARGS "${ARGV0} ${ARGV1} ${ARGV2}") + fail("expected:" ARGS "to resolve to true") endif() endif() elseif(ARGC EQUAL 4) if(ARGV0 STREQUAL NOT) if(ARGV2 STREQUAL MATCHES) if(DEFINED "${ARGV1}") - _assert_internal_format_message( - MESSAGE "expected string:" "${ARGV1}" - "of variable:" ARGV1 - "not to match:" ARGV3) + fail("expected string:" "${ARGV1}" "of variable:" ARGV1 + "not to match:" ARGV3) else() - _assert_internal_format_message( - MESSAGE "expected string:" ARGV1 "not to match:" ARGV3) + fail("expected string:" ARGV1 "not to match:" ARGV3) endif() elseif(ARGV2 STREQUAL STREQUAL) if(DEFINED "${ARGV1}") if(DEFINED "${ARGV3}") - _assert_internal_format_message( - MESSAGE "expected string:" "${ARGV1}" - "of variable:" ARGV1 - "not to be equal to string:" "${ARGV3}" - "of variable:" ARGV3) + fail("expected string:" "${ARGV1}" "of variable:" ARGV1 + "not to be equal to string:" "${ARGV3}" "of variable:" ARGV3) else() - _assert_internal_format_message( - MESSAGE "expected string:" "${ARGV1}" - "of variable:" ARGV1 - "not to be equal to:" ARGV3) + fail("expected string:" "${ARGV1}" "of variable:" ARGV1 + "not to be equal to:" ARGV3) endif() else() if(DEFINED "${ARGV3}") - _assert_internal_format_message( - MESSAGE "expected string:" ARGV1 - "not to be equal to string:" "${ARGV3}" - "of variable:" ARGV3) + fail("expected string:" ARGV1 + "not to be equal to string:" "${ARGV3}" "of variable:" ARGV3) else() - _assert_internal_format_message( - MESSAGE "expected string:" ARGV1 - "not to be equal to:" ARGV3) + fail("expected string:" ARGV1 "not to be equal to:" ARGV3) endif() endif() + else() + set(ARGS "${ARGV0} ${ARGV1} ${ARGV2} ${ARGV3}") + fail("expected:" ARGS "to resolve to true") endif() + else() + set(ARGS "${ARGV0} ${ARGV1} ${ARGV2} ${ARGV3}") + fail("expected:" ARGS "to resolve to true") endif() + else() + string(REPLACE ";" " " ARGS "${ARG_UNPARSED_ARGUMENTS}") + fail("expected:" ARGS "to resolve to true") endif() - - message(FATAL_ERROR "${MESSAGE}") endif() endfunction() @@ -180,11 +178,8 @@ function(assert_fatal_error) if(EXPECTED_MESSAGE_LENGTH GREATER 0 AND ARG0 STREQUAL FATAL_ERROR) list(POP_BACK _ASSERT_INTERNAL_EXPECTED_MESSAGES EXPECTED_MESSAGE) if(NOT "${ARG_UNPARSED_ARGUMENTS}" MATCHES "${EXPECTED_MESSAGE}") - _assert_internal_format_message( - ASSERT_MESSAGE - "expected fatal error message:" ARG_UNPARSED_ARGUMENTS + fail("expected fatal error message:" ARG_UNPARSED_ARGUMENTS "to match:" EXPECTED_MESSAGE) - message(FATAL_ERROR "${ASSERT_MESSAGE}") endif() else() _message("${ARG0}" ${ARG_UNPARSED_ARGUMENTS}) @@ -236,29 +231,18 @@ function(assert_execute_process) if(DEFINED ARG_ERROR AND RES EQUAL 0) string(REPLACE ";" " " COMMAND "${ARG_COMMAND}") - _assert_internal_format_message( - MESSAGE "expected command:" COMMAND "to fail") - message(FATAL_ERROR "${MESSAGE}") + fail("expected command:" COMMAND "to fail") elseif(NOT DEFINED ARG_ERROR AND NOT RES EQUAL 0) string(REPLACE ";" " " COMMAND "${ARG_COMMAND}") - _assert_internal_format_message( - MESSAGE "expected command:" COMMAND - "not to fail with error:" ERR) - message(FATAL_ERROR "${MESSAGE}") + fail("expected command:" COMMAND "not to fail with error:" ERR) elseif(DEFINED EXPECTED_OUTPUT AND NOT "${OUT}" MATCHES "${EXPECTED_OUTPUT}") string(REPLACE ";" " " COMMAND "${ARG_COMMAND}") - _assert_internal_format_message( - MESSAGE "expected the output:" OUT - "of command:" COMMAND - "to match:" EXPECTED_OUTPUT) - message(FATAL_ERROR "${MESSAGE}") + fail("expected the output:" OUT "of command:" COMMAND + "to match:" EXPECTED_OUTPUT) elseif(DEFINED EXPECTED_ERROR AND NOT "${ERR}" MATCHES "${EXPECTED_ERROR}") string(REPLACE ";" " " COMMAND "${ARG_COMMAND}") - _assert_internal_format_message( - MESSAGE "expected the error:" ERR - "of command:" COMMAND - "to match:" EXPECTED_ERROR) - message(FATAL_ERROR "${MESSAGE}") + fail("expected the error:" ERR "of command:" COMMAND + "to match:" EXPECTED_ERROR) endif() endfunction() diff --git a/test/Fail.cmake b/test/Fail.cmake new file mode 100644 index 0000000..8e34667 --- /dev/null +++ b/test/Fail.cmake @@ -0,0 +1,7 @@ +section("it should fail with a formatted fatal error message") + set(REASON "some reason") + + assert_fatal_error( + CALL fail "something happened:" REASON + MESSAGE "something happened:\n some reason") +endsection()