@@ 22,11 22,22 @@ def cmd3():
CMDTABLE_A = [
('foo', cmd1, '', [], 'foo fixes everything'),
('bar', cmd2, '', [], 'bar breaks it'),
- ('baz', cmd3, '', [
+ ('baz', cmd3, 'wibble|hamper', [
('shrimp', '', None, 'jumbo shrimp'),
], 'something helpful'),
]
+CMDTABLE_B = [
+ {'name': 'snorkel', 'target': cmd1, 'opts': [], 'help': 'dive in'},
+ {'name': 'fish', 'target': cmd2, 'opts': [], 'help': 'the angler'},
+ commander.Command('net', cmd3, opts=[], help='nab it'),
+ ]
+
+CMDTABLE_C = {
+ 'snorkel': {'target': cmd1, 'opts': [], 'help': 'magic stuff'},
+ 'fish': {'target': cmd2, 'opts': [], 'help': 'other stuff'},
+ }
+
class TestCliCommands(unittest.TestCase):
def test_parse_cli_cmd(self):
@@ 49,7 60,29 @@ class TestCliCommands(unittest.TestCase)
self.assertEqual(args, ['test.txt'])
self.assertEqual(opts, dict(verbose=True, quiet=True))
- def test_parse_cli_cmd4(self):
+ def test_partial_command_name(self):
+ arguments = 'fo xxx.txt'.split()
+ cmd, opts, args = commander.parse(GOPT_A, CMDTABLE_A, arguments)
+ self.assertEqual(cmd.target, cmd1)
+ arguments = 'f xxx.txt'.split()
+ cmd, opts, args = commander.parse(GOPT_A, CMDTABLE_A, arguments)
+ self.assertEqual(cmd.target, cmd1)
+ arguments = 'wi xxx.txt'.split()
+ cmd, opts, args = commander.parse(GOPT_A, CMDTABLE_A, arguments)
+ self.assertEqual(cmd.target, cmd3)
+
+ def test_ambiguous_command(self):
+ arguments = 'b zapp.txt'.split()
+ self.assertRaises(commander.AmbiguousCommand,
+ commander.parse, GOPT_A, CMDTABLE_A, arguments)
+
+ def test_invalid_command(self):
+ arguments = 'morton zapp.txt'.split()
+ self.assertRaises(commander.InvalidCommand,
+ commander.parse, GOPT_A, CMDTABLE_A, arguments)
+
+
+ def test_cmd_with_option(self):
arguments = '-v baz test.txt --shrimp'.split()
cmd, opts, args = commander.parse(GOPT_A, CMDTABLE_A, arguments)
self.assertEqual(cmd.target, cmd3)
@@ 59,6 92,20 @@ class TestCliCommands(unittest.TestCase)
cmd, opts, args = commander.parse(GOPT_A, CMDTABLE_A, arguments)
self.assertEqual(opts, dict(verbose=True, quiet=None, shrimp=None))
+ def test_table_mixed_format(self):
+ arguments = 'fish -v yes yes'.split()
+ cmd, opts, args = commander.parse(GOPT_A, CMDTABLE_B, arguments)
+ self.assertEqual(cmd.target, cmd2)
+ self.assertEqual(args, ['yes', 'yes'])
+ self.assertEqual(opts, dict(verbose=True, quiet=None))
+
+ def test_dict_table_style(self):
+ arguments = 'fish -v yes yes'.split()
+ cmd, opts, args = commander.parse(GOPT_A, CMDTABLE_C, arguments)
+ self.assertEqual(cmd.target, cmd2)
+ self.assertEqual(args, ['yes', 'yes'])
+ self.assertEqual(opts, dict(verbose=True, quiet=None))
+
if __name__ == '__main__':
unittest.main()
@@ 29,7 29,7 @@ class AmbiguousCommand(cli.CliError):
"""The given command was ambigouous"""
def __init__(self, matches):
msg = 'possible matches: %s' % ' '.join(matches)
- CliError.__init__(self, msg)
+ cli.CliError.__init__(self, msg)
self.matches = matches
@@ 118,9 118,9 @@ class CommandTable(object):
def __init__(self, table):
self._table = {}
- if hasattr(table, 'keys'):
+ if hasattr(table, 'keys') and hasattr(table, 'items'):
# if a user is giving us a dict, the entries **must** be dicts
- for name, entry in table:
+ for name, entry in table.items():
self._table[name] = Command(name, **entry)
else:
for entry in table:
@@ 138,9 138,9 @@ class CommandTable(object):
AmbiguousCommand exception is raised.
"""
namemap = dict((k,k) for k in self._table)
- for key in self._table:
- for alias in self._table[key].aliaslist():
- namemap[alias] = name
+ for key, cmd in self._table.iteritems():
+ for alias in cmd.aliaslist():
+ namemap[alias] = key
if name in namemap:
key = namemap[name]
return self._table[key]
@@ 150,7 150,8 @@ class CommandTable(object):
if alias.startswith(name):
canidates.add(alias)
if len(canidates) == 1:
- key = namemap[canidates[0]]
+ key = namemap[canidates.pop()]
+ print namemap
return self._table[key]
if not canidates:
raise InvalidCommand(name)