summaryrefslogtreecommitdiff
path: root/tests/test_argparse_completer.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_argparse_completer.py')
-rw-r--r--tests/test_argparse_completer.py206
1 files changed, 92 insertions, 114 deletions
diff --git a/tests/test_argparse_completer.py b/tests/test_argparse_completer.py
index 151923ea..b896a9bd 100644
--- a/tests/test_argparse_completer.py
+++ b/tests/test_argparse_completer.py
@@ -9,50 +9,10 @@ from typing import List
import pytest
import cmd2
-from cmd2 import Cmd2ArgumentParser, CompletionItem, with_argparser
-from cmd2.utils import CompletionError, StdSim, basic_complete
-
+from cmd2 import Cmd2ArgumentParser, CompletionError, CompletionItem, with_argparser
+from cmd2.utils import StdSim
from .conftest import complete_tester, run_cmd
-# Lists used in our tests (there is a mix of sorted and unsorted on purpose)
-static_int_choices_list = [-1, 1, -2, 2, 0, -12]
-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)
-
-
-def choices_takes_arg_tokens(arg_tokens: argparse.Namespace) -> List[str]:
- """Choices function that receives arg_tokens from ArgparseCompleter"""
- return [arg_tokens['parent_arg'][0], arg_tokens['subcommand'][0]]
-
-
-def completer_takes_arg_tokens(text: str, line: str, begidx: int, endidx: int,
- arg_tokens: argparse.Namespace) -> List[str]:
- """Completer function that receives arg_tokens from ArgparseCompleter"""
- match_against = [arg_tokens['parent_arg'][0], arg_tokens['subcommand'][0]]
- return basic_complete(text, line, begidx, endidx, match_against)
-
# noinspection PyMethodMayBeStatic,PyUnusedLocal,PyProtectedMember
class AutoCompleteTester(cmd2.Cmd):
@@ -105,15 +65,19 @@ class AutoCompleteTester(cmd2.Cmd):
pass
############################################################################################################
- # Begin code related to testing choices, choices_function, and choices_method parameters
+ # Begin code related to testing choices and choices_provider parameters
############################################################################################################
STR_METAVAR = "HEADLESS"
TUPLE_METAVAR = ('arg1', 'others')
CUSTOM_DESC_HEADER = "Custom Header"
- def choices_method(self) -> List[str]:
+ static_int_choices_list = [-1, 1, -2, 2, 0, -12]
+ static_choices_list = ['static', 'choices', 'stop', 'here']
+ choices_from_provider = ['choices', 'provider', 'probably', 'improved']
+
+ def choices_provider(self) -> List[str]:
"""Method that provides choices"""
- return choices_from_method
+ return self.choices_from_provider
def completion_item_method(self) -> List[CompletionItem]:
"""Choices method that returns CompletionItems"""
@@ -128,17 +92,15 @@ class AutoCompleteTester(cmd2.Cmd):
# 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("-p", "--provider", help="a flag populated with a choices provider",
+ choices_provider=choices_provider)
choices_parser.add_argument('-d', "--desc_header", help='this arg has a descriptive header',
- choices_method=completion_item_method,
+ choices_provider=completion_item_method,
descriptive_header=CUSTOM_DESC_HEADER)
choices_parser.add_argument('-n', "--no_header", help='this arg has no descriptive header',
- choices_method=completion_item_method, metavar=STR_METAVAR)
+ choices_provider=completion_item_method, metavar=STR_METAVAR)
choices_parser.add_argument('-t', "--tuple_metavar", help='this arg has tuple for a metavar',
- choices_method=completion_item_method, metavar=TUPLE_METAVAR,
+ choices_provider=completion_item_method, metavar=TUPLE_METAVAR,
nargs=argparse.ONE_OR_MORE)
choices_parser.add_argument('-i', '--int', type=int, help='a flag with an int type',
choices=static_int_choices_list)
@@ -146,35 +108,40 @@ class AutoCompleteTester(cmd2.Cmd):
# 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)
+ choices_parser.add_argument("method_pos", help="a positional populated with a choices provider",
+ choices_provider=choices_provider)
@with_argparser(choices_parser)
def do_choices(self, args: argparse.Namespace) -> None:
pass
############################################################################################################
- # Begin code related to testing completer_function and completer_method parameters
+ # Begin code related to testing completer parameter
############################################################################################################
- 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)
+ completions_for_flag = ['completions', 'flag', 'fairly', 'complete']
+ completions_for_pos_1 = ['completions', 'positional_1', 'probably', 'missed', 'spot']
+ completions_for_pos_2 = ['completions', 'positional_2', 'probably', 'missed', 'me']
+
+ def flag_completer(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
+ return self.basic_complete(text, line, begidx, endidx, self.completions_for_flag)
+
+ def pos_1_completer(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
+ return self.basic_complete(text, line, begidx, endidx, self.completions_for_pos_1)
+
+ def pos_2_completer(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
+ return self.basic_complete(text, line, begidx, endidx, self.completions_for_pos_2)
completer_parser = Cmd2ArgumentParser()
# 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)
+ completer_parser.add_argument("-c", "--completer", help="a flag using a completer",
+ completer=flag_completer)
# 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)
+ completer_parser.add_argument("pos_1", help="a positional using a completer method",
+ completer=pos_1_completer)
+ completer_parser.add_argument("pos_2", help="a positional using a completer method",
+ completer=pos_2_completer)
@with_argparser(completer_parser)
def do_completer(self, args: argparse.Namespace) -> None:
@@ -183,6 +150,13 @@ class AutoCompleteTester(cmd2.Cmd):
############################################################################################################
# Begin code related to nargs
############################################################################################################
+ 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']
+
nargs_parser = Cmd2ArgumentParser()
# Flag args for nargs command
@@ -234,10 +208,10 @@ class AutoCompleteTester(cmd2.Cmd):
raise CompletionError('choice broke something')
comp_error_parser = Cmd2ArgumentParser()
- comp_error_parser.add_argument('completer', help='positional arg',
- completer_method=completer_raise_error)
+ comp_error_parser.add_argument('completer_pos', help='positional arg',
+ completer=completer_raise_error)
comp_error_parser.add_argument('--choice', help='flag arg',
- choices_method=choice_raise_error)
+ choices_provider=choice_raise_error)
@with_argparser(comp_error_parser)
def do_raise_completion_error(self, args: argparse.Namespace) -> None:
@@ -246,6 +220,16 @@ class AutoCompleteTester(cmd2.Cmd):
############################################################################################################
# Begin code related to receiving arg_tokens
############################################################################################################
+ def choices_takes_arg_tokens(self, arg_tokens: argparse.Namespace) -> List[str]:
+ """Choices function that receives arg_tokens from ArgparseCompleter"""
+ return [arg_tokens['parent_arg'][0], arg_tokens['subcommand'][0]]
+
+ def completer_takes_arg_tokens(self, text: str, line: str, begidx: int, endidx: int,
+ arg_tokens: argparse.Namespace) -> List[str]:
+ """Completer function that receives arg_tokens from ArgparseCompleter"""
+ match_against = [arg_tokens['parent_arg'][0], arg_tokens['subcommand'][0]]
+ return self.basic_complete(text, line, begidx, endidx, match_against)
+
arg_tokens_parser = Cmd2ArgumentParser()
arg_tokens_parser.add_argument('parent_arg', help='arg from a parent parser')
@@ -253,8 +237,8 @@ class AutoCompleteTester(cmd2.Cmd):
arg_tokens_subparser = arg_tokens_parser.add_subparsers(dest='subcommand')
arg_tokens_subcmd_parser = arg_tokens_subparser.add_parser('subcmd')
- arg_tokens_subcmd_parser.add_argument('choices_pos', choices_function=choices_takes_arg_tokens)
- arg_tokens_subcmd_parser.add_argument('completer_pos', completer_function=completer_takes_arg_tokens)
+ arg_tokens_subcmd_parser.add_argument('choices_pos', choices_provider=choices_takes_arg_tokens)
+ arg_tokens_subcmd_parser.add_argument('completer_pos', completer=completer_takes_arg_tokens)
# Used to override parent_arg in arg_tokens_parser
arg_tokens_subcmd_parser.add_argument('--parent_arg')
@@ -409,13 +393,11 @@ def test_autcomp_flag_completion(ac_app, command_and_args, text, completions):
@pytest.mark.parametrize('flag, text, completions', [
- ('-l', '', static_choices_list),
+ ('-l', '', AutoCompleteTester.static_choices_list),
('--list', 's', ['static', 'stop']),
- ('-f', '', choices_from_function),
- ('--function', 'ch', ['choices', 'chatty']),
- ('-m', '', choices_from_method),
- ('--method', 'm', ['method', 'most']),
- ('-i', '', static_int_choices_list),
+ ('-p', '', AutoCompleteTester.choices_from_provider),
+ ('--provider', 'pr', ['provider', 'probably']),
+ ('-i', '', AutoCompleteTester.static_int_choices_list),
('--int', '1', ['1 ']),
('--int', '-', [-1, -2, -12]),
('--int', '-1', [-1, -12])
@@ -444,12 +426,10 @@ def test_autocomp_flag_choices_completion(ac_app, flag, text, completions):
@pytest.mark.parametrize('pos, text, completions', [
- (1, '', static_choices_list),
+ (1, '', AutoCompleteTester.static_choices_list),
(1, 's', ['static', 'stop']),
- (2, '', choices_from_function),
- (2, 'ch', ['choices', 'chatty']),
- (3, '', choices_from_method),
- (3, 'm', ['method', 'most'])
+ (2, '', AutoCompleteTester.choices_from_provider),
+ (2, 'pr', ['provider', 'probably']),
])
def test_autocomp_positional_choices_completion(ac_app, pos, text, completions):
# Generate line were preceding positionals are already filled
@@ -467,10 +447,8 @@ def test_autocomp_positional_choices_completion(ac_app, pos, text, completions):
@pytest.mark.parametrize('flag, text, completions', [
- ('-f', '', completions_from_function),
- ('--function', 'f', ['function', 'fairly']),
- ('-m', '', completions_from_method),
- ('--method', 'm', ['method', 'missed'])
+ ('-c', '', AutoCompleteTester.completions_for_flag),
+ ('--completer', 'f', ['flag', 'fairly'])
])
def test_autocomp_flag_completers(ac_app, flag, text, completions):
line = 'completer {} {}'.format(flag, text)
@@ -487,10 +465,10 @@ def test_autocomp_flag_completers(ac_app, flag, text, completions):
@pytest.mark.parametrize('pos, text, completions', [
- (1, '', completions_from_function),
- (1, 'c', ['completions', 'complete']),
- (2, '', completions_from_method),
- (2, 'm', ['method', 'missed'])
+ (1, '', AutoCompleteTester.completions_for_pos_1),
+ (1, 'p', ['positional_1', 'probably']),
+ (2, '', AutoCompleteTester.completions_for_pos_2),
+ (2, 'm', ['missed', 'me']),
])
def test_autocomp_positional_completers(ac_app, pos, text, completions):
# Generate line were preceding positionals are already filled
@@ -513,18 +491,18 @@ def test_autocomp_blank_token(ac_app):
blank = ''
- # Blank flag arg
+ # Blank flag arg will be consumed. Therefore we expect to be completing the first positional.
text = ''
- line = 'completer -m {} {}'.format(blank, text)
+ line = 'completer -c {} {}'.format(blank, text)
endidx = len(line)
begidx = endidx - len(text)
completer = ArgparseCompleter(ac_app.completer_parser, ac_app)
- tokens = ['completer', '-f', blank, text]
+ tokens = ['completer', '-c', blank, text]
completions = completer.complete_command(tokens, text, line, begidx, endidx)
- assert completions == completions_from_function
+ assert sorted(completions) == sorted(AutoCompleteTester.completions_for_pos_1)
- # Blank positional arg
+ # Blank arg for first positional will be consumed. Therefore we expect to be completing the second positional.
text = ''
line = 'completer {} {}'.format(blank, text)
endidx = len(line)
@@ -533,7 +511,7 @@ def test_autocomp_blank_token(ac_app):
completer = ArgparseCompleter(ac_app.completer_parser, ac_app)
tokens = ['completer', blank, text]
completions = completer.complete_command(tokens, text, line, begidx, endidx)
- assert completions == completions_from_method
+ assert sorted(completions) == sorted(AutoCompleteTester.completions_for_pos_2)
@pytest.mark.parametrize('num_aliases, show_description', [
@@ -567,54 +545,54 @@ def test_completion_items(ac_app, num_aliases, show_description):
@pytest.mark.parametrize('args, completions', [
# Flag with nargs = 2
- ('--set_value', set_value_choices),
+ ('--set_value', AutoCompleteTester.set_value_choices),
('--set_value set', ['value', 'choices']),
# Both args are filled. At positional arg now.
- ('--set_value set value', positional_choices),
+ ('--set_value set value', AutoCompleteTester.positional_choices),
# Using the flag again will reset the choices available
- ('--set_value set value --set_value', set_value_choices),
+ ('--set_value set value --set_value', AutoCompleteTester.set_value_choices),
# Flag with nargs = ONE_OR_MORE
- ('--one_or_more', one_or_more_choices),
+ ('--one_or_more', AutoCompleteTester.one_or_more_choices),
('--one_or_more one', ['or', 'more', 'choices']),
# Flag with nargs = OPTIONAL
- ('--optional', optional_choices),
+ ('--optional', AutoCompleteTester.optional_choices),
# Only one arg allowed for an OPTIONAL. At positional now.
- ('--optional optional', positional_choices),
+ ('--optional optional', AutoCompleteTester.positional_choices),
# Flag with nargs range (1, 2)
- ('--range', range_choices),
+ ('--range', AutoCompleteTester.range_choices),
('--range some', ['range', 'choices']),
# Already used 2 args so at positional
- ('--range some range', positional_choices),
+ ('--range some range', AutoCompleteTester.positional_choices),
# Flag with nargs = REMAINDER
- ('--remainder', remainder_choices),
+ ('--remainder', AutoCompleteTester.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
- ('--range choice --', positional_choices),
+ ('--range choice --', AutoCompleteTester.positional_choices),
# Double dash ends a REMAINDER flag
- ('--remainder remainder --', positional_choices),
+ ('--remainder remainder --', AutoCompleteTester.positional_choices),
# No more flags after a double dash
- ('-- --one_or_more ', positional_choices),
+ ('-- --one_or_more ', AutoCompleteTester.positional_choices),
# Consume positional
- ('', positional_choices),
+ ('', AutoCompleteTester.positional_choices),
('positional', ['the', 'choices']),
# Intermixed flag and positional
- ('positional --set_value', set_value_choices),
+ ('positional --set_value', AutoCompleteTester.set_value_choices),
('positional --set_value set', ['choices', 'value']),
# Intermixed flag and positional with flag finishing
@@ -622,12 +600,12 @@ def test_completion_items(ac_app, num_aliases, show_description):
('positional --range choice --', ['the', 'choices']),
# REMAINDER positional
- ('the positional', remainder_choices),
+ ('the positional', AutoCompleteTester.remainder_choices),
('the positional remainder', ['choices ']),
('the positional remainder choices', []),
# REMAINDER positional. Flags don't work in REMAINDER
- ('the positional --set_value', remainder_choices),
+ ('the positional --set_value', AutoCompleteTester.remainder_choices),
('the positional remainder --set_value', ['choices '])
])
def test_autcomp_nargs(ac_app, args, completions):