main
Raw Download raw file
  1package rfb
  2
  3import (
  4	"testing"
  5)
  6
  7func TestEncodeKeyEvent(t *testing.T) {
  8	tests := []struct {
  9		name string
 10		down bool
 11		key  uint32
 12		want []byte
 13	}{
 14		{
 15			name: "key down 'a'",
 16			down: true,
 17			key:  0x61,
 18			want: []byte{0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61},
 19		},
 20		{
 21			name: "key up 'a'",
 22			down: false,
 23			key:  0x61,
 24			want: []byte{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61},
 25		},
 26		{
 27			name: "key down Return",
 28			down: true,
 29			key:  KeyReturn,
 30			want: []byte{0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0d},
 31		},
 32	}
 33
 34	for _, tt := range tests {
 35		t.Run(tt.name, func(t *testing.T) {
 36			got := EncodeKeyEvent(tt.down, tt.key)
 37			if len(got) != len(tt.want) {
 38				t.Errorf("EncodeKeyEvent() len = %d, want %d", len(got), len(tt.want))
 39				return
 40			}
 41			for i := range got {
 42				if got[i] != tt.want[i] {
 43					t.Errorf("EncodeKeyEvent()[%d] = %02x, want %02x", i, got[i], tt.want[i])
 44				}
 45			}
 46		})
 47	}
 48}
 49
 50func TestEncodeClientCutText(t *testing.T) {
 51	text := "Hello"
 52	got := EncodeClientCutText(text)
 53
 54	// Type
 55	if got[0] != MsgTypeClientCutText {
 56		t.Errorf("type = %d, want %d", got[0], MsgTypeClientCutText)
 57	}
 58
 59	// Length (big-endian)
 60	length := uint32(got[4])<<24 | uint32(got[5])<<16 | uint32(got[6])<<8 | uint32(got[7])
 61	if length != uint32(len(text)) {
 62		t.Errorf("length = %d, want %d", length, len(text))
 63	}
 64
 65	// Text
 66	gotText := string(got[8:])
 67	if gotText != text {
 68		t.Errorf("text = %q, want %q", gotText, text)
 69	}
 70}
 71
 72func TestRuneToKeysym(t *testing.T) {
 73	tests := []struct {
 74		r    rune
 75		want uint32
 76	}{
 77		{'\n', KeyReturn},
 78		{'\t', KeyTab},
 79		{'\b', KeyBackspace},
 80		{'a', 0x61},
 81		{'A', 0x41},
 82		{'1', 0x31},
 83	}
 84
 85	for _, tt := range tests {
 86		got := RuneToKeysym(tt.r)
 87		if got != tt.want {
 88			t.Errorf("RuneToKeysym(%q) = %#x, want %#x", tt.r, got, tt.want)
 89		}
 90	}
 91}
 92
 93func TestParseServerCutText(t *testing.T) {
 94	// Build a valid ServerCutText message
 95	text := "clipboard content"
 96	msg := make([]byte, 8+len(text))
 97	msg[0] = MsgTypeServerCutText
 98	// padding msg[1:4]
 99	msg[4] = 0
100	msg[5] = 0
101	msg[6] = 0
102	msg[7] = byte(len(text))
103	copy(msg[8:], text)
104
105	cut, err := ParseServerCutText(msg)
106	if err != nil {
107		t.Fatalf("ParseServerCutText() error = %v", err)
108	}
109	if cut.Text != text {
110		t.Errorf("Text = %q, want %q", cut.Text, text)
111	}
112}
113
114func TestEncodeSetEncodings(t *testing.T) {
115	encodings := []int32{EncodingTight, EncodingRaw}
116	got := EncodeSetEncodings(encodings)
117
118	// Type
119	if got[0] != MsgTypeSetEncodings {
120		t.Errorf("type = %d, want %d", got[0], MsgTypeSetEncodings)
121	}
122
123	// Count
124	count := uint16(got[2])<<8 | uint16(got[3])
125	if count != uint16(len(encodings)) {
126		t.Errorf("count = %d, want %d", count, len(encodings))
127	}
128
129	// Expected length: 4 header + 4 per encoding
130	wantLen := 4 + 4*len(encodings)
131	if len(got) != wantLen {
132		t.Errorf("len = %d, want %d", len(got), wantLen)
133	}
134}
135
136func TestEncodeFramebufferUpdateRequest(t *testing.T) {
137	got := EncodeFramebufferUpdateRequest(true, 0, 0, 1920, 1080)
138
139	// Type
140	if got[0] != MsgTypeFramebufferUpdateRequest {
141		t.Errorf("type = %d, want %d", got[0], MsgTypeFramebufferUpdateRequest)
142	}
143
144	// Incremental
145	if got[1] != 1 {
146		t.Errorf("incremental = %d, want 1", got[1])
147	}
148
149	// Width
150	width := uint16(got[6])<<8 | uint16(got[7])
151	if width != 1920 {
152		t.Errorf("width = %d, want 1920", width)
153	}
154
155	// Height
156	height := uint16(got[8])<<8 | uint16(got[9])
157	if height != 1080 {
158		t.Errorf("height = %d, want 1080", height)
159	}
160}