Files
temp/features/steps/sandbox_protocol_coverage_boost_steps.py
freemo a808c395f9 test(coverage): add Behave BDD tests to improve unit test coverage across 53 source modules
Add 53 new .feature files and corresponding step definition files targeting
uncovered lines identified in build/coverage.xml. Fix AmbiguousStep conflicts
in 7 pre-existing step files by disambiguating step text.

New tests cover: ACP clients/facade, actor CLI/config, application container,
ACMS service/strategies, async worker, automation profile CLI, autonomy
guardrail, bridge, change model, config CLI/service, context service,
cross-plan correction, database models, decision service, decomposition
clustering/service, discovery handler, langchain chat provider, langgraph
nodes, materializers, multi-project service, plan apply/CLI/lifecycle/model/
preflight/resume/service, PostgreSQL analyzer, project CLI/context CLI,
provider registry, reactive application/route, repositories, resolver handler,
resource registry service, resume model, retry patterns, sandbox protocol,
server CLI, skill CLI/service, skills registry, subplan execution/service,
system CLI, UKO loader, UoW, and YAML template engine.

Closes #645
2026-03-09 13:01:58 -04:00

141 lines
4.6 KiB
Python

"""Step definitions for sandbox protocol coverage boost.
Targets uncovered lines in src/cleveragents/infrastructure/sandbox/protocol.py:
- Lines 121-123: SandboxStatus.assert_transition raising SandboxStateError
- Lines 223, 228, 233, 248, 263, 278, 290, 301: Sandbox Protocol default stubs
All steps use the ``spcb`` prefix to avoid collisions with other step files.
"""
from behave import given, then, when
from behave.runner import Context
from cleveragents.infrastructure.sandbox.protocol import (
Sandbox,
SandboxStateError,
SandboxStatus,
)
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
class _BareSandbox(Sandbox):
"""Minimal subclass that inherits all Protocol default stubs."""
pass
# ---------------------------------------------------------------------------
# Given steps
# ---------------------------------------------------------------------------
@given('spcb sandbox status "{from_status}" and target status "{to_status}"')
def step_given_spcb_statuses(
context: Context, from_status: str, to_status: str
) -> None:
context.spcb_from_status = SandboxStatus(from_status)
context.spcb_to_status = SandboxStatus(to_status)
context.spcb_raised = None
@given("spcb a bare Sandbox protocol subclass instance")
def step_given_spcb_bare_sandbox(context: Context) -> None:
context.spcb_bare = _BareSandbox()
context.spcb_result = None
context.spcb_raised = None
# ---------------------------------------------------------------------------
# When steps
# ---------------------------------------------------------------------------
@when("spcb assert_transition is called with those statuses")
def step_when_spcb_assert_transition(context: Context) -> None:
try:
SandboxStatus.assert_transition(
context.spcb_from_status, context.spcb_to_status
)
context.spcb_raised = None
except SandboxStateError as exc:
context.spcb_raised = exc
@when("spcb the sandbox_id property is accessed")
def step_when_spcb_sandbox_id(context: Context) -> None:
context.spcb_result = context.spcb_bare.sandbox_id
@when("spcb the status property is accessed")
def step_when_spcb_status(context: Context) -> None:
context.spcb_result = context.spcb_bare.status
@when("spcb the context property is accessed")
def step_when_spcb_context(context: Context) -> None:
context.spcb_result = context.spcb_bare.context
@when('spcb the create method is called with plan_id "{plan_id}"')
def step_when_spcb_create(context: Context, plan_id: str) -> None:
context.spcb_result = context.spcb_bare.create(plan_id)
@when('spcb the get_path method is called with path "{path}"')
def step_when_spcb_get_path(context: Context, path: str) -> None:
context.spcb_result = context.spcb_bare.get_path(path)
@when('spcb the commit method is called with message "{message}"')
def step_when_spcb_commit(context: Context, message: str) -> None:
context.spcb_result = context.spcb_bare.commit(message)
@when("spcb the rollback method is called")
def step_when_spcb_rollback(context: Context) -> None:
context.spcb_result = context.spcb_bare.rollback()
@when("spcb the cleanup method is called")
def step_when_spcb_cleanup(context: Context) -> None:
context.spcb_result = context.spcb_bare.cleanup()
# ---------------------------------------------------------------------------
# Then steps
# ---------------------------------------------------------------------------
@then("spcb a SandboxStateError should be raised")
def step_then_spcb_state_error(context: Context) -> None:
assert context.spcb_raised is not None, (
"Expected SandboxStateError but no exception was raised"
)
assert isinstance(context.spcb_raised, SandboxStateError), (
f"Expected SandboxStateError but got {type(context.spcb_raised).__name__}"
)
@then('spcb the error message should contain "{fragment}"')
def step_then_spcb_error_message_contains(context: Context, fragment: str) -> None:
assert context.spcb_raised is not None, "No exception was raised"
msg = str(context.spcb_raised)
assert fragment in msg, f"Expected '{fragment}' in error message, got: {msg}"
@then("spcb no exception should be raised")
def step_then_spcb_no_exception(context: Context) -> None:
assert context.spcb_raised is None, (
f"Expected no exception but got: {context.spcb_raised}"
)
@then("spcb the result should be None")
def step_then_spcb_result_none(context: Context) -> None:
assert context.spcb_result is None, (
f"Expected None but got: {context.spcb_result!r}"
)