def test_prefix_file_expansion(self): import json, os def test_handler(): pass def create_test_file(file, contents): with open(file, 'w') as f: f.write(contents) def remove_test_file(file): os.remove(file) json_test_data = json.dumps({'one': 1, 'two': 2, 'three': 3}) create_test_file('test.json', json_test_data) command = CLICommand(self.mock_ctx, 'test command', test_handler) command.add_argument('json_data', '--param') cmd_table = {'test command': command} self.mock_ctx.commands_loader.command_table = cmd_table parser = CLICommandParser() parser.load_command_table(self.mock_ctx.commands_loader) args = parser.parse_args('test command --param @test.json'.split()) self.assertEqual(json_test_data, args.json_data) remove_test_file('test.json')
def load_command_table(self, cmd_tbl): """Load a command table into our parser.""" # If we haven't already added a subparser, we # better do it. if not self.subparsers: sp = self.add_subparsers(dest='_command_package') sp.required = True self.subparsers = {(): sp} for command_name, metadata in cmd_tbl.items(): subparser = self._get_subparser(command_name.split()) command_verb = command_name.split()[-1] # To work around http://bugs.python.org/issue9253, we artificially add any new # parsers we add to the "choices" section of the subparser. subparser.choices[command_verb] = command_verb # inject command_module designer's help formatter -- default is HelpFormatter fc = metadata.formatter_class or argparse.HelpFormatter command_parser = subparser.add_parser(command_verb, description=metadata.description, parents=self.parents, conflict_handler='error', help_file=metadata.help, formatter_class=fc, cli_help=self.cli_help, _command_source=metadata.command_source) command_parser.cli_ctx = self.cli_ctx command_validator = metadata.validator argument_validators = [] argument_groups = {} for _, arg in metadata.arguments.items(): if arg.validator: argument_validators.append(arg.validator) try: if arg.arg_group: try: group = argument_groups[arg.arg_group] except KeyError: # group not found so create group_name = '{} Arguments'.format(arg.arg_group) group = command_parser.add_argument_group(arg.arg_group, group_name) argument_groups[arg.arg_group] = group param = CLICommandParser._add_argument(group, arg) else: param = CLICommandParser._add_argument(command_parser, arg) except argparse.ArgumentError as ex: raise CLIError("command authoring error for '{}': '{}' {}".format( command_name, ex.args[0].dest, ex.message)) # pylint: disable=no-member param.completer = arg.completer command_parser.set_defaults( func=metadata, command=command_name, _cmd=metadata, _command_validator=command_validator, _argument_validators=argument_validators, _parser=command_parser)
def test_register_simple_commands(self): def test_handler1(): pass def test_handler2(): pass command = CLICommand(self.mock_ctx, 'command the-name', test_handler1) command2 = CLICommand(self.mock_ctx, 'sub-command the-second-name', test_handler2) cmd_table = { 'command the-name': command, 'sub-command the-second-name': command2 } parser = CLICommandParser() parser.load_command_table(cmd_table) args = parser.parse_args('command the-name'.split()) self.assertIs(args.func, command) args = parser.parse_args('sub-command the-second-name'.split()) self.assertIs(args.func, command2) CLICommandParser.error = VerifyError(self, ) parser.parse_args('sub-command'.split()) self.assertTrue(CLICommandParser.error.called)
def test_extra_nonargparse_parameters(self): """ Add argument that has non argparse parameters. 'mycustomarg' should be filtered out and load_command_table should complete successfully instead of throwing TypeError: __init__() got an unexpected keyword argument 'mycustomarg' """ def test_handler(): pass command = CLICommand(self.mock_ctx, 'test command', test_handler) command.add_argument('req', '--req', required=True, mycustomarg=True) cmd_table = {'test command': command} parser = CLICommandParser() parser.load_command_table(cmd_table)
def test_case_insensitive_enum_choices(self): from enum import Enum class TestEnum(Enum): # pylint: disable=too-few-public-methods opt1 = "ALL_CAPS" opt2 = "camelCase" opt3 = "snake_case" def test_handler(): pass command = CLICommand(self.mock_ctx, 'test command', test_handler) command.add_argument('opt', '--opt', required=True, **enum_choice_list(TestEnum)) cmd_table = {'test command': command} parser = CLICommandParser() parser.load_command_table(cmd_table) args = parser.parse_args('test command --opt alL_cAps'.split()) self.assertEqual(args.opt, 'ALL_CAPS') args = parser.parse_args('test command --opt CAMELCASE'.split()) self.assertEqual(args.opt, 'camelCase') args = parser.parse_args('test command --opt sNake_CASE'.split()) self.assertEqual(args.opt, 'snake_case')
def test_nargs_parameter(self): def test_handler(): pass command = CLICommand(self.mock_ctx, 'test command', test_handler) command.add_argument('req', '--req', required=True, nargs=2) cmd_table = {'test command': command} parser = CLICommandParser() parser.load_command_table(cmd_table) args = parser.parse_args('test command --req yep nope'.split()) self.assertIs(args.func, command) CLICommandParser.error = VerifyError(self) parser.parse_args('test command -req yep'.split()) self.assertTrue(CLICommandParser.error.called)
def test_required_parameter(self): def test_handler(args): # pylint: disable=unused-argument pass command = CLICommand(self.mock_ctx, 'test command', test_handler) command.add_argument('req', '--req', required=True) cmd_table = {'test command': command} self.mock_ctx.commands_loader.command_table = cmd_table parser = CLICommandParser() parser.load_command_table(self.mock_ctx.commands_loader) args = parser.parse_args('test command --req yep'.split()) self.assertIs(args.func, command) CLICommandParser.error = VerifyError(self) parser.parse_args('test command'.split()) self.assertTrue(CLICommandParser.error.called)
def test_cli_ctx_type_error(self): with self.assertRaises(TypeError): CLICommandParser(cli_ctx=object())