tests: add signal marshalling return tests for int/uint
[platform/upstream/glib.git] / gobject / tests / signals.c
1 #include <glib-object.h>
2
3 typedef enum {
4   TEST_ENUM_NEGATIVE = -30,
5   TEST_ENUM_NONE = 0,
6   TEST_ENUM_FOO = 1,
7   TEST_ENUM_BAR = 2
8 } TestEnum;
9
10 typedef enum {
11   TEST_UNSIGNED_ENUM_FOO = 1,
12   TEST_UNSIGNED_ENUM_BAR = 0x80000000
13 } TestUnsignedEnum;
14
15 GType
16 test_enum_get_type (void)
17 {
18   static volatile gsize g_define_type_id__volatile = 0;
19
20   if (g_once_init_enter (&g_define_type_id__volatile))
21     {
22       static const GEnumValue values[] = {
23         { TEST_ENUM_NEGATIVE, "TEST_ENUM_NEGATIVE", "negative" },
24         { TEST_ENUM_NONE, "TEST_ENUM_NONE", "none" },
25         { TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" },
26         { TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" },
27         { 0, NULL, NULL }
28       };
29       GType g_define_type_id =
30         g_enum_register_static (g_intern_static_string ("TestEnum"), values);
31       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
32     }
33
34   return g_define_type_id__volatile;
35 }
36
37 GType
38 test_unsigned_enum_get_type (void)
39 {
40   static volatile gsize g_define_type_id__volatile = 0;
41
42   if (g_once_init_enter (&g_define_type_id__volatile))
43     {
44       static const GEnumValue values[] = {
45         { TEST_UNSIGNED_ENUM_FOO, "TEST_UNSIGNED_ENUM_FOO", "foo" },
46         { TEST_UNSIGNED_ENUM_BAR, "TEST_UNSIGNED_ENUM_BAR", "bar" },
47         { 0, NULL, NULL }
48       };
49       GType g_define_type_id =
50         g_enum_register_static (g_intern_static_string ("TestUnsignedEnum"), values);
51       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
52     }
53
54   return g_define_type_id__volatile;
55 }
56
57
58 typedef struct _Test Test;
59 typedef struct _TestClass TestClass;
60
61 struct _Test
62 {
63   GObject parent_instance;
64 };
65
66 struct _TestClass
67 {
68   GObjectClass parent_class;
69
70   void (* variant_changed) (Test *, GVariant *);
71 };
72
73 static GType test_get_type (void);
74 G_DEFINE_TYPE (Test, test, G_TYPE_OBJECT)
75
76 static void
77 test_init (Test *test)
78 {
79 }
80
81 static void
82 test_class_init (TestClass *klass)
83 {
84   g_signal_new ("generic-marshaller-1",
85                 G_TYPE_FROM_CLASS (klass),
86                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
87                 0,
88                 NULL, NULL,
89                 NULL,
90                 G_TYPE_NONE,
91                 7,
92                 G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_INT, G_TYPE_LONG, G_TYPE_POINTER, G_TYPE_DOUBLE, G_TYPE_FLOAT);
93   g_signal_new ("generic-marshaller-2",
94                 G_TYPE_FROM_CLASS (klass),
95                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
96                 0,
97                 NULL, NULL,
98                 NULL,
99                 G_TYPE_NONE,
100                 5,
101                 G_TYPE_INT, test_enum_get_type(), G_TYPE_INT, test_unsigned_enum_get_type (), G_TYPE_INT);
102   g_signal_new ("generic-marshaller-enum-return-signed",
103                 G_TYPE_FROM_CLASS (klass),
104                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
105                 0,
106                 NULL, NULL,
107                 NULL,
108                 test_enum_get_type(),
109                 0);
110   g_signal_new ("generic-marshaller-enum-return-unsigned",
111                 G_TYPE_FROM_CLASS (klass),
112                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
113                 0,
114                 NULL, NULL,
115                 NULL,
116                 test_unsigned_enum_get_type(),
117                 0);
118   g_signal_new ("generic-marshaller-int-return",
119                 G_TYPE_FROM_CLASS (klass),
120                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
121                 0,
122                 NULL, NULL,
123                 NULL,
124                 G_TYPE_INT,
125                 0);
126   g_signal_new ("generic-marshaller-uint-return",
127                 G_TYPE_FROM_CLASS (klass),
128                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
129                 0,
130                 NULL, NULL,
131                 NULL,
132                 G_TYPE_UINT,
133                 0);
134   g_signal_new ("variant-changed-no-slot",
135                 G_TYPE_FROM_CLASS (klass),
136                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
137                 0,
138                 NULL, NULL,
139                 g_cclosure_marshal_VOID__VARIANT,
140                 G_TYPE_NONE,
141                 1,
142                 G_TYPE_VARIANT);
143   g_signal_new ("variant-changed",
144                 G_TYPE_FROM_CLASS (klass),
145                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
146                 G_STRUCT_OFFSET (TestClass, variant_changed),
147                 NULL, NULL,
148                 g_cclosure_marshal_VOID__VARIANT,
149                 G_TYPE_NONE,
150                 1,
151                 G_TYPE_VARIANT);
152 }
153
154 static void
155 test_variant_signal (void)
156 {
157   Test *test;
158   GVariant *v;
159
160   /* Tests that the signal emission consumes the variant,
161    * even if there are no handlers connected.
162    */
163
164   test = g_object_new (test_get_type (), NULL);
165
166   v = g_variant_new_boolean (TRUE);
167   g_variant_ref (v);
168   g_assert (g_variant_is_floating (v));
169   g_signal_emit_by_name (test, "variant-changed-no-slot", v);
170   g_assert (!g_variant_is_floating (v));
171   g_variant_unref (v);
172
173   v = g_variant_new_boolean (TRUE);
174   g_variant_ref (v);
175   g_assert (g_variant_is_floating (v));
176   g_signal_emit_by_name (test, "variant-changed", v);
177   g_assert (!g_variant_is_floating (v));
178   g_variant_unref (v);
179
180   g_object_unref (test);
181 }
182
183 static void
184 on_generic_marshaller_1 (Test *obj,
185                          gint8 v_schar,
186                          guint8 v_uchar,
187                          gint v_int,
188                          glong v_long,
189                          gpointer v_pointer,
190                          gdouble v_double,
191                          gfloat v_float,
192                          gpointer user_data)
193 {
194   g_assert_cmpint (v_schar, ==, 42);
195   g_assert_cmpint (v_uchar, ==, 43);
196   g_assert_cmpint (v_int, ==, 4096);
197   g_assert_cmpint (v_long, ==, 8192);
198   g_assert (v_pointer == NULL);
199   g_assert_cmpfloat (v_double, >, 0.0);
200   g_assert_cmpfloat (v_double, <, 1.0);
201   g_assert_cmpfloat (v_float, >, 5.0);
202   g_assert_cmpfloat (v_float, <, 6.0);
203 }
204                          
205 static void
206 test_generic_marshaller_signal_1 (void)
207 {
208   Test *test;
209   test = g_object_new (test_get_type (), NULL);
210
211   g_signal_connect (test, "generic-marshaller-1", G_CALLBACK (on_generic_marshaller_1), NULL);
212
213   g_signal_emit_by_name (test, "generic-marshaller-1", 42, 43, 4096, 8192, NULL, 0.5, 5.5);
214
215   g_object_unref (test);
216 }
217
218 static void
219 on_generic_marshaller_2 (Test *obj,
220                          gint        v_int1,
221                          TestEnum    v_enum,
222                          gint        v_int2,
223                          TestUnsignedEnum v_uenum,
224                          gint        v_int3)
225 {
226   g_assert_cmpint (v_int1, ==, 42);
227   g_assert_cmpint (v_enum, ==, TEST_ENUM_BAR);
228   g_assert_cmpint (v_int2, ==, 43);
229   g_assert_cmpint (v_uenum, ==, TEST_UNSIGNED_ENUM_BAR);
230   g_assert_cmpint (v_int3, ==, 44);
231 }
232
233 static void
234 test_generic_marshaller_signal_2 (void)
235 {
236   Test *test;
237   test = g_object_new (test_get_type (), NULL);
238
239   g_signal_connect (test, "generic-marshaller-2", G_CALLBACK (on_generic_marshaller_2), NULL);
240
241   g_signal_emit_by_name (test, "generic-marshaller-2", 42, TEST_ENUM_BAR, 43, TEST_UNSIGNED_ENUM_BAR, 44);
242
243   g_object_unref (test);
244 }
245
246 static TestEnum
247 on_generic_marshaller_enum_return_signed_1 (Test *obj)
248 {
249   return TEST_ENUM_NEGATIVE;
250 }
251
252 static TestEnum
253 on_generic_marshaller_enum_return_signed_2 (Test *obj)
254 {
255   return TEST_ENUM_BAR;
256 }
257
258 static void
259 test_generic_marshaller_signal_enum_return_signed (void)
260 {
261   Test *test;
262   guint id;
263   TestEnum retval = 0;
264
265   test = g_object_new (test_get_type (), NULL);
266
267   /* Test return value NEGATIVE */
268   id = g_signal_connect (test,
269                          "generic-marshaller-enum-return-signed",
270                          G_CALLBACK (on_generic_marshaller_enum_return_signed_1),
271                          NULL);
272   g_signal_emit_by_name (test, "generic-marshaller-enum-return-signed", &retval);
273   g_assert_cmpint (retval, ==, TEST_ENUM_NEGATIVE);
274   g_signal_handler_disconnect (test, id);
275
276   /* Test return value BAR */
277   retval = 0;
278   id = g_signal_connect (test,
279                          "generic-marshaller-enum-return-signed",
280                          G_CALLBACK (on_generic_marshaller_enum_return_signed_2),
281                          NULL);
282   g_signal_emit_by_name (test, "generic-marshaller-enum-return-signed", &retval);
283   g_assert_cmpint (retval, ==, TEST_ENUM_BAR);
284   g_signal_handler_disconnect (test, id);
285
286   g_object_unref (test);
287 }
288
289 static TestUnsignedEnum
290 on_generic_marshaller_enum_return_unsigned_1 (Test *obj)
291 {
292   return TEST_UNSIGNED_ENUM_FOO;
293 }
294
295 static TestUnsignedEnum
296 on_generic_marshaller_enum_return_unsigned_2 (Test *obj)
297 {
298   return TEST_UNSIGNED_ENUM_BAR;
299 }
300
301 static void
302 test_generic_marshaller_signal_enum_return_unsigned (void)
303 {
304   Test *test;
305   guint id;
306   TestUnsignedEnum retval = 0;
307
308   test = g_object_new (test_get_type (), NULL);
309
310   /* Test return value FOO */
311   id = g_signal_connect (test,
312                          "generic-marshaller-enum-return-unsigned",
313                          G_CALLBACK (on_generic_marshaller_enum_return_unsigned_1),
314                          NULL);
315   g_signal_emit_by_name (test, "generic-marshaller-enum-return-unsigned", &retval);
316   g_assert_cmpint (retval, ==, TEST_UNSIGNED_ENUM_FOO);
317   g_signal_handler_disconnect (test, id);
318
319   /* Test return value BAR */
320   retval = 0;
321   id = g_signal_connect (test,
322                          "generic-marshaller-enum-return-unsigned",
323                          G_CALLBACK (on_generic_marshaller_enum_return_unsigned_2),
324                          NULL);
325   g_signal_emit_by_name (test, "generic-marshaller-enum-return-unsigned", &retval);
326   g_assert_cmpint (retval, ==, TEST_UNSIGNED_ENUM_BAR);
327   g_signal_handler_disconnect (test, id);
328
329   g_object_unref (test);
330 }
331
332 /**********************/
333
334 static gint
335 on_generic_marshaller_int_return_signed_1 (Test *obj)
336 {
337   return -30;
338 }
339
340 static gint
341 on_generic_marshaller_int_return_signed_2 (Test *obj)
342 {
343   return 2;
344 }
345
346 static void
347 test_generic_marshaller_signal_int_return (void)
348 {
349   Test *test;
350   guint id;
351   gint retval = 0;
352
353   test = g_object_new (test_get_type (), NULL);
354
355   /* Test return value -30 */
356   id = g_signal_connect (test,
357                          "generic-marshaller-int-return",
358                          G_CALLBACK (on_generic_marshaller_int_return_signed_1),
359                          NULL);
360   g_signal_emit_by_name (test, "generic-marshaller-int-return", &retval);
361   g_assert_cmpint (retval, ==, -30);
362   g_signal_handler_disconnect (test, id);
363
364   /* Test return value positive */
365   retval = 0;
366   id = g_signal_connect (test,
367                          "generic-marshaller-int-return",
368                          G_CALLBACK (on_generic_marshaller_int_return_signed_2),
369                          NULL);
370   g_signal_emit_by_name (test, "generic-marshaller-int-return", &retval);
371   g_assert_cmpint (retval, ==, 2);
372   g_signal_handler_disconnect (test, id);
373
374   g_object_unref (test);
375 }
376
377 static guint
378 on_generic_marshaller_uint_return_1 (Test *obj)
379 {
380   return 1;
381 }
382
383 static guint
384 on_generic_marshaller_uint_return_2 (Test *obj)
385 {
386   return G_MAXUINT;
387 }
388
389 static void
390 test_generic_marshaller_signal_uint_return (void)
391 {
392   Test *test;
393   guint id;
394   guint retval = 0;
395
396   test = g_object_new (test_get_type (), NULL);
397
398   id = g_signal_connect (test,
399                          "generic-marshaller-uint-return",
400                          G_CALLBACK (on_generic_marshaller_uint_return_1),
401                          NULL);
402   g_signal_emit_by_name (test, "generic-marshaller-uint-return", &retval);
403   g_assert_cmpint (retval, ==, 1);
404   g_signal_handler_disconnect (test, id);
405
406   retval = 0;
407   id = g_signal_connect (test,
408                          "generic-marshaller-uint-return",
409                          G_CALLBACK (on_generic_marshaller_uint_return_2),
410                          NULL);
411   g_signal_emit_by_name (test, "generic-marshaller-uint-return", &retval);
412   g_assert_cmpint (retval, ==, G_MAXUINT);
413   g_signal_handler_disconnect (test, id);
414
415   g_object_unref (test);
416 }
417
418 /* --- */
419
420 int
421 main (int argc,
422      char *argv[])
423 {
424   g_type_init ();
425
426   g_test_init (&argc, &argv, NULL);
427
428   g_test_add_func ("/gobject/signals/variant", test_variant_signal);
429   g_test_add_func ("/gobject/signals/generic-marshaller-1", test_generic_marshaller_signal_1);
430   g_test_add_func ("/gobject/signals/generic-marshaller-2", test_generic_marshaller_signal_2);
431   g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-signed", test_generic_marshaller_signal_enum_return_signed);
432   g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-unsigned", test_generic_marshaller_signal_enum_return_unsigned);
433   g_test_add_func ("/gobject/signals/generic-marshaller-int-return", test_generic_marshaller_signal_int_return);
434   g_test_add_func ("/gobject/signals/generic-marshaller-uint-return", test_generic_marshaller_signal_uint_return);
435
436   return g_test_run ();
437 }