Initial checkin of Pika from heckimp
This commit is contained in:
29
app/tests/create_test_env.sh
Normal file
29
app/tests/create_test_env.sh
Normal file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Copy tests resources
|
||||
for dir in files pikadir pikadir-empty; do
|
||||
rm -rf "${MESON_BUILD_ROOT}/${MESON_SUBDIR}/${dir}"
|
||||
cp -r "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}/${dir}" \
|
||||
"${MESON_BUILD_ROOT}/${MESON_SUBDIR}"
|
||||
done
|
||||
|
||||
# Link to Color icon theme for tests
|
||||
IconsRoot="${MESON_SOURCE_ROOT}/icons/Color"
|
||||
IconsDirs=$(find "${IconsRoot}" -name [0-9]* -type d -printf '%f\n' | sort -n)
|
||||
for dir in ${IconsDirs} ; do
|
||||
mkdir "${MESON_BUILD_ROOT}/${MESON_SUBDIR}/pika-test-icon-theme/hicolor/${dir}x${dir}" -p
|
||||
LnName="${MESON_BUILD_ROOT}/${MESON_SUBDIR}/pika-test-icon-theme/hicolor/${dir}x${dir}/apps"
|
||||
rm -rf "${LnName}"
|
||||
ln -s "${IconsRoot}/${dir}" "${LnName}"
|
||||
done
|
||||
|
||||
LnName="${MESON_BUILD_ROOT}/${MESON_SUBDIR}/pika-test-icon-theme/hicolor/index.theme"
|
||||
rm -rf "${LnName}"
|
||||
ln -s "${IconsRoot}/index.theme" "${LnName}"
|
||||
|
||||
|
||||
# Create output dirs
|
||||
rm -rf "${MESON_BUILD_ROOT}/${MESON_SUBDIR}/pikadir-output"
|
||||
for dir in brushes gradients patterns; do
|
||||
mkdir -p "${MESON_BUILD_ROOT}/${MESON_SUBDIR}/pikadir-output/${dir}"
|
||||
done
|
BIN
app/tests/files/pika-2-6-file.xcf
Normal file
BIN
app/tests/files/pika-2-6-file.xcf
Normal file
Binary file not shown.
15
app/tests/manual-testcases.txt
Normal file
15
app/tests/manual-testcases.txt
Normal file
@ -0,0 +1,15 @@
|
||||
This file contains manual test cases
|
||||
------------------------------------
|
||||
|
||||
/pika-manual-tests/opened_image_stays_on_top
|
||||
|
||||
Step-by-step:
|
||||
1. Create a new image, make the image window almost as big as the screen
|
||||
2. From the image window menu, do File -> Open
|
||||
3. Select an image and open it
|
||||
|
||||
Expected result:
|
||||
The image is opened and is kept above the image it was opened from
|
||||
|
||||
Last known PASS:
|
||||
2010-06-23
|
81
app/tests/meson.build
Normal file
81
app/tests/meson.build
Normal file
@ -0,0 +1,81 @@
|
||||
apptests_links = [
|
||||
libappconfig,
|
||||
libappactions,
|
||||
libappdialogs,
|
||||
libappdisplay,
|
||||
libappgui,
|
||||
libappmenus,
|
||||
libapppropgui,
|
||||
libapptools,
|
||||
libappwidgets,
|
||||
libpikabase,
|
||||
libpikacolor,
|
||||
libpikaconfig,
|
||||
libpikamath,
|
||||
libpikamodule,
|
||||
libpikathumb,
|
||||
libpikawidgets,
|
||||
]
|
||||
|
||||
|
||||
libapptestutils_sources = [
|
||||
'pika-app-test-utils.c',
|
||||
'pika-test-session-utils.c',
|
||||
]
|
||||
|
||||
libapptestutils = static_library('apptestutils',
|
||||
libapptestutils_sources,
|
||||
dependencies: libapp_dep,
|
||||
link_with: apptests_links,
|
||||
)
|
||||
|
||||
apptests_links += libapptestutils
|
||||
|
||||
|
||||
app_tests = [
|
||||
'core',
|
||||
'pikaidtable',
|
||||
'save-and-export',
|
||||
#'session-2-8-compatibility-multi-window',
|
||||
#'session-2-8-compatibility-single-window',
|
||||
'single-window-mode',
|
||||
#'tools',
|
||||
'ui',
|
||||
'xcf',
|
||||
]
|
||||
|
||||
cmd = run_command('create_test_env.sh', check: false)
|
||||
if cmd.returncode() != 0
|
||||
error(cmd.stderr().strip())
|
||||
endif
|
||||
|
||||
# Prevent parallel builds for the tests
|
||||
# The tests must not be run in parallel or in a different order as specified
|
||||
|
||||
prio = 1000
|
||||
foreach test_name : app_tests
|
||||
test_exe = executable(test_name,
|
||||
'test-@0@.c'.format(test_name),
|
||||
'tests.c',
|
||||
dependencies: [ libapp_dep, appstream_glib ],
|
||||
link_with: apptests_links,
|
||||
)
|
||||
|
||||
test(test_name,
|
||||
test_exe,
|
||||
env: [
|
||||
'PIKA_TESTING_ABS_TOP_SRCDIR=' + meson.project_source_root(),
|
||||
'PIKA_TESTING_ABS_TOP_BUILDDIR='+ meson.project_build_root(),
|
||||
'PIKA_TESTING_PLUGINDIRS=' + meson.project_build_root()/'plug-ins'/'common',
|
||||
'PIKA_TESTING_PLUGINDIRS_BASENAME_IGNORES=mkgen.pl',
|
||||
'UI_TEST=yes',
|
||||
],
|
||||
suite: 'app',
|
||||
timeout: 60,
|
||||
is_parallel : false,
|
||||
priority: prio,
|
||||
)
|
||||
|
||||
prio = prio - 10
|
||||
|
||||
endforeach
|
383
app/tests/pika-app-test-utils.c
Normal file
383
app/tests/pika-app-test-utils.c
Normal file
@ -0,0 +1,383 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "display/display-types.h"
|
||||
|
||||
#include "display/pikadisplay.h"
|
||||
#include "display/pikadisplayshell.h"
|
||||
#include "display/pikaimagewindow.h"
|
||||
|
||||
#include "menus/menus.h"
|
||||
|
||||
#include "widgets/pikauimanager.h"
|
||||
#include "widgets/pikadialogfactory.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer.h"
|
||||
#include "core/pikalayer-new.h"
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include "pika-app-test-utils.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* SendInput() requirement is Windows 2000 pro or over.
|
||||
* We may need to set WINVER to make sure the compiler does not try to
|
||||
* compile for on older version of win32, thus breaking the build.
|
||||
* See
|
||||
* http://msdn.microsoft.com/en-us/library/aa383745%28v=vs.85%29.aspx#setting_winver_or__win32_winnt
|
||||
*/
|
||||
#define WINVER 0x0500
|
||||
#include <windows.h>
|
||||
#endif /* G_OS_WIN32 */
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
// only to get keycode definitions from HIToolbox/Events.h
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#endif /* GDK_WINDOWING_QUARTZ */
|
||||
|
||||
void
|
||||
pika_test_utils_set_env_to_subdir (const gchar *root_env_var,
|
||||
const gchar *subdir,
|
||||
const gchar *target_env_var)
|
||||
{
|
||||
const gchar *root_dir = NULL;
|
||||
gchar *target_dir = NULL;
|
||||
|
||||
/* Get root dir */
|
||||
root_dir = g_getenv (root_env_var);
|
||||
if (! root_dir)
|
||||
g_printerr ("*\n"
|
||||
"* The env var %s is not set, you are probably running\n"
|
||||
"* in a debugger. Set it manually, e.g.:\n"
|
||||
"*\n"
|
||||
"* set env %s=%s/source/pika\n"
|
||||
"*\n",
|
||||
root_env_var,
|
||||
root_env_var, g_get_home_dir ());
|
||||
|
||||
/* Construct path and setup target env var */
|
||||
target_dir = g_build_filename (root_dir, subdir, NULL);
|
||||
g_setenv (target_env_var, target_dir, TRUE);
|
||||
g_free (target_dir);
|
||||
}
|
||||
|
||||
void
|
||||
pika_test_utils_set_env_to_subpath (const gchar *root_env_var1,
|
||||
const gchar *root_env_var2,
|
||||
const gchar *subdir,
|
||||
const gchar *target_env_var)
|
||||
{
|
||||
const gchar *root_dir1 = NULL;
|
||||
const gchar *root_dir2 = NULL;
|
||||
gchar *target_dir1 = NULL;
|
||||
gchar *target_dir2 = NULL;
|
||||
gchar *target_path = NULL;
|
||||
|
||||
/* Get root dir */
|
||||
root_dir1 = g_getenv (root_env_var1);
|
||||
if (! root_dir1)
|
||||
g_printerr ("*\n"
|
||||
"* The env var %s is not set, you are probably running\n"
|
||||
"* in a debugger. Set it manually, e.g.:\n"
|
||||
"*\n"
|
||||
"* set env %s=%s/source/pika\n"
|
||||
"*\n",
|
||||
root_env_var1,
|
||||
root_env_var1, g_get_home_dir ());
|
||||
|
||||
root_dir2 = g_getenv (root_env_var2);
|
||||
if (! root_dir2)
|
||||
g_printerr ("*\n"
|
||||
"* The env var %s is not set, you are probably running\n"
|
||||
"* in a debugger. Set it manually, e.g.:\n"
|
||||
"*\n"
|
||||
"* set env %s=%s/source/pika\n"
|
||||
"*\n",
|
||||
root_env_var2,
|
||||
root_env_var2, g_get_home_dir ());
|
||||
|
||||
/* Construct path and setup target env var */
|
||||
target_dir1 = g_build_filename (root_dir1, subdir, NULL);
|
||||
target_dir2 = g_build_filename (root_dir2, subdir, NULL);
|
||||
|
||||
target_path = g_strconcat (target_dir1, G_SEARCHPATH_SEPARATOR_S,
|
||||
target_dir2, NULL);
|
||||
|
||||
g_free (target_dir1);
|
||||
g_free (target_dir2);
|
||||
|
||||
g_setenv (target_env_var, target_path, TRUE);
|
||||
g_free (target_path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pika_test_utils_set_pika3_directory:
|
||||
* @root_env_var: Either "PIKA_TESTING_ABS_TOP_SRCDIR" or
|
||||
* "PIKA_TESTING_ABS_TOP_BUILDDIR"
|
||||
* @subdir: Subdir, may be %NULL
|
||||
*
|
||||
* Sets PIKA3_DIRECTORY to the source dir @root_env_var/@subdir. The
|
||||
* environment variables is set up by the test runner, see Makefile.am
|
||||
**/
|
||||
void
|
||||
pika_test_utils_set_pika3_directory (const gchar *root_env_var,
|
||||
const gchar *subdir)
|
||||
{
|
||||
pika_test_utils_set_env_to_subdir (root_env_var,
|
||||
subdir,
|
||||
"PIKA3_DIRECTORY" /*target_env_var*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_utils_setup_menus_path:
|
||||
*
|
||||
* Sets PIKA_TESTING_MENUS_PATH to "$top_srcdir/menus:$top_builddir/menus".
|
||||
**/
|
||||
void
|
||||
pika_test_utils_setup_menus_path (void)
|
||||
{
|
||||
/* PIKA_TESTING_ABS_TOP_SRCDIR is set by the automake test runner,
|
||||
* see Makefile.am
|
||||
*/
|
||||
pika_test_utils_set_env_to_subpath ("PIKA_TESTING_ABS_TOP_SRCDIR",
|
||||
"PIKA_TESTING_ABS_TOP_BUILDDIR",
|
||||
"menus",
|
||||
"PIKA_TESTING_MENUS_PATH");
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_utils_create_image:
|
||||
* @pika: A #Pika instance.
|
||||
* @width: Width of image (and layer)
|
||||
* @height: Height of image (and layer)
|
||||
*
|
||||
* Creates a new image of a given size with one layer of same size and
|
||||
* a display.
|
||||
*
|
||||
* Returns: The new #PikaImage.
|
||||
**/
|
||||
void
|
||||
pika_test_utils_create_image (Pika *pika,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
PikaImage *image;
|
||||
PikaLayer *layer;
|
||||
|
||||
image = pika_image_new (pika, width, height,
|
||||
PIKA_RGB, PIKA_PRECISION_U8_NON_LINEAR);
|
||||
|
||||
layer = pika_layer_new (image,
|
||||
width,
|
||||
height,
|
||||
pika_image_get_layer_format (image, TRUE),
|
||||
"layer1",
|
||||
1.0,
|
||||
PIKA_LAYER_MODE_NORMAL);
|
||||
|
||||
pika_image_add_layer (image,
|
||||
layer,
|
||||
NULL /*parent*/,
|
||||
0 /*position*/,
|
||||
FALSE /*push_undo*/);
|
||||
|
||||
pika_create_display (pika,
|
||||
image,
|
||||
PIKA_UNIT_PIXEL,
|
||||
1.0 /*scale*/,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_utils_synthesize_key_event:
|
||||
* @widget: Widget to target.
|
||||
* @keyval: Keyval, e.g. GDK_Return
|
||||
*
|
||||
* Simulates a keypress and release with gdk_test_simulate_key().
|
||||
**/
|
||||
void
|
||||
pika_test_utils_synthesize_key_event (GtkWidget *widget,
|
||||
guint keyval)
|
||||
{
|
||||
#if defined(GDK_WINDOWING_QUARTZ)
|
||||
|
||||
GdkKeymapKey *keys = NULL;
|
||||
gint n_keys = 0;
|
||||
gint i;
|
||||
CGEventRef keyUp, keyDown;
|
||||
|
||||
if (gdk_keymap_get_entries_for_keyval (gdk_keymap_get_for_display (gdk_display_get_default ()), keyval, &keys, &n_keys))
|
||||
{
|
||||
/* XXX not in use yet */
|
||||
CGEventRef commandDown = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)kVK_Command, true);
|
||||
CGEventRef commandUp = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)kVK_Command, false);
|
||||
|
||||
CGEventRef shiftDown = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)kVK_Shift, true);
|
||||
CGEventRef shiftUp = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)kVK_Shift, false);
|
||||
|
||||
CGEventRef optionDown = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)kVK_Option, true);
|
||||
CGEventRef optionUp = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)kVK_Option, false);
|
||||
|
||||
for (i = 0; i < n_keys; i++)
|
||||
{
|
||||
/* Option press. */
|
||||
if (keys[i].group)
|
||||
{
|
||||
CGEventPost (kCGHIDEventTap, optionDown);
|
||||
}
|
||||
/* Shift press. */
|
||||
if (keys[i].level)
|
||||
{
|
||||
CGEventPost(kCGHIDEventTap, shiftDown);
|
||||
}
|
||||
keyDown = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)keys[i].keycode, true);
|
||||
keyUp = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)keys[i].keycode, false);
|
||||
/* Key pressed. */
|
||||
CGEventPost (kCGHIDEventTap, keyDown);
|
||||
CFRelease (keyDown);
|
||||
usleep (100);
|
||||
/* key released */
|
||||
CGEventPost (kCGHIDEventTap, keyUp);
|
||||
CFRelease (keyUp);
|
||||
|
||||
/* Shift release. */
|
||||
if (keys[i].level)
|
||||
{
|
||||
CGEventPost (kCGHIDEventTap, shiftDown);
|
||||
}
|
||||
|
||||
/* Option release. */
|
||||
if (keys[i].group)
|
||||
{
|
||||
CGEventPost (kCGHIDEventTap, optionUp);
|
||||
}
|
||||
/* No need to loop for alternative keycodes. We want only one
|
||||
* key generated. */
|
||||
break;
|
||||
}
|
||||
CFRelease (commandDown);
|
||||
CFRelease (commandUp);
|
||||
CFRelease (shiftDown);
|
||||
CFRelease (shiftUp);
|
||||
CFRelease (optionDown);
|
||||
CFRelease (optionUp);
|
||||
g_free (keys);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("%s: no macOS key mapping found for keyval %d.", G_STRFUNC, keyval);
|
||||
}
|
||||
|
||||
#else /* ! GDK_WINDOWING_QUARTZ */
|
||||
gdk_test_simulate_key (gtk_widget_get_window (widget),
|
||||
-1, -1, /*x, y*/
|
||||
keyval,
|
||||
0 /*modifiers*/,
|
||||
GDK_KEY_PRESS);
|
||||
gdk_test_simulate_key (gtk_widget_get_window (widget),
|
||||
-1, -1, /*x, y*/
|
||||
keyval,
|
||||
0 /*modifiers*/,
|
||||
GDK_KEY_RELEASE);
|
||||
#endif /* ! GDK_WINDOWING_QUARTZ */
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_utils_get_ui_manager:
|
||||
* @pika: The #Pika instance.
|
||||
*
|
||||
* Returns the "best" #PikaUIManager to use when performing
|
||||
* actions. It gives the ui manager of the empty display if it exists,
|
||||
* otherwise it gives it the ui manager of the first display.
|
||||
*
|
||||
* Returns: The #PikaUIManager.
|
||||
**/
|
||||
PikaUIManager *
|
||||
pika_test_utils_get_ui_manager (Pika *pika)
|
||||
{
|
||||
return menus_get_image_manager_singleton (pika);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_utils_create_image_from_dalog:
|
||||
* @pika:
|
||||
*
|
||||
* Creates a new image using the "New image" dialog, and then returns
|
||||
* the #PikaImage created.
|
||||
*
|
||||
* Returns: The created #PikaImage.
|
||||
**/
|
||||
PikaImage *
|
||||
pika_test_utils_create_image_from_dialog (Pika *pika)
|
||||
{
|
||||
PikaImage *image = NULL;
|
||||
GtkWidget *new_image_dialog = NULL;
|
||||
guint n_initial_images = g_list_length (pika_get_image_iter (pika));
|
||||
guint n_images = -1;
|
||||
gint tries_left = 100;
|
||||
PikaUIManager *ui_manager = pika_test_utils_get_ui_manager (pika);
|
||||
|
||||
/* Bring up the new image dialog */
|
||||
pika_ui_manager_activate_action (ui_manager,
|
||||
"image",
|
||||
"image-new");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Get the GtkWindow of the dialog */
|
||||
new_image_dialog =
|
||||
pika_dialog_factory_dialog_raise (pika_dialog_factory_get_singleton (),
|
||||
gdk_display_get_monitor (gdk_display_get_default (), 0),
|
||||
NULL,
|
||||
"pika-image-new-dialog",
|
||||
-1 /*view_size*/);
|
||||
|
||||
/* Press the OK button. It will take a while for the image to be
|
||||
* created so loop for a while
|
||||
*/
|
||||
gtk_dialog_response (GTK_DIALOG (new_image_dialog), GTK_RESPONSE_OK);
|
||||
do
|
||||
{
|
||||
g_usleep (20 * 1000);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
n_images = g_list_length (pika_get_image_iter (pika));
|
||||
}
|
||||
while (tries_left-- &&
|
||||
n_images != n_initial_images + 1);
|
||||
|
||||
/* Make sure there now is one image more than initially */
|
||||
g_assert_cmpint (n_images,
|
||||
==,
|
||||
n_initial_images + 1);
|
||||
|
||||
image = PIKA_IMAGE (pika_get_image_iter (pika)->data);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
46
app/tests/pika-app-test-utils.h
Normal file
46
app/tests/pika-app-test-utils.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __PIKA_APP_TEST_UTILS_H__
|
||||
#define __PIKA_APP_TEST_UTILS_H__
|
||||
|
||||
|
||||
void pika_test_utils_set_env_to_subdir (const gchar *root_env_var,
|
||||
const gchar *subdir,
|
||||
const gchar *target_env_var);
|
||||
void pika_test_utils_set_env_to_subpath (const gchar *root_env_var1,
|
||||
const gchar *root_env_var2,
|
||||
const gchar *subdir,
|
||||
const gchar *target_env_var);
|
||||
void pika_test_utils_set_pika3_directory (const gchar *root_env_var,
|
||||
const gchar *subdir);
|
||||
void pika_test_utils_setup_menus_path (void);
|
||||
void pika_test_utils_create_image (Pika *pika,
|
||||
gint width,
|
||||
gint height);
|
||||
void pika_test_utils_synthesize_key_event (GtkWidget *widget,
|
||||
guint keyval);
|
||||
PikaUIManager * pika_test_utils_get_ui_manager (Pika *pika);
|
||||
PikaImage * pika_test_utils_create_image_from_dialog
|
||||
(Pika *pika);
|
||||
|
||||
|
||||
#endif /* __PIKA_APP_TEST_UTILS_H__ */
|
256
app/tests/pika-test-session-utils.c
Normal file
256
app/tests/pika-test-session-utils.c
Normal file
@ -0,0 +1,256 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 2011 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
|
||||
#include "dialogs/dialogs-types.h"
|
||||
|
||||
#include "widgets/pikadialogfactory.h"
|
||||
#include "widgets/pikasessioninfo.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikacontext.h"
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include "pika-app-test-utils.h"
|
||||
#include "pika-test-session-utils.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GFile *file;
|
||||
gchar *md5;
|
||||
guint64 modtime;
|
||||
} PikaTestFileState;
|
||||
|
||||
|
||||
static gboolean
|
||||
pika_test_get_file_state_verbose (GFile *file,
|
||||
PikaTestFileState *filestate)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
|
||||
filestate->file = g_object_ref (file);
|
||||
|
||||
/* Get checksum */
|
||||
if (success)
|
||||
{
|
||||
gchar *filename;
|
||||
gchar *contents = NULL;
|
||||
gsize length = 0;
|
||||
|
||||
filename = g_file_get_path (file);
|
||||
success = g_file_get_contents (filename,
|
||||
&contents,
|
||||
&length,
|
||||
NULL);
|
||||
g_free (filename);
|
||||
|
||||
if (success)
|
||||
{
|
||||
filestate->md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5,
|
||||
contents,
|
||||
length);
|
||||
}
|
||||
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
/* Get modification time */
|
||||
if (success)
|
||||
{
|
||||
GFileInfo *info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_TIME_MODIFIED, 0,
|
||||
NULL, NULL);
|
||||
if (info)
|
||||
{
|
||||
filestate->modtime = g_file_info_get_attribute_uint64 (
|
||||
info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
||||
success = TRUE;
|
||||
g_object_unref (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (! success)
|
||||
g_printerr ("Failed to get initial file info for '%s'\n",
|
||||
pika_file_get_utf8_name (file));
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pika_test_file_state_changes (GFile *file,
|
||||
PikaTestFileState *state1,
|
||||
PikaTestFileState *state2)
|
||||
{
|
||||
if (state1->modtime == state2->modtime)
|
||||
{
|
||||
g_printerr ("A new '%s' was not created\n",
|
||||
pika_file_get_utf8_name (file));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (strcmp (state1->md5, state2->md5) != 0)
|
||||
{
|
||||
char *diff_argv[5] = {
|
||||
"diff",
|
||||
"-u",
|
||||
g_file_get_path (state1->file),
|
||||
g_file_get_path (state2->file),
|
||||
NULL
|
||||
};
|
||||
|
||||
g_printerr ("'%s' was changed but should not have been. Reason, using "
|
||||
"`diff -u $expected $actual`\n",
|
||||
pika_file_get_utf8_name (file));
|
||||
|
||||
g_spawn_sync (NULL /*working_directory*/,
|
||||
diff_argv,
|
||||
NULL /*envp*/,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
NULL /*child_setup*/,
|
||||
NULL /*user_data*/,
|
||||
NULL /*standard_output*/,
|
||||
NULL /*standard_error*/,
|
||||
NULL /*exist_status*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_free (diff_argv[2]);
|
||||
g_free (diff_argv[3]);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_session_load_and_write_session_files:
|
||||
* @loaded_sessionrc: The name of the file of the sessionrc file to
|
||||
* load
|
||||
* @loaded_dockrc: The name of the file of the dockrc file to load
|
||||
* @expected_sessionrc: The name of the file with the expected
|
||||
* sessionrc file content
|
||||
* @expected_dockrc: The name of the file with the expected dockrc
|
||||
* file content
|
||||
*
|
||||
* Utility function for the various session management tests. We can't
|
||||
* easily have all those tests in a single program several Gimp
|
||||
* instance can't easily be initialized in the same process.
|
||||
**/
|
||||
void
|
||||
pika_test_session_load_and_write_session_files (const gchar *loaded_sessionrc,
|
||||
const gchar *loaded_dockrc,
|
||||
const gchar *expected_sessionrc,
|
||||
const gchar *expected_dockrc,
|
||||
gboolean single_window_mode)
|
||||
{
|
||||
Pika *pika;
|
||||
PikaTestFileState initial_sessionrc_state = { NULL, NULL, 0 };
|
||||
PikaTestFileState initial_dockrc_state = { NULL, NULL, 0 };
|
||||
PikaTestFileState final_sessionrc_state = { NULL, NULL, 0 };
|
||||
PikaTestFileState final_dockrc_state = { NULL, NULL, 0 };
|
||||
GFile *sessionrc_file = NULL;
|
||||
GFile *dockrc_file = NULL;
|
||||
|
||||
/* Make sure to run this before we use any PIKA functions */
|
||||
pika_test_utils_set_pika3_directory ("PIKA_TESTING_ABS_TOP_SRCDIR",
|
||||
"app/tests/pikadir");
|
||||
pika_test_utils_setup_menus_path ();
|
||||
|
||||
/* Note that we expect the resulting sessionrc to be different from
|
||||
* the read file, which is why we check the MD5 of the -expected
|
||||
* variant
|
||||
*/
|
||||
sessionrc_file = pika_directory_file (expected_sessionrc, NULL);
|
||||
dockrc_file = pika_directory_file (expected_dockrc, NULL);
|
||||
|
||||
/* Remember the modtimes and MD5s */
|
||||
g_assert (pika_test_get_file_state_verbose (sessionrc_file,
|
||||
&initial_sessionrc_state));
|
||||
g_assert (pika_test_get_file_state_verbose (dockrc_file,
|
||||
&initial_dockrc_state));
|
||||
|
||||
/* Use specific input files when restoring the session */
|
||||
g_setenv ("PIKA_TESTING_SESSIONRC_NAME", loaded_sessionrc, TRUE /*overwrite*/);
|
||||
g_setenv ("PIKA_TESTING_DOCKRC_NAME", loaded_dockrc, TRUE /*overwrite*/);
|
||||
|
||||
/* Start up PIKA */
|
||||
pika = pika_init_for_gui_testing (TRUE /*show_gui*/);
|
||||
|
||||
/* Let the main loop run until idle to let things stabilize. This
|
||||
* includes parsing sessionrc and dockrc
|
||||
*/
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Change the pika dir to the output dir so files are written there,
|
||||
* we don't want to (can't always) write to files in the source
|
||||
* dir. There is a hook in Makefile.am that makes sure the output
|
||||
* dir exists
|
||||
*/
|
||||
pika_test_utils_set_pika3_directory ("PIKA_TESTING_ABS_TOP_BUILDDIR",
|
||||
"app/tests/pikadir-output");
|
||||
/* Use normal output names */
|
||||
g_unsetenv ("PIKA_TESTING_SESSIONRC_NAME");
|
||||
g_unsetenv ("PIKA_TESTING_DOCKRC_NAME");
|
||||
|
||||
g_object_unref (sessionrc_file);
|
||||
g_object_unref (dockrc_file);
|
||||
|
||||
sessionrc_file = pika_directory_file ("sessionrc", NULL);
|
||||
dockrc_file = pika_directory_file ("dockrc", NULL);
|
||||
|
||||
/* Exit. This includes writing sessionrc and dockrc*/
|
||||
pika_exit (pika, TRUE);
|
||||
|
||||
/* Now get the new modtimes and MD5s */
|
||||
g_assert (pika_test_get_file_state_verbose (sessionrc_file,
|
||||
&final_sessionrc_state));
|
||||
g_assert (pika_test_get_file_state_verbose (dockrc_file,
|
||||
&final_dockrc_state));
|
||||
|
||||
/* If things have gone our way, PIKA will have deserialized
|
||||
* sessionrc and dockrc, shown the GUI, and then serialized the new
|
||||
* files. To make sure we have new files we check the modtime, and
|
||||
* to make sure that their content remains the same we compare their
|
||||
* MD5
|
||||
*/
|
||||
g_assert (pika_test_file_state_changes (g_file_new_for_path ("sessionrc"),
|
||||
&initial_sessionrc_state,
|
||||
&final_sessionrc_state));
|
||||
g_assert (pika_test_file_state_changes (g_file_new_for_path ("dockrc"),
|
||||
&initial_dockrc_state,
|
||||
&final_dockrc_state));
|
||||
}
|
33
app/tests/pika-test-session-utils.h
Normal file
33
app/tests/pika-test-session-utils.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __PIKA_TEST_SESSION_UTILS_H__
|
||||
#define __PIKA_TEST_SESSION_UTILS_H__
|
||||
|
||||
|
||||
void pika_test_session_load_and_write_session_files (const gchar *loaded_sessionrc,
|
||||
const gchar *loaded_dockrc,
|
||||
const gchar *expected_sessionrc,
|
||||
const gchar *expected_dockrc,
|
||||
gboolean single_window_mode);
|
||||
|
||||
|
||||
#endif /* __PIKA_TEST_SESSION_UTILS_H__ */
|
24
app/tests/pikadir-empty/tags.xml
Normal file
24
app/tests/pikadir-empty/tags.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<tags>
|
||||
|
||||
<resource identifier="pika-brush-clipboard" checksum="157dcef48665ab465439cfaf10d6feeb">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-pattern-clipboard" checksum="eff9598f9f61c1dc78d842f1798c2ab8">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-bg-rgb" checksum="12ad9439c57e897e50fb0399439e5b2b">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-bg-hsv-cw" checksum="86589f70c8a7777c6e2d1d14b99e3759">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-bg-hsv-ccw" checksum="65aacbbd72d99ff20ca1bd310f0a21a5">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-bg-rgb" checksum="4a878c6cfae0b0e03c0834723daadf92">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-transparent" checksum="1491f74caf057a39c8193470da2d2a29">
|
||||
</resource>
|
||||
</tags>
|
44
app/tests/pikadir/dockrc
Normal file
44
app/tests/pikadir/dockrc
Normal file
@ -0,0 +1,44 @@
|
||||
# recently closed docks
|
||||
|
||||
(PikaSessionInfo "Palettes - FG/BG - Images"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 585 115)
|
||||
(size 200 575)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-palette-list"
|
||||
(tab-style preview)))
|
||||
(book
|
||||
(position 140)
|
||||
(current-page 0)
|
||||
(dockable "pika-color-editor"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(current-page "PikaColorSelect"))))
|
||||
(book
|
||||
(position 415)
|
||||
(current-page 0)
|
||||
(dockable "pika-image-list"
|
||||
(tab-style preview)))))
|
||||
(PikaSessionInfo "Selection, Fonts"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 200 180)
|
||||
(size 200 300)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-selection-editor"
|
||||
(tab-style icon))
|
||||
(dockable "pika-font-list"
|
||||
(tab-style preview)))))
|
||||
|
||||
# end of recently closed docks
|
44
app/tests/pikadir/dockrc-2-8
Normal file
44
app/tests/pikadir/dockrc-2-8
Normal file
@ -0,0 +1,44 @@
|
||||
# recently closed docks
|
||||
|
||||
(PikaSessionInfo "Palettes - FG/BG - Images"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 585 115)
|
||||
(size 200 575)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-palette-list"
|
||||
(tab-style preview)))
|
||||
(book
|
||||
(position 140)
|
||||
(current-page 0)
|
||||
(dockable "pika-color-editor"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(current-page "PikaColorSelect"))))
|
||||
(book
|
||||
(position 415)
|
||||
(current-page 0)
|
||||
(dockable "pika-image-list"
|
||||
(tab-style preview)))))
|
||||
(PikaSessionInfo "Selection, Fonts"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 200 180)
|
||||
(size 200 300)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-selection-editor"
|
||||
(tab-style icon))
|
||||
(dockable "pika-font-list"
|
||||
(tab-style preview)))))
|
||||
|
||||
# end of recently closed docks
|
44
app/tests/pikadir/dockrc-expected
Normal file
44
app/tests/pikadir/dockrc-expected
Normal file
@ -0,0 +1,44 @@
|
||||
# recently closed docks
|
||||
|
||||
(PikaSessionInfo "Palettes - FG/BG - Images"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 585 115)
|
||||
(size 200 575)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-palette-list"
|
||||
(tab-style preview)))
|
||||
(book
|
||||
(position 140)
|
||||
(current-page 0)
|
||||
(dockable "pika-color-editor"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(current-page "PikaColorSelect"))))
|
||||
(book
|
||||
(position 415)
|
||||
(current-page 0)
|
||||
(dockable "pika-image-list"
|
||||
(tab-style preview)))))
|
||||
(PikaSessionInfo "Selection, Fonts"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 200 180)
|
||||
(size 200 300)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-selection-editor"
|
||||
(tab-style icon))
|
||||
(dockable "pika-font-list"
|
||||
(tab-style preview)))))
|
||||
|
||||
# end of recently closed docks
|
117
app/tests/pikadir/sessionrc
Normal file
117
app/tests/pikadir/sessionrc
Normal file
@ -0,0 +1,117 @@
|
||||
# PIKA sessionrc
|
||||
#
|
||||
# This file takes session-specific info (that is info, you want to keep
|
||||
# between two PIKA sessions). You are not supposed to edit it manually, but
|
||||
# of course you can do. The sessionrc will be entirely rewritten every time
|
||||
# you quit PIKA. If this file isn't found, defaults are used.
|
||||
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 565 170)
|
||||
(size 210 535)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-layer-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))
|
||||
(book
|
||||
(position 290)
|
||||
(current-page 0)
|
||||
(dockable "pika-brush-grid"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 140 290)
|
||||
(size 445 300)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-tool-options"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(show-button-bar "true")))))
|
||||
(pika-dock
|
||||
(position 230)
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-device-status"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 795 45)
|
||||
(size 200 265)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "true")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-pattern-grid"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true")))
|
||||
(dockable "pika-gradient-list"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 805 345)
|
||||
(size 200 450)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "true")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-channel-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))
|
||||
(book
|
||||
(position 200)
|
||||
(current-page 0)
|
||||
(dockable "pika-palette-editor"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(show-button-bar "true")
|
||||
(edit-active "true")
|
||||
(current-data "Color History")
|
||||
(zoom-factor "2.80"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-file-open-dialog")
|
||||
(position 390 140)
|
||||
(size 900 815))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-image-new-dialog")
|
||||
(position 100 100))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-empty-image-window")
|
||||
(position 140 30)
|
||||
(size 610 190))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-single-image-window")
|
||||
(position 10 40)
|
||||
(size 900 600))
|
||||
|
||||
(last-tip-shown 0)
|
||||
|
||||
# end of sessionrc
|
105
app/tests/pikadir/sessionrc-2-8-multi-window
Normal file
105
app/tests/pikadir/sessionrc-2-8-multi-window
Normal file
@ -0,0 +1,105 @@
|
||||
# PIKA sessionrc
|
||||
#
|
||||
# This file takes session-specific info (that is info, you want to keep
|
||||
# between two PIKA sessions). You are not supposed to edit it manually, but
|
||||
# of course you can do. The sessionrc will be entirely rewritten every time
|
||||
# you quit PIKA. If this file isn't found, defaults are used.
|
||||
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 565 170)
|
||||
(size 210 535)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-layer-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)))
|
||||
(book
|
||||
(position 290)
|
||||
(current-page 0)
|
||||
(dockable "pika-brush-grid"
|
||||
(tab-style preview)))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 140 290)
|
||||
(size 445 300)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-tool-options"
|
||||
(tab-style icon))))
|
||||
(pika-dock
|
||||
(position 230)
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-device-status"
|
||||
(tab-style icon)))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 795 45)
|
||||
(size 200 265)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "true")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-pattern-grid"
|
||||
(tab-style preview))
|
||||
(dockable "pika-gradient-list"
|
||||
(tab-style preview)))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 805 345)
|
||||
(size 200 450)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "true")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-channel-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)))
|
||||
(book
|
||||
(position 200)
|
||||
(current-page 0)
|
||||
(dockable "pika-palette-editor"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(edit-active "true")
|
||||
(current-data "Color History")
|
||||
(zoom-factor "2.80"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-file-open-dialog")
|
||||
(position 390 140)
|
||||
(size 900 815))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-image-new-dialog")
|
||||
(position 100 100))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-empty-image-window")
|
||||
(position 140 30)
|
||||
(size 610 190)
|
||||
(open-on-exit))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-single-image-window")
|
||||
(position 10 40)
|
||||
(size 900 600))
|
||||
|
||||
(hide-docks no)
|
||||
(single-window-mode no)
|
||||
(last-tip-shown 0)
|
||||
|
||||
# end of sessionrc
|
63
app/tests/pikadir/sessionrc-2-8-single-window
Normal file
63
app/tests/pikadir/sessionrc-2-8-single-window
Normal file
@ -0,0 +1,63 @@
|
||||
# PIKA sessionrc
|
||||
#
|
||||
# This file takes session-specific info (that is info, you want to keep
|
||||
# between two PIKA sessions). You are not supposed to edit it manually, but
|
||||
# of course you can do. The sessionrc will be entirely rewritten every time
|
||||
# you quit PIKA. If this file isn't found, defaults are used.
|
||||
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-file-open-dialog")
|
||||
(position 390 140)
|
||||
(size 900 815))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-image-new-dialog")
|
||||
(position 100 100))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-empty-image-window")
|
||||
(position 140 30)
|
||||
(size 1285 750))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-single-image-window")
|
||||
(position 140 30)
|
||||
(size 1050 770)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(left-docks-width "80")
|
||||
(right-docks-width "400")
|
||||
(maximized "no"))
|
||||
(pika-toolbox
|
||||
(side left))
|
||||
(pika-dock
|
||||
(side right)
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-layer-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)))
|
||||
(book
|
||||
(position 380)
|
||||
(current-page 0)
|
||||
(dockable "pika-brush-grid"
|
||||
(tab-style preview))))
|
||||
(pika-dock
|
||||
(side right)
|
||||
(position 200)
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-tool-options"
|
||||
(tab-style icon))))
|
||||
(pika-dock
|
||||
(side right)
|
||||
(position 550)
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-pattern-grid"
|
||||
(tab-style preview))
|
||||
(dockable "pika-gradient-list"
|
||||
(tab-style preview)))))
|
||||
|
||||
(hide-docks no)
|
||||
(single-window-mode yes)
|
||||
(last-tip-shown 0)
|
||||
|
||||
# end of sessionrc
|
105
app/tests/pikadir/sessionrc-expected
Normal file
105
app/tests/pikadir/sessionrc-expected
Normal file
@ -0,0 +1,105 @@
|
||||
# PIKA sessionrc
|
||||
#
|
||||
# This file takes session-specific info (that is info, you want to keep
|
||||
# between two PIKA sessions). You are not supposed to edit it manually, but
|
||||
# of course you can do. The sessionrc will be entirely rewritten every time
|
||||
# you quit PIKA. If this file isn't found, defaults are used.
|
||||
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 565 170)
|
||||
(size 210 535)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-layer-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)))
|
||||
(book
|
||||
(position 290)
|
||||
(current-page 0)
|
||||
(dockable "pika-brush-grid"
|
||||
(tab-style preview)))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 140 290)
|
||||
(size 445 300)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-tool-options"
|
||||
(tab-style icon))))
|
||||
(pika-dock
|
||||
(position 230)
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-device-status"
|
||||
(tab-style icon)))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 795 45)
|
||||
(size 200 265)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "true")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-pattern-grid"
|
||||
(tab-style preview))
|
||||
(dockable "pika-gradient-list"
|
||||
(tab-style preview)))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 805 345)
|
||||
(size 200 450)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "true")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-channel-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)))
|
||||
(book
|
||||
(position 200)
|
||||
(current-page 0)
|
||||
(dockable "pika-palette-editor"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(edit-active "true")
|
||||
(current-data "Color History")
|
||||
(zoom-factor "2.80"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-file-open-dialog")
|
||||
(position 390 140)
|
||||
(size 900 815))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-image-new-dialog")
|
||||
(position 100 100))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-empty-image-window")
|
||||
(position 140 30)
|
||||
(size 610 190)
|
||||
(open-on-exit))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-single-image-window")
|
||||
(position 10 40)
|
||||
(size 900 600))
|
||||
|
||||
(hide-docks no)
|
||||
(single-window-mode no)
|
||||
(last-tip-shown 0)
|
||||
|
||||
# end of sessionrc
|
122
app/tests/pikadir/sessionrc-expected-multi-window
Normal file
122
app/tests/pikadir/sessionrc-expected-multi-window
Normal file
@ -0,0 +1,122 @@
|
||||
# PIKA sessionrc
|
||||
#
|
||||
# This file takes session-specific info (that is info, you want to keep
|
||||
# between two PIKA sessions). You are not supposed to edit it manually, but
|
||||
# of course you can do. The sessionrc will be entirely rewritten every time
|
||||
# you quit PIKA. If this file isn't found, defaults are used.
|
||||
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 565 170)
|
||||
(size 210 535)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-layer-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))
|
||||
(book
|
||||
(position 290)
|
||||
(current-page 0)
|
||||
(dockable "pika-brush-grid"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 140 290)
|
||||
(size 445 300)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "false")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-tool-options"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(show-button-bar "true")))))
|
||||
(pika-dock
|
||||
(position 230)
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-device-status"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 795 45)
|
||||
(size 200 265)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "true")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-pattern-grid"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true")))
|
||||
(dockable "pika-gradient-list"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-dock-window")
|
||||
(position 805 345)
|
||||
(size 200 450)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(show-image-menu "true")
|
||||
(follow-active-image "true"))
|
||||
(pika-dock
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-channel-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))
|
||||
(book
|
||||
(position 200)
|
||||
(current-page 0)
|
||||
(dockable "pika-palette-editor"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(show-button-bar "true")
|
||||
(edit-active "true")
|
||||
(current-data "Color History")
|
||||
(zoom-factor "2.80"))))))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-file-open-dialog")
|
||||
(position 390 140)
|
||||
(size 900 815))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-image-new-dialog")
|
||||
(position 100 100))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-empty-image-window")
|
||||
(position 140 30)
|
||||
(size 610 190)
|
||||
(open-on-exit))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-single-image-window")
|
||||
(position 10 40)
|
||||
(size 900 600))
|
||||
|
||||
(hide-docks no)
|
||||
(single-window-mode no)
|
||||
(show-tabs yes)
|
||||
(tabs-position 0)
|
||||
(last-tip-shown 0)
|
||||
|
||||
# end of sessionrc
|
75
app/tests/pikadir/sessionrc-expected-single-window
Normal file
75
app/tests/pikadir/sessionrc-expected-single-window
Normal file
@ -0,0 +1,75 @@
|
||||
# PIKA sessionrc
|
||||
#
|
||||
# This file takes session-specific info (that is info, you want to keep
|
||||
# between two PIKA sessions). You are not supposed to edit it manually, but
|
||||
# of course you can do. The sessionrc will be entirely rewritten every time
|
||||
# you quit PIKA. If this file isn't found, defaults are used.
|
||||
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-file-open-dialog")
|
||||
(position 390 140)
|
||||
(size 900 815))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-image-new-dialog")
|
||||
(position 100 100))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-empty-image-window")
|
||||
(position 140 30)
|
||||
(size 1285 750))
|
||||
(session-info "toplevel"
|
||||
(factory-entry "pika-single-image-window")
|
||||
(position 140 30)
|
||||
(size 1050 770)
|
||||
(open-on-exit)
|
||||
(aux-info
|
||||
(left-docks-width "80")
|
||||
(right-docks-width "400")
|
||||
(maximized "no"))
|
||||
(pika-toolbox
|
||||
(side left))
|
||||
(pika-dock
|
||||
(side right)
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-layer-list"
|
||||
(tab-style icon)
|
||||
(preview-size 32)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))
|
||||
(book
|
||||
(position 380)
|
||||
(current-page 0)
|
||||
(dockable "pika-brush-grid"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true")))))
|
||||
(pika-dock
|
||||
(side right)
|
||||
(position 200)
|
||||
(book
|
||||
(current-page 0)
|
||||
(dockable "pika-tool-options"
|
||||
(tab-style icon)
|
||||
(aux-info
|
||||
(show-button-bar "true")))))
|
||||
(pika-dock
|
||||
(side right)
|
||||
(position 550)
|
||||
(book
|
||||
(current-page 1)
|
||||
(dockable "pika-pattern-grid"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true")))
|
||||
(dockable "pika-gradient-list"
|
||||
(tab-style preview)
|
||||
(aux-info
|
||||
(show-button-bar "true"))))))
|
||||
|
||||
(hide-docks no)
|
||||
(single-window-mode yes)
|
||||
(show-tabs yes)
|
||||
(tabs-position 0)
|
||||
(last-tip-shown 0)
|
||||
|
||||
# end of sessionrc
|
24
app/tests/pikadir/tags.xml
Normal file
24
app/tests/pikadir/tags.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<tags>
|
||||
|
||||
<resource identifier="pika-brush-clipboard" checksum="157dcef48665ab465439cfaf10d6feeb">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-pattern-clipboard" checksum="eff9598f9f61c1dc78d842f1798c2ab8">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-bg-hsv-cw" checksum="86589f70c8a7777c6e2d1d14b99e3759">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-bg-hsv-ccw" checksum="65aacbbd72d99ff20ca1bd310f0a21a5">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-bg-rgb" checksum="12ad9439c57e897e50fb0399439e5b2b">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-bg-rgb" checksum="4a878c6cfae0b0e03c0834723daadf92">
|
||||
</resource>
|
||||
|
||||
<resource identifier="pika-gradient-fg-transparent" checksum="1491f74caf057a39c8193470da2d2a29">
|
||||
</resource>
|
||||
</tags>
|
297
app/tests/test-core.c
Normal file
297
app/tests/test-core.c
Normal file
@ -0,0 +1,297 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 2009 Martin Nordholts
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "widgets/widgets-types.h"
|
||||
|
||||
#include "widgets/pikauimanager.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikacontext.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer.h"
|
||||
#include "core/pikalayer-new.h"
|
||||
|
||||
#include "operations/pikalevelsconfig.h"
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include "pika-app-test-utils.h"
|
||||
|
||||
|
||||
#define PIKA_TEST_IMAGE_SIZE 100
|
||||
|
||||
#define ADD_IMAGE_TEST(function) \
|
||||
g_test_add ("/pika-core/" #function, \
|
||||
PikaTestFixture, \
|
||||
pika, \
|
||||
pika_test_image_setup, \
|
||||
function, \
|
||||
pika_test_image_teardown);
|
||||
|
||||
#define ADD_TEST(function) \
|
||||
g_test_add ("/pika-core/" #function, \
|
||||
PikaTestFixture, \
|
||||
pika, \
|
||||
NULL, \
|
||||
function, \
|
||||
NULL);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PikaImage *image;
|
||||
} PikaTestFixture;
|
||||
|
||||
|
||||
static void pika_test_image_setup (PikaTestFixture *fixture,
|
||||
gconstpointer data);
|
||||
static void pika_test_image_teardown (PikaTestFixture *fixture,
|
||||
gconstpointer data);
|
||||
|
||||
|
||||
/**
|
||||
* pika_test_image_setup:
|
||||
* @fixture:
|
||||
* @data:
|
||||
*
|
||||
* Test fixture setup for a single image.
|
||||
**/
|
||||
static void
|
||||
pika_test_image_setup (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
|
||||
fixture->image = pika_image_new (pika,
|
||||
PIKA_TEST_IMAGE_SIZE,
|
||||
PIKA_TEST_IMAGE_SIZE,
|
||||
PIKA_RGB,
|
||||
PIKA_PRECISION_FLOAT_LINEAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_image_teardown:
|
||||
* @fixture:
|
||||
* @data:
|
||||
*
|
||||
* Test fixture teardown for a single image.
|
||||
**/
|
||||
static void
|
||||
pika_test_image_teardown (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
g_object_unref (fixture->image);
|
||||
}
|
||||
|
||||
/**
|
||||
* rotate_non_overlapping:
|
||||
* @fixture:
|
||||
* @data:
|
||||
*
|
||||
* Super basic test that makes sure we can add a layer
|
||||
* and call pika_item_rotate with center at (0, -10)
|
||||
* without triggering a failed assertion .
|
||||
**/
|
||||
static void
|
||||
rotate_non_overlapping (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image = fixture->image;
|
||||
PikaLayer *layer;
|
||||
PikaContext *context = pika_context_new (pika, "Test", NULL /*template*/);
|
||||
gboolean result;
|
||||
|
||||
g_assert_cmpint (pika_image_get_n_layers (image), ==, 0);
|
||||
|
||||
layer = pika_layer_new (image,
|
||||
PIKA_TEST_IMAGE_SIZE,
|
||||
PIKA_TEST_IMAGE_SIZE,
|
||||
babl_format ("R'G'B'A u8"),
|
||||
"Test Layer",
|
||||
PIKA_OPACITY_OPAQUE,
|
||||
PIKA_LAYER_MODE_NORMAL);
|
||||
|
||||
g_assert_cmpint (PIKA_IS_LAYER (layer), ==, TRUE);
|
||||
|
||||
result = pika_image_add_layer (image,
|
||||
layer,
|
||||
PIKA_IMAGE_ACTIVE_PARENT,
|
||||
0,
|
||||
FALSE);
|
||||
|
||||
pika_item_rotate (PIKA_ITEM (layer), context, PIKA_ROTATE_90, 0., -10., TRUE);
|
||||
|
||||
g_assert_cmpint (result, ==, TRUE);
|
||||
g_assert_cmpint (pika_image_get_n_layers (image), ==, 1);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* add_layer:
|
||||
* @fixture:
|
||||
* @data:
|
||||
*
|
||||
* Super basic test that makes sure we can add a layer.
|
||||
**/
|
||||
static void
|
||||
add_layer (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
PikaImage *image = fixture->image;
|
||||
PikaLayer *layer;
|
||||
gboolean result;
|
||||
|
||||
g_assert_cmpint (pika_image_get_n_layers (image), ==, 0);
|
||||
|
||||
layer = pika_layer_new (image,
|
||||
PIKA_TEST_IMAGE_SIZE,
|
||||
PIKA_TEST_IMAGE_SIZE,
|
||||
babl_format ("R'G'B'A u8"),
|
||||
"Test Layer",
|
||||
PIKA_OPACITY_OPAQUE,
|
||||
PIKA_LAYER_MODE_NORMAL);
|
||||
|
||||
g_assert_cmpint (PIKA_IS_LAYER (layer), ==, TRUE);
|
||||
|
||||
result = pika_image_add_layer (image,
|
||||
layer,
|
||||
PIKA_IMAGE_ACTIVE_PARENT,
|
||||
0,
|
||||
FALSE);
|
||||
|
||||
g_assert_cmpint (result, ==, TRUE);
|
||||
g_assert_cmpint (pika_image_get_n_layers (image), ==, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove_layer:
|
||||
* @fixture:
|
||||
* @data:
|
||||
*
|
||||
* Super basic test that makes sure we can remove a layer.
|
||||
**/
|
||||
static void
|
||||
remove_layer (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
PikaImage *image = fixture->image;
|
||||
PikaLayer *layer;
|
||||
gboolean result;
|
||||
|
||||
g_assert_cmpint (pika_image_get_n_layers (image), ==, 0);
|
||||
|
||||
layer = pika_layer_new (image,
|
||||
PIKA_TEST_IMAGE_SIZE,
|
||||
PIKA_TEST_IMAGE_SIZE,
|
||||
babl_format ("R'G'B'A u8"),
|
||||
"Test Layer",
|
||||
PIKA_OPACITY_OPAQUE,
|
||||
PIKA_LAYER_MODE_NORMAL);
|
||||
|
||||
g_assert_cmpint (PIKA_IS_LAYER (layer), ==, TRUE);
|
||||
|
||||
result = pika_image_add_layer (image,
|
||||
layer,
|
||||
PIKA_IMAGE_ACTIVE_PARENT,
|
||||
0,
|
||||
FALSE);
|
||||
|
||||
g_assert_cmpint (result, ==, TRUE);
|
||||
g_assert_cmpint (pika_image_get_n_layers (image), ==, 1);
|
||||
|
||||
pika_image_remove_layer (image,
|
||||
layer,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (pika_image_get_n_layers (image), ==, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* white_graypoint_in_red_levels:
|
||||
* @fixture:
|
||||
* @data:
|
||||
*
|
||||
* Makes sure the levels algorithm can handle when the graypoint is
|
||||
* white. It's easy to get a divide by zero problem when trying to
|
||||
* calculate what gamma will give a white graypoint.
|
||||
**/
|
||||
static void
|
||||
white_graypoint_in_red_levels (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
PikaRGB black = { 0, 0, 0, 0 };
|
||||
PikaRGB gray = { 1, 1, 1, 1 };
|
||||
PikaRGB white = { 1, 1, 1, 1 };
|
||||
PikaHistogramChannel channel = PIKA_HISTOGRAM_RED;
|
||||
PikaLevelsConfig *config;
|
||||
|
||||
config = g_object_new (PIKA_TYPE_LEVELS_CONFIG, NULL);
|
||||
|
||||
pika_levels_config_adjust_by_colors (config,
|
||||
channel,
|
||||
&black,
|
||||
&gray,
|
||||
&white);
|
||||
|
||||
/* Make sure we didn't end up with an invalid gamma value */
|
||||
g_object_set (config,
|
||||
"gamma", config->gamma[channel],
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
Pika *pika;
|
||||
int result;
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
pika_test_utils_set_pika3_directory ("PIKA_TESTING_ABS_TOP_SRCDIR",
|
||||
"app/tests/pikadir");
|
||||
|
||||
/* We share the same application instance across all tests */
|
||||
pika = pika_init_for_testing ();
|
||||
|
||||
/* Add tests */
|
||||
ADD_IMAGE_TEST (add_layer);
|
||||
ADD_IMAGE_TEST (remove_layer);
|
||||
ADD_IMAGE_TEST (rotate_non_overlapping);
|
||||
ADD_TEST (white_graypoint_in_red_levels);
|
||||
|
||||
/* Run the tests */
|
||||
result = g_test_run ();
|
||||
|
||||
/* Don't write files to the source dir */
|
||||
pika_test_utils_set_pika3_directory ("PIKA_TESTING_ABS_TOP_BUILDDIR",
|
||||
"app/tests/pikadir-output");
|
||||
|
||||
/* Exit so we don't break script-fu plug-in wire */
|
||||
pika_exit (pika, TRUE);
|
||||
|
||||
return result;
|
||||
}
|
231
app/tests/test-pikaidtable.c
Normal file
231
app/tests/test-pikaidtable.c
Normal file
@ -0,0 +1,231 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 2011 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "core/core-types.h"
|
||||
|
||||
#include "core/pikaidtable.h"
|
||||
|
||||
|
||||
#define ADD_TEST(function) \
|
||||
g_test_add ("/pikaidtable/" #function, \
|
||||
PikaTestFixture, \
|
||||
NULL, \
|
||||
pika_test_id_table_setup, \
|
||||
pika_test_id_table_ ## function, \
|
||||
pika_test_id_table_teardown);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PikaIdTable *id_table;
|
||||
} PikaTestFixture;
|
||||
|
||||
|
||||
static gpointer data1 = (gpointer) 0x00000001;
|
||||
static gpointer data2 = (gpointer) 0x00000002;
|
||||
|
||||
|
||||
static void
|
||||
pika_test_id_table_setup (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
fixture->id_table = pika_id_table_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
pika_test_id_table_teardown (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
g_object_unref (fixture->id_table);
|
||||
fixture->id_table = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_id_table_insert_and_lookup:
|
||||
*
|
||||
* Test that insert and lookup works.
|
||||
**/
|
||||
static void
|
||||
pika_test_id_table_insert_and_lookup (PikaTestFixture *f,
|
||||
gconstpointer data)
|
||||
{
|
||||
gint ret_id = pika_id_table_insert (f->id_table, data1);
|
||||
gpointer ret_data = pika_id_table_lookup (f->id_table, ret_id);
|
||||
|
||||
g_assert (ret_data == data1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_id_table_insert_twice:
|
||||
*
|
||||
* Test that two consecutive inserts generates different IDs.
|
||||
**/
|
||||
static void
|
||||
pika_test_id_table_insert_twice (PikaTestFixture *f,
|
||||
gconstpointer data)
|
||||
{
|
||||
gint ret_id = pika_id_table_insert (f->id_table, data1);
|
||||
gpointer ret_data = pika_id_table_lookup (f->id_table, ret_id);
|
||||
gint ret_id2 = pika_id_table_insert (f->id_table, data2);
|
||||
gpointer ret_data2 = pika_id_table_lookup (f->id_table, ret_id2);
|
||||
|
||||
g_assert (ret_id != ret_id2);
|
||||
g_assert (ret_data == data1);
|
||||
g_assert (ret_data2 == data2);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_id_table_insert_with_id:
|
||||
*
|
||||
* Test that it is possible to insert data with a specific ID.
|
||||
**/
|
||||
static void
|
||||
pika_test_id_table_insert_with_id (PikaTestFixture *f,
|
||||
gconstpointer data)
|
||||
{
|
||||
const int id = 10;
|
||||
|
||||
int ret_id = pika_id_table_insert_with_id (f->id_table, id, data1);
|
||||
gpointer ret_data = pika_id_table_lookup (f->id_table, id);
|
||||
|
||||
g_assert (ret_id == id);
|
||||
g_assert (ret_data == data1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_id_table_insert_with_id_existing:
|
||||
*
|
||||
* Test that it is not possible to insert data with a specific ID if
|
||||
* that ID already is inserted.
|
||||
**/
|
||||
static void
|
||||
pika_test_id_table_insert_with_id_existing (PikaTestFixture *f,
|
||||
gconstpointer data)
|
||||
{
|
||||
const int id = 10;
|
||||
|
||||
int ret_id = pika_id_table_insert_with_id (f->id_table, id, data1);
|
||||
gpointer ret_data = pika_id_table_lookup (f->id_table, ret_id);
|
||||
int ret_id2 = pika_id_table_insert_with_id (f->id_table, id, data2);
|
||||
gpointer ret_data2 = pika_id_table_lookup (f->id_table, ret_id2);
|
||||
|
||||
g_assert (id == ret_id);
|
||||
g_assert (ret_id2 == -1);
|
||||
g_assert (ret_data == data1);
|
||||
g_assert (ret_data2 == NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_id_table_replace:
|
||||
*
|
||||
* Test that it is possible to replace data with a given ID with
|
||||
* different data.
|
||||
**/
|
||||
static void
|
||||
pika_test_id_table_replace (PikaTestFixture *f,
|
||||
gconstpointer data)
|
||||
{
|
||||
int ret_id = pika_id_table_insert (f->id_table, data1);
|
||||
gpointer ret_data;
|
||||
|
||||
pika_id_table_replace (f->id_table, ret_id, data2);
|
||||
ret_data = pika_id_table_lookup (f->id_table, ret_id);
|
||||
|
||||
g_assert (ret_data == data2);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_id_table_replace_as_insert:
|
||||
*
|
||||
* Test that replace works like insert when there is no data to
|
||||
* replace.
|
||||
**/
|
||||
static void
|
||||
pika_test_id_table_replace_as_insert (PikaTestFixture *f,
|
||||
gconstpointer data)
|
||||
{
|
||||
const int id = 10;
|
||||
|
||||
gpointer ret_data;
|
||||
|
||||
pika_id_table_replace (f->id_table, id, data1);
|
||||
ret_data = pika_id_table_lookup (f->id_table, id);
|
||||
|
||||
g_assert (ret_data == data1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_id_table_remove:
|
||||
*
|
||||
* Test that it is possible to remove data identified by the ID:
|
||||
**/
|
||||
static void
|
||||
pika_test_id_table_remove (PikaTestFixture *f,
|
||||
gconstpointer data)
|
||||
{
|
||||
gint ret_id = pika_id_table_insert (f->id_table, data1);
|
||||
void *ret_data = pika_id_table_lookup (f->id_table, ret_id);
|
||||
gboolean remove_successful = pika_id_table_remove (f->id_table, ret_id);
|
||||
void *ret_data2 = pika_id_table_lookup (f->id_table, ret_id);
|
||||
|
||||
g_assert (remove_successful);
|
||||
g_assert (ret_data == data1);
|
||||
g_assert (ret_data2 == NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_id_table_remove_non_existing:
|
||||
*
|
||||
* Tests that things work properly when trying to remove data with an
|
||||
* ID that doesn't exist.
|
||||
**/
|
||||
static void
|
||||
pika_test_id_table_remove_non_existing (PikaTestFixture *f,
|
||||
gconstpointer data)
|
||||
{
|
||||
const int id = 10;
|
||||
|
||||
gboolean remove_successful = pika_id_table_remove (f->id_table, id);
|
||||
void *ret_data = pika_id_table_lookup (f->id_table, id);
|
||||
|
||||
g_assert (! remove_successful);
|
||||
g_assert (ret_data == NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
ADD_TEST (insert_and_lookup);
|
||||
ADD_TEST (insert_twice);
|
||||
ADD_TEST (insert_with_id);
|
||||
ADD_TEST (insert_with_id_existing);
|
||||
ADD_TEST (replace);
|
||||
ADD_TEST (replace_as_insert);
|
||||
ADD_TEST (remove);
|
||||
ADD_TEST (remove_non_existing);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
391
app/tests/test-save-and-export.c
Normal file
391
app/tests/test-save-and-export.c
Normal file
@ -0,0 +1,391 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gegl.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikamath/pikamath.h"
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "dialogs/dialogs-types.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikachannel.h"
|
||||
#include "core/pikacontext.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer.h"
|
||||
#include "core/pikatoolinfo.h"
|
||||
#include "core/pikatooloptions.h"
|
||||
|
||||
#include "plug-in/pikapluginmanager-file.h"
|
||||
|
||||
#include "file/file-open.h"
|
||||
#include "file/file-save.h"
|
||||
|
||||
#include "widgets/pikadialogfactory.h"
|
||||
#include "widgets/pikadock.h"
|
||||
#include "widgets/pikadockable.h"
|
||||
#include "widgets/pikadockbook.h"
|
||||
#include "widgets/pikadocked.h"
|
||||
#include "widgets/pikadockwindow.h"
|
||||
#include "widgets/pikahelp-ids.h"
|
||||
#include "widgets/pikasessioninfo.h"
|
||||
#include "widgets/pikatoolbox.h"
|
||||
#include "widgets/pikatooloptionseditor.h"
|
||||
#include "widgets/pikauimanager.h"
|
||||
#include "widgets/pikawidgets-utils.h"
|
||||
|
||||
#include "display/pikadisplay.h"
|
||||
#include "display/pikadisplayshell.h"
|
||||
#include "display/pikadisplayshell-scale.h"
|
||||
#include "display/pikadisplayshell-transform.h"
|
||||
#include "display/pikaimagewindow.h"
|
||||
|
||||
#include "pikacoreapp.h"
|
||||
|
||||
#include "pika-app-test-utils.h"
|
||||
#include "tests.h"
|
||||
|
||||
|
||||
#define ADD_TEST(function) \
|
||||
g_test_add_data_func ("/pika-save-and-export/" #function, pika, function);
|
||||
|
||||
|
||||
typedef gboolean (*PikaUiTestFunc) (GObject *object);
|
||||
|
||||
|
||||
/**
|
||||
* new_file_has_no_files:
|
||||
* @data:
|
||||
*
|
||||
* Tests that the URIs are correct for a newly created image.
|
||||
**/
|
||||
static void
|
||||
new_file_has_no_files (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image = pika_test_utils_create_image_from_dialog (pika);
|
||||
|
||||
g_assert (pika_image_get_file (image) == NULL);
|
||||
g_assert (pika_image_get_imported_file (image) == NULL);
|
||||
g_assert (pika_image_get_exported_file (image) == NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* opened_xcf_file_files:
|
||||
* @data:
|
||||
*
|
||||
* Tests that PikaImage URIs are correct for an XCF file that has just
|
||||
* been opened.
|
||||
**/
|
||||
static void
|
||||
opened_xcf_file_files (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image;
|
||||
GFile *file;
|
||||
gchar *filename;
|
||||
PikaPDBStatusType status;
|
||||
|
||||
filename = g_build_filename (g_getenv ("PIKA_TESTING_ABS_TOP_SRCDIR"),
|
||||
"app/tests/files/pika-2-6-file.xcf",
|
||||
NULL);
|
||||
file = g_file_new_for_path (filename);
|
||||
g_free (filename);
|
||||
|
||||
image = file_open_image (pika,
|
||||
pika_get_user_context (pika),
|
||||
NULL /*progress*/,
|
||||
file,
|
||||
FALSE /*as_new*/,
|
||||
NULL /*file_proc*/,
|
||||
PIKA_RUN_NONINTERACTIVE,
|
||||
&status,
|
||||
NULL /*mime_type*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_assert (g_file_equal (pika_image_get_file (image), file));
|
||||
g_assert (pika_image_get_imported_file (image) == NULL);
|
||||
g_assert (pika_image_get_exported_file (image) == NULL);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
/**
|
||||
* imported_file_files:
|
||||
* @data:
|
||||
*
|
||||
* Tests that URIs are correct for an imported image.
|
||||
**/
|
||||
static void
|
||||
imported_file_files (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image;
|
||||
GFile *file;
|
||||
gchar *filename;
|
||||
PikaPDBStatusType status;
|
||||
|
||||
filename = g_build_filename (g_getenv ("PIKA_TESTING_ABS_TOP_SRCDIR"),
|
||||
"desktop/64x64/pika.png",
|
||||
NULL);
|
||||
g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
|
||||
file = g_file_new_for_path (filename);
|
||||
g_free (filename);
|
||||
|
||||
image = file_open_image (pika,
|
||||
pika_get_user_context (pika),
|
||||
NULL /*progress*/,
|
||||
file,
|
||||
FALSE /*as_new*/,
|
||||
NULL /*file_proc*/,
|
||||
PIKA_RUN_NONINTERACTIVE,
|
||||
&status,
|
||||
NULL /*mime_type*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_assert (pika_image_get_file (image) == NULL);
|
||||
g_assert (g_file_equal (pika_image_get_imported_file (image), file));
|
||||
g_assert (pika_image_get_exported_file (image) == NULL);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
/**
|
||||
* saved_imported_file_files:
|
||||
* @data:
|
||||
*
|
||||
* Tests that the URIs are correct for an image that has been imported
|
||||
* and then saved.
|
||||
**/
|
||||
static void
|
||||
saved_imported_file_files (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image;
|
||||
GFile *import_file;
|
||||
gchar *import_filename;
|
||||
GFile *save_file;
|
||||
gchar *save_filename;
|
||||
PikaPDBStatusType status;
|
||||
PikaPlugInProcedure *proc;
|
||||
|
||||
import_filename = g_build_filename (g_getenv ("PIKA_TESTING_ABS_TOP_SRCDIR"),
|
||||
"desktop/64x64/pika.png",
|
||||
NULL);
|
||||
import_file = g_file_new_for_path (import_filename);
|
||||
g_free (import_filename);
|
||||
|
||||
save_filename = g_build_filename (g_get_tmp_dir (), "pika-test.xcf", NULL);
|
||||
save_file = g_file_new_for_path (save_filename);
|
||||
g_free (save_filename);
|
||||
|
||||
/* Import */
|
||||
image = file_open_image (pika,
|
||||
pika_get_user_context (pika),
|
||||
NULL /*progress*/,
|
||||
import_file,
|
||||
FALSE /*as_new*/,
|
||||
NULL /*file_proc*/,
|
||||
PIKA_RUN_NONINTERACTIVE,
|
||||
&status,
|
||||
NULL /*mime_type*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_object_unref (import_file);
|
||||
|
||||
/* Save */
|
||||
proc = pika_plug_in_manager_file_procedure_find (image->pika->plug_in_manager,
|
||||
PIKA_FILE_PROCEDURE_GROUP_SAVE,
|
||||
save_file,
|
||||
NULL /*error*/);
|
||||
file_save (pika,
|
||||
image,
|
||||
NULL /*progress*/,
|
||||
save_file,
|
||||
proc,
|
||||
PIKA_RUN_NONINTERACTIVE,
|
||||
TRUE /*change_saved_state*/,
|
||||
FALSE /*export_backward*/,
|
||||
FALSE /*export_forward*/,
|
||||
NULL /*error*/);
|
||||
|
||||
/* Assert */
|
||||
g_assert (g_file_equal (pika_image_get_file (image), save_file));
|
||||
g_assert (pika_image_get_imported_file (image) == NULL);
|
||||
g_assert (pika_image_get_exported_file (image) == NULL);
|
||||
|
||||
g_file_delete (save_file, NULL, NULL);
|
||||
g_object_unref (save_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* exported_file_files:
|
||||
* @data:
|
||||
*
|
||||
* Tests that the URIs for an exported, newly created file are
|
||||
* correct.
|
||||
**/
|
||||
static void
|
||||
exported_file_files (gconstpointer data)
|
||||
{
|
||||
GFile *save_file;
|
||||
gchar *save_filename;
|
||||
PikaPlugInProcedure *proc;
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image = pika_test_utils_create_image_from_dialog (pika);
|
||||
|
||||
save_filename = g_build_filename (g_get_tmp_dir (), "pika-test.png", NULL);
|
||||
save_file = g_file_new_for_path (save_filename);
|
||||
g_free (save_filename);
|
||||
|
||||
proc = pika_plug_in_manager_file_procedure_find (image->pika->plug_in_manager,
|
||||
PIKA_FILE_PROCEDURE_GROUP_EXPORT,
|
||||
save_file,
|
||||
NULL /*error*/);
|
||||
file_save (pika,
|
||||
image,
|
||||
NULL /*progress*/,
|
||||
save_file,
|
||||
proc,
|
||||
PIKA_RUN_NONINTERACTIVE,
|
||||
FALSE /*change_saved_state*/,
|
||||
FALSE /*export_backward*/,
|
||||
TRUE /*export_forward*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_assert (pika_image_get_file (image) == NULL);
|
||||
g_assert (pika_image_get_imported_file (image) == NULL);
|
||||
g_assert (g_file_equal (pika_image_get_exported_file (image), save_file));
|
||||
|
||||
g_file_delete (save_file, NULL, NULL);
|
||||
g_object_unref (save_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear_import_file_after_export:
|
||||
* @data:
|
||||
*
|
||||
* Tests that after a XCF file that was imported has been exported,
|
||||
* the import URI is cleared. An image can not be considered both
|
||||
* imported and exported at the same time.
|
||||
**/
|
||||
static void
|
||||
clear_import_file_after_export (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image;
|
||||
GFile *file;
|
||||
gchar *filename;
|
||||
GFile *save_file;
|
||||
gchar *save_filename;
|
||||
PikaPlugInProcedure *proc;
|
||||
PikaPDBStatusType status;
|
||||
|
||||
filename = g_build_filename (g_getenv ("PIKA_TESTING_ABS_TOP_SRCDIR"),
|
||||
"desktop/64x64/pika.png",
|
||||
NULL);
|
||||
file = g_file_new_for_path (filename);
|
||||
g_free (filename);
|
||||
|
||||
image = file_open_image (pika,
|
||||
pika_get_user_context (pika),
|
||||
NULL /*progress*/,
|
||||
file,
|
||||
FALSE /*as_new*/,
|
||||
NULL /*file_proc*/,
|
||||
PIKA_RUN_NONINTERACTIVE,
|
||||
&status,
|
||||
NULL /*mime_type*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_assert (pika_image_get_file (image) == NULL);
|
||||
g_assert (g_file_equal (pika_image_get_imported_file (image), file));
|
||||
g_assert (pika_image_get_exported_file (image) == NULL);
|
||||
|
||||
g_object_unref (file);
|
||||
|
||||
save_filename = g_build_filename (g_get_tmp_dir (), "pika-test.png", NULL);
|
||||
save_file = g_file_new_for_path (save_filename);
|
||||
g_free (save_filename);
|
||||
|
||||
proc = pika_plug_in_manager_file_procedure_find (image->pika->plug_in_manager,
|
||||
PIKA_FILE_PROCEDURE_GROUP_EXPORT,
|
||||
save_file,
|
||||
NULL /*error*/);
|
||||
file_save (pika,
|
||||
image,
|
||||
NULL /*progress*/,
|
||||
save_file,
|
||||
proc,
|
||||
PIKA_RUN_NONINTERACTIVE,
|
||||
FALSE /*change_saved_state*/,
|
||||
FALSE /*export_backward*/,
|
||||
TRUE /*export_forward*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_assert (pika_image_get_file (image) == NULL);
|
||||
g_assert (pika_image_get_imported_file (image) == NULL);
|
||||
g_assert (g_file_equal (pika_image_get_exported_file (image), save_file));
|
||||
|
||||
g_file_delete (save_file, NULL, NULL);
|
||||
g_object_unref (save_file);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc,
|
||||
char **argv)
|
||||
{
|
||||
Pika *pika = NULL;
|
||||
gint result = -1;
|
||||
|
||||
pika_test_bail_if_no_display ();
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
pika_test_utils_setup_menus_path ();
|
||||
|
||||
/* Start up PIKA */
|
||||
pika = pika_init_for_gui_testing (TRUE /*show_gui*/);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
ADD_TEST (new_file_has_no_files);
|
||||
ADD_TEST (opened_xcf_file_files);
|
||||
ADD_TEST (imported_file_files);
|
||||
ADD_TEST (saved_imported_file_files);
|
||||
ADD_TEST (exported_file_files);
|
||||
ADD_TEST (clear_import_file_after_export);
|
||||
|
||||
/* Run the tests and return status */
|
||||
g_application_run (pika->app, 0, NULL);
|
||||
result = pika_core_app_get_exit_status (PIKA_CORE_APP (pika->app));
|
||||
|
||||
g_application_quit (G_APPLICATION (pika->app));
|
||||
g_clear_object (&pika->app);
|
||||
|
||||
return result;
|
||||
}
|
75
app/tests/test-session-2-8-compatibility-multi-window.c
Normal file
75
app/tests/test-session-2-8-compatibility-multi-window.c
Normal file
@ -0,0 +1,75 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 2011 Martin Nordholts
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "dialogs/dialogs-types.h"
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include "pika-test-session-utils.h"
|
||||
#include "pika-app-test-utils.h"
|
||||
|
||||
|
||||
#define ADD_TEST(function) \
|
||||
g_test_add_func ("/pika-session-2-8-compatibility-multi-window/" #function, \
|
||||
function);
|
||||
|
||||
#define SKIP_TEST(function) \
|
||||
g_test_add_func ("/pika-session-2-8-compatibility-multi-window/subprocess/" #function, \
|
||||
function);
|
||||
|
||||
|
||||
/**
|
||||
* Tests that a single-window sessionrc in PIKA 2.8 format is loaded
|
||||
* and written (thus also interpreted) like we expect.
|
||||
**/
|
||||
static void
|
||||
read_and_write_session_files (void)
|
||||
{
|
||||
pika_test_session_load_and_write_session_files ("sessionrc-2-8-multi-window",
|
||||
"dockrc-2-8",
|
||||
"sessionrc-expected-multi-window",
|
||||
"dockrc-expected",
|
||||
FALSE /*single_window_mode*/);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pika_test_bail_if_no_display ();
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
#ifdef HAVE_XVFB_RUN
|
||||
ADD_TEST (read_and_write_session_files);
|
||||
#else
|
||||
SKIP_TEST (read_and_write_session_files);
|
||||
#endif
|
||||
|
||||
/* Don't bother freeing stuff, the process is short-lived */
|
||||
#ifdef HAVE_XVFB_RUN
|
||||
return g_test_run ();
|
||||
#else
|
||||
return PIKA_EXIT_TEST_SKIPPED;
|
||||
#endif
|
||||
}
|
74
app/tests/test-session-2-8-compatibility-single-window.c
Normal file
74
app/tests/test-session-2-8-compatibility-single-window.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 2011 Martin Nordholts
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "dialogs/dialogs-types.h"
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include "pika-test-session-utils.h"
|
||||
#include "pika-app-test-utils.h"
|
||||
|
||||
|
||||
#define ADD_TEST(function) \
|
||||
g_test_add_func ("/pika-session-2-8-compatibility-single-window/" #function, \
|
||||
function);
|
||||
|
||||
#define SKIP_TEST(function) \
|
||||
g_test_add_func ("/pika-session-2-8-compatibility-single-window/subprocess/" #function, \
|
||||
function);
|
||||
|
||||
/**
|
||||
* Tests that a multi-window sessionrc in PIKA 2.8 format is loaded
|
||||
* and written (thus also interpreted) like we expect.
|
||||
**/
|
||||
static void
|
||||
read_and_write_session_files (void)
|
||||
{
|
||||
pika_test_session_load_and_write_session_files ("sessionrc-2-8-single-window",
|
||||
"dockrc-2-8",
|
||||
"sessionrc-expected-single-window",
|
||||
"dockrc-expected",
|
||||
TRUE /*single_window_mode*/);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pika_test_bail_if_no_display ();
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
#ifdef HAVE_XVFB_RUN
|
||||
ADD_TEST (read_and_write_session_files);
|
||||
#else
|
||||
SKIP_TEST (read_and_write_session_files);
|
||||
#endif
|
||||
|
||||
/* Don't bother freeing stuff, the process is short-lived */
|
||||
#ifdef HAVE_XVFB_RUN
|
||||
return g_test_run ();
|
||||
#else
|
||||
return PIKA_EXIT_TEST_SKIPPED;
|
||||
#endif
|
||||
}
|
159
app/tests/test-single-window-mode.c
Normal file
159
app/tests/test-single-window-mode.c
Normal file
@ -0,0 +1,159 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* test-single-window-mode.c
|
||||
* Copyright (C) 2011 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikamath/pikamath.h"
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "dialogs/dialogs-types.h"
|
||||
|
||||
#include "display/pikadisplay.h"
|
||||
#include "display/pikadisplayshell.h"
|
||||
#include "display/pikadisplayshell-scale.h"
|
||||
#include "display/pikadisplayshell-transform.h"
|
||||
#include "display/pikaimagewindow.h"
|
||||
|
||||
#include "widgets/pikadialogfactory.h"
|
||||
#include "widgets/pikadock.h"
|
||||
#include "widgets/pikadockable.h"
|
||||
#include "widgets/pikadockbook.h"
|
||||
#include "widgets/pikadockcontainer.h"
|
||||
#include "widgets/pikadocked.h"
|
||||
#include "widgets/pikadockwindow.h"
|
||||
#include "widgets/pikahelp-ids.h"
|
||||
#include "widgets/pikasessioninfo.h"
|
||||
#include "widgets/pikatoolbox.h"
|
||||
#include "widgets/pikatooloptionseditor.h"
|
||||
#include "widgets/pikauimanager.h"
|
||||
#include "widgets/pikawidgets-utils.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikachannel.h"
|
||||
#include "core/pikacontext.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer.h"
|
||||
#include "core/pikatoolinfo.h"
|
||||
#include "core/pikatooloptions.h"
|
||||
|
||||
#include "pikacoreapp.h"
|
||||
|
||||
#include "pika-app-test-utils.h"
|
||||
#include "tests.h"
|
||||
|
||||
|
||||
#define ADD_TEST(function) \
|
||||
g_test_add_data_func ("/pika-single-window-mode/" #function, pika, function);
|
||||
|
||||
|
||||
/* 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 PIKA_PAUSE (g_usleep (20 * 1000 * 1000))
|
||||
|
||||
|
||||
/**
|
||||
* new_dockable_not_in_new_window:
|
||||
* @data:
|
||||
*
|
||||
* Test that in single-window mode, new dockables are not put in new
|
||||
* windows (they should end up in the single image window).
|
||||
**/
|
||||
static void
|
||||
new_dockable_not_in_new_window (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaDialogFactory *factory = pika_dialog_factory_get_singleton ();
|
||||
gint dialogs_before = 0;
|
||||
gint toplevels_before = 0;
|
||||
gint dialogs_after = 0;
|
||||
gint toplevels_after = 0;
|
||||
GList *dialogs;
|
||||
GList *iter;
|
||||
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Count dialogs before we create the dockable */
|
||||
dialogs = pika_dialog_factory_get_open_dialogs (factory);
|
||||
dialogs_before = g_list_length (dialogs);
|
||||
for (iter = dialogs; iter; iter = g_list_next (iter))
|
||||
{
|
||||
if (gtk_widget_is_toplevel (iter->data))
|
||||
toplevels_before++;
|
||||
}
|
||||
|
||||
/* Create a dockable */
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"dialogs",
|
||||
"dialogs-undo-history");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Count dialogs after we created the dockable */
|
||||
dialogs = pika_dialog_factory_get_open_dialogs (factory);
|
||||
dialogs_after = g_list_length (dialogs);
|
||||
for (iter = dialogs; iter; iter = g_list_next (iter))
|
||||
{
|
||||
if (gtk_widget_is_toplevel (iter->data))
|
||||
toplevels_after++;
|
||||
}
|
||||
|
||||
/* We got one more session managed dialog ... */
|
||||
g_assert_cmpint (dialogs_before + 1, ==, dialogs_after);
|
||||
/* ... but no new toplevels */
|
||||
g_assert_cmpint (toplevels_before, ==, toplevels_after);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Pika *pika = NULL;
|
||||
gint result = -1;
|
||||
|
||||
pika_test_bail_if_no_display ();
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
pika_test_utils_setup_menus_path ();
|
||||
|
||||
/* Launch PIKA in single-window mode */
|
||||
g_setenv ("PIKA_TESTING_SESSIONRC_NAME", "sessionrc-2-8-single-window", TRUE /*overwrite*/);
|
||||
pika = pika_init_for_gui_testing (TRUE /*show_gui*/);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
ADD_TEST (new_dockable_not_in_new_window);
|
||||
|
||||
/* Run the tests and return status */
|
||||
g_application_run (pika->app, 0, NULL);
|
||||
result = pika_core_app_get_exit_status (PIKA_CORE_APP (pika->app));
|
||||
|
||||
/* Exit properly so we don't break script-fu plug-in wire */
|
||||
g_application_quit (G_APPLICATION (pika->app));
|
||||
g_clear_object (&pika->app);
|
||||
|
||||
return result;
|
||||
}
|
498
app/tests/test-tools.c
Normal file
498
app/tests/test-tools.c
Normal file
@ -0,0 +1,498 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikamath/pikamath.h"
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "tools/tools-types.h"
|
||||
|
||||
#include "tools/pikarectangleoptions.h"
|
||||
#include "tools/tool_manager.h"
|
||||
|
||||
#include "display/pikadisplay.h"
|
||||
#include "display/pikadisplayshell.h"
|
||||
#include "display/pikadisplayshell-callbacks.h"
|
||||
#include "display/pikadisplayshell-scale.h"
|
||||
#include "display/pikadisplayshell-tool-events.h"
|
||||
#include "display/pikadisplayshell-transform.h"
|
||||
#include "display/pikaimagewindow.h"
|
||||
|
||||
#include "widgets/pikadialogfactory.h"
|
||||
#include "widgets/pikadock.h"
|
||||
#include "widgets/pikadockable.h"
|
||||
#include "widgets/pikadockbook.h"
|
||||
#include "widgets/pikadocked.h"
|
||||
#include "widgets/pikadockwindow.h"
|
||||
#include "widgets/pikahelp-ids.h"
|
||||
#include "widgets/pikasessioninfo.h"
|
||||
#include "widgets/pikatoolbox.h"
|
||||
#include "widgets/pikatooloptionseditor.h"
|
||||
#include "widgets/pikauimanager.h"
|
||||
#include "widgets/pikawidgets-utils.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikachannel.h"
|
||||
#include "core/pikacontext.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer.h"
|
||||
#include "core/pikatoolinfo.h"
|
||||
#include "core/pikatooloptions.h"
|
||||
|
||||
#include "pikacoreapp.h"
|
||||
|
||||
#include "pika-app-test-utils.h"
|
||||
#include "tests.h"
|
||||
|
||||
|
||||
#define PIKA_TEST_IMAGE_WIDTH 150
|
||||
#define PIKA_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 PIKA_PAUSE (g_usleep (2 * 1000 * 1000))
|
||||
|
||||
#define ADD_TEST(function) \
|
||||
g_test_add ("/pika-tools/" #function, \
|
||||
PikaTestFixture, \
|
||||
pika, \
|
||||
pika_tools_setup_image, \
|
||||
function, \
|
||||
pika_tools_teardown_image);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int avoid_sizeof_zero;
|
||||
} PikaTestFixture;
|
||||
|
||||
|
||||
static void pika_tools_setup_image (PikaTestFixture *fixture,
|
||||
gconstpointer data);
|
||||
static void pika_tools_teardown_image (PikaTestFixture *fixture,
|
||||
gconstpointer data);
|
||||
static void pika_tools_synthesize_image_click_drag_release (PikaDisplayShell *shell,
|
||||
gdouble start_image_x,
|
||||
gdouble start_image_y,
|
||||
gdouble end_image_x,
|
||||
gdouble end_image_y,
|
||||
gint button,
|
||||
GdkModifierType modifiers);
|
||||
static PikaDisplay * pika_test_get_only_display (Pika *pika);
|
||||
static PikaImage * pika_test_get_only_image (Pika *pika);
|
||||
static PikaDisplayShell * pika_test_get_only_display_shell (Pika *pika);
|
||||
|
||||
|
||||
static void
|
||||
pika_tools_setup_image (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
|
||||
pika_test_utils_create_image (pika,
|
||||
PIKA_TEST_IMAGE_WIDTH,
|
||||
PIKA_TEST_IMAGE_HEIGHT);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
}
|
||||
|
||||
static void
|
||||
pika_tools_teardown_image (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
|
||||
g_object_unref (pika_test_get_only_image (pika));
|
||||
pika_display_close (pika_test_get_only_display (pika));
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_tools_set_tool:
|
||||
* @pika:
|
||||
* @tool_id:
|
||||
* @display:
|
||||
*
|
||||
* Makes sure the given tool is the active tool and that the passed
|
||||
* display is the focused tool display.
|
||||
**/
|
||||
static void
|
||||
pika_tools_set_tool (Pika *pika,
|
||||
const gchar *tool_id,
|
||||
PikaDisplay *display)
|
||||
{
|
||||
/* Activate tool and setup active display for the new tool */
|
||||
pika_context_set_tool (pika_get_user_context (pika),
|
||||
pika_get_tool_info (pika, tool_id));
|
||||
tool_manager_focus_display_active (pika, display);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_get_only_display:
|
||||
* @pika:
|
||||
*
|
||||
* Asserts that there only is one image and display and then
|
||||
* returns the display.
|
||||
*
|
||||
* Returns: The #PikaDisplay.
|
||||
**/
|
||||
static PikaDisplay *
|
||||
pika_test_get_only_display (Pika *pika)
|
||||
{
|
||||
g_assert (g_list_length (pika_get_image_iter (pika)) == 1);
|
||||
g_assert (g_list_length (pika_get_display_iter (pika)) == 1);
|
||||
|
||||
return PIKA_DISPLAY (pika_get_display_iter (pika)->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_get_only_display_shell:
|
||||
* @pika:
|
||||
*
|
||||
* Asserts that there only is one image and display shell and then
|
||||
* returns the display shell.
|
||||
*
|
||||
* Returns: The #PikaDisplayShell.
|
||||
**/
|
||||
static PikaDisplayShell *
|
||||
pika_test_get_only_display_shell (Pika *pika)
|
||||
{
|
||||
return pika_display_get_shell (pika_test_get_only_display (pika));
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_get_only_image:
|
||||
* @pika:
|
||||
*
|
||||
* Asserts that there is only one image and returns that.
|
||||
*
|
||||
* Returns: The #PikaImage.
|
||||
**/
|
||||
static PikaImage *
|
||||
pika_test_get_only_image (Pika *pika)
|
||||
{
|
||||
g_assert (g_list_length (pika_get_image_iter (pika)) == 1);
|
||||
g_assert (g_list_length (pika_get_display_iter (pika)) == 1);
|
||||
|
||||
return PIKA_IMAGE (pika_get_image_iter (pika)->data);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_test_synthesize_tool_button_event (PikaDisplayShell *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_window_get_display (window);
|
||||
GdkSeat *seat = gdk_display_get_default_seat (display);
|
||||
|
||||
g_assert (button_event_type == GDK_BUTTON_PRESS ||
|
||||
button_event_type == GDK_BUTTON_RELEASE);
|
||||
|
||||
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
|
||||
|
||||
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.x_root = -1;
|
||||
event->button.y_root = -1;
|
||||
|
||||
pika_display_shell_canvas_tool_events (shell->canvas,
|
||||
event,
|
||||
shell);
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_test_synthesize_tool_motion_event (PikaDisplayShell *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_window_get_display (window);
|
||||
GdkSeat *seat = gdk_display_get_default_seat (display);
|
||||
|
||||
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
|
||||
|
||||
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.x_root = -1;
|
||||
event->motion.y_root = -1;
|
||||
|
||||
pika_display_shell_canvas_tool_events (shell->canvas,
|
||||
event,
|
||||
shell);
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_test_synthesize_tool_crossing_event (PikaDisplayShell *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));
|
||||
GdkDisplay *display = gdk_window_get_display (window);
|
||||
GdkSeat *seat = gdk_display_get_default_seat (display);
|
||||
|
||||
g_assert (crossing_event_type == GDK_ENTER_NOTIFY ||
|
||||
crossing_event_type == GDK_LEAVE_NOTIFY);
|
||||
|
||||
gdk_event_set_device (event, gdk_seat_get_pointer (seat));
|
||||
|
||||
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;
|
||||
|
||||
pika_display_shell_canvas_tool_events (shell->canvas,
|
||||
event,
|
||||
shell);
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_tools_synthesize_image_click_drag_release (PikaDisplayShell *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 middle_canvas_x = -1.0;
|
||||
gdouble middle_canvas_y = -1.0;
|
||||
gdouble end_canvas_x = -1.0;
|
||||
gdouble end_canvas_y = -1.0;
|
||||
|
||||
/* Transform coordinates */
|
||||
pika_display_shell_transform_xy_f (shell,
|
||||
start_image_x,
|
||||
start_image_y,
|
||||
&start_canvas_x,
|
||||
&start_canvas_y);
|
||||
pika_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 */
|
||||
pika_test_synthesize_tool_crossing_event (shell,
|
||||
(int)start_canvas_x,
|
||||
(int)start_canvas_y,
|
||||
modifiers,
|
||||
GDK_ENTER_NOTIFY);
|
||||
|
||||
/* Button press */
|
||||
pika_test_synthesize_tool_button_event (shell,
|
||||
(int)start_canvas_x,
|
||||
(int)start_canvas_y,
|
||||
button,
|
||||
modifiers,
|
||||
GDK_BUTTON_PRESS);
|
||||
|
||||
/* Move events */
|
||||
pika_test_synthesize_tool_motion_event (shell,
|
||||
(int)start_canvas_x,
|
||||
(int)start_canvas_y,
|
||||
modifiers);
|
||||
pika_test_synthesize_tool_motion_event (shell,
|
||||
(int)middle_canvas_x,
|
||||
(int)middle_canvas_y,
|
||||
modifiers);
|
||||
pika_test_synthesize_tool_motion_event (shell,
|
||||
(int)end_canvas_x,
|
||||
(int)end_canvas_y,
|
||||
modifiers);
|
||||
|
||||
/* Button release */
|
||||
pika_test_synthesize_tool_button_event (shell,
|
||||
(int)end_canvas_x,
|
||||
(int)end_canvas_y,
|
||||
button,
|
||||
modifiers,
|
||||
GDK_BUTTON_RELEASE);
|
||||
|
||||
/* Leave notify */
|
||||
pika_test_synthesize_tool_crossing_event (shell,
|
||||
(int)start_canvas_x,
|
||||
(int)start_canvas_y,
|
||||
modifiers,
|
||||
GDK_LEAVE_NOTIFY);
|
||||
|
||||
/* Process them */
|
||||
pika_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 - SIGSEGV, while doing a crop".
|
||||
**/
|
||||
static void
|
||||
crop_tool_can_crop (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image = pika_test_get_only_image (pika);
|
||||
PikaDisplayShell *shell = pika_test_get_only_display_shell (pika);
|
||||
|
||||
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)
|
||||
*/
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"view",
|
||||
"view-shrink-wrap");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Activate crop tool */
|
||||
pika_tools_set_tool (pika, "pika-crop-tool", shell->display);
|
||||
|
||||
/* Do the crop rect */
|
||||
pika_tools_synthesize_image_click_drag_release (shell,
|
||||
cropped_x,
|
||||
cropped_y,
|
||||
cropped_x + cropped_w,
|
||||
cropped_y + cropped_h,
|
||||
1 /*button*/,
|
||||
0 /*modifiers*/);
|
||||
|
||||
/* Crop */
|
||||
pika_test_utils_synthesize_key_event (GTK_WIDGET (shell), GDK_KEY_Return);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Make sure the new image has the expected size */
|
||||
g_assert_cmpint (cropped_w, ==, pika_image_get_width (image));
|
||||
g_assert_cmpint (cropped_h, ==, pika_image_get_height (image));
|
||||
}
|
||||
|
||||
/**
|
||||
* crop_tool_can_crop:
|
||||
* @fixture:
|
||||
* @data:
|
||||
*
|
||||
* Make sure it's possible to change width of crop rect in tool
|
||||
* options without there being a pending rectangle. Regression test
|
||||
* for "Bug 322396 - Crop dimension entering causes crash".
|
||||
**/
|
||||
static void
|
||||
crop_set_width_without_pending_rect (PikaTestFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaDisplay *display = pika_test_get_only_display (pika);
|
||||
PikaToolInfo *tool_info;
|
||||
PikaRectangleOptions *rectangle_options;
|
||||
GtkWidget *size_entry;
|
||||
|
||||
/* Activate crop tool */
|
||||
pika_tools_set_tool (pika, "pika-crop-tool", display);
|
||||
|
||||
/* Get tool options */
|
||||
tool_info = pika_get_tool_info (pika, "pika-crop-tool");
|
||||
rectangle_options = PIKA_RECTANGLE_OPTIONS (tool_info->tool_options);
|
||||
|
||||
/* Find 'Width' or 'Height' GtkTextEntry in tool options */
|
||||
size_entry = pika_rectangle_options_get_size_entry (rectangle_options);
|
||||
|
||||
/* Set arbitrary non-0 value */
|
||||
pika_size_entry_set_value (PIKA_SIZE_ENTRY (size_entry),
|
||||
0 /*field*/,
|
||||
42.0 /*lower*/);
|
||||
|
||||
/* If we don't crash, everything s fine */
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Pika *pika = NULL;
|
||||
gint result = -1;
|
||||
|
||||
pika_test_bail_if_no_display ();
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
pika_test_utils_setup_menus_path ();
|
||||
|
||||
/* Start up PIKA */
|
||||
pika = pika_init_for_gui_testing (TRUE /*show_gui*/);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Add tests */
|
||||
ADD_TEST (crop_tool_can_crop);
|
||||
ADD_TEST (crop_set_width_without_pending_rect);
|
||||
|
||||
/* Run the tests and return status */
|
||||
g_application_run (pika->app, 0, NULL);
|
||||
result = pika_core_app_get_exit_status (PIKA_CORE_APP (pika->app));
|
||||
|
||||
g_application_quit (G_APPLICATION (pika->app));
|
||||
g_clear_object (&pika->app);
|
||||
|
||||
return result;
|
||||
}
|
908
app/tests/test-ui.c
Normal file
908
app/tests/test-ui.c
Normal file
@ -0,0 +1,908 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikamath/pikamath.h"
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "dialogs/dialogs-types.h"
|
||||
|
||||
#include "display/pikadisplay.h"
|
||||
#include "display/pikadisplayshell.h"
|
||||
#include "display/pikadisplayshell-scale.h"
|
||||
#include "display/pikadisplayshell-transform.h"
|
||||
#include "display/pikaimagewindow.h"
|
||||
|
||||
#include "menus/menus.h"
|
||||
|
||||
#include "widgets/pikadialogfactory.h"
|
||||
#include "widgets/pikadock.h"
|
||||
#include "widgets/pikadockable.h"
|
||||
#include "widgets/pikadockbook.h"
|
||||
#include "widgets/pikadockcontainer.h"
|
||||
#include "widgets/pikadocked.h"
|
||||
#include "widgets/pikadockwindow.h"
|
||||
#include "widgets/pikahelp-ids.h"
|
||||
#include "widgets/pikasessioninfo.h"
|
||||
#include "widgets/pikasessioninfo-aux.h"
|
||||
#include "widgets/pikasessionmanaged.h"
|
||||
#include "widgets/pikatoolbox.h"
|
||||
#include "widgets/pikatooloptionseditor.h"
|
||||
#include "widgets/pikauimanager.h"
|
||||
#include "widgets/pikawidgets-utils.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikachannel.h"
|
||||
#include "core/pikacontext.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer.h"
|
||||
#include "core/pikalayer-new.h"
|
||||
#include "core/pikatoolinfo.h"
|
||||
#include "core/pikatooloptions.h"
|
||||
|
||||
#include "pikacoreapp.h"
|
||||
|
||||
#include "pika-app-test-utils.h"
|
||||
#include "tests.h"
|
||||
|
||||
|
||||
#define PIKA_UI_WINDOW_POSITION_EPSILON 30
|
||||
#define PIKA_UI_POSITION_EPSILON 1
|
||||
#define PIKA_UI_ZOOM_EPSILON 0.01
|
||||
|
||||
#define ADD_TEST(function) \
|
||||
g_test_add_data_func ("/pika-ui/" #function, pika, function);
|
||||
|
||||
|
||||
/* 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 PIKA_PAUSE (g_usleep (20 * 1000 * 1000))
|
||||
|
||||
|
||||
typedef gboolean (*PikaUiTestFunc) (GObject *object);
|
||||
|
||||
|
||||
static void pika_ui_synthesize_delete_event (GtkWidget *widget);
|
||||
static gboolean pika_ui_synthesize_click (GtkWidget *widget,
|
||||
gint x,
|
||||
gint y,
|
||||
gint button,
|
||||
GdkModifierType modifiers);
|
||||
static GtkWidget * pika_ui_find_window (PikaDialogFactory *dialog_factory,
|
||||
PikaUiTestFunc predicate);
|
||||
static gboolean pika_ui_not_toolbox_window (GObject *object);
|
||||
static gboolean pika_ui_multicolumn_not_toolbox_window (GObject *object);
|
||||
static gboolean pika_ui_is_pika_layer_list (GObject *object);
|
||||
static int pika_ui_aux_data_eqiuvalent (gconstpointer _a,
|
||||
gconstpointer _b);
|
||||
static void pika_ui_switch_window_mode (Pika *pika);
|
||||
|
||||
|
||||
/**
|
||||
* tool_options_editor_updates:
|
||||
* @data:
|
||||
*
|
||||
* Makes sure that the tool options editor is updated when the tool
|
||||
* changes.
|
||||
**/
|
||||
static void
|
||||
tool_options_editor_updates (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaDisplay *display = PIKA_DISPLAY (pika_get_empty_display (pika));
|
||||
PikaDisplayShell *shell = pika_display_get_shell (display);
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
|
||||
PikaUIManager *ui_manager = menus_get_image_manager_singleton (pika);
|
||||
GtkWidget *dockable = pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
|
||||
pika_widget_get_monitor (toplevel),
|
||||
NULL /*ui_manager*/,
|
||||
toplevel,
|
||||
"pika-tool-options",
|
||||
-1 /*view_size*/,
|
||||
FALSE /*present*/);
|
||||
PikaToolOptionsEditor *editor = PIKA_TOOL_OPTIONS_EDITOR (gtk_bin_get_child (GTK_BIN (dockable)));
|
||||
|
||||
/* First select the rect select tool */
|
||||
pika_ui_manager_activate_action (ui_manager,
|
||||
"tools",
|
||||
"tools-rect-select");
|
||||
g_assert_cmpstr (PIKA_HELP_TOOL_RECT_SELECT,
|
||||
==,
|
||||
pika_tool_options_editor_get_tool_options (editor)->
|
||||
tool_info->help_id);
|
||||
|
||||
/* Change tool and make sure the change is taken into account by the
|
||||
* tool options editor
|
||||
*/
|
||||
pika_ui_manager_activate_action (ui_manager,
|
||||
"tools",
|
||||
"tools-ellipse-select");
|
||||
g_assert_cmpstr (PIKA_HELP_TOOL_ELLIPSE_SELECT,
|
||||
==,
|
||||
pika_tool_options_editor_get_tool_options (editor)->
|
||||
tool_info->help_id);
|
||||
}
|
||||
|
||||
static void
|
||||
create_new_image_via_dialog (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image;
|
||||
PikaLayer *layer;
|
||||
|
||||
image = pika_test_utils_create_image_from_dialog (pika);
|
||||
|
||||
/* Add a layer to the image to make it more useful in later tests */
|
||||
layer = pika_layer_new (image,
|
||||
pika_image_get_width (image),
|
||||
pika_image_get_height (image),
|
||||
pika_image_get_layer_format (image, TRUE),
|
||||
"Layer for testing",
|
||||
PIKA_OPACITY_OPAQUE,
|
||||
PIKA_LAYER_MODE_NORMAL);
|
||||
|
||||
pika_image_add_layer (image, layer,
|
||||
PIKA_IMAGE_ACTIVE_PARENT, -1, TRUE);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_zoom_focus (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaDisplay *display = PIKA_DISPLAY (pika_get_display_iter (pika)->data);
|
||||
PikaDisplayShell *shell = pika_display_get_shell (display);
|
||||
PikaImageWindow *window = pika_display_shell_get_window (shell);
|
||||
gint image_x;
|
||||
gint image_y;
|
||||
gint shell_x_before_zoom;
|
||||
gint shell_y_before_zoom;
|
||||
gdouble factor_before_zoom;
|
||||
gint shell_x_after_zoom;
|
||||
gint shell_y_after_zoom;
|
||||
gdouble factor_after_zoom;
|
||||
|
||||
/* We need to use a point that is within the visible (exposed) part
|
||||
* of the canvas
|
||||
*/
|
||||
image_x = 400;
|
||||
image_y = 50;
|
||||
|
||||
/* Setup zoom focus on the bottom right part of the image. We avoid
|
||||
* 0,0 because that's essentially a particularly easy special case.
|
||||
*/
|
||||
pika_display_shell_transform_xy (shell,
|
||||
image_x,
|
||||
image_y,
|
||||
&shell_x_before_zoom,
|
||||
&shell_y_before_zoom);
|
||||
pika_display_shell_push_zoom_focus_pointer_pos (shell,
|
||||
shell_x_before_zoom,
|
||||
shell_y_before_zoom);
|
||||
factor_before_zoom = pika_zoom_model_get_factor (shell->zoom);
|
||||
|
||||
/* Do the zoom */
|
||||
pika_test_utils_synthesize_key_event (GTK_WIDGET (window), GDK_KEY_plus);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Make sure the zoom focus point remained fixed */
|
||||
pika_display_shell_transform_xy (shell,
|
||||
image_x,
|
||||
image_y,
|
||||
&shell_x_after_zoom,
|
||||
&shell_y_after_zoom);
|
||||
factor_after_zoom = pika_zoom_model_get_factor (shell->zoom);
|
||||
|
||||
/* First of all make sure a zoom happened at all. If this assert
|
||||
* fails, it means that the zoom didn't happen. Possible causes:
|
||||
*
|
||||
* * gdk_test_simulate_key() failed to map 'GDK_KEY_plus' to the proper
|
||||
* 'plus' X keysym, probably because it is mapped to a keycode
|
||||
* with modifiers like 'shift'. Run "xmodmap -pk | grep plus" to
|
||||
* find out. Make sure 'plus' is the first keysym for the given
|
||||
* keycode. If not, use "xmodmap <keycode> = plus" to correct it.
|
||||
*/
|
||||
g_assert_cmpfloat (fabs (factor_before_zoom - factor_after_zoom),
|
||||
>=,
|
||||
PIKA_UI_ZOOM_EPSILON);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#warning disabled zoom test, it fails randomly, no clue how to fix it
|
||||
#endif
|
||||
#if 0
|
||||
g_assert_cmpint (ABS (shell_x_after_zoom - shell_x_before_zoom),
|
||||
<=,
|
||||
PIKA_UI_POSITION_EPSILON);
|
||||
g_assert_cmpint (ABS (shell_y_after_zoom - shell_y_before_zoom),
|
||||
<=,
|
||||
PIKA_UI_POSITION_EPSILON);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* alt_click_is_layer_to_selection:
|
||||
* @data:
|
||||
*
|
||||
* Makes sure that we can alt-click on a layer to do
|
||||
* layer-to-selection. Also makes sure that the layer clicked on is
|
||||
* not set as the active layer.
|
||||
**/
|
||||
static void
|
||||
alt_click_is_layer_to_selection (gconstpointer data)
|
||||
{
|
||||
#if __GNUC__
|
||||
#warning FIXME: please fix alt_click_is_layer_to_selection test
|
||||
#endif
|
||||
#if 0
|
||||
Pika *pika = PIKA (data);
|
||||
PikaImage *image = PIKA_IMAGE (pika_get_image_iter (pika)->data);
|
||||
PikaChannel *selection = pika_image_get_mask (image);
|
||||
GList *selected_layers;
|
||||
GList *iter;
|
||||
GtkWidget *dockable;
|
||||
GtkWidget *gtk_tree_view;
|
||||
gint assumed_layer_x;
|
||||
gint assumed_empty_layer_y;
|
||||
gint assumed_background_layer_y;
|
||||
|
||||
/* Hardcode assumptions of where the layers are in the
|
||||
* GtkTreeView. Doesn't feel worth adding proper API for this. One
|
||||
* can just use PIKA_PAUSE and re-measure new coordinates if we
|
||||
* start to layout layers in the GtkTreeView differently
|
||||
*/
|
||||
assumed_layer_x = 96;
|
||||
assumed_empty_layer_y = 16;
|
||||
assumed_background_layer_y = 42;
|
||||
|
||||
/* Store the active layer, it shall not change during the execution
|
||||
* of this test
|
||||
*/
|
||||
selected_layers = pika_image_get_selected_layers (image);
|
||||
selected_layers = g_list_copy (selected_layers);
|
||||
|
||||
/* Find the layer tree view to click in. Note that there is a
|
||||
* potential problem with gtk_test_find_widget and GtkNotebook: it
|
||||
* will return e.g. a GtkTreeView from another page if that page is
|
||||
* "on top" of the reference label.
|
||||
*/
|
||||
dockable = pika_ui_find_window (pika_dialog_factory_get_singleton (),
|
||||
pika_ui_is_pika_layer_list);
|
||||
gtk_tree_view = gtk_test_find_widget (dockable,
|
||||
"Lock:",
|
||||
GTK_TYPE_TREE_VIEW);
|
||||
|
||||
/* First make sure there is no selection */
|
||||
g_assert (pika_channel_is_empty (selection));
|
||||
|
||||
/* Now simulate alt-click on the background layer */
|
||||
g_assert (pika_ui_synthesize_click (gtk_tree_view,
|
||||
assumed_layer_x,
|
||||
assumed_background_layer_y,
|
||||
1 /*button*/,
|
||||
GDK_MOD1_MASK));
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Make sure we got a selection and that the active layer didn't
|
||||
* change
|
||||
*/
|
||||
g_assert (! pika_channel_is_empty (selection));
|
||||
g_assert (g_list_length (pika_image_get_selected_layers (image)) ==
|
||||
g_list_length (selected_layers));
|
||||
for (iter = selected_layers; iter; iter = iter->next)
|
||||
g_assert (g_list_find (pika_image_get_selected_layers (image), iter->data));
|
||||
|
||||
/* Now simulate alt-click on the empty layer */
|
||||
g_assert (pika_ui_synthesize_click (gtk_tree_view,
|
||||
assumed_layer_x,
|
||||
assumed_empty_layer_y,
|
||||
1 /*button*/,
|
||||
GDK_MOD1_MASK));
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Make sure that emptied the selection and that the active layer
|
||||
* still didn't change
|
||||
*/
|
||||
g_assert (pika_channel_is_empty (selection));
|
||||
g_assert (g_list_length (pika_image_get_selected_layers (image)) ==
|
||||
g_list_length (selected_layers));
|
||||
for (iter = selected_layers; iter; iter = iter->next)
|
||||
g_assert (g_list_find (pika_image_get_selected_layers (image), iter->data));
|
||||
|
||||
g_list_free (selected_layers);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
restore_recently_closed_multi_column_dock (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
GtkWidget *dock_window = NULL;
|
||||
gint n_session_infos_before_close = -1;
|
||||
gint n_session_infos_after_close = -1;
|
||||
gint n_session_infos_after_restore = -1;
|
||||
GList *session_infos = NULL;
|
||||
|
||||
/* Find a non-toolbox dock window */
|
||||
dock_window = pika_ui_find_window (pika_dialog_factory_get_singleton (),
|
||||
pika_ui_multicolumn_not_toolbox_window);
|
||||
g_assert (dock_window != NULL);
|
||||
|
||||
/* Count number of docks */
|
||||
session_infos = pika_dialog_factory_get_session_infos (pika_dialog_factory_get_singleton ());
|
||||
n_session_infos_before_close = g_list_length (session_infos);
|
||||
|
||||
/* Close one of the dock windows */
|
||||
pika_ui_synthesize_delete_event (GTK_WIDGET (dock_window));
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Make sure the number of session infos went down */
|
||||
session_infos = pika_dialog_factory_get_session_infos (pika_dialog_factory_get_singleton ());
|
||||
n_session_infos_after_close = g_list_length (session_infos);
|
||||
g_assert_cmpint (n_session_infos_before_close,
|
||||
>,
|
||||
n_session_infos_after_close);
|
||||
|
||||
/* Restore the (only available) closed dock and make sure the session
|
||||
* infos in the global dock factory are increased again
|
||||
*/
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"windows",
|
||||
/* FIXME: This is severely hardcoded */
|
||||
"windows-recent-0003");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
session_infos = pika_dialog_factory_get_session_infos (pika_dialog_factory_get_singleton ());
|
||||
n_session_infos_after_restore = g_list_length (session_infos);
|
||||
g_assert_cmpint (n_session_infos_after_close,
|
||||
<,
|
||||
n_session_infos_after_restore);
|
||||
}
|
||||
|
||||
/**
|
||||
* tab_toggle_dont_change_dock_window_position:
|
||||
* @data:
|
||||
*
|
||||
* Makes sure that when dock windows are hidden with Tab and shown
|
||||
* again, their positions and sizes are not changed. We don't really
|
||||
* use Tab though, we only simulate its effect.
|
||||
**/
|
||||
static void
|
||||
tab_toggle_dont_change_dock_window_position (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
GtkWidget *dock_window = NULL;
|
||||
gint x_before_hide = -1;
|
||||
gint y_before_hide = -1;
|
||||
gint w_before_hide = -1;
|
||||
gint h_before_hide = -1;
|
||||
gint x_after_show = -1;
|
||||
gint y_after_show = -1;
|
||||
gint w_after_show = -1;
|
||||
gint h_after_show = -1;
|
||||
|
||||
/* Find a non-toolbox dock window */
|
||||
dock_window = pika_ui_find_window (pika_dialog_factory_get_singleton (),
|
||||
pika_ui_not_toolbox_window);
|
||||
g_assert (dock_window != NULL);
|
||||
g_assert (gtk_widget_get_visible (dock_window));
|
||||
|
||||
/* Get the position and size */
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
gtk_window_get_position (GTK_WINDOW (dock_window),
|
||||
&x_before_hide,
|
||||
&y_before_hide);
|
||||
gtk_window_get_size (GTK_WINDOW (dock_window),
|
||||
&w_before_hide,
|
||||
&h_before_hide);
|
||||
|
||||
/* Hide all dock windows */
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"windows",
|
||||
"windows-hide-docks");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
g_assert (! gtk_widget_get_visible (dock_window));
|
||||
|
||||
/* Show them again */
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"windows",
|
||||
"windows-hide-docks");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
g_assert (gtk_widget_get_visible (dock_window));
|
||||
|
||||
/* Get the position and size again and make sure it's the same as
|
||||
* before
|
||||
*/
|
||||
gtk_window_get_position (GTK_WINDOW (dock_window),
|
||||
&x_after_show,
|
||||
&y_after_show);
|
||||
gtk_window_get_size (GTK_WINDOW (dock_window),
|
||||
&w_after_show,
|
||||
&h_after_show);
|
||||
g_assert_cmpint ((int)abs (x_before_hide - x_after_show), <=, PIKA_UI_WINDOW_POSITION_EPSILON);
|
||||
g_assert_cmpint ((int)abs (y_before_hide - y_after_show), <=, PIKA_UI_WINDOW_POSITION_EPSILON);
|
||||
g_assert_cmpint ((int)abs (w_before_hide - w_after_show), <=, PIKA_UI_WINDOW_POSITION_EPSILON);
|
||||
g_assert_cmpint ((int)abs (h_before_hide - h_after_show), <=, PIKA_UI_WINDOW_POSITION_EPSILON);
|
||||
}
|
||||
|
||||
static void
|
||||
switch_to_single_window_mode (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
|
||||
/* Switch to single-window mode. We consider this test as passed if
|
||||
* we don't get any GLib warnings/errors
|
||||
*/
|
||||
pika_ui_switch_window_mode (pika);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_ui_toggle_docks_in_single_window_mode (Pika *pika)
|
||||
{
|
||||
PikaDisplay *display = PIKA_DISPLAY (pika_get_display_iter (pika)->data);
|
||||
PikaDisplayShell *shell = pika_display_get_shell (display);
|
||||
GtkWidget *toplevel = GTK_WIDGET (pika_display_shell_get_window (shell));
|
||||
gint x_temp = -1;
|
||||
gint y_temp = -1;
|
||||
gint x_before_hide = -1;
|
||||
gint y_before_hide = -1;
|
||||
gint x_after_hide = -1;
|
||||
gint y_after_hide = -1;
|
||||
g_assert (shell);
|
||||
g_assert (toplevel);
|
||||
|
||||
/* Get toplevel coordinate of image origin */
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
pika_display_shell_transform_xy (shell,
|
||||
0.0, 0.0,
|
||||
&x_temp, &y_temp);
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (shell),
|
||||
toplevel,
|
||||
x_temp, y_temp,
|
||||
&x_before_hide, &y_before_hide);
|
||||
|
||||
/* Hide all dock windows */
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"windows",
|
||||
"windows-hide-docks");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Get toplevel coordinate of image origin */
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
pika_display_shell_transform_xy (shell,
|
||||
0.0, 0.0,
|
||||
&x_temp, &y_temp);
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (shell),
|
||||
toplevel,
|
||||
x_temp, y_temp,
|
||||
&x_after_hide, &y_after_hide);
|
||||
|
||||
g_assert_cmpint ((int)abs (x_after_hide - x_before_hide), <=, PIKA_UI_POSITION_EPSILON);
|
||||
g_assert_cmpint ((int)abs (y_after_hide - y_before_hide), <=, PIKA_UI_POSITION_EPSILON);
|
||||
}
|
||||
|
||||
static void
|
||||
hide_docks_in_single_window_mode (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
pika_ui_toggle_docks_in_single_window_mode (pika);
|
||||
}
|
||||
|
||||
static void
|
||||
show_docks_in_single_window_mode (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
pika_ui_toggle_docks_in_single_window_mode (pika);
|
||||
}
|
||||
|
||||
static void
|
||||
maximize_state_in_aux_data (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaDisplay *display = PIKA_DISPLAY (pika_get_display_iter (pika)->data);
|
||||
PikaDisplayShell *shell = pika_display_get_shell (display);
|
||||
PikaImageWindow *window = pika_display_shell_get_window (shell);
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
GList *aux_info = NULL;
|
||||
PikaSessionInfoAux *target_info;
|
||||
gboolean target_max_state;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
target_info = pika_session_info_aux_new ("maximized" , "yes");
|
||||
target_max_state = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
target_info = pika_session_info_aux_new ("maximized", "no");
|
||||
target_max_state = FALSE;
|
||||
}
|
||||
|
||||
/* Set the aux info to out target data */
|
||||
aux_info = g_list_append (aux_info, target_info);
|
||||
pika_session_managed_set_aux_info (PIKA_SESSION_MANAGED (window), aux_info);
|
||||
g_list_free (aux_info);
|
||||
|
||||
/* Give the WM a chance to maximize/unmaximize us */
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
g_usleep (500 * 1000);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Make sure the maximize/unmaximize happened */
|
||||
g_assert (pika_image_window_is_maximized (window) == target_max_state);
|
||||
|
||||
/* Make sure we can read out the window state again */
|
||||
aux_info = pika_session_managed_get_aux_info (PIKA_SESSION_MANAGED (window));
|
||||
g_assert (g_list_find_custom (aux_info, target_info, pika_ui_aux_data_eqiuvalent));
|
||||
g_list_free_full (aux_info,
|
||||
(GDestroyNotify) pika_session_info_aux_free);
|
||||
|
||||
pika_session_info_aux_free (target_info);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
switch_back_to_multi_window_mode (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
|
||||
/* Switch back to multi-window mode. We consider this test as passed
|
||||
* if we don't get any GLib warnings/errors
|
||||
*/
|
||||
pika_ui_switch_window_mode (pika);
|
||||
}
|
||||
|
||||
static void
|
||||
close_image (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
int undo_count = 4;
|
||||
|
||||
/* Undo all changes so we don't need to find the 'Do you want to
|
||||
* save?'-dialog and its 'No' button
|
||||
*/
|
||||
while (undo_count--)
|
||||
{
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"edit",
|
||||
"edit-undo");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
}
|
||||
|
||||
/* Close the image */
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"view",
|
||||
"view-close");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Did it really disappear? */
|
||||
g_assert_cmpint (g_list_length (pika_get_image_iter (pika)), ==, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* repeatedly_switch_window_mode:
|
||||
* @data:
|
||||
*
|
||||
* Makes sure that the size of the image window is properly handled
|
||||
* when repeatedly switching between window modes.
|
||||
**/
|
||||
static void
|
||||
repeatedly_switch_window_mode (gconstpointer data)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
#warning FIXME: plesase fix repeatedly_switch_window_mode test
|
||||
#endif
|
||||
#if 0
|
||||
Pika *pika = PIKA (data);
|
||||
PikaDisplay *display = PIKA_DISPLAY (pika_get_empty_display (pika));
|
||||
PikaDisplayShell *shell = pika_display_get_shell (display);
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
|
||||
|
||||
gint expected_initial_height;
|
||||
gint expected_initial_width;
|
||||
gint expected_second_height;
|
||||
gint expected_second_width;
|
||||
gint initial_width;
|
||||
gint initial_height;
|
||||
gint second_width;
|
||||
gint second_height;
|
||||
|
||||
/* We need this for some reason */
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Remember the multi-window mode size */
|
||||
gtk_window_get_size (GTK_WINDOW (toplevel),
|
||||
&expected_initial_width,
|
||||
&expected_initial_height);
|
||||
|
||||
/* Switch to single-window mode */
|
||||
pika_ui_switch_window_mode (pika);
|
||||
|
||||
/* Remember the single-window mode size */
|
||||
gtk_window_get_size (GTK_WINDOW (toplevel),
|
||||
&expected_second_width,
|
||||
&expected_second_height);
|
||||
|
||||
/* Make sure they differ, otherwise the test is pointless */
|
||||
g_assert_cmpint (expected_initial_width, !=, expected_second_width);
|
||||
g_assert_cmpint (expected_initial_height, !=, expected_second_height);
|
||||
|
||||
/* Switch back to multi-window mode */
|
||||
pika_ui_switch_window_mode (pika);
|
||||
|
||||
/* Make sure the size is the same as before */
|
||||
gtk_window_get_size (GTK_WINDOW (toplevel), &initial_width, &initial_height);
|
||||
g_assert_cmpint (expected_initial_width, ==, initial_width);
|
||||
g_assert_cmpint (expected_initial_height, ==, initial_height);
|
||||
|
||||
/* Switch to single-window mode again... */
|
||||
pika_ui_switch_window_mode (pika);
|
||||
|
||||
/* Make sure the size is the same as before */
|
||||
gtk_window_get_size (GTK_WINDOW (toplevel), &second_width, &second_height);
|
||||
g_assert_cmpint (expected_second_width, ==, second_width);
|
||||
g_assert_cmpint (expected_second_height, ==, second_height);
|
||||
|
||||
/* Finally switch back to multi-window mode since that was the mode
|
||||
* when we started
|
||||
*/
|
||||
pika_ui_switch_window_mode (pika);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* window_roles:
|
||||
* @data:
|
||||
*
|
||||
* Makes sure that different windows have the right roles specified.
|
||||
**/
|
||||
static void
|
||||
window_roles (gconstpointer data)
|
||||
{
|
||||
GdkMonitor *monitor = NULL;
|
||||
GtkWidget *dock = NULL;
|
||||
GtkWidget *toolbox = NULL;
|
||||
PikaDockWindow *dock_window = NULL;
|
||||
PikaDockWindow *toolbox_window = NULL;
|
||||
|
||||
monitor = gdk_display_get_primary_monitor (gdk_display_get_default ());
|
||||
dock = pika_dock_with_window_new (pika_dialog_factory_get_singleton (),
|
||||
monitor,
|
||||
FALSE /*toolbox*/);
|
||||
toolbox = pika_dock_with_window_new (pika_dialog_factory_get_singleton (),
|
||||
monitor,
|
||||
TRUE /*toolbox*/);
|
||||
dock_window = pika_dock_window_from_dock (PIKA_DOCK (dock));
|
||||
toolbox_window = pika_dock_window_from_dock (PIKA_DOCK (toolbox));
|
||||
|
||||
g_assert_cmpint (g_str_has_prefix (gtk_window_get_role (GTK_WINDOW (dock_window)), "pika-dock-"), ==,
|
||||
TRUE);
|
||||
g_assert_cmpint (g_str_has_prefix (gtk_window_get_role (GTK_WINDOW (toolbox_window)), "pika-toolbox-"), ==,
|
||||
TRUE);
|
||||
|
||||
/* When we get here we have a ref count of one, but the signals we
|
||||
* emit cause the reference count to become less than zero for some
|
||||
* reason. So we're lazy and simply ignore to unref these
|
||||
g_object_unref (toolbox);
|
||||
g_object_unref (dock);
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
paintbrush_is_standard_tool (gconstpointer data)
|
||||
{
|
||||
Pika *pika = PIKA (data);
|
||||
PikaContext *user_context = pika_get_user_context (pika);
|
||||
PikaToolInfo *tool_info = pika_context_get_tool (user_context);
|
||||
|
||||
g_assert_cmpstr (tool_info->help_id,
|
||||
==,
|
||||
"pika-tool-paintbrush");
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_ui_synthesize_delete_event:
|
||||
* @widget:
|
||||
*
|
||||
* Synthesize a delete event to @widget.
|
||||
**/
|
||||
static void
|
||||
pika_ui_synthesize_delete_event (GtkWidget *widget)
|
||||
{
|
||||
GdkWindow *window = NULL;
|
||||
GdkEvent *event = NULL;
|
||||
|
||||
window = gtk_widget_get_window (widget);
|
||||
g_assert (window);
|
||||
|
||||
event = gdk_event_new (GDK_DELETE);
|
||||
event->any.window = g_object_ref (window);
|
||||
event->any.send_event = TRUE;
|
||||
gtk_main_do_event (event);
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pika_ui_synthesize_click (GtkWidget *widget,
|
||||
gint x,
|
||||
gint y,
|
||||
gint button, /*1..3*/
|
||||
GdkModifierType modifiers)
|
||||
{
|
||||
return (gdk_test_simulate_button (gtk_widget_get_window (widget),
|
||||
x, y,
|
||||
button,
|
||||
modifiers,
|
||||
GDK_BUTTON_PRESS) &&
|
||||
gdk_test_simulate_button (gtk_widget_get_window (widget),
|
||||
x, y,
|
||||
button,
|
||||
modifiers,
|
||||
GDK_BUTTON_RELEASE));
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
pika_ui_find_window (PikaDialogFactory *dialog_factory,
|
||||
PikaUiTestFunc predicate)
|
||||
{
|
||||
GList *iter = NULL;
|
||||
GtkWidget *dock_window = NULL;
|
||||
|
||||
g_return_val_if_fail (predicate != NULL, NULL);
|
||||
|
||||
for (iter = pika_dialog_factory_get_session_infos (dialog_factory);
|
||||
iter;
|
||||
iter = g_list_next (iter))
|
||||
{
|
||||
GtkWidget *widget = pika_session_info_get_widget (iter->data);
|
||||
|
||||
if (predicate (G_OBJECT (widget)))
|
||||
{
|
||||
dock_window = widget;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dock_window;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pika_ui_not_toolbox_window (GObject *object)
|
||||
{
|
||||
return (PIKA_IS_DOCK_WINDOW (object) &&
|
||||
! pika_dock_window_has_toolbox (PIKA_DOCK_WINDOW (object)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pika_ui_multicolumn_not_toolbox_window (GObject *object)
|
||||
{
|
||||
gboolean not_toolbox_window;
|
||||
PikaDockWindow *dock_window;
|
||||
PikaDockContainer *dock_container;
|
||||
GList *docks;
|
||||
|
||||
if (! PIKA_IS_DOCK_WINDOW (object))
|
||||
return FALSE;
|
||||
|
||||
dock_window = PIKA_DOCK_WINDOW (object);
|
||||
dock_container = PIKA_DOCK_CONTAINER (object);
|
||||
docks = pika_dock_container_get_docks (dock_container);
|
||||
|
||||
not_toolbox_window = (! pika_dock_window_has_toolbox (dock_window) &&
|
||||
g_list_length (docks) > 1);
|
||||
|
||||
g_list_free (docks);
|
||||
|
||||
return not_toolbox_window;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pika_ui_is_pika_layer_list (GObject *object)
|
||||
{
|
||||
PikaDialogFactoryEntry *entry = NULL;
|
||||
|
||||
if (! GTK_IS_WIDGET (object))
|
||||
return FALSE;
|
||||
|
||||
pika_dialog_factory_from_widget (GTK_WIDGET (object), &entry);
|
||||
|
||||
return strcmp (entry->identifier, "pika-layer-list") == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pika_ui_aux_data_eqiuvalent (gconstpointer _a, gconstpointer _b)
|
||||
{
|
||||
PikaSessionInfoAux *a = (PikaSessionInfoAux*) _a;
|
||||
PikaSessionInfoAux *b = (PikaSessionInfoAux*) _b;
|
||||
return (strcmp (a->name, b->name) || strcmp (a->value, b->value));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_ui_switch_window_mode (Pika *pika)
|
||||
{
|
||||
pika_ui_manager_activate_action (pika_test_utils_get_ui_manager (pika),
|
||||
"windows",
|
||||
"windows-use-single-window-mode");
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Add a small sleep to let things stabilize */
|
||||
g_usleep (500 * 1000);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Pika *pika = NULL;
|
||||
gint result = -1;
|
||||
|
||||
pika_test_bail_if_no_display ();
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
pika_test_utils_setup_menus_path ();
|
||||
|
||||
/* Start up PIKA */
|
||||
pika = pika_init_for_gui_testing (TRUE /*show_gui*/);
|
||||
pika_test_run_mainloop_until_idle ();
|
||||
|
||||
/* Add tests. Note that the order matters. For example,
|
||||
* 'paintbrush_is_standard_tool' can't be after
|
||||
* 'tool_options_editor_updates'
|
||||
*/
|
||||
ADD_TEST (paintbrush_is_standard_tool);
|
||||
ADD_TEST (tool_options_editor_updates);
|
||||
ADD_TEST (create_new_image_via_dialog);
|
||||
ADD_TEST (keyboard_zoom_focus);
|
||||
ADD_TEST (alt_click_is_layer_to_selection);
|
||||
ADD_TEST (restore_recently_closed_multi_column_dock);
|
||||
ADD_TEST (tab_toggle_dont_change_dock_window_position);
|
||||
ADD_TEST (switch_to_single_window_mode);
|
||||
#warning "FIXME: hide/show docks doesn't work when running make check"
|
||||
#if 0
|
||||
ADD_TEST (hide_docks_in_single_window_mode);
|
||||
ADD_TEST (show_docks_in_single_window_mode);
|
||||
#endif
|
||||
#warning "FIXME: maximize_state_in_aux_data doesn't work without WM"
|
||||
#if 0
|
||||
ADD_TEST (maximize_state_in_aux_data);
|
||||
#endif
|
||||
ADD_TEST (switch_back_to_multi_window_mode);
|
||||
ADD_TEST (close_image);
|
||||
ADD_TEST (repeatedly_switch_window_mode);
|
||||
ADD_TEST (window_roles);
|
||||
|
||||
/* Run the tests and return status */
|
||||
g_application_run (pika->app, 0, NULL);
|
||||
result = pika_core_app_get_exit_status (PIKA_CORE_APP (pika->app));
|
||||
|
||||
g_application_quit (G_APPLICATION (pika->app));
|
||||
g_clear_object (&pika->app);
|
||||
|
||||
return result;
|
||||
}
|
1047
app/tests/test-xcf.c
Normal file
1047
app/tests/test-xcf.c
Normal file
File diff suppressed because it is too large
Load Diff
287
app/tests/tests.c
Normal file
287
app/tests/tests.c
Normal file
@ -0,0 +1,287 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 2009 Martin Nordholts
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gui/gui-types.h"
|
||||
|
||||
#include "gui/gui.h"
|
||||
|
||||
#include "actions/actions.h"
|
||||
|
||||
#include "menus/menus.h"
|
||||
|
||||
#include "widgets/pikasessioninfo.h"
|
||||
|
||||
#include "config/pikageglconfig.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pika-contexts.h"
|
||||
|
||||
#include "gegl/pika-gegl.h"
|
||||
|
||||
#include "pika-log.h"
|
||||
#include "pikacoreapp.h"
|
||||
|
||||
#include "pika-app-test-utils.h"
|
||||
#include "tests.h"
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
pika_status_func_dummy (const gchar *text1,
|
||||
const gchar *text2,
|
||||
gdouble percentage)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_init_for_testing:
|
||||
*
|
||||
* Initialize the PIKA object system for unit testing. This is a
|
||||
* selected subset of the initialization happening in app_run().
|
||||
**/
|
||||
Pika *
|
||||
pika_init_for_testing (void)
|
||||
{
|
||||
Pika *pika;
|
||||
|
||||
pika_log_init ();
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
pika = pika_new ("Unit Tested PIKA", NULL, NULL, FALSE, TRUE, TRUE, TRUE,
|
||||
FALSE, FALSE, TRUE, FALSE, FALSE,
|
||||
PIKA_STACK_TRACE_QUERY, PIKA_PDB_COMPAT_OFF);
|
||||
|
||||
pika_load_config (pika, NULL, NULL);
|
||||
|
||||
pika_gegl_init (pika);
|
||||
pika_initialize (pika, pika_status_func_dummy);
|
||||
pika_restore (pika, pika_status_func_dummy, NULL);
|
||||
|
||||
return pika;
|
||||
}
|
||||
|
||||
|
||||
#ifndef PIKA_CONSOLE_COMPILATION
|
||||
|
||||
static void
|
||||
pika_init_icon_theme_for_testing (void)
|
||||
{
|
||||
gchar *icon_root;
|
||||
|
||||
icon_root = g_test_build_filename (G_TEST_BUILT, "pika-test-icon-theme", NULL);
|
||||
gtk_icon_theme_prepend_search_path (gtk_icon_theme_get_default (),
|
||||
icon_root);
|
||||
g_free (icon_root);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
static gboolean
|
||||
pika_osx_focus_window (gpointer user_data)
|
||||
{
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
pika_test_app_activate_callback (PikaCoreApp *app,
|
||||
gpointer user_data)
|
||||
{
|
||||
Pika *pika = NULL;
|
||||
|
||||
g_return_if_fail (PIKA_IS_CORE_APP (app));
|
||||
|
||||
pika = pika_core_app_get_pika (app);
|
||||
|
||||
pika_core_app_set_exit_status (app, EXIT_SUCCESS);
|
||||
|
||||
gui_init (pika, TRUE, NULL, g_getenv ("PIKA_TESTING_ABS_TOP_SRCDIR"));
|
||||
pika_init_icon_theme_for_testing ();
|
||||
pika_initialize (pika, pika_status_func_dummy);
|
||||
pika_restore (pika, pika_status_func_dummy, NULL);
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
g_idle_add (pika_osx_focus_window, NULL);
|
||||
#endif
|
||||
pika->initialized = TRUE;
|
||||
pika_core_app_set_exit_status (app, g_test_run ());
|
||||
|
||||
/* Don't write files to the source dir */
|
||||
pika_test_utils_set_pika3_directory ("PIKA_TESTING_ABS_TOP_BUILDDIR",
|
||||
"app/tests/pikadir-output");
|
||||
|
||||
pika_exit (pika, TRUE);
|
||||
}
|
||||
|
||||
static Pika *
|
||||
pika_init_for_gui_testing_internal (gboolean show_gui,
|
||||
GFile *pikarc)
|
||||
{
|
||||
Pika *pika;
|
||||
|
||||
/* Load configuration from the source dir */
|
||||
pika_test_utils_set_pika3_directory ("PIKA_TESTING_ABS_TOP_SRCDIR",
|
||||
"app/tests/pikadir");
|
||||
|
||||
#if defined (G_OS_WIN32)
|
||||
/* g_test_init() sets warnings always fatal, which is a usually a good
|
||||
testing default. Nevertheless the Windows platform may have a few
|
||||
quirks generating warnings, yet we want to finish tests. So we
|
||||
allow some relaxed rules on this platform. */
|
||||
|
||||
GLogLevelFlags fatal_mask;
|
||||
|
||||
fatal_mask = (GLogLevelFlags) (G_LOG_FATAL_MASK | G_LOG_LEVEL_CRITICAL);
|
||||
g_log_set_always_fatal (fatal_mask);
|
||||
#endif
|
||||
|
||||
/* from main() */
|
||||
pika_log_init ();
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
/* Introduce an error margin for positions written to sessionrc */
|
||||
pika_session_info_set_position_accuracy (5);
|
||||
|
||||
/* from app_run() */
|
||||
pika = pika_new ("Unit Tested PIKA", NULL, NULL, FALSE, TRUE, TRUE, !show_gui,
|
||||
FALSE, FALSE, TRUE, FALSE, FALSE,
|
||||
PIKA_STACK_TRACE_QUERY, PIKA_PDB_COMPAT_OFF);
|
||||
pika->app = pika_app_new (pika, TRUE, FALSE, FALSE, NULL, NULL, NULL);
|
||||
|
||||
pika_set_show_gui (pika, show_gui);
|
||||
pika_load_config (pika, pikarc, NULL);
|
||||
pika_gegl_init (pika);
|
||||
|
||||
g_signal_connect (pika->app, "activate",
|
||||
G_CALLBACK (pika_test_app_activate_callback),
|
||||
NULL);
|
||||
return pika;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_init_for_gui_testing:
|
||||
* @show_gui:
|
||||
*
|
||||
* Initializes a #Pika instance for use in test cases that rely on GUI
|
||||
* code to be initialized.
|
||||
*
|
||||
* Returns: The #Pika instance.
|
||||
**/
|
||||
Pika *
|
||||
pika_init_for_gui_testing (gboolean show_gui)
|
||||
{
|
||||
return pika_init_for_gui_testing_internal (show_gui, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_init_for_gui_testing:
|
||||
* @show_gui:
|
||||
* @pikarc:
|
||||
*
|
||||
* Like pika_init_for_gui_testing(), but also allows a custom pikarc
|
||||
* filename to be specified.
|
||||
*
|
||||
* Returns: The #Pika instance.
|
||||
**/
|
||||
Pika *
|
||||
pika_init_for_gui_testing_with_rc (gboolean show_gui,
|
||||
GFile *pikarc)
|
||||
{
|
||||
return pika_init_for_gui_testing_internal (show_gui, pikarc);
|
||||
}
|
||||
|
||||
#endif /* PIKA_CONSOLE_COMPILATION */
|
||||
|
||||
static gboolean
|
||||
pika_tests_quit_mainloop (GMainLoop *loop)
|
||||
{
|
||||
g_main_loop_quit (loop);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_run_temp_mainloop:
|
||||
* @running_time: The time to run the main loop.
|
||||
*
|
||||
* Helper function for tests that wants to run a main loop for a
|
||||
* while. Useful when you want PIKA's state to settle before doing
|
||||
* tests.
|
||||
**/
|
||||
void
|
||||
pika_test_run_temp_mainloop (guint32 running_time)
|
||||
{
|
||||
GMainLoop *loop;
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
g_timeout_add (running_time,
|
||||
(GSourceFunc) pika_tests_quit_mainloop,
|
||||
loop);
|
||||
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_main_loop_unref (loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_run_mainloop_until_idle:
|
||||
*
|
||||
* Creates and runs a main loop until it is idle, i.e. has no more
|
||||
* work to do.
|
||||
**/
|
||||
void
|
||||
pika_test_run_mainloop_until_idle (void)
|
||||
{
|
||||
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
g_idle_add ((GSourceFunc) pika_tests_quit_mainloop, loop);
|
||||
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_main_loop_unref (loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_test_bail_if_no_display:
|
||||
* @void:
|
||||
*
|
||||
* If no DISPLAY is set, call exit(EXIT_SUCCESS). There is no use in
|
||||
* having UI tests failing in DISPLAY-less environments.
|
||||
**/
|
||||
void
|
||||
pika_test_bail_if_no_display (void)
|
||||
{
|
||||
if (! g_getenv ("DISPLAY"))
|
||||
{
|
||||
g_message ("No DISPLAY set, not running UI tests\n");
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
}
|
45
app/tests/tests.h
Normal file
45
app/tests/tests.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 2009 Martin Nordholts
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __TESTS_H__
|
||||
#define __TESTS_H__
|
||||
|
||||
/* Automake doc says:
|
||||
"When no test protocol is in use, an exit status of 0 from a test
|
||||
script will denote a success, an exit status of 77 a skipped test,
|
||||
an exit status of 99 an hard error, and any other exit status will
|
||||
denote a failure."
|
||||
|
||||
Unfortunately glib returns a SUCCESS when you skip tests, which is
|
||||
not a reliable test feedback. So we hard-code the SKIPPED return
|
||||
value. */
|
||||
#define PIKA_EXIT_TEST_SKIPPED 77
|
||||
|
||||
Pika * pika_init_for_testing (void);
|
||||
Pika * pika_init_for_gui_testing (gboolean show_gui);
|
||||
Pika * pika_init_for_gui_testing_with_rc (gboolean show_gui,
|
||||
GFile *pikarc);
|
||||
void pika_test_run_temp_mainloop (guint32 running_time);
|
||||
void pika_test_run_mainloop_until_idle (void);
|
||||
void pika_test_bail_if_no_display (void);
|
||||
|
||||
|
||||
#endif /* __TESTS_H__ */
|
Reference in New Issue
Block a user