1 #include <glib.h>
2 #include <stdlib.h>
3
4 static void
5 test_quark_basic (void)
6 {
7 GQuark quark;
8 const gchar *orig = "blargh";
9 gchar *copy;
10 const gchar *str;
11
12 quark = g_quark_try_string ("no-such-quark");
13 g_assert (quark == 0);
14
15 copy = g_strdup (orig);
16 quark = g_quark_from_static_string (orig);
17 g_assert (quark != 0);
18 g_assert (g_quark_from_string (orig) == quark);
19 g_assert (g_quark_from_string (copy) == quark);
20 g_assert (g_quark_try_string (orig) == quark);
21
22 str = g_quark_to_string (quark);
23 g_assert_cmpstr (str, ==, orig);
24
25 g_free (copy);
26 }
27
28 static void
29 test_quark_string (void)
30 {
31 const gchar *orig = "string1";
32 gchar *copy;
33 const gchar *str1;
34 const gchar *str2;
35
36 copy = g_strdup (orig);
37
38 str1 = g_intern_static_string (orig);
39 str2 = g_intern_string (copy);
40 g_assert (str1 == str2);
41 g_assert (str1 == orig);
42
43 g_free (copy);
44 }
45
46 static void
47 test_dataset_basic (void)
48 {
49 gpointer location = (gpointer)test_dataset_basic;
50 gpointer other = (gpointer)test_quark_basic;
51 gpointer data = "test1";
52 gpointer ret;
53
54 g_dataset_set_data (location, "test1", data);
55
56 ret = g_dataset_get_data (location, "test1");
57 g_assert (ret == data);
58
59 ret = g_dataset_get_data (location, "test2");
60 g_assert (ret == NULL);
61
62 ret = g_dataset_get_data (other, "test1");
63 g_assert (ret == NULL);
64
65 g_dataset_set_data (location, "test1", "new-value");
66 ret = g_dataset_get_data (location, "test1");
67 g_assert (ret != data);
68
69 g_dataset_remove_data (location, "test1");
70 ret = g_dataset_get_data (location, "test1");
71 g_assert (ret == NULL);
72
73 ret = g_dataset_get_data (location, NULL);
74 g_assert (ret == NULL);
75 }
76
77 static gint destroy_count;
78
79 static void
80 notify (gpointer data)
81 {
82 destroy_count++;
83 }
84
85 static void
86 test_dataset_full (void)
87 {
88 gpointer location = (gpointer)test_dataset_full;
89
90 g_dataset_set_data_full (location, "test1", "test1", notify);
91
92 destroy_count = 0;
93 g_dataset_set_data (location, "test1", NULL);
94 g_assert (destroy_count == 1);
95
96 g_dataset_set_data_full (location, "test1", "test1", notify);
97
98 destroy_count = 0;
99 g_dataset_remove_data (location, "test1");
100 g_assert (destroy_count == 1);
101
102 g_dataset_set_data_full (location, "test1", "test1", notify);
103
104 destroy_count = 0;
105 g_dataset_remove_no_notify (location, "test1");
106 g_assert (destroy_count == 0);
107 }
108
109 static void
110 foreach (GQuark id,
111 gpointer data,
112 gpointer user_data)
113 {
114 gint *counter = user_data;
115
116 *counter += 1;
117 }
118
119 static void
120 test_dataset_foreach (void)
121 {
122 gpointer location = (gpointer)test_dataset_foreach;
123 gint my_count;
124
125 my_count = 0;
126 g_dataset_set_data_full (location, "test1", "test1", notify);
127 g_dataset_set_data_full (location, "test2", "test2", notify);
128 g_dataset_set_data_full (location, "test3", "test3", notify);
129 g_dataset_foreach (location, foreach, &my_count);
130 g_assert (my_count == 3);
131
132 g_dataset_destroy (location);
133 }
134
135 static void
136 test_dataset_destroy (void)
137 {
138 gpointer location = (gpointer)test_dataset_destroy;
139
140 destroy_count = 0;
141 g_dataset_set_data_full (location, "test1", "test1", notify);
142 g_dataset_set_data_full (location, "test2", "test2", notify);
143 g_dataset_set_data_full (location, "test3", "test3", notify);
144 g_dataset_destroy (location);
145 g_assert (destroy_count == 3);
146 }
147
148 static void
149 test_dataset_id (void)
150 {
151 gpointer location = (gpointer)test_dataset_id;
152 gpointer other = (gpointer)test_quark_basic;
153 gpointer data = "test1";
154 gpointer ret;
155 GQuark quark;
156
157 quark = g_quark_from_string ("test1");
158
159 g_dataset_id_set_data (location, quark, data);
160
161 ret = g_dataset_id_get_data (location, quark);
162 g_assert (ret == data);
163
164 ret = g_dataset_id_get_data (location, g_quark_from_string ("test2"));
165 g_assert (ret == NULL);
166
167 ret = g_dataset_id_get_data (other, quark);
168 g_assert (ret == NULL);
169
170 g_dataset_id_set_data (location, quark, "new-value");
171 ret = g_dataset_id_get_data (location, quark);
172 g_assert (ret != data);
173
174 g_dataset_id_remove_data (location, quark);
175 ret = g_dataset_id_get_data (location, quark);
176 g_assert (ret == NULL);
177
178 ret = g_dataset_id_get_data (location, 0);
179 g_assert (ret == NULL);
180 }
181
182 static GData *global_list;
183
184 static void
185 free_one (gpointer data)
186 {
187 /* recurse */
188 g_datalist_clear (&global_list);
189 }
190
191 static void
192 test_datalist_clear (void)
193 {
194 /* Need to use a subprocess because it will deadlock if it fails */
195 if (g_test_subprocess ())
196 {
197 g_datalist_init (&global_list);
198 g_datalist_set_data_full (&global_list, "one", GINT_TO_POINTER (1), free_one);
199 g_datalist_set_data_full (&global_list, "two", GINT_TO_POINTER (2), NULL);
200 g_datalist_clear (&global_list);
201 g_assert (global_list == NULL);
202 return;
203 }
204
205 g_test_trap_subprocess (NULL, 500000, G_TEST_SUBPROCESS_DEFAULT);
206 g_test_trap_assert_passed ();
207 }
208
209 static void
210 test_datalist_basic (void)
211 {
212 GData *list = NULL;
213 gpointer data;
214 gpointer ret;
215
216 g_datalist_init (&list);
217 data = "one";
218 g_datalist_set_data (&list, "one", data);
219 ret = g_datalist_get_data (&list, "one");
220 g_assert (ret == data);
221
222 ret = g_datalist_get_data (&list, "two");
223 g_assert (ret == NULL);
224
225 ret = g_datalist_get_data (&list, NULL);
226 g_assert (ret == NULL);
227
228 g_datalist_clear (&list);
229 }
230
231 static void
232 test_datalist_id (void)
233 {
234 GData *list = NULL;
235 gpointer data;
236 gpointer ret;
237
238 g_datalist_init (&list);
239 data = "one";
240 g_datalist_id_set_data (&list, g_quark_from_string ("one"), data);
241 ret = g_datalist_id_get_data (&list, g_quark_from_string ("one"));
242 g_assert (ret == data);
243
244 ret = g_datalist_id_get_data (&list, g_quark_from_string ("two"));
245 g_assert (ret == NULL);
246
247 ret = g_datalist_id_get_data (&list, 0);
248 g_assert (ret == NULL);
249
250 g_datalist_clear (&list);
251 }
252
253 static void
254 test_datalist_id_remove_multiple (void)
255 {
256 /* Test that g_datalist_id_remove_multiple() removes all the keys it
257 * is given. */
258 GData *list = NULL;
259 GQuark one = g_quark_from_static_string ("one");
260 GQuark two = g_quark_from_static_string ("two");
261 GQuark three = g_quark_from_static_string ("three");
262 GQuark keys[] = {
263 one,
264 two,
265 three,
266 };
267
268 g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/2672");
269
270 g_datalist_init (&list);
271 g_datalist_id_set_data (&list, one, GINT_TO_POINTER (1));
272 g_datalist_id_set_data (&list, two, GINT_TO_POINTER (2));
273 g_datalist_id_set_data (&list, three, GINT_TO_POINTER (3));
274
275 destroy_count = 0;
276 g_datalist_foreach (&list, (GDataForeachFunc) notify, NULL);
277 g_assert_cmpint (destroy_count, ==, 3);
278
279 g_datalist_id_remove_multiple (&list, keys, G_N_ELEMENTS (keys));
280
281 destroy_count = 0;
282 g_datalist_foreach (&list, (GDataForeachFunc) notify, NULL);
283 g_assert_cmpint (destroy_count, ==, 0);
284 }
285
286 static void
287 destroy_func (gpointer data)
288 {
289 destroy_count++;
290 g_assert_cmpint (GPOINTER_TO_INT (data), ==, destroy_count);
291 }
292
293 static void
294 test_datalist_id_remove_multiple_destroy_order (void)
295 {
296 /* Test that destroy-funcs are called in the order that the keys are
297 * specified, not the order that they are found in the datalist. */
298 GData *list = NULL;
299 GQuark one = g_quark_from_static_string ("one");
300 GQuark two = g_quark_from_static_string ("two");
301 GQuark three = g_quark_from_static_string ("three");
302 GQuark keys[] = {
303 one,
304 two,
305 three,
306 };
307
308 g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/2672");
309
310 g_datalist_init (&list);
311
312 g_datalist_id_set_data_full (&list, two, GINT_TO_POINTER (2), destroy_func);
313 g_datalist_id_set_data_full (&list, three, GINT_TO_POINTER (3), destroy_func);
314 g_datalist_id_set_data_full (&list, one, GINT_TO_POINTER (1), destroy_func);
315
316 destroy_count = 0;
317 g_datalist_id_remove_multiple (&list, keys, G_N_ELEMENTS (keys));
318 /* This verifies that destroy_func() was called three times: */
319 g_assert_cmpint (destroy_count, ==, 3);
320 }
321
322 int
323 main (int argc, char *argv[])
324 {
325 g_test_init (&argc, &argv, NULL);
326
327 g_test_add_func ("/quark/basic", test_quark_basic);
328 g_test_add_func ("/quark/string", test_quark_string);
329 g_test_add_func ("/dataset/basic", test_dataset_basic);
330 g_test_add_func ("/dataset/id", test_dataset_id);
331 g_test_add_func ("/dataset/full", test_dataset_full);
332 g_test_add_func ("/dataset/foreach", test_dataset_foreach);
333 g_test_add_func ("/dataset/destroy", test_dataset_destroy);
334 g_test_add_func ("/datalist/basic", test_datalist_basic);
335 g_test_add_func ("/datalist/id", test_datalist_id);
336 g_test_add_func ("/datalist/recursive-clear", test_datalist_clear);
337 g_test_add_func ("/datalist/id-remove-multiple", test_datalist_id_remove_multiple);
338 g_test_add_func ("/datalist/id-remove-multiple-destroy-order",
339 test_datalist_id_remove_multiple_destroy_order);
340
341 return g_test_run ();
342 }