diff options
author | Michael Natterer <mitch@imendio.com> | 2008-06-18 13:29:02 +0000 |
---|---|---|
committer | Michael Natterer <mitch@src.gnome.org> | 2008-06-18 13:29:02 +0000 |
commit | d5565f5b638a39c8c33f290e860a6cc38f5631be (patch) | |
tree | de3c1323a9e1179bf1f2aa23c1be1f8941b096de /gtk/tests/filechooser.c | |
parent | 67c6c28fe04237187645c55195012dbb831955e9 (diff) | |
download | gtk+-d5565f5b638a39c8c33f290e860a6cc38f5631be.tar.gz |
tests/Makefile.am tests/autotestfilechooser.c tests/buildertest.c
2008-06-18 Michael Natterer <mitch@imendio.com>
* tests/Makefile.am
* tests/autotestfilechooser.c
* tests/buildertest.c
* tests/defaultvaluetest.c
* tests/floatingtest.c
* tests/objecttests.c
* tests/pixbuf-init.c
* tests/textbuffertest.c: remove unit tests here...
* gtk/tests/Makefile.am
* gtk/tests/builder.c
* gtk/tests/defaultvalue.c
* gtk/tests/filechooser.c
* gtk/tests/floating.c
* gtk/tests/object.c
* gtk/tests/pixbuf-init.c
* gtk/tests/textbuffer.c: ...and add them here.
svn path=/trunk/; revision=20450
Diffstat (limited to 'gtk/tests/filechooser.c')
-rw-r--r-- | gtk/tests/filechooser.c | 1093 |
1 files changed, 1093 insertions, 0 deletions
diff --git a/gtk/tests/filechooser.c b/gtk/tests/filechooser.c new file mode 100644 index 0000000000..737e5fe272 --- /dev/null +++ b/gtk/tests/filechooser.c @@ -0,0 +1,1093 @@ +/* GTK - The GIMP Toolkit + * autotestfilechooser.c: Automated unit tests for the GtkFileChooser widget + * Copyright (C) 2005, Novell, Inc. + * + * Authors: + * Federico Mena-Quintero <federico@novell.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* TODO: + * + * - In test_reload_sequence(), test that the selection is preserved properly + * between unmap/map. + * + * - More tests! + */ + +#define GTK_FILE_SYSTEM_ENABLE_UNSUPPORTED +#undef GTK_DISABLE_DEPRECATED +#define SLEEP_DURATION 100 + +#include <config.h> +#include <string.h> +#include <glib/gprintf.h> +#include <gtk/gtk.h> +#include "gtk/gtkfilechooserprivate.h" +#include "gtk/gtkfilechooserdefault.h" +#include "gtk/gtkfilechooserentry.h" + +static void +log_test (gboolean passed, const char *test_name, ...) +{ + va_list args; + char *str; + + va_start (args, test_name); + str = g_strdup_vprintf (test_name, args); + va_end (args); + + if (g_test_verbose()) + g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str); + g_free (str); +} + +typedef void (* SetFilenameFn) (GtkFileChooser *chooser, gpointer data); +typedef gboolean (* CompareFilenameFn) (GtkFileChooser *chooser, gpointer data); + +struct test_set_filename_closure { + GtkWidget *chooser; + GtkWidget *accept_button; + gboolean focus_button; +}; + +static gboolean +set_filename_timeout_cb (gpointer data) +{ + struct test_set_filename_closure *closure; + + closure = data; + + if (closure->focus_button) + gtk_widget_grab_focus (closure->accept_button); + + gtk_button_clicked (GTK_BUTTON (closure->accept_button)); + + return FALSE; +} + + +static guint wait_for_idle_id = 0; + +static gboolean +wait_for_idle_idle (gpointer data) +{ + wait_for_idle_id = 0; + + return FALSE; +} + +static void +wait_for_idle (void) +{ + wait_for_idle_id = g_idle_add_full (G_PRIORITY_LOW + 100, + wait_for_idle_idle, + NULL, NULL); + + while (wait_for_idle_id) + gtk_main_iteration (); +} + +static gboolean +test_set_filename (GtkFileChooserAction action, + gboolean focus_button, + SetFilenameFn set_filename_fn,const + CompareFilenameFn compare_filename_fn, + gpointer data) +{ + GtkWidget *chooser; + struct test_set_filename_closure closure; + gboolean retval; + + chooser = gtk_file_chooser_dialog_new ("hello", NULL, action, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + NULL); + + closure.chooser = chooser; + closure.accept_button = gtk_dialog_add_button (GTK_DIALOG (chooser), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + closure.focus_button = focus_button; + + gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT); + + (* set_filename_fn) (GTK_FILE_CHOOSER (chooser), data); + + gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, set_filename_timeout_cb, &closure, NULL); + gtk_dialog_run (GTK_DIALOG (chooser)); + + retval = (* compare_filename_fn) (GTK_FILE_CHOOSER (chooser), data); + + gtk_widget_destroy (chooser); + + return retval; +} + +static void +set_filename_cb (GtkFileChooser *chooser, gpointer data) +{ + const char *filename; + + filename = data; + gtk_file_chooser_set_filename (chooser, filename); +} + +static gboolean +compare_filename_cb (GtkFileChooser *chooser, gpointer data) +{ + const char *filename; + char *out_filename; + gboolean retval; + + filename = data; + out_filename = gtk_file_chooser_get_filename (chooser); + + if (out_filename) + { + retval = (strcmp (out_filename, filename) == 0); + g_free (out_filename); + } else + retval = FALSE; + + return retval; +} + +static gboolean +test_black_box_set_filename (GtkFileChooserAction action, const char *filename, gboolean focus_button) +{ + gboolean passed; + + passed = test_set_filename (action, focus_button, set_filename_cb, compare_filename_cb, (char *) filename); + + log_test (passed, "set_filename: action %d, focus_button=%s", + (int) action, + focus_button ? "TRUE" : "FALSE"); + + return passed; + +} + +struct current_name_closure { + const char *path; + const char *current_name; +}; + +static void +set_current_name_cb (GtkFileChooser *chooser, gpointer data) +{ + struct current_name_closure *closure; + + closure = data; + + gtk_file_chooser_set_current_folder (chooser, closure->path); + gtk_file_chooser_set_current_name (chooser, closure->current_name); +} + +static gboolean +compare_current_name_cb (GtkFileChooser *chooser, gpointer data) +{ + struct current_name_closure *closure; + char *out_filename; + gboolean retval; + + closure = data; + + out_filename = gtk_file_chooser_get_filename (chooser); + + if (out_filename) + { + char *filename; + + filename = g_build_filename (closure->path, closure->current_name, NULL); + retval = (strcmp (filename, out_filename) == 0); + g_free (filename); + g_free (out_filename); + } else + retval = FALSE; + + return retval; +} + +static gboolean +test_black_box_set_current_name (GtkFileChooserAction action, const char *path, const char *current_name, gboolean focus_button) +{ + struct current_name_closure closure; + gboolean passed; + + closure.path = path; + closure.current_name = current_name; + + passed = test_set_filename (action, focus_button, + set_current_name_cb, compare_current_name_cb, &closure); + + log_test (passed, "set_current_name, focus_button=%s", focus_button ? "TRUE" : "FALSE"); + + return passed; +} + +/* FIXME: fails in CREATE_FOLDER mode when FOLDER_NAME == "/" */ + +#if 0 +#define FILE_NAME "/nonexistent" +#define FOLDER_NAME "/etc" +#else +#define FILE_NAME "/etc/passwd" +#define FOLDER_NAME "/etc" +#endif + +#define CURRENT_NAME "parangaricutirimicuaro.txt" +#define CURRENT_NAME_FOLDER "parangaricutirimicuaro" + +/* https://bugzilla.novell.com/show_bug.cgi?id=184875 + * http://bugzilla.gnome.org/show_bug.cgi?id=347066 + * http://bugzilla.gnome.org/show_bug.cgi?id=346058 + */ +static void +test_black_box (void) +{ + gboolean passed; + char *cwd; + + passed = TRUE; + + passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_OPEN, FILE_NAME, FALSE); + g_assert (passed); + passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_OPEN, FILE_NAME, TRUE); + g_assert (passed); + passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_SAVE, FILE_NAME, FALSE); + g_assert (passed); + passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_SAVE, FILE_NAME, TRUE); + g_assert (passed); + passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FOLDER_NAME, FALSE); + g_assert (passed); + passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FOLDER_NAME, TRUE); + g_assert (passed); + passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, FOLDER_NAME, FALSE); + g_assert (passed); + passed = passed && test_black_box_set_filename (GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, FOLDER_NAME, TRUE); + g_assert (passed); + + cwd = g_get_current_dir (); + + passed = passed && test_black_box_set_current_name (GTK_FILE_CHOOSER_ACTION_SAVE, cwd, CURRENT_NAME, FALSE); + g_assert (passed); + passed = passed && test_black_box_set_current_name (GTK_FILE_CHOOSER_ACTION_SAVE, cwd, CURRENT_NAME, TRUE); + g_assert (passed); + passed = passed && test_black_box_set_current_name (GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, cwd, CURRENT_NAME_FOLDER, FALSE); + g_assert (passed); + passed = passed && test_black_box_set_current_name (GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, cwd, CURRENT_NAME_FOLDER, TRUE); + g_assert (passed); + + g_free (cwd); + + log_test (passed, "Black box tests"); +} + +struct confirm_overwrite_closure { + GtkWidget *chooser; + GtkWidget *accept_button; + gint confirm_overwrite_signal_emitted; + gchar *extension; +}; + +static GtkFileChooserConfirmation +confirm_overwrite_cb (GtkFileChooser *chooser, gpointer data) +{ + struct confirm_overwrite_closure *closure = data; + + if (g_test_verbose()) + printf ("bling!\n"); + closure->confirm_overwrite_signal_emitted += 1; + + return GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME; +} + +static void +overwrite_response_cb (GtkFileChooser *chooser, gint response, gpointer data) +{ + struct confirm_overwrite_closure *closure = data; + char *filename; + + if (g_test_verbose()) + printf ("plong!\n"); + + if (response != GTK_RESPONSE_ACCEPT) + return; + + filename = gtk_file_chooser_get_filename (chooser); + + if (!g_str_has_suffix (filename, closure->extension)) + { + char *basename; + + basename = g_path_get_basename (filename); + g_free (filename); + + filename = g_strconcat (basename, closure->extension, NULL); + gtk_file_chooser_set_current_name (chooser, filename); + + g_signal_stop_emission_by_name (chooser, "response"); + gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT); + } +} + +static gboolean +confirm_overwrite_timeout_cb (gpointer data) +{ + struct confirm_overwrite_closure *closure; + + closure = data; + gtk_button_clicked (GTK_BUTTON (closure->accept_button)); + + return FALSE; +} + +/* http://bugzilla.gnome.org/show_bug.cgi?id=347883 */ +static gboolean +test_confirm_overwrite_for_path (const char *path, gboolean append_extension) +{ + gboolean passed; + struct confirm_overwrite_closure closure; + char *filename; + + passed = TRUE; + + closure.extension = NULL; + closure.confirm_overwrite_signal_emitted = 0; + closure.chooser = gtk_file_chooser_dialog_new ("hello", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + NULL); + closure.accept_button = gtk_dialog_add_button (GTK_DIALOG (closure.chooser), + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT); + gtk_dialog_set_default_response (GTK_DIALOG (closure.chooser), GTK_RESPONSE_ACCEPT); + + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (closure.chooser), TRUE); + + g_signal_connect (closure.chooser, "confirm-overwrite", + G_CALLBACK (confirm_overwrite_cb), &closure); + + if (append_extension) + { + char *extension; + + filename = g_path_get_dirname (path); + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (closure.chooser), filename); + g_free (filename); + + filename = g_path_get_basename (path); + extension = strchr (filename, '.'); + + if (extension) + { + closure.extension = g_strdup (extension); + *extension = '\0'; + } + + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (closure.chooser), filename); + g_free (filename); + + g_signal_connect (closure.chooser, "response", + G_CALLBACK (overwrite_response_cb), &closure); + } + else + { + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (closure.chooser), path); + } + + gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, confirm_overwrite_timeout_cb, &closure, NULL); + gtk_dialog_run (GTK_DIALOG (closure.chooser)); + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (closure.chooser)); + passed = passed && filename && (strcmp (filename, path) == 0); + g_free (filename); + + gtk_widget_destroy (closure.chooser); + + passed = passed && (1 == closure.confirm_overwrite_signal_emitted); + + log_test (passed, "Confirm overwrite for %s", path); + + return passed; +} + +static void +test_confirm_overwrite (void) +{ + gboolean passed = TRUE; + + /* first test for a file we know will always exist */ + passed = passed && test_confirm_overwrite_for_path ("/etc/passwd", FALSE); + g_assert (passed); + passed = passed && test_confirm_overwrite_for_path ("/etc/resolv.conf", TRUE); + g_assert (passed); +} + +static const GtkFileChooserAction open_actions[] = { + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER +}; + +static const GtkFileChooserAction save_actions[] = { + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER +}; + + +static gboolean +has_action (const GtkFileChooserAction *actions, + int n_actions, + GtkFileChooserAction sought_action) +{ + int i; + + for (i = 0; i < n_actions; i++) + if (actions[i] == sought_action) + return TRUE; + + return FALSE; +} + +static const char * +get_action_name (GtkFileChooserAction action) +{ + GEnumClass *enum_class; + GEnumValue *enum_value; + + enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION); + if (!enum_class) + g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION"); + + enum_value = g_enum_get_value (enum_class, (int) action); + if (!enum_value) + g_error ("BUG: get_action_name(): no GEnumValue for GtkFileChooserAction %d", (int) action); + + return enum_value->value_name; +} + +static GtkFileChooserDefault * +get_impl_from_dialog (GtkWidget *dialog) +{ + GtkFileChooserDialog *d; + GtkFileChooserDialogPrivate *dialog_priv; + GtkFileChooserWidget *chooser_widget; + GtkFileChooserWidgetPrivate *widget_priv; + GtkFileChooserDefault *impl; + + d = GTK_FILE_CHOOSER_DIALOG (dialog); + dialog_priv = d->priv; + chooser_widget = GTK_FILE_CHOOSER_WIDGET (dialog_priv->widget); + if (!chooser_widget) + g_error ("BUG: dialog_priv->widget is not a GtkFileChooserWidget"); + + widget_priv = chooser_widget->priv; + impl = (GtkFileChooserDefault *) (widget_priv->impl); + if (!impl) + g_error ("BUG: widget_priv->impl is not a GtkFileChooserDefault"); + + return impl; +} + +static gboolean +test_widgets_for_current_action (GtkFileChooserDialog *dialog, + GtkFileChooserAction expected_action) +{ + GtkFileChooserDefault *impl; + gboolean passed; + + if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) != expected_action) + return FALSE; + + impl = get_impl_from_dialog (GTK_WIDGET (dialog)); + + g_assert (impl->action == expected_action); + + passed = TRUE; + + /* OPEN implies that the "new folder" button is hidden; otherwise it is shown */ + if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) + passed = passed && !GTK_WIDGET_VISIBLE (impl->browse_new_folder_button); + else + passed = passed && GTK_WIDGET_VISIBLE (impl->browse_new_folder_button); + + /* Check that the widgets are present/visible or not */ + if (has_action (open_actions, G_N_ELEMENTS (open_actions), impl->action)) + { + passed = passed && (impl->save_widgets == NULL + && (impl->location_mode == LOCATION_MODE_PATH_BAR + ? impl->location_entry == NULL + : impl->location_entry != NULL) + && impl->save_folder_label == NULL + && impl->save_folder_combo == NULL + && impl->save_expander == NULL + && GTK_IS_CONTAINER (impl->browse_widgets) && GTK_WIDGET_DRAWABLE (impl->browse_widgets)); + } + else if (has_action (save_actions, G_N_ELEMENTS (save_actions), impl->action)) + { + /* FIXME: we can't use GTK_IS_FILE_CHOOSER_ENTRY() because it uses + * _gtk_file_chooser_entry_get_type(), which is a non-exported symbol. + * So, we just test impl->location_entry for being non-NULL + */ + passed = passed && (GTK_IS_CONTAINER (impl->save_widgets) && GTK_WIDGET_DRAWABLE (impl->save_widgets) + && impl->location_entry != NULL && GTK_WIDGET_DRAWABLE (impl->location_entry) + && GTK_IS_LABEL (impl->save_folder_label) && GTK_WIDGET_DRAWABLE (impl->save_folder_label) + && GTK_IS_COMBO_BOX (impl->save_folder_combo) && GTK_WIDGET_DRAWABLE (impl->save_folder_combo) + && GTK_IS_EXPANDER (impl->save_expander) && GTK_WIDGET_DRAWABLE (impl->save_expander) + && GTK_IS_CONTAINER (impl->browse_widgets)); + + /* FIXME: we are in a SAVE mode; test the visibility and sensitivity of + * the children that change depending on the state of the expander. + */ + } + else + { + g_error ("BAD TEST: test_widgets_for_current_action() doesn't know about %s", get_action_name (impl->action)); + passed = FALSE; + } + + return passed; +} + +typedef gboolean (* ForeachActionCallback) (GtkFileChooserDialog *dialog, + GtkFileChooserAction action, + gpointer user_data); + +static gboolean +foreach_action (GtkFileChooserDialog *dialog, + ForeachActionCallback callback, + gpointer user_data) +{ + GEnumClass *enum_class; + int i; + + enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION); + if (!enum_class) + g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION"); + + for (i = 0; i < enum_class->n_values; i++) + { + GEnumValue *enum_value; + GtkFileChooserAction action; + gboolean passed; + + enum_value = enum_class->values + i; + action = enum_value->value; + + passed = (* callback) (dialog, action, user_data); + if (!passed) + return FALSE; + } + + return TRUE; +} + +struct action_closure { + GtkFileChooserAction from_action; +}; + +static gboolean +switch_from_to_action_cb (GtkFileChooserDialog *dialog, + GtkFileChooserAction action, + gpointer user_data) +{ + struct action_closure *closure; + gboolean passed; + + closure = user_data; + + gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), closure->from_action); + + passed = test_widgets_for_current_action (dialog, closure->from_action); + log_test (passed, "switch_from_to_action_cb(): reset to action %s", get_action_name (closure->from_action)); + if (!passed) + return FALSE; + + gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), action); + + passed = test_widgets_for_current_action (dialog, action); + log_test (passed, "switch_from_to_action_cb(): transition from %s to %s", + get_action_name (closure->from_action), + get_action_name (action)); + return passed; +} + +static gboolean +switch_from_action_cb (GtkFileChooserDialog *dialog, + GtkFileChooserAction action, + gpointer user_data) +{ + struct action_closure closure; + + closure.from_action = action; + + return foreach_action (dialog, switch_from_to_action_cb, &closure); +} + +static void +test_action_widgets (void) +{ + GtkWidget *dialog; + GtkFileChooserAction action; + gboolean passed; + + dialog = gtk_file_chooser_dialog_new ("Test file chooser", + NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, + GTK_RESPONSE_ACCEPT, + NULL); + gtk_widget_show_now (dialog); + + action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)); + + passed = test_widgets_for_current_action (GTK_FILE_CHOOSER_DIALOG (dialog), action); + log_test (passed, "test_action_widgets(): widgets for initial action %s", get_action_name (action)); + g_assert (passed); + + passed = foreach_action (GTK_FILE_CHOOSER_DIALOG (dialog), switch_from_action_cb, NULL); + log_test (passed, "test_action_widgets(): all transitions through property change"); + g_assert (passed); + + gtk_widget_destroy (dialog); +} + +static gboolean +test_reload_sequence (gboolean set_folder_before_map) +{ + GtkWidget *dialog; + GtkFileChooserDefault *impl; + gboolean passed; + char *folder; + char *current_working_dir; + + passed = TRUE; + + current_working_dir = g_get_current_dir (); + + dialog = gtk_file_chooser_dialog_new ("Test file chooser", + NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, + GTK_RESPONSE_ACCEPT, + NULL); + impl = get_impl_from_dialog (dialog); + + if (set_folder_before_map) + { + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ()); + + wait_for_idle (); + + passed = passed && (impl->current_folder != NULL + && impl->browse_files_model != NULL + && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED) + && impl->reload_state == RELOAD_HAS_FOLDER + && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE) + && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED) + ? (impl->load_timeout_id == 0 && impl->sort_model != NULL) + : TRUE)); + + wait_for_idle (); + + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); + passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0); + g_free (folder); + } + else + { + /* Initially, no folder is not loaded or pending */ + passed = passed && (impl->current_folder == NULL + && impl->sort_model == NULL + && impl->browse_files_model == NULL + && impl->load_state == LOAD_EMPTY + && impl->reload_state == RELOAD_EMPTY + && impl->load_timeout_id == 0); + + wait_for_idle (); + + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); + passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0); + } + + log_test (passed, "test_reload_sequence(): initial status"); + + /* After mapping, it is loading some folder, either the one that was explicitly set or the default one */ + + gtk_widget_show_now (dialog); + + wait_for_idle (); + + passed = passed && (impl->current_folder != NULL + && impl->browse_files_model != NULL + && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED) + && impl->reload_state == RELOAD_HAS_FOLDER + && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE) + && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED) + ? (impl->load_timeout_id == 0 && impl->sort_model != NULL) + : TRUE)); + + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); + if (set_folder_before_map) + passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0); + else + passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0); + + g_free (folder); + + log_test (passed, "test_reload_sequence(): status after map"); + + /* Unmap it; we should still have a folder */ + + gtk_widget_hide (dialog); + + wait_for_idle (); + + passed = passed && (impl->current_folder != NULL + && impl->browse_files_model != NULL + && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED) + && impl->reload_state == RELOAD_WAS_UNMAPPED + && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE) + && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED) + ? (impl->load_timeout_id == 0 && impl->sort_model != NULL) + : TRUE)); + + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); + if (set_folder_before_map) + passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0); + else + passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0); + + g_free (folder); + + log_test (passed, "test_reload_sequence(): status after unmap"); + + /* Map it again! */ + + gtk_widget_show_now (dialog); + + wait_for_idle (); + + passed = passed && (impl->current_folder != NULL + && impl->browse_files_model != NULL + && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED) + && impl->reload_state == RELOAD_HAS_FOLDER + && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE) + && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED) + ? (impl->load_timeout_id == 0 && impl->sort_model != NULL) + : TRUE)); + + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); + if (set_folder_before_map) + passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0); + else + passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0); + + g_free (folder); + + log_test (passed, "test_reload_sequence(): status after re-map"); + + gtk_widget_destroy (dialog); + g_free (current_working_dir); + + return passed; +} + +static void +test_reload (void) +{ + gboolean passed; + + passed = test_reload_sequence (FALSE); + log_test (passed, "test_reload(): create and use the default folder"); + g_assert (passed); + + passed = test_reload_sequence (TRUE); + log_test (passed, "test_reload(): set a folder explicitly before mapping"); + g_assert (passed); +} + +static gboolean +test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_dialog, gboolean set_folder_on_dialog) +{ + gboolean passed; + GtkWidget *window; + GtkWidget *button; + char *folder; + GtkWidget *dialog; + char *current_working_dir; + gboolean must_have_cwd; + + passed = TRUE; + + current_working_dir = g_get_current_dir (); + must_have_cwd = !(use_dialog && set_folder_on_dialog); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + if (use_dialog) + { + dialog = gtk_file_chooser_dialog_new ("Test", NULL, action, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + NULL); + button = gtk_file_chooser_button_new_with_dialog (dialog); + + if (set_folder_on_dialog) + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ()); + } + else + { + button = gtk_file_chooser_button_new ("Test", action); + dialog = NULL; /* keep gcc happy */ + } + + gtk_container_add (GTK_CONTAINER (window), button); + + /* Pre-map; no folder is set */ + wait_for_idle (); + + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button)); + if (must_have_cwd) + passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0); + else + passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0); + + log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, pre-map, %s", + get_action_name (action), + use_dialog, + set_folder_on_dialog, + must_have_cwd ? "must have $cwd" : "must have explicit folder"); + + /* Map; folder should be set */ + + gtk_widget_show_all (window); + gtk_widget_show_now (window); + + wait_for_idle (); + + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button)); + + if (must_have_cwd) + passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0); + else + passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0); + + log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, mapped, %s", + get_action_name (action), + use_dialog, + set_folder_on_dialog, + must_have_cwd ? "must have $cwd" : "must have explicit folder"); + g_free (folder); + + /* Unmap; folder should be set */ + + gtk_widget_hide (window); + wait_for_idle (); + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button)); + + if (must_have_cwd) + passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0); + else + passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0); + + log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, unmapped, %s", + get_action_name (action), + use_dialog, + set_folder_on_dialog, + must_have_cwd ? "must have $cwd" : "must have explicit folder"); + g_free (folder); + + /* Re-map; folder should be set */ + + gtk_widget_show_now (window); + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button)); + + if (must_have_cwd) + passed = passed && (folder != NULL && strcmp (folder, current_working_dir) == 0); + else + passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0); + wait_for_idle (); + log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, re-mapped, %s", + get_action_name (action), + use_dialog, + set_folder_on_dialog, + must_have_cwd ? "must have $cwd" : "must have explicit folder"); + g_free (folder); + + g_free (current_working_dir); + + gtk_widget_destroy (window); + + return passed; +} + +static void +test_button_folder_states (void) +{ + /* GtkFileChooserButton only supports OPEN and SELECT_FOLDER */ + static const GtkFileChooserAction actions_to_test[] = { + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + }; + gboolean passed; + int i; + + passed = TRUE; + + for (i = 0; i < G_N_ELEMENTS (actions_to_test); i++) + { + passed = passed && test_button_folder_states_for_action (actions_to_test[i], FALSE, FALSE); + g_assert (passed); + passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, FALSE); + g_assert (passed); + passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, TRUE); + g_assert (passed); + log_test (passed, "test_button_folder_states(): action %s", get_action_name (actions_to_test[i])); + } + + log_test (passed, "test_button_folder_states(): all supported actions"); +} + +static gboolean +sleep_timeout_cb (gpointer data) +{ + gtk_main_quit (); + return FALSE; +} + +static void +sleep_in_main_loop (double fraction) +{ + /* process all pending idles and events */ + while (g_main_context_pending (NULL)) + g_main_context_iteration (NULL, FALSE); + /* sleeping probably isn't strictly necessary here */ + gdk_threads_add_timeout_full (G_MAXINT, fraction * SLEEP_DURATION, sleep_timeout_cb, NULL, NULL); + gtk_main (); + /* process any pending idles or events that arrived during sleep */ + while (g_main_context_pending (NULL)) + g_main_context_iteration (NULL, FALSE); +} + +static void +test_folder_switch_and_filters (void) +{ + gboolean passed; + char *cwd; + char *base_dir; + GtkFilePath *cwd_path; + GtkFilePath *base_dir_path; + GtkWidget *dialog; + GtkFileFilter *all_filter; + GtkFileFilter *txt_filter; + GtkFileChooserDefault *impl; + + passed = TRUE; + + cwd = g_get_current_dir (); + base_dir = g_build_filename (cwd, "file-chooser-test-dir", NULL); + + dialog = gtk_file_chooser_dialog_new ("Test", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + NULL); + impl = get_impl_from_dialog (dialog); + + cwd_path = gtk_file_system_filename_to_path (impl->file_system, cwd); + base_dir_path = gtk_file_system_filename_to_path (impl->file_system, base_dir); + + passed = passed && gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir); + g_assert (passed); + + /* All files filter */ + + all_filter = gtk_file_filter_new (); + gtk_file_filter_set_name (all_filter, "All files"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_filter); + + /* *.txt filter */ + + txt_filter = gtk_file_filter_new (); + gtk_file_filter_set_name (all_filter, "*.txt"); + gtk_file_filter_add_pattern (txt_filter, "*.txt"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), txt_filter); + + /* Test filter set */ + + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all_filter); + passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == all_filter); + g_assert (passed); + + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), txt_filter); + passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter); + log_test (passed, "test_folder_switch_and_filters(): set and get filter"); + g_assert (passed); + + gtk_widget_show (dialog); + + /* Test that filter is unchanged when we switch folders */ + + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd); + sleep_in_main_loop (0.5); + passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter); + g_assert (passed); + + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir); + sleep_in_main_loop (0.25); + + g_signal_emit_by_name (impl->browse_path_bar, "path-clicked", + (GtkFilePath *) cwd_path, + (GtkFilePath *) base_dir_path, + FALSE); + sleep_in_main_loop (0.25); + passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter); + log_test (passed, "test_folder_switch_and_filters(): filter after changing folder"); + g_assert (passed); + + /* cleanups */ + g_free (cwd); + g_free (base_dir); + gtk_file_path_free (cwd_path); + gtk_file_path_free (base_dir_path); + + gtk_widget_destroy (dialog); + + log_test (passed, "test_folder_switch_and_filters(): all filter tests"); +} + +extern void pixbuf_init (void); + +int +main (int argc, + char **argv) +{ + pixbuf_init (); + /* initialize test program */ + gtk_test_init (&argc, &argv); + + /* register tests */ + g_test_add_func ("/GtkFileChooser/black_box", test_black_box); + g_test_add_func ("/GtkFileChooser/confirm_overwrite", test_confirm_overwrite); + g_test_add_func ("/GtkFileChooser/action_widgets", test_action_widgets); + g_test_add_func ("/GtkFileChooser/reload", test_reload); + g_test_add_func ("/GtkFileChooser/button_folder_states", test_button_folder_states); + g_test_add_func ("/GtkFileChooser/folder_switch_and_filters", test_folder_switch_and_filters); + + /* run and check selected tests */ + return g_test_run(); +} |