Revision 0f383dcc

b/kamaki/cli/commands/pithos.py
39 39
from kamaki.cli.command_tree import CommandTree
40 40
from kamaki.cli.errors import raiseCLIError, CLISyntaxError, CLIBaseUrlError
41 41
from kamaki.cli.utils import (
42
    format_size, to_bytes, print_dict, print_items, pretty_keys, pretty_dict,
43
    page_hold, bold, ask_user, get_path_size, print_json, guess_mime_type)
42
    format_size, to_bytes, print_dict, print_items, page_hold, bold, ask_user,
43
    get_path_size, print_json, guess_mime_type)
44 44
from kamaki.cli.argument import FlagArgument, ValueArgument, IntArgument
45 45
from kamaki.cli.argument import KeyValueArgument, DateArgument
46 46
from kamaki.cli.argument import ProgressBarArgument
......
388 388
            prfx = ('%s%s. ' % (empty_space, index)) if self['enum'] else ''
389 389
            if self['detail']:
390 390
                print('%s%s' % (prfx, oname))
391
                print_dict(pretty_keys(pretty_obj), exclude=('name'))
391
                print_dict(pretty_obj, exclude=('name'))
392 392
                print
393 393
            else:
394 394
                oname = '%s%9s %s' % (prfx, size, oname)
......
413 413
                pretty_c = container.copy()
414 414
                if 'bytes' in container:
415 415
                    pretty_c['bytes'] = '%s (%s)' % (container['bytes'], size)
416
                print_dict(pretty_keys(pretty_c), exclude=('name'))
416
                print_dict(pretty_c, exclude=('name'))
417 417
                print
418 418
            else:
419 419
                if 'count' in container and 'bytes' in container:
......
1761 1761
        until = self['until']
1762 1762
        r = None
1763 1763
        if self.container is None:
1764
            if self['detail']:
1765
                r = self.client.get_account_info(until=until)
1766
            else:
1767
                r = self.client.get_account_meta(until=until)
1768
                r = pretty_keys(r, '-')
1764
            r = self.client.get_account_info(until=until)
1769 1765
        elif self.path is None:
1770 1766
            if self['detail']:
1771 1767
                r = self.client.get_container_info(until=until)
......
1774 1770
                ometa = self.client.get_container_object_meta(until=until)
1775 1771
                r = {}
1776 1772
                if cmeta:
1777
                    r['container-meta'] = pretty_keys(cmeta, '-')
1773
                    r['container-meta'] = cmeta
1778 1774
                if ometa:
1779
                    r['object-meta'] = pretty_keys(ometa, '-')
1775
                    r['object-meta'] = ometa
1780 1776
        else:
1781 1777
            if self['detail']:
1782 1778
                r = self.client.get_object_info(
......
1786 1782
                r = self.client.get_object_meta(
1787 1783
                    self.path,
1788 1784
                    version=self['object_version'])
1789
                r = pretty_keys(pretty_keys(r, '-'))
1790 1785
        if r:
1791 1786
            self._print(r, print_dict)
1792 1787

  
......
1859 1854
            if not self['in_bytes']:
1860 1855
                for k in output:
1861 1856
                    output[k] = format_size(output[k])
1862
            pretty_dict(output, '-')
1857
            print_dict(output, '-')
1863 1858

  
1864 1859
        self._print(self.client.get_account_quota(), pretty_print)
1865 1860

  
......
1889 1884
            if not self['in_bytes']:
1890 1885
                for k, v in output.items():
1891 1886
                    output[k] = 'unlimited' if '0' == v else format_size(v)
1892
            pretty_dict(output, '-')
1887
            print_dict(output, '-')
1893 1888

  
1894 1889
        self._print(
1895 1890
            self.client.get_container_limit(self.container), pretty_print)
......
2006 2001
    @errors.generic.all
2007 2002
    @errors.pithos.connection
2008 2003
    def _run(self):
2009
        self._print(self.client.get_account_group(), pretty_dict, delim='-')
2004
        self._print(self.client.get_account_group(), print_dict, delim='-')
2010 2005

  
2011 2006
    def main(self):
2012 2007
        super(self.__class__, self)._run()
b/kamaki/cli/utils/__init__.py
57 57
    suggest['ansicolors']['active'] = True
58 58

  
59 59

  
60
def _print(w):
61
    """Print wrapper is used to help unittests check what is printed"""
62
    print w
63

  
64

  
60 65
def suggest_missing(miss=None, exclude=[]):
61 66
    global suggest
62 67
    sgs = dict(suggest)
......
116 121

  
117 122
    :param data: json-dumpable data
118 123
    """
119
    print(dumps(data, indent=INDENT_TAB))
124
    _print(dumps(data, indent=INDENT_TAB))
120 125

  
121 126

  
122 127
def pretty_dict(d, *args, **kwargs):
......
156 161
        print_str += '%s.' % (i + 1) if with_enumeration else ''
157 162
        print_str += '%s:' % k
158 163
        if isinstance(v, dict):
159
            print print_str
164
            _print(print_str)
160 165
            print_dict(
161 166
                v, exclude, indent + INDENT_TAB,
162 167
                recursive_enumeration, recursive_enumeration)
163 168
        elif isinstance(v, list) or isinstance(v, tuple):
164
            print print_str
169
            _print(print_str)
165 170
            print_list(
166 171
                v, exclude, indent + INDENT_TAB,
167 172
                recursive_enumeration, recursive_enumeration)
168 173
        else:
169
            print '%s %s' % (print_str, v)
174
            _print('%s %s' % (print_str, v))
170 175

  
171 176

  
172 177
def print_list(
......
195 200
        'print_list prinbts a list or tuple')
196 201
    assert indent >= 0, 'print_list indent must be >= 0'
197 202

  
198
    counter = 0
199 203
    for i, item in enumerate(l):
200 204
        print_str = ' ' * indent
201 205
        print_str += '%s.' % (i + 1) if with_enumeration else ''
202 206
        if isinstance(item, dict):
203 207
            if with_enumeration:
204
                print print_str
205
            elif counter and counter < len(l):
206
                print
208
                _print(print_str)
209
            elif i and i < len(l):
210
                _print('')
207 211
            print_dict(
208 212
                item, exclude,
209 213
                indent + (INDENT_TAB if with_enumeration else 0),
210 214
                recursive_enumeration, recursive_enumeration)
211 215
        elif isinstance(item, list) or isinstance(item, tuple):
212 216
            if with_enumeration:
213
                print print_str
214
            elif counter and counter < len(l):
215
                print
217
                _print(print_str)
218
            elif i and i < len(l):
219
                _print()
216 220
            print_list(
217 221
                item, exclude, indent + INDENT_TAB,
218 222
                recursive_enumeration, recursive_enumeration)
......
220 224
            item = ('%s' % item).strip()
221 225
            if item in exclude:
222 226
                continue
223
            print '%s%s' % (print_str, item)
224
        counter += 1
227
            _print('%s%s' % (print_str, item))
225 228

  
226 229

  
227 230
def page_hold(index, limit, maxlen):
b/kamaki/cli/utils/test.py
33 33

  
34 34
from unittest import TestCase
35 35
#from tempfile import NamedTemporaryFile
36
#from mock import patch, call
36
from mock import patch, call
37 37
from itertools import product
38 38

  
39 39

  
......
63 63
            else:
64 64
                self.assertRaises(AssertionError, guess_mime_type, *args)
65 65

  
66
    def test_pretty_keys(self):
67
        from kamaki.cli.utils import pretty_keys
68
        for args, exp in (
69
                (
70
                    ({'k1': 'v1', 'k1_k2': 'v2'}, ),
71
                    {'k1': 'v1', 'k1 k2': 'v2'}),
72
                (
73
                    ({'k1': 'v1', 'k1_k2': 'v2'}, '1'),
74
                    {'k': 'v1', 'k _k2': 'v2'}),
75
                (
76
                    ({'k1_k2': 'v1', 'k1': {'k2': 'v2', 'k2_k3': 'v3'}}, ),
77
                    {'k1 k2': 'v1', 'k1': {'k2': 'v2', 'k2_k3': 'v3'}}),
78
                (
79
                    (
80
                        {'k1_k2': 'v1', 'k1': {'k2': 'v2', 'k2_k3': 'v3'}},
81
                        '_',
82
                        True),
83
                    {'k1 k2': 'v1', 'k1': {'k2': 'v2', 'k2 k3': 'v3'}}),
66
    @patch('kamaki.cli.utils.dumps', return_value='(dumps output)')
67
    @patch('kamaki.cli.utils._print')
68
    def test_print_json(self, PR, JD):
69
        from kamaki.cli.utils import print_json, INDENT_TAB
70
        print_json('some data')
71
        JD.assert_called_once_with('some data', indent=INDENT_TAB)
72
        PR.assert_called_once_with('(dumps output)')
73

  
74
    @patch('kamaki.cli.utils._print')
75
    def test_print_dict(self, PR):
76
        from kamaki.cli.utils import print_dict, INDENT_TAB
77
        call_counter = 0
78
        self.assertRaises(AssertionError, print_dict, 'non-dict think')
79
        self.assertRaises(AssertionError, print_dict, {}, indent=-10)
80
        for args in product(
84 81
                (
85
                    (
86
                        {
87
                            'k1_k2': {'k_1': 'v_1', 'k_2': {'k_3': 'v_3'}},
88
                            'k1': {'k2': 'v2', 'k2_k3': 'v3'}},
89
                        '_',
90
                        True),
82
                    {'k1': 'v1'},
83
                    {'k1': 'v1', 'k2': 'v2'},
84
                    {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'},
85
                    {'k1': 'v1', 'k2': {'k1': 'v1', 'k2': 'v2'}, 'k3': 'v3'},
91 86
                    {
92
                        'k1 k2': {'k 1': 'v_1', 'k 2': {'k 3': 'v_3'}},
93
                        'k1': {'k2': 'v2', 'k2 k3': 'v3'}}),
94
                (
95
                    (
96
                        {
97
                            'k1_k2': {'k_1': 'v_1', 'k_2': {'k_3': 'v_3'}},
98
                            'k1': {'k2': 'v2', 'k2_k3': 'v3'}},
99
                        '1',
100
                        True),
87
                        'k1': {'k1': 'v1', 'k2': 'v2'},
88
                        'k2': [1, 2, 3],
89
                        'k3': 'v3'},
90
                    {
91
                        'k1': {'k1': 'v1', 'k2': 'v2'},
92
                        'k2': 42,
93
                        'k3': {'k1': 1, 'k2': [1, 2, 3]}},
101 94
                    {
102
                        'k _k2': {'k_': 'v_1', 'k_2': {'k_3': 'v_3'}},
103
                        'k': {'k2': 'v2', 'k2_k3': 'v3'}})
104
            ):
105
            initial = dict(args[0])
106
            self.assert_dicts_are_equal(pretty_keys(*args), exp)
107
            self.assert_dicts_are_equal(initial, args[0])
95
                        'k1': {
96
                            'k1': 'v1',
97
                            'k2': [1, 2, 3],
98
                            'k3': {'k1': [(1, 2)]}},
99
                        'k2': (3, 4, 5),
100
                        'k3': {'k1': 1, 'k2': [1, 2, 3]}}),
101
                (tuple(), ('k1', ), ('k1', 'k2')),
102
                (0, 1, 2, 9), (False, True), (False, True)):
103
            d, exclude, indent, with_enumeration, recursive_enumeration = args
104
            with patch('kamaki.cli.utils.print_dict') as PD:
105
                with patch('kamaki.cli.utils.print_list') as PL:
106
                    pd_calls, pl_calls = 0, 0
107
                    print_dict(*args)
108
                    exp_calls = []
109
                    for i, (k, v) in enumerate(d.items()):
110
                        if k in exclude:
111
                            continue
112
                        str_k = ' ' * indent
113
                        str_k += '%s.' % (i + 1) if with_enumeration else ''
114
                        str_k += '%s:' % k
115
                        if isinstance(v, dict):
116
                            self.assertEqual(
117
                                PD.mock_calls[pd_calls],
118
                                call(
119
                                    v,
120
                                    exclude,
121
                                    indent + INDENT_TAB,
122
                                    recursive_enumeration,
123
                                    recursive_enumeration))
124
                            pd_calls += 1
125
                            exp_calls.append(call(str_k))
126
                        elif isinstance(v, list) or isinstance(v, tuple):
127
                            self.assertEqual(
128
                                PL.mock_calls[pl_calls],
129
                                call(
130
                                    v,
131
                                    exclude,
132
                                    indent + INDENT_TAB,
133
                                    recursive_enumeration,
134
                                    recursive_enumeration))
135
                            pl_calls += 1
136
                            exp_calls.append(call(str_k))
137
                        else:
138
                            exp_calls.append(call('%s %s' % (str_k, v)))
139
                    real_calls = PR.mock_calls[call_counter:]
140
                    call_counter = len(PR.mock_calls)
141
                    self.assertEqual(sorted(real_calls), sorted(exp_calls))
142

  
143
    @patch('kamaki.cli.utils._print')
144
    def test_print_list(self, PR):
145
        from kamaki.cli.utils import print_list, INDENT_TAB
146
        call_counter = 0
147
        self.assertRaises(AssertionError, print_list, 'non-list non-tuple')
148
        self.assertRaises(AssertionError, print_list, {}, indent=-10)
149
        for args in product(
150
                (
151
                    ['v1', ],
152
                    ('v2', 'v3'),
153
                    [1, '2', 'v3'],
154
                    ({'k1': 'v1'}, 2, 'v3'),
155
                    [(1, 2), 'v2', [(3, 4), {'k3': [5, 6], 'k4': 7}]]),
156
                (tuple(), ('v1', ), ('v1', 1), ('v1', 'k3')),
157
                (0, 1, 2, 9), (False, True), (False, True)):
158
            l, exclude, indent, with_enumeration, recursive_enumeration = args
159
            with patch('kamaki.cli.utils.print_dict') as PD:
160
                with patch('kamaki.cli.utils.print_list') as PL:
161
                    pd_calls, pl_calls = 0, 0
162
                    print_list(*args)
163
                    exp_calls = []
164
                    for i, v in enumerate(l):
165
                        str_v = ' ' * indent
166
                        str_v += '%s.' % (i + 1) if with_enumeration else ''
167
                        if isinstance(v, dict):
168
                            if with_enumeration:
169
                                exp_calls.append(call(str_v))
170
                            elif i and i < len(l):
171
                                exp_calls.append(call())
172
                            self.assertEqual(
173
                                PD.mock_calls[pd_calls],
174
                                call(
175
                                    v,
176
                                    exclude,
177
                                    indent + (
178
                                        INDENT_TAB if with_enumeration else 0),
179
                                    recursive_enumeration,
180
                                    recursive_enumeration))
181
                            pd_calls += 1
182
                        elif isinstance(v, list) or isinstance(v, tuple):
183
                            if with_enumeration:
184
                                exp_calls.append(call(str_v))
185
                            elif i and i < len(l):
186
                                exp_calls.append(call())
187
                            self.assertEqual(
188
                                PL.mock_calls[pl_calls],
189
                                call(
190
                                    v,
191
                                    exclude,
192
                                    indent + INDENT_TAB,
193
                                    recursive_enumeration,
194
                                    recursive_enumeration))
195
                            pl_calls += 1
196
                        elif ('%s' % v) in exclude:
197
                            continue
198
                        else:
199
                            exp_calls.append(call('%s%s' % (str_v, v)))
200
                    real_calls = PR.mock_calls[call_counter:]
201
                    call_counter = len(PR.mock_calls)
202
                    self.assertEqual(sorted(real_calls), sorted(exp_calls))
108 203

  
109 204

  
110 205
if __name__ == '__main__':

Also available in: Unified diff