aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_pyrepl/test_reader.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_pyrepl/test_reader.py')
-rw-r--r--Lib/test/test_pyrepl/test_reader.py149
1 files changed, 147 insertions, 2 deletions
diff --git a/Lib/test/test_pyrepl/test_reader.py b/Lib/test/test_pyrepl/test_reader.py
index 109cb603ae8..8d7fcf538d2 100644
--- a/Lib/test/test_pyrepl/test_reader.py
+++ b/Lib/test/test_pyrepl/test_reader.py
@@ -1,14 +1,21 @@
import itertools
import functools
import rlcompleter
+from textwrap import dedent
from unittest import TestCase
from unittest.mock import MagicMock
from .support import handle_all_events, handle_events_narrow_console
from .support import ScreenEqualMixin, code_to_events
-from .support import prepare_reader, prepare_console
+from .support import prepare_console, reader_force_colors
+from .support import reader_no_colors as prepare_reader
from _pyrepl.console import Event
from _pyrepl.reader import Reader
+from _colorize import theme
+
+
+overrides = {"RESET": "z", "SOFT_KEYWORD": "K"}
+colors = {overrides.get(k, k[0].lower()): v for k, v in theme.items()}
class TestReader(ScreenEqualMixin, TestCase):
@@ -123,8 +130,9 @@ class TestReader(ScreenEqualMixin, TestCase):
def test_control_characters(self):
code = 'flag = "🏳️‍🌈"'
events = code_to_events(code)
- reader, _ = handle_all_events(events)
+ reader, _ = handle_all_events(events, prepare_reader=reader_force_colors)
self.assert_screen_equal(reader, 'flag = "🏳️\\u200d🌈"', clean=True)
+ self.assert_screen_equal(reader, 'flag {o}={z} {s}"🏳️\\u200d🌈"{z}'.format(**colors))
def test_setpos_from_xy_multiple_lines(self):
# fmt: off
@@ -355,3 +363,140 @@ class TestReader(ScreenEqualMixin, TestCase):
reader, _ = handle_all_events(events)
reader.setpos_from_xy(8, 0)
self.assertEqual(reader.pos, 7)
+
+ def test_syntax_highlighting_basic(self):
+ code = dedent(
+ """\
+ import re, sys
+ def funct(case: str = sys.platform) -> None:
+ match = re.search(
+ "(me)",
+ '''
+ Come on
+ Come on now
+ You know that it's time to emerge
+ ''',
+ )
+ match case:
+ case "emscripten": print("on the web")
+ case "ios" | "android": print("on the phone")
+ case _: print('arms around', match.group(1))
+ """
+ )
+ expected = dedent(
+ """\
+ {k}import{z} re{o},{z} sys
+ {a}{k}def{z} {d}funct{z}{o}({z}case{o}:{z} {b}str{z} {o}={z} sys{o}.{z}platform{o}){z} {o}->{z} {k}None{z}{o}:{z}
+ match {o}={z} re{o}.{z}search{o}({z}
+ {s}"(me)"{z}{o},{z}
+ {s}'''{z}
+ {s} Come on{z}
+ {s} Come on now{z}
+ {s} You know that it's time to emerge{z}
+ {s} '''{z}{o},{z}
+ {o}){z}
+ {K}match{z} case{o}:{z}
+ {K}case{z} {s}"emscripten"{z}{o}:{z} {b}print{z}{o}({z}{s}"on the web"{z}{o}){z}
+ {K}case{z} {s}"ios"{z} {o}|{z} {s}"android"{z}{o}:{z} {b}print{z}{o}({z}{s}"on the phone"{z}{o}){z}
+ {K}case{z} {K}_{z}{o}:{z} {b}print{z}{o}({z}{s}'arms around'{z}{o},{z} match{o}.{z}group{o}({z}{n}1{z}{o}){z}{o}){z}
+ """
+ )
+ expected_sync = expected.format(a="", **colors)
+ events = code_to_events(code)
+ reader, _ = handle_all_events(events, prepare_reader=reader_force_colors)
+ self.assert_screen_equal(reader, code, clean=True)
+ self.assert_screen_equal(reader, expected_sync)
+ self.assertEqual(reader.pos, 2**7 + 2**8)
+ self.assertEqual(reader.cxy, (0, 14))
+
+ async_msg = "{k}async{z} ".format(**colors)
+ expected_async = expected.format(a=async_msg, **colors)
+ more_events = itertools.chain(
+ code_to_events(code),
+ [Event(evt="key", data="up", raw=bytearray(b"\x1bOA"))] * 13,
+ code_to_events("async "),
+ )
+ reader, _ = handle_all_events(more_events, prepare_reader=reader_force_colors)
+ self.assert_screen_equal(reader, expected_async)
+ self.assertEqual(reader.pos, 21)
+ self.assertEqual(reader.cxy, (6, 1))
+
+ def test_syntax_highlighting_incomplete_string_first_line(self):
+ code = dedent(
+ """\
+ def unfinished_function(arg: str = "still typing
+ """
+ )
+ expected = dedent(
+ """\
+ {k}def{z} {d}unfinished_function{z}{o}({z}arg{o}:{z} {b}str{z} {o}={z} {s}"still typing{z}
+ """
+ ).format(**colors)
+ events = code_to_events(code)
+ reader, _ = handle_all_events(events, prepare_reader=reader_force_colors)
+ self.assert_screen_equal(reader, code, clean=True)
+ self.assert_screen_equal(reader, expected)
+
+ def test_syntax_highlighting_incomplete_string_another_line(self):
+ code = dedent(
+ """\
+ def unfinished_function(
+ arg: str = "still typing
+ """
+ )
+ expected = dedent(
+ """\
+ {k}def{z} {d}unfinished_function{z}{o}({z}
+ arg{o}:{z} {b}str{z} {o}={z} {s}"still typing{z}
+ """
+ ).format(**colors)
+ events = code_to_events(code)
+ reader, _ = handle_all_events(events, prepare_reader=reader_force_colors)
+ self.assert_screen_equal(reader, code, clean=True)
+ self.assert_screen_equal(reader, expected)
+
+ def test_syntax_highlighting_incomplete_multiline_string(self):
+ code = dedent(
+ """\
+ def unfinished_function():
+ '''Still writing
+ the docstring
+ """
+ )
+ expected = dedent(
+ """\
+ {k}def{z} {d}unfinished_function{z}{o}({z}{o}){z}{o}:{z}
+ {s}'''Still writing{z}
+ {s} the docstring{z}
+ """
+ ).format(**colors)
+ events = code_to_events(code)
+ reader, _ = handle_all_events(events, prepare_reader=reader_force_colors)
+ self.assert_screen_equal(reader, code, clean=True)
+ self.assert_screen_equal(reader, expected)
+
+ def test_syntax_highlighting_incomplete_fstring(self):
+ code = dedent(
+ """\
+ def unfinished_function():
+ var = f"Single-quote but {
+ 1
+ +
+ 1
+ } multi-line!
+ """
+ )
+ expected = dedent(
+ """\
+ {k}def{z} {d}unfinished_function{z}{o}({z}{o}){z}{o}:{z}
+ var {o}={z} {s}f"{z}{s}Single-quote but {z}{o}{OB}{z}
+ {n}1{z}
+ {o}+{z}
+ {n}1{z}
+ {o}{CB}{z}{s} multi-line!{z}
+ """
+ ).format(OB="{", CB="}", **colors)
+ events = code_to_events(code)
+ reader, _ = handle_all_events(events, prepare_reader=reader_force_colors)
+ self.assert_screen_equal(reader, code, clean=True)
+ self.assert_screen_equal(reader, expected)