/* libmisc/tests/test_assert.c - Tests for * * Copyright (C) 2024 Luke T. Shumaker * SPDX-License-Identifier: AGPL-3.0-or-later */ #include #include #include #include #include #include "test.h" #define UNUSED(name) /* 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; \ }) __attribute__((noreturn)) void abort(void) { global_failed = true; longjmp(global_env, 1); } #define __builtin_unreachable() test_assert(0) int vprintf(const char *format, va_list ap) { return vasprintf(&global_log, format, ap); } /* 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) #define _STR(x) #x #define STR(x) _STR(x) /* Actual tests ***************************************************************/ static_assert(sizeof(char) == 1); int main() { test_should_succeed(assert(true)); test_should_fail(assert(false), "error: ASSERT: "__FILE__":"STR(__LINE__)":main(): assertion \"false\" failed\n"); test_should_succeed(assert_msg(true, "foo")); test_should_fail(assert_msg(false, "foo"), "error: ASSERT: "__FILE__":"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__":"STR(__LINE__)":main(): assertion \"false\" failed\n"); test_should_fail(assert_notreached("xxx"), "error: ASSERT: "__FILE__":"STR(__LINE__)":main(): assertion \"notreached\" failed: xxx\n"); if (global_log) { free(global_log); global_log = NULL; } return 0; }