diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c index 7109fc553..32d89f4d8 100644 --- a/gobject/tests/signals.c +++ b/gobject/tests/signals.c @@ -180,6 +180,14 @@ test_class_init (TestClass *klass) NULL, G_TYPE_NONE, 0); + g_signal_new ("simple-detailed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 0); /* Deliberately install this one in non-canonical form to check that’s handled correctly: */ simple2_id = g_signal_new ("simple_2", G_TYPE_FROM_CLASS (klass), @@ -1065,6 +1073,7 @@ test_introspection (void) gint i; const gchar *names[] = { "simple", + "simple-detailed", "simple-2", "generic-marshaller-1", "generic-marshaller-2", @@ -1277,6 +1286,123 @@ test_clear_signal_handler (void) g_object_unref (test_obj); } +static void +test_lookup (void) +{ + GTypeClass *test_class; + guint signal_id, saved_signal_id; + + g_test_summary ("Test that g_signal_lookup() works with a variety of inputs."); + + test_class = g_type_class_ref (test_get_type ()); + + signal_id = g_signal_lookup ("all-types", test_get_type ()); + g_assert_cmpint (signal_id, !=, 0); + + saved_signal_id = signal_id; + + /* Try with a non-canonical name. */ + signal_id = g_signal_lookup ("all_types", test_get_type ()); + g_assert_cmpint (signal_id, ==, saved_signal_id); + + /* Looking up a non-existent signal should return nothing. */ + g_assert_cmpint (g_signal_lookup ("nope", test_get_type ()), ==, 0); + + g_type_class_unref (test_class); +} + +static void +test_parse_name (void) +{ + GTypeClass *test_class; + guint signal_id, saved_signal_id; + gboolean retval; + GQuark detail, saved_detail; + + g_test_summary ("Test that g_signal_parse_name() works with a variety of inputs."); + + test_class = g_type_class_ref (test_get_type ()); + + /* Simple test. */ + retval = g_signal_parse_name ("simple-detailed", test_get_type (), &signal_id, &detail, TRUE); + g_assert_true (retval); + g_assert_cmpint (signal_id, !=, 0); + g_assert_cmpint (detail, ==, 0); + + saved_signal_id = signal_id; + + /* Simple test with detail. */ + retval = g_signal_parse_name ("simple-detailed::a-detail", test_get_type (), &signal_id, &detail, TRUE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, !=, 0); + + saved_detail = detail; + + /* Simple test with the same detail again. */ + retval = g_signal_parse_name ("simple-detailed::a-detail", test_get_type (), &signal_id, &detail, FALSE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, ==, saved_detail); + + /* Simple test with a new detail. */ + retval = g_signal_parse_name ("simple-detailed::another-detail", test_get_type (), &signal_id, &detail, FALSE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, ==, 0); /* we didn’t force the quark */ + + /* Canonicalisation shouldn’t affect the results. */ + retval = g_signal_parse_name ("simple_detailed::a-detail", test_get_type (), &signal_id, &detail, FALSE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, ==, saved_detail); + + /* Details don’t have to look like property names. */ + retval = g_signal_parse_name ("simple-detailed::hello::world", test_get_type (), &signal_id, &detail, TRUE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, !=, 0); + + /* Trying to parse a detail for a signal which isn’t %G_SIGNAL_DETAILED should fail. */ + retval = g_signal_parse_name ("all-types::a-detail", test_get_type (), &signal_id, &detail, FALSE); + g_assert_false (retval); + + g_type_class_unref (test_class); +} + +static void +test_parse_name_invalid (void) +{ + GTypeClass *test_class; + gsize i; + guint signal_id; + GQuark detail; + const gchar *vectors[] = + { + "", + "7zip", + "invalid:signal", + "simple-detailed::", + "simple-detailed:", + ":", + "::", + ":valid-detail", + "::valid-detail", + }; + + g_test_summary ("Test that g_signal_parse_name() ignores a variety of invalid inputs."); + + test_class = g_type_class_ref (test_get_type ()); + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + g_test_message ("Parser input: %s", vectors[i]); + g_assert_false (g_signal_parse_name (vectors[i], test_get_type (), &signal_id, &detail, TRUE)); + } + + g_type_class_unref (test_class); +} + /* --- */ int @@ -1303,6 +1429,9 @@ main (int argc, g_test_add_func ("/gobject/signals/invocation-hint", test_invocation_hint); g_test_add_func ("/gobject/signals/test-disconnection-wrong-object", test_signal_disconnect_wrong_object); g_test_add_func ("/gobject/signals/clear-signal-handler", test_clear_signal_handler); + g_test_add_func ("/gobject/signals/lookup", test_lookup); + g_test_add_func ("/gobject/signals/parse-name", test_parse_name); + g_test_add_func ("/gobject/signals/parse-name/invalid", test_parse_name_invalid); return g_test_run (); }