cepheid

An Aurora 4X clone
Log | Files | Refs | README

commit 3d2eac4ae2429b93d694efda884f23e5648f104c
parent 85f2ad59703942f0744110e658067d317d2efe1f
Author: hhvn <dev@hhvn.uk>
Date:   Sun, 27 Nov 2022 12:05:48 +0000

Testing with libcheck

Diffstat:
M.gitignore | 1+
MMakefile | 2+-
Mdev/config.mk | 28+++++++++++++++++++++++++---
Msrc/main.c | 9+++++++++
Msrc/main.h | 4++--
Atests/.gitignore | 4++++
Atests/Makefile | 27+++++++++++++++++++++++++++
Atests/main.c | 21+++++++++++++++++++++
Atests/mktest.awk | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 143 insertions(+), 6 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -7,3 +7,4 @@ saves/ core.* tags perf.* +.testing diff --git a/Makefile b/Makefile @@ -12,7 +12,7 @@ LDFLAGS = $(RAYLIB) $(DBLIB) include config.mk all: db data $(BIN) -src/data.o: data/icons/* +src/main.o: .testing .c.o: $(CC) $(CFLAGS) -D"SAVEDIR=\"$(SAVEDIR)\"" -c $< -o $@ diff --git a/dev/config.mk b/dev/config.mk @@ -1,6 +1,7 @@ CFLAGS += -Wall -g3 -O0 CFLAGS += -DDEBUG CFLAGS += -DCHECK_FRAME_MEM_FREE +ARGS = all: tags checks tags: $(SRC) @@ -9,10 +10,31 @@ tags: $(SRC) checks: $(SRC) ./dev/checkalloc.sh -test: all - gdb ./$(BIN) -ex 'set confirm on' -ex run -ex bt -ex quit --args $(ARGS) +# All objects in src/ that react to TEST should have .testing as a dependency. +# Updating it before and after running will: +# - Compile them with TEST if they weren't already +# - Compile them without TEST next time it should be compiled normally +test: + touch .testing + cd tests && make + make test-run + rm -rf test.* + touch .testing + +clean: test-clean +test-clean: + cd tests && make clean + +# Since the 'test' target will create *.c files in tests/, those can't be added +# to $(SRC), as shell macros are evaluated before the target is run. Hence, +# this target is required. +test-run: + make run CFLAGS="$(CFLAGS) -DTEST" LDFLAGS="$(LDFLAGS) -lcheck" SRC="$(SRC) $(shell find tests -type f -name "*.c")" + +run: all + gdb -ex 'set confirm on' -ex run -ex bt -ex quit --args $(BIN) $(ARGS) gdb: all - gdb ./$(BIN) --args $(ARGS) + gdb --args ./$(BIN) $(ARGS) VALFILE = dev/valgrind.log VALSUPP = dev/valgrind-suppress diff --git a/src/main.c b/src/main.c @@ -7,6 +7,10 @@ #define DEFSAVE "default" +#ifdef TEST +int test_run(void); +#endif /* TEST */ + Save *save = NULL; int sigint = 0; int sigterm = 0; @@ -26,12 +30,17 @@ main(void) { int view_prev; struct sigaction sa; + sa.sa_handler = sighandler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); +#ifdef TEST + return test_run(); +#endif /* TEST */ + ui_init(); data_load(); diff --git a/src/main.h b/src/main.h @@ -20,9 +20,9 @@ #define CUSTOM_FREE #endif /* CHECK_FRAME_MEM_FREE */ -#ifdef CUSTOM_FREE +#if defined(CUSTOM_FREE) && !defined(TEST) #define free(m) _free(m, __FILE__, __LINE__, __func__) -#endif /* CUSTOM_FREE */ +#endif /* defined(CUSTOM_FREE) && !defined(TEST) */ /* main.c */ extern Save *save; diff --git a/tests/.gitignore b/tests/.gitignore @@ -0,0 +1,4 @@ +# except for main.c +*.c +*.o +*.h diff --git a/tests/Makefile b/tests/Makefile @@ -0,0 +1,27 @@ +TESTS = $(shell find . -type f -name "*.test") +TESTC = $(TESTS:.test=.c) +CHECKS = `echo $(TESTS) | tr ' ' '\n' | sed 's/^.\//test_/;s/\.test$$//'` + +all: list.c test.h $(TESTC) +$(TESTC): mktest.awk Makefile + +list.c: test.h + printf '#include "test.h"\n\n' > $@ + printf 'int (*tests[TESTS])(void) = {\n' >> $@ + for f in $(CHECKS); do \ + printf '\t%s,\n' $$f >> $@; \ + done + printf '};\n' >> $@ + +test.h: $(TESTS) + printf '%s' "$(CHECKS)" | sed 's/^/int /;s/$$/(void);/' > $@ + printf '\n#define TESTS %d\n' $$(echo "$(CHECKS)" | wc -l) >> $@ + printf '\nextern int (*tests[TESTS])(void);\n' >> $@ + +clean: + rm -f `find . -name "*.c" -o -name "*.h" -o -name "*.o" | grep -v main\.c` + +.test.c: + ./mktest.awk -v "test=$*" < $< > $@ + +.SUFFIXES: .test .c diff --git a/tests/main.c b/tests/main.c @@ -0,0 +1,21 @@ +#include <check.h> +#include <stdio.h> +#include <limits.h> +#include <unistd.h> +#include <stdlib.h> +#include "test.h" +#include "../src/main.h" + +int +test_run(void) { + int ret, i; + + printf("\033[1mvvv Tests vvv\033[0m\n"); + + for (ret = i = 0; i < TESTS; i++) + ret += tests[i](); + + printf("\033[1m^^^ Tests ^^^\033[0m\n"); + + return !!ret; +} diff --git a/tests/mktest.awk b/tests/mktest.awk @@ -0,0 +1,53 @@ +#!/bin/awk -f + +BEGIN { + print "#include <check.h>" + done = 0 +} + +/^%{$/ { + print "START_TEST(ck_"test") {" +} + +!/^%{$/ && !/^}$/ { + if (done) + print "error: excess lines" > "/dev/stderr" + else + print +} + +/^}$/ { + print "}" + print "END_TEST" + print "" + print "#include <limits.h>" + print "#include <unistd.h>" + print "#include <stdlib.h>" + print "" + print "int" + print "test_"test"(void) {" + print " Suite *s = suite_create(\""test"\");" + print " TCase *tc = tcase_create(\""test"\");" + print " SRunner *sr = srunner_create(s);" + print " char restoredir[PATH_MAX];" + print " char tmp[] = \"test.XXXXXX\";" + print " int ret;" + print "" + print " getcwd(restoredir, sizeof(restoredir));" + print " mkdtemp(tmp);" + print " chdir(tmp);" + print "" + print " suite_add_tcase(s, tc);" + print " tcase_add_test(tc, ck_"test");" + print "" + print " srunner_run_all(sr, CK_ENV);" + print " ret = srunner_ntests_failed(sr);" + print " srunner_free(sr);" + print "" + print " chdir(restoredir);" + print " /* rmdirp(tmp); */" + print "" + print " return !!ret;" + print "}" + done = 1 +}