vibe/tests/cli/test_commands.py
Guillaume LE GOFF cafb6d4147
v2.15.0 (#773)
Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com>
Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai>
Co-authored-by: Maxime Dolores <maxime.dolores@ext.mistral.ai>
Co-authored-by: Nelson PROIA <144663685+Nelson-PROIA@users.noreply.github.com>
Co-authored-by: Paul VEZIA <166131032+le-codeur-rapide@users.noreply.github.com>
Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai>
Co-authored-by: Quentin <quentin.torroba@mistral.ai>
Co-authored-by: Val <102326092+vdeva@users.noreply.github.com>
Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
2026-06-12 13:16:04 +02:00

190 lines
8.2 KiB
Python

from __future__ import annotations
from vibe.cli.commands import Command, CommandAvailabilityContext, CommandRegistry
from vibe.cli.plan_offer.decide_plan_offer import PlanInfo
from vibe.cli.plan_offer.ports.whoami_gateway import WhoAmIPlanType
def _eligible_teleport_context() -> CommandAvailabilityContext:
return CommandAvailabilityContext(
vibe_code_enabled=True,
is_active_model_mistral=True,
plan_info=PlanInfo(
plan_type=WhoAmIPlanType.CHAT,
plan_name="INDIVIDUAL",
prompt_switching_to_pro_plan=False,
),
)
class TestCommandRegistry:
def test_get_command_name_returns_canonical_name_for_alias(self) -> None:
registry = CommandRegistry()
assert registry.get_command_name("/help") == "help"
assert registry.get_command_name("/config") == "config"
assert registry.get_command_name("/model") == "model"
assert registry.get_command_name("/connectors") == "mcp"
assert registry.get_command_name("/clear") == "clear"
assert registry.get_command_name("/exit") == "exit"
assert registry.get_command_name("/data-retention") == "data-retention"
def test_get_command_name_normalizes_input(self) -> None:
registry = CommandRegistry()
assert registry.get_command_name(" /help ") == "help"
assert registry.get_command_name("/HELP") == "help"
def test_get_command_name_returns_none_for_unknown(self) -> None:
registry = CommandRegistry()
assert registry.get_command_name("/unknown") is None
assert registry.get_command_name("hello") is None
assert registry.get_command_name("") is None
def test_parse_command_returns_command_when_alias_matches(self) -> None:
registry = CommandRegistry()
result = registry.parse_command("/help")
assert result is not None
cmd_name, cmd, cmd_args = result
assert cmd_name == "help"
assert cmd.handler == "_show_help"
assert isinstance(cmd, Command)
assert cmd_args == ""
def test_parse_command_returns_none_when_no_match(self) -> None:
registry = CommandRegistry()
assert registry.parse_command("/nonexistent") is None
def test_parse_command_uses_get_command_name(self) -> None:
"""parse_command and get_command_name stay in sync for same input."""
registry = CommandRegistry()
for alias in ["/help", "/config", "/clear", "/exit"]:
cmd_name = registry.get_command_name(alias)
result = registry.parse_command(alias)
if cmd_name is None:
assert result is None
else:
assert result is not None
found_name, found_cmd, _ = result
assert found_name == cmd_name
assert registry.commands[cmd_name] is found_cmd
def test_excluded_commands_not_in_registry(self) -> None:
registry = CommandRegistry(excluded_commands=["exit"])
assert registry.get_command_name("/exit") is None
assert registry.parse_command("/exit") is None
assert registry.get_command_name("/help") == "help"
def test_teleport_command_hidden_without_eligible_context(self) -> None:
registry = CommandRegistry()
assert registry.get_command_name("/teleport") is None
assert registry.parse_command("/teleport") is None
def test_teleport_command_registration_uses_resolved_context(self) -> None:
registry = CommandRegistry(availability_context=_eligible_teleport_context())
assert registry.get_command_name("/teleport") == "teleport"
assert registry.has_command("teleport")
def test_teleport_help_text_uses_resolved_context(self) -> None:
registry = CommandRegistry()
assert "/teleport" not in registry.get_help_text()
eligible_registry = CommandRegistry(
availability_context=_eligible_teleport_context()
)
assert eligible_registry.get("teleport") is not None
assert "/teleport" in eligible_registry.get_help_text()
def test_resume_command_registration(self) -> None:
registry = CommandRegistry()
assert registry.get_command_name("/resume") == "resume"
assert registry.get_command_name("/continue") == "resume"
result = registry.parse_command("/resume")
assert result is not None
_, cmd, _ = result
assert cmd.handler == "_show_session_picker"
assert cmd.description == "Browse, resume, or delete saved sessions"
def test_rename_command_registration(self) -> None:
registry = CommandRegistry()
assert registry.get_command_name("/rename") == "rename"
assert registry.get_command_name("/title") is None
result = registry.parse_command("/rename Better title")
assert result is not None
_, cmd, cmd_args = result
assert cmd.handler == "_rename_session"
assert cmd_args == "Better title"
def test_parse_command_keeps_args_for_no_arg_commands(self) -> None:
registry = CommandRegistry()
result = registry.parse_command("/help extra")
assert result == ("help", registry.commands["help"], "extra")
def test_parse_command_keeps_args_for_argument_commands(self) -> None:
registry = CommandRegistry()
result = registry.parse_command("/mcp filesystem")
assert result == ("mcp", registry.commands["mcp"], "filesystem")
def test_parse_command_maps_connector_alias_to_mcp(self) -> None:
registry = CommandRegistry()
result = registry.parse_command("/connectors filesystem")
assert result == ("mcp", registry.commands["mcp"], "filesystem")
def test_data_retention_command_registration(self) -> None:
registry = CommandRegistry()
result = registry.parse_command("/data-retention")
assert result is not None
_, cmd, _ = result
assert cmd.handler == "_show_data_retention"
def test_loop_command_registration(self) -> None:
registry = CommandRegistry()
assert registry.get_command_name("/loop") == "loop"
result = registry.parse_command("/loop 30s ping")
assert result is not None
cmd_name, cmd, cmd_args = result
assert cmd_name == "loop"
assert cmd.handler == "_loop_command"
assert cmd_args == "30s ping"
def test_exit_command_accepts_bare_synonyms(self) -> None:
registry = CommandRegistry()
for alias in ["/exit", "exit", "quit", ":q", ":quit"]:
assert registry.get_command_name(alias) == "exit", alias
result = registry.parse_command(alias)
assert result is not None, alias
cmd_name, cmd, _ = result
assert cmd_name == "exit"
assert cmd.handler == "_exit_app"
assert cmd.exits is True
def test_bare_exit_synonym_with_trailing_text_is_not_a_command(self) -> None:
registry = CommandRegistry()
assert registry.parse_command("exit the function early") is None
assert registry.parse_command("quit your job") is None
def test_bare_exit_synonym_in_multiline_message_is_not_a_command(self) -> None:
registry = CommandRegistry()
assert registry.parse_command("exit\nplease refactor this module") is None
def test_slash_exit_still_parses_with_trailing_text(self) -> None:
registry = CommandRegistry()
result = registry.parse_command("/exit now")
assert result is not None
cmd_name, _, cmd_args = result
assert cmd_name == "exit"
assert cmd_args == "now"
def test_exit_command_synonyms_are_case_insensitive(self) -> None:
registry = CommandRegistry()
for alias in ["EXIT", "Quit", " exit ", ":Q"]:
assert registry.get_command_name(alias) == "exit", alias
def test_exit_synonyms_excluded_when_command_disabled(self) -> None:
registry = CommandRegistry(excluded_commands=["exit"])
for alias in ["/exit", "exit", "quit", ":q", ":quit"]:
assert registry.get_command_name(alias) is None, alias
def test_help_text_lists_exit_synonyms(self) -> None:
registry = CommandRegistry()
help_text = registry.get_help_text()
for alias in ["`/exit`", "`exit`", "`quit`", "`:q`", "`:quit`"]:
assert alias in help_text, alias