diff options
author | Lars Uebernickel <lars.uebernickel@canonical.com> | 2013-02-14 22:25:39 +0000 |
---|---|---|
committer | Tarmac <Unknown> | 2013-02-14 22:25:39 +0000 |
commit | d05835eae4e47417fdd41a1d4fcaf6a2bcfd96ea (patch) | |
tree | 43995c9938a1039e251512d6f9ed71971b27a476 /tests | |
parent | e7966480ecd14bd6cb4c4ec5f527cfe10a1a0b0f (diff) | |
parent | 40d7c42d5212dc97ce6b07f05828fb62440d0694 (diff) | |
download | libayatana-indicator-d05835eae4e47417fdd41a1d4fcaf6a2bcfd96ea.tar.gz libayatana-indicator-d05835eae4e47417fdd41a1d4fcaf6a2bcfd96ea.tar.bz2 libayatana-indicator-d05835eae4e47417fdd41a1d4fcaf6a2bcfd96ea.zip |
Add IndicatorNg.
IndicatorNg is an indicator object that reads an indicator service file and watches the bus for a corresponding service to appear. It turns the menus and actions exported by the service into an indicator entry. I think this is a good solution for the transition period in which we support both styles of indicators. (It means we don't need to copy templates around.)
An indicator service file must have an ".indicator" extension and contents simlilar to this:
[Indicator Service]
Name=indicator-test
BusName=com.canonical.indicator.test
ObjectPath=/com/canonical/indicator/test
For unity-panel-service, these files will be installed somewhere. The indicator-loader in this branch accepts a path to such a file as the first command line argument (instead of the .so file).
This can be tested with the example indicator in lp:~larsu/libunity/add-indicator (examples/indicator.vala).
Approved by Charles Kerr, Ted Gould.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 43 | ||||
-rw-r--r-- | tests/com.canonical.indicator.test.service.in | 3 | ||||
-rw-r--r-- | tests/com.canonical.test.indicator | 4 | ||||
-rw-r--r-- | tests/com.canonical.test.nosuchservice.indicator | 4 | ||||
-rw-r--r-- | tests/indicator-test-service.c | 108 | ||||
-rw-r--r-- | tests/test-indicator-ng.c | 167 |
6 files changed, 328 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index c98bdbf..96825f3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,7 +26,8 @@ EXTRA_DIST = \ session.conf.in \ service-manager-connect.service.in \ service-version-bad.service.in \ - service-version-good.service.in + service-version-good.service.in \ + com.canonical.indicator.test.service.in ############################# # Test Loader @@ -466,3 +467,43 @@ DISTCLEANFILES += loader-tester DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT) +############################# +# Indicator-ng +############################# + +if USE_GTK3 + +com.canonical.indicator.test.service: com.canonical.indicator.test.service.in Makefile.am + sed -e "s|\@builddir\@|$(abspath $(builddir))|" $< > $@ + +check_PROGRAMS += test-indicator-ng + +test_indicator_ng_SOURCES = test-indicator-ng.c + +test_indicator_ng_CFLAGS = \ + $(LIBINDICATOR_CFLAGS) \ + -I$(top_srcdir) \ + -DSRCDIR="\"$(srcdir)\"" \ + -DBUILD_DIR="\"$(abs_builddir)\"" \ + -Wall + +test_indicator_ng_LDADD = \ + $(LIBINDICATOR_LIBS) \ + -L$(top_builddir)/libindicator/.libs \ + $(INDICATOR_LIB) + +TESTS += test-indicator-ng +DISTCLEANFILES += test-indicator-ng + +# Mock indicator service +check_PROGRAMS += indicator-test-service + +indicator_test_service_SOURCES = indicator-test-service.c +indicator_test_service_CFLAGS = $(LIBINDICATOR_CFLAGS) +indicator_test_service_LDADD = $(LIBINDICATOR_LIBS) + +EXTRA_indicator_test_service_DEPENDENCIES = com.canonical.indicator.test.service + +DISTCLEANFILES += indicator-test-service com.canonical.indicator.test.service + +endif diff --git a/tests/com.canonical.indicator.test.service.in b/tests/com.canonical.indicator.test.service.in new file mode 100644 index 0000000..3fdbe76 --- /dev/null +++ b/tests/com.canonical.indicator.test.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.canonical.indicator.test +Exec=@builddir@/indicator-test-service diff --git a/tests/com.canonical.test.indicator b/tests/com.canonical.test.indicator new file mode 100644 index 0000000..dad4c94 --- /dev/null +++ b/tests/com.canonical.test.indicator @@ -0,0 +1,4 @@ +[Indicator Service] +Name=indicator-test +BusName=com.canonical.indicator.test +ObjectPath=/com/canonical/indicator/test diff --git a/tests/com.canonical.test.nosuchservice.indicator b/tests/com.canonical.test.nosuchservice.indicator new file mode 100644 index 0000000..8464749 --- /dev/null +++ b/tests/com.canonical.test.nosuchservice.indicator @@ -0,0 +1,4 @@ +[Indicator Service] +Name=indicator-test +BusName=com.canonical.indicator.test.nosuchservice +ObjectPath=/com/canonical/indicator/test diff --git a/tests/indicator-test-service.c b/tests/indicator-test-service.c new file mode 100644 index 0000000..0393677 --- /dev/null +++ b/tests/indicator-test-service.c @@ -0,0 +1,108 @@ + +#include <gio/gio.h> + +typedef struct +{ + GSimpleActionGroup *actions; + GMenu *menu; + + guint actions_export_id; + guint menu_export_id; +} IndicatorTestService; + +static void +bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + IndicatorTestService *indicator = user_data; + GError *error = NULL; + + indicator->actions_export_id = g_dbus_connection_export_action_group (connection, + "/com/canonical/indicator/test", + G_ACTION_GROUP (indicator->actions), + &error); + if (indicator->actions_export_id == 0) + { + g_warning ("cannot export action group: %s", error->message); + g_error_free (error); + return; + } + + indicator->menu_export_id = g_dbus_connection_export_menu_model (connection, + "/com/canonical/indicator/test/desktop", + G_MENU_MODEL (indicator->menu), + &error); + if (indicator->menu_export_id == 0) + { + g_warning ("cannot export menu: %s", error->message); + g_error_free (error); + return; + } +} + +static void +name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + IndicatorTestService *indicator = user_data; + + if (indicator->actions_export_id) + g_dbus_connection_unexport_action_group (connection, indicator->actions_export_id); + + if (indicator->menu_export_id) + g_dbus_connection_unexport_menu_model (connection, indicator->menu_export_id); +} + +static void +activate_show (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + g_message ("showing"); +} + +int +main (int argc, char **argv) +{ + IndicatorTestService indicator = { 0 }; + GMenuItem *item; + GMenu *submenu; + GActionEntry entries[] = { + { "_header", NULL, NULL, "('Test', 'indicator-test', 'Test indicator', true)", NULL }, + { "show", activate_show, NULL, NULL, NULL } + }; + GMainLoop *loop; + + indicator.actions = g_simple_action_group_new (); + g_simple_action_group_add_entries (indicator.actions, entries, G_N_ELEMENTS (entries), NULL); + + submenu = g_menu_new (); + g_menu_append (submenu, "Show", "indicator.show"); + item = g_menu_item_new (NULL, "indicator._header"); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.root"); + g_menu_item_set_submenu (item, G_MENU_MODEL (submenu)); + indicator.menu = g_menu_new (); + g_menu_append_item (indicator.menu, item); + + g_bus_own_name (G_BUS_TYPE_SESSION, + "com.canonical.indicator.test", + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired, + NULL, + name_lost, + &indicator, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_object_unref (submenu); + g_object_unref (item); + g_object_unref (indicator.actions); + g_object_unref (indicator.menu); + g_object_unref (loop); + + return 0; +} diff --git a/tests/test-indicator-ng.c b/tests/test-indicator-ng.c new file mode 100644 index 0000000..150cc37 --- /dev/null +++ b/tests/test-indicator-ng.c @@ -0,0 +1,167 @@ + +#include <libindicator/indicator-ng.h> + +static void +indicator_ng_test_func (gconstpointer user_data) +{ + GTestFunc test_func = user_data; + GTestDBus *bus; + + bus = g_test_dbus_new (G_TEST_DBUS_NONE); + g_test_dbus_add_service_dir (bus, BUILD_DIR); + g_test_dbus_up (bus); + + test_func (); + + g_test_dbus_down (bus); + g_object_unref (bus); +} + +#define indicator_ng_test_add(name, test_func) \ + g_test_add_data_func ("/indicator-ng/" name, test_func, indicator_ng_test_func) + +static gboolean +stop_main_loop (gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_main_loop_quit (loop); + + return FALSE; +} + +static void +test_non_existing (void) +{ + IndicatorNg *indicator; + GError *error = NULL; + + indicator = indicator_ng_new (SRCDIR "/com.canonical.does.not.exist.indicator", &error); + g_assert (indicator == NULL); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); + + g_clear_error (&error); +} + +static void +test_instantiation (void) +{ + IndicatorNg *indicator; + GError *error = NULL; + GMainLoop *loop; + + indicator = indicator_ng_new (SRCDIR "/com.canonical.test.nosuchservice.indicator", &error); + g_assert (indicator); + g_assert (error == NULL); + + g_assert_cmpstr (indicator_ng_get_service_file (indicator), ==, SRCDIR "/com.canonical.test.nosuchservice.indicator"); + g_assert_cmpstr (indicator_ng_get_profile (indicator), ==, "desktop"); + + { + gchar *service_file; + gchar *profile; + + g_object_get (indicator, "service-file", &service_file, + "profile", &profile, + NULL); + + g_assert_cmpstr (service_file, ==, SRCDIR "/com.canonical.test.nosuchservice.indicator"); + g_assert_cmpstr (profile, ==, "desktop"); + + g_free (service_file); + g_free (profile); + } + + loop = g_main_loop_new (NULL, FALSE); + g_timeout_add (200, stop_main_loop, loop); + g_main_loop_run (loop); + + /* no such service, so there shouldn't be any indicators */ + g_assert (indicator_object_get_entries (INDICATOR_OBJECT (indicator)) == NULL); + + g_main_loop_unref (loop); + g_object_unref (indicator); +} + +static void +test_instantiation_with_profile (void) +{ + IndicatorNg *indicator; + GError *error = NULL; + + indicator = indicator_ng_new_for_profile (SRCDIR "/com.canonical.test.indicator", "greeter", &error); + g_assert (indicator); + g_assert (error == NULL); + + g_assert_cmpstr (indicator_ng_get_profile (indicator), ==, "greeter"); + + g_object_unref (indicator); +} + +static void +test_menu (void) +{ + IndicatorNg *indicator; + GError *error = NULL; + GMainLoop *loop; + GList *entries; + IndicatorObjectEntry *entry; + + indicator = indicator_ng_new (SRCDIR "/com.canonical.test.indicator", &error); + g_assert (indicator); + g_assert (error == NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_timeout_add (500, stop_main_loop, loop); + g_main_loop_run (loop); + + entries = indicator_object_get_entries (INDICATOR_OBJECT (indicator)); + g_assert_cmpint (g_list_length (entries), ==, 1); + + entry = entries->data; + g_assert_cmpstr (entry->name_hint, ==, "indicator-test"); + g_assert_cmpstr (entry->accessible_desc, ==, "Test indicator"); + g_assert_cmpstr (gtk_label_get_label (entry->label), ==, "Test"); + g_assert (gtk_image_get_storage_type (entry->image) == GTK_IMAGE_STOCK); + { + GList *children; + GtkMenuItem *item; + + g_assert (entry->menu != NULL); + + children = gtk_container_get_children (GTK_CONTAINER (entry->menu)); + g_assert_cmpint (g_list_length (children), ==, 1); + + item = children->data; + g_assert (GTK_IS_MENU_ITEM (item)); + g_assert (gtk_widget_is_sensitive (GTK_WIDGET (item))); + g_assert_cmpstr (gtk_menu_item_get_label (item), ==, "Show"); + + g_list_free (children); + } + + g_list_free (entries); + g_main_loop_unref (loop); + g_object_unref (indicator); +} + +int +main (int argc, char **argv) +{ + /* gvfs, dconf, and appmenu-gtk leak GDbusConnections, which confuses + * g_test_dbus_down. Make sure we're not using any of those. + */ + g_setenv ("GIO_USE_VFS", "local", TRUE); + g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); + g_unsetenv ("UBUNTU_MENUPROXY"); + + g_test_init (&argc, &argv, NULL); + gtk_init (&argc, &argv); + + indicator_ng_test_add ("non-existing", test_non_existing); + indicator_ng_test_add ("instantiation", test_instantiation); + indicator_ng_test_add ("instantiation-with-profile", test_instantiation_with_profile); + indicator_ng_test_add ("menu", test_menu); + + return g_test_run (); +} |