From 4ec041d593b91392b42129aab433554ef5d3596d Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Fri, 12 Sep 2003 20:37:09 +0000 Subject: [PATCH] New directory, framework for automated GObject tests. Fri Sep 12 16:26:21 2003 Owen Taylor * tests/gobject/ configure.in: New directory, framework for automated GObject tests. * tests/gobject/override.c: Move testoverride.c here, automate. * tests/gobject/ifaceinit.c: Move testifaceinit.c here. * tests/gobject/accumulator.c: Test signal accumulators, including g_signal_accumulator_true_handled. --- ChangeLog | 13 + ChangeLog.pre-2-10 | 13 + ChangeLog.pre-2-12 | 13 + ChangeLog.pre-2-4 | 13 + ChangeLog.pre-2-6 | 13 + ChangeLog.pre-2-8 | 13 + configure.in | 1 + tests/gobject/.cvsignore | 8 + tests/gobject/Makefile.am | 71 ++++++ tests/gobject/accumulator.c | 227 ++++++++++++++++++ tests/gobject/ifaceinit.c | 65 +---- tests/gobject/override.c | 421 ++++++++++++++------------------- tests/gobject/testcommon.h | 100 ++++++++ tests/gobject/testmarshal.list | 4 + 14 files changed, 676 insertions(+), 299 deletions(-) create mode 100644 tests/gobject/.cvsignore create mode 100644 tests/gobject/Makefile.am create mode 100644 tests/gobject/accumulator.c create mode 100644 tests/gobject/testcommon.h create mode 100644 tests/gobject/testmarshal.list diff --git a/ChangeLog b/ChangeLog index 2066effdd..8cb7d0900 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Fri Sep 12 16:26:21 2003 Owen Taylor + + * tests/gobject/ configure.in: New directory, framework + for automated GObject tests. + + * tests/gobject/override.c: Move testoverride.c + here, automate. + + * tests/gobject/ifaceinit.c: Move testifaceinit.c here. + + * tests/gobject/accumulator.c: Test signal accumulators, + including g_signal_accumulator_true_handled. + 2003-09-12 Noah Levitt * glib/gen-unicode-tables.pl: Take a directory where to look for the diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 2066effdd..8cb7d0900 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,16 @@ +Fri Sep 12 16:26:21 2003 Owen Taylor + + * tests/gobject/ configure.in: New directory, framework + for automated GObject tests. + + * tests/gobject/override.c: Move testoverride.c + here, automate. + + * tests/gobject/ifaceinit.c: Move testifaceinit.c here. + + * tests/gobject/accumulator.c: Test signal accumulators, + including g_signal_accumulator_true_handled. + 2003-09-12 Noah Levitt * glib/gen-unicode-tables.pl: Take a directory where to look for the diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 2066effdd..8cb7d0900 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,16 @@ +Fri Sep 12 16:26:21 2003 Owen Taylor + + * tests/gobject/ configure.in: New directory, framework + for automated GObject tests. + + * tests/gobject/override.c: Move testoverride.c + here, automate. + + * tests/gobject/ifaceinit.c: Move testifaceinit.c here. + + * tests/gobject/accumulator.c: Test signal accumulators, + including g_signal_accumulator_true_handled. + 2003-09-12 Noah Levitt * glib/gen-unicode-tables.pl: Take a directory where to look for the diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 2066effdd..8cb7d0900 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,16 @@ +Fri Sep 12 16:26:21 2003 Owen Taylor + + * tests/gobject/ configure.in: New directory, framework + for automated GObject tests. + + * tests/gobject/override.c: Move testoverride.c + here, automate. + + * tests/gobject/ifaceinit.c: Move testifaceinit.c here. + + * tests/gobject/accumulator.c: Test signal accumulators, + including g_signal_accumulator_true_handled. + 2003-09-12 Noah Levitt * glib/gen-unicode-tables.pl: Take a directory where to look for the diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 2066effdd..8cb7d0900 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,16 @@ +Fri Sep 12 16:26:21 2003 Owen Taylor + + * tests/gobject/ configure.in: New directory, framework + for automated GObject tests. + + * tests/gobject/override.c: Move testoverride.c + here, automate. + + * tests/gobject/ifaceinit.c: Move testifaceinit.c here. + + * tests/gobject/accumulator.c: Test signal accumulators, + including g_signal_accumulator_true_handled. + 2003-09-12 Noah Levitt * glib/gen-unicode-tables.pl: Take a directory where to look for the diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 2066effdd..8cb7d0900 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,16 @@ +Fri Sep 12 16:26:21 2003 Owen Taylor + + * tests/gobject/ configure.in: New directory, framework + for automated GObject tests. + + * tests/gobject/override.c: Move testoverride.c + here, automate. + + * tests/gobject/ifaceinit.c: Move testifaceinit.c here. + + * tests/gobject/accumulator.c: Test signal accumulators, + including g_signal_accumulator_true_handled. + 2003-09-12 Noah Levitt * glib/gen-unicode-tables.pl: Take a directory where to look for the diff --git a/configure.in b/configure.in index 7dec3c228..f142432e1 100644 --- a/configure.in +++ b/configure.in @@ -2549,6 +2549,7 @@ docs/reference/glib/version.xml docs/reference/gobject/Makefile docs/reference/gobject/version.xml tests/Makefile +tests/gobject/Makefile m4macros/Makefile ]) diff --git a/tests/gobject/.cvsignore b/tests/gobject/.cvsignore new file mode 100644 index 000000000..48ac7354d --- /dev/null +++ b/tests/gobject/.cvsignore @@ -0,0 +1,8 @@ +Makefile +Makefile.in +accumulator +ifaceinit +override +testmarshal.c +testmarshal.h +stamp-testmarshal.h \ No newline at end of file diff --git a/tests/gobject/Makefile.am b/tests/gobject/Makefile.am new file mode 100644 index 000000000..b66876685 --- /dev/null +++ b/tests/gobject/Makefile.am @@ -0,0 +1,71 @@ +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/glib \ + -I$(top_srcdir)/gmodule \ + $(GLIB_DEBUG_FLAGS) + +libglib = $(top_builddir)/glib/libglib-2.0.la +libgthread = $(top_builddir)/gthread/libgthread-2.0.la +libgmodule = $(top_builddir)/gmodule/libgmodule-2.0.la +libgobject = $(top_builddir)/gobject/libgobject-2.0.la + +######################################################################## + +noinst_LTLIBRARIES = libtestgobject.la + +libtestgobject_la_SOURCES = \ + testcommon.h \ + testmarshal.h \ + testmarshal.c + +if CROSS_COMPILING + glib_genmarshal=$(GLIB_GENMARSHAL) +else + glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal +endif + +testmarshal.h: stamp-testmarshal.h + @true +stamp-testmarshal.h: @REBUILD@ testmarshal.list $(glib_genmarshal) + $(glib_genmarshal) --prefix=test_marshal $(srcdir)/testmarshal.list --header >> xgen-gmh \ + && (cmp -s xgen-gmh testmarshal.h 2>/dev/null || cp xgen-gmh testmarshal.h) \ + && rm -f xgen-gmh xgen-gmh~ \ + && echo timestamp > $@ +testmarshal.c: @REBUILD@ testmarshal.list $(glib_genmarshal) + $(glib_genmarshal) --prefix=test_marshal $(srcdir)/testmarshal.list --body >> xgen-gmc \ + && cp xgen-gmc testmarshal.c \ + && rm -f xgen-gmc xgen-gmc~ + +BUILT_SOURCES = testmarshal.h testmarshal.c + +######################################################################## + +LDADD = $(libgobject) libtestgobject.la + +test_programs = \ + accumulator \ + ifaceinit \ + override + +check_PROGRAMS = $(test_programs) + +TESTS = $(test_programs) +TESTS_ENVIRONMENT = srcdir=$(srcdir) \ + LIBCHARSET_ALIAS_DIR=$(top_builddir)/glib/libcharset + +######################################################################## + +BUILT_EXTRA_DIST = \ + testmarshal.h \ + testmarshal.c + +dist-hook: $(BUILT_EXTRA_DIST) \ + files='$(BUILT_EXTRA_DIST)'; \ + for f in $$files; do \ + if test -f $$f; then d=.; else d=$(srcdir); fi; \ + cp $$d/$$f $(distdir) || exit 1; done + +distclean-local: \ + if test $(srcdir) = .; then :; else \ + rm -f $(BUILT_EXTRA_DIST); \ + fi diff --git a/tests/gobject/accumulator.c b/tests/gobject/accumulator.c new file mode 100644 index 000000000..602ab1146 --- /dev/null +++ b/tests/gobject/accumulator.c @@ -0,0 +1,227 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001, 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestAccumulator" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#include + +#include + +#include "testmarshal.h" +#include "testcommon.h" + +/* What this test tests is the behavior of signal accumulators + * Two accumulators are tested: + * + * 1: A custom accumulator that appends the returned strings + * 2: The standard g_signal_accumulator_true_handled that stops + * emission on TRUE returns. + */ + +/* + * TestObject, a parent class for TestObject + */ +#define TEST_TYPE_OBJECT (test_object_get_type ()) +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; + +struct _TestObject +{ + GObject parent_instance; +}; +struct _TestObjectClass +{ + GObjectClass parent_class; + + gchar* (*test_signal1) (TestObject *tobject, + gint param); + gboolean (*test_signal2) (TestObject *tobject, + gint param); +}; + +static GType test_object_get_type (void); + +static gboolean +test_signal1_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + const gchar *accu_string = g_value_get_string (return_accu); + const gchar *new_string = g_value_get_string (handler_return); + gchar *result_string; + + if (accu_string) + result_string = g_strconcat (accu_string, new_string, NULL); + else if (new_string) + result_string = g_strdup (new_string); + else + result_string = NULL; + + g_value_set_string_take_ownership (return_accu, result_string); + + return TRUE; +} + +gchar* +test_object_signal1_callback_before (TestObject *tobject, + gint param, + gpointer data) +{ + return g_strdup (""); +} + +gchar* +test_object_real_signal1 (TestObject *tobject, + gint param) +{ + return g_strdup (""); +} + +gchar* +test_object_signal1_callback_after (TestObject *tobject, + gint param, + gpointer data) +{ + return g_strdup (""); +} + +gboolean +test_object_signal2_callback_before (TestObject *tobject, + gint param) +{ + switch (param) + { + case 1: return TRUE; + case 2: return FALSE; + case 3: return FALSE; + case 4: return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +gboolean +test_object_real_signal2 (TestObject *tobject, + gint param) +{ + switch (param) + { + case 1: g_assert_not_reached (); return FALSE; + case 2: return TRUE; + case 3: return FALSE; + case 4: return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +gboolean +test_object_signal2_callback_after (TestObject *tobject, + gint param) +{ + switch (param) + { + case 1: g_assert_not_reached (); return FALSE; + case 2: g_assert_not_reached (); return FALSE; + case 3: return TRUE; + case 4: return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +static void +test_object_class_init (TestObjectClass *class) +{ + class->test_signal1 = test_object_real_signal1; + class->test_signal2 = test_object_real_signal2; + + g_signal_new ("test-signal1", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestObjectClass, test_signal1), + test_signal1_accumulator, NULL, + test_marshal_STRING__INT, + G_TYPE_STRING, 1, G_TYPE_INT); + g_signal_new ("test-signal2", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestObjectClass, test_signal2), + g_signal_accumulator_true_handled, NULL, + test_marshal_BOOLEAN__INT, + G_TYPE_BOOLEAN, 1, G_TYPE_INT); +} + +static DEFINE_TYPE(TestObject, test_object, + test_object_class_init, NULL, NULL, + G_TYPE_OBJECT) + +int +main (int argc, + char *argv[]) +{ + TestObject *object; + gchar *string_result; + gboolean bool_result; + + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + g_type_init (); + + object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_signal_connect (object, "test-signal1", + G_CALLBACK (test_object_signal1_callback_before), NULL); + g_signal_connect_after (object, "test-signal1", + G_CALLBACK (test_object_signal1_callback_after), NULL); + + g_signal_emit_by_name (object, "test-signal1", 0, &string_result); + g_assert (strcmp (string_result, "") == 0); + g_free (string_result); + + g_signal_connect (object, "test-signal2", + G_CALLBACK (test_object_signal2_callback_before), NULL); + g_signal_connect_after (object, "test-signal2", + G_CALLBACK (test_object_signal2_callback_after), NULL); + + bool_result = FALSE; + g_signal_emit_by_name (object, "test-signal2", 1, &bool_result); + g_assert (bool_result == TRUE); + bool_result = FALSE; + g_signal_emit_by_name (object, "test-signal2", 2, &bool_result); + g_assert (bool_result == TRUE); + bool_result = FALSE; + g_signal_emit_by_name (object, "test-signal2", 3, &bool_result); + g_assert (bool_result == TRUE); + bool_result = TRUE; + g_signal_emit_by_name (object, "test-signal2", 4, &bool_result); + g_assert (bool_result == FALSE); + + return 0; +} diff --git a/tests/gobject/ifaceinit.c b/tests/gobject/ifaceinit.c index c25bb2968..5d2686acc 100644 --- a/tests/gobject/ifaceinit.c +++ b/tests/gobject/ifaceinit.c @@ -21,6 +21,8 @@ #define G_LOG_DOMAIN "TestIfaceInit" #include +#include "testcommon.h" + /* What this test tests is the ability to add interfaces dynamically; in * particular adding interfaces to a class while that class is being * initialized. @@ -35,60 +37,6 @@ * - TestIface6 is added after the class is initialized */ -#define DEFINE_TYPE(name, prefix, \ - class_init, base_init, instance_init, \ - parent_type) \ -GType \ -prefix ## _get_type (void) \ -{ \ - static GType object_type = 0; \ - \ - if (!object_type) \ - { \ - static const GTypeInfo object_info = \ - { \ - sizeof (name ## Class), \ - (GBaseInitFunc) base_init, \ - (GBaseFinalizeFunc) NULL, \ - (GClassInitFunc) class_init, \ - (GClassFinalizeFunc) NULL, \ - NULL, /* class_data */ \ - sizeof (name), \ - 0, /* n_prelocs */ \ - (GInstanceInitFunc) instance_init \ - }; \ - \ - object_type = g_type_register_static (parent_type, \ - # name, \ - &object_info, 0); \ - } \ - \ - return object_type; \ -} - -#define DEFINE_IFACE(name, prefix, base_init, dflt_init) \ -GType \ -prefix ## _get_type (void) \ -{ \ - static GType iface_type = 0; \ - \ - if (!iface_type) \ - { \ - static const GTypeInfo iface_info = \ - { \ - sizeof (name ## Class), \ - (GBaseInitFunc) base_init, \ - (GBaseFinalizeFunc) NULL, \ - (GClassInitFunc) dflt_init, \ - }; \ - \ - iface_type = g_type_register_static (G_TYPE_INTERFACE, \ - # name, \ - &iface_info, 0); \ - } \ - return iface_type; \ -} - /* All 6 interfaces actually share the same class structure, though * we use separate typedefs */ @@ -241,7 +189,6 @@ test_object_test_iface1_init (TestIface1Class *iface) ADD_IFACE(5); iface1 = TRUE; - g_print ("interface1 object initializer\n"); } static void @@ -305,7 +252,6 @@ test_iface1_default_init (TestIface1Class *iface, g_assert (iface->val == 0); g_assert (iface->default_val == 0); iface->default_val = 0x111111; - g_print ("interface1 default initializer\n"); } static void @@ -330,7 +276,6 @@ test_iface1_base_init (TestIface1Class *iface) ADD_IFACE(3); base1 = TRUE; - g_print ("interface1 base initializer\n"); } static void @@ -415,10 +360,10 @@ test_object_class_init (TestObjectClass *class) static DEFINE_TYPE(BaseObject, base_object, NULL, base_object_base_init, NULL, - G_TYPE_OBJECT); + G_TYPE_OBJECT) static DEFINE_TYPE(TestObject, test_object, test_object_class_init, NULL, NULL, - BASE_TYPE_OBJECT); + BASE_TYPE_OBJECT) int main (int argc, @@ -468,7 +413,5 @@ main (int argc, iface = TEST_IFACE6_GET_CLASS (object); g_assert (iface && iface->val == 0x60006 && iface->base_val == 0x660066); - g_print ("testifaceinit: all done.\n"); - return 0; } diff --git a/tests/gobject/override.c b/tests/gobject/override.c index 2ac34e9f2..2d9353d91 100644 --- a/tests/gobject/override.c +++ b/tests/gobject/override.c @@ -1,379 +1,324 @@ -/* -*- mode: C; c-basic-offset: 4 -*- */ +/* GObject - GLib Type, Object, Parameter and Signal Library + * override.c: Closure override test program + * Copyright (C) 2001, James Henstridge + * Copyright (C) 2003, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestOverride" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#undef VERBOSE + +#include + #include #include +#include "testcommon.h" + static guint foo_signal_id = 0; static guint bar_signal_id = 0; - static GType test_i_get_type (void); static GType test_a_get_type (void); static GType test_b_get_type (void); static GType test_c_get_type (void); +static void record (const gchar *str); + #define TEST_TYPE_I (test_i_get_type ()) -#define TEST_I(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_I, TestI)) -#define TEST_I_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), TEST_TYPE_I, TestIClass)) -#define TEST_IS_I(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_I)) -#define TEST_IS_I_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), TEST_TYPE_I)) -#define TEST_I_GET_CLASS(object) (G_TYPE_INSTANCE_GET_INTERFACE((object), TEST_TYPE_I, TestIClass)) typedef struct _TestI TestI; typedef struct _TestIClass TestIClass; -struct _TestIClass { - GTypeInterface base_iface; +struct _TestIClass +{ + GTypeInterface base_iface; }; static void test_i_foo (TestI *self) { - g_print("TestI::foo called.\n"); + record ("TestI::foo"); } - static void -test_i_base_init (gpointer g_class) +test_i_default_init (gpointer g_class) { - static gboolean initialised = FALSE; - - if (!initialised) { - foo_signal_id = g_signal_newv("foo", - TEST_TYPE_I, - G_SIGNAL_RUN_LAST, - g_cclosure_new(G_CALLBACK(test_i_foo), - NULL, NULL), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, NULL); - } - initialised = TRUE; + foo_signal_id = g_signal_newv ("foo", + TEST_TYPE_I, + G_SIGNAL_RUN_LAST, + g_cclosure_new(G_CALLBACK(test_i_foo), + NULL, NULL), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, NULL); } -static GType -test_i_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo type_info = { - sizeof (TestIClass), - (GBaseInitFunc) test_i_base_init, /* base_init */ - NULL, /* base_finalize */ - }; - - type = g_type_register_static (G_TYPE_INTERFACE, "TestI", - &type_info, 0); - } - - return type; -} - - +static DEFINE_IFACE (TestI, test_i, NULL, test_i_default_init) #define TEST_TYPE_A (test_a_get_type()) -#define TEST_A(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_A, TestA)) -#define TEST_A_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_A, TestAClass)) -#define TEST_IS_A(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_A)) -#define TEST_IS_A_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_A)) -#define TEST_A_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_A, TestAClass)) -typedef struct _TestA TestA; -typedef struct _TestAClass TestAClass; + typedef struct _TestA TestA; + typedef struct _TestAClass TestAClass; struct _TestA { - GObject parent; + GObject parent; }; struct _TestAClass { - GObjectClass parent_class; + GObjectClass parent_class; - void (* bar) (TestA *self); + void (* bar) (TestA *self); }; static void test_a_foo (TestI *self) { - GValue args[1] = { { 0, } }; + GValue args[1] = { { 0, } }; - g_print("TestA::foo called. Chaining up.\n"); + record ("TestA::foo"); - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); - g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); - g_signal_chain_from_overridden (args, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); - g_value_unset (&args[0]); + g_value_unset (&args[0]); } static void test_a_bar (TestA *self) { - g_print("TestA::bar called.\n"); + record ("TestA::bar"); } static void test_a_class_init (TestAClass *class) { - class->bar = test_a_bar; + class->bar = test_a_bar; - bar_signal_id = g_signal_new("bar", - TEST_TYPE_A, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TestAClass, bar), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + bar_signal_id = g_signal_new ("bar", + TEST_TYPE_A, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestAClass, bar), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, NULL); } static void test_a_interface_init (TestIClass *iface) { - g_signal_override_class_closure (foo_signal_id, - TEST_TYPE_A, - g_cclosure_new (G_CALLBACK (test_a_foo), - NULL, NULL)); + g_signal_override_class_closure (foo_signal_id, + TEST_TYPE_A, + g_cclosure_new (G_CALLBACK (test_a_foo), + NULL, NULL)); } -static GType -test_a_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo type_info = { - sizeof(TestAClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) test_a_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(TestAClass), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - static const GInterfaceInfo interface_info = { - (GInterfaceInitFunc) test_a_interface_init, - NULL, - NULL - }; - - type = g_type_register_static (G_TYPE_OBJECT, "TestA", - &type_info, 0); - g_type_add_interface_static (type, TEST_TYPE_I, &interface_info); - } - - return type; -} - - +static DEFINE_TYPE_FULL (TestA, test_a, + test_a_class_init, NULL, NULL, + G_TYPE_OBJECT, + INTERFACE (test_a_interface_init, TEST_TYPE_I)) + #define TEST_TYPE_B (test_b_get_type()) -#define TEST_B(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_B, TestB)) -#define TEST_B_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_B, TestBClass)) -#define TEST_IS_B(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_B)) -#define TEST_IS_B_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_B)) -#define TEST_B_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_B, TestBClass)) typedef struct _TestB TestB; typedef struct _TestBClass TestBClass; struct _TestB { - TestA parent; + TestA parent; }; struct _TestBClass { - TestAClass parent_class; + TestAClass parent_class; }; static void test_b_foo (TestA *self) { - GValue args[1] = { { 0, } }; + GValue args[1] = { { 0, } }; - g_print("TestB::foo called. Chaining up.\n"); + record ("TestB::foo"); - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); - g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); - g_signal_chain_from_overridden (args, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); - g_value_unset (&args[0]); + g_value_unset (&args[0]); } static void test_b_bar (TestI *self) { - GValue args[1] = { { 0, } }; + GValue args[1] = { { 0, } }; - g_print("TestB::bar called. Chaining up.\n"); + record ("TestB::bar"); - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); - g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); - g_signal_chain_from_overridden (args, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); + g_signal_chain_from_overridden (args, NULL); - g_value_unset (&args[0]); + g_value_unset (&args[0]); } static void test_b_class_init (TestBClass *class) { - g_signal_override_class_closure (foo_signal_id, - TEST_TYPE_B, - g_cclosure_new (G_CALLBACK (test_b_foo), - NULL, NULL)); - g_signal_override_class_closure (bar_signal_id, - TEST_TYPE_B, - g_cclosure_new (G_CALLBACK (test_b_bar), - NULL, NULL)); -} - -static GType -test_b_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo type_info = { - sizeof(TestBClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) test_b_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(TestBClass), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - - type = g_type_register_static (TEST_TYPE_A, "TestB", - &type_info, 0); - } - - return type; + g_signal_override_class_closure (foo_signal_id, + TEST_TYPE_B, + g_cclosure_new (G_CALLBACK (test_b_foo), + NULL, NULL)); + g_signal_override_class_closure (bar_signal_id, + TEST_TYPE_B, + g_cclosure_new (G_CALLBACK (test_b_bar), + NULL, NULL)); } +static DEFINE_TYPE (TestB, test_b, + test_b_class_init, NULL, NULL, + TEST_TYPE_A) #define TEST_TYPE_C (test_c_get_type()) -#define TEST_C(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_C, TestC)) -#define TEST_C_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_C, TestCClass)) -#define TEST_IS_C(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_C)) -#define TEST_IS_C_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_C)) -#define TEST_C_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_C, TestCClass)) typedef struct _TestC TestC; typedef struct _TestCClass TestCClass; struct _TestC { - TestB parent; + TestB parent; }; struct _TestCClass { - TestBClass parent_class; + TestBClass parent_class; }; static void test_c_foo (TestA *self) { - GValue args[1] = { { 0, } }; + GValue args[1] = { { 0, } }; - g_print("TestC::foo called. Chaining up.\n"); + record ("TestC::foo"); - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); - g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); - g_signal_chain_from_overridden (args, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); - g_value_unset (&args[0]); + g_value_unset (&args[0]); } static void test_c_bar (TestI *self) { - GValue args[1] = { { 0, } }; + GValue args[1] = { { 0, } }; - g_print("TestC::bar called. Chaining up.\n"); + record ("TestC::bar"); - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); - g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); - g_signal_chain_from_overridden (args, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); + g_signal_chain_from_overridden (args, NULL); - g_value_unset (&args[0]); + g_value_unset (&args[0]); } static void test_c_class_init (TestBClass *class) { - g_signal_override_class_closure (foo_signal_id, - TEST_TYPE_C, - g_cclosure_new (G_CALLBACK (test_c_foo), - NULL, NULL)); - g_signal_override_class_closure (bar_signal_id, - TEST_TYPE_C, - g_cclosure_new (G_CALLBACK (test_c_bar), - NULL, NULL)); + g_signal_override_class_closure (foo_signal_id, + TEST_TYPE_C, + g_cclosure_new (G_CALLBACK (test_c_foo), + NULL, NULL)); + g_signal_override_class_closure (bar_signal_id, + TEST_TYPE_C, + g_cclosure_new (G_CALLBACK (test_c_bar), + NULL, NULL)); } -static GType -test_c_get_type (void) + +static DEFINE_TYPE (TestC, test_c, + test_c_class_init, NULL, NULL, + TEST_TYPE_B) + +static GString *test_string = NULL; +gboolean failed = FALSE; + +static void +record (const gchar *str) { - static GType type = 0; - - if (!type) { - static const GTypeInfo type_info = { - sizeof(TestCClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) test_c_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(TestCClass), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - - type = g_type_register_static (TEST_TYPE_B, "TestC", - &type_info, 0); - } - - return type; + if (test_string->len) + g_string_append_c (test_string, ','); + g_string_append (test_string, str); } + +static void +test (GType type, + const gchar *signal, + const gchar *expected) +{ + GObject *self = g_object_new (type, NULL); + test_string = g_string_new (NULL); + g_signal_emit_by_name (self, signal, 0); + +#ifndef VERBOSE + if (strcmp (test_string->str, expected) != 0) +#endif + { + g_printerr ("*** emitting %s on a %s instance\n" + " Expecting: %s\n" + " Got: %s\n", + signal, g_type_name (type), + expected, + test_string->str); + + if (strcmp (test_string->str, expected) != 0) + failed = TRUE; + } + + g_string_free (test_string, TRUE); +} + int main (int argc, char **argv) { - GObject *self; + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + g_type_init(); - g_type_init(); + test (TEST_TYPE_A, "foo", "TestA::foo,TestI::foo"); + test (TEST_TYPE_A, "bar", "TestA::bar"); - self = g_object_new(TEST_TYPE_A, NULL); - g_print("*** emiting foo on a TestA instance (expect chain A->I)\n"); - g_signal_emit(self, foo_signal_id, 0); - g_print("*** emiting bar on a TestA instance\n"); - g_signal_emit(self, bar_signal_id, 0); - g_object_unref(self); + test (TEST_TYPE_B, "foo", "TestB::foo,TestA::foo,TestI::foo"); + test (TEST_TYPE_B, "bar", "TestB::bar,TestA::bar"); - g_print("\n"); + test (TEST_TYPE_C, "foo", "TestC::foo,TestB::foo,TestA::foo,TestI::foo"); + test (TEST_TYPE_C, "bar", "TestC::bar,TestB::bar,TestA::bar"); - self = g_object_new(TEST_TYPE_B, NULL); - g_print("*** emiting foo on a TestB instance (expect chain B->A->I)\n"); - g_signal_emit(self, foo_signal_id, 0); - g_print("*** emiting bar on a TestB instance (expect chain B->A)\n"); - g_signal_emit(self, bar_signal_id, 0); - g_object_unref(self); - - g_print("\n"); - - self = g_object_new(TEST_TYPE_C, NULL); - g_print("*** emiting foo on a TestC instance (expect chain C->B->A->I)\n"); - g_signal_emit(self, foo_signal_id, 0); - g_print("*** emiting bar on a TestC instance (expect chain C->B->A)\n"); - g_signal_emit(self, bar_signal_id, 0); - g_object_unref(self); - - return 0; + return failed ? 1 : 0; } diff --git a/tests/gobject/testcommon.h b/tests/gobject/testcommon.h new file mode 100644 index 000000000..7bfef05c8 --- /dev/null +++ b/tests/gobject/testcommon.h @@ -0,0 +1,100 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __TEST_COMMON_H__ +#define __TEST_COMMON_H__ + +G_BEGIN_DECLS + +#define DEFINE_TYPE_FULL(name, prefix, \ + class_init, base_init, instance_init, \ + parent_type, interface_decl) \ +GType \ +prefix ## _get_type (void) \ +{ \ + static GType object_type = 0; \ + \ + if (!object_type) \ + { \ + static const GTypeInfo object_info = \ + { \ + sizeof (name ## Class), \ + (GBaseInitFunc) base_init, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) class_init, \ + (GClassFinalizeFunc) NULL, \ + NULL, /* class_data */ \ + sizeof (name), \ + 0, /* n_prelocs */ \ + (GInstanceInitFunc) instance_init \ + }; \ + \ + object_type = g_type_register_static (parent_type, \ + # name, \ + &object_info, 0); \ + interface_decl \ + } \ + \ + return object_type; \ +} + +#define DEFINE_TYPE(name, prefix, \ + class_init, base_init, instance_init, \ + parent_type) \ + DEFINE_TYPE_FULL(name, prefix, class_init, base_init, \ + instance_init, parent_type, {}) + +#define DEFINE_IFACE(name, prefix, base_init, dflt_init) \ +GType \ +prefix ## _get_type (void) \ +{ \ + static GType iface_type = 0; \ + \ + if (!iface_type) \ + { \ + static const GTypeInfo iface_info = \ + { \ + sizeof (name ## Class), \ + (GBaseInitFunc) base_init, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) dflt_init, \ + }; \ + \ + iface_type = g_type_register_static (G_TYPE_INTERFACE, \ + # name, \ + &iface_info, 0); \ + } \ + return iface_type; \ +} + +#define INTERFACE_FULL(type, init_func, iface_type) \ +{ \ + static GInterfaceInfo const iface = \ + { \ + (GInterfaceInitFunc) init_func, NULL, NULL \ + }; \ + \ + g_type_add_interface_static (type, iface_type, &iface); \ +} +#define INTERFACE(init_func, iface_type) \ + INTERFACE_FULL(object_type, init_func, iface_type) + +G_END_DECLS + +#endif /* __TEST_COMMON_H__ */ diff --git a/tests/gobject/testmarshal.list b/tests/gobject/testmarshal.list new file mode 100644 index 000000000..bed97e2cd --- /dev/null +++ b/tests/gobject/testmarshal.list @@ -0,0 +1,4 @@ +# Marshallers used in tests +BOOLEAN:INT +STRING:INT +