246 lines
5.7 KiB
Python
246 lines
5.7 KiB
Python
import sys
|
|
|
|
import pytest
|
|
|
|
import click
|
|
|
|
|
|
def debug():
|
|
click.echo(
|
|
f"{sys._getframe(1).f_code.co_name}"
|
|
f"={'|'.join(click.get_current_context().args)}"
|
|
)
|
|
|
|
|
|
def test_basic_chaining(runner):
|
|
@click.group(chain=True)
|
|
def cli():
|
|
pass
|
|
|
|
@cli.command("sdist")
|
|
def sdist():
|
|
click.echo("sdist called")
|
|
|
|
@cli.command("bdist")
|
|
def bdist():
|
|
click.echo("bdist called")
|
|
|
|
result = runner.invoke(cli, ["bdist", "sdist", "bdist"])
|
|
assert not result.exception
|
|
assert result.output.splitlines() == [
|
|
"bdist called",
|
|
"sdist called",
|
|
"bdist called",
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("args", "expect"),
|
|
[
|
|
(["--help"], "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..."),
|
|
(["--help"], "ROOT HELP"),
|
|
(["sdist", "--help"], "SDIST HELP"),
|
|
(["bdist", "--help"], "BDIST HELP"),
|
|
(["bdist", "sdist", "--help"], "SDIST HELP"),
|
|
],
|
|
)
|
|
def test_chaining_help(runner, args, expect):
|
|
@click.group(chain=True)
|
|
def cli():
|
|
"""ROOT HELP"""
|
|
pass
|
|
|
|
@cli.command("sdist")
|
|
def sdist():
|
|
"""SDIST HELP"""
|
|
click.echo("sdist called")
|
|
|
|
@cli.command("bdist")
|
|
def bdist():
|
|
"""BDIST HELP"""
|
|
click.echo("bdist called")
|
|
|
|
result = runner.invoke(cli, args)
|
|
assert not result.exception
|
|
assert expect in result.output
|
|
|
|
|
|
def test_chaining_with_options(runner):
|
|
@click.group(chain=True)
|
|
def cli():
|
|
pass
|
|
|
|
@cli.command("sdist")
|
|
@click.option("--format")
|
|
def sdist(format):
|
|
click.echo(f"sdist called {format}")
|
|
|
|
@cli.command("bdist")
|
|
@click.option("--format")
|
|
def bdist(format):
|
|
click.echo(f"bdist called {format}")
|
|
|
|
result = runner.invoke(cli, ["bdist", "--format=1", "sdist", "--format=2"])
|
|
assert not result.exception
|
|
assert result.output.splitlines() == ["bdist called 1", "sdist called 2"]
|
|
|
|
|
|
@pytest.mark.parametrize(("chain", "expect"), [(False, "1"), (True, "[]")])
|
|
def test_no_command_result_callback(runner, chain, expect):
|
|
"""When a group has ``invoke_without_command=True``, the result
|
|
callback is always invoked. A regular group invokes it with
|
|
its return value, a chained group with ``[]``.
|
|
"""
|
|
|
|
@click.group(invoke_without_command=True, chain=chain)
|
|
def cli():
|
|
return 1
|
|
|
|
@cli.result_callback()
|
|
def process_result(result):
|
|
click.echo(result, nl=False)
|
|
|
|
result = runner.invoke(cli, [])
|
|
assert result.output == expect
|
|
|
|
|
|
def test_chaining_with_arguments(runner):
|
|
@click.group(chain=True)
|
|
def cli():
|
|
pass
|
|
|
|
@cli.command("sdist")
|
|
@click.argument("format")
|
|
def sdist(format):
|
|
click.echo(f"sdist called {format}")
|
|
|
|
@cli.command("bdist")
|
|
@click.argument("format")
|
|
def bdist(format):
|
|
click.echo(f"bdist called {format}")
|
|
|
|
result = runner.invoke(cli, ["bdist", "1", "sdist", "2"])
|
|
assert not result.exception
|
|
assert result.output.splitlines() == ["bdist called 1", "sdist called 2"]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("args", "input", "expect"),
|
|
[
|
|
(["-f", "-"], "foo\nbar", ["foo", "bar"]),
|
|
(["-f", "-", "strip"], "foo \n bar", ["foo", "bar"]),
|
|
(["-f", "-", "strip", "uppercase"], "foo \n bar", ["FOO", "BAR"]),
|
|
],
|
|
)
|
|
def test_pipeline(runner, args, input, expect):
|
|
@click.group(chain=True, invoke_without_command=True)
|
|
@click.option("-f", type=click.File("r"))
|
|
def cli(f):
|
|
pass
|
|
|
|
@cli.result_callback()
|
|
def process_pipeline(processors, f):
|
|
iterator = (x.rstrip("\r\n") for x in f)
|
|
for processor in processors:
|
|
iterator = processor(iterator)
|
|
for item in iterator:
|
|
click.echo(item)
|
|
|
|
@cli.command("uppercase")
|
|
def make_uppercase():
|
|
def processor(iterator):
|
|
for line in iterator:
|
|
yield line.upper()
|
|
|
|
return processor
|
|
|
|
@cli.command("strip")
|
|
def make_strip():
|
|
def processor(iterator):
|
|
for line in iterator:
|
|
yield line.strip()
|
|
|
|
return processor
|
|
|
|
result = runner.invoke(cli, args, input=input)
|
|
assert not result.exception
|
|
assert result.output.splitlines() == expect
|
|
|
|
|
|
def test_args_and_chain(runner):
|
|
@click.group(chain=True)
|
|
def cli():
|
|
debug()
|
|
|
|
@cli.command()
|
|
def a():
|
|
debug()
|
|
|
|
@cli.command()
|
|
def b():
|
|
debug()
|
|
|
|
@cli.command()
|
|
def c():
|
|
debug()
|
|
|
|
result = runner.invoke(cli, ["a", "b", "c"])
|
|
assert not result.exception
|
|
assert result.output.splitlines() == ["cli=", "a=", "b=", "c="]
|
|
|
|
|
|
def test_multicommand_arg_behavior(runner):
|
|
with pytest.raises(RuntimeError):
|
|
|
|
@click.group(chain=True)
|
|
@click.argument("forbidden", required=False)
|
|
def bad_cli():
|
|
pass
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
@click.group(chain=True)
|
|
@click.argument("forbidden", nargs=-1)
|
|
def bad_cli2():
|
|
pass
|
|
|
|
@click.group(chain=True)
|
|
@click.argument("arg")
|
|
def cli(arg):
|
|
click.echo(f"cli:{arg}")
|
|
|
|
@cli.command()
|
|
def a():
|
|
click.echo("a")
|
|
|
|
result = runner.invoke(cli, ["foo", "a"])
|
|
assert not result.exception
|
|
assert result.output.splitlines() == ["cli:foo", "a"]
|
|
|
|
|
|
@pytest.mark.xfail
|
|
def test_multicommand_chaining(runner):
|
|
@click.group(chain=True)
|
|
def cli():
|
|
debug()
|
|
|
|
@cli.group()
|
|
def l1a():
|
|
debug()
|
|
|
|
@l1a.command()
|
|
def l2a():
|
|
debug()
|
|
|
|
@l1a.command()
|
|
def l2b():
|
|
debug()
|
|
|
|
@cli.command()
|
|
def l1b():
|
|
debug()
|
|
|
|
result = runner.invoke(cli, ["l1a", "l2a", "l1b"])
|
|
assert not result.exception
|
|
assert result.output.splitlines() == ["cli=", "l1a=", "l2a=", "l1b="]
|