-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinput_test.gala
More file actions
153 lines (134 loc) · 5.96 KB
/
input_test.gala
File metadata and controls
153 lines (134 loc) · 5.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package gala_tui
import (
. "martianoff/gala/go_interop"
. "martianoff/gala/test"
)
// ============================================================================
// ParseKey — byte-for-byte tests of every supported key sequence.
// Byte values use hex literals for readability (ANSI escape codes are canonically
// documented in hex — e.g., `0x1B 0x5B 0x41` for "ESC [ A" = Up).
// ============================================================================
func TestParseSingleChar(t T) T {
val (ev, n) = ParseKey(SliceOf[byte](0x61)) // 'a'
val t1 = Eq(t, n, 1)
val t2 = IsTrue(t1, KeyEqual(ev.Key, Char('a')))
return IsFalse(t2, ev.Ctrl)
}
func TestParseEnter(t T) T {
val (ev, n) = ParseKey(SliceOf[byte](0x0D)) // CR
val t1 = Eq(t, n, 1)
return IsTrue(t1, KeyEqual(ev.Key, Enter()))
}
func TestParseTabSpaceBackspace(t T) T {
val (tab, _) = ParseKey(SliceOf[byte](0x09)) // Tab
val (sp, _) = ParseKey(SliceOf[byte](0x20)) // Space
val (bs, _) = ParseKey(SliceOf[byte](0x7F)) // DEL
val t1 = IsTrue(t, KeyEqual(tab.Key, Tab()))
val t2 = IsTrue(t1, KeyEqual(sp.Key, Space()))
return IsTrue(t2, KeyEqual(bs.Key, Backspace()))
}
func TestParseArrowKeys(t T) T {
// ESC [ A/B/C/D → Up/Down/Right/Left
val (up, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x41))
val (down, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x42))
val (rt, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x43))
val (lt, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x44))
val t1 = IsTrue(t, KeyEqual(up.Key, Up()))
val t2 = IsTrue(t1, KeyEqual(down.Key, Down()))
val t3 = IsTrue(t2, KeyEqual(rt.Key, ArrowRight()))
return IsTrue(t3, KeyEqual(lt.Key, ArrowLeft()))
}
func TestParseHomeEnd(t T) T {
// xterm style: ESC [ H / F
val (h, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x48))
val (f, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x46))
val t1 = IsTrue(t, KeyEqual(h.Key, Home()))
return IsTrue(t1, KeyEqual(f.Key, End()))
}
func TestParsePageKeys(t T) T {
// ESC [ 5~ / ESC [ 6~
val (pu, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x35, 0x7E))
val (pd, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x36, 0x7E))
val t1 = IsTrue(t, KeyEqual(pu.Key, PageUp()))
return IsTrue(t1, KeyEqual(pd.Key, PageDown()))
}
func TestParseDeleteInsert(t T) T {
// ESC [ 3~ (Delete), ESC [ 2~ (Insert)
val (del, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x33, 0x7E))
val (ins, _) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x32, 0x7E))
val t1 = IsTrue(t, KeyEqual(del.Key, Delete()))
return IsTrue(t1, KeyEqual(ins.Key, Insert()))
}
func TestParseFunctionKeys(t T) T {
// ESC O P/Q/R/S → F1..F4 (VT100 / SS3 path)
val (f1, _) = ParseKey(SliceOf[byte](0x1B, 0x4F, 0x50))
val (f2, _) = ParseKey(SliceOf[byte](0x1B, 0x4F, 0x51))
val (f3, _) = ParseKey(SliceOf[byte](0x1B, 0x4F, 0x52))
val (f4, _) = ParseKey(SliceOf[byte](0x1B, 0x4F, 0x53))
val t1 = IsTrue(t, KeyEqual(f1.Key, FKey(1)))
val t2 = IsTrue(t1, KeyEqual(f2.Key, FKey(2)))
val t3 = IsTrue(t2, KeyEqual(f3.Key, FKey(3)))
return IsTrue(t3, KeyEqual(f4.Key, FKey(4)))
}
// F5..F12 use the xterm CSI two-digit form: ESC [ NN ~ where NN is
// 15/17/18/19 (F5..F8) and 20/21/23/24 (F9..F12). 16 and 22 are
// gaps in the table — never emitted by terminals. This test covers
// every key in the F5..F12 range so a regression that drops one
// of them doesn't slip through.
func TestParseFunctionKeysF5ToF12(t T) T {
val (f5, n5) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x31, 0x35, 0x7E))
val (f6, n6) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x31, 0x37, 0x7E))
val (f7, n7) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x31, 0x38, 0x7E))
val (f8, n8) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x31, 0x39, 0x7E))
val (f9, n9) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x32, 0x30, 0x7E))
val (f10, n10) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x32, 0x31, 0x7E))
val (f11, n11) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x32, 0x33, 0x7E))
val (f12, n12) = ParseKey(SliceOf[byte](0x1B, 0x5B, 0x32, 0x34, 0x7E))
val t1 = IsTrue(t, KeyEqual(f5.Key, FKey(5)) && n5 == 5)
val t2 = IsTrue(t1, KeyEqual(f6.Key, FKey(6)) && n6 == 5)
val t3 = IsTrue(t2, KeyEqual(f7.Key, FKey(7)) && n7 == 5)
val t4 = IsTrue(t3, KeyEqual(f8.Key, FKey(8)) && n8 == 5)
val t5 = IsTrue(t4, KeyEqual(f9.Key, FKey(9)) && n9 == 5)
val t6 = IsTrue(t5, KeyEqual(f10.Key, FKey(10)) && n10 == 5)
val t7 = IsTrue(t6, KeyEqual(f11.Key, FKey(11)) && n11 == 5)
return IsTrue(t7, KeyEqual(f12.Key, FKey(12)) && n12 == 5)
}
func TestParseEscAlone(t T) T {
val (ev, n) = ParseKey(SliceOf[byte](0x1B))
val t1 = Eq(t, n, 1)
return IsTrue(t1, KeyEqual(ev.Key, Esc()))
}
func TestParseCtrlLetter(t T) T {
// 3 = Ctrl-C, 4 = Ctrl-D
val (ctrlC, _) = ParseKey(SliceOf[byte](0x03))
val (ctrlD, _) = ParseKey(SliceOf[byte](0x04))
val t1 = IsTrue(t, ctrlC.Ctrl)
val t2 = IsTrue(t1, KeyEqual(ctrlC.Key, Char('c')))
val t3 = IsTrue(t2, ctrlD.Ctrl)
return IsTrue(t3, KeyEqual(ctrlD.Key, Char('d')))
}
func TestParseAltLetter(t T) T {
// ESC 'a' (27, 97) — Alt-a
val (ev, n) = ParseKey(SliceOf[byte](0x1B, 0x61))
val t1 = Eq(t, n, 2)
val t2 = IsTrue(t1, ev.Alt)
return IsTrue(t2, KeyEqual(ev.Key, Char('a')))
}
func TestParseEmpty(t T) T {
val (ev, n) = ParseKey(SliceEmpty[byte]())
val t1 = Eq(t, n, 0)
return IsTrue(t1, KeyEqual(ev.Key, Unknown()))
}
// ----------------------------------------------------------------------------
// KeyEqual — make sure variants with the same shape are NOT confused.
// ----------------------------------------------------------------------------
func TestKeyEqualCharsDiffer(t T) T {
val t1 = IsTrue(t, KeyEqual(Char('a'), Char('a')))
return IsFalse(t1, KeyEqual(Char('a'), Char('b')))
}
func TestKeyEqualTypesDiffer(t T) T {
return IsFalse(t, KeyEqual(Up(), Down()))
}
func TestKeyEqualFKeyVsChar(t T) T {
return IsFalse(t, KeyEqual(FKey(1), Char('1')))
}