def test_multiline_padding(padding): tbl = Txtble(DATA, headers=HEADERS, padding=padding) with pytest.raises( ValueError, match= "padding cannot contain newlines|string has indeterminate width", ): tbl.show()
def test_split_running_color(): tbl = Txtble( [ [ "\033[31mLorem" " \033[32mipsum" " \033[33mdolor" " \033[34msit \033[35mamet," " \033[36mconsectetur" " \033[41madipisicing" " \033[42melit\033[m" ] ], widths=[20], wrap_func=lambda s, _w: s.split(), ) assert str(tbl) == ( "+--------------------+\n" "|\033[31mLorem\033[m |\n" "|\033[31m\033[32mipsum\033[m |\n" "|\033[31m\033[32m\033[33mdolor\033[m |\n" "|\033[31m\033[32m\033[33m\033[34msit\033[m |\n" "|\033[31m\033[32m\033[33m\033[34m\033[35mamet,\033[m |\n" "|\033[31m\033[32m\033[33m\033[34m\033[35m\033[36mconsectetur\033[m |\n" "|\033[31m\033[32m\033[33m\033[34m\033[35m\033[36m\033[41madipisicing\033[m |\n" "|\033[31m\033[32m\033[33m\033[34m\033[35m\033[36m\033[41m\033[42melit\033[m |\n" "+--------------------+" )
def test_multiline_long_colors(): tbl = Txtble( [ [ "\033[1mThe Flower Poem\n" "All of the red\n" "flowers are \033[4mvery bold\n" "green, and\033[m the petals are \033[7mblue\n" "on cyan. The CMYK\n" "of it all just boggles\n" "the mind.\033[m" ] ] ) assert str(tbl) == ( "+------------------------------+\n" "|\033[1mThe Flower Poem\033[m |\n" "|\033[1mAll of the red\033[m |\n" "|\033[1mflowers are \033[4mvery bold\033[m |\n" "|\033[1m\033[4mgreen, and\033[m the petals are \033[7mblue\033[m|\n" "|\033[7mon cyan. The CMYK\033[m |\n" "|\033[7mof it all just boggles\033[m |\n" "|\033[7mthe mind.\033[m |\n" "+------------------------------+" )
def test_multiline_colors(): tbl = Txtble( [ [ "The \033[4mFlower\033[m Poem\n" "All of the \033[31mred\n" "flowers\033[m are very \033[01;32mbold\n" "green\033[0m, and the petals are \033[34mblue\033[46m\n" "on cyan\033[00m. The \033[36mC\033[35mM\033[33mY\033[30mK\n" "of it all\033[m just \033[40;34;46;0;7mboggles\n" "the mind\033[0m." ] ] ) assert str(tbl) == ( "+------------------------------+\n" "|The \033[4mFlower\033[m Poem |\n" "|All of the \033[31mred\033[m |\n" "|\033[31mflowers\033[m are very \033[01;32mbold\033[m |\n" "|\033[01;32mgreen\033[0m, and the petals are \033[34mblue\033[46m\033[m|\n" "|\033[34m\033[46mon cyan\033[00m. The \033[36mC\033[35mM\033[33mY\033[30mK\033[m |\n" "|\033[36m\033[35m\033[33m\033[30mof it all\033[m just \033[40;34;46;0;7mboggles\033[m |\n" "|\033[40;34;46;0;7mthe mind\033[0m. |\n" "+------------------------------+" )
def test_combining_builtin_len_func(): s = ( "L\u0301o\u0301r\u0301e\u0301m\u0301" " i\u0301p\u0301s\u0301u\u0301m\u0301" " d\u0301o\u0301l\u0301o\u0301r\u0301" " s\u0301i\u0301t\u0301" " a\u0301m\u0301e\u0301t\u0301" ) s2 = "Lorem ipsum dolor sit amet" tbl = Txtble([[s], [s2]], len_func=len) w = len(s) assert str(tbl) == ( "+" + "-" * w + "+\n" + "|" + s + "|\n" + "|" + s2 + " " * s.count("\u0301") + "|\n" + "+" + "-" * w + "+" )
def test_bad_border_style(border_style): tbl = Txtble(DATA, border_style=border_style) with pytest.raises( TypeError, match="border_style must be a BorderStyle instance", ): str(tbl)
def test_headers_not_matching_columns(columns): tbl = Txtble(DATA, headers=HEADERS, columns=columns) with pytest.raises( ValueError, match=r"len\(headers\) and columns do not match", ): str(tbl)
def test_hborders_on_styled(): tbl = Txtble( DATA, headers=HEADERS, border=False, border_style=ASCII_EQ_BORDERS, top_border=True, bottom_border=True, ) assert str(tbl) == ("=========+==========+==================\n" "Month |Birthstone|Birth Flower\n" "=========+==========+==================\n" "January |Garnet |Carnation\n" "February |Amethyst |Violet\n" "March |Aquamarine|Jonquil\n" "April |Diamond |Sweetpea\n" "May |Emerald |Lily Of The Valley\n" "June |Pearl |Rose\n" "July |Ruby |Larkspur\n" "August |Peridot |Gladiolus\n" "September|Sapphire |Aster\n" "October |Opal |Calendula\n" "November |Topaz |Chrysanthemum\n" "December |Turquoise |Narcissus\n" "=========+==========+==================")
def test_padding_embedded_newlines(): tbl = Txtble( [ [ "Verse 1", "Twas brillig, and the slithy toves\n" "Did gyre and gimble in the wabe;\n" "All mimsy were the borogoves,\n" "And the mome raths outgrabe.", ], [ "Verse 2", '"Beware the Jabberwock, my son!\n' "The jaws that bite, the claws that catch!\n" "Beware the Jubjub bird, and shun\n" 'The frumious Bandersnatch!"', ], ], padding=".", ) assert str(tbl) == ( "+---------+-------------------------------------------+\n" "|.Verse 1.|.Twas brillig, and the slithy toves .|\n" "|. .|.Did gyre and gimble in the wabe; .|\n" "|. .|.All mimsy were the borogoves, .|\n" "|. .|.And the mome raths outgrabe. .|\n" '|.Verse 2.|."Beware the Jabberwock, my son! .|\n' "|. .|.The jaws that bite, the claws that catch!.|\n" "|. .|.Beware the Jubjub bird, and shun .|\n" '|. .|.The frumious Bandersnatch!" .|\n' "+---------+-------------------------------------------+")
def test_every_inner_border_different(): tbl = Txtble( DATA, border=False, column_border=HEAVY_BORDERS, header_border=DOUBLE_BORDERS, headers=HEADERS, row_border=LIGHT_BORDERS, ) assert str(tbl) == ("Month ┃Birthstone┃Birth Flower\n" "═════════╬══════════╬══════════════════\n" "January ┃Garnet ┃Carnation\n" "─────────┼──────────┼──────────────────\n" "February ┃Amethyst ┃Violet\n" "─────────┼──────────┼──────────────────\n" "March ┃Aquamarine┃Jonquil\n" "─────────┼──────────┼──────────────────\n" "April ┃Diamond ┃Sweetpea\n" "─────────┼──────────┼──────────────────\n" "May ┃Emerald ┃Lily Of The Valley\n" "─────────┼──────────┼──────────────────\n" "June ┃Pearl ┃Rose\n" "─────────┼──────────┼──────────────────\n" "July ┃Ruby ┃Larkspur\n" "─────────┼──────────┼──────────────────\n" "August ┃Peridot ┃Gladiolus\n" "─────────┼──────────┼──────────────────\n" "September┃Sapphire ┃Aster\n" "─────────┼──────────┼──────────────────\n" "October ┃Opal ┃Calendula\n" "─────────┼──────────┼──────────────────\n" "November ┃Topaz ┃Chrysanthemum\n" "─────────┼──────────┼──────────────────\n" "December ┃Turquoise ┃Narcissus")
def test_row_border_embedded_newlines(): tbl = Txtble( [ [ "Verse 1", "Twas brillig, and the slithy toves\n" "Did gyre and gimble in the wabe;\n" "All mimsy were the borogoves,\n" "And the mome raths outgrabe.", ], [ "Verse 2", '"Beware the Jabberwock, my son!\n' "The jaws that bite, the claws that catch!\n" "Beware the Jubjub bird, and shun\n" 'The frumious Bandersnatch!"', ], ], row_border=True, ) assert str(tbl) == ( "+-------+-----------------------------------------+\n" "|Verse 1|Twas brillig, and the slithy toves |\n" "| |Did gyre and gimble in the wabe; |\n" "| |All mimsy were the borogoves, |\n" "| |And the mome raths outgrabe. |\n" "+-------+-----------------------------------------+\n" '|Verse 2|"Beware the Jabberwock, my son! |\n' "| |The jaws that bite, the claws that catch!|\n" "| |Beware the Jubjub bird, and shun |\n" '| |The frumious Bandersnatch!" |\n' "+-------+-----------------------------------------+" )
def test_invert_all_borders(): tbl = Txtble( DATA, border=False, column_border=False, header_border=False, headers=HEADERS, row_border=True, ) assert str(tbl) == ( "Month BirthstoneBirth Flower\n" "January Garnet Carnation\n" "-------------------------------------\n" "February Amethyst Violet\n" "-------------------------------------\n" "March AquamarineJonquil\n" "-------------------------------------\n" "April Diamond Sweetpea\n" "-------------------------------------\n" "May Emerald Lily Of The Valley\n" "-------------------------------------\n" "June Pearl Rose\n" "-------------------------------------\n" "July Ruby Larkspur\n" "-------------------------------------\n" "August Peridot Gladiolus\n" "-------------------------------------\n" "SeptemberSapphire Aster\n" "-------------------------------------\n" "October Opal Calendula\n" "-------------------------------------\n" "November Topaz Chrysanthemum\n" "-------------------------------------\n" "December Turquoise Narcissus" )
def test_valign(): tbl = Txtble( headers=[ "Line 1", "Line 2", "Line 3", "5 Syllables\n7 Syllables\n5 Syllables" ], data=[[ "Haikus are easy,", "But sometimes they don't make sense.", "Refrigerator.", "-- - --\n- -- - - - -\n-----", ]], valign=["t", "m", "b"], ) assert str(tbl) == ( "+----------------+------------------------------------+-------------+------------+\n" "|Line 1 | | |5 Syllables |\n" "| |Line 2 | |7 Syllables |\n" "| | |Line 3 |5 Syllables |\n" "+----------------+------------------------------------+-------------+------------+\n" "|Haikus are easy,| | |-- - -- |\n" "| |But sometimes they don't make sense.| |- -- - - - -|\n" "| | |Refrigerator.|----- |\n" "+----------------+------------------------------------+-------------+------------+" )
def test_empty_headers_no_header_fill(): tbl = Txtble(DATA, headers=[]) with pytest.raises( ValueError, match="headers is empty but header_fill is None", ): str(tbl)
def test_row_border(): tbl = Txtble(DATA, headers=HEADERS, row_border=True) assert str(tbl) == ( "+---------+----------+------------------+\n" "|Month |Birthstone|Birth Flower |\n" "+---------+----------+------------------+\n" "|January |Garnet |Carnation |\n" "+---------+----------+------------------+\n" "|February |Amethyst |Violet |\n" "+---------+----------+------------------+\n" "|March |Aquamarine|Jonquil |\n" "+---------+----------+------------------+\n" "|April |Diamond |Sweetpea |\n" "+---------+----------+------------------+\n" "|May |Emerald |Lily Of The Valley|\n" "+---------+----------+------------------+\n" "|June |Pearl |Rose |\n" "+---------+----------+------------------+\n" "|July |Ruby |Larkspur |\n" "+---------+----------+------------------+\n" "|August |Peridot |Gladiolus |\n" "+---------+----------+------------------+\n" "|September|Sapphire |Aster |\n" "+---------+----------+------------------+\n" "|October |Opal |Calendula |\n" "+---------+----------+------------------+\n" "|November |Topaz |Chrysanthemum |\n" "+---------+----------+------------------+\n" "|December |Turquoise |Narcissus |\n" "+---------+----------+------------------+" )
def test_border_style_overridden(): tbl = Txtble( DATA, border=LIGHT_BORDERS, border_style=DOT_BORDERS, column_border=HEAVY_BORDERS, header_border=DOUBLE_BORDERS, headers=HEADERS, ) assert str(tbl) == ("┌─────────┬──────────┬──────────────────┐\n" "│Month ┃Birthstone┃Birth Flower │\n" "╠═════════╬══════════╬══════════════════╣\n" "│January ┃Garnet ┃Carnation │\n" "│February ┃Amethyst ┃Violet │\n" "│March ┃Aquamarine┃Jonquil │\n" "│April ┃Diamond ┃Sweetpea │\n" "│May ┃Emerald ┃Lily Of The Valley│\n" "│June ┃Pearl ┃Rose │\n" "│July ┃Ruby ┃Larkspur │\n" "│August ┃Peridot ┃Gladiolus │\n" "│September┃Sapphire ┃Aster │\n" "│October ┃Opal ┃Calendula │\n" "│November ┃Topaz ┃Chrysanthemum │\n" "│December ┃Turquoise ┃Narcissus │\n" "└─────────┴──────────┴──────────────────┘")
def test_headers_blank_row(): tbl = Txtble(headers=("This", "That"), data=[["", ""]]) assert str(tbl) == ("+----+----+\n" "|This|That|\n" "+----+----+\n" "| | |\n" "+----+----+")
def test_every_side_different_style(border): tbl = Txtble( DATA, headers=HEADERS, border=border, top_border=HEAVY_BORDERS, bottom_border=ASCII_EQ_BORDERS, left_border=LIGHT_BORDERS, right_border=DOUBLE_BORDERS, ) assert str(tbl) == ("┏━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓\n" "│Month |Birthstone|Birth Flower ║\n" "+---------+----------+------------------+\n" "│January |Garnet |Carnation ║\n" "│February |Amethyst |Violet ║\n" "│March |Aquamarine|Jonquil ║\n" "│April |Diamond |Sweetpea ║\n" "│May |Emerald |Lily Of The Valley║\n" "│June |Pearl |Rose ║\n" "│July |Ruby |Larkspur ║\n" "│August |Peridot |Gladiolus ║\n" "│September|Sapphire |Aster ║\n" "│October |Opal |Calendula ║\n" "│November |Topaz |Chrysanthemum ║\n" "│December |Turquoise |Narcissus ║\n" "+=========+==========+==================+")
def test_align_n_numeric_dict_fill(): tbl = Txtble( headers=["A", "B", "C"], data=[ { "A": "Foo", "B": 12345 }, { "A": "Bar", "B": 123.45, "C": 54.321 }, { "A": "Baz", "B": 1.2345 }, ], align="n", dict_fill=1.2, ) assert str(tbl) == ("+---+----------+------+\n" "|A |B |C |\n" "+---+----------+------+\n" "|Foo|12345 | 1.2 |\n" "|Bar| 123.45 |54.321|\n" "|Baz| 1.2345| 1.2 |\n" "+---+----------+------+")
def test_align_nr_long_width_mixed(align): tbl = Txtble( headers=["Thing", "Value"], data=[ ["Foo", 12345], ["Bar", "red red red red"], ["Baz", 123.45], ["Quux", "blue"], ["Glarch", 1.23], ["Gnusto", "green"], ], align=["l", align], widths=[None, 9], ) assert str(tbl) == ("+------+---------+\n" "|Thing | Value|\n" "+------+---------+\n" "|Foo | 12345 |\n" "|Bar | red red|\n" "| | red red|\n" "|Baz | 123.45|\n" "|Quux | blue|\n" "|Glarch| 1.23|\n" "|Gnusto| green|\n" "+------+---------+")
def test_outer_border_only(): tbl = Txtble( DATA, border=True, column_border=False, header_border=False, headers=HEADERS, ) assert str(tbl) == ( "+-------------------------------------+\n" "|Month BirthstoneBirth Flower |\n" "|January Garnet Carnation |\n" "|February Amethyst Violet |\n" "|March AquamarineJonquil |\n" "|April Diamond Sweetpea |\n" "|May Emerald Lily Of The Valley|\n" "|June Pearl Rose |\n" "|July Ruby Larkspur |\n" "|August Peridot Gladiolus |\n" "|SeptemberSapphire Aster |\n" "|October Opal Calendula |\n" "|November Topaz Chrysanthemum |\n" "|December Turquoise Narcissus |\n" "+-------------------------------------+" )
def test_embedded_trailing_newlines_no_border(): tbl = Txtble( [ [ "Verse 1", "Twas brillig, and the slithy toves\n" "Did gyre and gimble in the wabe;\n" "All mimsy were the borogoves,\n" "And the mome raths outgrabe.\n", ], [ "Verse 2", '"Beware the Jabberwock, my son!\n' "The jaws that bite, the claws that catch!\n" "Beware the Jubjub bird, and shun\n" 'The frumious Bandersnatch!"\n', ], ], border=False, ) assert str(tbl) == ("Verse 1|Twas brillig, and the slithy toves\n" " |Did gyre and gimble in the wabe;\n" " |All mimsy were the borogoves,\n" " |And the mome raths outgrabe.\n" " |\n" 'Verse 2|"Beware the Jabberwock, my son!\n' " |The jaws that bite, the claws that catch!\n" " |Beware the Jubjub bird, and shun\n" ' |The frumious Bandersnatch!"\n' " |")
def test_no_wrap_wrap(): tbl = Txtble([[LONG_STRING, LONG_STRING]], widths=[None, 30]) assert str(tbl) == ( "+--------------------------------------------------------+------------------------------+\n" "|Lorem ipsum dolor sit amet, consectetur adipisicing elit|Lorem ipsum dolor sit amet, |\n" "| |consectetur adipisicing elit |\n" "+--------------------------------------------------------+------------------------------+" )
def test_width_fill_all(): tbl = Txtble([[LONG_STRING, LONG_STRING]], width_fill=20) assert str(tbl) == ("+--------------------+--------------------+\n" "|Lorem ipsum dolor |Lorem ipsum dolor |\n" "|sit amet, |sit amet, |\n" "|consectetur |consectetur |\n" "|adipisicing elit |adipisicing elit |\n" "+--------------------+--------------------+")
def test_wrap_none_str(): tbl = Txtble([[None]], none_str=LONG_STRING, widths=[20]) assert str(tbl) == ("+--------------------+\n" "|Lorem ipsum dolor |\n" "|sit amet, |\n" "|consectetur |\n" "|adipisicing elit |\n" "+--------------------+")
def test_bad_valign(valign): tbl = Txtble( [["Line", "Line 1\nLine 2\nLine 3\nLine 4", "Extra 1\nExtra 2"]], valign=["m", "m", valign], ) with pytest.raises(ValueError, match="invalid vertical alignment specifier"): str(tbl)
def test_wrap_long_color(): tbl = Txtble([["\033[31m" + LONG_STRING + "\033[0m"]], widths=[20]) assert str(tbl) == ("+--------------------+\n" "|\033[31mLorem ipsum dolor\033[m |\n" "|\033[31msit amet,\033[m |\n" "|\033[31mconsectetur\033[m |\n" "|\033[31madipisicing elit\033[0m |\n" "+--------------------+")
def test_extra_whitespace(): tbl = Txtble([ [" .leading.", ".trailing. "], [" ", "inn er"], ]) assert str(tbl) == ("+--------------+------------+\n" "| .leading. |.trailing. |\n" "| |inn er |\n" "+--------------+------------+")
def test_indeterminate_cell(s): tbl = Txtble( headers=["Header", "Header"], data=[["A", "B"], [s, "D"]], ) with pytest.raises(IndeterminateWidthError) as excinfo: str(tbl) assert excinfo.value.string == s assert str(excinfo.value) == repr(s) + ": string has indeterminate width"
def test_indeterminate_header(): tbl = Txtble( headers=["Header", BAD_STRING], data=[["A", "B"], ["C", "D"]], ) with pytest.raises(IndeterminateWidthError) as excinfo: str(tbl) assert excinfo.value.string == BAD_STRING assert str(excinfo.value) == ERRMSG