diff --git a/ceilometerclient/common/utils.py b/ceilometerclient/common/utils.py index 4f532e5..d466a19 100644 --- a/ceilometerclient/common/utils.py +++ b/ceilometerclient/common/utils.py @@ -66,18 +66,20 @@ def print_list(objs, fields, field_labels, formatters={}, sortby=0): sortby_index=sortby) -def nested_dict_formatter(field): +def nested_list_of_dict_formatter(field, column_names): # (TMaddox) Because the formatting scheme actually drops the whole object # into the formatter, rather than just the specified field, we have to # extract it and then pass the value. - return lambda o: format_nested_dict(getattr(o, field)) + return lambda o: format_nested_list_of_dict(getattr(o, field), + column_names) -def format_nested_dict(d): +def format_nested_list_of_dict(l, column_names): pt = prettytable.PrettyTable(caching=False, print_empty=False, - header=False, hrules=prettytable.FRAME) - for k, v in six.iteritems(d): - pt.add_row([k, format_nested_dict(v) if isinstance(v, dict) else v]) + header=True, hrules=prettytable.FRAME, + field_names=column_names) + for d in l: + pt.add_row(map(lambda k: d[k], column_names)) return pt.get_string() diff --git a/ceilometerclient/tests/test_utils.py b/ceilometerclient/tests/test_utils.py index 5166343..1f3074b 100644 --- a/ceilometerclient/tests/test_utils.py +++ b/ceilometerclient/tests/test_utils.py @@ -14,6 +14,7 @@ # under the License. +import mock import six import sys @@ -182,3 +183,27 @@ class UtilsTest(test_utils.BaseTestCase): self.assertEqual(dest, {'key': 'modified', 'nested': {'key3': 'modified3', 'nested2': {'key5': 'value5'}}}) + + @mock.patch('prettytable.PrettyTable') + def test_format_nested_list_of_dict(self, pt_mock): + actual_rows = [] + + def mock_add_row(row): + actual_rows.append(row) + + table = mock.Mock() + table.add_row = mock_add_row + table.get_string.return_value = "the table" + + test_data = [ + {'column_1': 'value_11', 'column_2': 'value_21'}, + {'column_1': 'value_12', 'column_2': 'value_22'} + + ] + columns = ['column_1', 'column_2'] + pt_mock.return_value = table + + rval = utils.format_nested_list_of_dict(test_data, columns) + self.assertEqual("the table", rval) + self.assertEqual([['value_11', 'value_21'], ['value_12', 'value_22']], + actual_rows) diff --git a/ceilometerclient/v2/shell.py b/ceilometerclient/v2/shell.py index 6b63873..4402fbe 100644 --- a/ceilometerclient/v2/shell.py +++ b/ceilometerclient/v2/shell.py @@ -570,7 +570,10 @@ def do_event_list(cc, args={}): fields = ['message_id', 'event_type', 'generated', 'traits'] utils.print_list(events, fields, field_labels, formatters={ - 'traits': utils.nested_dict_formatter('traits')}) + 'traits': utils.nested_list_of_dict_formatter('traits', + ['name', + 'type', + 'value'])}) @utils.arg('-m', '--message_id', metavar='',