added more tests for chess moves; they all pass
[naja.git] / naja / tests / test_actions.py
index 3d3a58ea63346c936ebfb2b1c8a619640dbb5d87..f590caa9e576adf99e6cb1ab9dbebd3dda15e498 100644 (file)
@@ -1,6 +1,6 @@
 from unittest import TestCase
 
 from unittest import TestCase
 
-from naja.constants import BITS
+from naja.constants import BITS, MOVES
 from naja.gameboard import GameBoard, LocationCard
 from naja.player import Player
 from naja import actions
 from naja.gameboard import GameBoard, LocationCard
 from naja.player import Player
 from naja import actions
@@ -8,7 +8,36 @@ from naja import actions
 
 class TestActions(TestCase):
     def make_player(self, *bits):
 
 class TestActions(TestCase):
     def make_player(self, *bits):
-        return Player(sum(1 << bit for bit in bits), None)
+        player_bits = 0
+        for bit in bits:
+            player_bits |= (1 << bit)
+        return Player(player_bits, None)
+
+    def make_board(self, player_bits=None, locations=None):
+        if locations is None:
+            locations = [{'actions': []}]
+        board = GameBoard.new_game(locations)
+        if player_bits is not None:
+            board.player.bits.bits = 0
+            board.player.bits.set_bits(player_bits)
+        return board
+
+    def assert_player_bits(self, board, *bits):
+        self.assertEqual(sum(1 << bit for bit in bits), board.player.bits.bits)
+
+    def assert_state(self, state1, state2, exclude=(), player_exclude=()):
+        def filter_dict(source, exclude_keys):
+            return dict((k, v) for k, v in source.items()
+                        if k not in exclude_keys)
+
+        state1 = filter_dict(state1, exclude)
+        if 'player' in state1:
+            state1['player'] = filter_dict(state1['player'], player_exclude)
+        state2 = filter_dict(state2, exclude)
+        if 'player' in state2:
+            state2['player'] = filter_dict(state2['player'], player_exclude)
+
+        self.assertEqual(state1, state2)
 
     def test_check_available(self):
         def check_available(action_bits, player_bits, expected_result):
 
     def test_check_available(self):
         def check_available(action_bits, player_bits, expected_result):
@@ -21,59 +50,157 @@ class TestActions(TestCase):
         check_available(set([BITS.MSB]), [], False)
         check_available(set([BITS.MSB]), [BITS.MSB], True)
 
         check_available(set([BITS.MSB]), [], False)
         check_available(set([BITS.MSB]), [BITS.MSB], True)
 
+    def test_get_text(self):
+        class LocationAction1(actions.LocationAction):
+            TEXT = "foo"
+        action1 = LocationAction1([])
+        self.assertEqual(action1.get_text(), "foo")
+
+        class LocationAction2(actions.LocationAction):
+            TEXT = "foo %(bar)s"
+        action2 = LocationAction2([], bar="baz")
+        self.assertEqual(action2.get_text(), "foo baz")
+
+    def test_get_text_row_column(self):
+        class DirectionAction(actions.LocationAction):
+            TEXT = "foo %(direction)s %(rowcol)s"
+
+        action_north = DirectionAction([], direction='NORTH')
+        self.assertEqual(action_north.get_text(), "foo NORTH column")
+
+        action_south = DirectionAction([], direction='SOUTH')
+        self.assertEqual(action_south.get_text(), "foo SOUTH column")
+
+        action_east = DirectionAction([], direction='EAST')
+        self.assertEqual(action_east.get_text(), "foo EAST row")
+
+        action_west = DirectionAction([], direction='WEST')
+        self.assertEqual(action_west.get_text(), "foo WEST row")
+
     def test_DoNothing(self):
     def test_DoNothing(self):
-        board = GameBoard.new_game([])
+        board = self.make_board()
         state_before = board.export()
         actions.DoNothing(set()).perform_action(board, None)
         state_after = board.export()
         state_before = board.export()
         actions.DoNothing(set()).perform_action(board, None)
         state_after = board.export()
-        self.assertEqual(state_before, state_after)
+        self.assert_state(state_before, state_after)
 
     def test_LoseHealthOrMSB_MSB_clear(self):
 
     def test_LoseHealthOrMSB_MSB_clear(self):
-        board = GameBoard.new_game([])
+        board = self.make_board()
         state_before = board.export()
         state_before = board.export()
-        actions.LoseHeathOrMSB(set()).perform_action(board, None)
+        actions.LoseHealthOrMSB(set()).perform_action(board, None)
         state_after = board.export()
         self.assertEqual(state_after['health'], state_before['health'] - 1)
         state_after = board.export()
         self.assertEqual(state_after['health'], state_before['health'] - 1)
-
-        state_before.pop('health')
-        state_after.pop('health')
-        self.assertEqual(state_before, state_after)
+        self.assert_state(state_before, state_after, exclude=['health'])
 
     def test_LoseHealthOrMSB_MSB_set(self):
 
     def test_LoseHealthOrMSB_MSB_set(self):
-        board = GameBoard.new_game([])
-        board.player.bits.set_bit(BITS.MSB)
+        board = self.make_board(player_bits=[BITS.MSB])
         state_before = board.export()
         state_before = board.export()
-        actions.LoseHeathOrMSB(set()).perform_action(board, None)
+        actions.LoseHealthOrMSB(set()).perform_action(board, None)
         state_after = board.export()
         self.assertEqual(board.player.bits.check_bit(BITS.MSB), False)
         state_after = board.export()
         self.assertEqual(board.player.bits.check_bit(BITS.MSB), False)
-
-        state_before['player'].pop('bits')
-        state_after['player'].pop('bits')
-        self.assertEqual(state_before, state_after)
+        self.assert_state(state_before, state_after, player_exclude=['bits'])
 
     def test_SetBits(self):
 
     def test_SetBits(self):
-        board = GameBoard.new_game([])
+        board = self.make_board()
         state_before = board.export()
         state_before = board.export()
-        location = LocationCard(set([BITS.MSB, BITS.NORTH]), [])
-        actions.SetBits(set()).perform_action(board, location)
+        card = LocationCard(set([BITS.MSB, BITS.NORTH]), [])
+        actions.SetBits(set()).perform_action(board, card)
         state_after = board.export()
         self.assertEqual(
             board.player.bits.check_bits([BITS.MSB, BITS.NORTH]), True)
         state_after = board.export()
         self.assertEqual(
             board.player.bits.check_bits([BITS.MSB, BITS.NORTH]), True)
-
-        state_before['player'].pop('bits')
-        state_after['player'].pop('bits')
-        self.assertEqual(state_before, state_after)
+        self.assert_state(state_before, state_after, player_exclude=['bits'])
 
     def test_ToggleBits(self):
 
     def test_ToggleBits(self):
-        board = GameBoard.new_game([])
-        board.player.bits.set_bit(BITS.NORTH)
+        board = self.make_board(player_bits=[BITS.NORTH])
         state_before = board.export()
         state_before = board.export()
-        location = LocationCard(set([BITS.MSB, BITS.NORTH]), [])
-        actions.ToggleBits(set()).perform_action(board, location)
+        card = LocationCard(set([BITS.MSB, BITS.NORTH]), [])
+        actions.ToggleBits(set()).perform_action(board, card)
         state_after = board.export()
         self.assertEqual(board.player.bits.check_bit(BITS.MSB), True)
         self.assertEqual(board.player.bits.check_bit(BITS.NORTH), False)
         state_after = board.export()
         self.assertEqual(board.player.bits.check_bit(BITS.MSB), True)
         self.assertEqual(board.player.bits.check_bit(BITS.NORTH), False)
+        self.assert_state(state_before, state_after, player_exclude=['bits'])
+
+    def test_LoseHealthOrMSBAndSetBits_MSB_clear(self):
+        board = self.make_board(player_bits=[])
+        state_before = board.export()
+        card = LocationCard(set([BITS.BLUE, BITS.NORTH]), [])
+        actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
+        state_after = board.export()
+        self.assertEqual(state_after['health'], state_before['health'] - 1)
+        self.assert_player_bits(board, BITS.BLUE, BITS.NORTH)
+        self.assert_state(
+            state_before, state_after, exclude=['health'],
+            player_exclude=['bits'])
+
+    def test_LoseHealthOrMSBAndSetBits_MSB_set(self):
+        board = self.make_board(player_bits=[BITS.MSB])
+        state_before = board.export()
+        card = LocationCard(set([BITS.BLUE, BITS.NORTH]), [])
+        actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
+        state_after = board.export()
+        self.assert_player_bits(board, BITS.BLUE, BITS.NORTH)
+        self.assert_state(state_before, state_after, player_exclude=['bits'])
+
+    def test_LoseHealthOrMSBAndSetBits_MSB_set_and_on_card(self):
+        board = self.make_board(player_bits=[BITS.MSB])
+        state_before = board.export()
+        card = LocationCard(set([BITS.MSB, BITS.NORTH]), [])
+        actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
+        state_after = board.export()
+        self.assert_player_bits(board, BITS.MSB, BITS.NORTH)
+        self.assert_state(state_before, state_after, player_exclude=['bits'])
+
+    def test_AcquireWinToken(self):
+        board = self.make_board(
+            player_bits=[BITS.RED, BITS.GREEN, BITS.BLUE])
+        state_before = board.export()
+        actions.AcquireWinToken(set()).perform_action(board, None)
+        state_after = board.export()
+        self.assertEqual(state_after['wins'], state_before['wins'] + 1)
+        self.assertEqual(board.player.bits.bits, 0)
+        self.assert_state(
+            state_before, state_after, exclude=['wins'],
+            player_exclude=['bits'])
+
+    def test_GainHealthAndClearBitsOrMSB_MSB_clear(self):
+        board = self.make_board(player_bits=[BITS.NORTH])
+        board.lose_health()
+        state_before = board.export()
+        card = LocationCard(set([BITS.BLUE, BITS.NORTH]), [])
+        actions.GainHealthAndClearBitsOrMSB(set()).perform_action(board, card)
+        state_after = board.export()
+        self.assertEqual(state_after['health'], state_before['health'] + 1)
+        self.assert_player_bits(board)
+        self.assert_state(
+            state_before, state_after, exclude=['health'],
+            player_exclude=['bits'])
+
+    def test_GainHealthAndClearBitsOrMSB_MSB_set(self):
+        board = self.make_board(player_bits=[BITS.MSB, BITS.NORTH])
+        board.lose_health()
+        state_before = board.export()
+        card = LocationCard(set([BITS.BLUE, BITS.NORTH]), [])
+        actions.GainHealthAndClearBitsOrMSB(set()).perform_action(board, card)
+        state_after = board.export()
+        self.assertEqual(state_after['health'], state_before['health'] + 1)
+        self.assert_player_bits(board, BITS.NORTH)
+        self.assert_state(
+            state_before, state_after, exclude=['health'],
+            player_exclude=['bits'])
+
+    def test_AllowKnightMove(self):
+        board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
+        actions.AllowChessMove(set([BITS.RED, BITS.BLUE]), chesspiece="KNIGHT").perform_action(board, None)
+        self.assertEqual(board.player.movement_mode, MOVES.KNIGHT)
+
+
+    def test_AllowBishopMove(self):
+        board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
+        actions.AllowChessMove(set([BITS.RED, BITS.BLUE]), chesspiece="BISHOP").perform_action(board, None)
+        self.assertEqual(board.player.movement_mode, MOVES.BISHOP)
+
 
 
-        state_before['player'].pop('bits')
-        state_after['player'].pop('bits')
-        self.assertEqual(state_before, state_after)
+    def test_AllowCastleMove(self):
+        board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
+        actions.AllowChessMove(set([BITS.RED, BITS.BLUE]), chesspiece="CASTLE").perform_action(board, None)
+        self.assertEqual(board.player.movement_mode, MOVES.CASTLE)