LCOV - code coverage report
Current view: top level - glib/gio/tests - appmonitor.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 65 71 91.5 %
Date: 2024-04-23 05:16:05 Functions: 7 8 87.5 %
Branches: 6 8 75.0 %

           Branch data     Line data    Source code
       1                 :            : /* GLib testing framework examples and tests
       2                 :            :  *
       3                 :            :  * Copyright © 2013 Red Hat, Inc.
       4                 :            :  * Copyright © 2015, 2017, 2018 Endless Mobile, Inc.
       5                 :            :  *
       6                 :            :  * SPDX-License-Identifier: LGPL-2.1-or-later
       7                 :            :  *
       8                 :            :  * This library is free software; you can redistribute it and/or
       9                 :            :  * modify it under the terms of the GNU Lesser General Public
      10                 :            :  * License as published by the Free Software Foundation; either
      11                 :            :  * version 2.1 of the License, or (at your option) any later version.
      12                 :            :  *
      13                 :            :  * This library is distributed in the hope that it will be useful,
      14                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16                 :            :  * Lesser General Public License for more details.
      17                 :            :  *
      18                 :            :  * You should have received a copy of the GNU Lesser General
      19                 :            :  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <gio/gio.h>
      23                 :            : #include <gstdio.h>
      24                 :            : 
      25                 :            : #if defined (G_OS_UNIX) && !defined (__APPLE__)
      26                 :            : #include <gio/gdesktopappinfo.h>
      27                 :            : #endif
      28                 :            : 
      29                 :            : typedef struct
      30                 :            : {
      31                 :            :   gchar *applications_dir;
      32                 :            : } Fixture;
      33                 :            : 
      34                 :            : static void
      35                 :          1 : setup (Fixture       *fixture,
      36                 :            :        gconstpointer  user_data)
      37                 :            : {
      38                 :          1 :   fixture->applications_dir = g_build_filename (g_get_user_data_dir (), "applications", NULL);
      39                 :          1 :   g_assert_no_errno (g_mkdir_with_parents (fixture->applications_dir, 0755));
      40                 :            : 
      41                 :          1 :   g_test_message ("Using data directory: %s", g_get_user_data_dir ());
      42                 :          1 : }
      43                 :            : 
      44                 :            : static void
      45                 :          1 : teardown (Fixture       *fixture,
      46                 :            :           gconstpointer  user_data)
      47                 :            : {
      48                 :          1 :   g_assert_no_errno (g_rmdir (fixture->applications_dir));
      49                 :          1 :   g_clear_pointer (&fixture->applications_dir, g_free);
      50                 :          1 : }
      51                 :            : 
      52                 :            : #if defined (G_OS_UNIX) && !defined (__APPLE__)
      53                 :            : static gboolean
      54                 :          1 : create_app (gpointer data)
      55                 :            : {
      56                 :          1 :   const gchar *path = data;
      57                 :          1 :   GError *error = NULL;
      58                 :          1 :   const gchar *contents = 
      59                 :            :     "[Desktop Entry]\n"
      60                 :            :     "Name=Application\n"
      61                 :            :     "Version=1.0\n"
      62                 :            :     "Type=Application\n"
      63                 :            :     "Exec=true\n";
      64                 :            : 
      65                 :          1 :   g_file_set_contents (path, contents, -1, &error);
      66                 :          1 :   g_assert_no_error (error);
      67                 :            : 
      68                 :          1 :   return G_SOURCE_REMOVE;
      69                 :            : }
      70                 :            : 
      71                 :            : static void
      72                 :          1 : delete_app (gpointer data)
      73                 :            : {
      74                 :          1 :   const gchar *path = data;
      75                 :            : 
      76                 :          1 :   g_remove (path);
      77                 :          1 : }
      78                 :            : 
      79                 :            : static void
      80                 :          2 : changed_cb (GAppInfoMonitor *monitor,
      81                 :            :             gpointer         user_data)
      82                 :            : {
      83                 :          2 :   gboolean *changed_fired = user_data;
      84                 :            : 
      85                 :          2 :   *changed_fired = TRUE;
      86                 :          2 :   g_main_context_wakeup (g_main_context_get_thread_default ());
      87                 :          2 : }
      88                 :            : 
      89                 :            : static gboolean
      90                 :          0 : timeout_cb (gpointer user_data)
      91                 :            : {
      92                 :          0 :   gboolean *timed_out = user_data;
      93                 :            : 
      94                 :          0 :   g_assert (!timed_out);
      95                 :          0 :   *timed_out = TRUE;
      96                 :          0 :   g_main_context_wakeup (g_main_context_get_thread_default ());
      97                 :            : 
      98                 :          0 :   return G_SOURCE_REMOVE;
      99                 :            : }
     100                 :            : #endif  /* defined (G_OS_UNIX) && !defined (__APPLE__) */
     101                 :            : 
     102                 :            : static void
     103                 :          1 : test_app_monitor (Fixture       *fixture,
     104                 :            :                   gconstpointer  user_data)
     105                 :            : {
     106                 :            : #if defined (G_OS_UNIX) && !defined (__APPLE__)
     107                 :            :   gchar *app_path;
     108                 :            :   GAppInfoMonitor *monitor;
     109                 :          1 :   GMainContext *context = NULL;  /* use the global default main context */
     110                 :          1 :   GSource *timeout_source = NULL;
     111                 :          1 :   GDesktopAppInfo *app = NULL;
     112                 :          1 :   gboolean changed_fired = FALSE;
     113                 :          1 :   gboolean timed_out = FALSE;
     114                 :            : 
     115                 :          1 :   app_path = g_build_filename (fixture->applications_dir, "app.desktop", NULL);
     116                 :            : 
     117                 :            :   /* FIXME: this shouldn't be required */
     118                 :          1 :   g_list_free_full (g_app_info_get_all (), g_object_unref);
     119                 :            : 
     120                 :            :   /* Create an app monitor and check that its ::changed signal is emitted when
     121                 :            :    * a new app is installed. */
     122                 :          1 :   monitor = g_app_info_monitor_get ();
     123                 :            : 
     124                 :          1 :   g_signal_connect (monitor, "changed", G_CALLBACK (changed_cb), &changed_fired);
     125                 :            : 
     126                 :          1 :   g_idle_add (create_app, app_path);
     127                 :          1 :   timeout_source = g_timeout_source_new_seconds (3);
     128                 :          1 :   g_source_set_callback (timeout_source, timeout_cb, &timed_out, NULL);
     129                 :          1 :   g_source_attach (timeout_source, NULL);
     130                 :            : 
     131   [ +  +  +  - ]:          3 :   while (!changed_fired && !timed_out)
     132                 :          2 :     g_main_context_iteration (context, TRUE);
     133                 :            : 
     134                 :          1 :   g_assert_true (changed_fired);
     135                 :          1 :   changed_fired = FALSE;
     136                 :            : 
     137                 :          1 :   g_source_destroy (timeout_source);
     138                 :          1 :   g_clear_pointer (&timeout_source, g_source_unref);
     139                 :            : 
     140                 :            :   /* Check that the app is now queryable. This has the side-effect of re-arming
     141                 :            :    * the #GAppInfoMonitor::changed signal for the next part of the test. */
     142                 :          1 :   app = g_desktop_app_info_new ("app.desktop");
     143                 :          1 :   g_assert_nonnull (app);
     144                 :          1 :   g_clear_object (&app);
     145                 :            : 
     146                 :            :   /* Now check that ::changed is emitted when an app is uninstalled. */
     147                 :          1 :   timeout_source = g_timeout_source_new_seconds (3);
     148                 :          1 :   g_source_set_callback (timeout_source, timeout_cb, &timed_out, NULL);
     149                 :          1 :   g_source_attach (timeout_source, NULL);
     150                 :            : 
     151                 :          1 :   delete_app (app_path);
     152                 :            : 
     153   [ +  +  +  - ]:          2 :   while (!changed_fired && !timed_out)
     154                 :          1 :     g_main_context_iteration (context, TRUE);
     155                 :            : 
     156                 :          1 :   g_assert_true (changed_fired);
     157                 :            : 
     158                 :          1 :   g_source_destroy (timeout_source);
     159                 :          1 :   g_clear_pointer (&timeout_source, g_source_unref);
     160                 :          1 :   g_remove (app_path);
     161                 :            : 
     162                 :          1 :   g_object_unref (monitor);
     163                 :            : 
     164                 :          1 :   g_free (app_path);
     165                 :            : #elif defined (__APPLE__)
     166                 :            :   g_test_skip (".desktop monitor on macos");
     167                 :            : #else  /* if !(defined (G_OS_UNIX) && !defined (__APPLE__)) */
     168                 :            :   g_test_skip (".desktop monitor on win32");
     169                 :            : #endif  /* !(defined (G_OS_UNIX) && !defined (__APPLE__)) */
     170                 :          1 : }
     171                 :            : 
     172                 :            : int
     173                 :          1 : main (int argc, char *argv[])
     174                 :            : {
     175                 :          1 :   g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
     176                 :            : 
     177                 :          1 :   g_test_add ("/monitor/app", Fixture, NULL, setup, test_app_monitor, teardown);
     178                 :            : 
     179                 :          1 :   return g_test_run ();
     180                 :            : }

Generated by: LCOV version 1.14