Skip to content

Commit 9531d73

Browse files
Copilotianfab
andcommitted
Add unit tests for promoted piece validation in FEN validation
Added comprehensive test cases to test.py covering the promoted piece validation feature: - test_validate_fen_promoted_pieces() method with test cases for: * Valid promoted pieces in shogi variants (should pass validation) * Invalid promoted pieces that cannot be promoted (should return FEN_INVALID_PROMOTED_PIECE = -12) * Non-shogi variants with '+' character (should fail with character validation, not promoted piece validation) - Added FEN_INVALID_PROMOTED_PIECE constant to Python bindings in pyffish.cpp - Tests verify the fix works correctly: * kyotoshogi correctly rejects +K (promoted king) with error -12 * shogi rejects double promotion (++K) with error -12 * chess rejects '+' as invalid character with error -10 * Valid promoted pieces in shogi (like +p, +b, +r, +s, +n, +l) pass validation All existing tests continue to pass, confirming no regression. Co-authored-by: ianfab <12969303+ianfab@users.noreply.github.com>
1 parent 9253991 commit 9531d73

3 files changed

Lines changed: 57 additions & 0 deletions

File tree

__pycache__/test.cpython-312.pyc

66.8 KB
Binary file not shown.

src/pyffish.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ PyMODINIT_FUNC PyInit_pyffish() {
462462

463463
// validation
464464
PyModule_AddObject(module, "FEN_OK", PyLong_FromLong(FEN::FEN_OK));
465+
PyModule_AddObject(module, "FEN_INVALID_PROMOTED_PIECE", PyLong_FromLong(FEN::FEN_INVALID_PROMOTED_PIECE));
465466

466467
// initialize stockfish
467468
pieceMap.init();

test.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,62 @@ def test_validate_fen(self):
11841184
fen = sf.start_fen(variant)
11851185
self.assertEqual(sf.validate_fen(fen, variant), sf.FEN_OK)
11861186

1187+
def test_validate_fen_promoted_pieces(self):
1188+
# Test promoted piece validation specifically
1189+
1190+
# Valid promoted pieces should pass
1191+
valid_promoted_fens = {
1192+
"shogi": [
1193+
"lnsgkgsnl/1r5b1/pppppp+ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL[-] w - - 0 1", # promoted pawn
1194+
"lnsgkgsnl/1r5+b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL[-] w - - 0 1", # promoted bishop
1195+
"lnsgkgsnl/1+r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL[-] w - - 0 1", # promoted rook
1196+
"ln+sgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL[-] w - - 0 1", # promoted silver
1197+
"l+nsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL[-] w - - 0 1", # promoted knight
1198+
"+lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL[-] w - - 0 1", # promoted lance
1199+
]
1200+
}
1201+
1202+
# Invalid promoted pieces should fail with FEN_INVALID_PROMOTED_PIECE (-12)
1203+
invalid_promoted_fens = {
1204+
"kyotoshogi": [
1205+
"p+nks+l/5/5/5/+LS+K+NP[-] w 0 1", # promoted king (+K) - kings cannot be promoted
1206+
],
1207+
"shogi": [
1208+
"lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSG++KGSNL[-] w - - 0 1", # double promotion (++K)
1209+
]
1210+
}
1211+
1212+
# Non-shogi variants should ignore promoted piece syntax ('+' should be invalid character)
1213+
non_shogi_promoted_fens = {
1214+
"chess": [
1215+
"rnb+qkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", # '+' not valid in chess
1216+
]
1217+
}
1218+
1219+
# Test valid promoted pieces
1220+
for variant, fens in valid_promoted_fens.items():
1221+
for fen in fens:
1222+
with self.subTest(variant=variant, fen=fen, test_type="valid_promoted"):
1223+
result = sf.validate_fen(fen, variant)
1224+
self.assertEqual(result, sf.FEN_OK, f"Expected valid promoted piece FEN to pass: {fen}")
1225+
1226+
# Test invalid promoted pieces (should return FEN_INVALID_PROMOTED_PIECE = -12)
1227+
for variant, fens in invalid_promoted_fens.items():
1228+
for fen in fens:
1229+
with self.subTest(variant=variant, fen=fen, test_type="invalid_promoted"):
1230+
result = sf.validate_fen(fen, variant)
1231+
self.assertEqual(result, sf.FEN_INVALID_PROMOTED_PIECE,
1232+
f"Expected invalid promoted piece FEN to return -12: {fen}, got {result}")
1233+
1234+
# Test non-shogi variants (should fail with character validation, not promoted piece validation)
1235+
for variant, fens in non_shogi_promoted_fens.items():
1236+
for fen in fens:
1237+
with self.subTest(variant=variant, fen=fen, test_type="non_shogi"):
1238+
result = sf.validate_fen(fen, variant)
1239+
# Should fail with character validation (FEN_INVALID_CHAR = -10), not promoted piece validation
1240+
self.assertEqual(result, -10,
1241+
f"Expected non-shogi variant to fail with character error (-10): {fen}, got {result}")
1242+
11871243
def test_get_fog_fen(self):
11881244
fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" # startpos
11891245
result = sf.get_fog_fen(fen, "fogofwar")

0 commit comments

Comments
 (0)