88 lines
2.5 KiB
Go
88 lines
2.5 KiB
Go
package netproto
|
||
|
||
import (
|
||
"bytes"
|
||
"math"
|
||
"testing"
|
||
)
|
||
|
||
// TestVarint 变长整数边界(网络协议.md §2)。
|
||
func TestVarint(t *testing.T) {
|
||
cases := []uint32{0, 1, 127, 128, 300, 16383, 16384, 1<<21 - 1, math.MaxUint32}
|
||
for _, want := range cases {
|
||
w := &Writer{}
|
||
w.Varint(want)
|
||
r := NewReader(w.B)
|
||
if got := r.Varint(); got != want || r.Err != nil {
|
||
t.Fatalf("varint %d 往返失败: got=%d err=%v", want, got, r.Err)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestFrame 帧编解码往返(网络协议.md §1)。
|
||
func TestFrame(t *testing.T) {
|
||
f := Frame{MsgID: MsgBlockChange, Flags: 0, Payload: BlockChange{X: 1, Y: 64, Z: -2, BlockID: 5, Meta: 0}.Encode()}
|
||
enc := EncodeFrame(f)
|
||
got, rest, err := DecodeFrame(enc)
|
||
if err != nil {
|
||
t.Fatalf("解码失败: %v", err)
|
||
}
|
||
if len(rest) != 0 {
|
||
t.Fatalf("应无剩余字节,实际 %d", len(rest))
|
||
}
|
||
if got.MsgID != f.MsgID || !bytes.Equal(got.Payload, f.Payload) {
|
||
t.Fatalf("帧往返不一致: %+v", got)
|
||
}
|
||
// 流式粘包:两帧连续
|
||
enc2 := EncodeFrame(Frame{MsgID: MsgHeartbeat, Payload: []byte{9, 9}})
|
||
stream := append(append([]byte{}, enc...), enc2...)
|
||
g1, rest, err := DecodeFrame(stream)
|
||
if err != nil || g1.MsgID != MsgBlockChange {
|
||
t.Fatalf("粘包第一帧解析失败: %v", err)
|
||
}
|
||
g2, rest2, err := DecodeFrame(rest)
|
||
if err != nil || g2.MsgID != MsgHeartbeat || len(rest2) != 0 {
|
||
t.Fatalf("粘包第二帧解析失败: %v", err)
|
||
}
|
||
}
|
||
|
||
// TestBlockChange 方块变更消息往返。
|
||
func TestBlockChangeMsg(t *testing.T) {
|
||
in := BlockChange{X: -17, Y: 63, Z: 42, BlockID: 7, Meta: 3}
|
||
out, err := DecodeBlockChange(in.Encode())
|
||
if err != nil {
|
||
t.Fatalf("解码失败: %v", err)
|
||
}
|
||
if out != in {
|
||
t.Fatalf("往返不一致: %+v != %+v", out, in)
|
||
}
|
||
}
|
||
|
||
// TestPlayerMove 玩家移动消息往返。
|
||
func TestPlayerMoveMsg(t *testing.T) {
|
||
in := PlayerMove{X: 8.5, Y: 64.0, Z: -3.25, Yaw: 1.57, Pitch: -0.5, OnGround: true}
|
||
out, err := DecodePlayerMove(in.Encode())
|
||
if err != nil {
|
||
t.Fatalf("解码失败: %v", err)
|
||
}
|
||
if out != in {
|
||
t.Fatalf("往返不一致: %+v != %+v", out, in)
|
||
}
|
||
}
|
||
|
||
// TestTruncated 截断数据必须报错(防崩溃,网络协议.md §8)。
|
||
func TestTruncated(t *testing.T) {
|
||
f := Frame{MsgID: MsgHandshake, Payload: []byte{1, 2, 3, 4}}
|
||
enc := EncodeFrame(f)
|
||
if _, _, err := DecodeFrame(enc[:len(enc)-2]); err == nil {
|
||
t.Fatal("截断帧应报错")
|
||
}
|
||
// 超长帧头应报错
|
||
bad := make([]byte, 8)
|
||
bad[0] = 0xFF
|
||
bad[1] = 0xFF
|
||
if _, _, err := DecodeFrame(bad); err == nil {
|
||
t.Fatal("超长帧头应报错")
|
||
}
|
||
}
|