コード例 #1
0
def test_tool_exec_command_dash_help_missing_params(help_option):
    """Execute a command (which needs params) asking for help."""
    def fill_parser(self, parser):
        parser.add_argument('mandatory')

    cmd = create_command('somecommand', 'This command does that.')
    cmd.fill_parser = fill_parser
    command_groups = COMMAND_GROUPS + [('group', 'help text', [cmd])]

    dispatcher = Dispatcher(['somecommand', help_option], command_groups)

    with patch('charmcraft.helptexts.get_command_help') as mock:
        mock.return_value = 'test help'
        with pytest.raises(CommandError) as cm:
            dispatcher.run()
    error = cm.value

    # check the given information to the builder
    args = mock.call_args[0]
    assert args[0] == COMMAND_GROUPS
    assert args[1].__class__ == cmd
    assert {x[0]
            for x in args[2]
            } == {'-h, --help', '-v, --verbose', '-q, --quiet', 'mandatory'}

    # check the result of the full help builder is what is shown
    assert error.argsparsing
    assert str(error) == "test help"
コード例 #2
0
def test_dispatcher_commands_are_not_loaded_if_not_needed():
    class MyCommand1(BaseCommand):
        """Expected to be executed."""

        name = "command1"
        help_msg = "some help"
        _executed = []

        def run(self, parsed_args):
            self._executed.append(parsed_args)

    class MyCommand2(BaseCommand):
        """Expected to not be instantiated, or parse args, or run."""

        name = "command2"
        help_msg = "some help"

        def __init__(self, *args):
            raise AssertionError

        def fill_parser(self, parser):
            raise AssertionError

        def run(self, parsed_args):
            raise AssertionError

    groups = [("test-group", "title", [MyCommand1, MyCommand2])]
    dispatcher = Dispatcher(["command1"], groups)
    dispatcher.run()
    assert isinstance(MyCommand1._executed[0], argparse.Namespace)
コード例 #3
0
def test_tool_exec_command_bad_option_type(help_builder):
    """Execute a correct command but giving the valid option a bad value."""
    def fill_parser(self, parser):
        parser.add_argument("--number", type=int)

    cmd = create_command("somecommand", "This command does that.")
    cmd.fill_parser = fill_parser

    command_groups = [CommandGroup("group", [cmd])]
    dispatcher = Dispatcher(command_groups)
    dispatcher.pre_parse_args(["somecommand", "--number=foo"])

    help_builder.init("testapp", "general summary", command_groups)
    with pytest.raises(ArgumentParsingError) as cm:
        dispatcher.load_command("config")

    expected = textwrap.dedent("""\
        Usage: testapp [options] command [args]...
        Try 'testapp somecommand -h' for help.

        Error: argument --number: invalid int value: 'foo'
        """)

    error = cm.value
    assert str(error) == expected
コード例 #4
0
def test_tool_exec_command_dash_help_reverse(help_option):
    """Execute a command (that needs no params) asking for help."""
    cmd = create_command('somecommand', 'This command does that.')
    command_groups = COMMAND_GROUPS + [('group', 'help text', [cmd])]

    dispatcher = Dispatcher([help_option, 'somecommand'], command_groups)

    with patch('charmcraft.helptexts.get_command_help') as mock:
        mock.return_value = 'test help'
        with pytest.raises(CommandError) as cm:
            dispatcher.run()
    error = cm.value

    # check the given information to the builder
    args = mock.call_args[0]
    assert args[0] == COMMAND_GROUPS
    assert args[1].__class__ == cmd
    assert sorted(x[0] for x in args[2]) == [
        '-h, --help', '-p, --project-dir', '-q, --quiet', '-v, --verbose'
    ]

    # check the result of the full help builder is what is shown
    assert error.argsparsing
    assert str(error) == "test help"
    assert error.retcode == 0
コード例 #5
0
ファイル: test_help.py プロジェクト: dstathis/charmcraft
def test_tool_exec_command_bad_option_type():
    """Execute a correct command but giving the valid option a bad value."""

    def fill_parser(self, parser):
        parser.add_argument("--number", type=int)

    cmd = create_command("somecommand", "This command does that.")
    cmd.fill_parser = fill_parser

    command_groups = [("group", "help text", [cmd])]
    with pytest.raises(CommandError) as cm:
        Dispatcher(["somecommand", "--number=foo"], command_groups)

    expected = textwrap.dedent(
        """\
        Usage: charmcraft [options] command [args]...
        Try 'charmcraft somecommand -h' for help.

        Error: argument --number: invalid int value: 'foo'
        """
    )

    error = cm.value
    assert error.argsparsing
    assert str(error) == expected
    assert error.retcode == 1
コード例 #6
0
ファイル: test_help.py プロジェクト: jnsgruk/charmcraft
def test_tool_exec_help_command_on_command_ok():
    """Execute charmcraft asking for help on a command ok."""
    dispatcher = Dispatcher(["help", "version"], COMMAND_GROUPS)

    with patch("charmcraft.helptexts.get_command_help") as mock:
        mock.return_value = "test help"
        with pytest.raises(CommandError) as cm:
            dispatcher.run()
    error = cm.value

    # check the given information to the builder
    args = mock.call_args[0]
    assert args[0] == COMMAND_GROUPS
    assert args[1].__class__ == VersionCommand
    assert sorted(x[0] for x in args[2]) == [
        "-h, --help",
        "-p, --project-dir",
        "-q, --quiet",
        "-v, --verbose",
    ]

    # check the result of the full help builder is what is shown
    assert error.argsparsing
    assert str(error) == "test help"
    assert error.retcode == 0
コード例 #7
0
def test_dispatcher_global_arguments_default():
    """The dispatcher uses the default global arguments."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]

    dispatcher = Dispatcher(groups)
    assert dispatcher.global_arguments == _DEFAULT_GLOBAL_ARGS
コード例 #8
0
def test_tool_exec_command_dash_help_missing_params(help_option):
    """Execute a command (which needs params) asking for help."""
    def fill_parser(self, parser):
        parser.add_argument("mandatory")

    cmd = create_command("somecommand", "This command does that.")
    cmd.fill_parser = fill_parser
    command_groups = [CommandGroup("group", [cmd])]
    dispatcher = Dispatcher(command_groups)

    with patch("charmcraft.helptexts.HelpBuilder.get_command_help") as mock:
        mock.return_value = "test help"
        with pytest.raises(ProvideHelpException) as cm:
            dispatcher.pre_parse_args(["somecommand", help_option])

    # check the result of the full help builder is what is transmitted
    assert str(cm.value) == "test help"

    # check the given information to the help text builder
    args = mock.call_args[0]
    assert args[0].__class__ == cmd
    assert sorted(x[0] for x in args[1]) == [
        "-h, --help",
        "-q, --quiet",
        "-t, --trace",
        "-v, --verbose",
        "mandatory",
    ]
コード例 #9
0
def test_dispatcher_generic_setup_projectdir_with_param(options):
    """Generic parameter handling for 'project dir' with the param, directly or after the cmd."""
    cmd = create_command("somecommand")
    groups = [("test-group", "title", [cmd])]
    with patch("charmcraft.config.load") as config_mock:
        Dispatcher(options, groups)
    config_mock.assert_called_once_with("foobar")
コード例 #10
0
def test_dispatcher_generic_setup_quiet(options):
    """Generic parameter handling for quiet log setup, directly or after the command."""
    cmd = create_command("somecommand")
    groups = [("test-group", "title", [cmd])]
    logsetup.message_handler.mode = None
    Dispatcher(options, groups)
    assert logsetup.message_handler.mode == logsetup.message_handler.QUIET
コード例 #11
0
ファイル: test_help.py プロジェクト: jnsgruk/charmcraft
def test_tool_exec_command_dash_help_missing_params(help_option):
    """Execute a command (which needs params) asking for help."""
    def fill_parser(self, parser):
        parser.add_argument("mandatory")

    cmd = create_command("somecommand", "This command does that.")
    cmd.fill_parser = fill_parser
    command_groups = COMMAND_GROUPS + [("group", "help text", [cmd])]

    dispatcher = Dispatcher(["somecommand", help_option], command_groups)

    with patch("charmcraft.helptexts.get_command_help") as mock:
        mock.return_value = "test help"
        with pytest.raises(CommandError) as cm:
            dispatcher.run()
    error = cm.value

    # check the given information to the builder
    args = mock.call_args[0]
    assert args[0] == COMMAND_GROUPS
    assert args[1].__class__ == cmd
    assert sorted(x[0] for x in args[2]) == [
        "-h, --help",
        "-p, --project-dir",
        "-q, --quiet",
        "-v, --verbose",
        "mandatory",
    ]

    # check the result of the full help builder is what is shown
    assert error.argsparsing
    assert str(error) == "test help"
    assert error.retcode == 0
コード例 #12
0
ファイル: test_main.py プロジェクト: tomwardill/charmcraft
def test_dispatcher_generic_setup_verbose(options):
    """Generic parameter handling for verbose log setup, directly or after the command."""
    cmd = create_command('somecommand')
    groups = [('test-group', 'title', [cmd])]
    logsetup.message_handler.mode = None
    Dispatcher(options, groups)
    assert logsetup.message_handler.mode == logsetup.message_handler.VERBOSE
コード例 #13
0
def test_dispatcher_generic_setup_projectdir_without_param_simple(options):
    """Generic parameter handling for 'project dir' without the requested parameter."""
    cmd = create_command("somecommand")
    groups = [("test-group", "title", [cmd])]
    with pytest.raises(CommandError) as err:
        Dispatcher(options, groups)
    assert str(err.value) == "The 'project-dir' option expects one argument."
コード例 #14
0
def test_dispatcher_generic_setup_trace(options):
    """Generic parameter handling for trace log setup, directly or after the command."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]
    emit.set_mode(EmitterMode.NORMAL)  # this is how `main` will init the Emitter
    dispatcher = Dispatcher(groups)
    dispatcher.pre_parse_args(options)
    assert emit.get_mode() == EmitterMode.TRACE
コード例 #15
0
def test_dispatcher_generic_setup_paramglobal_with_param(options):
    """Generic parameter handling for a param type global arg, directly or after the cmd."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]
    extra = GlobalArgument("globalparam", "option", "-g", "--globalparam", "Test global param.")
    dispatcher = Dispatcher(groups, [extra])
    global_args = dispatcher.pre_parse_args(options)
    assert global_args["globalparam"] == "foobar"
コード例 #16
0
def test_dispatcher_generic_setup_mutually_exclusive(options):
    """Disallow mutually exclusive generic options."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]
    dispatcher = Dispatcher(groups)
    with pytest.raises(ArgumentParsingError) as err:
        dispatcher.pre_parse_args(options)
    assert str(err.value) == "The 'verbose', 'trace' and 'quiet' options are mutually exclusive."
コード例 #17
0
def test_dispatcher_generic_setup_default():
    """Generic parameter handling for default values."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]
    emit.set_mode(EmitterMode.NORMAL)  # this is how `main` will init the Emitter
    dispatcher = Dispatcher(groups)
    dispatcher.pre_parse_args(["somecommand"])
    assert emit.get_mode() == EmitterMode.NORMAL
コード例 #18
0
def test_dispatcher_generic_setup_mutually_exclusive(options):
    """Disallow mutually exclusive generic options."""
    cmd = create_command('somecommand')
    groups = [('test-group', 'title', [cmd])]
    # test the system exit, which is done automatically by argparse
    with pytest.raises(CommandError) as err:
        Dispatcher(options, groups)
    assert str(err.value) == "The 'verbose' and 'quiet' options are mutually exclusive."
コード例 #19
0
def test_dispatcher_global_arguments_extra_arguments():
    """The dispatcher uses the default global arguments."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]

    extra_arg = GlobalArgument("other", "flag", "-o", "--other", "Other stuff")
    dispatcher = Dispatcher(groups, extra_global_args=[extra_arg])
    assert dispatcher.global_arguments == _DEFAULT_GLOBAL_ARGS + [extra_arg]
コード例 #20
0
def test_dispatcher_generic_setup_mutually_exclusive(options):
    """Disallow mutually exclusive generic options."""
    cmd = create_command('somecommand')
    groups = [('test-group', 'title', [cmd])]
    # test the system exit, which is done automatically by argparse
    with pytest.raises(SystemExit) as cm:
        Dispatcher(options, groups)
    assert cm.value.code == 2
コード例 #21
0
def test_dispatcher_generic_setup_quiet(options):
    """Generic parameter handling for silent log setup, directly of after the command."""
    cmd = create_command('somecommand')
    groups = [('test-group', 'title', [cmd])]
    dispatcher = Dispatcher(options, groups)
    logsetup.message_handler.mode = None
    dispatcher.run()
    assert logsetup.message_handler.mode == logsetup.message_handler.QUIET
コード例 #22
0
def test_dispatcher_no_command():
    """When no command is given we should get the "usage" help."""
    groups = [('test-group', 'title', [create_command('cmd-name', 'cmd help')])]
    dispatcher = Dispatcher([], groups)
    fake_stdout = io.StringIO()
    with patch('sys.stdout', fake_stdout):
        retcode = dispatcher.run()
    assert retcode == 1
    assert "usage: charmcraft" in fake_stdout.getvalue()
コード例 #23
0
def test_dispatcher_generic_setup_projectdir_without_param_confusing(options):
    """Generic parameter handling for 'project dir' taking confusingly the command as the arg."""
    cmd = create_command("somecommand")
    groups = [("test-group", "title", [cmd])]
    with pytest.raises(CommandError) as err:
        Dispatcher(options, groups)

    # generic usage message because "no command" (as 'somecommand' was consumed by --project-dir)
    assert "Usage" in str(err.value)
コード例 #24
0
def test_dispatcher_generic_setup_paramglobal_without_param_simple(options):
    """Generic parameter handling for a param type global arg without the requested parameter."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]
    extra = GlobalArgument("globalparam", "option", "-g", "--globalparam", "Test global param.")
    dispatcher = Dispatcher(groups, [extra])
    with pytest.raises(ArgumentParsingError) as err:
        dispatcher.pre_parse_args(options)
    assert str(err.value) == "The 'globalparam' option expects one argument."
コード例 #25
0
def test_dispatcher_generic_setup_default():
    """Generic parameter handling for default values."""
    cmd = create_command("somecommand")
    groups = [("test-group", "title", [cmd])]
    logsetup.message_handler.mode = None
    with patch("charmcraft.config.load") as config_mock:
        Dispatcher(["somecommand"], groups)
    assert logsetup.message_handler.mode is None
    config_mock.assert_called_once_with(None)
コード例 #26
0
def test_dispatcher_command_loading():
    """Parses and return global arguments."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]
    dispatcher = Dispatcher(groups)
    dispatcher.pre_parse_args(["somecommand"])
    command = dispatcher.load_command("test-config")
    assert isinstance(command, cmd)
    assert command.config == "test-config"
コード例 #27
0
ファイル: test_main.py プロジェクト: tomwardill/charmcraft
def test_dispatcher_config_not_needed():
    """Command does not needs a config."""
    class MyCommand(BaseCommand):
        help_msg = "some help"
        name = 'cmdname'

        def run(self, parsed_args):
            pass

    groups = [('test-group', 'title', [MyCommand])]
    dispatcher = Dispatcher(['cmdname'], groups)
    dispatcher.run()
コード例 #28
0
def test_dispatcher_build_commands_ok():
    """Correct command loading."""
    cmd0, cmd1, cmd2 = [create_command("cmd-name-{}".format(n), "cmd help") for n in range(3)]
    groups = [
        CommandGroup("whatever title", [cmd0]),
        CommandGroup("other title", [cmd1, cmd2]),
    ]
    dispatcher = Dispatcher(groups)
    assert len(dispatcher.commands) == 3
    for cmd in [cmd0, cmd1, cmd2]:
        expected_class = dispatcher.commands[cmd.name]
        assert expected_class == cmd
コード例 #29
0
def test_dispatcher_config_not_needed():
    """Command does not needs a config."""
    class MyCommand(BaseCommand):
        help_msg = "some help"
        name = "cmdname"

        def run(self, parsed_args):
            pass

    groups = [("test-group", "title", [MyCommand])]
    dispatcher = Dispatcher(["cmdname"], groups)
    dispatcher.run()
コード例 #30
0
def test_dispatcher_command_execution_crash():
    """Command crashing doesn't pass through, we inform nicely."""
    class MyCommand(BaseCommand):
        help_msg = "some help"
        name = "cmdname"

        def run(self, parsed_args):
            raise ValueError()

    groups = [("test-group", "title", [MyCommand])]
    dispatcher = Dispatcher(["cmdname"], groups)
    with pytest.raises(ValueError):
        dispatcher.run()