turbo-editors/turbo-corepublic Fork 0
v0.9.0
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

keys_test.go · 150 lines · 4.3 KBGo Blame HistoryRaw
🛟 Updated. 28d5985 k33g 17h ago1package terminal
2
3import (
4 "testing"
5
6 "github.com/gdamore/tcell/v2"
7)
8
9func TestEncodePrintableCharacters(t *testing.T) {
10 tests := []struct {
11 name string
12 rune rune
13 mods tcell.ModMask
14 want string
15 }{
16 {"a letter", 'a', tcell.ModNone, "a"},
17 {"a space", ' ', tcell.ModNone, " "},
18 {"an accented letter is UTF-8", 'é', tcell.ModNone, "é"},
19 {"Alt prefixes an escape", 'b', tcell.ModAlt, "\x1bb"},
20 }
21
22 for _, tc := range tests {
23 t.Run(tc.name, func(t *testing.T) {
24 got := Encode(tcell.NewEventKey(tcell.KeyRune, tc.rune, tc.mods), false)
25 if string(got) != tc.want {
26 t.Errorf("Encode() = %q, want %q", got, tc.want)
27 }
28 })
29 }
30}
31
32func TestEncodeNamedKeys(t *testing.T) {
33 tests := []struct {
34 key tcell.Key
35 want string
36 }{
37 {tcell.KeyEnter, "\r"},
38 {tcell.KeyTab, "\t"},
39 {tcell.KeyEscape, "\x1b"},
40 {tcell.KeyBacktab, "\x1b[Z"},
41 {tcell.KeyDelete, "\x1b[3~"},
42 {tcell.KeyInsert, "\x1b[2~"},
43 {tcell.KeyPgUp, "\x1b[5~"},
44 {tcell.KeyPgDn, "\x1b[6~"},
45 {tcell.KeyF1, "\x1bOP"},
46 {tcell.KeyF5, "\x1b[15~"},
47 {tcell.KeyF12, "\x1b[24~"},
48 }
49
50 for _, tc := range tests {
51 got := Encode(tcell.NewEventKey(tc.key, 0, tcell.ModNone), false)
52 if string(got) != tc.want {
53 t.Errorf("Encode(%v) = %q, want %q", tc.key, got, tc.want)
54 }
55 }
56}
57
58func TestEncodeCursorKeysFollowTheModeTheProgramAskedFor(t *testing.T) {
59 // This is the most visible thing an emulator can get wrong: the arrow keys
60 // inside vim or at a readline prompt.
61 tests := []struct {
62 key tcell.Key
63 normal, appMod string
64 }{
65 {tcell.KeyUp, "\x1b[A", "\x1bOA"},
66 {tcell.KeyDown, "\x1b[B", "\x1bOB"},
67 {tcell.KeyRight, "\x1b[C", "\x1bOC"},
68 {tcell.KeyLeft, "\x1b[D", "\x1bOD"},
69 {tcell.KeyHome, "\x1b[H", "\x1bOH"},
70 {tcell.KeyEnd, "\x1b[F", "\x1bOF"},
71 }
72
73 for _, tc := range tests {
74 if got := Encode(tcell.NewEventKey(tc.key, 0, tcell.ModNone), false); string(got) != tc.normal {
75 t.Errorf("Encode(%v) = %q, want %q", tc.key, got, tc.normal)
76 }
77 if got := Encode(tcell.NewEventKey(tc.key, 0, tcell.ModNone), true); string(got) != tc.appMod {
78 t.Errorf("Encode(%v) in application mode = %q, want %q", tc.key, got, tc.appMod)
79 }
80 }
81}
82
83func TestEncodeControlKeys(t *testing.T) {
84 // tcell's value for a control key *is* the byte a terminal expects.
85 tests := []struct {
86 name string
87 key tcell.Key
88 want byte
89 }{
90 {"Ctrl-A", tcell.KeyCtrlA, 0x01},
91 {"Ctrl-C interrupts", tcell.KeyCtrlC, 0x03},
92 {"Ctrl-D ends the input", tcell.KeyCtrlD, 0x04},
93 {"Ctrl-Z suspends", tcell.KeyCtrlZ, 0x1a},
94 }
95
96 for _, tc := range tests {
97 t.Run(tc.name, func(t *testing.T) {
98 got := Encode(tcell.NewEventKey(tc.key, 0, tcell.ModCtrl), false)
99 if len(got) != 1 || got[0] != tc.want {
100 t.Errorf("Encode() = %q, want the single byte %#02x", got, tc.want)
101 }
102 })
103 }
104}
105
106func TestBackspaceSendsDelete(t *testing.T) {
107 // tcell posts both 0x08 and 0x7f as KeyBackspace, so Ctrl-H and the
108 // backspace key cannot be told apart here. DEL is what a modern terminal
109 // sends for the key people actually press.
110 for _, key := range []tcell.Key{tcell.KeyBackspace, tcell.KeyBackspace2} {
111 if got := Encode(tcell.NewEventKey(key, 0, tcell.ModNone), false); string(got) != "\x7f" {
112 t.Errorf("Encode(%v) = %q, want DEL", key, got)
113 }
114 }
115}
116
117func TestControlKeysUseTcellsOwnOffset(t *testing.T) {
118 // A real terminal byte of 0x03 reaches tcell as KeyCtrlSpace+3. Encoding
119 // from the raw value instead would send nothing at all for every Ctrl-key,
120 // silently.
121 if got := int(tcell.KeyCtrlSpace); got != 64 {
122 t.Fatalf("tcell.KeyCtrlSpace = %d, want 64 — this test's premise has changed", got)
123 }
124
125 for control := byte(0); control < 32; control++ {
126 key := tcell.KeyCtrlSpace + tcell.Key(control)
127 if _, named := namedKeys[key]; named {
128 continue
129 }
130
131 got := Encode(tcell.NewEventKey(key, 0, tcell.ModCtrl), false)
132 if len(got) != 1 || got[0] != control {
133 t.Errorf("Encode(%v) = %q, want the single byte %#02x", key, got, control)
134 }
135 }
136}
137
138func TestAltWithAControlKeyPrefixesAnEscape(t *testing.T) {
139 got := Encode(tcell.NewEventKey(tcell.KeyCtrlC, 0, tcell.ModCtrl|tcell.ModAlt), false)
140
141 if string(got) != "\x1b\x03" {
142 t.Errorf("Encode() = %q, want an escape then the control byte", got)
143 }
144}
145
146func TestAKeyWithNoTerminalMeaningEncodesToNothing(t *testing.T) {
147 if got := Encode(tcell.NewEventKey(tcell.KeyF64, 0, tcell.ModNone), false); len(got) != 0 {
148 t.Errorf("Encode() = %q, want nothing to send", got)
149 }
150}