diff options
-rw-r--r-- | tests/test_argparse.py | 63 | ||||
-rw-r--r-- | tests_isolated/test_commandset/test_commandset.py | 27 |
2 files changed, 90 insertions, 0 deletions
diff --git a/tests/test_argparse.py b/tests/test_argparse.py index 1334f9e3..0d46b15a 100644 --- a/tests/test_argparse.py +++ b/tests/test_argparse.py @@ -92,6 +92,7 @@ class ArgparseApp(cmd2.Cmd): known_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay') known_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE') known_parser.add_argument('-r', '--repeat', type=int, help='output [n] times') + @cmd2.with_argparser(known_parser, with_unknown_args=True) def do_speak(self, args, extra, *, keyword_arg: Optional[str] = None): """Repeat what you tell me to.""" @@ -131,89 +132,108 @@ def test_invalid_syntax(argparse_app): out, err = run_cmd(argparse_app, 'speak "') assert err[0] == "Invalid syntax: No closing quotation" + def test_argparse_basic_command(argparse_app): out, err = run_cmd(argparse_app, 'say hello') assert out == ['hello'] + def test_argparse_remove_quotes(argparse_app): out, err = run_cmd(argparse_app, 'say "hello there"') assert out == ['hello there'] + def test_argparser_kwargs(argparse_app, capsys): """Test with_argparser wrapper passes through kwargs to command function""" argparse_app.do_say('word', keyword_arg="foo") out, err = capsys.readouterr() assert out == "foo\n" + def test_argparse_preserve_quotes(argparse_app): out, err = run_cmd(argparse_app, 'tag mytag "hello"') assert out[0] == '<mytag>"hello"</mytag>' + def test_argparse_custom_namespace(argparse_app): out, err = run_cmd(argparse_app, 'test_argparse_ns') assert out[0] == 'custom' + def test_argparse_with_list(argparse_app): out, err = run_cmd(argparse_app, 'speak -s hello world!') assert out == ['HELLO WORLD!'] + def test_argparse_with_list_remove_quotes(argparse_app): out, err = run_cmd(argparse_app, 'speak -s hello "world!"') assert out == ['HELLO WORLD!'] + def test_argparse_with_list_preserve_quotes(argparse_app): out, err = run_cmd(argparse_app, 'test_argparse_with_list_quotes "hello" person') assert out[0] == '"hello" person' + def test_argparse_with_list_custom_namespace(argparse_app): out, err = run_cmd(argparse_app, 'test_argparse_with_list_ns') assert out[0] == 'custom' + def test_argparse_with_list_and_empty_doc(argparse_app): out, err = run_cmd(argparse_app, 'speak -s hello world!') assert out == ['HELLO WORLD!'] + def test_argparser_correct_args_with_quotes_and_midline_options(argparse_app): out, err = run_cmd(argparse_app, "speak 'This is a' -s test of the emergency broadcast system!") assert out == ['THIS IS A TEST OF THE EMERGENCY BROADCAST SYSTEM!'] + def test_argparser_and_unknown_args_kwargs(argparse_app, capsys): """Test with_argparser_and_unknown_args wrapper passes through kwargs to command function""" argparse_app.do_speak('', keyword_arg="foo") out, err = capsys.readouterr() assert out == "foo\n" + def test_argparse_quoted_arguments_multiple(argparse_app): out, err = run_cmd(argparse_app, 'say "hello there" "rick & morty"') assert out == ['hello there rick & morty'] + def test_argparse_help_docstring(argparse_app): out, err = run_cmd(argparse_app, 'help say') assert out[0].startswith('usage: say') assert out[1] == '' assert out[2] == 'Repeat what you tell me to.' + def test_argparse_help_description(argparse_app): out, err = run_cmd(argparse_app, 'help tag') assert out[0].startswith('usage: tag') assert out[1] == '' assert out[2] == 'create a html tag' + def test_argparse_prog(argparse_app): out, err = run_cmd(argparse_app, 'help tag') progname = out[0].split(' ')[1] assert progname == 'tag' + def test_arglist(argparse_app): out, err = run_cmd(argparse_app, 'arglist "we should" get these') assert out[0] == 'True' + def test_arglist_kwargs(argparse_app, capsys): """Test with_argument_list wrapper passes through kwargs to command function""" argparse_app.do_arglist('arg', keyword_arg="foo") out, err = capsys.readouterr() assert out == "foo\n" + def test_preservelist(argparse_app): out, err = run_cmd(argparse_app, 'preservelist foo "bar baz"') assert out[0] == "['foo', '\"bar baz\"']" @@ -269,6 +289,7 @@ class SubcommandApp(cmd2.Cmd): func = getattr(args, 'func') func(self, args) + @pytest.fixture def subcommand_app(): app = SubcommandApp() @@ -284,17 +305,20 @@ def test_subcommand_bar(subcommand_app): out, err = run_cmd(subcommand_app, 'base bar baz') assert out == ['((baz))'] + def test_subcommand_invalid(subcommand_app): out, err = run_cmd(subcommand_app, 'base baz') assert err[0].startswith('usage: base') assert err[1].startswith("base: error: argument SUBCOMMAND: invalid choice: 'baz'") + def test_subcommand_base_help(subcommand_app): out, err = run_cmd(subcommand_app, 'help base') assert out[0].startswith('usage: base') assert out[1] == '' assert out[2] == 'Base command help' + def test_subcommand_help(subcommand_app): # foo has no aliases out, err = run_cmd(subcommand_app, 'help base foo') @@ -334,10 +358,12 @@ def test_subcommand_help(subcommand_app): assert out[1] == '' assert out[2] == 'positional arguments:' + def test_subcommand_invalid_help(subcommand_app): out, err = run_cmd(subcommand_app, 'help base baz') assert out[0].startswith('usage: base') + def test_add_another_subcommand(subcommand_app): """ This tests makes sure _set_parser_prog() sets _prog_prefix on every _SubParsersAction so that all future calls @@ -345,3 +371,40 @@ def test_add_another_subcommand(subcommand_app): """ new_parser = subcommand_app.base_subparsers.add_parser('new_sub', help="stuff") assert new_parser.prog == "base new_sub" + + +def test_unittest_mock(): + from unittest import mock + from cmd2 import CommandSetRegistrationError + + with mock.patch.object(ArgparseApp, 'namespace_provider'): + with pytest.raises(CommandSetRegistrationError): + app = ArgparseApp() + + with mock.patch.object(ArgparseApp, 'namespace_provider', spec=True): + app = ArgparseApp() + + with mock.patch.object(ArgparseApp, 'namespace_provider', spec_set=True): + app = ArgparseApp() + + with mock.patch.object(ArgparseApp, 'namespace_provider', autospec=True): + app = ArgparseApp() + + +def test_pytest_mock_invalid(mocker): + from cmd2 import CommandSetRegistrationError + + mocker.patch.object(ArgparseApp, 'namespace_provider') + with pytest.raises(CommandSetRegistrationError): + app = ArgparseApp() + + +@pytest.mark.parametrize('spec_param', [ + {'spec': True}, + {'spec_set': True}, + {'autospec': True}, +]) +def test_pytest_mock_valid(mocker, spec_param): + mocker.patch.object(ArgparseApp, 'namespace_provider', **spec_param) + app = ArgparseApp() + diff --git a/tests_isolated/test_commandset/test_commandset.py b/tests_isolated/test_commandset/test_commandset.py index ffeadf75..6856881a 100644 --- a/tests_isolated/test_commandset/test_commandset.py +++ b/tests_isolated/test_commandset/test_commandset.py @@ -844,3 +844,30 @@ def test_path_complete(command_sets_manual): first_match = complete_tester(text, line, begidx, endidx, command_sets_manual) assert first_match is not None + + +def test_bad_subcommand(): + class BadSubcommandApp(cmd2.Cmd): + """Class for testing usage of `as_subcommand_to` decorator directly in a Cmd2 subclass.""" + + def __init__(self, *args, **kwargs): + super(BadSubcommandApp, self).__init__(*args, **kwargs) + + cut_parser = cmd2.Cmd2ArgumentParser('cut') + cut_subparsers = cut_parser.add_subparsers(title='item', help='item to cut') + + @cmd2.with_argparser(cut_parser) + def do_cut(self, ns: argparse.Namespace): + """Cut something""" + pass + + banana_parser = cmd2.Cmd2ArgumentParser(add_help=False) + banana_parser.add_argument('direction', choices=['discs', 'lengthwise']) + + @cmd2.as_subcommand_to('cut', 'bad name', banana_parser, help='This should fail') + def cut_banana(self, ns: argparse.Namespace): + """Cut banana""" + self.poutput('cutting banana: ' + ns.direction) + + with pytest.raises(CommandSetRegistrationError): + app = BadSubcommandApp() |