Пример #1
0
class TUITest(TestCase):
    def setUp(self):
        self.screen = FakeScreen()
        curses_module = FakeCurses(screen=self.screen)
        self.subject = TUI(curses_module=curses_module)

    def test_initial_board_state(self):
        self.simulate_game([])

        expected_snapshot = ['.....',
                             '.....',
                             '.....',
                             '.....',
                             '.....']

        self.assertEqual(self.screen.get_snapshot(), expected_snapshot)

    def test_reveal_single_numbered_cell(self):
        self.simulate_game([curses.KEY_RIGHT, ' '])
        expected_snapshot = ['.2...',
                             '.....',
                             '.....',
                             '.....',
                             '.....']
        self.assert_equal_snapshots(self.screen.get_snapshot(), expected_snapshot)

    def test_reveal_expanding_zero_cell(self):
        self.simulate_game([curses.KEY_RIGHT, curses.KEY_RIGHT, curses.KEY_RIGHT, curses.KEY_RIGHT, ' '])
        expected_snapshot = ['..1  ',
                             '..21 ',
                             '...21',
                             '.....',
                             '.....']
        self.assert_equal_snapshots(self.screen.get_snapshot(), expected_snapshot)

    # Private
    def assert_equal_snapshots(self, snapshot, expected_snapshot):
        self.assertEqual(self.screen.get_snapshot(),
                         expected_snapshot,
                         "\n\nExpected: \n\n{}\n\nBut got this instead:\n\n{}".format("\n".join(expected_snapshot),
                                                                                      "\n".join(snapshot)))

    def simulate_game(self, commands):
        self.screen.simulate_commands(commands)

        minefield_repository = InMemoryMinefieldRepository()
        turn_repository = InMemoryTurnRepository()
        mine_planter = LazyBeeMinePlanter()
        self.game = Game(minefield_repository=minefield_repository,
                         turn_repository=turn_repository,
                         mine_planter=mine_planter)

        self.game.start_new_game(row_count=5,
                                 column_count=5,
                                 observer=self.subject)
Пример #2
0
class TestGame(TestCase):
    def setUp(self):
        minefield_repository = InMemoryMinefieldRepository()
        turn_repository = InMemoryTurnRepository()
        self.subject = Game(minefield_repository=minefield_repository,
                            turn_repository=turn_repository,
                            mine_planter=LazyBeeMinePlanter())

    def test_play_with_invalid_row_count(self):
        assert_invalid_board_parameters_should_raise_exception(create_board=self.subject.start_new_game,
                                                               row_count=4,
                                                               column_count=5,
                                                               expected_minimum_row_count=5,
                                                               expected_minimum_column_count=5,
                                                               test_case=self)

    def test_play_with_invalid_column_count(self):
        assert_invalid_board_parameters_should_raise_exception(create_board=self.subject.start_new_game,
                                                               row_count=5,
                                                               column_count=4,
                                                               expected_minimum_row_count=5,
                                                               expected_minimum_column_count=5,
                                                               test_case=self)

    def test_play_with_valid_dimensions_should_notify_observer_with_board(self):
        spy = Mock(GameObserver)
        self.subject.start_new_game(row_count=5, column_count=5, observer=spy)

        board = spy.game_did_create_board.call_args[1]['board']
        expected_board = Board(row_count=5, column_count=5)

        assert_boards_equal(board=board, expected_board=expected_board, test_case=self)

    def test_play_with_valid_dimensions_should_notify_observer_with_board_snapshot(self):
        spy = Mock(GameObserver)
        self.subject.start_new_game(row_count=5, column_count=5, observer=spy)

        board_snapshot = spy.game_did_create_board.call_args[1]['board_snapshot']

        expected_board_snapshot = [
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
        ]

        assert_board_snapshots_equal(board_snapshot=board_snapshot,
                                     expected_board_snapshot=expected_board_snapshot,
                                     test_case=self)

    def test_play_with_valid_dimensions_should_notify_observer_with_create_minefield(self):
        spy = Mock(GameObserver)
        self.subject.start_new_game(row_count=5, column_count=5, observer=spy)

        create_minefield = spy.game_did_create_board.call_args[1]['create_minefield']

        create_minefield(row_index=0, column_index=4)

        call_args = spy.game_did_create_minefield.call_args[1]
        board_snapshot = call_args['board_snapshot']

        expected_board_snapshot = [
            [CellType.Unknown, CellType.Unknown, CellType.One, CellType.Zero, CellType.Zero],
            [CellType.Unknown, CellType.Unknown, CellType.Two, CellType.One, CellType.Zero],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Two, CellType.One],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
        ]
        assert_board_snapshots_equal(board_snapshot=board_snapshot,
                                     expected_board_snapshot=expected_board_snapshot,
                                     test_case=self)

    def test_play_with_valid_dimensions_should_notify_observer_with_game_state(self):
        spy = Mock(GameObserver)
        self.subject.start_new_game(row_count=5, column_count=5, observer=spy)

        create_minefield = spy.game_did_create_board.call_args[1]['create_minefield']

        create_minefield(row_index=0, column_index=4)

        call_args = spy.game_did_create_minefield.call_args[1]
        game_state = call_args['game_state']
        self.assertEqual(game_state, GameState.Started)

    def test_play_with_valid_dimensions_should_notify_observer_with_board_snapshot_after_minefield_creation(self):
        first_turn = RawTurn(action=TurnAction.RevealCell, coordinate=Coordinate(row_index=0, column_index=4))

        board_snapshot = self.simulate_start_game(row_count=5, column_count=5, turns=[first_turn])

        expected_board_snapshot = [
            [CellType.Unknown, CellType.Unknown, CellType.One, CellType.Zero, CellType.Zero],
            [CellType.Unknown, CellType.Unknown, CellType.Two, CellType.One, CellType.Zero],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Two, CellType.One],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
        ]
        assert_board_snapshots_equal(board_snapshot=board_snapshot,
                                     expected_board_snapshot=expected_board_snapshot,
                                     test_case=self)

    def test_play_with_valid_dimensions_should_notify_observer_with_game_state_started_after_second_turn(self):
        spy = Mock(GameObserver)
        self.subject.start_new_game(row_count=5, column_count=5, observer=spy)

        create_minefield = spy.game_did_create_board.call_args[1]['create_minefield']

        create_minefield(row_index=0, column_index=4)

        call_args = spy.game_did_create_minefield.call_args[1]

        reveal_cell = call_args['reveal_cell']
        reveal_cell(row_index=0, column_index=1)

        call_args = spy.game_did_take_turn.call_args[1]
        game_state = call_args['game_state']

        self.assertEqual(game_state, GameState.Started)

    def test_play_with_valid_dimensions_should_notify_observer_with_game_state_started_after_second_turn_reveals_mine(
            self):
        spy = Mock(GameObserver)
        self.subject.start_new_game(row_count=5, column_count=5, observer=spy)

        create_minefield = spy.game_did_create_board.call_args[1]['create_minefield']

        create_minefield(row_index=0, column_index=4)

        call_args = spy.game_did_create_minefield.call_args[1]

        reveal_cell = call_args['reveal_cell']
        reveal_cell(row_index=0, column_index=0)

        call_args = spy.game_did_take_turn.call_args[1]
        game_state = call_args['game_state']

        self.assertEqual(game_state, GameState.Lost)

    def test_play_with_valid_dimensions_should_notify_observer_with_board_snapshot_after_second_turn(self):
        spy = Mock(GameObserver)
        self.subject.start_new_game(row_count=5, column_count=5, observer=spy)

        create_minefield = spy.game_did_create_board.call_args[1]['create_minefield']

        create_minefield(row_index=0, column_index=4)

        call_args = spy.game_did_create_minefield.call_args[1]

        reveal_cell = call_args['reveal_cell']
        reveal_cell(row_index=0, column_index=1)

        call_args = spy.game_did_take_turn.call_args[1]
        board_snapshot = call_args['board_snapshot']

        expected_board_snapshot = [
            [CellType.Unknown, CellType.Two, CellType.One, CellType.Zero, CellType.Zero],
            [CellType.Unknown, CellType.Unknown, CellType.Two, CellType.One, CellType.Zero],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Two, CellType.One],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
            [CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown, CellType.Unknown],
        ]
        assert_board_snapshots_equal(board_snapshot=board_snapshot,
                                     expected_board_snapshot=expected_board_snapshot,
                                     test_case=self)

    def test_present_start_menu_with_no_minefields_should_notify_observer_with_correct_start_menu_options(self):
        spy = Mock(GameObserver)
        self.subject.present_start_menu(observer=spy)

        keyword_arguments = spy.game_did_present_start_menu.call_args[1]
        menu_options = keyword_arguments['menu_options']
        expected_menu_options = MenuOptions(options=[StartMenuOptionType.StartNewGame, StartMenuOptionType.Quit],
                                            initially_selected_option=StartMenuOptionType.StartNewGame)
        self.assertEqual(menu_options, expected_menu_options)

    def test_present_start_menu_with_no_minefields_should_notify_observer_with_present_create_board_options(self):
        spy = Mock(GameObserver)
        self.subject.present_start_menu(observer=spy)

        keyword_arguments = spy.game_did_present_start_menu.call_args[1]
        present_create_board_options = keyword_arguments['present_create_board_options']
        present_create_board_options()
        keyword_arguments = spy.game_did_present_create_board_options.call_args[1]
        minimum_row_count = keyword_arguments['minimum_row_count']
        minimum_column_count = keyword_arguments['minimum_column_count']

        self.assertEqual(minimum_row_count, 5)
        self.assertEqual(minimum_column_count, 5)

        create_board = keyword_arguments['create_board']
        create_board(row_count=minimum_row_count, column_count=minimum_column_count)

        keyword_arguments = spy.game_did_create_board.call_args[1]

        board = keyword_arguments['board']
        expected_board = Board(row_count=5, column_count=5)

        assert_boards_equal(board=board, expected_board=expected_board, test_case=self)

    # "Private"

    def simulate_start_game(self, row_count: int, column_count: int, turns: [RawTurn]) -> [[CellType]]:
        spy = Mock(GameObserver)
        self.subject.start_new_game(row_count=row_count, column_count=column_count, observer=spy)

        first_turn = turns.pop(0)
        create_minefield = spy.game_did_create_board.call_args[1]['create_minefield']
        create_minefield(row_index=first_turn.coordinate.row_index, column_index=first_turn.coordinate.column_index)
        call_args = spy.game_did_create_minefield.call_args[1]

        for turn in turns:
            reveal_cell = call_args['reveal_cell']
            toggle_flag = call_args['toggle_flag']

            if turn.action == TurnAction.RevealCell:
                reveal_cell(row_index=turn.coordinate.row_index, column_index=turn.coordinate.column_index)
            elif turn.action == TurnAction.ToggleFlag:
                toggle_flag(row_index=turn.coordinate.row_index, column_index=turn.coordinate.column_index)

            call_args = spy.did_take_turn.call_args[1]

        return call_args['board_snapshot']