Files
strans/tests/unit_test.c
Hojun-Cho ef7fb627c6 compose: one Compose table for the XIM and IBus frontends
An IBus client throws away a dead key its engine did not take — the GTK
module's own comment says so, and Qt does the same — so é and ü were
lost in every IBus application, while XIM composed them with a table of
its own.  That table moves to compose.c, which both frontends now use;
xim.c is the shorter for it.

A finished sequence is text, not a key: the engine is asked to hand back
what it had pending, and the composed text follows it, so the composed
character can no longer land before the syllable typed before it.
2026-08-17 12:16:07 +09:00

179 lines
6.6 KiB
C

#define CT_IMPLEMENTATION
#include "dat.h"
#include "fn.h"
#include "test.h"
#include <stdarg.h>
Channel *drawc;
Channel *keyc;
Lang testvi;
void
die(char *fmt, ...)
{
va_list ap;
fprint(2, "unit_test: ");
va_start(ap, fmt);
vfprint(2, fmt, ap);
va_end(ap);
fprint(2, "\n");
threadexitsall("die");
}
void*
emalloc(ulong n)
{
void *p;
p = mallocz(n, 1);
if(p == nil)
die("out of memory");
return p;
}
void*
erealloc(void *p, ulong n)
{
p = realloc(p, n);
if(p == nil)
die("out of memory");
return p;
}
static void
testmapinit(void)
{
Lang *jp, *kata;
jp = getlang(LangJP);
kata = getlang(LangJPK);
if(jp == nil || kata == nil)
die("test language is not registered");
jp->map = trieopen("../map/hira.map");
kata->map = trieopen("../map/kata.map");
memset(&testvi, 0, sizeof testvi);
testvi.lang = LangVI;
testvi.mapname = "telex";
testvi.trans = transvi;
testvi.back = backvi;
testvi.map = trieopen("../map/telex.map");
}
#ifndef STRESS
static const struct ct_test tests[] = {
{ "str/init-utf8", str_init_utf8 },
{ "str/edit-and-alias", str_edit_and_alias },
{ "str/utf8-capacity", str_utf8_capacity },
{ "str/invalid-full-appends", str_invalid_and_full_appends },
{ "trie/exact-prefix-duplicate", trie_exact_prefix_and_duplicate },
{ "trie/put-and-unloaded", trie_put_and_unloaded },
{ "popup/layout", popup_layout },
{ "font/render", font_render },
{ "map/production-lifecycle", production_maps_load },
{ "transmap/states", transmap_states },
{ "hangul/sequences", korean_sequences },
{ "hangul/compound-vowels", korean_compound_vowels },
{ "hangul/compound-finals", korean_compound_finals },
{ "hangul/backspace", korean_backspace },
{ "telex/transitions", vietnamese_transitions },
{ "telex/backspace", vietnamese_backspace },
{ "telex/state-lifetime", vietnamese_state_lifetime },
{ "engine/clears-candidates", engine_clears_candidates },
{ "engine/backspace-clears-candidates", engine_backspace_clears_candidates },
{ "engine/selects-visible-candidate", engine_selects_visible_candidate },
{ "engine/candidate-shortcut-modifiers", engine_candidate_shortcut_modifiers },
{ "engine/candidate-page-metadata", engine_candidate_page_metadata },
{ "engine/candidate-page-snapshots", engine_candidate_page_snapshots },
{ "engine/candidate-page-movement", engine_candidate_page_movement },
{ "engine/candidate-completion", engine_candidate_completion },
{ "engine/active-owner-lifecycle", engine_active_owner_lifecycle },
{ "engine/active-owner-reset", engine_active_owner_reset },
{ "engine/active-owner-caret", engine_active_owner_caret },
{ "engine/popup-preedit-capability", engine_popup_preedit_capability },
{ "engine/vietnamese-client-preedit", engine_vietnamese_client_preedit },
{ "engine/commit-contract", engine_commit_contract },
{ "engine/language-switch-state", engine_language_switch_state },
{ "engine/telex-history-bound", engine_telex_history_bound },
{ "engine/korean-modifiers-backspace", engine_korean_modifiers_and_backspace },
{ "engine/direct-language-modes", engine_direct_language_modes },
{ "engine/japanese-readings", engine_japanese_readings },
{ "engine/japanese-candidates", engine_japanese_candidates },
{ "engine/japanese-backspace-boundaries", engine_japanese_backspace_and_boundaries },
{ "engine/katakana-sequences", engine_katakana_sequences },
{ "engine/emoji-single-candidate", engine_emoji_single_candidate },
{ "engine/emoji-queries", engine_emoji_queries },
{ "engine/emoji-japanese-multirune", engine_emoji_japanese_and_multirune },
{ "engine/emoji-digit-aliases", engine_emoji_digit_aliases },
{ "engine/emoji-navigation", engine_emoji_navigation },
{ "engine/search-candidate-keys", engine_search_candidate_keys },
{ "engine/emoji-preedit-languages", engine_emoji_preedit_languages },
{ "engine/emoji-start-and-unknown", engine_emoji_start_and_unknown },
{ "engine/hanja-search", engine_hanja_search },
{ "engine/hanja-unknown-cancel", engine_hanja_unknown_and_cancel },
{ "engine/hanja-korean-keys", engine_hanja_korean_keys },
{ "engine/hanja-backspace", engine_hanja_backspace },
{ "engine/hanja-input-languages", engine_hanja_input_languages },
{ "engine/full-boundary-passthrough", engine_full_boundary_passthrough },
{ "dict/candidates", dictionary_candidates },
{ "dict/misses", dictionary_misses },
{ "dict/prefix", dictionary_prefix },
{ "ipc/masks-modifiers", ipc_masks_modifiers },
{ "ipc/control-caret-frames", ipc_control_and_caret_frames },
{ "ipc/runtime-path", ipc_runtime_path },
{ "ipc/response-pack-boundaries", ipc_response_pack_boundaries },
{ "ipc/response-empty-preedit", ipc_response_empty_and_preedit },
{ "ipc/response-max-drain", ipc_response_max_and_drain },
{ "ipc/response-fragmented-truncated", ipc_response_fragmented_and_truncated },
{ "ipc/broken-peer-send", ipc_broken_peer_send },
{ "server/connection-ownership", server_connection_ownership },
{ "server/extension-stream", server_extension_stream },
{ "server/rejects-unknown-extension", server_rejects_unknown_extension },
{ "ibus/machine-id-fallback", ibus_machine_id_fallback },
{ "ibus/capability-policy", ibus_capability_policy },
{ "ibus/private-input-policy", ibus_private_input_policy },
{ "ibus/context-lifecycle", ibus_context_lifecycle },
{ "ibus/active-release-lifecycle", ibus_active_release_lifecycle },
{ "compose/sequences", compose_sequences },
{ "xim/keymap-lookup", xim_keymap_lookup },
{ "xim/compound-text", xim_compound_text },
{ "xim/adapter-key-contract", xim_adapter_key_contract },
{ "xim/adapter-release-lifecycle", xim_adapter_release_lifecycle },
{ "xim/adapter-free-waits-release", xim_adapter_free_waits_for_release },
{ "xim/styles", xim_adapter_styles },
{ "xim/placement", xim_adapter_placement },
{ "xim/placement-updates", xim_adapter_placement_updates },
{ "xim/callback-replacement", xim_adapter_callback_replacement },
{ "xim/callback-unicode", xim_adapter_callback_unicode },
{ "xim/callback-cleanup", xim_adapter_callback_cleanup },
{ "xim/callback-transfer", xim_adapter_callback_transfer },
{ "xim/callback-owner-loss", xim_adapter_callback_owner_loss },
{ "xim/commit-encoding", xim_adapter_commit_encoding },
};
#else
static const struct ct_test tests[] = {
{ "engine/randomized-stress", engine_randomized_stress },
};
#endif
void
threadmain(int argc, char **argv)
{
int i, status;
drawc = chancreate(sizeof(Drawcmd), 4);
keyc = chancreate(sizeof(Keyreq), 0);
testmapinit();
status = CT_RUN_ARGS(tests, argc, argv);
for(i = 0; i < nlang; i++){
trieclose(langs[i].map);
langs[i].map = nil;
}
trieclose(testvi.map);
testvi.map = nil;
chanfree(drawc);
chanfree(keyc);
threadexitsall(status == 0 ? nil : "tests failed");
}