2 * Copyright © 2011 Google, Inc.
4 * This is part of HarfBuzz, a text shaping library.
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.
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
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.
24 * Google Author(s): Behdad Esfahbod
29 /* Unit tests for hb-object-private.h */
40 static char data[] = "test data";
41 return hb_blob_create (data, sizeof (data), HB_MEMORY_MODE_READONLY, NULL, NULL);
44 create_blob_inert (void)
46 return hb_blob_get_empty ();
52 return hb_buffer_create (0);
55 create_buffer_inert (void)
57 return hb_buffer_create (-1);
63 hb_blob_t *blob = (hb_blob_t *) create_blob ();
64 hb_face_t *face = hb_face_create_for_data (blob, 0);
65 hb_blob_destroy (blob);
69 create_face_inert (void)
71 return hb_face_create_for_data ((hb_blob_t *) create_blob_inert (), 0);
77 hb_face_t *face = (hb_face_t *) create_face ();
78 hb_font_t *font = hb_font_create (face);
79 hb_face_destroy (face);
83 create_font_inert (void)
85 return hb_font_create (create_face_inert ());
89 create_font_funcs (void)
91 return hb_font_funcs_create ();
94 create_font_funcs_inert (void)
97 return hb_ft_get_font_funcs ();
104 create_unicode_funcs (void)
106 return hb_unicode_funcs_create (NULL);
109 create_unicode_funcs_inert (void)
111 return hb_unicode_funcs_get_default ();
116 typedef void *(*create_func_t) (void);
117 typedef void *(*reference_func_t) (void *obj);
118 typedef void (*destroy_func_t) (void *obj);
119 typedef hb_bool_t (*set_user_data_func_t) (void *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy);
120 typedef void * (*get_user_data_func_t) (void *obj, hb_user_data_key_t *key);
121 typedef void (*make_immutable_func_t) (void *obj);
122 typedef hb_bool_t (*is_immutable_func_t) (void *obj);
125 create_func_t create;
126 create_func_t create_inert;
127 reference_func_t reference;
128 destroy_func_t destroy;
129 set_user_data_func_t set_user_data;
130 get_user_data_func_t get_user_data;
131 make_immutable_func_t make_immutable;
132 is_immutable_func_t is_immutable;
136 #define OBJECT_WITHOUT_IMMUTABILITY(name) \
138 (create_func_t) create_##name, \
139 (create_func_t) create_##name##_inert, \
140 (reference_func_t) hb_##name##_reference, \
141 (destroy_func_t) hb_##name##_destroy, \
142 (set_user_data_func_t) hb_##name##_set_user_data, \
143 (get_user_data_func_t) hb_##name##_get_user_data, \
144 (make_immutable_func_t) NULL, \
145 (is_immutable_func_t) NULL, \
148 #define OBJECT_WITH_IMMUTABILITY(name) \
150 (create_func_t) create_##name, \
151 (create_func_t) create_##name##_inert, \
152 (reference_func_t) hb_##name##_reference, \
153 (destroy_func_t) hb_##name##_destroy, \
154 (set_user_data_func_t) hb_##name##_set_user_data, \
155 (get_user_data_func_t) hb_##name##_get_user_data, \
156 (make_immutable_func_t) hb_##name##_make_immutable, \
157 (is_immutable_func_t) hb_##name##_is_immutable, \
160 static const object_t objects[] =
162 OBJECT_WITHOUT_IMMUTABILITY (blob),
163 OBJECT_WITHOUT_IMMUTABILITY (buffer),
164 OBJECT_WITHOUT_IMMUTABILITY (face),
165 OBJECT_WITHOUT_IMMUTABILITY (font),
166 OBJECT_WITH_IMMUTABILITY (font_funcs),
167 OBJECT_WITH_IMMUTABILITY (unicode_funcs)
172 #define MAGIC0 0x12345678
173 #define MAGIC1 0x76543210
180 static int global_data;
182 static void global_free_up (void *p G_GNUC_UNUSED)
187 static void free_up0 (void *p)
189 data_t *data = (data_t *) p;
191 g_assert_cmphex (data->value, ==, MAGIC0);
192 g_assert (!data->freed);
196 static void free_up1 (void *p)
198 data_t *data = (data_t *) p;
200 g_assert_cmphex (data->value, ==, MAGIC1);
201 g_assert (!data->freed);
210 for (i = 0; i < G_N_ELEMENTS (objects); i++) {
211 const object_t *o = &objects[i];
213 hb_user_data_key_t key[2];
217 data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
219 g_test_message ("Testing object %s", o->name);
221 g_test_message ("->create()");
225 g_assert (obj == o->reference (obj));
229 g_assert (!o->is_immutable (obj));
231 g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
232 g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
234 if (o->is_immutable) {
235 o->make_immutable (obj);
236 g_assert (o->is_immutable (obj));
239 /* Should still work even if object is made immutable */
240 g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1));
241 g_assert (o->get_user_data (obj, &key[1]) == &data[1]);
243 g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0));
244 g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
245 g_assert (o->set_user_data (obj, &key[0], &data[1], NULL));
246 g_assert (data[0].freed);
247 g_assert (o->get_user_data (obj, &key[0]) == &data[1]);
248 g_assert (!data[1].freed);
250 data[0].freed = FALSE;
251 g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
252 g_assert (!data[0].freed);
253 g_assert (o->set_user_data (obj, &key[0], NULL, NULL));
254 g_assert (data[0].freed);
256 data[0].freed = FALSE;
258 g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
259 g_assert_cmpuint (global_data, ==, 0);
260 g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up));
261 g_assert_cmpuint (global_data, ==, 0);
262 g_assert (o->set_user_data (obj, &key[0], NULL, NULL));
263 g_assert_cmpuint (global_data, ==, 1);
266 for (i = 2; i < 1000; i++)
267 g_assert (o->set_user_data (obj, &key[i], &data[i], global_free_up));
268 for (i = 2; i < 1000; i++)
269 g_assert (o->get_user_data (obj, &key[i]) == &data[i]);
270 for (i = 100; i < 1000; i++)
271 g_assert (o->set_user_data (obj, &key[i], NULL, NULL));
272 for (i = 2; i < 100; i++)
273 g_assert (o->get_user_data (obj, &key[i]) == &data[i]);
274 for (i = 100; i < 1000; i++)
275 g_assert (!o->get_user_data (obj, &key[i]));
276 g_assert_cmpuint (global_data, ==, 900);
279 g_assert (!data[1].freed);
281 g_assert (data[0].freed);
282 g_assert (data[1].freed);
283 g_assert_cmpuint (global_data, ==, 1000-2);
287 data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
289 g_test_message ("->create_inert()");
290 obj = o->create_inert ();
294 g_assert (obj == o->reference (obj));
298 g_assert (o->is_immutable (obj));
300 g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0));
301 g_assert (!o->get_user_data (obj, &key[0]));
309 g_assert (!data[0].freed);
316 main (int argc, char **argv)
318 hb_test_init (&argc, &argv);
320 hb_test_add (test_object);
322 return hb_test_run ();