diff --git a/CHANGES b/CHANGES index ab6e42c53..5903a8e1b 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,8 @@ Version 7.0 - `secho`'s first argument can now be `None`, like in `echo`. - Usage errors now hint at the `--help` option. - ``launch`` now works properly under Cygwin. See #650. +- `CliRunner.invoke` now may receive `args` as a string representing + a Unix shell command. See #664. Version 6.7 ----------- diff --git a/click/testing.py b/click/testing.py index 4416c7741..09d37a72e 100644 --- a/click/testing.py +++ b/click/testing.py @@ -3,8 +3,9 @@ import shutil import tempfile import contextlib +import shlex -from ._compat import iteritems, PY2 +from ._compat import iteritems, PY2, string_types # If someone wants to vendor click, we want to ensure the @@ -260,7 +261,10 @@ def invoke(self, cli, args=None, input=None, env=None, The ``color`` parameter was added. :param cli: the command to invoke - :param args: the arguments to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. :param input: the input data for `sys.stdin`. :param env: the environment overrides. :param catch_exceptions: Whether to catch any other exceptions than @@ -274,6 +278,9 @@ def invoke(self, cli, args=None, input=None, env=None, exception = None exit_code = 0 + if isinstance(args, string_types): + args = shlex.split(args) + try: cli.main(args=args or (), prog_name=self.get_default_prog_name(cli), **extra) diff --git a/tests/test_testing.py b/tests/test_testing.py index 7fc284a5c..c09109515 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -202,3 +202,23 @@ def cli_env(): assert result.output == 'ENV=some_value\n' assert os.environ == env_orig + + +@pytest.mark.parametrize('args, expected_output', [ + (None, 'bar\n'), + ([], 'bar\n'), + ('', 'bar\n'), + (['--foo', 'one two'], 'one two\n'), + ('--foo "one two"', 'one two\n'), +]) +def test_args(args, expected_output): + + @click.command() + @click.option('--foo', default='bar') + def cli_args(foo): + click.echo(foo) + + runner = CliRunner() + result = runner.invoke(cli_args, args=args) + assert result.exit_code == 0 + assert result.output == expected_output