Test for interface properties and GParamSpecOverride.
[platform/upstream/glib.git] / tests / gobject / override.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * override.c: Closure override test program
3  * Copyright (C) 2001, James Henstridge
4  * Copyright (C) 2003, Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General
17  * Public License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #undef  G_LOG_DOMAIN
23 #define G_LOG_DOMAIN "TestOverride"
24
25 #undef G_DISABLE_ASSERT
26 #undef G_DISABLE_CHECKS
27 #undef G_DISABLE_CAST_CHECKS
28
29 #undef VERBOSE
30
31 #include <string.h>
32
33 #include <glib.h>
34 #include <glib-object.h>
35
36 #include "testcommon.h"
37
38 static guint foo_signal_id = 0;
39 static guint bar_signal_id = 0;
40
41 static GType test_i_get_type (void);
42 static GType test_a_get_type (void);
43 static GType test_b_get_type (void);
44 static GType test_c_get_type (void);
45
46 static void  record (const gchar *str);
47
48 #define TEST_TYPE_I (test_i_get_type ())
49
50 typedef struct _TestI TestI;
51 typedef struct _TestIClass TestIClass;
52
53 struct _TestIClass
54 {
55   GTypeInterface base_iface;
56 };
57
58 static void
59 test_i_foo (TestI *self)
60 {
61   record ("TestI::foo");
62 }
63
64 static void
65 test_i_default_init (gpointer g_class)
66 {
67   foo_signal_id = g_signal_newv ("foo",
68                                  TEST_TYPE_I,
69                                  G_SIGNAL_RUN_LAST,
70                                  g_cclosure_new(G_CALLBACK(test_i_foo),
71                                                 NULL, NULL),
72                                  NULL, NULL,
73                                  g_cclosure_marshal_VOID__VOID,
74                                  G_TYPE_NONE, 0, NULL);
75 }
76
77 static DEFINE_IFACE (TestI, test_i, NULL, test_i_default_init)
78
79 #define TEST_TYPE_A (test_a_get_type())
80
81      typedef struct _TestA TestA;
82      typedef struct _TestAClass TestAClass;
83
84 struct _TestA {
85   GObject parent;
86 };
87 struct _TestAClass {
88   GObjectClass parent_class;
89
90   void (* bar) (TestA *self);
91 };
92
93 static void
94 test_a_foo (TestI *self)
95 {
96   GValue args[1] = { { 0, } };
97
98   record ("TestA::foo");
99
100   g_value_init (&args[0], TEST_TYPE_A);
101   g_value_set_object (&args[0], self);
102
103   g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
104   g_signal_chain_from_overridden (args, NULL);
105
106   g_value_unset (&args[0]);
107 }
108
109 static void
110 test_a_bar (TestA *self)
111 {
112   record ("TestA::bar");
113 }
114
115 static void
116 test_a_class_init (TestAClass *class)
117 {
118   class->bar = test_a_bar;
119
120   bar_signal_id = g_signal_new ("bar",
121                                 TEST_TYPE_A,
122                                 G_SIGNAL_RUN_LAST,
123                                 G_STRUCT_OFFSET (TestAClass, bar),
124                                 NULL, NULL,
125                                 g_cclosure_marshal_VOID__VOID,
126                                 G_TYPE_NONE, 0, NULL);
127 }
128
129 static void
130 test_a_interface_init (TestIClass *iface)
131 {
132   g_signal_override_class_closure (foo_signal_id,
133                                    TEST_TYPE_A,
134                                    g_cclosure_new (G_CALLBACK (test_a_foo),
135                                                    NULL, NULL));
136 }
137
138 static DEFINE_TYPE_FULL (TestA, test_a,
139                          test_a_class_init, NULL, NULL,
140                          G_TYPE_OBJECT,
141                          INTERFACE (test_a_interface_init, TEST_TYPE_I))
142      
143 #define TEST_TYPE_B (test_b_get_type())
144
145 typedef struct _TestB TestB;
146 typedef struct _TestBClass TestBClass;
147
148 struct _TestB {
149   TestA parent;
150 };
151 struct _TestBClass {
152   TestAClass parent_class;
153 };
154
155 static void
156 test_b_foo (TestA *self)
157 {
158   GValue args[1] = { { 0, } };
159
160   record ("TestB::foo");
161
162   g_value_init (&args[0], TEST_TYPE_A);
163   g_value_set_object (&args[0], self);
164
165   g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
166   g_signal_chain_from_overridden (args, NULL);
167
168   g_value_unset (&args[0]);
169 }
170
171 static void
172 test_b_bar (TestI *self)
173 {
174   GValue args[1] = { { 0, } };
175
176   record ("TestB::bar");
177
178   g_value_init (&args[0], TEST_TYPE_A);
179   g_value_set_object (&args[0], self);
180
181   g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id);
182   g_signal_chain_from_overridden (args, NULL);
183
184   g_value_unset (&args[0]);
185 }
186
187 static void
188 test_b_class_init (TestBClass *class)
189 {
190   g_signal_override_class_closure (foo_signal_id,
191                                    TEST_TYPE_B,
192                                    g_cclosure_new (G_CALLBACK (test_b_foo),
193                                                    NULL, NULL));
194   g_signal_override_class_closure (bar_signal_id,
195                                    TEST_TYPE_B,
196                                    g_cclosure_new (G_CALLBACK (test_b_bar),
197                                                    NULL, NULL));
198 }
199
200 static DEFINE_TYPE (TestB, test_b,
201                     test_b_class_init, NULL, NULL,
202                     TEST_TYPE_A)
203
204 #define TEST_TYPE_C (test_c_get_type())
205
206 typedef struct _TestC TestC;
207 typedef struct _TestCClass TestCClass;
208
209 struct _TestC {
210   TestB parent;
211 };
212 struct _TestCClass {
213   TestBClass parent_class;
214 };
215
216 static void
217 test_c_foo (TestA *self)
218 {
219   GValue args[1] = { { 0, } };
220
221   record ("TestC::foo");
222
223   g_value_init (&args[0], TEST_TYPE_A);
224   g_value_set_object (&args[0], self);
225
226   g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
227   g_signal_chain_from_overridden (args, NULL);
228
229   g_value_unset (&args[0]);
230 }
231
232 static void
233 test_c_bar (TestI *self)
234 {
235   GValue args[1] = { { 0, } };
236
237   record ("TestC::bar");
238
239   g_value_init (&args[0], TEST_TYPE_A);
240   g_value_set_object (&args[0], self);
241
242   g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id);
243   g_signal_chain_from_overridden (args, NULL);
244
245   g_value_unset (&args[0]);
246 }
247
248 static void
249 test_c_class_init (TestBClass *class)
250 {
251   g_signal_override_class_closure (foo_signal_id,
252                                    TEST_TYPE_C,
253                                    g_cclosure_new (G_CALLBACK (test_c_foo),
254                                                    NULL, NULL));
255   g_signal_override_class_closure (bar_signal_id,
256                                    TEST_TYPE_C,
257                                    g_cclosure_new (G_CALLBACK (test_c_bar),
258                                                    NULL, NULL));
259 }
260
261
262 static DEFINE_TYPE (TestC, test_c,
263                     test_c_class_init, NULL, NULL,
264                     TEST_TYPE_B)
265
266 static GString *test_string = NULL;
267 gboolean failed = FALSE;
268      
269 static void
270 record (const gchar *str)
271 {
272   if (test_string->len)
273     g_string_append_c (test_string, ',');
274   g_string_append (test_string, str);
275 }
276      
277 static void
278 test (GType        type,
279       const gchar *signal,
280       const gchar *expected)
281 {
282   GObject *self = g_object_new (type, NULL);
283
284   test_string = g_string_new (NULL);
285
286   g_signal_emit_by_name (self, signal, 0);
287
288 #ifndef VERBOSE
289   if (strcmp (test_string->str, expected) != 0)
290 #endif
291     {
292       g_printerr ("*** emitting %s on a %s instance\n"
293                   "    Expecting: %s\n"
294                   "    Got: %s\n",
295                   signal, g_type_name (type),
296                   expected,
297                   test_string->str);
298       
299       if (strcmp (test_string->str, expected) != 0)
300         failed = TRUE;
301     }
302
303   g_string_free (test_string, TRUE);
304 }
305      
306 int
307 main (int argc, char **argv)
308 {
309   g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
310                           G_LOG_LEVEL_WARNING |
311                           G_LOG_LEVEL_CRITICAL);
312   g_type_init();
313
314   test (TEST_TYPE_A, "foo", "TestA::foo,TestI::foo");
315   test (TEST_TYPE_A, "bar", "TestA::bar");
316
317   test (TEST_TYPE_B, "foo", "TestB::foo,TestA::foo,TestI::foo");
318   test (TEST_TYPE_B, "bar", "TestB::bar,TestA::bar");
319
320   test (TEST_TYPE_C, "foo", "TestC::foo,TestB::foo,TestA::foo,TestI::foo");
321   test (TEST_TYPE_C, "bar", "TestC::bar,TestB::bar,TestA::bar");
322
323   return failed ? 1 : 0;
324 }