mirror of https://github.com/GNOME/gimp.git
plug-ins: add file-plug-in testing framework
Copied over from the original separate work in: https://gitlab.gnome.org/Wormnest/gimp-file-plugin-tests After that further improved and changed and added more file format tests. Added meson.build files to integrate it in our build, but we do not install it for releases.
This commit is contained in:
parent
44225ef1c0
commit
3478e1c00f
|
@ -607,6 +607,47 @@ gimp-win-x86:
|
|||
|
||||
## Analysis ##
|
||||
|
||||
file-plug-in-tests:
|
||||
# FIXME: Do we need another job testing this under Windows? MSYS2 usually has
|
||||
# the latest deps. It might be a good idea to test that too, maybe weekly?
|
||||
extends: .default
|
||||
rules:
|
||||
# Don't run on release since the plug-in doesn't get installed in releases
|
||||
- <<: *CI_MERGE
|
||||
- <<: *CI_COMMIT
|
||||
needs: ["deps-debian-x64", "gimp-debian-x64"]
|
||||
stage: analysis
|
||||
variables:
|
||||
GIMP_TESTS_DATA_FOLDER: "$CI_PROJECT_DIR/_data/gimp-test-images/"
|
||||
GIMP_TESTS_LOG_FILE: "$CI_PROJECT_DIR/_log/import-tests.log"
|
||||
REGRESSION_STRING: "Total number of regressions: 0"
|
||||
cache:
|
||||
- key: "$CI_JOB_NAME"
|
||||
paths:
|
||||
- _data
|
||||
image: $CI_REGISTRY_IMAGE:build-debian-latest
|
||||
artifacts:
|
||||
paths:
|
||||
- _log/
|
||||
expire_in: 2 days
|
||||
script:
|
||||
- API_VER=$(grep GIMP_PKGCONFIG_VERSION _build${ARTIFACTS_SUFFIX}/config.h | head -1 | sed 's/^.*"\([^"]*\)"$/\1/')
|
||||
- APP_VER=$(grep GIMP_USER_VERSION _build${ARTIFACTS_SUFFIX}/config.h | head -1 | sed 's/^.*"\([^"]*\)"$/\1/')
|
||||
- pkg-config --variable=gimplibdir gimp-${API_VER} 2>/dev/null | grep . && PLUG_IN_DIR=$(echo $(pkg-config --variable=gimplibdir gimp-${API_VER})'/plug-ins/')
|
||||
- export PYTHONPATH="${PLUG_IN_DIR}test-file-plug-ins"
|
||||
- export GIMP_TESTS_CONFIG_FILE="${PLUG_IN_DIR}test-file-plug-ins/tests/batch-config.ini"
|
||||
- mkdir _log
|
||||
- mkdir _data && cd _data
|
||||
- git clone --depth=${GIT_DEPTH} https://gitlab.gnome.org/Infrastructure/gimp-test-images.git gimp-test-images
|
||||
- cd ..
|
||||
- cat ${PLUG_IN_DIR}test-file-plug-ins/batch-import-tests.py | gimp-console-${APP_VER} -idf --batch-interpreter python-fu-eval -b - --quit
|
||||
- if [ $(grep -c "${REGRESSION_STRING}" "${GIMP_TESTS_LOG_FILE}") -ne 1 ]; then
|
||||
echo "There are file import regressions. Check the log at ${GIMP_TESTS_LOG_FILE}!";
|
||||
exit 1;
|
||||
fi
|
||||
# FIXME No export testing for now until it's more developed. A limited test
|
||||
# can be done from the plug-in for bmp export.
|
||||
|
||||
clang-format:
|
||||
extends: .default
|
||||
rules:
|
||||
|
|
|
@ -18,6 +18,7 @@ if not stable or not release
|
|||
endif
|
||||
|
||||
subdir('python-console')
|
||||
subdir('tests')
|
||||
|
||||
foreach plugin : plugins
|
||||
name = plugin.get('name')
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
if not have_python
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
subdir('test-file-plug-ins')
|
|
@ -0,0 +1,126 @@
|
|||
# test-file-plugins
|
||||
|
||||
Version 0.5
|
||||
Jacob Boerema, 2021-2024
|
||||
|
||||
## Introduction
|
||||
|
||||
This is a Python 3 framework for testing GIMP file import and export plug-ins.
|
||||
It can be run both as a plug-in from within GIMP (in case it is installed),
|
||||
and from the command line in batch mode.
|
||||
|
||||
|
||||
## Installation and set-up
|
||||
|
||||
1. For running as a plug-in in GIMP this plug-in needs to be in a location
|
||||
that GIMP knows of for plug-ins. By default it is only installed for
|
||||
unstable builds. For using the batch version, it is not necessary to
|
||||
have it installed.
|
||||
2. There is a `tests` folder inside the plug-in folder for
|
||||
configuration files. The main configuration file is
|
||||
`config.ini` for the plug-in; I use a separate `batch-config.ini` for
|
||||
command line testing, but that's not required.
|
||||
This configuration file is where you define the file import and export
|
||||
plug-ins to test. Each plug-in has its own separate configuration
|
||||
file that defines the tests and test files which should be in the same
|
||||
folder.
|
||||
The location and name of the main configuration file can be changed by
|
||||
setting an environment variable: `GIMP_TESTS_CONFIG_FILE`.
|
||||
3. The plug-in specific configuration file, e.g.
|
||||
`png-tests.ini` defines the specific test sets. This configuration file is
|
||||
expected to be in the same location as the main configuration file.
|
||||
Each test set can be enabled/disabled and needs to
|
||||
have a folder set where the test images can be found.
|
||||
This folder is expected to be relative to the base test data folder.
|
||||
By default this is the `./data/` folder, but it can also be
|
||||
changed, see below.
|
||||
The specific test images are defined in a file set in `files=`. These are
|
||||
expected to be in the same folder as the images they are testing.
|
||||
The root folder for all test images is by default `./data/`. This folder can
|
||||
be changed by setting the environment variable `GIMP_TESTS_DATA_FOLDER`.
|
||||
4. The file that defines the images to be tested, should be a text file
|
||||
where each line contains the filename of one test image, optionally
|
||||
followed by a ',' and then a code for the expected result.
|
||||
Currently there are four results defined:
|
||||
- `EXPECTED_OK` (the default if omitted, if loading should succeed)
|
||||
- `EXPECTED_FAIL` (if loading should fail)
|
||||
- `EXPECTED_TODO` (if loading is currently expected to fail, but the
|
||||
intention is to fix this in the future)
|
||||
- `SKIP` (this temporarily skips testing a file, useful when a file causes
|
||||
problems working on other test files) Note: this is **only** intended
|
||||
for temporary debugging purposes. They should not be committed like that
|
||||
to our repository.
|
||||
We may add `EXPECTED_NO_CRASH` in the future, to define fuzzed images
|
||||
where we don't care whether they load or not, as long as there is no crash.
|
||||
|
||||
## How to run
|
||||
|
||||
Start GIMP, then start the plug-in from:
|
||||
- Menu Filters, Development, Python-Fu, Test file import plug-ins.
|
||||
Note: this plug-in is not installed for stable builds.
|
||||
|
||||
Or, from the commandline or a shell script:
|
||||
```
|
||||
export GIMP_TESTS_CONFIG_FILE="/location/of/config.ini"
|
||||
export GIMP_TESTS_LOG_FILE="/location/of/logfile.log"
|
||||
export GIMP_TESTS_DATA_FOLDER="/location/of/test-images/rootfolder/"
|
||||
export PYTHONPATH="/location/of/your/python/script/"
|
||||
cd location/of/plug-in/gimp-file-plugin-tests
|
||||
cat batch-import-tests.py | gimp-console-2.99 -idf --batch-interpreter python-fu-eval -b - --quit
|
||||
```
|
||||
|
||||
In case you run the batch version, the log file is written to the folder
|
||||
where the plug-in resides. This location can be adjusted by setting the
|
||||
environment variable `GIMP_TESTS_LOG_FILE`. Note that the path to this file
|
||||
needs to exist!
|
||||
|
||||
To test for success or regressions in batch mode you can test whether there
|
||||
were regressions.
|
||||
You should grep for `Total number of regressions: 0`.
|
||||
|
||||
### Status
|
||||
|
||||
- The only thing currently being tested is whether the image loads or not. No
|
||||
testing is done to see if the image is correctly shown.
|
||||
- When running all tiff tests from inside GIMP, it may crash, at least on
|
||||
Windows, due to the error console running out of resources because of
|
||||
the amount of messages.
|
||||
- There is some preliminary export testing support, see `batch-export-tests.py`,
|
||||
but it is incomplete. That is: there is no error tracking yet, nor support
|
||||
for comparing exported images with reference images.
|
||||
|
||||
### File import plug-ins being tested
|
||||
|
||||
At this moment the following file import plug-ins have
|
||||
tests available:
|
||||
- file-bmp
|
||||
- file-dcx
|
||||
- file-dds
|
||||
- file-fits
|
||||
- file-gif
|
||||
- file-jpeg
|
||||
- file-pcx
|
||||
- file-png
|
||||
- file-pnm
|
||||
- file-psb
|
||||
- file-psd
|
||||
- file-psd-load-merged
|
||||
- file-psp
|
||||
- file-sgi
|
||||
- file-tga
|
||||
- file-tiff
|
||||
|
||||
|
||||
## Future enhancements
|
||||
|
||||
- Add tests for all our image loading plug-ins.
|
||||
- Test if loaded images are loaded correctly, i.e.
|
||||
do they look like they should.
|
||||
- Fuzzing of images before loading to test our handling of corrupt images.
|
||||
We may need to add another result type: `EXPECTED_NO_CRASH`, meaning we
|
||||
don't care whether it loads or not, as long as there is no crash.
|
||||
- GUI to select/deselect tests.
|
||||
- Improve file export testing.
|
||||
- It would be nice to be able to capture all stdout/stderr output and
|
||||
possibly filter it for crashes, criticals and warnings, and add that to
|
||||
the log file. Maybe with an option to filter out certain kinds of messages.
|
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# GIMP - The GNU Image Manipulation Program
|
||||
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
#
|
||||
# batch-export-tests.py
|
||||
# Copyright (C) 2021-2024 Jacob Boerema
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""Batch non-interactive GIMP file export plug-ins testing."""
|
||||
|
||||
from gimpconfig import GimpConfig
|
||||
from gimplogger import GimpLogger
|
||||
from gimptestframework import GimpExportTestRunner
|
||||
from gimpexporttests import BmpExportTests
|
||||
|
||||
|
||||
#DEBUGGING=True
|
||||
DEBUGGING=False
|
||||
|
||||
#PRINT_VERBOSE = True
|
||||
PRINT_VERBOSE = False
|
||||
|
||||
LOG_APPEND = False
|
||||
|
||||
test_cfg = GimpConfig()
|
||||
|
||||
log = GimpLogger(False, test_cfg.log_file, LOG_APPEND, PRINT_VERBOSE, DEBUGGING)
|
||||
|
||||
runner = GimpExportTestRunner(log, "export", test_cfg)
|
||||
if not runner:
|
||||
log.error("Failed to create export test runner!")
|
||||
else:
|
||||
runner.load_test_configs()
|
||||
|
||||
bmp_tests = BmpExportTests("bmp", log)
|
||||
runner.add_test(bmp_tests)
|
||||
|
||||
# Add additional tests here
|
||||
|
||||
runner.run_tests()
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# GIMP - The GNU Image Manipulation Program
|
||||
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
#
|
||||
# batch-import-tests.py
|
||||
# Copyright (C) 2021-2024 Jacob Boerema
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""Batch non-interactive GIMP file import plug-ins testing."""
|
||||
|
||||
from gimpconfig import GimpConfig
|
||||
from gimplogger import GimpLogger
|
||||
from gimptestframework import GimpTestRunner
|
||||
|
||||
|
||||
#DEBUGGING=True
|
||||
DEBUGGING=False
|
||||
|
||||
#PRINT_VERBOSE = True
|
||||
PRINT_VERBOSE = False
|
||||
|
||||
LOG_APPEND = False
|
||||
|
||||
test_cfg = GimpConfig()
|
||||
|
||||
log = GimpLogger(False, test_cfg.log_file, LOG_APPEND, PRINT_VERBOSE, DEBUGGING)
|
||||
|
||||
runner = GimpTestRunner(log, "import", test_cfg)
|
||||
runner.run_tests()
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# GIMP - The GNU Image Manipulation Program
|
||||
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
#
|
||||
# gimpconfig.py
|
||||
# Copyright (C) 2022-2024 Jacob Boerema
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""Configuration handling for use with our testing framework."""
|
||||
|
||||
|
||||
import os
|
||||
|
||||
class GimpConfig(object):
|
||||
DEFAULT_CONFIG = "config.ini"
|
||||
DEFAULT_CONFIG_FOLDER = "/tests/"
|
||||
DEFAULT_LOGFILE = "/tests/gimp-tests.log"
|
||||
DEFAULT_DATA_FOLDER = "/tests/"
|
||||
|
||||
def __init__(self, config_path=None, log_path=None, data_path=None):
|
||||
base_path = os.path.dirname(os.path.realpath(__file__))
|
||||
if config_path is None:
|
||||
config_path = os.getenv("GIMP_TESTS_CONFIG_FILE")
|
||||
if log_path is None:
|
||||
log_path = os.getenv("GIMP_TESTS_LOG_FILE")
|
||||
if data_path is None:
|
||||
data_path = os.getenv("GIMP_TESTS_DATA_FOLDER")
|
||||
|
||||
if config_path is None:
|
||||
config_path = base_path + self.DEFAULT_CONFIG_FOLDER + self.DEFAULT_CONFIG
|
||||
#print(f"Config path for file plug-in tests: {config_path}")
|
||||
|
||||
self.config_folder = os.path.dirname(config_path)
|
||||
if os.path.exists(self.config_folder):
|
||||
self.config_folder += "/"
|
||||
else:
|
||||
if self.config_folder is not None:
|
||||
print (f"Config folder '{self.config_folder}' does not exist!")
|
||||
self.config_folder = self.DEFAULT_CONFIG_FOLDER
|
||||
|
||||
self.config_file = os.path.basename(config_path)
|
||||
if self.config_file is None:
|
||||
self.config_file = self.DEFAULT_CONFIG
|
||||
|
||||
filepath = self.config_folder + self.config_file
|
||||
if not os.path.exists(filepath):
|
||||
raise Exception(f"Config file '{filepath}' does not exist!")
|
||||
|
||||
if log_path is None:
|
||||
log_path = base_path + self.DEFAULT_LOGFILE
|
||||
|
||||
filepath = os.path.dirname(log_path)
|
||||
if not os.path.exists(filepath):
|
||||
if filepath is not None:
|
||||
print (f"Log file path '{filepath}' does not exist!")
|
||||
self.log_file = self.DEFAULT_LOGFILE
|
||||
else:
|
||||
self.log_file = log_path
|
||||
|
||||
if data_path is None:
|
||||
data_path = base_path + self.DEFAULT_DATA_FOLDER
|
||||
|
||||
self.data_folder = data_path
|
||||
if not os.path.exists(self.data_folder):
|
||||
if self.data_folder is not None:
|
||||
print (f"Data path for test images '{self.data_folder}' does not exist!")
|
||||
self.data_folder = self.DEFAULT_DATA_FOLDER
|
|
@ -0,0 +1,140 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# GIMP - The GNU Image Manipulation Program
|
||||
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
#
|
||||
# gimpexporttests.py
|
||||
# Copyright (C) 2021-2024 Jacob Boerema
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""Module where we add export tests for GIMP's file export plug-ins."""
|
||||
|
||||
import sys
|
||||
|
||||
import gi
|
||||
gi.require_version('Gimp', '3.0')
|
||||
from gi.repository import Gimp
|
||||
from gi.repository import Gio
|
||||
|
||||
from gimptestframework import GimpExportTest
|
||||
|
||||
|
||||
class BmpExportTests(GimpExportTest):
|
||||
def __init__(self, group_name, log):
|
||||
super().__init__(group_name, log)
|
||||
|
||||
def load_bmp(self, bmp_name):
|
||||
pdb_proc = Gimp.get_pdb().lookup_procedure(self.file_import)
|
||||
pdb_config = pdb_proc.create_config()
|
||||
pdb_config.set_property('run-mode', Gimp.RunMode.NONINTERACTIVE)
|
||||
pdb_config.set_property('file', Gio.File.new_for_path(bmp_name))
|
||||
result = pdb_proc.run(pdb_config)
|
||||
status = result.index(0)
|
||||
img = result.index(1)
|
||||
|
||||
if (status == Gimp.PDBStatusType.SUCCESS and img is not None and img.is_valid()):
|
||||
return img
|
||||
else:
|
||||
self.log.error(f"Loading image {bmp_name} failed!")
|
||||
return None
|
||||
|
||||
def export_bmp(self, img, bmp_exp_name, rle, space, rgb):
|
||||
drw = img.list_layers()
|
||||
export_file_path = self.output_path + bmp_exp_name
|
||||
|
||||
pdb_proc = Gimp.get_pdb().lookup_procedure(self.file_export)
|
||||
pdb_config = pdb_proc.create_config()
|
||||
pdb_config.set_property('run-mode', Gimp.RunMode.NONINTERACTIVE)
|
||||
pdb_config.set_property('image', img)
|
||||
pdb_config.set_property('num-drawables', 1)
|
||||
pdb_config.set_property('drawables', Gimp.ObjectArray.new(Gimp.Drawable, drw, False))
|
||||
pdb_config.set_property('file', Gio.File.new_for_path(export_file_path))
|
||||
pdb_config.set_property('use-rle', rle)
|
||||
pdb_config.set_property('write-color-space', space)
|
||||
pdb_config.set_property('rgb-format', rgb)
|
||||
|
||||
result = pdb_proc.run(pdb_config)
|
||||
status = result.index(0)
|
||||
if status == Gimp.PDBStatusType.SUCCESS:
|
||||
self.log.info(f"Exporting image {export_file_path} succeeded.")
|
||||
else:
|
||||
self.log.error(f"Exporting image {export_file_path} failed!")
|
||||
|
||||
def bmp_setup(self, image_name, test_description):
|
||||
self.log.consoleinfo(test_description)
|
||||
tmp = self.input_path + image_name
|
||||
img = self.load_bmp(tmp)
|
||||
return img
|
||||
|
||||
def bmp_teardown(self, image):
|
||||
if image is not None:
|
||||
image.delete()
|
||||
|
||||
def bmp_1bpp_indexed(self, image_name, test_description):
|
||||
img = self.bmp_setup(image_name, test_description)
|
||||
if img is not None:
|
||||
self.export_bmp(img, "1bpp-norle-nospace.bmp", 0, 0, 0)
|
||||
self.export_bmp(img, "1bpp-norle-withspace.bmp", 0, 1, 0)
|
||||
# rle with 1-bit is not valid, test to see if it
|
||||
# is correctly ignored...
|
||||
self.export_bmp(img, "1bpp-rle-nospace.bmp", 1, 0, 0)
|
||||
self.export_bmp(img, "1bpp-rle-withspace.bmp", 1, 1, 0)
|
||||
self.bmp_teardown(img)
|
||||
|
||||
def bmp_4bpp_indexed(self, image_name, test_description):
|
||||
img = self.bmp_setup(image_name, test_description)
|
||||
if img is not None:
|
||||
self.export_bmp(img, "4bpp-norle-nospace.bmp", 0, 0, 0)
|
||||
self.export_bmp(img, "4bpp-norle-withspace.bmp", 0, 1, 0)
|
||||
self.export_bmp(img, "4bpp-rle-nospace.bmp", 1, 0, 0)
|
||||
self.export_bmp(img, "4bpp-rle-withspace.bmp", 1, 1, 0)
|
||||
self.bmp_teardown(img)
|
||||
|
||||
def bmp_8bpp_indexed(self, image_name, test_description):
|
||||
img = self.bmp_setup(image_name, test_description)
|
||||
if img is not None:
|
||||
self.export_bmp(img, "8bpp-norle-nospace.bmp", 0, 0, 0)
|
||||
self.export_bmp(img, "8bpp-norle-withspace.bmp", 0, 1, 0)
|
||||
self.export_bmp(img, "8bpp-rle-nospace.bmp", 1, 0, 0)
|
||||
self.export_bmp(img, "8bpp-rle-withspace.bmp", 1, 1, 0)
|
||||
self.bmp_teardown(img)
|
||||
|
||||
def bmp_rgba(self, image_name, test_description):
|
||||
img = self.bmp_setup(image_name, test_description)
|
||||
if img is not None:
|
||||
# first test correctly ignoring rle
|
||||
self.export_bmp(img, "rgb-with-rle-nospace.bmp", 1, 0, 3)
|
||||
# All rgb modes without color space
|
||||
self.export_bmp(img, "rgb-nrle-nospace-type0.bmp", 0, 0, 0)
|
||||
self.export_bmp(img, "rgb-nrle-nospace-type1.bmp", 0, 0, 1)
|
||||
self.export_bmp(img, "rgb-nrle-nospace-type2.bmp", 0, 0, 2)
|
||||
self.export_bmp(img, "rgb-nrle-nospace-type3.bmp", 0, 0, 3)
|
||||
self.export_bmp(img, "rgb-nrle-nospace-type4.bmp", 0, 0, 4)
|
||||
self.export_bmp(img, "rgb-nrle-nospace-type5.bmp", 0, 0, 5)
|
||||
# All rgb modes with color space
|
||||
self.export_bmp(img, "rgb-nrle-withspace-type0.bmp", 0, 1, 0)
|
||||
self.export_bmp(img, "rgb-nrle-withspace-type1.bmp", 0, 1, 1)
|
||||
self.export_bmp(img, "rgb-nrle-withspace-type2.bmp", 0, 1, 2)
|
||||
self.export_bmp(img, "rgb-nrle-withspace-type3.bmp", 0, 1, 3)
|
||||
self.export_bmp(img, "rgb-nrle-withspace-type4.bmp", 0, 1, 4)
|
||||
self.export_bmp(img, "rgb-nrle-withspace-type5.bmp", 0, 1, 5)
|
||||
self.bmp_teardown(img)
|
||||
|
||||
def run_test(self, group_config):
|
||||
self.bmp_1bpp_indexed('test1-exp1.bmp', " 1. Using 1bpp indexed BMP...")
|
||||
self.bmp_4bpp_indexed('pal4rle-exp1.bmp', " 2. Using 4bpp indexed BMP...")
|
||||
self.bmp_8bpp_indexed('pal8v5-exp1.bmp', " 3. Using 8bpp indexed BMP...")
|
||||
self.bmp_rgba('rgb32-with-alpha-1.bmp', " 4. Using rgb(a) BMP...")
|
|
@ -0,0 +1,100 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# GIMP - The GNU Image Manipulation Program
|
||||
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
#
|
||||
# gimplogger.py
|
||||
# Copyright (C) 2021-2024 Jacob Boerema
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""Logging framework for use with GIMP Python plug-ins."""
|
||||
|
||||
import os
|
||||
import logging
|
||||
|
||||
import gi
|
||||
gi.require_version('Gimp', '3.0')
|
||||
from gi.repository import Gimp
|
||||
|
||||
|
||||
class GimpLogger (object):
|
||||
def __init__(self, interactive, logfile, append=False, verbose=False, debugging=False):
|
||||
self.interactive = interactive
|
||||
|
||||
self.verbose = verbose
|
||||
self.debugging = debugging
|
||||
|
||||
if debugging:
|
||||
log_level = logging.DEBUG
|
||||
else:
|
||||
log_level = logging.INFO
|
||||
if append:
|
||||
log_filemode = 'a'
|
||||
else:
|
||||
log_filemode = 'w'
|
||||
|
||||
logging.basicConfig(
|
||||
filename=logfile,
|
||||
filemode=log_filemode,
|
||||
encoding='utf-8',
|
||||
level=log_level,
|
||||
format='%(asctime)s | %(name)s | %(levelname)s | %(message)s')
|
||||
|
||||
logging.debug("Starting logger...")
|
||||
logging.debug("Log file: %s", os.path.abspath(logfile))
|
||||
|
||||
def set_interactive(self, interactive):
|
||||
if self.interactive != interactive:
|
||||
self.interactive = interactive
|
||||
logging.debug("Interactive set to %s", self.interactive)
|
||||
|
||||
def message(self, msg):
|
||||
logging.info(msg)
|
||||
print(msg)
|
||||
if self.interactive:
|
||||
Gimp.message(msg)
|
||||
|
||||
def gimp_verbose_message(self, msg):
|
||||
if self.verbose and self.interactive:
|
||||
Gimp.message(msg)
|
||||
|
||||
def info(self, msg):
|
||||
if self.verbose:
|
||||
logging.info(msg)
|
||||
print(msg)
|
||||
|
||||
def consoleinfo(self, msg):
|
||||
logging.info(msg)
|
||||
print(msg)
|
||||
|
||||
def warning(self, msg):
|
||||
warn_msg = 'WARNING: ' + msg
|
||||
logging.warning(msg)
|
||||
print(warn_msg)
|
||||
if self.interactive:
|
||||
Gimp.message(warn_msg)
|
||||
|
||||
def error(self, msg):
|
||||
err_msg = 'ERROR: ' + msg
|
||||
logging.error(msg)
|
||||
print(err_msg)
|
||||
if self.interactive:
|
||||
Gimp.message(err_msg)
|
||||
|
||||
def debug(self, msg):
|
||||
logging.debug(msg)
|
||||
if self.debugging:
|
||||
print(msg)
|
|
@ -0,0 +1,573 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# GIMP - The GNU Image Manipulation Program
|
||||
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
#
|
||||
# gimptestframework.py
|
||||
# Copyright (C) 2021-2024 Jacob Boerema
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""GIMP file plug-ins testing framework."""
|
||||
|
||||
import os
|
||||
import configparser
|
||||
|
||||
import gi
|
||||
gi.require_version('Gimp', '3.0')
|
||||
from gi.repository import Gimp
|
||||
from gi.repository import Gio
|
||||
|
||||
|
||||
VERSION = "0.5"
|
||||
AUTHORS = "Jacob Boerema"
|
||||
YEARS = "2021-2024"
|
||||
|
||||
EXPECTED_FAIL = 0
|
||||
EXPECTED_OK = 1
|
||||
EXPECTED_TODO = 2
|
||||
|
||||
RESULT_FAIL = 0
|
||||
RESULT_OK = 1
|
||||
RESULT_CRASH = 2
|
||||
|
||||
|
||||
class PluginTestConfig(object):
|
||||
def __init__(self, log, path, testconfig):
|
||||
self.valid_config = False
|
||||
self.enabled = False
|
||||
|
||||
self.plugin = testconfig.get('plugin-import')
|
||||
if self.plugin is None:
|
||||
self.plugin = testconfig.get('plugin')
|
||||
if self.plugin is not None:
|
||||
log.warning("Test is using deprecated 'plugin' parameter. Use 'plugin-import' instead!")
|
||||
else:
|
||||
log.error("Missing required 'plugin-import' parameter!")
|
||||
return
|
||||
|
||||
tests = testconfig.get('tests')
|
||||
if tests is None:
|
||||
log.error("Missing required 'tests' parameter!")
|
||||
return
|
||||
self.tests = path + tests
|
||||
|
||||
enabled = testconfig.get('enabled')
|
||||
if enabled == 'True':
|
||||
self.enabled = True
|
||||
|
||||
self.extension = testconfig.get('extension','<missing>')
|
||||
self.valid_config = True
|
||||
|
||||
# preliminary export testing support
|
||||
self.export_plugin = testconfig.get('plugin-export')
|
||||
self.export_tests = testconfig.get('tests-export')
|
||||
self.export_enabled = testconfig.get('enabled-export')
|
||||
|
||||
|
||||
class ConfigLoader(object):
|
||||
def __init__(self, log, config_path, config_file):
|
||||
self.config_path = config_path
|
||||
self.config_file = config_file
|
||||
log.debug(f"Using config file: {self.config_path}{self.config_file}")
|
||||
self.tests = []
|
||||
self.export_tests = []
|
||||
self.problems = 0
|
||||
self.disabled = 0
|
||||
self.config = configparser.ConfigParser()
|
||||
self.config.read(self.config_path + self.config_file)
|
||||
|
||||
msg = "Available tests:"
|
||||
for key in self.config.sections():
|
||||
if key == 'main':
|
||||
pass
|
||||
else:
|
||||
# Add test config
|
||||
test = PluginTestConfig(log, self.config_path, self.config[key])
|
||||
if test.valid_config:
|
||||
self.tests.append(test)
|
||||
msg += f"\nPlugin: {test.plugin}, test config: {test.tests}, enabled: {test.enabled}"
|
||||
if not test.enabled:
|
||||
self.disabled += 1
|
||||
else:
|
||||
log.warning(f"\nSkipping invalid config for {key}!")
|
||||
self.problems += 1
|
||||
|
||||
if test.export_plugin is not None and test.export_tests is not None:
|
||||
log.info(f"Export test found for {key}")
|
||||
self.export_tests.append(test)
|
||||
|
||||
log.gimp_verbose_message(msg)
|
||||
|
||||
class FileLoadTest(object):
|
||||
def __init__(self, file_load_plugin_name, image_type, data_path, log):
|
||||
self.log = log
|
||||
self.data_root = data_path
|
||||
self.plugin_name = file_load_plugin_name
|
||||
self.image_type = image_type
|
||||
|
||||
self.unexpected_success_images = []
|
||||
self.unexpected_failure_images = []
|
||||
|
||||
self.total_tests = 0
|
||||
self.total_failed = 0
|
||||
self.total_todo = 0
|
||||
self.total_ok = 0
|
||||
self.total_crash = 0
|
||||
|
||||
def run_file_load(self, image_file, expected):
|
||||
if not os.path.exists(image_file):
|
||||
msg = "Regression loading " + image_file + ". File does not exist!"
|
||||
self.log.error("--> " + msg)
|
||||
return RESULT_FAIL
|
||||
|
||||
pdb_proc = Gimp.get_pdb().lookup_procedure(self.plugin_name)
|
||||
if pdb_proc is None:
|
||||
msg = "Plug-in procedure '" + self.plugin_name + "' not found!"
|
||||
self.log.error("--> " + msg)
|
||||
return RESULT_FAIL
|
||||
pdb_config = pdb_proc.create_config()
|
||||
pdb_config.set_property('run-mode', Gimp.RunMode.NONINTERACTIVE)
|
||||
pdb_config.set_property('file', Gio.File.new_for_path(image_file))
|
||||
result = pdb_proc.run(pdb_config)
|
||||
status = result.index(0)
|
||||
img = result.index(1)
|
||||
if (status == Gimp.PDBStatusType.SUCCESS and img is not None and img.is_valid()):
|
||||
self.log.info ("Loading succeeded for " + image_file)
|
||||
img.delete()
|
||||
if expected == EXPECTED_FAIL:
|
||||
self.unexpected_success_images.append(image_file)
|
||||
msg = "Regression loading " + image_file + ". Loading unexpectedly succeeded."
|
||||
self.log.error("--> " + msg)
|
||||
return RESULT_FAIL
|
||||
elif expected == EXPECTED_TODO:
|
||||
self.unexpected_success_images.append(image_file)
|
||||
msg = "Loading unexpectedly succeeded for test marked TODO. Image: " + image_file
|
||||
self.log.error("--> " + msg)
|
||||
return RESULT_FAIL
|
||||
|
||||
return RESULT_OK
|
||||
else:
|
||||
self.log.info ("Loading failed for " + image_file)
|
||||
if status == Gimp.PDBStatusType.CALLING_ERROR:
|
||||
# A calling error indicates the plug-in crashed, which should
|
||||
# always be considered failure!
|
||||
if expected == EXPECTED_OK:
|
||||
self.unexpected_failure_images.append(image_file)
|
||||
elif expected == EXPECTED_TODO:
|
||||
self.unexpected_success_images.append(image_file)
|
||||
msg = "Plug-in crashed while loading " + image_file + "."
|
||||
self.log.error("--> " + msg)
|
||||
return RESULT_CRASH
|
||||
elif expected == EXPECTED_OK:
|
||||
self.unexpected_failure_images.append(image_file)
|
||||
msg = "Regression loading " + image_file + ". Loading unexpectedly failed."
|
||||
self.log.error("--> " + msg)
|
||||
return RESULT_FAIL
|
||||
return RESULT_OK
|
||||
|
||||
def load_test_images(self, test_images):
|
||||
test_list = []
|
||||
|
||||
if not os.path.exists(test_images):
|
||||
msg = "Path does not exist: " + test_images
|
||||
self.log.error(msg)
|
||||
return None
|
||||
|
||||
with open(test_images, encoding='UTF-8') as f:
|
||||
try:
|
||||
content = f.readlines()
|
||||
except UnicodeDecodeError as err:
|
||||
self.log.error(f"Invalid encoding for {test_images}: {err}")
|
||||
return None
|
||||
|
||||
# strip whitespace
|
||||
content = [x.strip() for x in content]
|
||||
|
||||
for line in content:
|
||||
data = line.split(",")
|
||||
data[0] = data[0].strip()
|
||||
if len(data) > 1:
|
||||
expected_str = data[1].strip()
|
||||
else:
|
||||
expected_str = 'EXPECTED_OK'
|
||||
data.append(expected_str)
|
||||
|
||||
if expected_str == 'EXPECTED_FAIL':
|
||||
data[1] = EXPECTED_FAIL
|
||||
elif expected_str == 'EXPECTED_TODO':
|
||||
data[1] = EXPECTED_TODO
|
||||
elif expected_str == 'SKIP':
|
||||
continue
|
||||
else:
|
||||
# Assume that anything else is supposed to load OK
|
||||
data[1] = EXPECTED_OK
|
||||
test_list.append(data)
|
||||
|
||||
return test_list
|
||||
|
||||
def run_tests(self, image_folder, test_images, test_description):
|
||||
test_fail = 0
|
||||
test_ok = 0
|
||||
test_todo = 0
|
||||
test_crash = 0
|
||||
test_total = 0
|
||||
test_images_list = self.load_test_images(test_images)
|
||||
if not test_images_list:
|
||||
# Maybe we should create another type of test failure (test_filesystem?)
|
||||
test_fail += 1
|
||||
test_crash += 1
|
||||
self.total_failed += test_fail
|
||||
self.total_crash += test_crash
|
||||
msg = f"No images found for '{test_description}'.'"
|
||||
self.log.error(msg)
|
||||
return
|
||||
test_total = len(test_images_list)
|
||||
|
||||
for imgfile, expected in test_images_list:
|
||||
test_result = self.run_file_load(self.data_root + image_folder + imgfile, expected)
|
||||
if test_result == RESULT_FAIL:
|
||||
test_fail += 1
|
||||
elif test_result == RESULT_OK:
|
||||
test_ok += 1
|
||||
elif test_result == RESULT_CRASH:
|
||||
test_crash += 1
|
||||
test_fail += 1
|
||||
else:
|
||||
test_crash += 1
|
||||
test_fail += 1
|
||||
msg = "Invalid test result value: " + str(test_result)
|
||||
self.log.error(msg)
|
||||
|
||||
if expected == EXPECTED_TODO:
|
||||
test_todo += 1
|
||||
|
||||
result_msg = "Test: " + test_description + "\n"
|
||||
if test_crash > 0:
|
||||
result_msg += "Number of plug-in crashes: " + str(test_crash) + "\n"
|
||||
|
||||
if test_fail > 0:
|
||||
result_msg += "Failed " + str(test_fail) + " of " + str(test_total) + " tests"
|
||||
if test_todo > 0:
|
||||
result_msg += ", and " + str(test_todo) + " known test failures."
|
||||
elif test_todo > 0:
|
||||
result_msg += "All " + str(test_total) + " tests succeeded, but there are " + str(test_todo) + " known test failures."
|
||||
else:
|
||||
result_msg += "All " + str(test_total) + " tests succeeded."
|
||||
|
||||
self.log.info("\n--- results ---")
|
||||
self.log.info(result_msg)
|
||||
if ((test_fail > 0 or test_todo > 0) and self.log.interactive):
|
||||
Gimp.message (result_msg)
|
||||
|
||||
self.total_tests += test_total
|
||||
self.total_todo += test_todo
|
||||
self.total_failed += test_fail
|
||||
self.total_ok += test_ok
|
||||
self.total_crash += test_crash
|
||||
|
||||
def show_results_total(self):
|
||||
msg = "\n----- Test result totals -----"
|
||||
msg += f"\nTotal {self.image_type} tests: {self.total_tests}"
|
||||
if self.total_crash > 0:
|
||||
msg += f"\nTests crashed: {self.total_crash}"
|
||||
msg += f"\nTests failed: {self.total_failed}"
|
||||
if self.total_crash > 0:
|
||||
msg += f" (including crashes)"
|
||||
msg += f"\nTests todo: {self.total_todo}"
|
||||
self.log.message(msg)
|
||||
|
||||
msg = ""
|
||||
for img in self.unexpected_success_images:
|
||||
msg += f"{img}\n"
|
||||
if len(msg) > 0:
|
||||
msg = "\nImages that unexpectedly loaded:\n" + msg
|
||||
self.log.message(msg)
|
||||
msg = ""
|
||||
for img in self.unexpected_failure_images:
|
||||
msg += f"{img}\n"
|
||||
if len(msg) > 0:
|
||||
msg = "\nImages that unexpectedly failed to load:\n" + msg
|
||||
self.log.message(msg)
|
||||
|
||||
class RunTests(object):
|
||||
def __init__(self, test, config_path, data_path, log):
|
||||
self.test_count = 0
|
||||
self.regression_count = 0
|
||||
if os.path.exists(test.tests):
|
||||
self.plugin_test = FileLoadTest(test.plugin, test.extension, data_path, log)
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.read(test.tests)
|
||||
for subtest in cfg.sections():
|
||||
if not 'description' in cfg[subtest]:
|
||||
description = "Missing description for " + test.extension
|
||||
else:
|
||||
description = cfg[subtest]['description']
|
||||
enabled = True
|
||||
if 'enabled' in cfg[subtest]:
|
||||
if cfg[subtest]['enabled'] == 'False':
|
||||
enabled = False
|
||||
folder = cfg[subtest]['folder']
|
||||
files = self.plugin_test.data_root + folder + cfg[subtest]['files']
|
||||
if enabled:
|
||||
self.plugin_test.run_tests(folder, files, description)
|
||||
else:
|
||||
log.info(f"Testing is disabled for: {description}.")
|
||||
|
||||
self.plugin_test.show_results_total()
|
||||
self.test_count = self.plugin_test.total_tests
|
||||
self.regression_count = self.plugin_test.total_failed
|
||||
else:
|
||||
self.plugin_test = None
|
||||
log.error("Test path " + test.tests + " does not exist!")
|
||||
self.regression_count = 1
|
||||
|
||||
def get_unexpected_success_regressions(self):
|
||||
return self.plugin_test.unexpected_success_images
|
||||
|
||||
def get_unexpected_failure_regressions(self):
|
||||
return self.plugin_test.unexpected_failure_images
|
||||
|
||||
def get_todo_count(self):
|
||||
return self.plugin_test.total_todo
|
||||
|
||||
def get_crash_count(self):
|
||||
return self.plugin_test.total_crash
|
||||
|
||||
|
||||
class GimpTestRunner(object):
|
||||
def __init__(self, log, test_type, test_cfg):
|
||||
self.log = log
|
||||
self.test_type = test_type
|
||||
self.test_cfg = test_cfg
|
||||
|
||||
self.tests_total = 0
|
||||
self.error_total = 0
|
||||
self.todo_total = 0
|
||||
self.crash_total = 0
|
||||
|
||||
self.unexpected_success_images = []
|
||||
self.unexpected_failure_images = []
|
||||
|
||||
def print_header(self, test_type):
|
||||
divider = "\n--------------------------------"
|
||||
msg = f"\nGIMP file plug-in tests version {VERSION}\n"
|
||||
#msg += f"\n{AUTHORS}, {YEARS}\n"
|
||||
msg += f"\n--- Starting {test_type} test run ---"
|
||||
msg += divider
|
||||
|
||||
if self.log.verbose:
|
||||
msg += f"\nConfig: {self.test_cfg.config_folder + self.test_cfg.config_file}"
|
||||
msg += f"\nLog: {self.test_cfg.log_file}"
|
||||
msg += f"\nData path: {self.test_cfg.data_folder}"
|
||||
|
||||
self.log.message(msg)
|
||||
|
||||
def print_footer(self, msg):
|
||||
msg += "\n--------------------------------"
|
||||
self.log.message(msg)
|
||||
|
||||
def list_regressions(self):
|
||||
regression_list = ""
|
||||
msg = ""
|
||||
extra = "\n"
|
||||
for img in self.unexpected_success_images:
|
||||
msg += f"\n{img}"
|
||||
if len(msg) > 0:
|
||||
regression_list = "\nImages that unexpectedly loaded:" + msg + extra
|
||||
extra = ""
|
||||
|
||||
msg = ""
|
||||
for img in self.unexpected_failure_images:
|
||||
msg += f"\n{img}"
|
||||
if len(msg) > 0:
|
||||
regression_list += "\nImages that unexpectedly failed to load:" + msg + extra
|
||||
|
||||
return regression_list
|
||||
|
||||
def run_tests(self):
|
||||
self.print_header(self.test_type)
|
||||
|
||||
# Load test config
|
||||
cfg = ConfigLoader(self.log, self.test_cfg.config_folder, self.test_cfg.config_file)
|
||||
|
||||
# Actual tests
|
||||
for test in cfg.tests:
|
||||
if test.enabled:
|
||||
self.log.consoleinfo(f"\nTesting {test.extension} import using {test.plugin}...\n")
|
||||
plugin_tests = RunTests(test, cfg.config_path, self.test_cfg.data_folder, self.log)
|
||||
self.tests_total += plugin_tests.test_count
|
||||
self.error_total += plugin_tests.regression_count
|
||||
if plugin_tests.plugin_test is not None:
|
||||
self.todo_total += plugin_tests.get_todo_count()
|
||||
self.crash_total += plugin_tests.get_crash_count()
|
||||
if plugin_tests.regression_count > 0:
|
||||
temp = plugin_tests.get_unexpected_success_regressions()
|
||||
if len(temp) > 0:
|
||||
self.unexpected_success_images.extend(temp)
|
||||
temp = plugin_tests.get_unexpected_failure_regressions()
|
||||
if len(temp) > 0:
|
||||
self.unexpected_failure_images.extend(temp)
|
||||
else:
|
||||
self.crash_total += 1
|
||||
self.log.consoleinfo(f"\nFinished testing {test.extension}\n")
|
||||
else:
|
||||
self.log.consoleinfo(f"Testing {test.extension} import using {test.plugin} is disabled.")
|
||||
|
||||
msg = "\n--------- Test results ---------"
|
||||
if cfg.disabled > 0:
|
||||
msg += f"\nNumber of test sections disabled: {cfg.disabled}"
|
||||
if cfg.problems > 0:
|
||||
msg += f"\nNumber of test sections skipped due to configuration errors: {cfg.problems}"
|
||||
msg += f"\nTotal number of tests executed: {self.tests_total}"
|
||||
msg += f"\nTotal number of regressions: {self.error_total}"
|
||||
if self.crash_total > 0:
|
||||
msg += f"\nTotal number of crashes: {self.crash_total}"
|
||||
if self.todo_total > 0:
|
||||
msg += f"\nTotal number of todo tests: {self.todo_total}"
|
||||
if self.error_total > 0:
|
||||
msg += "\n" + self.list_regressions()
|
||||
self.print_footer(msg)
|
||||
|
||||
class GimpExportTestGroup(object):
|
||||
def __init__(self, group_test_cfg, group_name, group_description,
|
||||
input_folder, output_folder):
|
||||
self.group_test_cfg = group_test_cfg
|
||||
self.group_name = group_name
|
||||
self.group_description = group_description
|
||||
self.input_folder = input_folder
|
||||
self.output_folder = output_folder
|
||||
|
||||
class GimpExportTestSections(object):
|
||||
def __init__(self, test, config_path, data_path, log):
|
||||
self.test_groups = []
|
||||
self.test_count = 0
|
||||
self.regression_count = 0
|
||||
self.export_test_path = config_path + test.export_tests
|
||||
if os.path.exists(self.export_test_path):
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.read(self.export_test_path)
|
||||
for subtest in cfg.sections():
|
||||
if not 'description' in cfg[subtest]:
|
||||
description = "Missing description for " + test.extension
|
||||
log.warning(f"Missing description for {test.extension}")
|
||||
else:
|
||||
description = cfg[subtest]['description']
|
||||
log.info(f"Test: {description}")
|
||||
enabled = True
|
||||
if 'enabled' in cfg[subtest]:
|
||||
if cfg[subtest]['enabled'] == 'False':
|
||||
enabled = False
|
||||
|
||||
folder_input = cfg[subtest]['folder-input']
|
||||
folder_output = cfg[subtest]['folder-output']
|
||||
if enabled:
|
||||
group = GimpExportTestGroup(test, test.extension, description,
|
||||
folder_input, folder_output)
|
||||
self.test_groups.append(group)
|
||||
else:
|
||||
log.info(f"Testing is disabled for: {description}.")
|
||||
|
||||
else:
|
||||
log.error("Test path " + test.export_tests + " does not exist!")
|
||||
self.regression_count = 1
|
||||
|
||||
class GimpExportTest(object):
|
||||
def __init__(self, group_name, log):
|
||||
self.group_name = group_name
|
||||
self.log = log
|
||||
|
||||
self.base_path = None
|
||||
self.input_path = None
|
||||
self.output_path = None
|
||||
self.file_import = None
|
||||
self.file_export = None
|
||||
|
||||
def _setup(self, group_config, test_data_path):
|
||||
self.base_path = test_data_path
|
||||
self.input_path = self.base_path + group_config.input_folder
|
||||
self.output_path = self.base_path + group_config.output_folder
|
||||
if self.base_path is None or self.input_path is None or self.output_path is None:
|
||||
return False
|
||||
|
||||
self.file_import = group_config.group_test_cfg.plugin
|
||||
self.file_export = group_config.group_test_cfg.export_plugin
|
||||
if self.file_import is None or self.file_export is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
def setup(self, group_config):
|
||||
pass
|
||||
|
||||
def teardown(self, group_config):
|
||||
pass
|
||||
|
||||
def run_test(self, group_config):
|
||||
pass
|
||||
|
||||
def execute(self, group_config, test_data_path):
|
||||
if not self._setup(group_config, test_data_path):
|
||||
self.log.error("Invalid config, can't execute test!")
|
||||
return
|
||||
self.setup(group_config)
|
||||
self.run_test(group_config)
|
||||
self.teardown(group_config)
|
||||
|
||||
class GimpExportTestRunner(GimpTestRunner):
|
||||
def __init__(self, log, test_type, test_cfg):
|
||||
self.cfg = None
|
||||
self.log = log
|
||||
self.test_type = test_type
|
||||
self.test_cfg = test_cfg
|
||||
self.sections = None
|
||||
self.tests = []
|
||||
super().__init__(log, test_type, test_cfg)
|
||||
|
||||
def load_test_configs(self):
|
||||
self.cfg = ConfigLoader(self.log, self.test_cfg.config_folder,
|
||||
self.test_cfg.config_file)
|
||||
for test in self.cfg.export_tests:
|
||||
if test.export_enabled:
|
||||
self.sections = GimpExportTestSections(test, self.cfg.config_path,
|
||||
self.test_cfg.data_folder,
|
||||
self.log)
|
||||
else:
|
||||
pass
|
||||
|
||||
def get_test_group_config(self, test_name):
|
||||
#FIXME maybe have this sorted and use a search...
|
||||
for test in self.sections.test_groups:
|
||||
if test.group_name == test_name:
|
||||
return test
|
||||
return None
|
||||
|
||||
def add_test(self, test_class):
|
||||
self.log.info(f"Adding tests for {test_class.group_name}")
|
||||
self.tests.append(test_class)
|
||||
|
||||
def run_tests(self):
|
||||
self.print_header(self.test_type)
|
||||
for test in self.tests:
|
||||
self.log.message(f"Running tests for {test.group_name}")
|
||||
test_config = self.get_test_group_config(test.group_name)
|
||||
if test_config is None:
|
||||
self.log.error(f"Could not find configuration for {test.group_name}!")
|
||||
else:
|
||||
test.execute(test_config, self.test_cfg.data_folder)
|
||||
self.print_footer("Export tests finished")
|
||||
|
||||
def show_results(self):
|
||||
#FIXME export results are not implemented yet
|
||||
pass
|
|
@ -0,0 +1,23 @@
|
|||
if not stable or not release
|
||||
|
||||
# This does not get installed for releases
|
||||
plugins += {
|
||||
'name': 'test-file-plug-ins',
|
||||
'srcs': [
|
||||
# modules
|
||||
'tests/test-file-plug-ins/gimplogger.py',
|
||||
'tests/test-file-plug-ins/gimpconfig.py',
|
||||
'tests/test-file-plug-ins/gimptestframework.py',
|
||||
'tests/test-file-plug-ins/gimpexporttests.py',
|
||||
# actual GIMP plug-in
|
||||
'tests/test-file-plug-ins/test-file-plug-ins.py',
|
||||
# scripts to start the tests in batch mode
|
||||
'tests/test-file-plug-ins/batch-import-tests.py',
|
||||
'tests/test-file-plug-ins/batch-export-tests.py',
|
||||
],
|
||||
}
|
||||
|
||||
# configuration data for the tests
|
||||
subdir('tests')
|
||||
|
||||
endif
|
|
@ -0,0 +1,124 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# GIMP - The GNU Image Manipulation Program
|
||||
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
#
|
||||
# test-file-plug-ins.py
|
||||
# Copyright (C) 2021-2024 Jacob Boerema
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""Plug-in to test GIMP file import plug-ins from within GIMP."""
|
||||
|
||||
import sys
|
||||
|
||||
import gi
|
||||
gi.require_version('Gimp', '3.0')
|
||||
from gi.repository import Gimp
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
from gimpconfig import GimpConfig
|
||||
from gimplogger import GimpLogger
|
||||
from gimptestframework import GimpTestRunner, GimpExportTestRunner, AUTHORS, YEARS, VERSION
|
||||
from gimpexporttests import BmpExportTests
|
||||
|
||||
|
||||
#DEBUGGING=True
|
||||
DEBUGGING=False
|
||||
|
||||
#PRINT_VERBOSE = True
|
||||
PRINT_VERBOSE = False
|
||||
|
||||
LOG_APPEND = False
|
||||
|
||||
|
||||
test_cfg = GimpConfig()
|
||||
|
||||
log = GimpLogger(False, test_cfg.log_file, LOG_APPEND, PRINT_VERBOSE, DEBUGGING)
|
||||
|
||||
|
||||
class PythonTest (Gimp.PlugIn):
|
||||
|
||||
## GimpPlugIn virtual methods ##
|
||||
def do_set_i18n(self, _name):
|
||||
# We don't support internationalization here...
|
||||
return False
|
||||
|
||||
def do_query_procedures(self):
|
||||
return [ 'test-import-plug-ins',
|
||||
'test-export-plug-ins' ]
|
||||
|
||||
def do_create_procedure(self, name):
|
||||
|
||||
if name == 'test-import-plug-ins':
|
||||
procedure = Gimp.ImageProcedure.new(self, name,
|
||||
Gimp.PDBProcType.PLUGIN,
|
||||
self.run_import_tests, None)
|
||||
procedure.set_image_types("*")
|
||||
procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.ALWAYS)
|
||||
procedure.set_menu_label('Test file _import plug-ins')
|
||||
procedure.add_menu_path('<Image>/Filters/Development/Python-Fu/')
|
||||
procedure.set_documentation('Run file import plug-in tests',
|
||||
'Run file import plug-in tests',
|
||||
name)
|
||||
elif name == 'test-export-plug-ins':
|
||||
procedure = Gimp.ImageProcedure.new(self, name,
|
||||
Gimp.PDBProcType.PLUGIN,
|
||||
self.run_export_tests, None)
|
||||
procedure.set_image_types("*")
|
||||
procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.ALWAYS)
|
||||
procedure.set_menu_label('Test file _export plug-ins')
|
||||
procedure.add_menu_path('<Image>/Filters/Development/Python-Fu/')
|
||||
procedure.set_documentation('Run file export plug-in tests',
|
||||
'Run file export plug-in tests',
|
||||
name)
|
||||
else:
|
||||
return None
|
||||
|
||||
procedure.set_attribution(AUTHORS, #author
|
||||
AUTHORS, #copyright
|
||||
YEARS) #year
|
||||
return procedure
|
||||
|
||||
def run_import_tests(self, procedure, _run_mode, _image,
|
||||
_n_drawables, _drawable, _config, _data):
|
||||
log.set_interactive(True)
|
||||
|
||||
runner = GimpTestRunner(log, "import", test_cfg)
|
||||
runner.run_tests()
|
||||
|
||||
return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
|
||||
|
||||
def run_export_tests(self, procedure, _run_mode, _image,
|
||||
_n_drawables, _drawable, _config, _data):
|
||||
log.set_interactive(True)
|
||||
|
||||
runner = GimpExportTestRunner(log, "export", test_cfg)
|
||||
if not runner:
|
||||
log.error("Failed to create export test runner!")
|
||||
else:
|
||||
runner.load_test_configs()
|
||||
|
||||
bmp_tests = BmpExportTests("bmp", log)
|
||||
runner.add_test(bmp_tests)
|
||||
|
||||
# Add additional tests here
|
||||
|
||||
runner.run_tests()
|
||||
|
||||
return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
|
||||
|
||||
Gimp.main(PythonTest.__gtype__, sys.argv)
|
|
@ -0,0 +1,145 @@
|
|||
[main]
|
||||
verbose=0
|
||||
|
||||
[bmp]
|
||||
enabled=True
|
||||
enabled-export=False
|
||||
plugin-import=file-bmp-load
|
||||
plugin-export=file-bmp-export
|
||||
extension=bmp
|
||||
tests=bmp-tests.ini
|
||||
tests-export=bmp-export-tests.ini
|
||||
|
||||
[dcx]
|
||||
enabled=True
|
||||
plugin-import=file-dcx-load
|
||||
extension=dcx
|
||||
tests=dcx-tests.ini
|
||||
|
||||
[dds]
|
||||
enabled=True
|
||||
plugin-import=file-dds-load
|
||||
extension=dds
|
||||
tests=dds-tests.ini
|
||||
|
||||
[eps]
|
||||
enabled=True
|
||||
plugin-import=file-eps-load
|
||||
extension=eps
|
||||
tests=eps-tests.ini
|
||||
|
||||
[fits]
|
||||
enabled=True
|
||||
plugin-import=file-fits-load
|
||||
extension=fits
|
||||
tests=fits-tests.ini
|
||||
|
||||
[fli]
|
||||
enabled=True
|
||||
plugin-import=file-fli-load
|
||||
extension=fli
|
||||
tests=fli-tests.ini
|
||||
|
||||
[gif]
|
||||
enabled=True
|
||||
plugin-import=file-gif-load
|
||||
extension=gif
|
||||
tests=gif-tests.ini
|
||||
|
||||
[icns]
|
||||
enabled=True
|
||||
plugin-import=file-icns-load
|
||||
extension=icns
|
||||
tests=icns-tests.ini
|
||||
|
||||
[ico]
|
||||
enabled=True
|
||||
plugin-import=file-ico-load
|
||||
extension=ico
|
||||
tests=ico-tests.ini
|
||||
|
||||
[j2k]
|
||||
enabled=True
|
||||
plugin-import=file-j2k-load
|
||||
extension=j2k
|
||||
tests=j2k-tests.ini
|
||||
|
||||
[jp2]
|
||||
enabled=True
|
||||
plugin-import=file-jp2-load
|
||||
extension=jp2
|
||||
tests=jp2-tests.ini
|
||||
|
||||
[jpeg]
|
||||
enabled=True
|
||||
plugin-import=file-jpeg-load
|
||||
extension=jpg
|
||||
tests=jpeg-tests.ini
|
||||
|
||||
[pcx]
|
||||
enabled=True
|
||||
plugin-import=file-pcx-load
|
||||
extension=pcx
|
||||
tests=pcx-tests.ini
|
||||
|
||||
[png]
|
||||
enabled=True
|
||||
plugin-import=file-png-load
|
||||
extension=png
|
||||
tests=png-tests.ini
|
||||
|
||||
[pnm]
|
||||
enabled=True
|
||||
plugin-import=file-pnm-load
|
||||
extension=pnm
|
||||
tests=pnm-tests.ini
|
||||
|
||||
[psb]
|
||||
enabled=True
|
||||
plugin-import=file-psd-load
|
||||
extension=psb
|
||||
tests=psb-tests.ini
|
||||
|
||||
[psd]
|
||||
enabled=True
|
||||
plugin-import=file-psd-load
|
||||
extension=psd
|
||||
tests=psd-tests.ini
|
||||
|
||||
[psd-merged-image]
|
||||
# This uses the same tests configuration and files as above, but uses a different loader
|
||||
enabled=True
|
||||
plugin-import=file-psd-load-merged
|
||||
extension=psd
|
||||
tests=psd-tests.ini
|
||||
|
||||
[psp]
|
||||
enabled=True
|
||||
plugin-import=file-psp-load
|
||||
extension=psd
|
||||
tests=psp-tests.ini
|
||||
|
||||
[sgi]
|
||||
enabled=True
|
||||
plugin-import=file-sgi-load
|
||||
# Other extensions used: bw, rgb, rgba
|
||||
extension=sgi
|
||||
tests=sgi-tests.ini
|
||||
|
||||
[tga]
|
||||
enabled=True
|
||||
plugin-import=file-tga-load
|
||||
extension=tga
|
||||
tests=tga-tests.ini
|
||||
|
||||
[tif]
|
||||
enabled=True
|
||||
plugin-import=file-tiff-load
|
||||
extension=tif
|
||||
tests=tif-tests.ini
|
||||
|
||||
[webp]
|
||||
enabled=True
|
||||
plugin-import=file-webp-load
|
||||
extension=webp
|
||||
tests=webp-tests.ini
|
|
@ -0,0 +1,5 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test exporting bmp images
|
||||
folder-input=bmp/export/input/
|
||||
folder-output=bmp/export/
|
|
@ -0,0 +1,27 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading bmpsuite good images
|
||||
folder=bmp/bmpsuite/g/
|
||||
files=bmpsuite-g-tests.files
|
||||
source=https://github.com/jsummers/bmpsuite
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading bmpsuite questionable images
|
||||
folder=bmp/bmpsuite/q/
|
||||
files=bmpsuite-q-tests.files
|
||||
source=https://github.com/jsummers/bmpsuite
|
||||
|
||||
[test-3]
|
||||
enabled=True
|
||||
description=Test loading bmpsuite bad images
|
||||
folder=bmp/bmpsuite/b/
|
||||
files=bmpsuite-b-tests.files
|
||||
source=https://github.com/jsummers/bmpsuite
|
||||
|
||||
[test-4]
|
||||
enabled=True
|
||||
description=Test loading bmpsuite x (bmp related) images
|
||||
folder=bmp/bmpsuite/x/
|
||||
files=bmpsuite-x-tests.files
|
||||
source=https://github.com/jsummers/bmpsuite
|
|
@ -0,0 +1,7 @@
|
|||
[main]
|
||||
verbose=0
|
||||
|
||||
# Add tests here that you want to be executed when starting the plug-in
|
||||
# from within GIMP. See batch-config.ini for examples.
|
||||
# You will also need to make the test images available somewhere, see
|
||||
# the readme or .gitlab-ci.yml for more details.
|
|
@ -0,0 +1,6 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading dcx images from Sembiance (telparia)
|
||||
folder=dcx/sembiance/
|
||||
files=dcx-tests-1.files
|
||||
source=https://sembiance.com/fileFormatSamples/image/dcx/
|
|
@ -0,0 +1,13 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading dds images
|
||||
folder=zaail-testimages/DDS/
|
||||
files=dds-zaail-tests.files
|
||||
source=https://github.com/ZaaLabs/ZaaIL-TestImages
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading dds images from GIMP issues
|
||||
folder=dds/gimp-issues/
|
||||
files=dds-tests-2.files
|
||||
source=several GIMP GitLab issues
|
|
@ -0,0 +1,13 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading eps images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=eps-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading fits images from graphicex
|
||||
folder=graphicex/EPS/
|
||||
files=eps-graphicex-tests.files
|
||||
source=https://github.com/mike-lischke/GraphicEx/tree/master/TestSuite%20original
|
|
@ -0,0 +1,13 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading fits images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=fits-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading fits images from GIMP issues
|
||||
folder=fits/gimp-issues/
|
||||
files=fits-tests-2.files
|
||||
source=several GIMP GitLab issues
|
|
@ -0,0 +1,6 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading fli images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=fli-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
|
@ -0,0 +1,16 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading gif imagetestsuite images
|
||||
folder=gif/imagetestsuite/
|
||||
files=gif-imagetestsuite-tests.files
|
||||
# Warning some images in this repo may trigger AntiVirus programs
|
||||
source=https://github.com/Wormnest/imagetestsuite/
|
||||
# Original:
|
||||
source2=http://code.google.com/p/imagetestsuite/
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading gif test images from pillow
|
||||
folder=pillow/
|
||||
files=gif-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
|
@ -0,0 +1,6 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading icns images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=icns-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
|
@ -0,0 +1,6 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading ico images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=ico-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
|
@ -0,0 +1,6 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading j2k images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=j2k-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
|
@ -0,0 +1,6 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading jp2 images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=jp2-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
|
@ -0,0 +1,9 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading jpeg imagetestsuite images
|
||||
folder=jpg/imagetestsuite/
|
||||
files=jpeg-imagetestsuite-tests.files
|
||||
# Warning some images in this repo may trigger AntiVirus programs
|
||||
source=https://github.com/Wormnest/imagetestsuite/
|
||||
# Original:
|
||||
source2=http://code.google.com/p/imagetestsuite/
|
|
@ -0,0 +1,34 @@
|
|||
# Add test configuration data...
|
||||
|
||||
install_data([
|
||||
# main config files
|
||||
'config.ini', # not yet updated!
|
||||
'batch-config.ini',
|
||||
# file format specific config files for import testing
|
||||
'bmp-tests.ini',
|
||||
'dcx-tests.ini',
|
||||
'dds-tests.ini',
|
||||
'eps-tests.ini',
|
||||
'fits-tests.ini',
|
||||
'fli-tests.ini',
|
||||
'gif-tests.ini',
|
||||
'icns-tests.ini',
|
||||
'ico-tests.ini',
|
||||
'j2k-tests.ini',
|
||||
'jp2-tests.ini',
|
||||
'jpeg-tests.ini',
|
||||
'pcx-tests.ini',
|
||||
'png-tests.ini',
|
||||
'pnm-tests.ini',
|
||||
'psb-tests.ini',
|
||||
'psd-tests.ini',
|
||||
'psp-tests.ini',
|
||||
'sgi-tests.ini',
|
||||
'tga-tests.ini',
|
||||
'tif-tests.ini',
|
||||
'webp-tests.ini',
|
||||
# file format specific config files for export testing
|
||||
'bmp-export-tests.ini',
|
||||
],
|
||||
install_dir: gimpplugindir / 'plug-ins' / 'test-file-plug-ins' / 'tests',
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading pcx images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=pcx-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading pcx images from ZaaIL
|
||||
folder=zaail-testimages/PCX/
|
||||
files=pcx-zaail-tests.files
|
||||
source=https://github.com/ZaaLabs/ZaaIL-TestImages/PCX/
|
|
@ -0,0 +1,32 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading png suite images
|
||||
folder=png/pngsuite/
|
||||
files=png-suite-tests.files
|
||||
source=http://www.schaik.com/pngsuite/pngsuite.html
|
||||
#Also listing the below since there are some differences
|
||||
source2=http://www.schaik.com/pngsuite2011/pngsuite.html
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading corrupt png suite images
|
||||
folder=png/pngsuite/
|
||||
files=png-suite-tests-corrupt.files
|
||||
source=http://www.schaik.com/pngsuite/pngsuite_xxx_png.html
|
||||
|
||||
[test-3]
|
||||
enabled=True
|
||||
description=Test loading png brokensuite images
|
||||
folder=png/brokensuite/
|
||||
files=png-brokensuite-tests.files
|
||||
source=https://code.google.com/archive/p/javapng/downloads
|
||||
|
||||
[test-4]
|
||||
enabled=True
|
||||
description=Test loading png imagetestsuite images
|
||||
folder=png/imagetestsuite/
|
||||
files=png-imagetestsuite-tests.files
|
||||
# Warning some images in this repo may trigger AntiVirus programs
|
||||
source=https://github.com/Wormnest/imagetestsuite/
|
||||
# Original:
|
||||
source2=http://code.google.com/p/imagetestsuite/
|
|
@ -0,0 +1,20 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading pnm (pbm, pgm, ppm, pnm) images
|
||||
folder=zaail-testimages/PNM/
|
||||
files=pnm-zaail-tests.files
|
||||
source=https://github.com/ZaaLabs/ZaaIL-TestImages
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading pfm images
|
||||
folder=pnm/oiio-pfm/
|
||||
files=pnm-oiio-tests.files
|
||||
source=https://github.com/AcademySoftwareFoundation/OpenImageIO-images/tree/master/pnm
|
||||
|
||||
[test-3]
|
||||
enabled=True
|
||||
description=Test loading pam images
|
||||
folder=pnm/sembiance-pam/
|
||||
files=pnm-sembiance-tests.files
|
||||
source=https://sembiance.com/fileFormatSamples/image/pam/
|
|
@ -0,0 +1,7 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading psb images
|
||||
folder=psd/psd-tools/
|
||||
files=psb-tests.files
|
||||
source=https://github.com/psd-tools/psd-tools
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading psd images
|
||||
folder=psd/psd-tools/
|
||||
files=psd-tests.files
|
||||
source=https://github.com/psd-tools/psd-tools
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading psd colormode images
|
||||
folder=psd/psd-tools/colormodes/
|
||||
files=psd-colormodes-tests.files
|
||||
source=https://github.com/psd-tools/psd-tools/tree/master/tests/psd_files/colormodes
|
||||
|
||||
[test-3]
|
||||
enabled=True
|
||||
description=Test loading psdparse sample images
|
||||
folder=psd/psdparse/
|
||||
files=psdparse-tests.files
|
||||
source=http://www.telegraphics.com.au/svn/psdparse/trunk/psd/
|
|
@ -0,0 +1,13 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading psp images from GraphicEx TestSuite
|
||||
folder=graphicex/PSP/
|
||||
files=psp-graphicex-tests.files
|
||||
source=https://github.com/mike-lischke/GraphicEx/tree/master/TestSuite%20original
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading psp images from GIMP issues
|
||||
folder=psp/gimp-issues/
|
||||
files=psp-tests-2.files
|
||||
source=several GIMP GitLab issues
|
|
@ -0,0 +1,20 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading sgi images from GraphicEx TestSuite
|
||||
folder=graphicex/SGI/
|
||||
files=sgi-graphicex-tests.files
|
||||
source=https://github.com/mike-lischke/GraphicEx/tree/master/TestSuite%20original
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading sgi images from ZaaIL
|
||||
folder=zaail-testimages/SGI/
|
||||
files=sgi-zaail-tests.files
|
||||
source=https://github.com/ZaaLabs/ZaaIL-TestImages/SGI/
|
||||
|
||||
[test-3]
|
||||
enabled=True
|
||||
description=Test loading sgi images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=sgi-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
|
@ -0,0 +1,13 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading tga images
|
||||
folder=zaail-testimages/TGA/
|
||||
files=tga-zaail-tests.files
|
||||
source=https://github.com/ZaaLabs/ZaaIL-TestImages
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading tga test images from pillow
|
||||
folder=pillow/
|
||||
files=tga-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
|
@ -0,0 +1,31 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading tif test images from cpan: Imager-File-TIFF
|
||||
folder=tiff/cpan-imager-file-tiff/
|
||||
files=tif-cpan-tests.files
|
||||
source=https://metacpan.org/source/TONYC/Imager-File-TIFF-0.92/testimg
|
||||
|
||||
[test-2]
|
||||
enabled=True
|
||||
description=Test loading tif imagetestsuite images, part 1
|
||||
folder=tiff/imagetestsuite/
|
||||
files=tif-imagetestsuite-tests.files
|
||||
# Warning some images in this repo may trigger AntiVirus programs
|
||||
source=https://github.com/Wormnest/imagetestsuite/tif/
|
||||
# Original:
|
||||
source2=http://code.google.com/p/imagetestsuite/
|
||||
|
||||
[test-3]
|
||||
enabled=True
|
||||
description=Test loading tif imagetestsuite images, part 2
|
||||
folder=tiff/imagetestsuite/
|
||||
files=tif-imagetestsuite-tests-2.files
|
||||
source=https://github.com/Wormnest/imagetestsuite/tif/
|
||||
|
||||
[test-4]
|
||||
enabled=True
|
||||
description=Test loading tif imagetestsuite images, part 3
|
||||
folder=tiff/imagetestsuite/
|
||||
files=tif-imagetestsuite-tests-3.files
|
||||
# Some are processed real slow, needs to be investigated
|
||||
source=https://github.com/Wormnest/imagetestsuite/tif/
|
|
@ -0,0 +1,7 @@
|
|||
[test-1]
|
||||
enabled=True
|
||||
description=Test loading webp images from Pillow TestSuite
|
||||
folder=pillow/
|
||||
files=webp-pillow-tests.files
|
||||
source=https://github.com/python-pillow/Pillow/tree/master/Tests/images
|
||||
|
|
@ -49,6 +49,7 @@ plug-ins/maze
|
|||
plug-ins/metadata
|
||||
plug-ins/pagecurl
|
||||
plug-ins/print
|
||||
plug-ins/python/tests
|
||||
plug-ins/screenshot
|
||||
plug-ins/script-fu
|
||||
plug-ins/selection-to-path
|
||||
|
|
Loading…
Reference in New Issue