root / kamaki / cli / command_tree / test.py @ 58602137
History | View | Annotate | Download (16.3 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 |
(None, 'long description')): |
50 |
path, help, subcommands, cmd_class, long_help = args |
51 |
try:
|
52 |
cmd = command_tree.Command(*args) |
53 |
except Exception as e: |
54 |
if path:
|
55 |
raise
|
56 |
self.assertTrue(isinstance(e, AssertionError)) |
57 |
continue
|
58 |
self.assertEqual(cmd.help, help or '') |
59 |
self.assertEqual(cmd.subcommands, subcommands or {}) |
60 |
self.assertEqual(cmd.cmd_class, cmd_class or None) |
61 |
self.assertEqual(cmd.long_help, long_help or '') |
62 |
|
63 |
def test_name(self): |
64 |
for path in ('cmd', 'cmd_cmd0', 'cmd_cmd0_cmd1', '', None): |
65 |
if path:
|
66 |
cmd = command_tree.Command(path) |
67 |
self.assertEqual(cmd.name, path.split('_')[-1]) |
68 |
else:
|
69 |
try:
|
70 |
command_tree.Command(path) |
71 |
except Exception as e: |
72 |
self.assertTrue(isinstance(e, AssertionError)) |
73 |
|
74 |
def test_add_subcmd(self): |
75 |
cmd = command_tree.Command('cmd')
|
76 |
for subname in (None, 'cmd0', 'cmd_cmd0'): |
77 |
if subname:
|
78 |
subcmd = command_tree.Command(subname) |
79 |
if subname.startswith(cmd.name + '_'): |
80 |
self.assertTrue(cmd.add_subcmd(subcmd))
|
81 |
self.assertTrue(subcmd.name in cmd.subcommands) |
82 |
else:
|
83 |
self.assertFalse(cmd.add_subcmd(subcmd))
|
84 |
self.assertTrue(len(cmd.subcommands) == 0) |
85 |
else:
|
86 |
self.assertRaises(cmd.add_subcmd, subname, AttributeError) |
87 |
|
88 |
def test_get_subcmd(self): |
89 |
cmd = command_tree.Command('cmd')
|
90 |
cmd.subcommands = dict(
|
91 |
cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict( |
92 |
cmd1=command_tree.Command('cmd_cmd0a_cmd1'))),
|
93 |
cmd0b=command_tree.Command('cmd_cmd0b'))
|
94 |
for subname in ('', None, 'cmd0a', 'cmd1', 'cmd0b'): |
95 |
try:
|
96 |
expected = cmd.subcommands[subname] if subname else None |
97 |
except KeyError: |
98 |
expected = None
|
99 |
self.assertEqual(cmd.get_subcmd(subname), expected)
|
100 |
|
101 |
def test_contains(self): |
102 |
cmd = command_tree.Command('cmd')
|
103 |
for subname in ('', 'cmd0'): |
104 |
self.assertFalse(cmd.contains(subname))
|
105 |
cmd.subcommands = dict(
|
106 |
cmd0a=command_tree.Command('cmd_cmd0a'),
|
107 |
cmd0b=command_tree.Command('cmd_cmd0b'))
|
108 |
for subname in ('cmd0a', 'cmd0b'): |
109 |
self.assertTrue(cmd.contains(subname))
|
110 |
for subname in ('', 'cmd0c'): |
111 |
self.assertFalse(cmd.contains(subname))
|
112 |
cmd.subcommands['cmd0a'].subcommands = dict( |
113 |
cmd1=command_tree.Command('cmd_cmd0a_cmd1'))
|
114 |
for subname in ('cmd0a', 'cmd0b'): |
115 |
self.assertTrue(cmd.contains(subname))
|
116 |
for subname in ('', 'cmd0c', 'cmd1', 'cmd0a_cmd1'): |
117 |
self.assertFalse(cmd.contains(subname))
|
118 |
|
119 |
def test_is_command(self): |
120 |
cmd = command_tree.Command('cmd')
|
121 |
cmd.subcommands = dict(
|
122 |
itis=command_tree.Command('cmd_itis', cmd_class=Command),
|
123 |
itsnot=command_tree.Command('cmd_itsnot'))
|
124 |
self.assertFalse(cmd.is_command)
|
125 |
self.assertTrue(cmd.subcommands['itis'].is_command) |
126 |
self.assertFalse(cmd.subcommands['itsnot'].is_command) |
127 |
|
128 |
def test_parent_path(self): |
129 |
cmd = command_tree.Command('cmd')
|
130 |
cmd.subcommands = dict(
|
131 |
cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict( |
132 |
cmd1=command_tree.Command('cmd_cmd0a_cmd1'))),
|
133 |
cmd0b=command_tree.Command('cmd_cmd0b'))
|
134 |
self.assertEqual(cmd.parent_path, '') |
135 |
self.assertEqual(cmd.subcommands['cmd0a'].parent_path, cmd.path) |
136 |
self.assertEqual(cmd.subcommands['cmd0b'].parent_path, cmd.path) |
137 |
cmd0a = cmd.subcommands['cmd0a']
|
138 |
self.assertEqual(cmd0a.subcommands['cmd1'].parent_path, cmd0a.path) |
139 |
|
140 |
def test_parse_out(self): |
141 |
cmd = command_tree.Command('cmd')
|
142 |
cmd.subcommands = dict(
|
143 |
cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict( |
144 |
cmd1=command_tree.Command('cmd_cmd0a_cmd1'))),
|
145 |
cmd0b=command_tree.Command('cmd_cmd0b'))
|
146 |
for invalids in (None, 42, 0.88): |
147 |
self.assertRaises(TypeError, cmd.parse_out, invalids) |
148 |
for c, l, expc, expl in ( |
149 |
(cmd, ['cmd'], cmd, ['cmd']), |
150 |
(cmd, ['XXX'], cmd, ['XXX']), |
151 |
(cmd, ['cmd0a'], cmd.subcommands['cmd0a'], []), |
152 |
(cmd, ['XXX', 'cmd0a'], cmd, ['XXX', 'cmd0a']), |
153 |
(cmd, ['cmd0a', 'XXX'], cmd.subcommands['cmd0a'], ['XXX']), |
154 |
(cmd, ['cmd0a', 'cmd0b'], cmd.subcommands['cmd0a'], ['cmd0b']), |
155 |
(cmd, ['cmd0b', 'XXX'], cmd.subcommands['cmd0b'], ['XXX']), |
156 |
( |
157 |
cmd, ['cmd0a', 'cmd1'], |
158 |
cmd.subcommands['cmd0a'].subcommands['cmd1'], []), |
159 |
( |
160 |
cmd, ['cmd0a', 'cmd1', 'XXX'], |
161 |
cmd.subcommands['cmd0a'].subcommands['cmd1'], ['XXX']), |
162 |
( |
163 |
cmd, ['cmd0a', 'XXX', 'cmd1'], |
164 |
cmd.subcommands['cmd0a'], ['XXX', 'cmd1'])): |
165 |
self.assertEqual((expc, expl), c.parse_out(l))
|
166 |
|
167 |
|
168 |
class CommandTree(TestCase): |
169 |
|
170 |
def _add_commands(self, ctree): |
171 |
for cmd in self.commands: |
172 |
ctree.add_command(cmd.path, cmd.help, cmd.cmd_class) |
173 |
|
174 |
def _commands_are_equal(self, c1, c2): |
175 |
self.assertEqual(c1.path, c2.path)
|
176 |
self.assertEqual(c1.name, c2.name)
|
177 |
self.assertEqual(c1.cmd_class, c2.cmd_class)
|
178 |
self.assertEqual(c1.help, c2.help)
|
179 |
|
180 |
def setUp(self): |
181 |
cmd = command_tree.Command('cmd', subcommands=dict( |
182 |
cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict( |
183 |
cmd1a=command_tree.Command( |
184 |
'cmd_cmd0a_cmd1a', subcommands=dict( |
185 |
cmd2=command_tree.Command( |
186 |
'cmd_cmd0a_cmd1a_cmd2', cmd_class=Command)
|
187 |
), |
188 |
), |
189 |
cmd1b=command_tree.Command( |
190 |
'cmd_cmd0a_cmd1b', subcommands=dict( |
191 |
cmd2=command_tree.Command( |
192 |
'cmd_cmd0a_cmd1b_cmd2', cmd_class=Command)
|
193 |
), |
194 |
) |
195 |
)), |
196 |
cmd0b=command_tree.Command('cmd_cmd0b'),
|
197 |
cmd0c=command_tree.Command('cmd_cmd0c', subcommands=dict( |
198 |
cmd1a=command_tree.Command('cmd_cmd0c_cmd1a'),
|
199 |
cmd1b=command_tree.Command( |
200 |
'cmd_cmd0c_cmd1b', subcommands=dict( |
201 |
cmd2=command_tree.Command( |
202 |
'cmd_cmd0c_cmd1b_cmd2', cmd_class=Command)
|
203 |
), |
204 |
) |
205 |
)) |
206 |
)) |
207 |
self.commands = [
|
208 |
cmd, |
209 |
cmd.subcommands['cmd0a'],
|
210 |
cmd.subcommands['cmd0a'].subcommands['cmd1a'], |
211 |
cmd.subcommands['cmd0a'].subcommands['cmd1a'].subcommands['cmd2'], |
212 |
cmd.subcommands['cmd0a'].subcommands['cmd1b'], |
213 |
cmd.subcommands['cmd0a'].subcommands['cmd1b'].subcommands['cmd2'], |
214 |
cmd.subcommands['cmd0b'],
|
215 |
cmd.subcommands['cmd0c'],
|
216 |
cmd.subcommands['cmd0c'].subcommands['cmd1a'], |
217 |
cmd.subcommands['cmd0c'].subcommands['cmd1b'], |
218 |
cmd.subcommands['cmd0c'].subcommands['cmd1b'].subcommands['cmd2'], |
219 |
command_tree.Command('othercmd')
|
220 |
] |
221 |
|
222 |
def tearDown(self): |
223 |
for cmd in self.commands: |
224 |
del cmd
|
225 |
del self.commands |
226 |
|
227 |
def test___init__(self): |
228 |
name, description = 'sampleTree', 'a sample Tree' |
229 |
ctree = command_tree.CommandTree(name) |
230 |
for attr, exp in ( |
231 |
('groups', {}), ('_all_commands', {}), |
232 |
('name', name), ('description', '')): |
233 |
self.assertEqual(getattr(ctree, attr), exp) |
234 |
ctree = command_tree.CommandTree(name, description) |
235 |
for attr, exp in ( |
236 |
('groups', {}), ('_all_commands', {}), |
237 |
('name', name), ('description', description)): |
238 |
self.assertEqual(getattr(ctree, attr), exp) |
239 |
|
240 |
def test_exclude(self): |
241 |
ctree = command_tree.CommandTree('excludeTree', 'test exclude group') |
242 |
exp = dict()
|
243 |
for cmd in self.commands[0:6]: |
244 |
ctree.groups[cmd.name] = cmd |
245 |
exp[cmd.name] = cmd |
246 |
self.assertEqual(exp, ctree.groups)
|
247 |
ctree.exclude(exp.keys()[1::2]) |
248 |
for key in exp.keys()[1::2]: |
249 |
exp.pop(key) |
250 |
self.assertEqual(exp, ctree.groups)
|
251 |
|
252 |
def test_add_command(self): |
253 |
ctree = command_tree.CommandTree('addCommand', 'test add_command') |
254 |
self._add_commands(ctree)
|
255 |
for cmd in self.commands: |
256 |
self.assertTrue(cmd, ctree._all_commands)
|
257 |
if cmd.path.count('_'): |
258 |
self.assertFalse(cmd.name in ctree.groups) |
259 |
else:
|
260 |
self.assertTrue(cmd.name in ctree.groups) |
261 |
self._commands_are_equal(cmd, ctree.groups[cmd.name])
|
262 |
|
263 |
def test_find_best_match(self): |
264 |
ctree = command_tree.CommandTree('bestMatch', 'test find_best_match') |
265 |
for cmd in self.commands: |
266 |
terms = cmd.path.split('_')
|
267 |
best_match, rest = ctree.find_best_match(terms) |
268 |
if len(terms) > 1: |
269 |
self.assertEqual(best_match.path, '_'.join(terms[:-1])) |
270 |
else:
|
271 |
self.assertEqual(best_match, None) |
272 |
self.assertEqual(rest, terms[-1:]) |
273 |
ctree.add_command(cmd.path, cmd.help, cmd.cmd_class) |
274 |
best_match, rest = ctree.find_best_match(terms) |
275 |
self._commands_are_equal(best_match, cmd)
|
276 |
self.assertEqual(rest, [])
|
277 |
|
278 |
def test_add_tree(self): |
279 |
ctree = command_tree.CommandTree('tree', 'the main tree') |
280 |
ctree1 = command_tree.CommandTree('tree1', 'the first tree') |
281 |
ctree2 = command_tree.CommandTree('tree2', 'the second tree') |
282 |
|
283 |
cmds = list(self.commands) |
284 |
del self.commands |
285 |
cmds1, cmds2 = cmds[:6], cmds[6:] |
286 |
self.commands = cmds1
|
287 |
self._add_commands(ctree1)
|
288 |
self.commands = cmds2
|
289 |
self._add_commands(ctree2)
|
290 |
self.commands = cmds
|
291 |
|
292 |
def check_all( |
293 |
p1=False, p2=False, p3=False, p4=False, p5=False, p6=False): |
294 |
for cmd in cmds[:6]: |
295 |
self.assertEquals(cmd.path in ctree._all_commands, p1) |
296 |
self.assertEquals(cmd.path in ctree1._all_commands, p2) |
297 |
if cmd.path != 'cmd': |
298 |
self.assertEquals(cmd.path in ctree2._all_commands, p3) |
299 |
for cmd in cmds[6:]: |
300 |
self.assertEquals(cmd.path in ctree._all_commands, p4) |
301 |
if cmd.path != 'cmd': |
302 |
self.assertEquals(cmd.path in ctree1._all_commands, p5) |
303 |
self.assertEquals(cmd.path in ctree2._all_commands, p6) |
304 |
|
305 |
check_all(False, True, False, False, False, True) |
306 |
ctree.add_tree(ctree1) |
307 |
check_all(True, True, False, False, False, True) |
308 |
ctree.add_tree(ctree2) |
309 |
check_all(True, True, False, True, False, True) |
310 |
ctree2.add_tree(ctree1) |
311 |
check_all(True, True, True, True, False, True) |
312 |
|
313 |
def test_has_command(self): |
314 |
ctree = command_tree.CommandTree('treeHasCommand', 'test has_command') |
315 |
for cmd in self.commands: |
316 |
self.assertFalse(ctree.has_command(cmd.path))
|
317 |
self._add_commands(ctree)
|
318 |
for cmd in self.commands: |
319 |
self.assertTrue(ctree.has_command(cmd.path))
|
320 |
self.assertFalse(ctree.has_command('NON_EXISTING_COMMAND')) |
321 |
|
322 |
def test_get_command(self): |
323 |
ctree = command_tree.CommandTree('treeGetCommand', 'test get_command') |
324 |
for cmd in self.commands: |
325 |
self.assertRaises(KeyError, ctree.get_command, cmd.path) |
326 |
self._add_commands(ctree)
|
327 |
for cmd in self.commands: |
328 |
self._commands_are_equal(ctree.get_command(cmd.path), cmd)
|
329 |
self.assertRaises(KeyError, ctree.get_command, 'NON_EXISTNG_COMMAND') |
330 |
|
331 |
def test_subnames(self): |
332 |
ctree = command_tree.CommandTree('treeSubnames', 'test subnames') |
333 |
self.assertEqual(ctree.subnames(), [])
|
334 |
self.assertRaises(KeyError, ctree.subnames, 'cmd') |
335 |
self._add_commands(ctree)
|
336 |
for l1, l2 in ( |
337 |
(ctree.subnames(), ['cmd', 'othercmd']), |
338 |
(ctree.subnames('cmd'), ['cmd0a', 'cmd0b', 'cmd0c']), |
339 |
(ctree.subnames('cmd_cmd0a'), ['cmd1a', 'cmd1b']), |
340 |
(ctree.subnames('cmd_cmd0a_cmd1a'), ['cmd2', ]), |
341 |
(ctree.subnames('cmd_cmd0a_cmd1b'), ['cmd2', ]), |
342 |
(ctree.subnames('cmd_cmd0a_cmd1a_cmd2'), []),
|
343 |
(ctree.subnames('cmd_cmd0a_cmd1b_cmd2'), []),
|
344 |
(ctree.subnames('cmd_cmd0b'), []),
|
345 |
(ctree.subnames('cmd_cmd0c'), ['cmd1a', 'cmd1b']), |
346 |
(ctree.subnames('cmd_cmd0c_cmd1a'), []),
|
347 |
(ctree.subnames('cmd_cmd0c_cmd1b'), ['cmd2', ]), |
348 |
(ctree.subnames('cmd_cmd0c_cmd1b_cmd2'), []),
|
349 |
(ctree.subnames('othercmd'), [])):
|
350 |
l1.sort(), l2.sort(), self.assertEqual(l1, l2)
|
351 |
self.assertRaises(KeyError, ctree.subnames, 'NON_EXISTNG_CMD') |
352 |
|
353 |
def test_get_subcommands(self): |
354 |
ctree = command_tree.CommandTree('treeSub', 'test get_subcommands') |
355 |
self.assertEqual(ctree.get_subcommands(), [])
|
356 |
self.assertRaises(KeyError, ctree.get_subcommands, 'cmd') |
357 |
self._add_commands(ctree)
|
358 |
for s1, l2 in ( |
359 |
('', ['cmd', 'othercmd']), |
360 |
('cmd', ['cmd0a', 'cmd0b', 'cmd0c']), |
361 |
('cmd_cmd0a', ['cmd1a', 'cmd1b']), |
362 |
('cmd_cmd0a_cmd1a', ['cmd2', ]), |
363 |
('cmd_cmd0a_cmd1b', ['cmd2', ]), |
364 |
('cmd_cmd0a_cmd1a_cmd2', []),
|
365 |
('cmd_cmd0a_cmd1b_cmd2', []),
|
366 |
('cmd_cmd0b', []),
|
367 |
('cmd_cmd0c', ['cmd1a', 'cmd1b']), |
368 |
('cmd_cmd0c_cmd1a', []),
|
369 |
('cmd_cmd0c_cmd1b', ['cmd2', ]), |
370 |
('cmd_cmd0c_cmd1b_cmd2', []),
|
371 |
('othercmd', [])
|
372 |
): |
373 |
l1 = [cmd.path for cmd in ctree.get_subcommands(s1)] |
374 |
l2 = ['_'.join([s1, i]) for i in l2] if s1 else l2 |
375 |
l1.sort(), l2.sort(), self.assertEqual(l1, l2)
|
376 |
self.assertRaises(KeyError, ctree.get_subcommands, 'NON_EXISTNG_CMD') |
377 |
|
378 |
|
379 |
if __name__ == '__main__': |
380 |
from sys import argv |
381 |
from kamaki.cli.test import runTestCase |
382 |
runTestCase(Command, 'Command', argv[1:]) |
383 |
runTestCase(CommandTree, 'CommandTree', argv[1:]) |