1 /* GTK - The GIMP Toolkit
2 * autotestfilechooser.c: Automated unit tests for the GtkFileChooser widget
3 * Copyright (C) 2005, Novell, Inc.
6 * Federico Mena-Quintero <federico@novell.com>
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.
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.
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.
26 * - In test_reload_sequence(), test that the selection is preserved properly
32 #define GTK_FILE_SYSTEM_ENABLE_UNSUPPORTED
36 #include <glib/gprintf.h>
38 #include "gtk/gtkfilechooserprivate.h"
39 #include "gtk/gtkfilechooserdefault.h"
40 #include "gtk/gtkfilechooserentry.h"
43 log_test (gboolean passed, const char *test_name, ...)
48 va_start (args, test_name);
49 str = g_strdup_vprintf (test_name, args);
52 g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str);
56 typedef void (* SetFilenameFn) (GtkFileChooser *chooser, gpointer data);
57 typedef gboolean (* CompareFilenameFn) (GtkFileChooser *chooser, gpointer data);
59 struct test_set_filename_closure {
61 GtkWidget *accept_button;
62 gboolean focus_button;
66 set_filename_timeout_cb (gpointer data)
68 struct test_set_filename_closure *closure;
72 if (closure->focus_button)
73 gtk_widget_grab_focus (closure->accept_button);
75 gtk_button_clicked (GTK_BUTTON (closure->accept_button));
81 static guint wait_for_idle_id = 0;
84 wait_for_idle_idle (gpointer data)
94 wait_for_idle_id = g_idle_add_full (G_PRIORITY_LOW + 100,
98 while (wait_for_idle_id)
99 gtk_main_iteration ();
103 test_set_filename (GtkFileChooserAction action,
104 gboolean focus_button,
105 SetFilenameFn set_filename_fn,const
106 CompareFilenameFn compare_filename_fn,
110 struct test_set_filename_closure closure;
113 chooser = gtk_file_chooser_dialog_new ("hello", NULL, action,
114 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
117 closure.chooser = chooser;
118 closure.accept_button = gtk_dialog_add_button (GTK_DIALOG (chooser), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
119 closure.focus_button = focus_button;
121 gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
123 (* set_filename_fn) (GTK_FILE_CHOOSER (chooser), data);
125 gdk_threads_add_timeout (2000, set_filename_timeout_cb, &closure);
126 gtk_dialog_run (GTK_DIALOG (chooser));
128 retval = (* compare_filename_fn) (GTK_FILE_CHOOSER (chooser), data);
130 gtk_widget_destroy (chooser);
136 set_filename_cb (GtkFileChooser *chooser, gpointer data)
138 const char *filename;
141 gtk_file_chooser_set_filename (chooser, filename);
145 compare_filename_cb (GtkFileChooser *chooser, gpointer data)
147 const char *filename;
152 out_filename = gtk_file_chooser_get_filename (chooser);
156 retval = (strcmp (out_filename, filename) == 0);
157 g_free (out_filename);
165 test_black_box_set_filename (GtkFileChooserAction action, const char *filename, gboolean focus_button)
169 passed = test_set_filename (action, focus_button, set_filename_cb, compare_filename_cb, (char *) filename);
171 log_test (passed, "set_filename: action %d, focus_button=%s",
173 focus_button ? "TRUE" : "FALSE");
179 struct current_name_closure {
181 const char *current_name;
185 set_current_name_cb (GtkFileChooser *chooser, gpointer data)
187 struct current_name_closure *closure;
191 gtk_file_chooser_set_current_folder (chooser, closure->path);
192 gtk_file_chooser_set_current_name (chooser, closure->current_name);
196 compare_current_name_cb (GtkFileChooser *chooser, gpointer data)
198 struct current_name_closure *closure;
204 out_filename = gtk_file_chooser_get_filename (chooser);
210 filename = g_build_filename (closure->path, closure->current_name, NULL);
211 retval = (strcmp (filename, out_filename) == 0);
213 g_free (out_filename);
221 test_black_box_set_current_name (const char *path, const char *current_name, gboolean focus_button)
223 struct current_name_closure closure;
227 closure.current_name = current_name;
229 passed = test_set_filename (GTK_FILE_CHOOSER_ACTION_SAVE, focus_button,
230 set_current_name_cb, compare_current_name_cb, &closure);
232 log_test (passed, "set_current_name, focus_button=%s", focus_button ? "TRUE" : "FALSE");
237 /* FIXME: fails in CREATE_FOLDER mode when FOLDER_NAME == "/" */
240 #define FILE_NAME "/nonexistent"
241 #define FOLDER_NAME "/etc"
243 #define FILE_NAME "/etc/passwd"
244 #define FOLDER_NAME "/etc"
247 #define CURRENT_NAME "parangaricutirimicuaro.txt"
249 /* https://bugzilla.novell.com/show_bug.cgi?id=184875
250 * http://bugzilla.gnome.org/show_bug.cgi?id=347066
253 test_black_box (void)
260 passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_OPEN, FILE_NAME, FALSE);
261 passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_OPEN, FILE_NAME, TRUE);
262 passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_SAVE, FILE_NAME, FALSE);
263 passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_SAVE, FILE_NAME, TRUE);
264 passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FOLDER_NAME, FALSE);
265 passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FOLDER_NAME, TRUE);
266 passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, FOLDER_NAME, FALSE);
267 passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, FOLDER_NAME, TRUE);
269 cwd = g_get_current_dir ();
271 passed = passed && test_black_box_set_current_name (cwd, CURRENT_NAME, FALSE);
272 passed = passed && test_black_box_set_current_name (cwd, CURRENT_NAME, TRUE);
276 log_test (passed, "Black box tests");
281 struct confirm_overwrite_closure {
283 GtkWidget *accept_button;
284 gint confirm_overwrite_signal_emitted;
288 static GtkFileChooserConfirmation
289 confirm_overwrite_cb (GtkFileChooser *chooser, gpointer data)
291 struct confirm_overwrite_closure *closure = data;
294 closure->confirm_overwrite_signal_emitted += 1;
296 return GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME;
300 overwrite_response_cb (GtkFileChooser *chooser, gint response, gpointer data)
302 struct confirm_overwrite_closure *closure = data;
307 if (response != GTK_RESPONSE_ACCEPT)
310 filename = gtk_file_chooser_get_filename (chooser);
312 if (!g_str_has_suffix (filename, closure->extension))
316 basename = g_path_get_basename (filename);
319 filename = g_strconcat (basename, closure->extension, NULL);
320 gtk_file_chooser_set_current_name (chooser, filename);
322 g_signal_stop_emission_by_name (chooser, "response");
323 gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
328 confirm_overwrite_timeout_cb (gpointer data)
330 struct confirm_overwrite_closure *closure;
333 gtk_button_clicked (GTK_BUTTON (closure->accept_button));
338 /* http://bugzilla.gnome.org/show_bug.cgi?id=347883 */
340 test_confirm_overwrite_for_path (const char *path, gboolean append_extension)
343 struct confirm_overwrite_closure closure;
348 closure.extension = NULL;
349 closure.confirm_overwrite_signal_emitted = 0;
350 closure.chooser = gtk_file_chooser_dialog_new ("hello", NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
351 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
353 closure.accept_button = gtk_dialog_add_button (GTK_DIALOG (closure.chooser),
354 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT);
355 gtk_dialog_set_default_response (GTK_DIALOG (closure.chooser), GTK_RESPONSE_ACCEPT);
357 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (closure.chooser), TRUE);
359 g_signal_connect (closure.chooser, "confirm-overwrite",
360 G_CALLBACK (confirm_overwrite_cb), &closure);
362 if (append_extension)
366 filename = g_path_get_dirname (path);
367 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (closure.chooser), filename);
370 filename = g_path_get_basename (path);
371 extension = strchr (filename, '.');
375 closure.extension = g_strdup (extension);
379 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (closure.chooser), filename);
382 g_signal_connect (closure.chooser, "response",
383 G_CALLBACK (overwrite_response_cb), &closure);
387 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (closure.chooser), path);
390 gdk_threads_add_timeout (2000, confirm_overwrite_timeout_cb, &closure);
391 gtk_dialog_run (GTK_DIALOG (closure.chooser));
393 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (closure.chooser));
394 passed = passed && filename && (strcmp (filename, path) == 0);
397 gtk_widget_destroy (closure.chooser);
399 passed = passed && (1 == closure.confirm_overwrite_signal_emitted);
401 log_test (passed, "Confirm overwrite for %s", path);
407 test_confirm_overwrite (void)
409 gboolean passed = TRUE;
411 /* first test for a file we know will always exist */
412 passed = passed && test_confirm_overwrite_for_path ("/etc/passwd", FALSE);
413 passed = passed && test_confirm_overwrite_for_path ("/etc/resolv.conf", TRUE);
418 static const GtkFileChooserAction open_actions[] = {
419 GTK_FILE_CHOOSER_ACTION_OPEN,
420 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
423 static const GtkFileChooserAction save_actions[] = {
424 GTK_FILE_CHOOSER_ACTION_SAVE,
425 GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
430 has_action (const GtkFileChooserAction *actions,
432 GtkFileChooserAction sought_action)
436 for (i = 0; i < n_actions; i++)
437 if (actions[i] == sought_action)
444 get_action_name (GtkFileChooserAction action)
446 GEnumClass *enum_class;
447 GEnumValue *enum_value;
449 enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION);
451 g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION");
453 enum_value = g_enum_get_value (enum_class, (int) action);
455 g_error ("BUG: get_action_name(): no GEnumValue for GtkFileChooserAction %d", (int) action);
457 return enum_value->value_name;
460 static GtkFileChooserDefault *
461 get_impl_from_dialog (GtkWidget *dialog)
463 GtkFileChooserDialog *d;
464 GtkFileChooserDialogPrivate *dialog_priv;
465 GtkFileChooserWidget *chooser_widget;
466 GtkFileChooserWidgetPrivate *widget_priv;
467 GtkFileChooserDefault *impl;
469 d = GTK_FILE_CHOOSER_DIALOG (dialog);
470 dialog_priv = d->priv;
471 chooser_widget = GTK_FILE_CHOOSER_WIDGET (dialog_priv->widget);
473 g_error ("BUG: dialog_priv->widget is not a GtkFileChooserWidget");
475 widget_priv = chooser_widget->priv;
476 impl = (GtkFileChooserDefault *) (widget_priv->impl);
478 g_error ("BUG: widget_priv->impl is not a GtkFileChooserDefault");
484 test_widgets_for_current_action (GtkFileChooserDialog *dialog,
485 GtkFileChooserAction expected_action)
487 GtkFileChooserDefault *impl;
490 if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) != expected_action)
493 impl = get_impl_from_dialog (GTK_WIDGET (dialog));
495 g_assert (impl->action == expected_action);
499 /* OPEN implies that the "new folder" button is hidden; otherwise it is shown */
500 if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
501 passed = passed && !GTK_WIDGET_VISIBLE (impl->browse_new_folder_button);
503 passed = passed && GTK_WIDGET_VISIBLE (impl->browse_new_folder_button);
505 /* Check that the widgets are present/visible or not */
506 if (has_action (open_actions, G_N_ELEMENTS (open_actions), impl->action))
508 passed = passed && (impl->save_widgets == NULL
509 && (impl->location_mode == LOCATION_MODE_PATH_BAR
510 ? impl->location_entry == NULL
511 : impl->location_entry != NULL)
512 && impl->save_folder_label == NULL
513 && impl->save_folder_combo == NULL
514 && impl->save_expander == NULL
515 && GTK_IS_CONTAINER (impl->browse_widgets) && GTK_WIDGET_DRAWABLE (impl->browse_widgets));
517 else if (has_action (save_actions, G_N_ELEMENTS (save_actions), impl->action))
519 /* FIXME: we can't use GTK_IS_FILE_CHOOSER_ENTRY() because it uses
520 * _gtk_file_chooser_entry_get_type(), which is a non-exported symbol.
521 * So, we just test impl->location_entry for being non-NULL
523 passed = passed && (GTK_IS_CONTAINER (impl->save_widgets) && GTK_WIDGET_DRAWABLE (impl->save_widgets)
524 && impl->location_entry != NULL && GTK_WIDGET_DRAWABLE (impl->location_entry)
525 && GTK_IS_LABEL (impl->save_folder_label) && GTK_WIDGET_DRAWABLE (impl->save_folder_label)
526 && GTK_IS_COMBO_BOX (impl->save_folder_combo) && GTK_WIDGET_DRAWABLE (impl->save_folder_combo)
527 && GTK_IS_EXPANDER (impl->save_expander) && GTK_WIDGET_DRAWABLE (impl->save_expander)
528 && GTK_IS_CONTAINER (impl->browse_widgets));
530 /* FIXME: we are in a SAVE mode; test the visibility and sensitivity of
531 * the children that change depending on the state of the expander.
536 g_error ("BAD TEST: test_widgets_for_current_action() doesn't know about %s", get_action_name (impl->action));
543 typedef gboolean (* ForeachActionCallback) (GtkFileChooserDialog *dialog,
544 GtkFileChooserAction action,
548 foreach_action (GtkFileChooserDialog *dialog,
549 ForeachActionCallback callback,
552 GEnumClass *enum_class;
555 enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION);
557 g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION");
559 for (i = 0; i < enum_class->n_values; i++)
561 GEnumValue *enum_value;
562 GtkFileChooserAction action;
565 enum_value = enum_class->values + i;
566 action = enum_value->value;
568 passed = (* callback) (dialog, action, user_data);
576 struct action_closure {
577 GtkFileChooserAction from_action;
581 switch_from_to_action_cb (GtkFileChooserDialog *dialog,
582 GtkFileChooserAction action,
585 struct action_closure *closure;
590 gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), closure->from_action);
592 passed = test_widgets_for_current_action (dialog, closure->from_action);
593 log_test (passed, "switch_from_to_action_cb(): reset to action %s", get_action_name (closure->from_action));
597 gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), action);
599 passed = test_widgets_for_current_action (dialog, action);
600 log_test (passed, "switch_from_to_action_cb(): transition from %s to %s",
601 get_action_name (closure->from_action),
602 get_action_name (action));
607 switch_from_action_cb (GtkFileChooserDialog *dialog,
608 GtkFileChooserAction action,
611 struct action_closure closure;
613 closure.from_action = action;
615 return foreach_action (dialog, switch_from_to_action_cb, &closure);
619 test_action_widgets (void)
622 GtkFileChooserAction action;
625 dialog = gtk_file_chooser_dialog_new ("Test file chooser",
627 GTK_FILE_CHOOSER_ACTION_OPEN,
633 gtk_widget_show_now (dialog);
635 action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog));
637 passed = test_widgets_for_current_action (GTK_FILE_CHOOSER_DIALOG (dialog), action);
638 log_test (passed, "test_action_widgets(): widgets for initial action %s", get_action_name (action));
642 passed = foreach_action (GTK_FILE_CHOOSER_DIALOG (dialog), switch_from_action_cb, NULL);
643 log_test (passed, "test_action_widgets(): all transitions through property change");
645 gtk_widget_destroy (dialog);
651 test_reload_sequence (gboolean set_folder_before_map)
654 GtkFileChooserDefault *impl;
657 char *current_working_dir;
661 current_working_dir = g_get_current_dir ();
663 dialog = gtk_file_chooser_dialog_new ("Test file chooser",
665 GTK_FILE_CHOOSER_ACTION_OPEN,
671 impl = get_impl_from_dialog (dialog);
673 if (set_folder_before_map)
675 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
679 passed = passed && (impl->current_folder != NULL
680 && impl->browse_files_model != NULL
681 && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
682 && impl->reload_state == RELOAD_HAS_FOLDER
683 && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
684 && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
685 ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
690 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
691 passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
696 /* Initially, no folder is not loaded or pending */
697 passed = passed && (impl->current_folder == NULL
698 && impl->sort_model == NULL
699 && impl->browse_files_model == NULL
700 && impl->load_state == LOAD_EMPTY
701 && impl->reload_state == RELOAD_EMPTY
702 && impl->load_timeout_id == 0);
706 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
707 passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
710 log_test (passed, "test_reload_sequence(): initial status");
712 /* After mapping, it is loading some folder, either the one that was explicitly set or the default one */
714 gtk_widget_show_now (dialog);
718 passed = passed && (impl->current_folder != NULL
719 && impl->browse_files_model != NULL
720 && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
721 && impl->reload_state == RELOAD_HAS_FOLDER
722 && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
723 && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
724 ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
727 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
728 if (set_folder_before_map)
729 passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
731 passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
735 log_test (passed, "test_reload_sequence(): status after map");
737 /* Unmap it; we should still have a folder */
739 gtk_widget_hide (dialog);
743 passed = passed && (impl->current_folder != NULL
744 && impl->browse_files_model != NULL
745 && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
746 && impl->reload_state == RELOAD_WAS_UNMAPPED
747 && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
748 && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
749 ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
752 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
753 if (set_folder_before_map)
754 passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
756 passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
760 log_test (passed, "test_reload_sequence(): status after unmap");
764 gtk_widget_show_now (dialog);
768 passed = passed && (impl->current_folder != NULL
769 && impl->browse_files_model != NULL
770 && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
771 && impl->reload_state == RELOAD_HAS_FOLDER
772 && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
773 && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
774 ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
777 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
778 if (set_folder_before_map)
779 passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
781 passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
785 log_test (passed, "test_reload_sequence(): status after re-map");
787 gtk_widget_destroy (dialog);
788 g_free (current_working_dir);
798 passed = test_reload_sequence (FALSE);
799 log_test (passed, "test_reload(): create and use the default folder");
803 passed = test_reload_sequence (TRUE);
804 log_test (passed, "test_reload(): set a folder explicitly before mapping");
810 test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_dialog, gboolean set_folder_on_dialog)
817 char *current_working_dir;
818 gboolean must_have_cwd;
822 current_working_dir = g_get_current_dir ();
823 must_have_cwd = !(use_dialog && set_folder_on_dialog);
825 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
829 dialog = gtk_file_chooser_dialog_new ("Test", NULL, action,
830 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
831 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
833 button = gtk_file_chooser_button_new_with_dialog (dialog);
835 if (set_folder_on_dialog)
836 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
840 button = gtk_file_chooser_button_new ("Test", action);
841 dialog = NULL; /* keep gcc happy */
844 gtk_container_add (GTK_CONTAINER (window), button);
846 /* Pre-map; no folder is set */
849 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
851 passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
853 passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
855 log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, pre-map, %s",
856 get_action_name (action),
858 set_folder_on_dialog,
859 must_have_cwd ? "must have $cwd" : "must have explicit folder");
861 /* Map; folder should be set */
863 gtk_widget_show_all (window);
864 gtk_widget_show_now (window);
868 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
871 passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
873 passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
875 log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, mapped, %s",
876 get_action_name (action),
878 set_folder_on_dialog,
879 must_have_cwd ? "must have $cwd" : "must have explicit folder");
882 /* Unmap; folder should be set */
884 gtk_widget_hide (window);
886 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
889 passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
891 passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
893 log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, unmapped, %s",
894 get_action_name (action),
896 set_folder_on_dialog,
897 must_have_cwd ? "must have $cwd" : "must have explicit folder");
900 /* Re-map; folder should be set */
902 gtk_widget_show_now (window);
903 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
906 passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0);
908 passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
910 log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, re-mapped, %s",
911 get_action_name (action),
913 set_folder_on_dialog,
914 must_have_cwd ? "must have $cwd" : "must have explicit folder");
917 g_free (current_working_dir);
919 gtk_widget_destroy (window);
925 test_button_folder_states (void)
927 /* GtkFileChooserButton only supports OPEN and SELECT_FOLDER */
928 static const GtkFileChooserAction actions_to_test[] = {
929 GTK_FILE_CHOOSER_ACTION_OPEN,
930 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
937 for (i = 0; i < G_N_ELEMENTS (actions_to_test); i++)
939 passed = passed && test_button_folder_states_for_action (actions_to_test[i], FALSE, FALSE);
940 passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, FALSE);
941 passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, TRUE);
942 log_test (passed, "test_button_folder_states(): action %s", get_action_name (actions_to_test[i]));
945 log_test (passed, "test_button_folder_states(): all supported actions");
950 sleep_timeout_cb (gpointer data)
957 sleep_in_main_loop (int milliseconds)
959 gdk_threads_add_timeout (milliseconds, sleep_timeout_cb, NULL);
964 test_folder_switch_and_filters (void)
969 GtkFilePath *cwd_path;
970 GtkFilePath *base_dir_path;
972 GtkFileFilter *all_filter;
973 GtkFileFilter *txt_filter;
974 GtkFileChooserDefault *impl;
978 cwd = g_get_current_dir ();
979 base_dir = g_build_filename (cwd, "file-chooser-test-dir", NULL);
981 dialog = gtk_file_chooser_dialog_new ("Test", NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
982 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
983 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
985 impl = get_impl_from_dialog (dialog);
987 cwd_path = gtk_file_system_filename_to_path (impl->file_system, cwd);
988 base_dir_path = gtk_file_system_filename_to_path (impl->file_system, base_dir);
990 passed = passed && gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
994 /* All files filter */
996 all_filter = gtk_file_filter_new ();
997 gtk_file_filter_set_name (all_filter, "All files");
998 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_filter);
1002 txt_filter = gtk_file_filter_new ();
1003 gtk_file_filter_set_name (all_filter, "*.txt");
1004 gtk_file_filter_add_pattern (txt_filter, "*.txt");
1005 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
1007 /* Test filter set */
1009 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all_filter);
1010 passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == all_filter);
1012 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
1013 passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
1015 log_test (passed, "test_folder_switch_and_filters(): set and get filter");
1017 gtk_widget_show (dialog);
1019 /* Test that filter is unchanged when we switch folders */
1021 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd);
1022 sleep_in_main_loop (1000);
1023 passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
1025 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
1026 sleep_in_main_loop (500);
1028 g_signal_emit_by_name (impl->browse_path_bar, "path-clicked",
1029 (GtkFilePath *) cwd_path,
1030 (GtkFilePath *) base_dir_path,
1032 sleep_in_main_loop (500);
1033 passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
1035 log_test (passed, "test_folder_switch_and_filters(): filter after changing folder");
1040 gtk_file_path_free (cwd_path);
1041 gtk_file_path_free (base_dir_path);
1043 gtk_widget_destroy (dialog);
1045 log_test (passed, "test_folder_switch_and_filters(): all filter tests");
1049 static GLogFunc default_log_handler;
1050 static int num_warnings;
1051 static int num_errors;
1052 static int num_critical_errors;
1055 log_override_cb (const gchar *log_domain,
1056 GLogLevelFlags log_level,
1057 const gchar *message,
1060 if (log_level & G_LOG_LEVEL_WARNING)
1063 if (log_level & G_LOG_LEVEL_ERROR)
1066 if (log_level & G_LOG_LEVEL_CRITICAL)
1067 num_critical_errors++;
1069 (* default_log_handler) (log_domain, log_level, message, user_data);
1073 main (int argc, char **argv)
1076 gboolean zero_warnings;
1077 gboolean zero_errors;
1078 gboolean zero_critical_errors;
1080 default_log_handler = g_log_set_default_handler (log_override_cb, NULL);
1083 gtk_init (&argc, &argv);
1088 passed = passed && test_black_box ();
1090 passed = passed && test_confirm_overwrite ();
1092 passed = passed && test_action_widgets ();
1093 passed = passed && test_reload ();
1094 passed = passed && test_button_folder_states ();
1095 passed = passed && test_folder_switch_and_filters ();
1097 log_test (passed, "main(): main tests");
1099 /* Warnings and errors */
1101 zero_warnings = num_warnings == 0;
1102 zero_errors = num_errors == 0;
1103 zero_critical_errors = num_critical_errors == 0;
1105 log_test (zero_warnings, "main(): zero warnings (actual number %d)", num_warnings);
1106 log_test (zero_errors, "main(): zero errors (actual number %d)", num_errors);
1107 log_test (zero_critical_errors, "main(): zero critical errors (actual number %d)", num_critical_errors);
1111 passed = passed && zero_warnings && zero_errors && zero_critical_errors;
1113 log_test (passed, "main(): ALL TESTS");