summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd2/parsing.py15
-rw-r--r--tests/test_parsing.py109
2 files changed, 84 insertions, 40 deletions
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index 61b6f745..8edfacb9 100644
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -452,13 +452,16 @@ class StatementParser:
This method is used by tab completion code and therefore must not
generate an exception if there are unclosed quotes.
- The Statement object returned by this method can at most contain values
+ The `Statement` object returned by this method can at most contain values
in the following attributes:
- args
- raw
- command
- multiline_command
+ `Statement.args` includes all output redirection clauses and command
+ terminators.
+
Different from parse(), this method does not remove redundant whitespace
within args. However, it does ensure args has no leading or trailing
whitespace.
@@ -473,12 +476,10 @@ class StatementParser:
# we got a match, extract the command
command = match.group(1)
- # the _command_pattern regex is designed to match the spaces
- # between command and args with a second match group. Using
- # the end of the second match group ensures that args has
- # no leading whitespace. The rstrip() makes sure there is
- # no trailing whitespace
- args = line[match.end(2):].rstrip()
+ # take everything from the end of the first match group to
+ # the end of the line as the arguments (stripping leading
+ # and trailing spaces)
+ args = line[match.end(1):].strip()
# if the command is empty that means the input was either empty
# or something weird like '>'. args should be empty if we couldn't
# parse a command
diff --git a/tests/test_parsing.py b/tests/test_parsing.py
index b0d370ac..9cf9429a 100644
--- a/tests/test_parsing.py
+++ b/tests/test_parsing.py
@@ -584,77 +584,109 @@ def test_parse_command_only_command_and_args(parser):
statement = parser.parse_command_only(line)
assert statement == 'history'
assert statement.args == statement
- assert statement.raw == line
+ assert statement.arg_list == []
assert statement.command == 'help'
assert statement.command_and_args == line
- assert statement.arg_list == []
assert statement.multiline_command == ''
+ assert statement.raw == line
assert statement.terminator == ''
assert statement.suffix == ''
assert statement.pipe_to == []
assert statement.output == ''
assert statement.output_to == ''
-def test_parse_command_only_emptyline(parser):
- line = ''
- statement = parser.parse_command_only(line)
- # statement is a subclass of str(), the value of the str
- # should be '', to retain backwards compatibility with
- # the cmd in the standard library
- assert statement.command == ''
- assert statement == ''
- assert statement.args == statement
- assert not statement.argv
- assert not statement.arg_list
- assert statement.command_and_args == ''
-
def test_parse_command_only_strips_line(parser):
line = ' help history '
statement = parser.parse_command_only(line)
- assert statement.command == 'help'
assert statement == 'history'
assert statement.args == statement
+ assert statement.arg_list == []
+ assert statement.command == 'help'
assert statement.command_and_args == line.strip()
+ assert statement.multiline_command == ''
+ assert statement.raw == line
+ assert statement.terminator == ''
+ assert statement.suffix == ''
+ assert statement.pipe_to == []
+ assert statement.output == ''
+ assert statement.output_to == ''
def test_parse_command_only_expands_alias(parser):
- line = 'fake foobar.py'
+ line = 'fake foobar.py "somebody.py'
statement = parser.parse_command_only(line)
- assert statement.command == 'pyscript'
- assert statement == 'foobar.py'
+ assert statement == 'foobar.py "somebody.py'
assert statement.args == statement
+ assert statement.arg_list == []
+ assert statement.command == 'pyscript'
+ assert statement.command_and_args == 'pyscript foobar.py "somebody.py'
+ assert statement.multiline_command == ''
+ assert statement.raw == line
+ assert statement.terminator == ''
+ assert statement.suffix == ''
+ assert statement.pipe_to == []
+ assert statement.output == ''
+ assert statement.output_to == ''
def test_parse_command_only_expands_shortcuts(parser):
line = '!cat foobar.txt'
statement = parser.parse_command_only(line)
- assert statement.command == 'shell'
assert statement == 'cat foobar.txt'
assert statement.args == statement
+ assert statement.arg_list == []
+ assert statement.command == 'shell'
assert statement.command_and_args == 'shell cat foobar.txt'
+ assert statement.multiline_command == ''
+ assert statement.raw == line
+ assert statement.multiline_command == ''
+ assert statement.terminator == ''
+ assert statement.suffix == ''
+ assert statement.pipe_to == []
+ assert statement.output == ''
+ assert statement.output_to == ''
def test_parse_command_only_quoted_args(parser):
line = 'l "/tmp/directory with spaces/doit.sh"'
statement = parser.parse_command_only(line)
- assert statement.command == 'shell'
assert statement == 'ls -al "/tmp/directory with spaces/doit.sh"'
assert statement.args == statement
+ assert statement.arg_list == []
+ assert statement.command == 'shell'
assert statement.command_and_args == line.replace('l', 'shell ls -al')
+ assert statement.multiline_command == ''
+ assert statement.raw == line
+ assert statement.multiline_command == ''
+ assert statement.terminator == ''
+ assert statement.suffix == ''
+ assert statement.pipe_to == []
+ assert statement.output == ''
+ assert statement.output_to == ''
-@pytest.mark.parametrize('line', [
- 'helpalias > out.txt',
- 'helpalias>out.txt',
- 'helpalias >> out.txt',
- 'helpalias>>out.txt',
- 'help|less',
- 'helpalias;',
- 'help ;;',
- 'help; ;;',
+@pytest.mark.parametrize('line,args', [
+ ('helpalias > out.txt', '> out.txt'),
+ ('helpalias>out.txt', '>out.txt'),
+ ('helpalias >> out.txt', '>> out.txt'),
+ ('helpalias>>out.txt', '>>out.txt'),
+ ('help|less', '|less'),
+ ('helpalias;', ';'),
+ ('help ;;', ';;'),
+ ('help; ;;', '; ;;'),
])
-def test_parse_command_only_specialchars(parser, line):
+def test_parse_command_only_specialchars(parser, line, args):
statement = parser.parse_command_only(line)
+ assert statement == args
+ assert statement.args == args
assert statement.command == 'help'
- assert statement.args == statement
+ assert statement.multiline_command == ''
+ assert statement.raw == line
+ assert statement.multiline_command == ''
+ assert statement.terminator == ''
+ assert statement.suffix == ''
+ assert statement.pipe_to == []
+ assert statement.output == ''
+ assert statement.output_to == ''
@pytest.mark.parametrize('line', [
+ '',
';',
';;',
';; ;',
@@ -668,8 +700,19 @@ def test_parse_command_only_specialchars(parser, line):
])
def test_parse_command_only_empty(parser, line):
statement = parser.parse_command_only(line)
- assert statement.command == ''
assert statement == ''
+ assert statement.args == statement
+ assert statement.arg_list == []
+ assert statement.command == ''
+ assert statement.command_and_args == ''
+ assert statement.multiline_command == ''
+ assert statement.raw == line
+ assert statement.multiline_command == ''
+ assert statement.terminator == ''
+ assert statement.suffix == ''
+ assert statement.pipe_to == []
+ assert statement.output == ''
+ assert statement.output_to == ''
def test_parse_command_only_multiline(parser):
line = 'multiline with partially "open quotes and no terminator'