Files
EvoScientist/tests/test_cli_completion.py
T
m4 57176b359a feat(runtime)!: switch middleware and agent factories to snapshot-driven models
Replace config.yaml-driven model selection with registry snapshot resolution
across the runtime chain:

- ConfigurableModelMiddleware reads configurable["runtime_snapshot_id"] only;
  model/model_provider overrides are rejected with MODEL_CONFIG_OUTSIDE_SNAPSHOT
- MessageBudgetMiddleware derives budgets from snapshot reserves
  (system/tools/attachments) and re-resolves the summarizer per snapshot
- Agent factory and subagent factory resolve models via SnapshotRuntime
  (auxiliary/tool_selector/scheduler -> defaults.auxiliary ?? defaults.primary)
- Remove ModelFallbackMiddleware, /model-fallback command, and fallback chain
- Add model_registry/runtime.py SnapshotRuntime glue layer

Legacy config.yaml LLM fields, /model command, and llm/models.py remain for
Task 7. Report: .superpowers/sdd/briefs/task-6-report.md
2026-07-21 12:54:35 +08:00

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: ``/model`` must hide on exact match 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.
The original prefix sibling (``/model-fallback``) was removed with
the fallback chain; a temporary stub command recreates the scenario.
"""
from EvoScientist.commands.base import Command
from EvoScientist.commands.manager import manager
class _StubCommand(Command):
name = "/model-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("/mode"), None)}
assert {"/model", "/model-extra"} <= partial
# Exact ``/model`` with no trailing space → hide.
completions = list(completer.get_completions(_doc("/model"), None))
assert completions == []
finally:
manager._commands.pop("/model-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
]