|
1 | 1 | import itertools |
2 | 2 | import os |
3 | 3 | import rlcompleter |
4 | | -import sys |
5 | 4 | import tempfile |
6 | 5 | import unittest |
7 | 6 | from code import InteractiveConsole |
8 | 7 | from functools import partial |
9 | 8 | from unittest import TestCase |
10 | 9 | from unittest.mock import MagicMock, patch |
| 10 | +from textwrap import dedent |
| 11 | +import contextlib |
| 12 | +import io |
11 | 13 |
|
12 | 14 | from test.support import requires |
13 | 15 | from test.support.import_helper import import_module |
| 16 | +from test.support import force_not_colorized |
14 | 17 |
|
15 | 18 | # Optionally test pyrepl. This currently requires that the |
16 | 19 | # 'curses' resource be given on the regrtest command line using the -u |
@@ -1002,5 +1005,92 @@ def test_up_arrow_after_ctrl_r(self): |
1002 | 1005 | self.assert_screen_equals(reader, "") |
1003 | 1006 |
|
1004 | 1007 |
|
| 1008 | +class TestSimpleInteract(unittest.TestCase): |
| 1009 | + def test_multiple_statements(self): |
| 1010 | + namespace = {} |
| 1011 | + code = dedent("""\ |
| 1012 | + class A: |
| 1013 | + def foo(self): |
| 1014 | +
|
| 1015 | +
|
| 1016 | + pass |
| 1017 | +
|
| 1018 | + class B: |
| 1019 | + def bar(self): |
| 1020 | + pass |
| 1021 | +
|
| 1022 | + a = 1 |
| 1023 | + a |
| 1024 | + """) |
| 1025 | + console = InteractiveColoredConsole(namespace, filename="<stdin>") |
| 1026 | + with ( |
| 1027 | + patch.object(InteractiveColoredConsole, "showsyntaxerror") as showsyntaxerror, |
| 1028 | + patch.object(InteractiveColoredConsole, "runsource", wraps=console.runsource) as runsource, |
| 1029 | + ): |
| 1030 | + more = console.push(code, filename="<stdin>", _symbol="single") # type: ignore[call-arg] |
| 1031 | + self.assertFalse(more) |
| 1032 | + showsyntaxerror.assert_not_called() |
| 1033 | + |
| 1034 | + |
| 1035 | + def test_multiple_statements_output(self): |
| 1036 | + namespace = {} |
| 1037 | + code = dedent("""\ |
| 1038 | + b = 1 |
| 1039 | + b |
| 1040 | + a = 1 |
| 1041 | + a |
| 1042 | + """) |
| 1043 | + console = InteractiveColoredConsole(namespace, filename="<stdin>") |
| 1044 | + f = io.StringIO() |
| 1045 | + with contextlib.redirect_stdout(f): |
| 1046 | + more = console.push(code, filename="<stdin>", _symbol="single") # type: ignore[call-arg] |
| 1047 | + self.assertFalse(more) |
| 1048 | + self.assertEqual(f.getvalue(), "1\n") |
| 1049 | + |
| 1050 | + def test_empty(self): |
| 1051 | + namespace = {} |
| 1052 | + code = "" |
| 1053 | + console = InteractiveColoredConsole(namespace, filename="<stdin>") |
| 1054 | + f = io.StringIO() |
| 1055 | + with contextlib.redirect_stdout(f): |
| 1056 | + more = console.push(code, filename="<stdin>", _symbol="single") # type: ignore[call-arg] |
| 1057 | + self.assertFalse(more) |
| 1058 | + self.assertEqual(f.getvalue(), "") |
| 1059 | + |
| 1060 | + def test_runsource_compiles_and_runs_code(self): |
| 1061 | + console = InteractiveColoredConsole() |
| 1062 | + source = "print('Hello, world!')" |
| 1063 | + with patch.object(console, "runcode") as mock_runcode: |
| 1064 | + console.runsource(source) |
| 1065 | + mock_runcode.assert_called_once() |
| 1066 | + |
| 1067 | + def test_runsource_returns_false_for_successful_compilation(self): |
| 1068 | + console = InteractiveColoredConsole() |
| 1069 | + source = "print('Hello, world!')" |
| 1070 | + result = console.runsource(source) |
| 1071 | + self.assertFalse(result) |
| 1072 | + |
| 1073 | + @force_not_colorized |
| 1074 | + def test_runsource_returns_false_for_failed_compilation(self): |
| 1075 | + console = InteractiveColoredConsole() |
| 1076 | + source = "print('Hello, world!'" |
| 1077 | + f = io.StringIO() |
| 1078 | + with contextlib.redirect_stderr(f): |
| 1079 | + result = console.runsource(source) |
| 1080 | + self.assertFalse(result) |
| 1081 | + self.assertIn('SyntaxError', f.getvalue()) |
| 1082 | + |
| 1083 | + def test_runsource_shows_syntax_error_for_failed_compilation(self): |
| 1084 | + console = InteractiveColoredConsole() |
| 1085 | + source = "print('Hello, world!'" |
| 1086 | + with patch.object(console, "showsyntaxerror") as mock_showsyntaxerror: |
| 1087 | + console.runsource(source) |
| 1088 | + mock_showsyntaxerror.assert_called_once() |
| 1089 | + |
| 1090 | + |
| 1091 | +if __name__ == '__main__': |
| 1092 | + unittest.main() |
| 1093 | + |
| 1094 | + |
1005 | 1095 | if __name__ == '__main__': |
1006 | 1096 | unittest.main() |
0 commit comments