def test_highlight_words(): test = Text("Do NOT! touch anything!") words = ["NOT", "!"] count = test.highlight_words(words, "red") assert count == 3 assert sorted(test._spans) == [ Span(3, 6, "red"), # NOT Span(6, 7, "red"), # ! Span(22, 23, "red"), # ! ] # regex escape test test = Text("[o|u]aeiou") words = ["[a|e|i]", "[o|u]"] count = test.highlight_words(words, "red") assert count == 1 assert test._spans == [Span(0, 5, "red")] # case sensitive test = Text("AB Ab aB ab") words = ["AB"] count = test.highlight_words(words, "red") assert count == 1 assert test._spans == [Span(0, 2, "red")] test = Text("AB Ab aB ab") count = test.highlight_words(words, "red", case_sensitive=False) assert count == 4
def test_decode(): console = Console(force_terminal=True, legacy_windows=False, color_system="truecolor") console.begin_capture() console.print("Hello") console.print("[b]foo[/b]") console.print("[link http://example.org]bar") console.print("[#ff0000 on color(200)]red") console.print("[color(200) on #ff0000]red") terminal_codes = console.end_capture() decoder = AnsiDecoder() lines = list(decoder.decode(terminal_codes)) expected = [ Text("Hello"), Text("foo", spans=[Span(0, 3, Style.parse("bold"))]), Text("bar", spans=[Span(0, 3, Style.parse("link http://example.org"))]), Text("red", spans=[Span(0, 3, Style.parse("#ff0000 on color(200)"))]), Text("red", spans=[Span(0, 3, Style.parse("color(200) on #ff0000"))]), ] assert lines == expected
def ansify(style: Style, text: Union[Text, str]) -> Text: if isinstance(text, Text): spans = [Span(s.start, s.end, s.style + style) for s in text.spans] return Text(text.plain, spans=spans, style=text.style + style) elif isinstance(text, str): spans = [Span(0, len(text), style)] return Text(text, spans=spans)
def test_render_overlap(): result = render("[green]X[bold]Y[/green]Z[/bold]") assert str(result) == "XYZ" assert result.spans == [ Span(0, 2, "green"), Span(1, 3, "bold"), ]
def test_render_combine(): result = render("[green]X[blue]Y[/blue]Z[/green]") assert str(result) == "XYZ" assert result.spans == [ Span(0, 3, "green"), Span(1, 2, "blue"), ]
def test_split_spans(): test = Text.from_markup("[red]Hello\n[b]World") lines = test.split("\n") assert lines[0].plain == "Hello" assert lines[1].plain == "World" assert lines[0].spans == [Span(0, 5, "red")] assert lines[1].spans == [Span(0, 5, "red"), Span(0, 5, "bold")]
def test_trim_spans(): test = Text("Hello") test._spans[:] = [ Span(0, 3, "red"), Span(3, 6, "green"), Span(6, 9, "blue") ] test._trim_spans() assert test._spans == [Span(0, 3, "red"), Span(3, 5, "green")]
def from_html(text: Union[Text, str], tag: str, **kwargs) -> Text: mark = ProtoStyle() mark.tag = tag mark.xml_attr = kwargs style = mark.convert() if isinstance(text, Text): spans = [Span(s.start, s.end, s.style + style) for s in text.spans] return Text(text.plain, spans=spans, style=text.style + style) elif isinstance(text, str): spans = [Span(0, len(text), mark.convert())] return Text(text, spans=spans)
def test_rich() -> None: color = Color.parse("red") as_text = color.__rich__() print(repr(as_text)) print(repr(as_text.spans)) assert as_text == Text("<color 'red' (standard)⬤ >", spans=[Span(23, 24, Style(color=color))])
def test_highlight_regex(): test = Text("peek-a-boo") count = test.highlight_regex(r"NEVER_MATCH", "red") assert count == 0 assert len(test._spans) == 0 # text: peek-a-boo # indx: 0123456789 count = test.highlight_regex(r"[a|e|o]+", "red") assert count == 3 assert sorted(test._spans) == [ Span(1, 3, "red"), Span(5, 6, "red"), Span(8, 10, "red"), ] test = Text("Ada Lovelace, Alan Turing") count = test.highlight_regex( r"(?P<yellow>[A-Za-z]+)[ ]+(?P<red>[A-Za-z]+)(?P<NEVER_MATCH>NEVER_MATCH)*" ) # The number of matched name should be 2 assert count == 2 assert sorted(test._spans) == [ Span(0, 3, "yellow"), # Ada Span(4, 12, "red"), # Lovelace Span(14, 18, "yellow"), # Alan Span(19, 25, "red"), # Turing ]
def test_plain_property_setter(): test = Text("foo") test.plain = "bar" assert str(test) == "bar" test = Text() test.append("Hello, World", "bold") test.plain = "Hello" assert str(test) == "Hello" assert test._spans == [Span(0, 5, "bold")]
def test_slice(): text = Text.from_markup("[red]foo [bold]bar[/red] baz[/bold]") assert text[0] == Text("f", spans=[Span(0, 1, "red")]) assert text[4] == Text("b", spans=[Span(0, 1, "red"), Span(0, 1, "bold")]) assert text[:3] == Text("foo", spans=[Span(0, 3, "red")]) assert text[:4] == Text("foo ", spans=[Span(0, 4, "red")]) assert text[:5] == Text("foo b", spans=[Span(0, 5, "red"), Span(4, 5, "bold")]) assert text[4:] == Text("bar baz", spans=[Span(0, 3, "red"), Span(0, 7, "bold")]) with pytest.raises(TypeError): text[::-1]
def test_append(): test = Text("foo") test.append("bar") assert str(test) == "foobar" test.append(Text("baz", "bold")) assert str(test) == "foobarbaz" assert test._spans == [Span(6, 9, "bold")] with pytest.raises(ValueError): test.append(Text("foo"), "bar") with pytest.raises(TypeError): test.append(1)
def test_lines_justify(): console = Console() lines1 = Lines([Text("foo", style="b"), Text("test", style="b")]) lines1.justify(console, 10, justify="left") assert lines1._lines == [Text("foo "), Text("test ")] lines1.justify(console, 10, justify="center") assert lines1._lines == [Text(" foo "), Text(" test ")] lines1.justify(console, 10, justify="right") assert lines1._lines == [Text(" foo"), Text(" test")] lines2 = Lines([Text("foo bar", style="b"), Text("test", style="b")]) lines2.justify(console, 7, justify="full") print(repr(lines2._lines[0].spans)) assert lines2._lines == [ Text( "foo bar", spans=[ Span(0, 3, "b"), Span(3, 4, Style.parse("bold")), Span(4, 7, "b") ], ), Text("test"), ]
def test_append_text(): test = Text("foo") test.append_text(Text("bar", style="bold")) assert str(test) == "foobar" assert test._spans == [Span(3, 6, "bold")]
def test_span_right_crop(): assert Span(5, 10, "foo").right_crop(15) == Span(5, 10, "foo") assert Span(5, 10, "foo").right_crop(7) == Span(5, 7, "foo")
def test_join(): test = Text("bar").join([Text("foo", "red"), Text("baz", "blue")]) assert str(test) == "foobarbaz" assert test._spans == [Span(0, 3, "red"), Span(6, 9, "blue")]
def test_render_link(): result = render("[link=foo]FOO[/link]") assert str(result) == "FOO" assert result.spans == [Span(0, 3, "link foo")]
def test_assemble(): text = Text.assemble("foo", ("bar", "bold")) assert str(text) == "foobar" assert text._spans == [Span(3, 6, "bold")]
def test_divide(): lines = Text("foo").divide([]) assert len(lines) == 1 assert lines[0] == Text("foo") text = Text() text.append("foo", "bold") lines = text.divide([1, 2]) assert len(lines) == 3 assert str(lines[0]) == "f" assert str(lines[1]) == "o" assert str(lines[2]) == "o" assert lines[0]._spans == [Span(0, 1, "bold")] assert lines[1]._spans == [Span(0, 1, "bold")] assert lines[2]._spans == [Span(0, 1, "bold")] text = Text() text.append("foo", "red") text.append("bar", "green") text.append("baz", "blue") lines = text.divide([8]) assert len(lines) == 2 assert str(lines[0]) == "foobarba" assert str(lines[1]) == "z" assert lines[0]._spans == [ Span(0, 3, "red"), Span(3, 6, "green"), Span(6, 8, "blue"), ] assert lines[1]._spans == [Span(0, 1, "blue")] lines = text.divide([1]) assert len(lines) == 2 assert str(lines[0]) == "f" assert str(lines[1]) == "oobarbaz" assert lines[0]._spans == [Span(0, 1, "red")] assert lines[1]._spans == [ Span(0, 2, "red"), Span(2, 5, "green"), Span(5, 8, "blue"), ]
def test_stylize_negative_index(): test = Text("Hello, World!") test.stylize("bold", -6, -1) assert test._spans == [Span(7, 12, "bold")]
def test_stylize(): test = Text("Hello, World!") test.stylize("bold", 7, 11) assert test._spans == [Span(7, 11, "bold")] test.stylize("bold", 20, 25) assert test._spans == [Span(7, 11, "bold")]
def test_right_crop(): test = Text() test.append("foobar", "red") test.right_crop(3) assert str(test) == "foo" assert test._spans == [Span(0, 3, "red")]
def test_span_split(): assert Span(5, 10, "foo").split(2) == (Span(5, 10, "foo"), None) assert Span(5, 10, "foo").split(15) == (Span(5, 10, "foo"), None) assert Span(0, 10, "foo").split(5) == (Span(0, 5, "foo"), Span(5, 10, "foo"))
def test_styled(): text = Text.styled("foo", "bold red") assert text.style == "" assert str(text) == "foo" assert text._spans == [Span(0, 3, "bold red")]
def test_span(): span = Span(1, 10, "foo") repr(span) assert bool(span) assert not Span(10, 10, "foo")
def test_render_close_ambiguous(): result = render("[green]X[bold]Y[/]Z[/]") assert str(result) == "XYZ" assert result.spans == [Span(0, 3, "green"), Span(1, 2, "bold")]
def test_render(): result = render("[bold]FOO[/bold]") assert str(result) == "FOO" assert result.spans == [Span(0, 3, "bold")]
def test_from_markup(): text = Text.from_markup("Hello, [bold]World![/bold]") assert str(text) == "Hello, World!" assert text._spans == [Span(7, 13, "bold")]
def test_span_move(): assert Span(5, 10, "foo").move(2) == Span(7, 12, "foo")