Skip to content

Commit 7be23d2

Browse files
committed
Added more tests.
1 parent d6a274c commit 7be23d2

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

tests/test_cmd2.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4419,3 +4419,75 @@ def test_auto_suggest_default():
44194419
"""Test that auto_suggest defaults to True."""
44204420
app = cmd2.Cmd()
44214421
assert isinstance(app.main_session.auto_suggest, AutoSuggestFromHistory)
4422+
4423+
4424+
def test_attach_subcommand() -> None:
4425+
import argparse
4426+
4427+
class SubcmdApp(cmd2.Cmd):
4428+
def __init__(self) -> None:
4429+
super().__init__()
4430+
4431+
root_parser = cmd2.Cmd2ArgumentParser()
4432+
root_parser.add_subparsers()
4433+
4434+
@cmd2.with_argparser(root_parser)
4435+
def do_root(self, _args: argparse.Namespace) -> None:
4436+
pass
4437+
4438+
app = SubcmdApp()
4439+
4440+
# Verify root exists and uses argparse
4441+
root_parser = app._command_parsers.get(app.do_root)
4442+
assert root_parser is not None
4443+
4444+
# Attach child to root
4445+
child_parser = cmd2.Cmd2ArgumentParser(prog="child")
4446+
child_parser.add_subparsers()
4447+
app.attach_subcommand("root", "child", child_parser, help="child help")
4448+
4449+
# Verify child was attached
4450+
root_subparsers_action = root_parser._get_subparsers_action()
4451+
assert "child" in root_subparsers_action._name_parser_map
4452+
assert root_subparsers_action._name_parser_map["child"] is child_parser
4453+
4454+
# Attach grandchild to child
4455+
grandchild_parser = cmd2.Cmd2ArgumentParser(prog="grandchild")
4456+
app.attach_subcommand("root child", "grandchild", grandchild_parser)
4457+
4458+
# Verify grandchild was attached
4459+
child_subparsers_action = child_parser._get_subparsers_action()
4460+
assert "grandchild" in child_subparsers_action._name_parser_map
4461+
4462+
# Detach grandchild
4463+
detached_grandchild = app.detach_subcommand("root child", "grandchild")
4464+
assert detached_grandchild is grandchild_parser
4465+
assert "grandchild" not in child_subparsers_action._name_parser_map
4466+
4467+
# Detach child
4468+
detached_child = app.detach_subcommand("root", "child")
4469+
assert detached_child is child_parser
4470+
assert "child" not in root_subparsers_action._name_parser_map
4471+
4472+
4473+
def test_attach_subcommand_errors() -> None:
4474+
class SubcmdErrorApp(cmd2.Cmd):
4475+
def __init__(self) -> None:
4476+
super().__init__()
4477+
4478+
def do_no_argparse(self, _statement: cmd2.Statement) -> None:
4479+
pass
4480+
4481+
app = SubcmdErrorApp()
4482+
4483+
# Test empty command
4484+
with pytest.raises(ValueError, match="Command path cannot be empty"):
4485+
app.attach_subcommand("", "sub", cmd2.Cmd2ArgumentParser())
4486+
4487+
# Test non-existent command
4488+
with pytest.raises(ValueError, match="Root command 'fake' not found"):
4489+
app.attach_subcommand("fake", "sub", cmd2.Cmd2ArgumentParser())
4490+
4491+
# Test command that doesn't use argparse
4492+
with pytest.raises(ValueError, match="Command 'no_argparse' does not use argparse"):
4493+
app.attach_subcommand("no_argparse", "sub", cmd2.Cmd2ArgumentParser())

0 commit comments

Comments
 (0)