def test_create_a_game_and_public_interface(self):
        board = Board()
        game = Game(board=board, player_1='X', player_2='O')

        self.assertFalse(game.is_finished())
        self.assertFalse(game.has_winner())
        self.assertFalse(game.is_tied())
        self.assertIsNone(game.get_winner())

        self.assertEqual(game.next_turn(), 'X')

        self.assertEqual(game.board, board)
    def test_game_is_tied(self):
        board = Board([
            ['O', 'X', 'X'],
            ['X', 'O', 'O'],
            ['X', 'O', 'X'],
        ])

        game = Game(board=board, player_1='X', player_2='O')

        self.assertTrue(game.is_finished())
        self.assertFalse(game.has_winner())
        self.assertTrue(game.is_tied())
        self.assertIsNone(game.get_winner())
    def test_check_winner_returns_true_second_diagonal(self):
        board = Board([
            [None, None, 'X'],
            [None, 'X', None],
            ['X', 'O', 'O'],
        ])

        game = Game(board=board, player_1='X', player_2='O')

        self.assertTrue(game.is_finished())
        self.assertTrue(game.has_winner())
        self.assertFalse(game.is_tied())
        self.assertEqual(game.get_winner(), 'X')
    def test_check_winner_returns_false(self):
        board = Board([
            [None, None, None],
            ['X', None, 'O'],
            [None, 'X', None],
        ])

        game = Game(board=board, player_1='X', player_2='O')

        self.assertFalse(game.is_finished())
        self.assertFalse(game.has_winner())
        self.assertFalse(game.is_tied())
        self.assertIsNone(game.get_winner())
    def test_invalid_move_game_over_game_is_tied(self):
        board = Board([
            ['O', 'X', 'X'],
            ['X', 'O', 'O'],
            ['X', 'O', 'X'],
        ])
        game = Game(board=board, player_1='X', player_2='O')

        self.assertTrue(game.is_finished())
        self.assertFalse(game.has_winner())
        self.assertTrue(game.is_tied())
        self.assertIsNone(game.get_winner())

        with self.assertRaises(InvalidMovementException):
            game.move('X', row=0, col=0)
    def test_invalid_move_game_has_winner(self):
        board = Board([
            ['X', None, None],
            ['O', 'X', None],
            [None, 'O', 'X'],
        ])

        game = Game(board=board, player_1='X', player_2='O')

        self.assertTrue(game.is_finished())
        self.assertTrue(game.has_winner())
        self.assertFalse(game.is_tied())
        self.assertEqual(game.get_winner(), 'X')

        self.assertEqual(game.next_turn(), 'X')
        with self.assertRaises(InvalidMovementException):
            game.move('X', row=0, col=2)