Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from collections.abc import Callable
from contextlib import redirect_stderr
from typing import (
TYPE_CHECKING,
ParamSpec,
TextIO,
TypeVar,
Expand Down Expand Up @@ -164,3 +165,71 @@ def find_subcommand(action: argparse.ArgumentParser, subcmd_names: list[str]) ->
return find_subcommand(choice, subcmd_names)
break
raise ValueError(f"Could not find subcommand '{subcmd_names}'")


if TYPE_CHECKING:
_Base = cmd2.Cmd
else:
_Base = object


class ExternalTestMixin(_Base):
"""A cmd2 plugin (mixin class) that exposes an interface to execute application commands from python"""

def __init__(self, *args, **kwargs):
"""

:type self: cmd2.Cmd
:param args:
:param kwargs:
"""
# code placed here runs before cmd2 initializes
super().__init__(*args, **kwargs)
assert isinstance(self, cmd2.Cmd)
# code placed here runs after cmd2 initializes
self._pybridge = cmd2.py_bridge.PyBridge(self)

def app_cmd(self, command: str, echo: bool | None = None) -> cmd2.CommandResult:
"""
Run the application command

:param command: The application command as it would be written on the cmd2 application prompt
:param echo: Flag whether the command's output should be echoed to stdout/stderr
:return: A CommandResult object that captures stdout, stderr, and the command's result object
"""
assert isinstance(self, cmd2.Cmd)
assert isinstance(self, ExternalTestMixin)
try:
self._in_py = True

return self._pybridge(command, echo=echo)

finally:
self._in_py = False

def fixture_setup(self):
"""
Replicates the behavior of `cmdloop()` preparing the state of the application
:type self: cmd2.Cmd
"""

for func in self._preloop_hooks:
func()
self.preloop()

def fixture_teardown(self):
"""
Replicates the behavior of `cmdloop()` tearing down the application

:type self: cmd2.Cmd
"""
for func in self._postloop_hooks:
func()
self.postloop()


class WithCommandSets(ExternalTestMixin, cmd2.Cmd):
"""Class for testing custom help_* methods which override docstring help."""

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
Empty file.
Loading