From 7698b0c7774f89b8329e898b534329f7a945cbd0 Mon Sep 17 00:00:00 2001 From: Mosder Date: Tue, 13 Oct 2026 17:44:16 +0200 Subject: refactor: changed API in tester, so the output related functions use FILE * streams insted of file descriptors --- include/moslib/tester.h | 32 +++++++++++++++++++------------- src/tester.c | 20 ++++++++++++-------- tests/safe_tests.c | 20 ++++++++++---------- tests/string_tests.c | 2 +- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/include/moslib/tester.h b/include/moslib/tester.h index 838341a..d2443c5 100644 --- a/include/moslib/tester.h +++ b/include/moslib/tester.h @@ -47,21 +47,21 @@ // // You can also test if a function writes correct output. // You need to create a helper test and pass it into test_assert_out in main test. -// Pass the helper test, output stream's fd, and expected output to it. +// Pass the helper test, output stream, and expected output to it. // Example: // TEST_HELPER(helper_test) { // printf("output"); // } // TEST(main_test) { -// test_assert_out(helper_test, STDOUT_FILENO, "output"); +// test_assert_out(helper_test, stdout, "output"); // } // // If your functions have output and you want to suppress them for the sake of tests, // you can do so using suppress_output and unsupress_outputs. // Example: // TEST(error_test) { -// suppress_output(STDOUT_FILENO); -// suppress_output(STDERR_FILENO); +// suppress_output(stdout); +// suppress_output(stderr); // int code = fun_that_fails_with_output(); // unsuppress_outputs(); // test_assert(code == 0, "function didn't fail"); @@ -91,6 +91,8 @@ #ifndef MOSLIB_TESTER_H #define MOSLIB_TESTER_H +#include + #ifndef MOS_FORCE_PREFIXES #define TEST MOS_TEST @@ -166,20 +168,20 @@ extern void mos_test_assert(int expression, const char *fail_message); // function // function that is supposed to write output // -// fd -// file descriptor of stream to write the output to +// stream +// stream to write the output to // // output // expected output of the function -#define mos_test_assert_out(function, fd, output) \ - mos_test_assert_out_fn(function, fd, output, #function, #fd) +#define mos_test_assert_out(function, stream, output) \ + mos_test_assert_out_fn(function, stream, output, #function, #stream) // Suppress given output // // Arguments: -// fd -// file descriptor of output to suppress -#define mos_suppress_output(fd) mos_suppress_output_fn(fd) +// stream +// file stream to suppress +#define mos_suppress_output(stream) mos_suppress_output_fn(stream) // Unuppress previously suppressed outputs // Will unsupress all of the outputs that were suppressed @@ -216,9 +218,13 @@ extern void mos_free_tester(MosTester *tester); extern MosTestGroup *mos_add_test_group_fn(MosTester *tester, const char *group_name); extern void mos_test_assert_exit_fn(MosTestFn function, int code, const char *name); extern void mos_test_assert_out_fn( - MosTestFn function, int fd, const char *output, const char *fn_name, const char *fd_name + MosTestFn function, + FILE *stream, + const char *output, + const char *fn_name, + const char *stream_name ); -extern void mos_suppress_output_fn(int fd); +extern void mos_suppress_output_fn(FILE *stream); extern void mos_add_test_fn(MosTestGroup *group, MosTestFn test, const char *name); #endif // MOSLIB_TESTER_H diff --git a/src/tester.c b/src/tester.c index b6f6fa8..c027811 100644 --- a/src/tester.c +++ b/src/tester.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -149,19 +148,24 @@ void mos_test_assert_exit_fn(MosTestFn function, int code, const char *name) { } void mos_test_assert_out_fn( - MosTestFn function, int fd, const char *output, const char *fn_name, const char *fd_name + MosTestFn function, + FILE *stream, + const char *output, + const char *fn_name, + const char *stream_name ) { size_t n = strlen(output); char *out = mos_safe_calloc(n + 2, 1); FILE *tmp = mos_safe_tmpfile(); + int fd = fileno(stream); int og = mos_safe_dup(fd); - fflush(NULL); + fflush(stream); mos_safe_dup2(fileno(tmp), fd); function(); - fflush(NULL); + fflush(stream); lseek(fd, 0, SEEK_SET); read(fd, out, n + 1); fclose(tmp); @@ -172,26 +176,26 @@ void mos_test_assert_out_fn( if (strcmp(out, output)) { failed = 1; print_color(RED, "ASSERT FAILED: "); - printf("function %s outputed to %s:\n", fn_name, fd_name); + printf("function %s outputed to %s:\n", fn_name, stream_name); printf(" %s (capped at %zu chars)\n", out, n + 1); printf(" expected: %s\n", output); } free(out); } -void mos_suppress_output_fn(int fd) { +void mos_suppress_output_fn(FILE *stream) { if (!suppressed.outs || suppressed.n_outs >= suppressed.out_cap) { while (suppressed.n_outs >= suppressed.out_cap) suppressed.out_cap *= 2; suppressed.outs = mos_safe_realloc(suppressed.outs, suppressed.out_cap * sizeof(int)); suppressed.ogs = mos_safe_realloc(suppressed.ogs, suppressed.out_cap * sizeof(int)); } + int fd = fileno(stream); suppressed.outs[suppressed.n_outs] = fd; suppressed.ogs[suppressed.n_outs++] = mos_safe_dup(fd); - if (dev_null == NULL) { + if (dev_null == NULL) dev_null = mos_safe_tmpfile(); - } fflush(NULL); mos_safe_dup2(fileno(dev_null), fd); diff --git a/tests/safe_tests.c b/tests/safe_tests.c index 47b927d..0915550 100644 --- a/tests/safe_tests.c +++ b/tests/safe_tests.c @@ -14,7 +14,7 @@ TEST(test_safe_malloc) { void *p = safe_malloc(1024); test_assert(p != NULL, "Failed to malloc 1KiB"); - suppress_output(STDERR_FILENO); + suppress_output(stderr); test_assert_exit(malloc_exit, EXIT_FAILURE); unsuppress_outputs(); } @@ -27,7 +27,7 @@ TEST(test_safe_calloc) { void *p = safe_calloc(16, 16); test_assert(p != NULL, "Failed to calloc 16 items of 16 bytes"); - suppress_output(STDERR_FILENO); + suppress_output(stderr); test_assert_exit(calloc_exit, EXIT_FAILURE); unsuppress_outputs(); } @@ -45,7 +45,7 @@ TEST(test_safe_realloc) { p = safe_realloc(p, 4096); test_assert(p != NULL, "Failed to realloc 1KiB to 4KiB"); - suppress_output(STDERR_FILENO); + suppress_output(stderr); test_assert_exit(realloc_exit, EXIT_FAILURE); unsuppress_outputs(); } @@ -58,7 +58,7 @@ TEST(test_safe_fopen) { FILE *fp = safe_fopen(__FILE__, "r"); test_assert(fp != NULL, "Failed to fopen current file"); - suppress_output(STDERR_FILENO); + suppress_output(stderr); test_assert_exit(fopen_exit, EXIT_FAILURE); unsuppress_outputs(); } @@ -74,10 +74,10 @@ TEST_HELPER(dup_exit) { TEST(test_safe_dup) { int fd = safe_dup(STDOUT_FILENO); - test_assert(fd != -1, "Failed to dup STDOUT_FILENO"); + test_assert(fd != -1, "Failed to dup stdout"); close(fd); - suppress_output(STDERR_FILENO); + suppress_output(stderr); test_assert_exit(dup_exit, EXIT_FAILURE); unsuppress_outputs(); } @@ -88,16 +88,16 @@ TEST_HELPER(dup2_exit) { TEST(test_safe_dup2) { int res = dup2(STDOUT_FILENO, STDOUT_FILENO); - test_assert(res != -1, "Failed to dup STDOUT_FILENO 2 itself"); + test_assert(res != -1, "Failed to dup stdout 2 itself"); int fd = dup(STDOUT_FILENO); res = dup2(STDERR_FILENO, STDOUT_FILENO); - test_assert(res != -1, "Failed to dup STDERR_FILENO 2 STDOUT_FILENO"); + test_assert(res != -1, "Failed to dup stderr 2 stdout"); res = dup2(fd, STDOUT_FILENO); - test_assert(res != -1, "Failed to restore STDOUT_FILENO"); + test_assert(res != -1, "Failed to restore stdout"); close(fd); - suppress_output(STDERR_FILENO); + suppress_output(stderr); test_assert_exit(dup2_exit, EXIT_FAILURE); unsuppress_outputs(); } diff --git a/tests/string_tests.c b/tests/string_tests.c index f1009f9..7638f9b 100644 --- a/tests/string_tests.c +++ b/tests/string_tests.c @@ -43,7 +43,7 @@ TEST(ss_print_helper) { } TEST(printing) { - test_assert_out(ss_print_helper, STDOUT_FILENO, "test"); + test_assert_out(ss_print_helper, stdout, "test"); StringSlice ss = ss_from_str("slice"); char buf[16]; -- cgit v1.2.3