83 lines
2.6 KiB
Go
83 lines
2.6 KiB
Go
package app
|
|
|
|
import "testing"
|
|
|
|
func TestMatchCtrlK(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
chunk string
|
|
offset int
|
|
wantMatch bool
|
|
wantAdvance int
|
|
}{
|
|
{"legacy lone byte", "\x0b", 0, true, 1},
|
|
{"legacy followed by text", "\x0bx", 0, true, 1},
|
|
{"kitty plain Ctrl-K", "\x1b[107;5u", 0, true, 8},
|
|
{"kitty with press event", "\x1b[107;5:1u", 0, true, 10},
|
|
{"kitty with key release", "\x1b[107;5:3u", 0, false, 0},
|
|
{"kitty with extra shift", "\x1b[107;6u", 0, false, 0},
|
|
{"kitty no modifier", "\x1b[107u", 0, false, 0},
|
|
{"kitty wrong key", "\x1b[108;5u", 0, false, 0},
|
|
{"kitty with associated text trailing group", "\x1b[107;5;107u", 0, true, 12},
|
|
{"modifyOtherKeys Ctrl-K", "\x1b[27;5;107~", 0, true, 11},
|
|
{"modifyOtherKeys wrong mods", "\x1b[27;6;107~", 0, false, 0},
|
|
{"unrelated CSI", "\x1b[A", 0, false, 0},
|
|
{"plain ascii", "k", 0, false, 0},
|
|
{"empty", "", 0, false, 0},
|
|
{"incomplete CSI", "\x1b[107;5", 0, false, 0},
|
|
{"offset past legacy", "x\x0b", 1, true, 1},
|
|
{"offset past kitty prefix", "x\x1b[107;5u", 1, true, 8},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got, adv := matchCtrlK([]byte(tc.chunk), tc.offset)
|
|
if got != tc.wantMatch || adv != tc.wantAdvance {
|
|
t.Fatalf("matchCtrlK(%q, %d) = (%v, %d); want (%v, %d)",
|
|
tc.chunk, tc.offset, got, adv, tc.wantMatch, tc.wantAdvance)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseSGRMouseWheel(t *testing.T) {
|
|
cases := []struct {
|
|
params string
|
|
want int
|
|
ok bool
|
|
}{
|
|
{"64;1;1", -3, true}, // wheel up
|
|
{"65;1;1", 3, true}, // wheel down
|
|
{"68;1;1", -3, true}, // shift+wheel up
|
|
{"69;1;1", 3, true}, // shift+wheel down
|
|
{"80;1;1", -3, true}, // ctrl+wheel up
|
|
{"81;1;1", 3, true}, // ctrl+wheel down
|
|
{"0;5;7", 0, false}, // left press
|
|
{"2;5;7", 0, false}, // right press
|
|
{"32;5;7", 0, false}, // drag
|
|
{"", 0, false}, // empty
|
|
{"abc;1;1", 0, false}, // garbage button
|
|
}
|
|
for _, c := range cases {
|
|
got, ok := parseSGRMouseWheel([]byte(c.params))
|
|
if ok != c.ok || got != c.want {
|
|
t.Errorf("parseSGRMouseWheel(%q) = (%d,%v), want (%d,%v)", c.params, got, ok, c.want, c.ok)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMatchCtrlKConsecutive(t *testing.T) {
|
|
// Two kitty Ctrl-K sequences back to back, the chord case.
|
|
chunk := []byte("\x1b[107;5u\x1b[107;5u")
|
|
hit, adv := matchCtrlK(chunk, 0)
|
|
if !hit || adv != 8 {
|
|
t.Fatalf("first: hit=%v adv=%d", hit, adv)
|
|
}
|
|
hit2, adv2 := matchCtrlK(chunk, adv)
|
|
if !hit2 || adv2 != 8 {
|
|
t.Fatalf("second: hit=%v adv=%d", hit2, adv2)
|
|
}
|
|
if adv+adv2 != len(chunk) {
|
|
t.Fatalf("expected to cover the whole chunk, got %d/%d", adv+adv2, len(chunk))
|
|
}
|
|
}
|