[gtk+] tests: add a test for gtk_menu_shell_bind()



commit e250e52175d5f62e99c7491d95923ad521e1421c
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Mar 22 17:20:43 2013 -0400

    tests: add a test for gtk_menu_shell_bind()
    
    Borrow the RandomMenu code from the GLib testsuite and hook it up to
    gtk_menu_shell_bind().
    
    https://bugzilla.gnome.org/show_bug.cgi?id=696468

 gtk/tests/Makefile.am |    4 +
 gtk/tests/gtkmenu.c   |  251 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 255 insertions(+), 0 deletions(-)
---
diff --git a/gtk/tests/Makefile.am b/gtk/tests/Makefile.am
index b28105d..fb57368 100644
--- a/gtk/tests/Makefile.am
+++ b/gtk/tests/Makefile.am
@@ -156,6 +156,10 @@ keyhash_CFLAGS                      = -DGTK_COMPILATION \
                                   -DGTK_DATA_PREFIX=\"$(prefix)\" \
                                   -DGTK_SYSCONFDIR=\"$(sysconfdir)\"
 
+TEST_PROGS                     += gtkmenu
+gtkmenu_SOURCES                         = gtkmenu.c
+gtkmenu_LDADD                   = $(progs_ldadd)
+
 EXTRA_DIST +=                          \
        file-chooser-test-dir/empty     \
        file-chooser-test-dir/text.txt
diff --git a/gtk/tests/gtkmenu.c b/gtk/tests/gtkmenu.c
new file mode 100644
index 0000000..fc97843
--- /dev/null
+++ b/gtk/tests/gtkmenu.c
@@ -0,0 +1,251 @@
+#include <gtk/gtk.h>
+
+/* TestItem {{{1 */
+
+/* This utility struct is used by both the RandomMenu and MirrorMenu
+ * class implementations below.
+ */
+typedef struct {
+  GHashTable *attributes;
+  GHashTable *links;
+} TestItem;
+
+static TestItem *
+test_item_new (GHashTable *attributes,
+               GHashTable *links)
+{
+  TestItem *item;
+
+  item = g_slice_new (TestItem);
+  item->attributes = g_hash_table_ref (attributes);
+  item->links = g_hash_table_ref (links);
+
+  return item;
+}
+
+static void
+test_item_free (gpointer data)
+{
+  TestItem *item = data;
+
+  g_hash_table_unref (item->attributes);
+  g_hash_table_unref (item->links);
+
+  g_slice_free (TestItem, item);
+}
+
+/* RandomMenu {{{1 */
+#define MAX_ITEMS 10
+#define TOP_ORDER 4
+
+typedef struct {
+  GMenuModel parent_instance;
+
+  GSequence *items;
+  gint order;
+} RandomMenu;
+
+typedef GMenuModelClass RandomMenuClass;
+
+static GType random_menu_get_type (void);
+G_DEFINE_TYPE (RandomMenu, random_menu, G_TYPE_MENU_MODEL);
+
+static gboolean
+random_menu_is_mutable (GMenuModel *model)
+{
+  return TRUE;
+}
+
+static gint
+random_menu_get_n_items (GMenuModel *model)
+{
+  RandomMenu *menu = (RandomMenu *) model;
+
+  return g_sequence_get_length (menu->items);
+}
+
+static void
+random_menu_get_item_attributes (GMenuModel  *model,
+                                 gint         position,
+                                 GHashTable **table)
+{
+  RandomMenu *menu = (RandomMenu *) model;
+  TestItem *item;
+
+  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
+  *table = g_hash_table_ref (item->attributes);
+}
+
+static void
+random_menu_get_item_links (GMenuModel  *model,
+                            gint         position,
+                            GHashTable **table)
+{
+  RandomMenu *menu = (RandomMenu *) model;
+  TestItem *item;
+
+  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
+  *table = g_hash_table_ref (item->links);
+}
+
+static void
+random_menu_finalize (GObject *object)
+{
+  RandomMenu *menu = (RandomMenu *) object;
+
+  g_sequence_free (menu->items);
+
+  G_OBJECT_CLASS (random_menu_parent_class)
+    ->finalize (object);
+}
+
+static void
+random_menu_init (RandomMenu *menu)
+{
+}
+
+static void
+random_menu_class_init (GMenuModelClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  class->is_mutable = random_menu_is_mutable;
+  class->get_n_items = random_menu_get_n_items;
+  class->get_item_attributes = random_menu_get_item_attributes;
+  class->get_item_links = random_menu_get_item_links;
+
+  object_class->finalize = random_menu_finalize;
+}
+
+static RandomMenu * random_menu_new (GRand *rand, gint order);
+
+static void
+random_menu_change (RandomMenu *menu,
+                    GRand      *rand)
+{
+  gint position, removes, adds;
+  GSequenceIter *point;
+  gint n_items;
+  gint i;
+
+  n_items = g_sequence_get_length (menu->items);
+
+  do
+    {
+      position = g_rand_int_range (rand, 0, n_items + 1);
+      removes = g_rand_int_range (rand, 0, n_items - position + 1);
+      adds = g_rand_int_range (rand, 0, MAX_ITEMS - (n_items - removes) + 1);
+    }
+  while (removes == 0 && adds == 0);
+
+  point = g_sequence_get_iter_at_pos (menu->items, position + removes);
+
+  if (removes)
+    {
+      GSequenceIter *start;
+
+      start = g_sequence_get_iter_at_pos (menu->items, position);
+      g_sequence_remove_range (start, point);
+    }
+
+  for (i = 0; i < adds; i++)
+    {
+      const gchar *label;
+      GHashTable *links;
+      GHashTable *attributes;
+
+      attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
+      links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
+
+      if (menu->order > 0 && g_rand_boolean (rand))
+        {
+          RandomMenu *child;
+          const gchar *subtype;
+
+          child = random_menu_new (rand, menu->order - 1);
+
+          if (g_rand_boolean (rand))
+            {
+              subtype = G_MENU_LINK_SECTION;
+              /* label some section headers */
+              if (g_rand_boolean (rand))
+                label = "Section";
+              else
+                label = NULL;
+            }
+          else
+            {
+              /* label all submenus */
+              subtype = G_MENU_LINK_SUBMENU;
+              label = "Submenu";
+            }
+
+          g_hash_table_insert (links, g_strdup (subtype), child);
+        }
+      else
+        /* label all terminals */
+        label = "Menu Item";
+
+      if (label)
+        g_hash_table_insert (attributes, g_strdup ("label"), g_variant_ref_sink (g_variant_new_string 
(label)));
+
+      g_sequence_insert_before (point, test_item_new (attributes, links));
+      g_hash_table_unref (links);
+      g_hash_table_unref (attributes);
+    }
+
+  g_menu_model_items_changed (G_MENU_MODEL (menu), position, removes, adds);
+}
+
+static RandomMenu *
+random_menu_new (GRand *rand,
+                 gint   order)
+{
+  RandomMenu *menu;
+
+  menu = g_object_new (random_menu_get_type (), NULL);
+  menu->items = g_sequence_new (test_item_free);
+  menu->order = order;
+
+  random_menu_change (menu, rand);
+
+  return menu;
+}
+
+/* Test cases {{{1 */
+static void
+test_bind_menu (void)
+{
+  RandomMenu *model;
+  GtkWidget *menu;
+  GRand *rand;
+  gint i;
+
+  gtk_init (0, 0);
+
+  rand = g_rand_new_with_seed (g_test_rand_int ());
+  model = random_menu_new (rand, TOP_ORDER);
+  menu = gtk_menu_new_from_model (G_MENU_MODEL (model));
+  g_object_ref_sink (menu);
+  for (i = 0; i < 100; i++)
+    {
+      random_menu_change (model, rand);
+      while (g_main_context_iteration (NULL, FALSE));
+      g_print (".");
+    }
+  g_object_unref (model);
+  gtk_widget_destroy (menu);
+  g_object_unref (menu);
+  g_rand_free (rand);
+}
+/* Epilogue {{{1 */
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/gmenu/bind", test_bind_menu);
+
+  return g_test_run ();
+}
+/* vim:set foldmethod=marker: */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]