Skip to content

Commit 27b1093

Browse files
committed
Added tests for invalid subcommands
1 parent dddf868 commit 27b1093

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

tests/test_argparse.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ def do_preservelist(self, arglist):
9292
known_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
9393
known_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
9494
known_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
95+
9596
@cmd2.with_argparser(known_parser, with_unknown_args=True)
9697
def do_speak(self, args, extra, *, keyword_arg: Optional[str] = None):
9798
"""Repeat what you tell me to."""
@@ -131,89 +132,108 @@ def test_invalid_syntax(argparse_app):
131132
out, err = run_cmd(argparse_app, 'speak "')
132133
assert err[0] == "Invalid syntax: No closing quotation"
133134

135+
134136
def test_argparse_basic_command(argparse_app):
135137
out, err = run_cmd(argparse_app, 'say hello')
136138
assert out == ['hello']
137139

140+
138141
def test_argparse_remove_quotes(argparse_app):
139142
out, err = run_cmd(argparse_app, 'say "hello there"')
140143
assert out == ['hello there']
141144

145+
142146
def test_argparser_kwargs(argparse_app, capsys):
143147
"""Test with_argparser wrapper passes through kwargs to command function"""
144148
argparse_app.do_say('word', keyword_arg="foo")
145149
out, err = capsys.readouterr()
146150
assert out == "foo\n"
147151

152+
148153
def test_argparse_preserve_quotes(argparse_app):
149154
out, err = run_cmd(argparse_app, 'tag mytag "hello"')
150155
assert out[0] == '<mytag>"hello"</mytag>'
151156

157+
152158
def test_argparse_custom_namespace(argparse_app):
153159
out, err = run_cmd(argparse_app, 'test_argparse_ns')
154160
assert out[0] == 'custom'
155161

162+
156163
def test_argparse_with_list(argparse_app):
157164
out, err = run_cmd(argparse_app, 'speak -s hello world!')
158165
assert out == ['HELLO WORLD!']
159166

167+
160168
def test_argparse_with_list_remove_quotes(argparse_app):
161169
out, err = run_cmd(argparse_app, 'speak -s hello "world!"')
162170
assert out == ['HELLO WORLD!']
163171

172+
164173
def test_argparse_with_list_preserve_quotes(argparse_app):
165174
out, err = run_cmd(argparse_app, 'test_argparse_with_list_quotes "hello" person')
166175
assert out[0] == '"hello" person'
167176

177+
168178
def test_argparse_with_list_custom_namespace(argparse_app):
169179
out, err = run_cmd(argparse_app, 'test_argparse_with_list_ns')
170180
assert out[0] == 'custom'
171181

182+
172183
def test_argparse_with_list_and_empty_doc(argparse_app):
173184
out, err = run_cmd(argparse_app, 'speak -s hello world!')
174185
assert out == ['HELLO WORLD!']
175186

187+
176188
def test_argparser_correct_args_with_quotes_and_midline_options(argparse_app):
177189
out, err = run_cmd(argparse_app, "speak 'This is a' -s test of the emergency broadcast system!")
178190
assert out == ['THIS IS A TEST OF THE EMERGENCY BROADCAST SYSTEM!']
179191

192+
180193
def test_argparser_and_unknown_args_kwargs(argparse_app, capsys):
181194
"""Test with_argparser_and_unknown_args wrapper passes through kwargs to command function"""
182195
argparse_app.do_speak('', keyword_arg="foo")
183196
out, err = capsys.readouterr()
184197
assert out == "foo\n"
185198

199+
186200
def test_argparse_quoted_arguments_multiple(argparse_app):
187201
out, err = run_cmd(argparse_app, 'say "hello there" "rick & morty"')
188202
assert out == ['hello there rick & morty']
189203

204+
190205
def test_argparse_help_docstring(argparse_app):
191206
out, err = run_cmd(argparse_app, 'help say')
192207
assert out[0].startswith('usage: say')
193208
assert out[1] == ''
194209
assert out[2] == 'Repeat what you tell me to.'
195210

211+
196212
def test_argparse_help_description(argparse_app):
197213
out, err = run_cmd(argparse_app, 'help tag')
198214
assert out[0].startswith('usage: tag')
199215
assert out[1] == ''
200216
assert out[2] == 'create a html tag'
201217

218+
202219
def test_argparse_prog(argparse_app):
203220
out, err = run_cmd(argparse_app, 'help tag')
204221
progname = out[0].split(' ')[1]
205222
assert progname == 'tag'
206223

224+
207225
def test_arglist(argparse_app):
208226
out, err = run_cmd(argparse_app, 'arglist "we should" get these')
209227
assert out[0] == 'True'
210228

229+
211230
def test_arglist_kwargs(argparse_app, capsys):
212231
"""Test with_argument_list wrapper passes through kwargs to command function"""
213232
argparse_app.do_arglist('arg', keyword_arg="foo")
214233
out, err = capsys.readouterr()
215234
assert out == "foo\n"
216235

236+
217237
def test_preservelist(argparse_app):
218238
out, err = run_cmd(argparse_app, 'preservelist foo "bar baz"')
219239
assert out[0] == "['foo', '\"bar baz\"']"
@@ -269,6 +289,7 @@ def do_base(self, args):
269289
func = getattr(args, 'func')
270290
func(self, args)
271291

292+
272293
@pytest.fixture
273294
def subcommand_app():
274295
app = SubcommandApp()
@@ -284,17 +305,20 @@ def test_subcommand_bar(subcommand_app):
284305
out, err = run_cmd(subcommand_app, 'base bar baz')
285306
assert out == ['((baz))']
286307

308+
287309
def test_subcommand_invalid(subcommand_app):
288310
out, err = run_cmd(subcommand_app, 'base baz')
289311
assert err[0].startswith('usage: base')
290312
assert err[1].startswith("base: error: argument SUBCOMMAND: invalid choice: 'baz'")
291313

314+
292315
def test_subcommand_base_help(subcommand_app):
293316
out, err = run_cmd(subcommand_app, 'help base')
294317
assert out[0].startswith('usage: base')
295318
assert out[1] == ''
296319
assert out[2] == 'Base command help'
297320

321+
298322
def test_subcommand_help(subcommand_app):
299323
# foo has no aliases
300324
out, err = run_cmd(subcommand_app, 'help base foo')
@@ -334,14 +358,53 @@ def test_subcommand_help(subcommand_app):
334358
assert out[1] == ''
335359
assert out[2] == 'positional arguments:'
336360

361+
337362
def test_subcommand_invalid_help(subcommand_app):
338363
out, err = run_cmd(subcommand_app, 'help base baz')
339364
assert out[0].startswith('usage: base')
340365

366+
341367
def test_add_another_subcommand(subcommand_app):
342368
"""
343369
This tests makes sure _set_parser_prog() sets _prog_prefix on every _SubParsersAction so that all future calls
344370
to add_parser() write the correct prog value to the parser being added.
345371
"""
346372
new_parser = subcommand_app.base_subparsers.add_parser('new_sub', help="stuff")
347373
assert new_parser.prog == "base new_sub"
374+
375+
376+
def test_unittest_mock():
377+
from unittest import mock
378+
from cmd2 import CommandSetRegistrationError
379+
380+
with mock.patch.object(ArgparseApp, 'namespace_provider'):
381+
with pytest.raises(CommandSetRegistrationError):
382+
app = ArgparseApp()
383+
384+
with mock.patch.object(ArgparseApp, 'namespace_provider', spec=True):
385+
app = ArgparseApp()
386+
387+
with mock.patch.object(ArgparseApp, 'namespace_provider', spec_set=True):
388+
app = ArgparseApp()
389+
390+
with mock.patch.object(ArgparseApp, 'namespace_provider', autospec=True):
391+
app = ArgparseApp()
392+
393+
394+
def test_pytest_mock_invalid(mocker):
395+
from cmd2 import CommandSetRegistrationError
396+
397+
mocker.patch.object(ArgparseApp, 'namespace_provider')
398+
with pytest.raises(CommandSetRegistrationError):
399+
app = ArgparseApp()
400+
401+
402+
@pytest.mark.parametrize('spec_param', [
403+
{'spec': True},
404+
{'spec_set': True},
405+
{'autospec': True},
406+
])
407+
def test_pytest_mock_valid(mocker, spec_param):
408+
mocker.patch.object(ArgparseApp, 'namespace_provider', **spec_param)
409+
app = ArgparseApp()
410+

tests_isolated/test_commandset/test_commandset.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,3 +844,30 @@ def test_path_complete(command_sets_manual):
844844
first_match = complete_tester(text, line, begidx, endidx, command_sets_manual)
845845

846846
assert first_match is not None
847+
848+
849+
def test_bad_subcommand():
850+
class BadSubcommandApp(cmd2.Cmd):
851+
"""Class for testing usage of `as_subcommand_to` decorator directly in a Cmd2 subclass."""
852+
853+
def __init__(self, *args, **kwargs):
854+
super(BadSubcommandApp, self).__init__(*args, **kwargs)
855+
856+
cut_parser = cmd2.Cmd2ArgumentParser('cut')
857+
cut_subparsers = cut_parser.add_subparsers(title='item', help='item to cut')
858+
859+
@cmd2.with_argparser(cut_parser)
860+
def do_cut(self, ns: argparse.Namespace):
861+
"""Cut something"""
862+
pass
863+
864+
banana_parser = cmd2.Cmd2ArgumentParser(add_help=False)
865+
banana_parser.add_argument('direction', choices=['discs', 'lengthwise'])
866+
867+
@cmd2.as_subcommand_to('cut', 'bad name', banana_parser, help='This should fail')
868+
def cut_banana(self, ns: argparse.Namespace):
869+
"""Cut banana"""
870+
self.poutput('cutting banana: ' + ns.direction)
871+
872+
with pytest.raises(CommandSetRegistrationError):
873+
app = BadSubcommandApp()

0 commit comments

Comments
 (0)