Add test suite infrastructure

Wraps around glib for convenience and ease of use.
This commit is contained in:
Behdad Esfahbod 2011-04-28 17:10:44 -04:00
parent c7ffe2ad5f
commit aafe395ab5
5 changed files with 159 additions and 47 deletions

View File

@ -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 \

View File

@ -27,12 +27,10 @@
#ifndef HB_TEST_H
#define HB_TEST_H
#include <hb.h>
#include <hb-glib.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
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 */

View File

@ -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);
hb_test_init (&argc, &argv);
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
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();
}

View File

@ -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();
}

View File

@ -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 ();
}