Implement execution mode property
[nautilus-actions.git] / src / test / test-virtuals.c
blobc48eaac0c9782726fd50d4ec56c4a35f43749110
1 /*
2 * Nautilus-Actions
3 * A Nautilus extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
9 * This Program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * This Program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this Library; see the file COPYING. If not,
21 * write to the Free Software Foundation, Inc., 59 Temple Place,
22 * Suite 330, Boston, MA 02111-1307, USA.
24 * Authors:
25 * Frederic Ruaudel <grumz@grumz.net>
26 * Rodrigo Moya <rodrigo@gnome-db.org>
27 * Pierre Wieser <pwieser@trychlos.org>
28 * ... and many others (see AUTHORS)
31 /* We want test here what is the exact behavior of virtual functions in
32 * derived classes, whether or not base class has implemented them or
33 * not.
35 * We define three classes, and some virtual functions :
36 * class 'first': fn_a, fn_b, fn_c
37 * class 'second', derived from 'first', implements fn_a, fn_b
38 * class 'three', derived from 'second': implements fn_a, fn_c
40 * Public entry points are defined in class 'first': we check that calling
41 * public entry points with an object of each class actually calls the
42 * relevant virtual function.
44 * Also we check if calling the parent class is possible even if the
45 * parent class has not explicitely defined the virtual function.
47 * NOTE: this only works if we do _not_ set the virtual method to NULL
48 * in intermediate classes.
51 #include <glib-object.h>
52 #include <glib.h>
54 #define PWI_TYPE_FIRST ( pwi_first_get_type())
55 #define PWI_FIRST( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, PWI_TYPE_FIRST, PwiFirst ))
56 #define PWI_FIRST_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, PWI_TYPE_FIRST, PwiFirstClass ))
57 #define PWI_IS_FIRST( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, PWI_TYPE_FIRST ))
58 #define PWI_IS_FIRST_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), PWI_TYPE_FIRST ))
59 #define PWI_FIRST_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), PWI_TYPE_FIRST, PwiFirstClass ))
61 typedef struct {
62 void *empty; /* so that gcc -pedantic is happy */
64 PwiFirstPrivate;
66 typedef struct {
67 GObject parent;
68 PwiFirstPrivate *private;
70 PwiFirst;
72 typedef struct {
73 void *empty; /* so that gcc -pedantic is happy */
75 PwiFirstClassPrivate;
77 typedef struct {
78 GObjectClass parent;
79 PwiFirstClassPrivate *private;
81 /* virtual functions */
82 void ( *fn_a )( PwiFirst *instance );
83 void ( *fn_b )( PwiFirst *instance );
84 void ( *fn_c )( PwiFirst *instance );
86 PwiFirstClass;
88 static GObjectClass *pwi_first_parent_class = NULL;
89 static GType pwi_first_get_type( void );
90 static void pwi_first_class_init( PwiFirstClass *klass );
91 static void pwi_first_init( PwiFirst *instance, gpointer klass );
93 static GType
94 pwi_first_register_type( void )
96 static const gchar *thisfn = "first_register_type";
98 static GTypeInfo info = {
99 sizeof( PwiFirstClass ),
100 ( GBaseInitFunc ) NULL,
101 ( GBaseFinalizeFunc ) NULL,
102 ( GClassInitFunc ) pwi_first_class_init,
103 NULL,
104 NULL,
105 sizeof( PwiFirst ),
107 ( GInstanceInitFunc ) pwi_first_init
110 g_debug( "%s", thisfn );
111 return( g_type_register_static( G_TYPE_OBJECT, "PwiFirst", &info, 0 ));
114 static GType
115 pwi_first_get_type( void )
117 static GType type = 0;
119 if( !type ){
120 type = pwi_first_register_type();
123 return( type );
126 static void
127 do_first_fn_a( PwiFirst *instance )
129 g_debug( "do_first_fn_a: instance=%p", ( void * ) instance );
132 static void
133 do_first_fn_b( PwiFirst *instance )
135 g_debug( "do_first_fn_b: instance=%p", ( void * ) instance );
138 static void
139 do_first_fn_c( PwiFirst *instance )
141 g_debug( "do_first_fn_c: instance=%p", ( void * ) instance );
144 static void
145 pwi_first_class_init( PwiFirstClass *klass )
147 static const gchar *thisfn = "pwi_first_class_init";
149 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
151 pwi_first_parent_class = g_type_class_peek_parent( klass );
153 klass->private = g_new0( PwiFirstClassPrivate, 1 );
155 klass->fn_a = do_first_fn_a;
156 klass->fn_b = do_first_fn_b;
157 klass->fn_c = do_first_fn_c;
160 static void
161 pwi_first_init( PwiFirst *self, gpointer klass )
163 static const gchar *thisfn = "pwi_first_init";
165 g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) self, ( void * ) klass );
167 self->private = g_new0( PwiFirstPrivate, 1 );
170 void pwi_first_fn_a( PwiFirst *instance );
171 void pwi_first_fn_b( PwiFirst *instance );
172 void pwi_first_fn_c( PwiFirst *instance );
174 void
175 pwi_first_fn_a( PwiFirst *instance )
177 g_debug( "pwi_first_fn_a: instance=%p", ( void * ) instance );
178 g_assert( PWI_IS_FIRST( instance ));
180 if( PWI_FIRST_GET_CLASS( instance )->fn_a ){
181 PWI_FIRST_GET_CLASS( instance )->fn_a( instance );
182 } else {
183 g_debug( "default to invoke do_first_fn_a()" );
184 do_first_fn_a( instance );
188 void
189 pwi_first_fn_b( PwiFirst *instance )
191 g_debug( "pwi_first_fn_b: instance=%p", ( void * ) instance );
192 g_assert( PWI_IS_FIRST( instance ));
194 if( PWI_FIRST_GET_CLASS( instance )->fn_b ){
195 PWI_FIRST_GET_CLASS( instance )->fn_b( instance );
196 } else {
197 g_debug( "default to invoke do_first_fn_b()" );
198 do_first_fn_b( instance );
202 void
203 pwi_first_fn_c( PwiFirst *instance )
205 g_debug( "pwi_first_fn_c: instance=%p", ( void * ) instance );
206 g_assert( PWI_IS_FIRST( instance ));
208 if( PWI_FIRST_GET_CLASS( instance )->fn_c ){
209 PWI_FIRST_GET_CLASS( instance )->fn_c( instance );
210 } else {
211 g_debug( "default to invoke do_first_fn_c()" );
212 do_first_fn_c( instance );
216 #define PWI_TYPE_SECOND ( pwi_second_get_type())
217 #define PWI_SECOND( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, PWI_TYPE_SECOND, PwiSecond ))
218 #define PWI_SECOND_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, PWI_TYPE_SECOND, PwiSecondClass ))
219 #define PWI_IS_SECOND( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, PWI_TYPE_SECOND ))
220 #define PWI_IS_SECOND_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), PWI_TYPE_SECOND ))
221 #define PWI_SECOND_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), PWI_TYPE_SECOND, PwiSecondClass ))
223 typedef struct {
224 void *empty; /* so that gcc -pedantic is happy */
226 PwiSecondPrivate;
228 typedef struct {
229 PwiFirst parent;
230 PwiSecondPrivate *private;
232 PwiSecond;
234 typedef struct {
235 void *empty; /* so that gcc -pedantic is happy */
237 PwiSecondClassPrivate;
239 typedef struct {
240 PwiFirstClass parent;
241 PwiSecondClassPrivate *private;
243 PwiSecondClass;
245 static GObjectClass *pwi_second_parent_class = NULL;
246 static GType pwi_second_get_type( void );
247 static void pwi_second_class_init( PwiSecondClass *klass );
248 static void pwi_second_init( PwiSecond *instance, gpointer klass );
250 static GType
251 pwi_second_register_type( void )
253 static const gchar *thisfn = "second_register_type";
255 static GTypeInfo info = {
256 sizeof( PwiSecondClass ),
257 ( GBaseInitFunc ) NULL,
258 ( GBaseFinalizeFunc ) NULL,
259 ( GClassInitFunc ) pwi_second_class_init,
260 NULL,
261 NULL,
262 sizeof( PwiSecond ),
264 ( GInstanceInitFunc ) pwi_second_init
267 g_debug( "%s", thisfn );
268 return( g_type_register_static( PWI_TYPE_FIRST, "PwiSecond", &info, 0 ));
271 static GType
272 pwi_second_get_type( void )
274 static GType type = 0;
276 if( !type ){
277 type = pwi_second_register_type();
280 return( type );
283 static void
284 do_second_fn_a( PwiFirst *instance )
286 g_debug( "do_second_fn_a: instance=%p", ( void * ) instance );
287 if( PWI_FIRST_CLASS( pwi_second_parent_class )->fn_a ){
288 PWI_FIRST_CLASS( pwi_second_parent_class )->fn_a( instance );
292 static void
293 do_second_fn_b( PwiFirst *instance )
295 g_debug( "do_second_fn_b: instance=%p", ( void * ) instance );
296 if( PWI_FIRST_CLASS( pwi_second_parent_class )->fn_b ){
297 PWI_FIRST_CLASS( pwi_second_parent_class )->fn_b( instance );
301 static void
302 pwi_second_class_init( PwiSecondClass *klass )
304 static const gchar *thisfn = "pwi_second_class_init";
305 PwiFirstClass *parent_class;
307 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
309 pwi_second_parent_class = g_type_class_peek_parent( klass );
311 klass->private = g_new0( PwiSecondClassPrivate, 1 );
313 parent_class = PWI_FIRST_CLASS( klass );
314 parent_class->fn_a = do_second_fn_a;
315 parent_class->fn_b = do_second_fn_b;
316 /*parent_class->fn_c = NULL;*/
319 static void
320 pwi_second_init( PwiSecond *self, gpointer klass )
322 static const gchar *thisfn = "pwi_second_init";
324 g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) self, ( void * ) klass );
326 self->private = g_new0( PwiSecondPrivate, 1 );
329 #define PWI_TYPE_THREE ( pwi_three_get_type())
330 #define PWI_THREE( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, PWI_TYPE_THREE, PwiThree ))
331 #define PWI_THREE_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, PWI_TYPE_THREE, PwiThreeClass ))
332 #define PWI_IS_THREE( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, PWI_TYPE_THREE ))
333 #define PWI_IS_THREE_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), PWI_TYPE_THREE ))
334 #define PWI_THREE_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), PWI_TYPE_THREE, PwiThreeClass ))
336 typedef struct {
337 void *empty; /* so that gcc -pedantic is happy */
339 PwiThreePrivate;
341 typedef struct {
342 PwiSecond parent;
343 PwiThreePrivate *private;
345 PwiThree;
347 typedef struct {
348 void *empty; /* so that gcc -pedantic is happy */
350 PwiThreeClassPrivate;
352 typedef struct {
353 PwiSecondClass parent;
354 PwiThreeClassPrivate *private;
356 PwiThreeClass;
358 static GObjectClass *pwi_three_parent_class = NULL;
359 static GType pwi_three_get_type( void );
360 static void pwi_three_class_init( PwiThreeClass *klass );
361 static void pwi_three_init( PwiThree *instance, gpointer klass );
363 static GType
364 pwi_three_register_type( void )
366 static const gchar *thisfn = "three_register_type";
368 static GTypeInfo info = {
369 sizeof( PwiThreeClass ),
370 ( GBaseInitFunc ) NULL,
371 ( GBaseFinalizeFunc ) NULL,
372 ( GClassInitFunc ) pwi_three_class_init,
373 NULL,
374 NULL,
375 sizeof( PwiThree ),
377 ( GInstanceInitFunc ) pwi_three_init
380 g_debug( "%s", thisfn );
381 return( g_type_register_static( PWI_TYPE_SECOND, "PwiThree", &info, 0 ));
384 static GType
385 pwi_three_get_type( void )
387 static GType type = 0;
389 if( !type ){
390 type = pwi_three_register_type();
393 return( type );
396 static void
397 do_three_fn_a( PwiFirst *instance )
399 g_debug( "do_three_fn_a: instance=%p", ( void * ) instance );
400 if( PWI_FIRST_CLASS( pwi_three_parent_class )->fn_a ){
401 PWI_FIRST_CLASS( pwi_three_parent_class )->fn_a( instance );
405 static void
406 do_three_fn_c( PwiFirst *instance )
408 g_debug( "do_three_fn_c: instance=%p", ( void * ) instance );
409 if( PWI_FIRST_CLASS( pwi_three_parent_class )->fn_c ){
410 PWI_FIRST_CLASS( pwi_three_parent_class )->fn_c( instance );
414 static void
415 pwi_three_class_init( PwiThreeClass *klass )
417 static const gchar *thisfn = "pwi_three_class_init";
418 PwiFirstClass *parent_class;
420 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
422 pwi_three_parent_class = g_type_class_peek_parent( klass );
424 klass->private = g_new0( PwiThreeClassPrivate, 1 );
426 parent_class = PWI_FIRST_CLASS( klass );
427 parent_class->fn_a = do_three_fn_a;
428 /*parent_class->fn_b = NULL;*/
429 parent_class->fn_c = do_three_fn_c;
432 static void
433 pwi_three_init( PwiThree *self, gpointer klass )
435 static const gchar *thisfn = "pwi_three_init";
437 g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) self, ( void * ) klass );
439 self->private = g_new0( PwiThreePrivate, 1 );
443 main( int argc, char **argv )
445 PwiFirst *a;
446 PwiSecond *b;
447 PwiThree *c;
449 g_type_init();
451 a = g_object_new( PWI_TYPE_FIRST, NULL );
452 b = g_object_new( PWI_TYPE_SECOND, NULL );
453 c = g_object_new( PWI_TYPE_THREE, NULL );
455 g_debug( "%s", "" );
457 g_debug( "expected pwi_first_fn_a, do_first_fn_a" );
458 pwi_first_fn_a( PWI_FIRST( a ));
459 g_debug( "expected pwi_first_fn_a, do_second_fn_a, do_first_fn_a" );
460 pwi_first_fn_a( PWI_FIRST( b ));
461 g_debug( "expected pwi_first_fn_a, do_three_fn_a, do_second_fn_a, do_first_fn_a" );
462 pwi_first_fn_a( PWI_FIRST( c ));
464 g_debug( "%s", "" );
466 g_debug( "expected pwi_first_fn_b, do_first_fn_b" );
467 pwi_first_fn_b( PWI_FIRST( a ));
468 g_debug( "expected pwi_first_fn_b, do_second_fn_b, do_first_fn_b" );
469 pwi_first_fn_b( PWI_FIRST( b ));
470 g_debug( "expected pwi_first_fn_b, do_second_fn_b, do_first_fn_b" );
471 /* NOT OK
472 * result is pwi_first_fn_b, default to do_first_fn_b */
473 pwi_first_fn_b( PWI_FIRST( c ));
475 g_debug( "%s", "" );
477 g_debug( "expected pwi_first_fn_c, do_first_fn_c" );
478 pwi_first_fn_c( PWI_FIRST( a ));
479 g_debug( "expected pwi_first_fn_c, do_first_fn_c" );
480 pwi_first_fn_c( PWI_FIRST( b ));
481 g_debug( "expected pwi_first_fn_c, do_three_fn_c, do_first_fn_c" );
482 /* NOT OK
483 * result is pwi_first_fn_c, do_three_fn_c */
484 pwi_first_fn_c( PWI_FIRST( c ));
486 return( 0 );