keysyms: Add tests with ICU

Added tests of the simple case mappings when the ICU library is
available. A warning is raised for missing mappings.

Note: `xkb_keysym_is_upper` is interpreted as matching the disjunction of the
Unicode character properties “Uppercase” or “Titlecase”.
master
Pierre Le Marre 2023-12-07 12:21:53 +01:00 committed by Wismill
parent 82305adb51
commit c88fe4b692
3 changed files with 99 additions and 3 deletions

View File

@ -30,7 +30,7 @@ jobs:
sudo apt update sudo apt update
sudo apt install -y \ sudo apt install -y \
doxygen libxcb-xkb-dev valgrind ninja-build \ doxygen libxcb-xkb-dev valgrind ninja-build \
libwayland-dev wayland-protocols bison graphviz libwayland-dev wayland-protocols bison graphviz libicu-dev
- name: Install xkeyboard-config - name: Install xkeyboard-config
run: | run: |
# Install master version of xkeyboard-config, in order to ensure # Install master version of xkeyboard-config, in order to ensure

View File

@ -651,10 +651,18 @@ if get_option('enable-x11')
], ],
) )
endif endif
# TODO: version range?
keysyms_test_dep = [test_dep]
keysyms_test_c_args = ['-DENABLE_PRIVATE_APIS']
icu_dep = dependency('icu-uc', required: false)
if icu_dep.found()
keysyms_test_dep += [icu_dep]
configh_data.set10('HAVE_ICU', true)
endif
test( test(
'keysym', 'keysym',
executable('test-keysym', 'test/keysym.c', dependencies: test_dep, executable('test-keysym', 'test/keysym.c', dependencies: keysyms_test_dep,
c_args: ['-DENABLE_PRIVATE_APIS']), c_args: keysyms_test_c_args),
env: test_env, env: test_env,
) )
test( test(

View File

@ -24,6 +24,9 @@
#include <locale.h> #include <locale.h>
#include <stdbool.h> #include <stdbool.h>
#if HAVE_ICU
#include <unicode/uchar.h>
#endif
#include "test.h" #include "test.h"
#include "keysym.h" /* For unexported is_lower/upper/keypad() */ #include "keysym.h" /* For unexported is_lower/upper/keypad() */
@ -169,6 +172,87 @@ test_utf8(xkb_keysym_t keysym, const char *expected)
return streq(s, expected); return streq(s, expected);
} }
#if HAVE_ICU
static inline uint32_t
to_simple_lower(uint32_t cp)
{
return (uint32_t)u_tolower((UChar32) cp);
}
static inline uint32_t
to_simple_upper(uint32_t cp)
{
return (uint32_t)u_toupper((UChar32) cp);
}
#define KEYSYM "0x%04"PRIx32
#define CODE_POINT "U+%04"PRIX32
static void
test_icu_case_mappings(xkb_keysym_t ks)
{
/* Check lower case mapping */
xkb_keysym_t ks_mapped = xkb_keysym_to_lower(ks);
uint32_t cp = xkb_keysym_to_utf32(ks);
uint32_t expected = to_simple_lower(cp);
if (ks_mapped && ks_mapped != ks) {
uint32_t got = xkb_keysym_to_utf32(ks_mapped);
assert_printf(got == expected,
"Invalid xkb_keysym_to_lower("KEYSYM") == "KEYSYM": "
"expected "CODE_POINT", got: "CODE_POINT"\n",
ks, ks_mapped, expected, got);
got = !!xkb_keysym_is_upper(ks);
expected = !!(u_isUUppercase(cp) || u_istitle(cp));
assert_printf(got == expected || u_istitle(cp),
"Invalid xkb_keysym_is_upper("KEYSYM") ("CODE_POINT"): "
"expected %d, got: %d\n",
ks, cp, expected, got);
if (u_istitle(cp)) {
fprintf(stderr,
"%s title case handling "KEYSYM" ("CODE_POINT")\n",
(got == expected) ? "[INFO] valid" : "[WARNING] invalid",
ks, cp);
}
} else if (expected != cp) {
fprintf(stderr,
"[WARNING] missing lower case mapping for "KEYSYM": "
"expected "CODE_POINT", got: "CODE_POINT"\n",
ks, expected, cp);
assert_printf(!xkb_keysym_is_upper(ks),
"Invalid xkb_keysym_is_upper("KEYSYM") ("CODE_POINT"): "
"expected false, got: true\n",
ks, cp);
}
/* Check upper case mapping */
ks_mapped = xkb_keysym_to_upper(ks);
expected = to_simple_upper(cp);
if (ks_mapped && ks_mapped != ks) {
uint32_t got = xkb_keysym_to_utf32(ks_mapped);
assert_printf(got == expected,
"Invalid xkb_keysym_to_upper("KEYSYM") == "KEYSYM": "
"expected "CODE_POINT", got: "CODE_POINT"\n",
ks, ks_mapped, expected, got);
got = !!xkb_keysym_is_lower(ks);
expected = !!u_isULowercase(cp);
assert_printf(got == expected,
"Invalid xkb_keysym_is_lower("KEYSYM") ("CODE_POINT"): "
"expected %d, got: %d\n",
ks, cp, expected, got);
} else if (expected != cp) {
fprintf(stderr,
"[WARNING] missing upper case mapping for "KEYSYM": "
"expected "CODE_POINT", got: "CODE_POINT"\n",
ks, expected, cp);
assert_printf(!xkb_keysym_is_lower(ks),
"Invalid xkb_keysym_is_lower("KEYSYM") ("CODE_POINT"): "
"expected false, got: true\n",
ks, cp);
}
}
#endif
static void static void
test_github_issue_42(void) test_github_issue_42(void)
{ {
@ -285,6 +369,10 @@ main(void)
"xkb_keysym_is_keypad(0x%04"PRIx32") \"%s\": " "xkb_keysym_is_keypad(0x%04"PRIx32") \"%s\": "
"expected %d, got: %d\n", "expected %d, got: %d\n",
ks, name, expected, got); ks, name, expected, got);
#if HAVE_ICU
/* Check case mappings */
test_icu_case_mappings(ks);
#endif
} }
iter = xkb_keysym_iterator_unref(iter); iter = xkb_keysym_iterator_unref(iter);
assert(ks_prev == XKB_KEYSYM_MAX_ASSIGNED); assert(ks_prev == XKB_KEYSYM_MAX_ASSIGNED);