7ed9c1279f
CI / push-validation (pull_request) Successful in 33s
CI / helm (pull_request) Successful in 36s
CI / lint (pull_request) Successful in 44s
CI / quality (pull_request) Successful in 51s
CI / build (pull_request) Successful in 47s
CI / typecheck (pull_request) Successful in 1m10s
CI / security (pull_request) Successful in 1m27s
CI / unit_tests (pull_request) Successful in 6m15s
CI / docker (pull_request) Successful in 1m46s
CI / integration_tests (pull_request) Successful in 9m40s
CI / coverage (pull_request) Successful in 8m29s
CI / status-check (pull_request) Successful in 3s
- Replace deprecated typing imports (Dict, Callable, Generic) with
collections.abc.Callable and built-in dict
- Convert Command from ABC to plain base class (B024: no abstract methods)
- Convert CommandHandler to PEP 695 type parameter syntax (UP046)
- Remove unused PlanService/ProjectService imports from command_registry
- Fix ruff format: blank line before nested defs in command_registry and steps
- Rename @then('a ValueError should be raised') to domain-specific suffix
to avoid AmbiguousStep collision with lsp_registry_steps.py
ISSUES CLOSED: #8880
208 lines
5.7 KiB
Python
208 lines
5.7 KiB
Python
"""Step definitions for CLI command bus decoupling tests."""
|
|
|
|
from behave import given, when, then
|
|
from cleveragents.cli.command_bus import (
|
|
Command,
|
|
CommandBus,
|
|
get_command_bus,
|
|
set_command_bus,
|
|
)
|
|
|
|
|
|
class TestCommand(Command):
|
|
"""Test command for BDD tests."""
|
|
|
|
def __init__(self, value: str = "test") -> None:
|
|
"""Initialize test command."""
|
|
self.value = value
|
|
|
|
|
|
@given("the command bus is initialized")
|
|
def step_command_bus_initialized(context):
|
|
"""Initialize a fresh command bus."""
|
|
context.bus = CommandBus()
|
|
|
|
|
|
@given("no handlers are registered")
|
|
def step_no_handlers_registered(context):
|
|
"""Ensure no handlers are registered."""
|
|
if not hasattr(context, "bus"):
|
|
context.bus = CommandBus()
|
|
|
|
|
|
@when("I create a new command bus")
|
|
def step_create_command_bus(context):
|
|
"""Create a new command bus."""
|
|
context.bus = CommandBus()
|
|
|
|
|
|
@then("the command bus should be empty")
|
|
def step_bus_is_empty(context):
|
|
"""Verify the command bus is empty."""
|
|
assert isinstance(context.bus, CommandBus)
|
|
|
|
|
|
@then("no handlers should be registered")
|
|
def step_no_handlers_registered_check(context):
|
|
"""Verify no handlers are registered."""
|
|
assert not context.bus.has_handler(TestCommand)
|
|
|
|
|
|
@given("a command bus")
|
|
def step_given_command_bus(context):
|
|
"""Given a command bus."""
|
|
context.bus = CommandBus()
|
|
|
|
|
|
@when("I register a handler for a command type")
|
|
def step_register_handler(context):
|
|
"""Register a handler for a command type."""
|
|
|
|
def handler(cmd: TestCommand) -> str:
|
|
return f"Handled: {cmd.value}"
|
|
|
|
context.bus.register_handler(TestCommand, handler)
|
|
context.handler = handler
|
|
|
|
|
|
@then("the handler should be registered")
|
|
def step_handler_registered(context):
|
|
"""Verify the handler is registered."""
|
|
assert context.bus.has_handler(TestCommand)
|
|
|
|
|
|
@then("the command bus should have the handler")
|
|
def step_bus_has_handler(context):
|
|
"""Verify the bus has the handler."""
|
|
assert context.bus.has_handler(TestCommand)
|
|
|
|
|
|
@given("a command bus with a registered handler")
|
|
def step_bus_with_handler(context):
|
|
"""Given a command bus with a registered handler."""
|
|
context.bus = CommandBus()
|
|
|
|
def handler(cmd: TestCommand) -> str:
|
|
return f"Handled: {cmd.value}"
|
|
|
|
context.bus.register_handler(TestCommand, handler)
|
|
|
|
|
|
@when("I dispatch a command")
|
|
def step_dispatch_command(context):
|
|
"""Dispatch a command."""
|
|
context.command = TestCommand("test_value")
|
|
context.result = context.bus.dispatch(context.command)
|
|
|
|
|
|
@then("the handler should be invoked")
|
|
def step_handler_invoked(context):
|
|
"""Verify the handler was invoked."""
|
|
assert context.result is not None
|
|
|
|
|
|
@then("the result should be returned")
|
|
def step_result_returned(context):
|
|
"""Verify the result was returned."""
|
|
assert context.result == "Handled: test_value"
|
|
|
|
|
|
@given("a command bus with no handlers")
|
|
def step_bus_no_handlers(context):
|
|
"""Given a command bus with no handlers."""
|
|
context.bus = CommandBus()
|
|
|
|
|
|
@when("I dispatch a command without a registered handler")
|
|
def step_dispatch_unregistered(context):
|
|
"""Dispatch a command without a registered handler."""
|
|
context.command = TestCommand()
|
|
try:
|
|
context.bus.dispatch(context.command)
|
|
context.error_raised = False
|
|
except ValueError as e:
|
|
context.error_raised = True
|
|
context.error = e
|
|
|
|
|
|
@then("a ValueError should be raised for unregistered command dispatch")
|
|
def step_value_error_raised(context):
|
|
"""Verify a ValueError was raised."""
|
|
assert context.error_raised
|
|
|
|
|
|
@then("the error message should mention the command type")
|
|
def step_error_message_check(context):
|
|
"""Verify the error message mentions the command type."""
|
|
assert "TestCommand" in str(context.error)
|
|
|
|
|
|
@when("I check if a handler exists for a command type")
|
|
def step_check_handler_exists(context):
|
|
"""Check if a handler exists."""
|
|
context.bus = CommandBus()
|
|
|
|
def handler(cmd: TestCommand) -> str:
|
|
return "handled"
|
|
|
|
context.bus.register_handler(TestCommand, handler)
|
|
context.has_handler = context.bus.has_handler(TestCommand)
|
|
context.has_other = context.bus.has_handler(Command)
|
|
|
|
|
|
@then("the result should be accurate")
|
|
def step_result_accurate(context):
|
|
"""Verify the result is accurate."""
|
|
assert context.has_handler is True
|
|
|
|
|
|
@then("reflect the registration status")
|
|
def step_reflect_status(context):
|
|
"""Verify it reflects the registration status."""
|
|
assert context.has_other is False
|
|
|
|
|
|
@when("I get the global command bus")
|
|
def step_get_global_bus(context):
|
|
"""Get the global command bus."""
|
|
context.bus1 = get_command_bus()
|
|
|
|
|
|
@then("I should receive a CommandBus instance")
|
|
def step_receive_bus_instance(context):
|
|
"""Verify we received a CommandBus instance."""
|
|
assert isinstance(context.bus1, CommandBus)
|
|
|
|
|
|
@then("subsequent calls should return the same instance")
|
|
def step_same_instance(context):
|
|
"""Verify subsequent calls return the same instance."""
|
|
context.bus2 = get_command_bus()
|
|
assert context.bus1 is context.bus2
|
|
|
|
|
|
@given("a new command bus")
|
|
def step_new_command_bus(context):
|
|
"""Create a new command bus."""
|
|
context.new_bus = CommandBus()
|
|
|
|
|
|
@when("I set it as the global command bus")
|
|
def step_set_global_bus(context):
|
|
"""Set it as the global command bus."""
|
|
set_command_bus(context.new_bus)
|
|
|
|
|
|
@then("subsequent calls to get_command_bus should return it")
|
|
def step_get_returns_set_bus(context):
|
|
"""Verify get_command_bus returns the set bus."""
|
|
retrieved = get_command_bus()
|
|
assert retrieved is context.new_bus
|
|
|
|
|
|
@then("the previous instance should be replaced")
|
|
def step_previous_replaced(context):
|
|
"""Verify the previous instance was replaced."""
|
|
# This is implicitly verified by the previous step
|
|
pass
|