[gimp] app/tests: Add '/gimp-tools/crop_tool_can_crop' test



commit fc8ab634a8fba3f88e38dad06e0152e0d431838e
Author: Martin Nordholts <martinn src gnome org>
Date:   Mon Oct 25 14:32:22 2010 +0200

    app/tests: Add '/gimp-tools/crop_tool_can_crop' test
    
    Begin adding a new set of tests meant to test tools. The first test is
    a regression test for "Bug 315255 - SIGSEGV, while doing a crop".

 app/tests/.gitignore   |    1 +
 app/tests/Makefile.am  |    1 +
 app/tests/test-tools.c |  432 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 434 insertions(+), 0 deletions(-)
---
diff --git a/app/tests/.gitignore b/app/tests/.gitignore
index 9c58683..2e2561d 100644
--- a/app/tests/.gitignore
+++ b/app/tests/.gitignore
@@ -7,6 +7,7 @@ libgimpapptestutils.a
 test-core*
 test-layer-grouping*
 test-session-management*
+test-tools*
 test-ui*
 test-window-management*
 test-xcf*
diff --git a/app/tests/Makefile.am b/app/tests/Makefile.am
index 6acfe07..c981c4f 100644
--- a/app/tests/Makefile.am
+++ b/app/tests/Makefile.am
@@ -13,6 +13,7 @@ TESTS_ENVIRONMENT = \
 TESTS = \
 	test-core		\
 	test-session-management	\
+	test-tools		\
 	test-ui			\
 	test-xcf
 
diff --git a/app/tests/test-tools.c b/app/tests/test-tools.c
new file mode 100644
index 0000000..0c43bdd
--- /dev/null
+++ b/app/tests/test-tools.c
@@ -0,0 +1,432 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 2009 Martin Nordholts <martinn src gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpmath/gimpmath.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "tools/tools-types.h"
+
+#include "tools/tool_manager.h"
+
+#include "display/gimpdisplay.h"
+#include "display/gimpdisplayshell.h"
+#include "display/gimpdisplayshell-scale.h"
+#include "display/gimpdisplayshell-callbacks.h"
+#include "display/gimpdisplayshell-transform.h"
+#include "display/gimpimagewindow.h"
+
+#include "widgets/gimpdialogfactory.h"
+#include "widgets/gimpdock.h"
+#include "widgets/gimpdockable.h"
+#include "widgets/gimpdockbook.h"
+#include "widgets/gimpdocked.h"
+#include "widgets/gimpdockwindow.h"
+#include "widgets/gimphelp-ids.h"
+#include "widgets/gimpsessioninfo.h"
+#include "widgets/gimptoolbox.h"
+#include "widgets/gimptooloptionseditor.h"
+#include "widgets/gimpuimanager.h"
+#include "widgets/gimpwidgets-utils.h"
+
+#include "core/gimp.h"
+#include "core/gimpchannel.h"
+#include "core/gimpcontext.h"
+#include "core/gimpimage.h"
+#include "core/gimplayer.h"
+#include "core/gimptoolinfo.h"
+#include "core/gimptooloptions.h"
+
+#include "tests.h"
+
+#include "gimp-app-test-utils.h"
+
+
+#define GIMP_TEST_IMAGE_WIDTH            150
+#define GIMP_TEST_IMAGE_HEIGHT           267
+
+/* Put this in the code below when you want the test to pause so you
+ * can do measurements of widgets on the screen for example
+ */
+#define GIMP_PAUSE (g_usleep (2 * 1000 * 1000))
+
+#define ADD_TEST(function) \
+  g_test_add ("/gimp-tools/" #function, \
+              GimpTestFixture, \
+              gimp, \
+              gimp_tools_setup_image, \
+              function, \
+              gimp_tools_teardown_image);
+
+
+typedef struct
+{
+  int avoid_sizeof_zero;
+} GimpTestFixture;
+
+
+static void               gimp_tools_setup_image                         (GimpTestFixture  *fixture,
+                                                                          gconstpointer     data);
+static void               gimp_tools_teardown_image                      (GimpTestFixture  *fixture,
+                                                                          gconstpointer     data);
+static void               gimp_tools_synthesize_image_click_drag_release (GimpDisplayShell *shell,
+                                                                          gdouble           start_image_x,
+                                                                          gdouble           start_image_y,
+                                                                          gdouble           end_image_x,
+                                                                          gdouble           end_image_y,
+                                                                          gint              button,
+                                                                          GdkModifierType   modifiers);
+static GimpDisplay      * gimp_test_get_only_display                     (Gimp             *gimp);
+static GimpImage        * gimp_test_get_only_image                       (Gimp             *gimp);
+static GimpDisplayShell * gimp_test_get_only_display_shell               (Gimp             *gimp);
+
+
+static void
+gimp_tools_setup_image (GimpTestFixture *fixture,
+                        gconstpointer    data)
+{
+  Gimp *gimp = GIMP (data);
+
+  gimp_test_utils_create_image (gimp, 
+                                GIMP_TEST_IMAGE_WIDTH,
+                                GIMP_TEST_IMAGE_HEIGHT);
+  gimp_test_run_mainloop_until_idle ();
+}
+
+static void
+gimp_tools_teardown_image (GimpTestFixture *fixture,
+                           gconstpointer    data)
+{
+  Gimp *gimp = GIMP (data);
+
+  g_object_unref (gimp_test_get_only_image (gimp));
+  gimp_display_close (gimp_test_get_only_display (gimp));
+  gimp_test_run_mainloop_until_idle ();
+}
+
+/**
+ * gimp_test_get_only_display:
+ * @gimp:
+ *
+ * Asserts that there only is one image and display and then
+ * returns the display.
+ *
+ * Returns: The #GimpDisplay.
+ **/
+static GimpDisplay *
+gimp_test_get_only_display (Gimp *gimp)
+{
+  g_assert (g_list_length (gimp_get_image_iter (gimp)) == 1);
+  g_assert (g_list_length (gimp_get_display_iter (gimp)) == 1);
+
+  return GIMP_DISPLAY (gimp_get_display_iter (gimp)->data);
+}
+
+/**
+ * gimp_test_get_only_display_shell:
+ * @gimp:
+ *
+ * Asserts that there only is one image and display shell and then
+ * returns the display shell.
+ *
+ * Returns: The #GimpDisplayShell.
+ **/
+static GimpDisplayShell *
+gimp_test_get_only_display_shell (Gimp *gimp)
+{
+  return gimp_display_get_shell (gimp_test_get_only_display (gimp));
+}
+
+/**
+ * gimp_test_get_only_image:
+ * @gimp:
+ *
+ * Asserts that there is only one image and returns that.
+ *
+ * Returns: The #GimpImage.
+ **/
+static GimpImage *
+gimp_test_get_only_image (Gimp *gimp)
+{
+  g_assert (g_list_length (gimp_get_image_iter (gimp)) == 1);
+  g_assert (g_list_length (gimp_get_display_iter (gimp)) == 1);
+
+  return GIMP_IMAGE (gimp_get_image_iter (gimp)->data);
+}
+
+static void
+gimp_test_synthesize_tool_button_event (GimpDisplayShell *shell,
+                                       gint              x,
+                                       gint              y,
+                                       gint              button,
+                                       gint              modifiers,
+                                       GdkEventType      button_event_type)
+{
+  GdkEvent   *event   = gdk_event_new (button_event_type);
+  GdkWindow  *window  = gtk_widget_get_window (GTK_WIDGET (shell->canvas));
+  GdkDisplay *display = gdk_drawable_get_display (GDK_DRAWABLE (window));
+
+  g_assert (button_event_type == GDK_BUTTON_PRESS ||
+            button_event_type == GDK_BUTTON_RELEASE);
+
+  event->button.window     = g_object_ref (window);
+  event->button.send_event = TRUE;
+  event->button.time       = gtk_get_current_event_time ();
+  event->button.x          = x;
+  event->button.y          = y;
+  event->button.axes       = NULL;
+  event->button.state      = 0;
+  event->button.button     = button;
+  event->button.device     = gdk_display_get_core_pointer (display);
+  event->button.x_root     = -1;
+  event->button.y_root     = -1;
+
+  gimp_display_shell_canvas_tool_events (shell->canvas,
+                                         event,
+                                         shell);
+  gdk_event_free (event);
+}
+
+static void
+gimp_test_synthesize_tool_motion_event (GimpDisplayShell *shell,
+                                        gint              x,
+                                        gint              y,
+                                        gint              modifiers)
+{
+  GdkEvent   *event   = gdk_event_new (GDK_MOTION_NOTIFY);
+  GdkWindow  *window  = gtk_widget_get_window (GTK_WIDGET (shell->canvas));
+  GdkDisplay *display = gdk_drawable_get_display (GDK_DRAWABLE (window));
+
+  event->motion.window     = g_object_ref (window);
+  event->motion.send_event = TRUE;
+  event->motion.time       = gtk_get_current_event_time ();
+  event->motion.x          = x;
+  event->motion.y          = y;
+  event->motion.axes       = NULL;
+  event->motion.state      = GDK_BUTTON1_MASK | modifiers;
+  event->motion.is_hint    = FALSE;
+  event->motion.device     = gdk_display_get_core_pointer (display);
+  event->motion.x_root     = -1;
+  event->motion.y_root     = -1;
+
+  gimp_display_shell_canvas_tool_events (shell->canvas,
+                                         event,
+                                         shell);
+  gdk_event_free (event);
+}
+
+static void
+gimp_test_synthesize_tool_crossing_event (GimpDisplayShell *shell,
+                                          gint              x,
+                                          gint              y,
+                                          gint              modifiers,
+                                          GdkEventType      crossing_event_type)
+{
+  GdkEvent   *event   = gdk_event_new (crossing_event_type);
+  GdkWindow  *window  = gtk_widget_get_window (GTK_WIDGET (shell->canvas));
+
+  g_assert (crossing_event_type == GDK_ENTER_NOTIFY ||
+            crossing_event_type == GDK_LEAVE_NOTIFY);
+
+  event->crossing.window     = g_object_ref (window);
+  event->crossing.send_event = TRUE;
+  event->crossing.subwindow  = NULL;
+  event->crossing.time       = gtk_get_current_event_time ();
+  event->crossing.x          = x;
+  event->crossing.y          = y;
+  event->crossing.x_root     = -1;
+  event->crossing.y_root     = -1;
+  event->crossing.mode       = GDK_CROSSING_NORMAL;
+  event->crossing.detail     = GDK_NOTIFY_UNKNOWN;
+  event->crossing.focus      = TRUE;
+  event->crossing.state      = modifiers;
+
+  gimp_display_shell_canvas_tool_events (shell->canvas,
+                                         event,
+                                         shell);
+  gdk_event_free (event);
+}
+
+static void
+gimp_tools_synthesize_image_click_drag_release (GimpDisplayShell *shell,
+                                                gdouble           start_image_x,
+                                                gdouble           start_image_y,
+                                                gdouble           end_image_x,
+                                                gdouble           end_image_y,
+                                                gint              button /*1..3*/,
+                                                GdkModifierType   modifiers)
+{
+  gdouble  start_canvas_x = -1.0;
+  gdouble  start_canvas_y = -1.0;
+  gdouble  end_canvas_x   = -1.0;
+  gdouble  end_canvas_y   = -1.0;
+  gdouble  middle_canvas_x   = -1.0;
+  gdouble  middle_canvas_y   = -1.0;
+
+  /* Transform coordinates */
+  gimp_display_shell_transform_xy_f (shell,
+                                     start_image_x,
+                                     start_image_y,
+                                     &start_canvas_x,
+                                     &start_canvas_y);
+  gimp_display_shell_transform_xy_f (shell,
+                                     end_image_x,
+                                     end_image_y,
+                                     &end_canvas_x,
+                                     &end_canvas_y);
+  middle_canvas_x = (start_canvas_x + end_canvas_x) / 2;
+  middle_canvas_y = (start_canvas_y + end_canvas_y) / 2;
+
+  /* Enter notify */
+  gimp_test_synthesize_tool_crossing_event (shell,
+                                            (int)start_canvas_x,
+                                            (int)start_canvas_y,
+                                            modifiers,
+                                            GDK_ENTER_NOTIFY);
+
+  /* Button press */
+  gimp_test_synthesize_tool_button_event (shell,
+                                          (int)start_canvas_x,
+                                          (int)start_canvas_y,
+                                          button,
+                                          modifiers,
+                                          GDK_BUTTON_PRESS);
+
+  /* Move events */
+  gimp_test_synthesize_tool_motion_event (shell,
+                                          (int)start_canvas_x,
+                                          (int)start_canvas_y,
+                                          modifiers);
+  gimp_test_synthesize_tool_motion_event (shell,
+                                          (int)middle_canvas_x,
+                                          (int)middle_canvas_y,
+                                          modifiers);
+  gimp_test_synthesize_tool_motion_event (shell,
+                                          (int)end_canvas_x,
+                                          (int)end_canvas_y,
+                                          modifiers);
+
+  /* Button release */
+  gimp_test_synthesize_tool_button_event (shell,
+                                          (int)end_canvas_x,
+                                          (int)end_canvas_y,
+                                          button,
+                                          modifiers,
+                                          GDK_BUTTON_RELEASE);
+
+  /* Leave notify */
+  gimp_test_synthesize_tool_crossing_event (shell,
+                                            (int)start_canvas_x,
+                                            (int)start_canvas_y,
+                                            modifiers,
+                                            GDK_LEAVE_NOTIFY);
+
+  /* Process them */
+  gimp_test_run_mainloop_until_idle ();
+}
+
+/**
+ * crop_tool_can_crop:
+ * @fixture:
+ * @data:
+ *
+ * Make sure it's possible to crop at all. Regression test for bug
+ * 315255.
+ **/
+static void
+crop_tool_can_crop (GimpTestFixture *fixture,
+                    gconstpointer    data)
+{
+  Gimp             *gimp  = GIMP (data);
+  GimpImage        *image = gimp_test_get_only_image (gimp);
+  GimpDisplayShell *shell = gimp_test_get_only_display_shell (gimp);
+
+  gint cropped_x = 10;
+  gint cropped_y = 10;
+  gint cropped_w = 20;
+  gint cropped_h = 30;
+
+  /* Fit display and pause and let it stabalize (two idlings seems to
+   * always be enough)
+   */
+  gimp_ui_manager_activate_action (gimp_test_utils_get_ui_manager (gimp),
+                                   "view",
+                                   "view-shrink-wrap");
+  gimp_test_run_mainloop_until_idle ();
+  gimp_test_run_mainloop_until_idle ();
+
+  /* Activate tool and setup active display for the new tool */
+  gimp_context_set_tool (gimp_get_user_context (gimp),
+                         gimp_get_tool_info (gimp, "gimp-crop-tool"));
+  tool_manager_focus_display_active (gimp, shell->display);
+
+  /* Do the crop rect */
+  gimp_tools_synthesize_image_click_drag_release (shell,
+                                                  cropped_x,
+                                                  cropped_y,
+                                                  cropped_x + cropped_w,
+                                                  cropped_y + cropped_h,
+                                                  1 /*button*/,
+                                                  0 /*modifiers*/);
+
+  /* Crop */
+  gimp_test_utils_synthesize_key_event (GTK_WIDGET (shell), GDK_Return);
+  gimp_test_run_mainloop_until_idle ();
+
+  /* Make sure the new image has the expected size */
+  g_assert_cmpint (cropped_w, ==, gimp_image_get_width (image));
+  g_assert_cmpint (cropped_h, ==, gimp_image_get_height (image));
+}
+
+int main(int argc, char **argv)
+{
+  Gimp *gimp   = NULL;
+  gint  result = -1;
+
+  gimp_test_bail_if_no_display ();
+  gtk_test_init (&argc, &argv, NULL);
+
+  gimp_test_utils_set_gimp2_directory ("GIMP_TESTING_ABS_TOP_SRCDIR",
+                                       "app/tests/gimpdir");
+  gimp_test_utils_setup_menus_dir ();
+
+  /* Start up GIMP */
+  gimp = gimp_init_for_gui_testing (TRUE /*show_gui*/);
+  gimp_test_run_mainloop_until_idle ();
+
+  /* Add tests */
+  ADD_TEST (crop_tool_can_crop);
+
+  /* Run the tests and return status */
+  result = g_test_run ();
+
+  /* Don't write files to the source dir */
+  gimp_test_utils_set_gimp2_directory ("GIMP_TESTING_ABS_TOP_BUILDDIR",
+                                       "app/tests/gimpdir-output");
+
+  /* Exit properly so we don't break script-fu plug-in wire */
+  gimp_exit (gimp, TRUE);
+
+  return result;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]