forked from AuroraMiddleware/gtk
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
This commit is contained in:
parent
d599985a41
commit
e250e52175
@ -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
|
||||
|
251
gtk/tests/gtkmenu.c
Normal file
251
gtk/tests/gtkmenu.c
Normal file
@ -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: */
|
Loading…
Reference in New Issue
Block a user