1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
"""Test for the "subcommand sections" feature/module."""
import click
import pytest
from click import pass_context
import cloup
from cloup import Section
from cloup._util import pick_non_missing, reindent
from cloup.typing import MISSING
from tests.util import new_dummy_func, pick_first_bool
@pytest.mark.parametrize(
'align_sections', [True, False], ids=['aligned', 'non-aligned']
)
def test_subcommand_sections_are_correctly_rendered_in_help(
runner, align_sections, get_example_group
):
grp = get_example_group(align_sections)
result = runner.invoke(grp, args=('--help',))
if result.exception:
raise result.exception
assert result.exit_code == 0
assert result.output.strip() == grp.expected_help
@pytest.mark.parametrize(
'subcommand_cls', [click.Command, cloup.Command, click.Group, cloup.Group],
ids=['click_Command', 'cloup_Command', 'click_Group', 'cloup_Group'],
)
@pytest.mark.parametrize(
'assign_to_section', [True, False],
ids=['with_section', 'without_section'],
)
def test_Group_subcommand_decorator(subcommand_cls, assign_to_section):
grp = cloup.Group('name')
# Use @grp.group if subcommand_class is a Group, else @grp.Command
method_name = ('group' if issubclass(subcommand_cls, cloup.Group)
else 'command')
decorator = getattr(grp, method_name)
# Add a subcommand to the Group using the decorator
subcommand_name = 'cmd'
section_arg = Section('title') if assign_to_section else None
subcommand = decorator(
subcommand_name,
section=section_arg,
cls=subcommand_cls,
help='Help'
)(new_dummy_func())
assert subcommand.__class__ is subcommand_cls
assert subcommand.help == 'Help'
assert grp.commands[subcommand_name] is subcommand
if assign_to_section:
section = grp._user_sections[0]
assert section is section_arg
assert section.commands[subcommand_name] is subcommand
else:
assert grp._default_section.commands[subcommand_name] is subcommand
@pytest.mark.parametrize(
'cmd_value', [MISSING, None, True, False],
ids=lambda val: f'cmd_{val}'
)
@pytest.mark.parametrize(
'ctx_value', [MISSING, None, True, False],
ids=lambda val: f'ctx_{val}'
)
def test_align_sections_context_setting(runner, ctx_value, cmd_value):
should_align = pick_first_bool([cmd_value, ctx_value], default=True)
cxt_settings = pick_non_missing(dict(
align_sections=ctx_value,
terminal_width=80,
))
cmd_kwargs = pick_non_missing(dict(
align_sections=cmd_value,
context_settings=cxt_settings
))
@cloup.group(**cmd_kwargs)
@pass_context
def cmd(ctx, one, much_longer_opt):
assert cmd.must_align_sections(ctx) == should_align
cmd.section(
"First section",
cloup.command('cmd', help='First command help')(new_dummy_func()),
)
cmd.section(
"Second section",
cloup.command('longer-cmd', help='Second command help')(new_dummy_func()),
)
result = runner.invoke(cmd, args=('--help',))
start = result.output.find('First section')
if should_align:
expected = """
First section:
cmd First command help
Second section:
longer-cmd Second command help"""
else:
expected = """
First section:
cmd First command help
Second section:
longer-cmd Second command help"""
expected = reindent(expected)
end = start + len(expected)
assert result.output[start:end] == expected
def test_override_format_subcommand_name(runner):
class MyGroup(cloup.Group):
def format_subcommand_name(self, ctx, name, cmd) -> str:
return '*special*' if name == 'special' else name
main = MyGroup(name='main')
main.section(
'Commands',
cloup.Command(name='special', help='A special command.'),
cloup.Command(name='ordinary', help='An ordinary command.')
)
res = runner.invoke(main, ['--help'])
expected_help = reindent("""
Usage: main [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
*special* A special command.
ordinary An ordinary command.
""")
assert res.output == expected_help
def test_section_error_if_first_arg_is_not_a_string():
with pytest.raises(TypeError, match="the first argument must be a string"):
Section([cloup.Command('cmd')])
grp = cloup.Group()
with pytest.raises(TypeError, match="the first argument must be a string"):
grp.section([cloup.Command('cmd')])
|