summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPhilip Withnall <philip.withnall@collabora.co.uk>2014-05-07 23:35:17 +0100
committerPhilip Withnall <philip.withnall@collabora.co.uk>2014-05-08 17:02:54 +0100
commitae4c44466742d74a4a3f951757a23c88f9699464 (patch)
tree47b9b860d49c432b46385fd68b6232c254a27e92 /tests
parent9221b85d5f41a666b2a3551b373330d9eca14a63 (diff)
clang-plugin: Add a g_signal_connect() checker
This validates that: • The named signal exists on the given GObject subclass. • The type of the callback function matches that declared for the signal. Unit tests are included.
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/gsignal-connect.c174
-rw-r--r--tests/gsignal.head.c82
-rw-r--r--tests/gsignal.tail.c4
4 files changed, 263 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 26d1c02..3fc9e91 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -8,6 +8,7 @@ C_LOG_COMPILER = $(top_srcdir)/tests/wrapper-compiler-errors
c_tests = \
assertion-extraction.c \
assertion-extraction-return.c \
+ gsignal-connect.c \
gvariant-builder.c \
gvariant-get.c \
gvariant-get-child.c \
@@ -24,6 +25,8 @@ templates = \
assertion-return.tail.c \
generic.head.c \
generic.tail.c \
+ gsignal.head.c \
+ gsignal.tail.c \
gvariant.head.c \
gvariant.tail.c \
$(NULL)
diff --git a/tests/gsignal-connect.c b/tests/gsignal-connect.c
new file mode 100644
index 0000000..7f529bf
--- /dev/null
+++ b/tests/gsignal-connect.c
@@ -0,0 +1,174 @@
+/* Template: gsignal */
+
+/*
+ * No error
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify", (GCallback) object_notify_cb,
+ NULL);
+}
+
+/*
+ * No error
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+
+ // Detailed signal
+ // FIXME: Check the detail is a valid property name too?
+ g_signal_connect (some_object, "notify::something",
+ (GCallback) object_notify_cb, NULL);
+}
+
+/*
+ * No error
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_proto_cb,
+ NULL);
+}
+
+/*
+ * Could not check type of handler for signal ‘GObject::notify’. Callback function declaration does not contain parameter types.
+ * (GCallback) object_notify_no_proto_cb,
+ * ^
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_no_proto_cb,
+ NULL);
+}
+
+/*
+ * Incorrect return type from signal handler for signal ‘GObject::notify’. Expected ‘void’ but saw ‘gboolean’.
+ * (GCallback) object_notify_invalid_return_cb, NULL);
+ * ^
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_invalid_return_cb, NULL);
+}
+
+/*
+ * Incorrect type for argument 1 in signal handler for signal ‘GObject::notify’. Expected ‘GObject *’ but saw ‘GIOStream *’.
+ * (GCallback) object_notify_invalid_parameter_subclass_cb,
+ * ^
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_invalid_parameter_subclass_cb,
+ NULL);
+}
+
+/*
+ * Incorrect type for argument 1 in signal handler for signal ‘GObject::notify’. Expected ‘GObject *’ but saw ‘const GObject *’.
+ * (GCallback) object_notify_invalid_parameter_const_cb,
+ * ^
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_invalid_parameter_const_cb,
+ NULL);
+}
+
+/*
+ * Incorrect type for argument 2 in signal handler for signal ‘GObject::notify’. Expected ‘GParamSpec *’ but saw ‘void *’.
+ * (GCallback) object_notify_invalid_parameter_middle_cb,
+ * ^
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_invalid_parameter_middle_cb,
+ NULL);
+}
+
+/*
+ * Incorrect type for argument 3 in signal handler for signal ‘GObject::notify’. Expected ‘void *’ but saw ‘guint’.
+ * (GCallback) object_notify_invalid_parameter_user_data_cb,
+ * ^
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_invalid_parameter_user_data_cb,
+ NULL);
+}
+
+/*
+ * No error
+ */
+{
+ // Non-void* pointer types for user_data are allowed.
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_invalid_parameter_user_data_ptr_cb,
+ NULL);
+}
+
+/*
+ * Incorrect number of arguments in signal handler for signal ‘GObject::notify’. Expected 3 but saw 2.
+ * (GCallback) object_notify_missing_parameter_cb, NULL);
+ * ^
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_missing_parameter_cb, NULL);
+}
+
+/*
+ * Incorrect number of arguments in signal handler for signal ‘GObject::notify’. Expected 3 but saw 4.
+ * (GCallback) object_notify_extra_parameter_cb, NULL);
+ * ^
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "notify",
+ (GCallback) object_notify_extra_parameter_cb, NULL);
+}
+
+/*
+ * No signal named ‘invalid-signal’ in GObject class ‘Object’.
+ * g_signal_connect (some_object, "invalid-signal",
+ * ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * note: expanded from macro 'g_signal_connect'
+ * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+ * ^ ~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
+ */
+{
+ GObject *some_object = g_malloc (5); // only checking the type
+ g_signal_connect (some_object, "invalid-signal",
+ (GCallback) object_notify_cb, NULL);
+}
diff --git a/tests/gsignal.head.c b/tests/gsignal.head.c
new file mode 100644
index 0000000..8b6e1ac
--- /dev/null
+++ b/tests/gsignal.head.c
@@ -0,0 +1,82 @@
+#include <stdio.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+static void
+object_notify_cb (GObject *gobject, GParamSpec *pspec, gpointer user_data)
+{
+ /* Something */
+}
+
+extern void
+object_notify_proto_cb (GObject *gobject, GParamSpec *pspec, gpointer user_data);
+
+extern void
+object_notify_no_proto_cb ();
+
+static gboolean
+object_notify_invalid_return_cb (GObject *gobject, GParamSpec *pspec,
+ gpointer user_data)
+{
+ /* Something */
+ return FALSE;
+}
+
+static void
+object_notify_invalid_parameter_subclass_cb (GIOStream *gobject,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ /* Something */
+}
+
+static void
+object_notify_invalid_parameter_const_cb (const GObject *gobject,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ /* Something */
+}
+
+static void
+object_notify_invalid_parameter_middle_cb (GObject *gobject,
+ void *pspec,
+ gpointer user_data)
+{
+ /* Something */
+}
+
+static void
+object_notify_invalid_parameter_user_data_cb (GObject *gobject,
+ GParamSpec *pspec,
+ guint user_data)
+{
+ /* Something */
+}
+
+static void
+object_notify_invalid_parameter_user_data_ptr_cb (GObject *gobject,
+ GParamSpec *pspec,
+ GObject *user_data)
+{
+ /* Something */
+}
+
+static void
+object_notify_missing_parameter_cb (GObject *gobject, GParamSpec *pspec)
+{
+ /* Something */
+}
+
+static void
+object_notify_extra_parameter_cb (GObject *gobject, GParamSpec *pspec,
+ gpointer user_data, gpointer user_data2)
+{
+ /* Something */
+}
+
+int
+main (void)
+{
diff --git a/tests/gsignal.tail.c b/tests/gsignal.tail.c
new file mode 100644
index 0000000..aa0c781
--- /dev/null
+++ b/tests/gsignal.tail.c
@@ -0,0 +1,4 @@
+ /* End of main(). */
+
+ return 0;
+}