Files
whc-shell/app/src/test/java/xyz/whcself/whcshell/KeyEncoderTest.java
T
WHC a0023fd2ae WHC Shell: keyboard-first Android terminal over SSH to local Termux
Vendored Termux terminal-emulator/renderer (Apache 2.0) with kitty keyboard
protocol, modifyOtherKeys and any-event mouse tracking; sshj client with
Ed25519 key login and TOFU host keys; Termux font/colors/cursor sync;
mouse selection, context menu, zoom and fullscreen shortcuts.
2026-10-06 01:51:31 +08:00

107 lines
5.5 KiB
Java

package xyz.whcself.whcshell;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static xyz.whcself.whcshell.KeyEncoder.ALT;
import static xyz.whcself.whcshell.KeyEncoder.CTRL;
import static xyz.whcself.whcshell.KeyEncoder.SHIFT;
import android.view.KeyEvent;
import org.junit.Test;
public class KeyEncoderTest {
private static KeyEncoder.Modes modes(int kitty, int mok) {
KeyEncoder.Modes m = new KeyEncoder.Modes();
m.kittyFlags = kitty;
m.modifyOtherKeys = mok;
return m;
}
private static String key(int code, int base, int text, int mods, KeyEncoder.Modes m) {
return KeyEncoder.encode(code, base, text, mods, false, m);
}
@Test
public void legacy() {
KeyEncoder.Modes m = modes(0, 0);
assertEquals("a", key(KeyEvent.KEYCODE_A, 'a', 'a', 0, m));
assertEquals("A", key(KeyEvent.KEYCODE_A, 'a', 'A', SHIFT, m));
assertEquals("\u0001", key(KeyEvent.KEYCODE_A, 'a', 'a', CTRL, m));
assertEquals("\u0001", key(KeyEvent.KEYCODE_A, 'a', 'A', CTRL | SHIFT, m));
assertEquals("\033b", key(KeyEvent.KEYCODE_B, 'b', 'b', ALT, m));
assertEquals("\033\u0002", key(KeyEvent.KEYCODE_B, 'b', 'b', ALT | CTRL, m));
assertEquals("\0", key(KeyEvent.KEYCODE_SPACE, ' ', ' ', CTRL, m));
assertEquals(" ", key(KeyEvent.KEYCODE_SPACE, ' ', ' ', SHIFT, m));
assertEquals("\033", key(KeyEvent.KEYCODE_ESCAPE, 0, 0, 0, m));
assertEquals("\r", key(KeyEvent.KEYCODE_ENTER, 0, 0, 0, m));
assertEquals("\r", key(KeyEvent.KEYCODE_ENTER, 0, 0, SHIFT, m));
assertEquals("\033\r", key(KeyEvent.KEYCODE_ENTER, 0, 0, ALT, m));
assertEquals("\r", key(KeyEvent.KEYCODE_NUMPAD_ENTER, 0, 0, 0, m));
assertEquals("\t", key(KeyEvent.KEYCODE_TAB, 0, 0, 0, m));
assertEquals("\033[Z", key(KeyEvent.KEYCODE_TAB, 0, 0, SHIFT, m));
assertEquals("\u007f", key(KeyEvent.KEYCODE_DEL, 0, 0, 0, m));
assertEquals("\b", key(KeyEvent.KEYCODE_DEL, 0, 0, CTRL, m));
assertEquals("\033\u007f", key(KeyEvent.KEYCODE_DEL, 0, 0, ALT, m));
assertEquals("\033[1;5D", key(KeyEvent.KEYCODE_DPAD_LEFT, 0, 0, CTRL, m));
assertEquals("\033[1;3C", key(KeyEvent.KEYCODE_DPAD_RIGHT, 0, 0, ALT, m));
assertEquals("\033[3;5~", key(KeyEvent.KEYCODE_FORWARD_DEL, 0, 0, CTRL, m));
assertEquals("\033[5;5~", key(KeyEvent.KEYCODE_PAGE_UP, 0, 0, CTRL, m));
assertEquals("\033[6~", key(KeyEvent.KEYCODE_PAGE_DOWN, 0, 0, 0, m));
assertEquals("\033[1;2P", key(KeyEvent.KEYCODE_F1, 0, 0, SHIFT, m));
assertEquals("中", key(KeyEvent.KEYCODE_UNKNOWN, 0, '中', 0, m));
assertNull(key(KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0, SHIFT, m));
}
@Test
public void cursorApplicationMode() {
KeyEncoder.Modes m = modes(0, 0);
m.cursorApp = true;
assertEquals("\033OA", key(KeyEvent.KEYCODE_DPAD_UP, 0, 0, 0, m));
assertEquals("\033[1;5A", key(KeyEvent.KEYCODE_DPAD_UP, 0, 0, CTRL, m));
}
@Test
public void kittyDisambiguate() {
KeyEncoder.Modes m = modes(1, 0);
assertEquals("a", key(KeyEvent.KEYCODE_A, 'a', 'a', 0, m));
assertEquals("A", key(KeyEvent.KEYCODE_A, 'a', 'A', SHIFT, m));
assertEquals("\033[97;5u", key(KeyEvent.KEYCODE_A, 'a', 'a', CTRL, m));
assertEquals("\033[97;6u", key(KeyEvent.KEYCODE_A, 'a', 'A', CTRL | SHIFT, m));
assertEquals("\033[98;3u", key(KeyEvent.KEYCODE_B, 'b', 'b', ALT, m));
assertEquals("\033[105;5u", key(KeyEvent.KEYCODE_I, 'i', 'i', CTRL, m));
assertEquals("\033[32;5u", key(KeyEvent.KEYCODE_SPACE, ' ', ' ', CTRL, m));
assertEquals("\033[27u", key(KeyEvent.KEYCODE_ESCAPE, 0, 0, 0, m));
assertEquals("\033[27;3u", key(KeyEvent.KEYCODE_ESCAPE, 0, 0, ALT, m));
assertEquals("\r", key(KeyEvent.KEYCODE_ENTER, 0, 0, 0, m));
assertEquals("\033[13;2u", key(KeyEvent.KEYCODE_ENTER, 0, 0, SHIFT, m));
assertEquals("\033[13;5u", key(KeyEvent.KEYCODE_ENTER, 0, 0, CTRL, m));
assertEquals("\t", key(KeyEvent.KEYCODE_TAB, 0, 0, 0, m));
assertEquals("\033[9;2u", key(KeyEvent.KEYCODE_TAB, 0, 0, SHIFT, m));
assertEquals("\u007f", key(KeyEvent.KEYCODE_DEL, 0, 0, 0, m));
assertEquals("\033[127;5u", key(KeyEvent.KEYCODE_DEL, 0, 0, CTRL, m));
assertEquals("\033[127;3u", key(KeyEvent.KEYCODE_DEL, 0, 0, ALT, m));
assertEquals("\033[1;5D", key(KeyEvent.KEYCODE_DPAD_LEFT, 0, 0, CTRL, m));
assertEquals("\033[3;5~", key(KeyEvent.KEYCODE_FORWARD_DEL, 0, 0, CTRL, m));
}
@Test
public void modifyOtherKeys() {
KeyEncoder.Modes m1 = modes(0, 1);
assertEquals("\u0001", key(KeyEvent.KEYCODE_A, 'a', 'a', CTRL, m1));
assertEquals("\033[27;6;65~", key(KeyEvent.KEYCODE_A, 'a', 'A', CTRL | SHIFT, m1));
assertEquals("\033[27;5;49~", key(KeyEvent.KEYCODE_1, '1', '1', CTRL, m1));
assertEquals("\033[27;2;13~", key(KeyEvent.KEYCODE_ENTER, 0, 0, SHIFT, m1));
assertEquals("\t", key(KeyEvent.KEYCODE_TAB, 0, 0, 0, m1));
assertEquals("\033b", key(KeyEvent.KEYCODE_B, 'b', 'b', ALT, m1));
KeyEncoder.Modes m2 = modes(0, 2);
assertEquals("\033[27;5;97~", key(KeyEvent.KEYCODE_A, 'a', 'a', CTRL, m2));
assertEquals("\033[27;3;98~", key(KeyEvent.KEYCODE_B, 'b', 'b', ALT, m2));
assertEquals("\033[27;5;9~", key(KeyEvent.KEYCODE_TAB, 0, 0, CTRL, m2));
assertEquals("\033[27;5;127~", key(KeyEvent.KEYCODE_DEL, 0, 0, CTRL, m2));
assertEquals("a", key(KeyEvent.KEYCODE_A, 'a', 'a', 0, m2));
}
}