Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils / test.py @ 46d130c9

History | View | Annotate | Download (13.4 kB)

1
# Copyright 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

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

    
39

    
40
class UtilsMethods(TestCase):
41

    
42
    def assert_dicts_are_equal(self, d1, d2):
43
        for k, v in d1.items():
44
            self.assertTrue(k in d2)
45
            if isinstance(v, dict):
46
                self.assert_dicts_are_equal(v, d2[k])
47
            else:
48
                self.assertEqual(unicode(v), unicode(d2[k]))
49

    
50
    def test_guess_mime_type(self):
51
        from kamaki.cli.utils import guess_mime_type
52
        from mimetypes import guess_type
53
        for args in product(
54
                ('file.txt', 'file.png', 'file.zip', 'file.gz', None, 'X'),
55
                ('a type', None),
56
                ('an/encoding', None)):
57
            filename, ctype, cencoding = args
58
            if filename:
59
                exp_type, exp_enc = guess_type(filename)
60
                self.assertEqual(
61
                    guess_mime_type(*args),
62
                    (exp_type or ctype, exp_enc or cencoding))
63
            else:
64
                self.assertRaises(AssertionError, guess_mime_type, *args)
65

    
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(
81
                (
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'},
86
                    {
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]}},
94
                    {
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))
203

    
204
    @patch('__builtin__.raw_input')
205
    def test_page_hold(self, RI):
206
        from kamaki.cli.utils import page_hold
207
        ri_counter = 0
208
        for args, expected in (
209
                ((0, 0, 0), False),
210
                ((1, 3, 10), True),
211
                ((3, 3, 10), True),
212
                ((5, 3, 10), True),
213
                ((6, 3, 10), True),
214
                ((10, 3, 10), False),
215
                ((11, 3, 10), False)):
216
            self.assertEqual(page_hold(*args), expected)
217
            index, limit, maxlen = args
218
            if index and index < maxlen and index % limit == 0:
219
                self.assertEqual(ri_counter + 1, len(RI.mock_calls))
220
                self.assertEqual(RI.mock_calls[-1], call(
221
                    '(%s listed - %s more - "enter" to continue)' % (
222
                        index, maxlen - index)))
223
            else:
224
                self.assertEqual(ri_counter, len(RI.mock_calls))
225
            ri_counter = len(RI.mock_calls)
226

    
227
    @patch('kamaki.cli.utils._print')
228
    @patch('kamaki.cli.utils._write')
229
    @patch('kamaki.cli.utils.print_dict')
230
    @patch('kamaki.cli.utils.print_list')
231
    @patch('kamaki.cli.utils.page_hold')
232
    @patch('kamaki.cli.utils.bold', return_value='bold')
233
    def test_print_items(self, bold, PH, PL, PD, WR, PR):
234
        from kamaki.cli.utils import print_items, INDENT_TAB
235
        for args in product(
236
                (
237
                    42, None, 'simple outputs',
238
                    [1, 2, 3], {1: 1, 2: 2}, (3, 4),
239
                    ({'k': 1, 'id': 2}, [5, 6, 7], (8, 9), '10')),
240
                (('id', 'name'), ('something', 2), ('lala', )),
241
                (False, True),
242
                (False, True),
243
                (0, 1, 2, 10)):
244
            items, title, with_enumeration, with_redundancy, page_size = args
245
            wr_counter, pr_counter = len(WR.mock_calls), len(PR.mock_calls)
246
            pl_counter, pd_counter = len(PL.mock_calls), len(PD.mock_calls)
247
            bold_counter, ph_counter = len(bold.mock_calls), len(PH.mock_calls)
248
            print_items(*args)
249
            if not (isinstance(items, dict) or isinstance(
250
                    items, list) or isinstance(items, tuple)):
251
                self.assertEqual(PR.mock_calls[-1], call(
252
                    '%s' % items if items is not None else ''))
253
            else:
254
                for i, item in enumerate(items):
255
                    if with_enumeration:
256
                        self.assertEqual(
257
                            WR.mock_calls[wr_counter],
258
                            call('%s. ' % (i + 1)))
259
                        wr_counter += 1
260
                    if isinstance(item, dict):
261
                        title = sorted(set(title).intersection(item))
262
                        pick = item.get if with_redundancy else item.pop
263
                        header = ' '.join('%s' % pick(key) for key in title)
264
                        self.assertEqual(
265
                            bold.mock_calls[bold_counter], call(header))
266
                        self.assertEqual(
267
                            PR.mock_calls[pr_counter], call('bold'))
268
                        self.assertEqual(
269
                            PD.mock_calls[pd_counter],
270
                            call(item, indent=INDENT_TAB))
271
                        pr_counter += 1
272
                        pd_counter += 1
273
                        bold_counter += 1
274
                    elif isinstance(item, list) or isinstance(item, tuple):
275
                        self.assertEqual(
276
                            PL.mock_calls[pl_counter],
277
                            call(item, indent=INDENT_TAB))
278
                        pl_counter += 1
279
                    else:
280
                        self.assertEqual(
281
                            PR.mock_calls[pr_counter], call(' %s' % item))
282
                        pr_counter += 1
283
                    page_size = page_size if page_size > 0 else len(items)
284
                    self.assertEqual(
285
                        PH.mock_calls[ph_counter],
286
                        call(i + 1, page_size, len(items)))
287
                    ph_counter += 1
288

    
289

    
290
if __name__ == '__main__':
291
    from sys import argv
292
    from kamaki.cli.test import runTestCase
293
    runTestCase(UtilsMethods, 'UtilsMethods', argv[1:])