glyph for return
[naja.git] / naja / tests / test_actions.py
1 from unittest import TestCase
2
3 from naja.constants import BITS, MOVES
4 from naja.gameboard import GameBoard, LocationCard
5 from naja.options import parse_args
6 from naja.player import Player
7 from naja import actions
8
9
10 class TestActions(TestCase):
11     def setUp(self):
12         parse_args([])
13
14     def make_player(self, *bits):
15         player_bits = 0
16         for bit in bits:
17             player_bits |= (1 << bit)
18         return Player(player_bits, None)
19
20     def make_board(self, player_bits=None, locations=None):
21         if locations is None:
22             locations = [{'card_name': 'card', 'actions': []}]
23         board = GameBoard.new_game({'cards': locations})
24         if player_bits is not None:
25             board.player.bits.bits = 0
26             board.player.bits.set_bits(player_bits)
27         return board
28
29     def make_location_card(self, bits=(), name='card', actions=()):
30         return LocationCard(name, set(bits), list(actions), None)
31
32     def assert_player_bits(self, board, *bits):
33         self.assertEqual(sum(1 << bit for bit in bits), board.player.bits.bits)
34
35     def assert_state(self, state1, state2, exclude=(), player_exclude=()):
36         def filter_dict(source, exclude_keys):
37             return dict((k, v) for k, v in source.items()
38                         if k not in exclude_keys)
39
40         state1 = filter_dict(state1, exclude)
41         if 'player' in state1:
42             state1['player'] = filter_dict(state1['player'], player_exclude)
43         state2 = filter_dict(state2, exclude)
44         if 'player' in state2:
45             state2['player'] = filter_dict(state2['player'], player_exclude)
46
47         self.assertEqual(state1, state2)
48
49     def test_check_available(self):
50         def check_available(action_bits, player_bits, expected_result):
51             action = actions.LocationAction(action_bits)
52             player = self.make_player(*player_bits)
53             self.assertEqual(action.check_available(player), expected_result)
54
55         check_available(set(), [], True)
56         check_available(set(), [BITS.MSB], True)
57         check_available(set([BITS.MSB]), [], False)
58         check_available(set([BITS.MSB]), [BITS.MSB], True)
59
60     def test_get_text(self):
61         class LocationAction1(actions.LocationAction):
62             TEXT = "foo"
63         action1 = LocationAction1([])
64         self.assertEqual(action1.get_text(), "foo")
65
66         class LocationAction2(actions.LocationAction):
67             TEXT = "foo %(bar)s"
68         action2 = LocationAction2([], bar="baz")
69         self.assertEqual(action2.get_text(), "foo baz")
70
71     def test_get_text_row_column(self):
72         class DirectionAction(actions.LocationAction):
73             TEXT = "foo %(direction)s %(rowcol)s"
74
75         action_north = DirectionAction([], direction='NORTH')
76         self.assertEqual(action_north.get_text(), "foo {NORTH} column")
77
78         action_south = DirectionAction([], direction='SOUTH')
79         self.assertEqual(action_south.get_text(), "foo {SOUTH} column")
80
81         action_east = DirectionAction([], direction='EAST')
82         self.assertEqual(action_east.get_text(), "foo {EAST} row")
83
84         action_west = DirectionAction([], direction='WEST')
85         self.assertEqual(action_west.get_text(), "foo {WEST} row")
86
87     def test_DoNothing(self):
88         board = self.make_board()
89         state_before = board.export()
90         actions.DoNothing(set()).perform_action(board, None)
91         state_after = board.export()
92         self.assert_state(state_before, state_after)
93
94     def test_LoseHealthOrMSB_MSB_clear(self):
95         board = self.make_board()
96         state_before = board.export()
97         actions.LoseHealthOrMSB(set()).perform_action(board, None)
98         state_after = board.export()
99         self.assertEqual(state_after['health'], state_before['health'] - 1)
100         self.assert_state(state_before, state_after, exclude=['health'])
101
102     def test_LoseHealthOrMSB_MSB_set(self):
103         board = self.make_board(player_bits=[BITS.MSB])
104         state_before = board.export()
105         actions.LoseHealthOrMSB(set()).perform_action(board, None)
106         state_after = board.export()
107         self.assertEqual(board.player.bits.check_bit(BITS.MSB), False)
108         self.assert_state(state_before, state_after, player_exclude=['bits'])
109
110     def test_SetBits(self):
111         board = self.make_board()
112         state_before = board.export()
113         card = self.make_location_card([BITS.MSB, BITS.NORTH])
114         actions.SetBits(set()).perform_action(board, card)
115         state_after = board.export()
116         self.assertEqual(
117             board.player.bits.check_bits([BITS.MSB, BITS.NORTH]), True)
118         self.assert_state(state_before, state_after, player_exclude=['bits'])
119
120     def test_ToggleBits(self):
121         board = self.make_board(player_bits=[BITS.NORTH])
122         state_before = board.export()
123         card = self.make_location_card([BITS.MSB, BITS.NORTH])
124         actions.ToggleBits(set()).perform_action(board, card)
125         state_after = board.export()
126         self.assertEqual(board.player.bits.check_bit(BITS.MSB), True)
127         self.assertEqual(board.player.bits.check_bit(BITS.NORTH), False)
128         self.assert_state(state_before, state_after, player_exclude=['bits'])
129
130     def test_LoseHealthOrMSBAndSetBits_MSB_clear(self):
131         board = self.make_board(player_bits=[])
132         state_before = board.export()
133         card = self.make_location_card([BITS.BLUE, BITS.NORTH])
134         actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
135         state_after = board.export()
136         self.assertEqual(state_after['health'], state_before['health'] - 1)
137         self.assert_player_bits(board, BITS.BLUE, BITS.NORTH)
138         self.assert_state(
139             state_before, state_after, exclude=['health'],
140             player_exclude=['bits'])
141
142     def test_LoseHealthOrMSBAndSetBits_MSB_set(self):
143         board = self.make_board(player_bits=[BITS.MSB])
144         state_before = board.export()
145         card = self.make_location_card([BITS.BLUE, BITS.NORTH])
146         actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
147         state_after = board.export()
148         self.assert_player_bits(board, BITS.BLUE, BITS.NORTH)
149         self.assert_state(state_before, state_after, player_exclude=['bits'])
150
151     def test_LoseHealthOrMSBAndSetBits_MSB_set_and_on_card(self):
152         board = self.make_board(player_bits=[BITS.MSB])
153         state_before = board.export()
154         card = self.make_location_card([BITS.MSB, BITS.NORTH])
155         actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
156         state_after = board.export()
157         self.assert_player_bits(board, BITS.MSB, BITS.NORTH)
158         self.assert_state(state_before, state_after, player_exclude=['bits'])
159
160     def test_AcquireWinToken(self):
161         board = self.make_board(
162             player_bits=[BITS.RED, BITS.GREEN, BITS.BLUE])
163         state_before = board.export()
164         actions.AcquireWinToken(set()).perform_action(board, None)
165         state_after = board.export()
166         self.assertEqual(state_after['wins'], state_before['wins'] + 1)
167         self.assertEqual(board.player.bits.bits, 0)
168         self.assert_state(
169             state_before, state_after, exclude=['wins'],
170             player_exclude=['bits'])
171
172     def test_GainHealthAndClearBitsOrMSB_MSB_clear(self):
173         board = self.make_board(player_bits=[BITS.NORTH])
174         board.lose_health()
175         state_before = board.export()
176         card = self.make_location_card([BITS.BLUE, BITS.NORTH])
177         actions.GainHealthAndClearBitsOrMSB(set()).perform_action(board, card)
178         state_after = board.export()
179         self.assertEqual(state_after['health'], state_before['health'] + 1)
180         self.assert_player_bits(board)
181         self.assert_state(
182             state_before, state_after, exclude=['health'],
183             player_exclude=['bits'])
184
185     def test_GainHealthAndClearBitsOrMSB_MSB_set(self):
186         board = self.make_board(player_bits=[BITS.MSB, BITS.NORTH])
187         board.lose_health()
188         state_before = board.export()
189         card = self.make_location_card([BITS.BLUE, BITS.NORTH])
190         actions.GainHealthAndClearBitsOrMSB(set()).perform_action(board, card)
191         state_after = board.export()
192         self.assertEqual(state_after['health'], state_before['health'] + 1)
193         self.assert_player_bits(board, BITS.NORTH)
194         self.assert_state(
195             state_before, state_after, exclude=['health'],
196             player_exclude=['bits'])
197
198     def test_AllowKnightMove(self):
199         board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
200         actions.AllowChessMove(
201             set([BITS.RED, BITS.BLUE]), chesspiece="KNIGHT"
202         ).perform_action(board, None)
203         self.assertEqual(board.player.movement_mode, MOVES.KNIGHT)
204
205     def test_AllowBishopMove(self):
206         board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
207         actions.AllowChessMove(
208             set([BITS.RED, BITS.BLUE]), chesspiece="BISHOP"
209         ).perform_action(board, None)
210         self.assertEqual(board.player.movement_mode, MOVES.BISHOP)
211
212     def test_AllowCastleMove(self):
213         board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
214         actions.AllowChessMove(
215             set([BITS.RED, BITS.BLUE]), chesspiece="CASTLE"
216         ).perform_action(board, None)
217         self.assertEqual(board.player.movement_mode, MOVES.CASTLE)