diff --git a/libgimp/tests/meson.build b/libgimp/tests/meson.build index 80daba137f..9628260fe0 100644 --- a/libgimp/tests/meson.build +++ b/libgimp/tests/meson.build @@ -7,6 +7,7 @@ if not meson.can_run_host_binaries() endif tests = [ + 'color-parser', 'palette', 'selection-float' ] diff --git a/libgimp/tests/test-color-parser.c b/libgimp/tests/test-color-parser.c new file mode 100644 index 0000000000..eb1ea7b0d2 --- /dev/null +++ b/libgimp/tests/test-color-parser.c @@ -0,0 +1,121 @@ +#define DBL(c) ((gdouble)(c) / 255.0) +#define EPSILON 1e-6 + +typedef struct +{ + const gchar *str; + gboolean fail; + const gdouble r; + const gdouble g; + const gdouble b; + const gdouble a; +} ColorSample; + +static const ColorSample samples[] = +{ + /* sample fail red green blue alpha */ + + { "#000000", FALSE, 0.0, 0.0, 0.0, 1.0 }, + { "#FFff00", FALSE, 1.0, 1.0, 0.0, 1.0 }, + { "#6495ed", FALSE, DBL(100), DBL(149), DBL(237), 1.0 }, + { "#fff", FALSE, 1.0, 1.0, 1.0, 1.0 }, + /* Very unsure about this one. Our code has some support for values on 3 or 4 + * hexa per channel, but this doesn't exist in CSS specs. + * On the other hand, we should add support for alpha. + * And in any case, the result of the below should not be (1, 0, 0). + * See: https://drafts.csswg.org/css-color/#hex-notation + */ + /*{ "#64649595eded", FALSE, 1.0, 1.0, 0.0, 1.0 },*/ + { "rgb(0,0,0)", FALSE, 0.0, 0.0, 0.0, 1.0 }, + { "rgb(100,149,237)", FALSE, DBL(100), DBL(149), DBL(237), 1.0 }, + { "rgba(100%,0,100%,0.5)", FALSE, 1.0, 0.0, 1.0, 0.5 }, + { "rgb(100%,149,20%)", FALSE, 1.0, DBL(149), 0.2, 1.0 }, + { "rgb(foobar)", TRUE, 0.0, 0.0, 0.0, 1.0 }, + { "rgb(100,149,237", TRUE, 0.0, 0.0, 0.0, 1.0 }, + { "rED", FALSE, 1.0, 0.0, 0.0, 1.0 }, + { "cornflowerblue", FALSE, DBL(100), DBL(149), DBL(237), 1.0 }, + { " red", FALSE, 1.0, 0.0, 0.0, 1.0 }, + { "red ", FALSE, 1.0, 0.0, 0.0, 1.0 }, + { "red", FALSE, 1.0, 0.0, 0.0, 1.0 }, + { "red blue", TRUE, 0.0, 0.0, 0.0, 0.0 }, + { "transparent", FALSE, 0.0, 0.0, 0.0, 0.0 }, + { "23foobar", TRUE, 0.0, 0.0, 0.0, 0.0 }, + { "", TRUE, 0.0, 0.0, 0.0, 0.0 } +}; + +static gint +check_failure (const ColorSample *sample, + GeglColor *color) +{ + gdouble red; + gdouble green; + gdouble blue; + gdouble alpha; + + if (color && sample->fail) + { + gegl_color_get_rgba_with_space (color, &red, &green, &blue, &alpha, + babl_format ("R'G'B'A double")); + g_printerr ("\n\tParser succeeded for sample \"%s\" but should have failed!\n" + "\t parsed color: (%g, %g, %g, %g)\n", + sample->str, red, green, blue, alpha); + return 1; + } + else if (! color && ! sample->fail) + { + g_printerr ("\n\tParser failed for sample \"%s\" but should have succeeded!\n" + "\t expected color: (%g, %g, %g, %g)\n", + sample->str, sample->r, sample->g, sample->b, sample->a); + return 1; + } + else if (! color && sample->fail) + { + return 0; + } + + gegl_color_get_rgba_with_space (color, &red, &green, &blue, &alpha, + babl_format ("R'G'B'A double")); + if (fabs (red - sample->r) > EPSILON || fabs (green - sample->g) > EPSILON || + fabs (blue - sample->b) > EPSILON || fabs (alpha - sample->a) > EPSILON) + { + g_printerr ("\nParser succeeded for sample \"%s\" but found the wrong values!\n" + " parsed color: (%g, %g, %g, %g)\n" + " expected color: (%g, %g, %g, %g)\n", + sample->str, red, green, blue, alpha, + sample->r, sample->g, sample->b, sample->a); + return 1; + } + + return 0; +} + +static GimpValueArray * +gimp_c_test_run (GimpProcedure *procedure, + GimpRunMode run_mode, + GimpImage *image, + gint n_drawables, + GimpDrawable **drawables, + GimpProcedureConfig *config, + gpointer run_data) +{ + gint i; + + g_print ("\nTesting the GIMP color parser ...\n"); + + for (i = 0; i < G_N_ELEMENTS (samples); i++) + { + GeglColor *color = NULL; + gchar *test; + + test = g_strdup_printf ("Parsing [%d] \"%s\" (should %s)", + i, samples[i].str, + samples[i].fail ? "fail" : "succeed"); + GIMP_TEST_START(test) + color = gimp_color_parse_css (samples[i].str); + + GIMP_TEST_END(check_failure (samples + i, color) == 0) + g_free (test); + } + + GIMP_TEST_RETURN +} diff --git a/libgimp/tests/test-color-parser.py b/libgimp/tests/test-color-parser.py new file mode 100644 index 0000000000..8111fea2d7 --- /dev/null +++ b/libgimp/tests/test-color-parser.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 + +EPSILON=1e-6 + +def DBL(c): + return c / 255.0 + +samples = [ + { 'str': "#000000", + 'fail': False, + 'red': 0.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "#FFff00", + 'fail': False, + 'red': 1.0, + 'green': 1.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "#6495ed", + 'fail': False, + 'red': DBL(100), + 'green': DBL(149), + 'blue': DBL(237), + 'alpha': 1.0 }, + { 'str': "#fff", + 'fail': False, + 'red': 1.0, + 'green': 1.0, + 'blue': 1.0, + 'alpha': 1.0 }, + #{ 'str': "#64649595eded", + #'fail': False, + #'red': 1.0, + #'green': 1.0, + #'blue': 0.0, + #'alpha': 1.0 }, + { 'str': "rgb(0,0,0)", + 'fail': False, + 'red': 0.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "rgb(100,149,237)", + 'fail': False, + 'red': DBL(100), + 'green': DBL(149), + 'blue': DBL(237), + 'alpha': 1.0 }, + { 'str': "rgba(100%,0,100%,0.5)", + 'fail': False, + 'red': 1.0, + 'green': 0.0, + 'blue': 1.0, + 'alpha': 0.5 }, + { 'str': "rgb(100%,149,20%)", + 'fail': False, + 'red': 1.0, + 'green': DBL(149), + 'blue': 0.2, + 'alpha': 1.0 }, + { 'str': "rgb(foobar)", + 'fail': True, + 'red': 0.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "rgb(100,149,237", + 'fail': True, + 'red': 0.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "rED", + 'fail': False, + 'red': 1.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "cornflowerblue", + 'fail': False, + 'red': DBL(100), + 'green': DBL(149), + 'blue': DBL(237), + 'alpha': 1.0 }, + { 'str': " red", + 'fail': False, + 'red': 1.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "red ", + 'fail': False, + 'red': 1.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "red", + 'fail': False, + 'red': 1.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 1.0 }, + { 'str': "red blue", + 'fail': True, + 'red': 0.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 0.0 }, + { 'str': "transparent", + 'fail': False, + 'red': 0.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 0.0 }, + { 'str': "23foobar", + 'fail': True, + 'red': 0.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 0.0 }, + { 'str': "", + 'fail': True, + 'red': 0.0, + 'green': 0.0, + 'blue': 0.0, + 'alpha': 0.0 } +] + +for sample in samples: + color = Gimp.color_parse_css(sample['str']) + print(color) + if sample['fail']: + gimp_assert('Parsing "{}" should fail.'.format(sample['str']), color is None) + else: + gimp_assert('Parsing "{}" should generate a color.'.format(sample['str']), color is not None) + + r, g, b, a = color.get_rgba_with_space(Babl.format("R'G'B'A double")) + gimp_assert('"{}" generated ({}, {}, {}, {}) - expected ({}, {}, {}, {}).'.format(sample['str'], + r, g, b, a, + sample['red'], + sample['green'], + sample['blue'], + sample['alpha']), + abs(r - sample['red']) < EPSILON and abs(g - sample['green']) < EPSILON and + abs(b - sample['blue']) < EPSILON and abs(a - sample['alpha']) < EPSILON) diff --git a/libgimpcolor/meson.build b/libgimpcolor/meson.build index 40e70e1868..9fc976c710 100644 --- a/libgimpcolor/meson.build +++ b/libgimpcolor/meson.build @@ -1,4 +1,3 @@ - libgimpcolor_sources = files( 'gimpadaptivesupersample.c', 'gimpbilinear.c', @@ -44,7 +43,6 @@ libgimpcolor_introspectable = [ libgimpcolor_headers_introspectable, ] - libgimpcolor = library('gimpcolor-' + gimp_api_version, libgimpcolor_sources, include_directories: rootInclude, @@ -62,18 +60,3 @@ install_headers( libgimpcolor_headers, subdir: gimp_api_name / 'libgimpcolor', ) - - -# Test program, not installed -executable('test-color-parser', - 'test-color-parser.c', - include_directories: rootInclude, - dependencies: [ - cairo, gdk_pixbuf, gegl, lcms, math, - babl, - # glib, - ], - c_args: '-DG_LOG_DOMAIN="LibGimpColor"', - link_with: [ libgimpbase, libgimpcolor, ], - install: false, -) diff --git a/libgimpcolor/test-color-parser.c b/libgimpcolor/test-color-parser.c deleted file mode 100644 index 4ce7c50927..0000000000 --- a/libgimpcolor/test-color-parser.c +++ /dev/null @@ -1,119 +0,0 @@ -/* unit tests for the color parsing routines in gimprgb-parse.c - */ - -#include "config.h" - -#include - -#include -#include -#include - -#include -#include - -#include "gimpcolor.h" - - -#define DBL(c) ((gdouble)(c) / 255.0) - - -typedef struct -{ - const gchar *str; - gboolean alpha; - gboolean fail; - const gdouble r; - const gdouble g; - const gdouble b; - const gdouble a; -} ColorSample; - -static const ColorSample samples[] = -{ - /* sample alpha fail red green blue alpha */ - - { "#000000", FALSE, FALSE, 0.0, 0.0, 0.0, 0.0 }, - { "#FFff00", FALSE, FALSE, 1.0, 1.0, 0.0, 0.0 }, - { "#6495ed", FALSE, FALSE, DBL(100), DBL(149), DBL(237), 0.0 }, - { "#fff", FALSE, FALSE, 1.0, 1.0, 1.0, 0.0 }, - { "#64649595eded", FALSE, FALSE, 1.0, 1.0, 0.0, 0.0 }, - { "rgb(0,0,0)", FALSE, FALSE, 0.0, 0.0, 0.0, 0.0 }, - { "rgb(100,149,237)", FALSE, FALSE, DBL(100), DBL(149), DBL(237), 0.0 }, - { "rgba(100%,0,100%,0.5)", TRUE, FALSE, 255.0, 0.0, 255.0, 0.5 }, - { "rgba(100%,0,100%,0.5)", FALSE, TRUE, 255.0, 0.0, 255.0, 0.5 }, - { "rgb(100%,149,20%)", FALSE, FALSE, 1.0, DBL(149), 0.2, 0.0 }, - { "rgb(100%,149,20%)", TRUE, TRUE, 1.0, DBL(149), 0.2, 0.0 }, - { "rgb(foobar)", FALSE, TRUE, 0.0, 0.0, 0.0, 0.0 }, - { "rgb(100,149,237", FALSE, TRUE, 0.0, 0.0, 0.0, 0.0 }, - { "rED", FALSE, FALSE, 1.0, 0.0, 0.0, 0.0 }, - { "cornflowerblue", FALSE, FALSE, DBL(100), DBL(149), DBL(237), 0.0 }, - { " red", FALSE, FALSE, 1.0, 0.0, 0.0, 0.0 }, - { "red ", FALSE, FALSE, 1.0, 0.0, 0.0, 0.0 }, - { "red", TRUE, TRUE, 1.0, 0.0, 0.0, 0.0 }, - { "red blue", FALSE, TRUE, 0.0, 0.0, 0.0, 0.0 }, - { "transparent", FALSE, TRUE, 0.0, 0.0, 0.0, 0.0 }, - { "transparent", TRUE, FALSE, 0.0, 0.0, 0.0, 0.0 }, - { "23foobar", FALSE, TRUE, 0.0, 0.0, 0.0, 0.0 }, - { "", FALSE, TRUE, 0.0, 0.0, 0.0, 0.0 } -}; - - -static gint -check_failure (const ColorSample *sample, - gboolean success, - GimpRGB *rgb) -{ - if (success && sample->fail) - { - g_print ("Parser succeeded for sample \"%s\" but should have failed!\n" - " parsed color: (%g, %g, %g, %g)\n", - sample->str, rgb->r, rgb->g, rgb->b, rgb->a); - return 1; - } - - if (!success && !sample->fail) - { - g_print ("Parser failed for sample \"%s\" but should have succeeded!\n" - " parsed color: (%g, %g, %g, %g)\n", - sample->str, rgb->r, rgb->g, rgb->b, rgb->a); - return 1; - } - - return 0; -} - -int -main (void) -{ - gint failures = 0; - gint i; - - g_print ("\nTesting the GIMP color parser ...\n"); - - for (i = 0; i < G_N_ELEMENTS (samples); i++) - { - GimpRGB rgb = { 0.0, 0.0, 0.0, 0.0 }; - gboolean success; - - if (samples[i].alpha) - success = gimp_rgba_parse_css (&rgb, samples[i].str, -1); - else - success = gimp_rgb_parse_css (&rgb, samples[i].str, -1); - - failures += check_failure (samples + i, success, &rgb); - } - - if (failures) - { - g_print ("%d out of %d samples failed!\n\n", - failures, (int)G_N_ELEMENTS (samples)); - return EXIT_FAILURE; - } - else - { - g_print ("All %d samples passed.\n\n", (int)G_N_ELEMENTS (samples)); - return EXIT_SUCCESS; - } -} -