1package tui
2
3import "testing"
4
5func TestReaderParsesCSIUShiftEnter(t *testing.T) {
6 k := readKey(t, "\x1b[13;2u")
7 if k.Kind != KeyEnter || !k.Shift || k.Alt {
8 t.Fatalf("Read kind=%v shift=%v alt=%v, want shift+enter", k.Kind, k.Shift, k.Alt)
9 }
10}
11
12func TestReaderParsesModifyOtherKeysShiftEnter(t *testing.T) {
13 k := readKey(t, "\x1b[27;2;13~")
14 if k.Kind != KeyEnter || !k.Shift || k.Alt {
15 t.Fatalf("Read kind=%v shift=%v alt=%v, want shift+enter", k.Kind, k.Shift, k.Alt)
16 }
17}
18
19func TestReaderParsesCSIUCtrlC(t *testing.T) {
20 k := readKey(t, "\x1b[99;5u")
21 if k.Kind != KeyCtrlC || !k.Ctrl {
22 t.Fatalf("Read kind=%v ctrl=%v, want ctrl+c", k.Kind, k.Ctrl)
23 }
24}
25
26func TestReaderParsesRawCtrlVAsClipboardPaste(t *testing.T) {
27 k := readKey(t, "\x16")
28 if k.Kind != KeyPasteClipboard || !k.Ctrl {
29 t.Fatalf("Read kind=%v ctrl=%v, want ctrl+v clipboard paste", k.Kind, k.Ctrl)
30 }
31}
32
33func TestReaderParsesCSIUCtrlVAsClipboardPaste(t *testing.T) {
34 k := readKey(t, "\x1b[118;5u")
35 if k.Kind != KeyPasteClipboard || !k.Ctrl {
36 t.Fatalf("Read kind=%v ctrl=%v, want enhanced ctrl+v clipboard paste", k.Kind, k.Ctrl)
37 }
38}
39
40func TestReaderParsesModifyOtherKeysCtrlC(t *testing.T) {
41 k := readKey(t, "\x1b[27;5;99~")
42 if k.Kind != KeyCtrlC || !k.Ctrl {
43 t.Fatalf("Read kind=%v ctrl=%v, want ctrl+c", k.Kind, k.Ctrl)
44 }
45}
46
47func TestReaderParsesCSIUEsc(t *testing.T) {
48 k := readKey(t, "\x1b[27u")
49 if k.Kind != KeyEsc {
50 t.Fatalf("Read kind=%v, want esc", k.Kind)
51 }
52}
53
54func TestReaderParsesCSIUTabAndBackspace(t *testing.T) {
55 if k := readKey(t, "\x1b[9u"); k.Kind != KeyTab {
56 t.Fatalf("Read kind=%v, want tab", k.Kind)
57 }
58 if k := readKey(t, "\x1b[9;2u"); k.Kind != KeyShiftTab {
59 t.Fatalf("Read kind=%v, want shift-tab", k.Kind)
60 }
61 if k := readKey(t, "\x1b[127u"); k.Kind != KeyBackspace {
62 t.Fatalf("Read kind=%v, want backspace", k.Kind)
63 }
64}
65
66func TestReaderParsesSGRMouseWheel(t *testing.T) {
67 cases := []struct {
68 seq string
69 want KeyKind
70 }{
71 {"\x1b[<64;10;20M", KeyMouseWheelUp},
72 {"\x1b[<65;10;20M", KeyMouseWheelDown},
73 }
74 for _, tc := range cases {
75 k := readKey(t, tc.seq)
76 if k.Kind != tc.want {
77 t.Fatalf("Read(%q) kind=%v, want %v", tc.seq, k.Kind, tc.want)
78 }
79 }
80}
81
82func readKey(t *testing.T, seq string) Key {
83 t.Helper()
84 idx := 0
85 r := NewReader(func() (byte, error) {
86 b := seq[idx]
87 idx++
88 return b, nil
89 })
90 k, err := r.Read()
91 if err != nil {
92 t.Fatalf("Read(%q): %v", seq, err)
93 }
94 return k
95}