From aafe395ab550d3ba2fabc69155662e87d45e74a8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 28 Apr 2011 17:10:44 -0400 Subject: [PATCH] Add test suite infrastructure Wraps around glib for convenience and ease of use. --- test/Makefile.am | 1 + test/hb-test.h | 132 +++++++++++++++++++++++++++++++++++++++++--- test/test-buffer.c | 29 +++++----- test/test-common.c | 14 ++--- test/test-unicode.c | 32 +++++------ 5 files changed, 160 insertions(+), 48 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index e4fdb2028..e48708b37 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -7,6 +7,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/ $(GLIB_CFLAGS) LDADD = $(top_builddir)/src/libharfbuzz.la $(GLIB_LIBS) check_PROGRAMS = $(TEST_PROGS) +noinst_PROGRAMS = $(TEST_PROGS) TEST_PROGS += \ test-buffer \ diff --git a/test/hb-test.h b/test/hb-test.h index 2c0464225..44c9405de 100644 --- a/test/hb-test.h +++ b/test/hb-test.h @@ -27,12 +27,10 @@ #ifndef HB_TEST_H #define HB_TEST_H -#include #include -#include - #include +#include HB_BEGIN_DECLS @@ -40,6 +38,30 @@ HB_BEGIN_DECLS #undef G_DISABLE_ASSERT +/* Misc */ + +/* This is too ugly to be public API, but quite handy. */ +#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \ + ((const char *) s)[1], \ + ((const char *) s)[2], \ + ((const char *) s)[3])) + + +/* Helpers */ + +static inline void +hb_test_init (int *argc, char ***argv) +{ + g_test_init (argc, argv, NULL); +} + +static inline int +hb_test_run (void) +{ + return g_test_run (); +} + + /* Bugzilla helpers */ static inline void @@ -78,13 +100,105 @@ hb_test_bug_redhat (unsigned int number) } -/* Misc */ +/* Wrap glib test functions to simplify. Should have been in glib already. */ + +/* Drops the "test_" prefix and converts '_' to '/'. + * Essentially builds test path from function name. */ +static inline char * +hb_test_normalize_path (const char *path) +{ + char *s, *p; + + g_assert (0 == strncmp (path, "test_", 5)); + path += 4; + + s = g_strdup (path); + for (p = s; *p; p++) + if (*p == '_') + *p = '/'; + + return s; +} + + +static inline void +hb_test_add_func (const char *test_path, + GTestFunc test_func) +{ + char *normal_path = hb_test_normalize_path (test_path); + g_test_add_func (normal_path, test_func); + g_free (normal_path); +} +#define hb_test_add(Func) hb_test_add_func (#Func, Func) + +static inline void +hb_test_add_func_flavor (const char *test_path, + const char *flavor, + GTestFunc test_func) +{ + char *path = g_strdup_printf ("%s/%s", test_path, flavor); + hb_test_add_func (path, test_func); + g_free (path); +} +#define hb_test_add_flavor(Func, Flavor) hb_test_add_func (#Func, Flavor, Func) + + +static inline void +hb_test_add_vtable (const char *test_path, + gsize data_size, + gconstpointer test_data, + GTestFixtureFunc data_setup, + GTestFixtureFunc data_test, + GTestFixtureFunc data_teardown) +{ + char *normal_path = hb_test_normalize_path (test_path); + g_test_add_vtable (normal_path, data_size, test_data, data_setup, data_test, data_teardown); + g_free (normal_path); +} +#define hb_test_add_fixture(FixturePrefix, UserData, Func) \ +G_STMT_START { \ + typedef G_PASTE (FixturePrefix, _t) Fixture; \ + void (*add_vtable) (const char*, gsize, gconstpointer, \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer)) \ + = (void (*) (const gchar *, gsize, gconstpointer, \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer))) hb_test_add_vtable; \ + add_vtable (#Func, sizeof (G_PASTE (FixturePrefix, _t)), UserData, \ + G_PASTE (FixturePrefix, _init), Func, G_PASTE (FixturePrefix, _finish)); \ +} G_STMT_END + +static inline void +hb_test_add_vtable_flavor (const char *test_path, + const char *flavor, + gsize data_size, + gconstpointer test_data, + GTestFixtureFunc data_setup, + GTestFixtureFunc data_test, + GTestFixtureFunc data_teardown) +{ + char *path = g_strdup_printf ("%s/%s", test_path, flavor); + hb_test_add_vtable (path, data_size, test_data, data_setup, data_test, data_teardown); + g_free (path); +} +#define hb_test_add_fixture_flavor(FixturePrefix, UserData, Flavor, Func) \ +G_STMT_START { \ + typedef G_PASTE (FixturePrefix, _t) Fixture; \ + void (*add_vtable) (const char*, const char *, gsize, gconstpointer, \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer)) \ + = (void (*) (const gchar *, const char *, gsize, gconstpointer, \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer))) hb_test_add_vtable_flavor; \ + add_vtable (#Func, Flavor, sizeof (G_PASTE (FixturePrefix, _t)), UserData, \ + G_PASTE (FixturePrefix, _init), Func, G_PASTE (FixturePrefix, _finish)); \ +} G_STMT_END + -/* This is too ugly to be public API, but quite handy. */ -#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \ - ((const char *) s)[1], \ - ((const char *) s)[2], \ - ((const char *) s)[3])) HB_END_DECLS #endif /* HB_TEST_H */ diff --git a/test/test-buffer.c b/test/test-buffer.c index 7da4c922b..149955067 100644 --- a/test/test-buffer.c +++ b/test/test-buffer.c @@ -89,7 +89,7 @@ fixture_init (fixture_t *fixture, gconstpointer user_data) } static void -fixture_fini (fixture_t *fixture, gconstpointer user_data) +fixture_finish (fixture_t *fixture, gconstpointer user_data) { hb_buffer_destroy (fixture->b); } @@ -321,24 +321,21 @@ main (int argc, char **argv) { int i; - g_test_init (&argc, &argv, NULL); - - for (i = 0; i < BUFFER_NUM_TYPES; i++) { -#define TEST_ADD(path, func) \ - G_STMT_START { \ - char *s = g_strdup_printf ("%s/%s", path, buffer_names[i]); \ - g_test_add (s, fixture_t, GINT_TO_POINTER (i), fixture_init, func, fixture_fini); \ - g_free (s); \ - } G_STMT_END - TEST_ADD ("/buffer/properties", test_buffer_properties); - TEST_ADD ("/buffer/contents", test_buffer_contents); - TEST_ADD ("/buffer/positions", test_buffer_positions); -#undef TEST_ADD + hb_test_init (&argc, &argv); + + for (i = 0; i < BUFFER_NUM_TYPES; i++) + { + const void *buffer_type = GINT_TO_POINTER (i); + const char *buffer_name = buffer_names[i]; + + hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_properties); + hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_contents); + hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_positions); } - g_test_add ("/buffer/allocation", fixture_t, GINT_TO_POINTER (BUFFER_EMPTY), fixture_init, test_buffer_allocation, fixture_fini); + hb_test_add_fixture (fixture, GINT_TO_POINTER (BUFFER_EMPTY), test_buffer_allocation); /* XXX test invalid UTF-8 / UTF-16 text input (also overlong sequences) */ - return g_test_run(); + return hb_test_run(); } diff --git a/test/test-common.c b/test/test-common.c index d232740ac..31661f07a 100644 --- a/test/test-common.c +++ b/test/test-common.c @@ -173,13 +173,13 @@ test_types_language (void) int main (int argc, char **argv) { - g_test_init (&argc, &argv, NULL); + hb_test_init (&argc, &argv); - g_test_add_func ("/types/int", test_types_int); - g_test_add_func ("/types/direction", test_types_direction); - g_test_add_func ("/types/tag", test_types_tag); - g_test_add_func ("/types/script", test_types_script); - g_test_add_func ("/types/language", test_types_language); + hb_test_add (test_types_int); + hb_test_add (test_types_direction); + hb_test_add (test_types_tag); + hb_test_add (test_types_script); + hb_test_add (test_types_language); - return g_test_run(); + return hb_test_run(); } diff --git a/test/test-unicode.c b/test/test-unicode.c index c69634110..30a89bec1 100644 --- a/test/test-unicode.c +++ b/test/test-unicode.c @@ -29,7 +29,7 @@ /* This file tests the unicode virtual functions interface */ static void -test_nil (void) +test_unicode_nil (void) { hb_unicode_funcs_t *uf = hb_unicode_funcs_create (NULL); @@ -39,7 +39,7 @@ test_nil (void) } static void -test_glib (void) +test_unicode_glib (void) { hb_unicode_funcs_t *uf = hb_glib_get_unicode_funcs (); @@ -47,7 +47,7 @@ test_glib (void) } static void -test_default (void) +test_unicode_default (void) { hb_unicode_funcs_t *uf = hb_unicode_funcs_get_default (); @@ -85,7 +85,7 @@ simple_get_script (hb_unicode_funcs_t *ufuncs, } static void -test_custom (void) +test_unicode_custom (void) { hb_unicode_funcs_t *uf = hb_unicode_funcs_create (NULL); @@ -120,7 +120,7 @@ a_is_for_arabic_get_script (hb_unicode_funcs_t *ufuncs, } static void -test_subclassing_nil (void) +test_unicode_subclassing_nil (void) { hb_unicode_funcs_t *uf, *aa; @@ -143,7 +143,7 @@ test_subclassing_nil (void) } static void -test_subclassing_glib (void) +test_unicode_subclassing_glib (void) { hb_unicode_funcs_t *uf, *aa; @@ -163,7 +163,7 @@ test_subclassing_glib (void) } static void -test_subclassing_deep (void) +test_unicode_subclassing_deep (void) { hb_unicode_funcs_t *uf, *aa; @@ -195,18 +195,18 @@ test_subclassing_deep (void) int main (int argc, char **argv) { - g_test_init (&argc, &argv, NULL); + hb_test_init (&argc, &argv); - g_test_add_func ("/unicode/nil", test_nil); - g_test_add_func ("/unicode/glib", test_glib); - g_test_add_func ("/unicode/default", test_default); - g_test_add_func ("/unicode/custom", test_custom); - g_test_add_func ("/unicode/subclassing/nil", test_subclassing_nil); - g_test_add_func ("/unicode/subclassing/glib", test_subclassing_glib); - g_test_add_func ("/unicode/subclassing/deep", test_subclassing_deep); + hb_test_add (test_unicode_nil); + hb_test_add (test_unicode_glib); + hb_test_add (test_unicode_default); + hb_test_add (test_unicode_custom); + hb_test_add (test_unicode_subclassing_nil); + hb_test_add (test_unicode_subclassing_glib); + hb_test_add (test_unicode_subclassing_deep); /* XXX test all methods for their defaults and various (glib, icu, default) implementations. */ /* XXX test glib & icu two-way script conversion */ - return g_test_run (); + return hb_test_run (); }