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_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 cal_dimensions(schema: Schema, rows: List[dict]): """Calculate dimensions of a table so that we can render it properly""" meta = {"current_dim": None, "nested_dims": {}} placeholder = {} for attr, val in schema.attributes.items(): if isinstance(val, Schema): if val.is_list_of_objects: meta['nested_dims'][attr], sample_str = cal_dimensions( val, [r for row in rows for r in row[attr]]) else: meta['nested_dims'][attr], sample_str = cal_dimensions( val, [row[attr] for row in rows]) placeholder[attr] = sample_str elif val == Schema.LIST_VALUE: nested_arrays = [[r] for row in rows if row[attr] is not None for r in row[attr]] instance = clazz(nested_arrays[:1]) dimensions = max_dimensions(nested_arrays, instance.padding_left, instance.padding_right)[:3] meta['nested_dims'][attr] = { "current_dim": (dimensions[0], dimensions[2]), "nested_dims": {} } placeholder[attr] = build.flatten( instance.gen_table(dimensions[0], dimensions[1][:1], dimensions[2])) arrays = [[]] for attr, val in schema.attributes.items(): if isinstance(val, Schema): arrays[-1].append(placeholder[attr]) else: arrays[-1].append(attr) for row in rows: array = [] for attr, val in schema.attributes.items(): if isinstance(val, Schema) or val == Schema.LIST_VALUE: array.append(placeholder[attr]) else: array.append(row[attr]) arrays.append(array) instance = clazz([arrays[0]]) dimensions = max_dimensions(arrays, instance.padding_left, instance.padding_right)[:3] meta['current_dim'] = dimensions[0], dimensions[2] sample_str = build.flatten( instance.gen_table(dimensions[0], dimensions[1][:1], dimensions[2])) return meta, sample_str
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 table(self): """Return a large string of the entire table ready to be printed to the terminal.""" column_widths = [c + self.padding_left + self.padding_right for c in self.column_widths] widths, heights = max_dimensions(self.table_data) final_table_data = list() for row_index, row_data in enumerate(self.table_data): for line in self.gen_cell_lines(row_data, widths, heights[row_index]): final_table_data.append(''.join(line)) if row_index != 0: continue # Header row separator. column_separators = [] for column_index, column_width in enumerate(column_widths): column_justify = self.justify_columns.get(column_index) if column_justify == 'left': separator = ':' + self.CHAR_HORIZONTAL * (column_width - 1) elif column_justify == 'right': separator = self.CHAR_HORIZONTAL * (column_width - 1) + ':' elif column_justify == 'center': separator = self.CHAR_HORIZONTAL * (column_width - 2) separator = ':' + separator + ':' else: separator = self.CHAR_HORIZONTAL * column_width column_separators.append(separator) final_table_data.append( self.CHAR_VERTICAL + self.CHAR_VERTICAL.join(column_separators) + self.CHAR_VERTICAL ) return '\n'.join(final_table_data)
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
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])
def test_heading_footing(inner_column_border, outer_border, style): """Test heading and footing borders. :param bool inner_column_border: Passed to table class. :param bool outer_border: Passed to table class. :param str style: Passed to method. """ table = BaseTable(SINGLE_LINE) table.inner_column_border = inner_column_border table.outer_border = outer_border outer_widths = max_dimensions(table.table_data, table.padding_left, table.padding_right)[2] # Determine expected. if style == 'heading' and outer_border: expected = '+---------+-------+-----------+' if inner_column_border else '+---------------------------+' elif style == 'heading': expected = '---------+-------+-----------' if inner_column_border else '---------------------------' elif style == 'footing' and outer_border: expected = '+---------+-------+-----------+' if inner_column_border else '+---------------------------+' else: expected = '---------+-------+-----------' if inner_column_border else '---------------------------' # Test. actual = ''.join(table.horizontal_border(style, outer_widths)) assert actual == expected
def test_outer_borders(outer_border): """Test left/right/top/bottom table borders. :param bool outer_border: Passed to table. """ table_data = [ ['Name', 'Color', 'Type'], ['Avocado', 'green', 'nut'], ['Tomato', 'red', 'fruit'], ['Lettuce', 'green', 'vegetable'], ] table = BaseTable(table_data, 'Example Table') table.outer_border = outer_border inner_widths, inner_heights, outer_widths = max_dimensions( table_data, table.padding_left, table.padding_right)[:3] actual = flatten(table.gen_table(inner_widths, inner_heights, outer_widths)) # Determine expected. if outer_border: expected = ('+Example Table----+-----------+\n' '| Name | Color | Type |\n' '+---------+-------+-----------+\n' '| Avocado | green | nut |\n' '| Tomato | red | fruit |\n' '| Lettuce | green | vegetable |\n' '+---------+-------+-----------+') else: expected = (' Name | Color | Type \n' '---------+-------+-----------\n' ' Avocado | green | nut \n' ' Tomato | red | fruit \n' ' Lettuce | green | vegetable ') assert actual == expected
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) == ([7, 5, 9], [1, 1, 1, 1]) assert max_dimensions(table_data, [1, 1, 0, 0]) == ([9, 7, 11], [1, 1, 1, 1]) table_data.append(['Watermelon', 'green', 'fruit']) assert max_dimensions(table_data) == ([10, 5, 9], [1, 1, 1, 1, 1]) assert max_dimensions(table_data, [2, 2, 0, 0]) == ([14, 9, 13], [1, 1, 1, 1, 1])
def test_row(inner_column_border, outer_border): """Test inner borders. :param bool inner_column_border: Passed to table class. :param bool outer_border: Passed to table class. """ table = BaseTable(SINGLE_LINE) table.inner_column_border = inner_column_border table.outer_border = outer_border outer_widths = max_dimensions(table.table_data, table.padding_left, table.padding_right)[2] # Determine expected. if inner_column_border and outer_border: expected = '+---------+-------+-----------+' elif inner_column_border: expected = '---------+-------+-----------' elif outer_border: expected = '+---------------------------+' else: expected = '---------------------------' # Test. actual = ''.join(table.horizontal_border('row', outer_widths)) assert actual == expected
def table_width(self): """Return the width of the table including padding and borders.""" outer_widths = max_dimensions(self.table_data, self.padding_left, self.padding_right)[2] outer_border = 2 if self.outer_border else 0 inner_border = 1 if self.inner_column_border else 0 return table_width(outer_widths, outer_border, inner_border)
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 ascii_table_last(ascii_table): dimensions = max_dimensions(ascii_table.table_data, ascii_table.padding_left, ascii_table.padding_right)[:3] whole_table = ascii_table.table_data ascii_table.table_data = (ascii_table.table_data[-1], ) last_table = flatten(ascii_table.gen_table(*dimensions)) ascii_table.table_data = whole_table return last_table
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])
def table(self): """Return a large string of the entire table ready to be printed to the terminal.""" widths = [ c + self.padding_left + self.padding_right for c in self.column_widths ] inner_widths, inner_heights = width_and_alignment.max_dimensions( self.table_data) final_table_data = list() # Append top border. if self.outer_border: final_table_data.append(''.join( build_border( widths, self.CHAR_HORIZONTAL, self.CHAR_CORNER_UPPER_LEFT, self.CHAR_INTERSECT_TOP if self.inner_column_border else '', self.CHAR_CORNER_UPPER_RIGHT, self.title))) # Build table body. indexes = range(len(self.table_data)) for i in indexes: for line in self.gen_cell_lines(self.table_data[i], inner_widths, inner_heights[i]): final_table_data.append(''.join(line)) # Insert row separator. if i == indexes[-1]: continue # Last row. if self.inner_row_border or (self.inner_heading_row_border and i == 0): final_table_data.append(''.join( build_border( widths, self.CHAR_HORIZONTAL, self.CHAR_INTERSECT_LEFT if self.outer_border else '', self.CHAR_INTERSECT_CENTER if self.inner_column_border else '', self.CHAR_INTERSECT_RIGHT if self.outer_border else ''))) if i == indexes[-2] and self.inner_footing_row_border: final_table_data.append(''.join( build_border( widths, self.CHAR_HORIZONTAL, self.CHAR_INTERSECT_LEFT if self.outer_border else '', self.CHAR_INTERSECT_CENTER if self.inner_column_border else '', self.CHAR_INTERSECT_RIGHT if self.outer_border else ''))) # Append bottom border. if self.outer_border: final_table_data.append(''.join( build_border( widths, self.CHAR_HORIZONTAL, self.CHAR_CORNER_LOWER_LEFT, self.CHAR_INTERSECT_BOTTOM if self.inner_column_border else '', self.CHAR_CORNER_LOWER_RIGHT))) return '\n'.join(final_table_data)
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
def render_tbl(title, arrays, meta_dim): inst = clazz(arrays) inst.title = title inst.inner_heading_row_border = False inst.inner_row_border = inner_row_border dimensions = max_dimensions(inst.table_data, inst.padding_left, inst.padding_right)[:3] return build.flatten( inst.gen_table(meta_dim['current_dim'][0], dimensions[1], meta_dim['current_dim'][1]))
def table(self): """Return a large string of the entire table ready to be printed to the terminal.""" widths = [c + self.padding_left + self.padding_right for c in self.column_widths] inner_widths, inner_heights = width_and_alignment.max_dimensions(self.table_data) final_table_data = list() # Append top border. if self.outer_border: final_table_data.append(''.join(build_border( widths, self.CHAR_HORIZONTAL, self.CHAR_CORNER_UPPER_LEFT, self.CHAR_INTERSECT_TOP if self.inner_column_border else '', self.CHAR_CORNER_UPPER_RIGHT, self.title ))) # Build table body. indexes = range(len(self.table_data)) for i in indexes: for line in self.gen_cell_lines(self.table_data[i], inner_widths, inner_heights[i]): final_table_data.append(''.join(line)) # Insert row separator. if i == indexes[-1]: continue # Last row. if self.inner_row_border or (self.inner_heading_row_border and i == 0): final_table_data.append(''.join(build_border( widths, self.CHAR_HORIZONTAL, self.CHAR_INTERSECT_LEFT if self.outer_border else '', self.CHAR_INTERSECT_CENTER if self.inner_column_border else '', self.CHAR_INTERSECT_RIGHT if self.outer_border else '' ))) if i == indexes[-2] and self.inner_footing_row_border: final_table_data.append(''.join(build_border( widths, self.CHAR_HORIZONTAL, self.CHAR_INTERSECT_LEFT if self.outer_border else '', self.CHAR_INTERSECT_CENTER if self.inner_column_border else '', self.CHAR_INTERSECT_RIGHT if self.outer_border else '' ))) # Append bottom border. if self.outer_border: final_table_data.append(''.join(build_border( widths, self.CHAR_HORIZONTAL, self.CHAR_CORNER_LOWER_LEFT, self.CHAR_INTERSECT_BOTTOM if self.inner_column_border else '', self.CHAR_CORNER_LOWER_RIGHT ))) return '\n'.join(final_table_data)
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_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]) table_data = [ ['蓝色'], ['世界你好'], ] assert max_dimensions(table_data) == ([8], [1, 1]) table_data = [ ['שלום'], ['معرب'], ] assert max_dimensions(table_data) == ([4], [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 column_max_width(self, column_number): """Return the maximum width of a column based on the current terminal width. :param int column_number: The column number to query. :return: The max width of the column. :rtype: int """ inner_widths = max_dimensions(self.table_data)[0] outer_border = 2 if self.outer_border else 0 inner_border = 1 if self.inner_column_border else 0 padding = self.padding_left + self.padding_right return column_max_width(inner_widths, column_number, outer_border, inner_border, padding)
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_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_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
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 table(self): """ Return a large string of the entire table ready to be printed to the terminal. In this version we actually add a padding of one space to the title. It looks nicer that way. """ if self.title: self.title = " %s " % self.title.strip( ) # add spaces around the title (remove existing ones beforehand) if self.__column_widths: dimensions = (self.column_widths, [1] * len(self.table_data), [i + 2 for i in self.column_widths]) else: dimensions = max_dimensions(self.table_data, self.padding_left, self.padding_right)[:3] return flatten(self.gen_table(*dimensions))
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_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
def test_top_bottom(inner_column_border, style): """Test top and bottom borders. :param bool inner_column_border: Passed to table class. :param str style: Passed to method. """ table = BaseTable(SINGLE_LINE, 'Example') table.inner_column_border = inner_column_border outer_widths = max_dimensions(table.table_data, table.padding_left, table.padding_right)[2] # Determine expected. if style == 'top' and inner_column_border: expected = '+Example--+-------+-----------+' elif style == 'top': expected = '+Example--------------------+' elif style == 'bottom' and inner_column_border: expected = '+---------+-------+-----------+' else: expected = '+---------------------------+' # Test. actual = ''.join(table.horizontal_border(style, outer_widths)) assert actual == expected
def table(self): """Return a large string of the entire table ready to be printed to the terminal.""" column_widths = [ c + self.padding_left + self.padding_right for c in self.column_widths ] widths, heights = max_dimensions(self.table_data) final_table_data = list() for row_index, row_data in enumerate(self.table_data): for line in self.gen_cell_lines(row_data, widths, heights[row_index]): final_table_data.append(''.join(line)) if row_index != 0: continue # Header row separator. column_separators = [] for column_index, column_width in enumerate(column_widths): column_justify = self.justify_columns.get(column_index) if column_justify == 'left': separator = ':' + self.CHAR_HORIZONTAL * (column_width - 1) elif column_justify == 'right': separator = self.CHAR_HORIZONTAL * (column_width - 1) + ':' elif column_justify == 'center': separator = self.CHAR_HORIZONTAL * (column_width - 2) separator = ':' + separator + ':' else: separator = self.CHAR_HORIZONTAL * column_width column_separators.append(separator) final_table_data.append( self.CHAR_VERTICAL + self.CHAR_VERTICAL.join(column_separators) + self.CHAR_VERTICAL) return '\n'.join(final_table_data)
def test_outer_borders(outer_border): """Test left/right/top/bottom table borders. :param bool outer_border: Passed to table. """ table_data = [ ['Name', 'Color', 'Type'], ['Avocado', 'green', 'nut'], ['Tomato', 'red', 'fruit'], ['Lettuce', 'green', 'vegetable'], ] table = BaseTable(table_data, 'Example Table') table.outer_border = outer_border inner_widths, inner_heights, outer_widths = max_dimensions(table_data, table.padding_left, table.padding_right)[:3] actual = flatten(table.gen_table(inner_widths, inner_heights, outer_widths)) # Determine expected. if outer_border: expected = ( '+Example Table----+-----------+\n' '| Name | Color | Type |\n' '+---------+-------+-----------+\n' '| Avocado | green | nut |\n' '| Tomato | red | fruit |\n' '| Lettuce | green | vegetable |\n' '+---------+-------+-----------+' ) else: expected = ( ' Name | Color | Type \n' '---------+-------+-----------\n' ' Avocado | green | nut \n' ' Tomato | red | fruit \n' ' Lettuce | green | vegetable ' ) assert actual == expected
def make_table_rows(title, table_data): table = AsciiTable(table_data, title) dimensions = max_dimensions(table.table_data, table.padding_left, table.padding_right)[:3] output = table.gen_table(*dimensions) return map(lambda i: ''.join(i), list(output))
def gen_table(table): dimensions = max_dimensions(table.table_data, table.padding_left, table.padding_right)[:3] return [''.join(r) for r in table.gen_table(*dimensions)]
def table(rows, title='', prefix='', alignment=(), wrap_width=-1, indent=wrap_indent): """Format the list of rows as a table. - Each row is a sequence of column cells. - The first row defines the column headers. When terminaltables package is accessible, use it to get nice pretty tables, otherwise use some home-made primitive replacement - see https://pypi.org/project/terminaltables - see https://github.com/Robpol86/terminaltables >>> table_data = [ ... ( 'Name' , 'Occupation' , 'Note' ) , ... ( 'Alice' , '?' , '---' ) , ... ( 'Bob' , 'unemployed' , '' ) ] >>> t = table ( table_data , 'Title' ) >>> print (t) """ from ostap.utils.basic import isatty title = allright(decolorize(title)) if rows: rows = list(rows) header_row = rows[0] header_row = [infostr(decolorize(c)) for c in header_row] rows[0] = header_row rows = tuple(rows) rows = [list(row) for row in rows] if not terminaltables: ## use the local replacement return the_table(rows, title, prefix, alignment=alignment) if isatty(): title = allright(title) table_instance = terminaltables.SingleTable(rows, title) else: title = allright(title) table_instance = terminaltables.AsciiTable(rows, title) cw = table_instance.column_widths nc = len(cw) wraps = [i for (i, a) in enumerate(alignment) if a in wrapped] if wraps: from terminaltables.width_and_alignment import max_dimensions widths = max_dimensions(table_instance.table_data, table_instance.padding_left, table_instance.padding_right)[2] widths = sum(l for (i, l) in enumerate(widths) if not i in wraps) widths += nc + 1 + len(prefix) + 4 + 2 * len(wraps) _, w = terminal_size() ww = w - widths ww, _ = divmod(ww, len(wraps)) if 12 < ww and ww < wrap_width: wrap_width = ww elif 12 < ww and wrap_width <= 0: wrap_width = ww if wrap_width < 12: wrap_width = max_width nw = len(wraps) for i, a in zip(range(nc), alignment): if a and isinstance(a, str): al = a.lower() if al in left: table_instance.justify_columns[i] = 'left' elif al in right: table_instance.justify_columns[i] = 'right' elif al in center: table_instance.justify_columns[i] = 'center' elif al in wrapped: maxw = table_instance.column_max_width(i) if 15 < wrap_width * nw < maxw: maxw = (wrap_width - 3) * nw if 1 < nw else wrap_width if maxw < 15: maxw = (wrap_width - 3) * nw if 1 < nw else wrap_width if maxw < 15: maxw = (max_width - 3) * nw if 1 < nw else max_width width = maxw / nw if 1 < nw else maxw for l, line in enumerate(table_instance.table_data): if width < len(line[i]): table_instance.table_data[l][i] = textwrap.fill( indent + line[i], wrap_width) return add_prefix(table_instance.table, prefix)
def column_widths(self): """Return a list of integers representing the widths of each table column without padding.""" if not self.table_data: return list() return max_dimensions(self.table_data)[0]
def get_max_dimensions(ascii_table): return max_dimensions(ascii_table.table_data, ascii_table.padding_left, ascii_table.padding_right)[:3]
def test_one_no_rows(mode, bare): """Test with one or no rows. :param str mode: Type of table contents to test. :param bool bare: Disable padding/borders. """ if mode == 'row': table_data = [ ['Avocado', 'green', 'nut'], ] elif mode == 'one': table_data = [ ['Avocado'], ] elif mode == 'blank': table_data = [ [''], ] elif mode == 'empty': table_data = [ [], ] else: table_data = [ ] table = BaseTable(table_data) if bare: table.inner_column_border = False table.inner_footing_row_border = False table.inner_heading_row_border = False table.inner_row_border = False table.outer_border = False table.padding_left = 0 table.padding_right = 0 inner_widths, inner_heights, outer_widths = max_dimensions(table_data, table.padding_left, table.padding_right)[:3] actual = flatten(table.gen_table(inner_widths, inner_heights, outer_widths)) # Determine expected. if mode == 'row': if bare: expected = ( 'Avocadogreennut' ) else: expected = ( '+---------+-------+-----+\n' '| Avocado | green | nut |\n' '+---------+-------+-----+' ) elif mode == 'one': if bare: expected = ( 'Avocado' ) else: expected = ( '+---------+\n' '| Avocado |\n' '+---------+' ) elif mode == 'blank': # Remember there's still padding. if bare: expected = ( '' ) else: expected = ( '+--+\n' '| |\n' '+--+' ) elif mode == 'empty': if bare: expected = ( '' ) else: expected = ( '++\n' '||\n' '++' ) else: if bare: expected = ( '' ) else: expected = ( '++\n' '++' ) assert actual == expected
def table(self): """Return a large string of the entire table ready to be printed to the terminal.""" dimensions = max_dimensions(self.table_data, self.padding_left, self.padding_right)[:3] return flatten(self.gen_table(*dimensions))
def test_inner_row_borders(inner_heading_row_border, inner_footing_row_border, inner_row_border): """Test heading/footing/row borders. :param bool inner_heading_row_border: Passed to table. :param bool inner_footing_row_border: Passed to table. :param bool inner_row_border: Passed to table. """ table_data = [ ['Name', 'Color', 'Type'], ['Avocado', 'green', 'nut'], ['Tomato', 'red', 'fruit'], ['Lettuce', 'green', 'vegetable'], ] table = BaseTable(table_data) table.inner_heading_row_border = inner_heading_row_border table.inner_footing_row_border = inner_footing_row_border table.inner_row_border = inner_row_border inner_widths, inner_heights, outer_widths = max_dimensions(table_data, table.padding_left, table.padding_right)[:3] actual = flatten(table.gen_table(inner_widths, inner_heights, outer_widths)) # Determine expected. if inner_row_border: expected = ( '+---------+-------+-----------+\n' '| Name | Color | Type |\n' '+---------+-------+-----------+\n' '| Avocado | green | nut |\n' '+---------+-------+-----------+\n' '| Tomato | red | fruit |\n' '+---------+-------+-----------+\n' '| Lettuce | green | vegetable |\n' '+---------+-------+-----------+' ) elif inner_heading_row_border and inner_footing_row_border: expected = ( '+---------+-------+-----------+\n' '| Name | Color | Type |\n' '+---------+-------+-----------+\n' '| Avocado | green | nut |\n' '| Tomato | red | fruit |\n' '+---------+-------+-----------+\n' '| Lettuce | green | vegetable |\n' '+---------+-------+-----------+' ) elif inner_heading_row_border: expected = ( '+---------+-------+-----------+\n' '| Name | Color | Type |\n' '+---------+-------+-----------+\n' '| Avocado | green | nut |\n' '| Tomato | red | fruit |\n' '| Lettuce | green | vegetable |\n' '+---------+-------+-----------+' ) elif inner_footing_row_border: expected = ( '+---------+-------+-----------+\n' '| Name | Color | Type |\n' '| Avocado | green | nut |\n' '| Tomato | red | fruit |\n' '+---------+-------+-----------+\n' '| Lettuce | green | vegetable |\n' '+---------+-------+-----------+' ) else: expected = ( '+---------+-------+-----------+\n' '| Name | Color | Type |\n' '| Avocado | green | nut |\n' '| Tomato | red | fruit |\n' '| Lettuce | green | vegetable |\n' '+---------+-------+-----------+' ) assert actual == expected