evennia/evennia/utils/tests/test_evtable.py

453 lines
15 KiB
Python

"""
Tests for EvTable component.
"""
from evennia.utils import ansi, evtable
from evennia.utils.test_resources import EvenniaTestCase
class TestEvTable(EvenniaTestCase):
def _validate(self, expected, result):
"""easier debug"""
expected = ansi.strip_ansi(expected).strip()
result = ansi.strip_ansi(result).strip()
err = f"\n{'expected':-^60}\n{expected}\n{'result':-^60}\n{result}\n{'':-^60}"
self.assertEqual(expected, result, err)
def test_base(self):
"""
Create plain table.
"""
table = evtable.EvTable(
"|yHeading1|n",
"|gHeading2|n",
"|rHeading3|n",
table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
border="cells",
align="l",
)
expected = """
+----------+----------+----------+
| Heading1 | Heading2 | Heading3 |
+~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~+
| 1 | 4 | 7 |
+----------+----------+----------+
| 2 | 5 | 8 |
+----------+----------+----------+
| 3 | 6 | 9 |
+----------+----------+----------+
"""
self._validate(expected, str(table))
def test_table_with_short_header(self):
"""
Don't provide header3
"""
table = evtable.EvTable(
"|yHeading1|n",
"|gHeading2|n",
table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
border="cells",
align="l",
)
expected = """
+----------+----------+---+
| Heading1 | Heading2 | |
+~~~~~~~~~~+~~~~~~~~~~+~~~+
| 1 | 4 | 7 |
+----------+----------+---+
| 2 | 5 | 8 |
+----------+----------+---+
| 3 | 6 | 9 |
+----------+----------+---+
"""
self._validate(expected, str(table))
def test_add_column(self):
table = evtable.EvTable(
"|yHeading1|n",
"|gHeading2|n",
"|rHeading3|n",
table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
border="cells",
align="l",
)
table.add_column("|rThis is long data|n", "|bThis is even longer data|n")
expected = """
+----------+----------+----------+--------------------------+
| Heading1 | Heading2 | Heading3 | |
+~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~+
| 1 | 4 | 7 | This is long data |
+----------+----------+----------+--------------------------+
| 2 | 5 | 8 | This is even longer data |
+----------+----------+----------+--------------------------+
| 3 | 6 | 9 | |
+----------+----------+----------+--------------------------+
"""
self._validate(expected, str(table))
def test_add_row(self):
table = evtable.EvTable(
"|yHeading1|n",
"|gHeading2|n",
"|rHeading3|n",
table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
border="cells",
align="l",
)
table.add_row("This is a single row")
expected = """
+----------------------+----------+----------+
| Heading1 | Heading2 | Heading3 |
+~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~+
| 1 | 4 | 7 |
+----------------------+----------+----------+
| 2 | 5 | 8 |
+----------------------+----------+----------+
| 3 | 6 | 9 |
+----------------------+----------+----------+
| This is a single row | | |
+----------------------+----------+----------+
"""
self._validate(expected, str(table))
def test_right_align(self):
table = evtable.EvTable(
"|yHeading1|n",
"|gHeading2|n",
"|rHeading3|n",
table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
border="cells",
align="r",
)
expected = """
+----------+----------+----------+
| Heading1 | Heading2 | Heading3 |
+~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~+
| 1 | 4 | 7 |
+----------+----------+----------+
| 2 | 5 | 8 |
+----------+----------+----------+
| 3 | 6 | 9 |
+----------+----------+----------+
"""
def test_add_row_and_column(self):
table = evtable.EvTable(
"|yHeading1|n",
"|gHeading2|n",
"|rHeading3|n",
table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
border="cells",
align="l",
)
table.add_row("This is a single row")
table.add_column("|rThis is long data|n", "|bThis is even longer data|n")
expected = """
+----------------------+----------+----------+--------------------------+
| Heading1 | Heading2 | Heading3 | |
+~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~+
| 1 | 4 | 7 | This is long data |
+----------------------+----------+----------+--------------------------+
| 2 | 5 | 8 | This is even longer data |
+----------------------+----------+----------+--------------------------+
| 3 | 6 | 9 | |
+----------------------+----------+----------+--------------------------+
| This is a single row | | | |
+----------------------+----------+----------+--------------------------+
"""
self._validate(expected, str(table))
def test_reformat(self):
table = evtable.EvTable(
"|yHeading1|n",
"|gHeading2|n",
"|rHeading3|n",
table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
border="cells",
align="l",
)
# width
table.reformat(width=50)
expected = """
+----------------+---------------+---------------+
| Heading1 | Heading2 | Heading3 |
+~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~+
| 1 | 4 | 7 |
+----------------+---------------+---------------+
| 2 | 5 | 8 |
+----------------+---------------+---------------+
| 3 | 6 | 9 |
+----------------+---------------+---------------+
"""
self._validate(expected, str(table))
# right-aligned
table.reformat_column(2, width=30, align="r")
expected = """
+---------+--------+-----------------------------+
| Heading | Headin | Heading3 |
| 1 | g2 | |
+~~~~~~~~~+~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| 1 | 4 | 7 |
+---------+--------+-----------------------------+
| 2 | 5 | 8 |
+---------+--------+-----------------------------+
| 3 | 6 | 9 |
+---------+--------+-----------------------------+
"""
self._validate(expected, str(table))
def test_multiple_rows(self):
"""
Adding a lot of rows with `.add_row`.
"""
table = evtable.EvTable("|yHeading1|n", "|B|[GHeading2|n", "Heading3")
nlines = 12
for i in range(nlines):
table.add_row(
f"This is col 0, row {i}",
f"|gThis is col 1, row |w{i}|n|g|n",
f"This is col 2, row {i}",
)
expected = [
"+-----------------------+-----------------------+-----------------------+",
"| Heading1 | Heading2 | Heading3 |",
"+~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~+",
]
for i in range(nlines):
expected.append(
f"| This is col 0, row {i:<2} | This is col 1, row {i:<2} | This is col 2, row"
f" {i:<2} |"
)
expected.append(expected[0])
expected = "\n".join(expected)
self._validate(expected, str(table))
def test_direct_evcolumn_adds(self):
"""
Testing https://github.com/evennia/evennia/issues/2762
Extra spaces getting added to cell content
Also testing out adding EvColumns directly to the table kwarg.
"""
# direct table add
table = evtable.EvTable(table=[["another"]], fill_char=".", pad_char="#", width=8)
expected = """
+------+
|#anot#|
|#her.#|
+------+
"""
self._validate(expected, str(table))
# add with .add_column
table = evtable.EvTable(fill_char=".", pad_char="#")
table.add_column("another", width=8)
self._validate(expected, str(table))
# add by passing a column to constructor directly
colB = evtable.EvColumn("another", width=8)
table = evtable.EvTable(table=[colB], fill_char=".", pad_char="#")
self._validate(expected, str(table))
# more complex table
colA = evtable.EvColumn("this", "is", "a", "column") # no width
colB = evtable.EvColumn("and", "another", "one", "here", width=8)
table = evtable.EvTable(table=[colA, colB], fill_char=".", pad_char="#")
expected = """
+--------+-------+
|#this..#|#and..#|
|#is....#|#anoth#|
|#......#|#er...#|
|#a.....#|#one..#|
|#column#|#here.#|
+--------+-------+
"""
self._validate(expected, str(table))
def test_nested_table_preserves_inner_spacing(self):
"""
Testing https://github.com/evennia/evennia/issues/3193
Nested EvTables should preserve spacing in inner table rows.
"""
content = [evtable.EvColumn(align="r"), evtable.EvColumn(align="l")]
content[0].add_rows("Item 1")
content[0].add_rows("Item 2")
content[1].add_rows("Item 3")
content[1].add_rows("Item 4")
left_table = evtable.EvTable(table=content, border="cells", header=False, width=24, align="l")
right_table = evtable.EvTable(
table=content, border="cells", header=False, width=24, align="r"
)
nested_table = evtable.EvTable(
table=[[left_table], [right_table]], border="incols", width=55, align="c"
)
rendered = ansi.strip_ansi(str(nested_table))
self.assertIn("| Item 1 | Item 3 |", rendered)
self.assertIn("| Item 2 | Item 4 |", rendered)
def test_width_enforcement(self):
"""
Testing https://github.com/evennia/evennia/issues/2761
EvTable enforces width kwarg, expanding the wrong column
"""
# simple crop
table = evtable.EvTable(table=[["column"]], width=7, enforce_size=True)
expected = """
+-----+
| col |
+-----+
"""
# more advanced table with crop
self._validate(expected, str(table))
colA = evtable.EvColumn("it", "is", "a", "column", width=6, enforce_size=True)
colB = evtable.EvColumn("and", "another", "column", "here")
table = evtable.EvTable(table=[colA, colB], width=40)
expected = """
+----+---------------------------------+
| it | and |
| is | another |
| a | column |
| co | here |
+----+---------------------------------+
"""
self._validate(expected, str(table))
def test_styling_overrides(self):
"""
Testing https://github.com/evennia/evennia/issues/2760
Not being able to override table settings.
"""
column = evtable.EvColumn("this", "is", "a", "column", fill_char=".")
table = evtable.EvTable(table=[column])
expected = """
+--------+
| this.. |
| is.... |
| a..... |
| column |
+--------+
"""
self._validate(expected, str(table))
def test_color_transfer(self):
"""
Testing https://github.com/evennia/evennia/issues/2986
EvTable swallowing color tags.
"""
from evennia.utils.ansi import ANSI_CYAN, ANSI_RED
row1 = "|cAn entire colored row|n"
row2 = "A single |rred|n word"
table = evtable.EvTable(table=[[row1, row2]])
self.assertIn(ANSI_RED, str(table))
self.assertIn(ANSI_CYAN, str(table))
def test_mxp_links(self):
"""
Testing https://github.com/evennia/evennia/issues/3082
EvTable not properly handling mxp links given to it.
"""
commands1 = [f"|lcsay This is command {inum}|ltcommand {inum}|le" for inum in range(1, 4)]
commands2 = [f"command {inum}" for inum in range(1, 4)] # comparison strings, no MXP
cell1 = ansi.strip_mxp(str(evtable.EvCell(f"|lcsay This is command 1|ltcommand 1|le")))
cell2 = str(evtable.EvCell(f"command 1"))
table1a = ansi.strip_mxp(str(evtable.EvTable(*commands1)))
table1b = str(evtable.EvTable(*commands2))
table2a = ansi.strip_mxp(str(evtable.EvTable(table=[commands1])))
table2b = str(evtable.EvTable(table=[commands2]))
self.assertEqual(cell2, cell1)
self.assertEqual(table1b, table1a)
self.assertEqual(table2b, table2a)
def test_formatting_with_carriage_return_marker_3693_a(self):
"""
Testing of issue https://github.com/evennia/evennia/issues/3693
Adding a |/ marker causes a misalignment of the side border.
"""
data = "This is a test |/on a separate line"
table = evtable.EvTable("", table=[[data]], width=20, border="cols")
expected = """
| |
+~~~~~~~~~~~~~~~~~~+
| This is a test |
| on a separate |
| line |
"""
self._validate(expected, str(table))
def test_formatting_with_carriage_return_marker_3693_b(self):
"""
Testing of issue https://github.com/evennia/evennia/issues/3693
Adding a |/ marker causes a misalignment of the side border.
"""
data = "This is a test |/on a separate line"
data = "Welcome to your new Evennia-based game! Visit https://www.evennia.com if you need help, want to contribute, report issues or just join the community. |/|/As a privileged user, write batchcommand tutorial_world.build to build tutorial content. Once built, try intro for starting help and tutorial to play the demo game." # noqa
table = evtable.EvTable("", table=[[data]], width=80, border="cols")
expected = """
| |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| Welcome to your new Evennia-based game! Visit https://www.evennia.com if you |
| need help, want to contribute, report issues or just join the community. |
| |
| As a privileged user, write batchcommand tutorial_world.build to build |
| tutorial content. Once built, try intro for starting help and tutorial to |
| play the demo game. |
"""
self._validate(expected, str(table))