-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.py
290 lines (249 loc) · 11.2 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# Schach is a basic chess application that uses the Stockfish chess engine.
# Copyright (C) 2021 Samuel Matzko
# This file is part of Schach.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# or see <http://www.gnu.org/licenses/>
"""Schach test suite."""
import chess
import chess.dcn
import chess.pgn
import gi
import io
import json
import unittest
import dcn
import game
import pgn
gi.require_version("Gtk", "3.0")
from constants import *
from gi.repository import Gtk
BOARD_FEN = "2b4r/p3p1pp/1p2q3/Q1pn2kP/2bPnp2/1P5p/P1PrBP1P/RN2KBNR"
FEN = "2b4r/p3p1pp/1p2q3/Q1pn2kP/2bPnp2/1P5p/P1PrBP1P/RN2KBNR w KQkq - 0 1"
CHECKMATE = "4k3/8/8/8/8/8/1r6/Kq6 w KQkq - 0 67"
STATUS_LIST = {
"board": "r n b q k b n r\np p p p p p p p\n. . . . . . . .\n. . . . . . . .\n. . . . . . . .\n. . . . . . . .\nP P P P P P P P\nR N B Q K B N R",
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"turn": True
}
DCN_FILE = """<game><header name="Event">A Test</header><header name="Site">This computer</header><header name="Date">1234.56.78</header><header name="Round">8</header><header name="White">A fake person</header><header name="Black">Dummy D. Dude</header><header name="Result">1-0</header><board fen="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" /><stack><move>a2a3</move><move>b8a6</move><move>e2e4</move></stack></game>\n\n\n"""
PGN_FILE = """[Event "A Test"]
[Site "This computer"]
[Date "1234.56.78"]
[Round "8"]
[White "A fake person"]
[Black "Dummy D. Dude"]
[Result "1-0"]
1. a3 Na6 2. e4 1-0\n\n\n"""
chessboard_method_tested = False
promote_method_tested = False
status_method_tested = False
class GameManagerTest(unittest.TestCase):
"""Tests for the Schach game manager (game.Game)."""
def create_game_manager_instance(self):
"""Return a new game.Game instance."""
game_manager = game.Game()
game_manager.bind_status(self.test_status_method)
return game_manager
def bound_method(self):
pass
def test_bind_and_initialize(self):
"""Test the class's initialization and method binding."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
game_manager.update_status()
game_manager.promote_function = self.test_promote_function
game_manager.bind_chessboard(self.test_chessboard_function)
game_manager._promote()
def test_chessboard_function(self, board=None):
"""Test the call to chessboard_function in game.Game._promote."""
global chessboard_method_tested
if not chessboard_method_tested:
self.assertEqual(str(board), str(chess.Board()))
chessboard_method_tested = True
def test_engine_move(self):
"""Test the class's engine_move method."""
global status_method_tested
game_manager = self.create_game_manager_instance()
game_manager.engine_move()
game_manager.engine.quit()
def test_method_binding(self):
"""Test the method binding for the game manager."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
game_manager.bind_chessboard(self.bound_method)
self.assertEqual(game_manager.chessboard_function, self.bound_method)
game_manager.bind_status(self.bound_method)
self.assertEqual(game_manager.status_function, self.bound_method)
def test_move_redo(self):
"""Test the move_redo method."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
game_manager._push_move(chess.Move.from_uci("a2a3"))
game_manager.move_undo()
# board_stack = game_manager.board.move_stack
board_stack = []
for item in game_manager.board.move_stack:
board_stack.append(item)
game_manager.move_redo()
self.assertEqual(board_stack, [])
self.assertEqual(game_manager.undo_stack, [])
self.assertEqual(game_manager.board.move_stack, [chess.Move.from_uci("a2a3")])
def test_move_undo(self):
"""Test the move_undo method."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
board_stack = game_manager.board.move_stack
game_manager._push_move(chess.Move.from_uci("a2a3"))
self.assertEqual(game_manager.board.move_stack, [chess.Move.from_uci("a2a3")])
self.assertEqual(game_manager.undo_stack, [])
game_manager.move_undo()
self.assertEqual(game_manager.board.move_stack, board_stack)
self.assertEqual(game_manager.undo_stack, [chess.Move.from_uci("a2a3")])
def test_new_game(self):
"""Test the new_game method."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
game_manager._push_move(chess.Move.from_uci("a2a3"))
game_manager.new_game()
self.assertEqual(game_manager.undo_stack, [])
self.assertEqual(game_manager.board, chess.Board())
def test_new_game_from_dcn(self):
"""Test the new_game method, but give an argument."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
dcn_game = chess.dcn.Game().from_file("%ssamples/game.dcn" % ROOT_PATH)
game_manager.new_game(dcn_game)
board = chess.Board()
for move in dcn_game.moves:
board.push(move)
self.assertEqual(str(game_manager.board), str(board))
game_manager.new_game()
def test_new_game_from_fen(self):
"""Test the new_game_from_fen method."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
board = chess.Board(BOARD_FEN)
game_manager.new_game_from_fen(BOARD_FEN)
self.assertEqual(str(game_manager.board), str(board))
def test_new_game_from_pgn(self):
"""Test the new_game_from_pgn method."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
with open("%ssamples/game.pgn" % ROOT_PATH) as f:
pgn_game = chess.pgn.read_game(f)
f.close()
game_manager.new_game_from_pgn(pgn_game)
board = chess.Board()
for move in pgn_game.mainline_moves():
board.push(move)
self.assertEqual(game_manager.board, board)
def test_promote_function(self, color=None):
"""Test the call to promote_function in the game.Game._promote method."""
global promote_method_tested
if not promote_method_tested:
self.assertEqual(color, "white")
promote_method_tested = True
return "q"
def test_push_move(self):
"""Test the _push_move method."""
game_manager = self.create_game_manager_instance()
game_manager.engine.quit()
move = chess.Move.from_uci("a2a3")
game_manager._push_move(move)
self.assertEqual(game_manager.board.move_stack, [move])
def test_status_method(self, *args, **kw):
"""The method to call when status is updated."""
global status_method_tested
if not status_method_tested:
self.assertEqual(kw, STATUS_LIST)
status_method_tested = True
class GameSaverTestCase(unittest.TestCase):
"""A test case for dcn and pgn game saving."""
def create_chess_game(self):
"""Create a chess.Board instance to work with."""
board = chess.Board()
board.push_uci("a2a3")
board.push_uci("b8a6")
board.push_uci("e2e4")
return board
def test_parse_dcn(self):
"""Test dcn parsing by first writing a dcn to a file from a board, and
then load it again and compare the data stored in the original game."""
game_instance = chess.dcn.Game().from_board(self.create_chess_game())
game_instance.write("%ssamples/game_.dcn" % ROOT_PATH)
game_instance2 = chess.dcn.Game().from_file("%ssamples/game_.dcn" % ROOT_PATH)
self.assertEqual(game_instance.moves, game_instance2.moves)
def test_save_dcn(self):
"""Test dcn saving by writing a game to a file and then comparing it to
a string that is what the file should look like."""
# Create the game and write it to the file
board = self.create_chess_game()
game_instance = chess.dcn.Game().from_board(board)
game_instance.set_headers(
{
"Event": "A Test",
"Site": "This computer",
"Date": "1234.56.78",
"Round": "8",
"White": "A fake person",
"Black": "Dummy D. Dude",
"Result": "1-0"
}
)
dcn.save_game(game_instance, "%ssamples/game_.dcn" % ROOT_PATH)
# Compare the file with what it should look like
with open("%ssamples/game_.dcn" % ROOT_PATH) as f:
file = f.read()
f.close()
self.assertEqual(file, DCN_FILE)
def test_parse_pgn(self):
"""Test dcn parsing by first writing a dcn to a file from a board, and
then load it again and compare the data stored in the original game."""
moves = []
moves2 = []
game_instance = chess.pgn.Game().from_board(self.create_chess_game())
with open("%ssamples/game_.pgn" % ROOT_PATH, "w") as f:
f.write(str(game_instance))
f.close()
with open("%ssamples/game_.pgn" % ROOT_PATH) as f:
game_instance2 = chess.pgn.read_game(f)
for move in game_instance.mainline_moves():
moves.append(move)
for move in game_instance2.mainline_moves():
moves2.append(move)
self.assertEqual(moves, moves2)
def test_save_pgn(self):
"""Test pgn saving by writing a game to a file and then comparing it to
a string that is what the file should look like."""
# Create the game and write it to the file
board = self.create_chess_game()
game_instance = chess.pgn.Game().from_board(board)
headers = {
"Event": "A Test",
"Site": "This computer",
"Date": "1234.56.78",
"Round": "8",
"White": "A fake person",
"Black": "Dummy D. Dude",
"Result": "1-0"
}
for header in headers:
game_instance.headers[header] = headers[header]
pgn.save_game(game_instance, "%ssamples/game_.pgn" % ROOT_PATH)
# Compare the file with what it should look like
with open("%ssamples/game_.pgn" % ROOT_PATH) as f:
file = f.read()
f.close()
self.assertEqual(file, PGN_FILE)
if __name__ == "__main__":
unittest.main()