/* libmisc/tests/test_assert.c - Tests for * * Copyright (C) 2024-2025 Luke T. Shumaker * SPDX-License-Identifier: AGPL-3.0-or-later */ #include #include /* for va_list, va_start(), va_end() */ #include #include #include #include #include #include #include "test.h" /* Intercept failures and logging *********************************************/ static bool global_failed; static struct fmt_buf global_log; static jmp_buf global_env; #define with_intercept() ({ \ global_failed = false; \ global_log_clear(); \ setjmp(global_env) == 0; \ }) void __lm_abort(void) { global_failed = true; longjmp(global_env, 1); } void __lm_putchar(unsigned char c) { if (global_log.len+1 >= global_log.cap) { global_log.cap += 16; global_log.dat = realloc(global_log.dat, global_log.cap); memset(global_log.dat + global_log.len, 0, global_log.cap - global_log.len); } ((uint8_t *)global_log.dat)[global_log.len++] = (uint8_t)c; } static void global_log_clear(void) { if (global_log.dat) memset(global_log.dat, 0, global_log.cap); global_log.len = 0; } #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.len == 0); \ } while (0) #define test_should_fail(test, exp_log) do { \ if (with_intercept()) { \ test; \ } \ test_assert(global_failed == true); \ if (!(global_log.len != 0 && \ strcmp(global_log.dat, exp_log) == 0)) { \ printf("exp = \"%s\"\n" \ "act = \"%s\"\n", \ exp_log, (char *)global_log.dat); \ 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"); #endif if (global_log.dat) { global_log_clear(); free(global_log.dat); global_log.dat = NULL; global_log.cap = 0; } return 0; }