"Test InteractiveConsole and InteractiveInterpreter from code module"
import sys
import traceback
import unittest
from textwrap import dedent
from contextlib import ExitStack
from unittest import mock
from test.support import force_not_colorized_test_class
from test.support import import_helper

code = import_helper.import_module('code')


class MockSys:

    def mock_sys(self):
        "Mock system environment for InteractiveConsole"
        # use exit stack to match patch context managers to addCleanup
        stack = ExitStack()
        self.addCleanup(stack.close)
        self.infunc = stack.enter_context(mock.patch('code.input',
                                          create=True))
        self.stdout = stack.enter_context(mock.patch('code.sys.stdout'))
        self.stderr = stack.enter_context(mock.patch('code.sys.stderr'))
        prepatch = mock.patch('code.sys', wraps=code.sys, spec=code.sys)
        self.sysmod = stack.enter_context(prepatch)
        if sys.excepthook is sys.__excepthook__:
            self.sysmod.excepthook = self.sysmod.__excepthook__
        del self.sysmod.ps1
        del self.sysmod.ps2


@force_not_colorized_test_class
class TestInteractiveConsole(unittest.TestCase, MockSys):
    maxDiff = None

    def setUp(self):
        self.console = code.InteractiveConsole()
        self.mock_sys()

    def test_ps1(self):
        self.infunc.side_effect = [
            "import code",
            "code.sys.ps1",
            EOFError('Finished')
        ]
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stdout.method_calls)
        self.assertIn('>>> ', output)
        self.assertNotHasAttr(self.sysmod, 'ps1')

        self.infunc.side_effect = [
            "import code",
            "code.sys.ps1",
            EOFError('Finished')
        ]
        self.sysmod.ps1 = 'custom1> '
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stdout.method_calls)
        self.assertIn('custom1> ', output)
        self.assertEqual(self.sysmod.ps1, 'custom1> ')

    def test_ps2(self):
        self.infunc.side_effect = [
            "import code",
            "code.sys.ps2",
            EOFError('Finished')
        ]
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stdout.method_calls)
        self.assertIn('... ', output)
        self.assertNotHasAttr(self.sysmod, 'ps2')

        self.infunc.side_effect = [
            "import code",
            "code.sys.ps2",
            EOFError('Finished')
        ]
        self.sysmod.ps2 = 'custom2> '
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stdout.method_calls)
        self.assertIn('custom2> ', output)
        self.assertEqual(self.sysmod.ps2, 'custom2> ')

    def test_console_stderr(self):
        self.infunc.side_effect = ["'antioch'", "", EOFError('Finished')]
        self.console.interact()
        for call in list(self.stdout.method_calls):
            if 'antioch' in ''.join(call[1]):
                break
        else:
            raise AssertionError("no console stdout")

    def test_syntax_error(self):
        self.infunc.side_effect = ["def f():",
                                   "    x = ?",
                                   "",
                                    EOFError('Finished')]
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stderr.method_calls)
        output = output[output.index('(InteractiveConsole)'):]
        output = output[:output.index('\nnow exiting')]
        self.assertEqual(output.splitlines()[1:], [
            '  File "<console>", line 2',
            '    x = ?',
            '        ^',
            'SyntaxError: invalid syntax'])
        self.assertIs(self.sysmod.last_type, SyntaxError)
        self.assertIs(type(self.sysmod.last_value), SyntaxError)
        self.assertIsNone(self.sysmod.last_traceback)
        self.assertIsNone(self.sysmod.last_value.__traceback__)
        self.assertIs(self.sysmod.last_exc, self.sysmod.last_value)

    def test_indentation_error(self):
        self.infunc.side_effect = ["  1", EOFError('Finished')]
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stderr.method_calls)
        output = output[output.index('(InteractiveConsole)'):]
        output = output[:output.index('\nnow exiting')]
        self.assertEqual(output.splitlines()[1:], [
            '  File "<console>", line 1',
            '    1',
            'IndentationError: unexpected indent'])
        self.assertIs(self.sysmod.last_type, IndentationError)
        self.assertIs(type(self.sysmod.last_value), IndentationError)
        self.assertIsNone(self.sysmod.last_traceback)
        self.assertIsNone(self.sysmod.last_value.__traceback__)
        self.assertIs(self.sysmod.last_exc, self.sysmod.last_value)

    def test_unicode_error(self):
        self.infunc.side_effect = ["'\ud800'", EOFError('Finished')]
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stderr.method_calls)
        output = output[output.index('(InteractiveConsole)'):]
        output = output[output.index('\n') + 1:]
        self.assertStartsWith(output, 'UnicodeEncodeError: ')
        self.assertIs(self.sysmod.last_type, UnicodeEncodeError)
        self.assertIs(type(self.sysmod.last_value), UnicodeEncodeError)
        self.assertIsNone(self.sysmod.last_traceback)
        self.assertIsNone(self.sysmod.last_value.__traceback__)
        self.assertIs(self.sysmod.last_exc, self.sysmod.last_value)

    def test_sysexcepthook(self):
        self.infunc.side_effect = ["def f():",
                                   "    raise ValueError('BOOM!')",
                                   "",
                                   "f()",
                                    EOFError('Finished')]
        hook = mock.Mock()
        self.sysmod.excepthook = hook
        self.console.interact()
        hook.assert_called()
        hook.assert_called_with(self.sysmod.last_type,
                                self.sysmod.last_value,
                                self.sysmod.last_traceback)
        self.assertIs(self.sysmod.last_type, ValueError)
        self.assertIs(type(self.sysmod.last_value), ValueError)
        self.assertIs(self.sysmod.last_traceback, self.sysmod.last_value.__traceback__)
        self.assertIs(self.sysmod.last_exc, self.sysmod.last_value)
        self.assertEqual(traceback.format_exception(self.sysmod.last_exc), [
            'Traceback (most recent call last):\n',
            '  File "<console>", line 1, in <module>\n',
            '  File "<console>", line 2, in f\n',
            'ValueError: BOOM!\n'])

    def test_sysexcepthook_syntax_error(self):
        self.infunc.side_effect = ["def f():",
                                   "    x = ?",
                                   "",
                                    EOFError('Finished')]
        hook = mock.Mock()
        self.sysmod.excepthook = hook
        self.console.interact()
        hook.assert_called()
        hook.assert_called_with(self.sysmod.last_type,
                                self.sysmod.last_value,
                                self.sysmod.last_traceback)
        self.assertIs(self.sysmod.last_type, SyntaxError)
        self.assertIs(type(self.sysmod.last_value), SyntaxError)
        self.assertIsNone(self.sysmod.last_traceback)
        self.assertIsNone(self.sysmod.last_value.__traceback__)
        self.assertIs(self.sysmod.last_exc, self.sysmod.last_value)
        self.assertEqual(traceback.format_exception(self.sysmod.last_exc), [
            '  File "<console>", line 2\n',
            '    x = ?\n',
            '        ^\n',
            'SyntaxError: invalid syntax\n'])

    def test_sysexcepthook_indentation_error(self):
        self.infunc.side_effect = ["  1", EOFError('Finished')]
        hook = mock.Mock()
        self.sysmod.excepthook = hook
        self.console.interact()
        hook.assert_called()
        hook.assert_called_with(self.sysmod.last_type,
                                self.sysmod.last_value,
                                self.sysmod.last_traceback)
        self.assertIs(self.sysmod.last_type, IndentationError)
        self.assertIs(type(self.sysmod.last_value), IndentationError)
        self.assertIsNone(self.sysmod.last_traceback)
        self.assertIsNone(self.sysmod.last_value.__traceback__)
        self.assertIs(self.sysmod.last_exc, self.sysmod.last_value)
        self.assertEqual(traceback.format_exception(self.sysmod.last_exc), [
            '  File "<console>", line 1\n',
            '    1\n',
            'IndentationError: unexpected indent\n'])

    def test_sysexcepthook_crashing_doesnt_close_repl(self):
        self.infunc.side_effect = ["1/0", "a = 123", "print(a)", EOFError('Finished')]
        self.sysmod.excepthook = 1
        self.console.interact()
        self.assertEqual(['write', ('123', ), {}], self.stdout.method_calls[0])
        error = "".join(call.args[0] for call in self.stderr.method_calls if call[0] == 'write')
        self.assertIn("Error in sys.excepthook:", error)
        self.assertEqual(error.count("'int' object is not callable"), 1)
        self.assertIn("Original exception was:", error)
        self.assertIn("division by zero", error)

    def test_sysexcepthook_raising_BaseException(self):
        self.infunc.side_effect = ["1/0", "a = 123", "print(a)", EOFError('Finished')]
        s = "not so fast"
        def raise_base(*args, **kwargs):
            raise BaseException(s)
        self.sysmod.excepthook = raise_base
        self.console.interact()
        self.assertEqual(['write', ('123', ), {}], self.stdout.method_calls[0])
        error = "".join(call.args[0] for call in self.stderr.method_calls if call[0] == 'write')
        self.assertIn("Error in sys.excepthook:", error)
        self.assertEqual(error.count("not so fast"), 1)
        self.assertIn("Original exception was:", error)
        self.assertIn("division by zero", error)

    def test_sysexcepthook_raising_SystemExit_gets_through(self):
        self.infunc.side_effect = ["1/0"]
        def raise_base(*args, **kwargs):
            raise SystemExit
        self.sysmod.excepthook = raise_base
        with self.assertRaises(SystemExit):
            self.console.interact()

    def test_banner(self):
        # with banner
        self.infunc.side_effect = EOFError('Finished')
        self.console.interact(banner='Foo')
        self.assertEqual(len(self.stderr.method_calls), 3)
        banner_call = self.stderr.method_calls[0]
        self.assertEqual(banner_call, ['write', ('Foo\n',), {}])

        # no banner
        self.stderr.reset_mock()
        self.infunc.side_effect = EOFError('Finished')
        self.console.interact(banner='')
        self.assertEqual(len(self.stderr.method_calls), 2)

    def test_exit_msg(self):
        # default exit message
        self.infunc.side_effect = EOFError('Finished')
        self.console.interact(banner='')
        self.assertEqual(len(self.stderr.method_calls), 2)
        err_msg = self.stderr.method_calls[1]
        expected = 'now exiting InteractiveConsole...\n'
        self.assertEqual(err_msg, ['write', (expected,), {}])

        # no exit message
        self.stderr.reset_mock()
        self.infunc.side_effect = EOFError('Finished')
        self.console.interact(banner='', exitmsg='')
        self.assertEqual(len(self.stderr.method_calls), 1)

        # custom exit message
        self.stderr.reset_mock()
        message = (
            'bye! \N{GREEK SMALL LETTER ZETA}\N{CYRILLIC SMALL LETTER ZHE}'
            )
        self.infunc.side_effect = EOFError('Finished')
        self.console.interact(banner='', exitmsg=message)
        self.assertEqual(len(self.stderr.method_calls), 2)
        err_msg = self.stderr.method_calls[1]
        expected = message + '\n'
        self.assertEqual(err_msg, ['write', (expected,), {}])


    def test_cause_tb(self):
        self.infunc.side_effect = ["raise ValueError('') from AttributeError",
                                    EOFError('Finished')]
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stderr.method_calls)
        expected = dedent("""
        AttributeError

        The above exception was the direct cause of the following exception:

        Traceback (most recent call last):
          File "<console>", line 1, in <module>
        ValueError
        """)
        self.assertIn(expected, output)
        self.assertIs(self.sysmod.last_type, ValueError)
        self.assertIs(type(self.sysmod.last_value), ValueError)
        self.assertIs(self.sysmod.last_traceback, self.sysmod.last_value.__traceback__)
        self.assertIsNotNone(self.sysmod.last_traceback)
        self.assertIs(self.sysmod.last_exc, self.sysmod.last_value)

    def test_context_tb(self):
        self.infunc.side_effect = ["try: ham\nexcept: eggs\n",
                                    EOFError('Finished')]
        self.console.interact()
        output = ''.join(''.join(call[1]) for call in self.stderr.method_calls)
        expected = dedent("""
        Traceback (most recent call last):
          File "<console>", line 1, in <module>
        NameError: name 'ham' is not defined

        During handling of the above exception, another exception occurred:

        Traceback (most recent call last):
          File "<console>", line 2, in <module>
        NameError: name 'eggs' is not defined
        """)
        self.assertIn(expected, output)
        self.assertIs(self.sysmod.last_type, NameError)
        self.assertIs(type(self.sysmod.last_value), NameError)
        self.assertIs(self.sysmod.last_traceback, self.sysmod.last_value.__traceback__)
        self.assertIsNotNone(self.sysmod.last_traceback)
        self.assertIs(self.sysmod.last_exc, self.sysmod.last_value)


class TestInteractiveConsoleLocalExit(unittest.TestCase, MockSys):

    def setUp(self):
        self.console = code.InteractiveConsole(local_exit=True)
        self.mock_sys()

    @unittest.skipIf(sys.flags.no_site, "exit() isn't defined unless there's a site module")
    def test_exit(self):
        # default exit message
        self.infunc.side_effect = ["exit()"]
        self.console.interact(banner='')
        self.assertEqual(len(self.stderr.method_calls), 2)
        err_msg = self.stderr.method_calls[1]
        expected = 'now exiting InteractiveConsole...\n'
        self.assertEqual(err_msg, ['write', (expected,), {}])


if __name__ == "__main__":
    unittest.main()
