diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test_completion.py | 855 |
1 files changed, 263 insertions, 592 deletions
diff --git a/tests/test_completion.py b/tests/test_completion.py index daeb94bf..8b9eba63 100644 --- a/tests/test_completion.py +++ b/tests/test_completion.py @@ -31,32 +31,69 @@ except ImportError: pass -@pytest.fixture -def cmd2_app(): - c = cmd2.Cmd() - return c +# List of strings used with basic, flag, and index based completion functions +weird_strings = ['string with space', '@a symbol'] +delimited_strings = ['bob::tampa::car', 'bill::tampa::truck', 'frank::atlanta::motorcycle'] +food_item_strs = ['Pizza', 'Hamburger', 'Ham', 'Potato'] +sport_item_strs = ['Bat', 'Basket', 'Basketball', 'Football'] -@pytest.fixture -def cs_app(): - c = cmd2.Cmd() - return c +# Dictionary used with flag based completion functions +flag_dict = \ + { + '-f': food_item_strs, # Tab-complete food items after -f flag in command line + '--food': food_item_strs, # Tab-complete food items after --food flag in command line + '-s': sport_item_strs, # Tab-complete sport items after -s flag in command line + '--sport': sport_item_strs, # Tab-complete sport items after --sport flag in command line + '-o': path_complete, # Tab-complete using path_complete function after -o flag in command line + '--other': path_complete, # Tab-complete using path_complete function after --other flag in command line + } + +# Dictionary used with index based completion functions +index_dict = \ + { + 1: food_item_strs, # Tab-complete food items at index 1 in command line + 2: sport_item_strs, # Tab-complete sport items at index 2 in command line + 3: path_complete, # Tab-complete using path_complete function at index 3 in command line + } -def test_cmd2_command_completion_single_end(cmd2_app): - text = 'he' - line = 'he' - endidx = len(line) - begidx = endidx - len(text) - # It is at end of line, so extra space is present - assert cmd2_app.completenames(text, line, begidx, endidx) == ['help '] +class Cmd2App(cmd2.Cmd): + """ Example cmd2 application with commands for completion tests """ -def test_complete_command_single_end(cmd2_app): - text = 'he' - line = 'he' - state = 0 - endidx = len(line) - begidx = endidx - len(text) + def __init__(self): + cmd2.Cmd.__init__(self) + + def do_completion_cmd(self, args): + pass + + def complete_completion_cmd(self, text, line, begidx, endidx): + return basic_complete(text, line, begidx, endidx, weird_strings) + def do_delimited_completion(self, args): + pass + + +@pytest.fixture +def cmd2_app(): + c = Cmd2App() + return c + +def complete_tester(text, line, begidx, endidx, app): + """ + This is a convenience function to test cmd2.complete() since + in a unit test environment there is no actual console readline + is monitoring. Therefore we use mock to provide readline data + to complete(). + + :param text: str - the string prefix we are attempting to match + :param line: str - the current input line with leading whitespace removed + :param begidx: int - the beginning index of the prefix text + :param endidx: int - the ending index of the prefix text + :param app: the cmd2 app that will run completions + :return: The first matched string or None if there are no matches + Matches are stored in app.completion_matches + These matches have been sorted by complete() + """ def get_line(): return line @@ -66,157 +103,158 @@ def test_complete_command_single_end(cmd2_app): def get_endidx(): return endidx + first_match = None with mock.patch.object(readline, 'get_line_buffer', get_line): with mock.patch.object(readline, 'get_begidx', get_begidx): with mock.patch.object(readline, 'get_endidx', get_endidx): # Run the readline tab-completion function with readline mocks in place - first_match = cmd2_app.complete(text, state) + first_match = app.complete(text, 0) - assert first_match is not None and cmd2_app.completion_matches == ['help '] + return first_match -def test_complete_command_invalid_state(cmd2_app): - text = 'he' - line = 'he' - state = 1 +def test_complete_unclosed_quote(cmd2_app): + text = 's' + line = 'completion_cmd "string with {}'.format(text) endidx = len(line) begidx = endidx - len(text) - def get_line(): - return line + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is not None and cmd2_app.completion_matches == ['space" '] - def get_begidx(): - return begidx - def get_endidx(): - return endidx +def test_complete_add_opening_quote(cmd2_app): + text = 'string' + line = 'completion_cmd {}'.format(text) + endidx = len(line) + begidx = endidx - len(text) - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place get None - first_match = cmd2_app.complete(text, state) + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + expected = ['"' + 'string with space' + '" '] - assert first_match is None + assert first_match is not None and cmd2_app.completion_matches == expected -def test_complete_empty_arg(cmd2_app): - text = '' - line = 'help ' - state = 0 +def test_complete_add_opening_quote_symbol(cmd2_app): + """ + This tests adding an opening quote to a string with spaces when begidx comes + after a readline word delimiting character. In this case, the opening quote + is only printed to the screen and not the actual completion. + """ + text = 'a' + line = 'completion_cmd @{}'.format(text) endidx = len(line) begidx = endidx - len(text) - def get_line(): - return line + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) - def get_begidx(): - return begidx + # Since there is one match at the end of the line, the added opening + # quote is closed and a space is added + expected = ['@a symbol" '] - def get_endidx(): - return endidx + assert first_match is not None and cmd2_app.completion_matches == expected - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = cmd2_app.complete(text, state) +def test_cmd2_command_completion_single(cmd2_app): + text = 'he' + line = text + endidx = len(line) + begidx = endidx - len(text) + assert cmd2_app.completenames(text, line, begidx, endidx) == ['help'] - assert first_match is not None and \ - cmd2_app.completion_matches == cmd2_app.complete_help(text, line, begidx, endidx) +def test_complete_command_single(cmd2_app): + text = 'he' + line = text + endidx = len(line) + begidx = endidx - len(text) -def test_complete_bogus_command(cmd2_app): + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is not None and cmd2_app.completion_matches == ['help '] + +def test_complete_empty_arg(cmd2_app): text = '' - line = 'fizbuzz ' - state = 0 + line = 'help {}'.format(text) endidx = len(line) begidx = endidx - len(text) - def get_line(): - return line + expected = cmd2_app.complete_help(text, line, begidx, endidx) + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) - def get_begidx(): - return begidx - - def get_endidx(): - return endidx + assert first_match is not None and \ + cmd2_app.completion_matches == expected - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = cmd2_app.complete(text, state) +def test_complete_bogus_command(cmd2_app): + text = '' + line = 'fizbuzz {}'.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_cmd2_command_completion_is_case_sensitive(cmd2_app): - text = 'HE' - line = 'HE' + +def test_cmd2_command_completion_single(cmd2_app): + text = 'hel' + line = text endidx = len(line) begidx = endidx - len(text) - # It is at end of line, so extra space is present - assert cmd2_app.completenames(text, line, begidx, endidx) == [] - -def test_cmd2_command_completion_single_mid(cmd2_app): - text = 'he' - line = 'he' - begidx = 0 - endidx = 1 - # It is not at end of line, so no extra space assert cmd2_app.completenames(text, line, begidx, endidx) == ['help'] def test_cmd2_command_completion_multiple(cmd2_app): text = 'h' - line = 'h' + line = text endidx = len(line) begidx = endidx - len(text) - # It is not at end of line, so no extra space assert cmd2_app.completenames(text, line, begidx, endidx) == ['help', 'history'] def test_cmd2_command_completion_nomatch(cmd2_app): - text = 'z' - line = 'z' + text = 'fakecommand' + line = text endidx = len(line) begidx = endidx - len(text) assert cmd2_app.completenames(text, line, begidx, endidx) == [] -def test_cmd2_help_completion_single_end(cmd2_app): + +def test_cmd2_help_completion_single(cmd2_app): text = 'he' - line = 'help he' + line = 'help {}'.format(text) endidx = len(line) begidx = endidx - len(text) - # Even though it is at end of line, no extra space is present when tab completing a command name to get help on - assert cmd2_app.complete_help(text, line, begidx, endidx) == ['help'] - -def test_cmd2_help_completion_single_mid(cmd2_app): - text = 'he' - line = 'help he' - begidx = 5 - endidx = 6 assert cmd2_app.complete_help(text, line, begidx, endidx) == ['help'] def test_cmd2_help_completion_multiple(cmd2_app): text = 'h' - line = 'help h' + line = 'help {}'.format(text) endidx = len(line) begidx = endidx - len(text) + assert cmd2_app.complete_help(text, line, begidx, endidx) == ['help', 'history'] def test_cmd2_help_completion_nomatch(cmd2_app): - text = 'z' - line = 'help z' + text = 'fakecommand' + line = 'help {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert cmd2_app.complete_help(text, line, begidx, endidx) == [] + +def test_complete_cursor_by_closing_quote(cmd2_app): + text = '' + line = 'fake ""{}'.format(text) + endidx = len(line) + begidx = endidx - len(text) + + # If the cursor is right after a closing quote, then a space is returned + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is not None and cmd2_app.completion_matches == [' '] + + def test_shell_command_completion(cmd2_app): if sys.platform == "win32": text = 'calc' - line = 'shell {}'.format(text) - expected = ['calc.exe '] + expected = ['calc.exe'] else: text = 'egr' - line = 'shell {}'.format(text) - expected = ['egrep '] + expected = ['egrep'] + line = 'shell {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert cmd2_app.complete_shell(text, line, begidx, endidx) == expected @@ -224,11 +262,10 @@ def test_shell_command_completion(cmd2_app): def test_shell_command_completion_doesnt_match_wildcards(cmd2_app): if sys.platform == "win32": text = 'c*' - line = 'shell {}'.format(text) else: text = 'e*' - line = 'shell {}'.format(text) + line = 'shell {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert cmd2_app.complete_shell(text, line, begidx, endidx) == [] @@ -236,20 +273,19 @@ def test_shell_command_completion_doesnt_match_wildcards(cmd2_app): def test_shell_command_completion_multiple(cmd2_app): if sys.platform == "win32": text = 'c' - line = 'shell {}'.format(text) expected = 'calc.exe' else: text = 'l' - line = 'shell {}'.format(text) expected = 'ls' + line = 'shell {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert expected in cmd2_app.complete_shell(text, line, begidx, endidx) def test_shell_command_completion_nomatch(cmd2_app): text = 'zzzz' - line = 'shell zzzz' + line = 'shell {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert cmd2_app.complete_shell(text, line, begidx, endidx) == [] @@ -257,7 +293,6 @@ def test_shell_command_completion_nomatch(cmd2_app): def test_shell_command_completion_doesnt_complete_when_just_shell(cmd2_app): text = '' line = 'shell' - endidx = len(line) begidx = 0 assert cmd2_app.complete_shell(text, line, begidx, endidx) == [] @@ -265,58 +300,43 @@ def test_shell_command_completion_doesnt_complete_when_just_shell(cmd2_app): def test_shell_command_completion_does_path_completion_when_after_command(cmd2_app, request): test_dir = os.path.dirname(request.module.__file__) - text = 'c' - path = os.path.join(test_dir, text) - line = 'shell cat {}'.format(path) + text = os.path.join(test_dir, 'conftest') + line = 'shell cat {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert cmd2_app.complete_shell(text, line, begidx, endidx) == ['conftest.py '] + assert cmd2_app.complete_shell(text, line, begidx, endidx) == [text + '.py'] def test_path_completion_single_end(request): test_dir = os.path.dirname(request.module.__file__) - text = 'c' - path = os.path.join(test_dir, text) - line = 'shell cat {}'.format(path) + text = os.path.join(test_dir, 'conftest') + line = 'shell cat {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert path_complete(text, line, begidx, endidx) == ['conftest.py '] - -def test_path_completion_single_mid(request): - test_dir = os.path.dirname(request.module.__file__) - - text = 'tes' - path = os.path.join(test_dir, 'c') - line = 'shell cat {}'.format(path) - - begidx = line.find(text) - endidx = begidx + len(text) - - assert path_complete(text, line, begidx, endidx) == ['tests' + os.path.sep] + assert path_complete(text, line, begidx, endidx) == [text + '.py'] def test_path_completion_multiple(request): test_dir = os.path.dirname(request.module.__file__) - text = 's' - path = os.path.join(test_dir, text) - line = 'shell cat {}'.format(path) + text = os.path.join(test_dir, 's') + line = 'shell cat {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert path_complete(text, line, begidx, endidx) == ['script.py', 'script.txt', 'scripts' + os.path.sep] + expected = [text + 'cript.py', text + 'cript.txt', text + 'cripts' + os.path.sep] + assert expected == path_complete(text, line, begidx, endidx) def test_path_completion_nomatch(request): test_dir = os.path.dirname(request.module.__file__) - text = 'z' - path = os.path.join(test_dir, text) - line = 'shell cat {}'.format(path) + text = os.path.join(test_dir, 'fakepath') + line = 'shell cat {}'.format(text) endidx = len(line) begidx = endidx - len(text) @@ -328,8 +348,7 @@ def test_default_to_shell_completion(cmd2_app, request): cmd2_app.default_to_shell = True test_dir = os.path.dirname(request.module.__file__) - text = 'c' - path = os.path.join(test_dir, text) + text = os.path.join(test_dir, 'conftest') if sys.platform == "win32": command = 'calc.exe' @@ -337,56 +356,42 @@ def test_default_to_shell_completion(cmd2_app, request): command = 'egrep' # Make sure the command is on the testing system - assert command in cmd2.Cmd._get_exes_in_path(command) - line = '{} {}'.format(command, path) + assert command in cmd2.get_exes_in_path(command) + line = '{} {}'.format(command, text) endidx = len(line) begidx = endidx - len(text) - state = 0 - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = cmd2_app.complete(text, state) - - assert first_match is not None and cmd2_app.completion_matches == ['conftest.py '] + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is not None and cmd2_app.completion_matches == [text + '.py '] def test_path_completion_cwd(): - # Run path complete with no path and no search text + # Run path complete with no search text text = '' line = 'shell ls {}'.format(text) endidx = len(line) begidx = endidx - len(text) - completions_empty = path_complete(text, line, begidx, endidx) + completions_no_text = path_complete(text, line, begidx, endidx) # Run path complete with path set to the CWD - cwd = os.getcwd() + os.path.sep - line = 'shell ls {}'.format(cwd) + text = os.getcwd() + os.path.sep + line = 'shell ls {}'.format(text) endidx = len(line) begidx = endidx - len(text) - completions_cwd = path_complete(text, line, begidx, endidx) - # Verify that the results are the same in both cases and that there is something there - assert completions_empty == completions_cwd + # We have to strip off the text from the beginning since the matches are entire paths + completions_cwd = [match.replace(text, '', 1) for match in path_complete(text, line, begidx, endidx)] + + # Verify that the first test gave results for entries in the cwd + assert completions_no_text == completions_cwd assert completions_cwd def test_path_completion_doesnt_match_wildcards(request): test_dir = os.path.dirname(request.module.__file__) - text = 'c*' - path = os.path.join(test_dir, text) - line = 'shell cat {}'.format(path) + text = os.path.join(test_dir, 'c*') + line = 'shell cat {}'.format(text) endidx = len(line) begidx = endidx - len(text) @@ -396,8 +401,8 @@ def test_path_completion_doesnt_match_wildcards(request): def test_path_completion_invalid_syntax(): # Test a missing separator between a ~ and path - text = '' - line = 'shell fake ~Desktop' + text = '~Desktop' + line = 'shell fake {}'.format(text) endidx = len(line) begidx = endidx - len(text) @@ -405,104 +410,62 @@ def test_path_completion_invalid_syntax(): def test_path_completion_just_tilde(): # Run path with just a tilde - text = '' - line = 'shell fake ~' + text = '~' + line = 'shell fake {}'.format(text) endidx = len(line) begidx = endidx - len(text) completions_tilde = path_complete(text, line, begidx, endidx) - # Path complete should return a slash - assert completions_tilde == [os.path.sep] + # Path complete should complete the tilde with a slash + assert completions_tilde == [text + os.path.sep] def test_path_completion_user_expansion(): # Run path with a tilde and a slash - text = '' if sys.platform.startswith('win'): cmd = 'dir' else: cmd = 'ls' - line = 'shell {} ~{}'.format(cmd, os.path.sep) + # Use a ~ which will be expanded into the user's home directory + text = '~{}'.format(os.path.sep) + line = 'shell {} {}'.format(cmd, text) endidx = len(line) begidx = endidx - len(text) - completions_tilde_slash = path_complete(text, line, begidx, endidx) + completions_tilde_slash = [match.replace(text, '', 1) for match in path_complete(text, line, begidx, endidx)] # Run path complete on the user's home directory - user_dir = os.path.expanduser('~') + os.path.sep - line = 'shell {} {}'.format(cmd, user_dir) + text = os.path.expanduser('~') + os.path.sep + line = 'shell {} {}'.format(cmd, text) endidx = len(line) begidx = endidx - len(text) - completions_home = path_complete(text, line, begidx, endidx) + completions_home = [match.replace(text, '', 1) for match in path_complete(text, line, begidx, endidx)] - # Verify that the results are the same in both cases assert completions_tilde_slash == completions_home def test_path_completion_directories_only(request): test_dir = os.path.dirname(request.module.__file__) - text = 's' - path = os.path.join(test_dir, text) - line = 'shell cat {}'.format(path) - - endidx = len(line) - begidx = endidx - len(text) - - assert path_complete(text, line, begidx, endidx, dir_only=True) == ['scripts' + os.path.sep] - -def test_path_completion_syntax_err(request): - test_dir = os.path.dirname(request.module.__file__) - - text = 'c' - path = os.path.join(test_dir, text) - line = 'shell cat " {}'.format(path) + text = os.path.join(test_dir, 's') + line = 'shell cat {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert path_complete(text, line, begidx, endidx) == [] - -def test_path_completion_no_tokens(): - text = '' - line = 'shell' - endidx = len(line) - begidx = 0 - assert path_complete(text, line, begidx, endidx) == [] + expected = [text + 'cripts' + os.path.sep] + assert path_complete(text, line, begidx, endidx, dir_only=True) == expected -# List of strings used with basic, flag, and index based completion functions -food_item_strs = ['Pizza', 'Hamburger', 'Ham', 'Potato'] -sport_item_strs = ['Bat', 'Basket', 'Basketball', 'Football'] - -# Dictionary used with flag based completion functions -flag_dict = \ - { - '-f': food_item_strs, # Tab-complete food items after -f flag in command line - '--food': food_item_strs, # Tab-complete food items after --food flag in command line - '-s': sport_item_strs, # Tab-complete sport items after -s flag in command line - '--sport': sport_item_strs, # Tab-complete sport items after --sport flag in command line - '-o': path_complete, # Tab-complete using path_complete function after -o flag in command line - '--other': path_complete, # Tab-complete using path_complete function after --other flag in command line - } - -def test_basic_completion_single_end(): +def test_basic_completion_single(): text = 'Pi' - line = 'list_food -f Pi' + line = 'list_food -f {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert basic_complete(text, line, begidx, endidx, food_item_strs) == ['Pizza '] - -def test_basic_completion_single_mid(): - text = 'Pi' - line = 'list_food -f Pi' - begidx = len(line) - len(text) - endidx = begidx + 1 - assert basic_complete(text, line, begidx, endidx, food_item_strs) == ['Pizza'] def test_basic_completion_multiple(): text = '' - line = 'list_food -f ' + line = 'list_food -f {}'.format(text) endidx = len(line) begidx = endidx - len(text) @@ -510,32 +473,40 @@ def test_basic_completion_multiple(): def test_basic_completion_nomatch(): text = 'q' - line = 'list_food -f q' + line = 'list_food -f {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert basic_complete(text, line, begidx, endidx, food_item_strs) == [] +def test_basic_completion_quoted(): + text = 'Pi' + line = 'list_food -f "{}"'.format(text) + endidx = len(line) - 1 + begidx = endidx - len(text) + 1 + + assert basic_complete(text, line, begidx, endidx, food_item_strs) == ['Pizza'] -def test_flag_based_completion_single_end(): +def test_basic_completion_unclosed_quote(): text = 'Pi' - line = 'list_food -f Pi' + line = 'list_food -f "{}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert flag_based_complete(text, line, begidx, endidx, flag_dict) == ['Pizza '] + assert basic_complete(text, line, begidx, endidx, food_item_strs) == ['Pizza'] + -def test_flag_based_completion_single_mid(): +def test_flag_based_completion_single(): text = 'Pi' - line = 'list_food -f Pi' - begidx = len(line) - len(text) - endidx = begidx + 1 + line = 'list_food -f {}'.format(text) + endidx = len(line) + begidx = endidx - len(text) assert flag_based_complete(text, line, begidx, endidx, flag_dict) == ['Pizza'] def test_flag_based_completion_multiple(): text = '' - line = 'list_food -f ' + line = 'list_food -f {}'.format(text) endidx = len(line) begidx = endidx - len(text) @@ -543,7 +514,7 @@ def test_flag_based_completion_multiple(): def test_flag_based_completion_nomatch(): text = 'q' - line = 'list_food -f q' + line = 'list_food -f {}'.format(text) endidx = len(line) begidx = endidx - len(text) @@ -552,78 +523,44 @@ def test_flag_based_completion_nomatch(): def test_flag_based_default_completer(request): test_dir = os.path.dirname(request.module.__file__) - text = 'c' - path = os.path.join(test_dir, text) - line = 'list_food {}'.format(path) + text = os.path.join(test_dir, 'c') + line = 'list_food {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert flag_based_complete(text, line, begidx, endidx, flag_dict, path_complete) == ['conftest.py '] + assert flag_based_complete(text, line, begidx, endidx, flag_dict, path_complete) == [text + 'onftest.py'] def test_flag_based_callable_completer(request): test_dir = os.path.dirname(request.module.__file__) - text = 'c' - path = os.path.join(test_dir, text) - line = 'list_food -o {}'.format(path) - - endidx = len(line) - begidx = endidx - len(text) - - assert flag_based_complete(text, line, begidx, endidx, flag_dict, path_complete) == ['conftest.py '] + text = os.path.join(test_dir, 'c') + line = 'list_food -o {}'.format(text) -def test_flag_based_completion_syntax_err(): - text = 'Pi' - line = 'list_food -f " Pi' endidx = len(line) begidx = endidx - len(text) - assert flag_based_complete(text, line, begidx, endidx, flag_dict) == [] - -def test_flag_based_completion_no_tokens(): - text = '' - line = 'list_food' - endidx = len(line) - begidx = 0 - - assert flag_based_complete(text, line, begidx, endidx, flag_dict) == [] - + assert flag_based_complete(text, line, begidx, endidx, flag_dict, path_complete) == [text + 'onftest.py'] -# Dictionary used with index based completion functions -index_dict = \ - { - 1: food_item_strs, # Tab-complete food items at index 1 in command line - 2: sport_item_strs, # Tab-complete sport items at index 2 in command line - 3: path_complete, # Tab-complete using path_complete function at index 3 in command line - } - -def test_index_based_completion_single_end(): +def test_index_based_completion_single(): text = 'Foo' - line = 'command Pizza Foo' + line = 'command Pizza {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert index_based_complete(text, line, begidx, endidx, index_dict) == ['Football '] - -def test_index_based_completion_single_mid(): - text = 'Foo' - line = 'command Pizza Foo' - begidx = len(line) - len(text) - endidx = begidx + 1 - assert index_based_complete(text, line, begidx, endidx, index_dict) == ['Football'] def test_index_based_completion_multiple(): text = '' - line = 'command Pizza ' + line = 'command Pizza {}'.format(text) endidx = len(line) begidx = endidx - len(text) + assert index_based_complete(text, line, begidx, endidx, index_dict) == sorted(sport_item_strs) def test_index_based_completion_nomatch(): text = 'q' - line = 'command q' + line = 'command {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert index_based_complete(text, line, begidx, endidx, index_dict) == [] @@ -631,34 +568,24 @@ def test_index_based_completion_nomatch(): def test_index_based_default_completer(request): test_dir = os.path.dirname(request.module.__file__) - text = 'c' - path = os.path.join(test_dir, text) - line = 'command Pizza Bat Computer {}'.format(path) + text = os.path.join(test_dir, 'c') + line = 'command Pizza Bat Computer {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert index_based_complete(text, line, begidx, endidx, index_dict, path_complete) == ['conftest.py '] + assert index_based_complete(text, line, begidx, endidx, index_dict, path_complete) == [text + 'onftest.py'] def test_index_based_callable_completer(request): test_dir = os.path.dirname(request.module.__file__) - text = 'c' - path = os.path.join(test_dir, text) - line = 'command Pizza Bat {}'.format(path) - - endidx = len(line) - begidx = endidx - len(text) - - assert index_based_complete(text, line, begidx, endidx, index_dict) == ['conftest.py '] + text = os.path.join(test_dir, 'c') + line = 'command Pizza Bat {}'.format(text) -def test_index_based_completion_syntax_err(): - text = 'Foo' - line = 'command "Pizza Foo' endidx = len(line) begidx = endidx - len(text) - assert index_based_complete(text, line, begidx, endidx, index_dict) == [] + assert index_based_complete(text, line, begidx, endidx, index_dict) == [text + 'onftest.py'] def test_parseline_command_and_args(cmd2_app): @@ -740,155 +667,53 @@ def sc_app(): def test_cmd2_subcommand_completion_single_end(sc_app): text = 'f' - line = 'base f' + line = 'base {}'.format(text) endidx = len(line) begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sc_app.complete(text, state) + first_match = complete_tester(text, line, begidx, endidx, sc_app) # It is at end of line, so extra space is present assert first_match is not None and sc_app.completion_matches == ['foo '] -def test_cmd2_subcommand_completion_single_mid(sc_app): - text = 'f' - line = 'base fo' - endidx = len(line) - 1 - begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sc_app.complete(text, state) - - assert first_match is not None and sc_app.completion_matches == ['foo'] - def test_cmd2_subcommand_completion_multiple(sc_app): text = '' - line = 'base ' + line = 'base {}'.format(text) endidx = len(line) begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sc_app.complete(text, state) + first_match = complete_tester(text, line, begidx, endidx, sc_app) assert first_match is not None and sc_app.completion_matches == ['bar', 'foo'] def test_cmd2_subcommand_completion_nomatch(sc_app): text = 'z' - line = 'base z' - endidx = len(line) - begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sc_app.complete(text, state) - - assert first_match is None - -def test_cmd2_subcommand_completion_after_subcommand(sc_app): - text = 'f' - line = 'base foo f' + line = 'base {}'.format(text) endidx = len(line) begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sc_app.complete(text, state) + first_match = complete_tester(text, line, begidx, endidx, sc_app) assert first_match is None -def test_cmd2_help_subcommand_completion_single_end(sc_app): +def test_cmd2_help_subcommand_completion_single(sc_app): text = 'base' - line = 'help base' + line = 'help {}'.format(text) endidx = len(line) begidx = endidx - len(text) - - # Commands with subcommands have a space at the end when the cursor is at the end of the line - assert sc_app.complete_help(text, line, begidx, endidx) == ['base '] - - -def test_cmd2_help_subcommand_completion_single_mid(sc_app): - text = 'ba' - line = 'help base' - begidx = 5 - endidx = 6 assert sc_app.complete_help(text, line, begidx, endidx) == ['base'] - def test_cmd2_help_subcommand_completion_multiple(sc_app): text = '' - line = 'help base ' + line = 'help base {}'.format(text) endidx = len(line) begidx = endidx - len(text) + assert sc_app.complete_help(text, line, begidx, endidx) == ['bar', 'foo'] def test_cmd2_help_subcommand_completion_nomatch(sc_app): text = 'z' - line = 'help base z' + line = 'help base {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert sc_app.complete_help(text, line, begidx, endidx) == [] @@ -933,233 +758,79 @@ def sb_app(): def test_cmd2_submenu_completion_single_end(sb_app): text = 'f' - line = 'second f' + line = 'second {}'.format(text) endidx = len(line) begidx = endidx - len(text) - state = 0 - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sb_app.complete(text, state) + first_match = complete_tester(text, line, begidx, endidx, sb_app) # It is at end of line, so extra space is present assert first_match is not None and sb_app.completion_matches == ['foo '] -def test_cmd2_submenu_completion_single_mid(sb_app): - text = 'f' - line = 'second fo' - endidx = len(line) - 1 - begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sb_app.complete(text, state) - - assert first_match is not None and sb_app.completion_matches == ['foo'] - - def test_cmd2_submenu_completion_multiple(sb_app): - text = '' - line = 'second ' + text = 'e' + line = 'second {}'.format(text) endidx = len(line) begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - def get_endidx(): - return endidx + expected = ['edit', 'eof', 'eos'] + first_match = complete_tester(text, line, begidx, endidx, sb_app) - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sb_app.complete(text, state) - - assert first_match is not None and sb_app.completion_matches == [ - '_relative_load', - 'alias', - 'edit', - 'eof', - 'eos', - 'foo', - 'help', - 'history', - 'load', - 'py', - 'pyscript', - 'quit', - 'set', - 'shell', - 'shortcuts', - 'unalias' - ] + assert first_match is not None and sb_app.completion_matches == expected def test_cmd2_submenu_completion_nomatch(sb_app): text = 'z' - line = 'second z' + line = 'second {}'.format(text) endidx = len(line) begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sb_app.complete(text, state) + first_match = complete_tester(text, line, begidx, endidx, sb_app) assert first_match is None def test_cmd2_submenu_completion_after_submenu_match(sb_app): text = 'a' - line = 'second foo a' + line = 'second foo {}'.format(text) endidx = len(line) begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sb_app.complete(text, state) - assert first_match is not None and sb_app.completion_matches == ['asd'] + first_match = complete_tester(text, line, begidx, endidx, sb_app) + assert first_match is not None and sb_app.completion_matches == ['asd '] def test_cmd2_submenu_completion_after_submenu_nomatch(sb_app): text = 'b' - line = 'second foo b' + line = 'second foo {}'.format(text) endidx = len(line) begidx = endidx - len(text) - state = 0 - - def get_line(): - return line - - def get_begidx(): - return begidx - - def get_endidx(): - return endidx - - with mock.patch.object(readline, 'get_line_buffer', get_line): - with mock.patch.object(readline, 'get_begidx', get_begidx): - with mock.patch.object(readline, 'get_endidx', get_endidx): - # Run the readline tab-completion function with readline mocks in place - first_match = sb_app.complete(text, state) + first_match = complete_tester(text, line, begidx, endidx, sb_app) assert first_match is None -def test_cmd2_help_submenu_completion_single_mid(sb_app): - text = 'sec' - line = 'help sec' - begidx = 5 - endidx = 8 - assert sb_app.complete_help(text, line, begidx, endidx) == ['second'] - - def test_cmd2_help_submenu_completion_multiple(sb_app): - text = '' - line = 'help second ' + text = 'p' + line = 'help second {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert sb_app.complete_help(text, line, begidx, endidx) == [ - '_relative_load', - 'alias', - 'edit', - 'eof', - 'eos', - 'foo', - 'help', - 'history', - 'load', - 'py', - 'pyscript', - 'quit', - 'set', - 'shell', - 'shortcuts', - 'unalias' - ] + + assert sb_app.complete_help(text, line, begidx, endidx) == ['py', 'pyscript'] def test_cmd2_help_submenu_completion_nomatch(sb_app): - text = 'b' - line = 'help second b' + text = 'fake' + line = 'help second {}'.format(text) endidx = len(line) begidx = endidx - len(text) assert sb_app.complete_help(text, line, begidx, endidx) == [] def test_cmd2_help_submenu_completion_subcommands(sb_app): - text = '' - line = 'help second ' + text = 'p' + line = 'help second {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert sb_app.complete_help(text, line, begidx, endidx) == [ - '_relative_load', - 'alias', - 'edit', - 'eof', - 'eos', - 'foo', - 'help', - 'history', - 'load', - 'py', - 'pyscript', - 'quit', - 'set', - 'shell', - 'shortcuts', - 'unalias' - ] + + assert sb_app.complete_help(text, line, begidx, endidx) == ['py', 'pyscript'] |