def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult: if not self._lines: self.render(console, options) style = console.get_style(self.style) width = self._render_width or console.width height = options.height or console.height x, y = self.offset window_lines = self._lines[y:y + height] if x: def width_view(line: list[Segment]) -> list[Segment]: _, line = Segment.divide(line, [x, x + width]) return line window_lines = [width_view(line) for line in window_lines] missing_lines = len(window_lines) - height if missing_lines: blank_line = [Segment(" " * width, style), Segment.line()] window_lines.extend(blank_line for _ in range(missing_lines)) new_line = Segment.line() for line in window_lines: yield from line yield new_line
def test_text_multiple_segments(legacy_term_mock): buffer = [Segment("Hello, "), Segment("world!")] legacy_windows_render(buffer, legacy_term_mock) assert legacy_term_mock.write_text.call_args_list == [ call("Hello, "), call("world!"), ]
def setup(self): self.line = [ Segment("foo"), Segment("bar"), Segment("egg"), Segment("Where there is a Will"), Segment("There is a way"), ] * 2
def test_segments_renderable(): segments = Segments([Segment("foo")]) assert list(segments.__rich_console__(None, None)) == [Segment("foo")] segments = Segments([Segment("foo")], new_lines=True) assert list(segments.__rich_console__(None, None)) == [ Segment("foo"), Segment.line(), ]
def test_remove_color(): segments = [ Segment("foo", Style(bold=True, color="red")), Segment("bar", None), ] assert list(Segment.remove_color(segments)) == [ Segment("foo", Style(bold=True)), Segment("bar", None), ]
def test_control_move(): assert Control.move(0, 0).segment == Segment("", None, []) control = Control.move(3, 4) print(repr(control.segment)) assert control.segment == Segment( "\x1b[3C\x1b[4B", None, [(ControlType.CURSOR_FORWARD, 3), (ControlType.CURSOR_DOWN, 4)], )
def test_divide_edge_2(): segments = [ Segment("╭─"), Segment("────── Placeholder ───────", ), Segment("─╮", ), ] result = list(Segment.divide(segments, [30, 60])) expected = [segments, []] print(repr(result)) assert result == expected
def test_divide_edge_2(): segments = [ Segment("â•â”€"), Segment("────── Placeholder ───────", ), Segment("─╮", ), ] result = list(Segment.divide(segments, [30, 60])) expected = [segments, []] print(repr(result)) assert result == expected
def test_repr(): assert repr(Segment("foo")) == "Segment('foo', None)" home = (ControlType.HOME, 0) if sys.version_info >= (3, 10): assert (repr(Segment( "foo", None, [home])) == "Segment('foo', None, [(ControlType.HOME, 0)])") else: assert (repr(Segment( "foo", None, [home])) == "Segment('foo', None, [(<ControlType.HOME: 3>, 0)])")
def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult: for y in range(0, 5): for x in range(options.max_width): h = x / options.max_width l = 0.1 + ((y / 5) * 0.7) r, g, b = colorsys.hls_to_rgb(h, l, 1.0) yield Segment( "█", Style(color=Color.from_rgb(r * 255, g * 255, b * 255))) yield Segment.line()
def test_split_and_crop_lines(): assert list( Segment.split_and_crop_lines([Segment("Hello\nWorld!\n"), Segment("foo")], 4) ) == [ [Segment("Hell"), Segment("\n", None)], [Segment("Worl"), Segment("\n", None)], [Segment("foo"), Segment(" ")], ]
def test_set_shape(): assert Segment.set_shape([[Segment("Hello")]], 10) == [[Segment("Hello"), Segment(" ")]] assert Segment.set_shape([[Segment("Hello")]], 10, 2) == [ [Segment("Hello"), Segment(" ")], [Segment(" " * 10)], ]
def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult: for y in range(0, 5): for x in range(options.max_width): h = x / options.max_width l = 0.1 + ((y / 5) * 0.7) r1, g1, b1 = colorsys.hls_to_rgb(h, l, 1.0) r2, g2, b2 = colorsys.hls_to_rgb(h, l + 0.7 / 10, 1.0) bgcolor = Color.from_rgb(r1 * 255, g1 * 255, b1 * 255) color = Color.from_rgb(r2 * 255, g2 * 255, b2 * 255) yield Segment("▄", Style(color=color, bgcolor=bgcolor)) yield Segment.line()
def test_screen_update_class(): screen_update = ScreenUpdate([[Segment("foo")], [Segment("bar")]], 5, 10) assert screen_update.x == 5 assert screen_update.y == 10 console = Console(force_terminal=True) console.begin_capture() console.print(screen_update) result = console.end_capture() print(repr(result)) expected = "\x1b[11;6Hfoo\x1b[12;6Hbar" assert result == expected
def render(self, x: int, y: int, width: int, height: int) -> Iterable[Segment]: move_to = Control.move_to lines = self.lines[:height] new_line = Segment.line() for last, (offset_y, (line, dirty)) in loop_last( enumerate(zip(lines, self._dirty), y) ): if dirty: yield move_to(x, offset_y).segment yield from Segment.adjust_line_length(line, width) if not last: yield new_line self._dirty[:] = [False] * len(self.lines)
def test_rich_console(live_render): options = ConsoleOptions( legacy_windows=False, min_width=10, max_width=20, is_terminal=False, encoding="utf-8", ) rich_console = live_render.__rich_console__(Console(), options) assert [Segment("my string", Style.parse("none"))] == list(rich_console) live_render.style = "red" rich_console = live_render.__rich_console__(Console(), options) assert [Segment("my string", Style.parse("red"))] == list(rich_console)
def test_move_to_column(): print(repr(Control.move_to_column(10, 20).segment)) assert Control.move_to_column(10, 20).segment == Segment( "\x1b[11G\x1b[20B", None, [(ControlType.CURSOR_MOVE_TO_COLUMN, 10), (ControlType.CURSOR_DOWN, 20)], ) assert Control.move_to_column(10, -20).segment == Segment( "\x1b[11G\x1b[20A", None, [(ControlType.CURSOR_MOVE_TO_COLUMN, 10), (ControlType.CURSOR_UP, 20)], )
def __rich_console__(self, console: Console, options: ConsoleOptions) -> Iterable[Segment]: height = console.size.height - 3 for y in range(0, height): for x in range(options.max_width): h = x / options.max_width l = y / (height + 1) r1, g1, b1 = colorsys.hls_to_rgb(h, l, 1.0) r2, g2, b2 = colorsys.hls_to_rgb(h, l + (1 / height / 2), 1.0) bgcolor = Color.from_rgb(r1 * 255, g1 * 255, b1 * 255) color = Color.from_rgb(r2 * 255, g2 * 255, b2 * 255) yield Segment("▄", Style(color=color, bgcolor=bgcolor)) yield Segment.line()
def test_move_to_row(): print(repr(Control.move_to_row(10, 20).segment)) assert Control.move_to_row(10, 20).segment == Segment( "\x1b[12G\x1b[20B", None, [(ControlType.CURSOR_MOVE_TO_ROW, 11), (ControlType.CURSOR_DOWN, 20)], )
def test_control_cursor_single_cell_movement(legacy_term_mock, control_type, method_name): buffer = [Segment("", None, [(control_type, )])] legacy_windows_render(buffer, legacy_term_mock) getattr(legacy_term_mock, method_name).assert_called_once_with()
def test_control_home(legacy_term_mock): buffer = [Segment("", None, [(ControlType.HOME, )])] legacy_windows_render(buffer, legacy_term_mock) legacy_term_mock.move_cursor_to.assert_called_once_with( WindowsCoordinates(0, 0))
def test_control_cursor_move_to(legacy_term_mock): buffer = [Segment("", None, [(ControlType.CURSOR_MOVE_TO, 20, 30)])] legacy_windows_render(buffer, legacy_term_mock) legacy_term_mock.move_cursor_to.assert_called_once_with( WindowsCoordinates(row=29, col=19))
def test_title(): control_segment = Control.title("hello").segment assert control_segment == Segment( "\x1b]0;hello\x07", None, [(ControlType.SET_WINDOW_TITLE, "hello")], )
def test_divide_edge(): segments = [Segment("foo"), Segment("bar"), Segment("baz")] result = list(Segment.divide(segments, [1, 3, 9])) print(result) assert result == [ [Segment("f")], [Segment("oo")], [Segment("bar"), Segment("baz")], ]
def test_text_with_style(legacy_term_mock): text = "Hello, world!" style = Style.parse("black on red") buffer = [Segment(text, style)] legacy_windows_render(buffer, legacy_term_mock) legacy_term_mock.write_styled.assert_called_once_with(text, style)
def __rich_console__(self, console, options): if self.at_end: self.start = len(self) self.start = max(0, min(self.start, len(self) - self.window_size)) for i, line in enumerate(self.lines[self.start:len(self)]): yield RawSegment(line.text) if i < len(self) - 1: yield Segment.line()
def test_rich_console(): renderable = "test renderable" style = Style(color="red") options = ConsoleOptions(min_width=10, max_width=20, is_terminal=False, encoding="utf-8") expected_outputs = [ Segment(renderable, style=style), Segment(" " * (20 - len(renderable)), style=style), Segment("\n", style=None), ] padding_generator = Padding(renderable, style=style).__rich_console__( Console(), options) for output, expected in zip(padding_generator, expected_outputs): assert output == expected
def render(self, x: int, y: int) -> Iterable[Segment]: move_to = Control.move_to new_line = Segment.line() for last, (offset_y, line) in loop_last(enumerate(self.lines, y)): yield move_to(x, offset_y).segment yield from line if not last: yield new_line
def __rich_console__( self, console: Console, options: ConsoleOptions ) -> RenderResult: new_line = Segment.line() for line in self.lines: yield from line yield new_line
def test_control_set_terminal_window_title(legacy_term_mock): buffer = [ Segment("", None, [(ControlType.SET_WINDOW_TITLE, "Hello, world!")]) ] legacy_windows_render(buffer, legacy_term_mock) legacy_term_mock.set_title.assert_called_once_with("Hello, world!")