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