1 /* GTK - The GIMP Toolkit
2  * gtkrecentmanager.c: a manager for the recently used resources
3  *
4  * Copyright (C) 2006 Emmanuele Bassi
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <glib/gstdio.h>
21 #include <gtk/gtk.h>
22 
23 const char *uri = "file:///tmp/testrecentchooser.txt";
24 const char *uri2 = "file:///tmp/testrecentchooser2.txt";
25 
26 static void
recent_manager_get_default(void)27 recent_manager_get_default (void)
28 {
29   GtkRecentManager *manager;
30   GtkRecentManager *manager2;
31 
32   manager = gtk_recent_manager_get_default ();
33   g_assert_nonnull (manager);
34 
35   manager2 = gtk_recent_manager_get_default ();
36   g_assert_true (manager == manager2);
37 }
38 
39 static void
recent_manager_add(void)40 recent_manager_add (void)
41 {
42   GtkRecentManager *manager;
43   GtkRecentData *recent_data;
44   gboolean res;
45 
46   manager = gtk_recent_manager_get_default ();
47 
48   recent_data = g_slice_new0 (GtkRecentData);
49 
50   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
51 
52   /* mime type is mandatory */
53   recent_data->mime_type = NULL;
54   recent_data->app_name = (char *)"testrecentchooser";
55   recent_data->app_exec = (char *)"testrecentchooser %u";
56   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
57     {
58       res = gtk_recent_manager_add_full (manager,
59                                          uri,
60                                          recent_data);
61     }
62   g_test_trap_assert_failed ();
63 
64   /* app name is mandatory */
65   recent_data->mime_type = (char *)"text/plain";
66   recent_data->app_name = NULL;
67   recent_data->app_exec = (char *)"testrecentchooser %u";
68   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
69     {
70       res = gtk_recent_manager_add_full (manager,
71                                          uri,
72                                          recent_data);
73     }
74   g_test_trap_assert_failed ();
75 
76   /* app exec is mandatory */
77   recent_data->mime_type = (char *)"text/plain";
78   recent_data->app_name = (char *)"testrecentchooser";
79   recent_data->app_exec = NULL;
80   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
81     {
82       res = gtk_recent_manager_add_full (manager,
83                                          uri,
84                                          recent_data);
85     }
86   g_test_trap_assert_failed ();
87 
88   G_GNUC_END_IGNORE_DEPRECATIONS;
89 
90   recent_data->mime_type = (char *)"text/plain";
91   recent_data->app_name = (char *)"testrecentchooser";
92   recent_data->app_exec = (char *)"testrecentchooser %u";
93   res = gtk_recent_manager_add_full (manager,
94                                      uri,
95                                      recent_data);
96   g_assert_true (res);
97 
98   g_slice_free (GtkRecentData, recent_data);
99 }
100 
101 typedef struct {
102   GtkRecentManager *manager;
103   GMainLoop *main_loop;
104   int counter;
105 } AddManyClosure;
106 
107 static void
check_bulk(GtkRecentManager * manager,gpointer data)108 check_bulk (GtkRecentManager *manager,
109             gpointer          data)
110 {
111   AddManyClosure *closure = data;
112 
113   if (g_test_verbose ())
114     g_print (G_STRLOC ": counter = %d\n", closure->counter);
115 
116   g_assert_cmpint (closure->counter, ==, 100);
117 
118   if (g_main_loop_is_running (closure->main_loop))
119     g_main_loop_quit (closure->main_loop);
120 }
121 
122 static gboolean
add_bulk(gpointer data_)123 add_bulk (gpointer data_)
124 {
125   AddManyClosure *closure = data_;
126   GtkRecentData *data = g_slice_new0 (GtkRecentData);
127   int i;
128 
129   for (i = 0; i < 100; i++)
130     {
131       char *new_uri;
132 
133       data->mime_type = (char *)"text/plain";
134       data->app_name = (char *)"testrecentchooser";
135       data->app_exec = (char *)"testrecentchooser %u";
136 
137       if (g_test_verbose ())
138         g_print (G_STRLOC ": adding item %d\n", i);
139 
140       new_uri = g_strdup_printf ("file:///doesnotexist-%d.txt", i);
141       gtk_recent_manager_add_full (closure->manager, new_uri, data);
142       g_free (new_uri);
143 
144       closure->counter += 1;
145     }
146 
147   g_slice_free (GtkRecentData, data);
148 
149   return G_SOURCE_REMOVE;
150 }
151 
152 static void
recent_manager_add_many(void)153 recent_manager_add_many (void)
154 {
155   GtkRecentManager *manager = g_object_new (GTK_TYPE_RECENT_MANAGER,
156                                             "filename", "recently-used.xbel",
157                                             NULL);
158   AddManyClosure *closure = g_new (AddManyClosure, 1);
159 
160   closure->main_loop = g_main_loop_new (NULL, FALSE);
161   closure->counter = 0;
162   closure->manager = manager;
163 
164   g_signal_connect (manager, "changed", G_CALLBACK (check_bulk), closure);
165 
166   g_idle_add (add_bulk, closure);
167 
168   g_main_loop_run (closure->main_loop);
169 
170   g_main_loop_unref (closure->main_loop);
171   g_object_unref (closure->manager);
172   g_free (closure);
173 
174   g_assert_cmpint (g_unlink ("recently-used.xbel"), ==, 0);
175 }
176 
177 static void
recent_manager_has_item(void)178 recent_manager_has_item (void)
179 {
180   GtkRecentManager *manager;
181   gboolean res;
182 
183   manager = gtk_recent_manager_get_default ();
184 
185   res = gtk_recent_manager_has_item (manager, "file:///tmp/testrecentdoesnotexist.txt");
186   g_assert_false (res);
187 
188   res = gtk_recent_manager_has_item (manager, uri);
189   g_assert_true (res);
190 }
191 
192 static void
recent_manager_move_item(void)193 recent_manager_move_item (void)
194 {
195   GtkRecentManager *manager;
196   gboolean res;
197   GError *error;
198 
199   manager = gtk_recent_manager_get_default ();
200 
201   error = NULL;
202   res = gtk_recent_manager_move_item (manager,
203                                       "file:///tmp/testrecentdoesnotexist.txt",
204                                       uri2,
205                                       &error);
206   g_assert_false (res);
207   g_assert_error (error, GTK_RECENT_MANAGER_ERROR, GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
208   g_error_free (error);
209 
210   error = NULL;
211   res = gtk_recent_manager_move_item (manager, uri, uri2, &error);
212   g_assert_true (res);
213   g_assert_null (error);
214 
215   res = gtk_recent_manager_has_item (manager, uri);
216   g_assert_false (res);
217 
218   res = gtk_recent_manager_has_item (manager, uri2);
219   g_assert_true (res);
220 }
221 
222 static void
recent_manager_lookup_item(void)223 recent_manager_lookup_item (void)
224 {
225   GtkRecentManager *manager;
226   GtkRecentInfo *info;
227   GError *error;
228 
229   manager = gtk_recent_manager_get_default ();
230 
231   error = NULL;
232   info = gtk_recent_manager_lookup_item (manager,
233                                          "file:///tmp/testrecentdoesnotexist.txt",
234                                          &error);
235   g_assert_null (info);
236   g_assert_error (error, GTK_RECENT_MANAGER_ERROR, GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
237   g_error_free (error);
238 
239   error = NULL;
240   info = gtk_recent_manager_lookup_item (manager, uri2, &error);
241   g_assert_nonnull (info);
242   g_assert_null (error);
243 
244   g_assert_true (gtk_recent_info_has_application (info, "testrecentchooser"));
245 
246   gtk_recent_info_unref (info);
247 }
248 
249 static void
recent_manager_remove_item(void)250 recent_manager_remove_item (void)
251 {
252   GtkRecentManager *manager;
253   gboolean res;
254   GError *error;
255 
256   manager = gtk_recent_manager_get_default ();
257 
258   error = NULL;
259   res = gtk_recent_manager_remove_item (manager,
260                                         "file:///tmp/testrecentdoesnotexist.txt",
261                                         &error);
262   g_assert_false (res);
263   g_assert_error (error, GTK_RECENT_MANAGER_ERROR, GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
264   g_error_free (error);
265 
266   /* remove an item that's actually there */
267   error = NULL;
268   res = gtk_recent_manager_remove_item (manager, uri2, &error);
269   g_assert_true (res);
270   g_assert_null (error);
271 
272   res = gtk_recent_manager_has_item (manager, uri2);
273   g_assert_false (res);
274 }
275 
276 static void
recent_manager_purge(void)277 recent_manager_purge (void)
278 {
279   GtkRecentManager *manager;
280   GtkRecentData *recent_data;
281   int n;
282   GError *error;
283 
284   manager = gtk_recent_manager_get_default ();
285 
286   /* purge, add 1, purge again and check that 1 item has been purged */
287   error = NULL;
288   n = gtk_recent_manager_purge_items (manager, &error);
289   g_assert_null (error);
290 
291   recent_data = g_slice_new0 (GtkRecentData);
292   recent_data->mime_type = (char *)"text/plain";
293   recent_data->app_name = (char *)"testrecentchooser";
294   recent_data->app_exec = (char *)"testrecentchooser %u";
295   gtk_recent_manager_add_full (manager, uri, recent_data);
296   g_slice_free (GtkRecentData, recent_data);
297 
298   error = NULL;
299   n = gtk_recent_manager_purge_items (manager, &error);
300   g_assert_null (error);
301   g_assert_cmpint (n, ==, 1);
302 }
303 
304 int
main(int argc,char ** argv)305 main (int    argc,
306       char **argv)
307 {
308   gtk_test_init (&argc, &argv, NULL);
309 
310   g_test_add_func ("/recent-manager/get-default", recent_manager_get_default);
311   g_test_add_func ("/recent-manager/add", recent_manager_add);
312   g_test_add_func ("/recent-manager/add-many", recent_manager_add_many);
313   g_test_add_func ("/recent-manager/has-item", recent_manager_has_item);
314   g_test_add_func ("/recent-manager/move-item", recent_manager_move_item);
315   g_test_add_func ("/recent-manager/lookup-item", recent_manager_lookup_item);
316   g_test_add_func ("/recent-manager/remove-item", recent_manager_remove_item);
317   g_test_add_func ("/recent-manager/purge", recent_manager_purge);
318 
319   return g_test_run ();
320 }
321