from prompt_toolkit.formatted_text import (
ANSI,
HTML,
FormattedText,
PygmentsTokens,
Template,
merge_formatted_text,
to_formatted_text,
)
from prompt_toolkit.formatted_text.utils import split_lines
def test_basic_html():
html = HTML("hello")
assert to_formatted_text(html) == [("class:i", "hello")]
html = HTML("hello")
assert to_formatted_text(html) == [("class:i,b", "hello")]
html = HTML("helloworldtestafter")
assert to_formatted_text(html) == [
("class:i,b", "hello"),
("class:i", "world"),
("class:i,strong", "test"),
("", "after"),
]
# It's important that `to_formatted_text` returns a `FormattedText`
# instance. Otherwise, `print_formatted_text` won't recognise it and will
# print a list literal instead.
assert isinstance(to_formatted_text(html), FormattedText)
def test_html_with_fg_bg():
html = HTML('')
assert to_formatted_text(html) == [
("bg:ansired", "hello"),
]
html = HTML('')
assert to_formatted_text(html) == [
("fg:#ff0000 bg:ansired", "hello"),
]
html = HTML(
''
)
assert to_formatted_text(html) == [
("fg:#ff0000 bg:ansired", "hello "),
("class:world fg:ansiblue bg:ansired", "world"),
]
def test_ansi_formatting():
value = ANSI("\x1b[32mHe\x1b[45mllo")
assert to_formatted_text(value) == [
("ansigreen", "H"),
("ansigreen", "e"),
("ansigreen bg:ansimagenta", "l"),
("ansigreen bg:ansimagenta", "l"),
("ansigreen bg:ansimagenta", "o"),
]
# Bold and italic.
value = ANSI("\x1b[1mhe\x1b[0mllo")
assert to_formatted_text(value) == [
("bold", "h"),
("bold", "e"),
("", "l"),
("", "l"),
("", "o"),
]
# Zero width escapes.
value = ANSI("ab\001cd\002ef")
assert to_formatted_text(value) == [
("", "a"),
("", "b"),
("[ZeroWidthEscape]", "cd"),
("", "e"),
("", "f"),
]
assert isinstance(to_formatted_text(value), FormattedText)
def test_ansi_256_color():
assert to_formatted_text(ANSI("\x1b[38;5;124mtest")) == [
("#af0000", "t"),
("#af0000", "e"),
("#af0000", "s"),
("#af0000", "t"),
]
def test_ansi_true_color():
assert to_formatted_text(ANSI("\033[38;2;144;238;144m$\033[0;39;49m ")) == [
("#90ee90", "$"),
("ansidefault bg:ansidefault", " "),
]
def test_ansi_interpolation():
# %-style interpolation.
value = ANSI("\x1b[1m%s\x1b[0m") % "hello\x1b"
assert to_formatted_text(value) == [
("bold", "h"),
("bold", "e"),
("bold", "l"),
("bold", "l"),
("bold", "o"),
("bold", "?"),
]
value = ANSI("\x1b[1m%s\x1b[0m") % ("\x1bhello",)
assert to_formatted_text(value) == [
("bold", "?"),
("bold", "h"),
("bold", "e"),
("bold", "l"),
("bold", "l"),
("bold", "o"),
]
value = ANSI("\x1b[32m%s\x1b[45m%s") % ("He", "\x1bllo")
assert to_formatted_text(value) == [
("ansigreen", "H"),
("ansigreen", "e"),
("ansigreen bg:ansimagenta", "?"),
("ansigreen bg:ansimagenta", "l"),
("ansigreen bg:ansimagenta", "l"),
("ansigreen bg:ansimagenta", "o"),
]
# Format function.
value = ANSI("\x1b[32m{0}\x1b[45m{1}").format("He\x1b", "llo")
assert to_formatted_text(value) == [
("ansigreen", "H"),
("ansigreen", "e"),
("ansigreen", "?"),
("ansigreen bg:ansimagenta", "l"),
("ansigreen bg:ansimagenta", "l"),
("ansigreen bg:ansimagenta", "o"),
]
value = ANSI("\x1b[32m{a}\x1b[45m{b}").format(a="\x1bHe", b="llo")
assert to_formatted_text(value) == [
("ansigreen", "?"),
("ansigreen", "H"),
("ansigreen", "e"),
("ansigreen bg:ansimagenta", "l"),
("ansigreen bg:ansimagenta", "l"),
("ansigreen bg:ansimagenta", "o"),
]
value = ANSI("\x1b[32m{:02d}\x1b[45m{:.3f}").format(3, 3.14159)
assert to_formatted_text(value) == [
("ansigreen", "0"),
("ansigreen", "3"),
("ansigreen bg:ansimagenta", "3"),
("ansigreen bg:ansimagenta", "."),
("ansigreen bg:ansimagenta", "1"),
("ansigreen bg:ansimagenta", "4"),
("ansigreen bg:ansimagenta", "2"),
]
def test_interpolation():
value = Template(" {} ").format(HTML("hello"))
assert to_formatted_text(value) == [
("", " "),
("class:b", "hello"),
("", " "),
]
value = Template("a{}b{}c").format(HTML("hello"), "world")
assert to_formatted_text(value) == [
("", "a"),
("class:b", "hello"),
("", "b"),
("", "world"),
("", "c"),
]
def test_html_interpolation():
# %-style interpolation.
value = HTML("%s") % "&hello"
assert to_formatted_text(value) == [("class:b", "&hello")]
value = HTML("%s") % ("",)
assert to_formatted_text(value) == [("class:b", "")]
value = HTML("%s%s") % ("", "")
assert to_formatted_text(value) == [("class:b", ""), ("class:u", "")]
# Format function.
value = HTML("{0}{1}").format("'hello'", '"world"')
assert to_formatted_text(value) == [("class:b", "'hello'"), ("class:u", '"world"')]
value = HTML("{a}{b}").format(a="hello", b="world")
assert to_formatted_text(value) == [("class:b", "hello"), ("class:u", "world")]
value = HTML("{:02d}{:.3f}").format(3, 3.14159)
assert to_formatted_text(value) == [("class:b", "03"), ("class:u", "3.142")]
def test_merge_formatted_text():
html1 = HTML("hello")
html2 = HTML("world")
result = merge_formatted_text([html1, html2])
assert to_formatted_text(result) == [
("class:u", "hello"),
("class:b", "world"),
]
def test_pygments_tokens():
text = [
(("A", "B"), "hello"), # Token.A.B
(("C", "D", "E"), "hello"), # Token.C.D.E
((), "world"), # Token
]
assert to_formatted_text(PygmentsTokens(text)) == [
("class:pygments.a.b", "hello"),
("class:pygments.c.d.e", "hello"),
("class:pygments", "world"),
]
def test_split_lines():
lines = list(split_lines([("class:a", "line1\nline2\nline3")]))
assert lines == [
[("class:a", "line1")],
[("class:a", "line2")],
[("class:a", "line3")],
]
def test_split_lines_2():
lines = list(
split_lines([("class:a", "line1"), ("class:b", "line2\nline3\nline4")])
)
assert lines == [
[("class:a", "line1"), ("class:b", "line2")],
[("class:b", "line3")],
[("class:b", "line4")],
]
def test_split_lines_3():
"Edge cases: inputs ending with newlines."
# -1-
lines = list(split_lines([("class:a", "line1\nline2\n")]))
assert lines == [
[("class:a", "line1")],
[("class:a", "line2")],
[("class:a", "")],
]
# -2-
lines = list(split_lines([("class:a", "\n")]))
assert lines == [
[],
[("class:a", "")],
]
# -3-
lines = list(split_lines([("class:a", "")]))
assert lines == [
[("class:a", "")],
]