421a664336
- Remove legacy provider profiles, admin-token auth, /model command, model picker widget, and config.yaml LLM fields (design doc section 10) - Wire CLI/channels/cron and async sub-agents through the local snapshot entry; run creation rejects model config outside runtime_snapshot_id - Add periodic run-snapshot TTL cleanup to the config service lifespan - Isolate tests from the real config dir and activate the registry where run/model paths fail closed in bootstrap Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
114 lines
4.5 KiB
Python
114 lines
4.5 KiB
Python
"""Tests for CLI SlashCommandCompleter (prompt_toolkit adapter)."""
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
from EvoScientist.cli.interactive import SlashCommandCompleter
|
|
|
|
|
|
def _doc(text: str):
|
|
"""Create a minimal prompt_toolkit Document stub."""
|
|
doc = MagicMock()
|
|
doc.text_before_cursor = text
|
|
return doc
|
|
|
|
|
|
class TestSlashCommandCompleter:
|
|
"""Verify that ``SlashCommandCompleter.get_completions`` correctly
|
|
delegates to the shared ``compute_completions`` engine and translates
|
|
candidates into prompt_toolkit ``Completion`` objects.
|
|
"""
|
|
|
|
def test_top_level_slash_shows_commands(self):
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("/he"), None))
|
|
texts = {c.text for c in completions}
|
|
assert "/help" in texts
|
|
|
|
def test_exact_command_no_space_hides(self):
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("/help"), None))
|
|
assert completions == []
|
|
|
|
def test_exact_command_hides_even_when_prefix_of_another(self):
|
|
"""Regression for #293: an exact command match must hide the popup so
|
|
Enter submits it, even when another command shares the prefix. Before
|
|
the fix the popup stayed visible (two prefix matches) and the TUI's
|
|
Enter handler completed the text instead of executing the command.
|
|
|
|
A temporary stub command recreates the prefix-sibling scenario
|
|
against the existing ``/help`` command.
|
|
"""
|
|
from EvoScientist.commands.base import Command
|
|
from EvoScientist.commands.manager import manager
|
|
|
|
class _StubCommand(Command):
|
|
name = "/help-extra"
|
|
description = "stub"
|
|
|
|
async def execute(self, ctx, args):
|
|
return None
|
|
|
|
manager.register(_StubCommand())
|
|
try:
|
|
completer = SlashCommandCompleter()
|
|
# Sanity: both commands share the prefix, so a partial prefix lists both.
|
|
partial = {c.text for c in completer.get_completions(_doc("/hel"), None)}
|
|
assert {"/help", "/help-extra"} <= partial
|
|
# Exact ``/help`` with no trailing space → hide.
|
|
completions = list(completer.get_completions(_doc("/help"), None))
|
|
assert completions == []
|
|
finally:
|
|
manager._commands.pop("/help-extra", None)
|
|
|
|
def test_non_slash_returns_empty(self):
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("hello"), None))
|
|
assert completions == []
|
|
|
|
def test_trailing_space_shows_subcommands(self):
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("/mcp "), None))
|
|
texts = {c.text for c in completions}
|
|
assert "list" in texts
|
|
assert "add" in texts
|
|
|
|
def test_subcommand_prefix_filters(self):
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("/mcp lis"), None))
|
|
texts = {c.text for c in completions}
|
|
assert texts == {"list"}
|
|
|
|
def test_exact_subcommand_hides(self):
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("/mcp list"), None))
|
|
assert completions == []
|
|
|
|
def test_results_match_engine_order(self):
|
|
"""Completer preserves the category-based order from compute_completions."""
|
|
from EvoScientist.commands._completion_engine import compute_completions
|
|
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("/"), None))
|
|
engine_result = compute_completions("/", 1)
|
|
assert [c.text for c in completions] == [
|
|
c.text for c in engine_result.candidates
|
|
]
|
|
|
|
def test_display_meta_is_description(self):
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("/he"), None))
|
|
for c in completions:
|
|
if c.text == "/help":
|
|
assert c.display_meta is not None
|
|
|
|
def test_subcommand_completions_match_engine_order(self):
|
|
"""Subcommand completions preserve the order from compute_completions."""
|
|
from EvoScientist.commands._completion_engine import compute_completions
|
|
|
|
completer = SlashCommandCompleter()
|
|
completions = list(completer.get_completions(_doc("/mcp "), None))
|
|
engine_result = compute_completions("/mcp ", 5)
|
|
assert [c.text for c in completions] == [
|
|
c.text for c in engine_result.candidates
|
|
]
|