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("超长帧头应报错") } }