From 07168724d74cb656938df7abaa42dacff94c62cf Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 29 May 2013 08:33:55 -0400 Subject: [PATCH] Improve signal test coverage --- gobject/tests/signals.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 205 insertions(+), 1 deletion(-) diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c index 671e168..95c0501 100644 --- a/gobject/tests/signals.c +++ b/gobject/tests/signals.c @@ -74,6 +74,7 @@ static const GFlagsValue my_flag_values[] = static GType enum_type; static GType flags_type; +static guint simple_id; typedef struct _Test Test; typedef struct _TestClass TestClass; @@ -112,7 +113,7 @@ test_class_init (TestClass *klass) klass->all_types = all_types_handler; - g_signal_new ("simple", + simple_id = g_signal_new ("simple", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, @@ -839,6 +840,205 @@ test_destroy_target_object (void) g_object_unref (sender); } +static gboolean +hook_func (GSignalInvocationHint *ihint, + guint n_params, + const GValue *params, + gpointer data) +{ + gint *count = data; + + (*count)++; + + return TRUE; +} + +static void +test_emission_hook (void) +{ + GObject *test1, *test2; + gint count = 0; + gulong hook; + + test1 = g_object_new (test_get_type (), NULL); + test2 = g_object_new (test_get_type (), NULL); + + hook = g_signal_add_emission_hook (simple_id, 0, hook_func, &count, NULL); + g_assert_cmpint (count, ==, 0); + g_signal_emit_by_name (test1, "simple"); + g_assert_cmpint (count, ==, 1); + g_signal_emit_by_name (test2, "simple"); + g_assert_cmpint (count, ==, 2); + g_signal_remove_emission_hook (simple_id, hook); + g_signal_emit_by_name (test1, "simple"); + g_assert_cmpint (count, ==, 2); +} + +static gboolean +in_set (const gchar *s, + const gchar *set[]) +{ + gint i; + + for (i = 0; set[i]; i++) + { + if (g_strcmp0 (s, set[i]) == 0) + return TRUE; + } + + return FALSE; +} + +static void +test_introspection (void) +{ + guint *ids; + guint n_ids; + const gchar *name; + gint i; + const gchar *names[] = { + "simple", + "generic-marshaller-1", + "generic-marshaller-2", + "generic-marshaller-enum-return-signed", + "generic-marshaller-enum-return-unsigned", + "generic-marshaller-int-return", + "va-marshaller-int-return", + "generic-marshaller-uint-return", + "va-marshaller-uint-return", + "variant-changed-no-slot", + "variant-changed", + "all-types", + "all-types-va", + "all-types-generic", + "all-types-null", + "all-types-empty", + NULL + }; + GSignalQuery query; + + ids = g_signal_list_ids (test_get_type (), &n_ids); + g_assert_cmpuint (n_ids, ==, g_strv_length ((gchar**)names)); + + for (i = 0; i < n_ids; i++) + { + name = g_signal_name (ids[i]); + g_assert (in_set (name, names)); + } + + g_signal_query (simple_id, &query); + g_assert_cmpuint (query.signal_id, ==, simple_id); + g_assert_cmpstr (query.signal_name, ==, "simple"); + g_assert (query.itype == test_get_type ()); + g_assert (query.signal_flags == G_SIGNAL_RUN_LAST); + g_assert (query.return_type == G_TYPE_NONE); + g_assert_cmpuint (query.n_params, ==, 0); +} + +static void +test_handler (gpointer instance, gpointer data) +{ + gint *count = data; + + (*count)++; +} + +static void +test_block_handler (void) +{ + GObject *test1, *test2; + gint count1 = 0; + gint count2 = 0; + gulong handler1, handler; + + test1 = g_object_new (test_get_type (), NULL); + test2 = g_object_new (test_get_type (), NULL); + + handler1 = g_signal_connect (test1, "simple", G_CALLBACK (test_handler), &count1); + g_signal_connect (test2, "simple", G_CALLBACK (test_handler), &count2); + + handler = g_signal_handler_find (test1, G_SIGNAL_MATCH_ID, simple_id, 0, NULL, NULL, NULL); + + g_assert (handler == handler1); + + g_assert_cmpint (count1, ==, 0); + g_assert_cmpint (count2, ==, 0); + + g_signal_emit_by_name (test1, "simple"); + g_signal_emit_by_name (test2, "simple"); + + g_assert_cmpint (count1, ==, 1); + g_assert_cmpint (count2, ==, 1); + + g_signal_handler_block (test1, handler1); + + g_signal_emit_by_name (test1, "simple"); + g_signal_emit_by_name (test2, "simple"); + + g_assert_cmpint (count1, ==, 1); + g_assert_cmpint (count2, ==, 2); + + g_signal_handler_unblock (test1, handler1); + + g_signal_emit_by_name (test1, "simple"); + g_signal_emit_by_name (test2, "simple"); + + g_assert_cmpint (count1, ==, 2); + g_assert_cmpint (count2, ==, 3); + + g_assert_cmpuint (g_signal_handlers_block_matched (test1, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_block_handler, NULL), ==, 0); + g_assert_cmpuint (g_signal_handlers_block_matched (test2, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_handler, NULL), ==, 1); + + g_signal_emit_by_name (test1, "simple"); + g_signal_emit_by_name (test2, "simple"); + + g_assert_cmpint (count1, ==, 3); + g_assert_cmpint (count2, ==, 3); + + g_signal_handlers_unblock_matched (test2, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_handler, NULL); + + g_object_unref (test1); + g_object_unref (test2); +} + +static void +stop_emission (gpointer instance, gpointer data) +{ + g_signal_stop_emission (instance, simple_id, 0); +} + +static void +stop_emission_by_name (gpointer instance, gpointer data) +{ + g_signal_stop_emission_by_name (instance, "simple"); +} + +static void +dont_reach (gpointer instance, gpointer data) +{ + g_assert_not_reached (); +} + +static void +test_stop_emission (void) +{ + GObject *test1; + gulong handler; + + test1 = g_object_new (test_get_type (), NULL); + handler = g_signal_connect (test1, "simple", G_CALLBACK (stop_emission), NULL); + g_signal_connect_after (test1, "simple", G_CALLBACK (dont_reach), NULL); + + g_signal_emit_by_name (test1, "simple"); + + g_signal_handler_disconnect (test1, handler); + g_signal_connect (test1, "simple", G_CALLBACK (stop_emission_by_name), NULL); + + g_signal_emit_by_name (test1, "simple"); + + g_object_unref (test1); +} + /* --- */ int @@ -857,6 +1057,10 @@ main (int argc, g_test_add_func ("/gobject/signals/generic-marshaller-int-return", test_generic_marshaller_signal_int_return); g_test_add_func ("/gobject/signals/generic-marshaller-uint-return", test_generic_marshaller_signal_uint_return); g_test_add_func ("/gobject/signals/connect", test_connect); + g_test_add_func ("/gobject/signals/emission-hook", test_emission_hook); + g_test_add_func ("/gobject/signals/introspection", test_introspection); + g_test_add_func ("/gobject/signals/block-handler", test_block_handler); + g_test_add_func ("/gobject/signals/stop-emission", test_stop_emission); return g_test_run (); } -- 2.7.4