def test_KQk_Passed_position_unclear(): # Blk Rook moved and moved back test = Fen('r1bqkb1r/ppp2ppp/2np1n2/4p3/4P3/2NP1N2/PPP2PPP/R1BQKB1R w KQk -') # in this position it is not clear whether or not the Kings or Rooks # have moved as each Rook could have moved and moved back and the kings # could have moved and directly moved back or taken a triangluar # route back to their original square. assert test.castling == 'KQk'
def good_ep_fen(): # sets up a Fen object with a valid test.ep square # NB I am currently not clear whether this should be set ONLY if there is # an enemy pawn positioned to perform a ep capture. ie only when it matters! # The following position is after 1 e4 e6 2 e5 d5 when white could play # 3 exd6 e.p. return Fen('rnbqkbnr/pppp1ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 3')
def test_2Blanks_castling_set(): test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b - - KQkq 1 2') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'b' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_ep_None(): test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'b' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_2Blanks_ep_setIncorrectly(): test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b - - e3 1 2') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'b' assert test.castling == '-' assert test.ep == '-' # e3 inconsistant with board assert test.halfMove == '1' assert test.move == '2'
def test_fenTrailingWhiteSpace(): test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/8/2p5/4P3/PPPP1PPP/RNBQKBNR w KQkq d6 0 3 ') assert test.board == 'rnbqkbnr/pp1ppppp/8/8/2p5/4P3/PPPP1PPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' # d6 inconsistant with board assert test.halfMove == '0' assert test.move == '3' assert str(test) == 'rnbqkbnr/pp1ppppp/8/8/2p5/4P3/PPPP1PPP/RNBQKBNR w KQkq - 0 3'
def test_epwtpValid(): test = Fen(fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKB1R w KQkq d6 0 3') # after 1 e4 e6 2 e5 d4: e6 correct assert test.board == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == 'd6' assert test.halfMove == '0' assert test.move == '3'
def test_epbtpValid(): test = Fen(fen = 'rnbqkbnr/ppp1pppp/8/8/3pP3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq e3 0 4') # after 1 Nf3 d5 2 Nc3 d4 3 e4: e3 correct assert test.board == 'rnbqkbnr/ppp1pppp/8/8/3pP3/2N2N2/PPPP1PPP/R1BQKB1R' assert test.toPlay == 'b' assert test.castling == 'KQkq' assert test.ep == 'e3' assert test.halfMove == '0' assert test.move == '4'
def test_castling_None_EPwrong(): test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b - e3 1 2') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'b' assert test.castling == '-' # no enemy pawns in place so reset to '-' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_epError(): with mock.patch('builtins.input',side_effect = ['-']): test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq x 1 2') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'b' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_2Blanks_ep_setCorrectly(): test = Fen(fen = 'rnbqkbnr/ppp1pppp/8/8/3pP3/2N2N2/PPPP1PPP/R1BQKB1R b - - e3 1 2') # 1 Nf3 d5 2 Nc3 d4 3 e4 - e3 valid assert test.board == 'rnbqkbnr/ppp1pppp/8/8/3pP3/2N2N2/PPPP1PPP/R1BQKB1R' assert test.toPlay == 'b' assert test.castling == '-' assert test.ep == 'e3' assert test.halfMove == '0' # last move was pawn move assert test.move == '2'
def test_orderFenValidEP(): test = Fen(fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR d6 w KQkq 0 3') assert test.board == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == 'd6' assert test.halfMove == '0' assert test.move == '3' assert str(test) == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 3'
def test_fenMissingEP(): with mock.patch('builtins.input',side_effect = ['d6']): test = Fen(fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq 0 3') assert test.board == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == 'd6' assert test.halfMove == '0' assert test.move == '3' assert str(test) == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 3'
def test_manyBlackKings(): with mock.patch('builtins.input',side_effect = ['rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R KQkq']): # full reset to starting position test = Fen(fen = 'rnbkkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQQB1R b KQkq - 1 2') # input of corrected board element assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R KQkq' assert test.toPlay == 'b' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_tooManyBlackPawns(): with mock.patch('builtins.input',side_effect = ['rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R']): test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4p3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2') # input of corrected board element assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'b' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_epwtpInvalid(): with mock.patch('builtins.input',side_effect = ['-']): test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq e3 1 2') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'w' assert test.castling == 'KQkq' # temporary: reset fentest.ep to '-' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_CastlingError(): with mock.patch('builtins.input',side_effect = ['KQkq', '-']): # as the castling element is unrecognisable, '-' # cannot be allocated, so ep needs to be set test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkx - 1 2') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'b' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_MisplacedDigitsboth(): # misplaced digits will be reset # half move will be reset to 0, move to 1 test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w 1 2 KQkq -') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '0' assert test.move == '1' assert str(test) == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 0 1'
def test_castling_None_EPok(): test = Fen(fen = 'rnbqkbnr/ppp1pppp/8/8/3pP3/2N2N2/PPPP1PPP/R1BQKB1R b - e3 1 2') # position after 1 Nf3 d5 2 Nc3 d4 3 e4: e3 is a ep square assert test.board == 'rnbqkbnr/ppp1pppp/8/8/3pP3/2N2N2/PPPP1PPP/R1BQKB1R' assert test.toPlay == 'b' assert test.castling == '-' # e3 is valid assert test.ep == 'e3' assert test.halfMove == '0' # last move was pawn move assert test.move == '2'
def test_fenMissingDigit(): test = Fen(fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 3') # assumed that the provided digit is the move number # half move will be reset to 0 assert test.board == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == 'd6' assert test.halfMove == '0' assert test.move == '3' assert str(test) == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 3'
def test_NoDigit(): # the available digit should be taken as the move number # half move will be reset to 0, move to 1 test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '0' assert test.move == '1' assert str(test) == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 0 1'
def test_noWhiteKing(): # this checks that the absence of a white king results in an error with mock.patch('builtins.input',side_effect = ['rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R KQkq']): # full reset to starting position test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQQB1R b KQkq - 1 2') # input of corrected board element assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R KQkq' assert test.toPlay == 'b' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2'
def test_fenMissingBoard(): with mock.patch('builtins.input',side_effect = ['rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R']): test = Fen(fen = 'w KQkq - 1 2') # reset all but board and halfMove/move, as missing element # requires input of all other elements of the fen assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '1' assert test.move == '2' assert str(test) == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 1 2'
def test_fenWhiteSpaceInCandEP(): with mock.patch('builtins.input',side_effect = ['KQkq', 'd6']): # problem this would result in two valid castling elements # should be caught as contradictory and require input of castling test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/8/2p5/4P3/PPPP1PPP/RNBQKBNR w K Qkq d 6 0 3') assert test.board == 'rnbqkbnr/pp1ppppp/8/8/2p5/4P3/PPPP1PPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' # d6 inconsistent with board assert test.halfMove == '0' assert test.move == '3' assert str(test) == 'rnbqkbnr/pp1ppppp/8/8/2p5/4P3/PPPP1PPP/RNBQKBNR w KQkq - 0 3'
def test_MisplacedDigitsOne(): # misplaced digits will be reset # half move will be reset to 0 test = Fen(fen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w 1 KQkq - 2') assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '0' # the last digit is assumed to be the move counter assert test.move == '2' assert str(test) == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 0 2'
def test_nonStringFenFloat(): with mock.patch('builtins.input',side_effect = ['rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR', 'w','KQkq','-']): # reset to starting position test = Fen(fen = 5.45) # float passed # 5.45 could be read as a board with 10 squares and one invalid # character ('.') assert test.board == 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '0' assert test.move == '1' assert str(test) == startingFen
def test_fenMissingToPlay(): with mock.patch('builtins.input',side_effect = ['w']): test = Fen(fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR KQkq d6 0 3') # position after 1 e4 e6 2 e5 d5 # the missing toPlay would make it impossible to check ep, # but toPlay should be set in time to prevent problem assert test.board == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == 'd6' assert test.halfMove == '0' assert test.move == '3' assert str(test) == 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 3'
def test_nonStringFenBool(): with mock.patch('builtins.input',side_effect = ['rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR', 'w','KQkq','-']): # full reset to starting position test = Fen(True) # bool passed # 5 is a valid fen character, so the board element consists of 5 # blank squares assert test.board == 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '0' assert test.move == '1' assert str(test) == startingFen
def test_missingFen(): with mock.patch('builtins.input',side_effect = ['rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR', 'w','KQkq','-']): # full reset to starting position # currently this is not an automatic reset to the starting position # as in pychess, but requires manual input of each element # of the fen test = Fen() # nothing passed assert test.board == 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '0' assert test.move == '1' assert str(test) == startingFen
def test_noBoardSubstring(): with mock.patch('builtins.input',side_effect = ['rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R']): test = Fen(fen = 'w KQkq - 5 20') # toPlay, castling and ep should be recognised # no board element passed # last two items accepted as they are digits assert test.fenElements == ['w', 'KQkq', '-', '5', '20'] assert test.board == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R' # fenToPlay set to test default 'w' assert test.toPlay == 'w' assert test.castling == 'KQkq' assert test.ep == '-' assert test.halfMove == '5' assert test.move == '20' assert str(test) == 'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 5 20'