summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2019-07-17 20:29:39 -0400
committerKevin Van Brunt <kmvanbrunt@gmail.com>2019-07-17 20:29:39 -0400
commitd9728550f0996dc5900a48f5948c1950143e0801 (patch)
tree677108fc33446585f5e9618b6e9d4f8ce010cd56
parent2496f09bc9a0b373bba756f680b91d676db93f83 (diff)
downloadcmd2-git-d9728550f0996dc5900a48f5948c1950143e0801.tar.gz
Added unit tests for tab completing multiline commands
-rw-r--r--CHANGELOG.md1
-rw-r--r--cmd2/cmd2.py2
-rw-r--r--tests/test_completion.py56
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,