package protocol import ( "encoding/json" "testing" ) func TestParseJoinRoundtrip(t *testing.T) { opcode, args, err := ParseMessage([]byte(`[1,"game-token","user-token"]`)) if err != nil { t.Fatalf("parse: %v", err) } if opcode != OpJoin { t.Fatalf("opcode = %d, want %d", opcode, OpJoin) } gt, ut, err := ParseJoin(args) if err != nil { t.Fatalf("parse join: %v", err) } if gt != "game-token" || ut != "user-token" { t.Fatalf("got (%q, %q)", gt, ut) } } func TestParseMessageErrors(t *testing.T) { for _, data := range []string{`{}`, `[]`, `["1"]`, `not json`} { if _, _, err := ParseMessage([]byte(data)); err == nil { t.Fatalf("expected error for %s", data) } } } func TestBuildEnd(t *testing.T) { data := BuildEnd(7, EndCodeJoinTimeout, "join timeout exceeded") var v []any if err := json.Unmarshal(data, &v); err != nil { t.Fatalf("unmarshal: %v", err) } want := []any{float64(2), float64(7), float64(-1), "join timeout exceeded"} if len(v) != len(want) { t.Fatalf("got %v, want %v", v, want) } for i := range want { if v[i] != want[i] { t.Fatalf("got %v, want %v", v, want) } } } func TestBuildStateAndAck(t *testing.T) { if got := string(BuildState(3, StatePlacingShips)); got != `[3,3,1]` { t.Fatalf("BuildState = %s", got) } if got := string(BuildAck(3)); got != `[4,3]` { t.Fatalf("BuildAck = %s", got) } } func TestParseAck(t *testing.T) { _, args, err := ParseMessage([]byte(`[4,12]`)) if err != nil { t.Fatalf("parse: %v", err) } seq, err := ParseAck(args) if err != nil { t.Fatalf("parse ack: %v", err) } if seq != 12 { t.Fatalf("seq = %d, want 12", seq) } }