File: test_sections.py

package info (click to toggle)
python-cloup 3.0.8-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 936 kB
  • sloc: python: 5,371; makefile: 120
file content (148 lines) | stat: -rw-r--r-- 4,721 bytes parent folder | download | duplicates (2)
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')])