Passed
Push — master ( 691bd8...662939 )
by Marco
01:32
created

test_command_flag_count()   B

Complexity

Conditions 4

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
c 1
b 0
f 0
dl 0
loc 22
rs 8.9197
1
"""
2
For ideas how to test commands based on clicks, see http://click.pocoo.org/5/testing/#basic-testing
3
"""
4
import click
0 ignored issues
show
introduced by
Unable to import 'click'
Loading history...
5
import pytest
0 ignored issues
show
introduced by
Unable to import 'pytest'
Loading history...
6
from click import Argument, Option
0 ignored issues
show
introduced by
Unable to import 'click'
Loading history...
introduced by
Imports from package click are not grouped
Loading history...
7
from click.testing import CliRunner
0 ignored issues
show
introduced by
Unable to import 'click.testing'
Loading history...
8
9
from groundwork.patterns.gw_commands_pattern import CommandExistException
10
11
12
def test_command_plugin_activation(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
13
    plugin = basicApp.plugins.get("CommandPlugin")
14
    assert plugin is not None
15
    assert plugin.active is True
16
17
18
# def test_command_cli_activation(basicApp):
19
#     test = basicApp.commands.start_cli(standalone_mode=True, args=[])
20
#     print(test)
21
22
23
def test_command_plugin_execution(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
24
    runner = CliRunner()
25
    result = runner.invoke(basicApp.commands._commands["test"].click_command, ["--invalid"])
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _commands was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
26
    assert "no such option" in result.output
27
    assert result.exit_code == 2
28
29
    result = runner.invoke(basicApp.commands._commands["test"].click_command, ["--arg", "12345"])
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _commands was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
30
    assert "12345" in result.output
31
    assert result.exit_code == 0
32
33
    command = basicApp.commands.get("test")
34
    assert command is not None
35
36
37
def test_command_multi_registration(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
38
    def _test_command(arg):
39
        print(arg)
40
41
    plugin = basicApp.plugins.get("CommandPlugin")
42
    with pytest.raises(CommandExistException):
43
        plugin.commands.register("test", "my test command", _test_command, params=[Option(("--arg", "-a"))])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (108/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
44
45
    plugin.commands.unregister("test")
46
    plugin.commands.register("test", "my test command", _test_command, params=[Option(("--arg", "-a"))])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (104/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
47
    assert len(basicApp.commands.get()) == 1
48
49
    plugin.commands.register("test2", "my test2 command", _test_command, params=[Option(("--arg", "-a"))])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
50
    assert len(basicApp.commands.get()) == 2
51
52
    basicApp.plugins.deactivate(["CommandPlugin"])
53
    print(basicApp.commands.get().keys())
54
    assert len(basicApp.commands.get().keys()) == 0
0 ignored issues
show
Unused Code introduced by
Do not use len(SEQUENCE) as condition value
Loading history...
55
56
57
def test_command_multi_plugin_registration(basicApp, EmptyCommandPlugin):
0 ignored issues
show
Coding Style Naming introduced by
The name test_command_multi_plugin_registration does not conform to the function naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name EmptyCommandPlugin does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
58
    def _test_command(arg):
59
        print(arg)
60
61
    plugin = basicApp.plugins.get("CommandPlugin")
62
    plugin2 = EmptyCommandPlugin(app=basicApp, name="CommandPlugin2")
63
    plugin2.activate()
64
    plugin2.commands.register("test2", "my test2 command", _test_command, params=[Option(("--arg", "-a"))])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
65
    assert len(basicApp.commands.get()) == 2
66
    assert len(plugin.commands.get()) == 1
67
    assert len(plugin2.commands.get()) == 1
68
69
    basicApp.plugins.deactivate(["CommandPlugin2"])
70
    assert len(basicApp.commands.get()) == 1
71
    assert len(plugin.commands.get()) == 1
72
    assert len(plugin2.commands.get()) == 0
0 ignored issues
show
Unused Code introduced by
Do not use len(SEQUENCE) as condition value
Loading history...
73
74
75
def test_command_mandatory_argument(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
76
    """
77
    This test case registers a command with a mandatory argument. Then it calls that command twice: first with the
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (114/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
78
    mandatory argument there; then with it missing.
79
80
    It is asserted, that the first call returns 0, the second one 2 as exit code.
81
    """
82
    def _test_command(*args, **kwargs):
83
        print(args)
84
        print(kwargs)
85
86
    plugin = basicApp.plugins.get("CommandPlugin")
87
    plugin.commands.unregister("test")
88
    # register a command with a mandatory argument
89
    plugin.commands.register("test", "my test command", _test_command, params=[Argument(("man_arg",), required=True)])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (118/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
90
    # call command with argument -> expect ok
91
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ["arg"])
92
    assert result.exit_code == 0
93
94
    # call command with no argument -> expect error
95
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, [])
96
    assert result.exit_code == 2
97
98
99
def test_command_optional_argument(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
100
    """
101
    This test case registers a command with an optional argument. Then it calls that command twice: first with the
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (114/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
102
    optional argument there; then with it missing.
103
104
    It is asserted, that both calls return 0 exit code.
105
    """
106
    def _test_command(*args, **kwargs):
107
        print(args)
108
        print(kwargs)
109
110
    plugin = basicApp.plugins.get("CommandPlugin")
111
    plugin.commands.unregister("test")
112
    # register a command with an optional argument
113
    plugin.commands.register("test", "my test command", _test_command, params=[Argument(("opt_arg",), required=False)])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (119/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
114
    # call command with argument -> expect ok
115
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ["arg"])
116
    assert result.exit_code == 0
117
118
    # call command with no argument -> expect ok
119
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, [])
120
    assert result.exit_code == 0
121
122
123
def test_command_mandatory_option(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
124
    """
125
    This test case registers a command with a mandatory option. Then it calls that command twice: first with the
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (112/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
126
    mandatory option there; then with it missing.
127
128
    It is asserted, that the first call returns 0, the second one 2 as exit code.
129
    """
130
    def _test_command(*args, **kwargs):
131
        print(args)
132
        print(kwargs)
133
134
    plugin = basicApp.plugins.get("CommandPlugin")
135
    plugin.commands.unregister("test")
136
    # register a command with a mandatory option
137
    plugin.commands.register("test", "my test command", _test_command, params=[Option(["--man-opt"], required=True)])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (117/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
138
    # call command with option --man-opt -> expect ok
139
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ["--man-opt", 123])
140
    assert result.exit_code == 0
141
142
    # call command with no option -> expect error
143
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, [])
144
    assert result.exit_code == 2
145
146
147
def test_command_optional_option(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
148
    """
149
    This test case registers a command with an optional option. Then it calls that command twice: first with the
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (112/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
150
    optional option there; then with it missing.
151
152
    It is asserted, that both calls return 0 exit code.
153
    """
154
    def _test_command(*args, **kwargs):
155
        print(args)
156
        print(kwargs)
157
158
    plugin = basicApp.plugins.get("CommandPlugin")
159
    plugin.commands.unregister("test")
160
    # register a command with a mandatory option
161
    plugin.commands.register("test", "my test command", _test_command, params=[Option(["--opt-opt"], required=False)])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (118/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
162
    # call command with option --opt-opt -> expect ok
163
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ["--opt-opt", 123])
164
    assert result.exit_code == 0
165
166
    # call command with no option -> expect ok
167
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, [])
168
    assert result.exit_code == 0
169
170
171
def test_command_path_argument(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
172
    """
173
    This test case registers a command with a path argument that need to exist.
174
    Then it calls that command twice: first with an existing path (the path of this source file); then with a
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
175
    non-existent one.
176
177
    It is asserted, that the first call returns 0, the second one 2 as exit code.
178
    """
179
    def _test_command(*args, **kwargs):
180
        print(args)
181
        print(kwargs)
182
183
    plugin = basicApp.plugins.get("CommandPlugin")
184
    plugin.commands.unregister("test")
185
    # register a command with a path argument, that must exist
186
    plugin.commands.register("test", "my test command", _test_command, params=[Argument(("man_arg",),
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (101/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
187
                                                                                        type=click.Path(exists=True))])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (119/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
188
    # call command with existing path as argument -> expect ok
189
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, [__file__])
190
    assert result.exit_code == 0
191
192
    # call command with non-existing path as argument -> expect error
193
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ['no such path'])
194
    assert result.exit_code == 2
195
196
197 View Code Duplication
def test_command_path_option(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
198
    """
199
    This test case registers a command with a path option that need to exist.
200
    Then it calls that command twice: first with an existing path (the path of this source file); then with a
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
201
    non-existent one.
202
203
    It is asserted, that the first call returns 0, the second one 2 as exit code.
204
    """
205
    def _test_command(*args, **kwargs):
206
        print(args)
207
        print(kwargs)
208
209
    plugin = basicApp.plugins.get("CommandPlugin")
210
    plugin.commands.unregister("test")
211
    # register a command with a path option, that must exist
212
    plugin.commands.register("test", "my test command", _test_command, params=[Option(["--path"],
213
                                                                                      type=click.Path(exists=True))])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (117/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
214
    # call command with existing path as option -> expect ok
215
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ['--path', __file__])
216
    assert result.exit_code == 0
217
218
    # call command with non-existing path as option -> expect error
219
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ['--path', 'no such path'])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (104/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
220
    assert result.exit_code == 2
221
222
223 View Code Duplication
def test_command_flag_on_off(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
224
    """
225
    This test case registers a command with a flag option. The assigned command handler throws an exception if
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (110/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
226
    the flag is not set.
227
    Then it calls that command twice: fist with the flag set; then with the flag not set.
228
229
    It is asserted, that the first call returns 0, the second one -1 - as that is exit code click's CliRunner returns
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (117/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
230
    in case an unhandled exception has been thrown in the command handler.
231
    """
232
    def _test_command(*args, **kwargs):
233
        print(args)
234
        print(kwargs)
235
        if not kwargs['flag_on']:
236
            raise Exception
237
238
    plugin = basicApp.plugins.get("CommandPlugin")
239
    plugin.commands.unregister("test")
240
    # register a command with an on/off flag; command throws exception if flag is off
241
    plugin.commands.register("test", "my test command", _test_command, params=[Option(["--flag-on/--flag-off"])])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (113/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
242
243
    # call command with --flag-on (True) -> expect ok
244
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ['--flag-on'])
245
    assert result.exit_code == 0
246
247
    # call command with --flag-off (False)  -> expect error
248
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ['--flag-off'])
249
    assert result.exit_code == -1
250
251
252
def test_command_flag_count(basicApp):
0 ignored issues
show
Coding Style Naming introduced by
The name basicApp does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
253
    """
254
    This test case registers a command with a countable flag option.
255
    The assigned command handler throws an exception if the flag count is not equal to 3.
256
    Then it calls that command with the flag multiplied 3 times.
257
258
    It is asserted, that the first call returns 0, thus proving that flag count was passed correctly to the handler,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (116/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
259
    otherwise it would have thrown an exception resulting in exit code -1 from the CliRunner.
260
    """
261
    def _test_command(*args, **kwargs):
262
        print(args)
263
        print(kwargs)
264
        assert kwargs['flag'] == 3
265
266
    plugin = basicApp.plugins.get("CommandPlugin")
267
    plugin.commands.unregister("test")
268
    # register a command with a countable flag
269
    plugin.commands.register("test", "my test command", _test_command, params=[Option(["-f", "--flag"], count=True)])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (117/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
270
271
    # call command with --fff -> count == 3 is asserted in the command handler
272
    result = CliRunner().invoke(basicApp.commands.get("test").click_command, ['-fff'])
273
    assert result.exit_code == 0
274