test(input): add missing test coverage for routing and key classification
Add TestKeyboardHandler_SetRouteKey, quotedbl/caret cases for IsTextInputKey, and shift+E case for RoutePassToWidget.
- commit
- 2b4d718c84b88cd87024a21c016c8694ff6c89c7
- author
- bnema · · 2026-03-10 22:09 UTC
- committer
- brice · · 2026-03-11 04:05 UTC
- parent
- d91ea3e
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +26 -0
M internal/ui/input/keyboard_test.go +26 -0
| @@ -48,6 +48,8 @@ func TestIsTextInputKey(t *testing.T) { | |||
| 48 | 48 | {"apostrophe", 0x027, true}, | |
| 49 | 49 | {"grave accent", 0x060, true}, | |
| 50 | 50 | {"tilde", 0x07e, true}, | |
| 51 | + | {"quotedbl", 0x022, true}, | |
| 52 | + | {"caret", 0x05e, true}, | |
| 51 | 53 | ||
| 52 | 54 | // Dead keys (used by US International layout) | |
| 53 | 55 | {"dead acute", 0xfe51, true}, | |
| @@ -99,6 +101,7 @@ func TestHandleKeyPress_RoutePassToWidget(t *testing.T) { | |||
| 99 | 101 | }{ | |
| 100 | 102 | {"plain 'e'", uint('e'), 0}, | |
| 101 | 103 | {"plain 'a'", uint('a'), 0}, | |
| 104 | + | {"shift 'E'", uint('E'), gdk.ShiftMaskValue}, | |
| 102 | 105 | {"space", 0x020, 0}, | |
| 103 | 106 | {"digit 1", uint('1'), 0}, | |
| 104 | 107 | } | |
| @@ -179,6 +182,29 @@ func TestHandleKeyPress_ModalModeIgnoresRoute(t *testing.T) { | |||
| 179 | 182 | assert.True(t, result, "modal mode should consume unknown keys regardless of route") | |
| 180 | 183 | } | |
| 181 | 184 | ||
| 185 | + | func TestKeyboardHandler_SetRouteKey(t *testing.T) { | |
| 186 | + | ctx := context.Background() | |
| 187 | + | cfg := &config.Config{} | |
| 188 | + | h := NewKeyboardHandler(ctx, cfg) | |
| 189 | + | ||
| 190 | + | // Default: no callback set | |
| 191 | + | h.mu.RLock() | |
| 192 | + | fn := h.routeKey | |
| 193 | + | h.mu.RUnlock() | |
| 194 | + | assert.Nil(t, fn, "routeKey should be nil by default") | |
| 195 | + | ||
| 196 | + | // Set callback | |
| 197 | + | h.SetRouteKey(func(kc KeyContext) KeyRoute { | |
| 198 | + | return RoutePassToWidget | |
| 199 | + | }) | |
| 200 | + | ||
| 201 | + | h.mu.RLock() | |
| 202 | + | fn = h.routeKey | |
| 203 | + | h.mu.RUnlock() | |
| 204 | + | assert.NotNil(t, fn, "routeKey should be set") | |
| 205 | + | assert.Equal(t, RoutePassToWidget, fn(KeyContext{})) | |
| 206 | + | } | |
| 207 | + | ||
| 182 | 208 | func TestHandleKeyPress_NoRouteCallback_DefaultsToShortcuts(t *testing.T) { | |
| 183 | 209 | ctx := context.Background() | |
| 184 | 210 | cfg := &config.Config{} | |
| @@ -48,6 +48,8 @@ func TestIsTextInputKey(t *testing.T) { | |||||
| 48 | {"apostrophe", 0x027, true}, | 48 | {"apostrophe", 0x027, true}, | ||
| 49 | {"grave accent", 0x060, true}, | 49 | {"grave accent", 0x060, true}, | ||
| 50 | {"tilde", 0x07e, true}, | 50 | {"tilde", 0x07e, true}, | ||
| 51 | + | {"quotedbl", 0x022, true}, | |||
| 52 | + | {"caret", 0x05e, true}, | |||
| 51 | 53 | ||||
| 52 | // Dead keys (used by US International layout) | 54 | // Dead keys (used by US International layout) | ||
| 53 | {"dead acute", 0xfe51, true}, | 55 | {"dead acute", 0xfe51, true}, | ||
| @@ -99,6 +101,7 @@ func TestHandleKeyPress_RoutePassToWidget(t *testing.T) { | |||||
| 99 | }{ | 101 | }{ | ||
| 100 | {"plain 'e'", uint('e'), 0}, | 102 | {"plain 'e'", uint('e'), 0}, | ||
| 101 | {"plain 'a'", uint('a'), 0}, | 103 | {"plain 'a'", uint('a'), 0}, | ||
| 104 | + | {"shift 'E'", uint('E'), gdk.ShiftMaskValue}, | |||
| 102 | {"space", 0x020, 0}, | 105 | {"space", 0x020, 0}, | ||
| 103 | {"digit 1", uint('1'), 0}, | 106 | {"digit 1", uint('1'), 0}, | ||
| 104 | } | 107 | } | ||
| @@ -179,6 +182,29 @@ func TestHandleKeyPress_ModalModeIgnoresRoute(t *testing.T) { | |||||
| 179 | assert.True(t, result, "modal mode should consume unknown keys regardless of route") | 182 | assert.True(t, result, "modal mode should consume unknown keys regardless of route") | ||
| 180 | } | 183 | } | ||
| 181 | 184 | ||||
| 185 | + | func TestKeyboardHandler_SetRouteKey(t *testing.T) { | |||
| 186 | + | ctx := context.Background() | |||
| 187 | + | cfg := &config.Config{} | |||
| 188 | + | h := NewKeyboardHandler(ctx, cfg) | |||
| 189 | + | ||||
| 190 | + | // Default: no callback set | |||
| 191 | + | h.mu.RLock() | |||
| 192 | + | fn := h.routeKey | |||
| 193 | + | h.mu.RUnlock() | |||
| 194 | + | assert.Nil(t, fn, "routeKey should be nil by default") | |||
| 195 | + | ||||
| 196 | + | // Set callback | |||
| 197 | + | h.SetRouteKey(func(kc KeyContext) KeyRoute { | |||
| 198 | + | return RoutePassToWidget | |||
| 199 | + | }) | |||
| 200 | + | ||||
| 201 | + | h.mu.RLock() | |||
| 202 | + | fn = h.routeKey | |||
| 203 | + | h.mu.RUnlock() | |||
| 204 | + | assert.NotNil(t, fn, "routeKey should be set") | |||
| 205 | + | assert.Equal(t, RoutePassToWidget, fn(KeyContext{})) | |||
| 206 | + | } | |||
| 207 | + | ||||
| 182 | func TestHandleKeyPress_NoRouteCallback_DefaultsToShortcuts(t *testing.T) { | 208 | func TestHandleKeyPress_NoRouteCallback_DefaultsToShortcuts(t *testing.T) { | ||
| 183 | ctx := context.Background() | 209 | ctx := context.Background() | ||
| 184 | cfg := &config.Config{} | 210 | cfg := &config.Config{} | ||