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