aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2013-03-13 17:16:48 +0000
committerCharles Kerr <charles.kerr@canonical.com>2013-03-13 17:16:48 +0000
commit9b75358ca14e1ad8a41c364195df748a1a1bbf5d (patch)
treebaf1e3f7051216f46da49a8a1d82dde3d4ca20e9 /tests
parent7453a4ef0ecd0e44b8296899f3021587e8110f4e (diff)
downloadlibdbusmenu-9b75358ca14e1ad8a41c364195df748a1a1bbf5d.tar.gz
libdbusmenu-9b75358ca14e1ad8a41c364195df748a1a1bbf5d.tar.bz2
libdbusmenu-9b75358ca14e1ad8a41c364195df748a1a1bbf5d.zip
stop listening to a widget's signals when it's removed from the menu tree that we're mirroring. This condition was detected by a flood of g_warnings, so add a regression test to confirm that the warning messages no longer appear.
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am21
-rw-r--r--tests/test-gtk-remove.c118
2 files changed, 139 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0cd68d0..356d803 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -29,6 +29,7 @@ TESTS += \
test-gtk-label \
test-gtk-shortcut \
test-gtk-reorder \
+ test-gtk-remove \
test-gtk-parser-test
# Not working with GTK3 and a critical grab that is in
# the GTK3 code.
@@ -71,6 +72,7 @@ endif
if WANT_LIBDBUSMENUGTK
check_PROGRAMS += \
test-gtk-objects \
+ test-gtk-remove \
test-gtk-label-client \
test-gtk-label-server \
test-gtk-shortcut-client \
@@ -621,6 +623,25 @@ EXTRA_DIST += test-gtk-shortcut-client.py
CLEANFILES += test-gtk-shortcut-client.pyc
#########################
+# Test GTK Remove
+#########################
+
+test_gtk_remove_SOURCES = \
+ test-gtk-remove.c
+
+test_gtk_remove_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_remove_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk$(VER).la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+#########################
# Test GTK Reorder
#########################
diff --git a/tests/test-gtk-remove.c b/tests/test-gtk-remove.c
new file mode 100644
index 0000000..0655fc0
--- /dev/null
+++ b/tests/test-gtk-remove.c
@@ -0,0 +1,118 @@
+/*
+ Confirm that no warnings/criticals get generated by including
+ multiple add/removes in a match w/o waiting on the mainloop to iterate.
+
+ Copyright 2013 Canonical Ltd.
+
+ Original sample code by Drew Bliss <drewb@valvesoftware.com>
+ Modified for automatic testing by Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#include <stdlib.h> /* exit() */
+#include <gtk/gtk.h>
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-gtk/menu.h>
+#include <libdbusmenu-gtk/parser.h>
+
+static GMainLoop * loop = NULL;
+static GtkWidget * top_gtk = NULL;
+static DbusmenuMenuitem * top_dbusmenu = NULL;
+static DbusmenuServer * menuservice = NULL;
+
+static void
+rebuild_menu (void)
+{
+ GList * l;
+ GList * children;
+ int i;
+ const int n = 10;
+ static int count = 0;
+
+ if (top_gtk == NULL)
+ {
+ top_gtk = gtk_menu_new ();
+ gtk_widget_show (top_gtk);
+ top_dbusmenu = dbusmenu_gtk_parse_menu_structure (top_gtk);
+ menuservice = dbusmenu_server_new ("/org/ayatana/NotificationItem/test/Menu");
+ dbusmenu_server_set_root (menuservice, top_dbusmenu);
+ }
+
+ // remove all the previous children
+ children = gtk_container_get_children (GTK_CONTAINER(top_gtk));
+ for (l=children; l!=NULL; l=l->next)
+ gtk_widget_destroy (GTK_WIDGET (l->data));
+
+ // add a handful of new children
+ for (i=0; i<n; ++i)
+ {
+ char buf[80];
+ GtkWidget * child;
+
+ g_snprintf (buf, sizeof(buf), "Test item %d", ++count);
+ child = gtk_menu_item_new_with_label (buf);
+ gtk_menu_shell_append (GTK_MENU_SHELL(top_gtk), child);
+ gtk_widget_show (child);
+ }
+}
+
+/*
+ * Periodically rebuild the menu.
+ *
+ * After we've looped a couple of times with only one rebuild,
+ * attempt to reproduce the bug Drew reported by rebuilding multiple
+ * times before returning control to the main loop.
+ *
+ * If we survive doing this a handful of times without encountering
+ * a g_warning or g_critical, pass the test.
+ */
+static gint
+on_timer (gpointer unused G_GNUC_UNUSED)
+{
+ static int iteration = 0;
+
+ ++iteration;
+
+ if (iteration > 5)
+ {
+ g_main_loop_quit (loop);
+ return G_SOURCE_REMOVE;
+ }
+
+ if (iteration <= 2)
+ {
+ rebuild_menu ();
+ }
+ else
+ {
+ int i;
+
+ for (i=0; i<iteration; ++i)
+ rebuild_menu ();
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+warning_counter (const gchar * log_domain,
+ GLogLevelFlags log_level G_GNUC_UNUSED,
+ const gchar * message,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ g_message ("Failing the test due to warning: %s %s", log_domain, message);
+ exit (EXIT_FAILURE);
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_log_set_handler ("LIBDBUSMENU-GLIB", G_LOG_LEVEL_WARNING|G_LOG_LEVEL_CRITICAL, warning_counter, NULL);
+
+
+ gtk_init (&argc, &argv);
+ loop = g_main_loop_new (NULL, FALSE);
+ g_timeout_add (200, on_timer, NULL);
+ g_main_loop_run (loop);
+
+ return 0;
+}