diff options
author | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2019-07-17 20:29:39 -0400 |
---|---|---|
committer | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2019-07-17 20:29:39 -0400 |
commit | d9728550f0996dc5900a48f5948c1950143e0801 (patch) | |
tree | 677108fc33446585f5e9618b6e9d4f8ce010cd56 | |
parent | 2496f09bc9a0b373bba756f680b91d676db93f83 (diff) | |
download | cmd2-git-d9728550f0996dc5900a48f5948c1950143e0801.tar.gz |
Added unit tests for tab completing multiline commands
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | cmd2/cmd2.py | 2 | ||||
-rw-r--r-- | tests/test_completion.py | 56 |
3 files changed, 48 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index abb440dd..e26c60d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Greatly simplified using argparse-based tab completion. The new interface is a complete overhaul that breaks the previous way of specifying completion and choices functions. See header of [argparse_custom.py](https://github.com/python-cmd2/cmd2/blob/master/cmd2/argparse_custom.py) for more information. + * Enabled tab completion on multiline commands * **Renamed Commands Notice** * The following commands were renamed in the last release and have been removed in this release * `load` - replaced by `run_script` diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index d63af879..1f07f2cb 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -1863,7 +1863,7 @@ class Cmd(cmd.Cmd): try: self._at_continuation_prompt = True - # Save the command line up to this point + # Save the command line up to this point for tab completion self._multiline_in_progress = line + '\n' nextline = self._pseudo_raw_input(self.continuation_prompt) diff --git a/tests/test_completion.py b/tests/test_completion.py index 3cee1955..233783c6 100644 --- a/tests/test_completion.py +++ b/tests/test_completion.py @@ -61,7 +61,7 @@ class CompletionsExample(cmd2.Cmd): Example cmd2 application used to exercise tab-completion tests """ def __init__(self): - cmd2.Cmd.__init__(self) + cmd2.Cmd.__init__(self, multiline_commands=['test_multiline']) def do_test_basic(self, args): pass @@ -88,6 +88,12 @@ class CompletionsExample(cmd2.Cmd): def complete_test_raise_exception(self, text, line, begidx, endidx): raise IndexError("You are out of bounds!!") + def do_test_multiline(self, args): + pass + + def complete_test_multiline(self, text, line, begidx, endidx): + return utils.basic_complete(text, line, begidx, endidx, sport_item_strs) + def do_test_no_completer(self, args): """Completing this should result in completedefault() being called""" pass @@ -128,7 +134,7 @@ def test_complete_empty_arg(cmd2_app): endidx = len(line) begidx = endidx - len(text) - expected = sorted(cmd2_app.get_visible_commands()) + expected = sorted(cmd2_app.get_visible_commands(), key=cmd2_app.default_sort_key) first_match = complete_tester(text, line, begidx, endidx, cmd2_app) assert first_match is not None and cmd2_app.completion_matches == expected @@ -733,7 +739,8 @@ def test_add_opening_quote_basic_no_text(cmd2_app): # The whole list will be returned with no opening quotes added first_match = complete_tester(text, line, begidx, endidx, cmd2_app) - assert first_match is not None and cmd2_app.completion_matches == sorted(food_item_strs) + assert first_match is not None and cmd2_app.completion_matches == sorted(food_item_strs, + key=cmd2_app.default_sort_key) def test_add_opening_quote_basic_nothing_added(cmd2_app): text = 'P' @@ -750,7 +757,7 @@ def test_add_opening_quote_basic_quote_added(cmd2_app): endidx = len(line) begidx = endidx - len(text) - expected = sorted(['"Ham', '"Ham Sandwich']) + expected = sorted(['"Ham', '"Ham Sandwich'], key=cmd2_app.default_sort_key) first_match = complete_tester(text, line, begidx, endidx, cmd2_app) assert first_match is not None and cmd2_app.completion_matches == expected @@ -771,7 +778,7 @@ def test_add_opening_quote_basic_text_is_common_prefix(cmd2_app): endidx = len(line) begidx = endidx - len(text) - expected = sorted(['"Ham', '"Ham Sandwich']) + expected = sorted(['"Ham', '"Ham Sandwich'], key=cmd2_app.default_sort_key) first_match = complete_tester(text, line, begidx, endidx, cmd2_app) assert first_match is not None and cmd2_app.completion_matches == expected @@ -783,7 +790,8 @@ def test_add_opening_quote_delimited_no_text(cmd2_app): # The whole list will be returned with no opening quotes added first_match = complete_tester(text, line, begidx, endidx, cmd2_app) - assert first_match is not None and cmd2_app.completion_matches == sorted(delimited_strs) + assert first_match is not None and cmd2_app.completion_matches == sorted(delimited_strs, + key=cmd2_app.default_sort_key) def test_add_opening_quote_delimited_nothing_added(cmd2_app): text = '/ho' @@ -791,8 +799,8 @@ def test_add_opening_quote_delimited_nothing_added(cmd2_app): endidx = len(line) begidx = endidx - len(text) - expected_matches = sorted(delimited_strs) - expected_display = sorted(['other user', 'user']) + expected_matches = sorted(delimited_strs, key=cmd2_app.default_sort_key) + expected_display = sorted(['other user', 'user'], key=cmd2_app.default_sort_key) first_match = complete_tester(text, line, begidx, endidx, cmd2_app) assert first_match is not None and \ @@ -806,7 +814,7 @@ def test_add_opening_quote_delimited_quote_added(cmd2_app): begidx = endidx - len(text) expected_common_prefix = '"/home/user/file' - expected_display = sorted(['file.txt', 'file space.txt']) + expected_display = sorted(['file.txt', 'file space.txt'], key=cmd2_app.default_sort_key) first_match = complete_tester(text, line, begidx, endidx, cmd2_app) assert first_match is not None and \ @@ -821,7 +829,7 @@ def test_add_opening_quote_delimited_text_is_common_prefix(cmd2_app): begidx = endidx - len(text) expected_common_prefix = '"/home/user/file' - expected_display = sorted(['file.txt', 'file space.txt']) + expected_display = sorted(['file.txt', 'file space.txt'], key=cmd2_app.default_sort_key) first_match = complete_tester(text, line, begidx, endidx, cmd2_app) assert first_match is not None and \ @@ -863,6 +871,34 @@ def test_quote_as_command(cmd2_app): assert first_match is None and not cmd2_app.completion_matches +def test_complete_multiline_on_single_line(cmd2_app): + text = '' + line = 'test_multiline {}'.format(text) + endidx = len(line) + begidx = endidx - len(text) + + expected = sorted(sport_item_strs, key=cmd2_app.default_sort_key) + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + + assert first_match is not None and cmd2_app.completion_matches == expected + + +def test_complete_multiline_on_multiple_lines(cmd2_app): + # Set the same variables _complete_statement() sets when a user is entering data at a continuation prompt + cmd2_app._at_continuation_prompt = True + cmd2_app._multiline_in_progress = "test_multiline\n" + + text = 'Ba' + line = '{}'.format(text) + endidx = len(line) + begidx = endidx - len(text) + + expected = sorted(['Bat', 'Basket', 'Basketball'], key=cmd2_app.default_sort_key) + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + + assert first_match is not None and cmd2_app.completion_matches == expected + + # Used by redirect_complete tests class RedirCompType(enum.Enum): SHELL_CMD = 1, |