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_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_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_join(): test = Text("bar").join([Text("foo", "red"), Text("baz", "blue")]) assert str(test) == "foobarbaz" assert test._spans == [ Span(0, 3, "red"), Span(3, 6, ""), Span(6, 9, "blue") ]
def test_from_ansi(): text = Text.from_ansi("Hello, \033[1mWorld!\033[0m") assert str(text) == "Hello, World!" assert text._spans == [Span(7, 13, Style(bold=True))] text = Text.from_ansi("Hello, \033[1m\nWorld!\033[0m") assert str(text) == "Hello, \nWorld!" assert text._spans == [Span(8, 14, Style(bold=True))]
def test_assemble_meta(): text = Text.assemble("foo", ("bar", "bold"), meta={"foo": "bar"}) assert str(text) == "foobar" assert text._spans == [ Span(3, 6, "bold"), Span(0, 6, Style(meta={"foo": "bar"})) ] console = Console() assert text.get_style_at_offset(console, 0).meta == {"foo": "bar"}
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, style + s.style) for s in text.spans] return Text(text.plain, spans=spans) elif isinstance(text, str): spans = [Span(0, len(text), mark.convert())] return Text(text, spans=spans)
def test_from_ansi(): text = Text.from_ansi("Hello, \033[1mWorld!\033[0m") assert str(text) == "Hello, World!" assert text._spans == [Span(7, 13, Style(bold=True))] text = Text.from_ansi("Hello, \033[1m\nWorld!\033[0m") assert str(text) == "Hello, \nWorld!" assert text._spans == [Span(8, 14, Style(bold=True))] text = Text.from_ansi("\033[1mBOLD\033[m not bold") assert str(text) == "BOLD not bold" assert text._spans == [Span(0, 4, Style(bold=True))] text = Text.from_ansi("\033[1m\033[Kfoo barmbaz") assert str(text) == "foo barmbaz" assert text._spans == [Span(0, 11, Style(bold=True))]
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_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_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_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 _(lhs=molecule_man, rhs=molecule_woman): diff = Diff(lhs, rhs, 80) diff_lines: List[Text] = list(diff.__rich_console__(None, None)) assert diff_lines == [ Text("{"), Text(" 'age': 29,"), Text( " 'name': 'Molecule Man',", spans=[ Span(0, 22, "green"), Span(22, 23, "white on green"), Span(23, 27, "green"), ], ), Text( " 'name': 'Molecule Woman',", spans=[ Span(0, 22, "red"), Span(22, 25, "white on red"), Span(25, 29, "red"), ], ), Text(" 'powers': ['Turning tiny', 'Radiation blast'],"), Text(" 'secretIdentity': 'Dan Jukes',"), Text("}"), ]
def _(): lhs = "the quick brown fox jumped over the lazy dog" rhs = "the quick brown cat jumped over the lazy dog" diff = Diff(lhs, rhs, 12) render_iter = diff.__rich_console__(None, None) actual_lhs: Text = next(render_iter) actual_rhs: Text = next(render_iter) assert actual_lhs == Text( lhs, spans=[ Span(0, 16, "green"), Span(16, 19, "white on green"), Span(19, 44, "green"), ], ) assert actual_rhs == Text( rhs, spans=[ Span(0, 16, "red"), Span(16, 19, "white on red"), Span(19, 44, "red") ], )
def _(): lhs = "hello" rhs = "hallo" diff = Diff(lhs, rhs, 80) render_iter = diff.__rich_console__(None, None) actual_lhs: Text = next(render_iter) actual_rhs: Text = next(render_iter) expected_lhs = Text( lhs, spans=[ Span(0, 1, "green"), Span(1, 2, "white on green"), Span(2, 5, "green") ], ) expected_rhs = Text(rhs, spans=[ Span(0, 1, "red"), Span(1, 2, "white on red"), Span(2, 5, "red") ]) assert actual_lhs == expected_lhs assert actual_rhs == expected_rhs
def from_html(text: Union[Text, str], tag: str, **kwargs) -> Text: mark = ProtoStyle() mark.tag = tag mark.xml_attr = kwargs if isinstance(text, Text): t = [ Segment(text.plain[s.start:s.end - s.start], s.style) for s in text.spans ] return Text.assemble(*t, style=mark.convert()) elif isinstance(text, str): spans = [Span(0, len(text), mark.convert())] return Text(text, spans=spans)
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_highlight_json_with_indent(): json_string = json.dumps({"name": "apple", "count": 1}, indent=4) text = Text(json_string) highlighter = JSONHighlighter() highlighter.highlight(text) assert text.spans == [ Span(0, 1, "json.brace"), Span(6, 12, "json.str"), Span(14, 21, "json.str"), Span(27, 34, "json.str"), Span(36, 37, "json.number"), Span(38, 39, "json.brace"), Span(6, 12, "json.key"), Span(27, 34, "json.key"), ]
def test_highlight_json_no_indent(): json_string = json.dumps({"name": "apple", "count": 1}, indent=None) text = Text(json_string) highlighter = JSONHighlighter() highlighter.highlight(text) assert text.spans == [ Span(0, 1, "json.brace"), Span(1, 7, "json.str"), Span(9, 16, "json.str"), Span(18, 25, "json.str"), Span(27, 28, "json.number"), Span(28, 29, "json.brace"), Span(1, 7, "json.key"), Span(18, 25, "json.key"), ]
def test_lines_justify(): console = Console() lines1 = Lines([Text("foo"), Text("test")]) 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"), Text("test")]) lines2.justify(console, 7, justify="full") assert lines2._lines == [ Text( "foo bar", spans=[ Span(0, 3, ""), Span(3, 4, Style.parse("none")), Span(4, 7, "") ], ), Text("test"), ]
def ansi_fun(code: str, text: Union[Text, str]) -> Text: """ This constructor is used to create a Text from a PennMUSH style ansi() call, such as: ansi(hr,texthere!) """ code = code.strip() mark = ProtoStyle() apply_rules(mark, code) if isinstance(text, Text): t = [ Segment(text.plain[s.start:s.end - s.start], s.style) for s in text.spans ] return Text.assemble(*t) elif isinstance(text, str): spans = [Span(0, len(text), mark.convert())] return Text(text, spans=spans)
def test_span(): span = Span(1, 10, "foo") repr(span) assert bool(span) assert not Span(10, 10, "foo")
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_assemble(): text = Text.assemble("foo", ("bar", "bold")) assert str(text) == "foobar" assert text._spans == [Span(3, 6, "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_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_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")