aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--include/moslib/tester.h28
-rw-r--r--src/tester.c63
-rw-r--r--tests/ds/array_tests.c6
-rw-r--r--tests/mem/alloc_tests.c11
5 files changed, 94 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index 48ad409..8f9ca5c 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,7 @@ test:
$(CC) $(CFLAGS_TEST) -c tests/mem/alloc_tests.c
$(CC) $(CFLAGS_TEST) -c tests/ds/array_tests.c
$(CC) $(CFLAGS_TEST) -lmoslib *.o tests/tests.c -o run_tests
- ./run_tests 2>/dev/null
+ ./run_tests
rm run_tests *.o
.PHONY: clean
diff --git a/include/moslib/tester.h b/include/moslib/tester.h
index 52a9f14..b48a03a 100644
--- a/include/moslib/tester.h
+++ b/include/moslib/tester.h
@@ -30,8 +30,8 @@
// int result1 = 1 + 2;
// int result2 = 3 + 5;
//
-// test_assert(result1 == 3, "1 + 2 should equal 3");
-// test_assert(result2 == 8, "3 + 5 should equal 8");
+// test_assert(result1 == 3, "1 + 2 is not equal 3");
+// test_assert(result2 == 8, "3 + 5 is not equal 8");
// }
//
// You can also test if a function is supposed to call exit.
@@ -46,6 +46,17 @@
// test_assert_exit(helper_test, EXIT_FAILURE);
// }
//
+// 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);
+// suppress_output(&stderr);
+// int code = fun_that_fails_with_output();
+// unsuppress_outputs();
+// test_assert(code == 0, "function didn't fail");
+// }
+//
// ----------------------------------------------------------------------------------------------------
//
// Add tests to test group:
@@ -67,6 +78,8 @@
// ----------------------------------------------------------------------------------------------------
// ===================================== END OF QUICK USAGE GUIDE =====================================
+#include <stdio.h>
+
#ifndef MOSLIB_TESTER_H
#define MOSLIB_TESTER_H
@@ -117,6 +130,17 @@ extern void test_assert(int expression, const char *fail_message);
// expected exit code
#define test_assert_exit(function, code) test_assert_exit_fn((function), (code), #function);
+// Suppress given output
+//
+// Arguments:
+// out
+// pointer to outpout to suppress
+extern void suppress_output(FILE **out);
+
+// Unuppress previously suppressed outputs
+// Will unsupress all of the outputs that were suppressed
+extern void unsuppress_outputs(void);
+
// Add test to a test group
//
// Arguments:
diff --git a/src/tester.c b/src/tester.c
index c166a48..afabc22 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -18,6 +18,21 @@
#define RENDER_WIDTH 80
int failed = 0;
+FILE *dev_null = NULL;
+
+typedef struct {
+ FILE ***outs;
+ FILE **ogs;
+ size_t n_outs;
+ size_t out_cap;
+} Outputs;
+
+Outputs suppressed = {
+ .outs = NULL,
+ .ogs = NULL,
+ .n_outs = 0,
+ .out_cap = 4,
+};
#define print_color(template, ...) printf("\033[%dm" template "\033[0m", __VA_ARGS__)
#define nl printf("\n")
@@ -112,6 +127,35 @@ void test_assert_exit_fn(TestFn function, int code, const char *name) {
}
}
+void 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 = safe_realloc(suppressed.outs, suppressed.out_cap);
+ suppressed.ogs = safe_realloc(suppressed.ogs, suppressed.out_cap);
+ }
+ suppressed.outs[suppressed.n_outs] = out;
+ suppressed.ogs[suppressed.n_outs++] = *out;
+
+ if (!dev_null) {
+ dev_null = fopen("/dev/null", "w");
+ if (!dev_null)
+ return;
+ }
+
+ *out = dev_null;
+}
+
+void 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];
+
+ suppressed.n_outs = 0;
+}
+
void add_test_fn(TestGroup *group, TestFn test, const char *name) {
if (group->n_tests >= group->test_cap) {
group->test_cap *= 2;
@@ -178,12 +222,17 @@ void run_tests(Tester *tester) {
}
void free_tester(Tester *tester) {
- if (!tester)
- return;
-
- for (size_t i = 0; i < tester->n_groups; i++) {
- free(tester->groups[i].tests);
+ if (tester) {
+ for (size_t i = 0; i < tester->n_groups; i++)
+ free(tester->groups[i].tests);
+ free(tester->groups);
+ free(tester);
+ }
+ if (dev_null) {
+ fclose(dev_null);
+ }
+ if (suppressed.outs) {
+ free(suppressed.outs);
+ suppressed.n_outs = 0;
}
- free(tester->groups);
- free(tester);
}
diff --git a/tests/ds/array_tests.c b/tests/ds/array_tests.c
index d674066..a9d4ec7 100644
--- a/tests/ds/array_tests.c
+++ b/tests/ds/array_tests.c
@@ -90,7 +90,7 @@ Test getting_items() {
arr_append(arr, (struct test){0});
test_assert(arr_first(arr) == arr_last(arr), "first and last are different for array of length 1");
- arr_append(arr, (struct test){1});
+ arr_append(arr, (struct test){1, 1});
test_assert(arr_first(arr) != arr_last(arr), "first and last are the same for array of length >1");
struct test *next_first = arr_next(arr, NULL);
@@ -114,7 +114,7 @@ Test getting_items() {
Test deleting_items() {
int *arr = NULL;
- int *items = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int items[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
arr_append_n(arr, items, 9);
// {1, 2, 3, 4, 5, 6, 7, 8}
@@ -160,7 +160,7 @@ Test arr_concat_test() {
test_assert(index == 2, "arr_concat returned wrong index");
unsigned long expected[] = {4, 5, 1, 2, 3, 4, 5};
test_assert(arr_len(arr2) == 7, "arr_concat produced array of wrong length");
- test_assert(!memcmp(arr2, items, 7 * sizeof(unsigned long)), "arr_concat produced wrong array");
+ test_assert(!memcmp(arr2, expected, 7 * sizeof(unsigned long)), "arr_concat produced wrong array");
}
void ds_array_tests(Tester *tester) {
diff --git a/tests/mem/alloc_tests.c b/tests/mem/alloc_tests.c
index 6eb2e9c..17973c7 100644
--- a/tests/mem/alloc_tests.c
+++ b/tests/mem/alloc_tests.c
@@ -10,8 +10,11 @@ Test malloc_exit() {
Test test_safe_malloc() {
void *p = safe_malloc(1024);
- test_assert(p != NULL, "Should be able to malloc 1KiB");
+ test_assert(p != NULL, "Failed to malloc 1KiB");
+
+ suppress_output(&stderr);
test_assert_exit(malloc_exit, EXIT_FAILURE);
+ unsuppress_outputs();
}
Test realloc_exit() {
@@ -22,12 +25,14 @@ Test realloc_exit() {
Test test_safe_realloc() {
void *p = NULL;
p = safe_realloc(p, 1024);
- test_assert(p != NULL, "Should be able to realloc NULL to 1KiB");
+ test_assert(p != NULL, "Failed to realloc NULL to 1KiB");
p = safe_realloc(p, 4096);
- test_assert(p != NULL, "Should be able to realloc 1KiB to 4KiB");
+ test_assert(p != NULL, "Failed to realloc 1KiB to 4KiB");
+ suppress_output(&stderr);
test_assert_exit(realloc_exit, EXIT_FAILURE);
+ unsuppress_outputs();
}
void mem_alloc_tests(Tester *tester) {