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