Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / command_tree / test.py @ ada3f332

History | View | Annotate | Download (16.2 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 mock import patch, call
35
from unittest import TestCase
36
from itertools import product
37

    
38
from kamaki.cli import command_tree
39

    
40

    
41
class Command(TestCase):
42

    
43
    def test___init__(self):
44
        for args in product(
45
                (None, '', 'cmd'),
46
                (None, '', 'Some help'),
47
                (None, '', {}, dict(cmd0a=None, cmd0b=None)),
48
                (None, command_tree.Command('cmd_cmd0'))):
49
            path, help, subcommands, cmd_class = args
50
            try:
51
                cmd = command_tree.Command(*args)
52
            except Exception as e:
53
                if path:
54
                    raise
55
                self.assertTrue(isinstance(e, AssertionError))
56
                continue
57
            self.assertEqual(cmd.help, help or '')
58
            self.assertEqual(cmd.subcommands, subcommands or {})
59
            self.assertEqual(cmd.cmd_class, cmd_class or None)
60

    
61
    def test_name(self):
62
        for path in ('cmd', 'cmd_cmd0', 'cmd_cmd0_cmd1', '', None):
63
            if path:
64
                cmd = command_tree.Command(path)
65
                self.assertEqual(cmd.name, path.split('_')[-1])
66
            else:
67
                try:
68
                    command_tree.Command(path)
69
                except Exception as e:
70
                    self.assertTrue(isinstance(e, AssertionError))
71

    
72
    def test_add_subcmd(self):
73
        cmd = command_tree.Command('cmd')
74
        for subname in (None, 'cmd0', 'cmd_cmd0'):
75
            if subname:
76
                subcmd = command_tree.Command(subname)
77
                if subname.startswith(cmd.name + '_'):
78
                    self.assertTrue(cmd.add_subcmd(subcmd))
79
                    self.assertTrue(subcmd.name in cmd.subcommands)
80
                else:
81
                    self.assertFalse(cmd.add_subcmd(subcmd))
82
                    self.assertTrue(len(cmd.subcommands) == 0)
83
            else:
84
                self.assertRaises(cmd.add_subcmd, subname, AttributeError)
85

    
86
    def test_get_subcmd(self):
87
        cmd = command_tree.Command('cmd')
88
        cmd.subcommands = dict(
89
            cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict(
90
                cmd1=command_tree.Command('cmd_cmd0a_cmd1'))),
91
            cmd0b=command_tree.Command('cmd_cmd0b'))
92
        for subname in ('', None, 'cmd0a', 'cmd1', 'cmd0b'):
93
            try:
94
                expected = cmd.subcommands[subname] if subname else None
95
            except KeyError:
96
                expected = None
97
            self.assertEqual(cmd.get_subcmd(subname), expected)
98

    
99
    def test_contains(self):
100
        cmd = command_tree.Command('cmd')
101
        for subname in ('', 'cmd0'):
102
            self.assertFalse(cmd.contains(subname))
103
        cmd.subcommands = dict(
104
            cmd0a=command_tree.Command('cmd_cmd0a'),
105
            cmd0b=command_tree.Command('cmd_cmd0b'))
106
        for subname in ('cmd0a', 'cmd0b'):
107
            self.assertTrue(cmd.contains(subname))
108
        for subname in ('', 'cmd0c'):
109
            self.assertFalse(cmd.contains(subname))
110
        cmd.subcommands['cmd0a'].subcommands = dict(
111
            cmd1=command_tree.Command('cmd_cmd0a_cmd1'))
112
        for subname in ('cmd0a', 'cmd0b'):
113
            self.assertTrue(cmd.contains(subname))
114
        for subname in ('', 'cmd0c', 'cmd1', 'cmd0a_cmd1'):
115
            self.assertFalse(cmd.contains(subname))
116

    
117
    def test_is_command(self):
118
        cmd = command_tree.Command('cmd')
119
        cmd.subcommands = dict(
120
            itis=command_tree.Command('cmd_itis', cmd_class=Command),
121
            itsnot=command_tree.Command('cmd_itsnot'))
122
        self.assertFalse(cmd.is_command)
123
        self.assertTrue(cmd.subcommands['itis'].is_command)
124
        self.assertFalse(cmd.subcommands['itsnot'].is_command)
125

    
126
    def test_parent_path(self):
127
        cmd = command_tree.Command('cmd')
128
        cmd.subcommands = dict(
129
            cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict(
130
                cmd1=command_tree.Command('cmd_cmd0a_cmd1'))),
131
            cmd0b=command_tree.Command('cmd_cmd0b'))
132
        self.assertEqual(cmd.parent_path, '')
133
        self.assertEqual(cmd.subcommands['cmd0a'].parent_path, cmd.path)
134
        self.assertEqual(cmd.subcommands['cmd0b'].parent_path, cmd.path)
135
        cmd0a = cmd.subcommands['cmd0a']
136
        self.assertEqual(cmd0a.subcommands['cmd1'].parent_path, cmd0a.path)
137

    
138
    def test_parse_out(self):
139
        cmd = command_tree.Command('cmd')
140
        cmd.subcommands = dict(
141
            cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict(
142
                cmd1=command_tree.Command('cmd_cmd0a_cmd1'))),
143
            cmd0b=command_tree.Command('cmd_cmd0b'))
144
        for invalids in (None, 42, 0.88):
145
            self.assertRaises(TypeError, cmd.parse_out, invalids)
146
        for c, l, expc, expl in (
147
                (cmd, ['cmd'], cmd, ['cmd']),
148
                (cmd, ['XXX'], cmd, ['XXX']),
149
                (cmd, ['cmd0a'], cmd.subcommands['cmd0a'], []),
150
                (cmd, ['XXX', 'cmd0a'], cmd, ['XXX', 'cmd0a']),
151
                (cmd, ['cmd0a', 'XXX'], cmd.subcommands['cmd0a'], ['XXX']),
152
                (cmd, ['cmd0a', 'cmd0b'], cmd.subcommands['cmd0a'], ['cmd0b']),
153
                (cmd, ['cmd0b', 'XXX'], cmd.subcommands['cmd0b'], ['XXX']),
154
                (
155
                    cmd, ['cmd0a', 'cmd1'],
156
                    cmd.subcommands['cmd0a'].subcommands['cmd1'], []),
157
                (
158
                    cmd, ['cmd0a', 'cmd1', 'XXX'],
159
                    cmd.subcommands['cmd0a'].subcommands['cmd1'], ['XXX']),
160
                (
161
                    cmd, ['cmd0a', 'XXX', 'cmd1'],
162
                    cmd.subcommands['cmd0a'], ['XXX', 'cmd1'])):
163
            self.assertEqual((expc, expl), c.parse_out(l))
164

    
165

    
166
class CommandTree(TestCase):
167

    
168
    def _add_commands(self, ctree):
169
        for cmd in self.commands:
170
            ctree.add_command(cmd.path, cmd.help, cmd.cmd_class)
171

    
172
    def _commands_are_equal(self, c1, c2):
173
        self.assertEqual(c1.path, c2.path)
174
        self.assertEqual(c1.name, c2.name)
175
        self.assertEqual(c1.cmd_class, c2.cmd_class)
176
        self.assertEqual(c1.help, c2.help)
177

    
178
    def setUp(self):
179
        cmd = command_tree.Command('cmd', subcommands=dict(
180
            cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict(
181
                cmd1a=command_tree.Command(
182
                    'cmd_cmd0a_cmd1a', subcommands=dict(
183
                        cmd2=command_tree.Command(
184
                            'cmd_cmd0a_cmd1a_cmd2', cmd_class=Command)
185
                        ),
186
                ),
187
                cmd1b=command_tree.Command(
188
                    'cmd_cmd0a_cmd1b', subcommands=dict(
189
                        cmd2=command_tree.Command(
190
                            'cmd_cmd0a_cmd1b_cmd2', cmd_class=Command)
191
                        ),
192
                )
193
            )),
194
            cmd0b=command_tree.Command('cmd_cmd0b'),
195
            cmd0c=command_tree.Command('cmd_cmd0c', subcommands=dict(
196
                cmd1a=command_tree.Command('cmd_cmd0c_cmd1a'),
197
                cmd1b=command_tree.Command(
198
                    'cmd_cmd0c_cmd1b', subcommands=dict(
199
                        cmd2=command_tree.Command(
200
                            'cmd_cmd0c_cmd1b_cmd2', cmd_class=Command)
201
                        ),
202
                )
203
            ))
204
        ))
205
        self.commands = [
206
            cmd,
207
            cmd.subcommands['cmd0a'],
208
            cmd.subcommands['cmd0a'].subcommands['cmd1a'],
209
            cmd.subcommands['cmd0a'].subcommands['cmd1a'].subcommands['cmd2'],
210
            cmd.subcommands['cmd0a'].subcommands['cmd1b'],
211
            cmd.subcommands['cmd0a'].subcommands['cmd1b'].subcommands['cmd2'],
212
            cmd.subcommands['cmd0b'],
213
            cmd.subcommands['cmd0c'],
214
            cmd.subcommands['cmd0c'].subcommands['cmd1a'],
215
            cmd.subcommands['cmd0c'].subcommands['cmd1b'],
216
            cmd.subcommands['cmd0c'].subcommands['cmd1b'].subcommands['cmd2'],
217
            command_tree.Command('othercmd')
218
        ]
219

    
220
    def tearDown(self):
221
        for cmd in self.commands:
222
            del cmd
223
        del self.commands
224

    
225
    def test___init__(self):
226
        name, description = 'sampleTree', 'a sample Tree'
227
        ctree = command_tree.CommandTree(name)
228
        for attr, exp in (
229
                ('groups', {}), ('_all_commands', {}),
230
                ('name', name), ('description', '')):
231
            self.assertEqual(getattr(ctree, attr), exp)
232
        ctree = command_tree.CommandTree(name, description)
233
        for attr, exp in (
234
                ('groups', {}), ('_all_commands', {}),
235
                ('name', name), ('description', description)):
236
            self.assertEqual(getattr(ctree, attr), exp)
237

    
238
    def test_exclude(self):
239
        ctree = command_tree.CommandTree('excludeTree', 'test exclude group')
240
        exp = dict()
241
        for cmd in self.commands[0:6]:
242
            ctree.groups[cmd.name] = cmd
243
            exp[cmd.name] = cmd
244
        self.assertEqual(exp, ctree.groups)
245
        ctree.exclude(exp.keys()[1::2])
246
        for key in exp.keys()[1::2]:
247
            exp.pop(key)
248
        self.assertEqual(exp, ctree.groups)
249

    
250
    def test_add_command(self):
251
        ctree = command_tree.CommandTree('addCommand', 'test add_command')
252
        self._add_commands(ctree)
253
        for cmd in self.commands:
254
            self.assertTrue(cmd, ctree._all_commands)
255
            if cmd.path.count('_'):
256
                self.assertFalse(cmd.name in ctree.groups)
257
            else:
258
                self.assertTrue(cmd.name in ctree.groups)
259
                self._commands_are_equal(cmd, ctree.groups[cmd.name])
260

    
261
    def test_find_best_match(self):
262
        ctree = command_tree.CommandTree('bestMatch', 'test find_best_match')
263
        for cmd in self.commands:
264
            terms = cmd.path.split('_')
265
            best_match, rest = ctree.find_best_match(terms)
266
            if len(terms) > 1:
267
                self.assertEqual(best_match.path, '_'.join(terms[:-1]))
268
            else:
269
                self.assertEqual(best_match, None)
270
            self.assertEqual(rest, terms[-1:])
271
            ctree.add_command(cmd.path, cmd.help, cmd.cmd_class)
272
            best_match, rest = ctree.find_best_match(terms)
273
            self._commands_are_equal(best_match, cmd)
274
            self.assertEqual(rest, [])
275

    
276
    def test_add_tree(self):
277
        ctree = command_tree.CommandTree('tree', 'the main tree')
278
        ctree1 = command_tree.CommandTree('tree1', 'the first tree')
279
        ctree2 = command_tree.CommandTree('tree2', 'the second tree')
280

    
281
        cmds = list(self.commands)
282
        del self.commands
283
        cmds1, cmds2 = cmds[:6], cmds[6:]
284
        self.commands = cmds1
285
        self._add_commands(ctree1)
286
        self.commands = cmds2
287
        self._add_commands(ctree2)
288
        self.commands = cmds
289

    
290
        def check_all(
291
                p1=False, p2=False, p3=False, p4=False, p5=False, p6=False):
292
            for cmd in cmds[:6]:
293
                self.assertEquals(cmd.path in ctree._all_commands, p1)
294
                self.assertEquals(cmd.path in ctree1._all_commands, p2)
295
                if cmd.path != 'cmd':
296
                    self.assertEquals(cmd.path in ctree2._all_commands, p3)
297
            for cmd in cmds[6:]:
298
                self.assertEquals(cmd.path in ctree._all_commands, p4)
299
                if cmd.path != 'cmd':
300
                    self.assertEquals(cmd.path in ctree1._all_commands, p5)
301
                self.assertEquals(cmd.path in ctree2._all_commands, p6)
302

    
303
        check_all(False, True, False, False, False, True)
304
        ctree.add_tree(ctree1)
305
        check_all(True, True, False, False, False, True)
306
        ctree.add_tree(ctree2)
307
        check_all(True, True, False, True, False, True)
308
        ctree2.add_tree(ctree1)
309
        check_all(True, True, True, True, False, True)
310

    
311
    def test_has_command(self):
312
        ctree = command_tree.CommandTree('treeHasCommand', 'test has_command')
313
        for cmd in self.commands:
314
            self.assertFalse(ctree.has_command(cmd.path))
315
        self._add_commands(ctree)
316
        for cmd in self.commands:
317
            self.assertTrue(ctree.has_command(cmd.path))
318
        self.assertFalse(ctree.has_command('NON_EXISTING_COMMAND'))
319

    
320
    def test_get_command(self):
321
        ctree = command_tree.CommandTree('treeGetCommand', 'test get_command')
322
        for cmd in self.commands:
323
            self.assertRaises(KeyError, ctree.get_command, cmd.path)
324
        self._add_commands(ctree)
325
        for cmd in self.commands:
326
            self._commands_are_equal(ctree.get_command(cmd.path), cmd)
327
        self.assertRaises(KeyError, ctree.get_command, 'NON_EXISTNG_COMMAND')
328

    
329
    def test_subnames(self):
330
        ctree = command_tree.CommandTree('treeSubnames', 'test subnames')
331
        self.assertEqual(ctree.subnames(), [])
332
        self.assertRaises(KeyError, ctree.subnames, 'cmd')
333
        self._add_commands(ctree)
334
        for l1, l2 in (
335
                (ctree.subnames(), ['cmd', 'othercmd']),
336
                (ctree.subnames('cmd'), ['cmd0a', 'cmd0b', 'cmd0c']),
337
                (ctree.subnames('cmd_cmd0a'), ['cmd1a', 'cmd1b']),
338
                (ctree.subnames('cmd_cmd0a_cmd1a'), ['cmd2', ]),
339
                (ctree.subnames('cmd_cmd0a_cmd1b'), ['cmd2', ]),
340
                (ctree.subnames('cmd_cmd0a_cmd1a_cmd2'), []),
341
                (ctree.subnames('cmd_cmd0a_cmd1b_cmd2'), []),
342
                (ctree.subnames('cmd_cmd0b'), []),
343
                (ctree.subnames('cmd_cmd0c'), ['cmd1a', 'cmd1b']),
344
                (ctree.subnames('cmd_cmd0c_cmd1a'), []),
345
                (ctree.subnames('cmd_cmd0c_cmd1b'), ['cmd2', ]),
346
                (ctree.subnames('cmd_cmd0c_cmd1b_cmd2'), []),
347
                (ctree.subnames('othercmd'), [])):
348
            l1.sort(), l2.sort(), self.assertEqual(l1, l2)
349
        self.assertRaises(KeyError, ctree.subnames, 'NON_EXISTNG_CMD')
350

    
351
    def test_get_subcommands(self):
352
        ctree = command_tree.CommandTree('treeSub', 'test get_subcommands')
353
        self.assertEqual(ctree.get_subcommands(), [])
354
        self.assertRaises(KeyError, ctree.get_subcommands, 'cmd')
355
        self._add_commands(ctree)
356
        for s1, l2 in (
357
            ('', ['cmd', 'othercmd']),
358
            ('cmd', ['cmd0a', 'cmd0b', 'cmd0c']),
359
            ('cmd_cmd0a', ['cmd1a', 'cmd1b']),
360
            ('cmd_cmd0a_cmd1a', ['cmd2', ]),
361
            ('cmd_cmd0a_cmd1b', ['cmd2', ]),
362
            ('cmd_cmd0a_cmd1a_cmd2', []),
363
            ('cmd_cmd0a_cmd1b_cmd2', []),
364
            ('cmd_cmd0b', []),
365
            ('cmd_cmd0c', ['cmd1a', 'cmd1b']),
366
            ('cmd_cmd0c_cmd1a', []),
367
            ('cmd_cmd0c_cmd1b', ['cmd2', ]),
368
            ('cmd_cmd0c_cmd1b_cmd2', []),
369
            ('othercmd', [])
370
        ):
371
            l1 = [cmd.path for cmd in ctree.get_subcommands(s1)]
372
            l2 = ['_'.join([s1, i]) for i in l2] if s1 else l2
373
            l1.sort(), l2.sort(), self.assertEqual(l1, l2)
374
        self.assertRaises(KeyError, ctree.get_subcommands, 'NON_EXISTNG_CMD')
375

    
376

    
377
if __name__ == '__main__':
378
    from sys import argv
379
    from kamaki.cli.test import runTestCase
380
    runTestCase(Command, 'Command', argv[1:])
381
    runTestCase(CommandTree, 'CommandTree', argv[1:])