# HG changeset patch # User John Mulligan # Date 1257044900 14400 # Sat Oct 31 23:08:20 2009 -0400 # Node ID fc6fcfdd8e1585ec648365a2c7eeb9058be16044 # Parent d6ec6a714ac2143f9c2c33591f35f3ebc86ef872 commander: add tests and fix exposed bugs diff --git a/test/test_cli_commands.py b/test/test_cli_commands.py --- a/test/test_cli_commands.py +++ b/test/test_cli_commands.py @@ -22,11 +22,22 @@ 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 @@ 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 @@ 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() diff --git a/vanity/commander.py b/vanity/commander.py --- a/vanity/commander.py +++ b/vanity/commander.py @@ -29,7 +29,7 @@ """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 @@ 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 @@ 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 @@ 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)