hb-test.h revision 5e113a4b7921ced6af2d53460a7a2f1d0185c02a
1/*
2 * Copyright © 2011  Google, Inc.
3 *
4 *  This is part of HarfBuzz, a text shaping library.
5 *
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
11 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
17 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 *
24 * Google Author(s): Behdad Esfahbod
25 */
26
27#ifndef HB_TEST_H
28#define HB_TEST_H
29
30#include <config.h>
31
32#include <hb-glib.h>
33
34#include <stdlib.h>
35#include <string.h>
36
37HB_BEGIN_DECLS
38
39/* Just in case */
40#undef G_DISABLE_ASSERT
41
42
43/* Misc */
44
45/* This is too ugly to be public API, but quite handy. */
46#define HB_TAG_CHAR4(s)   (HB_TAG(((const char *) s)[0], \
47				  ((const char *) s)[1], \
48				  ((const char *) s)[2], \
49				  ((const char *) s)[3]))
50
51
52static inline const char *
53srcdir (void)
54{
55  static const char *s;
56
57  if (!s) {
58    s = getenv ("srcdir");
59
60#ifdef SRCDIR
61    if (!s || !s[0])
62      s = SRCDIR;
63#endif
64
65    if (!s || !s[0])
66      s = ".";
67  }
68
69  return s;
70}
71
72
73/* Helpers */
74
75static inline void
76hb_test_init (int *argc, char ***argv)
77{
78#if !GLIB_CHECK_VERSION(2,32,0)
79  g_thread_init (NULL);
80#endif
81  g_test_init (argc, argv, NULL);
82}
83
84static inline int
85hb_test_run (void)
86{
87  return g_test_run ();
88}
89
90
91/* Bugzilla helpers */
92
93static inline void
94hb_test_bug (const char *uri_base, unsigned int number)
95{
96  char *s = g_strdup_printf ("%u", number);
97
98  g_test_bug_base (uri_base);
99  g_test_bug (s);
100
101  g_free (s);
102}
103
104static inline void
105hb_test_bug_freedesktop (unsigned int number)
106{
107  hb_test_bug ("http://bugs.freedesktop.org/", number);
108}
109
110static inline void
111hb_test_bug_gnome (unsigned int number)
112{
113  hb_test_bug ("http://bugzilla.gnome.org/", number);
114}
115
116static inline void
117hb_test_bug_mozilla (unsigned int number)
118{
119  hb_test_bug ("http://bugzilla.mozilla.org/", number);
120}
121
122static inline void
123hb_test_bug_redhat (unsigned int number)
124{
125  hb_test_bug ("http://bugzilla.redhat.com/", number);
126}
127
128
129/* Wrap glib test functions to simplify.  Should have been in glib already. */
130
131/* Drops the "test_" prefix and converts '_' to '/'.
132 * Essentially builds test path from function name. */
133static inline char *
134hb_test_normalize_path (const char *path)
135{
136  char *s, *p;
137
138  g_assert (0 == strncmp (path, "test_", 5));
139  path += 4;
140
141  s = g_strdup (path);
142  for (p = s; *p; p++)
143    if (*p == '_')
144      *p = '/';
145
146  return s;
147}
148
149
150#if GLIB_CHECK_VERSION(2,25,12)
151typedef GTestFunc        hb_test_func_t;
152typedef GTestDataFunc    hb_test_data_func_t;
153typedef GTestFixtureFunc hb_test_fixture_func_t;
154#else
155typedef void (*hb_test_func_t)         (void);
156typedef void (*hb_test_data_func_t)    (gconstpointer user_data);
157typedef void (*hb_test_fixture_func_t) (void);
158#endif
159
160#if !GLIB_CHECK_VERSION(2,30,0)
161#define g_test_fail() g_error("Test failed")
162#endif
163
164static inline void
165hb_test_add_func (const char *test_path,
166		  hb_test_func_t   test_func)
167{
168  char *normal_path = hb_test_normalize_path (test_path);
169  g_test_add_func (normal_path, test_func);
170  g_free (normal_path);
171}
172#define hb_test_add(Func) hb_test_add_func (#Func, Func)
173
174static inline void
175hb_test_add_func_flavor (const char *test_path,
176			 const char *flavor,
177			 hb_test_func_t   test_func)
178{
179  char *path = g_strdup_printf ("%s/%s", test_path, flavor);
180  hb_test_add_func (path, test_func);
181  g_free (path);
182}
183#define hb_test_add_flavor(Flavor, Func) hb_test_add_func (#Func, Flavor, Func)
184
185static inline void
186hb_test_add_data_func (const char          *test_path,
187		       gconstpointer        test_data,
188		       hb_test_data_func_t  test_func)
189{
190  char *normal_path = hb_test_normalize_path (test_path);
191  g_test_add_data_func (normal_path, test_data, test_func);
192  g_free (normal_path);
193}
194#define hb_test_add_data(UserData, Func) hb_test_add_data_func (#Func, UserData, Func)
195
196static inline void
197hb_test_add_data_func_flavor (const char          *test_path,
198			      const char          *flavor,
199			      gconstpointer        test_data,
200			      hb_test_data_func_t  test_func)
201{
202  char *path = g_strdup_printf ("%s/%s", test_path, flavor);
203  hb_test_add_data_func (path, test_data, test_func);
204  g_free (path);
205}
206#define hb_test_add_data_flavor(UserData, Flavor, Func) hb_test_add_data_func_flavor (#Func, Flavor, UserData, Func)
207
208
209static inline void
210hb_test_add_vtable (const char             *test_path,
211		    gsize                   data_size,
212		    gconstpointer           test_data,
213		    hb_test_fixture_func_t  data_setup,
214		    hb_test_fixture_func_t  data_test,
215		    hb_test_fixture_func_t  data_teardown)
216{
217  char *normal_path = hb_test_normalize_path (test_path);
218  g_test_add_vtable (normal_path, data_size, test_data, data_setup, data_test, data_teardown);
219  g_free (normal_path);
220}
221#define hb_test_add_fixture(FixturePrefix, UserData, Func) \
222G_STMT_START { \
223  typedef G_PASTE (FixturePrefix, _t) Fixture; \
224  void (*add_vtable) (const char*, gsize, gconstpointer, \
225		      void (*) (Fixture*, gconstpointer), \
226		      void (*) (Fixture*, gconstpointer), \
227		      void (*) (Fixture*, gconstpointer)) \
228	= (void (*) (const gchar *, gsize, gconstpointer, \
229		     void (*) (Fixture*, gconstpointer), \
230		     void (*) (Fixture*, gconstpointer), \
231		     void (*) (Fixture*, gconstpointer))) hb_test_add_vtable; \
232  add_vtable (#Func, sizeof (G_PASTE (FixturePrefix, _t)), UserData, \
233	      G_PASTE (FixturePrefix, _init), Func, G_PASTE (FixturePrefix, _finish)); \
234} G_STMT_END
235
236static inline void
237hb_test_add_vtable_flavor (const char             *test_path,
238			   const char             *flavor,
239			   gsize                   data_size,
240			   gconstpointer           test_data,
241			   hb_test_fixture_func_t  data_setup,
242			   hb_test_fixture_func_t  data_test,
243			   hb_test_fixture_func_t  data_teardown)
244{
245  char *path = g_strdup_printf ("%s/%s", test_path, flavor);
246  hb_test_add_vtable (path, data_size, test_data, data_setup, data_test, data_teardown);
247  g_free (path);
248}
249#define hb_test_add_fixture_flavor(FixturePrefix, UserData, Flavor, Func) \
250G_STMT_START { \
251  typedef G_PASTE (FixturePrefix, _t) Fixture; \
252  void (*add_vtable) (const char*, const char *, gsize, gconstpointer, \
253		      void (*) (Fixture*, gconstpointer), \
254		      void (*) (Fixture*, gconstpointer), \
255		      void (*) (Fixture*, gconstpointer)) \
256	= (void (*) (const gchar *, const char *, gsize, gconstpointer, \
257		     void (*) (Fixture*, gconstpointer), \
258		     void (*) (Fixture*, gconstpointer), \
259		     void (*) (Fixture*, gconstpointer))) hb_test_add_vtable_flavor; \
260  add_vtable (#Func, Flavor, sizeof (G_PASTE (FixturePrefix, _t)), UserData, \
261	      G_PASTE (FixturePrefix, _init), Func, G_PASTE (FixturePrefix, _finish)); \
262} G_STMT_END
263
264
265HB_END_DECLS
266
267#endif /* HB_TEST_H */
268