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_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_one_line(): """Test with one line cells.""" table = [ ['>', 'Left Cell', '|', 'Center Cell', '|', 'Right Cell', '<'], ] actual = flatten(table) expected = '>Left Cell|Center Cell|Right Cell<' assert actual == expected
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_two_line(): """Test with two line cells.""" table = [ ['>', 'Left ', '|', 'Center', '|', 'Right', '<'], ['>', 'Cell1', '|', 'Cell2 ', '|', 'Cell3', '<'], ] actual = flatten(table) expected = ('>Left |Center|Right<\n' '>Cell1|Cell2 |Cell3<') assert actual == expected
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. 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_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 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
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
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 test_two_line(): """Test with two line cells.""" table = [[">", "Left ", "|", "Center", "|", "Right", "<"], [">", "Cell1", "|", "Cell2 ", "|", "Cell3", "<"]] actual = flatten(table) expected = ">Left |Center|Right<\n" ">Cell1|Cell2 |Cell3<" assert actual == expected
def test_one_line(): """Test with one line cells.""" table = [[">", "Left Cell", "|", "Center Cell", "|", "Right Cell", "<"]] actual = flatten(table) expected = ">Left Cell|Center Cell|Right Cell<" assert actual == expected
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