lobby_test.gno
4.23 Kb ยท 184 lines
1package chess
2
3import (
4 "os"
5 "testing"
6 "time"
7
8 "gno.land/p/morgan/chess/glicko2"
9)
10
11func TestLobbyJoin(t *testing.T) {
12 cleanup()
13 testing.SetRealm(testing.NewUserRealm(white))
14 LobbyJoin(cross, 10*60, 5)
15 os.Sleep(time.Second * 5)
16 testing.SetRealm(testing.NewUserRealm(black))
17 LobbyJoin(cross, 10*60, 5)
18 res := LobbyGameFound(cross)
19 if res == "null" {
20 t.Errorf("LobbyGameFound is null")
21 }
22}
23
24func sublobbyToIDs(pl []lobbyPlayer) []string {
25 s := make([]string, len(pl))
26 for idx, p := range pl {
27 s[idx] = string(p.player.Address)
28 }
29 return s
30}
31
32func TestLobbyGameFound(t *testing.T) {
33 check := func(checker ...func(t *testing.T)) func(t *testing.T) {
34 return func(t *testing.T) {
35 for _, ck := range checker {
36 ck(t)
37 }
38 }
39 }
40 ids := func(ids ...address) func(t *testing.T) {
41 return func(t *testing.T) {
42 if len(ids) != len(lobby[0]) {
43 t.Errorf("lobby doesn't match expected ids: lobby: %v, newIDs: %v", sublobbyToIDs(lobby[0]), ids)
44 return
45 }
46 for idx, i := range ids {
47 if pa := lobby[0][idx].player.Address; pa != i {
48 t.Errorf("check pos %d: player id doesnt match (got %q want %q)", idx, pa, i)
49 }
50 }
51 }
52 }
53 numGames := func(n int) func(t *testing.T) {
54 return func(t *testing.T) {
55 l := gameStore.Size()
56 if l != n {
57 t.Errorf("invalid gameStore size; want %d got %d", n, l)
58 }
59 }
60 }
61
62 type pl struct {
63 id address
64 rating float64
65 // use negative values here to indicate how many seconds in the past;
66 // ie: joinedAt: -1, means player joined 1 second ago.
67 joinedAt int
68 seenAt int
69 }
70 tt := []struct {
71 name string
72 pre []pl
73 caller address
74 check func(t *testing.T)
75 }{
76 {
77 "equalRating",
78 []pl{{"1", 1200, -1, -1}, {"2", 1200, 0, 0}},
79 "1",
80 check(ids(), numGames(1)),
81 },
82 {
83 "minimumApart", // delta <= 25
84 []pl{{"1", 1200, 0, 0}, {"2", 1225, 0, 0}},
85 "2",
86 check(ids(), numGames(1)),
87 },
88 {
89 "tooFarApart", // delta > 25
90 []pl{{"1", 1200, 0, 0}, {"2", 1230, 0, 0}},
91 "2",
92 check(ids("1", "2"), numGames(0)),
93 },
94 {
95 "oldHighPriority",
96 // kicked hasn't been seen in too long, so should not be considered.
97 // 1 is active and has been looking for 30s, so it gets priority, even if 2-3 is
98 // a closer match.
99 []pl{{"kicked", 1800, -60, -50}, {"1", 1900, -30, -10}, {"2", 1400, 0, 0}, {"3", 1420, 0, 0}},
100 "3",
101 check(ids("2"), numGames(1)),
102 },
103 {
104 "oldHighPriority2",
105 []pl{{"comeback", 1800, -60, -50}, {"1", 1900, -30, -10}, {"2", 1400, 0, 0}, {"3", 1420, 0, 0}},
106 // same as last one, except the player who was kicked last time, because
107 // he's the caller, has their seenAt set back to the current time, so they're matched with 1.
108 "comeback",
109 check(ids("2", "3"), numGames(1)),
110 },
111 {
112 "alone",
113 []pl{{"1", 1200, 0, 0}},
114 "1",
115 check(ids("1"), numGames(0)),
116 },
117 {
118 "brackFail",
119 []pl{{"1", 1200, -4, -4}, {"2", 1450, -5, -5}},
120 "1",
121 check(ids("1", "2"), numGames(0)),
122 },
123 {
124 "brackFail2",
125 []pl{{"1", 1200, -5, -5}, {"2", 1450, -4, -4}},
126 "1",
127 check(ids("1", "2"), numGames(0)),
128 },
129 {
130 "brackSuccess",
131 []pl{{"1", 1200, -5, -5}, {"2", 1450, -5, -5}},
132 "1",
133 check(ids(), numGames(1)),
134 },
135 }
136
137 for _, tc := range tt {
138 t.Run(tc.name, func(t *testing.T) {
139 cleanup()
140 now := time.Now()
141 for _, p := range tc.pre {
142 lobby[0] = append(lobby[0], lobbyPlayer{
143 joinedAt: now.Add(time.Duration(p.joinedAt) * time.Second),
144 seenAt: now.Add(time.Duration(p.seenAt) * time.Second),
145 player: &Player{
146 Address: p.id,
147 CategoryInfo: [CategoryMax]CategoryInfo{
148 Blitz: {PlayerRating: &glicko2.PlayerRating{Rating: p.rating}},
149 },
150 },
151 })
152 }
153
154 testing.SetRealm(testing.NewUserRealm(tc.caller))
155 LobbyGameFound(cross)
156
157 if tc.check != nil {
158 tc.check(t)
159 }
160 })
161 }
162}
163
164func TestLobbyJoin_HasOpenGames(t *testing.T) {
165 cleanup()
166 g := &Game{
167 ID: "123",
168 White: white,
169 Black: black,
170 State: GameStateOpen,
171 }
172 gameStore.Set(g.ID, g)
173 addToUser2Games(white, g)
174 addToUser2Games(black, g)
175
176 testing.SetRealm(testing.NewUserRealm(white))
177 LobbyJoin(cross, 10*60, 5)
178 if g.State != GameStateAborted {
179 t.Errorf("state wrong: want %d got %d", GameStateAborted, g.State)
180 }
181 if g.Winner != WinnerNone {
182 t.Errorf("winner wrong: want %q got %q", "none", g.Winner)
183 }
184}