strengthen core unit tests

Add table-driven dictionary miss and language-switch state coverage, regress stale candidates after backspace, and clear them before dictionary refresh. Keep IPC and runtime-created file checks outside the unit runner.
This commit is contained in:
2026-08-11 21:12:23 +09:00
parent 9b3f2c46f0
commit 82276bf37f
10 changed files with 149 additions and 464 deletions

View File

@@ -54,6 +54,32 @@ engine_clears_candidates(struct ct *t)
CT_EQ_INT(t, -1, im.sel);
}
void
engine_backspace_clears_candidates(struct ct *t)
{
Lang *lang;
Str com, shown;
lang = getlang(LangJP);
init();
im.l = lang;
sclear(&com);
CT_CHECK(t, keystroke('n', 0, &com));
CT_CHECK(t, keystroke('a', 0, &com));
shown = shownpre(&im);
checkstr(t, "before backspace", "", &shown);
im.kouho[0] = mkstr("stale-candidate");
im.nkouho = 1;
im.sel = 0;
CT_CHECK(t, keystroke(Kback, 0, &com));
checkstr(t, "backspace commit", "", &com);
checkstr(t, "raw preedit after backspace", "n", &im.pre);
shown = shownpre(&im);
checkstr(t, "shown preedit after backspace", "", &shown);
CT_EQ_INT(t, 0, im.nkouho);
CT_EQ_INT(t, -1, im.sel);
}
void
engine_selects_visible_candidate(struct ct *t)
{
@@ -156,3 +182,76 @@ engine_telex_history_bound(struct ct *t)
CT_EQ_INT(t, 0, im.pre.n);
CT_EQ_INT(t, 0, im.raw.n);
}
void
engine_language_switch_state(struct ct *t)
{
static const struct {
char *name;
Rune key;
int mod;
int lang;
char *pre;
char *raw;
char *commit;
int stale;
} steps[] = {
{ "select Vietnamese", 'v', Mctrl, LangVI, "", "", "", 0 },
{ "Vietnamese a", 'a', 0, LangVI, "a", "a", "", 0 },
{ "Vietnamese tone", 's', 0, LangVI, "as", "as", "", 0 },
{ "switch to Korean", 's', Mctrl, LangKO, "", "", "", 1 },
{ "Korean initial", 'r', 0, LangKO, "", "", "", 0 },
{ "Korean syllable", 'k', 0, LangKO, "", "", "", 0 },
{ "switch to Vietnamese", 'v', Mctrl, LangVI, "", "", "", 0 },
{ "Vietnamese a again", 'a', 0, LangVI, "a", "a", "", 0 },
{ "Vietnamese tone again", 's', 0, LangVI, "as", "as", "", 0 },
{ "commit Vietnamese", Kret, 0, LangVI, "", "", "á", 0 },
};
char where[80];
Lang *vi;
Trie *saved;
Str com;
int eaten, i;
vi = getlang(LangVI);
if(!CT_CHECK(t, vi != nil))
return;
saved = vi->map;
vi->map = testvi.map;
init();
for(i = 0; i < nelem(steps); i++){
if(steps[i].stale){
im.kouho[0] = mkstr("stale");
im.nkouho = 1;
im.sel = 0;
}
sclear(&com);
eaten = keystroke(steps[i].key, steps[i].mod, &com);
if(eaten != 1){
CT_ERRORF(t, "%s: want eaten 1, got %d",
steps[i].name, eaten);
break;
}
if(im.l == nil || im.l->lang != steps[i].lang){
CT_ERRORF(t, "%s: want language %d, got %d",
steps[i].name, steps[i].lang,
im.l == nil ? -1 : im.l->lang);
break;
}
snprint(where, sizeof where, "%s preedit", steps[i].name);
if(!checkstr(t, where, steps[i].pre, &im.pre))
break;
snprint(where, sizeof where, "%s raw", steps[i].name);
if(!checkstr(t, where, steps[i].raw, &im.raw))
break;
snprint(where, sizeof where, "%s commit", steps[i].name);
if(!checkstr(t, where, steps[i].commit, &com))
break;
if(im.nkouho != 0 || im.sel != -1){
CT_ERRORF(t, "%s: want candidates 0 and selection -1, got %d and %d",
steps[i].name, im.nkouho, im.sel);
break;
}
}
vi->map = saved;
}