Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
Go + Wails v3 + Vue 3 + SQLite + FreeRDP3 (purego) 183 tests, 76 source files, 9,910 lines of code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
228 lines
5.9 KiB
Go
228 lines
5.9 KiB
Go
package rdp
|
|
|
|
import "testing"
|
|
|
|
func TestScancodeMapping(t *testing.T) {
|
|
tests := []struct {
|
|
jsCode string
|
|
expected uint32
|
|
}{
|
|
{"Escape", 0x0001},
|
|
{"Digit1", 0x0002},
|
|
{"Digit0", 0x000B},
|
|
{"KeyA", 0x001E},
|
|
{"KeyZ", 0x002C},
|
|
{"Enter", 0x001C},
|
|
{"Space", 0x0039},
|
|
{"Tab", 0x000F},
|
|
{"Backspace", 0x000E},
|
|
{"ShiftLeft", 0x002A},
|
|
{"ShiftRight", 0x0036},
|
|
{"ControlLeft", 0x001D},
|
|
{"ControlRight", 0xE01D},
|
|
{"AltLeft", 0x0038},
|
|
{"AltRight", 0xE038},
|
|
{"CapsLock", 0x003A},
|
|
{"F1", 0x003B},
|
|
{"F12", 0x0058},
|
|
{"ArrowUp", 0xE048},
|
|
{"ArrowDown", 0xE050},
|
|
{"ArrowLeft", 0xE04B},
|
|
{"ArrowRight", 0xE04D},
|
|
{"Insert", 0xE052},
|
|
{"Delete", 0xE053},
|
|
{"Home", 0xE047},
|
|
{"End", 0xE04F},
|
|
{"PageUp", 0xE049},
|
|
{"PageDown", 0xE051},
|
|
{"NumLock", 0x0045},
|
|
{"Numpad0", 0x0052},
|
|
{"Numpad9", 0x0049},
|
|
{"NumpadEnter", 0xE01C},
|
|
{"NumpadAdd", 0x004E},
|
|
{"NumpadSubtract", 0x004A},
|
|
{"NumpadMultiply", 0x0037},
|
|
{"NumpadDivide", 0xE035},
|
|
{"NumpadDecimal", 0x0053},
|
|
{"MetaLeft", 0xE05B},
|
|
{"MetaRight", 0xE05C},
|
|
{"ContextMenu", 0xE05D},
|
|
{"PrintScreen", 0xE037},
|
|
{"ScrollLock", 0x0046},
|
|
{"Backquote", 0x0029},
|
|
{"Minus", 0x000C},
|
|
{"Equal", 0x000D},
|
|
{"BracketLeft", 0x001A},
|
|
{"BracketRight", 0x001B},
|
|
{"Backslash", 0x002B},
|
|
{"Semicolon", 0x0027},
|
|
{"Quote", 0x0028},
|
|
{"Comma", 0x0033},
|
|
{"Period", 0x0034},
|
|
{"Slash", 0x0035},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.jsCode, func(t *testing.T) {
|
|
sc, ok := JSKeyToScancode(tt.jsCode)
|
|
if !ok {
|
|
t.Fatalf("JSKeyToScancode(%q) returned false", tt.jsCode)
|
|
}
|
|
if sc != tt.expected {
|
|
t.Errorf("JSKeyToScancode(%q) = 0x%04X, want 0x%04X", tt.jsCode, sc, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAllLetterKeys(t *testing.T) {
|
|
// Verify all 26 letter keys are mapped
|
|
letters := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
for _, ch := range letters {
|
|
code := "Key" + string(ch)
|
|
_, ok := JSKeyToScancode(code)
|
|
if !ok {
|
|
t.Errorf("missing mapping for %s", code)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAllDigitKeys(t *testing.T) {
|
|
for i := 0; i <= 9; i++ {
|
|
code := "Digit" + string(rune('0'+i))
|
|
_, ok := JSKeyToScancode(code)
|
|
if !ok {
|
|
t.Errorf("missing mapping for %s", code)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAllFunctionKeys(t *testing.T) {
|
|
fKeys := []string{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"}
|
|
for _, key := range fKeys {
|
|
_, ok := JSKeyToScancode(key)
|
|
if !ok {
|
|
t.Errorf("missing mapping for %s", key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAllNumpadKeys(t *testing.T) {
|
|
numpadKeys := []string{
|
|
"Numpad0", "Numpad1", "Numpad2", "Numpad3", "Numpad4",
|
|
"Numpad5", "Numpad6", "Numpad7", "Numpad8", "Numpad9",
|
|
"NumpadAdd", "NumpadSubtract", "NumpadMultiply", "NumpadDivide",
|
|
"NumpadDecimal", "NumpadEnter", "NumLock",
|
|
}
|
|
for _, key := range numpadKeys {
|
|
_, ok := JSKeyToScancode(key)
|
|
if !ok {
|
|
t.Errorf("missing mapping for %s", key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUnknownKey(t *testing.T) {
|
|
sc, ok := JSKeyToScancode("FakeKey123")
|
|
if ok {
|
|
t.Errorf("unknown key returned ok=true with scancode 0x%04X", sc)
|
|
}
|
|
if sc != 0 {
|
|
t.Errorf("unknown key scancode = 0x%04X, want 0", sc)
|
|
}
|
|
}
|
|
|
|
func TestIsExtendedKey(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
scancode uint32
|
|
extended bool
|
|
}{
|
|
{"Escape (not extended)", 0x0001, false},
|
|
{"Enter (not extended)", 0x001C, false},
|
|
{"Right Ctrl (extended)", 0xE01D, true},
|
|
{"Right Alt (extended)", 0xE038, true},
|
|
{"ArrowUp (extended)", 0xE048, true},
|
|
{"Insert (extended)", 0xE052, true},
|
|
{"NumpadEnter (extended)", 0xE01C, true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := IsExtendedKey(tt.scancode)
|
|
if got != tt.extended {
|
|
t.Errorf("IsExtendedKey(0x%04X) = %v, want %v", tt.scancode, got, tt.extended)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestScancodeValue(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
scancode uint32
|
|
value uint8
|
|
}{
|
|
{"Escape", 0x0001, 0x01},
|
|
{"Right Ctrl", 0xE01D, 0x1D},
|
|
{"ArrowUp", 0xE048, 0x48},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := ScancodeValue(tt.scancode)
|
|
if got != tt.value {
|
|
t.Errorf("ScancodeValue(0x%04X) = 0x%02X, want 0x%02X", tt.scancode, got, tt.value)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMouseFlags(t *testing.T) {
|
|
// Verify the flag constants have the right values
|
|
if MouseFlagMove != 0x0800 {
|
|
t.Errorf("MouseFlagMove = 0x%04X, want 0x0800", MouseFlagMove)
|
|
}
|
|
if MouseFlagButton1 != 0x1000 {
|
|
t.Errorf("MouseFlagButton1 = 0x%04X, want 0x1000", MouseFlagButton1)
|
|
}
|
|
if MouseFlagButton2 != 0x2000 {
|
|
t.Errorf("MouseFlagButton2 = 0x%04X, want 0x2000", MouseFlagButton2)
|
|
}
|
|
if MouseFlagButton3 != 0x4000 {
|
|
t.Errorf("MouseFlagButton3 = 0x%04X, want 0x4000", MouseFlagButton3)
|
|
}
|
|
if MouseFlagDown != 0x8000 {
|
|
t.Errorf("MouseFlagDown = 0x%04X, want 0x8000", MouseFlagDown)
|
|
}
|
|
|
|
// Test combining flags — left click down
|
|
flags := MouseFlagButton1 | MouseFlagDown
|
|
if flags != 0x9000 {
|
|
t.Errorf("left click down = 0x%04X, want 0x9000", flags)
|
|
}
|
|
|
|
// Test combining flags — right click up (no Down flag)
|
|
flags = MouseFlagButton2
|
|
if flags != 0x2000 {
|
|
t.Errorf("right click up = 0x%04X, want 0x2000", flags)
|
|
}
|
|
}
|
|
|
|
func TestScancodeMapCompleteness(t *testing.T) {
|
|
// Minimum expected mappings for a standard 104-key US keyboard:
|
|
// 26 letters + 10 digits + 12 F-keys + escape + tab + caps + 2 shifts +
|
|
// 2 ctrls + 2 alts + 2 metas + space + enter + backspace +
|
|
// numrow punctuation (backquote, minus, equal) +
|
|
// bracket pair + backslash + semicolon + quote + comma + period + slash +
|
|
// 4 arrows + insert + delete + home + end + pageup + pagedown +
|
|
// printscreen + scrolllock + pause +
|
|
// numlock + numpad 0-9 + numpad operators (5) + numpad enter + numpad decimal +
|
|
// context menu
|
|
// = 26+10+12+1+1+1+2+2+2+2+1+1+1+3+2+1+1+1+1+1+1+4+6+3+1+10+5+1+1+1 = ~104
|
|
minExpected := 90 // conservative lower bound for core keys
|
|
if len(ScancodeMap) < minExpected {
|
|
t.Errorf("ScancodeMap has %d entries, expected at least %d", len(ScancodeMap), minExpected)
|
|
}
|
|
}
|