package game import ( "strings" "testing" "github.com/google/uuid" "scrabble/backend/internal/engine" ) func TestWriteGCG(t *testing.T) { g := Game{ ID: uuid.MustParse("00000000-0000-7000-8000-000000000001"), Variant: engine.VariantEnglish, DictVersion: "v1", Players: 2, } moves := []HistoryMove{ { Seq: 0, Seat: 0, Action: "play", Score: 10, RunningTotal: 10, Dir: "H", MainRow: 7, MainCol: 7, Tiles: []engine.TileRecord{{Row: 7, Col: 7, Letter: "c"}, {Row: 7, Col: 8, Letter: "a"}, {Row: 7, Col: 9, Letter: "t"}}, Words: []string{"cat"}, Rack: []string{"c", "a", "t", "s", "e", "r", "?"}, }, { Seq: 1, Seat: 1, Action: "play", Score: 2, RunningTotal: 2, Dir: "V", MainRow: 7, MainCol: 8, Tiles: []engine.TileRecord{{Row: 8, Col: 8, Letter: "s", Blank: true}}, Words: []string{"as"}, Rack: []string{"a", "s", "?", "e"}, }, {Seq: 2, Seat: 0, Action: "pass", RunningTotal: 10, Rack: []string{"x", "y", "z"}}, {Seq: 3, Seat: 1, Action: "exchange", RunningTotal: 2, Exchanged: []string{"q", "u"}, Rack: []string{"q", "u", "i"}}, {Seq: 4, Seat: 0, Action: "resign", RunningTotal: 10, Rack: []string{"a", "b"}}, {Seq: 5, Seat: 1, Action: "timeout", RunningTotal: 2, Rack: []string{"c"}}, } out := writeGCG(g, []string{"Alice", "Bob"}, moves) wantLines := []string{ "#character-encoding UTF-8", "#player1 p1 Alice", "#player2 p2 Bob", "#lexicon english/v1", "#title game 00000000-0000-7000-8000-000000000001", ">p1: CATSER? 8H CAT +10 10", ">p2: AS?E I8 .s +2 2", ">p1: XYZ - +0 10", ">p2: QUI -QU +0 2", "#note p1 resigned (rack AB)", "#note p2 timed out (rack C)", } lines := strings.Split(strings.TrimRight(out, "\n"), "\n") got := make(map[string]bool, len(lines)) for _, l := range lines { got[l] = true } for _, want := range wantLines { if !got[want] { t.Errorf("GCG missing line %q\n--- full output ---\n%s", want, out) } } } func TestGCGTilesUppercasesCyrillic(t *testing.T) { if got := gcgTiles([]string{"к", "о", "т", "?"}); got != "КОТ?" { t.Errorf("gcgTiles = %q, want КОТ?", got) } } func TestGCGPos(t *testing.T) { across := gcgPos(HistoryMove{Dir: "H", MainRow: 7, MainCol: 6}) if across != "8G" { t.Errorf("across pos = %q, want 8G", across) } down := gcgPos(HistoryMove{Dir: "V", MainRow: 6, MainCol: 7}) if down != "H7" { t.Errorf("down pos = %q, want H7", down) } }