forked from HAL9000/cleveragents-core
a808c395f9
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
166 lines
6.2 KiB
Python
166 lines
6.2 KiB
Python
"""Step definitions for application_container_coverage_boost.feature.
|
|
|
|
Targets the remaining uncovered lines in
|
|
``cleveragents.application.container``:
|
|
|
|
- Lines 187-195: ``_build_checkpoint_service`` function body
|
|
- Lines 204-211: ``_build_trace_service`` function body
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
from behave import given, then, when
|
|
|
|
from cleveragents.application.container import (
|
|
_build_checkpoint_service,
|
|
_build_trace_service,
|
|
reset_container,
|
|
)
|
|
from cleveragents.application.services.checkpoint_service import CheckpointService
|
|
from cleveragents.application.services.trace_service import TraceService
|
|
from cleveragents.infrastructure.database.llm_trace_repository import (
|
|
LLMTraceRepository,
|
|
)
|
|
from cleveragents.infrastructure.database.repositories import CheckpointRepository
|
|
|
|
_IN_MEMORY_URL = "sqlite:///:memory:"
|
|
|
|
|
|
# -------------------------------------------------------------------
|
|
# Background
|
|
# -------------------------------------------------------------------
|
|
|
|
|
|
@given("a clean container state for coverage boost tests")
|
|
def step_clean_container_state(context):
|
|
"""Reset the global container to avoid cross-test interference."""
|
|
reset_container()
|
|
|
|
|
|
# -------------------------------------------------------------------
|
|
# _build_checkpoint_service scenarios
|
|
# -------------------------------------------------------------------
|
|
|
|
|
|
@given("a mock plan lifecycle service")
|
|
def step_mock_plan_lifecycle_service(context):
|
|
"""Create a mock PlanLifecycleService for injection."""
|
|
context.boost_mock_lifecycle = MagicMock()
|
|
context.boost_mock_lifecycle.__class__.__name__ = "PlanLifecycleService"
|
|
|
|
|
|
@when("I build a checkpoint service with an in-memory database URL")
|
|
def step_build_checkpoint_service_default(context):
|
|
"""Call _build_checkpoint_service with only a database URL (no lifecycle)."""
|
|
context.boost_checkpoint_svc = _build_checkpoint_service(_IN_MEMORY_URL)
|
|
|
|
|
|
@when("I build a checkpoint service with the mock plan lifecycle service")
|
|
def step_build_checkpoint_service_with_lifecycle(context):
|
|
"""Call _build_checkpoint_service with a database URL and lifecycle service."""
|
|
context.boost_checkpoint_svc = _build_checkpoint_service(
|
|
_IN_MEMORY_URL,
|
|
plan_lifecycle_service=context.boost_mock_lifecycle,
|
|
)
|
|
|
|
|
|
@then("the result should be a CheckpointService instance")
|
|
def step_verify_checkpoint_service_type(context):
|
|
"""Assert the returned object is a CheckpointService."""
|
|
assert isinstance(context.boost_checkpoint_svc, CheckpointService), (
|
|
f"Expected CheckpointService, got {type(context.boost_checkpoint_svc).__name__}"
|
|
)
|
|
|
|
|
|
@then("the checkpoint service should have a repository")
|
|
def step_verify_checkpoint_has_repository(context):
|
|
"""Assert the service was initialised with a CheckpointRepository."""
|
|
repo = context.boost_checkpoint_svc._repository
|
|
assert repo is not None, "Expected a repository, got None"
|
|
assert isinstance(repo, CheckpointRepository), (
|
|
f"Expected CheckpointRepository, got {type(repo).__name__}"
|
|
)
|
|
|
|
|
|
@then("the checkpoint service should have no plan lifecycle service")
|
|
def step_verify_checkpoint_no_lifecycle(context):
|
|
"""Assert the service has no plan_lifecycle_service (default None)."""
|
|
assert context.boost_checkpoint_svc._plan_lifecycle_service is None
|
|
|
|
|
|
@then("the checkpoint service should reference the mock plan lifecycle service")
|
|
def step_verify_checkpoint_has_lifecycle(context):
|
|
"""Assert the service references the mock lifecycle we injected."""
|
|
assert (
|
|
context.boost_checkpoint_svc._plan_lifecycle_service
|
|
is context.boost_mock_lifecycle
|
|
)
|
|
|
|
|
|
# -------------------------------------------------------------------
|
|
# _build_trace_service scenarios
|
|
# -------------------------------------------------------------------
|
|
|
|
|
|
@given("explicit application settings for trace service")
|
|
def step_explicit_settings_for_trace(context):
|
|
"""Create a real Settings instance to pass explicitly."""
|
|
from cleveragents.config.settings import get_settings
|
|
|
|
context.boost_explicit_settings = get_settings()
|
|
|
|
|
|
@when("I build a trace service with an in-memory database URL and no explicit settings")
|
|
def step_build_trace_service_default(context):
|
|
"""Call _build_trace_service with only a database URL."""
|
|
context.boost_trace_svc = _build_trace_service(_IN_MEMORY_URL)
|
|
|
|
|
|
@when("I build a trace service with the explicit settings")
|
|
def step_build_trace_service_with_settings(context):
|
|
"""Call _build_trace_service with a database URL and explicit settings."""
|
|
context.boost_trace_svc = _build_trace_service(
|
|
_IN_MEMORY_URL,
|
|
settings=context.boost_explicit_settings,
|
|
)
|
|
|
|
|
|
@then("the result should be a TraceService instance")
|
|
def step_verify_trace_service_type(context):
|
|
"""Assert the returned object is a TraceService."""
|
|
assert isinstance(context.boost_trace_svc, TraceService), (
|
|
f"Expected TraceService, got {type(context.boost_trace_svc).__name__}"
|
|
)
|
|
|
|
|
|
@then("the trace service should have a repository")
|
|
def step_verify_trace_has_repository(context):
|
|
"""Assert the service was initialised with an LLMTraceRepository."""
|
|
repo = context.boost_trace_svc._repository
|
|
assert repo is not None, "Expected a repository, got None"
|
|
assert isinstance(repo, LLMTraceRepository), (
|
|
f"Expected LLMTraceRepository, got {type(repo).__name__}"
|
|
)
|
|
|
|
|
|
@then("the trace service should have resolved settings from defaults")
|
|
def step_verify_trace_default_settings(context):
|
|
"""Assert the service has settings resolved via get_settings() fallback."""
|
|
from cleveragents.config.settings import Settings
|
|
|
|
svc_settings = context.boost_trace_svc._settings
|
|
assert svc_settings is not None, "Expected settings, got None"
|
|
assert isinstance(svc_settings, Settings), (
|
|
f"Expected Settings, got {type(svc_settings).__name__}"
|
|
)
|
|
|
|
|
|
@then("the trace service should use the explicitly provided settings")
|
|
def step_verify_trace_explicit_settings(context):
|
|
"""Assert the service uses the exact Settings object we injected."""
|
|
assert context.boost_trace_svc._settings is context.boost_explicit_settings, (
|
|
"Expected the explicitly provided settings instance"
|
|
)
|