/* libmisc/tests/test_assert.c - Tests for <libmisc/assert.h> * * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ #include <setjmp.h> #include <stdarg.h> /* for va_list, va_start(), va_end() */ #include <stdbool.h> #include <stdlib.h> #include <string.h> #include <libmisc/macro.h> #include <libmisc/assert.h> #include <libmisc/_intercept.h> #include "test.h" /* Intercept failures and logging *********************************************/ bool global_failed; char *global_log; jmp_buf global_env; #define with_intercept() ({ \ global_failed = false; \ if (global_log) \ free(global_log); \ global_log = NULL; \ setjmp(global_env) == 0; \ }) void __lm_abort(void) { global_failed = true; longjmp(global_env, 1); } int __lm_printf(const char *format, ...) { va_list va; va_start(va, format); int ret = vasprintf(&global_log, format, va); va_end(va); return ret; } #define __builtin_unreachable() test_assert(0) /* Utilities ******************************************************************/ #define test_should_succeed(test) do { \ if (with_intercept()) { \ test; \ } \ test_assert(global_failed == false); \ test_assert(global_log == NULL); \ } while (0) #define test_should_fail(test, exp_log) do { \ if (with_intercept()) { \ test; \ } \ test_assert(global_failed == true); \ if (!(global_log != NULL && \ strcmp(global_log, exp_log) == 0)) { \ printf("exp = \"%s\"\n" \ "act = \"%s\"\n", \ exp_log, global_log); \ test_assert(0); \ } \ } while (0) /* Actual tests ***************************************************************/ static_assert(sizeof(char) == 1); int main() { #ifndef NDEBUG test_should_succeed(assert(true)); test_should_fail(assert(false), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"false\" failed\n"); test_should_succeed(assert_msg(true, "foo")); test_should_fail(assert_msg(false, "foo"), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"false\" failed: foo\n"); test_should_succeed(assert_msg(true, NULL)); test_should_fail(assert_msg(false, NULL), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"false\" failed\n"); test_should_fail(assert_notreached("xxx"), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"notreached\" failed: xxx\n"); if (global_log) { free(global_log); global_log = NULL; } #endif return 0; }