aboutsummaryrefslogtreecommitdiff
path: root/src/tester.c
diff options
context:
space:
mode:
authorMosder <xmosder12@gmail.com>2026-08-21 14:41:26 +0200
committerMosder <xmosder12@gmail.com>2026-08-21 14:41:26 +0200
commit06954da1e847072f9e95df0f183d9327a0f05b5b (patch)
treebd10a6e5e960dc73d11de0b91ae73d8b6fb1a1a0 /src/tester.c
parentb6b7a01987dca604a161c8c73a240ec4430baed0 (diff)
feat: added some for safe wrappers + added ability to capture and test whether output is what was expected
Diffstat (limited to 'src/tester.c')
-rw-r--r--src/tester.c68
1 files changed, 52 insertions, 16 deletions
diff --git a/src/tester.c b/src/tester.c
index 84c1ca6..39dfb1a 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -6,8 +6,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
-#include "moslib/mem/alloc.h"
+#include "moslib/safe.h"
#define INIT_GROUP_CAP 8
#define INIT_TEST_CAP 16
@@ -22,8 +23,8 @@ int failed = 0;
FILE *dev_null = NULL;
typedef struct {
- FILE ***outs;
- FILE **ogs;
+ int *outs;
+ int *ogs;
size_t n_outs;
size_t out_cap;
} Outputs;
@@ -128,31 +129,64 @@ void mos_test_assert_exit_fn(MosTestFn function, int code, const char *name) {
}
}
-void mos_suppress_output(FILE **out) {
+void mos_test_assert_out_fn(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(stream);
+ mos_safe_dup2(fileno(tmp), fd);
+
+ function();
+ fflush(stream);
+ rewind(tmp);
+ fread(out, 1, n + 1, tmp);
+ fclose(tmp);
+
+ mos_safe_dup2(og, fd);
+ close(og);
+
+ if (strcmp(out, output)) {
+ failed = 1;
+ print_color("ASSERT FAILED: ", RED);
+ printf("function %s outputed to %s:\n", fn_name, stream_name);
+ printf(" %s (first %zu chars)\n", out, n + 1);
+ printf(" expected: %s\n", output);
+ }
+ free(out);
+}
+
+void mos_suppress_output(FILE *out) {
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(FILE **));
- suppressed.ogs = mos_safe_realloc(suppressed.ogs, suppressed.out_cap * sizeof(FILE *));
+ suppressed.outs = mos_safe_realloc(suppressed.outs, suppressed.out_cap * sizeof(int));
+ suppressed.ogs = mos_safe_realloc(suppressed.ogs, suppressed.out_cap * sizeof(int));
}
- suppressed.outs[suppressed.n_outs] = out;
- suppressed.ogs[suppressed.n_outs++] = *out;
+ suppressed.outs[suppressed.n_outs] = fileno(out);
+ suppressed.ogs[suppressed.n_outs++] = dup(fileno(out));
- if (!dev_null) {
- dev_null = fopen("/dev/null", "w");
- if (!dev_null)
- return;
- }
+ if (!dev_null)
+ dev_null = mos_safe_fopen("/dev/null", "w");
- *out = dev_null;
+ fflush(out);
+ dup2(fileno(dev_null), fileno(out));
}
void mos_unsuppress_outputs(void) {
if (!suppressed.outs || !suppressed.ogs)
return;
- for (size_t i = 0; i < suppressed.n_outs; i++)
- *suppressed.outs[i] = suppressed.ogs[i];
+ if (dev_null)
+ fflush(dev_null);
+
+ for (size_t i = suppressed.n_outs; i-- > 0;) {
+ dup2(suppressed.ogs[i], suppressed.outs[i]);
+ close(suppressed.ogs[i]);
+ }
suppressed.n_outs = 0;
}
@@ -231,8 +265,10 @@ void mos_free_tester(MosTester *tester) {
free(tester->groups);
free(tester);
}
+ mos_unsuppress_outputs();
if (dev_null) {
fclose(dev_null);
+ dev_null = NULL;
}
if (suppressed.outs) {
free(suppressed.outs);