summaryrefslogtreecommitdiffstats
path: root/tests/test_width_and_alignment
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_width_and_alignment')
-rw-r--r--tests/test_width_and_alignment/test_align_and_pad_cell.py202
-rw-r--r--tests/test_width_and_alignment/test_column_max_width.py107
-rw-r--r--tests/test_width_and_alignment/test_max_dimensions.py100
-rw-r--r--tests/test_width_and_alignment/test_table_width.py70
-rw-r--r--tests/test_width_and_alignment/test_visible_width.py59
5 files changed, 538 insertions, 0 deletions
diff --git a/tests/test_width_and_alignment/test_align_and_pad_cell.py b/tests/test_width_and_alignment/test_align_and_pad_cell.py
new file mode 100644
index 0000000..e0a928e
--- /dev/null
+++ b/tests/test_width_and_alignment/test_align_and_pad_cell.py
@@ -0,0 +1,202 @@
+# coding: utf-8
+"""Test function in module."""
+
+import pytest
+from colorama import Fore
+from colorclass import Color
+from termcolor import colored
+
+from terminaltables.width_and_alignment import align_and_pad_cell
+
+
+@pytest.mark.parametrize('string,align,width,expected', [
+ ('test', '', 4, ['test']),
+ (123, '', 3, ['123']),
+ (0.9, '', 3, ['0.9']),
+ (None, '', 4, ['None']),
+ (True, '', 4, ['True']),
+ (False, '', 5, ['False']),
+ (Color('{blue}Test{/blue}'), '', 4, ['\x1b[34mTest\x1b[39m']),
+ (Fore.BLUE + 'Test' + Fore.RESET, '', 4, ['\x1b[34mTest\x1b[39m']),
+ (colored('Test', 'blue'), '', 4, ['\x1b[34mTest\x1b[0m']),
+ ('蓝色', '', 4, ['蓝色']),
+ (u'שלום', '', 4, [u'\u05e9\u05dc\u05d5\u05dd']),
+ (u'معرب', '', 4, [u'\u0645\u0639\u0631\u0628']),
+
+ ('test', '', 5, ['test ']),
+ (123, '', 4, ['123 ']),
+ (0.9, '', 4, ['0.9 ']),
+ (None, '', 5, ['None ']),
+ (True, '', 5, ['True ']),
+ (False, '', 6, ['False ']),
+ (Color('{blue}Test{/blue}'), '', 5, ['\x1b[34mTest\x1b[39m ']),
+ (Fore.BLUE + 'Test' + Fore.RESET, '', 5, ['\x1b[34mTest\x1b[39m ']),
+ (colored('Test', 'blue'), '', 5, ['\x1b[34mTest\x1b[0m ']),
+ ('蓝色', '', 5, ['蓝色 ']),
+ (u'שלום', '', 5, [u'\u05e9\u05dc\u05d5\u05dd ']),
+ (u'معرب', '', 5, [u'\u0645\u0639\u0631\u0628 ']),
+
+ ('test', 'left', 5, ['test ']),
+ (123, 'left', 4, ['123 ']),
+ (0.9, 'left', 4, ['0.9 ']),
+ (None, 'left', 5, ['None ']),
+ (True, 'left', 5, ['True ']),
+ (False, 'left', 6, ['False ']),
+ (Color('{blue}Test{/blue}'), 'left', 5, ['\x1b[34mTest\x1b[39m ']),
+ (Fore.BLUE + 'Test' + Fore.RESET, 'left', 5, ['\x1b[34mTest\x1b[39m ']),
+ (colored('Test', 'blue'), 'left', 5, ['\x1b[34mTest\x1b[0m ']),
+ ('蓝色', 'left', 5, ['蓝色 ']),
+ (u'שלום', 'left', 5, [u'\u05e9\u05dc\u05d5\u05dd ']),
+ (u'معرب', 'left', 5, [u'\u0645\u0639\u0631\u0628 ']),
+
+ ('test', 'right', 5, [' test']),
+ (123, 'right', 4, [' 123']),
+ (0.9, 'right', 4, [' 0.9']),
+ (None, 'right', 5, [' None']),
+ (True, 'right', 5, [' True']),
+ (False, 'right', 6, [' False']),
+ (Color('{blue}Test{/blue}'), 'right', 5, [' \x1b[34mTest\x1b[39m']),
+ (Fore.BLUE + 'Test' + Fore.RESET, 'right', 5, [' \x1b[34mTest\x1b[39m']),
+ (colored('Test', 'blue'), 'right', 5, [' \x1b[34mTest\x1b[0m']),
+ ('蓝色', 'right', 5, [' 蓝色']),
+ (u'שלום', 'right', 5, [u' \u05e9\u05dc\u05d5\u05dd']),
+ (u'معرب', 'right', 5, [u' \u0645\u0639\u0631\u0628']),
+
+ ('test', 'center', 6, [' test ']),
+ (123, 'center', 5, [' 123 ']),
+ (0.9, 'center', 5, [' 0.9 ']),
+ (None, 'center', 6, [' None ']),
+ (True, 'center', 6, [' True ']),
+ (False, 'center', 7, [' False ']),
+ (Color('{blue}Test{/blue}'), 'center', 6, [' \x1b[34mTest\x1b[39m ']),
+ (Fore.BLUE + 'Test' + Fore.RESET, 'center', 6, [' \x1b[34mTest\x1b[39m ']),
+ (colored('Test', 'blue'), 'center', 6, [' \x1b[34mTest\x1b[0m ']),
+ ('蓝色', 'center', 6, [' 蓝色 ']),
+ (u'שלום', 'center', 6, [u' \u05e9\u05dc\u05d5\u05dd ']),
+ (u'معرب', 'center', 6, [u' \u0645\u0639\u0631\u0628 ']),
+])
+def test_width(string, align, width, expected):
+ """Test width and horizontal alignment.
+
+ :param str string: String to test.
+ :param str align: Horizontal alignment.
+ :param int width: Expand string to this width without padding.
+ :param list expected: Expected output string.
+ """
+ actual = align_and_pad_cell(string, (align,), (width, 1), (0, 0, 0, 0))
+ assert actual == expected
+
+
+@pytest.mark.parametrize('string,align,height,expected', [
+ ('test', '', 1, ['test']),
+ (Color('{blue}Test{/blue}'), '', 1, ['\x1b[34mTest\x1b[39m']),
+ (Fore.BLUE + 'Test' + Fore.RESET, '', 1, ['\x1b[34mTest\x1b[39m']),
+ (colored('Test', 'blue'), '', 1, ['\x1b[34mTest\x1b[0m']),
+ ('蓝色', '', 1, ['蓝色']),
+ (u'שלום', '', 1, [u'\u05e9\u05dc\u05d5\u05dd']),
+ (u'معرب', '', 1, [u'\u0645\u0639\u0631\u0628']),
+
+ ('test', '', 2, ['test', ' ']),
+ (Color('{blue}Test{/blue}'), '', 2, ['\x1b[34mTest\x1b[39m', ' ']),
+ (Fore.BLUE + 'Test' + Fore.RESET, '', 2, ['\x1b[34mTest\x1b[39m', ' ']),
+ (colored('Test', 'blue'), '', 2, ['\x1b[34mTest\x1b[0m', ' ']),
+ ('蓝色', '', 2, ['蓝色', ' ']),
+ (u'שלום', '', 2, [u'\u05e9\u05dc\u05d5\u05dd', ' ']),
+ (u'معرب', '', 2, [u'\u0645\u0639\u0631\u0628', ' ']),
+
+ ('test', 'top', 2, ['test', ' ']),
+ (Color('{blue}Test{/blue}'), 'top', 2, ['\x1b[34mTest\x1b[39m', ' ']),
+ (Fore.BLUE + 'Test' + Fore.RESET, 'top', 2, ['\x1b[34mTest\x1b[39m', ' ']),
+ (colored('Test', 'blue'), 'top', 2, ['\x1b[34mTest\x1b[0m', ' ']),
+ ('蓝色', 'top', 2, ['蓝色', ' ']),
+ (u'שלום', 'top', 2, [u'\u05e9\u05dc\u05d5\u05dd', ' ']),
+ (u'معرب', 'top', 2, [u'\u0645\u0639\u0631\u0628', ' ']),
+
+ ('test', 'bottom', 2, [' ', 'test']),
+ (Color('{blue}Test{/blue}'), 'bottom', 2, [' ', '\x1b[34mTest\x1b[39m']),
+ (Fore.BLUE + 'Test' + Fore.RESET, 'bottom', 2, [' ', '\x1b[34mTest\x1b[39m']),
+ (colored('Test', 'blue'), 'bottom', 2, [' ', '\x1b[34mTest\x1b[0m']),
+ ('蓝色', 'bottom', 2, [' ', '蓝色']),
+ (u'שלום', 'bottom', 2, [' ', u'\u05e9\u05dc\u05d5\u05dd']),
+ (u'معرب', 'bottom', 2, [' ', u'\u0645\u0639\u0631\u0628']),
+
+ ('test', 'middle', 3, [' ', 'test', ' ']),
+ (Color('{blue}Test{/blue}'), 'middle', 3, [' ', '\x1b[34mTest\x1b[39m', ' ']),
+ (Fore.BLUE + 'Test' + Fore.RESET, 'middle', 3, [' ', '\x1b[34mTest\x1b[39m', ' ']),
+ (colored('Test', 'blue'), 'middle', 3, [' ', '\x1b[34mTest\x1b[0m', ' ']),
+ ('蓝色', 'middle', 3, [' ', '蓝色', ' ']),
+ (u'שלום', 'middle', 3, [' ', u'\u05e9\u05dc\u05d5\u05dd', ' ']),
+ (u'معرب', 'middle', 3, [' ', u'\u0645\u0639\u0631\u0628', ' ']),
+])
+def test_height(string, align, height, expected):
+ """Test height and vertical alignment.
+
+ :param str string: String to test.
+ :param str align: Horizontal alignment.
+ :param int height: Expand string to this height without padding.
+ :param list expected: Expected output string.
+ """
+ actual = align_and_pad_cell(string, (align,), (4, height), (0, 0, 0, 0))
+ assert actual == expected
+
+
+@pytest.mark.parametrize('string,align,expected', [
+ ('', '', ['.......', '.......', '.......', '.......', '.......']),
+ ('\n', '', ['.......', '.......', '.......', '.......', '.......']),
+ ('a\nb\nc', '', ['.......', '.a.....', '.b.....', '.c.....', '.......']),
+ ('test', '', ['.......', '.test..', '.......', '.......', '.......']),
+
+ ('', 'left', ['.......', '.......', '.......', '.......', '.......']),
+ ('\n', 'left', ['.......', '.......', '.......', '.......', '.......']),
+ ('a\nb\nc', 'left', ['.......', '.a.....', '.b.....', '.c.....', '.......']),
+ ('test', 'left', ['.......', '.test..', '.......', '.......', '.......']),
+
+ ('', 'right', ['.......', '.......', '.......', '.......', '.......']),
+ ('\n', 'right', ['.......', '.......', '.......', '.......', '.......']),
+ ('a\nb\nc', 'right', ['.......', '.....a.', '.....b.', '.....c.', '.......']),
+ ('test', 'right', ['.......', '..test.', '.......', '.......', '.......']),
+
+ ('', 'center', ['.......', '.......', '.......', '.......', '.......']),
+ ('\n', 'center', ['.......', '.......', '.......', '.......', '.......']),
+ ('a\nb\nc', 'center', ['.......', '...a...', '...b...', '...c...', '.......']),
+ ('test', 'center', ['.......', '..test.', '.......', '.......', '.......']),
+
+ ('', 'top', ['.......', '.......', '.......', '.......', '.......']),
+ ('\n', 'top', ['.......', '.......', '.......', '.......', '.......']),
+ ('a\nb\nc', 'top', ['.......', '.a.....', '.b.....', '.c.....', '.......']),
+ ('test', 'top', ['.......', '.test..', '.......', '.......', '.......']),
+
+ ('', 'bottom', ['.......', '.......', '.......', '.......', '.......']),
+ ('\n', 'bottom', ['.......', '.......', '.......', '.......', '.......']),
+ ('a\nb\nc', 'bottom', ['.......', '.a.....', '.b.....', '.c.....', '.......']),
+ ('test', 'bottom', ['.......', '.......', '.......', '.test..', '.......']),
+
+ ('', 'middle', ['.......', '.......', '.......', '.......', '.......']),
+ ('\n', 'middle', ['.......', '.......', '.......', '.......', '.......']),
+ ('a\nb\nc', 'middle', ['.......', '.a.....', '.b.....', '.c.....', '.......']),
+ ('test', 'middle', ['.......', '.......', '.test..', '.......', '.......']),
+
+ (
+ u'蓝色\nשלום\nمعرب',
+ '',
+ ['.......', u'.蓝色..', u'.\u05e9\u05dc\u05d5\u05dd..', u'.\u0645\u0639\u0631\u0628..', '.......']
+ ),
+
+ (
+ '\n'.join((Color('{blue}Test{/blue}'), Fore.BLUE + 'Test' + Fore.RESET, colored('Test', 'blue'))),
+ '',
+ ['.......', '.\x1b[34mTest\x1b[39m..', '.\x1b[34mTest\x1b[39m..', '.\x1b[34mTest\x1b[0m..', '.......']
+ ),
+
+ # (Color('{blue}A\nB{/blue}'), '', '.......\n.\x1b[34mA\x1b[39m.....\n.\x1b[34mB\x1b[39m.....\n.......\n.......'),
+
+])
+def test_odd_width_height_pad_space(string, align, expected):
+ """Test odd number width, height, padding, and dots for whitespaces.
+
+ :param str string: String to test.
+ :param str align: Alignment in any dimension but one at a time.
+ :param list expected: Expected output string.
+ """
+ actual = align_and_pad_cell(string, (align,), (5, 3), (1, 1, 1, 1), '.')
+ assert actual == expected
diff --git a/tests/test_width_and_alignment/test_column_max_width.py b/tests/test_width_and_alignment/test_column_max_width.py
new file mode 100644
index 0000000..696c9bf
--- /dev/null
+++ b/tests/test_width_and_alignment/test_column_max_width.py
@@ -0,0 +1,107 @@
+"""Test function in module."""
+
+import pytest
+
+from terminaltables.width_and_alignment import column_max_width, max_dimensions
+
+
+@pytest.fixture(autouse=True)
+def patch(monkeypatch):
+ """Monkeypatch before every test function in this module.
+
+ :param monkeypatch: pytest fixture.
+ """
+ monkeypatch.setattr('terminaltables.width_and_alignment.terminal_size', lambda: (79, 24))
+
+
+def test_empty():
+ """Test with zero-length cells."""
+ assert column_max_width(max_dimensions([['']])[0], 0, 0, 0, 0) == 79
+ assert column_max_width(max_dimensions([['', '', '']])[0], 0, 0, 0, 0) == 79
+ assert column_max_width(max_dimensions([['', '', ''], ['', '', '']])[0], 0, 0, 0, 0) == 79
+
+ assert column_max_width(max_dimensions([['']])[0], 0, 2, 1, 2) == 75
+ assert column_max_width(max_dimensions([['', '', '']])[0], 0, 2, 1, 2) == 69
+ assert column_max_width(max_dimensions([['', '', ''], ['', '', '']])[0], 0, 2, 1, 2) == 69
+
+
+def test_single_line():
+ """Test with single-line cells."""
+ table_data = [
+ ['Name', 'Color', 'Type'],
+ ['Avocado', 'green', 'nut'],
+ ['Tomato', 'red', 'fruit'],
+ ['Lettuce', 'green', 'vegetable'],
+ ]
+ inner_widths = max_dimensions(table_data)[0]
+
+ # '| Lettuce | green | vegetable |'
+ outer, inner, padding = 2, 1, 2
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == 55
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 53
+ assert column_max_width(inner_widths, 2, outer, inner, padding) == 57
+
+ # ' Lettuce | green | vegetable '
+ outer = 0
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == 57
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 55
+ assert column_max_width(inner_widths, 2, outer, inner, padding) == 59
+
+ # '| Lettuce green vegetable |'
+ outer, inner = 2, 0
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == 57
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 55
+ assert column_max_width(inner_widths, 2, outer, inner, padding) == 59
+
+ # ' Lettuce green vegetable '
+ outer = 0
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == 59
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 57
+ assert column_max_width(inner_widths, 2, outer, inner, padding) == 61
+
+ # '|Lettuce |green |vegetable |'
+ outer, inner, padding = 2, 1, 1
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == 58
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 56
+ assert column_max_width(inner_widths, 2, outer, inner, padding) == 60
+
+ # '|Lettuce |green |vegetable |'
+ padding = 5
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == 46
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 44
+ assert column_max_width(inner_widths, 2, outer, inner, padding) == 48
+
+ table_data = [
+ ['Name', 'Color', 'Type'],
+ ['Avocado', 'green', 'nut'],
+ ['Tomato', 'red', 'fruit'],
+ ['Lettuce', 'green', 'vegetable'],
+ ['Watermelon', 'green', 'fruit'],
+ ]
+ inner_widths = max_dimensions(table_data)[0]
+ outer, inner, padding = 2, 1, 2
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == 55
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 50
+ assert column_max_width(inner_widths, 2, outer, inner, padding) == 54
+
+
+def test_multi_line(monkeypatch):
+ """Test with multi-line cells.
+
+ :param monkeypatch: pytest fixture.
+ """
+ table_data = [
+ ['Show', 'Characters'],
+ ['Rugrats', ('Tommy Pickles, Chuckie Finster, Phillip DeVille, Lillian DeVille, Angelica Pickles,\n'
+ 'Susie Carmichael, Dil Pickles, Kimi Finster, Spike')],
+ ['South Park', 'Stan Marsh, Kyle Broflovski, Eric Cartman, Kenny McCormick']
+ ]
+ inner_widths = max_dimensions(table_data)[0]
+ outer, inner, padding = 2, 1, 2
+
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == -11
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 62
+
+ monkeypatch.setattr('terminaltables.width_and_alignment.terminal_size', lambda: (100, 24))
+ assert column_max_width(inner_widths, 0, outer, inner, padding) == 10
+ assert column_max_width(inner_widths, 1, outer, inner, padding) == 83
diff --git a/tests/test_width_and_alignment/test_max_dimensions.py b/tests/test_width_and_alignment/test_max_dimensions.py
new file mode 100644
index 0000000..fc97883
--- /dev/null
+++ b/tests/test_width_and_alignment/test_max_dimensions.py
@@ -0,0 +1,100 @@
+# coding: utf-8
+"""Test function in module."""
+
+import pytest
+from colorama import Fore
+from colorclass import Color
+from termcolor import colored
+
+from terminaltables.width_and_alignment import max_dimensions
+
+
+@pytest.mark.parametrize('table_data,expected_w,expected_h', [
+ ([[]], [], [0]),
+ ([['']], [0], [0]),
+ ([['', '']], [0, 0], [0]),
+
+ ([[], []], [], [0, 0]),
+ ([[''], ['']], [0], [0, 0]),
+ ([['', ''], ['', '']], [0, 0], [0, 0]),
+])
+def test_zero_length(table_data, expected_w, expected_h):
+ """Test zero-length or empty tables.
+
+ :param list table_data: Input table data to test.
+ :param list expected_w: Expected widths.
+ :param list expected_h: Expected heights.
+ """
+ actual = max_dimensions(table_data)
+ assert actual == (expected_w, expected_h, expected_w, expected_h)
+
+
+def test_single_line():
+ """Test widths."""
+ table_data = [
+ ['Name', 'Color', 'Type'],
+ ['Avocado', 'green', 'nut'],
+ ['Tomato', 'red', 'fruit'],
+ ['Lettuce', 'green', 'vegetable'],
+ ]
+ assert max_dimensions(table_data, 1, 1) == ([7, 5, 9], [1, 1, 1, 1], [9, 7, 11], [1, 1, 1, 1])
+
+ table_data.append(['Watermelon', 'green', 'fruit'])
+ assert max_dimensions(table_data, 2, 2) == ([10, 5, 9], [1, 1, 1, 1, 1], [14, 9, 13], [1, 1, 1, 1, 1])
+
+
+def test_multi_line():
+ """Test heights."""
+ table_data = [
+ ['One\nTwo', 'Buckle\nMy\nShoe'],
+ ]
+ assert max_dimensions(table_data, 0, 0, 1, 1) == ([3, 6], [3], [3, 6], [5])
+
+ table_data = [
+ ['Show', 'Characters'],
+ ['Rugrats', ('Tommy Pickles, Chuckie Finster, Phillip DeVille, Lillian DeVille, Angelica Pickles,\n'
+ 'Susie Carmichael, Dil Pickles, Kimi Finster, Spike')],
+ ['South Park', 'Stan Marsh, Kyle Broflovski, Eric Cartman, Kenny McCormick']
+ ]
+ assert max_dimensions(table_data, 0, 0, 2, 2) == ([10, 83], [1, 2, 1], [10, 83], [5, 6, 5])
+
+
+def test_trailing_newline():
+ r"""Test with trailing \n."""
+ table_data = [
+ ['Row One\n<blank>'],
+ ['<blank>\nRow Two'],
+ ['Row Three\n'],
+ ['\nRow Four'],
+ ]
+ assert max_dimensions(table_data) == ([9], [2, 2, 2, 2], [9], [2, 2, 2, 2])
+
+
+def test_colors_cjk_rtl():
+ """Test color text, CJK characters, and RTL characters."""
+ table_data = [
+ [Color('{blue}Test{/blue}')],
+ [Fore.BLUE + 'Test' + Fore.RESET],
+ [colored('Test', 'blue')],
+ ]
+ assert max_dimensions(table_data) == ([4], [1, 1, 1], [4], [1, 1, 1])
+
+ table_data = [
+ ['蓝色'],
+ ['世界你好'],
+ ]
+ assert max_dimensions(table_data) == ([8], [1, 1], [8], [1, 1])
+
+ table_data = [
+ ['שלום'],
+ ['معرب'],
+ ]
+ assert max_dimensions(table_data) == ([4], [1, 1], [4], [1, 1])
+
+
+def test_non_string():
+ """Test with non-string values."""
+ table_data = [
+ [123, 0.9, None, True, False],
+ ]
+ assert max_dimensions(table_data) == ([3, 3, 4, 4, 5], [1], [3, 3, 4, 4, 5], [1])
diff --git a/tests/test_width_and_alignment/test_table_width.py b/tests/test_width_and_alignment/test_table_width.py
new file mode 100644
index 0000000..5818789
--- /dev/null
+++ b/tests/test_width_and_alignment/test_table_width.py
@@ -0,0 +1,70 @@
+"""Test function in module."""
+
+from terminaltables.width_and_alignment import max_dimensions, table_width
+
+
+def test_empty():
+ """Test with zero-length cells."""
+ assert table_width(max_dimensions([['']])[2], 0, 0) == 0
+ assert table_width(max_dimensions([['', '', '']])[2], 0, 0) == 0
+ assert table_width(max_dimensions([['', '', ''], ['', '', '']])[2], 0, 0) == 0
+
+ assert table_width(max_dimensions([['']], 1, 1)[2], 2, 1) == 4
+ assert table_width(max_dimensions([['', '', '']], 1, 1)[2], 2, 1) == 10
+ assert table_width(max_dimensions([['', '', ''], ['', '', '']], 1, 1)[2], 2, 1) == 10
+
+
+def test_single_line():
+ """Test with single-line cells."""
+ table_data = [
+ ['Name', 'Color', 'Type'],
+ ['Avocado', 'green', 'nut'],
+ ['Tomato', 'red', 'fruit'],
+ ['Lettuce', 'green', 'vegetable'],
+ ]
+
+ # '| Lettuce | green | vegetable |'
+ outer, inner, outer_widths = 2, 1, max_dimensions(table_data, 1, 1)[2]
+ assert table_width(outer_widths, outer, inner) == 31
+
+ # ' Lettuce | green | vegetable '
+ outer = 0
+ assert table_width(outer_widths, outer, inner) == 29
+
+ # '| Lettuce green vegetable |'
+ outer, inner = 2, 0
+ assert table_width(outer_widths, outer, inner) == 29
+
+ # ' Lettuce green vegetable '
+ outer = 0
+ assert table_width(outer_widths, outer, inner) == 27
+
+ # '|Lettuce |green |vegetable |'
+ outer, inner, outer_widths = 2, 1, max_dimensions(table_data, 1)[2]
+ assert table_width(outer_widths, outer, inner) == 28
+
+ # '|Lettuce |green |vegetable |'
+ outer_widths = max_dimensions(table_data, 3, 2)[2]
+ assert table_width(outer_widths, outer, inner) == 40
+
+ table_data = [
+ ['Name', 'Color', 'Type'],
+ ['Avocado', 'green', 'nut'],
+ ['Tomato', 'red', 'fruit'],
+ ['Lettuce', 'green', 'vegetable'],
+ ['Watermelon', 'green', 'fruit'],
+ ]
+ outer, inner, outer_widths = 2, 1, max_dimensions(table_data, 1, 1)[2]
+ assert table_width(outer_widths, outer, inner) == 34
+
+
+def test_multi_line():
+ """Test with multi-line cells."""
+ table_data = [
+ ['Show', 'Characters'],
+ ['Rugrats', ('Tommy Pickles, Chuckie Finster, Phillip DeVille, Lillian DeVille, Angelica Pickles,\n'
+ 'Susie Carmichael, Dil Pickles, Kimi Finster, Spike')],
+ ['South Park', 'Stan Marsh, Kyle Broflovski, Eric Cartman, Kenny McCormick']
+ ]
+ outer, inner, outer_widths = 2, 1, max_dimensions(table_data, 1, 1)[2]
+ assert table_width(outer_widths, outer, inner) == 100
diff --git a/tests/test_width_and_alignment/test_visible_width.py b/tests/test_width_and_alignment/test_visible_width.py
new file mode 100644
index 0000000..79cebcb
--- /dev/null
+++ b/tests/test_width_and_alignment/test_visible_width.py
@@ -0,0 +1,59 @@
+# coding: utf-8
+"""Test function in module."""
+
+import pytest
+from colorama import Fore
+from colorclass import Color
+from termcolor import colored
+
+from terminaltables.width_and_alignment import visible_width
+
+
+@pytest.mark.parametrize('string,expected', [
+ # str
+ ('hello, world', 12),
+ ('世界你好', 8),
+ ('蓝色', 4),
+ ('שלום', 4),
+ ('معرب', 4),
+ ('hello 世界', 10),
+
+ # str+ansi
+ ('\x1b[34mhello, world\x1b[39m', 12),
+ ('\x1b[34m世界你好\x1b[39m', 8),
+ ('\x1b[34m蓝色\x1b[39m', 4),
+ ('\x1b[34mשלום\x1b[39m', 4),
+ ('\x1b[34mمعرب\x1b[39m', 4),
+ ('\x1b[34mhello 世界\x1b[39m', 10),
+
+ # colorclass
+ (Color(u'{blue}hello, world{/blue}'), 12),
+ (Color(u'{blue}世界你好{/blue}'), 8),
+ (Color(u'{blue}蓝色{/blue}'), 4),
+ (Color(u'{blue}שלום{/blue}'), 4),
+ (Color(u'{blue}معرب{/blue}'), 4),
+ (Color(u'{blue}hello 世界{/blue}'), 10),
+
+ # colorama
+ (Fore.BLUE + 'hello, world' + Fore.RESET, 12),
+ (Fore.BLUE + '世界你好' + Fore.RESET, 8),
+ (Fore.BLUE + '蓝色' + Fore.RESET, 4),
+ (Fore.BLUE + 'שלום' + Fore.RESET, 4),
+ (Fore.BLUE + 'معرب' + Fore.RESET, 4),
+ (Fore.BLUE + 'hello 世界' + Fore.RESET, 10),
+
+ # termcolor
+ (colored('hello, world', 'blue'), 12),
+ (colored('世界你好', 'blue'), 8),
+ (colored('蓝色', 'blue'), 4),
+ (colored('שלום', 'blue'), 4),
+ (colored('معرب', 'blue'), 4),
+ (colored('hello 世界', 'blue'), 10),
+])
+def test(string, expected):
+ """Test function with different color libraries.
+
+ :param str string: Input string to measure.
+ :param int expected: Expected visible width of string (some characters are len() == 1 but take up 2 spaces).
+ """
+ assert visible_width(string) == expected