[gnome-games] chess: Run tests on make check, add tests for PGN files, remove obsolete manual test PGN files
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] chess: Run tests on make check, add tests for PGN files, remove obsolete manual test PGN files
- Date: Tue, 22 Feb 2011 01:34:26 +0000 (UTC)
commit f190a87b5725522c8900e963079f056370cb3e0a
Author: Robert Ancell <robert ancell canonical com>
Date: Tue Feb 22 12:34:19 2011 +1100
chess: Run tests on make check, add tests for PGN files, remove obsolete manual test PGN files
glchess/src/Makefile.am | 17 +++++--
glchess/src/chess-pgn.vala | 108 +++++++++++++++++++++++--------------
glchess/src/test-chess-pgn.vala | 100 ++++++++++++++++++++++++++++++++++
glchess/tests/carriage_return.pgn | 9 ---
glchess/tests/castle.pgn | 10 ----
glchess/tests/castleblock.pgn | 10 ----
glchess/tests/castleblock2.pgn | 11 ----
glchess/tests/castleblock3.pgn | 10 ----
glchess/tests/castleblock4.pgn | 10 ----
glchess/tests/castleblock5.pgn | 10 ----
glchess/tests/castleblock6.pgn | 11 ----
glchess/tests/checkmate.pgn | 10 ----
glchess/tests/comments.pgn | 12 ----
glchess/tests/complex.pgn | 12 ----
glchess/tests/complex2.pgn | 10 ----
glchess/tests/manual1.pgn | 1 -
glchess/tests/manual2.pgn | 1 -
glchess/tests/move0.pgn | 10 ----
glchess/tests/move1.pgn | 10 ----
glchess/tests/move2.pgn | 9 ---
glchess/tests/move3.pgn | 10 ----
glchess/tests/promotion.pgn | 10 ----
glchess/tests/stalemate.pgn | 24 --------
glchess/tests/stalemate2.pgn | 31 -----------
glchess/tests/threefoldrep.pgn | 25 ---------
glchess/tests/threefoldrep2.pgn | 17 ------
glchess/tests/threefoldrep3.pgn | 17 ------
glchess/tests/yahoo_chess.pgn | 33 -----------
28 files changed, 180 insertions(+), 368 deletions(-)
---
diff --git a/glchess/src/Makefile.am b/glchess/src/Makefile.am
index 065c455..8dd1bc4 100644
--- a/glchess/src/Makefile.am
+++ b/glchess/src/Makefile.am
@@ -1,6 +1,8 @@
bin_PROGRAMS = glchess
-noinst_PROGRAMS = test-chess-game
+noinst_PROGRAMS = test-chess-game test-chess-pgn
+
+TESTS = test-chess-game test-chess-pgn
glchess_SOURCES = \
config.vapi \
@@ -28,17 +30,24 @@ test_chess_game_SOURCES = \
chess-clock.vala \
chess-game.vala \
test-chess-game.vala
-
test_chess_game_CFLAGS = \
$(GOBJECT_CFLAGS)
-
test_chess_game_LDADD = \
$(GOBJECT_LIBS)
-
test_chess_game_VALAFLAGS = \
--pkg gobject-2.0 \
--pkg posix
+test_chess_pgn_SOURCES = \
+ chess-pgn.vala \
+ test-chess-pgn.vala
+test_chess_pgn_CFLAGS = \
+ $(GIO_CFLAGS)
+test_chess_pgn_LDADD = \
+ $(GIO_LIBS)
+test_chess_pgn_VALAFLAGS = \
+ --pkg gio-2.0
+
glchess_CFLAGS = \
-DPKGDATADIR=\"@datadir@/glchess\" \
$(GMODULE_CFLAGS) \
diff --git a/glchess/src/chess-pgn.vala b/glchess/src/chess-pgn.vala
index a4cf04b..ee02c65 100644
--- a/glchess/src/chess-pgn.vala
+++ b/glchess/src/chess-pgn.vala
@@ -161,7 +161,8 @@ public class PGNGame
enum State
{
- IDLE,
+ TAGS,
+ MOVE_TEXT,
LINE_COMMENT,
BRACE_COMMENT,
TAG_START,
@@ -170,6 +171,7 @@ enum State
TAG_VALUE,
POST_TAG_VALUE,
SYMBOL,
+ PERIOD,
NAG,
ERROR
}
@@ -182,27 +184,22 @@ public class PGN
{
}
- public PGN.from_file (File file) throws Error
+ public PGN.from_string (string data) throws PGNError
{
- string contents;
- size_t n_read;
- file.load_contents (null, out contents, out n_read);
-
// FIXME: Feed through newline at end to make sure parsing complete
-
- State state = State.IDLE;
+
+ State state = State.TAGS, home_state = State.TAGS;
PGNGame game = new PGNGame ();
bool in_escape = false;
size_t token_start = 0, line_offset = 0;
string tag_name = "";
StringBuilder tag_value = new StringBuilder ();
int line = 1;
- bool have_tags = false;
int rav_level = 0;
- for (size_t offset = 0; offset < contents.length; offset++)
+ for (size_t offset = 0; offset <= data.length; offset++)
{
- unichar c = contents[(long) offset];
-
+ unichar c = data[(long) offset];
+
if (c == '\n')
{
line++;
@@ -211,47 +208,63 @@ public class PGN
switch (state)
{
- case State.IDLE:
+ case State.TAGS:
+ home_state = State.TAGS;
if (c.isspace ())
- ;//
+ ; /* Ignore whitespace */
else if (c == ';')
state = State.LINE_COMMENT;
else if (c == '{')
state = State.BRACE_COMMENT;
else if (c == '[')
- {
- have_tags = true;
state = State.TAG_START;
+ else
+ {
+ offset--;
+ state = State.MOVE_TEXT;
+ continue;
}
- else if (have_tags && c == '*')
+ break;
+
+ case State.MOVE_TEXT:
+ home_state = State.MOVE_TEXT;
+ if (c.isspace ())
+ ; /* Ignore whitespace */
+ else if (c == ';')
+ state = State.LINE_COMMENT;
+ else if (c == '{')
+ state = State.BRACE_COMMENT;
+ else if (c == '*')
{
if (rav_level == 0)
{
game.result = PGNGame.RESULT_IN_PROGRESS;
games.append (game);
game = new PGNGame ();
- have_tags = false;
+ state = State.TAGS;
}
- state = State.IDLE;
}
- else if (have_tags && c == '.')
- continue;
- else if (have_tags && c.isalnum ())
+ else if (c == '.')
+ {
+ offset--;
+ state = State.PERIOD;
+ }
+ else if (c.isalnum ())
{
token_start = offset;
state = State.SYMBOL;
}
- else if (have_tags && c == '$')
+ else if (c == '$')
{
token_start = offset + 1;
state = State.NAG;
}
- else if (have_tags && c == '(')
+ else if (c == '(')
{
rav_level++;
continue;
}
- else if (have_tags && c == ')')
+ else if (c == ')')
{
if (rav_level == 0)
state = State.ERROR;
@@ -264,12 +277,12 @@ public class PGN
case State.LINE_COMMENT:
if (c == '\n')
- state = State.IDLE;
+ state = home_state;
break;
case State.BRACE_COMMENT:
if (c == '}')
- state = State.IDLE;
+ state = home_state;
break;
case State.TAG_START:
@@ -287,7 +300,7 @@ public class PGN
case State.TAG_NAME:
if (c.isspace ())
{
- tag_name = contents[(long)token_start:(long)offset];
+ tag_name = data[(long)token_start:(long)offset];
state = State.PRE_TAG_VALUE;
}
else if (c.isalnum() || c == '_' || c == '+' || c == '#' || c == '=' || c == ':' || c == '-')
@@ -329,7 +342,7 @@ public class PGN
else if (c == ']')
{
game.tags.insert (tag_name, tag_value.str);
- state = State.IDLE;
+ state = State.TAGS;
}
else
state = State.ERROR;
@@ -341,13 +354,16 @@ public class PGN
continue;
else
{
- string symbol = contents[(long)token_start:(long)offset];
+ string symbol = data[(long)token_start:(long)offset];
bool is_number = true;
for (int i = 0; i < symbol.length; i++)
if (!symbol[i].isdigit ())
is_number = false;
+ state = State.MOVE_TEXT;
+ offset--;
+
/* Game termination markers */
if (symbol == PGNGame.RESULT_DRAW || symbol == PGNGame.RESULT_WHITE || symbol == PGNGame.RESULT_BLACK)
{
@@ -356,7 +372,7 @@ public class PGN
game.result = symbol;
games.append (game);
game = new PGNGame ();
- have_tags = false;
+ state = State.TAGS;
}
}
else if (!is_number)
@@ -364,31 +380,30 @@ public class PGN
if (rav_level == 0)
game.moves.append (symbol);
}
-
- state = State.IDLE;
- offset--;
}
break;
+ case State.PERIOD:
+ /* FIXME: Should check these move carefully, e.g. "1. e2" */
+ state = State.MOVE_TEXT;
+ break;
+
case State.NAG:
if (c.isdigit ())
continue;
else
{
- //string nag = contents[(long)token_start:(long)offset];
+ //string nag = data[(long)token_start:(long)offset];
//stdout.printf ("nag = '%s'\n", nag);
- state = State.IDLE;
+ state = State.MOVE_TEXT;
offset--;
}
break;
case State.ERROR:
size_t char_offset = offset - line_offset - 1;
- var filename = file.get_path ();
- if (filename == null)
- filename = file.get_uri ();
- stderr.printf ("%s:%d.%d: error: Unexpected character\n", filename, line, (int) (char_offset + 1));
- stderr.printf ("%s\n", contents[(long)line_offset:(long)offset]);
+ stderr.printf ("%d.%d: error: Unexpected character\n", line, (int) (char_offset + 1));
+ stderr.printf ("%s\n", data[(long)line_offset:(long)offset]);
for (int i = 0; i < char_offset; i++)
stderr.printf (" ");
stderr.printf ("^\n");
@@ -396,8 +411,19 @@ public class PGN
}
}
+ if (game.moves.length () > 0 || game.tags.size () > 0)
+ games.append (game);
+
/* Must have at least one game */
if (games == null)
throw new PGNError.LOAD_ERROR("No games in PGN file");
+ }
+
+ public PGN.from_file (File file) throws Error
+ {
+ string contents;
+ size_t n_read;
+ file.load_contents (null, out contents, out n_read);
+ this.from_string (contents);
}
}
\ No newline at end of file
diff --git a/glchess/src/test-chess-pgn.vala b/glchess/src/test-chess-pgn.vala
new file mode 100644
index 0000000..741d99f
--- /dev/null
+++ b/glchess/src/test-chess-pgn.vala
@@ -0,0 +1,100 @@
+class GlChess
+{
+ static int test_count = 0;
+ static int failure_count = 0;
+
+ private static void test_pgn_file (string data, string moves)
+ {
+ test_count++;
+
+ PGN file;
+ try
+ {
+ file = new PGN.from_string (data);
+ }
+ catch (PGNError e)
+ {
+ stderr.printf ("%d. FAIL %s\n", test_count, e.message);
+ failure_count++;
+ return;
+ }
+
+ var game = file.games.nth_data (0);
+ var move_string = "";
+ foreach (var move in game.moves)
+ move_string += "%s ".printf (move);
+ move_string = move_string.strip ();
+
+ if (move_string == moves)
+ stderr.printf ("%d. PASS\n", test_count);
+ else
+ {
+ failure_count++;
+ stderr.printf ("%d. FAIL got moves '%s', expected '%s'\n", test_count, move_string, moves);
+ }
+ }
+
+ public static int main (string[] args)
+ {
+ /* Simple file in export format */
+ test_pgn_file ("[Event \"?\"]\n" +
+ "[Site \"?\"]\n" +
+ "[Date \"????.??.??\"]\n" +
+ "[Round \"?\"]\n" +
+ "[White \"\"]\n" +
+ "[Black \"\"]\n" +
+ "[Result \"*\"]\n" +
+ "\n" +
+ "1. *\n",
+ "");
+
+ /* No tags */
+ test_pgn_file ("1. e1 *\n", "e1");
+
+ /* No move numbers */
+ test_pgn_file ("e1 *\n", "e1");
+
+ /* No move result */
+ test_pgn_file ("e1\n", "e1");
+
+ /* No trailing newline */
+ test_pgn_file ("e1", "e1");
+
+ /* Carriage returns instead of newlines */
+ test_pgn_file ("[Event \"?\"]\r" +
+ "\r" +
+ "1. d4 *\r",
+ "d4");
+
+ /* Comments */
+ test_pgn_file ("; Line comment 1\n" +
+ "[Event \"?\"]\n" +
+ "; Line comment 2\n" +
+ "\n" +
+ "1. e4 {First Move} e5 {Multi\n" +
+ "line\n" +
+ "comment} 2. Nc3 {More comments} * {Comment about game end}\n",
+ "e4 e5 Nc3");
+
+ /* Format used by Yahoo Chess */
+ test_pgn_file (";Title: Yahoo! Chess Game\n" +
+ ";White: roovis\n" +
+ ";Black: ladyjones96\n" +
+ ";Date: Fri Oct 19 12:51:54 GMT 2007\n" +
+ "\n" +
+ "1. e2-e4 e7-e5\n",
+ "e2-e4 e7-e5");
+
+ /* Recursive Annotation Variation */
+ test_pgn_file ("1.Ra8+ (1.Bxd6+ Kb7 2.Rc7+ Kb8 (2...Kb6 3.Ra6#) 3.Rd7+ Kc8 4.Rc1# (4.Ra8#))",
+ "Ra8+");
+
+ /* Numeric Annotation Glyph */
+ test_pgn_file ("e4 e5 $1 Nc3 $2",
+ "e4 e5 Nc3");
+
+ stdout.printf ("%d/%d tests successful\n", test_count - failure_count, test_count);
+
+ return failure_count;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]