Files
cleveragents-core/features/steps/tui_input_modes_steps.py
HAL9000 97f8f56468 fix(tui): resolve B009 getattr lint violation in test steps
Replace getattr(tui_app_module, '_strip_pending_reference_token')
with direct attribute access. Ruff B009 flags this as unnecessary
because the attribute is a compile-time constant — normal access
is equally safe and preferred.
2026-06-02 00:38:09 -04:00

163 lines
5.6 KiB
Python

"""Behave steps for TUI input mode router."""
from __future__ import annotations
import os
import shutil
import tempfile
from pathlib import Path
from unittest.mock import patch
from behave import given, then, when
from behave.runner import Context
from cleveragents.tui import app as tui_app_module
from cleveragents.tui.input import reference_parser
from cleveragents.tui.input.modes import InputModeRouter
from cleveragents.tui.input.reference_parser import parse_references, suggestions
from cleveragents.tui.input.shell_exec import looks_dangerous
@when('I parse TUI references for "{line}"')
def step_parse_references(context: Context, line: str) -> None:
context.tui_ref_result = parse_references(line)
@then('the parsed line should include "{token}"')
def step_parsed_contains(context: Context, token: str) -> None:
assert token in context.tui_ref_result.expanded_line
@when('I route TUI input "{line}"')
def step_route_input(context: Context, line: str) -> None:
router = InputModeRouter(command_handler=lambda raw: f"ok:/{raw}")
context.tui_mode_result = router.process(line)
@then('the TUI mode should be "{mode}"')
def step_mode_equals(context: Context, mode: str) -> None:
assert context.tui_mode_result.mode.value == mode
@then('the TUI command result should be "{value}"')
def step_command_result(context: Context, value: str) -> None:
assert context.tui_mode_result.command_result == value
@then('the TUI shell stdout should contain "{value}"')
def step_shell_stdout(context: Context, value: str) -> None:
shell = context.tui_mode_result.shell_result
assert shell is not None
assert value in shell.stdout
@then('the TUI shell stderr should contain "{value}"')
def step_shell_stderr(context: Context, value: str) -> None:
shell = context.tui_mode_result.shell_result
assert shell is not None
assert value in shell.stderr
@when('I check shell danger detection for "{command}"')
def step_check_shell_danger(context: Context, command: str) -> None:
context.shell_danger_result = looks_dangerous(command)
@then('shell danger detection result should be "{value}"')
def step_shell_danger_result(context: Context, value: str) -> None:
expected = value.strip().lower() == "true"
assert context.shell_danger_result is expected
@given("a deterministic TUI reference fixture")
def step_deterministic_tui_reference_fixture(context: Context) -> None:
fixture_dir = Path(tempfile.mkdtemp())
(fixture_dir / "README.md").write_text("# fixture\n", encoding="utf-8")
(fixture_dir / ".git").mkdir(exist_ok=True)
(fixture_dir / ".git" / "secret.txt").write_text("secret\n", encoding="utf-8")
context.tui_reference_fixture_dir = fixture_dir
context.add_cleanup(lambda: shutil.rmtree(str(fixture_dir), ignore_errors=True))
@when("I parse and suggest TUI references using fixture")
def step_parse_and_suggest_with_fixture(context: Context) -> None:
context.tui_walk_count = 0
context.tui_fixture_suggestions = []
reference_parser._catalog_cache["cwd"] = None
reference_parser._catalog_cache["created_at"] = 0.0
reference_parser._catalog_cache["catalog"] = None
real_walk = os.walk
def counting_walk(*args: object, **kwargs: object):
context.tui_walk_count += 1
return real_walk(*args, **kwargs)
with (
patch(
"cleveragents.tui.input.reference_parser.Path.cwd",
return_value=context.tui_reference_fixture_dir,
),
patch(
"cleveragents.tui.input.reference_parser.os.walk", side_effect=counting_walk
),
):
parse_references("inspect @README.md")
context.tui_fixture_suggestions = suggestions("secret", category="resource")
@then('TUI walk count should be "{count}"')
def step_tui_walk_count(context: Context, count: str) -> None:
assert context.tui_walk_count == int(count)
@then('TUI suggestions should not include "{value}"')
def step_tui_suggestions_not_include(context: Context, value: str) -> None:
assert all(
value not in suggestion for suggestion in context.tui_fixture_suggestions
)
@when("I check TUI app textual availability flag")
def step_check_tui_textual_availability(context: Context) -> None:
context.tui_textual_available = tui_app_module.textual_available()
@then("TUI textual availability should be boolean")
def step_tui_textual_is_bool(context: Context) -> None:
assert isinstance(context.tui_textual_available, bool)
@when("I run fallback TUI app")
def step_run_fallback_tui_app(context: Context) -> None:
context.tui_fallback_error = None
fallback = tui_app_module._FallbackCleverAgentsTuiApp(
command_router=object(), persona_state=object()
)
try:
fallback.run()
except RuntimeError as exc:
context.tui_fallback_error = exc
@then('fallback TUI app should fail with "{message}"')
def step_fallback_tui_fails(context: Context, message: str) -> None:
assert context.tui_fallback_error is not None
assert message in str(context.tui_fallback_error)
@given('a TUI prompt value "{value}"')
def step_set_tui_prompt_value(context: Context, value: str) -> None:
context.tui_prompt_value = value
@when("I clear pending TUI reference token via escape")
def step_clear_pending_reference(context: Context) -> None:
cleanup = tui_app_module._strip_pending_reference_token
assert callable(cleanup)
context.tui_prompt_value = cleanup(context.tui_prompt_value)
@then('the TUI prompt value should be "{expected}"')
def step_assert_tui_prompt_value(context: Context, expected: str) -> None:
assert context.tui_prompt_value == expected