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".
This commit is contained in:
432
app/tests/test-tools.c
Normal file
432
app/tests/test-tools.c
Normal file
@ -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;
|
||||
}
|
Reference in New Issue
Block a user