[V3 Utils] Improve bordered function and add tests (#1206)

This commit is contained in:
Tobotimus 2018-01-13 11:15:34 +11:00 committed by GitHub
parent 1c504f681e
commit 05c5c58eaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 98 additions and 21 deletions

View File

@ -1,5 +1,5 @@
import itertools
from typing import List, Iterator
from typing import Sequence, Iterator
def error(text: str) -> str:
"""Get text prefixed with an error emoji.
@ -120,7 +120,7 @@ def italics(text: str) -> str:
return "*{}*".format(text)
def bordered(text1: List[str], text2: List[str]) -> str:
def bordered(*columns: Sequence[str], ascii_border: bool=False) -> str:
"""Get two blocks of text in a borders.
Note
@ -129,10 +129,10 @@ def bordered(text1: List[str], text2: List[str]) -> str:
Parameters
----------
text1 : `list` of `str`
The 1st block of text, with each string being a new line.
text2 : `list` of `str`
The 2nd block of text. Should not be longer than ``text1``.
*columns : `sequence` of `str`
The columns of text, each being a list of lines in that column.
ascii_border : bool
Whether or not the border should be pure ASCII.
Returns
-------
@ -140,24 +140,53 @@ def bordered(text1: List[str], text2: List[str]) -> str:
The bordered text.
"""
width1, width2 = max((len(s1) + 9, len(s2) + 9) for s1 in text1 for s2 in text2)
res = ['{}{}{}'.format(""*width1, " "*4, ""*width2)]
flag = True
for x, y in itertools.zip_longest(text1, text2):
if y:
m = "{}{}{}".format((x + " " * width1)[:width1], " "*4, (y + " " * width2)[:width2])
elif x and flag and not y:
m = "{}{}{}".format((x + " " * width1)[:width1], " "*4, "" * width2)
flag = False
borders = {
'TL': '-' if ascii_border else '', # Top-left
'TR': '-' if ascii_border else '', # Top-right
'BL': '-' if ascii_border else '', # Bottom-left
'BR': '-' if ascii_border else '', # Bottom-right
'HZ': '-' if ascii_border else '', # Horizontal
'VT': '|' if ascii_border else '', # Vertical
}
sep = ' ' * 4 # Separator between boxes
widths = tuple(max(len(row) for row in column) + 9 for column in columns) # width of each col
colsdone = [False] * len(columns) # whether or not each column is done
lines = [sep.join('{TL}' + '{HZ}'*width + '{TR}' for width in widths)]
for line in itertools.zip_longest(*columns):
row = []
for colidx, column in enumerate(line):
width = widths[colidx]
done = colsdone[colidx]
if column is None:
if not done:
# bottom border of column
column = '{HZ}' * width
row.append('{BL}' + column + '{BR}')
colsdone[colidx] = True # mark column as done
else:
m = "{}".format((x + " " * width1)[:width1])
res.append(m)
res.append("" + "" * width1 + "")
return "\n".join(res)
# leave empty
row.append(' ' * (width + 2))
else:
column += ' ' * (width - len(column)) # append padded spaces
row.append('{VT}' + column + '{VT}')
lines.append(sep.join(row))
final_row = []
for width, done in zip(widths, colsdone):
if not done:
final_row.append('{BL}' + '{HZ}' * width + '{BR}')
else:
final_row.append(' ' * (width + 2))
lines.append(sep.join(final_row))
return "\n".join(lines).format(**borders)
def pagify(text: str,
delims: List[str]=["\n"],
delims: Sequence[str]=["\n"],
*,
priority: bool=False,
escape_mass_mentions: bool=True,
@ -173,7 +202,7 @@ def pagify(text: str,
----------
text : str
The content to pagify and send.
delims : `list` of `str`, optional
delims : `sequence` of `str`, optional
Characters where page breaks will occur. If no delimiters are found
in a page, the page will break after ``page_length`` characters.
By default this only contains the newline.

48
tests/core/test_utils.py Normal file
View File

@ -0,0 +1,48 @@
import textwrap
from redbot.core.utils import chat_formatting
def test_bordered_symmetrical():
expected = textwrap.dedent("""\
one four
two five
three six
""")
col1, col2 = ['one', 'two', 'three'], ['four', 'five', 'six']
assert chat_formatting.bordered(col1, col2) == expected
def test_bordered_asymmetrical():
expected = textwrap.dedent("""\
one four
two five
three six
seven
""")
col1, col2 = ['one', 'two', 'three'], ['four', 'five', 'six', 'seven']
assert chat_formatting.bordered(col1, col2) == expected
def test_bordered_asymmetrical_2():
expected = textwrap.dedent("""\
one five
two six
three
four
""")
col1, col2 = ['one', 'two', 'three', 'four'], ['five', 'six']
assert chat_formatting.bordered(col1, col2) == expected
def test_bordered_ascii():
expected = textwrap.dedent("""\
---------------- ---------------
|one | |four |
|two | |five |
|three | |six |
---------------- ---------------""")
col1, col2 = ['one', 'two', 'three'], ['four', 'five', 'six']
assert chat_formatting.bordered(col1, col2, ascii_border=True) == expected