summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test_acargparse.py66
-rw-r--r--tests/test_argparse_completer.py648
-rw-r--r--tests/test_argparse_custom.py145
-rw-r--r--tests/test_autocompletion.py345
-rw-r--r--tests/test_cmd2.py31
-rw-r--r--tests/test_completion.py19
6 files changed, 823 insertions, 431 deletions
diff --git a/tests/test_acargparse.py b/tests/test_acargparse.py
deleted file mode 100644
index 436158db..00000000
--- a/tests/test_acargparse.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# flake8: noqa E302
-"""
-Unit/functional testing for argparse customizations in cmd2
-"""
-import pytest
-from cmd2.argparse_completer import ACArgumentParser, is_potential_flag
-
-
-def test_acarg_narg_empty_tuple():
- with pytest.raises(ValueError) as excinfo:
- parser = ACArgumentParser(prog='test')
- parser.add_argument('invalid_tuple', nargs=())
- assert 'Ranged values for nargs must be a tuple of 2 integers' in str(excinfo.value)
-
-
-def test_acarg_narg_single_tuple():
- with pytest.raises(ValueError) as excinfo:
- parser = ACArgumentParser(prog='test')
- parser.add_argument('invalid_tuple', nargs=(1,))
- assert 'Ranged values for nargs must be a tuple of 2 integers' in str(excinfo.value)
-
-
-def test_acarg_narg_tuple_triple():
- with pytest.raises(ValueError) as excinfo:
- parser = ACArgumentParser(prog='test')
- parser.add_argument('invalid_tuple', nargs=(1, 2, 3))
- assert 'Ranged values for nargs must be a tuple of 2 integers' in str(excinfo.value)
-
-
-def test_acarg_narg_tuple_order():
- with pytest.raises(ValueError) as excinfo:
- parser = ACArgumentParser(prog='test')
- parser.add_argument('invalid_tuple', nargs=(2, 1))
- assert 'Invalid nargs range. The first value must be less than the second' in str(excinfo.value)
-
-
-def test_acarg_narg_tuple_negative():
- with pytest.raises(ValueError) as excinfo:
- parser = ACArgumentParser(prog='test')
- parser.add_argument('invalid_tuple', nargs=(-1, 1))
- assert 'Negative numbers are invalid for nargs range' in str(excinfo.value)
-
-
-def test_acarg_narg_tuple_zero_base():
- parser = ACArgumentParser(prog='test')
- parser.add_argument('tuple', nargs=(0, 3))
-
-
-def test_acarg_narg_tuple_zero_to_one():
- parser = ACArgumentParser(prog='test')
- parser.add_argument('tuple', nargs=(0, 1))
-
-
-def test_is_potential_flag():
- parser = ACArgumentParser()
-
- # Not valid flags
- assert not is_potential_flag('', parser)
- assert not is_potential_flag('non-flag', parser)
- assert not is_potential_flag('-', parser)
- assert not is_potential_flag('--has space', parser)
- assert not is_potential_flag('-2', parser)
-
- # Valid flags
- assert is_potential_flag('-flag', parser)
- assert is_potential_flag('--flag', parser)
diff --git a/tests/test_argparse_completer.py b/tests/test_argparse_completer.py
new file mode 100644
index 00000000..f1faa66a
--- /dev/null
+++ b/tests/test_argparse_completer.py
@@ -0,0 +1,648 @@
+# coding=utf-8
+# flake8: noqa E302
+"""
+Unit/functional testing for argparse completer in cmd2
+"""
+import argparse
+from typing import List
+
+import pytest
+
+import cmd2
+from cmd2 import with_argparser, Cmd2ArgParser, CompletionItem
+from cmd2.utils import StdSim, basic_complete
+from .conftest import run_cmd, complete_tester
+
+# Lists used in our tests
+static_int_choices_list = [1, 2, 3, 4, 5]
+static_choices_list = ['static', 'choices', 'stop', 'here']
+choices_from_function = ['choices', 'function', 'chatty', 'smith']
+choices_from_method = ['choices', 'method', 'most', 'improved']
+
+set_value_choices = ['set', 'value', 'choices']
+one_or_more_choices = ['one', 'or', 'more', 'choices']
+optional_choices = ['a', 'few', 'optional', 'choices']
+range_choices = ['some', 'range', 'choices']
+remainder_choices = ['remainder', 'choices']
+
+positional_choices = ['the', 'positional', 'choices']
+
+completions_from_function = ['completions', 'function', 'fairly', 'complete']
+completions_from_method = ['completions', 'method', 'missed', 'spot']
+
+
+def choices_function() -> List[str]:
+ """Function that provides choices"""
+ return choices_from_function
+
+
+def completer_function(text: str, line: str, begidx: int, endidx: int) -> List[str]:
+ """Tab completion function"""
+ return basic_complete(text, line, begidx, endidx, completions_from_function)
+
+
+# noinspection PyMethodMayBeStatic,PyUnusedLocal
+class AutoCompleteTester(cmd2.Cmd):
+ """Cmd2 app that exercises AutoCompleter class"""
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ ############################################################################################################
+ # Begin code related to help and command name completion
+ ############################################################################################################
+ def _music_create(self, args: argparse.Namespace) -> None:
+ """Implements the 'music create' command"""
+ self.poutput('music create')
+
+ def _music_create_jazz(self, args: argparse.Namespace) -> None:
+ """Implements the 'music create jazz' command"""
+ self.poutput('music create jazz')
+
+ def _music_create_rock(self, args: argparse.Namespace) -> None:
+ """Implements the 'music create rock' command"""
+ self.poutput('music create rock')
+
+ # Top level parser for music command
+ music_parser = Cmd2ArgParser(description='Manage music', prog='music')
+
+ # Add sub-commands to music
+ music_subparsers = music_parser.add_subparsers()
+
+ # music -> create
+ music_create_parser = music_subparsers.add_parser('create', help='Create music')
+ music_create_parser.set_defaults(func=_music_create)
+
+ # Add sub-commands to music -> create
+ music_create_subparsers = music_create_parser.add_subparsers()
+
+ # music -> create -> jazz
+ music_create_jazz_parser = music_create_subparsers.add_parser('jazz', help='Create jazz')
+ music_create_jazz_parser.set_defaults(func=_music_create_jazz)
+
+ # music -> create -> rock
+ music_create_rock_parser = music_create_subparsers.add_parser('rock', help='Create rocks')
+ music_create_rock_parser.set_defaults(func=_music_create_rock)
+
+ @with_argparser(music_parser)
+ def do_music(self, args: argparse.Namespace) -> None:
+ """Music command"""
+ func = getattr(args, 'func', None)
+ if func is not None:
+ # Call whatever sub-command function was selected
+ func(self, args)
+ else:
+ # No sub-command was provided, so call help
+ # noinspection PyTypeChecker
+ self.do_help('music')
+
+ ############################################################################################################
+ # Begin code related to flag completion
+ ############################################################################################################
+
+ # Uses default flag prefix value (-)
+ flag_parser = Cmd2ArgParser()
+ flag_parser.add_argument('-n', '--normal_flag', help='A normal flag', action='store_true')
+ flag_parser.add_argument('-a', '--append_flag', help='Append flag', action='append')
+ flag_parser.add_argument('-o', '--append_const_flag', help='Append const flag', action='append_const', const=True)
+ flag_parser.add_argument('-c', '--count_flag', help='Count flag', action='count')
+ flag_parser.add_argument('-s', '--suppressed_flag', help=argparse.SUPPRESS, action='store_true')
+ flag_parser.add_argument('-r', '--remainder_flag', nargs=argparse.REMAINDER, help='a remainder flag')
+
+ @with_argparser(flag_parser)
+ def do_flag(self, args: argparse.Namespace) -> None:
+ pass
+
+ # Uses non-default flag prefix value (+)
+ plus_flag_parser = Cmd2ArgParser(prefix_chars='+')
+ plus_flag_parser.add_argument('+n', '++normal_flag', help='A normal flag', action='store_true')
+
+ @with_argparser(plus_flag_parser)
+ def do_plus_flag(self, args: argparse.Namespace) -> None:
+ pass
+
+ ############################################################################################################
+ # Begin code related to testing choices, choices_function, and choices_method parameters
+ ############################################################################################################
+ def choices_method(self) -> List[str]:
+ """Method that provides choices"""
+ return choices_from_method
+
+ def completion_item_method(self) -> List[CompletionItem]:
+ """Choices method that returns CompletionItems"""
+ items = []
+ for i in range(0, 10):
+ main_str = 'main_str{}'.format(i)
+ items.append(CompletionItem(main_str, desc='blah blah'))
+ return items
+
+ choices_parser = Cmd2ArgParser()
+
+ # Flag args for choices command. Include string and non-string arg types.
+ choices_parser.add_argument("-l", "--list", help="a flag populated with a choices list",
+ choices=static_choices_list)
+ choices_parser.add_argument("-f", "--function", help="a flag populated with a choices function",
+ choices_function=choices_function)
+ choices_parser.add_argument("-m", "--method", help="a flag populated with a choices method",
+ choices_method=choices_method)
+ choices_parser.add_argument('-n', "--no_header", help='this arg has a no descriptive header',
+ choices_method=completion_item_method)
+ choices_parser.add_argument('-i', '--int', type=int, help='a flag with an int type',
+ choices=static_int_choices_list)
+
+ # Positional args for choices command
+ choices_parser.add_argument("list_pos", help="a positional populated with a choices list",
+ choices=static_choices_list)
+ choices_parser.add_argument("function_pos", help="a positional populated with a choices function",
+ choices_function=choices_function)
+ choices_parser.add_argument("method_pos", help="a positional populated with a choices method",
+ choices_method=choices_method)
+
+ @with_argparser(choices_parser)
+ def do_choices(self, args: argparse.Namespace) -> None:
+ pass
+
+ ############################################################################################################
+ # Begin code related to testing completer_function and completer_method parameters
+ ############################################################################################################
+ def completer_method(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
+ """Tab completion method"""
+ return basic_complete(text, line, begidx, endidx, completions_from_method)
+
+ completer_parser = Cmd2ArgParser()
+
+ # Flag args for completer command
+ completer_parser.add_argument("-f", "--function", help="a flag using a completer function",
+ completer_function=completer_function)
+ completer_parser.add_argument("-m", "--method", help="a flag using a completer method",
+ completer_method=completer_method)
+
+ # Positional args for completer command
+ completer_parser.add_argument("function_pos", help="a positional using a completer function",
+ completer_function=completer_function)
+ completer_parser.add_argument("method_pos", help="a positional using a completer method",
+ completer_method=completer_method)
+
+ @with_argparser(completer_parser)
+ def do_completer(self, args: argparse.Namespace) -> None:
+ pass
+
+ ############################################################################################################
+ # Begin code related to nargs
+ ############################################################################################################
+ nargs_parser = Cmd2ArgParser()
+
+ # Flag args for nargs command
+ nargs_parser.add_argument("--set_value", help="a flag with a set value for nargs", nargs=2,
+ choices=set_value_choices)
+ nargs_parser.add_argument("--one_or_more", help="a flag wanting one or more args", nargs=argparse.ONE_OR_MORE,
+ choices=one_or_more_choices)
+ nargs_parser.add_argument("--optional", help="a flag with an optional value", nargs=argparse.OPTIONAL,
+ choices=optional_choices)
+ nargs_parser.add_argument("--range", help="a flag with nargs range", nargs=(1, 2),
+ choices=range_choices)
+ nargs_parser.add_argument("--remainder", help="a flag wanting remaining", nargs=argparse.REMAINDER,
+ choices=remainder_choices)
+
+ nargs_parser.add_argument("normal_pos", help="a remainder positional", nargs=2,
+ choices=positional_choices)
+ nargs_parser.add_argument("remainder_pos", help="a remainder positional", nargs=argparse.REMAINDER,
+ choices=remainder_choices)
+
+ @with_argparser(nargs_parser)
+ def do_nargs(self, args: argparse.Namespace) -> None:
+ pass
+
+ ############################################################################################################
+ # Begin code related to testing tab hints
+ ############################################################################################################
+ hint_parser = Cmd2ArgParser()
+ hint_parser.add_argument('-f', '--flag', help='a flag arg')
+ hint_parser.add_argument('-s', '--suppressed_help', help=argparse.SUPPRESS)
+ hint_parser.add_argument('-t', '--suppressed_hint', help='a flag arg', suppress_tab_hint=True)
+
+ hint_parser.add_argument('hint_pos', help='here is a hint\nwith new lines')
+ hint_parser.add_argument('no_help_pos')
+
+ @with_argparser(hint_parser)
+ def do_hint(self, args: argparse.Namespace) -> None:
+ pass
+
+
+@pytest.fixture
+def ac_app():
+ app = AutoCompleteTester()
+ app.stdout = StdSim(app.stdout)
+ return app
+
+
+@pytest.mark.parametrize('command', [
+ 'music',
+ 'music create',
+ 'music create rock',
+ 'music create jazz'
+])
+def test_help(ac_app, command):
+ out1, err1 = run_cmd(ac_app, '{} -h'.format(command))
+ out2, err2 = run_cmd(ac_app, 'help {}'.format(command))
+ assert out1 == out2
+
+
+@pytest.mark.parametrize('command, text, completions', [
+ ('', 'mu', ['music ']),
+ ('music', 'cre', ['create ']),
+ ('music create', '', ['jazz', 'rock'])
+])
+def test_complete_help(ac_app, command, text, completions):
+ line = 'help {} {}'.format(command, text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ if completions:
+ assert first_match is not None
+ else:
+ assert first_match is None
+
+ assert ac_app.completion_matches == sorted(completions, key=ac_app.matches_sort_key)
+
+
+@pytest.mark.parametrize('command_and_args, text, completions', [
+ # Complete all flags (suppressed will not show)
+ ('flag', '-', ['--append_const_flag', '--append_flag', '--count_flag', '--help', '--normal_flag',
+ '--remainder_flag', '-a', '-c', '-h', '-n', '-o', '-r']),
+ ('flag', '--', ['--append_const_flag', '--append_flag', '--count_flag', '--help',
+ '--normal_flag', '--remainder_flag']),
+
+ # Complete individual flag
+ ('flag', '-n', ['-n ']),
+ ('flag', '--n', ['--normal_flag ']),
+
+ # No flags should complete until current flag has its args
+ ('flag --append_flag', '-', []),
+
+ # Complete REMAINDER flag name
+ ('flag', '-r', ['-r ']),
+ ('flag', '--r', ['--remainder_flag ']),
+
+ # No flags after a REMAINDER should complete
+ ('flag -r value', '-', []),
+ ('flag --remainder_flag value', '--', []),
+
+ # Suppressed flag should not complete
+ ('flag', '-s', []),
+ ('flag', '--s', []),
+
+ # A used flag should not show in completions
+ ('flag -n', '--', ['--append_const_flag', '--append_flag', '--count_flag', '--help', '--remainder_flag']),
+
+ # Flags with actions set to append, append_const, and count will always show even if they've been used
+ ('flag --append_const_flag -c --append_flag value', '--', ['--append_const_flag', '--append_flag', '--count_flag',
+ '--help', '--normal_flag', '--remainder_flag']),
+
+ # Non-default flag prefix character (+)
+ ('plus_flag', '+', ['++help', '++normal_flag', '+h', '+n']),
+ ('plus_flag', '++', ['++help', '++normal_flag']),
+
+ # Flag completion should not occur after '--' since that tells argparse all remaining arguments are non-flags
+ ('flag --', '--', []),
+ ('flag --help --', '--', []),
+ ('plus_flag --', '++', []),
+ ('plus_flag ++help --', '++', [])
+])
+def test_autcomp_flag_completion(ac_app, command_and_args, text, completions):
+ line = '{} {}'.format(command_and_args, text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ if completions:
+ assert first_match is not None
+ else:
+ assert first_match is None
+
+ assert ac_app.completion_matches == sorted(completions, key=ac_app.matches_sort_key)
+
+
+@pytest.mark.parametrize('flag, text, completions', [
+ ('-l', '', static_choices_list),
+ ('--list', 's', ['static', 'stop']),
+ ('-f', '', choices_from_function),
+ ('--function', 'ch', ['choices', 'chatty']),
+ ('-m', '', choices_from_method),
+ ('--method', 'm', ['method', 'most']),
+ ('-i', '', [str(i) for i in static_int_choices_list]),
+ ('--int', '1', ['1 '])
+])
+def test_autocomp_flag_choices_completion(ac_app, flag, text, completions):
+ line = 'choices {} {}'.format(flag, text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ if completions:
+ assert first_match is not None
+ else:
+ assert first_match is None
+
+ assert ac_app.completion_matches == sorted(completions, key=ac_app.matches_sort_key)
+
+
+@pytest.mark.parametrize('pos, text, completions', [
+ (1, '', static_choices_list),
+ (1, 's', ['static', 'stop']),
+ (2, '', choices_from_function),
+ (2, 'ch', ['choices', 'chatty']),
+ (3, '', choices_from_method),
+ (3, 'm', ['method', 'most'])
+])
+def test_autocomp_positional_choices_completion(ac_app, pos, text, completions):
+ # Generate line were preceding positionals are already filled
+ line = 'choices {} {}'.format('foo ' * (pos - 1), text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ if completions:
+ assert first_match is not None
+ else:
+ assert first_match is None
+
+ assert ac_app.completion_matches == sorted(completions, key=ac_app.matches_sort_key)
+
+
+@pytest.mark.parametrize('flag, text, completions', [
+ ('-f', '', completions_from_function),
+ ('--function', 'f', ['function', 'fairly']),
+ ('-m', '', completions_from_method),
+ ('--method', 'm', ['method', 'missed'])
+])
+def test_autocomp_flag_completers(ac_app, flag, text, completions):
+ line = 'completer {} {}'.format(flag, text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ if completions:
+ assert first_match is not None
+ else:
+ assert first_match is None
+
+ assert ac_app.completion_matches == sorted(completions, key=ac_app.matches_sort_key)
+
+
+@pytest.mark.parametrize('pos, text, completions', [
+ (1, '', completions_from_function),
+ (1, 'c', ['completions', 'complete']),
+ (2, '', completions_from_method),
+ (2, 'm', ['method', 'missed'])
+])
+def test_autocomp_positional_completers(ac_app, pos, text, completions):
+ # Generate line were preceding positionals are already filled
+ line = 'completer {} {}'.format('foo ' * (pos - 1), text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ if completions:
+ assert first_match is not None
+ else:
+ assert first_match is None
+
+ assert ac_app.completion_matches == sorted(completions, key=ac_app.matches_sort_key)
+
+
+@pytest.mark.parametrize('num_aliases, show_description', [
+ # The number of completion results determines if the description field of CompletionItems gets displayed
+ # in the tab completions. The count must be greater than 1 and less than ac_app.max_completion_items,
+ # which defaults to 50.
+ (1, False),
+ (5, True),
+ (100, False)
+])
+def test_completion_items(ac_app, num_aliases, show_description):
+ # Create aliases
+ for i in range(0, num_aliases):
+ run_cmd(ac_app, 'alias create fake{} help'.format(i))
+
+ assert len(ac_app.aliases) == num_aliases
+
+ text = 'fake'
+ line = 'alias list {}'.format(text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ assert first_match is not None
+ assert len(ac_app.completion_matches) == num_aliases
+ assert len(ac_app.display_matches) == num_aliases
+
+ # If show_description is True, the alias's value will be in the display text
+ assert ('help' in ac_app.display_matches[0]) == show_description
+
+
+@pytest.mark.parametrize('args, completions', [
+ # Flag with nargs = 2
+ ('--set_value', set_value_choices),
+ ('--set_value set', ['value', 'choices']),
+
+ # Both args are filled. At positional arg now.
+ ('--set_value set value', positional_choices),
+
+ # Another flag can't start until all expected args are filled out
+ ('--set_value --one_or_more', set_value_choices),
+
+ # Using the flag again will reset the choices available
+ ('--set_value set value --set_value', set_value_choices),
+
+ # Flag with nargs = ONE_OR_MORE
+ ('--one_or_more', one_or_more_choices),
+ ('--one_or_more one', ['or', 'more', 'choices']),
+
+ # Flag with nargs = OPTIONAL
+ ('--optional', optional_choices),
+
+ # Only one arg allowed for an OPTIONAL. At positional now.
+ ('--optional optional', positional_choices),
+
+ # Flag with nargs range (1, 2)
+ ('--range', range_choices),
+ ('--range some', ['range', 'choices']),
+
+ # Already used 2 args so at positional
+ ('--range some range', positional_choices),
+
+ # Flag with nargs = REMAINDER
+ ('--remainder', remainder_choices),
+ ('--remainder remainder ', ['choices ']),
+
+ # No more flags can appear after a REMAINDER flag)
+ ('--remainder choices --set_value', ['remainder ']),
+
+ # Double dash ends the current flag (even if all expected args aren't entered)
+ ('--set_value --', positional_choices),
+
+ # Double dash ends a REMAINDER flag
+ ('--remainder remainder --', positional_choices),
+
+ # No more flags after a double dash
+ ('-- --one_or_more ', positional_choices),
+
+ # Consume positional
+ ('', positional_choices),
+ ('positional', ['the', 'choices']),
+
+ # Intermixed flag and positional
+ ('positional --set_value', set_value_choices),
+ ('positional --set_value set', ['value', 'choices']),
+
+ # Intermixed flag and positional with flag finishing
+ ('positional --set_value set value', ['the', 'choices']),
+ ('positional --set_value set --', ['the', 'choices']),
+
+ # REMAINDER positional
+ ('the positional', remainder_choices),
+ ('the positional remainder', ['choices ']),
+
+ # REMAINDER positional. Flags don't work in REMAINDER
+ ('the positional --set_value', remainder_choices),
+])
+def test_autcomp_nargs(ac_app, args, completions):
+ text = ''
+ line = 'nargs {} {}'.format(args, text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ if completions:
+ assert first_match is not None
+ else:
+ assert first_match is None
+
+ assert ac_app.completion_matches == sorted(completions, key=ac_app.matches_sort_key)
+
+
+def test_completion_items_default_header(ac_app):
+ from cmd2.argparse_completer import DEFAULT_DESCRIPTIVE_HEADER
+
+ text = ''
+ line = 'choices -n {}'.format(text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ # This positional argument did not provide a descriptive header, so it should be DEFAULT_DESCRIPTIVE_HEADER
+ complete_tester(text, line, begidx, endidx, ac_app)
+ assert DEFAULT_DESCRIPTIVE_HEADER in ac_app.completion_header
+
+
+def test_autocomp_hint_flag(ac_app, capsys):
+ text = ''
+ line = 'hint --flag {}'.format(text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ out, err = capsys.readouterr()
+
+ assert first_match is None
+ assert out == '''
+Hint:
+ -f, --flag FLAG a flag arg
+
+'''
+
+
+def test_autocomp_hint_suppressed_help(ac_app, capsys):
+ text = ''
+ line = 'hint --suppressed_help {}'.format(text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ out, err = capsys.readouterr()
+
+ assert first_match is None
+ assert not out
+
+
+def test_autocomp_hint_suppressed_hint(ac_app, capsys):
+ text = ''
+ line = 'hint --suppressed_hint {}'.format(text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ out, err = capsys.readouterr()
+
+ assert first_match is None
+ assert not out
+
+
+def test_autocomp_hint_pos(ac_app, capsys):
+ text = ''
+ line = 'hint {}'.format(text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ out, err = capsys.readouterr()
+
+ assert first_match is None
+ assert out == '''
+Hint:
+ HINT_POS here is a hint
+ with new lines
+
+'''
+
+
+def test_autocomp_hint_no_help(ac_app, capsys):
+ text = ''
+ line = 'hint foo {}'.format(text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ out, err = capsys.readouterr()
+
+ assert first_match is None
+ assert not out == '''
+Hint:
+ NO_HELP_POS
+
+'''
+
+def test_is_potential_flag():
+ from cmd2.argparse_completer import is_potential_flag
+ parser = Cmd2ArgParser()
+
+ # Not potential flags
+ assert not is_potential_flag('', parser)
+ assert not is_potential_flag('non-flag', parser)
+ assert not is_potential_flag('--has space', parser)
+ assert not is_potential_flag('-2', parser)
+
+ # Potential flags
+ assert is_potential_flag('-', parser)
+ assert is_potential_flag('--', parser)
+ assert is_potential_flag('-flag', parser)
+ assert is_potential_flag('--flag', parser)
+
+
+def test_complete_command_no_tokens(ac_app):
+ from cmd2.argparse_completer import AutoCompleter
+
+ parser = Cmd2ArgParser()
+ ac = AutoCompleter(parser, ac_app)
+
+ completions = ac.complete_command(tokens=[], text='', line='', begidx=0, endidx=0)
+ assert not completions
+
+
+def test_complete_command_help_no_tokens(ac_app):
+ from cmd2.argparse_completer import AutoCompleter
+
+ parser = Cmd2ArgParser()
+ ac = AutoCompleter(parser, ac_app)
+
+ completions = ac.complete_command_help(tokens=[], text='', line='', begidx=0, endidx=0)
+ assert not completions
diff --git a/tests/test_argparse_custom.py b/tests/test_argparse_custom.py
new file mode 100644
index 00000000..35d97974
--- /dev/null
+++ b/tests/test_argparse_custom.py
@@ -0,0 +1,145 @@
+# flake8: noqa E302
+"""
+Unit/functional testing for argparse customizations in cmd2
+"""
+import argparse
+
+import pytest
+
+import cmd2
+from cmd2.argparse_custom import Cmd2ArgParser
+from .conftest import run_cmd
+
+
+class ApCustomTestApp(cmd2.Cmd):
+ """Test app for cmd2's argparse customization"""
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ range_parser = Cmd2ArgParser()
+ range_parser.add_argument('--arg1', nargs=(2, 3))
+ range_parser.add_argument('--arg2', nargs=argparse.ZERO_OR_MORE)
+ range_parser.add_argument('--arg3', nargs=argparse.ONE_OR_MORE)
+
+ @cmd2.with_argparser(range_parser)
+ def do_range(self, _):
+ pass
+
+
+@pytest.fixture
+def cust_app():
+ return ApCustomTestApp()
+
+
+def fake_func():
+ pass
+
+
+@pytest.mark.parametrize('args, is_valid', [
+ ({'choices': []}, True),
+ ({'choices_function': fake_func}, True),
+ ({'choices_method': fake_func}, True),
+ ({'completer_function': fake_func}, True),
+ ({'completer_method': fake_func}, True),
+ ({'choices': [], 'choices_function': fake_func}, False),
+ ({'choices': [], 'choices_method': fake_func}, False),
+ ({'choices_method': fake_func, 'completer_function': fake_func}, False),
+ ({'choices_method': fake_func, 'completer_method': fake_func}, False),
+])
+def test_apcustom_invalid_args(args, is_valid):
+ parser = Cmd2ArgParser(prog='test')
+ try:
+ parser.add_argument('name', **args)
+ assert is_valid
+ except ValueError as ex:
+ assert not is_valid
+ assert 'Only one of the following may be used' in str(ex)
+
+
+def test_apcustom_usage():
+ usage = "A custom usage statement"
+ parser = Cmd2ArgParser(usage=usage)
+ help = parser.format_help()
+ assert usage in help
+
+
+def test_apcustom_nargs_help_format(cust_app):
+ out, err = run_cmd(cust_app, 'help range')
+ assert 'Usage: range [-h] [--arg1 ARG1{2..3}] [--arg2 [ARG2 [...]]]' in out[0]
+ assert ' [--arg3 ARG3 [...]]' in out[1]
+
+
+def test_apcustom_nargs_not_enough(cust_app):
+ out, err = run_cmd(cust_app, 'range --arg1 one')
+ assert 'Error: argument --arg1: Expected between 2 and 3 arguments' in err[2]
+
+
+def test_apcustom_narg_empty_tuple():
+ with pytest.raises(ValueError) as excinfo:
+ parser = Cmd2ArgParser(prog='test')
+ parser.add_argument('invalid_tuple', nargs=())
+ assert 'Ranged values for nargs must be a tuple of 2 integers' in str(excinfo.value)
+
+
+def test_apcustom_narg_single_tuple():
+ with pytest.raises(ValueError) as excinfo:
+ parser = Cmd2ArgParser(prog='test')
+ parser.add_argument('invalid_tuple', nargs=(1,))
+ assert 'Ranged values for nargs must be a tuple of 2 integers' in str(excinfo.value)
+
+
+def test_apcustom_narg_tuple_triple():
+ with pytest.raises(ValueError) as excinfo:
+ parser = Cmd2ArgParser(prog='test')
+ parser.add_argument('invalid_tuple', nargs=(1, 2, 3))
+ assert 'Ranged values for nargs must be a tuple of 2 integers' in str(excinfo.value)
+
+
+def test_apcustom_narg_tuple_order():
+ with pytest.raises(ValueError) as excinfo:
+ parser = Cmd2ArgParser(prog='test')
+ parser.add_argument('invalid_tuple', nargs=(2, 1))
+ assert 'Invalid nargs range. The first value must be less than the second' in str(excinfo.value)
+
+
+def test_apcustom_narg_tuple_negative():
+ with pytest.raises(ValueError) as excinfo:
+ parser = Cmd2ArgParser(prog='test')
+ parser.add_argument('invalid_tuple', nargs=(-1, 1))
+ assert 'Negative numbers are invalid for nargs range' in str(excinfo.value)
+
+
+def test_apcustom_narg_tuple_zero_base():
+ parser = Cmd2ArgParser(prog='test')
+ parser.add_argument('tuple', nargs=(0, 3))
+
+
+def test_apcustom_narg_tuple_zero_to_one():
+ parser = Cmd2ArgParser(prog='test')
+ parser.add_argument('tuple', nargs=(0, 1))
+
+
+def test_apcustom_print_message(capsys):
+ import sys
+ test_message = 'The test message'
+
+ # Specify the file
+ parser = Cmd2ArgParser(prog='test')
+ parser._print_message(test_message, file=sys.stdout)
+ out, err = capsys.readouterr()
+ assert test_message in out
+
+ # Make sure file defaults to sys.stderr
+ parser = Cmd2ArgParser(prog='test')
+ parser._print_message(test_message)
+ out, err = capsys.readouterr()
+ assert test_message in err
+
+
+def test_apcustom_required_options():
+ # Make sure a 'required arguments' section shows when a flag is marked required
+ parser = Cmd2ArgParser(prog='test')
+ parser.add_argument('--required_flag', required=True)
+ help = parser.format_help()
+
+ assert 'required arguments' in help
diff --git a/tests/test_autocompletion.py b/tests/test_autocompletion.py
deleted file mode 100644
index 4e1ceff0..00000000
--- a/tests/test_autocompletion.py
+++ /dev/null
@@ -1,345 +0,0 @@
-# coding=utf-8
-# flake8: noqa E302
-"""
-Unit/functional testing for argparse completer in cmd2
-"""
-import pytest
-
-from cmd2.utils import StdSim
-from .conftest import run_cmd, normalize, complete_tester
-
-from examples.tab_autocompletion import TabCompleteExample
-
-@pytest.fixture
-def cmd2_app():
- app = TabCompleteExample()
- app.stdout = StdSim(app.stdout)
- return app
-
-
-SUGGEST_HELP = '''Usage: suggest -t {movie, show} [-h] [-d DURATION{1..2}]
-
-Suggest command demonstrates argparse customizations.
-See hybrid_suggest and orig_suggest to compare the help output.
-
-required arguments:
- -t, --type {movie, show}
-
-optional arguments:
- -h, --help show this help message and exit
- -d, --duration DURATION{1..2}
- Duration constraint in minutes.
- single value - maximum duration
- [a, b] - duration range'''
-
-MEDIA_MOVIES_ADD_HELP = '''Usage: media movies add -d DIRECTOR{1..2}
- [-h]
- title {G, PG, PG-13, R, NC-17} ...
-
-positional arguments:
- title Movie Title
- {G, PG, PG-13, R, NC-17}
- Movie Rating
- actor Actors
-
-required arguments:
- -d, --director DIRECTOR{1..2}
- Director
-
-optional arguments:
- -h, --help show this help message and exit'''
-
-def test_help_required_group(cmd2_app):
- out1, err1 = run_cmd(cmd2_app, 'suggest -h')
- out2, err2 = run_cmd(cmd2_app, 'help suggest')
-
- assert out1 == out2
- assert out1[0].startswith('Usage: suggest')
- assert out1[1] == ''
- assert out1[2].startswith('Suggest command demonstrates argparse customizations.')
- assert out1 == normalize(SUGGEST_HELP)
-
-
-def test_help_required_group_long(cmd2_app):
- out1, err1 = run_cmd(cmd2_app, 'media movies add -h')
- out2, err2 = run_cmd(cmd2_app, 'help media movies add')
-
- assert out1 == out2
- assert out1[0].startswith('Usage: media movies add')
- assert out1 == normalize(MEDIA_MOVIES_ADD_HELP)
-
-
-def test_autocomp_flags(cmd2_app):
- text = '-'
- line = 'suggest {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['--duration', '--help', '--type', '-d', '-h', '-t']
-
-def test_autcomp_hint(cmd2_app, capsys):
- text = ''
- line = 'suggest -d {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- out, err = capsys.readouterr()
-
- assert out == '''
-Hint:
- -d, --duration DURATION Duration constraint in minutes.
- single value - maximum duration
- [a, b] - duration range
-
-'''
-
-def test_autcomp_flag_comp(cmd2_app, capsys):
- text = '--d'
- line = 'suggest {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- out, err = capsys.readouterr()
-
- assert first_match is not None and \
- cmd2_app.completion_matches == ['--duration ']
-
-
-def test_autocomp_flags_choices(cmd2_app):
- text = ''
- line = 'suggest -t {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['movie', 'show']
-
-
-def test_autcomp_hint_in_narg_range(cmd2_app, capsys):
- text = ''
- line = 'suggest -d 2 {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- out, err = capsys.readouterr()
-
- assert out == '''
-Hint:
- -d, --duration DURATION Duration constraint in minutes.
- single value - maximum duration
- [a, b] - duration range
-
-'''
-
-def test_autocomp_flags_narg_max(cmd2_app):
- text = ''
- line = 'suggest d 2 3 {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is None
-
-
-def test_autcomp_narg_beyond_max(cmd2_app):
- out, err = run_cmd(cmd2_app, 'suggest -t movie -d 3 4 5')
- assert 'Error: unrecognized arguments: 5' in err[1]
-
-
-def test_autocomp_subcmd_nested(cmd2_app):
- text = ''
- line = 'media movies {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['add', 'delete', 'list', 'load']
-
-
-def test_autocomp_subcmd_flag_choices_append(cmd2_app):
- text = ''
- line = 'media movies list -r {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['G', 'NC-17', 'PG', 'PG-13', 'R']
-
-def test_autocomp_subcmd_flag_choices_append_exclude(cmd2_app):
- text = ''
- line = 'media movies list -r PG PG-13 {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['G', 'NC-17', 'R']
-
-
-def test_autocomp_subcmd_flag_comp_func(cmd2_app):
- text = 'A'
- line = 'media movies list -a "{}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['Adam Driver', 'Alec Guinness', 'Andy Serkis', 'Anthony Daniels']
-
-
-def test_autocomp_subcmd_flag_comp_list(cmd2_app):
- text = 'G'
- line = 'media movies list -d {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and first_match == '"Gareth Edwards'
-
-
-def test_autocomp_subcmd_flag_comp_func_attr(cmd2_app):
- text = 'A'
- line = 'video movies list -a "{}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['Adam Driver', 'Alec Guinness', 'Andy Serkis', 'Anthony Daniels']
-
-
-def test_autocomp_subcmd_flag_comp_list_attr(cmd2_app):
- text = 'G'
- line = 'video movies list -d {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and first_match == '"Gareth Edwards'
-
-
-def test_autocomp_pos_consumed(cmd2_app):
- text = ''
- line = 'library movie add SW_EP01 {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is None
-
-
-def test_autocomp_pos_after_flag(cmd2_app):
- text = 'Joh'
- line = 'video movies add -d "George Lucas" -- "Han Solo" PG "Emilia Clarke" "{}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['John Boyega" ']
-
-
-def test_autocomp_custom_func_list_arg(cmd2_app):
- text = 'SW_'
- line = 'library show add {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['SW_CW', 'SW_REB', 'SW_TCW']
-
-
-def test_autocomp_custom_func_list_and_dict_arg(cmd2_app):
- text = ''
- line = 'library show add SW_REB {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['S01E02', 'S01E03', 'S02E01', 'S02E03']
-
-
-def test_autocomp_custom_func_dict_arg(cmd2_app):
- text = '/home/user/'
- line = 'video movies load {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and \
- cmd2_app.completion_matches == ['/home/user/another.db', '/home/user/file space.db', '/home/user/file.db']
-
-
-def test_argparse_remainder_flag_completion(cmd2_app):
- import cmd2
- import argparse
-
- # Test flag completion as first arg of positional with nargs=argparse.REMAINDER
- text = '--h'
- line = 'help command {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- # --h should not complete into --help because we are in the argparse.REMAINDER section
- assert complete_tester(text, line, begidx, endidx, cmd2_app) is None
-
- # Test flag completion within an already started positional with nargs=argparse.REMAINDER
- text = '--h'
- line = 'help command subcommand {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- # --h should not complete into --help because we are in the argparse.REMAINDER section
- assert complete_tester(text, line, begidx, endidx, cmd2_app) is None
-
- # Test a flag with nargs=argparse.REMAINDER
- parser = argparse.ArgumentParser()
- parser.add_argument('-f', nargs=argparse.REMAINDER)
-
- # Overwrite eof's parser for this test
- cmd2.Cmd.do_eof.argparser = parser
-
- text = '--h'
- line = 'eof -f {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- # --h should not complete into --help because we are in the argparse.REMAINDER section
- assert complete_tester(text, line, begidx, endidx, cmd2_app) is None
-
-
-def test_completion_after_double_dash(cmd2_app):
- """
- Test completion after --, which argparse says (all args after -- are non-options)
- All of these tests occur outside of an argparse.REMAINDER section since those tests
- are handled in test_argparse_remainder_flag_completion
- """
-
- # Test -- as the last token
- text = '--'
- line = 'help {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- # Since -- is the last token, then it should show flag choices
- first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
- assert first_match is not None and '--help' in cmd2_app.completion_matches
-
- # Test -- to end all flag completion
- text = '--'
- line = 'help -- {}'.format(text)
- endidx = len(line)
- begidx = endidx - len(text)
-
- # Since -- appeared before the -- being completed, nothing should be completed
- assert complete_tester(text, line, begidx, endidx, cmd2_app) is None
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 9ffe547a..1bdbea5f 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -1504,22 +1504,33 @@ invalid_command_name = [
'noembedded"quotes',
]
-def test_get_alias_names(base_app):
- assert len(base_app.aliases) == 0
+def test_get_alias_completion_items(base_app):
run_cmd(base_app, 'alias create fake run_pyscript')
run_cmd(base_app, 'alias create ls !ls -hal')
- assert len(base_app.aliases) == 2
- assert sorted(base_app._get_alias_names()) == ['fake', 'ls']
-def test_get_macro_names(base_app):
- assert len(base_app.macros) == 0
+ results = base_app._get_alias_completion_items()
+ assert len(results) == len(base_app.aliases)
+
+ for cur_res in results:
+ assert cur_res in base_app.aliases
+ assert cur_res.description == base_app.aliases[cur_res]
+
+def test_get_macro_completion_items(base_app):
run_cmd(base_app, 'macro create foo !echo foo')
run_cmd(base_app, 'macro create bar !echo bar')
- assert len(base_app.macros) == 2
- assert sorted(base_app._get_macro_names()) == ['bar', 'foo']
-def test_get_settable_names(base_app):
- assert sorted(base_app._get_settable_names()) == sorted(base_app.settable.keys())
+ results = base_app._get_macro_completion_items()
+ assert len(results) == len(base_app.macros)
+
+ for cur_res in results:
+ assert cur_res in base_app.macros
+ assert cur_res.description == base_app.macros[cur_res].value
+
+def test_get_settable_completion_items(base_app):
+ results = base_app._get_settable_completion_items()
+ for cur_res in results:
+ assert cur_res in base_app.settable
+ assert cur_res.description == base_app.settable[cur_res]
def test_alias_no_subcommand(base_app):
out, err = run_cmd(base_app, 'alias')
diff --git a/tests/test_completion.py b/tests/test_completion.py
index 5cfc741c..1411cc49 100644
--- a/tests/test_completion.py
+++ b/tests/test_completion.py
@@ -67,7 +67,7 @@ class CompletionsExample(cmd2.Cmd):
pass
def complete_test_basic(self, text, line, begidx, endidx):
- return self.basic_complete(text, line, begidx, endidx, food_item_strs)
+ return utils.basic_complete(text, line, begidx, endidx, food_item_strs)
def do_test_delimited(self, args):
pass
@@ -80,7 +80,7 @@ class CompletionsExample(cmd2.Cmd):
def complete_test_sort_key(self, text, line, begidx, endidx):
num_strs = ['2', '11', '1']
- return self.basic_complete(text, line, begidx, endidx, num_strs)
+ return utils.basic_complete(text, line, begidx, endidx, num_strs)
def do_test_raise_exception(self, args):
pass
@@ -516,7 +516,7 @@ def test_path_completion_directories_only(cmd2_app, request):
expected = [text + 'cripts' + os.path.sep]
- assert cmd2_app.path_complete(text, line, begidx, endidx, os.path.isdir) == expected
+ assert cmd2_app.path_complete(text, line, begidx, endidx, path_filter=os.path.isdir) == expected
def test_basic_completion_single(cmd2_app):
text = 'Pi'
@@ -524,7 +524,7 @@ def test_basic_completion_single(cmd2_app):
endidx = len(line)
begidx = endidx - len(text)
- assert cmd2_app.basic_complete(text, line, begidx, endidx, food_item_strs) == ['Pizza']
+ assert utils.basic_complete(text, line, begidx, endidx, food_item_strs) == ['Pizza']
def test_basic_completion_multiple(cmd2_app):
text = ''
@@ -532,7 +532,7 @@ def test_basic_completion_multiple(cmd2_app):
endidx = len(line)
begidx = endidx - len(text)
- matches = sorted(cmd2_app.basic_complete(text, line, begidx, endidx, food_item_strs))
+ matches = sorted(utils.basic_complete(text, line, begidx, endidx, food_item_strs))
assert matches == sorted(food_item_strs)
def test_basic_completion_nomatch(cmd2_app):
@@ -541,7 +541,7 @@ def test_basic_completion_nomatch(cmd2_app):
endidx = len(line)
begidx = endidx - len(text)
- assert cmd2_app.basic_complete(text, line, begidx, endidx, food_item_strs) == []
+ assert utils.basic_complete(text, line, begidx, endidx, food_item_strs) == []
def test_delimiter_completion(cmd2_app):
text = '/home/'
@@ -592,7 +592,7 @@ def test_flag_based_default_completer(cmd2_app, request):
begidx = endidx - len(text)
assert cmd2_app.flag_based_complete(text, line, begidx, endidx,
- flag_dict, cmd2_app.path_complete) == [text + 'onftest.py']
+ flag_dict, all_else=cmd2_app.path_complete) == [text + 'onftest.py']
def test_flag_based_callable_completer(cmd2_app, request):
test_dir = os.path.dirname(request.module.__file__)
@@ -642,7 +642,7 @@ def test_index_based_default_completer(cmd2_app, request):
begidx = endidx - len(text)
assert cmd2_app.index_based_complete(text, line, begidx, endidx,
- index_dict, cmd2_app.path_complete) == [text + 'onftest.py']
+ index_dict, all_else=cmd2_app.path_complete) == [text + 'onftest.py']
def test_index_based_callable_completer(cmd2_app, request):
test_dir = os.path.dirname(request.module.__file__)
@@ -1072,8 +1072,7 @@ class SubcommandsWithUnknownExample(cmd2.Cmd):
# create the parser for the "sport" sub-command
parser_sport = base_subparsers.add_parser('sport', help='sport help')
- sport_arg = parser_sport.add_argument('sport', help='Enter name of a sport')
- setattr(sport_arg, 'arg_choices', sport_item_strs)
+ sport_arg = parser_sport.add_argument('sport', help='Enter name of a sport', choices=sport_item_strs)
@cmd2.with_argparser_and_unknown_args(base_parser)
def do_base(self, args):