5 /* This utility struct is used by both the RandomMenu and MirrorMenu
6 * class implementations below.
9 GHashTable
*attributes
;
14 test_item_new (GHashTable
*attributes
,
19 item
= g_slice_new (TestItem
);
20 item
->attributes
= g_hash_table_ref (attributes
);
21 item
->links
= g_hash_table_ref (links
);
27 test_item_free (gpointer data
)
29 TestItem
*item
= data
;
31 g_hash_table_unref (item
->attributes
);
32 g_hash_table_unref (item
->links
);
34 g_slice_free (TestItem
, item
);
42 GMenuModel parent_instance
;
48 typedef GMenuModelClass RandomMenuClass
;
50 static GType
random_menu_get_type (void);
51 G_DEFINE_TYPE (RandomMenu
, random_menu
, G_TYPE_MENU_MODEL
);
54 random_menu_is_mutable (GMenuModel
*model
)
60 random_menu_get_n_items (GMenuModel
*model
)
62 RandomMenu
*menu
= (RandomMenu
*) model
;
64 return g_sequence_get_length (menu
->items
);
68 random_menu_get_item_attributes (GMenuModel
*model
,
72 RandomMenu
*menu
= (RandomMenu
*) model
;
75 item
= g_sequence_get (g_sequence_get_iter_at_pos (menu
->items
, position
));
76 *table
= g_hash_table_ref (item
->attributes
);
80 random_menu_get_item_links (GMenuModel
*model
,
84 RandomMenu
*menu
= (RandomMenu
*) model
;
87 item
= g_sequence_get (g_sequence_get_iter_at_pos (menu
->items
, position
));
88 *table
= g_hash_table_ref (item
->links
);
92 random_menu_finalize (GObject
*object
)
94 RandomMenu
*menu
= (RandomMenu
*) object
;
96 g_sequence_free (menu
->items
);
98 G_OBJECT_CLASS (random_menu_parent_class
)
103 random_menu_init (RandomMenu
*menu
)
108 random_menu_class_init (GMenuModelClass
*class)
110 GObjectClass
*object_class
= G_OBJECT_CLASS (class);
112 class->is_mutable
= random_menu_is_mutable
;
113 class->get_n_items
= random_menu_get_n_items
;
114 class->get_item_attributes
= random_menu_get_item_attributes
;
115 class->get_item_links
= random_menu_get_item_links
;
117 object_class
->finalize
= random_menu_finalize
;
120 static RandomMenu
* random_menu_new (GRand
*rand
, gint order
);
123 random_menu_change (RandomMenu
*menu
,
126 gint position
, removes
, adds
;
127 GSequenceIter
*point
;
131 n_items
= g_sequence_get_length (menu
->items
);
135 position
= g_rand_int_range (rand
, 0, n_items
+ 1);
136 removes
= g_rand_int_range (rand
, 0, n_items
- position
+ 1);
137 adds
= g_rand_int_range (rand
, 0, MAX_ITEMS
- (n_items
- removes
) + 1);
139 while (removes
== 0 && adds
== 0);
141 point
= g_sequence_get_iter_at_pos (menu
->items
, position
+ removes
);
145 GSequenceIter
*start
;
147 start
= g_sequence_get_iter_at_pos (menu
->items
, position
);
148 g_sequence_remove_range (start
, point
);
151 for (i
= 0; i
< adds
; i
++)
155 GHashTable
*attributes
;
157 attributes
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
) g_variant_unref
);
158 links
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
) g_object_unref
);
160 if (menu
->order
> 0 && g_rand_boolean (rand
))
163 const gchar
*subtype
;
165 child
= random_menu_new (rand
, menu
->order
- 1);
167 if (g_rand_boolean (rand
))
169 subtype
= G_MENU_LINK_SECTION
;
170 /* label some section headers */
171 if (g_rand_boolean (rand
))
178 /* label all submenus */
179 subtype
= G_MENU_LINK_SUBMENU
;
183 g_hash_table_insert (links
, g_strdup (subtype
), child
);
186 /* label all terminals */
190 g_hash_table_insert (attributes
, g_strdup ("label"), g_variant_ref_sink (g_variant_new_string (label
)));
192 g_sequence_insert_before (point
, test_item_new (attributes
, links
));
193 g_hash_table_unref (links
);
194 g_hash_table_unref (attributes
);
197 g_menu_model_items_changed (G_MENU_MODEL (menu
), position
, removes
, adds
);
201 random_menu_new (GRand
*rand
,
206 menu
= g_object_new (random_menu_get_type (), NULL
);
207 menu
->items
= g_sequence_new (test_item_free
);
210 random_menu_change (menu
, rand
);
215 /* MirrorMenu {{{1 */
217 GMenuModel parent_instance
;
219 GMenuModel
*clone_of
;
224 typedef GMenuModelClass MirrorMenuClass
;
226 static GType
mirror_menu_get_type (void);
227 G_DEFINE_TYPE (MirrorMenu
, mirror_menu
, G_TYPE_MENU_MODEL
);
230 mirror_menu_is_mutable (GMenuModel
*model
)
232 MirrorMenu
*menu
= (MirrorMenu
*) model
;
234 return menu
->handler_id
!= 0;
238 mirror_menu_get_n_items (GMenuModel
*model
)
240 MirrorMenu
*menu
= (MirrorMenu
*) model
;
242 return g_sequence_get_length (menu
->items
);
246 mirror_menu_get_item_attributes (GMenuModel
*model
,
250 MirrorMenu
*menu
= (MirrorMenu
*) model
;
253 item
= g_sequence_get (g_sequence_get_iter_at_pos (menu
->items
, position
));
254 *table
= g_hash_table_ref (item
->attributes
);
258 mirror_menu_get_item_links (GMenuModel
*model
,
262 MirrorMenu
*menu
= (MirrorMenu
*) model
;
265 item
= g_sequence_get (g_sequence_get_iter_at_pos (menu
->items
, position
));
266 *table
= g_hash_table_ref (item
->links
);
270 mirror_menu_finalize (GObject
*object
)
272 MirrorMenu
*menu
= (MirrorMenu
*) object
;
274 if (menu
->handler_id
)
275 g_signal_handler_disconnect (menu
->clone_of
, menu
->handler_id
);
277 g_sequence_free (menu
->items
);
278 g_object_unref (menu
->clone_of
);
280 G_OBJECT_CLASS (mirror_menu_parent_class
)
285 mirror_menu_init (MirrorMenu
*menu
)
290 mirror_menu_class_init (GMenuModelClass
*class)
292 GObjectClass
*object_class
= G_OBJECT_CLASS (class);
294 class->is_mutable
= mirror_menu_is_mutable
;
295 class->get_n_items
= mirror_menu_get_n_items
;
296 class->get_item_attributes
= mirror_menu_get_item_attributes
;
297 class->get_item_links
= mirror_menu_get_item_links
;
299 object_class
->finalize
= mirror_menu_finalize
;
302 static MirrorMenu
* mirror_menu_new (GMenuModel
*clone_of
);
305 mirror_menu_changed (GMenuModel
*model
,
311 MirrorMenu
*menu
= user_data
;
312 GSequenceIter
*point
;
315 g_assert (model
== menu
->clone_of
);
317 point
= g_sequence_get_iter_at_pos (menu
->items
, position
+ removed
);
321 GSequenceIter
*start
;
323 start
= g_sequence_get_iter_at_pos (menu
->items
, position
);
324 g_sequence_remove_range (start
, point
);
327 for (i
= position
; i
< position
+ added
; i
++)
329 GMenuAttributeIter
*attr_iter
;
330 GMenuLinkIter
*link_iter
;
332 GHashTable
*attributes
;
337 attributes
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
) g_variant_unref
);
338 links
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
) g_object_unref
);
340 attr_iter
= g_menu_model_iterate_item_attributes (model
, i
);
341 while (g_menu_attribute_iter_get_next (attr_iter
, &name
, &value
))
343 g_hash_table_insert (attributes
, g_strdup (name
), value
);
345 g_object_unref (attr_iter
);
347 link_iter
= g_menu_model_iterate_item_links (model
, i
);
348 while (g_menu_link_iter_get_next (link_iter
, &name
, &child
))
350 g_hash_table_insert (links
, g_strdup (name
), mirror_menu_new (child
));
351 g_object_unref (child
);
353 g_object_unref (link_iter
);
355 g_sequence_insert_before (point
, test_item_new (attributes
, links
));
356 g_hash_table_unref (attributes
);
357 g_hash_table_unref (links
);
360 g_menu_model_items_changed (G_MENU_MODEL (menu
), position
, removed
, added
);
364 mirror_menu_new (GMenuModel
*clone_of
)
368 menu
= g_object_new (mirror_menu_get_type (), NULL
);
369 menu
->items
= g_sequence_new (test_item_free
);
370 menu
->clone_of
= g_object_ref (clone_of
);
372 if (g_menu_model_is_mutable (clone_of
))
373 menu
->handler_id
= g_signal_connect (clone_of
, "items-changed", G_CALLBACK (mirror_menu_changed
), menu
);
374 mirror_menu_changed (clone_of
, 0, 0, g_menu_model_get_n_items (clone_of
), menu
);
379 /* check_menus_equal(), assert_menus_equal() {{{1 */
381 check_menus_equal (GMenuModel
*a
,
384 gboolean equal
= TRUE
;
388 a_n
= g_menu_model_get_n_items (a
);
389 b_n
= g_menu_model_get_n_items (b
);
394 for (i
= 0; i
< a_n
; i
++)
396 GMenuAttributeIter
*attr_iter
;
397 GVariant
*a_value
, *b_value
;
398 GMenuLinkIter
*link_iter
;
399 GMenuModel
*a_menu
, *b_menu
;
402 attr_iter
= g_menu_model_iterate_item_attributes (a
, i
);
403 while (g_menu_attribute_iter_get_next (attr_iter
, &name
, &a_value
))
405 b_value
= g_menu_model_get_item_attribute_value (b
, i
, name
, NULL
);
406 equal
&= b_value
&& g_variant_equal (a_value
, b_value
);
408 g_variant_unref (b_value
);
409 g_variant_unref (a_value
);
411 g_object_unref (attr_iter
);
413 attr_iter
= g_menu_model_iterate_item_attributes (b
, i
);
414 while (g_menu_attribute_iter_get_next (attr_iter
, &name
, &b_value
))
416 a_value
= g_menu_model_get_item_attribute_value (a
, i
, name
, NULL
);
417 equal
&= a_value
&& g_variant_equal (a_value
, b_value
);
419 g_variant_unref (a_value
);
420 g_variant_unref (b_value
);
422 g_object_unref (attr_iter
);
424 link_iter
= g_menu_model_iterate_item_links (a
, i
);
425 while (g_menu_link_iter_get_next (link_iter
, &name
, &a_menu
))
427 b_menu
= g_menu_model_get_item_link (b
, i
, name
);
428 equal
&= b_menu
&& check_menus_equal (a_menu
, b_menu
);
430 g_object_unref (b_menu
);
431 g_object_unref (a_menu
);
433 g_object_unref (link_iter
);
435 link_iter
= g_menu_model_iterate_item_links (b
, i
);
436 while (g_menu_link_iter_get_next (link_iter
, &name
, &b_menu
))
438 a_menu
= g_menu_model_get_item_link (a
, i
, name
);
439 equal
&= a_menu
&& check_menus_equal (a_menu
, b_menu
);
441 g_object_unref (a_menu
);
442 g_object_unref (b_menu
);
444 g_object_unref (link_iter
);
451 assert_menus_equal (GMenuModel
*a
,
454 if (!check_menus_equal (a
, b
))
458 string
= g_string_new ("\n <a>\n");
459 g_menu_markup_print_string (string
, G_MENU_MODEL (a
), 4, 2);
460 g_string_append (string
, " </a>\n\n-------------\n <b>\n");
461 g_menu_markup_print_string (string
, G_MENU_MODEL (b
), 4, 2);
462 g_string_append (string
, " </b>\n");
463 g_error ("%s", string
->str
);
467 /* Test cases {{{1 */
471 GRand
*randa
, *randb
;
475 seed
= g_test_rand_int ();
477 randa
= g_rand_new_with_seed (seed
);
478 randb
= g_rand_new_with_seed (seed
);
480 for (i
= 0; i
< 500; i
++)
484 a
= random_menu_new (randa
, TOP_ORDER
);
485 b
= random_menu_new (randb
, TOP_ORDER
);
486 assert_menus_equal (G_MENU_MODEL (a
), G_MENU_MODEL (b
));
493 for (i
= 0; i
< 500;)
497 a
= random_menu_new (randa
, TOP_ORDER
);
498 b
= random_menu_new (randb
, TOP_ORDER
);
499 if (check_menus_equal (G_MENU_MODEL (a
), G_MENU_MODEL (b
)))
501 /* by chance, they may really be equal. double check. */
504 as
= g_menu_markup_print_string (NULL
, G_MENU_MODEL (a
), 4, 2);
505 bs
= g_menu_markup_print_string (NULL
, G_MENU_MODEL (b
), 4, 2);
506 g_assert_cmpstr (as
->str
, ==, bs
->str
);
507 g_string_free (bs
, TRUE
);
508 g_string_free (as
, TRUE
);
511 /* make sure we get enough unequals (ie: no GRand failure) */
530 rand
= g_rand_new_with_seed (g_test_rand_int ());
531 random
= random_menu_new (rand
, TOP_ORDER
);
532 mirror
= mirror_menu_new (G_MENU_MODEL (random
));
534 for (i
= 0; i
< 500; i
++)
536 assert_menus_equal (G_MENU_MODEL (random
), G_MENU_MODEL (mirror
));
537 random_menu_change (random
, rand
);
540 g_object_unref (mirror
);
541 g_object_unref (random
);
546 struct roundtrip_state
549 MirrorMenu
*proxy_mirror
;
558 roundtrip_step (gpointer data
)
560 struct roundtrip_state
*state
= data
;
562 if (check_menus_equal (G_MENU_MODEL (state
->random
), G_MENU_MODEL (state
->proxy
)) &&
563 check_menus_equal (G_MENU_MODEL (state
->random
), G_MENU_MODEL (state
->proxy_mirror
)))
568 if (state
->success
< 100)
569 random_menu_change (state
->random
, state
->rand
);
571 g_main_loop_quit (state
->loop
);
573 else if (state
->count
== 100)
575 assert_menus_equal (G_MENU_MODEL (state
->random
), G_MENU_MODEL (state
->proxy
));
576 g_assert_not_reached ();
581 return G_SOURCE_CONTINUE
;
585 test_dbus_roundtrip (void)
587 struct roundtrip_state state
;
588 GDBusConnection
*bus
;
591 bus
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, NULL
);
593 state
.rand
= g_rand_new_with_seed (g_test_rand_int ());
595 state
.random
= random_menu_new (state
.rand
, 2);
596 g_menu_model_dbus_export_start (bus
, "/", G_MENU_MODEL (state
.random
), NULL
);
597 g_assert (g_menu_model_dbus_export_query (G_MENU_MODEL (state
.random
), NULL
, NULL
));
598 state
.proxy
= g_menu_proxy_get (bus
, g_dbus_connection_get_unique_name (bus
), "/");
599 state
.proxy_mirror
= mirror_menu_new (G_MENU_MODEL (state
.proxy
));
603 id
= g_timeout_add (10, roundtrip_step
, &state
);
605 state
.loop
= g_main_loop_new (NULL
, FALSE
);
606 g_main_loop_run (state
.loop
);
608 g_main_loop_unref (state
.loop
);
609 g_source_remove (id
);
610 g_object_unref (state
.proxy
);
611 g_menu_model_dbus_export_stop (G_MENU_MODEL (state
.random
));
612 g_assert (!g_menu_model_dbus_export_query (G_MENU_MODEL (state
.random
), NULL
, NULL
));
613 g_object_unref (state
.random
);
614 g_object_unref (state
.proxy_mirror
);
615 g_rand_free (state
.rand
);
616 g_object_unref (bus
);
619 static gint items_changed_count
;
622 items_changed (GMenuModel
*model
,
628 items_changed_count
++;
632 stop_loop (gpointer data
)
634 GMainLoop
*loop
= data
;
636 g_main_loop_quit (loop
);
638 return G_SOURCE_REMOVE
;
642 test_dbus_subscriptions (void)
644 GDBusConnection
*bus
;
648 GError
*error
= NULL
;
650 loop
= g_main_loop_new (NULL
, FALSE
);
652 bus
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, NULL
);
654 menu
= g_menu_new ();
656 g_menu_model_dbus_export_start (bus
, "/", G_MENU_MODEL (menu
), &error
);
657 g_assert_no_error (error
);
659 proxy
= g_menu_proxy_get (bus
, g_dbus_connection_get_unique_name (bus
), "/");
660 items_changed_count
= 0;
661 g_signal_connect (proxy
, "items-changed",
662 G_CALLBACK (items_changed
), NULL
);
664 g_menu_append (menu
, "item1", NULL
);
665 g_menu_append (menu
, "item2", NULL
);
666 g_menu_append (menu
, "item3", NULL
);
668 g_assert_cmpint (items_changed_count
, ==, 0);
670 g_timeout_add (100, stop_loop
, loop
);
671 g_main_loop_run (loop
);
673 g_menu_model_get_n_items (G_MENU_MODEL (proxy
));
675 g_timeout_add (100, stop_loop
, loop
);
676 g_main_loop_run (loop
);
678 g_assert_cmpint (items_changed_count
, ==, 1);
679 g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (proxy
)), ==, 3);
681 g_timeout_add (100, stop_loop
, loop
);
682 g_main_loop_run (loop
);
684 g_menu_append (menu
, "item4", NULL
);
685 g_menu_append (menu
, "item5", NULL
);
686 g_menu_append (menu
, "item6", NULL
);
687 g_menu_remove (menu
, 0);
688 g_menu_remove (menu
, 0);
690 g_timeout_add (200, stop_loop
, loop
);
691 g_main_loop_run (loop
);
693 g_assert_cmpint (items_changed_count
, ==, 6);
695 g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (proxy
)), ==, 4);
696 g_object_unref (proxy
);
698 g_timeout_add (100, stop_loop
, loop
);
699 g_main_loop_run (loop
);
701 g_menu_remove (menu
, 0);
702 g_menu_remove (menu
, 0);
704 g_timeout_add (100, stop_loop
, loop
);
705 g_main_loop_run (loop
);
707 g_assert_cmpint (items_changed_count
, ==, 6);
709 g_menu_model_dbus_export_stop (G_MENU_MODEL (menu
));
710 g_object_unref (menu
);
712 g_main_loop_unref (loop
);
716 start_element (GMarkupParseContext
*context
,
717 const gchar
*element_name
,
718 const gchar
**attribute_names
,
719 const gchar
**attribute_values
,
723 if (g_strcmp0 (element_name
, "menu") == 0)
724 g_menu_markup_parser_start_menu (context
, "domain", NULL
);
728 end_element (GMarkupParseContext
*context
,
729 const gchar
*element_name
,
733 GMenu
**menu
= user_data
;
735 if (g_strcmp0 (element_name
, "menu") == 0)
736 *menu
= g_menu_markup_parser_end_menu (context
);
740 parse_menu_string (const gchar
*string
, GError
**error
)
742 const GMarkupParser parser
= {
743 start_element
, end_element
, NULL
, NULL
, NULL
745 GMarkupParseContext
*context
;
746 GMenuModel
*menu
= NULL
;
748 context
= g_markup_parse_context_new (&parser
, 0, &menu
, NULL
);
749 g_markup_parse_context_parse (context
, string
, -1, error
);
750 g_markup_parse_context_free (context
);
756 menu_to_string (GMenuModel
*menu
)
760 s
= g_string_new ("<menu>\n");
761 g_menu_markup_print_string (s
, menu
, 2, 2);
762 g_string_append (s
, "</menu>\n");
764 return g_string_free (s
, FALSE
);
768 test_markup_roundtrip (void)
771 "<menu id='edit-menu'>\n"
773 " <item action='undo'>\n"
774 " <attribute name='label' translatable='yes' context='Stock label'>'_Undo'</attribute>\n"
776 " <item label='Redo' action='redo'/>\n"
778 " <section></section>\n"
779 " <section label='Copy & Paste'>\n"
780 " <item label='Cut' action='cut'/>\n"
781 " <item label='Copy' action='copy'/>\n"
782 " <item label='Paste' action='paste'/>\n"
785 " <item label='Bold' action='bold'/>\n"
786 " <submenu label='Language'>\n"
787 " <item label='Latin' action='lang' target='latin'/>\n"
788 " <item label='Greek' action='lang' target='greek'/>\n"
789 " <item label='Urdu' action='lang' target='urdu'/>\n"
791 " <item name='test unusual attributes'>\n"
792 " <attribute name='action' type='s'>'quite-some-action'</attribute>\n"
793 " <attribute name='target' type='i'>36</attribute>\n"
794 " <attribute name='chocolate-thunda' type='as'>['a','b']</attribute>\n"
795 " <attribute name='thing1' type='g'>'s(uu)'</attribute>\n"
796 " <attribute name='icon' type='s'>'small blue thing'</attribute>\n"
800 GError
*error
= NULL
;
806 a
= parse_menu_string (data
, &error
);
807 g_assert_no_error (error
);
808 g_assert (G_IS_MENU_MODEL (a
));
810 /* normalized representation */
811 s
= menu_to_string (a
);
813 b
= parse_menu_string (s
, &error
);
814 g_assert_no_error (error
);
815 g_assert (G_IS_MENU_MODEL (b
));
817 assert_menus_equal (G_MENU_MODEL (a
), G_MENU_MODEL (b
));
819 s2
= menu_to_string (b
);
821 g_assert_cmpstr (s
, ==, s2
);
830 test_attributes (void)
836 menu
= g_menu_new ();
838 item
= g_menu_item_new ("test", NULL
);
839 g_menu_item_set_attribute_value (item
, "boolean", g_variant_new_boolean (FALSE
));
840 g_menu_item_set_attribute_value (item
, "string", g_variant_new_string ("bla"));
841 g_menu_item_set_attribute_value (item
, "double", g_variant_new_double (1.5));
842 v
= g_variant_new_parsed ("[('one', 1), ('two', %i), (%s, 3)]", 2, "three");
843 g_menu_item_set_attribute_value (item
, "complex", v
);
844 g_menu_item_set_attribute_value (item
, "test-123", g_variant_new_string ("test-123"));
846 g_menu_append_item (menu
, item
);
848 g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (menu
)), ==, 1);
850 v
= g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu
), 0, "boolean", NULL
);
851 g_assert (g_variant_is_of_type (v
, G_VARIANT_TYPE_BOOLEAN
));
854 v
= g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu
), 0, "string", NULL
);
855 g_assert (g_variant_is_of_type (v
, G_VARIANT_TYPE_STRING
));
858 v
= g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu
), 0, "double", NULL
);
859 g_assert (g_variant_is_of_type (v
, G_VARIANT_TYPE_DOUBLE
));
862 v
= g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu
), 0, "complex", NULL
);
863 g_assert (g_variant_is_of_type (v
, G_VARIANT_TYPE("a(si)")));
866 g_object_unref (menu
);
877 m
= G_MENU_MODEL (g_menu_new ());
878 g_menu_append (G_MENU (m
), "test", NULL
);
880 menu
= g_menu_new ();
882 item
= g_menu_item_new ("test1", NULL
);
883 g_menu_item_set_link (item
, "section", m
);
884 g_menu_append_item (menu
, item
);
886 item
= g_menu_item_new ("test2", NULL
);
887 g_menu_item_set_link (item
, "submenu", m
);
888 g_menu_append_item (menu
, item
);
890 item
= g_menu_item_new ("test3", NULL
);
891 g_menu_item_set_link (item
, "wallet", m
);
892 g_menu_append_item (menu
, item
);
894 item
= g_menu_item_new ("test4", NULL
);
895 g_menu_item_set_link (item
, "purse", m
);
896 g_menu_item_set_link (item
, "purse", NULL
);
897 g_menu_append_item (menu
, item
);
899 g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (menu
)), ==, 4);
901 x
= g_menu_model_get_item_link (G_MENU_MODEL (menu
), 0, "section");
905 x
= g_menu_model_get_item_link (G_MENU_MODEL (menu
), 1, "submenu");
909 x
= g_menu_model_get_item_link (G_MENU_MODEL (menu
), 2, "wallet");
913 x
= g_menu_model_get_item_link (G_MENU_MODEL (menu
), 3, "purse");
914 g_assert (x
== NULL
);
917 g_object_unref (menu
);
925 menu
= g_menu_new ();
926 g_menu_append (menu
, "test", "test");
928 g_assert (g_menu_model_is_mutable (G_MENU_MODEL (menu
)));
929 g_menu_freeze (menu
);
930 g_assert (!g_menu_model_is_mutable (G_MENU_MODEL (menu
)));
932 g_object_unref (menu
);
938 /* trying to use most of the GMenu api for constructing the
939 * same menu two different ways
947 item
= g_menu_item_new ("test1", "action1::target1");
948 g_menu_prepend_item (a
, item
);
949 g_object_unref (item
);
952 g_menu_prepend (m
, "test2a", "action2");
953 g_menu_append (m
, "test2c", NULL
);
954 g_menu_insert (m
, 1, "test2b", NULL
);
956 item
= g_menu_item_new_submenu ("test2", G_MENU_MODEL (m
));
957 g_menu_append_item (a
, item
);
958 g_object_unref (item
);
964 g_menu_append (m2
, "x", NULL
);
965 g_menu_prepend_section (m
, "test3a", G_MENU_MODEL (m2
));
968 item
= g_menu_item_new_section ("test3", G_MENU_MODEL (m
));
969 g_menu_insert_item (a
, -1, item
);
970 g_object_unref (item
);
975 " <item target='target1' action='action1' label='test1'/>"
976 " <item label='test2'>"
977 " <link name='submenu'>"
978 " <item action='action2' label='test2a'/>"
979 " <item label='test2b'/>"
980 " <item label='test2c'/>"
983 " <item label='test3'>"
984 " <link name='section'>"
985 " <item label='test3a'>"
986 " <link name='section'>"
994 b
= parse_menu_string (s
, NULL
);
996 assert_menus_equal (G_MENU_MODEL (a
), G_MENU_MODEL (b
));
1003 main (int argc
, char **argv
)
1005 g_test_init (&argc
, &argv
, NULL
);
1009 g_test_add_func ("/gmenu/equality", test_equality
);
1010 g_test_add_func ("/gmenu/random", test_random
);
1011 g_test_add_func ("/gmenu/dbus/roundtrip", test_dbus_roundtrip
);
1012 g_test_add_func ("/gmenu/dbus/subscriptions", test_dbus_subscriptions
);
1013 g_test_add_func ("/gmenu/markup/roundtrip", test_markup_roundtrip
);
1014 g_test_add_func ("/gmenu/attributes", test_attributes
);
1015 g_test_add_func ("/gmenu/links", test_links
);
1016 g_test_add_func ("/gmenu/mutable", test_mutable
);
1017 g_test_add_func ("/gmenu/misc", test_misc
);
1019 return g_test_run ();
1021 /* vim:set foldmethod=marker: */