]> Pileus Git - ~andy/gtk/blob - tests/autotestfilechooser.c
bf654bccb518fc7bd4cf76f04d2875c23fa8826d
[~andy/gtk] / tests / autotestfilechooser.c
1 /* GTK - The GIMP Toolkit
2  * autotestfilechooser.c: Automated unit tests for the GtkFileChooser widget
3  * Copyright (C) 2005, Novell, Inc.
4  *
5  * Authors:
6  *   Federico Mena-Quintero <federico@novell.com>
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 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 Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /* TODO:
25  *
26  * - Use g_log_set_default_handler() instead of the mess of specific handlers we
27  *   have in main().
28  *
29  * - In test_reload_sequence(), test that the selection is preserved properly
30  *   between unmap/map.
31  *
32  * - More tests!
33  */
34
35 #define GTK_FILE_SYSTEM_ENABLE_UNSUPPORTED
36
37 #include <config.h>
38 #include <string.h>
39 #include <glib/gprintf.h>
40 #include <gtk/gtk.h>
41 #include "gtk/gtkfilechooserprivate.h"
42 #include "gtk/gtkfilechooserdefault.h"
43 #include "gtk/gtkfilechooserentry.h"
44
45 static void
46 log_test (gboolean passed, const char *test_name, ...)
47 {
48   va_list args;
49   char *str;
50
51   va_start (args, test_name);
52   str = g_strdup_vprintf (test_name, args);
53   va_end (args);
54
55   g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str);
56   g_free (str);
57 }
58
59 static const GtkFileChooserAction open_actions[] = {
60   GTK_FILE_CHOOSER_ACTION_OPEN,
61   GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
62 };
63
64 static const GtkFileChooserAction save_actions[] = {
65   GTK_FILE_CHOOSER_ACTION_SAVE,
66   GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
67 };
68
69
70 static gboolean
71 has_action (const GtkFileChooserAction *actions,
72             int n_actions,
73             GtkFileChooserAction sought_action)
74 {
75   int i;
76
77   for (i = 0; i < n_actions; i++)
78     if (actions[i] == sought_action)
79       return TRUE;
80
81   return FALSE;
82 }
83
84 static const char *
85 get_action_name (GtkFileChooserAction action)
86 {
87   GEnumClass *enum_class;
88   GEnumValue *enum_value;
89
90   enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION);
91   if (!enum_class)
92     g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION");
93
94   enum_value = g_enum_get_value (enum_class, (int) action);
95   if (!enum_value)
96     g_error ("BUG: get_action_name(): no GEnumValue for GtkFileChooserAction %d", (int) action);
97
98   return enum_value->value_name;
99 }
100
101 static GtkFileChooserDefault *
102 get_impl_from_dialog (GtkWidget *dialog)
103 {
104   GtkFileChooserDialog *d;
105   GtkFileChooserDialogPrivate *dialog_priv;
106   GtkFileChooserWidget *chooser_widget;
107   GtkFileChooserWidgetPrivate *widget_priv;
108   GtkFileChooserDefault *impl;
109
110   d = GTK_FILE_CHOOSER_DIALOG (dialog);
111   dialog_priv = d->priv;
112   chooser_widget = GTK_FILE_CHOOSER_WIDGET (dialog_priv->widget);
113   if (!chooser_widget)
114     g_error ("BUG: dialog_priv->widget is not a GtkFileChooserWidget");
115
116   widget_priv = chooser_widget->priv;
117   impl = (GtkFileChooserDefault *) (widget_priv->impl);
118   if (!impl)
119     g_error ("BUG: widget_priv->impl is not a GtkFileChooserDefault");
120
121   return impl;
122 }
123
124 static gboolean
125 test_widgets_for_current_action (GtkFileChooserDialog *dialog,
126                                  GtkFileChooserAction  expected_action)
127 {
128   GtkFileChooserDefault *impl;
129   gboolean passed;
130
131   if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) != expected_action)
132     return FALSE;
133
134   impl = get_impl_from_dialog (GTK_WIDGET (dialog));
135
136   g_assert (impl->action == expected_action);
137
138   passed = TRUE;
139
140   /* OPEN implies that the "new folder" button is hidden; otherwise it is shown */
141   if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
142     passed = passed && !GTK_WIDGET_VISIBLE (impl->browse_new_folder_button);
143   else
144     passed = passed && GTK_WIDGET_VISIBLE (impl->browse_new_folder_button);
145
146   /* Check that the widgets are present/visible or not */
147   if (has_action (open_actions, G_N_ELEMENTS (open_actions), impl->action))
148     {
149       passed = passed && (impl->save_widgets == NULL
150                           && (impl->location_mode == LOCATION_MODE_PATH_BAR
151                               ? impl->location_entry == NULL
152                               : impl->location_entry != NULL)
153                           && impl->save_folder_label == NULL
154                           && impl->save_folder_combo == NULL
155                           && impl->save_expander == NULL
156                           && GTK_IS_CONTAINER (impl->browse_widgets) && GTK_WIDGET_DRAWABLE (impl->browse_widgets));
157     }
158   else if (has_action (save_actions, G_N_ELEMENTS (save_actions), impl->action))
159     {
160       /* FIXME: we can't use GTK_IS_FILE_CHOOSER_ENTRY() because it uses
161        * _gtk_file_chooser_entry_get_type(), which is a non-exported symbol.
162        * So, we just test impl->location_entry for being non-NULL
163        */
164       passed = passed && (GTK_IS_CONTAINER (impl->save_widgets) && GTK_WIDGET_DRAWABLE (impl->save_widgets)
165                           && impl->location_entry != NULL && GTK_WIDGET_DRAWABLE (impl->location_entry)
166                           && GTK_IS_LABEL (impl->save_folder_label) && GTK_WIDGET_DRAWABLE (impl->save_folder_label)
167                           && GTK_IS_COMBO_BOX (impl->save_folder_combo) && GTK_WIDGET_DRAWABLE (impl->save_folder_combo)
168                           && GTK_IS_EXPANDER (impl->save_expander) && GTK_WIDGET_DRAWABLE (impl->save_expander)
169                           && GTK_IS_CONTAINER (impl->browse_widgets));
170
171       /* FIXME: we are in a SAVE mode; test the visibility and sensitivity of
172        * the children that change depending on the state of the expander.
173        */
174     }
175   else
176     {
177       g_error ("BAD TEST: test_widgets_for_current_action() doesn't know about %s", get_action_name (impl->action));
178       passed = FALSE;
179     }
180
181   return passed;
182 }
183
184 typedef gboolean (* ForeachActionCallback) (GtkFileChooserDialog *dialog,
185                                             GtkFileChooserAction  action,
186                                             gpointer              user_data);
187
188 static gboolean
189 foreach_action (GtkFileChooserDialog *dialog,
190                 ForeachActionCallback callback,
191                 gpointer              user_data)
192 {
193   GEnumClass *enum_class;
194   int i;
195
196   enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION);
197   if (!enum_class)
198     g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION");
199
200   for (i = 0; i < enum_class->n_values; i++)
201     {
202       GEnumValue *enum_value;
203       GtkFileChooserAction action;
204       gboolean passed;
205
206       enum_value = enum_class->values + i;
207       action = enum_value->value;
208
209       passed = (* callback) (dialog, action, user_data);
210       if (!passed)
211         return FALSE;
212     }
213
214   return TRUE;
215 }
216
217 struct action_closure {
218   GtkFileChooserAction from_action;
219 };
220
221 static gboolean
222 switch_from_to_action_cb (GtkFileChooserDialog *dialog,
223                           GtkFileChooserAction  action,
224                           gpointer              user_data)
225 {
226   struct action_closure *closure;
227   gboolean passed;
228
229   closure = user_data;
230
231   gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), closure->from_action);
232
233   passed = test_widgets_for_current_action (dialog, closure->from_action);
234   log_test (passed, "switch_from_to_action_cb(): reset to action %s", get_action_name (closure->from_action));
235   if (!passed)
236     return FALSE;
237
238   gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), action);
239
240   passed = test_widgets_for_current_action (dialog, action);
241   log_test (passed, "switch_from_to_action_cb(): transition from %s to %s",
242             get_action_name (closure->from_action),
243             get_action_name (action));
244   return passed;
245 }
246
247 static gboolean
248 switch_from_action_cb (GtkFileChooserDialog *dialog,
249                        GtkFileChooserAction  action,
250                        gpointer              user_data)
251 {
252   struct action_closure closure;
253
254   closure.from_action = action;
255
256   return foreach_action (dialog, switch_from_to_action_cb, &closure);
257 }
258
259 static gboolean
260 test_action_widgets (void)
261 {
262   GtkWidget *dialog;
263   GtkFileChooserAction action;
264   gboolean passed;
265
266   dialog = gtk_file_chooser_dialog_new ("Test file chooser",
267                                         NULL,
268                                         GTK_FILE_CHOOSER_ACTION_OPEN,
269                                         GTK_STOCK_CANCEL,
270                                         GTK_RESPONSE_CANCEL,
271                                         GTK_STOCK_OK,
272                                         GTK_RESPONSE_ACCEPT,
273                                         NULL);
274   gtk_widget_show_now (dialog);
275
276   action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog));
277
278   passed = test_widgets_for_current_action (GTK_FILE_CHOOSER_DIALOG (dialog), action);
279   log_test (passed, "test_action_widgets(): widgets for initial action %s", get_action_name (action));
280   if (!passed)
281     return FALSE;
282
283   passed = foreach_action (GTK_FILE_CHOOSER_DIALOG (dialog), switch_from_action_cb, NULL);
284   log_test (passed, "test_action_widgets(): all transitions through property change");
285
286   gtk_widget_destroy (dialog);
287
288   return passed;
289 }
290
291 static gboolean
292 test_reload_sequence (gboolean set_folder_before_map)
293 {
294   GtkWidget *dialog;
295   GtkFileChooserDefault *impl;
296   gboolean passed;
297   char *folder;
298   char *current_working_dir;
299
300   passed = TRUE;
301
302   current_working_dir = g_get_current_dir ();
303
304   dialog = gtk_file_chooser_dialog_new ("Test file chooser",
305                                         NULL,
306                                         GTK_FILE_CHOOSER_ACTION_OPEN,
307                                         GTK_STOCK_CANCEL,
308                                         GTK_RESPONSE_CANCEL,
309                                         GTK_STOCK_OK,
310                                         GTK_RESPONSE_ACCEPT,
311                                         NULL);
312   impl = get_impl_from_dialog (dialog);
313
314   if (set_folder_before_map)
315     {
316       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
317
318       passed = passed && (impl->current_folder != NULL
319                           && impl->browse_files_model != NULL
320                           && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
321                           && impl->reload_state == RELOAD_HAS_FOLDER
322                           && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
323                           && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
324                               ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
325                               : TRUE));
326
327       folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
328       passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
329       g_free (folder);
330     }
331   else
332     {
333       /* Initially, no folder is not loaded or pending */
334       passed = passed && (impl->current_folder == NULL
335                           && impl->sort_model == NULL
336                           && impl->browse_files_model == NULL
337                           && impl->load_state == LOAD_EMPTY
338                           && impl->reload_state == RELOAD_EMPTY
339                           && impl->load_timeout_id == 0);
340
341       folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
342       passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
343     }
344
345   log_test (passed, "test_reload_sequence(): initial status");
346
347   /* After mapping, it is loading some folder, either the one that was explicitly set or the default one */
348
349   gtk_widget_show_now (dialog);
350
351   passed = passed && (impl->current_folder != NULL
352                       && impl->browse_files_model != NULL
353                       && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
354                       && impl->reload_state == RELOAD_HAS_FOLDER
355                       && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
356                       && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
357                           ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
358                           : TRUE));
359
360   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
361   if (set_folder_before_map)
362     passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
363   else
364     passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
365
366   g_free (folder);
367
368   log_test (passed, "test_reload_sequence(): status after map");
369
370   /* Unmap it; we should still have a folder */
371
372   gtk_widget_hide (dialog);
373
374   passed = passed && (impl->current_folder != NULL
375                       && impl->browse_files_model != NULL
376                       && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
377                       && impl->reload_state == RELOAD_WAS_UNMAPPED
378                       && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
379                       && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
380                           ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
381                           : TRUE));
382
383   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
384   if (set_folder_before_map)
385     passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
386   else
387     passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
388
389   g_free (folder);
390
391   log_test (passed, "test_reload_sequence(): status after unmap");
392
393   /* Map it again! */
394
395   gtk_widget_show_now (dialog);
396
397   passed = passed && (impl->current_folder != NULL
398                       && impl->browse_files_model != NULL
399                       && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
400                       && impl->reload_state == RELOAD_HAS_FOLDER
401                       && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
402                       && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
403                           ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
404                           : TRUE));
405
406   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
407   if (set_folder_before_map)
408     passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
409   else
410     passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
411
412   g_free (folder);
413
414   log_test (passed, "test_reload_sequence(): status after re-map");
415
416   gtk_widget_destroy (dialog);
417   g_free (current_working_dir);
418
419   return passed;
420 }
421
422 static gboolean
423 test_reload (void)
424 {
425   gboolean passed;
426
427   passed = test_reload_sequence (FALSE);
428   log_test (passed, "test_reload(): create and use the default folder");
429   if (!passed)
430     return FALSE;
431
432   passed = test_reload_sequence (TRUE);
433   log_test (passed, "test_reload(): set a folder explicitly before mapping");
434
435   return passed;
436 }
437
438 static gboolean
439 test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_dialog, gboolean set_folder_on_dialog)
440 {
441   gboolean passed;
442   GtkWidget *window;
443   GtkWidget *button;
444   char *folder;
445   GtkWidget *dialog;
446   char *current_working_dir;
447   gboolean must_have_cwd;
448
449   passed = TRUE;
450
451   current_working_dir = g_get_current_dir ();
452   must_have_cwd = !(use_dialog && set_folder_on_dialog);
453
454   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
455
456   if (use_dialog)
457     {
458       dialog = gtk_file_chooser_dialog_new ("Test", NULL, action,
459                                             GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
460                                             GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
461                                             NULL);
462       button = gtk_file_chooser_button_new_with_dialog (dialog);
463
464       if (set_folder_on_dialog)
465         gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
466     }
467   else
468     {
469       button = gtk_file_chooser_button_new ("Test", action);
470       dialog = NULL; /* keep gcc happy */
471     }
472
473   gtk_container_add (GTK_CONTAINER (window), button);
474
475   /* Pre-map; no folder is set */
476
477   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
478   if (must_have_cwd)
479     passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
480   else
481     passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
482
483   log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, pre-map, %s",
484             get_action_name (action),
485             use_dialog,
486             set_folder_on_dialog,
487             must_have_cwd ? "must have $cwd" : "must have explicit folder");
488
489   /* Map; folder should be set */
490
491   gtk_widget_show_all (window);
492   gtk_widget_show_now (window);
493   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
494
495   if (must_have_cwd)
496     passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
497   else
498     passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
499
500   log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, mapped, %s",
501             get_action_name (action),
502             use_dialog,
503             set_folder_on_dialog,
504             must_have_cwd ? "must have $cwd" : "must have explicit folder");
505   g_free (folder);
506
507   /* Unmap; folder should be set */
508
509   gtk_widget_hide (window);
510   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
511
512   if (must_have_cwd)
513     passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
514   else
515     passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
516
517   log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, unmapped, %s",
518             get_action_name (action),
519             use_dialog,
520             set_folder_on_dialog,
521             must_have_cwd ? "must have $cwd" : "must have explicit folder");
522   g_free (folder);
523
524   /* Re-map; folder should be set */
525
526   gtk_widget_show_now (window);
527   folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
528
529   if (must_have_cwd)
530     passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
531   else
532     passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
533
534   log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, re-mapped, %s",
535             get_action_name (action),
536             use_dialog,
537             set_folder_on_dialog,
538             must_have_cwd ? "must have $cwd" : "must have explicit folder");
539   g_free (folder);
540
541   g_free (current_working_dir);
542
543   gtk_widget_destroy (window);
544
545   return passed;
546 }
547
548 static gboolean
549 test_button_folder_states (void)
550 {
551   /* GtkFileChooserButton only supports OPEN and SELECT_FOLDER */
552   static const GtkFileChooserAction actions_to_test[] = {
553     GTK_FILE_CHOOSER_ACTION_OPEN,
554     GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
555   };
556   gboolean passed;
557   int i;
558
559   passed = TRUE;
560
561   for (i = 0; i < G_N_ELEMENTS (actions_to_test); i++)
562     {
563       passed = passed && test_button_folder_states_for_action (actions_to_test[i], FALSE, FALSE);
564       passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, FALSE);
565       passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, TRUE);
566       log_test (passed, "test_button_folder_states(): action %s", get_action_name (actions_to_test[i]));
567     }
568
569   log_test (passed, "test_button_folder_states(): all supported actions");
570   return passed;
571 }
572
573 static gboolean
574 sleep_timeout_cb (gpointer data)
575 {
576   gtk_main_quit ();
577   return FALSE;
578 }
579
580 static void
581 sleep_in_main_loop (int milliseconds)
582 {
583   g_timeout_add (milliseconds, sleep_timeout_cb, NULL);
584   gtk_main ();
585 }
586
587 static gboolean
588 test_folder_switch_and_filters (void)
589 {
590   gboolean passed;
591   char *cwd;
592   char *base_dir;
593   GtkFilePath *cwd_path;
594   GtkFilePath *base_dir_path;
595   GtkWidget *dialog;
596   GtkFileFilter *all_filter;
597   GtkFileFilter *txt_filter;
598   GtkFileChooserDefault *impl;
599
600   passed = TRUE;
601
602   cwd = g_get_current_dir ();
603   base_dir = g_build_filename (cwd, "file-chooser-test-dir", NULL);
604
605   dialog = gtk_file_chooser_dialog_new ("Test", NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
606                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
607                                         GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
608                                         NULL);
609   impl = get_impl_from_dialog (dialog);
610
611   cwd_path = gtk_file_system_filename_to_path (impl->file_system, cwd);
612   base_dir_path = gtk_file_system_filename_to_path (impl->file_system, base_dir);
613
614   passed = passed && gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
615   if (!passed)
616     goto out;
617
618   /* All files filter */
619
620   all_filter = gtk_file_filter_new ();
621   gtk_file_filter_set_name (all_filter, "All files");
622   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_filter);
623
624   /* *.txt filter */
625
626   txt_filter = gtk_file_filter_new ();
627   gtk_file_filter_set_name (all_filter, "*.txt");
628   gtk_file_filter_add_pattern (txt_filter, "*.txt");
629   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
630
631   /* Test filter set */
632
633   gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all_filter);
634   passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == all_filter);
635
636   gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
637   passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
638
639   log_test (passed, "test_folder_switch_and_filters(): set and get filter");
640
641   gtk_widget_show (dialog);
642
643   /* Test that filter is unchanged when we switch folders */
644
645   gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd);
646   sleep_in_main_loop (1000);
647   passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
648
649   gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
650   sleep_in_main_loop (500);
651
652   g_signal_emit_by_name (impl->browse_path_bar, "path-clicked",
653                          (GtkFilePath *) cwd_path,
654                          (GtkFilePath *) base_dir_path,
655                          FALSE);
656   sleep_in_main_loop (500);
657   passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
658
659   log_test (passed, "test_folder_switch_and_filters(): filter after changing folder");
660
661  out:
662   g_free (cwd);
663   g_free (base_dir);
664   gtk_file_path_free (cwd_path);
665   gtk_file_path_free (base_dir_path);
666
667   gtk_widget_destroy (dialog);
668
669   log_test (passed, "test_folder_switch_and_filters(): all filter tests");
670   return passed;
671 }
672
673 static GLogFunc default_log_handler;
674 static int num_warnings;
675 static int num_errors;
676 static int num_critical_errors;
677
678 static void
679 log_override_cb (const gchar   *log_domain,
680                  GLogLevelFlags log_level,
681                  const gchar   *message,
682                  gpointer       user_data)
683 {
684   if (log_level & G_LOG_LEVEL_WARNING)
685     num_warnings++;
686
687   if (log_level & G_LOG_LEVEL_ERROR)
688     num_errors++;
689
690   if (log_level & G_LOG_LEVEL_CRITICAL)
691     num_critical_errors++;
692
693   (* default_log_handler) (log_domain, log_level, message, user_data);
694 }
695
696 int
697 main (int argc, char **argv)
698 {
699   gboolean passed;
700   gboolean zero_warnings;
701   gboolean zero_errors;
702   gboolean zero_critical_errors;
703
704   default_log_handler = g_log_set_default_handler (log_override_cb, NULL);
705   passed = TRUE;
706
707   gtk_init (&argc, &argv);
708
709   /* Start tests */
710   passed = passed && test_action_widgets ();
711   passed = passed && test_reload ();
712   passed = passed && test_button_folder_states ();
713   passed = passed && test_folder_switch_and_filters ();
714   log_test (passed, "main(): main tests");
715
716   /* Warnings and errors */
717
718   zero_warnings = num_warnings == 0;
719   zero_errors = num_errors == 0;
720   zero_critical_errors = num_critical_errors == 0;
721
722   log_test (zero_warnings, "main(): zero warnings (actual number %d)", num_warnings);
723   log_test (zero_errors, "main(): zero errors (actual number %d)", num_errors);
724   log_test (zero_critical_errors, "main(): zero critical errors (actual number %d)", num_critical_errors);
725
726   /* Done */
727
728   passed = passed && zero_warnings && zero_errors && zero_critical_errors;
729
730   log_test (passed, "main(): ALL TESTS");
731
732   return 0;
733 }