class LogViewerTest(unittest.TestCase): FILENAME = 'filename' GAME0 = '{"moves": [{"to_move": "player1", "player1_cards": ["AS", "QS", "AH", "9D", "8D", "7H"], "moves_and_responds": ["7H", "TH"], "deck_count": 24, "player2_cards": ["JH", "TH", "QH", "6H", "8C", "TD"], "given_more": []}, {"to_move": "player2", "player1_cards": ["AS", "QC", "AH", "QS", "8D", "9D"], "moves_and_responds": ["6H"], "deck_count": 22, "player2_cards": ["6C", "QH", "6H", "8C", "TD", "JH"], "given_more": ["6C"]}], "ended_at": "2014-10-19T01:41:23.161425", "deck": ["QS", "8D", "AH", "AS", "7H", "9D", "TD", "JH", "QH", "TH", "8C", "6H", "QC", "6C", "JD", "9C", "9S", "KH", "AC", "8H", "KC", "8S", "TC", "7C", "TS", "9H", "6S", "6D", "7D", "JS", "KS", "AD", "KD", "JC", "QD", "7S"], "player2_name": "ENGINE", "result": "1-0", "player1_name": "HUMAN", "started_at": "2014-10-19T01:40:51.473966", "opened_trump": "7S"}' LOG_FILE_CONTENTS = '''\ ####2014-10-19T01:40:51, HUMAN - ENGINE (1-0)#### %s ####2014-11-19T01:40:51, VOVAN - KOLYAN (1-0)#### {"moves": [{"to_move": "player1", "player1_cards": ["AS", "QS", "AH", "9D", "8D", "7H"], "moves_and_responds": ["7H", "TH"], "deck_count": 24, "player2_cards": ["JH", "TH", "QH", "6H", "8C", "TD"], "given_more": []}], "ended_at": "2014-10-19T01:41:23.161425", "deck": ["QS", "8D", "AH", "AS", "7H", "9D", "TD", "JH", "QH", "TH", "8C", "6H", "QC", "7C", "JD", "9C", "9S", "KH", "AC", "8H", "KC", "8S", "TC", "6C", "TS", "9H", "6S", "6D", "7D", "JS", "KS", "AD", "KD", "JC", "QD", "7S"], "player2_name": "KOLYAN", "result": "1-0", "player1_name": "VOVAN", "started_at": "2014-10-19T01:40:51.473966", "opened_trump": "7S"} ''' % GAME0 def setUp(self): self.open_mock = MagicMock(spec=open) self._set_file_contents(self.LOG_FILE_CONTENTS) self.open_patcher = patch( '__builtin__.open', self.open_mock, create=True ) self.open_patcher.start() self.log_viewer = LogViewer(self.FILENAME) self.game0 = json.loads(self.GAME0) def tearDown(self): self.open_patcher.stop() def _set_file_contents(self, contents): self.open_mock.return_value.__enter__.return_value = StringIO(contents) def test_fill_game_index_parsing(self): self.assertEqual(self.log_viewer._game_index, [ { 'prev_end_offset': 0, 'start_offset': 50, 'title': '2014-10-19T01:40:51, HUMAN - ENGINE (1-0)' }, { 'prev_end_offset': 874, 'start_offset': 924, 'title': '2014-11-19T01:40:51, VOVAN - KOLYAN (1-0)' }, ]) def test_io_error_in_fill_game_index_is_invalid_log_format_error(self): self.open_mock.side_effect = IOError with self.assertRaises(InvalidLogFormat): self.log_viewer._fill_game_index() def test_no_games_in_file_is_invalid_log_format_error(self): self._set_file_contents('no games for you') with self.assertRaises(InvalidLogFormat): self.log_viewer._fill_game_index() def test_iterindex_returns_iterator_over_game_index(self): self.assertItemsEqual( self.log_viewer.iterindex(), iter(self.log_viewer._game_index) ) def test_load_game_loads_game_according_to_index(self): self.log_viewer.load_game(0) self.assertEqual(self.log_viewer.player1_name, 'HUMAN') self.log_viewer.load_game(1) self.assertEqual(self.log_viewer.player1_name, 'VOVAN') def test_io_error_in_load_game_is_invalid_log_format_error(self): self.open_mock.side_effect = IOError with self.assertRaises(InvalidLogFormat): self.log_viewer.load_game(0) def test_value_error_in_load_game_is_invalid_log_format_error(self): self._set_file_contents('no games for you') with self.assertRaises(InvalidLogFormat): self.log_viewer.load_game(0) def test_has_game_loaded_property(self): self.assertFalse(self.log_viewer.has_game_loaded) self.log_viewer.load_game(0) self.assertTrue(self.log_viewer.has_game_loaded) def test_get_new_move(self): self.log_viewer.load_game(0) move = self.game0['moves'][0] result = self.log_viewer._get_new_move(move) self.assertItemsEqual(result.keys(), move.keys() + ['event_type']) self.assertEqual(result['event_type'], self.log_viewer.NEW_MOVE) def test_opened_trump_property(self): self.log_viewer.load_game(0) self.assertEqual( self.log_viewer.opened_trump, DurakCard(self.game0['opened_trump']) ) def test_to_game_start(self): self.log_viewer.load_game(0) self.log_viewer._current_move = 666 self.log_viewer._current_table_index = 777 self.log_viewer.to_game_start() self.assertEqual( self.log_viewer._current_move, self.log_viewer.INITIAL_CURRENT_MOVE ) self.assertEqual( self.log_viewer._current_table_index, self.log_viewer.INITIAL_CURRENT_TABLE_INDEX ) def test_to_game_end(self): self.log_viewer.load_game(0) self.log_viewer._current_move = 666 self.log_viewer._current_table_index = 777 self.log_viewer.to_game_end() self.assertEqual( self.log_viewer._current_move, len(self.game0['moves']) ) self.assertEqual( self.log_viewer._current_table_index, self.log_viewer.INITIAL_CURRENT_TABLE_INDEX + 1 ) def test_player1_name_property(self): self.log_viewer.load_game(0) self.assertEqual( self.log_viewer.player1_name, self.game0['player1_name'] ) def test_player2_name_property(self): self.log_viewer.load_game(0) self.assertEqual( self.log_viewer.player2_name, self.game0['player2_name'] ) def test_get_opposite_player(self): self.assertEqual( self.log_viewer._get_opposite_player(self.log_viewer.PLAYER1), self.log_viewer.PLAYER2 ) self.assertEqual( self.log_viewer._get_opposite_player(self.log_viewer.PLAYER2), self.log_viewer.PLAYER1 ) def test_to_card_set(self): self.log_viewer.load_game(0) cards = ['AS', 'QS', 'AH', '9D', '8D', '7H'] result = self.log_viewer._to_card_set(cards) self.assertTrue(isinstance(result, CardSet)) self.assertItemsEqual(result, map(DurakCard, cards)) self.assertEqual(result._trump, DurakCard(self.game0['opened_trump'])) def test_has_next(self): self.log_viewer.load_game(0) self.assertTrue(self.log_viewer.has_next) self.log_viewer._current_move = 1 self.log_viewer._current_table_index = 1 self.assertTrue(self.log_viewer.has_next) self.log_viewer._current_table_index = 2 self.assertFalse(self.log_viewer.has_next) self.log_viewer._current_move = 3 self.log_viewer._current_table_index = ( self.log_viewer.INITIAL_CURRENT_TABLE_INDEX ) self.assertFalse(self.log_viewer.has_next) def test_has_prev(self): self.log_viewer._current_move = 666 self.log_viewer._current_table_index = 777 self.assertTrue(self.log_viewer.has_prev) self.log_viewer._current_move = self.log_viewer.INITIAL_CURRENT_MOVE self.assertTrue(self.log_viewer.has_prev) self.log_viewer._current_table_index = ( self.log_viewer.INITIAL_CURRENT_TABLE_INDEX ) self.assertFalse(self.log_viewer.has_prev) def test_get_next_and_get_prev(self): # проверяю оба метода в одном тесте, чтобы протестировать в условиях, # приближенных к реальным, а не городить моки EXPECTED_EVENTS = [ { 'to_move': self.log_viewer.PLAYER1, 'event_type': self.log_viewer.NEW_MOVE, 'moves_and_responds': [DurakCard('7H'), DurakCard('TH')], 'deck_count': 24, 'given_more': [], 'player2_cards': set(map(DurakCard, ( '6H', '8C', 'JH', 'TH', 'QH', 'TD' ))), 'player1_cards': set(map(DurakCard, ( 'QS', 'AH', '9D', '8D', '7H', 'AS' ))), }, { 'to_move': self.log_viewer.PLAYER1, 'event_type': self.log_viewer.MOVE, 'card': DurakCard('7H'), }, { 'to_move': self.log_viewer.PLAYER2, 'event_type': self.log_viewer.RESPOND, 'card': DurakCard('TH'), }, { 'to_move': self.log_viewer.PLAYER2, 'event_type': self.log_viewer.NEW_MOVE, 'moves_and_responds': [DurakCard('6H')], 'deck_count': 22, 'given_more': [DurakCard('6C')], 'player2_cards': set(map(DurakCard, ( '6H', '8C', 'JH', '6C', 'QH', 'TD' ))), 'player1_cards': set(map(DurakCard, ( 'QS', 'AH', '9D', '8D', 'QC', 'AS' ))), }, { 'to_move': self.log_viewer.PLAYER2, 'event_type': self.log_viewer.MOVE, 'card': DurakCard('6H'), }, { 'to_move': self.log_viewer.PLAYER2, 'event_type': self.log_viewer.GIVE_MORE, 'card': DurakCard('6C'), }, ] self.log_viewer.load_game(0) expected = iter(EXPECTED_EVENTS) while self.log_viewer.has_next: log_event = self.log_viewer.get_next() self.assertEqual(log_event, next(expected)) first_event = EXPECTED_EVENTS.pop(0) EXPECTED_EVENTS[2] = first_event expected = iter(reversed(EXPECTED_EVENTS)) while self.log_viewer.has_prev: log_event = self.log_viewer.get_prev() self.assertEqual(log_event, next(expected))