mirror of
https://github.com/jixishi/SerialTerminalForWindowsTerminal.git
synced 2026-06-15 16:42:46 +00:00
e0de872740
Extract ConvertChunk/FormatHexFrame into pkg/charset (zero external deps). Extract UIEvent/UIEventKind/UIPanelKind types into internal/event. Update all references across main package to use qualified imports. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
124 lines
3.3 KiB
Go
124 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestParseCSIu(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
seq []byte
|
|
cp int
|
|
mod int
|
|
ok bool
|
|
}{
|
|
{
|
|
name: "ctrl+alt+c lowercase",
|
|
seq: []byte{0x1b, '[', '9', '9', ';', '6', 'u'},
|
|
cp: 99, mod: 6, ok: true,
|
|
},
|
|
{
|
|
name: "ctrl+shift+c uppercase",
|
|
seq: []byte{0x1b, '[', '6', '7', ';', '5', 'u'},
|
|
cp: 67, mod: 5, ok: true,
|
|
},
|
|
{
|
|
name: "too short",
|
|
seq: []byte{0x1b, '[', '9', '9'},
|
|
cp: 0, mod: 0, ok: false,
|
|
},
|
|
{
|
|
name: "no escape prefix",
|
|
seq: []byte{'[', '9', '9', ';', '6', 'u'},
|
|
cp: 0, mod: 0, ok: false,
|
|
},
|
|
{
|
|
name: "no u terminator",
|
|
seq: []byte{0x1b, '[', '9', '9', ';', '6', 'x'},
|
|
cp: 0, mod: 0, ok: false,
|
|
},
|
|
{
|
|
name: "bad format no semicolon",
|
|
seq: []byte{0x1b, '[', '9', '9', '6', 'u'},
|
|
cp: 0, mod: 0, ok: false,
|
|
},
|
|
{
|
|
name: "empty",
|
|
seq: []byte{},
|
|
cp: 0, mod: 0, ok: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cp, mod, ok := parseCSIu(tt.seq)
|
|
if ok != tt.ok || cp != tt.cp || mod != tt.mod {
|
|
t.Fatalf("parseCSIu(%v) got=(%d,%d,%v) want=(%d,%d,%v)", tt.seq, cp, mod, ok, tt.cp, tt.mod, tt.ok)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsExitHotkeySeq(t *testing.T) {
|
|
oldCfg := config
|
|
defer func() { config = oldCfg }()
|
|
|
|
config = Config{hotkeyMod: "ctrl+alt"}
|
|
|
|
// CSI u Ctrl+Alt+C (mod=6)
|
|
if !isExitHotkeySeq([]byte{0x1b, '[', '9', '9', ';', '6', 'u'}) {
|
|
t.Fatalf("Ctrl+Alt+C CSI should exit with ctrl+alt config")
|
|
}
|
|
// CSI u Ctrl+Alt+Shift+C (mod=7, includes Ctrl+Alt)
|
|
if !isExitHotkeySeq([]byte{0x1b, '[', '9', '9', ';', '7', 'u'}) {
|
|
t.Fatalf("Ctrl+Alt+Shift+C should also exit")
|
|
}
|
|
// CSI u Ctrl+Shift+C (mod=5)
|
|
if isExitHotkeySeq([]byte{0x1b, '[', '9', '9', ';', '5', 'u'}) {
|
|
t.Fatalf("Ctrl+Shift+C should NOT exit with ctrl+alt config")
|
|
}
|
|
// CSI for other key
|
|
if isExitHotkeySeq([]byte{0x1b, '[', '9', '7', ';', '6', 'u'}) {
|
|
t.Fatalf("Ctrl+Alt+A should not exit")
|
|
}
|
|
|
|
// Simple ESC c (Alt+C) should NOT exit — requires Ctrl modifier
|
|
if isExitHotkeySeq([]byte{0x1b, 'c'}) {
|
|
t.Fatalf("Alt+C (ESC c) should NOT exit — Ctrl modifier required")
|
|
}
|
|
|
|
// Switch to ctrl+shift
|
|
config = Config{hotkeyMod: "ctrl+shift"}
|
|
|
|
if !isExitHotkeySeq([]byte{0x1b, '[', '9', '9', ';', '5', 'u'}) {
|
|
t.Fatalf("Ctrl+Shift+C should exit with ctrl+shift config")
|
|
}
|
|
if !isExitHotkeySeq([]byte{0x1b, '[', '9', '9', ';', '7', 'u'}) {
|
|
t.Fatalf("Ctrl+Shift+Alt+C should also exit (includes Ctrl+Shift)")
|
|
}
|
|
if isExitHotkeySeq([]byte{0x1b, '[', '9', '9', ';', '6', 'u'}) {
|
|
t.Fatalf("Ctrl+Alt+C should NOT exit with ctrl+shift config")
|
|
}
|
|
// Simple ESC c should NOT exit with ctrl+shift
|
|
if isExitHotkeySeq([]byte{0x1b, 'c'}) {
|
|
t.Fatalf("ESC c should NOT exit with ctrl+shift config")
|
|
}
|
|
// Non-CSI garbage
|
|
if isExitHotkeySeq([]byte{0x1b, 'x'}) {
|
|
t.Fatalf("ESC x should not exit")
|
|
}
|
|
if isExitHotkeySeq([]byte("hello")) {
|
|
t.Fatalf("plain bytes should not exit")
|
|
}
|
|
|
|
config = Config{hotkeyMod: "ctrl+alt"}
|
|
// Ctrl only (mod=4) should not exit (requires Alt too)
|
|
if isExitHotkeySeq([]byte{0x1b, '[', '9', '9', ';', '4', 'u'}) {
|
|
t.Fatalf("Ctrl+C (without Alt) should not exit")
|
|
}
|
|
// Alt only (mod=2) should not exit (requires Ctrl too)
|
|
if isExitHotkeySeq([]byte{0x1b, '[', '9', '9', ';', '2', 'u'}) {
|
|
t.Fatalf("Alt+C (without Ctrl) should not exit")
|
|
}
|
|
}
|