src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/ui/key_test.go (about) 1 package ui 2 3 import ( 4 "testing" 5 6 "src.elv.sh/pkg/eval/vals" 7 "src.elv.sh/pkg/persistent/hash" 8 ) 9 10 var KTests = []struct { 11 k1 Key 12 k2 Key 13 }{ 14 {K('a'), Key{'a', 0}}, 15 {K('a', Alt), Key{'a', Alt}}, 16 {K('a', Alt, Ctrl), Key{'a', Alt | Ctrl}}, 17 } 18 19 func TestK(t *testing.T) { 20 for _, test := range KTests { 21 if test.k1 != test.k2 { 22 t.Errorf("%v != %v", test.k1, test.k2) 23 } 24 } 25 } 26 27 func TestKeyAsElvishValue(t *testing.T) { 28 vals.TestValue(t, K('a')). 29 Kind("edit:key"). 30 Hash(hash.DJB('a', 0)). 31 Repr("(edit:key a)"). 32 Equal(K('a')). 33 NotEqual(K('A'), K('a', Alt)) 34 35 vals.TestValue(t, K('a', Alt)).Repr("(edit:key Alt-a)") 36 vals.TestValue(t, K('a', Ctrl, Alt, Shift)).Repr("(edit:key Ctrl-Alt-Shift-a)") 37 38 vals.TestValue(t, K('\t')).Repr("(edit:key Tab)") 39 vals.TestValue(t, K(F1)).Repr("(edit:key F1)") 40 vals.TestValue(t, K(-1)).Repr("(edit:key '(bad function key -1)')") 41 vals.TestValue(t, K(-2000)).Repr("(edit:key '(bad function key -2000)')") 42 } 43 44 var parseKeyTests = []struct { 45 s string 46 wantKey Key 47 wantErr string 48 }{ 49 {s: "x", wantKey: K('x')}, 50 {s: "Tab", wantKey: K(Tab)}, 51 {s: "F1", wantKey: K(F1)}, 52 53 // Alt- keys are case-sensitive. 54 {s: "A-x", wantKey: Key{'x', Alt}}, 55 {s: "A-X", wantKey: Key{'X', Alt}}, 56 57 // Ctrl- keys are case-insensitive. 58 {s: "C-x", wantKey: Key{'X', Ctrl}}, 59 {s: "C-X", wantKey: Key{'X', Ctrl}}, 60 61 // Literal control chars are equivalent to the preferred Ctrl-<key> 62 // formulation. 63 {s: "\033", wantKey: Key{'[', Ctrl}}, 64 65 // + is the same as -. 66 {s: "C+X", wantKey: Key{'X', Ctrl}}, 67 68 // Full names and alternative names can also be used. 69 {s: "M-x", wantKey: Key{'x', Alt}}, 70 {s: "Meta-x", wantKey: Key{'x', Alt}}, 71 72 // Multiple modifiers can appear in any order and with alternative 73 // separator chars. 74 {s: "Alt-Ctrl+Delete", wantKey: Key{Delete, Alt | Ctrl}}, 75 {s: "Ctrl+Alt-Delete", wantKey: Key{Delete, Alt | Ctrl}}, 76 77 // Confirm alternative symbolic keys are turned into the canonical form. 78 {s: "\t", wantKey: K(Tab)}, // literal tab is normalized to Tab 79 {s: "\n", wantKey: K(Enter)}, // literal newline is normalized to Enter 80 {s: "Ctrl-I", wantKey: K(Tab)}, // Ctrl-I is normalized to Tab 81 {s: "Ctrl-J", wantKey: K(Enter)}, // Ctrl-J is normalized to Enter 82 {s: "Alt-\t", wantKey: Key{Tab, Alt}}, 83 {s: "\x7F", wantKey: K(Backspace)}, 84 85 // Errors. 86 {s: "F123", wantErr: "bad key: F123"}, 87 {s: "Super-X", wantErr: "bad modifier: Super"}, 88 {s: "a-x", wantErr: "bad modifier: a"}, 89 {s: "Ctrl-\t", wantErr: `Ctrl modifier with literal control char: '\t'`}, 90 } 91 92 func TestParseKey(t *testing.T) { 93 for _, test := range parseKeyTests { 94 key, err := ParseKey(test.s) 95 if key != test.wantKey { 96 t.Errorf("ParseKey(%q) => %v, want %v", test.s, key, test.wantKey) 97 } 98 if test.wantErr == "" { 99 if err != nil { 100 t.Errorf("ParseKey(%q) => error %v, want nil", test.s, err) 101 } 102 } else { 103 if err == nil || err.Error() != test.wantErr { 104 t.Errorf("ParseKey(%q) => error %v, want error with message %q", 105 test.s, err, test.wantErr) 106 } 107 } 108 } 109 }