Esempio n. 1
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 = [CommandGroup("title", [MyCommand1, MyCommand2])]
    dispatcher = Dispatcher(groups)
    dispatcher.pre_parse_args(["command1"])
    dispatcher.load_command("config")
    dispatcher.run()
    assert isinstance(MyCommand1._executed[0], argparse.Namespace)
Esempio n. 2
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",
    ]
Esempio n. 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
Esempio n. 4
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
Esempio n. 5
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."
Esempio n. 6
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
Esempio n. 7
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."
Esempio n. 8
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"
Esempio n. 9
0
def test_dispatcher_generic_setup_paramglobal_without_param_confusing(options):
    """Generic parameter handling for a param type global arg confusing the command as the arg."""
    cmd = create_command("somecommand")
    groups = [CommandGroup("title", [cmd])]
    extra = GlobalArgument("globalparam", "option", "-g", "--globalparam", "Test global param.")
    dispatcher = Dispatcher(groups, [extra])
    with patch("charmcraft.helptexts.HelpBuilder.get_full_help") as mock_helper:
        mock_helper.return_value = "help text"
        with pytest.raises(ArgumentParsingError) as err:
            dispatcher.pre_parse_args(options)

    # generic usage message because "no command" (as 'somecommand' was consumed by --globalparam)
    assert str(err.value) == "help text"
Esempio n. 10
0
def test_tool_exec_help_on_too_many_things(sysargv, help_builder):
    """Trying to get help on too many items."""
    help_builder.init("testapp", "general summary", [])
    dispatcher = Dispatcher([])
    with pytest.raises(ArgumentParsingError) as cm:
        dispatcher.pre_parse_args(sysargv)

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

        Error: Too many parameters when requesting help; pass a command, '--all', or leave it empty
        """)

    error = cm.value
    assert str(error) == expected
Esempio n. 11
0
def test_tool_exec_help_on_command_incorrect(sysargv, help_builder):
    """Execute a command that doesn't exist."""
    help_builder.init("testapp", "general summary", [])
    dispatcher = Dispatcher([])
    with pytest.raises(ArgumentParsingError) as cm:
        dispatcher.pre_parse_args(sysargv)

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

        Error: command 'wrongcommand' not found to provide help for
        """)

    error = cm.value
    assert str(error) == expected
Esempio n. 12
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 = [CommandGroup("title", [MyCommand])]
    dispatcher = Dispatcher(groups)
    dispatcher.pre_parse_args(["cmdname"])
    dispatcher.load_command("config")
    with pytest.raises(ValueError):
        dispatcher.run()
Esempio n. 13
0
def test_dispatcher_command_return_code():
    """Command ends indicating the return code to be used."""

    class MyCommand(BaseCommand):
        help_msg = "some help"
        name = "cmdname"

        def run(self, parsed_args):
            return 17

    groups = [CommandGroup("title", [MyCommand])]
    dispatcher = Dispatcher(groups)
    dispatcher.pre_parse_args(["cmdname"])
    dispatcher.load_command("config")
    retcode = dispatcher.run()
    assert retcode == 17
Esempio n. 14
0
def test_tool_exec_help_command_on_command_wrong():
    """Execute charmcraft asking for help on a command which does not exist."""
    command_groups = [CommandGroup("group", [])]
    dispatcher = Dispatcher(command_groups)

    with patch("charmcraft.helptexts.HelpBuilder.get_usage_message") as mock:
        mock.return_value = "test help"
        with pytest.raises(ArgumentParsingError) as cm:
            dispatcher.pre_parse_args(["help", "wrongcommand"])
    error = cm.value

    # check the given information to the help text builder
    assert mock.call_args[0] == (
        "command 'wrongcommand' not found to provide help for", )

    # check the result of the help builder is what is shown
    assert str(error) == "test help"
Esempio n. 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"
Esempio n. 16
0
def test_tool_exec_full_help(sysargv):
    """Execute charmcraft explicitly asking for help."""
    dispatcher = Dispatcher([])
    with patch("charmcraft.helptexts.HelpBuilder.get_full_help") as mock:
        mock.return_value = "test help"
        with pytest.raises(ProvideHelpException) as cm:
            dispatcher.pre_parse_args(sysargv)

    # 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 sorted(x[0] for x in args[0]) == [
        "-h, --help",
        "-q, --quiet",
        "-t, --trace",
        "-v, --verbose",
    ]
Esempio n. 17
0
def test_tool_exec_no_arguments_help():
    """Execute charmcraft without any option at all."""
    dispatcher = Dispatcher([])
    with patch("charmcraft.helptexts.HelpBuilder.get_full_help") as mock:
        mock.return_value = "test help"
        with pytest.raises(ArgumentParsingError) as cm:
            dispatcher.pre_parse_args([])
    error = cm.value

    # check the given information to the help text builder
    args = mock.call_args[0]
    assert sorted(x[0] for x in args[0]) == [
        "-h, --help",
        "-q, --quiet",
        "-t, --trace",
        "-v, --verbose",
    ]

    # check the result of the full help builder is what is shown
    assert str(error) == "test help"
Esempio n. 18
0
def test_tool_exec_command_wrong_option(help_builder):
    """Execute a correct command but with a wrong option."""
    cmd = create_command("somecommand", "This command does that.")
    command_groups = [CommandGroup("group", [cmd])]
    dispatcher = Dispatcher(command_groups)
    dispatcher.pre_parse_args(["somecommand", "--whatever"])

    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: unrecognized arguments: --whatever
        """)

    error = cm.value
    assert str(error) == expected
Esempio n. 19
0
def test_tool_exec_help_command_all():
    """Execute charmcraft asking for detailed help."""
    command_groups = [CommandGroup("group", [])]
    dispatcher = Dispatcher(command_groups)

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

    # check the result of the 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 sorted(x[0] for x in args[0]) == [
        "-h, --help",
        "-q, --quiet",
        "-t, --trace",
        "-v, --verbose",
    ]
Esempio n. 20
0
def test_tool_exec_help_command_on_command_complex():
    """Execute charmcraft asking for help on a command with parameters and options."""
    def fill_parser(self, parser):
        parser.add_argument("param1", help="help on param1")
        parser.add_argument("param2", help="help on param2")
        parser.add_argument("param3",
                            metavar="transformed3",
                            help="help on param2")
        parser.add_argument("--option1", help="help on option1")
        parser.add_argument("-o2", "--option2", help="help on option2")

    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(["help", "somecommand"])

    # check the result of the 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
    expected_options = [
        "--option1",
        "-h, --help",
        "-o2, --option2",
        "-q, --quiet",
        "-t, --trace",
        "-v, --verbose",
        "param1",
        "param2",
        "transformed3",
    ]
    assert sorted(x[0] for x in args[1]) == expected_options
Esempio n. 21
0
def test_tool_exec_help_command_on_command_ok():
    """Execute charmcraft asking for help on a command ok."""
    cmd = create_command("somecommand", "This command does that.")
    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(["help", "somecommand"])

    # check the result of the 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 isinstance(args[0], cmd)
    assert sorted(x[0] for x in args[1]) == [
        "-h, --help",
        "-q, --quiet",
        "-t, --trace",
        "-v, --verbose",
    ]
Esempio n. 22
0
def test_dispatcher_command_execution_ok():
    """Command execution depends of the indicated name in command line, return code ok."""

    class MyCommandControl(BaseCommand):
        help_msg = "some help"

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

    class MyCommand1(MyCommandControl):
        name = "name1"
        _executed = []

    class MyCommand2(MyCommandControl):
        name = "name2"
        _executed = []

    groups = [CommandGroup("title", [MyCommand1, MyCommand2])]
    dispatcher = Dispatcher(groups)
    dispatcher.pre_parse_args(["name2"])
    dispatcher.load_command("config")
    dispatcher.run()
    assert MyCommand1._executed == []
    assert isinstance(MyCommand2._executed[0], argparse.Namespace)
Esempio n. 23
0
def test_dispatcher_pre_parsing():
    """Parses and return global arguments."""
    groups = [CommandGroup("title", [create_command("somecommand")])]
    dispatcher = Dispatcher(groups)
    global_args = dispatcher.pre_parse_args(["-q", "somecommand"])
    assert global_args == {"help": False, "verbose": False, "quiet": True, "trace": False}