From ad091d02678a632f0f91f26072bbec29eba4c66e Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 24 Sep 2013 23:14:46 -0700 Subject: [PATCH] Add Glk unit test framework This is the beginning of a unit test framework for Glk. Currently it has only one test. But the potential is infinite! It could be used to test how well other Glk implementations conform too. --- Makefile.am | 2 +- configure.ac | 1 + tests/Makefile.am | 2 ++ tests/unit/Makefile.am | 28 ++++++++++++++++++++++++++++ tests/unit/datetime.c | 26 ++++++++++++++++++++++++++ tests/unit/glkunit.c | 28 ++++++++++++++++++++++++++++ tests/unit/glkunit.h | 25 +++++++++++++++++++++++++ 7 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 tests/unit/Makefile.am create mode 100644 tests/unit/datetime.c create mode 100644 tests/unit/glkunit.c create mode 100644 tests/unit/glkunit.h diff --git a/Makefile.am b/Makefile.am index d0d290d..b7200b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,7 +31,7 @@ macros_ignore = codeset gettext glibc2 glibc21 gtk-doc iconv intdiv0 intl \ MAINTAINERCLEANFILES = ABOUT-NLS INSTALL aclocal.m4 compile config.guess \ config.h.in config.rpath config.sub depcomp gtk-doc.make install-sh \ intltool-extract.in intltool-merge.in intltool-update.in ltmain.sh missing \ - ylwrap autom4te.cache \ + ylwrap autom4te.cache test-driver \ $(addprefix 'm4/',$(addsuffix '.m4', $(macros_ignore))) ACLOCAL_AMFLAGS = -I m4 diff --git a/configure.ac b/configure.ac index 7e72a84..2d89075 100644 --- a/configure.ac +++ b/configure.ac @@ -171,6 +171,7 @@ interpreters/glulxe/Makefile interpreters/git/Makefile interpreters/bocfel/Makefile tests/Makefile +tests/unit/Makefile player/Makefile player/config.py docs/Makefile diff --git a/tests/Makefile.am b/tests/Makefile.am index aacfc6e..f8909a5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = unit + AM_CFLAGS = -Wall AM_CPPFLAGS = -I$(top_srcdir) diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am new file mode 100644 index 0000000..fc51028 --- /dev/null +++ b/tests/unit/Makefile.am @@ -0,0 +1,28 @@ +# The rpath is necessary for check_ too (see rant in ../Makefile.am) +TEST_PLUGIN_LIBTOOL_FLAGS = \ + -module \ + -shared \ + -avoid-version \ + -export-symbols-regex "^glk_main$$" \ + -rpath $(abs_builddir) \ + $(NULL) + +# Set up include dirs so that #include "glk.h" works +AM_CPPFLAGS = -I$(top_srcdir)/libchimara $(CPPFLAGS) + +check_LTLIBRARIES = datetime.la +datetime_la_SOURCES = datetime.c glkunit.c glkunit.h +datetime_la_LDFLAGS = $(TEST_PLUGIN_LIBTOOL_FLAGS) + +TESTS = datetime.la +TEST_EXTENSIONS = .la +LA_LOG_COMPILER = $(builddir)/../plugin-loader + +CLEANFILES = \ + test-suite.log \ + $(TESTS) \ + $(TESTS:.la=.log) \ + $(TESTS:.la=.trs) \ + $(NULL) + +-include $(top_srcdir)/git.mk diff --git a/tests/unit/datetime.c b/tests/unit/datetime.c new file mode 100644 index 0000000..591dc9f --- /dev/null +++ b/tests/unit/datetime.c @@ -0,0 +1,26 @@ +#include "glk.h" +#include "glkunit.h" + +static int +test_current_time_equals_current_simple_time(void) +{ + glktimeval_t timeval; + + /* This test will fail if the following two operations do not occur within + a second of each other. That is not a robust test, but you could argue that + there is a serious bug if either operation takes more than one second. */ + glk_current_time(&timeval); + glsi32 simple_time = glk_current_simple_time(1); + ASSERT_EQUAL(simple_time, timeval.low_sec); + + glk_current_time(&timeval); + glsi32 simple_time_high_bits = glk_current_simple_time(0xFFFFFFFF); + ASSERT_EQUAL(simple_time_high_bits, timeval.high_sec); + + SUCCEED; +} + +struct TestDescription tests[] = { + { "current time equals simple time", test_current_time_equals_current_simple_time }, + { NULL, NULL } +}; diff --git a/tests/unit/glkunit.c b/tests/unit/glkunit.c new file mode 100644 index 0000000..63d8134 --- /dev/null +++ b/tests/unit/glkunit.c @@ -0,0 +1,28 @@ +#include +#include +#include "glk.h" +#include "glkunit.h" + +extern struct TestDescription tests[]; + +void +glk_main(void) +{ + struct TestDescription *test = tests; + int tested = 0, succeeded = 0, failed = 0; + while(test->name != NULL) { + tested++; + /* Use stdio.h to print to stdout, Glk can't do that */ + printf(" Testing %s... ", test->name); + if( test->testfunc() ) { + succeeded++; + printf("PASS\n"); + } else { + failed++; + printf("FAIL\n"); + } + test++; + } + printf("%d tests run, %d failures\n", tested, failed); + exit(failed > 0); +} diff --git a/tests/unit/glkunit.h b/tests/unit/glkunit.h new file mode 100644 index 0000000..3828987 --- /dev/null +++ b/tests/unit/glkunit.h @@ -0,0 +1,25 @@ +#ifndef GLKUNIT_H +#define GLKUNIT_H + +#include + +#define _BEGIN do { +#define _END } while(0); + +/* msg must be a string literal */ +#define _ASSERT(expr, msg, ...) _BEGIN \ + if( !(expr) ) { \ + fprintf(stderr, "Assertion failed: " msg "\n", __VA_ARGS__); \ + return 0; \ + } _END + +#define SUCCEED _BEGIN return 1; _END +#define ASSERT(expr) _ASSERT(expr, "%s", #expr) +#define ASSERT_EQUAL(expected, actual) _ASSERT((expected) == (actual), "%s == %s", #expected, #actual); + +struct TestDescription { + char *name; + int (*testfunc)(void); +}; + +#endif /* GLKUNIT_H */ -- 2.30.2